mirror of
				https://github.com/continew-org/continew-admin-ui.git
				synced 2025-10-31 22:57:15 +08:00 
			
		
		
		
	refactor: 使用用户选择器组件重构角色分配功能
This commit is contained in:
		| @@ -9,10 +9,7 @@ const BASE_URL = '/common' | ||||
| export function listDeptTree(query: { description: string }) { | ||||
|   return http.get<TreeNodeData[]>(`${BASE_URL}/tree/dept`, query) | ||||
| } | ||||
| /** @desc 查询部门用户树 */ | ||||
| export function listDeptWithUsersTree(query: { description?: string, status: number }) { | ||||
|   return http.get<TreeNodeData[]>(`${BASE_URL}/tree/deptWithUsers`, query) | ||||
| } | ||||
|  | ||||
| /** @desc 查询菜单树 */ | ||||
| export function listMenuTree(query: { description: string }) { | ||||
|   return http.get<TreeNodeData[]>(`${BASE_URL}/tree/menu`, query) | ||||
|   | ||||
| @@ -29,11 +29,13 @@ export function updateRole(data: any, id: string) { | ||||
| export function deleteRole(ids: string | Array<string>) { | ||||
|   return http.del(`${BASE_URL}/${ids}`) | ||||
| } | ||||
| /** @desc 获取角色绑定的用户列表 */ | ||||
|  | ||||
| /** @desc 查询角色关联用户 */ | ||||
| export function listRoleUsers(id: string) { | ||||
|   return http.get(`${BASE_URL}/listRoleUsers/${id}`) | ||||
|   return http.get(`${BASE_URL}/${id}/user`) | ||||
| } | ||||
|  | ||||
| export function bindUsers(id: string, userIds: Array<string>) { | ||||
|   return http.post(`${BASE_URL}/bindUsers/${id}`, userIds) | ||||
| /** @desc 分配角色给用户 */ | ||||
| export function assignToUsers(id: string, userIds: Array<string>) { | ||||
|   return http.post(`${BASE_URL}/${id}/user`, userIds) | ||||
| } | ||||
|   | ||||
							
								
								
									
										71
									
								
								src/views/system/role/RoleAssignModal.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										71
									
								
								src/views/system/role/RoleAssignModal.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,71 @@ | ||||
| <template> | ||||
|   <a-modal | ||||
|     v-model:visible="visible" | ||||
|     title="分配角色" | ||||
|     :mask-closable="false" | ||||
|     :esc-to-close="false" | ||||
|     :width="width >= 1350 ? 1350 : '100%'" | ||||
|     draggable | ||||
|     @before-ok="save" | ||||
|     @close="reset" | ||||
|   > | ||||
|     <UserSelect v-if="visible" ref="UserSelectRef" v-model:value="selectedUsers" @select-user="onSelectUser" /> | ||||
|   </a-modal> | ||||
| </template> | ||||
|  | ||||
| <script lang="ts" setup> | ||||
| import { ref } from 'vue' | ||||
| import { Message } from '@arco-design/web-vue' | ||||
| import { useWindowSize } from '@vueuse/core' | ||||
| import { assignToUsers, listRoleUsers } from '@/apis/system' | ||||
|  | ||||
| const { width } = useWindowSize() | ||||
| const visible = ref(false) | ||||
| const dataId = ref('') | ||||
| const selectedUsers = ref<string[]>([]) | ||||
|  | ||||
| const UserSelectRef = ref() | ||||
| // 重置 | ||||
| const reset = () => { | ||||
|   dataId.value = '' | ||||
|   selectedUsers.value = [] | ||||
|   UserSelectRef.value?.onClearSelected() | ||||
| } | ||||
|  | ||||
| // 保存 | ||||
| const save = async () => { | ||||
|   try { | ||||
|     const isInvalid = selectedUsers.value.length === 0 | ||||
|     if (isInvalid) { | ||||
|       Message.warning('请选择用户') | ||||
|       return false | ||||
|     } | ||||
|     await assignToUsers(dataId.value, selectedUsers.value) | ||||
|     Message.success('分配成功') | ||||
|     reset() | ||||
|     return true | ||||
|   } catch (error) { | ||||
|     return false | ||||
|   } | ||||
| } | ||||
|  | ||||
| // 用户选择回调 | ||||
| const onSelectUser = (value: string[]) => { | ||||
|   selectedUsers.value = value | ||||
| } | ||||
|  | ||||
| // 打开 | ||||
| const onOpen = async (id: string) => { | ||||
|   dataId.value = id | ||||
|   // 初始化选择的用户 | ||||
|   const { data } = await listRoleUsers(id) | ||||
|   selectedUsers.value = data | ||||
|   visible.value = true | ||||
| } | ||||
|  | ||||
| defineExpose({ | ||||
|   onOpen, | ||||
| }) | ||||
| </script> | ||||
|  | ||||
| <style lang="scss" scoped></style> | ||||
| @@ -1,113 +0,0 @@ | ||||
| <template> | ||||
|   <a-modal | ||||
|     v-model:visible="visible" | ||||
|     title="关联用户" | ||||
|     :mask-closable="false" | ||||
|     :esc-to-close="false" | ||||
|     :modal-style="{ maxWidth: '625px' }" | ||||
|     :body-style="{ maxHeight: '70vh' }" | ||||
|     width="90%" | ||||
|     draggable | ||||
|     @before-ok="save" | ||||
|     @close="close" | ||||
|   > | ||||
|     <a-transfer :data="transferData" :model-value="values" :title="['未选择', '已选择']" @change="handleChange"> | ||||
|       <template #source="{ selectedKeys, onSelect }"> | ||||
|         <a-tree | ||||
|           size="medium" | ||||
|           :checkable="true" | ||||
|           checked-strategy="child" | ||||
|           :checked-keys="selectedKeys" | ||||
|           :data="getTreeData()" | ||||
|           @check="(keys) => onSelect(keys)" | ||||
|         /> | ||||
|       </template> | ||||
|     </a-transfer> | ||||
|   </a-modal> | ||||
| </template> | ||||
|  | ||||
| <script lang="ts" setup> | ||||
| import { ref } from 'vue' | ||||
| import type { TransferItem } from '@arco-design/web-vue/es/transfer/interface' | ||||
| import { Message, type TreeNodeData } from '@arco-design/web-vue' | ||||
| import { bindUsers, listDeptWithUsersTree, listRoleUsers } from '@/apis' | ||||
|  | ||||
| const visible = ref(false) | ||||
| const roleId = ref('') | ||||
| const treeData = ref<TreeNodeData[]>([]) | ||||
| const transferData = ref<TransferItem[]>([]) | ||||
| const values = ref<string[]>(['']) | ||||
| const close = () => { | ||||
|   visible.value = false | ||||
| } | ||||
| const save = async () => { | ||||
|   const newValues = values.value.map((item) => item.replace('user_', '')) | ||||
|   const res = await bindUsers(roleId.value, newValues) | ||||
|   if (res.success) { | ||||
|     Message.success('修改成功') | ||||
|     visible.value = false | ||||
|     return false | ||||
|   } else { | ||||
|     Message.error(res.msg) | ||||
|   } | ||||
| } | ||||
| const handleChange = (value: string[]) => { | ||||
|   values.value = value | ||||
| } | ||||
| const getTransferData = (treeData: TreeNodeData[], transferDataSource: TransferItem[] = []) => { | ||||
|   treeData.forEach((item) => { | ||||
|     if (item.isUser === true) { | ||||
|       transferDataSource.push({ label: item.title ?? '', value: String(item.key) ?? '', disabled: false }) | ||||
|     } | ||||
|     if (item.children) { | ||||
|       getTransferData(item.children, transferDataSource) | ||||
|     } | ||||
|   }) | ||||
|   return transferDataSource | ||||
| } | ||||
|  | ||||
| const getTreeData = () => { | ||||
|   const travel = (_treeData: TreeNodeData[] = []) => { | ||||
|     const treeDataSource: TreeNodeData[] = [] | ||||
|     _treeData.forEach((item) => { | ||||
|       const disabled = values.value.filter((v) => v === item.key).length > 0 | ||||
|       treeDataSource.push({ title: item.title, key: item.key, children: travel(item.children), disabled }) | ||||
|     }) | ||||
|     return treeDataSource | ||||
|   } | ||||
|  | ||||
|   return travel(treeData.value) | ||||
| } | ||||
|  | ||||
| const listUsers = async (roleId: string) => { | ||||
|   const res = await listRoleUsers(roleId) | ||||
|   res.data.forEach((item) => { | ||||
|     values.value.push(`user_${item}`) | ||||
|   }) | ||||
| } | ||||
|  | ||||
| const getDeptList = async () => { | ||||
|   const res = await listDeptWithUsersTree({ status: 1 }) | ||||
|   treeData.value = res.data | ||||
|   transferData.value = getTransferData(treeData.value) | ||||
| } | ||||
|  | ||||
| const onAssociation = async (id: string) => { | ||||
|   visible.value = true | ||||
|   roleId.value = id | ||||
|   values.value = [] | ||||
|   await getDeptList() | ||||
|   await listUsers(roleId.value) | ||||
| } | ||||
|  | ||||
| defineExpose({ | ||||
|   onAssociation, | ||||
| }) | ||||
| </script> | ||||
|  | ||||
| <style lang="scss" scoped> | ||||
| :deep(.arco-transfer-view) { | ||||
|     height: 40vh; | ||||
|     width: 300px; | ||||
| } | ||||
| </style> | ||||
| @@ -51,7 +51,7 @@ | ||||
|       <template #action="{ record }"> | ||||
|         <a-space> | ||||
|           <a-link v-permission="['system:role:update']" @click="onUpdate(record)">修改</a-link> | ||||
|           <a-link v-permission="['system:role:bindUsers']" @click="onAssociation(record)">关联用户</a-link> | ||||
|           <a-link v-permission="['system:role:assign']" @click="onAssign(record)">分配</a-link> | ||||
|           <a-link | ||||
|             v-permission="['system:role:delete']" | ||||
|             status="danger" | ||||
| @@ -68,7 +68,7 @@ | ||||
|     <RoleAddModal ref="RoleAddModalRef" @save-success="search" /> | ||||
|     <RoleUpdateDrawer ref="RoleUpdateDrawerRef" @save-success="search" /> | ||||
|     <RoleDetailDrawer ref="RoleDetailDrawerRef" /> | ||||
|     <RoleUserAssociation ref="RoleUserAssociationRef" /> | ||||
|     <RoleAssignModal ref="RoleAssignModalRef" /> | ||||
|   </div> | ||||
| </template> | ||||
|  | ||||
| @@ -76,7 +76,7 @@ | ||||
| import RoleUpdateDrawer from './RoleUpdateDrawer.vue' | ||||
| import RoleDetailDrawer from './RoleDetailDrawer.vue' | ||||
| import RoleAddModal from './RoleAddModal.vue' | ||||
| import RoleUserAssociation from './RoleUserAssociation.vue' | ||||
| import RoleAssignModal from './RoleAssignModal.vue' | ||||
| import { type RoleQuery, type RoleResp, deleteRole, listRole } from '@/apis/system' | ||||
| import type { TableInstanceColumns } from '@/components/GiTable/type' | ||||
| import { useTable } from '@/hooks' | ||||
| @@ -156,10 +156,10 @@ const onDetail = (record: RoleResp) => { | ||||
|   RoleDetailDrawerRef.value?.onDetail(record.id) | ||||
| } | ||||
|  | ||||
| const RoleUserAssociationRef = ref<InstanceType<typeof RoleUserAssociation>>() | ||||
| // 关联用户 | ||||
| const onAssociation = (record: RoleResp) => { | ||||
|   RoleUserAssociationRef.value?.onAssociation(record.id) | ||||
| const RoleAssignModalRef = ref<InstanceType<typeof RoleAssignModal>>() | ||||
| // 分配 | ||||
| const onAssign = (record: RoleResp) => { | ||||
|   RoleAssignModalRef.value?.onOpen(record.id) | ||||
| } | ||||
| </script> | ||||
|  | ||||
|   | ||||
| @@ -109,7 +109,7 @@ import { DisEnableStatusList } from '@/constant/common' | ||||
| defineOptions({ name: 'SystemUser' }) | ||||
|  | ||||
| const queryForm = reactive<UserQuery>({ | ||||
|   sort: ['t1.createTime,desc'], | ||||
|   sort: ['t1.createTime,desc', 't1.id,desc'], | ||||
| }) | ||||
| const { | ||||
|   tableData: dataList, | ||||
|   | ||||
		Reference in New Issue
	
	Block a user