Commit a123c47042d01c9ad3956ea442bf760f9e024999

Authored by xingyu
1 parent fb5b71ca

refactor: role

yudao-ui-admin-vue3/src/api/system/role/index.ts
1 import request from '@/config/axios' 1 import request from '@/config/axios'
2 -import type { RoleVO } from './types' 2 +
  3 +export type RoleVO = {
  4 + id: number
  5 + name: string
  6 + code: string
  7 + sort: number
  8 + status: number
  9 + type: number
  10 + createTime: string
  11 +}
  12 +
  13 +export interface RolePageReqVO extends PageParam {
  14 + name?: string
  15 + code?: string
  16 + status?: number
  17 + createTime?: string[]
  18 +}
3 19
4 // 查询角色列表 20 // 查询角色列表
5 -export const getRolePageApi = async (params) => { 21 +export const getRolePageApi = async (params: RolePageReqVO) => {
6 return await request.get({ url: '/system/role/page', params }) 22 return await request.get({ url: '/system/role/page', params })
7 } 23 }
8 24
yudao-ui-admin-vue3/src/api/system/role/types.ts deleted
1 -export type RoleVO = {  
2 - id: number  
3 - name: string  
4 - code: string  
5 - sort: number  
6 - status: number  
7 - type: number  
8 - createTime: string  
9 -}  
yudao-ui-admin-vue3/src/views/system/role/index.vue
1 <template> 1 <template>
2 - <!-- 搜索工作区 -->  
3 <ContentWrap> 2 <ContentWrap>
4 - <Search :schema="allSchemas.searchSchema" @search="setSearchParams" @reset="setSearchParams" />  
5 - </ContentWrap>  
6 - <ContentWrap>  
7 - <!-- 操作工具栏 -->  
8 - <div class="mb-10px">  
9 - <XButton  
10 - type="primary"  
11 - preIcon="ep:zoom-in"  
12 - :title="t('action.add')"  
13 - v-hasPermi="['system:role:create']"  
14 - @click="handleCreate()"  
15 - />  
16 - </div>  
17 <!-- 列表 --> 3 <!-- 列表 -->
18 - <Table  
19 - :columns="allSchemas.tableColumns"  
20 - :selection="false"  
21 - :data="tableObject.tableList"  
22 - :loading="tableObject.loading"  
23 - :pagination="{  
24 - total: tableObject.total  
25 - }"  
26 - v-model:pageSize="tableObject.pageSize"  
27 - v-model:currentPage="tableObject.currentPage"  
28 - @register="register"  
29 - >  
30 - <template #type="{ row }">  
31 - <DictTag :type="DICT_TYPE.SYSTEM_ROLE_TYPE" :value="row.type" />  
32 - </template>  
33 - <template #status="{ row }">  
34 - <DictTag :type="DICT_TYPE.COMMON_STATUS" :value="row.status" />  
35 - </template>  
36 - <template #createTime="{ row }">  
37 - <span>{{ dayjs(row.createTime).format('YYYY-MM-DD HH:mm:ss') }}</span> 4 + <vxe-grid ref="xGrid" v-bind="gridOptions" class="xtable-scrollbar">
  5 + <!-- 操作:新增 -->
  6 + <template #toolbar_buttons>
  7 + <XButton
  8 + type="primary"
  9 + preIcon="ep:zoom-in"
  10 + :title="t('action.add')"
  11 + v-hasPermi="['system:role:create']"
  12 + @click="handleCreate()"
  13 + />
