Forráskód Böngészése

修改左侧listlist

liujiejie 1 éve
szülő
commit
3c71ffd323

+ 0 - 2
src/components/IconSelect/requireIcons.js

@@ -4,6 +4,4 @@ const re = /\.\/(.*)\.svg/;
 const icons = requireAll(req).map((i) => {
   return i.match(re)[1];
 });
-
-console.log(icons, "icons");
 export default icons;

+ 15 - 17
src/components/SvgIcons/index.vue

@@ -5,10 +5,7 @@
       aria-hidden="true"
       :style="{ width: width, height: height }"
     >
-      <use
-        :xlink:href="iconName"
-        :fill="color"
-      ></use>
+      <use :xlink:href="iconName" :fill="color"></use>
     </svg>
   </div>
 </template>
@@ -19,39 +16,40 @@
 // import '@/assets/icons/iconfont-svg.js'
 // 引入本地的svg文件
 // 定义一个加载目录的函数
-const requireAll = (requireContext) => requireContext.keys().map(requireContext)
-const req = require.context('@/icons/svg', false, /\.svg$/)
+const requireAll = (requireContext) =>
+  requireContext.keys().map(requireContext);
+const req = require.context("@/icons/svg", false, /\.svg$/);
 // 加载目录下的所有的 svg 文件
-requireAll(req)
+requireAll(req);
 
 export default {
-  name: 'Icon',
+  name: "Icon",
   props: {
     name: String,
     prefix: {
       type: String,
-      default: 'icon-'
+      default: "icon-",
     },
     color: {
       type: String,
-      default: ''
+      default: "",
     },
     width: {
       type: String,
-      default: '16px'
+      default: "16px",
     },
     //svg高度
     height: {
       type: String,
-      default: '16px'
-    }
+      default: "16px",
+    },
   },
   computed: {
     iconName() {
-      return `#${this.prefix}${this.name}`
-    }
-  }
-}
+      return `#${this.prefix}${this.name}`;
+    },
+  },
+};
 </script>
 
 <style lang="scss" scoped>

+ 64 - 61
src/router/index.js

