🔱: [client] sync upgrade with 21 commits [trident-sync]

'admin-22.12.12:发布v2.4.21版本,具体更新内容查看CHANGELOG.md'
!42 修复 工作流无法添加新节点问题
Merge pull request !42 from beta/bugfix_workflow
修复 工作流无法添加新节点问题

1. 修复 工作流无法添加新节点问题
2. 修复 左侧导航无法隐藏问题
'admin-22.12.09:发布v2.4.2版本,具体更新内容查看CHANGELOG.md'
!41 修复get请求传递嵌套对象或数组时无法正常编码问题
Merge pull request !41 from 随心/master
!40 开启TagsView缓存后,刷新后所有的路由都变成组件缓存了
Merge pull request !40 from mrjimin/master
修复get请求传递嵌套对象或数组时无法正常编码问题
update src/layout/routerView/parent.vue.

Signed-off-by: mrjimin <z8888788@163.com>
update src/layout/routerView/parent.vue.
这里应该拿到的是已经设置开启组件缓存的路由,而不是全部,需要先判断item.meta.isKeepAlive

Signed-off-by: mrjimin <z8888788@163.com>
'admin-22.11.30:发布v2.4.1版本,具体更新内容查看CHANGELOG.md'
Merge branch 'master' of https://gitee.com/lyt-top/vue-next-admin
'admin-22.11.30:删除v2.4.0版本不需要的依赖'
update src/views/error/404.vue.

Signed-off-by: lyt-Top <1105290566@qq.com>
update src/components/table/index.vue.

Signed-off-by: lyt-Top <1105290566@qq.com>
'admin-22.11.30:修改v2.4.0文字说明'
'admin-22.11.30:修改v2.4.0文字说明'
'admin-22.11.29:发布v2.4.0版本,具体更新内容查看CHANGELOG.md'
'admin-22.11.19:修复v2.3.0版本动态路由事件调用关闭当前tagsview、普通路由刷新界面参数丢失问题'
'admin-22.11.18:优化v2.3.0版本tagsview风格5兼容火狐'
'admin-22.11.17:优化v2.3.0版本iframe右键菜单刷新问题'
...
This commit is contained in:
H0nGzA1
2023-02-13 00:17:30 +08:00
parent 8e5fba2532
commit 80323dd641
228 changed files with 35680 additions and 25 deletions

View File

