Files
medical-mall/docs/admin/ORDER_MENU_HIGHLIGHT_FIX.md
2026-02-02 20:07:37 +08:00

291 lines
8.0 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 订单菜单高亮问题修复文档
## 问题描述
在订单管理页面,无论点击哪个订单子菜单项(订单统计、订单管理、售后订单等),菜单高亮显示都始终停留在"订单管理",不会切换到实际选中的菜单项。
### 根本原因(两层)
#### 1. 路径标准化移除query参数
所有订单子菜单项使用相同的路由路径 `/pages/mall/admin/order-management`仅通过不同的query参数?tab=stats、?tab=list等来区分。
`layouts/admin/utils/nav.uts` 中的 `normalize()` 函数会将路径标准化,**移除query参数部分**
```uts
// 旧代码 - 问题所在
function normalize(p: string): string {
if (!p) return ''
const s = p.startsWith('/') ? p.slice(1) : p
const q = s.indexOf('?')
return q >= 0 ? s.slice(0, q) : s // ❌ 移除了 ?tab=xxx
}
```
这导致所有订单子菜单路径被标准化为相同值:
- `/pages/mall/admin/order-management?tab=stats``pages/mall/admin/order-management`
- `/pages/mall/admin/order-management?tab=list``pages/mall/admin/order-management` ✓(第一个命中)
- `/pages/mall/admin/order-management?tab=aftersale``pages/mall/admin/order-management` ✓(第一个命中)
#### 2. 页面硬编码currentPage
订单管理页面 (`pages/mall/admin/order-management.uvue`) 硬编码了:
```typescript
const currentPage = ref<string>("order-list"); // ❌ 始终是 order-list
```
导致即使路由正确布局组件收到的activeSubId也始终是`order-list`
---
## 解决方案
### 修改1保留query参数在路径标准化中
**文件:** `layouts/admin/utils/nav.uts`
```uts
// 新代码 - 支持 query 参数匹配
function normalize(p: string): string {
if (!p) return ''
const s = p.startsWith('/') ? p.slice(1) : p
// ✅ 保留完整路径包括query参数以支持 tab 参数的正确匹配
return s
}
```
### 修改2增强getCurrentRoutePath()支持query参数
**文件:** `layouts/admin/utils/nav.uts`
```typescript
export function getCurrentRoutePath(): string {
const pages = getCurrentPages();
const last: any = pages[pages.length - 1];
// #ifdef H5
if (last?.route) {
// H5 环境下从 location.search 获取 query 参数
const qs = typeof window !== "undefined" ? window.location.search : "";
return `/${last.route}${qs}`;
}
return "";
// #endif
// #ifndef H5
// 小程序/App 环境处理
if (last?.route) {
const qs = last?.$page?.options
? new URLSearchParams(last.$page.options).toString()
: "";
return `/${last.route}${qs ? "?" + qs : ""}`;
}
return last?.$page?.fullPath || "";
// #endif
}
```
### 修改3页面动态设置currentPage
**文件:** `pages/mall/admin/order-management.uvue`
```typescript
onLoad((options: Record<string, string | undefined>) => {
params.value = JSON.stringify(options ?? {});
// ✅ 改:根据 tab 参数动态设置 currentPage以实现正确的菜单高亮
const tab = options?.tab as string | undefined;
if (tab) {
// 从 tab 值映射到菜单 id保持与 menu.uts 中的定义一致)
const tabToMenuIdMap: Record<string, string> = {
stats: "order-stats",
list: "order-list",
aftersale: "order-aftersale",
cashier: "order-cashier",
verify: "order-verify",
config: "order-config",
};
const menuId = tabToMenuIdMap[tab];
if (menuId) {
currentPage.value = menuId;
// 同时更新页面标题
const titleMap: Record<string, string> = {
"order-stats": "订单统计",
"order-list": "订单管理",
"order-aftersale": "售后订单",
"order-cashier": "收银订单",
"order-verify": "核销记录",
"order-config": "订单配置",
};
title.value = titleMap[menuId] || "订单管理";
}
}
});
```
---
## 影响范围
此修改**直接影响所有使用query参数进行功能区分的页面**
### 受益的菜单项:
1. **订单管理** - 使用 ?tab 参数区分不同订单视图 ✅
2. **营销管理** - 使用 ?tab 参数区分不同营销功能(建议采用相同方案)
3. **其他tab式菜单** - 同样依赖query参数的任何菜单
### 兼容性:
- ✅ 不影响不使用query参数的菜单项
- ✅ 不影响传统路由参数(如 :id的菜单项
- ✅ 向后兼容现有所有路由结构
---
## 菜单结构参考
### 订单管理菜单(正确结构)
```typescript
{
id: 'order',
title: '订单',
icon: '/static/order.svg',
path: '/pages/mall/admin/order-management?tab=list',
groups: [
{
id: 'order-management',
title: '订单管理',
children: [
{
id: 'order-stats',
title: '订单统计',
path: '/pages/mall/admin/order-management?tab=stats' // ✓ 唯一的tab值
},
{
id: 'order-list',
title: '订单管理',
path: '/pages/mall/admin/order-management?tab=list' // ✓ 唯一的tab值
},
{
id: 'order-aftersale',
title: '售后订单',
path: '/pages/mall/admin/order-management?tab=aftersale' // ✓ 唯一的tab值
},
// ... 其他订单菜单项
]
}
]
}
```
---
## 高亮匹配流程(修复后)
```
用户点击"售后订单"菜单
导航至: /pages/mall/admin/order-management?tab=aftersale
order-management.uvue onLoad() 获取 tab=aftersale
映射到菜单id: order-aftersale
设置 currentPage.value = 'order-aftersale'
AdminLayout 接收 currentPage='order-aftersale'
findActiveByCurrentPage() 匹配菜单项
设置 activeSubId = 'order-aftersale'
高亮显示: "售后订单" ✓ 正确
```
---
## 测试检查清单
- [ ] 订单统计 - 点击并验证高亮显示正确
- [ ] 订单管理 - 点击并验证高亮显示正确
- [ ] 售后订单 - 点击并验证高亮显示正确
- [ ] 收银订单 - 点击并验证高亮显示正确
- [ ] 核销记录 - 点击并验证高亮显示正确
- [ ] 订单配置 - 点击并验证高亮显示正确
- [ ] 页面刷新 - 验证高亮仍能正确还原基于当前URL的tab参数
- [ ] 其他菜单 - 验证无回归,其他菜单仍能正常工作
---
## 与营销管理的对应方案
营销管理页面使用同样的?tab结构建议对 `pages/mall/admin/marketing-management.uvue` 采用同样的修复方案:
```typescript
// marketing-management.uvue 中的 onLoad
onLoad((options: Record<string, string | undefined>) => {
const tab = options?.tab as string | undefined;
if (tab) {
const tabToMenuIdMap: Record<string, string> = {
stats: "marketing-stats",
coupon: "coupon-list",
points: "points-stats",
member: "member-type",
// ... 其他映射
};
const menuId = tabToMenuIdMap[tab];
if (menuId) {
currentPage.value = menuId;
// 更新标题
}
}
});
```
---
## 提交信息
```
fix: 修复订单菜单高亮问题 - 支持query参数的完整路径匹配
问题:
- 订单菜单的所有子项高亮都显示为"订单管理"
- 原因路径标准化移除query参数导致路径重复页面硬编码currentPage
解决方案:
1. 保留query参数在路径标准化中nav.uts normalize函数
2. 增强getCurrentRoutePath()支持完整URL含query参数
3. 页面根据tab参数动态设置currentPage实现菜单项与页面的同步
文件修改:
- layouts/admin/utils/nav.uts (normalize + getCurrentRoutePath)
- pages/mall/admin/order-management.uvue (onLoad中的tab处理)
验证:点击各个订单子菜单,高亮正确切换
```
---
## 相关文件
- [nav.uts](../layouts/admin/utils/nav.uts) - 导航高亮逻辑
- [menu.uts](../layouts/admin/utils/menu.uts) - 菜单结构定义
- [order-management.uvue](../pages/mall/admin/order-management.uvue) - 订单管理页面
- [AdminLayout.uvue](../layouts/admin/AdminLayout.uvue) - 布局组件
- [AdminSubsider.uvue](../layouts/admin/components/AdminSubsider.uvue) - 二级侧边栏
---
## 修复日期
2026年1月31日
## 修复版本
v1.1.0