rui.jiang hai 1 ano
pai
achega
18410e6813

+ 1 - 1
src/api/dataManage.js

@@ -1,7 +1,7 @@
 /*
  * @Author: your name
  * @Date: 2024-06-04 09:48:21
- * @LastEditTime: 2024-06-05 15:24:06
+ * @LastEditTime: 2024-07-05 15:34:58
  * @LastEditors: bogon
  * @Description: In User Settings Edit
  * @FilePath: /dashengmag/performance-test/src/api/dataManage.js

+ 9 - 1
src/api/performance.js

@@ -1,12 +1,20 @@
 /*
  * @Author: your name
  * @Date: 2024-06-03 09:29:50
- * @LastEditTime: 2024-06-17 14:31:34
+ * @LastEditTime: 2024-07-05 15:35:24
  * @LastEditors: bogon
  * @Description: In User Settings Edit
  * @FilePath: /performance-test/src/api/performance。.js
  */
 import request from "@/utils/request";
+//自动生成批次名称
+export function createBatchName(data) {
+  return request({
+    url: "/energy-manage-service/windEnginBatch/createBatchName",
+    method: "post",
+    data,
+  });
+}
 //批次管理性能分析列表获取
 export function getBatchMagList(data) {
   return request({

+ 24 - 0
src/directives/permission.js

@@ -0,0 +1,24 @@
+import { store } from "../store/index.js";
+
+export default {
+  inserted(el, binding, vnode) {
+    const { value } = binding;
+    const all_permission = "*:*:*";
+    const permissions = store.getters && store.getters.permissions;
+
+    if (value && value instanceof Array && value.length > 0) {
+      const permissionFlag = value;
+
+      const hasPermissions = permissions.some((permission) => {
+        return (
+          all_permission === permission || permissionFlag.includes(permission)
+        );
+      });
+      if (!hasPermissions) {
+        el.parentNode && el.parentNode.removeChild(el);
+      }
+    } else {
+      throw new Error(`请设置操作权限标签值`);
+    }
+  },
+};

+ 2 - 1
src/main.js

@@ -17,6 +17,7 @@ Vue.component("SvgIcons", SvgIcons);
 import qs from "qs";
 // 将自动注册所有组件为全局组件
 import dataV from "@jiaminghi/data-view";
+import permission from "./directives/permission"; // 导入自定义指令
 import lazyLoad from "./directives/lazyLoad";
 Vue.use(dataV);
 Vue.prototype.$qs = qs;
@@ -44,7 +45,7 @@ Vue.prototype.$formatDate = function (date) {
   return `${year}-${month}-${day}`;
 };
 Vue.directive("lazy-load", lazyLoad);
-
+Vue.directive("hasPermi", permission);
 // 时间戳转换
 Vue.prototype.$formatDateTWO = function (timestamp) {
   const date = new Date(timestamp);

+ 15 - 15
src/mixins/echartsMixin.js

@@ -4,8 +4,8 @@ const myMixin = {
     resize() {
       // 当宽高变化时就会执行
       //执行某些操作 重新改变图表, 同时传参,设置动画效果
-      this.myChart.resize({ animation: { duration: 1000 }})
-    }
+      this.myChart.resize({ animation: { duration: 1000 } });
+    },
   },
   //自定义指令,图表的宽度采用百分比,父盒子宽度变化,那图表盒子大小也变化了,但是图表不会重新绘制
   //原理:判断盒子本身宽度改变了,再调用echarts的resize方法重新绘制
@@ -15,30 +15,30 @@ const myMixin = {
       // 指令的名称
       bind(el, binding) {
         // el为绑定的元素,binding为绑定给指令的对象
-        let width = ''
-        let height = ''
+        let width = "";
+        let height = "";
         function isReize() {
           //这个方法可以获取元素的css样式对象
-          const style = document.defaultView.getComputedStyle(el)
+          const style = document.defaultView.getComputedStyle(el);
           //对比跟上次宽度是否改变,如果改变了
           if (width !== style.width || height !== style.height) {
             //调用resize方法
-            binding.value() // 关键
+            binding.value(); // 关键
           }
           //记录当前宽高
-          width = style.width
-          height = style.height
+          width = style.width;
+          height = style.height;
         }
         //设置监听器,每隔一段时间对比看看
-        el.__vueSetInterval__ = setInterval(isReize, 300)
+        el.__vueSetInterval__ = setInterval(isReize, 300);
       },
       //只调用一次,指令与元素解绑时调用
       unbind(el) {
         //清除定时器
-        clearInterval(el.__vueSetInterval__)
-      }
-    }
-  }
-}
+        clearInterval(el.__vueSetInterval__);
+      },
+    },
+  },
+};
 