@@ -0,0 +1,260 @@
<template>
<div class="system-menu-dialog-container">
<el-dialog :title="state.dialog.title" v-model="state.dialog.isShowDialog" width="769px">
<el-form ref="menuDialogFormRef" :model="state.ruleForm" size="default" label-width="80px">
<el-row :gutter="35">
<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mb20">
<el-form-item label="上级菜单">
<el-cascader
:options="state.menuData"
:props="{ checkStrictly: true, value: 'path', label: 'title' }"
placeholder="请选择上级菜单"
clearable
class="w100"
v-model="state.ruleForm.menuSuperior"
>
<template #default="{ node, data }">
<span>{{ data.title }}</span>
<span v-if="!node.isLeaf"> ({{ data.children.length }}) </span>
</template>
</el-cascader>
</el-form-item>
</el-col>
<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mb20">
<el-form-item label="菜单类型">
<el-radio-group v-model="state.ruleForm.menuType">
<el-radio label="menu">菜单</el-radio>
<el-radio label="btn">按钮</el-radio>
</el-radio-group>
</el-form-item>
</el-col>
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
<el-form-item label="菜单名称">
<el-input v-model="state.ruleForm.meta.title" placeholder="格式message.router.xxx" clearable></el-input>
</el-form-item>
</el-col>
<template v-if="state.ruleForm.menuType === 'menu'">
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
<el-form-item label="路由名称">
<el-input v-model="state.ruleForm.name" placeholder="路由中的 name 值" clearable></el-input>
</el-form-item>
</el-col>
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
<el-form-item label="路由路径">
<el-input v-model="state.ruleForm.path" placeholder="路由中的 path 值" clearable></el-input>
</el-form-item>
</el-col>
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
<el-form-item label="重定向">
<el-input v-model="state.ruleForm.redirect" placeholder="请输入路由重定向" clearable></el-input>
</el-form-item>
</el-col>
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
<el-form-item label="菜单图标">
<IconSelector placeholder="请输入菜单图标" v-model="state.ruleForm.meta.icon" />
</el-form-item>
</el-col>
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
<el-form-item label="组件路径">
<el-input v-model="state.ruleForm.component" placeholder="组件路径" clearable></el-input>
</el-form-item>
</el-col>
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
<el-form-item label="链接地址">
<el-input
v-model="state.ruleForm.meta.isLink"
placeholder="外链/内嵌时链接地址http:xxx.com"
clearable
:disabled="!state.ruleForm.isLink"
>
</el-input>
</el-form-item>
</el-col>
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
<el-form-item label="权限标识">
<el-select v-model="state.ruleForm.meta.roles" multiple placeholder="取角色管理" clearable class="w100">
<el-option label="admin" value="admin"></el-option>
<el-option label="common" value="common"></el-option>
</el-select>
</el-form-item>
</el-col>
</template>
<template v-if="state.ruleForm.menuType === 'btn'">
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
<el-form-item label="权限标识">
<el-input v-model="state.ruleForm.btnPower" placeholder="请输入权限标识" clearable></el-input>
</el-form-item>
</el-col>
</template>
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
<el-form-item label="菜单排序">
<el-input-number v-model="state.ruleForm.menuSort" controls-position="right" placeholder="请输入排序" class="w100" />
</el-form-item>
</el-col>
<template v-if="state.ruleForm.menuType === 'menu'">
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
<el-form-item label="是否隐藏">
<el-radio-group v-model="state.ruleForm.meta.isHide">
<el-radio :label="true">隐藏</el-radio>
<el-radio :label="false">不隐藏</el-radio>
</el-radio-group>
</el-form-item>
</el-col>
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
<el-form-item label="页面缓存">
<el-radio-group v-model="state.ruleForm.meta.isKeepAlive">
<el-radio :label="true">缓存</el-radio>
<el-radio :label="false">不缓存</el-radio>
</el-radio-group>
</el-form-item>
</el-col>
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
<el-form-item label="是否固定">
<el-radio-group v-model="state.ruleForm.meta.isAffix">
<el-radio :label="true">固定</el-radio>
<el-radio :label="false">不固定</el-radio>
</el-radio-group>
</el-form-item>
</el-col>
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
<el-form-item label="是否外链">
<el-radio-group v-model="state.ruleForm.isLink" :disabled="state.ruleForm.meta.isIframe">
<el-radio :label="true"></el-radio>
<el-radio :label="false"></el-radio>
</el-radio-group>
</el-form-item>
</el-col>
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
<el-form-item label="是否内嵌">
<el-radio-group v-model="state.ruleForm.meta.isIframe" @change="onSelectIframeChange">
<el-radio :label="true"></el-radio>
<el-radio :label="false"></el-radio>
</el-radio-group>
</el-form-item>
</el-col>
</template>
</el-row>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button @click="onCancel" size="default"> </el-button>
<el-button type="primary" @click="onSubmit" size="default">{{ state.dialog.submitTxt }}</el-button>
</span>
</template>
</el-dialog>
</div>
</template>
<script setup lang="ts" name="systemMenuDialog">
import { defineAsyncComponent, reactive, onMounted, ref } from 'vue';
import { storeToRefs } from 'pinia';
import { useRoutesList } from '/@/stores/routesList';
import { i18n } from '/@/i18n/index';
// import { setBackEndControlRefreshRoutes } from "/@/router/backEnd";
// 定义子组件向父组件传值/事件
const emit = defineEmits(['refresh']);
// 引入组件
const IconSelector = defineAsyncComponent(() => import('/@/components/iconSelector/index.vue'));
// 定义变量内容
const menuDialogFormRef = ref();
const stores = useRoutesList();
const { routesList } = storeToRefs(stores);
const state = reactive({
// 参数请参考 `/src/router/route.ts` 中的 `dynamicRoutes` 路由菜单格式
ruleForm: {
menuSuperior: [], // 上级菜单
menuType: 'menu', // 菜单类型
name: '', // 路由名称
component: '', // 组件路径
isLink: false, // 是否外链
menuSort: 0, // 菜单排序
path: '', // 路由路径
redirect: '', // 路由重定向,有子集 children 时
meta: {
title: '', // 菜单名称
icon: '', // 菜单图标
isHide: false, // 是否隐藏
isKeepAlive: true, // 是否缓存
isAffix: false, // 是否固定
isLink: '', // 外链/内嵌时链接地址http:xxx.com开启外链条件`1、isLink: 链接地址不为空`
isIframe: false, // 是否内嵌,开启条件,`1、isIframe:true 2、isLink链接地址不为空`
roles: '', // 权限标识,取角色管理
},
btnPower: '', // 菜单类型为按钮时,权限标识
},
menuData: [] as RouteItems, // 上级菜单数据
dialog: {
isShowDialog: false,
type: '',
title: '',
submitTxt: '',
},
});
// 获取 pinia 中的路由
const getMenuData = (routes: RouteItems) => {
const arr: RouteItems = [];
routes.map((val: RouteItem) => {
val['title'] = i18n.global.t(val.meta?.title as string);
arr.push({ ...val });
if (val.children) getMenuData(val.children);
});
return arr;
};
// 打开弹窗
const openDialog = (type: string, row?: any) => {
if (type === 'edit') {
// 模拟数据,实际请走接口
row.menuType = 'menu';
row.menuSort = Math.random();
row.component = `${row.component} `
.match(/\'(.+)\'/g)
?.join('')
.replace(/\'/g, '');
state.ruleForm = row;
state.dialog.title = '修改菜单';
state.dialog.submitTxt = '修 改';
} else {
state.dialog.title = '新增菜单';
state.dialog.submitTxt = '新 增';
// 清空表单,此项需加表单验证才能使用
// nextTick(() => {
// menuDialogFormRef.value.resetFields();
// });
}
state.dialog.type = type;
state.dialog.isShowDialog = true;
};
// 关闭弹窗
const closeDialog = () => {
state.dialog.isShowDialog = false;
};
// 是否内嵌下拉改变
const onSelectIframeChange = () => {
if (state.ruleForm.meta.isIframe) state.ruleForm.isLink = true;
else state.ruleForm.isLink = false;
};
// 取消
const onCancel = () => {
closeDialog();
};
// 提交
const onSubmit = () => {
closeDialog(); // 关闭弹窗
emit('refresh');
// if (state.dialog.type === 'add') { }
// setBackEndControlRefreshRoutes() // 刷新菜单,未进行后端接口测试
};
// 页面加载时
onMounted(() => {
state.menuData = getMenuData(routesList.value);
});
// 暴露变量
defineExpose({
openDialog,
});
</script>

View File

@@ -0,0 +1,122 @@
<template>
<div class="system-menu-container layout-pd">
<el-card shadow="hover">
<div class="system-menu-search mb15">
<el-input size="default" placeholder="请输入菜单名称" style="max-width: 180px"> </el-input>
<el-button size="default" type="primary" class="ml10">
<el-icon>
<ele-Search />
</el-icon>
查询
</el-button>
<el-button size="default" type="success" class="ml10" @click="onOpenAddMenu">
<el-icon>
<ele-FolderAdd />
</el-icon>
新增菜单
</el-button>
</div>
<el-table
:data="state.tableData.data"
v-loading="state.tableData.loading"
style="width: 100%"
row-key="path"
:tree-props="{ children: 'children', hasChildren: 'hasChildren' }"
>
<el-table-column label="菜单名称" show-overflow-tooltip>
<template #default="scope">
<SvgIcon :name="scope.row.meta.icon" />
<span class="ml10">{{ $t(scope.row.meta.title) }}</span>
</template>
</el-table-column>
<el-table-column prop="path" label="路由路径" show-overflow-tooltip></el-table-column>
<el-table-column label="组件路径" show-overflow-tooltip>
<template #default="scope">
<span>{{ scope.row.component }}</span>
</template>
</el-table-column>
<el-table-column label="权限标识" show-overflow-tooltip>
<template #default="scope">
<span>{{ scope.row.meta.roles }}</span>
</template>
</el-table-column>
<el-table-column label="排序" show-overflow-tooltip width="80">
<template #default="scope">
{{ scope.$index }}
</template>
</el-table-column>
<el-table-column label="类型" show-overflow-tooltip width="80">
<template #default="scope">
<el-tag type="success" size="small">{{ scope.row.xx }}菜单</el-tag>
</template>
</el-table-column>
<el-table-column label="操作" show-overflow-tooltip width="140">
<template #default="scope">
<el-button size="small" text type="primary" @click="onOpenAddMenu('add')">新增</el-button>
<el-button size="small" text type="primary" @click="onOpenEditMenu('edit', scope.row)">修改</el-button>
<el-button size="small" text type="primary" @click="onTabelRowDel(scope.row)">删除</el-button>
</template>
</el-table-column>
</el-table>
</el-card>
<MenuDialog ref="menuDialogRef" @refresh="getTableData()" />
</div>
</template>
<script setup lang="ts" name="systemMenu">
import { defineAsyncComponent, ref, onMounted, reactive } from 'vue';
import { RouteRecordRaw } from 'vue-router';
import { ElMessageBox, ElMessage } from 'element-plus';
import { storeToRefs } from 'pinia';
import { useRoutesList } from '/@/stores/routesList';
// import { setBackEndControlRefreshRoutes } from "/@/router/backEnd";
// 引入组件
const MenuDialog = defineAsyncComponent(() => import('/@/views/system/menu/dialog.vue'));
// 定义变量内容
const stores = useRoutesList();
const { routesList } = storeToRefs(stores);
const menuDialogRef = ref();
const state = reactive({
tableData: {
data: [] as RouteRecordRaw[],
loading: true,
},
});
// 获取路由数据,真实请从接口获取
const getTableData = () => {
state.tableData.loading = true;
state.tableData.data = routesList.value;
setTimeout(() => {
state.tableData.loading = false;
}, 500);
};
// 打开新增菜单弹窗
const onOpenAddMenu = (type: string) => {
menuDialogRef.value.openDialog(type);
};
// 打开编辑菜单弹窗
const onOpenEditMenu = (type: string, row: RouteRecordRaw) => {
menuDialogRef.value.openDialog(type, row);
};
// 删除当前行
const onTabelRowDel = (row: RouteRecordRaw) => {
ElMessageBox.confirm(`此操作将永久删除路由:${row.path}, 是否继续?`, '提示', {
confirmButtonText: '删除',
cancelButtonText: '取消',
type: 'warning',
})
.then(() => {
ElMessage.success('删除成功');
getTableData();
//await setBackEndControlRefreshRoutes() // 刷新菜单,未进行后端接口测试
})
.catch(() => {});
};
// 页面加载时
onMounted(() => {
getTableData();
});
</script>