# 入口模块绑定最终设计方案 > 适用项目:`leaudit-platform` > > 参考来源: > - 老系统:`/home/wren-dev/Porject/docauditai` > - 新前端:`/home/wren-dev/Porject/leaudit-platform/new_doc_review` > - 新后端:`/home/wren-dev/Porject/leaudit-platform/fastapi_modules` --- ## 1. 这份文档解决什么问题 本方案要解决的是: 1. 老系统“入口模块”到底是什么语义 2. 新系统里 `entry_modules / document_types / sys_routes / role_route` 各自该负责什么 3. 首页入口模块应该由谁来组装 4. 现有逻辑有哪些遗漏和隐患 5. 下一步如何把它收口成一套稳定方案 这份文档的目标不是直接讲实现细节,而是先把**边界、语义、数据流、遗漏点**固定下来,避免后续继续前后端双写规则。 --- ## 2. 结论先行 ### 2.1 核心结论 老系统里的“入口模块”**不是权限系统**,而是**首页业务入口编排系统**。 它的职责是: - 决定首页显示哪些入口卡片 - 给每个入口卡片绑定一组文档类型 - 按地区启用/禁用入口 它**不负责**: - 控制用户是否可以访问某个页面 - 控制用户是否可以调用某个 API - 替代 RBAC 路由菜单系统 真正的权限系统始终是: - `sys_routes` - `role_route` - `permissions` - `role_permissions` ### 2.2 新系统必须收口的总原则 新系统应该明确分成三层: 1. **首页入口层** - 数据源:`leaudit_entry_modules` - 作用:决定首页显示什么入口 2. **业务归类层** - 数据源:`leaudit_document_types.entry_module_id` - 作用:决定某入口下挂哪些文档类型 3. **权限控制层** - 数据源:`sys_routes / role_route / permissions / role_permissions` - 作用:决定用户是否真的能访问页面和动作 ### 2.3 当前已落地接口口径 当前首页入口已经统一走: - `GET /api/home/entry-modules` 当前返回结构核心字段包括: - `id` - `name` - `description` - `targetPath` - `routePath` - `iconPath` - `sortOrder` - `requiresDocumentTypes` - `areas` - `documentTypes` 当前过滤顺序为: 1. `leaudit_entry_modules.is_enabled = true` 2. `leaudit_entry_modules.deleted_at is null` 3. 地区过滤 4. 若目标页面已存在于 `sys_routes`,则继续做 `role_route` 权限过滤 这意味着首页入口已经不是前端自己拼装,而是后端统一组装后返回。 --- ## 3. 老系统深度分析结论 ## 3.1 首页入口不是从 sys_routes 直接来 老系统首页入口不是直接根据 RBAC 路由树生成,而是单独查询入口模块配置。 对应证据: - 老系统入口模块服务: - `/home/wren-dev/Porject/docauditai/app/services/entry_module_service.py` - 老系统入口模块路由: - `/home/wren-dev/Porject/docauditai/app/routes/entry_modules.py` - 老系统文档类型服务: - `/home/wren-dev/Porject/docauditai/app/services/document_type_service.py` ### 实际链路 老系统首页逻辑本质是: 1. 查 `entry_modules` 2. 按 `areas` 做地区过滤 3. 对每个入口模块,再查 `document_types where entry_module_id = module.id` 4. 拼成首页卡片 5. 点击卡片后跳转目标页面 6. 目标页面再走 RBAC 校验 所以首页入口和页面权限本来就是两套体系。 --- ## 3.2 老系统中 entry_modules 的真实职责 老系统 `entry_modules` 本质上存的是“首页业务入口卡片配置”。 典型字段语义: - `id`:入口模块主键 - `name`:入口名称 - `description`:说明 - `path`:旧系统里语义不稳定,常被当成资源/图片路径使用 - `areas`:地区配置 - `created_at / updated_at` ### 关键观察 老系统里 `path` 不是一个稳定可靠的“点击后跳转路由字段”。 也就是说: - 它并不总是纯前端路由 - 它常常承担资源路径、展示配置、模块图片等混合语义 这也是老系统最容易让后续维护者误解的地方之一。 --- ## 3.3 文档类型和入口模块的关系 老系统文档类型是通过 `entry_module_id` 绑定到入口模块的。 这说明: - 一个入口模块下面挂很多文档类型 - 一个文档类型归属于一个入口模块 这个设计本身是合理的,属于“业务归类关系”,不属于“权限关系”。 ### 当前判断 除非未来明确出现“一个文档类型必须出现在多个入口模块”的业务需求,否则: - 新系统应继续保留 `entry_module_id` - 没必要提前拆成中间表 --- ## 3.4 真正的页面权限来自 RBAC 老系统页面权限来源一直是: - `sys_routes` - `role_route` 动作/API 权限来源是: - `permissions` - `role_permissions` 这意味着在老系统中可能出现: 1. 首页能看到某个入口模块 2. 点击后跳到某个页面 3. 页面又因为 RBAC 不通过而拒绝访问 这是老系统长期存在的结构性问题,不是 Bug,而是设计分层没有被清楚说明。 --- ## 4. 新系统最终语义边界 ## 4.1 `leaudit_entry_modules` ### 负责 - 首页显示哪些业务入口 - 每个入口的名称、图标、排序、地区启用规则 - 每个入口点击后去哪 ### 不负责 - 页面访问权限 - API 权限 - 替代路由表 --- ## 4.2 `leaudit_document_types` ### 负责 - 定义系统支持的文档类型 - 通过 `entry_module_id` 归属到某个入口模块 ### 不负责 - 决定首页是否展示入口模块 - 决定菜单权限 --- ## 4.3 `sys_routes / role_route` ### 负责 - 页面路由菜单权限 - 用户可访问哪些页面 ### 不负责 - 首页模块展示编排 - 文档类型归类 --- ## 4.4 `permissions / role_permissions` ### 负责 - API 权限 - 动作按钮权限 - 数据范围权限 ### 不负责 - 首页入口展示 - 文档类型归属 --- ## 5. 新系统最终数据模型建议 ## 5.1 `leaudit_entry_modules` 建议字段 当前表建议正式化为以下语义: - `id` - `module_key` - `name` - `description` - `icon_path` - `target_path` - `route_path` - `module_type` - `allow_empty_types` - `areas` - `sort_order` - `is_enabled` - `create_time` - `update_time` ### 字段解释 #### `module_key` 稳定的业务标识,用于程序判断,不可依赖 `name`。 示例: - `contract` - `case_review` - `assistant` - `cross_review` #### `icon_path` 首页卡片图标/图片路径。 应从旧的 `path` 语义中剥离出来,单独承担展示职责。 #### `target_path` 用户点击首页卡片后实际跳转的前端路径。 示例: - `/contract-template/search` - `/home` - `/chat-with-llm/chat` - `/cross-checking` #### `route_path` 与 RBAC 路由树关联的目标页面路径,用于做“当前用户是否真的有访问权限”的判断。 通常可与 `target_path` 相同,但不强制必须相同。 #### `module_type` 建议枚举: - `document` - `assistant` - `cross_review` - `settings_link` #### `allow_empty_types` 控制“没有绑定文档类型时是否仍然允许显示”。 建议: - 文档类模块:`false` - 助手类模块:`true` - 交叉评查类模块:`true` --- ## 5.2 `leaudit_document_types` 继续保留: - `entry_module_id` 表示“该文档类型归属哪个入口模块”。 ### 当前不建议做的事 暂不建议改成: - `leaudit_entry_module_document_type_bindings` 因为当前没有明确“一种文档类型要同时挂多个入口”的需求。 --- ## 6. 首页统一接口最终设计 建议新增: - `GET /api/home/entry-modules` 由后端直接根据当前登录用户返回首页入口列表。 前端不再自己拼 `entry_modules + document_types + area + 跳转规则`。 --- ## 6.1 接口职责 后端统一完成: 1. 识别当前用户 2. 读取用户角色 3. 读取用户地区 4. 查询可用入口模块 5. 按地区过滤 6. 按页面权限做一次 RBAC 二次过滤 7. 挂载该入口下的文档类型 8. 返回最终首页可见入口列表 --- ## 6.2 建议返回结构 ```json { "code": 200, "message": "ok", "data": { "items": [ { "id": 1, "moduleKey": "contract", "name": "合同管理", "description": "合同智能审核与模板管理", "iconPath": "static/modules/contract.png", "targetPath": "/contract-template/search", "routePath": "/contract-template/search", "moduleType": "document", "allowEmptyTypes": false, "sortOrder": 10, "documentTypes": [ { "id": 9, "code": "contract.sale", "name": "买卖合同" } ] } ] } } ``` --- ## 7. 首页统一接口的推荐过滤规则 ## 7.1 基础过滤 必须满足: - `is_enabled = true` --- ## 7.2 地区过滤 ### 省级管理员 - `provincial_admin` 可查看所有启用入口模块 ### 地市管理员 / 普通用户 - `admin` - `common` 仅可看到 `areas` 中当前 `user.area` 且 `enabled = true` 的模块。 ### 重要约束 地区过滤必须在后端完成,不能信前端传 area。 --- ## 7.3 RBAC 二次过滤 如果入口模块配置了 `route_path`,则需要再检查当前用户是否有该页面的访问权限。 ### 目的 避免出现: - 首页看得到入口 - 点进去却被 RBAC 拒绝 ### 推荐做法 基于当前用户角色集合,查询: - `sys_routes.route_path = route_path` - 是否被 `role_route` 授权 若未授权,则该入口模块不返回。 --- ## 7.4 文档类型过滤 ### 对 `module_type = document` 必须至少有一个启用中的文档类型,否则不返回。 ### 对 `module_type = assistant / cross_review` 允许没有文档类型,只要模块本身启用并通过权限检查即可返回。 --- ## 7.5 排序规则 建议优先级: 1. `areas[].sort_order`(如果当前地区有配置) 2. `leaudit_entry_modules.sort_order` 3. `id` --- ## 8. 前端必须删掉的旧逻辑 ## 8.1 不能再由前端自己查 `entry_modules` 当前旧逻辑: - 前端查入口模块 - 前端按地区过滤 - 前端再查文档类型 这会导致规则散落在前端,不利于后端统一治理。 应改为: - 前端只调用 `GET /api/home/entry-modules` --- ## 8.2 不能再按模块名硬编码跳转 当前风险逻辑: - 模块名包含“合同” -> `/contract-template/search` - 模块名是“智慧法务助手” -> `/chat-with-llm/chat` 这类逻辑必须移除。 应改为直接使用后端返回的: - `targetPath` --- ## 8.3 不能再在前端默认硬塞特殊模块 例如: - “智慧法务助手” 不应再由前端强行 `push()` 到入口列表里。 必须和普通模块一样进入 `leaudit_entry_modules` 正式配置。 这样做的好处: - 权限统一 - 排序统一 - 是否启用统一 - 图标统一 - 后台管理统一 --- ## 9. 当前逻辑遗漏点深度检查 下面是本次分析中确认存在或高概率会出现的遗漏点。 ## 9.1 首页可见 ≠ 页面可访问 这是老系统就存在的问题。 如果首页只按 `entry_modules` 过滤,不按 RBAC 再过滤,就会出现: - 首页看到入口 - 点进去又被页面权限拦住 ### 结论 首页接口必须做 RBAC 二次过滤。 --- ## 9.2 `path` 字段语义不稳定 老系统里 `entry_modules.path` 混杂: - 图片路径 - 资源路径 - 可能被误当成前端路由 ### 结论 新系统不能继续复用一个 `path` 字段承担两种含义。 必须拆成: - `icon_path` - `target_path` --- ## 9.3 特殊模块没有文档类型时会被误过滤 如果首页统一规则是“模块下必须有文档类型”,那么: - 智慧法务助手 - 交叉评查 这类模块会被错误隐藏。 ### 结论 必须引入: - `module_type` - `allow_empty_types` --- ## 9.4 省级管理员是否应该看到所有模块 这个规则必须固定,不然以后省级账号行为会不一致。 ### 建议 - `provincial_admin` 看全部已启用入口 - 但仍需受目标页面 RBAC 权限约束 --- ## 9.5 文档类型全部停用后,文档类入口是否显示 如果一个“合同管理”模块下面一个启用文档类型都没有,继续显示没有意义。 ### 建议 - `module_type = document` 且无可用文档类型 -> 不显示 - `assistant / cross_review` 不受此规则影响 --- ## 9.6 入口模块与左侧菜单不是同一概念 首页入口模块是“业务入口卡片”,左侧菜单是“页面路由树”。 如果不写清楚,后面会经常出现误解: - 为什么首页有入口,但侧边栏没有? - 为什么有路由权限,但首页不显示? ### 结论 文档中必须明确: - 首页入口 = 业务编排 - 左侧菜单 = RBAC 路由 --- ## 9.7 交叉评查专属模式不应混入入口模块业务规则 当前前端已有: - `CROSS_CHECKING_ONLY_MODE` 它本质上是部署态开关,不是入口模块自身规则。 ### 结论 该逻辑应作为部署模式单独处理,不要污染 `entry_modules` 基础语义。 --- ## 9.8 首页入口上下文仍然需要保留 即使首页入口最终完全由后端返回,前端仍然建议保留: - `selectedModuleId` - `selectedModuleName` - `documentTypeIds` 写入 `sessionStorage` ### 原因 后续页面仍然需要知道: - 当前用户是从哪个入口进入的 - 当前模块下允许哪些文档类型 --- ## 10. 新系统最终推荐方案 ## 10.1 强约束 新系统正式规则建议固定如下: 1. 首页入口只认 `leaudit_entry_modules` 2. 文档类型归属只认 `leaudit_document_types.entry_module_id` 3. 页面访问权限只认 `sys_routes + role_route` 4. API/动作权限只认 `permissions + role_permissions` 5. 首页入口列表必须由后端统一接口生成 6. 前端只能消费最终结果,不再自己拼规则 --- ## 10.2 最终推荐模型 ### 模块主数据 - `leaudit_entry_modules` ### 文档类型归属 - `leaudit_document_types.entry_module_id` ### 页面访问权限 - `sys_routes` - `role_route` ### 动作/API 权限 - `permissions` - `role_permissions` --- ## 10.3 首页统一接口 - `GET /api/home/entry-modules` 由后端返回: - 当前用户可见的入口模块 - 每个入口模块的目标跳转路径 - 每个入口模块挂载的文档类型列表 --- ## 11. 后续代码改造建议 本次先定方案,代码实现建议按以下顺序推进。 ### 阶段 1:后端收口 1. 新增首页入口接口 2. 后端实现地区过滤 3. 后端实现 RBAC 二次过滤 4. 后端挂载 `document_types` ### 阶段 2:前端收口 1. 首页改为只调用后端统一接口 2. 删除前端拼 `entry_modules + document_types` 的逻辑 3. 删除按模块名硬编码跳转 4. 删除前端默认注入“智慧法务助手” ### 阶段 3:表结构正式化 1. 给 `leaudit_entry_modules` 增加: - `module_key` - `target_path` - `route_path` - `module_type` - `allow_empty_types` 2. 若历史字段 `path` 仍在使用,则明确其迁移方向: - 老 `path` -> `icon_path` --- ## 12. 当前审阅建议 本方案建议你重点审阅以下 5 个点: 1. 是否同意“入口模块不是权限系统”的边界 2. 是否同意首页入口改为后端统一生成 3. 是否同意给 `entry_modules` 新增 `module_key / target_path / route_path / module_type / allow_empty_types` 4. 是否同意“智慧法务助手”这类特殊入口也必须正式落表 5. 是否同意“首页可见”和“页面可访问”保留两层校验,但由后端首页接口统一兜一次 --- ## 13. 一句话版最终结论 新系统应把“首页入口模块”正式定义为**首页业务入口编排层**,把“文档类型绑定”定义为**业务归类层**,把“页面/API权限”继续留在 **RBAC 层**,并由后端统一输出首页入口列表,彻底结束前端自己拼入口、自己判地区、自己硬编码跳转的旧模式。