Browse Source

页面菜单优化

main
wang 1 month ago
parent
commit
0cfafa6633
  1. 21
      smart-flow-web/src/layout/components/side-menu/recursion-menu.vue
  2. 30
      smart-flow-web/src/layout/components/top-side-menu/recursion-menu.vue
  3. 6
      smart-flow-web/src/router/index.js
  4. 73
      smart-flow-web/src/store/modules/system/user.js
  5. 26
      smart-flow-web/src/views/jwpy/jwpy/flow/index.vue

21
smart-flow-web/src/layout/components/side-menu/recursion-menu.vue

@ -33,7 +33,7 @@
import SubMenu from './sub-menu.vue';
import { router } from '/@/router/index';
import { useAppConfigStore } from '/@/store/modules/system/app-config';
import { useUserStore } from '/@/store/modules/system/user';
import { useUserStore, stateIndexMap } from '/@/store/modules/system/user';
const theme = computed(() => useAppConfigStore().$state.sideMenuTheme);
const flatPattern = computed(() => useAppConfigStore().$state.flatPattern);
@ -64,16 +64,31 @@
* SmartAdmin中 router的name 就是 后端存储menu的id
* 所以此处可以直接监听路由根据路由更新菜单的选中和展开
*/
function updateOpenKeysAndSelectKeys() {
let currentMenuId = _.toNumber(currentRoute.name);
//
const tabType = currentRoute.params.tabType;
if (tabType && stateIndexMap[tabType]) {
currentMenuId = currentMenuId * 100 + stateIndexMap[tabType];
}
// watch
if (selectedKeys.value.includes(currentMenuId)) {
return;
}
//
selectedKeys.value = [_.toNumber(currentRoute.name)];
selectedKeys.value = [currentMenuId];
/**
* 更新展开1获取新展开的menu key集合2保留原有的openkeys然后把新展开的与之合并
*/
//menu key
let menuParentIdListMap = useUserStore().getMenuParentIdListMap;
let parentList = menuParentIdListMap.get(currentRoute.name) || [];
let parentList = menuParentIdListMap.get(currentMenuId.toString()) || [];
// openkey
if (!props.collapsed) {

30
smart-flow-web/src/layout/components/top-side-menu/recursion-menu.vue

@ -29,7 +29,7 @@
import SubMenu from './sub-menu.vue';
import { router } from '/@/router/index';
import { useAppConfigStore } from '/@/store/modules/system/app-config';
import { useUserStore } from '/@/store/modules/system/user';
import { useUserStore, stateIndexMap } from '/@/store/modules/system/user';
const theme = computed(() => useAppConfigStore().$state.sideMenuTheme);
const flatPattern = computed(() => useAppConfigStore().$state.flatPattern);
@ -58,13 +58,28 @@
router.push({ path: menu.path });
}
function updateOpenKeysAndSelectKeys() {
let currentMenuId = _.toNumber(currentRoute.name);
//
const tabType = currentRoute.params.tabType;
if (tabType && stateIndexMap[tabType]) {
currentMenuId = currentMenuId * 100 + stateIndexMap[tabType];
}
// watch
if (selectedKeys.value.includes(currentMenuId)) {
return;
}
//
selectedKeys.value = [_.toNumber(currentRoute.name)];
selectedKeys.value = [currentMenuId];
// menu key
let menuParentIdListMap = useUserStore().getMenuParentIdListMap;
let parentList = menuParentIdListMap.get(currentRoute.name) || [];
let parentList = menuParentIdListMap.get(currentMenuId.toString()) || [];
// openkey
if (!props.collapsed) {
@ -105,5 +120,14 @@
position: relative;
border-right: none;
background: transparent;
// SubMenu
:deep(.ant-menu-submenu-title) {
color: rgba(30, 41, 59, 0.85) !important; // Slate-800
font-weight: 500;
}
:deep(.ant-menu-submenu-arrow) {
color: rgba(30, 41, 59, 0.45) !important;
}
}
</style>

6
smart-flow-web/src/router/index.js

@ -117,8 +117,12 @@ export function buildRoutes(menuRouterList) {
if (e.deletedFlag && e.deletedFlag === true) {
continue;
}
let routePath = e.path.startsWith('/') ? e.path : `/${e.path}`;
if (e.component && e.component.includes('jwpy/flow/index')) {
routePath = `${routePath}/:tabType?`;
}
let route = {
path: e.path.startsWith('/') ? e.path : `/${e.path}`,
path: routePath,
// 使用【menuId】作为name唯一标识
name: e.menuId.toString(),
meta: {

73
smart-flow-web/src/store/modules/system/user.js

@ -73,7 +73,7 @@ export const useUserStore = defineStore({
}
return localRead(localKey.USER_TOKEN);
},
getNeedUpdatePwdFlag(state){
getNeedUpdatePwdFlag(state) {
return state.needUpdatePwdFlag;
},
//是否初始化了 路由
@ -212,7 +212,7 @@ export const useUserStore = defineStore({
// @ts-ignore
menuTitle: route.meta.title,
menuQuery: route.query,
menuIcon:route.meta?.icon,
menuIcon: route.meta?.icon,
// @ts-ignore
fromMenuName: from.name,
fromMenuQuery: from.query,
@ -345,6 +345,12 @@ function buildMenuTree(menuList) {
for (const topCatalog of topCatalogList) {
buildMenuChildren(topCatalog, catalogAndMenuList);
}
// 3 动态为警务评议与问题处置业务菜单挂载状态折叠子菜单
for (const topCatalog of topCatalogList) {
injectWorkflowSubMenus(topCatalog);
}
return topCatalogList;
}
@ -358,3 +364,66 @@ function buildMenuChildren(menu, allMenuList) {
buildMenuChildren(item, allMenuList);
}
}
// ---------------------------- 动态工单流转状态插拔装配 ----------------------------
export const statePool = {
'all': { title: '全部工单', queryType: 'all' },
'to_handle': { title: '待办工单', queryType: 'to_handle' },
'transferred': { title: '已流转工单', queryType: 'transferred' },
'about_to_expire': { title: '即将超期工单', queryType: 'about_to_expire' },
'expired': { title: '已超期工单', queryType: 'expired' },
'completed': { title: '已办结工单', queryType: 'completed' },
'invalid': { title: '已作废工单', queryType: 'invalid' }
};
export const businessWorkflowConfig = {
default: ['all', 'to_handle', 'transferred', 'about_to_expire', 'expired', 'completed', 'invalid']
};
// 动态根据默认数组顺序生成索引映射,防止后续修改顺序时高亮乱蹦
export const stateIndexMap = {};
businessWorkflowConfig.default.forEach((key, index) => {
stateIndexMap[key] = index + 1;
});
function injectWorkflowSubMenus(menuNode) {
if (menuNode.children && menuNode.children.length > 0) {
for (const child of menuNode.children) {
injectWorkflowSubMenus(child);
}
}
// 检测组件路径是否为警务评议与问题处置的通用工单列表
if (menuNode.component && menuNode.component.includes('jwpy/flow/index')) {
let states = businessWorkflowConfig.default;
// 支持通过后端菜单的扩展字段配置该业务支持的状态,实现可插拔
if (menuNode.extendInfo) {
try {
const config = JSON.parse(menuNode.extendInfo);
if (config.workflowStates && config.workflowStates.length > 0) {
states = config.workflowStates;
}
} catch (e) { }
}
const sjlyNo = menuNode.path ? menuNode.path.split('/').pop() : menuNode.menuId.toString();
const children = [];
states.forEach((stateKey, index) => {
const stateObj = statePool[stateKey];
if (stateObj) {
children.push({
menuId: menuNode.menuId * 100 + (index + 1), // 生成全局唯一数字 ID
parentId: menuNode.menuId,
menuName: stateObj.title,
path: `${menuNode.path}/${stateObj.queryType}`,
component: menuNode.component,
menuType: MENU_TYPE_ENUM.MENU.value,
visibleFlag: true,
disabledFlag: false
});
}
});
menuNode.children = [...(menuNode.children || []), ...children];
}
}

26
smart-flow-web/src/views/jwpy/jwpy/flow/index.vue

@ -8,15 +8,6 @@
<div class="page-container">
<div class="glass-card">
<div class="content-box">
<!-- Tab 切换区域 -->
<a-tabs v-model:activeKey="activeTab" @change="onTabChange" class="custom-tabs">
<a-tab-pane key="mine" tab="我的" />
<a-tab-pane key="todo" tab="待办" />
<a-tab-pane key="expiring" tab="即将超期" />
<a-tab-pane key="expired" tab="已超期" />
<a-tab-pane key="all" tab="全部" />
</a-tabs>
<!-- 头部查询过滤区域 -->
<a-form layout="inline" class="query-form">
<a-form-item label="工单编号">
@ -130,12 +121,6 @@ const route = useRoute();
// ---------------------------- Tab ----------------------------
const activeTab = ref('all');
// Tab
function onTabChange(key) {
queryForm.pageNum = 1;
queryData();
}
// URL
const currentBizTypeCode = computed(() => {
// 1. query
@ -235,7 +220,16 @@ function resetQuery() {
queryData();
}
onMounted(queryData);
//
watch(
() => route.params.tabType,
(newTabType) => {
activeTab.value = newTabType ? newTabType : 'all';
queryForm.pageNum = 1;
queryData();
},
{ immediate: true }
);
//
watch(

Loading…
Cancel
Save