# 管理导航闭环与单公司体验收敛 ## Goal 让管理人员从「管理」进入任一配置页后始终知道当前位置并能一键返回管理首页,同时把管理入口、侧栏归属和页面标题收敛到同一份路由事实源;在此基础上按“单公司、内部 OA、非产品化”边界简化公司信息和企业银行账户配置,不让用户面对无业务价值的多公司选择。 ## Background - 侧栏管理分组只有一个顶层入口:`client/src/features/navigation/schema.ts` 的 `ADMIN_NAV_ORDER` 仅包含 `/system/settings`。这符合“管理聚合入口”的产品方向,本任务不把每个配置页重新铺回侧栏。 - 子页归属目前是重复且不完整的手工事实:`SystemSettingsPage.tsx` 维护管理首页入口;`NavLinks.tsx` 维护独立的 `MANAGEMENT_ACTIVE_PATHS`;`features/navigation/schema.ts` 的 `PAGE_TITLES` 又维护 Topbar 标题。三者已经漂移。 - `/system/payment-accounts` 未加入 `MANAGEMENT_ACTIVE_PATHS`,因此当前页面不保持侧栏「管理」高亮。`PAGE_TITLES` 还缺少用户、部门、费用标准、报销模板、主数据、企业银行账户和通知渠道等多个管理页,缺失时可能回退为原始路径。 - 管理子页没有统一父级面包屑。用户从聚合页进入配置页后,只能自行重新寻找侧栏「管理」,深链或刷新后更缺少上下文。 - 本任务规划期间,生产曾因没有 `LegalEntity` 数据而使企业银行账户页面出现无选项的法人主体下拉框;管理员现已通过既有路径完成公司信息、付款账户和员工银行机构配置。该业务阻塞已经解除,但零公司状态仍需修复,避免以后初始化或测试环境再次走入死路。 - 本系统只服务当前公司内部、小于 10 人团队,不作为产品发布,不支持多公司、多租户或公司切换。`LegalEntity` 仍作为付款账户、成本中心等数据的内部关联锚点保留,不因前端简化而重做数据库模型。 - `docs/产品口径.md` 的权限口径目前编号到 R-5;单公司长期边界应作为下一条 R-6 固化,避免制造缺号的 R-7。 ## Priority 1. 高:管理导航闭环与共享路由事实源,覆盖每次管理页面访问。 2. 中:企业银行账户空状态与唯一公司自动关联,避免配置死路。 3. 低:公司信息单例化表达和「法体」自然中文改名;不阻塞当前一次性生产录入。 ## Scope - 前端管理路由元数据、管理聚合页入口、PC 侧栏选中状态、Topbar 标题/面包屑和最近访问标题。 - 主数据中的公司信息单例表达,以及企业银行账户页面在零个、一个或异常多个启用公司时的交互。 - 与上述行为直接相关的前端类型、单元/组件测试和现有产品口径文档。 - 不修改后端数据模型、权限、银行资料加密/审计、制单逻辑或生产数据;不包含付款详情结构统一。 ## Requirements ### R1 管理路由单一事实源 - 新建一份前端管理路由注册表,至少包含稳定 key、路径匹配规则、标题、父级、管理首页分组、图标、说明和权限要求。 - 「管理」聚合页入口、侧栏「管理」选中判断、Topbar 页面标题/分组和管理面包屑必须从该注册表派生,不再分别维护 `ITEMS`、`MANAGEMENT_ACTIVE_PATHS` 和不完整的管理 `PAGE_TITLES`。 - 注册表中的权限条件是路由元数据合同的一部分;管理根入口的权限集合从可见子项派生,不再在 `NavLinks.tsx` 单独维护另一份 `anyOf`。 - React Router 的页面组件与权限边界继续在 `router/index.tsx` 显式声明;本任务不为追求配置化而把懒加载组件塞进产品元数据。 - 注册表必须覆盖当前管理首页全部入口及必要详情层级,包括人员档案;新增管理页如果未登记,测试必须失败,而不是回退为原始路径后静默上线。 ### R2 管理导航闭环 - PC 管理首页仍只占一个侧栏入口,不把低频配置页铺回主导航。 - 任一管理子页的 Topbar 显示可点击父级路径,例如 `管理 / 企业银行账户`;点击「管理」固定回到 `/system/settings`,不依赖浏览器历史。 - 人员档案等二级页面显示 `管理 / 人员 / 员工档案`;中间「人员」可返回人员列表。 - 直接访问深链、刷新页面或从全局搜索进入时,面包屑和侧栏高亮仍正确。 - 管理标题和父链解析必须接收当前用户权限;无权访问某个管理页时不得通过 Topbar 面包屑、父链或管理入口泄露该页面名称。 - 管理首页本身只显示当前页标题,不显示自指的「返回管理」。 ### R3 页面标题与侧栏状态 - `/system/payment-accounts` 及所有已登记管理子页均保持侧栏「管理」选中。 - Topbar 不得把管理子页显示为原始 URL;管理页标题和分组必须与聚合页卡片一致。 - 最近访问记录只写入当前有权访问的管理路由,并继续使用自然中文标题,不因注册表重构写入原始路径。 - 读取最近访问时必须按当前权限重新过滤;用户权限被收回后,旧记录不得继续显示受限管理页面标题或链接。当前实现只有 localStorage 写入、尚无读取 UI,本任务修正写入/读取合同但不新建最近访问页面。 ### R4 单公司长期边界 - 在 `docs/产品口径.md` 增加下一条可用编号 R-6:系统只服务当前公司内部,不做多公司、多租户、公司切换或面向外部客户的产品化配置。 - 不新增 tenant/company switcher、跨公司权限、公司维度工作区或多公司初始化流程。 - 保留 `LegalEntity` 表和现有关联作为内部账务/主数据锚点;本任务不重命名数据库表、不迁移外键、不删除历史能力。 - 前端用户文案把「法体」统一改为「公司信息」或「公司」,不向普通管理员暴露会计/产品化术语。 ### R5 公司信息单例表达 - 公司信息为空时,主数据页显示一次性初始化表单和明确说明。 - 正常存在一条启用公司信息时,以单公司查看/维护方式展示,不提供公司切换器或鼓励继续创建第二家公司。 - 若历史或测试环境异常存在多条启用记录,不静默选择,不自动合并或删除;显示管理员可理解的异常提示,并保留现有数据供单独治理。 - 当前生产通过既有「主数据 → 法体」录入不被本任务阻塞;本任务不执行任何生产公司资料写入。 ### R6 企业银行账户配置不走死路 - 没有公司信息时,不显示无解释的空法人主体下拉框;显示「请先完善公司信息」和可点击入口。 - 恰有一条启用公司信息时自动关联并只读显示公司名称,不要求用户重复选择。 - 异常存在多条启用公司信息时禁止猜测默认值,明确提示先处理公司信息。 - 公司银行账户、员工银行资料、权限、加密、审计和通知合同保持不变;本任务不读取、回填或迁移真实完整账号。 ### R7 范围与设备 - 本任务服务 PC 管理配置体验;按照现有产品规则,不新建复杂移动端管理台。 - 窄屏通过现有 Topbar 菜单和可换行面包屑保持可用,但不新增移动专属公司/银行配置页面。 - 付款详情结构统一、处理进度时间线、粘性操作区和银行制单业务逻辑不纳入本任务。 ## Acceptance Criteria - [x] 管理首页全部可见入口、侧栏归属、Topbar 标题和面包屑来自同一管理路由注册表;不存在第二份手工管理路径列表。 - [x] 自动化逐项证明当前管理入口均有标题、权限、父级和路径匹配;新增未登记管理页会导致测试失败。 - [x] 无权限用户看不到对应管理入口;深链访问期间 Topbar 不渲染受限页面名称或面包屑。 - [x] 所有管理页面均显示 `管理 / 当前页面`,且「管理」可返回聚合页;员工档案显示 `管理 / 人员 / 员工档案`。 - [x] 直接深链、刷新和前进后退后父链仍正确;管理首页不显示自指面包屑。 - [x] 所有管理子页保持侧栏「管理」高亮,`/system/payment-accounts` 回归测试覆盖此前遗漏。 - [x] Topbar 与最近访问记录不再为管理子页回退显示原始路径。 - [x] 最近访问按当前权限过滤:撤销权限后,既有 localStorage 记录不再向用户显示受限页面标题或链接;聚焦测试覆盖权限变更场景。 - [x] 主数据 UI 使用「公司信息」而不是「法体」,正常单公司状态不出现公司切换器或新增第二公司的主导入口。 - [x] 零公司信息时,企业银行账户页提供明确说明和「完善公司信息」入口;一条时自动关联;多条异常时不静默选择。 - [x] `LegalEntity` 数据模型、现有外键、付款账户加密/审计/通知和生产数据保持不变,无数据库迁移、无真实资料写入。 - [x] `docs/产品口径.md` 以连续编号 R-6 固化单公司内部 OA 边界。 - [x] 前端相关单元/组件测试、TypeScript 检查和生产构建通过;Trellis、敏感内容和 diff 门禁通过。 - [x] 只有部署与公网检查通过后才通知用户线上验收;生产公司资料录入另由管理员执行。 ## Test Plan - 注册表契约测试:逐项校验稳定 key、唯一匹配、父级、标题、权限和管理首页可见项;覆盖未登记管理入口的失败用例。 - 导航组件测试:覆盖管理首页、企业银行账户、人员列表与员工档案深链,验证侧栏高亮、Topbar 标题、面包屑链接和最近访问中文标题;同一路径分别验证有权和无权状态。 - 权限变更测试:先以有权状态写入最近访问,再撤销权限读取,断言受限页面标题和链接均不返回;无权深链不渲染受限面包屑。 - 公司状态组件测试:分别覆盖零个、一个和多个启用公司;验证引导入口、自动关联、只读公司名称和异常 fail-closed 行为。 - 回归检查:确认管理页权限边界及 React Router 显式路由未改变,付款账户敏感字段不会进入测试快照或日志。 - 前端门禁:运行相关 Vitest、`npm run typecheck` 与 `npm run build`。 - 治理门禁:运行 Trellis task validate、Trellis governance、敏感内容检查(如当前流程要求)与 `git diff --check`。 - 面向线上用户的验收仅在另行批准部署且公网检查通过后进行;生产配置和真实数据写入不属于自动化测试。 ## Out of Scope - 多租户、多公司切换、跨公司数据隔离、集团组织、合并报表或 SaaS 产品化。 - 重命名或删除 `LegalEntity` 数据模型、外键迁移、历史数据合并和生产数据修复。 - 把所有管理子页重新放进侧栏,或建设复杂的二级侧栏导航。 - 移动端管理配置台、付款详情结构统一、审批/处理进度重构和银行制单业务变更。 - 代替管理员录入公司全称、税号、银行账户或员工收款资料。 - 取消或重建既有付款批次、生成制单、网银导入、上传回单或登记付款完成;这些属于独立的生产操作与制单验收。