38 </template> 14 </template>
39 - <template #action="{ row }"> 15 + <template #actionbtns_default="{ row }">
40 <XTextButton 16 <XTextButton
41 preIcon="ep:edit" 17 preIcon="ep:edit"
42 :title="t('action.edit')" 18 :title="t('action.edit')"
@@ -47,7 +23,7 @@ @@ -47,7 +23,7 @@
47 preIcon="ep:view" 23 preIcon="ep:view"
48 :title="t('action.detail')" 24 :title="t('action.detail')"
49 v-hasPermi="['system:role:update']" 25 v-hasPermi="['system:role:update']"
50 - @click="handleDetail(row)" 26 + @click="handleDetail(row.id)"
51 /> 27 />
52 <XTextButton 28 <XTextButton
53 preIcon="ep:basketball" 29 preIcon="ep:basketball"
@@ -65,10 +41,10 @@ @@ -65,10 +41,10 @@
65 preIcon="ep:delete" 41 preIcon="ep:delete"
66 :title="t('action.del')" 42 :title="t('action.del')"
67 v-hasPermi="['system:role:delete']" 43 v-hasPermi="['system:role:delete']"
68 - @click="delList(row.id, false)" 44 + @click="handleDelete(row.id)"
69 /> 45 />
70 </template> 46 </template>
71 - </Table> 47 + </vxe-grid>
72 </ContentWrap> 48 </ContentWrap>
73 49
74 <XModal v-model="dialogVisible" :title="dialogTitle"> 50 <XModal v-model="dialogVisible" :title="dialogTitle">
@@ -91,10 +67,10 @@ @@ -91,10 +67,10 @@
91 v-if="['create', 'update'].includes(actionType)" 67 v-if="['create', 'update'].includes(actionType)"
92 type="primary" 68 type="primary"
93 :title="t('action.save')" 69 :title="t('action.save')"
94 - :loading="loading" 70 + :loading="actionLoading"
95 @click="submitForm()" 71 @click="submitForm()"
96 /> 72 />
97 - <XButton :loading="loading" :title="t('dialog.close')" @click="dialogVisible = false" /> 73 + <XButton :loading="actionLoading" :title="t('dialog.close')" @click="dialogVisible = false" />
98 </template> 74 </template>
99 </XModal> 75 </XModal>
100 <XModal v-model="dialogScopeVisible" :title="dialogScopeTitle"> 76 <XModal v-model="dialogScopeVisible" :title="dialogScopeTitle">
@@ -151,56 +127,66 @@ @@ -151,56 +127,66 @@
151 </el-form> 127 </el-form>
152 <!-- 操作按钮 --> 128 <!-- 操作按钮 -->
153 <template #footer> 129 <template #footer>
154 - <XButton type="primary" :title="t('action.save')" :loading="loading" @click="submitScope()" />  
155 - <XButton :loading="loading" :title="t('dialog.close')" @click="dialogScopeVisible = false" /> 130 + <XButton
  131 + type="primary"
  132 + :title="t('action.save')"
  133 + :loading="actionLoading"
  134 + @click="submitScope()"
  135 + />
  136 + <XButton
  137 + :loading="actionLoading"
  138 + :title="t('dialog.close')"
  139 + @click="dialogScopeVisible = false"
  140 + />
156 </template> 141 </template>
157 </XModal> 142 </XModal>
158 </template> 143 </template>
159 <script setup lang="ts"> 144 <script setup lang="ts">
160 import { onMounted, reactive, ref, unref } from 'vue' 145 import { onMounted, reactive, ref, unref } from 'vue'
161 -import dayjs from 'dayjs'  
162 import { 146 import {
163 ElForm, 147 ElForm,
164 ElFormItem, 148 ElFormItem,
165 ElInput, 149 ElInput,
166 ElSelect, 150 ElSelect,
167 ElOption, 151 ElOption,
168 - ElMessage,  
169 ElTree, 152 ElTree,
170 ElCard, 153 ElCard,
171 ElSwitch 154 ElSwitch
172 } from 'element-plus' 155 } from 'element-plus'
173 import { DICT_TYPE, getDictOptions } from '@/utils/dict' 156 import { DICT_TYPE, getDictOptions } from '@/utils/dict'
174 -import { useTable } from '@/hooks/web/useTable'  
175 import { useI18n } from '@/hooks/web/useI18n' 157 import { useI18n } from '@/hooks/web/useI18n'
  158 +import { useMessage } from '@/hooks/web/useMessage'