@@ -22,9 +22,10 @@ const createRouter = () =>
         children: [
           // 驾驶舱
           {
+            id: 1,
             path: "cockpitManage",
             name: "cockpitManage",
-
+            iconName: "gps",
             component: () =>
               import(
                 /*webpackChunkName:'home-cockpitManage'*/ "../views/admin/cockpitManage/Index.vue"
@@ -32,6 +33,8 @@ const createRouter = () =>
             children: [
               // 电子地图
               {
+                id: 11,
+                iconName: "gps",
                 path: "electronic-map",
                 name: "electronicMap",
                 component: () =>
@@ -42,68 +45,68 @@ const createRouter = () =>
             ],
           },
           // 电子地图
-          {
-            path: "electronic-map",
-            name: "electronicMap",
-            component: () =>
-              import(
-                /*webpackChunkName:'electronic-map'*/ "../views/admin/cockpitManage/electronicMap.vue"
-              ),
-          },
-          // 数据操作
-          {
-            path: "dataAdministration",
-            name: "dataAdministration",
-            component: () =>
-              import(
-                /*webpackChunkName:'dataAdministration'*/ "../views/dataAdministration/index.vue"
-              ),
-          },
-          // 企业信息
-          {
-            path: "enterprise",
-            name: "enterprise",
-            component: () =>
-              import(
-                /*webpackChunkName:'enterprise'*/ "../views/ledger/enterprise.vue"
-              ),
-          },
+          // {
+          //   path: "electronic-map",
+          //   name: "electronicMap",
+          //   component: () =>
+          //     import(
+          //       /*webpackChunkName:'electronic-map'*/ "../views/admin/cockpitManage/electronicMap.vue"
+          //     ),
+          // },
+          // // 数据操作
+          // {
+          //   path: "dataAdministration",
+          //   name: "dataAdministration",
+          //   component: () =>
+          //     import(
+          //       /*webpackChunkName:'dataAdministration'*/ "../views/dataAdministration/index.vue"
+          //     ),
+          // },
+          // // 企业信息
+          // {
+          //   path: "enterprise",
+          //   name: "enterprise",
+          //   component: () =>
+          //     import(
+          //       /*webpackChunkName:'enterprise'*/ "../views/ledger/enterprise.vue"
+          //     ),
+          // },
           // 风场信息
-          {
-            path: "windsite",
-            name: "windsite",
-            component: () =>
-              import(
-                /*webpackChunkName:'windsite'*/ "../views/ledger/windsite.vue"
-              ),
-          },
+          // {
+          //   path: "windsite",
+          //   name: "windsite",
+          //   component: () =>
+          //     import(
+          //       /*webpackChunkName:'windsite'*/ "../views/ledger/windsite.vue"
+          //     ),
+          // },
           // 风机信息
-          {
-            path: "draught",
-            name: "draught",
-            component: () =>
-              import(
-                /*webpackChunkName:'draught'*/ "../views/ledger/draught.vue"
-              ),
-          },
-          // 机型信息
-          {
-            path: "milltype",
-            name: "milltype",
-            component: () =>
-              import(
-                /*webpackChunkName:'milltype'*/ "../views/ledger/milltype.vue"
-              ),
-          },
-          // 测风塔信息
-          {
-            path: "anemometer",
-            name: "anemometer",
-            component: () =>
-              import(
-                /*webpackChunkName:'anemometer'*/ "../views/ledger/anemometer.vue"
-              ),
-          },
+          // {
+          //   path: "draught",
+          //   name: "draught",
+          //   component: () =>
+          //     import(
+          //       /*webpackChunkName:'draught'*/ "../views/ledger/draught.vue"
+          //     ),
+          // },
+          // // 机型信息
+          // {
+          //   path: "milltype",
+          //   name: "milltype",
+          //   component: () =>
+          //     import(
+          //       /*webpackChunkName:'milltype'*/ "../views/ledger/milltype.vue"
+          //     ),
+          // },
+          // // 测风塔信息
+          // {
+          //   path: "anemometer",
+          //   name: "anemometer",
+          //   component: () =>
+          //     import(
+          //       /*webpackChunkName:'anemometer'*/ "../views/ledger/anemometer.vue"
+          //     ),
+          // },
         ],
       },
       {

+ 6 - 0
src/store/auth.js

@@ -6,6 +6,7 @@ export default {
   namespaced: true, // 子模块一定要开启命名空间
   state: {
     userInfo: {},
+    dynamicRouter: [],
   },
   getters: {},
   mutations: {
@@ -16,6 +17,9 @@ export default {
       state.userInfo = {};
       resetRouter();
     },
+    SET_DYNAMIC_ROUTER(state, payload) {
+      state.dynamicRouter = payload;
+    },
   },
   actions: {
     async goLogin({ commit, dispatch }, { loginForm, router }) {
@@ -47,6 +51,7 @@ export default {
         // 清空原有的动态子路由
         homeRoute.children = originalChildren;
         const { authRouterList } = getAuthRouterFn(resultRouter);
+        commit("SET_DYNAMIC_ROUTER", authRouterList);
         authRouterList.forEach((item) => {
           // 动态路由的父路径设置为home
           homeRoute.children.push(item);
@@ -54,6 +59,7 @@ export default {
         // 重新添加home路由
         router.addRoute(homeRoute);
       }
+      // console.log("/homeRoute", homeRoute, router.getRoutes());
       // 添加404页面路由
       router.addRoute({
         path: "/:pathMatch(.*)*",

+ 12 - 11
src/utils/getAuth.js

@@ -1,13 +1,6 @@
-/*
- * @Author: your name
- * @Date: 2024-05-17 16:09:03
- * @LastEditTime: 2024-05-18 18:40:13
- * @LastEditors: bogon
- * @Description: In User Settings Edit
- * @FilePath: /performance-test/src/utils/getAuth.js
- */
 import { orgList } from "@/views/home/components/mockData";
-//返回可动态添加的路由
+
+// 返回可动态添加的路由
 export const getAuthRouterFn = (list) => {
   // 将list 转成一维数组,按钮级别权限拿到 返回为[]格式
   const { result, anthBtnList } = flattenTree(list);
@@ -33,13 +26,13 @@ const flattenTree = (tree) => {
   flattenRecursive(tree);
   return { result, anthBtnList };
 };
+
 const filterTreeByPermissions = (permissions, tree) => {
   const permissionSet = new Set(permissions.map((item) => item.permissionName));
 
   const filterTreeRecursive = (nodes) => {
     return nodes.reduce((filteredNodes, node) => {
       const newNode = { ...node };
-
       if (newNode.children && newNode.children.length > 0) {
         newNode.children = filterTreeRecursive(newNode.children);
       }
@@ -47,9 +40,17 @@ const filterTreeByPermissions = (permissions, tree) => {
         permissionSet.has(newNode.name) ||
         (newNode.children && newNode.children.length > 0)
       ) {
+        // 找到对应的iconName
+        const permission = permissions.find(
+          (perm) => perm.permissionName === newNode.name
+        );
+        if (permission && permission.permissionIconUrl) {
+          newNode.iconName = permission.permissionIconUrl;
+        } else {
+          newNode.iconName = "";
+        }
         filteredNodes.push(newNode);
       }
-
       return filteredNodes;
     }, []);
   };

+ 70 - 77
src/views/home/components/Menu.vue

@@ -1,5 +1,5 @@
 <template>
-  <el-aside :width="!isCollapse ? '300px' : '100px'" class="asideBox">
+  <el-aside :width="!isCollapse ? '250px' : '100px'" class="asideBox">
     <div class="homeBox">
       <div class="logoItem" :class="{ 'flexCenter ': isCollapse }">
         <div
@@ -38,71 +38,49 @@
       ref="menu"
       class="mt-3 el-menu-vertical-demo"
       @open="handleOpen"
-      @select="handleOpen"
       @close="handleClose"
       background-color="#eff1f3"
       text-color="#000"
       active-text-color="#0754a1"
-      :router="false"
+      :router="true"
       :default-active="defaultActive"
       :unique-opened="true"
       :collapse="isCollapse"
     >
-      <el-submenu
-        v-for="(item, index) in orgList"
-        :key="index"
-        :index="item.id"
-      >
-        <template slot="title">
-          <div class="flex items-center justify-start">
-            <i
-              class="flex items-center justify-center mr-2"
-              style="margin-left: 3px"
-            >
-              <SvgIcons
-                :name="item.iconName"
-                class="dnao"
-                width="20px"
-                height="22px"
-                color="#222"
-              ></SvgIcons>
-            </i>
-            <span
-              slot="title"
-              style="display: inline-block"
-              :class="{
-                'active-menu':
-                  defaultActive ===
-                  `/windField?id=${item.id}&name=${item.name}`,
-              }"
-              >{{ item.name }}</span
-            >
-          </div>
-        </template>
-        <el-menu-item
-          v-for="(child, childIndex) in item.children"
-          :key="childIndex"
-          :index="`/home/${item.path}/${child.path}?id=${child.id}&name=${child.name}`"
+      <template v-for="item in routerList">
+        <el-submenu
+          :index="item.path"
+          v-if="item.children && item.children.length > 0"
         >
           <template slot="title">
-            <span
-              slot="title"
-              style="padding-left: 22px; width: 100%; display: inline-block"
-              :class="{
-                'active-menu':
-                  defaultActive === `/dynamo?id=${item.id}&name=${item.name}`,
-              }"
-              @click="
-                handleChangeMenuUrl(
-                  item,
-                  `/home/${item.path}/${child.path}?id=${item.id}&name=${item.name}`
-                )
-              "
-              >{{ child.name }}</span
-            >
+            <i class="el-icon-menu" v-if="isElPrefix(item.iconName)"></i>
+            <i v-else class="svnIcon"
+              ><svg-icon :icon-class="item.iconName"
+            /></i>
+            <span>{{ item.name }}</span>
           </template>
+          <el-menu-item
+            v-for="child in item.children"
+            :key="child.id"
+            :index="`/home/${item.path}/${child.path}?id=${child.id}&name=${child.name}`"
+          >
+            <i class="el-icon-menu" v-if="isElPrefix(child.iconName)"></i>
+            <i v-else class="svnIcon"
+              ><svg-icon :icon-class="child.iconName"
+            /></i>
+            <span>{{ child.name }}</span>
+          </el-menu-item>
+        </el-submenu>
+        <el-menu-item
+          :key="item.id"
+          :index="`/home/${item.path}?id=${item.id}&name=${item.name}`"
+          v-else
+        >
+          <i class="el-icon-menu" v-if="isElPrefix(item.iconName)"></i>
+          <i v-else class="svnIcon"><svg-icon :icon-class="item.iconName" /></i>
+          <span>{{ item.name }}</span>
         </el-menu-item>
-      </el-submenu>
+      </template>
     </el-menu>
     <div class="foldBox flexCenter">
       <span
@@ -120,30 +98,46 @@
     </div>
   </el-aside>
 </template>
+
 <script>
 import { orgList } from "./mockData";
-
 export default {
   data() {
     return {
-      // 展开收起
       isCollapse: false,
-      // 三级菜单数组
       orgList: orgList,
-      // 搜索值
       searchInputValue: "",
       defaultActive: "",
       activeIndex: false,
       keyObject: {},
+      routerList: [
+        {
+          path: "cockpitManage",
+          name: "驾驶舱",
+          iconName: "gps",
+          children: [
+            {
+              iconName: "gps",
+              path: "electronic-map",
+              name: "电子地图",
+            },
+          ],
+        },
+      ],
     };
   },
-
+  created() {
+    this.routerList = [
+      ...this.routerList,
+      ...this.$store.state.auth.dynamicRouter,
+    ];
+    console.log(this.routerList, "组件内dynamicRouter");
+  },
   computed: {
     currentMenuIndex() {
       return this.$store.state.breadStore?.currentUrl?.routeUrl;
     },
   },
-
   watch: {
     currentMenuIndex: {
       deep: true,
@@ -162,27 +156,27 @@ export default {
       },
     },
   },
-  created() {},
   methods: {
+    isElPrefix(str) {
+      const regex = /^el-/;
+      return regex.test(str);
+    },
     getBreadcrumbList(keyPath) {
       const urls = keyPath;
       const result = urls.map((url, index) => {
-        const params = new URLSearchParams(url.split("?")[1]); // 解析 URL 参数
+        const params = new URLSearchParams(url.split("?")[1]);
         const id = params.get("id");
         const name = params.get("name");
         const routeUrl = url;
-        // 如果是最后一个路由,则添加额外属性
         if (index === urls.length - 1) {
           return { id, name, routeUrl, currentPage: true };
         }
         return { id, name, routeUrl };
       });
-      // console.log(result)
       this.$store.commit("breadStore/ADD_BREAD", result);
       return result;
     },
     handleOpen(key, keyPath) {
-      // console.log(key, keyPath)
       this.activeIndex = false;
       this.keyObject = {
         key,
@@ -190,14 +184,12 @@ export default {
       };
     },
     handleClose(key, keyPath) {
-      // console.log(key, keyPath)
       this.activeIndex = false;
       this.keyObject = {
         key,
         keyPath,
       };
     },
-
     shrinkTree() {
       this.$refs.menu.close(`/orgsPage?id=${orgList.id}&name=${orgList.name}`);
     },
@@ -220,6 +212,7 @@ export default {
   },
 };
 </script>
+
 <style lang="scss" scoped>
 .el-menu-vertical-demo:not(.el-menu--collapse) {
   width: 200px;
@@ -318,26 +311,19 @@ export default {
       &:hover {
         p {
           color: #19436d;
-          // border-bottom: 1px solid #409eff;
         }
-
-        // background-color: rgb(64, 158, 255, 0.6);
         transition: width 0.5s ease, transform 0.5s ease;
-        /* 过渡效果 */
         transform-origin: left;
-        /* 设置变换的原点在左侧 */
       }
 
       .left {
         left: 50%;
         transform: scaleX(0);
-        /* 初始时将左侧元素宽度设为 0 */
       }
 
       .right {
         left: 0;
         transform: scaleX(0);
-        /* 初始时将右侧元素宽度设为 0 */
       }
     }
   }
@@ -371,19 +357,27 @@ export default {
 }
 
 ::v-deep .el-submenu__title {
-  padding-left: 30px !important;
+  display: flex;
+  align-items: center;
 }
 
 ::v-deep .el-submenu__icon-arrow {
   right: 30px;
 }
 
+::v-deep .svnIcon {
+  vertical-align: middle;
+  margin-right: 5px;
+  width: 24px;
+  text-align: center;
+  font-size: 18px;
+}
+
 ::-webkit-scrollbar {
   width: 6px;
   display: none;
 }
 
-/* 滚动条上的滚动滑块 */
 ::-webkit-scrollbar-thumb {
   border-radius: 10px;
   background-color: #aaabaa;
@@ -394,7 +388,6 @@ export default {
   background-color: #efeff0;
 }
 
-/* 滚动条没有滑块的轨道部分 */
 ::-webkit-scrollbar-track-piece {
   background-color: #efeff0;
   border-radius: 10px;

+ 3 - 0
src/views/home/components/mockData.js

@@ -12,6 +12,7 @@ export const orgList = [
       {
         id: 11,
         name: "电子地图",
+        iconName: "gps",
         path: "electronic-map",
         component: () =>
           import(
@@ -50,6 +51,7 @@ export const orgList = [
       {
         id: 31,
         name: "数据操作",
+        iconName: "gps",
         path: "dataAdministration",
         component: () =>
           import(
@@ -101,6 +103,7 @@ export const orgList = [
       {
         id: 51,
         name: "用户管理",
+
         path: "userMag",
         component: () =>
           import(