From 5da038138e5629359939679936e68a65a077daca Mon Sep 17 00:00:00 2001
From: doum <doum>
Date: 星期五, 19 九月 2025 09:59:58 +0800
Subject: [PATCH] Merge remote-tracking branch 'origin/master'
---
admin/src/components/common/Menu.vue | 195 ++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 195 insertions(+), 0 deletions(-)
diff --git a/admin/src/components/common/Menu.vue b/admin/src/components/common/Menu.vue
new file mode 100644
index 0000000..ba8acec
--- /dev/null
+++ b/admin/src/components/common/Menu.vue
@@ -0,0 +1,195 @@
+<template>
+ <div class="menu" :class="{collapse: menuData.collapse}">
+ <div class="logo">
+ <div><img src="@/assets/logo.png"></div>
+ <h1 :class="{hidden: menuData.collapse}">璞嗙背璺宠烦瀹樼綉鍚庡彴绠$悊</h1>
+ </div>
+ <scrollbar>
+ <el-menu
+ ref="menu"
+ :default-active="activeIndex"
+ text-color="#fff"
+ active-text-color="#fff"
+ :collapse="menuData.collapse"
+ :default-openeds="defaultOpeneds"
+ :collapse-transition="false"
+ @select="handleSelect"
+ >
+ <MenuItems v-for="menu in menuData.list" :key="menu.index" :menu="menu" :is-root-menu="true"/>
+ </el-menu>
+ </scrollbar>
+ </div>
+</template>
+
+<script>
+import { mapState } from 'vuex'
+import MenuItems from './MenuItems'
+import Scrollbar from './Scrollbar'
+export default {
+ name: 'Menu',
+ components: { Scrollbar, MenuItems },
+ computed: {
+ ...mapState(['menuData']),
+ // 閫変腑鐨勮彍鍗昳ndex
+ activeIndex () {
+ let path = this.$route.path
+ if (path.endsWith('/')) {
+ path = path.substring(0, path.length - 1)
+ }
+ const menuConfig = this.__getMenuConfig(path, 'url', this.menuData.list)
+ if (menuConfig == null) {
+ return null
+ }
+ return menuConfig.index
+ },
+ // 榛樿灞曞紑鐨勮彍鍗昳ndex
+ defaultOpeneds () {
+ return this.menuData.list.map(menu => menu.index)
+ }
+ },
+ methods: {
+ /**
+ * 澶勭悊鑿滃崟閫変腑
+ *
+ * @param menuIndex 閫変腑鐨勮彍鍗曠储寮�
+ */
+ handleSelect (menuIndex) {
+ const menuConfig = this.__getMenuConfig(menuIndex, 'index', this.menuData.list)
+ // 鎵句笉鍒伴〉闈�
+ try {
+ require('@/views' + menuConfig.url)
+ } catch (e) {
+ this.$tip.error('鏈壘鍒伴〉闈㈡枃浠禓/views' + menuConfig.url + '.vue锛岃妫�鏌ヨ彍鍗曡矾寰勬槸鍚︽纭�')
+ }
+ // 鐐瑰嚮褰撳墠鑿滃崟涓嶅仛澶勭悊
+ if (menuConfig.url === this.$route.path) {
+ return
+ }
+ if (menuConfig.url == null || menuConfig.url.trim().length === 0) {
+ return
+ }
+ this.$router.push(menuConfig.url)
+ },
+ /**
+ * 鑾峰彇鑿滃崟閰嶇疆
+ *
+ * @param value 鍞竴鏍囪瘑鍊�
+ * @param key 鍞竴鏍囪瘑key
+ * @param menus 鏌ユ壘鑿滃崟鑼冨洿
+ * @returns {null|*|null}
+ * @private
+ */
+ __getMenuConfig (value, key, menus) {
+ for (const menu of menus) {
+ if (menu[key] === value) {
+ return menu
+ }
+ if (menu.children != null && menu.children.length > 0) {
+ const menuConfig = this.__getMenuConfig(value, key, menu.children)
+ if (menuConfig != null) {
+ return menuConfig
+ }
+ }
+ }
+ return null
+ }
+ }
+}
+</script>
+
+<style lang="scss" scoped>
+@import "@/assets/style/variables.scss";
+.menu {
+ height: 100%;
+ display: flex;
+ flex-direction: column;
+ // LOGO
+ .logo {
+ height: 60px;
+ flex-shrink: 0;
+ line-height: 60px;
+ overflow: hidden;
+ display: flex;
+ background: $primary-color - 20;
+ padding: 0 16px;
+ & > div {
+ width: 32px;
+ flex-shrink: 0;
+ margin-right: 12px;
+ img {
+ width: 100%;
+ flex-shrink: 0;
+ vertical-align: middle;
+ position: relative;
+ top: -2px;
+ }
+ }
+ h1 {
+ font-size: 16px;
+ font-weight: 500;
+ transition: opacity ease .3s;
+ overflow: hidden;
+ &.hidden {
+ opacity: 0;
+ }
+ }
+ }
+}
+</style>
+<style lang="scss">
+@import "@/assets/style/variables.scss";
+// 鑿滃崟鏍峰紡
+.el-menu {
+ border-right: 0 !important;
+ user-select: none;
+ background: $primary-color !important;
+ .el-menu-item {
+ background: $primary-color;
+ // 閫変腑鐘舵��
+ &.is-active {
+ background: $primary-color - 40 !important;
+ }
+ // 鎮诞
+ &:hover {
+ background-color: $primary-color - 12;
+ }
+ &:focus {
+ background: $primary-color;
+ }
+ }
+ // 瀛愯彍鍗�
+ .el-submenu {
+ .el-submenu__title{
+ background-color: $primary-color;
+ }
+ &.is-active {
+ .el-submenu__title{
+ background-color: $primary-color - 20;
+ }
+ .el-menu .el-menu-item{
+ background-color: $primary-color - 20;
+ // 鎮诞
+ &:hover {
+ background-color: $primary-color - 30;
+ }
+ }
+ }
+ // 鑿滃崟涓婁笅绠ご
+ .el-submenu__title i {
+ color: #f7f7f7;
+ }
+ }
+ // 鑿滃崟鍥炬爣
+ i:not(.el-submenu__icon-arrow) {
+ color: #f7f7f7 !important;
+ position: relative;
+ top: -1px;
+ // 鑷畾涔夊浘鏍�
+ &[class^="eva-icon-"] {
+ width: 24px;
+ margin-right: 5px;
+ background-size: 15px;
+ }
+ }
+}
+</style>
--
Gitblit v1.9.3