Просмотр исходного кода

增加按钮权限功能
- 用户: system:user
- 角色: system:role
- 标签: fdhb:tag
- 系统服务项目: fdhb:service_items_system

cc12458 9 месяцев назад
Родитель
Сommit
d5d181d2e8

+ 14 - 0
src/core/usePermission.ts

@@ -0,0 +1,14 @@
+import type { ComputedRef } from 'vue';
+import { useAccountStore } from '@/stores';
+import { storeToRefs } from 'pinia';
+
+export function usePermission(code: string | string[]): ComputedRef<boolean> {
+  const store = useAccountStore();
+  const { permission } = storeToRefs(store);
+
+  const codes = Array.isArray(code) ? code : code.split('|');
+  return computed(() => {
+    if (!permission.value.length || !codes.length) return true;
+    return codes.some((value) => permission.value.includes(value));
+  });
+}

+ 5 - 3
src/pages/index/system/role.vue

@@ -3,6 +3,7 @@ import RoleEdit          from '@/components/RoleEdit.vue';
 import { statusOptions } from '@/model/options';
 
 import type { RoleModel, RoleQuery } from '@/model/system.model';
+import { usePermission } from '@/core/usePermission';
 
 import { deleteRoleMethod, rolesMethod, updateRoleStatusMethod } from '@/request/api/system.api';
 import { usePagination }                                         from 'alova/client';
