Files
medical-mall/pages/mall/admin/docs/ORDER_MENU_HIGHLIGHT_FIX.md
2026-02-03 21:35:57 +08:00

8.0 KiB
Raw Blame History

订单菜单高亮问题修复文档

问题描述

在订单管理页面,无论点击哪个订单子菜单项(订单统计、订单管理、售后订单等),菜单高亮显示都始终停留在"订单管理",不会切换到实际选中的菜单项。

根本原因(两层)

1. 路径标准化移除query参数

所有订单子菜单项使用相同的路由路径 /pages/mall/admin/order-management仅通过不同的query参数?tab=stats、?tab=list等来区分。

layouts/admin/utils/nav.uts 中的 normalize() 函数会将路径标准化,移除query参数部分

// 旧代码 - 问题所在
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=statspages/mall/admin/order-management
  • /pages/mall/admin/order-management?tab=listpages/mall/admin/order-management ✓(第一个命中)
  • /pages/mall/admin/order-management?tab=aftersalepages/mall/admin/order-management ✓(第一个命中)

2. 页面硬编码currentPage

订单管理页面 (pages/mall/admin/order-management.uvue) 硬编码了:

const currentPage = ref<string>("order-list"); // ❌ 始终是 order-list

导致即使路由正确布局组件收到的activeSubId也始终是order-list


解决方案

修改1保留query参数在路径标准化中

文件: layouts/admin/utils/nav.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

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

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的菜单项
  • 向后兼容现有所有路由结构

菜单结构参考

订单管理菜单(正确结构)

{
  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 采用同样的修复方案:

// 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处理)

验证:点击各个订单子菜单,高亮正确切换

相关文件


修复日期

2026年1月31日

修复版本

v1.1.0