refactor: use vxeCrud refactor menus

This commit is contained in:
xingyu4j 2022-12-14 17:51:23 +08:00
parent 753d8dda73
commit 8cfc0736fa
5 changed files with 120 additions and 150 deletions

View File

@ -14,7 +14,7 @@ import { usePermissionStoreWithOut } from '@/store/modules/permission'
import { getInfoApi } from '@/api/login' import { getInfoApi } from '@/api/login'
import { listSimpleDictDataApi } from '@/api/system/dict/dict.data' import { listSimpleDictDataApi } from '@/api/system/dict/dict.data'
const { wsCache } = useCache('sessionStorage') const { wsCache } = useCache()
const { start, done } = useNProgress() const { start, done } = useNProgress()

View File

@ -12,8 +12,7 @@ export const rules = reactive({
email: [required], email: [required],
phone: [ phone: [
{ {
min: 11, len: 11,
max: 11,
trigger: 'blur', trigger: 'blur',
message: '请输入正确的手机号码' message: '请输入正确的手机号码'
} }

View File

@ -75,16 +75,15 @@
</XModal> </XModal>
</template> </template>
<script setup lang="ts" name="Dept"> <script setup lang="ts" name="Dept">
import { nextTick, onMounted, reactive, ref, unref } from 'vue' import { nextTick, onMounted, ref, unref } from 'vue'
import { ElSelect, ElTreeSelect, ElOption } from 'element-plus' import { ElSelect, ElTreeSelect, ElOption } from 'element-plus'
import { VxeGridInstance } from 'vxe-table' import { VxeGridInstance } from 'vxe-table'
import { handleTree, defaultProps } from '@/utils/tree' import { handleTree, defaultProps } from '@/utils/tree'
import { required } from '@/utils/formRules.js'
import { useI18n } from '@/hooks/web/useI18n' import { useI18n } from '@/hooks/web/useI18n'
import { useMessage } from '@/hooks/web/useMessage' import { useMessage } from '@/hooks/web/useMessage'
import { useVxeGrid } from '@/hooks/web/useVxeGrid' import { useVxeGrid } from '@/hooks/web/useVxeGrid'
import { FormExpose } from '@/components/Form' import { FormExpose } from '@/components/Form'
import { allSchemas } from './dept.data' import { allSchemas, rules } from './dept.data'
import * as DeptApi from '@/api/system/dept' import * as DeptApi from '@/api/system/dept'
import { getListSimpleUsersApi, UserVO } from '@/api/system/user' import { getListSimpleUsersApi, UserVO } from '@/api/system/user'
@ -107,13 +106,6 @@ const actionLoading = ref(false) // 遮罩层
const formRef = ref<FormExpose>() // Ref const formRef = ref<FormExpose>() // Ref
const deptOptions = ref() // const deptOptions = ref() //
const userOption = ref<UserVO[]>([]) const userOption = ref<UserVO[]>([])
//
const rules = reactive({
name: [required],
sort: [required],
path: [required],
status: [required]
})
const getUserList = async () => { const getUserList = async () => {
const res = await getListSimpleUsersApi() const res = await getListSimpleUsersApi()

View File

@ -1,34 +1,8 @@
<template> <template>
<ContentWrap> <ContentWrap>
<!-- 搜索工作栏 --> <!-- 列表 -->
<el-form :model="queryParams" ref="queryForm" :inline="true"> <vxe-grid ref="xGrid" v-bind="gridOptions" show-overflow class="xtable-scrollbar">
<el-form-item label="菜单名称" prop="name"> <template #toolbar_buttons>
<el-input v-model="queryParams.name" placeholder="请输入菜单名称" />
</el-form-item>
<el-form-item label="状态" prop="status">
<el-select v-model="queryParams.status" placeholder="请选择菜单状态">
<el-option
v-for="(dict, index) in getIntDictOptions(DICT_TYPE.COMMON_STATUS)"
:key="index"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
<el-form-item>
<!-- 操作搜索 -->
<XButton
type="primary"
preIcon="ep:search"
:title="t('common.query')"
@click="handleQuery()"
/>
<!-- 操作重置 -->
<XButton preIcon="ep:refresh-right" :title="t('common.reset')" @click="resetQuery()" />
</el-form-item>
</el-form>
<vxe-toolbar>
<template #buttons>
<!-- 操作新增 --> <!-- 操作新增 -->
<XButton <XButton
type="primary" type="primary"
@ -37,63 +11,26 @@
v-hasPermi="['system:menu:create']" v-hasPermi="['system:menu:create']"
@click="handleCreate()" @click="handleCreate()"
/> />
<XButton title="展开所有" @click="xTable?.setAllTreeExpand(true)" /> <XButton title="展开所有" @click="xGrid?.setAllTreeExpand(true)" />
<XButton title="关闭所有" @click="xTable?.clearTreeExpand()" /> <XButton title="关闭所有" @click="xGrid?.clearTreeExpand()" />
</template> </template>
</vxe-toolbar> <template #actionbtns_default="{ row }">
<!-- 列表 --> <!-- 操作修改 -->
<vxe-table <XTextButton
show-overflow preIcon="ep:edit"
keep-source :title="t('action.edit')"
ref="xTable" v-hasPermi="['system:menu:update']"
:loading="tableLoading" @click="handleUpdate(row.id)"
:row-config="{ keyField: 'id' }" />
:column-config="{ resizable: true }" <!-- 操作删除 -->
:tree-config="{ transform: true, rowField: 'id', parentField: 'parentId' }" <XTextButton
:print-config="{}" preIcon="ep:delete"
:export-config="{}" :title="t('action.del')"
:data="tableData" v-hasPermi="['system:menu:delete']"
> @click="handleDelete(row.id)"
<vxe-column title="菜单名称" field="name" width="200" tree-node> />
<template #default="{ row }"> </template>
<Icon :icon="row.icon" /> </vxe-grid>
<span class="ml-3">{{ row.name }}</span>
</template>
</vxe-column>
<vxe-column title="菜单类型" field="type">
<template #default="{ row }">
<DictTag :type="DICT_TYPE.SYSTEM_MENU_TYPE" :value="row.type" />
</template>
</vxe-column>
<vxe-column title="路由地址" field="path" />
<vxe-column title="组件路径" field="component" />
<vxe-column title="权限标识" field="permission" />
<vxe-column title="排序" field="sort" />
<vxe-column title="状态" field="status">
<template #default="{ row }">
<DictTag :type="DICT_TYPE.COMMON_STATUS" :value="row.status" />
</template>
</vxe-column>
<vxe-column title="创建时间" field="createTime" formatter="formatDate" />
<vxe-column title="操作" width="200">
<template #default="{ row }">
<!-- 操作修改 -->
<XTextButton
preIcon="ep:edit"
:title="t('action.edit')"
v-hasPermi="['system:menu:update']"
@click="handleUpdate(row.id)"
/>
<!-- 操作删除 -->
<XTextButton
preIcon="ep:delete"
:title="t('action.del')"
v-hasPermi="['system:menu:delete']"
@click="handleDelete(row.id)"
/>
</template>
</vxe-column>
</vxe-table>
</ContentWrap> </ContentWrap>
<!-- 添加或修改菜单对话框 --> <!-- 添加或修改菜单对话框 -->
<XModal id="menuModel" v-model="dialogVisible" :title="dialogTitle"> <XModal id="menuModel" v-model="dialogVisible" :title="dialogTitle">
@ -235,7 +172,7 @@
</template> </template>
<script setup lang="ts" name="Menu"> <script setup lang="ts" name="Menu">
// import // import
import { onMounted, reactive, ref } from 'vue' import { ref } from 'vue'
import { useI18n } from '@/hooks/web/useI18n' import { useI18n } from '@/hooks/web/useI18n'
import { CACHE_KEY, useCache } from '@/hooks/web/useCache' import { CACHE_KEY, useCache } from '@/hooks/web/useCache'
import { useMessage } from '@/hooks/web/useMessage' import { useMessage } from '@/hooks/web/useMessage'
@ -245,9 +182,7 @@ import {
ElFormItem, ElFormItem,
ElInput, ElInput,
ElInputNumber, ElInputNumber,
ElSelect,
ElTreeSelect, ElTreeSelect,
ElOption,
ElRadio, ElRadio,
ElRadioGroup, ElRadioGroup,
ElRadioButton, ElRadioButton,
@ -255,21 +190,33 @@ import {
} from 'element-plus' } from 'element-plus'
import { Tooltip } from '@/components/Tooltip' import { Tooltip } from '@/components/Tooltip'
import { IconSelect } from '@/components/Icon' import { IconSelect } from '@/components/Icon'
import { VxeTableInstance } from 'vxe-table' import { VxeGridInstance } from 'vxe-table'
// import // import
import * as MenuApi from '@/api/system/menu'
import { required } from '@/utils/formRules.js'
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict' import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
import { SystemMenuTypeEnum, CommonStatusEnum } from '@/utils/constants' import { SystemMenuTypeEnum, CommonStatusEnum } from '@/utils/constants'
import { handleTree, defaultProps } from '@/utils/tree' import { handleTree, defaultProps } from '@/utils/tree'
import * as MenuApi from '@/api/system/menu'
import { allSchemas, rules } from './menu.data'
import { useVxeGrid } from '@/hooks/web/useVxeGrid'
const { t } = useI18n() // const { t } = useI18n() //
const message = useMessage() // const message = useMessage() //
const { wsCache } = useCache() const { wsCache } = useCache()
// //
const xTable = ref<VxeTableInstance>() //
const tableLoading = ref(false) const xGrid = ref<VxeGridInstance>() // Grid Ref
const tableData = ref() const treeConfig = {
transform: true,
rowField: 'id',
parentField: 'parentId',
expandAll: false
}
const { gridOptions, getList, deleteData } = useVxeGrid<MenuApi.MenuVO>({
allSchemas: allSchemas,
treeConfig: treeConfig,
getListApi: MenuApi.getMenuListApi,
deleteApi: MenuApi.deleteMenuApi
})
// //
const dialogVisible = ref(false) // const dialogVisible = ref(false) //
const dialogTitle = ref('edit') // const dialogTitle = ref('edit') //
@ -292,13 +239,6 @@ const menuForm = ref<MenuApi.MenuVO>({
keepAlive: true, keepAlive: true,
createTime: new Date() createTime: new Date()
}) })
//
const rules = reactive({
name: [required],
sort: [required],
path: [required],
status: [required]
})
// ========== [] ========== // ========== [] ==========
const menuOptions = ref<any[]>([]) // const menuOptions = ref<any[]>([]) //
@ -311,31 +251,6 @@ const getTree = async () => {
menuOptions.value.push(menu) menuOptions.value.push(menu)
} }
// ========== ==========
const queryParams = reactive<MenuApi.MenuPageReqVO>({
name: undefined,
status: undefined
})
//
const getList = async () => {
tableLoading.value = true
const res = await MenuApi.getMenuListApi(queryParams)
tableData.value = res
tableLoading.value = false
}
//
const handleQuery = async () => {
await getList()
}
//
const resetQuery = async () => {
queryParams.name = undefined
queryParams.status = undefined
await getList()
}
// ========== / ========== // ========== / ==========
// //
@ -407,7 +322,7 @@ const submitForm = async () => {
actionLoading.value = false actionLoading.value = false
wsCache.delete(CACHE_KEY.ROLE_ROUTERS) wsCache.delete(CACHE_KEY.ROLE_ROUTERS)
// //
await getList() await getList(xGrid)
} }
} }
@ -419,15 +334,6 @@ const isExternal = (path: string) => {
// ========== ========== // ========== ==========
// //
const handleDelete = async (rowId: number) => { const handleDelete = async (rowId: number) => {
message.delConfirm().then(async () => { await deleteData(xGrid, rowId)
await MenuApi.deleteMenuApi(rowId)
message.success(t('common.delSuccess'))
await getList()
})
} }
// ========== ==========
onMounted(async () => {
await getList()
})
</script> </script>

View File

@ -0,0 +1,73 @@
import { reactive } from 'vue'
import { useI18n } from '@/hooks/web/useI18n'
import { DICT_TYPE } from '@/utils/dict'
import { required } from '@/utils/formRules'
import { VxeCrudSchema, useVxeCrudSchemas } from '@/hooks/web/useVxeCrudSchemas'
const { t } = useI18n() // 国际化
// 新增和修改的表单校验
export const rules = reactive({
name: [required],
sort: [required],
path: [required],
status: [required]
})
// CrudSchema
const crudSchemas = reactive<VxeCrudSchema>({
primaryKey: 'id',
primaryType: null,
action: true,
columns: [
{
title: '上级菜单',
field: 'parentId',
isTable: false
},
{
title: '菜单名称',
field: 'name',
isSearch: true,
table: {
treeNode: true,
align: 'left',
width: '200px'
}
},
{
title: '菜单类型',
field: 'type',
dictType: DICT_TYPE.SYSTEM_MENU_TYPE
},
{
title: '路由地址',
field: 'path'
},
{
title: '组件路径',
field: 'component'
},
{
title: '权限标识',
field: 'permission'
},
{
title: '排序',
field: 'sort'
},
{
title: t('common.status'),
field: 'status',
dictType: DICT_TYPE.COMMON_STATUS,
dictClass: 'number',
isSearch: true
},
{
title: t('common.createTime'),
field: 'createTime',
formatter: 'formatDate',
isForm: false
}
]
})
export const { allSchemas } = useVxeCrudSchemas(crudSchemas)