feat:角色 role 的数据权限 50%
							parent
							
								
									9f48aeb434
								
							
						
					
					
						commit
						108d13b896
					
				|  | @ -1,5 +1,5 @@ | |||
| import { requestClient } from '#/api/request'; | ||||
| import type { PageParam } from '@vben/request'; | ||||
| import type { PageParam, PageResult } from '@vben/request'; | ||||
| 
 | ||||
| export namespace SystemRoleApi { | ||||
|   /** 角色信息 */ | ||||
|  | @ -18,17 +18,17 @@ export namespace SystemRoleApi { | |||
| 
 | ||||
| /** 查询角色列表 */ | ||||
| export function getRolePage(params: PageParam) { | ||||
|   return requestClient.get('/system/role/page', { params }); | ||||
|   return requestClient.get<PageResult<SystemRoleApi.SystemRole>>('/system/role/page', { params }); | ||||
| } | ||||
| 
 | ||||
| /** 查询角色(精简)列表 */ | ||||
| export function getSimpleRoleList(): Promise<SystemRoleApi.SystemRole[]> { | ||||
|   return requestClient.get('/system/role/simple-list'); | ||||
|   return requestClient.get<SystemRoleApi.SystemRole[]>('/system/role/simple-list'); | ||||
| } | ||||
| 
 | ||||
| /** 查询角色详情 */ | ||||
| export function getRole(id: number) { | ||||
|   return requestClient.get(`/system/role/get?id=${id}`); | ||||
|   return requestClient.get<SystemRoleApi.SystemRole>(`/system/role/get?id=${id}`); | ||||
| } | ||||
| 
 | ||||
| /** 新增角色 */ | ||||
|  |  | |||
|  | @ -3,8 +3,9 @@ import type { OnActionClickFn, VxeTableGridOptions } from '#/adapter/vxe-table'; | |||
| import type { SystemRoleApi } from '#/api/system/role'; | ||||
| 
 | ||||
| import { DICT_TYPE, getDictOptions } from '#/utils/dict'; | ||||
| import { CommonStatusEnum } from '#/utils/constants'; | ||||
| import { CommonStatusEnum, SystemDataScopeEnum } from '#/utils/constants'; | ||||
| 
 | ||||
| /** 新增/修改的表单 */ | ||||
| export function useFormSchema(): VbenFormSchema[] { | ||||
|   return [ | ||||
|     { | ||||
|  | @ -59,6 +60,60 @@ export function useFormSchema(): VbenFormSchema[] { | |||
|   ]; | ||||
| } | ||||
| 
 | ||||
| /** 分配数据权限的表单 */ | ||||
| export function useAssignDataPermissionFormSchema(): VbenFormSchema[] { | ||||
|   return [ | ||||
|     { | ||||
|       component: 'Input', | ||||
|       fieldName: 'id', | ||||
|       label: 'id', | ||||
|       dependencies: { | ||||
|         triggerFields: [''], | ||||
|         show: () => false, | ||||
|       }, | ||||
|     }, | ||||
|     { | ||||
|       component: 'Input', | ||||
|       fieldName: 'name', | ||||
|       label: '角色名称', | ||||
|       componentProps: { | ||||
|         disabled: true, | ||||
|       } | ||||
|     }, | ||||
|     { | ||||
|       component: 'Input', | ||||
|       fieldName: 'code', | ||||
|       label: '角色标识', | ||||
|       componentProps: { | ||||
|         disabled: true, | ||||
|       } | ||||
|     }, | ||||
|     { | ||||
|       component: 'Select', | ||||
|       fieldName: 'dataScope', | ||||
|       label: '权限范围', | ||||
|       componentProps: { | ||||
|         class: 'w-full', | ||||
|         options: getDictOptions(DICT_TYPE.SYSTEM_DATA_SCOPE, 'number'), | ||||
|       } | ||||
|     }, | ||||
|     { | ||||
|       component: 'Input', | ||||
|       fieldName: 'dataScopeDeptIds', | ||||
|       label: '部门范围', | ||||
|       // dependencies: {
 | ||||
|       //   triggerFields: ['dataScope'],
 | ||||
|       //   show: (values) => {
 | ||||
|       //     return values.dataScope === SystemDataScopeEnum.DEPT_CUSTOM;
 | ||||
|       //   }
 | ||||
|       // },
 | ||||
|       formItemClass: 'items-start', // TODO @芋艿:
 | ||||
|       modelPropName: 'modelValue', // TODO @芋艿:
 | ||||
|     } | ||||
|   ] | ||||
| } | ||||
| 
 | ||||
| /** 列表的搜索表单 */ | ||||
| export function useGridFormSchema(): VbenFormSchema[] { | ||||
|   return [ | ||||
|     { | ||||
|  | @ -88,6 +143,7 @@ export function useGridFormSchema(): VbenFormSchema[] { | |||
|   ]; | ||||
| } | ||||
| 
 | ||||
| /** 列表的字段 */ | ||||
| export function useGridColumns<T = SystemRoleApi.SystemRole>( | ||||
|   onActionClick: OnActionClickFn<T>, | ||||
| ): VxeTableGridOptions['columns'] { | ||||
|  | @ -150,11 +206,19 @@ export function useGridColumns<T = SystemRoleApi.SystemRole>( | |||
|           onClick: onActionClick, | ||||
|         }, | ||||
|         name: 'CellOperation', | ||||
|         options: [ | ||||
|           'edit', // 默认的编辑按钮
 | ||||
|           'delete', // 默认的删除按钮
 | ||||
|           { | ||||
|             code: 'assign-data-permission', | ||||
|             text: '数据权限', | ||||
|           }, | ||||
|         ], | ||||
|       }, | ||||
|       field: 'operation', | ||||
|       fixed: 'right', | ||||
|       title: '操作', | ||||
|       width: 130, | ||||
|       width: 220, | ||||
|     }, | ||||
|   ]; | ||||
| } | ||||
|  |  | |||
|  | @ -15,6 +15,7 @@ import { Plus, Download } from '@vben/icons'; | |||
| 
 | ||||
| import { useGridColumns, useGridFormSchema } from './data'; | ||||
| import Form from './modules/form.vue'; | ||||
| import AssignDataPermissionForm from './modules/assign-data-permission-form.vue'; | ||||
| import { downloadByData } from '#/utils/download'; | ||||
| 
 | ||||
| const [FormModal, formModalApi] = useVbenModal({ | ||||
|  | @ -22,6 +23,11 @@ const [FormModal, formModalApi] = useVbenModal({ | |||
|   destroyOnClose: true, | ||||
| }); | ||||
| 
 | ||||
| const [AssignDataPermissionFormModel, assignDataPermissionFormApi] = useVbenModal({ | ||||
|   connectedComponent: AssignDataPermissionForm, | ||||
|   destroyOnClose: true, | ||||
| }); | ||||
| 
 | ||||
| /** 编辑角色 */ | ||||
| function onEdit(row: SystemRoleApi.SystemRole) { | ||||
|   formModalApi.setData(row).open(); | ||||
|  | @ -51,15 +57,27 @@ async function onDelete(row: SystemRoleApi.SystemRole) { | |||
|   } | ||||
| } | ||||
| 
 | ||||
| /** 分配角色的数据权限 */ | ||||
| function onAssignDataPermission(row: SystemRoleApi.SystemRole) { | ||||
|   assignDataPermissionFormApi.setData(row).open(); | ||||
| } | ||||
| 
 | ||||
| /** 表格操作按钮的回调函数 */ | ||||
| function onActionClick(e: OnActionClickParams<SystemRoleApi.SystemRole>) { | ||||
|   switch (e.code) { | ||||
| function onActionClick({ | ||||
|    code, | ||||
|    row | ||||
| }: OnActionClickParams<SystemRoleApi.SystemRole>) { | ||||
|   switch (code) { | ||||
|     case 'delete': { | ||||
|       onDelete(e.row); | ||||
|       onDelete(row); | ||||
|       break; | ||||
|     } | ||||
|     case 'edit': { | ||||
|       onEdit(e.row); | ||||
|       onEdit(row); | ||||
|       break; | ||||
|     } | ||||
|     case 'assign-data-permission': { | ||||
|       onAssignDataPermission(row); | ||||
|       break; | ||||
|     } | ||||
|   } | ||||
|  | @ -110,6 +128,7 @@ async function onExport() { | |||
| <template> | ||||
|   <Page auto-content-height> | ||||
|     <FormModal @success="onRefresh" /> | ||||
|     <AssignDataPermissionFormModel @success="onRefresh" /> | ||||
|     <Grid table-title="角色列表"> | ||||
|       <template #toolbar-tools> | ||||
|         <Button type="primary" @click="onCreate"> | ||||
|  |  | |||
|  | @ -0,0 +1,149 @@ | |||
| <script lang="ts" setup> | ||||
| import type { SystemRoleApi } from '#/api/system/role'; | ||||
| 
 | ||||
| import { ref } from 'vue'; | ||||
| 
 | ||||
| import { useVbenModal } from '@vben/common-ui'; | ||||
| import { Button, message } from 'ant-design-vue'; | ||||
| 
 | ||||
| import { useVbenForm } from '#/adapter/form'; | ||||
| import { createRole, updateRole, getRole } from '#/api/system/role'; | ||||
| import { $t } from '#/locales'; | ||||
| 
 | ||||
| import { useAssignDataPermissionFormSchema } from '../data'; | ||||
| 
 | ||||
| const emit = defineEmits(['success']); | ||||
| const formData = ref<SystemRoleApi.SystemRole>(); | ||||
| 
 | ||||
| // TODO @待处理 | ||||
| import { getDeptList, type SystemDeptApi } from '#/api/system/dept'; | ||||
| import { handleTree } from '#/utils/tree'; | ||||
| import type { Recordable } from '@vben-core/typings'; | ||||
| 
 | ||||
| const [Form, formApi] = useVbenForm({ | ||||
|   layout: 'horizontal', | ||||
|   schema: useAssignDataPermissionFormSchema(), | ||||
|   showDefaultActions: false, | ||||
| }); | ||||
| 
 | ||||
| function resetForm() { | ||||
|   formApi.resetForm(); | ||||
|   formApi.setValues(formData.value || {}); | ||||
| } | ||||
| 
 | ||||
| const [Modal, modalApi] = useVbenModal({ | ||||
|   async onConfirm() { | ||||
|     const { valid } = await formApi.validate(); | ||||
|     if (!valid) { | ||||
|       return; | ||||
|     } | ||||
|     modalApi.lock(); | ||||
|     const data = (await formApi.getValues()) as SystemRoleApi.SystemRole; | ||||
|     try { | ||||
|       await (formData.value?.id | ||||
|         ? updateRole(data) | ||||
|         : createRole(data)); | ||||
|       await modalApi.close(); | ||||
|       emit('success'); | ||||
|       message.success({ | ||||
|         content: $t('ui.actionMessage.operationSuccess'), | ||||
|         key: 'action_process_msg', | ||||
|       }); | ||||
|     } finally { | ||||
|       modalApi.lock(false); | ||||
|     } | ||||
|   }, | ||||
|   async onOpenChange(isOpen) { | ||||
|     if (!isOpen) { | ||||
|       return; | ||||
|     } | ||||
|     const data = modalApi.getData<SystemRoleApi.SystemRole>(); | ||||
|     if (!data || !data.id) { | ||||
|       return; | ||||
|     } | ||||
|     modalApi.lock(); | ||||
|     try { | ||||
|       formData.value = await getRole(data.id as number); | ||||
|       await formApi.setValues(formData.value); | ||||
|       await loadPermissions(); | ||||
|     } finally { | ||||
|       modalApi.lock(false); | ||||
|     } | ||||
|   }, | ||||
| }); | ||||
| 
 | ||||
| // TODO 待处理 | ||||
| const permissions = ref<SystemDeptApi.SystemDept[]>([]); | ||||
| const loadingPermissions = ref(false); | ||||
| 
 | ||||
| // TODO 待处理 | ||||
| async function loadPermissions() { | ||||
|   loadingPermissions.value = true; | ||||
|   try { | ||||
|     debugger | ||||
|     const res = await getDeptList(); | ||||
|     permissions.value = handleTree(res); | ||||
|   } finally { | ||||
|     loadingPermissions.value = false; | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| // TODO 待处理 | ||||
| function getNodeClass(node: Recordable<any>) { | ||||
|   const classes: string[] = []; | ||||
|   if (node.value?.type === 'button') { | ||||
|     classes.push('inline-flex'); | ||||
|     if (node.index % 3 >= 1) { | ||||
|       classes.push('!pl-0'); | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   return classes.join(' '); | ||||
| } | ||||
| </script> | ||||
| 
 | ||||
| <template> | ||||
|   <Modal title="数据权限"> | ||||
|     <Form class="mx-4"> | ||||
|       <template #dataScopeDeptIds="slotProps"> | ||||
|         <Spin :spinning="loadingPermissions" wrapper-class-name="w-full"> | ||||
|           <VbenTree | ||||
|             :tree-data="permissions" | ||||
|             multiple | ||||
|             bordered | ||||
|             :default-expanded-level="2" | ||||
|             :get-node-class="getNodeClass" | ||||
|             v-bind="slotProps" | ||||
|             value-field="id" | ||||
|             label-field="name" | ||||
|           /> | ||||
|         </Spin> | ||||
|       </template> | ||||
|     </Form> | ||||
|     <template #prepend-footer> | ||||
|       <div class="flex-auto"> | ||||
|         <Button type="primary" danger @click="resetForm"> | ||||
|           {{ $t('common.reset') }} | ||||
|         </Button> | ||||
|       </div> | ||||
|     </template> | ||||
|   </Modal> | ||||
| </template> | ||||
| <!-- TODO @芋艿:测试 --> | ||||
| <style lang="css" scoped> | ||||
| :deep(.ant-tree-title) { | ||||
|   .tree-actions { | ||||
|     display: none; | ||||
|     margin-left: 20px; | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| :deep(.ant-tree-title:hover) { | ||||
|   .tree-actions { | ||||
|     display: flex; | ||||
|     flex: auto; | ||||
|     justify-content: flex-end; | ||||
|     margin-left: 20px; | ||||
|   } | ||||
| } | ||||
| </style> | ||||
		Loading…
	
		Reference in New Issue
	
	 YunaiV
						YunaiV