176 import { FormExpose } from '@/components/Form' 159 import { FormExpose } from '@/components/Form'
177 import { rules, allSchemas } from './role.data' 160 import { rules, allSchemas } from './role.data'
178 -import type { RoleVO } from '@/api/system/role/types' 161 +import { handleTree } from '@/utils/tree'
  162 +import { SystemDataScopeEnum } from '@/utils/constants'
  163 +import { useVxeGrid } from '@/hooks/web/useVxeGrid'
  164 +import { VxeGridInstance } from 'vxe-table'
  165 +import * as RoleApi from '@/api/system/role'
  166 +import { listSimpleMenusApi } from '@/api/system/menu'
  167 +import { listSimpleDeptApi } from '@/api/system/dept'
  168 +import * as PermissionApi from '@/api/system/permission'
179 import type { 169 import type {
180 PermissionAssignRoleDataScopeReqVO, 170 PermissionAssignRoleDataScopeReqVO,
181 PermissionAssignRoleMenuReqVO 171 PermissionAssignRoleMenuReqVO
182 } from '@/api/system/permission/types' 172 } from '@/api/system/permission/types'
183 -import * as RoleApi from '@/api/system/role'  
184 -import * as PermissionApi from '@/api/system/permission'  
185 -import { listSimpleMenusApi } from '@/api/system/menu'  
186 -import { listSimpleDeptApi } from '@/api/system/dept'  
187 -import { handleTree } from '@/utils/tree'  
188 -import { SystemDataScopeEnum } from '@/utils/constants'  
189 const { t } = useI18n() // 国际化 173 const { t } = useI18n() // 国际化
190 -  
191 -// ========== 列表相关 ==========  
192 -const { register, tableObject, methods } = useTable<RoleVO>({ 174 +const message = useMessage() // 消息弹窗
  175 +// 列表相关的变量
  176 +const xGrid = ref<VxeGridInstance>() // 列表 Grid Ref
  177 +const { gridOptions, reloadList, delList } = useVxeGrid<RoleApi.RoleVO>({
  178 + allSchemas: allSchemas,
193 getListApi: RoleApi.getRolePageApi, 179 getListApi: RoleApi.getRolePageApi,
194 delListApi: RoleApi.deleteRoleApi 180 delListApi: RoleApi.deleteRoleApi
195 }) 181 })
196 -const { getList, setSearchParams, delList } = methods  
197 182
198 // ========== CRUD 相关 ========== 183 // ========== CRUD 相关 ==========
199 -const loading = ref(false) // 遮罩层 184 +const actionLoading = ref(false) // 遮罩层
200 const actionType = ref('') // 操作按钮的类型 185 const actionType = ref('') // 操作按钮的类型
201 const dialogVisible = ref(false) // 是否显示弹出层 186 const dialogVisible = ref(false) // 是否显示弹出层
202 const dialogTitle = ref('edit') // 弹出层标题 187 const dialogTitle = ref('edit') // 弹出层标题
203 const formRef = ref<FormExpose>() // 表单 Ref 188 const formRef = ref<FormExpose>() // 表单 Ref
  189 +const detailRef = ref() // 详情 Ref