-export { myMixin }
+export { myMixin };

+ 15 - 77
src/router/index.js

@@ -30,92 +30,17 @@ const createRouter = () =>
               import(
                 /*webpackChunkName:'home-cockpitManage'*/ "../views/admin/cockpitManage/Index.vue"
               ),
-            // children: [
-            //   // 电子地图
-            //   {
-            //     id: 11,
-            //     path: "electronic-map",
-            //     name: "electronicMap",
-            //     component: () =>
-            //       import(
-            //         /*webpackChunkName:'home-cockpitManage'*/ "../views/admin/cockpitManage/electronicMap.vue"
-            //       ),
-            //   },
-            // ],
           },
           {
             // 电子地图
             id: 11,
-            path: "cockpitManage/electronic-map",
+            path: "/home/cockpitManage/electronic-map",
             name: "电子地图",
             component: () =>
               import(
                 /*webpackChunkName:'home-cockpitManage'*/ "../views/admin/cockpitManage/electronicMap.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: "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"
-          //     ),
-          // },
         ],
       },
       {
@@ -123,6 +48,12 @@ const createRouter = () =>
         name: "login",
         component: () => import("../views/login/Index.vue"),
       },
+      // 404 Page Not Found
+      // {
+      //   path: "*",
+      //   name: "NotFound",
+      //   component: () => import("../views/error/404.vue"),
+      // },
     ],
   });
 