@@ -85,6 +86,7 @@ const gridOptions = reactive<VxeGridProps<RoleModel>>({
         props: {
           openLabel: '启用', openValue: '0',
           closeLabel: '停用', closeValue: '1',
+          disabled: !usePermission('system:role:edit').value
         },
         events: {
           change({ row, rowIndex }, { value }) {
@@ -105,8 +107,8 @@ const gridOptions = reactive<VxeGridProps<RoleModel>>({
           mode: 'text',
         },
         options: [
-          { content: '修改', status: 'warning', name: 'editRole' },
-          { content: '删除', status: 'error', name: 'deleteRole' },
+          { content: '修改', status: 'warning', name: 'editRole', permissionCode: 'system:role:edit' },
+          { content: '删除', status: 'error', name: 'deleteRole', permissionCode: 'system:role:remove' },
         ],
         events: {
           click({ row, rowIndex }, { name }) {
@@ -211,7 +213,7 @@ function editRole(model?: RoleModel, index?: number) {
     <main class="flex-auto overflow-hidden">
       <vxe-grid ref="gridRef" v-bind="gridOptions" v-on="gridEvents" :loading="loading">
         <template #handle>
-          <vxe-button status="primary" @click="editRole()">新增</vxe-button>
+          <vxe-button status="primary" permission-code="system:role:add" @click="editRole()">新增</vxe-button>
         </template>
         <template #toolbar-extra>
           <vxe-button style="margin-right: 12px;" icon="vxe-icon-repeat" circle @click="refresh(page)"></vxe-button>

+ 8 - 4
src/pages/index/system/tag.vue

@@ -8,6 +8,8 @@ import { tagDeleteMethod, tagsMethod, tagsSearchMethod, tagUpdateStatusMethod }
 import { usePagination, useRequest }                                            from 'alova/client';
 import { notification }                                                         from 'ant-design-vue';
 
+import { usePermission } from '@/core/usePermission';
+
 import {
   type VxeFormListeners,
   type VxeFormProps,
@@ -193,6 +195,8 @@ function editTag(model?: TagModel, index?: number) {
     },
   });
 }
+
+const editableForStatus = usePermission('fdhb:tag:status')
 </script>
 <template>
   <div class="page-container flex flex-col">
@@ -202,14 +206,14 @@ function editTag(model?: TagModel, index?: number) {
     <main class="flex-auto overflow-hidden">
       <vxe-grid ref="gridRef" v-bind="gridOptions" v-on="gridEvents" :loading="loading">
         <template #handle>
-          <vxe-button status="primary" @click="editTag()">新增</vxe-button>
+          <vxe-button status="primary" permission-code="fdhb:tag:add" @click="editTag()">新增</vxe-button>
         </template>
         <template #toolbar-extra>
           <vxe-button style="margin-right: 12px;" icon="vxe-icon-repeat" circle @click="refresh(page)"></vxe-button>
         </template>
 
         <template #cell-status="{ row }">
-          <vxe-switch :modelValue="row.status" :disabled="!row.editable"
+          <vxe-switch :modelValue="row.status" :disabled="!(editableForStatus && row.editable)"
             openLabel="启用" openValue="0"
             closeLabel="停用" closeValue="1"
             @change="updateTagStatus($event.value, row)"
@@ -217,8 +221,8 @@ function editTag(model?: TagModel, index?: number) {
         </template>
         <template #cell-operation="{ row }">
           <vxe-button-group mode="text">
-            <vxe-button content="修改" :disabled="!row.editable" status="warning" @click="editTag(row)"></vxe-button>
-            <vxe-button content="删除" :disabled="!row.deletable" status="error" @click="deleteTag(row)"></vxe-button>
+            <vxe-button content="修改" permission-code="fdhb:tag:update" :disabled="!row.editable" status="warning" @click="editTag(row)"></vxe-button>
+            <vxe-button content="删除" permission-code="fdhb:tag:delete" :disabled="!row.deletable" status="error" @click="deleteTag(row)"></vxe-button>
           </vxe-button-group>
         </template>
       </vxe-grid>

+ 3 - 3
src/pages/index/system/user.vue

@@ -103,8 +103,8 @@ const gridOptions = reactive<VxeGridProps<UserModel>>({
         },
         options: [
           { content: '小程序码', status: 'primary', name: 'QRCode' },
-          { content: '修改', status: 'warning', name: 'editUser' },
-          { content: '删除', status: 'error', name: 'deleteUser' },
+          { content: '修改', status: 'warning', name: 'editUser',  permissionCode: 'system:user:edit' },
+          { content: '删除', status: 'error', name: 'deleteUser', permissionCode: 'system:user:remove' },
         ],
         events: {
           click({ row, rowIndex }, { name }) {
@@ -262,7 +262,7 @@ function QRCode(model: UserModel) {
     <main class="flex-auto overflow-hidden">
       <vxe-grid ref="gridRef" v-bind="gridOptions" v-on="gridEvents" :loading="loading">
         <template #handle>
-          <vxe-button status="primary" @click="editUser()">新增</vxe-button>
+          <vxe-button status="primary" permission-code="system:user:add" @click="editUser()">新增</vxe-button>
         </template>
         <template #toolbar-extra>
           <vxe-button style="margin-right: 12px;" icon="vxe-icon-repeat" circle @click="refresh(page)"></vxe-button>

+ 3 - 2
src/request/api/account.api.ts

@@ -4,7 +4,7 @@ import request from '@/request/alova';
 import router from '@/router';
 import { roleMethod } from './system.api';
 
-interface Menu {
+export interface Menu {
   label: string;
   title: string;
   key: string;
@@ -15,7 +15,7 @@ export interface AccountModel {
   token: string;
   local: PeopleModel;
   menus?: Menu[];
-
+  permission: string[];
   user?: UserModel;
 }
 
@@ -34,6 +34,7 @@ export function accountMethod(token: string) {
       return {
         token,
         local: transformAccount(data.user),
+        permission: Array.isArray(data.permissions) ? data.permissions : [],
         user: data.user,
       };
     },

+ 3 - 3
src/service/ServiceItemsSystem.vue

@@ -39,7 +39,7 @@ const searchFormProps = reactive<VxeFormProps<SystemIteQuery>>({
         options: [
           { name: 'search', type: 'submit', content: '查询', status: 'primary' },
           { name: 'reset', type: 'reset', content: '清空', status: 'warning' },
-          { name: 'add', content: '新增', status: 'primary' },
+          { name: 'add', content: '新增', status: 'primary', permissionCode: 'fdhb:service_items_system:add' },
         ],
         events: {
           click(slotParams, { name }) {
@@ -323,8 +323,8 @@ defineExpose({
         </template>
         <template #actionSlot="{ row, rowIndex }">
           <vxe-button mode="text" status="primary" @click="seeItems(row, rowIndex)">查看</vxe-button>
-          <vxe-button mode="text" status="primary" @click="editItems(row, rowIndex)">编辑</vxe-button>
-          <vxe-button mode="text" status="primary" @click="deleteItems(row, rowIndex)" v-if="row.isErasable === 'N' ? false : true">删除</vxe-button>
+          <vxe-button mode="text" status="primary" permission-code="fdhb:service_items_system:edit" @click="editItems(row, rowIndex)">编辑</vxe-button>
+          <vxe-button mode="text" status="primary" permission-code="fdhb:service_items_system:remove" v-if="row.isErasable !== 'N'" @click="deleteItems(row, rowIndex)">删除</vxe-button>
         </template>
       </vxe-grid>
     </main>

+ 18 - 1
src/stores/account.store.ts

@@ -1,16 +1,33 @@
 import type { AccountModel } from '@/request/api/account.api';
 import { defineStore }       from 'pinia';
+import { VxeUI } from 'vxe-pc-ui';
 
 
 export const useAccountStore = defineStore('account', () => {
   const token = ref<string>();
+  const permission = ref<string[]>([]);
   const local = ref<AccountModel['local'] | null>();
   const menus = ref<AccountModel['menus']>([]);
 
+  watch(
+    permission,
+    (value) => {
+      if (!value.length) return;
+      VxeUI.setConfig({
+        permissionMethod({ code }) {
+          const has = value.includes(code as string);
+          return { visible: has, disabled: !has };
+        },
+      });
+    },
+    { deep: false }
+  );
+
   const $init = (data: AccountModel) => {
     token.value = data.token;
     local.value = data.local;
     menus.value = data.menus;
+    permission.value = data.permission;
     return getFirstMenu(menus.value) ?? '/';
   };
 
@@ -20,7 +37,7 @@ export const useAccountStore = defineStore('account', () => {
     menus.value = [];
   };
 
-  return { token, local, menus, $init, $reset };
+  return { token, local, menus, permission, $init, $reset };
 });
 
 function getFirstMenu(menus?: AccountModel['menus']): string | void {