瀏覽代碼

权限管理优化

wangwei 4 年之前
父節點
當前提交
5a59ae9a4d

+ 1 - 0
package.json

@@ -50,6 +50,7 @@
     "vue-i18n": "9.1.6",
     "vue-router": "^4.0.8",
     "vue-types": "^3.0.2",
+    "vuedraggable": "^2.24.3",
     "xlsx": "^0.17.0"
   },
   "devDependencies": {

+ 5 - 2
src/api/sys/menu.ts

@@ -2,7 +2,7 @@ import { defHttp } from '/@/utils/http/axios';
 import { getMenuListResultModel } from './model/menuModel';
 
 enum Api {
-  GetMenuList = '/getMenuList',
+  GetMenuList = '/menu',
 }
 
 /**
@@ -10,5 +10,8 @@ enum Api {
  */
 
 export const getMenuList = () => {
-  return defHttp.get<getMenuListResultModel>({ url: Api.GetMenuList });
+  return defHttp.get<getMenuListResultModel>({
+    url: Api.GetMenuList,
+    method: 'GET',
+  });
 };

+ 3 - 1
src/api/sys/model/menuModel.ts

@@ -13,4 +13,6 @@ export interface RouteItem {
 /**
  * @description: Get menu return value
  */
-export type getMenuListResultModel = RouteItem[];
+export type getMenuListResultModel = {
+  tree: RouteItem[];
+};

+ 1 - 1
src/router/helper/menuHelper.ts

@@ -39,7 +39,7 @@ export function transformMenuModule(menuModule: MenuModule): Menu {
 export function transformRouteToMenu(routeModList: AppRouteModule[]) {
   const cloneRouteModList = cloneDeep(routeModList);
   const routeList: AppRouteRecordRaw[] = [];
-
+  console.log('==========transformRouteToMenu=========');
   cloneRouteModList.forEach((item) => {
     if (item.meta?.single) {
       const realItem = item?.children?.[0];

+ 5 - 1
src/store/modules/permission.ts

@@ -120,16 +120,20 @@ export const usePermissionStore = defineStore({
         let routeList: AppRouteRecordRaw[] = [];
         try {
           // this.changePermissionCode();
-          routeList = (await getMenuList()) as AppRouteRecordRaw[]; //请求后端路由菜单数组
+          routeList = (await getMenuList()).tree as AppRouteRecordRaw[]; //请求后端路由菜单数组
+          console.log(`routeList`, routeList);
+          console.log(`routeList==tree`, routeList);
         } catch (error) {
           console.error(error);
         }
 
         // Dynamically introduce components
         routeList = transformObjToRoute(routeList);
+        console.log(`routeList2222`, routeList);
 
         //  Background routing to menu structure
         const backMenuList = transformRouteToMenu(routeList);
+        console.log(`backMenuList2222`, backMenuList);
         this.setBackMenuList(backMenuList);
 
         routeList = flatMultiLevelRoutes(routeList);

+ 2 - 0
src/views/permission/admin/data.ts

@@ -278,6 +278,7 @@ export const schemas: FormSchema[] = [
     colProps: {
       span: adaptWidth.elContainer,
     },
+    required: true,
   },
   {
     field: 'username',
@@ -332,6 +333,7 @@ export const schemas: FormSchema[] = [
     field: 'status',
     label: '状态',
     component: 'RadioButtonGroup',
+    defaultValue: 'normal',
     componentProps: {
       options: [
         { label: '启用', value: 'normal' },

+ 6 - 6
src/views/permission/admin_log/index.vue

@@ -15,7 +15,7 @@
       </template>
     </BasicTable>
     <ExpExcelModel @register="register" @success="defaultHeader" />
-    <Popup @register="addRegister" :modelData="modelData" />
+    <Popup @register="PopupRegister" :popupData="popupData" />
   </div>
 </template>
 <script lang="ts">
@@ -35,7 +35,7 @@
     TableActionType,
   } from '/@/components/Table';
 
-  //   interface ModelData {
+  //   interface popupData {
   //     title: string,
   //     treeData: object[],
   //     checkedKeys: string[] | number[],
@@ -69,7 +69,7 @@
     setup() {
       const tableRef = ref<Nullable<TableActionType>>(null);
       const currentEditKeyRef = ref('');
-      const modelData = reactive({
+      const popupData = reactive({
         title: '详情',
       });
       const [register, { openModal }] = useModal();
@@ -91,7 +91,7 @@
         showIndexColumn: false,
         bordered: true,
       });
-      const [addRegister, { openModal: openAdd }] = useModal();
+      const [PopupRegister, { openModal: openAdd }] = useModal();
 
       function getTableAction() {
         // 获取组件
@@ -171,7 +171,7 @@
       }
       return {
         defaultHeader,
-        modelData,
+        popupData,
         tableRef,
         registerTable,
         handleDetail,
@@ -179,7 +179,7 @@
         getTableAction,
         getSelectRowList,
         getSelectRowKeyList,
-        addRegister,
+        PopupRegister,
         getUserList,
         register,
         openModal,

+ 2 - 1
src/views/permission/group/data.ts

@@ -42,7 +42,7 @@ export const columns: BasicColumn[] = [
 // popup =====================================================
 export const schemas: FormSchema[] = [
   {
-    field: 'pname',
+    field: 'pid',
     label: '父级',
     component: 'TreeSelect',
     componentProps: {
@@ -80,6 +80,7 @@ export const schemas: FormSchema[] = [
     field: 'status',
     label: '状态',
     component: 'RadioButtonGroup',
+    defaultValue: 'normal',
     componentProps: {
       options: [
         { label: '启用', value: 'normal' },

+ 29 - 26
src/views/permission/group/index.vue

@@ -3,13 +3,13 @@
     <BasicTable
       ref="tableRef"
       @register="registerTable"
-      @fetchSuccess="fetchSuccess"
+      @fetchSuccess="ExpandAllRows"
       defaultExpandAllRows
       rowKey="id"
     >
       <template #toolbar>
         <a-button type="primary" @click="toggleRowShow">{{ btn_text }}</a-button>
-        <a-button type="primary" @click="addRole"> 添加 </a-button>
+        <a-button type="primary" @click="addGroupFn"> 添加 </a-button>
         <a-button type="danger" @click="deleteBatches"> 删除 </a-button>
       </template>
       <template #action="{ record, column }">
@@ -25,6 +25,7 @@
   import { useModal } from '/@/components/Modal';
   //   import { getAllMenuList } from '/@/api/sys/menu';
   import { columns } from './data';
+  import { useUserStore } from '/@/store/modules/user';
   import { useMessage } from '/@/hooks/web/useMessage';
   import {
     getGroupTree,
@@ -50,14 +51,20 @@
     btn_text: string;
     btn_status: boolean;
   }
+  interface Group {
+    id: string;
+    name: boolean;
+  }
 
   export default defineComponent({
     components: { BasicTable, TableAction, Popup },
     setup() {
+      const userStore = useUserStore();
       const { createMessage } = useMessage();
       const { success /*, error */ } = createMessage;
       const tableRef = ref<Nullable<TableActionType>>(null);
       const currentEditKeyRef = ref('');
+      const groups = userStore.getUserInfo.groups as Group[];
       const popupData = reactive<PopupData>({
         title: '添加',
         treeData: [{}],
@@ -88,21 +95,9 @@
         bordered: true,
       });
       const [addRegister, { openModal: openPopup }] = useModal();
-      function mapTree(tree) {
-        tree.map((item) => {
-          if (item.children) {
-            item.children.map((c_item) => {
-              c_item.pname = item.name;
-            });
-            mapTree(item.children);
-          }
-        });
-      }
 
       function afterFetch(result) {
-        mapTree(result);
         popupData.treeData = result;
-        console.log(`result--fetch`, result);
       }
 
       function getTableAction() {
@@ -123,13 +118,13 @@
         console.log(getTableAction().getSelectRowKeys());
       }
 
-      function addRole() {
+      function addGroupFn() {
         console.log('添加');
         popupData.title = '添加';
         openPopup(true, {});
       }
 
-      function fetchSuccess() {
+      function ExpandAllRows() {
         setTimeout(() => {
           toggleRowShow();
         }, 1);
@@ -157,12 +152,6 @@
           if (item.id === record.id) {
             record = item;
           }
-          if (record.pid === 0) {
-            record.pname = null;
-          }
-          if (record.pid === item.id) {
-            record.pname = item.name;
-          }
         });
         openPopup(true, record);
       }
@@ -173,7 +162,7 @@
         await deleteGroup({ id: record.id }).then((res) => {
           console.log(res);
           getTableAction().reload();
-          fetchSuccess();
+          ExpandAllRows();
           success('删除成功!');
         });
       }
@@ -186,7 +175,7 @@
         await deleteBatchesGroup({ id }).then((res) => {
           console.log(res);
           getTableAction().reload();
-          fetchSuccess();
+          ExpandAllRows();
           success('删除成功!');
           getTableAction().setSelectedRowKeys([]);
         });
@@ -194,6 +183,7 @@
 
       async function saveData(params: any) {
         console.log('------------save---------');
+        params.data.rules = params.data.rules.toString();
         const data = params.data;
         const closeModel = params.closeModal;
         console.log(`data`, data);
@@ -202,6 +192,7 @@
             console.log(res);
             getTableAction().reload();
             closeModel();
+            ExpandAllRows();
             success('创建成功!');
           });
           console.log('----------add---');
@@ -210,6 +201,7 @@
             console.log(res);
             getTableAction().reload();
             closeModel();
+            ExpandAllRows();
             success('修改成功!');
           });
           console.log('----------edit---');
@@ -225,6 +217,17 @@
             },
           ];
         }
+
+        const permission = groups.some((item) => item.id > record.pid);
+
+        if (permission) {
+          return [
+            {
+              label: '',
+              icon: '',
+            },
+          ];
+        }
         return [
           {
             label: '编辑',
@@ -247,7 +250,7 @@
         popupData,
         tableRef,
         registerTable,
-        addRole,
+        addGroupFn,
         handleEdit,
         deleteBatches,
         createActions,
@@ -257,7 +260,7 @@
         toggleRowShow,
         addRegister,
         saveData,
-        fetchSuccess,
+        ExpandAllRows,
         ...toRefs(btn),
       };
     },

+ 49 - 14
src/views/permission/group/popup.vue

@@ -5,6 +5,7 @@
     <div class="tree-wrap">
       <p class="tree-label">权限</p>
       <a-tree
+        v-if="allowRule.length"
         checkable
         :tree-data="allowRule"
         showLine
@@ -35,6 +36,7 @@
     allowRule: AllowRule[];
     initRules: number[];
     rules: number[];
+    treeData: object[];
   }
 
   export default defineComponent({
@@ -52,6 +54,7 @@
         allowRule: [],
         initRules: [],
         rules: [],
+        treeData: [],
       });
       const popupData = props.popupData as PopupData;
       const modelRef = ref({});
@@ -80,17 +83,21 @@
         // }
         if (data.id) {
           reactData.id = data.id;
+        } else {
+          reactData.id = 0;
+          reactData.rules = [];
         }
         getRuleTree(data.pid);
         if (data.rules) {
           reactData.initRules = data.rules.split(',');
           reactData.initRules = reactData.initRules.map((item) => parseInt(item));
         }
-        console.log(`reactData.rules`, reactData.rules);
 
         setFieldsValue(data);
+        formatTreeData(popupData.treeData); // 禁止选取自己或自己下级为父id
+        console.log(`popupData.treeData`, popupData.treeData);
         updateSchema({
-          field: 'pname',
+          field: 'pid',
           componentProps: {
             onChange: (e: ChangeEvent) => {
               console.log('===========onChange1====ddd===');
@@ -102,23 +109,52 @@
         });
       });
 
+      function formatChildren(child) {
+        child.map((item) => {
+          item.selectable = false;
+          if (item.children) {
+            formatChildren(child);
+          }
+        });
+      }
+
+      // 添加不可选
+      function formatTreeData(tree) {
+        tree.map((item) => {
+          if (item.children) {
+            formatTreeData(item.children);
+          }
+          if (item.id === reactData.id) {
+            item.selectable = false;
+            if (item.children) {
+              formatChildren(item.children);
+            }
+          } else {
+            item.selectable = true;
+          }
+        });
+      }
+
+      function setReactDataId(allowRule) {
+        allowRule.map((item) => {
+          if (reactData.initRules.includes(item.id)) {
+            reactData.rules.push(item.id);
+          }
+          if (item.children) {
+            setReactDataId(item.children);
+          }
+        });
+      }
+
       async function getRuleTree(id) {
         console.log(`id`, id);
         if (!id) {
           id = 1;
         }
         await getAllowRule({ id }).then((res) => {
-          console.log(res);
           reactData.allowRule = res.tree as AllowRule[];
-          if (reactData.initRules) {
-            reactData.rules = [];
-            reactData.allowRule.map((item) => {
-              if (reactData.initRules.includes(item.id)) {
-                reactData.rules.push(item.id);
-              }
-            });
-          }
-          console.log(` reactData.rules`, reactData.rules);
+          reactData.rules = [];
+          setReactDataId(reactData.allowRule);
         });
       }
 
@@ -129,8 +165,7 @@
         if (reactData.id) {
           data.id = reactData.id;
         }
-        data.pid = data.pname;
-        // delete data.pname;
+        console.log(`pid`, data);
         console.log(`data`, data);
         const childerData = { closeModal, data };
         emit('saveData', childerData);

+ 3 - 2
src/views/permission/rule/data.ts

@@ -164,7 +164,7 @@ export const columns: BasicColumn[] = [
   },
   {
     title: '权重',
-    dataIndex: 'weight',
+    dataIndex: 'weigh',
     width: 160,
   },
 ];
@@ -172,7 +172,7 @@ export const columns: BasicColumn[] = [
 // popup =====================================================
 export const schemas: FormSchema[] = [
   {
-    field: 'pname',
+    field: 'pid',
     label: '父级',
     component: 'TreeSelect',
     componentProps: {
@@ -210,6 +210,7 @@ export const schemas: FormSchema[] = [
     field: 'status',
     label: '状态',
     component: 'RadioButtonGroup',
+    defaultValue: 'normal',
     componentProps: {
       options: [
         { label: '启用', value: 'normal' },

+ 10 - 21
src/views/permission/rule/index.vue

@@ -1,9 +1,9 @@
 <template>
   <div>
-    <BasicTable ref="tableRef" @register="registerTable" @fetchSuccess="fetchSuccess" rowKey="id">
+    <BasicTable ref="tableRef" @register="registerTable" @fetchSuccess="ExpandAllRows" rowKey="id">
       <template #toolbar>
         <a-button type="primary" @click="toggleRowShow">{{ btn_text }}</a-button>
-        <a-button type="primary" @click="addRole"> 添加 </a-button>
+        <a-button type="primary" @click="addRuleFn"> 添加 </a-button>
         <a-button type="danger" @click="deleteBatches"> 删除 </a-button>
       </template>
       <template #action="{ record, column }">
@@ -79,25 +79,12 @@
       });
       const [addRegister, { openModal: openAdd }] = useModal();
 
-      function mapTree(tree) {
-        // 添加pname字段
-        tree.map((item) => {
-          if (item.children) {
-            item.children.map((c_item) => {
-              c_item.pname = item.title;
-            });
-            mapTree(item.children);
-          }
-        });
-      }
-
       function afterFetch(result) {
-        mapTree(result);
         popupData.treeData = result;
         console.log(`result`, result);
       }
 
-      function fetchSuccess() {
+      function ExpandAllRows() {
         setTimeout(() => {
           toggleRowShow();
         }, 1);
@@ -133,7 +120,7 @@
         console.log(getTableAction().getSelectRowKeys());
       }
 
-      function addRole() {
+      function addRuleFn() {
         console.log('添加');
         popupData.title = '添加';
         openAdd(true, {});
@@ -159,7 +146,7 @@
         await deleteRule({ id: record.id }).then((res) => {
           console.log(res);
           getTableAction().reload();
-          fetchSuccess();
+          ExpandAllRows();
           success('删除成功!');
         });
       }
@@ -173,7 +160,7 @@
           console.log(res);
           getTableAction().reload();
           getTableAction().setSelectedRowKeys([]);
-          fetchSuccess();
+          ExpandAllRows();
           success('删除成功!');
         });
       }
@@ -188,6 +175,7 @@
             getTableAction().reload();
             closeModel();
           });
+          ExpandAllRows();
           success('创建成功!');
           console.log('----------add---');
         } else {
@@ -196,6 +184,7 @@
             getTableAction().reload();
             closeModel();
           });
+          ExpandAllRows();
           success('修改成功!');
           console.log('----------edit---');
         }
@@ -227,7 +216,7 @@
         popupData,
         tableRef,
         registerTable,
-        addRole,
+        addRuleFn,
         handleEdit,
         deleteBatches,
         createActions,
@@ -236,7 +225,7 @@
         getSelectRowKeyList,
         addRegister,
         saveData,
-        fetchSuccess,
+        ExpandAllRows,
         toggleRowShow,
         ...toRefs(btn),
       };

+ 1 - 2
src/views/permission/rule/popup.vue

@@ -70,7 +70,7 @@
         }
         setFieldsValue(data);
         updateSchema({
-          field: 'pname',
+          field: 'pid',
           componentProps: { treeData: popupData.treeData },
         });
       });
@@ -81,7 +81,6 @@
         if (role.id) {
           data.id = role.id;
         }
-        data.pid = data.pname;
         // delete data.pname;
         console.log(`data`, data);
         // const data = {

+ 5 - 1
types/store.ts

@@ -34,7 +34,11 @@ export interface UserInfo {
   username: string;
   nickname: string;
   avatar: string;
-  desc?: string;
+  groups?: [];
+  email?: string;
+  loginip?: string;
+  loginfailure?: number;
+  status?: string;
 }
 
 export interface BeforeMiniState {

+ 12 - 0
yarn.lock

@@ -9101,6 +9101,11 @@ sort-keys@^2.0.0:
   dependencies:
     is-plain-obj "^1.0.0"
 
+sortablejs@1.10.2:
+  version "1.10.2"
+  resolved "https://registry.yarnpkg.com/sortablejs/-/sortablejs-1.10.2.tgz#6e40364d913f98b85a14f6678f92b5c1221f5290"
+  integrity sha512-YkPGufevysvfwn5rfdlGyrGjt7/CRHwvRPogD/lC+TnvcN29jDpCifKP+rBqf+LRldfXSTh+0CGLcSg0VIxq3A==
+
 sortablejs@^1.13.0:
   version "1.13.0"
   resolved "https://registry.npmjs.org/sortablejs/-/sortablejs-1.13.0.tgz#3ab2473f8c69ca63569e80b1cd1b5669b51269e9"
@@ -10807,6 +10812,13 @@ vue@3.0.11, vue@^3.0.0:
     "@vue/runtime-dom" "3.0.11"
     "@vue/shared" "3.0.11"
 
+vuedraggable@^2.24.3:
+  version "2.24.3"
+  resolved "https://registry.yarnpkg.com/vuedraggable/-/vuedraggable-2.24.3.tgz#43c93849b746a24ce503e123d5b259c701ba0d19"
+  integrity sha512-6/HDXi92GzB+Hcs9fC6PAAozK1RLt1ewPTLjK0anTYguXLAeySDmcnqE8IC0xa7shvSzRjQXq3/+dsZ7ETGF3g==
+  dependencies:
+    sortablejs "1.10.2"
+
 warning@^4.0.0:
   version "4.0.3"
   resolved "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz#16e9e077eb8a86d6af7d64aa1e05fd85b4678ca3"