From 18a3bfb50e87e70b276b7a831fa5ee6833396bba Mon Sep 17 00:00:00 2001 From: wangzhibiao Date: Fri, 18 Sep 2026 09:36:39 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=87=E6=A1=A3=E4=BC=98=E5=8C=96=EF=BC=9A?= =?UTF-8?q?=E5=B0=86=E6=A0=B8=E5=BF=83=E6=9E=B6=E6=9E=84=E4=B8=8E=E6=B5=81?= =?UTF-8?q?=E7=A8=8B=E5=AD=97=E7=AC=A6=E5=9B=BE=E8=BD=AC=E6=8D=A2=E4=B8=BA?= =?UTF-8?q?Mermaid?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/api-v2/01_api_design_principles.md | 10 +- docs/current/03-shared-trial.md | 24 ++-- docs/current/05-next-actions.md | 28 ++--- .../dms-r3/02_current_accommodation_audit.md | 41 ++++--- .../dms-r3/04_auth_and_token_strategy.md | 30 ++--- .../07_retry_idempotency_and_compensation.md | 21 +--- .../dms-r3/08_security_and_audit.md | 20 +--- .../dms-r3/10_api_and_ui_proposal.md | 24 ++-- .../dms-r3/11_testing_and_mock_plan.md | 20 ++-- .../development/dms-r3/14_decision_summary.md | 31 +++--- .../rbac-r2/03_data_scope_design.md | 103 ++++++------------ docs/development/rbac-r2/05_ui_design.md | 33 +++--- 12 files changed, 141 insertions(+), 244 deletions(-) diff --git a/docs/api-v2/01_api_design_principles.md b/docs/api-v2/01_api_design_principles.md index 5cbbdf99d..a2924a204 100644 --- a/docs/api-v2/01_api_design_principles.md +++ b/docs/api-v2/01_api_design_principles.md @@ -9,11 +9,11 @@ ### 1.1 拒绝单表 CRUD 堆砌 本系统是面向铁路培训基地的**智慧培训业务系统**,不是 21 张数据库表的 CRUD 管理后台。严禁出现以下反模式: -```text -一张数据库表 -→ 一个单表 Controller -→ 一个单表 Service -→ 一套单表 CRUD 页面 +```mermaid +flowchart TD + A["一张数据库表"] --> B["一个单表 Controller"] + B --> C["一个单表 Service"] + C --> D["一套单表 CRUD 页面"] ``` ### 1.2 业务工作台与聚合驱动 diff --git a/docs/current/03-shared-trial.md b/docs/current/03-shared-trial.md index bfd5fe51b..9365d6f4d 100644 --- a/docs/current/03-shared-trial.md +++ b/docs/current/03-shared-trial.md @@ -31,21 +31,15 @@ 为确保试用反馈高效闭环,请按以下流程反馈问题与建议: -```text -[试用人员发现问题/提出需求] - │ - ▼ -[记录现象截图与复现步骤] - │ - ▼ -[提交至项目微信群 / 试用问题登记表] - │ - ▼ -[研发团队定级分类] - ├── 🔴 BUG (功能缺陷) ── 即时排查,进入热修复流程 - ├── 🟡 UX (操作体验/展示优化) ── 纳入小版本 UI 优化 - ├── 🔵 KNOWN_GAP (已知缺口) ── 对齐 C03/C05 计划进度 - └── ⚪ REQUIREMENT (新增需求) ── 登记入《甲方需求确认清单》待甲方定级 +```mermaid +flowchart TD + A["试用人员发现问题 / 提出需求"] --> B["记录现象截图与复现步骤"] + B --> C["提交至项目微信群 / 试用问题登记表"] + C --> D["研发团队定级分类"] + D --> E1["🔴 BUG (功能缺陷)
即时排查,进入热修复流程"] + D --> E2["🟡 UX (操作体验/展示优化)
纳入小版本 UI 优化"] + D --> E3["🔵 KNOWN_GAP (已知缺口)
对齐 C03/C05 计划进度"] + D --> E4["⚪ REQUIREMENT (新增需求)
登记入《甲方需求确认清单》待甲方定级"] ``` --- diff --git a/docs/current/05-next-actions.md b/docs/current/05-next-actions.md index 65fef2102..82e4fc0ec 100644 --- a/docs/current/05-next-actions.md +++ b/docs/current/05-next-actions.md @@ -8,26 +8,14 @@ 后续研发与交付严格遵循以下反馈流转机制: -```text - ┌────────────────────────────────────────────────────────┐ - │ 1. 局域网共享试用 (http://192.168.139.230:8082/) │ - │ 段内业务老师与教务主管开展真实教学排课与考勤试用 │ - └─────────────────────────┬──────────────────────────────┘ - │ 发现问题/提出需求 - ▼ - ┌────────────────────────────────────────────────────────┐ - │ 2. 问题归类与定级 (Triage) │ - │ - 🔴 BUG : 阻断缺陷,当日修复并自动化回归 │ - │ - 🟡 UX : 界面与交互体验,周版本批次优化 │ - │ - 🔵 KNOWN_GAP : 归入已知技术缺口专项排期 │ - │ - ⚪ REQUIREMENT : 登记入甲方确认清单待批复 │ - └─────────────────────────┬──────────────────────────────┘ - │ 敏捷推进 - ▼ - ┌────────────────────────────────────────────────────────┐ - │ 3. 小版本迭代与发布 (Release Cycles) │ - │ 本地构建验证 → Surefire 全量通过 → 部署试用分支 │ - └────────────────────────────────────────────────────────┘ +```mermaid +flowchart TD + Step1["1. 局域网共享试用
段内业务老师与教务主管开展真实教学排课与考勤试用"] + Step2["2. 问题归类与定级 (Triage)
🔴 BUG:阻断缺陷,当日修复并自动化回归
🟡 UX:界面与交互体验,周版本批次优化
🔵 KNOWN_GAP:归入已知技术缺口专项排期
⚪ REQUIREMENT:登记入甲方确认清单待批复"] + Step3["3. 小版本迭代与发布 (Release Cycles)
本地构建验证 → Surefire 全量通过 → 部署试用分支"] + + Step1 -->|"发现问题 / 提出需求"| Step2 + Step2 -->|"敏捷推进"| Step3 ``` --- diff --git a/docs/development/dms-r3/02_current_accommodation_audit.md b/docs/development/dms-r3/02_current_accommodation_audit.md index b8407a41f..79e1f4d7c 100644 --- a/docs/development/dms-r3/02_current_accommodation_audit.md +++ b/docs/development/dms-r3/02_current_accommodation_audit.md @@ -77,28 +77,25 @@ 当前系统必须在概念模型与后续实现中**严格切分以下三个业务对象**,严禁混为一谈: -``` -+-----------------------------------------------------------------------------+ -| A. 物理宿舍资源 (Dormitory Resource - train_dormitory_info) | -| - 物理属性:楼栋、楼层、房间号、核定床位容量、适用性别、房间可用/停用状态 | -| - 生命周期:独立于任何培训班和学员,长期相对稳定 | -+-----------------------------------------------------------------------------+ - ▲ - │ 1 间宿舍可容纳多个住宿安排 -+-----------------------------------------------------------------------------+ -| B. 住宿业务事实 (Accommodation - train_accommodation) | -| - 业务属性:某个学员参训档案 (enrollment_id) 在本次开班中分配到了哪个房间与床位 | -| - 状态流转:预分配 (0) -> 已入住 (1) -> 已退宿 (2) | -| - 事实归属:RailwaySystem 是本业务的绝对 Source of Truth (事实唯一真源) | -+-----------------------------------------------------------------------------+ - ▲ - │ 1 条住宿事实产生门禁授权要求 -+-----------------------------------------------------------------------------+ -| C. 门锁设备授权 (Door Authorization - 门禁授权模型) | -| - 设备属性:基于该住宿事实,向 DMS 门锁下发的有效时间区间与电子钥匙凭据 (密码/卡片) | -| - 状态流转:待下发 -> 平台已受理 -> 设备执行中 -> 设备生效 -> 撤销中 -> 已注销 | -| - 属性特征:依赖外部网络与硬件状态,可异步重试,失败不推翻住宿业务事实 | -+-----------------------------------------------------------------------------+ +```mermaid +flowchart TB + subgraph LayerA["A. 物理宿舍资源 (train_dormitory_info)"] + direction TB + A1["物理属性:楼栋、楼层、房间号、核定床位容量、适用性别、房间可用/停用状态
生命周期:独立于任何培训班和学员,长期相对稳定"] + end + + subgraph LayerB["B. 住宿业务事实 (train_accommodation)"] + direction TB + B1["业务属性:学员参训档案 (enrollment_id) 在本次开班中分配到的房间与床位
状态流转:预分配 (0) -> 已入住 (1) -> 已退宿 (2)
事实归属:RailwaySystem 是本业务的绝对 Source of Truth (事实唯一真源)"] + end + + subgraph LayerC["C. 门锁设备授权 (门禁授权模型)"] + direction TB + C1["设备属性:向 DMS 门锁下发的有效时间区间与电子钥匙凭据 (密码/卡片)
状态流转:待下发 -> 平台已受理 -> 设备执行中 -> 设备生效 -> 撤销中 -> 已注销
属性特征:依赖外部网络与硬件状态,可异步重试,失败不推翻住宿业务事实"] + end + + LayerB -->|"1 间宿舍可容纳多个住宿安排"| LayerA + LayerC -->|"1 条住宿事实产生门禁授权要求"| LayerB ``` --- diff --git a/docs/development/dms-r3/04_auth_and_token_strategy.md b/docs/development/dms-r3/04_auth_and_token_strategy.md index 4d2bd8e67..5cb97e3a6 100644 --- a/docs/development/dms-r3/04_auth_and_token_strategy.md +++ b/docs/development/dms-r3/04_auth_and_token_strategy.md @@ -113,26 +113,16 @@ sequenceDiagram 当由于外部原因(例如运维人员在第三方控制台手动注销、或 DMS 服务端异常重启导致 Session 丢失)出现 `401 Unauthorized` 时的处理规范: -``` -业务请求触发调用 - │ - ▼ -使用本地 Token 调用 DMS API - │ - ├─────────────────────────────────┐ - ▼ [成功 200 OK] ▼ [失败 401 Unauthorized] -正常返回业务数据 立即令本地缓存的 Token 失效 (invalidate) -通知 TokenManager.touch() 延展寿命 │ - ▼ - 单飞排他锁获取新 Token (Single-Flight Login) - │ - ├─────────────────────────┐ - ▼ [重登录成功] ▼ [重登录失败] - 安全重试原始业务请求 (最多 1 次) 标记操作失败 (FAILED) - │ 记录审计日志 - ├──────────────┐ 不影响本地住宿业务事实 - ▼ [重试成功] ▼ [依然401] - 成功返回 熔断抛出异常 +```mermaid +flowchart TD + Start["业务请求触发调用"] --> CallDms["使用本地 Token 调用 DMS API"] + CallDms -->|"成功 200 OK"| Success1["正常返回业务数据
通知 TokenManager.touch() 延展寿命"] + CallDms -->|"失败 401 Unauthorized"| Invalidate["立即令本地缓存的 Token 失效 (invalidate)"] + Invalidate --> SingleFlight["单飞排他锁获取新 Token (Single-Flight Login)"] + SingleFlight -->|"重登录成功"| Retry["安全重试原始业务请求 (最多 1 次)"] + SingleFlight -->|"重登录失败"| LoginFail["标记操作失败 (FAILED)
记录审计日志
不影响本地住宿业务事实"] + Retry -->|"重试成功"| Success2["成功返回"] + Retry -->|"依然 401"| CircuitBreak["熔断抛出异常"] ``` ### 5.1 恢复红线守则 diff --git a/docs/development/dms-r3/07_retry_idempotency_and_compensation.md b/docs/development/dms-r3/07_retry_idempotency_and_compensation.md index 8d93e707d..a94239e12 100644 --- a/docs/development/dms-r3/07_retry_idempotency_and_compensation.md +++ b/docs/development/dms-r3/07_retry_idempotency_and_compensation.md @@ -11,22 +11,11 @@ - 官方文档明示:**“门锁的实际执行结果,务必在调用相关操作后 10 秒查询”**。 - **严重红线**:绝对禁止在 Web 请求线程(Controller/Service)中执行 `Thread.sleep(10000)`!这会迅速耗尽 Tomcat 工作线程池,引发系统雪崩。 - **轮询架构设计**: - ``` - Web 请求 (如确认入住) - │ - ▼ - 本地持久化 Accommodation (已入住) 与 DoorAuthorization (ISSUING) - 提交本地数据库事务 (Commit Local DB) - │ - ▼ - 异步派发调用 DMS 创建钥匙 -> 返回 operationId (耗时 ~200ms) - 本地记录 ExternalOperationRecord (status = ACCEPTED, next_poll_time = now + 10s) - 快速向前端返回 HTTP 200 (附带提示:“住宿已分配,门锁授权下发中”) - │ - ▼ - 后台调度引擎 (Quartz / Spring Scheduled ThreadPool - 专用IO线程池) - 扫描 next_poll_time <= NOW() 的任务 -> 调用 /doorlock/query-operation-status - 更新操作记录与授权记录状态 -> 若为 success 则推为 ACTIVE + ```mermaid + flowchart TD + Req["Web 请求 (如确认入住)"] --> LocalDB["本地持久化 Accommodation (已入住) 与 DoorAuthorization (ISSUING)
提交本地数据库事务 (Commit Local DB)"] + LocalDB --> AsyncDms["异步派发调用 DMS 创建钥匙 -> 返回 operationId (耗时 ~200ms)
本地记录 ExternalOperationRecord (status = ACCEPTED, next_poll_time = now + 10s)
快速向前端返回 HTTP 200 (附带提示:“住宿已分配,门锁授权下发中”)"] + AsyncDms --> Scheduler["后台调度引擎 (Quartz / Spring Scheduled ThreadPool - 专用IO线程池)
扫描 next_poll_time <= NOW() 的任务 -> 调用 /doorlock/query-operation-status
更新操作记录与授权记录状态 -> 若为 success 则推为 ACTIVE"] ``` ### 1.2 门锁 vs 网关轮询参数隔离 diff --git a/docs/development/dms-r3/08_security_and_audit.md b/docs/development/dms-r3/08_security_and_audit.md index 187ce5450..b2dda8604 100644 --- a/docs/development/dms-r3/08_security_and_audit.md +++ b/docs/development/dms-r3/08_security_and_audit.md @@ -35,20 +35,12 @@ 官方文档对在线卡片(`POST /rest/doorlock/online-card/create`)的卡号规定了非常特殊的**小端字节序十六进制转换规则**: -``` -[读卡器读取 10 进制原始卡号] - │ - ▼ 例: 3161082660 -[转成标准 16 进制大端串] - │ - ▼ 例: BC 6A 4B 24 -[不足 8 位时高位补零] - │ - ▼ 例: 09 99 ED 24 -[低位在前的字节序逆序转换 (Little-Endian)] - │ - ▼ 例: 24 4B 6A BC (或 24 ED 99 09) -[送入 DMS API 的 cardNumber 参数] +```mermaid +flowchart TD + Step1["读卡器读取 10 进制原始卡号"] -->|"例: 3161082660"| Step2["转成标准 16 进制大端串"] + Step2 -->|"例: BC 6A 4B 24"| Step3["不足 8 位时高位补零"] + Step3 -->|"例: 09 99 ED 24"| Step4["低位在前的字节序逆序转换 (Little-Endian)"] + Step4 -->|"例: 24 4B 6A BC 或 24 ED 99 09"| Step5["送入 DMS API 的 cardNumber 参数"] ``` ### 2.1 架构封装纪律 diff --git a/docs/development/dms-r3/10_api_and_ui_proposal.md b/docs/development/dms-r3/10_api_and_ui_proposal.md index e7e9b3d46..967a4f07f 100644 --- a/docs/development/dms-r3/10_api_and_ui_proposal.md +++ b/docs/development/dms-r3/10_api_and_ui_proposal.md @@ -96,23 +96,13 @@ ## 5. DMS 资源映射与同步管理界面设计 (`Resource Sync UI`) ### 5.1 房源对齐工作流 -``` -[管理员进入"门锁资源映射"界面] - │ - ▼ -[点击"从DMS拉取房源目录"] - │ - ▼ 适配器调用 POST /rest/place/room/list -[系统解析出 DMS 的 Building, Floor, Room, placeId, 挂载的 lockId, 硬件SN] - │ - ▼ -[系统依据"楼栋-楼层-房间"名称执行规则预匹配] - │ - ▼ -[管理员在界面核对预配对结果, 确认手动微调后点击"确认持久化绑定"] - │ - ▼ -[写入 train_external_resource_mapping, 完成两套系统物理基线的稳定锁定] +```mermaid +flowchart TD + Step1["管理员进入“门锁资源映射”界面"] --> Step2["点击“从 DMS 拉取房源目录”"] + Step2 -->|"适配器调用 POST /rest/place/room/list"| Step3["系统解析出 DMS 的 Building, Floor, Room, placeId, 挂载的 lockId, 硬件SN"] + Step3 --> Step4["系统依据“楼栋-楼层-房间”名称执行规则预匹配"] + Step4 --> Step5["管理员在界面核对预配对结果,确认手动微调后点击“确认持久化绑定”"] + Step5 --> Step6["写入 train_external_resource_mapping,完成两套系统物理基线的稳定锁定"] ``` - **核心保障**:同步操作仅建立与更新映射表,**绝不自动删除或篡改本地 `train_dormitory_info` 的基础房源台账**。本地房源依然是学员管理系统的独立主数据。 diff --git a/docs/development/dms-r3/11_testing_and_mock_plan.md b/docs/development/dms-r3/11_testing_and_mock_plan.md index f5164012f..f888ce59c 100644 --- a/docs/development/dms-r3/11_testing_and_mock_plan.md +++ b/docs/development/dms-r3/11_testing_and_mock_plan.md @@ -8,16 +8,16 @@ ## 1. 分层测试策略体系 (Testing Strategy) -``` -+--------------------------------------------------------------------------------+ -| L4. 现场沙箱验收测试 (Live Sandbox E2E - 独立测试账号 + 实验台独立挂载测试锁) | -+--------------------------------------------------------------------------------+ -| L3. 契约与故障注入测试 (WireMock Failure Injection - 401/超时/宕机/乱序状态) | -+--------------------------------------------------------------------------------+ -| L2. 并发与状态机集成测试 (Concurrency & State Machine Test - 20并发Token竞争/幂等) | -+--------------------------------------------------------------------------------+ -| L1. 纯领域单元测试 (Unit Test - CardNumberCodec 编码 / 状态机转换 / DTO 转换) | -+--------------------------------------------------------------------------------+ +```mermaid +flowchart BT + L1["L1. 纯领域单元测试
Unit Test - CardNumberCodec 编码 / 状态机转换 / DTO 转换"] + L2["L2. 并发与状态机集成测试
Concurrency & State Machine Test - 20并发Token竞争/幂等"] + L3["L3. 契约与故障注入测试
WireMock Failure Injection - 401/超时/宕机/乱序状态"] + L4["L4. 现场沙箱验收测试
Live Sandbox E2E - 独立测试账号 + 实验台独立挂载测试锁"] + + L1 --> L2 + L2 --> L3 + L3 --> L4 ``` --- diff --git a/docs/development/dms-r3/14_decision_summary.md b/docs/development/dms-r3/14_decision_summary.md index aba751930..5dab9b0dc 100644 --- a/docs/development/dms-r3/14_decision_summary.md +++ b/docs/development/dms-r3/14_decision_summary.md @@ -75,23 +75,20 @@ ## 5. 推荐技术架构设计 -``` -[前端 Accommodation / 个人中心] - │ - ▼ -[业务领域层: 住宿分配 / 换房补偿 / 报到联动] <--- 绝对 Source of Truth - │ - ▼ (通过强类型 DTO,完全屏蔽外部厂商细节) -[中立网关接口: DoorAccessGateway (grant / revoke / query)] - │ - ▼ (SPI 模式) -[DMS 集成适配器: DmsDoorAccessGateway] - ├── DmsTokenManager: 进程级单飞排他锁 (防并发覆盖踩踏) - ├── 细分 HTTP 客户端: PlaceClient / DoorLockClient / KeyClient / OpClient - └── DmsOperationPoller: 后台 10 秒对账调度器 (解除 HTTP 线程阻塞) - │ - ▼ (HTTPS / Cookie 传递 token) -[外部 DMS 物联网平台: https://dms.dmsiot.com] +```mermaid +flowchart TD + UI["前端 Accommodation / 个人中心"] --> Domain["业务领域层: 住宿分配 / 换房补偿 / 报到联动
(绝对 Source of Truth)"] + Domain -->|"通过强类型 DTO,屏蔽外部厂商细节"| Gateway["中立网关接口: DoorAccessGateway
(grant / revoke / query)"] + + subgraph Adapter["DMS 集成适配器: DmsDoorAccessGateway (SPI 模式)"] + direction TB + TM["DmsTokenManager: 进程级单飞排他锁 (防并发覆盖踩踏)"] + Clients["细分 HTTP 客户端: PlaceClient / DoorLockClient / KeyClient / OpClient"] + Poller["DmsOperationPoller: 后台 10 秒对账调度器 (解除 HTTP 线程阻塞)"] + end + + Gateway --> Adapter + Adapter -->|"HTTPS / Cookie 传递 token"| External["外部 DMS 物联网平台: https://dms.dmsiot.com"] ``` --- diff --git a/docs/development/rbac-r2/03_data_scope_design.md b/docs/development/rbac-r2/03_data_scope_design.md index f72afa7c4..0a4dd255e 100644 --- a/docs/development/rbac-r2/03_data_scope_design.md +++ b/docs/development/rbac-r2/03_data_scope_design.md @@ -10,27 +10,20 @@ 在多角色(Admin, Teacher, Student)登录体系中,数据范围安全必须建立在**零信任前端参数**的基石之上: -``` -+─────────────────────────────────────────────────────────────────────────────+ -| 零信任推导核心防线 (Secure Chain) | -| | -| 客户端 HTTP Request | -| │ (仅携带 Bearer JWT Token,禁止/忽略 query 或 body 中的 identityId) | -| ▼ | -| Spring Security Filter: JwtAuthenticationTokenFilter | -| │ (验签并提取 claims 中的 userId) | -| ▼ | -| SecurityContextHolder.getContext().getAuthentication() | -| │ (获取受信任的 LoginUser.getUserId()) | -| ▼ | -| Service 内部数据推导 (SecurityContextHelper) | -| ├─ 若拥有 train_teacher 角色: | -| │ SELECT t_id FROM train_teacher WHERE user_id = #{userId} | -| ├─ 若拥有 train_student 角色: | -| │ SELECT s_id FROM train_student WHERE user_id = #{userId} | -| └─ 若拥有 admin / train_admin 角色: | -| 按管理员角色规则放行或基于组织机构过滤 | -+─────────────────────────────────────────────────────────────────────────────+ +```mermaid +flowchart TD + Req["客户端 HTTP Request
(仅携带 Bearer JWT Token,禁止/忽略 query 或 body 中的 identityId)"] + Filter["Spring Security Filter: JwtAuthenticationTokenFilter
(验签并提取 claims 中的 userId)"] + SecCtx["SecurityContextHolder.getContext().getAuthentication()
(获取受信任的 LoginUser.getUserId())"] + Helper["Service 内部数据推导 (SecurityContextHelper)"] + + Req --> Filter + Filter --> SecCtx + SecCtx --> Helper + + Helper -->|"拥有 train_teacher 角色"| TeacherRole["SELECT t_id FROM train_teacher WHERE user_id = #{userId}"] + Helper -->|"拥有 train_student 角色"| StudentRole["SELECT s_id FROM train_student WHERE user_id = #{userId}"] + Helper -->|"拥有 admin / train_admin 角色"| AdminRole["按管理员角色规则放行或基于组织机构过滤"] ``` ### 1.1 核心铁律 @@ -44,30 +37,16 @@ 教师登录后,其可访问的所有教学资源必须严格基于其受聘授课关系动态推导: -``` - ┌──────────────────────┐ - │ sys_user (userId) │ - └──────────┬───────────┘ - │ WHERE user_id = #{userId} - ▼ - ┌──────────────────────┐ - │ train_teacher (t_id)│ - └──────────┬───────────┘ - │ - ┌───────────────────────┼────────────────────────┐ - │ (排课直接授课) │ (计划课程关联) │ (关联教学班级) - ▼ ▼ ▼ -┌──────────────────┐ ┌──────────────────┐ ┌──────────────────┐ -│timetable_lesson │ │train_plan_course │ │ train_class_plan │ -│WHERE teacher_id │ │WHERE teacher_id │ │ WHERE plan_id IN │ -│ = #{t_id} │ │ = #{t_id} │ │ (授课班级集合) │ -└────────┬─────────┘ └──────────────────┘ └────────┬─────────┘ - │ │ - ▼ ▼ -┌──────────────────┐ ┌──────────────────┐ -│student_checkin │ │training_enrollment -│(本人课次考勤流水) │ │(我带的班级学员名单)│ -└──────────────────┘ └──────────────────┘ +```mermaid +flowchart TD + User["sys_user (userId)"] -->|"WHERE user_id = #{userId}"| Teacher["train_teacher (t_id)"] + + Teacher -->|"排课直接授课"| Lesson["timetable_lesson
WHERE teacher_id = #{t_id}"] + Teacher -->|"计划课程关联"| PlanCourse["train_plan_course
WHERE teacher_id = #{t_id}"] + Teacher -->|"关联教学班级"| ClassPlan["train_class_plan
WHERE plan_id IN (授课班级集合)"] + + Lesson --> Checkin["student_checkin
(本人课次考勤流水)"] + ClassPlan --> Enrollment["training_enrollment
(我带的班级学员名单)"] ``` - **授课课表数据**: 仅能查到 `train_timetable_lesson.teacher_id = #{currentTeacherId}` 的课次。 @@ -80,29 +59,17 @@ 学员登录后,进入极简个人培训中心,数据范围完全收敛于“本人”: -``` - ┌──────────────────────┐ - │ sys_user (userId) │ - └──────────┬───────────┘ - │ WHERE user_id = #{userId} - ▼ - ┌──────────────────────┐ - │ train_student (s_id)│ - └──────────┬───────────┘ - │ - ┌─────────────┬───────────────┼───────────────┬─────────────┐ - ▼ ▼ ▼ ▼ ▼ -┌───────┐ ┌──────────────┐ ┌───────────┐ ┌──────────────┐ ┌────────────┐ -│ 个人 │ │ 参训班级名单 │ │ 个人报到 │ │ 个人考勤记录 │ │ 个人画像/ │ -│ 档案 │ │ Enrollment │ │ Report │ │ Checkin │ │ 学时累计 │ -│(只读) │ │WHERE s_id=...│ │WHERE s_id │ │WHERE s_id=...│ │WHERE s_id │ -└───────┘ └──────┬───────┘ └───────────┘ └──────────────┘ └────────────┘ - │ - ▼ - ┌──────────────┐ - │ 班级参训课表 │ - │(仅限正常在训)│ - └──────────────┘ +```mermaid +flowchart TD + User["sys_user (userId)"] -->|"WHERE user_id = #{userId}"| Student["train_student (s_id)"] + + Student --> Profile["个人档案 (只读)"] + Student --> Enrollment["参训班级名单 (Enrollment)
WHERE s_id = ..."] + Student --> Report["个人报到 (Report)
WHERE s_id = ..."] + Student --> Checkin["个人考勤记录 (Checkin)
WHERE s_id = ..."] + Student --> Portrait["个人画像 / 学时累计
WHERE s_id = ..."] + + Enrollment --> Timetable["班级参训课表
(仅限正常在训)"] ``` - **学员档案**: 仅能读取与更新本人通讯电话、邮箱。 diff --git a/docs/development/rbac-r2/05_ui_design.md b/docs/development/rbac-r2/05_ui_design.md index c85c3f235..cb9263fb7 100644 --- a/docs/development/rbac-r2/05_ui_design.md +++ b/docs/development/rbac-r2/05_ui_design.md @@ -35,26 +35,19 @@ 系统全员使用同一个登录入口 `http://192.168.139.230:8082/login`。用户验证成功颁发 JWT 后,前端路由守卫(`permission.js`)执行如下分流重定向策略: -``` - 用户输入账号密码 - │ - ▼ - POST /login (200 OK) - │ - ▼ - GET /getInfo (拉取 roles 与 permissions) - │ - ▼ - 角色判定 (Role Branching) - │ - ┌───────────────────────────┼───────────────────────────┐ - ▼ ▼ ▼ -拥有 admin 或 train_admin 拥有 train_teacher 拥有 train_student - │ │ │ - ▼ ▼ ▼ - Landing 重定向至: Landing 重定向至: Landing 重定向至: - /index /train/teacher/dashboard /train/student/portal - (系统综合驾驶舱) (教师授课工作台) (学员个人培训中心) +```mermaid +flowchart TD + LoginInput["用户输入账号密码"] --> PostLogin["POST /login (200 OK)"] + PostLogin --> GetInfo["GET /getInfo (拉取 roles 与 permissions)"] + GetInfo --> RoleBranch["角色判定 (Role Branching)"] + + RoleBranch --> BranchAdmin["拥有 admin 或 train_admin"] + RoleBranch --> BranchTeacher["拥有 train_teacher"] + RoleBranch --> BranchStudent["拥有 train_student"] + + BranchAdmin --> LandingAdmin["Landing 重定向至:
/index (系统综合驾驶舱)"] + BranchTeacher --> LandingTeacher["Landing 重定向至:
/train/teacher/dashboard (教师授课工作台)"] + BranchStudent --> LandingStudent["Landing 重定向至:
/train/student/portal (学员个人培训中心)"] ``` - **兜底方案 (Fallback)**: 若用户被赋予复合角色或自定义角色,前端自动跳转至 `asyncRoutes` 生成的动态路由树的第一个叶子节点页面,杜绝 404 或白屏。