houzhongjian
2024-08-08 820397e43a0b64d35c6d31d2a55475061438593b
提交 | 用户 | 时间
820397 1 <template>
H 2   <Dialog v-model="dialogVisible" title="菜单权限" width="800">
3     <el-form ref="formRef" v-loading="formLoading" :model="formData" label-width="80px">
4       <el-form-item label="角色名称">
5         <el-tag>{{ formData.name }}</el-tag>
6       </el-form-item>
7       <el-form-item label="角色标识">
8         <el-tag>{{ formData.code }}</el-tag>
9       </el-form-item>
10       <el-form-item label="权限范围">
11         <el-select v-model="formData.dataScope">
12           <el-option
13             v-for="item in getIntDictOptions(DICT_TYPE.SYSTEM_DATA_SCOPE)"
14             :key="item.value"
15             :label="item.label"
16             :value="item.value"
17           />
18         </el-select>
19       </el-form-item>
20     </el-form>
21     <el-form-item
22       v-if="formData.dataScope === SystemDataScopeEnum.DEPT_CUSTOM"
23       label="权限范围"
24       style="display: flex"
25     >
26       <el-card class="card" shadow="never">
27         <template #header>
28           全选/全不选:
29           <el-switch
30             v-model="treeNodeAll"
31             active-text="是"
32             inactive-text="否"
33             inline-prompt
34             @change="handleCheckedTreeNodeAll()"
35           />
36           全部展开/折叠:
37           <el-switch
38             v-model="deptExpand"
39             active-text="展开"
40             inactive-text="折叠"
41             inline-prompt
42             @change="handleCheckedTreeExpand"
43           />
44           父子联动(选中父节点,自动选择子节点):
45           <el-switch v-model="checkStrictly" active-text="是" inactive-text="否" inline-prompt />
46         </template>
47         <el-tree
48           ref="treeRef"
49           :check-strictly="!checkStrictly"
50           :data="deptOptions"
51           :props="defaultProps"
52           default-expand-all
53           empty-text="加载中,请稍后"
54           node-key="id"
55           show-checkbox
56         />
57       </el-card>
58     </el-form-item>
59     <template #footer>
60       <el-button :disabled="formLoading" type="primary" @click="submitForm">确 定</el-button>
61       <el-button @click="dialogVisible = false">取 消</el-button>
62     </template>
63   </Dialog>
64 </template>
65 <script lang="ts" setup>
66 import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
67 import { defaultProps, handleTree } from '@/utils/tree'
68 import { SystemDataScopeEnum } from '@/utils/constants'
69 import * as RoleApi from '@/api/system/role'
70 import * as DeptApi from '@/api/system/dept'
71 import * as PermissionApi from '@/api/system/permission'
72
73 defineOptions({ name: 'SystemRoleDataPermissionForm' })
74
75 const { t } = useI18n() // 国际化
76 const message = useMessage() // 消息弹窗
77
78 const dialogVisible = ref(false) // 弹窗的是否展示
79 const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
80 const formData = reactive({
81   id: undefined,
82   name: '',
83   code: '',
84   dataScope: undefined,
85   dataScopeDeptIds: []
86 })
87 const formRef = ref() // 表单 Ref
88 const deptOptions = ref<any[]>([]) // 部门树形结构
89 const deptExpand = ref(true) // 展开/折叠
90 const treeRef = ref() // 菜单树组件 Ref
91 const treeNodeAll = ref(false) // 全选/全不选
92 const checkStrictly = ref(true) // 是否严格模式,即父子不关联
93
94 /** 打开弹窗 */
95 const open = async (row: RoleApi.RoleVO) => {
96   dialogVisible.value = true
97   resetForm()
98   // 加载 Dept 列表。注意,必须放在前面,不然下面 setChecked 没数据节点
99   deptOptions.value = handleTree(await DeptApi.getSimpleDeptList())
100   // 设置数据
101   formData.id = row.id
102   formData.name = row.name
103   formData.code = row.code
104   formData.dataScope = row.dataScope
105   await nextTick()
106   // 需要在 DOM 渲染完成后,再设置选中状态
107   row.dataScopeDeptIds?.forEach((deptId: number): void => {
108     treeRef.value.setChecked(deptId, true, false)
109   })
110 }
111 defineExpose({ open }) // 提供 open 方法,用于打开弹窗
112
113 /** 提交表单 */
114 const emit = defineEmits(['success']) // 定义 success 事件,用于操作成功后的回调
115 const submitForm = async () => {
116   formLoading.value = true
117   try {
118     const data = {
119       roleId: formData.id,
120       dataScope: formData.dataScope,
121       dataScopeDeptIds:
122         formData.dataScope !== SystemDataScopeEnum.DEPT_CUSTOM
123           ? []
124           : treeRef.value.getCheckedKeys(false)
125     }
126     await PermissionApi.assignRoleDataScope(data)
127     message.success(t('common.updateSuccess'))
128     dialogVisible.value = false
129     // 发送操作成功的事件
130     emit('success')
131   } finally {
132     formLoading.value = false
133   }
134 }
135
136 /** 重置表单 */
137 const resetForm = () => {
138   // 重置选项
139   treeNodeAll.value = false
140   deptExpand.value = true
141   checkStrictly.value = true
142   // 重置表单
143   formData.value = {
144     id: undefined,
145     name: '',
146     code: '',
147     dataScope: undefined,
148     dataScopeDeptIds: []
149   }
150   treeRef.value?.setCheckedNodes([])
151   formRef.value?.resetFields()
152 }
153
154 /** 全选/全不选 */
155 const handleCheckedTreeNodeAll = () => {
156   treeRef.value.setCheckedNodes(treeNodeAll.value ? deptOptions.value : [])
157 }
158
159 /** 展开/折叠全部 */
160 const handleCheckedTreeExpand = () => {
161   const nodes = treeRef.value?.store.nodesMap
162   for (let node in nodes) {
163     if (nodes[node].expanded === deptExpand.value) {
164       continue
165     }
166     nodes[node].expanded = deptExpand.value
167   }
168 }
169 </script>