Files
leaudit-platform-backend/docs/入口模块/入口模块绑定最终设计方案.md
2026-05-09 20:04:08 +08:00

16 KiB
Raw Permalink Blame History

入口模块绑定最终设计方案

适用项目: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 建议返回结构

{
  "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.areaenabled = 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 层,并由后端统一输出首页入口列表,彻底结束前端自己拼入口、自己判地区、自己硬编码跳转的旧模式。