Commit 8cfc0736faf6a303ebfaee523d9bfc059f1ccdac

Authored by xingyu4j
1 parent 753d8dda

refactor: use vxeCrud refactor menus

yudao-ui-admin-vue3/src/router/index.ts
... ... @@ -14,7 +14,7 @@ import { usePermissionStoreWithOut } from '@/store/modules/permission'
14 14 import { getInfoApi } from '@/api/login'
15 15 import { listSimpleDictDataApi } from '@/api/system/dict/dict.data'
16 16  
17   -const { wsCache } = useCache('sessionStorage')
  17 +const { wsCache } = useCache()
18 18  
19 19 const { start, done } = useNProgress()
20 20  
... ...
yudao-ui-admin-vue3/src/views/system/dept/dept.data.ts
... ... @@ -12,8 +12,7 @@ export const rules = reactive({
12 12 email: [required],
13 13 phone: [
14 14 {
15   - min: 11,
16   - max: 11,
  15 + len: 11,
17 16 trigger: 'blur',
18 17 message: '请输入正确的手机号码'
19 18 }
... ...
yudao-ui-admin-vue3/src/views/system/dept/index.vue
... ... @@ -75,16 +75,15 @@
75 75 </XModal>
76 76 </template>
77 77 <script setup lang="ts" name="Dept">
78   -import { nextTick, onMounted, reactive, ref, unref } from 'vue'
  78 +import { nextTick, onMounted, ref, unref } from 'vue'
79 79 import { ElSelect, ElTreeSelect, ElOption } from 'element-plus'
80 80 import { VxeGridInstance } from 'vxe-table'
81 81 import { handleTree, defaultProps } from '@/utils/tree'
82   -import { required } from '@/utils/formRules.js'
83 82 import { useI18n } from '@/hooks/web/useI18n'
84 83 import { useMessage } from '@/hooks/web/useMessage'
85 84 import { useVxeGrid } from '@/hooks/web/useVxeGrid'
86 85 import { FormExpose } from '@/components/Form'
87   -import { allSchemas } from './dept.data'
  86 +import { allSchemas, rules } from './dept.data'
88 87 import * as DeptApi from '@/api/system/dept'
89 88 import { getListSimpleUsersApi, UserVO } from '@/api/system/user'
90 89  
... ... @@ -107,13 +106,6 @@ const actionLoading = ref(false) // 遮罩层
107 106 const formRef = ref<FormExpose>() // 表单 Ref
108 107 const deptOptions = ref() // 树形结构
109 108 const userOption = ref<UserVO[]>([])
110   -// 新增和修改的表单校验
111   -const rules = reactive({
112   - name: [required],
113   - sort: [required],
114   - path: [required],
115   - status: [required]
116   -})
117 109  
118 110 const getUserList = async () => {
119 111 const res = await getListSimpleUsersApi()
... ...
yudao-ui-admin-vue3/src/views/system/menu/index.vue
1 1 <template>
2 2 <ContentWrap>
3   - <!-- 搜索工作栏 -->
4   - <el-form :model="queryParams" ref="queryForm" :inline="true">
5   - <el-form-item label="菜单名称" prop="name">
6   - <el-input v-model="queryParams.name" placeholder="请输入菜单名称" />
7   - </el-form-item>
8   - <el-form-item label="状态" prop="status">
9   - <el-select v-model="queryParams.status" placeholder="请选择菜单状态">
10   - <el-option
11   - v-for="(dict, index) in getIntDictOptions(DICT_TYPE.COMMON_STATUS)"
12   - :key="index"
13   - :label="dict.label"
14   - :value="dict.value"
15   - />
16   - </el-select>
17   - </el-form-item>
18   - <el-form-item>
19   - <!-- 操作:搜索 -->
20   - <XButton
21   - type="primary"
22   - preIcon="ep:search"
23   - :title="t('common.query')"
24   - @click="handleQuery()"
25   - />
26   - <!-- 操作:重置 -->
27   - <XButton preIcon="ep:refresh-right" :title="t('common.reset')" @click="resetQuery()" />
28   - </el-form-item>
29   - </el-form>
30   - <vxe-toolbar>
31   - <template #buttons>
  3 + <!-- 列表 -->
  4 + <vxe-grid ref="xGrid" v-bind="gridOptions" show-overflow class="xtable-scrollbar">
  5 + <template #toolbar_buttons>
32 6 <!-- 操作:新增 -->
33 7 <XButton
34 8 type="primary"
... ... @@ -37,63 +11,26 @@
37 11 v-hasPermi="['system:menu:create']"
38 12 @click="handleCreate()"
39 13 />
40   - <XButton title="展开所有" @click="xTable?.setAllTreeExpand(true)" />
41   - <XButton title="关闭所有" @click="xTable?.clearTreeExpand()" />
  14 + <XButton title="展开所有" @click="xGrid?.setAllTreeExpand(true)" />
  15 + <XButton title="关闭所有" @click="xGrid?.clearTreeExpand()" />
42 16 </template>
43   - </vxe-toolbar>
44   - <!-- 列表 -->
45   - <vxe-table
46   - show-overflow
47   - keep-source
48   - ref="xTable"
49   - :loading="tableLoading"
50   - :row-config="{ keyField: 'id' }"
51   - :column-config="{ resizable: true }"
52   - :tree-config="{ transform: true, rowField: 'id', parentField: 'parentId' }"
53   - :print-config="{}"
54   - :export-config="{}"
55   - :data="tableData"
56   - >
57   - <vxe-column title="菜单名称" field="name" width="200" tree-node>
58   - <template #default="{ row }">
59   - <Icon :icon="row.icon" />
60   - <span class="ml-3">{{ row.name }}</span>
61   - </template>
62   - </vxe-column>
63   - <vxe-column title="菜单类型" field="type">
64   - <template #default="{ row }">
65   - <DictTag :type="DICT_TYPE.SYSTEM_MENU_TYPE" :value="row.type" />
66   - </template>
67   - </vxe-column>
68   - <vxe-column title="路由地址" field="path" />
69   - <vxe-column title="组件路径" field="component" />
70   - <vxe-column title="权限标识" field="permission" />
71   - <vxe-column title="排序" field="sort" />
72   - <vxe-column title="状态" field="status">
73   - <template #default="{ row }">
74   - <DictTag :type="DICT_TYPE.COMMON_STATUS" :value="row.status" />
75   - </template>
76   - </vxe-column>
77   - <vxe-column title="创建时间" field="createTime" formatter="formatDate" />
78   - <vxe-column title="操作" width="200">
79   - <template #default="{ row }">
80   - <!-- 操作:修改 -->
81   - <XTextButton
82   - preIcon="ep:edit"
83   - :title="t('action.edit')"
84   - v-hasPermi="['system:menu:update']"
85   - @click="handleUpdate(row.id)"
86   - />
87   - <!-- 操作:删除 -->
88   - <XTextButton
89   - preIcon="ep:delete"
90   - :title="t('action.del')"
91   - v-hasPermi="['system:menu:delete']"
92   - @click="handleDelete(row.id)"
93   - />
94   - </template>
95   - </vxe-column>
96   - </vxe-table>
  17 + <template #actionbtns_default="{ row }">
  18 + <!-- 操作:修改 -->
  19 + <XTextButton
  20 + preIcon="ep:edit"
  21 + :title="t('action.edit')"
  22 + v-hasPermi="['system:menu:update']"
  23 + @click="handleUpdate(row.id)"
  24 + />
  25 + <!-- 操作:删除 -->
  26 + <XTextButton
  27 + preIcon="ep:delete"
  28 + :title="t('action.del')"
  29 + v-hasPermi="['system:menu:delete']"
  30 + @click="handleDelete(row.id)"
  31 + />
  32 + </template>
  33 + </vxe-grid>
97 34 </ContentWrap>
98 35 <!-- 添加或修改菜单对话框 -->
99 36 <XModal id="menuModel" v-model="dialogVisible" :title="dialogTitle">
... ... @@ -235,7 +172,7 @@
235 172 </template>
236 173 <script setup lang="ts" name="Menu">
237 174 // 全局相关的 import
238   -import { onMounted, reactive, ref } from 'vue'
  175 +import { ref } from 'vue'
239 176 import { useI18n } from '@/hooks/web/useI18n'
240 177 import { CACHE_KEY, useCache } from '@/hooks/web/useCache'
241 178 import { useMessage } from '@/hooks/web/useMessage'
... ... @@ -245,9 +182,7 @@ import {
245 182 ElFormItem,
246 183 ElInput,
247 184 ElInputNumber,
248   - ElSelect,
249 185 ElTreeSelect,
250   - ElOption,
251 186 ElRadio,
252 187 ElRadioGroup,
253 188 ElRadioButton,
... ... @@ -255,21 +190,33 @@ import {
255 190 } from 'element-plus'
256 191 import { Tooltip } from '@/components/Tooltip'
257 192 import { IconSelect } from '@/components/Icon'
258   -import { VxeTableInstance } from 'vxe-table'
  193 +import { VxeGridInstance } from 'vxe-table'
259 194 // 业务相关的 import
260   -import * as MenuApi from '@/api/system/menu'
261   -import { required } from '@/utils/formRules.js'
262 195 import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
263 196 import { SystemMenuTypeEnum, CommonStatusEnum } from '@/utils/constants'
264 197 import { handleTree, defaultProps } from '@/utils/tree'
  198 +import * as MenuApi from '@/api/system/menu'
  199 +import { allSchemas, rules } from './menu.data'
  200 +import { useVxeGrid } from '@/hooks/web/useVxeGrid'
265 201  
266 202 const { t } = useI18n() // 国际化
267 203 const message = useMessage() // 消息弹窗
268 204 const { wsCache } = useCache()
269 205 // 列表相关的变量
270   -const xTable = ref<VxeTableInstance>()
271   -const tableLoading = ref(false)
272   -const tableData = ref()
  206 +// 列表相关的变量
  207 +const xGrid = ref<VxeGridInstance>() // 列表 Grid Ref
  208 +const treeConfig = {
  209 + transform: true,
  210 + rowField: 'id',
  211 + parentField: 'parentId',
  212 + expandAll: false
  213 +}
  214 +const { gridOptions, getList, deleteData } = useVxeGrid<MenuApi.MenuVO>({
  215 + allSchemas: allSchemas,
  216 + treeConfig: treeConfig,
  217 + getListApi: MenuApi.getMenuListApi,
  218 + deleteApi: MenuApi.deleteMenuApi
  219 +})
273 220 // 弹窗相关的变量
274 221 const dialogVisible = ref(false) // 是否显示弹出层
275 222 const dialogTitle = ref('edit') // 弹出层标题
... ... @@ -292,13 +239,6 @@ const menuForm = ref&lt;MenuApi.MenuVO&gt;({
292 239 keepAlive: true,
293 240 createTime: new Date()
294 241 })
295   -// 新增和修改的表单校验
296   -const rules = reactive({
297   - name: [required],
298   - sort: [required],
299   - path: [required],
300   - status: [required]
301   -})
302 242  
303 243 // ========== 下拉框[上级菜单] ==========
304 244 const menuOptions = ref<any[]>([]) // 树形结构
... ... @@ -311,31 +251,6 @@ const getTree = async () =&gt; {
311 251 menuOptions.value.push(menu)
312 252 }
313 253  
314   -// ========== 查询 ==========
315   -const queryParams = reactive<MenuApi.MenuPageReqVO>({
316   - name: undefined,
317   - status: undefined
318   -})
319   -// 执行查询
320   -const getList = async () => {
321   - tableLoading.value = true
322   - const res = await MenuApi.getMenuListApi(queryParams)
323   - tableData.value = res
324   - tableLoading.value = false
325   -}
326   -
327   -// 查询操作
328   -const handleQuery = async () => {
329   - await getList()
330   -}
331   -
332   -// 重置操作
333   -const resetQuery = async () => {
334   - queryParams.name = undefined
335   - queryParams.status = undefined
336   - await getList()
337   -}
338   -
339 254 // ========== 新增/修改 ==========
340 255  
341 256 // 设置标题
... ... @@ -407,7 +322,7 @@ const submitForm = async () =&gt; {
407 322 actionLoading.value = false
408 323 wsCache.delete(CACHE_KEY.ROLE_ROUTERS)
409 324 // 操作成功,重新加载列表
410   - await getList()
  325 + await getList(xGrid)
411 326 }
412 327 }
413 328  
... ... @@ -419,15 +334,6 @@ const isExternal = (path: string) =&gt; {
419 334 // ========== 删除 ==========
420 335 // 删除操作
421 336 const handleDelete = async (rowId: number) => {
422   - message.delConfirm().then(async () => {
423   - await MenuApi.deleteMenuApi(rowId)
424   - message.success(t('common.delSuccess'))
425   - await getList()
426   - })
  337 + await deleteData(xGrid, rowId)
427 338 }
428   -
429   -// ========== 初始化 ==========
430   -onMounted(async () => {
431   - await getList()
432   -})
433 339 </script>
... ...
yudao-ui-admin-vue3/src/views/system/menu/menu.data.ts 0 → 100644
  1 +import { reactive } from 'vue'
  2 +import { useI18n } from '@/hooks/web/useI18n'
  3 +import { DICT_TYPE } from '@/utils/dict'
  4 +import { required } from '@/utils/formRules'
  5 +import { VxeCrudSchema, useVxeCrudSchemas } from '@/hooks/web/useVxeCrudSchemas'
  6 +const { t } = useI18n() // 国际化
  7 +
  8 +// 新增和修改的表单校验
  9 +export const rules = reactive({
  10 + name: [required],
  11 + sort: [required],
  12 + path: [required],
  13 + status: [required]
  14 +})
  15 +
  16 +// CrudSchema
  17 +const crudSchemas = reactive<VxeCrudSchema>({
  18 + primaryKey: 'id',
  19 + primaryType: null,
  20 + action: true,
  21 + columns: [
  22 + {
  23 + title: '上级菜单',
  24 + field: 'parentId',
  25 + isTable: false
  26 + },
  27 + {
  28 + title: '菜单名称',
  29 + field: 'name',
  30 + isSearch: true,
  31 + table: {
  32 + treeNode: true,
  33 + align: 'left',
  34 + width: '200px'
  35 + }
  36 + },
  37 + {
  38 + title: '菜单类型',
  39 + field: 'type',
  40 + dictType: DICT_TYPE.SYSTEM_MENU_TYPE
  41 + },
  42 + {
  43 + title: '路由地址',
  44 + field: 'path'
  45 + },
  46 + {
  47 + title: '组件路径',
  48 + field: 'component'
  49 + },
  50 + {
  51 + title: '权限标识',
  52 + field: 'permission'
  53 + },
  54 + {
  55 + title: '排序',
  56 + field: 'sort'
  57 + },
  58 + {
  59 + title: t('common.status'),
  60 + field: 'status',
  61 + dictType: DICT_TYPE.COMMON_STATUS,
  62 + dictClass: 'number',
  63 + isSearch: true
  64 + },
  65 + {
  66 + title: t('common.createTime'),
  67 + field: 'createTime',
  68 + formatter: 'formatDate',
  69 + isForm: false
  70 + }
  71 + ]
  72 +})
  73 +export const { allSchemas } = useVxeCrudSchemas(crudSchemas)
... ...