diff --git a/AGENTS.md b/AGENTS.md index d6fb9710..7802e242 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -3,7 +3,7 @@ ## 项目定位 - 本项目是虫虫出海内部运营与管理后台,仅服务平台员工。 -- 当前范围包括工作台、客户管理、头程订单、内部用户、角色管理和菜单权限。 +- 当前范围包括工作台、客户管理、头程订单、仓储与国内出仓协同、财务管理、内部用户、角色管理和菜单权限。 - 不在本项目承载企业客户自助流程、品牌官网、微信小程序、独立 APP 或仓库 PDA 作业。 ## 技术基线 @@ -37,15 +37,19 @@ | 业务 | 模块入口 | 联查模块或服务端 | |---|---|---| +| 工作台与业务总览 | `modules/dashboard/` | 按具体指标联查其所属业务模块和服务端,不在工作台复制领域契约 | | 客户、企业审核 | `modules/customers/` | `iam/`、`file/` | | 平台用户与 RBAC | `modules/iam/`、`core/access/` | `auth/`、`iam/` | | 平台仓库与仓储资源 | `modules/warehouses/`、`modules/warehouse-resources/` | `warehouse/` | | 订单列表与详情编排 | `modules/unified-orders/`、`modules/first-leg-orders/` | `order/`、`firstleg/` | | 入库、测量和计费 | `modules/inbounds/`、`modules/fba-pricing/`、`modules/dimension-config/`、`modules/fee-items/` | `firstleg/`、`file/`、`integration-service/` | +| 财务账户、账单、收款与成本 | `modules/finance/` | `finance/`;费用来源与柜次成本快照联查 `firstleg/`,凭证联查 `file/` | | 货柜与智能排柜 | `modules/container-loading/` | `firstleg/loading/`、`firstleg/split/` | | 预装与装柜清单 | `modules/loading-lists/` | `firstleg/loading/`、`file/`、`warehouse/` | -| 海运订舱与船期 | `modules/ocean-bookings/` | `firstleg/oceanbooking/`、`firstleg/portschedule/`、`integration-service/` | +| 海运订舱与船期 | `modules/ocean-bookings/`、`modules/port-schedules/` | `firstleg/oceanbooking/`、`firstleg/portschedule/`、`integration-service/` | | 拖车预约 | `modules/trucking/` | `firstleg/outbound/dispatch/`、`firstleg/` | +| 报关协同 | `modules/customs/` | `firstleg/customs/`、`file/` | +| 国内出仓确认 | `modules/outbound-dispatch/` | `firstleg/outbound/dispatch/` | | 主数据与下载 | `modules/master-data/`、`modules/downloads/` | `warehouse/`、`file/` | ## 一期/二期/三期 Admin 快速索引 @@ -56,7 +60,7 @@ |---|---|---| | 一期:头程订单闭环 | `modules/auth/` 登录;`customers/` 客户与企业审核;`iam/` 内部用户、角色、权限;`warehouses/` 平台收货仓;`master-data/` 快递公司、往来单位;`first-leg-orders/` 头程订单;`dashboard/` 工作台 | 企业审核归客户列表,平台 RBAC 仅维护平台员工与平台权限资源 | | 二期:到仓与头程计费 | `modules/inbounds/` 入库预报、收货、测量/OCR、审核、差异与费用快照;`warehouse-resources/pallets/` 托盘;`warehouse-resources/locations/` 库位;`fba-pricing/`、`dimension-config/` 计费规则与尺寸配置;`unified-orders/` 订单工作流编排 | 页面范围停在 `WAIT_SPLIT + APPROVED + CONFIRMED`;海外仓阶梯费用页面是否开放需单独确认;客户侧可见字段按授权结果映射,内部备注、文件和原始证据不得进入 Client 契约 | -| 三期:国内出仓 | `unified-orders/` 订单编排;`container-loading/` 货柜与排柜;`loading-lists/` 预装/装柜清单;`ocean-bookings/` 订舱船期;`trucking/` 拖车 | 页面、权限和 API 以稳定服务端契约发布;完整 WMS、海外仓及原型未纳入能力不属于本范围 | +| 三期:国内出仓 | `unified-orders/` 订单编排;`container-loading/` 货柜与排柜;`loading-lists/` 预装/装柜清单;`ocean-bookings/` 订舱;`port-schedules/` 船期;`trucking/` 拖车;`customs/` 报关;`outbound-dispatch/` 国内出仓确认 | 页面、权限和 API 以稳定服务端契约发布;完整 WMS、海外仓及原型未纳入能力不属于本范围 | 阶段文档入口(路径相对本文件所在目录):一期读 `../../docs/一期/README.md` 与闭环设计;二期读 `../../docs/二期/README.md` 和主流程;三期读 `../../docs/三期/README.md`、需求确认表、开工门禁、开发规划和页面清单。进度、排期或验收状态问题再读取相应进度表和验收报告。 diff --git a/src/app/components/AdminSidebarMenu.test.ts b/src/app/components/AdminSidebarMenu.test.ts index ab1814d6..b74f2b3f 100644 --- a/src/app/components/AdminSidebarMenu.test.ts +++ b/src/app/components/AdminSidebarMenu.test.ts @@ -105,4 +105,17 @@ describe('AdminSidebarMenu', () => { expect(wrapper.findAll('[data-kind="group"]')).toHaveLength(2) expect(wrapper.get('[data-kind="item"]').attributes('data-index')).toBe('/tracking') }) + + it('recreates the menu when asynchronously loaded groups change', async () => { + const wrapper = mount(AdminSidebarMenu, { + props: { items: [adminNavigation[0]], activePath: '/dashboard', collapsed: false }, + global: { stubs }, + }) + const initialMenu = wrapper.get('nav').element + + await wrapper.setProps({ items: visibleNavigation }) + + expect(wrapper.get('nav').element).not.toBe(initialMenu) + expect(wrapper.text()).toContain('系统管理') + }) }) diff --git a/src/app/components/AdminSidebarMenu.vue b/src/app/components/AdminSidebarMenu.vue index 9e2737dc..ea4cc052 100644 --- a/src/app/components/AdminSidebarMenu.vue +++ b/src/app/components/AdminSidebarMenu.vue @@ -16,10 +16,12 @@ function getGroupKeys(nodes: AdminNavigationNode[]): string[] { } const defaultOpeneds = computed(() => getGroupKeys(props.items)) +const menuInstanceKey = computed(() => `${props.collapsed ? 'collapsed' : 'expanded'}:${defaultOpeneds.value.join('|')}`)