Commit 8cfc0736faf6a303ebfaee523d9bfc059f1ccdac
1 parent
753d8dda
refactor: use vxeCrud refactor menus
Showing
5 changed files
with
120 additions
and
150 deletions
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
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<MenuApi.MenuVO>({ |
| 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 () => { |
| 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 () => { |
| 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) => { |
| 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) | ... | ... |