204 190
205 // 设置标题 191 // 设置标题
206 const setDialogTile = (type: string) => { 192 const setDialogTile = (type: string) => {
@@ -222,41 +208,44 @@ const handleUpdate = async (rowId: number) =&gt; { @@ -222,41 +208,44 @@ const handleUpdate = async (rowId: number) =&gt; {
222 unref(formRef)?.setValues(res) 208 unref(formRef)?.setValues(res)
223 } 209 }
224 210
  211 +// 删除操作
  212 +const handleDelete = async (rowId: number) => {
  213 + await delList(xGrid, rowId)
  214 +}
  215 +
225 // 提交按钮 216 // 提交按钮
226 const submitForm = async () => { 217 const submitForm = async () => {
227 const elForm = unref(formRef)?.getElFormRef() 218 const elForm = unref(formRef)?.getElFormRef()
228 if (!elForm) return 219 if (!elForm) return
229 elForm.validate(async (valid) => { 220 elForm.validate(async (valid) => {
230 if (valid) { 221 if (valid) {
231 - loading.value = true 222 + actionLoading.value = true
232 // 提交请求 223 // 提交请求
233 try { 224 try {
234 - const data = unref(formRef)?.formModel as RoleVO 225 + const data = unref(formRef)?.formModel as RoleApi.RoleVO
235 if (actionType.value === 'create') { 226 if (actionType.value === 'create') {
236 await RoleApi.createRoleApi(data) 227 await RoleApi.createRoleApi(data)
237 - ElMessage.success(t('common.createSuccess')) 228 + message.success(t('common.createSuccess'))
238 } else { 229 } else {
239 await RoleApi.updateRoleApi(data) 230 await RoleApi.updateRoleApi(data)
240 - ElMessage.success(t('common.updateSuccess')) 231 + message.success(t('common.updateSuccess'))
241 } 232 }
242 - // 操作成功,重新加载列表  
243 dialogVisible.value = false 233 dialogVisible.value = false
244 - await getList()  
245 } finally { 234 } finally {
246 - loading.value = false 235 + actionLoading.value = false
  236 + // 刷新列表
  237 + reloadList(xGrid)
247 } 238 }
248 } 239 }
249 }) 240 })
250 } 241 }
251 242
252 -// ========== 详情相关 ==========  
253 -const detailRef = ref() // 详情 Ref  
254 -  
255 // 详情操作 243 // 详情操作
256 -const handleDetail = async (row: RoleVO) => {  
257 - // 设置数据  
258 - detailRef.value = row 244 +const handleDetail = async (rowId: number) => {
259 setDialogTile('detail') 245 setDialogTile('detail')
  246 + // 设置数据
  247 + const res = await RoleApi.getRoleApi(rowId)
  248 + detailRef.value = res
260 } 249 }
261 250
262 // ========== 数据权限 ========== 251 // ========== 数据权限 ==========
@@ -287,7 +276,7 @@ const handleCheckedTreeNodeAll = () =&gt; { @@ -287,7 +276,7 @@ const handleCheckedTreeNodeAll = () =&gt; {
287 treeRef.value!.setCheckedNodes(treeNodeAll.value ? treeOptions.value : []) 276 treeRef.value!.setCheckedNodes(treeNodeAll.value ? treeOptions.value : [])
288 } 277 }
289 // 权限操作 278 // 权限操作
290 -const handleScope = async (type: string, row: RoleVO) => { 279 +const handleScope = async (type: string, row: RoleApi.RoleVO) => {
291 dataScopeForm.id = row.id 280 dataScopeForm.id = row.id
292 dataScopeForm.name = row.name 281 dataScopeForm.name = row.name
293 dataScopeForm.code = row.code 282 dataScopeForm.code = row.code
@@ -329,7 +318,7 @@ const submitScope = async () =&gt; { @@ -329,7 +318,7 @@ const submitScope = async () =&gt; {
329 }) 318 })
330 await PermissionApi.assignRoleMenuApi(data.value) 319 await PermissionApi.assignRoleMenuApi(data.value)
331 } 320 }
332 - ElMessage.success(t('common.updateSuccess')) 321 + message.success(t('common.updateSuccess'))
333 dialogScopeVisible.value = false 322 dialogScopeVisible.value = false
334 } 323 }
335 const init = () => { 324 const init = () => {
@@ -337,7 +326,6 @@ const init = () =&gt; { @@ -337,7 +326,6 @@ const init = () =&gt; {
337 } 326 }
338 // ========== 初始化 ========== 327 // ========== 初始化 ==========
339 onMounted(() => { 328 onMounted(() => {
340 - getList()  
341 init() 329 init()
342 }) 330 })
343 </script> 331 </script>
yudao-ui-admin-vue3/src/views/system/role/role.data.ts
@@ -2,7 +2,7 @@ import { reactive } from &#39;vue&#39; @@ -2,7 +2,7 @@ import { reactive } from &#39;vue&#39;
2 import { useI18n } from '@/hooks/web/useI18n' 2 import { useI18n } from '@/hooks/web/useI18n'
3 import { required } from '@/utils/formRules' 3 import { required } from '@/utils/formRules'
4 import { DICT_TYPE } from '@/utils/dict' 4 import { DICT_TYPE } from '@/utils/dict'
5 -import { CrudSchema, useCrudSchemas } from '@/hooks/web/useCrudSchemas' 5 +import { VxeCrudSchema, useVxeCrudSchemas } from '@/hooks/web/useVxeCrudSchemas'
6 // 国际化 6 // 国际化
7 const { t } = useI18n() 7 const { t } = useI18n()
8 // 表单校验 8 // 表单校验
@@ -12,82 +12,52 @@ export const rules = reactive({ @@ -12,82 +12,52 @@ export const rules = reactive({
12 sort: [required] 12 sort: [required]
13 }) 13 })
14 // CrudSchema 14 // CrudSchema
15 -const crudSchemas = reactive<CrudSchema[]>([  
16 - {  
17 - label: t('common.index'),  
18 - field: 'id',  
19 - type: 'index',  
20 - form: {  
21 - show: false 15 +const crudSchemas = reactive<VxeCrudSchema>({
  16 + primaryKey: 'id',
  17 + primaryType: 'seq',
  18 + action: true,
  19 + actionWidth: '400px',
  20 + columns: [
  21 + {
  22 + title: '角色名称',
  23 + field: 'name',
  24 + isSearch: true
22 }, 25 },
23 - detail: {  
24 - show: false  
25 - }  
26 - },  
27 - {  
28 - label: '角色名称',  
29 - field: 'name',  
30 - search: {  
31 - show: true  
32 - }  
33 - },  
34 - {  
35 - label: '角色类型',  
36 - field: 'type',  
37 - dictType: DICT_TYPE.SYSTEM_ROLE_TYPE  
38 - },  
39 - {  
40 - label: '角色标识',  
41 - field: 'code',  
42 - search: {  
43 - show: true  
44 - }  
45 - },  
46 - {  
47 - label: '显示顺序',  
48 - field: 'sort',  
49 - form: {  
50 - component: 'InputNumber',  
51 - value: 0  
52 - }  
53 - },  
54 - {  
55 - label: t('common.status'),  
56 - field: 'status',  
57 - dictType: DICT_TYPE.COMMON_STATUS,  
58 - search: {  
59 - show: true  
60 - }  
61 - },  
62 - {  
63 - label: t('common.createTime'),  
64 - field: 'createTime',  
65 - form: {  
66 - show: false 26 + {
  27 + title: '角色类型',
  28 + field: 'type',
  29 + dictType: DICT_TYPE.SYSTEM_ROLE_TYPE
67 }, 30 },
68 - detail: {  
69 - show: false 31 + {
  32 + title: '角色标识',
  33 + field: 'code',
  34 + isSearch: true
70 }, 35 },
71 - search: {  
72 - show: true,  
73 - component: 'DatePicker',  
74 - componentProps: {  
75 - type: 'daterange',  
76 - valueFormat: 'YYYY-MM-DD HH:mm:ss',  
77 - defaultTime: [new Date(2000, 1, 1, 0, 0, 0), new Date(2000, 2, 1, 23, 59, 59)] 36 + {
  37 + title: '显示顺序',
  38 + field: 'sort',
  39 + form: {
  40 + component: 'InputNumber'
78 } 41 }
79 - }  
80 - },  
81 - {  
82 - field: 'action',  
83 - width: '450px',  
84 - label: t('table.action'),  
85 - form: {  
86 - show: false  
87 }, 42 },
88 - detail: {  
89 - show: false 43 + {
  44 + title: t('common.status'),
  45 + field: 'status',
  46 + dictType: DICT_TYPE.COMMON_STATUS,
  47 + isSearch: true
  48 + },
  49 + {
  50 + title: t('common.createTime'),
  51 + field: 'createTime',
  52 + formatter: 'formatDate',
  53 + isForm: false,
  54 + search: {
  55 + show: true,
  56 + itemRender: {
  57 + name: 'XDataTimePicker'
  58 + }
  59 + }
90 } 60 }
91 - }  
92 -])  
93 -export const { allSchemas } = useCrudSchemas(crudSchemas) 61 + ]
  62 +})
  63 +export const { allSchemas } = useVxeCrudSchemas(crudSchemas)