@@ -137,7 +68,14 @@ VueRouter.prototype.push = function push(location) {
 export function resetRouter() {
   const newRouter = createRouter();
   router.matcher = newRouter.matcher; // reset router
-  console.log(router.getRoutes(), "重置后的路由");
 }
+router.beforeEach((to, from, next) => {
+  console.log(to, "to");
+  if (to.matched.length === 0) {
+    return next("/login");
+  } else {
+    next();
+  }
+});
 
 export default router;

+ 7 - 1
src/store/auth.js

@@ -7,6 +7,7 @@ export default {
   state: {
     userInfo: {},
     dynamicRouter: [],
+    authBtnList: [],
   },
   getters: {},
   mutations: {
@@ -20,6 +21,9 @@ export default {
     SET_DYNAMIC_ROUTER(state, payload) {
       state.dynamicRouter = payload;
     },
+    SET_AUTHBTNLIST(state, payload) {
+      state.authBtnList = payload;
+    },
   },
   actions: {
     async goLogin({ commit, dispatch }, { loginForm, router }) {
@@ -50,7 +54,9 @@ export default {
         );
         // 清空原有的动态子路由
         homeRoute.children = originalChildren;
-        const { authRouterList } = getAuthRouterFn(resultRouter);
+        const { authRouterList, anthBtnList } = getAuthRouterFn(resultRouter);
+        console.log();
+        commit("SET_AUTHBTNLIST", anthBtnList);
         commit("SET_DYNAMIC_ROUTER", authRouterList);
         authRouterList.forEach((item) => {
           // 动态路由的父路径设置为home

+ 1 - 0
src/store/index.js

@@ -18,6 +18,7 @@ export const store = new Vuex.Store({
     getterPrice(state) {
       return (state.price += 100);
     },
+    permissions: (state) => state.auth.authBtnList,
     //调用this.$store.getters.getterPrice
   },
   mutations: {

+ 71 - 50
src/utils/getAuth.js

@@ -1,62 +1,83 @@
-import { orgList } from "@/views/home/components/mockData";
+//import { orgList } from "@/views/home/components/mockData";
 
 // 返回可动态添加的路由
 export const getAuthRouterFn = (list) => {
-  // 将list 转成一维数组,按钮级别权限拿到 返回为[]格式
-  const { result, anthBtnList } = flattenTree(list);
-  const arr = filterTreeByPermissions(result, orgList);
-  return { authRouterList: arr, anthBtnList };
-};
-
-const flattenTree = (tree) => {
-  let result = [];
   let anthBtnList = [];
-  const flattenRecursive = (nodes) => {
-    nodes.forEach((node) => {
-      result.push(node);
-      if (node.children && node.children.length > 0) {
-        flattenRecursive(node.children);
-      }
-      if (node.permissionDepth === 2) {
-        anthBtnList.push(node);
-      }
-    });
-  };
-
-  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);
-      }
-      if (
-        permissionSet.has(newNode.name) ||
-        (newNode.children && newNode.children.length > 0)
-      ) {
-        // 找到对应的iconName
-        const permission = permissions.find(
-          (perm) => perm.permissionName === newNode.name
-        );
-        if (permission && permission.permissionShow) {
-          newNode.meta.hidden = permission.permissionShow == 1 ? false : true;
-        }
-        if (permission && permission.permissionIconUrl) {
-          newNode.iconName = permission.permissionIconUrl;
-        } else {
-          newNode.iconName = "";
-        }
-        filteredNodes.push(newNode);
+      filteredNodes.push({
+        id: node.permissionId,
+        name: node.permissionName,
+        path: node.permissionCode,
+        meta: {
+          hidden: node.permissionShow == 1 ? false : true,
+        },
+        iconName: node.permissionIconUrl ? node.permissionIconUrl : "",
+        component: () =>
+          import(/*webpackChunkName:'system'*/ `@/views${node.permissionUrl}`),
+        children:
+          newNode.children && newNode.children.length > 0
+            ? filterTreeRecursive(newNode.children)
+            : undefined,
+      });
+      if (node.permissionType === 3) {
+        anthBtnList.push(node.permissionCode);
       }
       return filteredNodes;
     }, []);
   };
-
-  return filterTreeRecursive(tree);
+  return { authRouterList: filterTreeRecursive(list), anthBtnList };
+  // 将list 转成一维数组,按钮级别权限拿到 返回为[]格式
+  //   const { result, anthBtnList } = flattenTree(list);
+  //   const arr = filterTreeByPermissions(result, orgList);
+  //   return { authRouterList: arr, anthBtnList };
+  // };
+  // const flattenTree = (tree) => {
+  //   let result = [];
+  //   let anthBtnList = [];
+  //   const flattenRecursive = (nodes) => {
+  //     nodes.forEach((node) => {
+  //       result.push(node);
+  //       if (node.children && node.children.length > 0) {
+  //         flattenRecursive(node.children);
+  //       }
+  //       if (node.permissionDepth === 2) {
+  //         anthBtnList.push(node);
+  //       }
+  //     });
+  //   };
+  //   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);
+  //       }
+  //       if (
+  //         permissionSet.has(newNode.name) ||
+  //         (newNode.children && newNode.children.length > 0)
+  //       ) {
+  //         // 找到对应的iconName
+  //         const permission = permissions.find(
+  //           (perm) => perm.permissionName === newNode.name
+  //         );
+  //         if (permission && permission.permissionShow) {
+  //           newNode.meta.hidden = permission.permissionShow == 1 ? false : true;
+  //         }
+  //         if (permission && permission.permissionIconUrl) {
+  //           newNode.iconName = permission.permissionIconUrl;
+  //         } else {
+  //           newNode.iconName = "";
+  //         }
+  //         filteredNodes.push(newNode);
+  //       }
+  //       return filteredNodes;
+  //     }, []);
+  //   };
+  //   return filterTreeRecursive(tree);
 };

+ 7 - 7
src/views/error/405.vue

@@ -3,16 +3,16 @@
 </template>
 
 <script>
-import Page405 from '@/assets/error/405.svg'
-import ErrorPage from './components/ErrorPage.vue'
+import Page405 from "@/assets/error/404.svg";
+import ErrorPage from "./components/ErrorPage.vue";
 export default {
   components: {
-    ErrorPage
+    ErrorPage,
   },
   data() {
     return {
-      Page405: Page405
-    }
-  }
-}
+      Page405: Page405,
+    };
+  },
+};
 </script>

+ 9 - 9
src/views/home/components/Menu.vue

@@ -63,13 +63,8 @@
             v-for="child in item.children"
             v-if="child.meta?.hidden === false"
             :key="child.id"
-            :index="`/home/${item.path}/${child.path}?id=${child.id}`"
-            @click="
-              handleChangeMenuUrl(
-                child,
-                `/home/${item.path}/${child.path}?id=${child.id}`
-              )
-            "
+            :index="`${child.path}?id=${child.id}`"
+            @click="handleChangeMenuUrl(child, `${child.path}?id=${child.id}`)"
           >
             <i v-if="isElPrefix(child.iconName)" class="el-icon-menu"></i>
             <i v-else class="svnIcon">
@@ -81,8 +76,8 @@
         <el-menu-item
           v-else-if="item.meta?.hidden === false"
           :key="item.id"
-          :index="`/home/${item.path}?id=${item.id}`"
-          @click="handleChangeMenuUrl(item, `/home/${item.path}?id=${item.id}`)"
+          :index="`${item.path}?id=${item.id}`"
+          @click="handleChangeMenuUrl(item, `${item.path}?id=${item.id}`)"
         >
           <i v-if="isElPrefix(item.iconName)" class="el-icon-menu"></i>
           <i v-else class="svnIcon">
@@ -127,8 +122,13 @@ export default {
       routerList: [
         {
           id: 1,
+<<<<<<< HEAD
           path: "cockpitManage",
           name: "首页",
+=======
+          path: "/home/cockpitManage",
+          name: "驾驶舱",
+>>>>>>> 426f0b43f3a3fc4d5f4762ce74d3944c183a9d52
           iconName: "gps",
           meta: {
             hidden: false,

+ 45 - 18
src/views/performance/batchMag.vue

@@ -1,7 +1,7 @@
 <!--
  * @Author: your name
  * @Date: 2024-05-27 09:23:37
- * @LastEditTime: 2024-06-27 09:35:32
+ * @LastEditTime: 2024-07-05 16:03:11
  * @LastEditors: bogon
  * @Description: In User Settings Edit
  * @FilePath: /performance-test/src/views/performance/batchMag.vue
@@ -51,7 +51,11 @@
     </div>
     <div class="list-page">
       <div class="newly">
-        <el-button type="primary" @click="newnuedialog" size="small"
+        <el-button
+          v-hasPermi="['performance:batchMag:add']"
+          type="primary"
+          @click="newnuedialog"
+          size="small"
           >新增</el-button
         >
       </div>
@@ -96,10 +100,15 @@
           width="200"
         >
           <template slot-scope="scope">
-            <el-button @click="compile(scope.row)" type="text" size="small"
+            <el-button
+              v-hasPermi="['performance:batchMag:edit']"
+              @click="compile(scope.row)"
+              type="text"
+              size="small"
               >编辑</el-button
             >
             <el-button
+              v-hasPermi="['performance:batchMag:editState']"
               v-if="scope.row.batchState == 0"
               @click="setState(1, scope.row)"
               type="text"
@@ -108,6 +117,7 @@
             >
             <el-button
               v-else
+              v-hasPermi="['performance:batchMag:editState']"
               style="color: #666"
               @click="setState(0, scope.row)"
               type="text"
@@ -118,6 +128,7 @@
             <el-button
               style="color: #f00"
               @click="deleted(scope.row)"
+              v-hasPermi="['performance:batchMag:delete']"
               type="text"
               size="small"
               :disabled="scope.row.batchState == 1"
@@ -168,7 +179,11 @@
               ></el-option>
             </el-select>
           </el-form-item>
-          <el-form-item label="批次名称" prop="batchName">
+          <el-form-item
+            label="批次名称"
+            prop="batchName"
+            v-if="title === '编辑'"
+          >
             <el-input
               v-model="ruleForm.batchName"
               placeholder="请输入批次名称"
@@ -199,6 +214,7 @@ import {
   queryCodeNum,
   onOrOffFieldBatch,
   deleteFieldBatch,
+  createBatchName,
 } from "@/api/performance.js";
 export default {
   data() {
@@ -352,21 +368,32 @@ export default {
           this.loadingView = true;
           switch (this.title) {
             case "新增":
-              addFieldBatch({ ...this.ruleForm, batchCode: undefined })
-                .then((res) => {
-                  this.$message({
-                    type: "success",
-                    message: res.msg,
-                  });
-                  // this.loading = false;
-                  this.getTableList();
-                  this.nuedialog = false;
-                  this.loadingView = false;
+              const obj = this.fieldCodeList.find(
+                (item) => item.codeNumber === this.ruleForm.fieldCode
+              );
+              const form = new FormData();
+              form.append("fieldName", obj.fieldName);
+              createBatchName(form).then((results) => {
+                addFieldBatch({
+                  ...this.ruleForm,
+                  batchName: results.data,
+                  batchCode: undefined,
                 })
-                .catch(() => {
-                  this.loadingView = false;
-                  // this.loading = false;
-                });
+                  .then((res) => {
+                    this.$message({
+                      type: "success",
+                      message: res.msg,
+                    });
+                    // this.loading = false;
+                    this.getTableList();
+                    this.nuedialog = false;
+                    this.loadingView = false;
+                  })
+                  .catch(() => {
+                    this.loadingView = false;
+                    // this.loading = false;
+                  });
+              });
 
               break;
             case "编辑":

+ 44 - 3
src/views/performance/components/analysisEvent.vue

@@ -1,7 +1,7 @@
 <!--
  * @Author: your name
  * @Date: 2024-05-29 09:13:51
- * @LastEditTime: 2024-06-26 16:15:40
+ * @LastEditTime: 2024-07-04 10:37:21
  * @LastEditors: bogon
  * @Description: In User Settings Edit
  * @FilePath: /performance-test/src/views/performance/components/analysisEvent.vue
@@ -43,6 +43,9 @@
                   multiple
                   clearable
                 >
+                  <el-checkbox v-model="checked" @change="selectAll"
+                    >全选</el-checkbox
+                  >
                   <el-option
                     v-for="item in analysisTypeList"
                     :key="item.typeCode"
@@ -64,6 +67,11 @@
                   size="small"
                   clearable
                 >
+                  <el-checkbox
+                    v-model="checkedTurbines"
+                    @change="selectAllTurbines"
+                    >全选</el-checkbox
+                  >
                   <el-option
                     v-for="item in windEngineGroupList"
                     :key="item.engineCode"
@@ -682,6 +690,8 @@ import { getWindEngineGroup } from "@/api/ledger";
 export default {
   data() {
     return {
+      checkedTurbines: false,
+      checked: false,
       htmlLoading: true,
       engineCode: null, //台账机组编号
       picker: [],
@@ -735,6 +745,26 @@ export default {
     this.getWindCodeList();
   },
   methods: {
+    selectAllTurbines() {
+      this.form.turbines = [];
+      if (this.checkedTurbines) {
+        this.windEngineGroupList.map((item) => {
+          this.form.turbines.push(item.engineCode);
+        });
+      } else {
+        this.form.turbines = [];
+      }
+    },
+    selectAll() {
+      this.form.configAnalysis = [];
+      if (this.checked) {
+        this.analysisTypeList.map((item) => {
+          this.form.configAnalysis.push(item.typeCode);
+        });
+      } else {
+        this.form.configAnalysis = [];
+      }
+    },
     iframeLoad() {
       this.htmlLoading = false;
     },
@@ -955,13 +985,24 @@ export default {
     }
   }
 }
+.el-select-dropdown__wrap {
+  .el-select-dropdown__list {
+    .el-checkbox {
+      display: flex;
+      justify-content: end;
+      margin: 0px 20px;
+    }
+  }
+}
+
 // .setting {
 //   font-size: 20px;
 //   font-weight: 900;
 // }
 ::v-deep.el-select--small,
 ::v-deep.el-select__tags {
-  width: 200px !important;
+  width: 220px !important;
+  // min-width: 180px !important;
   .el-tag--light {
     display: flex;
     justify-content: space-between;
@@ -1026,7 +1067,7 @@ export default {
   }
 }
 ::v-deep.el-input--small .el-input__inner {
-  width: 200px !important;
+  width: 220px !important;
 }
 .demo-input-suffix {
   display: flex !important;

+ 5 - 3
src/views/system/menuMag/components/editDialog.vue

@@ -157,6 +157,7 @@ export default {
   created() {
     this.initializeForm();
   },
+
   watch: {
     row: {
       handler(newVal) {
@@ -193,7 +194,6 @@ export default {
       };
     },
     initializeForm() {
-      console.log(this.checkId, "checkid");
       this.menuOptions[0].children.push(...this.tableData);
       if (this.row && this.title === "编辑" && this.activeName === "2") {
         this.menuForm = {
@@ -241,13 +241,14 @@ export default {
     },
 
     normalizer(node) {
-      if (node.children && !node.children.length) {
+      const children = Array.isArray(node.children) ? node.children : [];
+      if (children.length === 0) {
         delete node.children;
       }
       return {
         id: node.permissionId,
         label: node.permissionName,
-        children: node.children,
+        children: children.length > 0 ? [...children] : undefined,
       };
     },
     submit() {
@@ -256,6 +257,7 @@ export default {
           if (this.title === "编辑" && this.row) {
             updateMenuFn({
               ...this.menuForm,
+              ptype: this.activeName,
               permissionId: this.row.permissionId,
             })
               .then((res) => {

+ 248 - 0
src/views/system/menuMag/components/editDialogBtn.vue

@@ -0,0 +1,248 @@
+<template>
+  <div>
+    <el-form
+      :model="menuForm"
+      :rules="addMenuRules"
+      ref="addUserForm"
+      label-width="100px"
+      class="demo-ruleForm"
+    >
+      <el-form-item label="上级目录:" prop="parentId">
+        <treeselect
+          :normalizer="normalizer"
+          :noChildrenText="'没有子选项'"
+          :noOptionsText="'没有可选项'"
+          :noResultsText="'没有匹配的结果'"
+          :placeholder="'请选择'"
+          :searchable="true"
+          v-model="menuForm.parentId"
+          placeholder="请选择"
+          :options="menuOptions"
+        ></treeselect>
+      </el-form-item>
+      <el-form-item label="菜单名称:" prop="pname">
+        <el-input
+          v-model="menuForm.pname"
+          placeholder="请输入菜单名称"
+        ></el-input>
+      </el-form-item>
+      <el-form-item label="权限标识:" prop="pcode">
+        <el-input
+          v-model="menuForm.pcode"
+          placeholder="请输入权限标识"
+        ></el-input>
+      </el-form-item>
+      <el-form-item label="状态:" prop="pstat">
+        <el-select
+          v-model="menuForm.pstat"
+          placeholder="请选择状态"
+          style="width: 100%"
+        >
+          <el-option label="启用" :value="1"></el-option>
+          <el-option label="停用" :value="0"></el-option>
+        </el-select>
+      </el-form-item>
+    </el-form>
+  </div>
+</template>
+
+<script>
+import Treeselect from "@riophae/vue-treeselect";
+import { addMenuFn, updateMenuFn } from "@/api/system";
+import "@riophae/vue-treeselect/dist/vue-treeselect.css";
+
+export default {
+  components: {
+    Treeselect,
+  },
+  props: {
+    activeName: {
+      type: String,
+    },
+    tableData: {
+      type: Array,
+    },
+    checkId: {
+      type: Number,
+    },
+    title: {
+      type: String,
+    },
+    row: {
+      type: Object,
+    },
+  },
+  data() {
+    return {
+      name: "",
+      menuForm: {
+        parentId: null,
+        pname: null,
+        purl: null,
+        pstat: null,
+        pcode: null,
+        permissionShow: 2,
+        piconUrl: "",
+      },
+      addMenuRules: {
+        // permissionShow: {
+        //   required: true,
+        //   message: "请选择",
+        //   trigger: "change",
+        // },
+        pcode: [{ required: true, message: "请填写权限标识", trigger: "blur" }],
+        pname: [{ required: true, message: "请填写菜单名称", trigger: "blur" }],
+        // purl: [{ required: true, message: "请填写路由地址", trigger: "blur" }],
+        parentId: [
+          { required: true, message: "请选择上级目录", trigger: "change" },
+        ],
+        pstat: [{ required: true, message: "请选择状态", trigger: "change" }],
+      },
+      stateOptions: [],
+      menuOptions: [
+        { permissionId: 0, permissionName: "主类目", children: [] },
+      ],
+    };
+  },
+  created() {
+    this.initializeForm();
+  },
+  watch: {
+    row: {
+      handler(newVal) {
+        if (newVal) {
+          this.initializeForm();
+        }
+      },
+      immediate: true,
+      deep: true,
+    },
+    checkId(newVal) {
+      if (newVal !== null && newVal !== undefined) {
+        this.menuForm.parentId = newVal;
+        this.initializeForm();
+      }
+    },
+    tableData: {
+      handler(newData) {
+        this.$nextTick(() => {
+          this.menuOptions[0].children = [];
+          this.menuOptions[0].children.push(...newData);
+        });
+      },
+      immediate: true,
+      deep: true,
+    },
+  },
+  methods: {
+    // 选择图标
+    selected(name) {
+      this.menuForm = {
+        ...this.menuForm,
+        piconUrl: name,
+      };
+    },
+    initializeForm() {
+      this.menuOptions[0].children.push(...this.tableData);
+      if (this.row && this.title === "编辑") {
+        this.menuForm = {
+          parentId: this.row.parentId,
+          pname: this.row.permissionName,
+          purl: this.row.permissionUrl,
+          pstat: this.row.permissionState,
+          pcode: this.row.permissionCode,
+          permissionShow: 2,
+        };
+      } else if (this.title === "新增") {
+        this.menuForm.parentId = this.checkId;
+      } else {
+        this.menuForm.parentId = 0;
+      }
+    },
+    normalizer(node) {
+      const children = Array.isArray(node.children) ? node.children : [];
+      if (children.length === 0) {
+        delete node.children;
+      }
+      return {
+        id: node.permissionId,
+        label: node.permissionName,
+        children: children.length > 0 ? [...children] : undefined,
+      };
+    },
+    submit() {
+      this.$refs["addUserForm"].validate((valid) => {
+        if (valid) {
+          if (this.title === "编辑" && this.row) {
+            updateMenuFn({
+              ...this.menuForm,
+              ptype: this.activeName,
+              permissionId: this.row.permissionId,
+            })
+              .then((res) => {
+                this.$message({
+                  type: "success",
+                  message: "编辑成功",
+                });
+                this.cancel();
+                this.$emit("updateList");
+              })
+              .catch((error) => {
+                this.$message({
+                  type: "error",
+                  message: "编辑失败",
+                });
+              });
+          } else if (this.title === "新增") {
+            addMenuFn({
+              ...this.menuForm,
+              purl:
+                this.menuForm.purl !== null ? this.menuForm.purl : undefined,
+              ptype: this.activeName,
+              parentId: this.menuForm.parentId,
+            })
+              .then((res) => {
+                this.$message({
+                  type: "success",
+                  message: "新增成功",
+                });
+                this.cancel();
+                this.$emit("updateList");
+              })
+              .catch((error) => {
+                this.$message({
+                  type: "error",
+                  message: "新增失败",
+                });
+              });
+          }
+        } else {
+          return false;
+        }
+      });
+    },
+    cancel() {
+      this.$refs["addUserForm"].resetFields();
+      this.menuForm = {
+        parentId: null,
+        pname: null,
+        purl: null,
+        pstat: null,
+        pcode: null,
+        permissionShow: 2,
+      };
+    },
+  },
+};
+</script>
+
+<style scoped lang="scss">
+::v-deep .el-input__prefix {
+  line-height: 50px !important;
+}
+.demo-ruleForm {
+  .el-form-item {
+    margin-bottom: 25px;
+  }
+}
+</style>

+ 37 - 5
src/views/system/menuMag/index.vue

@@ -154,6 +154,17 @@
               @updateList="updateList"
               :row="row"
           /></el-tab-pane>
+          <el-tab-pane label="功能" name="3"
+            ><EditMenuBtn
+              v-if="activeName === '3'"
+              ref="addMenuBtn"
+              :activeName="activeName"
+              :tableData="tableData"
+              :checkId="checkId"
+              :title="title"
+              @updateList="updateList"
+              :row="row"
+          /></el-tab-pane>
         </el-tabs>
         <span slot="footer" class="dialog-footer">
           <el-button @click="handleClose" size="small">取 消</el-button>
@@ -174,9 +185,11 @@ import {
   getAllMenu,
 } from "@/api/system";
 import EditMenu from "./components/editDialog.vue";
+import EditMenuBtn from "./components/editDialogBtn.vue";
 export default {
   components: {
     EditMenu,
+    EditMenuBtn,
   },
   data() {
     return {
@@ -197,7 +210,7 @@ export default {
       },
       tableData: [],
       unusualdialog: false,
-      checkId: "",
+      checkId: 0,
     };
   },
   created() {
@@ -229,10 +242,11 @@ export default {
     handleClose() {
       if (this.activeName === "1") {
         this.$refs.addList.cancel();
-      } else {
+      } else if (this.activeName === "2") {
         this.$refs.addMenu.cancel();
+      } else if (this.activeName === "3") {
+        this.$refs.addMenuBtn.cancel();
       }
-
       this.loadingView = false;
       this.unusualdialog = false;
       this.checkId = null;
@@ -275,10 +289,13 @@ export default {
         this.$refs.addList.submit();
         this.checkId = null;
         //目录
-      } else {
+      } else if (this.activeName === "2") {
         //菜单
         this.$refs.addMenu.submit();
         this.checkId = null;
+      } else if (this.activeName === "3") {
+        this.$refs.addMenuBtn.submit();
+        this.checkId = null;
       }
     },
     updateList() {
@@ -301,9 +318,12 @@ export default {
       if (row.permissionType === 1) {
         this.activeName = "1";
         this.checkId = 0;
-      } else {
+      } else if (row.permissionType === 2) {
         this.activeName = "2";
         this.checkId = row.parentId;
+      } else if (row.permissionType === 3) {
+        this.activeName = "3";
+        this.checkId = row.parentId;
       }
       this.row = { ...row };
       this.title = "编辑";
@@ -313,6 +333,10 @@ export default {
       this.unusualdialog = true;
       this.checkId = row.permissionId;
       this.activeName = "2";
+      if (row.permissionType === 2) {
+        this.activeName = "3";
+      }
+
       this.title = "新增";
     },
     // 启用/停用
@@ -369,4 +393,12 @@ export default {
 .el-select {
   width: 250px;
 }
+.views {
+  .el-tabs--border-card {
+    min-height: 470px;
+  }
+}
+.dialog-footer {
+  margin-top: 20px;
+}
 </style>