xto-fronted 0.4.99 → 0.4.101

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "xto-fronted",
3
- "version": "0.4.99",
3
+ "version": "0.4.101",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "description": "XTO 前端应用框架",
@@ -36,25 +36,44 @@ const displayMenuList = computed(() => props.menuList.length > 0 ? props.menuLis
36
36
  const isCollapsed = computed(() => appStore.isCollapsed)
37
37
  const activeMenu = computed(() => route.path)
38
38
 
39
- // 菜单展开状态持久化
39
+ // 获取菜单的唯一标识(优先使用 menuId,其次 menuCode,最后 menuUrl)
40
+ const getMenuKey = (menu: any): string => {
41
+ return menu.menuId || menu.menuCode || menu.menuUrl || ''
42
+ }
43
+
44
+ // 菜单展开状态持久化(基于当前菜单列表的标识)
40
45
  const OPENED_MENUS_KEY = 'sidebar_opened_menus'
41
- const openedMenus = ref<string[]>(local.get<string[]>(OPENED_MENUS_KEY) || [])
46
+ const MENU_LIST_KEY = 'sidebar_menu_list_key'
47
+
48
+ // 获取当前菜单列表的唯一标识
49
+ const getCurrentMenuListKey = (): string => {
50
+ return displayMenuList.value.map(getMenuKey).join(',')
51
+ }
52
+
53
+ // 初始化展开状态:只有当菜单列表相同时才恢复之前的展开状态
54
+ const savedMenuListKey = local.get<string>(MENU_LIST_KEY) || ''
55
+ const currentKey = getCurrentMenuListKey()
56
+ const initialOpenedMenus = savedMenuListKey === currentKey
57
+ ? (local.get<string[]>(OPENED_MENUS_KEY) || [])
58
+ : []
59
+ const openedMenus = ref<string[]>(initialOpenedMenus)
42
60
 
43
61
  // 监听变化并持久化
44
62
  watch(openedMenus, (val) => {
45
63
  local.set(OPENED_MENUS_KEY, val)
64
+ local.set(MENU_LIST_KEY, getCurrentMenuListKey())
46
65
  }, { deep: true })
47
66
 
48
- // 递归查找当前路由对应的父菜单路径
49
- const findMenuPath = (menus: any[], path: string, parentUrls: string[] = []): string[] | null => {
67
+ // 递归查找当前路由对应的父菜单路径(返回 menuId)
68
+ const findMenuPath = (menus: any[], path: string, parentIds: string[] = []): string[] | null => {
50
69
  for (const menu of menus) {
51
- // 当前菜单匹配
52
- if (path === menu.menuUrl || path.startsWith(menu.menuUrl + '/')) {
53
- return [...parentUrls, menu.menuUrl]
70
+ // 当前菜单匹配(使用 menuUrl 匹配路由)
71
+ if (menu.menuUrl && (path === menu.menuUrl || path.startsWith(menu.menuUrl + '/'))) {
72
+ return [...parentIds, getMenuKey(menu)]
54
73
  }
55
74
  // 递归查找子菜单
56
75
  if (menu.children?.length) {
57
- const result = findMenuPath(menu.children, path, [...parentUrls, menu.menuUrl])
76
+ const result = findMenuPath(menu.children, path, [...parentIds, getMenuKey(menu)])
58
77
  if (result) return result
59
78
  }
60
79
  }
@@ -81,8 +100,9 @@ watch(displayMenuList, (newList, oldList) => {
81
100
  if (newList !== oldList) {
82
101
  openedMenus.value = []
83
102
  local.set(OPENED_MENUS_KEY, [])
103
+ local.set(MENU_LIST_KEY, getCurrentMenuListKey())
84
104
  }
85
- })
105
+ }, { immediate: false })
86
106
 
87
107
  // 菜单主题相关
88
108
  const menuBgColor = computed(() => appStore.isDark ? '#1d1e1f' : '#fff')
@@ -126,7 +146,7 @@ const handleLogout = () => {
126
146
  class="sidebar__menu"
127
147
  @select="handleMenuSelect"
128
148
  >
129
- <template v-for="menu in displayMenuList" :key="menu.menuUrl">
149
+ <template v-for="menu in displayMenuList" :key="getMenuKey(menu)">
130
150
  <SidebarMenuItem :menu="menu" />
131
151
  </template>
132
152
  </Menu>
@@ -85,6 +85,11 @@ const iconExists = (iconName: string): boolean => {
85
85
  return knownIcons.has(iconName)
86
86
  }
87
87
 
88
+ // 获取菜单的唯一标识(优先使用 menuId,其次 menuCode,最后 menuUrl)
89
+ const menuIndex = computed(() => {
90
+ return props.menu.menuId || props.menu.menuCode || props.menu.menuUrl || ''
91
+ })
92
+
88
93
  // 是否有子菜单
89
94
  const hasChildren = computed(() => {
90
95
  return props.menu.children && props.menu.children.length > 0
@@ -93,7 +98,7 @@ const hasChildren = computed(() => {
93
98
 
94
99
  <template>
95
100
  <!-- 有子菜单 -->
96
- <SubMenu v-if="hasChildren" :index="menu.menuUrl">
101
+ <SubMenu v-if="hasChildren" :index="menuIndex">
97
102
  <template #title>
98
103
  <span class="menu-item__content">
99
104
  <span class="menu-item__icon">
@@ -104,13 +109,13 @@ const hasChildren = computed(() => {
104
109
  </span>
105
110
  </template>
106
111
  <!-- 递归渲染子菜单 -->
107
- <template v-for="child in menu.children" :key="child.menuUrl">
112
+ <template v-for="child in menu.children" :key="child.menuId || child.menuCode || child.menuUrl">
108
113
  <SidebarMenuItem :menu="child" />
109
114
  </template>
110
115
  </SubMenu>
111
116
 
112
117
  <!-- 无子菜单 -->
113
- <MenuItem v-else :index="menu.menuUrl">
118
+ <MenuItem v-else :index="menu.menuUrl || menuIndex">
114
119
  <span class="menu-item__content">
115
120
  <span v-if="menu.menuName !== '首页'" class="menu-item__icon">
116
121
  <Icon v-if="iconExists(getMenuIcon(menu.icon))" :name="getMenuIcon(menu.icon)" :size="16" />