|
@@ -1,32 +1,40 @@
|
|
|
<template>
|
|
|
<div class="system-menu-container layout-padding">
|
|
|
<div class="layout-padding-auto layout-padding-view pd20">
|
|
|
- <el-row class="mb20" :gutter="10">
|
|
|
- <el-col :xs="24" :sm="12" :md="18" :lg="18" :xl="18">
|
|
|
- <el-form :model="state.queryParams" ref="ruleFormRef" :inline="true" @submit.native.prevent>
|
|
|
- <el-form-item label="关键字" prop="keyword" class="mb0">
|
|
|
- <el-input v-model="state.queryParams.keyword" placeholder="菜单名称/权限编码" clearable @keyup.enter="handleQuery" style="width: 250px" />
|
|
|
- </el-form-item>
|
|
|
- <el-form-item class="mb0">
|
|
|
- <el-button type="primary" @click="handleQuery" :loading="state.loading" v-waves>
|
|
|
- <SvgIcon name="ele-Search" class="mr5" />查询
|
|
|
- </el-button>
|
|
|
- <el-button @click="resetQuery(ruleFormRef)" v-waves class="default-button" :loading="state.loading"> <SvgIcon name="ele-Refresh" class="mr5" />重置 </el-button>
|
|
|
- </el-form-item>
|
|
|
- </el-form>
|
|
|
- </el-col>
|
|
|
- <el-col :xs="24" :sm="12" :md="6" :lg="6" :xl="6" style="text-align: right">
|
|
|
- <el-button type="primary" @click="expand">
|
|
|
- <SvgIcon
|
|
|
- name="ele-ArrowDownBold"
|
|
|
- style="transition: transform var(--el-transition-duration)"
|
|
|
- :style="state.isExpand ? 'transform: none' : 'transform: rotateZ(180deg)'"
|
|
|
- class="mr5"
|
|
|
- />{{ state.isExpand ? '收起' : '展开' }}</el-button
|
|
|
- >
|
|
|
- <el-button type="primary" @click="onOpenAddMenu" v-auth="'system:menu:add'"> <SvgIcon name="ele-Plus" class="mr5" /> 新增菜单 </el-button>
|
|
|
- </el-col>
|
|
|
- </el-row>
|
|
|
+ <el-row class="mb20" :gutter="10">
|
|
|
+ <el-col :xs="24" :sm="12" :md="18" :lg="18" :xl="18">
|
|
|
+ <el-form :model="state.queryParams" ref="ruleFormRef" :inline="true" @submit.native.prevent>
|
|
|
+ <el-form-item label="关键字" prop="keyword" class="mb0">
|
|
|
+ <el-input
|
|
|
+ v-model="state.queryParams.keyword"
|
|
|
+ placeholder="菜单名称/权限编码"
|
|
|
+ clearable
|
|
|
+ @keyup.enter="handleQuery"
|
|
|
+ style="width: 250px"
|
|
|
+ />
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item class="mb0">
|
|
|
+ <el-button type="primary" @click="handleQuery" :loading="state.loading" v-waves>
|
|
|
+ <SvgIcon name="ele-Search" class="mr5" />查询
|
|
|
+ </el-button>
|
|
|
+ <el-button @click="resetQuery(ruleFormRef)" v-waves class="default-button" :loading="state.loading">
|
|
|
+ <SvgIcon name="ele-Refresh" class="mr5" />重置
|
|
|
+ </el-button>
|
|
|
+ </el-form-item>
|
|
|
+ </el-form>
|
|
|
+ </el-col>
|
|
|
+ <el-col :xs="24" :sm="12" :md="6" :lg="6" :xl="6" style="text-align: right">
|
|
|
+ <el-button type="primary" @click="expand">
|
|
|
+ <SvgIcon
|
|
|
+ name="ele-ArrowDownBold"
|
|
|
+ style="transition: transform var(--el-transition-duration)"
|
|
|
+ :style="state.isExpand ? 'transform: none' : 'transform: rotateZ(180deg)'"
|
|
|
+ class="mr5"
|
|
|
+ />{{ state.isExpand ? '收起' : '展开' }}</el-button
|
|
|
+ >
|
|
|
+ <el-button type="primary" @click="onOpenAddMenu" v-auth="'system:menu:add'"> <SvgIcon name="ele-Plus" class="mr5" /> 新增菜单 </el-button>
|
|
|
+ </el-col>
|
|
|
+ </el-row>
|
|
|
<!-- 表格 -->
|
|
|
<el-auto-resizer class="table" v-loading="state.loading">
|
|
|
<template #default="{ height, width }">
|
|
@@ -46,34 +54,34 @@
|
|
|
</template>
|
|
|
</el-auto-resizer>
|
|
|
</div>
|
|
|
- <menu-add ref="menuAddRef" @updateList="quertyList" :menuData="getMenuDataWithOutBtn(state.menuTableData)"/>
|
|
|
- <menu-edit ref="menuEditRef" @updateList="quertyList" :menuData="getMenuDataWithOutBtn(state.menuTableData)"/>
|
|
|
+ <menu-add ref="menuAddRef" @updateList="quertyList" :menuData="getMenuDataWithOutBtn(state.menuTableData)" />
|
|
|
+ <menu-edit ref="menuEditRef" @updateList="quertyList" :menuData="getMenuDataWithOutBtn(state.menuTableData)" />
|
|
|
</div>
|
|
|
</template>
|
|
|
|
|
|
-<script setup lang="ts" name="systemMenu">
|
|
|
-import {defineAsyncComponent, h, onMounted, reactive, ref, watch} from 'vue';
|
|
|
-import {RouteRecordRaw} from 'vue-router';
|
|
|
-import type {FormInstance} from 'element-plus';
|
|
|
-import {ElButton, ElMessage, ElMessageBox, ElTag} from 'element-plus';
|
|
|
-import {getMenuList, removeMenu} from '/@/api/system/menu';
|
|
|
-import {auth} from '/@/utils/authFunction';
|
|
|
+<script lang="tsx" setup name="systemMenu">
|
|
|
+import { defineAsyncComponent, onMounted, reactive, ref, watch } from 'vue';
|
|
|
+import { RouteRecordRaw } from 'vue-router';
|
|
|
+import type { FormInstance } from 'element-plus';
|
|
|
+import { ElMessage, ElMessageBox } from 'element-plus';
|
|
|
+import { getMenuList, removeMenu } from '/@/api/system/menu';
|
|
|
+import { auth } from '/@/utils/authFunction';
|
|
|
import MenuSvgIcon from '/@/views/system/menu/component/Menu-svgIcon.vue';
|
|
|
-import {throttle} from '/@/utils/tools';
|
|
|
+import { throttle } from '/@/utils/tools';
|
|
|
import other from '/@/utils/other';
|
|
|
// 引入组件
|
|
|
-const MenuAdd = defineAsyncComponent(() => import('/@/views/system/menu/component/Menu-add.vue')); // 新增菜单组件
|
|
|
-const MenuEdit = defineAsyncComponent(() => import('/@/views/system/menu/component/Menu-edit.vue')); // 编辑菜单组件
|
|
|
+const MenuAdd = defineAsyncComponent(() => import('/@/views/system/menu/component/Menu-add.vue')); // 新增菜单组件
|
|
|
+const MenuEdit = defineAsyncComponent(() => import('/@/views/system/menu/component/Menu-edit.vue')); // 编辑菜单组件
|
|
|
|
|
|
// 定义变量内容
|
|
|
const state = reactive({
|
|
|
- menuTableData: <EmptyArrayType>[], // 获取所有菜单
|
|
|
- staticArr: <EmptyArrayType>[], // 静态路由
|
|
|
+ menuTableData: [], // 获取所有菜单
|
|
|
+ staticArr: [], // 静态路由
|
|
|
loading: false, // 加载状态
|
|
|
queryParams: {
|
|
|
- keyword: null, // 关键字
|
|
|
+ keyword: null, // 关键字
|
|
|
},
|
|
|
- expandedRowKeys: <EmptyArrayType>[], // 展开的行
|
|
|
+ expandedRowKeys: [], // 展开的行
|
|
|
columns: [
|
|
|
{
|
|
|
key: 'pageName',
|
|
@@ -81,18 +89,12 @@ const state = reactive({
|
|
|
title: '菜单名称',
|
|
|
width: 300,
|
|
|
cellRenderer: (data: any) => {
|
|
|
-
|
|
|
- return
|
|
|
- /* (
|
|
|
- <p style="display: flex;align-items: center;">
|
|
|
- <MenuSvgIcon name={data.rowData.icon} />
|
|
|
- <span class="pl5">{data.rowData.pageName}</span>
|
|
|
- <p/>
|
|
|
- )*/
|
|
|
-/* return h('p', { style: { display:'flex',alignItems:'center' } }, [
|
|
|
- h(MenuSvgIcon, { name: data.rowData.icon }, ''),
|
|
|
- h('span', { class: 'pl5' }, { default: () => data.rowData.pageName }),
|
|
|
- ]);*/
|
|
|
+ return (
|
|
|
+ <p style="dispaly:flex;align-items:center">
|
|
|
+ <MenuSvgIcon name={data.rowData.icon} />
|
|
|
+ <span className="pl5">{data.rowData.pageName}</span>
|
|
|
+ </p>
|
|
|
+ );
|
|
|
},
|
|
|
},
|
|
|
{
|
|
@@ -103,13 +105,13 @@ const state = reactive({
|
|
|
cellRenderer: ({ rowData }: any) => {
|
|
|
switch (rowData.menuType) {
|
|
|
case 1:
|
|
|
- return h(ElTag, { type: 'success' }, { default: () => '目录' });
|
|
|
+ return <el-tag type="success">目录</el-tag>;
|
|
|
case 2:
|
|
|
- return h(ElTag, { type: 'success' }, { default: () => '菜单' });
|
|
|
+ return <el-tag type="warning">菜单</el-tag>;
|
|
|
case 3:
|
|
|
- return h(ElTag, { type: 'info' }, { default: () => '按钮' });
|
|
|
+ return <el-tag type="info">按钮</el-tag>;
|
|
|
default:
|
|
|
- return h(ElTag, { type: 'success' }, { default: () => '按钮' });
|
|
|
+ return <el-tag type="info">按钮</el-tag>;
|
|
|
}
|
|
|
},
|
|
|
},
|
|
@@ -144,7 +146,7 @@ const state = reactive({
|
|
|
width: 100,
|
|
|
cellRenderer: ({ rowData }) => {
|
|
|
if ([1, 2].includes(rowData.menuType)) {
|
|
|
- return h(ElTag, { type: rowData.isFast ? 'success' : 'info' }, { default: () => (rowData.isFast ? '是' : '否') });
|
|
|
+ return <el-tag type={rowData.isFast ? 'success' : 'info'}>{rowData.isFast ? '是' : '否'}</el-tag>;
|
|
|
}
|
|
|
},
|
|
|
},
|
|
@@ -155,7 +157,7 @@ const state = reactive({
|
|
|
width: 100,
|
|
|
cellRenderer: ({ rowData }) => {
|
|
|
if ([1, 2].includes(rowData.menuType)) {
|
|
|
- return h(ElTag, { type: rowData.isHide ? 'success' : 'info' }, { default: () => (rowData.isHide ? '是' : '否') });
|
|
|
+ return <el-tag type={rowData.isHide ? 'success' : 'info'}>{rowData.isHide ? '是' : '否'}</el-tag>;
|
|
|
}
|
|
|
},
|
|
|
},
|
|
@@ -166,7 +168,7 @@ const state = reactive({
|
|
|
width: 100,
|
|
|
cellRenderer: ({ rowData }) => {
|
|
|
if ([1, 2].includes(rowData.menuType)) {
|
|
|
- return h(ElTag, { type: rowData.isKeepAlive ? 'success' : 'info' }, { default: () => (rowData.isKeepAlive ? '是' : '否') });
|
|
|
+ return <el-tag type={rowData.isKeepAlive ? 'success' : 'info'}>{rowData.isKeepAlive ? '是' : '否'}</el-tag>;
|
|
|
}
|
|
|
},
|
|
|
},
|
|
@@ -177,7 +179,7 @@ const state = reactive({
|
|
|
width: 100,
|
|
|
cellRenderer: ({ rowData }) => {
|
|
|
if ([1, 2].includes(rowData.menuType)) {
|
|
|
- return h(ElTag, { type: rowData.isAffix ? 'success' : 'info' }, { default: () => (rowData.isAffix ? '是' : '否') });
|
|
|
+ return <el-tag type={rowData.isAffix ? 'success' : 'info'}>{rowData.isAffix ? '是' : '否'}</el-tag>;
|
|
|
}
|
|
|
},
|
|
|
},
|
|
@@ -188,7 +190,7 @@ const state = reactive({
|
|
|
width: 100,
|
|
|
cellRenderer: ({ rowData }) => {
|
|
|
if ([1, 2].includes(rowData.menuType)) {
|
|
|
- return h(ElTag, { type: rowData.isLink ? 'success' : 'info' }, { default: () => (rowData.isLink ? '是' : '否') });
|
|
|
+ return <el-tag type={rowData.isLink ? 'success' : 'info'}>{rowData.isLink ? '是' : '否'}</el-tag>;
|
|
|
}
|
|
|
},
|
|
|
},
|
|
@@ -200,34 +202,28 @@ const state = reactive({
|
|
|
align: 'center',
|
|
|
cellRenderer: (data: any) => {
|
|
|
// 权限判断
|
|
|
- return h('span', { class: 'flex' }, [
|
|
|
- auth('system:menu:edit')
|
|
|
- ? h(
|
|
|
- ElButton,
|
|
|
- {
|
|
|
- onClick: () => onOpenEditMenu(data.rowData),
|
|
|
- type: 'primary',
|
|
|
- link: true,
|
|
|
- title: '修改菜单',
|
|
|
- },
|
|
|
- { default: () => '修改' })
|
|
|
- : '',
|
|
|
- auth('system:menu:delete')
|
|
|
- ? h(
|
|
|
- ElButton,
|
|
|
- {
|
|
|
- onClick: () => onTableRowDel(data.rowData),
|
|
|
- type: 'danger',
|
|
|
- link: true,
|
|
|
- title: '删除菜单',
|
|
|
- },
|
|
|
- { default: () => '删除' })
|
|
|
- : '',
|
|
|
- ]);
|
|
|
+ return (
|
|
|
+ <span class="flex">
|
|
|
+ {auth('system:menu:edit') ? (
|
|
|
+ <el-button onClick={() => onOpenEditMenu(data.rowData)} type="primary" link title="修改菜单">
|
|
|
+ 修改
|
|
|
+ </el-button>
|
|
|
+ ) : (
|
|
|
+ ''
|
|
|
+ )}
|
|
|
+ {auth('system:menu:delete') ? (
|
|
|
+ <el-button onClick={() => onTableRowDel(data.rowData)} type="danger" link title="删除菜单">
|
|
|
+ 删除
|
|
|
+ </el-button>
|
|
|
+ ) : (
|
|
|
+ ''
|
|
|
+ )}
|
|
|
+ </span>
|
|
|
+ );
|
|
|
},
|
|
|
},
|
|
|
],
|
|
|
- isExpand: false, // 是否展开
|
|
|
+ isExpand: false, // 是否展开
|
|
|
});
|
|
|
const ruleFormRef = ref<RefType>(); // 表单ref
|
|
|
const formatTable = (list: any[], keyword: string) => {
|
|
@@ -267,7 +263,7 @@ const handleQuery = throttle(() => {
|
|
|
emptyArr = [];
|
|
|
state.menuTableData = formatTable(other.deepClone(state.staticArr), state.queryParams.keyword);
|
|
|
state.expandedRowKeys = getExpand(state.menuTableData);
|
|
|
- state.isExpand = true;
|
|
|
+ state.isExpand = true;
|
|
|
state.loading = false;
|
|
|
} else {
|
|
|
quertyList();
|
|
@@ -280,10 +276,10 @@ const resetQuery = (formEl: FormInstance | undefined) => {
|
|
|
quertyList();
|
|
|
state.expandedRowKeys = [];
|
|
|
emptyArr = [];
|
|
|
- state.isExpand = false;
|
|
|
+ state.isExpand = false;
|
|
|
};
|
|
|
// 打开新增菜单弹窗
|
|
|
-const menuAddRef = ref<RefType>(); // 新增菜单弹窗
|
|
|
+const menuAddRef = ref<RefType>(); // 新增菜单弹窗
|
|
|
const onOpenAddMenu = () => {
|
|
|
menuAddRef.value.openDialog();
|
|
|
};
|
|
@@ -346,16 +342,16 @@ const quertyList = () => {
|
|
|
};
|
|
|
// 格式化菜单数据并排除按钮
|
|
|
const getMenuDataWithOutBtn = (routes: any) => {
|
|
|
- if (!routes) return [];
|
|
|
- return routes.map((route: any) => {
|
|
|
- const { pageName: title, children, ...rest } = route;
|
|
|
- let filteredChildren = children ? children.filter((child: any) => child.menuType !== 3) : [];
|
|
|
- return {
|
|
|
- ...rest,
|
|
|
- title,
|
|
|
- children: getMenuDataWithOutBtn(filteredChildren),
|
|
|
- };
|
|
|
- });
|
|
|
+ if (!routes) return [];
|
|
|
+ return routes.map((route: any) => {
|
|
|
+ const { pageName: title, children, ...rest } = route;
|
|
|
+ let filteredChildren = children ? children.filter((child: any) => child.menuType !== 3) : [];
|
|
|
+ return {
|
|
|
+ ...rest,
|
|
|
+ title,
|
|
|
+ children: getMenuDataWithOutBtn(filteredChildren),
|
|
|
+ };
|
|
|
+ });
|
|
|
};
|
|
|
|
|
|
// 页面加载时
|