菜单
This commit is contained in:
parent
b2b8ddf114
commit
d5b0cb36b2
@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<el-sub-menu :index="parent.key">
|
<el-sub-menu :index="parent.key">
|
||||||
<template #title>
|
<template #title>
|
||||||
<el-icon v-if="parent.icon"><component :is="parent.icon" /></el-icon>
|
<icon :name="parent.icon" :size="20" v-if="parent.icon"/>
|
||||||
<span>{{ parent.title }}</span>
|
<span>{{ parent.title }}</span>
|
||||||
</template>
|
</template>
|
||||||
<template v-for="(item, key) in parent.children" :key="item.key">
|
<template v-for="(item, key) in parent.children" :key="item.key">
|
||||||
@ -16,6 +16,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
|
import icon from "@/components/icon/index.vue";
|
||||||
export default {
|
export default {
|
||||||
name: 'ReSubMenu',
|
name: 'ReSubMenu',
|
||||||
};
|
};
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
<template v-for="item in menus" :key="item.key">
|
<template v-for="item in menus" :key="item.key">
|
||||||
<el-menu-item v-if="!item.children" :key="getMenuKey(item.key)" :index="item.key">
|
<el-menu-item v-if="!item.children" :key="getMenuKey(item.key)" :index="item.key">
|
||||||
<template #title>
|
<template #title>
|
||||||
<el-icon v-if="item.icon"><component :is="item.icon" /></el-icon>
|
<icon :name="item.icon" :size="20" v-if="item.icon"/>
|
||||||
<span>{{ item.title }}</span>
|
<span>{{ item.title }}</span>
|
||||||
</template>
|
</template>
|
||||||
</el-menu-item>
|
</el-menu-item>
|
||||||
@ -32,6 +32,7 @@
|
|||||||
import { useProjectSetting } from '@/hooks/setting/useProjectSetting';
|
import { useProjectSetting } from '@/hooks/setting/useProjectSetting';
|
||||||
import { useAsyncRouteStore } from '@/store/modules/asyncRoute';
|
import { useAsyncRouteStore } from '@/store/modules/asyncRoute';
|
||||||
import { useProjectSettingStore } from '@/store/modules/projectSetting';
|
import { useProjectSettingStore } from '@/store/modules/projectSetting';
|
||||||
|
import icon from "@/components/icon/index.vue";
|
||||||
import ReSubMenu from './ReSubMenu.vue';
|
import ReSubMenu from './ReSubMenu.vue';
|
||||||
|
|
||||||
const collapsed = inject('collapsed');
|
const collapsed = inject('collapsed');
|
||||||
|
@ -22,23 +22,24 @@ export const routerGenerator = (routerMap, parent?): any[] => {
|
|||||||
return routerMap.map((item) => {
|
return routerMap.map((item) => {
|
||||||
item.meta = {
|
item.meta = {
|
||||||
title:item.name,
|
title:item.name,
|
||||||
icon:renderIcon(DashboardOutlined),
|
icon:item.icon,
|
||||||
sort:item.sort,
|
sort:item.sort,
|
||||||
permissions:item.permission
|
permissions:item.permission
|
||||||
}
|
}
|
||||||
const components =''
|
const components =''
|
||||||
|
const names = /http(s)?:/.test(item.path)?item.path:item.path.replaceAll('/','')
|
||||||
const currentRouter: any = {
|
const currentRouter: any = {
|
||||||
// 路由地址 动态拼接生成如 /dashboard/workplace
|
// 路由地址 动态拼接生成如 /dashboard/workplace
|
||||||
path: `${item.path}`,
|
path: `${item.path}`,
|
||||||
// 路由名称,建议唯一
|
// 路由名称,建议唯一
|
||||||
name: item.name || '',
|
name: names,
|
||||||
// 该路由对应页面的 组件
|
// 该路由对应页面的 组件
|
||||||
component: item.component,
|
component: item.component,
|
||||||
// meta: 页面标题, 菜单图标, 页面权限(供指令权限用,可去掉)
|
// meta: 页面标题, 菜单图标, 页面权限(供指令权限用,可去掉)
|
||||||
meta: {
|
meta: {
|
||||||
...item.meta,
|
...item.meta,
|
||||||
label: item.meta.title,
|
label: item.meta.title,
|
||||||
icon: renderIcon(DashboardOutlined) || null,
|
icon: item.meta.icon || null,
|
||||||
permissions: item.meta.permissions || null,
|
permissions: item.meta.permissions || null,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
<el-dialog
|
<el-dialog
|
||||||
v-model="props.visible"
|
v-model="props.visible"
|
||||||
:title="props.menuId?'编辑':'新增'"
|
:title="props.menuId?'编辑':'新增'"
|
||||||
:append-to-body="true"
|
|
||||||
width="600"
|
width="600"
|
||||||
:close-on-click-modal="false"
|
:close-on-click-modal="false"
|
||||||
:before-close="dialogClose"
|
:before-close="dialogClose"
|
||||||
@ -20,12 +19,12 @@
|
|||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item
|
<el-form-item
|
||||||
label="父级菜单"
|
label="父级菜单"
|
||||||
prop="pid"
|
prop="parentId"
|
||||||
:rules="{ required: true, message: '请选择父级菜单', trigger: 'change' }"
|
:rules="{ required: true, message: '请选择父级菜单', trigger: 'change' }"
|
||||||
>
|
>
|
||||||
<el-tree-select
|
<el-tree-select
|
||||||
class="flex-1"
|
class="flex-1"
|
||||||
v-model="formData.pid"
|
v-model="formData.parentId"
|
||||||
:data="menuOptions"
|
:data="menuOptions"
|
||||||
clearable
|
clearable
|
||||||
node-key="id"
|
node-key="id"
|
||||||
@ -39,11 +38,11 @@
|
|||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item
|
<el-form-item
|
||||||
label="菜单名称"
|
label="菜单名称"
|
||||||
prop="menuName"
|
prop="name"
|
||||||
:rules="{ required: true, message: '请输入菜单名称', trigger: 'blur' }"
|
:rules="{ required: true, message: '请输入菜单名称', trigger: 'blur' }"
|
||||||
>
|
>
|
||||||
<el-input
|
<el-input
|
||||||
v-model="formData.menuName"
|
v-model="formData.name"
|
||||||
placeholder="请输入菜单名称"
|
placeholder="请输入菜单名称"
|
||||||
clearable
|
clearable
|
||||||
/>
|
/>
|
||||||
@ -55,16 +54,30 @@
|
|||||||
>
|
>
|
||||||
<IconPicker class="flex-1" v-model="formData.icon"/>
|
<IconPicker class="flex-1" v-model="formData.icon"/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
<el-form-item
|
||||||
|
label="是否外链"
|
||||||
|
prop="target"
|
||||||
|
required
|
||||||
|
>
|
||||||
|
<div>
|
||||||
|
<el-radio-group v-model="formData.target">
|
||||||
|
<el-radio :label="1">是</el-radio>
|
||||||
|
<el-radio :label="0">否</el-radio>
|
||||||
|
</el-radio-group>
|
||||||
|
<div class="form-tips">
|
||||||
|
选择外链打开,刚新窗口打开页面
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</el-form-item>
|
||||||
<el-form-item
|
<el-form-item
|
||||||
v-if="formData.type==0"
|
v-if="formData.type==0"
|
||||||
label="路由路径"
|
label="路由路径"
|
||||||
prop="paths"
|
prop="path"
|
||||||
:rules="{ required: true, message: '请输入路由路径', trigger: 'blur' }"
|
:rules="{ required: true, message: '请输入路由路径', trigger: 'blur' }"
|
||||||
>
|
>
|
||||||
<div class="flex-1">
|
<div class="flex-1">
|
||||||
<el-input
|
<el-input
|
||||||
v-model="formData.paths"
|
v-model="formData.path"
|
||||||
placeholder="请输入路由路径"
|
placeholder="请输入路由路径"
|
||||||
clearable
|
clearable
|
||||||
/>
|
/>
|
||||||
@ -74,7 +87,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item
|
<el-form-item
|
||||||
v-if="formData.type == 0"
|
v-if="formData.type == 0 && formData.target ==0"
|
||||||
label="组件路径"
|
label="组件路径"
|
||||||
prop="component"
|
prop="component"
|
||||||
:rules="{ required: true, message: '请输入组件路径', trigger: 'blur' }"
|
:rules="{ required: true, message: '请输入组件路径', trigger: 'blur' }"
|
||||||
@ -93,28 +106,13 @@
|
|||||||
</div>
|
</div>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item
|
<el-form-item
|
||||||
label="选中菜单"
|
v-if="formData.target ==0"
|
||||||
prop="selected"
|
|
||||||
v-if="formData.type== 0"
|
|
||||||
>
|
|
||||||
<div class="flex-1">
|
|
||||||
<el-input
|
|
||||||
v-model="formData.selected"
|
|
||||||
placeholder="请输入路由路径"
|
|
||||||
clearable
|
|
||||||
/>
|
|
||||||
<div class="form-tips">
|
|
||||||
访问详情页面,编辑页面时,菜单高亮显示,如`/consumer/lists`
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item
|
|
||||||
label="权限字符"
|
label="权限字符"
|
||||||
prop="perms"
|
prop="permission"
|
||||||
>
|
>
|
||||||
<div class="flex-1">
|
<div class="flex-1">
|
||||||
<el-input
|
<el-input
|
||||||
v-model="formData.perms"
|
v-model="formData.permission"
|
||||||
placeholder="请输入权限字符"
|
placeholder="请输入权限字符"
|
||||||
clearable
|
clearable
|
||||||
/>
|
/>
|
||||||
@ -123,35 +121,16 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item
|
|
||||||
v-if="formData.type == 0"
|
|
||||||
label="路由参数"
|
|
||||||
prop="params"
|
|
||||||
>
|
|
||||||
<div>
|
|
||||||
<div class="flex-1">
|
|
||||||
<el-input
|
|
||||||
v-model="formData.params"
|
|
||||||
placeholder="请输入路由参数"
|
|
||||||
clearable
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div class="form-tips">
|
|
||||||
访问路由的默认传递参数,如:`{"menuId": 1, "name":
|
|
||||||
"admin"}`或`menuId=1&name=admin`
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item
|
<el-form-item
|
||||||
v-if="formData.type ==0"
|
v-if="formData.type ==0"
|
||||||
label="是否显示"
|
label="是否显示"
|
||||||
prop="isShow"
|
prop="hide"
|
||||||
required
|
required
|
||||||
>
|
>
|
||||||
<div>
|
<div>
|
||||||
<el-radio-group v-model="formData.isShow">
|
<el-radio-group v-model="formData.hide">
|
||||||
<el-radio :label="1">显示</el-radio>
|
<el-radio :label="0">显示</el-radio>
|
||||||
<el-radio :label="0">隐藏</el-radio>
|
<el-radio :label="1">隐藏</el-radio>
|
||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
<div class="form-tips">
|
<div class="form-tips">
|
||||||
选择隐藏则路由将不会出现在侧边栏,但仍然可以访问
|
选择隐藏则路由将不会出现在侧边栏,但仍然可以访问
|
||||||
@ -161,11 +140,11 @@
|
|||||||
<el-form-item
|
<el-form-item
|
||||||
v-if="formData.type ==0"
|
v-if="formData.type ==0"
|
||||||
label="菜单状态"
|
label="菜单状态"
|
||||||
prop="isDisable"
|
prop="hide"
|
||||||
required
|
required
|
||||||
>
|
>
|
||||||
<div>
|
<div>
|
||||||
<el-radio-group v-model="formData.isDisable">
|
<el-radio-group v-model="formData.hide">
|
||||||
<el-radio :label="0">正常</el-radio>
|
<el-radio :label="0">正常</el-radio>
|
||||||
<el-radio :label="1">停用</el-radio>
|
<el-radio :label="1">停用</el-radio>
|
||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
@ -174,9 +153,9 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="菜单排序" prop="menuSort">
|
<el-form-item label="菜单排序" prop="sort">
|
||||||
<div>
|
<div>
|
||||||
<el-input-number v-model="formData.menuSort" :max="9999"/>
|
<el-input-number v-model="formData.sort" :max="9999"/>
|
||||||
<div class="form-tips">数值越小越排前</div>
|
<div class="form-tips">数值越小越排前</div>
|
||||||
</div>
|
</div>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
@ -193,7 +172,7 @@
|
|||||||
</template>
|
</template>
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import type {FormInstance} from "element-plus";
|
import type {FormInstance} from "element-plus";
|
||||||
import { menuAdd,menuUpdate,getMenuList } from '@/api/system/menu';
|
import { menuAdd,menuUpdate,getMenuList,getMenuDetail } from '@/api/system/menu';
|
||||||
import {onMounted, reactive, readonly, ref, shallowRef} from "vue";
|
import {onMounted, reactive, readonly, ref, shallowRef} from "vue";
|
||||||
import {getModulesKey} from "@/router";
|
import {getModulesKey} from "@/router";
|
||||||
import {arrayToTree, treeToArray,message,buildTree} from "@/utils/auth";
|
import {arrayToTree, treeToArray,message,buildTree} from "@/utils/auth";
|
||||||
@ -231,31 +210,25 @@ const querySearch = (queryString: string, cb: any) => {
|
|||||||
const formData = reactive({
|
const formData = reactive({
|
||||||
menuId: "",
|
menuId: "",
|
||||||
//父级id
|
//父级id
|
||||||
pid: 0,
|
parentId: 0,
|
||||||
//类型
|
//类型
|
||||||
type: 0,
|
type: 0,
|
||||||
//图标
|
//图标
|
||||||
menuIcon: "",
|
icon: "",
|
||||||
//名称
|
//名称
|
||||||
menuName: "",
|
name: "",
|
||||||
//排序号
|
//排序号
|
||||||
menuSort: 0,
|
sort: 0,
|
||||||
// 路由路径
|
// 路由路径
|
||||||
paths: "",
|
path: "",
|
||||||
//权限链接
|
//权限链接
|
||||||
perms: "",
|
permission: "",
|
||||||
//前端组件
|
//前端组件
|
||||||
component: "",
|
component: "",
|
||||||
//选中路径
|
//是否显示 0=显示, 1=不显示
|
||||||
selected: "",
|
hide: 0,
|
||||||
//路由参数
|
target:0,
|
||||||
params: "",
|
status:0
|
||||||
//是否缓存 0=否, 1=是
|
|
||||||
isCache: 0,
|
|
||||||
//是否显示 0=否, 1=是
|
|
||||||
isShow: 1,
|
|
||||||
//是否禁用 0=否, 1=是
|
|
||||||
isDisable: 0
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const dialogClose = () => {
|
const dialogClose = () => {
|
||||||
@ -295,7 +268,7 @@ const setFormData = (data: Record<any, any>) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const getDetail = async () => {
|
const getDetail = async () => {
|
||||||
const data = await api.menuDetail(
|
const data = await getMenuDetail(
|
||||||
props.menuId
|
props.menuId
|
||||||
);
|
);
|
||||||
setFormData(data);
|
setFormData(data);
|
||||||
@ -312,7 +285,7 @@ onMounted(() => {
|
|||||||
if (props.menuId) {
|
if (props.menuId) {
|
||||||
getDetail()
|
getDetail()
|
||||||
}else{
|
}else{
|
||||||
formData.pid=props.pid
|
formData.parentId=props.parentId
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
@ -25,7 +25,7 @@
|
|||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column align="center" label="图标" prop="icon" min-width="80">
|
<el-table-column align="center" label="图标" prop="icon" min-width="80">
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
<icon :name="row.icon" :size="20"/>
|
<icon :name="row.icon" :size="20" v-if="row.icon"/>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column align="center" label="权限标识" prop="permission" min-width="150" show-overflow-tooltip/>
|
<el-table-column align="center" label="权限标识" prop="permission" min-width="150" show-overflow-tooltip/>
|
||||||
@ -69,7 +69,7 @@
|
|||||||
import {defineAsyncComponent, nextTick, onMounted, readonly, ref, shallowRef,onActivated} from "vue";
|
import {defineAsyncComponent, nextTick, onMounted, readonly, ref, shallowRef,onActivated} from "vue";
|
||||||
import {getMenuList,menuDelete} from "@/api/system/menu";
|
import {getMenuList,menuDelete} from "@/api/system/menu";
|
||||||
import type {ElTable} from "element-plus";
|
import type {ElTable} from "element-plus";
|
||||||
|
import icon from "@/components/icon/index.vue";
|
||||||
const tableRef = shallowRef<InstanceType<typeof ElTable>>();
|
const tableRef = shallowRef<InstanceType<typeof ElTable>>();
|
||||||
import {confirm, message,buildTree} from "@/utils/auth";
|
import {confirm, message,buildTree} from "@/utils/auth";
|
||||||
|
|
||||||
@ -103,7 +103,7 @@ const handleAdd = async (parentId:any) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const handleEdit = async (data: any) => {
|
const handleEdit = async (data: any) => {
|
||||||
menuId.value=data.menuId
|
menuId.value=data.id
|
||||||
await nextTick();
|
await nextTick();
|
||||||
editVisible.value=true
|
editVisible.value=true
|
||||||
};
|
};
|
||||||
|
@ -218,7 +218,6 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
function checkedAllHandle() {
|
function checkedAllHandle() {
|
||||||
console.log(treeRef.value);
|
|
||||||
if (!checkedAll.value) {
|
if (!checkedAll.value) {
|
||||||
checkedKeys.value = getTreeAll(treeData.value);
|
checkedKeys.value = getTreeAll(treeData.value);
|
||||||
treeRef.value!.setCheckedKeys(getTreeAll(treeData.value));
|
treeRef.value!.setCheckedKeys(getTreeAll(treeData.value));
|
||||||
@ -238,7 +237,6 @@
|
|||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
const treeMenuList = await getMenuList();
|
const treeMenuList = await getMenuList();
|
||||||
console.log(treeMenuList)
|
|
||||||
treeMenuList.forEach((item) => {
|
treeMenuList.forEach((item) => {
|
||||||
item.expanded = false;
|
item.expanded = false;
|
||||||
});
|
});
|
||||||
|
@ -53,7 +53,7 @@ export const columns = [
|
|||||||
ElTag,
|
ElTag,
|
||||||
{},
|
{},
|
||||||
{
|
{
|
||||||
default: () => record.row.roles[0].name,
|
default: () => record.row.roles.length>0?record.row.roles[0].name:'',
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
Loading…
Reference in New Issue
Block a user