123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331 |
- <template>
- <div class="table-box">
- <ProTable
- ref="proTable"
- title="菜单列表"
- row-key="menuId"
- :columns="columns"
- :pagination="false"
- :request-api="listMenuApi"
- :init-param="initParam"
- :data-callback="dataCallback"
- >
- <!-- 表格 header 按钮 -->
- <template #tableHeader>
- <el-button type="primary" v-auth="['system:menu:add']" @click="openDialog(1, '菜单新增')">新增</el-button>
- </template>
- <!-- 菜单图标 -->
- <template #icon="scope">
- <!-- <el-icon :size="18" v-if="scope.row.icon">
- <component :is="scope.row.icon"></component>
- </el-icon> -->
- <svg-icon v-if="scope.row.icon" :name="scope.row.icon" />
- </template>
- <!-- 表格操作 -->
- <template #operation="scope">
- <el-button type="primary" link icon="EditPen" v-auth="['system:menu:edit']" @click="openDialog(2, '菜单编辑', scope.row)"> 编辑 </el-button>
- <el-button type="primary" link icon="CirclePlus" v-auth="['system:menu:add']" @click="openDialog(1, '菜单新增')"> 新增 </el-button>
- <el-button type="primary" link icon="Delete" v-auth="['system:menu:remove']" @click="deleteMenu(scope.row)"> 删除 </el-button>
- </template>
- </ProTable>
- <FormDialog ref="formDialogRef" :items-options="itemsOptions" :model="model" />
- </div>
- </template>
- <script setup lang="tsx" name="MenuManage">
- import { useHandleData } from '@/hooks/useHandleData'
- import FormDialog from '@/components/FormDialog/index.vue'
- import { ProTableInstance, ColumnProps } from '@/components/ProTable/interface'
- import { handleTree } from '@/utils/common'
- import { listMenuApi, delMenuApi, addMenuApi, updateMenuApi, getMenuApi } from '@/api/modules/system/menu'
- const { proxy } = getCurrentInstance() as ComponentInternalInstance
- const { sys_normal_disable, sys_yes_no, sys_show_hide } = toRefs<any>(proxy?.useDict('sys_normal_disable', 'sys_yes_no', 'sys_show_hide'))
- // ProTable 实例
- const proTable = ref<ProTableInstance>()
- // 表单model
- const model = ref({})
- // 如果表格需要初始化请求参数,直接定义传给 ProTable (之后每次请求都会自动带上该参数,此参数更改之后也会一直带上,改变此参数会自动刷新表格数据)
- const initParam = reactive({})
- const menuOptions = ref<any[]>([])
- const menuTypeOptions = ref<any[]>([
- { value: 'M', label: '目录' },
- { value: 'C', label: '菜单' },
- { value: 'F', label: '按钮' }
- ])
- // dataCallback 是对于返回的表格数据做处理,如果你后台返回的数据不是 list && total && pageNum && pageSize 这些字段,可以在这里进行处理成这些字段
- const dataCallback = (res: any) => {
- const data = handleTree(res, 'menuId')
- menuOptions.value = []
- const menu: any = { menuId: 0, menuName: '主类目', children: [] }
- menu.children = data
- menuOptions.value.push(menu)
- setItemsOptions()
- return data
- }
- // 删除用户信息
- const deleteMenu = async (params: any) => {
- await useHandleData(delMenuApi, params.menuId, `删除【${params.menuName}】菜单`)
- proTable.value?.getTableList()
- }
- const formDialogRef = ref<InstanceType<typeof FormDialog> | null>(null)
- // 打开弹框的功能
- const openDialog = async (type: number, title: string, row?: any) => {
- let res = { data: {} }
- if (row?.menuId) {
- res = await getMenuApi(row?.menuId || null)
- }
- model.value = type == 1 ? {} : res.data
- const params = {
- title,
- width: 720,
- isEdit: type !== 3,
- api: type == 1 ? addMenuApi : updateMenuApi,
- getTableList: proTable.value?.getTableList
- }
- formDialogRef.value?.openDialog(params)
- }
- // 表格配置项
- const columns = reactive<ColumnProps<any>[]>([
- {
- prop: 'menuName',
- label: '菜单名称',
- align: 'left',
- search: {
- el: 'input'
- },
- width: 180
- },
- {
- prop: 'orderNum',
- label: '显示排序',
- search: {
- el: 'input'
- },
- width: 120
- },
- {
- prop: 'path',
- label: '路由地址',
- search: {
- el: 'input'
- },
- width: 120
- },
- {
- prop: 'status',
- label: '状态',
- tag: true,
- enum: sys_normal_disable,
- search: {
- el: 'tree-select'
- }
- },
- {
- prop: 'perms',
- label: '权限标识',
- search: {
- el: 'input'
- },
- width: 120
- },
- {
- prop: 'icon',
- label: '图标',
- search: {
- el: 'input'
- },
- width: 120
- },
- {
- prop: 'createTime',
- label: '创建时间',
- search: {
- el: 'date-picker',
- props: { type: 'datetimerange', valueFormat: 'YYYY-MM-DD HH:mm:ss' }
- },
- width: 120
- },
- { prop: 'operation', label: '操作', width: 230, fixed: 'right' }
- ])
- // 表单配置项
- let itemsOptions = ref<ProForm.ItemsOptions[]>([])
- const setItemsOptions = () => {
- itemsOptions.value = [
- {
- label: '菜单类型',
- prop: 'menuType',
- span: 12,
- rules: [{ required: true, message: '菜单类型不能为空', trigger: 'change' }],
- compOptions: {
- elTagName: 'radio-button',
- enum: menuTypeOptions.value
- }
- },
- {
- label: '菜单状态',
- prop: 'status',
- rules: [{ required: true, message: '菜单状态不能为空', trigger: 'change' }],
- span: 12,
- compOptions: {
- elTagName: 'radio-button',
- value: '0',
- enum: sys_normal_disable.value
- }
- },
- {
- label: '上级菜单',
- rules: [{ required: true, message: '上级菜单不能为空', trigger: 'change' }],
- prop: 'parentId',
- compOptions: {
- elTagName: 'tree-select',
- placeholder: '请选择上级菜单',
- props: { label: 'menuName', value: 'menuId' },
- enum: menuOptions.value,
- checkStrictly: true
- }
- },
- {
- label: '菜单名称',
- prop: 'menuName',
- span: 12,
- rules: [{ required: true, message: '菜单名称不能为空', trigger: 'blur' }],
- compOptions: {
- elTagName: 'input',
- placeholder: '请输入菜单名称'
- }
- },
- {
- label: '显示排序',
- prop: 'orderNum',
- span: 12,
- compOptions: {
- elTagName: 'input-number',
- min: 0,
- controlsPosition: 'right'
- }
- },
- {
- label: '图标',
- prop: 'icon',
- show: val => {
- return val?.menuType !== 'F'
- },
- compOptions: {
- elTagName: 'icon'
- }
- },
- {
- label: '是否外链',
- prop: 'isFrame',
- span: 12,
- show: val => {
- return val?.menuType !== 'F'
- },
- tooltip: '选择是外链则路由地址需要以`http(s)://`开头',
- compOptions: {
- elTagName: 'radio-button',
- enum: sys_yes_no.value,
- enumKey: 'sys_yes_no'
- }
- },
- {
- label: '显示状态',
- prop: 'visible',
- tooltip: '选择隐藏则路由将不会出现在侧边栏,但仍然可以访问',
- span: 12,
- show: val => {
- return val?.menuType !== 'F'
- },
- compOptions: {
- elTagName: 'radio-button',
- value: '0',
- enum: sys_show_hide.value
- }
- },
- {
- label: '路由地址',
- rules: [{ required: true, message: '路由地址不能为空', trigger: 'blur' }],
- prop: 'path',
- show: val => {
- return val?.menuType !== 'F'
- },
- tooltip: '访问的路由地址,如:`user`,如外网地址需内链访问则以`http(s)://`开头',
- compOptions: {
- elTagName: 'input',
- placeholder: '请输入路由地址'
- }
- },
- {
- label: '路由参数',
- prop: 'query',
- show: val => {
- return val?.menuType !== 'F'
- },
- tooltip: '访问路由的默认传递参数,如:`{"id": 1, "name": "eco"}`',
- compOptions: {
- elTagName: 'input',
- placeholder: '请输入路由地址'
- }
- },
- {
- label: '组件路径',
- rules: [{ required: true, message: '组件路径不能为空', trigger: 'blur' }],
- prop: 'component',
- tooltip: '访问的组件路径,如:`system/user/index`,默认在`views`目录下',
- span: 12,
- show: val => {
- return val?.menuType == 'C'
- },
- compOptions: {
- elTagName: 'input',
- placeholder: '请输入组件路径'
- }
- },
- {
- label: '路由名称',
- // rules: [{ required: true, message: '路由名称不能为空', trigger: 'blur' }],
- prop: 'componentName',
- tooltip: '路由名称,匹配路由内Name属性,如:UserManage',
- span: 12,
- show: val => {
- return val?.menuType == 'C'
- },
- compOptions: {
- elTagName: 'input',
- placeholder: '请输入路由名称'
- }
- },
- {
- label: '权限标识',
- prop: 'perms',
- tooltip: '控制器中定义的权限字符,如:system:user:list',
- span: 12,
- show: val => {
- return val?.menuType !== 'M'
- },
- compOptions: {
- elTagName: 'input',
- placeholder: '请输入权限标识'
- }
- },
- {
- label: '是否缓存',
- prop: 'isCache',
- span: 12,
- show: val => {
- return val?.menuType == 'C'
- },
- compOptions: {
- elTagName: 'radio-button',
- enum: sys_show_hide.value,
- enumKey: 'sys_yes_no'
- }
- }
- ]
- }
- </script>
|