1 parent
417c076465
commit
35751b4f00
144 files changed
+13905
-342
No files matched your search
@@ -100,6 +100,40 @@
|
||||
| 权威关系 | 阶段划分与验收仍以 `公寓端/07` 为准,业务规则 / 状态 / 接口仍以 CR-02 §11~§15 为准;`15` 只记实现、验证、口径偏离与影响范围 |
|
||||
| **变更点与影响范围** | 新增 1 篇交付说明与 1 个 M0 验收脚本;同步 `公寓端/README.md`、`公寓端/14` 表 14-23、`docs/README.md` 与 CR-02 表 0-2 **v1.8**;不改动 CR-02 §12~§15 权威表述、不新增既有编号,跨端 20 编号、`v2-draft`、平台零回调、59 张表不变;**契约冻结签字与 `D5` 签字仍为 P0 待办** |
|
||||
|
||||
### 第三轮开发(IT-2)交付(2026-11-11)
|
||||
|
||||
| 项 | 内容 |
|
||||
| --- | --- |
|
||||
| 文档 | [公寓端/16-第三轮开发(IT-2)交付说明.md](./公寓端/16-第三轮开发(IT-2)交付说明.md)(v1.0,**实现说明,非设计变更**) |
|
||||
| 范围 | M1 交路 CRUD / 启停原因审计 / 复算校验、M2 房间档案 / 房态 / `state_version` / `commandId` 幂等、主数据下行 Mock 灌数与版本标记(`/apt/master/versions`)、审计独立事务与参数校验异常分派;不含人员关联 Tab 与叫乘;前端页面已补齐,见 `公寓端/16` 第 10 章与下文「公寓端前端页面」段 |
|
||||
| 验证 | `mvn package` 7 模块 `BUILD SUCCESS`;79 个单测全绿;`dev/sql/apt_rev01/10~12` 实库执行与校验通过;`dev/scripts/verify-it2-m1m2.ps1` 真实进程端到端 **24/24 通过**(第 9 章模块归置后新增 M0-5 配置导入校验) |
|
||||
| 权威关系 | 阶段划分与验收仍以 `公寓端/07` 为准,业务规则 / 状态 / 接口仍以 CR-02 §11~§15 为准;`16` 只记实现、验证、口径偏离与影响范围 |
|
||||
| **变更点与影响范围** | 新增 1 篇交付说明与 2 个脚本(SQL 重放、端到端验收);同步 `公寓端/README.md`、`公寓端/14` 表 14-23、`公寓端/15` 表 15-17、`docs/README.md` 与 CR-02 表 0-2 **v1.9**;不改动 CR-02 §12~§15 权威表述、不新增既有编号,跨端 20 编号、`v2-draft`、平台零回调、59 张表不变;**契约冻结 / `D5` / `D8'` / `D3` / `D7` 签字仍为 P0 待办** |
|
||||
|
||||
### 公寓端集中模块 `ruoyi-apt`(2026-11-11)
|
||||
|
||||
| 项 | 内容 |
|
||||
| --- | --- |
|
||||
| 模块 | `dev/RuoYi-Vue-master/ruoyi-apt`(Maven jar,包 `com.ruoyi.apt.**`);64 个公寓端文件从 4 个旧模块统一迁入 |
|
||||
| 职责 | 四前缀接口、业务逻辑、上下文与错误码、拦截器与鉴权、审计、`apt.*` 配置、Mapper XML、79 个测试、前端静态资源挂载点 |
|
||||
| 结构定位 | 上层业务模块:依赖 `ruoyi-common` / `ruoyi-framework`(传递 `ruoyi-system`),被唯一启动模块 `ruoyi-admin` 依赖;`ruoyi-framework` 仅按 Spring Security 接口 + bean 名运行时装配 401/403 处理器,编译期零反向依赖 |
|
||||
| 前端 / 运维边界 | Vue 源码已落在 `dev/RuoYi-Vue2-master/src/views/apt/**`(§2.5 前端落地口径:单入口 + `sys_menu` 动态路由),构建产物可挂载到模块内 `static/apt/`;DDL 与验收脚本保持 `dev/sql/apt_rev01`、`dev/scripts` 原位,不进 Maven jar |
|
||||
| 验证 | `mvn -pl ruoyi-admin -am clean package` 7 模块 `BUILD SUCCESS`;79 个单测全绿;`verify-it2-m1m2.ps1` 端到端 **24/24 通过**(含 `apt-defaults.yml` 导入与 springdoc 分组校验) |
|
||||
| 权威落点 | [公寓端/02](./公寓端/02-技术基线与工程结构.md) §2.5(表 2-14 / 2-15、图 2-3)、[公寓端/16](./公寓端/16-第三轮开发(IT-2)交付说明.md) 第 9 章(归置清单、图 16-2、验证) |
|
||||
| **非设计变更** | 只调整实现层模块归属与构建配置;不改动 CR-02 §12~§15 权威表述、不新增既有编号,跨端 20 编号、`v2-draft`、平台零回调、59 张表不变 |
|
||||
|
||||
### 公寓端前端页面补齐(2026-11-11)
|
||||
|
||||
| 项 | 内容 |
|
||||
| --- | --- |
|
||||
| 范围 | 只补齐 `IT-0`~`IT-2` 已有后端 Controller 的 4 个功能域:交路、房间、主数据版本、连通性自检;`IT-3`~`IT-11` 仅设计页面不建(判据见 `公寓端/16` 表 16-25) |
|
||||
| 页面 | `dev/RuoYi-Vue2-master/src/views/apt/`:4 个菜单列表页 + 2 个隐藏详情页;API 在 `src/api/apt/**`,公共常量 / 错误提示 / 导出在 `src/utils/apt.js` |
|
||||
| 规范 | 与 `system/post`、`system/user` 同构:`.app-container` + 查询 `el-form` + `el-row.mb8` 按钮区 + `el-table` + `pagination` + `el-dialog`;复用 `Pagination` / `RightToolbar` / `DictTag`、Element 语义色与主题变量、`v-hasPermi`、`$modal`、`rules` 校验、`v-loading`、响应式栅格与小屏全屏弹窗 |
|
||||
| 路由与菜单 | `dev/sql/apt_rev01/13_it2_frontend_menus.sql` 新增 4 条 `C` 菜单(3101~3104),由 `getRouters` 下发、已实库执行;详情页走 `dynamicRoutes` 并按权限过滤 |
|
||||
| 未开放能力 | 房间新增 / 删除 / 导入 / 主数据重同步以禁用态 + tooltip 如实呈现;导出为前端 CSV(后端无 `/export`,不伪造接口) |
|
||||
| 验证 | `npm run build:prod` `exitCode=0`;菜单树 `M=1 / C=4 / F=15`、超管关联 4、置灰项 0、M0 账号 0;lints 0 |
|
||||
| 权威落点 | [公寓端/16](./公寓端/16-第三轮开发(IT-2)交付说明.md) 第 10 章(表 16-25~16-30、图 16-3)、[公寓端/02](./公寓端/02-技术基线与工程结构.md) §2.5 前端落地口径、CR-02 表 0-2 **v2.1** |
|
||||
|
||||
## 建议阅读路径
|
||||
|
||||
- **第一次接触项目**:01 → 02 → 03 → 04;再看前端 01 → 02 → 04。
|
||||
|
||||
@@ -136,6 +136,85 @@ flowchart TD
|
||||
**代价**:`sys_menu` 里登记的 apt 菜单 `component` 不参与路由渲染,只作为权限点载体,需在菜单备注中写明。
|
||||
该细化列入 `08` §4 待确认(差-7)。
|
||||
|
||||
### 2.5 实现层公寓端集中模块 `ruoyi-apt`(2026-11-11 归置)
|
||||
|
||||
> §2.1 的 12 模块是**设计期的逻辑划分**;实际工程复用 RuoYi-Vue 上游后,`IT-0`~`IT-2` 的公寓端代码曾分散在
|
||||
> `ruoyi-common` / `ruoyi-framework` / `ruoyi-system` / `ruoyi-admin` 四个 Maven 模块中。为集中管理,
|
||||
> 现新增单一 Maven 模块 **`ruoyi-apt`**,把全部公寓端实现收拢到 `com.ruoyi.apt.**` 包下。
|
||||
> 本节为实现层说明,**不改变** §2.1 的设计口径与 `docs/10` 表 4-3。
|
||||
|
||||
表 2-14 `ruoyi-apt` 职责范围
|
||||
|
||||
| 类别 | 归置内容 | 落点 | 边界 |
|
||||
| --- | --- | --- | --- |
|
||||
| 接口 | `/apt/route/**`、`/apt/room/**`、`/apt/master/**`、`/apt/ops/**` 全部 Controller | `src/main/java/com/ruoyi/apt/{master,stay,ops}/controller` | 不含 `/system/**`、`/duty/**`、`/open/v1/**`(后者仅预留) |
|
||||
| 业务逻辑 | 交路 CRUD / 启停 / 复算,房间档案 / 房态重算 / `state_version`,主数据版本只读 | `.../apt/{master,stay}/service` | 不改 59 张表口径;`room_status` 只由领域服务写 |
|
||||
| 上下文与错误码 | `AptContext`、`AptErrorCode`、`AptException`、`AptPageSupport`、`AptTableDataInfo` | `.../apt/common` | `gyid` 只由服务端注入 |
|
||||
| 框架适配 | 四前缀拦截器、`WebMvcConfig`、401/403 处理器、异常分派、审计切面、`AptProperties`、Mock 启动护栏 | `.../apt/framework`、`.../apt/infra` | 只承接公寓端;非公寓端路径委托 RuoYi 原行为 |
|
||||
| 配置项 | `apt.*`(`gy-id` / `probe` / `page` / `master-client`)、springdoc 三个分组、`com.ruoyi.apt` 日志级别 | `src/main/resources/apt-defaults.yml` | 由 `ruoyi-admin/application.yml` 用 `spring.config.import: optional:classpath:apt-defaults.yml` 引入 |
|
||||
| 持久层 | 4 个 Mapper 接口 + 4 个 `mapper/apt/*.xml` | `.../apt/*/mapper`、`src/main/resources/mapper/apt` | 每条 SQL 带 `gyid`;`classpath*:mapper/**/*Mapper.xml` 通配加载 |
|
||||
| 前端资源 | 静态资源挂载点 `src/main/resources/static/apt/` | 模块内 | **Vue 源码不进 Maven jar**:前端源码已落在 `dev/RuoYi-Vue2-master/src/views/apt/**`(API 在 `src/api/apt/**`,路由在 `src/router/index.js`),由 `sys_menu` 的 4 条 `C` 菜单经 `getRouters` 动态下发;构建产物可输出到该挂载目录 |
|
||||
| 测试 | 79 个 JUnit5/Mockito 用例(含架构约束与 SQL 静态校验) | `src/test/java/com/ruoyi/apt` | 测试随模块走,不再落在 `ruoyi-admin` |
|
||||
| 不纳入 | DDL / 种子 / 权限点 SQL、PowerShell 验收脚本、`.env` 凭据 | 仍在 `dev/sql/apt_rev01`、`dev/scripts`、`dev/.env` | 工程级运维资产,由模块文档登记与驱动,但不参与 Maven 打包 |
|
||||
|
||||
表 2-15 `ruoyi-apt` 与既有模块的依赖 / 被依赖关系
|
||||
|
||||
| 关系 | 对象 | 内容与依据 |
|
||||
| --- | --- | --- |
|
||||
| **依赖** | `ruoyi-common` | `AjaxResult` / `TableDataInfo` / `SecurityUtils`、Spring Security、Validation、PageHelper、fastjson2、Redis、MyBatis 传递 |
|
||||
| **依赖** | `ruoyi-framework` | Spring WebMVC、AspectJ、Druid、`SecurityConfig`、`AuthenticationEntryPointImpl`、`BaseController`、`@Anonymous` |
|
||||
| **依赖(传递)** | `ruoyi-system` | 经 `ruoyi-framework` 传递;模块内不直接引用 `com.ruoyi.system.**` 业务类 |
|
||||
| **依赖** | 第三方 | `mybatis-spring-boot-starter`、`spring-tx`、`spring-boot-starter-test`(test) |
|
||||
| **被依赖** | `ruoyi-admin` | 启动模块显式声明 `ruoyi-apt`,使其进入 classpath 与 `ruoyi-admin.jar` fat jar |
|
||||
| **被引用(运行时)** | `ruoyi-framework` | `SecurityConfig` 按 Spring Security 标准接口 + bean 名 `aptAuthenticationEntryPoint` / `aptAccessDeniedHandler` 装配,**编译期不 import 任何 `com.ruoyi.apt.*` 类**,避免循环依赖 |
|
||||
| **无依赖** | `ruoyi-quartz`、`ruoyi-generator` | 两者与公寓端完全解耦 |
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
ADMIN["ruoyi-admin<br/>唯一启动模块 / fat jar"] --> APT["ruoyi-apt<br/>公寓端集中模块"]
|
||||
APT --> FRAME["ruoyi-framework<br/>安全链 / AOP / MVC"]
|
||||
APT --> COMMON["ruoyi-common<br/>基础工具 / Security / Validation"]
|
||||
FRAME --> SYS["ruoyi-system"]
|
||||
SYS --> COMMON
|
||||
ADMIN --> QUARTZ["ruoyi-quartz"]
|
||||
ADMIN --> GEN["ruoyi-generator"]
|
||||
QUARTZ --> COMMON
|
||||
GEN --> COMMON
|
||||
FRAME -.->|"运行时按 bean 名装配 401/403 处理器<br/>编译期零依赖"| APT
|
||||
APT --> RES["apt-defaults.yml<br/>mapper/apt/*.xml<br/>static/apt/**"]
|
||||
FE["RuoYi-Vue2-master<br/>src/views/apt(前端源码)"] -.->|"构建产物挂载"| RES
|
||||
FE -.->|"getRouters 下发路由<br/>/apt/** 请求"| APT
|
||||
OPS["dev/sql/apt_rev01<br/>dev/scripts"] -.->|"运维驱动,不进 Maven jar"| APT
|
||||
```
|
||||
|
||||
图 2-3 `ruoyi-apt` 在整体工程中的定位与模块关系(箭头为编译期依赖,虚线为运行时/工程级关联)
|
||||
|
||||
构建识别与引用调整(保证模块可被正确加载):
|
||||
|
||||
1. 根 `pom.xml`:`<modules>` 增加 `ruoyi-apt`;`<dependencyManagement>` 按 `${ruoyi.version}` 登记其版本。
|
||||
2. `ruoyi-admin/pom.xml`:显式依赖 `ruoyi-apt`;Maven 反应堆顺序为 `common → system → framework → apt → admin`(单向无环)。
|
||||
3. 包扫描:启动类 `@SpringBootApplication` 位于 `com.ruoyi`,自动覆盖 `com.ruoyi.apt.**`;`ApplicationConfig` 的
|
||||
`@MapperScan("com.ruoyi.**.mapper")` 与 `mybatis.mapperLocations: classpath*:mapper/**/*Mapper.xml` 均为通配,
|
||||
无需改包名;`typeAliasesPackage: com.ruoyi.**.domain` 同理。
|
||||
4. 配置:`apt-defaults.yml` 由主配置 `spring.config.import` 引入;`optional:` 前缀保证模块缺失时后台仍可启动。
|
||||
springdoc `packages-to-scan` 用包名 `com.ruoyi.apt`(不使用 Ant 通配),否则分组 `paths` 为空。
|
||||
5. 迁移后必须 `mvn clean package`:`classpath*:mapper/**/*Mapper.xml` 会同时命中旧模块 `target/classes` 残留,
|
||||
导致 MyBatis 重复注册 MappedStatement;仅 `package` 不清 target 会启动失败。
|
||||
|
||||
**前端落地口径(2026-11-11 补齐,权威记录见 `16` 第 10 章)**:§2.1 与 `docs/10` 表 2-3(差-7)描述的是
|
||||
「单工程双入口 + `entries/apt` 静态路由表」的**设计期**形态;而本仓库实际上游 `RuoYi-Vue2-master` 是标准
|
||||
**单入口**工程(无 `src/entries/`、`vue.config.js` 无 `pages` 配置,`src/main.js` 为唯一挂载点)。本期前端页面
|
||||
因此落在 `src/views/apt/**`,与 `system/user` 等既有页面同构:
|
||||
|
||||
- 菜单:`dev/sql/apt_rev01/13_it2_frontend_menus.sql` 新增 4 条 `menu_type='C'` 记录(3101~3104,`parent_id=3000`),
|
||||
由后端 `getRouters` 下发,`permission.js` 的 `loadView('@/views/' + component)` 懒加载;业务页不写进 `constantRoutes`。
|
||||
- 详情:`src/router/index.js` 的 `dynamicRoutes` 增加 2 条 `hidden` 路由,按 `permissions` 过滤,`activeMenu` 回指列表页。
|
||||
- 权限:按钮级 `v-hasPermi` 复用 `F` 权限点 3001~3015;菜单可见性由 `sys_role_menu` 控制。
|
||||
- 范围:只补齐已有后端 Controller 的交路 / 房间 / 版本 / 连通性自检 4 个功能域;`IT-3`~`IT-11` 的设计页面不建。
|
||||
|
||||
该选择是实现层对设计期口径的偏离(`16` 偏离项 16-19),**不改** §2.1 与 `docs/10` 的权威表述;
|
||||
若后续真要落地双入口,需先完成前端工程改造并另行评审。
|
||||
|
||||
## 3. 分层与编码规范
|
||||
|
||||
### 3.1 请求链路
|
||||
|
||||
+8
-1
@@ -195,17 +195,24 @@
|
||||
| 1 叫乘中 | 30s 无入会(本地超时) | 2 叫乘报警 | `jcbjsj_s`、`is_jcbj='1'`、写 `gy_bjxx` | `docs/10` §7.9 超时口径 |
|
||||
| 2 叫乘报警 | 复叫入会 | 3 已应答待离寓 | `fjsj_s`、`hjxysj`、`finish_jc='1'` | 表 7-5 复叫 |
|
||||
| 2 叫乘报警 | 人工"停止叫乘" | 2(保持)+ `stoped='1'` | `stoped` | `docs/10` 表 2-3 `duty:call:stop` |
|
||||
| 2 叫乘报警(或 `stoped='1'` 的任意态) | 人工"复叫"命令(`RE_CALL`) | 1 叫乘中 | 清除 `stoped`、`ryzt=1`、`jcsj_s`、新增一行 `apt_call_session` | 表 4-3 `apt.duty.state`、`04` 命令矩阵 |
|
||||
| 0 待叫乘 | 人工"取消叫乘"命令(`CANCEL`) | 0(保持)+ `stoped='1'` | `stoped` | 同上 |
|
||||
| 0/1 | 平板 `TABLET_RESULT`:`ANSWERED` + `VERIFIED`(平板上报) | 3 已应答待离寓 | `hjxysj`、`finish_jc='1'` | `05` 表 5-20、CR-02 表 3-16 |
|
||||
| 1 | 平板 `TABLET_RESULT`:`NO_ANSWER` / `FAILED`(含签到窗口超时,由平板上报) | 2 叫乘报警 | `jcbjsj_s`、`is_jcbj='1'`、写 `gy_bjxx(TIMEOUT)` | `05` 表 5-20 |
|
||||
| 0/1/2 | 平板 `TABLET_RESULT`:`ANSWERED` + `UNVERIFIED` / `SKIPPED`(平板上报) | 保持当前 `ryzt`(复叫 + 告警) | 不改状态字段,只记 `duty_operation_log` / 告警 | `05` 表 5-20、Q-22 |
|
||||
| 任意 | 平板 `TABLET_RESULT` 迟到 / 重复 | 保持(`IGNORED`) | 只记 `apt_tablet_call_result.applied_state='IGNORED'` | `05` 表 5-20 |
|
||||
| 3 已应答 | 会议桥通话开始 | 5 通话中 | — | 表 5-3 `apt_call_session.state` |
|
||||
| 5 通话中 | 挂断 | 3 | — | 同上 |
|
||||
| 3 已应答 | 超时未离寓 | 4 离寓报警 | `lybjsj`、`is_lybj='1'` | 表 4-3 `apt.duty.engine` |
|
||||
| 任意 | 离寓事件(设备/人脸/人工) | 保持 `ryzt`,置离寓 | `finish_ly='1'`、`sjlysj`、`leave_type`、`leave_event_id` | `docs/05` 离寓语义 |
|
||||
| 任意 | 人工"强制结束" | 保持,置结束 | `finish_jc='1'`、`finish_ly='1'` | `duty_manual_action.action_type=FORCE_FINISH` |
|
||||
|
||||
三条保护语义(沿用存量,`docs/10` §5.4 处理关系第 3 条):
|
||||
三条保护语义与一条平板链路约束(沿用存量,`docs/10` §5.4 处理关系第 3 条):
|
||||
|
||||
1. **已结束叫乘不回写**:`finish_jc='1'` 后到达的迟到事件只记 `apt_call_event`,不改 `ryzt`。
|
||||
2. **已离寓不回写**:`finish_ly='1'` 后不因叫乘事件回到"待叫乘"。
|
||||
3. **停止叫乘不可逆至报警**:`stoped='1'` 后只允许人工"重新叫乘"命令清除,不允许超时判定自动改。
|
||||
4. **平板模式无内部自动迁移**:`call_mode='TABLET'` 的 `ryzt` 迁移只由平板上报结果(N-04 `TABLET_RESULT`)触发,服务端不做定时自动迁移;签到窗口超时同样由平板上报 `NO_ANSWER`。
|
||||
|
||||
### 3.3 分机资源状态机
|
||||
|
||||
|
||||
+2
-2
@@ -573,9 +573,9 @@ sequenceDiagram
|
||||
| SIP 接通 | `ConfbridgeJoin` | `ANSWERED` | `ryzt=3`、`finish_jc='1'`、`hjxysj` | #9 `DUTY_RESULT` + #24 | `state.changed(1→3)` + `session.changed` |
|
||||
| SIP 无应答 | 30s 无入会 / `OriginateResponse.Failure` | `CALL_FAILED` | `ryzt=2`、`jcbjsj_s`、`is_jcbj='1'` | #9 + #12 | `alarm.raised(NO_ANSWER)` + 复叫 |
|
||||
| 平板刷脸签到 | `ANSWERED` + `VERIFIED` | `ANSWERED` | `ryzt=3`、`finish_jc='1'` | #9 `TABLET_RESULT` | `tablet.result` + `state.changed` |
|
||||
| 平板未刷脸 | `ANSWERED` + `UNVERIFIED` / `SKIPPED` | 保持待确认 + 复叫 | `ryzt` 不变(超窗口转 `2`) | #9 + #12 | `tablet.result` + `alarm.raised` |
|
||||
| 平板未刷脸 | `ANSWERED` + `UNVERIFIED` / `SKIPPED` | 保持待确认 + 复叫 | `ryzt` 不变(签到窗口超时由平板上报 `NO_ANSWER`,服务端不自动迁移) | #9 + #12 | `tablet.result` + `alarm.raised` |
|
||||
| 平板无应答 | `NO_ANSWER` / `FAILED` | `CALL_FAILED` | `ryzt=2` | #9 | `alarm.raised` + 复叫 |
|
||||
| 任务取消 | `CANCELLED` | `STOP`(值班台) | `stoped='1'`,`ryzt` 不变 | #9 | `state.changed` |
|
||||
| 任务取消 | `CANCELLED` | `STOP`(`ryzt in (1,2)` 时)/ `CANCEL`(`ryzt=0` 时) | `stoped='1'`,`ryzt` 不变 | #9 | `state.changed` |
|
||||
| 迟到 / 重复结果 | 任意 | `IGNORED` | 不回写 | 不重复上报 | 只记留痕(`applied_state=IGNORED`) |
|
||||
|
||||
### 9.6 与既有章节的关系与待决策
|
||||
|
||||
@@ -206,7 +206,7 @@ flowchart LR
|
||||
| `matchState` | `PENDING` / `MATCHED` / `UNMATCHED` / `LOCKED` / `REJECTED` | 沿用 `docs/设计变更/01` 表 1-17 正式五值;`LOCAL_ONLY` 属 `offlineScope`,**不是**匹配状态 |
|
||||
| `origin` | `CHECKIN_ROUTE` / `CHECKIN_PENDING` / `LOCAL_ASSIGN` / `LOCAL_TEMP_EXTRA` / `LOCAL_ADJUST` | 交路可确定时取 `CHECKIN_ROUTE`,否则 `CHECKIN_PENDING` |
|
||||
| `reviewVerdict` | `APPROVE` / `APPROVE_WITH_ROOM_CHANGE` / `REJECT` | N-44 审核命令 |
|
||||
| `faceVerifyState` | `VERIFIED` / `UNVERIFIED` / `NOT_FOUND` | 与 CR-02 表 3-16 同字典 |
|
||||
| `faceVerifyState` | `VERIFIED` / `UNVERIFIED` / `SKIPPED` | 与 CR-02 表 3-16 同字典;只用于平板叫乘时人员刷脸进行**叫乘结果确认**,**不是**入住核验结论(核验未命中用 `personFound=false` 表达) |
|
||||
| `eventType` | `CHECKIN` / `CHECKOUT` / `ROOM_SWAP` | CR-02 表 3-14 |
|
||||
| `source` | `DEVICE` / `DUTY` / `SELF` | CR-02 表 3-14 |
|
||||
|
||||
@@ -223,7 +223,7 @@ flowchart LR
|
||||
| 触发 | 人员在签到终端发起"扫脸办理入住";终端按设备凭据 + HMAC + ±5 min 时间窗 + `nonce` 调用 N-38 |
|
||||
| 数据范围 | 设备凭据解析出的 `gyid` / `deviceCode`、`deviceEventId`、现场比对结论(`faceVerifyState` / `verifiedRyid` / `featureVersion`)、`occurredAt`;**不上传抓拍帧、人脸原图、比对帧** |
|
||||
| 前置 | 设备已注册且人脸缓存为 `SYNCED`(`docs/公寓端/10` §6);同一 `(deviceCode, deviceEventId)` 未处理过 |
|
||||
| 不触发 | 仅查询、心跳、缓存摘要上报;`faceVerifyState=NOT_FOUND` 且人员明确拒绝注册 |
|
||||
| 不触发 | 仅查询、心跳、缓存摘要上报;比对未命中(`personFound=false`)且人员明确拒绝注册 |
|
||||
|
||||
表 11-11 身份核验步骤
|
||||
|
||||
@@ -264,7 +264,7 @@ flowchart LR
|
||||
|
||||
| 场景 | 处理 | 不做什么 |
|
||||
| --- | --- | --- |
|
||||
| 比对未命中 `NOT_FOUND` | 返回 `REGISTER_REQUIRED` 并引导 N-34 注册 | 不自动建人员、不建申请单 |
|
||||
| 比对未命中(`personFound=false`) | 返回 `REGISTER_REQUIRED` 并引导 N-34 注册 | 不自动建人员、不建申请单 |
|
||||
| 注册申请未确认 `APPLIED` | `40914`(CR-C25),返回 `REG_PENDING` + `regId` | 不参与入住、不参与运安匹配 |
|
||||
| 设备人脸缓存过期 | `40927` 要求 `FACE_FULL_SYNC` 后重试 | 不用过期缓存放行 |
|
||||
| 抓拍上传 / 凭据越 `gyid` | `40919` / `40301` 拒收并记审计 | 不落库、不生成待办 |
|
||||
|
||||
@@ -185,6 +185,11 @@ flowchart LR
|
||||
| 交付物 `DV-2` | Controller/Service/Mapper/DTO/VO/页面/路由/权限点;Mock 灌数脚本(3 交路 / 5 房间 / 5 人员 / 2 天计划);表 7-6 的 M1/M2 用例记录 |
|
||||
| 验收标准 | 缺 `cc`/`kcsj`/`reason` → 40001 且指出字段;同 `jlid` 重复 → 40901;停用审计 `duty_operation_log` 含原因;房态筛选只返回 `room_status=4`;停用后恢复触发重算且 `state_version` 递增;快照字段改 `xm` → 40904;Mock 数据标记 `source=LOCAL` / `source_version=0` |
|
||||
|
||||
> **实现层注记(2026-11-11)**:本表「对齐代码模块」的 `src/entries/apt/views/{route,room}` 与 `ruoyi-system` 内业务包均为**设计期**口径。
|
||||
> 实际交付:后端统一归置到 `ruoyi-apt` 模块(`16` 第 9 章);前端因实际上游 `RuoYi-Vue2-master` 为标准单入口,
|
||||
> 页面落在 `src/views/apt/**`、由 `sys_menu` 4 条 `C` 菜单动态下发路由(`16` 第 10 章、`02` §2.5)。
|
||||
> 本表设计口径不变,偏离登记见 `16` 偏离项 16-19。
|
||||
|
||||
表 13-13 `IT-3` 人脸注册与签到核验最小闭环(2 周)
|
||||
|
||||
| 项 | 内容 |
|
||||
|
||||
@@ -48,6 +48,9 @@
|
||||
| `sql/apt_rev01` | `dev/sql/apt_rev01/*.sql` | 59 张业务表结构、幂等补列、可重放种子、验收校验 | DDL 与回填分离;不建外键;不含真实凭据 | MySQL 9.5 |
|
||||
| `ci` | `.github/workflows/it0-verify.yml` | 编译 / 单测 / 明文凭据扫描卡口 | 不执行 DDL、不连生产库 | GitHub Actions |
|
||||
|
||||
> **归置说明(2026-11-11)**:本表为 IT-0 当时的代码落点记录。当前全部公寓端 Java / Mapper XML / 测试已统一迁入
|
||||
> `dev/RuoYi-Vue-master/ruoyi-apt`(`com.ruoyi.apt.**`),职责、定位与依赖见 `公寓端/02` §2.5 与 `公寓端/16` 第 9 章。
|
||||
|
||||
图 14-1 模块依赖(单向,无环)
|
||||
|
||||
```mermaid
|
||||
@@ -386,7 +389,8 @@ graph TD
|
||||
| 迭代 | 本轮提供的前置 | 下一轮要做 |
|
||||
| --- | --- | --- |
|
||||
| `IT-1` M0 运行时基座 | 错误码 / gyid 上下文 / 四前缀中 `/apt/**` 拦截器骨架 / 测试与 CI | **已完成**:四前缀拦截器与 `/open/v1/**` 放行、401/403 处理器、统一错误码与真实 HTTP 状态、审计切面、分页上限、权限点种子、只读列表骨架、41 个单测与端到端 M0 5/5;见 `公寓端/15` |
|
||||
| `IT-2`~`IT-3` | 59 张表结构、幂等补列脚本 | 主数据 / 房间 / 人脸最小闭环业务代码(落 `ruoyi-system`) |
|
||||
| `IT-2` M1 + M2 | 59 张表结构、幂等补列脚本 | **已完成**:交路 / 房间 / 主数据版本只读、Mock 灌数与版本标记、79 个单测与端到端 24/24;见 `公寓端/16` |
|
||||
| `IT-3` | 59 张表结构、幂等补列脚本 | 人脸注册最小闭环业务代码(落 `ruoyi-system`) |
|
||||
| `IT-4`~`IT-5` | `apt_local_task` / `gy_jcxx` 结构、单一状态写入口约束 | 入住 CI-01~CI-05、叫乘状态机 M3 |
|
||||
| `IT-9`~`IT-11` 延后域 | 账务 6 张表**已建结构但不开放读写**、错误码与权限点可预埋 | 阶段三退出 + `D1/D2/P-07/Q-41~Q-45` 决策后再开 `/apt/ledger/**` |
|
||||
|
||||
|
||||
@@ -59,6 +59,10 @@
|
||||
| 配置 | `SecurityConfig`、`application.yml`、`application-druid.yml` | 过滤器链、springdoc 分组、数据源与 Redis | 凭据一律外置,不落明文 |
|
||||
| SQL | `09_it1_permissions.sql` | 只写 `sys_*` 框架表的权限点种子 | 不触碰 59 张业务表 |
|
||||
|
||||
> **归置说明(2026-11-11)**:本表为 IT-1 当时的代码落点记录。当前公寓端代码、Mapper XML、测试与 `apt.*` 配置
|
||||
> 已统一迁入 `dev/RuoYi-Vue-master/ruoyi-apt`;`SecurityConfig` 改为按 Spring Security 接口 + bean 名装配,
|
||||
> 编译期不再依赖公寓端类。见 `公寓端/02` §2.5 与 `公寓端/16` 第 9 章。
|
||||
|
||||
图 15-1 依赖方向
|
||||
|
||||
```mermaid
|
||||
@@ -260,3 +264,5 @@ flowchart LR
|
||||
| 需补 | `BindException` / `MethodArgumentNotValidException` 的非公寓端类型分派;审计写入独立事务;只读骨架 Controller 迁入 `com.ruoyi.apt.master.*` |
|
||||
| 回归 | 表 7-3 M1/M2、表 7-6 八类用例 M0~M2 部分;本文件表 15-14 的 M0 五项须持续全绿 |
|
||||
| 延后 | `IT-9`~`IT-11` 消费 / 充值 / 菜品,本期不开 `/apt/ledger/**`、不建 `com.ruoyi.apt.ledger` 包 |
|
||||
|
||||
> **进度同步(2026-11-11)**:`IT-2` 已完成(含本表「需补」三项),79 个单测与端到端 24/24 通过;详见 `公寓端/16` 表 16-2 / 16-15 / 16-16。
|
||||
@@ -0,0 +1,545 @@
|
||||
# 16 第三轮开发(IT-2)交付说明
|
||||
|
||||
> 文档定位:IT-2「交路、房间与主数据快照可读可管」(M1 + M2)的实现说明与验收记录,对应 `13` 表 13-12 / DV-2。
|
||||
> 版本:v1.1 | 2026-11-11(v1.1 追加第 10 章「前端页面补齐」,同步表 16-1 / 16-17 / 16-19 / 16-21)
|
||||
> 环境:MySQL `apt_rev01`(`dev/.env`)、Redis `database=1`、JDK 24 / Maven 3.8.x / Spring Boot 4.1.0、Windows PowerShell 5.1
|
||||
> 上位依据:`07` 表 7-2/7-3/7-6/7-7、`04` 表 4-5/4-7/4-17、`03` §4、`09` 表 9-16、`13` 表 13-12/13-21/13-22、`15` 表 15-15/15-17
|
||||
> 权威关系:本文只记录实现与验证结果,**不改变** `02`~`09` 的设计口径;与 `13`/`15` 不一致时以 `07` 验收标准和 `04` 接口契约为准,偏离项在第 7 章登记。
|
||||
|
||||
---
|
||||
|
||||
## 1. 交付概览与验收对照
|
||||
|
||||
### 1.1 交付物清单(DV-2)
|
||||
|
||||
| 编号 | 交付物 | 落点 | 状态 |
|
||||
|---|---|---|---|
|
||||
| DV-2-1 | M1 交路 CRUD、启停、复算校验 | `ruoyi-apt/.../apt/master`(领域 + Controller) | 完成 |
|
||||
| DV-2-2 | M2 房间档案、房态、停用/恢复、`state_version` | `ruoyi-apt/.../apt/stay` | 完成 |
|
||||
| DV-2-3 | 主数据快照版本只读与 Mock 标记 | `ruoyi-apt/.../apt/master` / `/apt/master/versions` | 完成 |
|
||||
| DV-2-4 | IT-1 遗留项闭环(审计独立事务、参数校验异常分派) | `ruoyi-apt/.../apt/framework` | 完成 |
|
||||
| DV-2-5 | 幂等 DDL 补列 + 中文注释修复 | `dev/sql/apt_rev01/10_it2_columns.sql` | 完成 |
|
||||
| DV-2-6 | Mock 灌数与版本标记校验 | `dev/sql/apt_rev01/11_it2_seed.sql` | 完成 |
|
||||
| DV-2-7 | IT-2 权限点种子与校验 | `dev/sql/apt_rev01/12_it2_permissions.sql` | 完成 |
|
||||
| DV-2-8 | SQL 重放执行脚本 | `dev/scripts/apply-it2-sql.ps1` | 完成 |
|
||||
| DV-2-9 | 真实进程端到端验收脚本 | `dev/scripts/verify-it2-m1m2.ps1` | 完成 |
|
||||
| DV-2-10 | 回归测试 | `ruoyi-apt/src/test`(79 用例) | 完成 |
|
||||
| DV-2-11 | 本交付说明与索引同步 | 本文 + `README` / `14` / `15` / CR-02 表 0-2 | 完成 |
|
||||
| DV-2-12 | `ruoyi-apt` 集中模块归置 | `dev/RuoYi-Vue-master/ruoyi-apt`(本文第 9 章) | 完成 |
|
||||
| DV-2-13 | 公寓端前端页面、API 层、菜单与路由 | `dev/RuoYi-Vue2-master/src/{api,views,router}`、`dev/sql/apt_rev01/13_it2_frontend_menus.sql`(本文第 10 章) | 完成 |
|
||||
|
||||
表 16-1 IT-2 交付物清单(DV-2)
|
||||
|
||||
### 1.2 表 13-12 验收标准逐条对照
|
||||
|
||||
| # | `13` 表 13-12 验收标准 | 本轮结果 | 证据 |
|
||||
|---|---|---|---|
|
||||
| 1 | 缺 `cc` / `kcsj` / `reason` → `40001` 且指出具体字段 | 达成 | `AptRouteServiceTest`、`AptRoomServiceTest`、端到端 M1-4/M2-6 |
|
||||
| 2 | 同 `jlid` 再次新增 → `40901` | 达成 | 端到端 M1-3(HTTP 409 / 40901) |
|
||||
| 3 | 停用写 `duty_operation_log` 且 `detail` 含原因 | 达成 | `AptRouteController.writeReasonAudit`、`AptRoomController.writeStatusAudit`、端到端 M1-6 |
|
||||
| 4 | 选「不能入住」只返回 `room_status=4` | 达成 | 端到端 M2-2(rows=1,全部 `roomStatus=4`) |
|
||||
| 5 | 恢复触发重算,`state_version` 递增 | 达成 | 端到端 M2-7 / M2-10(`v=3→4→5`) |
|
||||
| 6 | 改平台下发字段(如 `xm`)→ `40904` | **部分达成,登记偏离** | 房间侧 `roomFloor` / `bedNumbers` / `sourceVersion` → `40904`(M2-5);人员 `xm` 编辑属 M4,不在 IT-2 范围 |
|
||||
| 7 | Mock 数据标 `source='LOCAL'` / `source_version=0` | 达成 | `11` 校验段 `local_applied_domains=6`、端到端 M2-12 |
|
||||
|
||||
表 16-2 表 13-12 验收标准逐条对照
|
||||
|
||||
### 1.3 前置条件与 Go / No-Go
|
||||
|
||||
| 前置 | `13` / `15` 要求 | 实际状态 | 开工处理 |
|
||||
|---|---|---|---|
|
||||
| IT-1 M0 六项验收 | 全部通过 | 通过(`15` 表 15-13,端到端 5/5) | 无 |
|
||||
| D8' / D3 / D7 口径签字 | 编码前完成 | **未签字(P0)** | 用户显式推进,按「带条件开工」登记 |
|
||||
| 契约冻结(表 9-6) | 编码前完成 | **未冻结(P0)** | 同上;`#1~#4` 以本地 Mock 替代 |
|
||||
| 技术基线 | JDK 1.8 / Boot 2.5.15(IR-01) | JDK 24 / Boot 4.1.0 | 沿用 IT-1 已核准的偏离 |
|
||||
| 数据库 / Redis / 59 张表 | 可用 | 可用,`dev/.env` 已提供凭据 | 无 |
|
||||
| `APT_TOKEN_SECRET` | Base64 且解码 ≥64 字节 | `.env` 仅 39 字节 | 端到端脚本进程内生成临时密钥,不写回 `.env` |
|
||||
|
||||
表 16-3 前置条件与 Go / No-Go 状态
|
||||
|
||||
> **结论**:IT-2 的实现与验证已闭环,但 P0 签字类前置仍未满足;本轮仍属「带条件开工」交付,不得据此认定设计口径已冻结。
|
||||
|
||||
---
|
||||
|
||||
## 2. 模块与分层
|
||||
|
||||
| 层 | 包 / 目录(第 9 章归置后) | 职责 | 关键约束 |
|
||||
|---|---|---|---|
|
||||
| 集中模块 | `ruoyi-apt/src/main/java/com/ruoyi/apt/**` | 公共基础 / 框架适配 / 主数据 / 房态 / 接口全部内聚 | 单一 Maven 模块,包路径 `com.ruoyi.apt.**` 不变 |
|
||||
| 公共基础 | `ruoyi-apt/.../apt/common` | `AptContext`、`AptErrorCode`、`AptException`、`AptTableDataInfo` | `gyid` 只由服务端注入;列表追加 `warnings[]` |
|
||||
| 框架适配 | `ruoyi-apt/.../apt/framework` | 四前缀拦截器、鉴权、异常分派、审计切面、Mock 开关护栏 | 审计 `REQUIRES_NEW`;非 `local` 禁用 Mock |
|
||||
| 主数据 | `ruoyi-apt/.../apt/master` | 交路领域、版本只读 | 每条 SQL 带 `gyid`;平台快照字段只读 |
|
||||
| 房态 | `ruoyi-apt/.../apt/stay` | 房间档案、房态重算、幂等命令 | `room_status` 仅由领域服务条件更新 |
|
||||
| 接口 | `ruoyi-apt/.../apt/{master,stay,ops}/controller` | `/apt/route/**`、`/apt/room/**`、`/apt/master/**` | 权限点 + 原因审计 + `AptBaseController` 分页上限 |
|
||||
| 配置与资源 | `ruoyi-apt/src/main/resources`(`apt-defaults.yml`、`mapper/apt/*.xml`、`static/apt/`) | 公寓端配置、Mapper XML、前端静态资源挂载点 | `spring.config.import` 引入;`classpath*:mapper/**/*Mapper.xml` 通配 |
|
||||
| 工程级资产 | `dev/sql/apt_rev01/10~12`、`dev/scripts/*` | DDL 补列、Mock 灌数、权限点、实库重放、端到端 | 不进 Maven jar;UTF-8 字节流;独立端口 8099 |
|
||||
|
||||
表 16-4 IT-2 模块与分层(第 9 章归置后的实际落点)
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
Admin["ruoyi-admin<br/>启动 / fat jar"] --> Apt["ruoyi-apt<br/>四前缀接口 + 业务 + 配置"]
|
||||
Framework["ruoyi-framework<br/>安全链 / AOP / MVC"] -. "按 bean 名装配 401/403" .-> Apt
|
||||
Common["ruoyi-common<br/>基础工具 / Security / Validation"] --> Framework
|
||||
Apt --> Framework
|
||||
Apt --> DB[(MySQL apt_rev01)]
|
||||
SQL["dev/sql/apt_rev01 10~12"] --> DB
|
||||
E2E["verify-it2-m1m2.ps1"] --> Admin
|
||||
```
|
||||
|
||||
图 16-1 IT-2 依赖与数据流向(第 9 章归置后)
|
||||
|
||||
---
|
||||
|
||||
## 3. M1 交路管理
|
||||
|
||||
### 3.1 字段映射(不改 59 张表口径)
|
||||
|
||||
| 表 4-5 字段 | DDL 列 | 说明 |
|
||||
|---|---|---|
|
||||
| `jlid` | `jlid` | 业务唯一键 |
|
||||
| `jch` | `route_name` | 交路名 |
|
||||
| `qd` / `zd` | `start_station` / `end_station` | 起止站 |
|
||||
| `cc` / `kcsj` | `cc` / `kcsj` | 车次 / 开车时刻 |
|
||||
| `jcsj` / `lysj` | 本轮补列 | 叫乘 / 离寓时刻基线 |
|
||||
| `enabled` | `state` | `ACTIVE` / `STOPPED` |
|
||||
| `sourceVersion` | `source_version` | 平台下发版本 |
|
||||
| `cclx` / `bz` | 本轮补列 | 车次类型 / 备注 |
|
||||
|
||||
表 16-5 M1 字段映射
|
||||
|
||||
### 3.2 接口清单
|
||||
|
||||
| # | 方法 / 路径 | 权限点 | 关键行为 |
|
||||
|---|---|---|---|
|
||||
| 1 | `GET /apt/route/list` | `apt:route:list` | 分页上限、`jch/qd/zd/enabled` 映射 |
|
||||
| 2 | `GET /apt/route/options` | `apt:route:query` | 下拉选项 |
|
||||
| 3 | `GET /apt/route/{id}` | `apt:route:query` | 详情 |
|
||||
| 4 | `POST /apt/route` | `apt:route:add` | 新增;`jlid` 重复 `40901` |
|
||||
| 5 | `PUT /apt/route/{id}` | `apt:route:edit` | 编辑;快照字段 `40904` |
|
||||
| 6 | `PUT /apt/route/{id}/status` | `apt:route:changeStatus` | 启停,原因写入审计 |
|
||||
| 7 | `POST /apt/route/{id}/recalc-check` | `apt:route:query` | 只算不落库 |
|
||||
|
||||
表 16-6 M1 接口清单(表 4-5 #1~#7)
|
||||
|
||||
### 3.3 校验、错误码与复算
|
||||
|
||||
| 场景 | 错误码 | HTTP |
|
||||
|---|---|---|
|
||||
| 缺 `cc` / `kcsj` / 时序错误 | `40001 PARAM_INVALID` | 400 |
|
||||
| `jlid` 重复 | `40901 DUPLICATE_KEY` | 409 |
|
||||
| 改平台下发字段(`sourceVersion` / `createTime`) | `40904 SNAPSHOT_READONLY` | 409 |
|
||||
| 启停缺 `reason` | `40001 PARAM_INVALID` | 400 |
|
||||
|
||||
表 16-7 M1 校验与错误码
|
||||
|
||||
| 规则 | 取值 |
|
||||
|---|---|
|
||||
| 叫乘提前量 | `CALL_TIME` 规则;无规则时默认 120 分钟,节假日 180 分钟 |
|
||||
| `computedJcsj` | `kcsj - 提前量` |
|
||||
| `computedFjsj` | `computedJcsj - wakeMinutes` |
|
||||
| 返回 | `diffMs`、`warnings[]`,**不落库** |
|
||||
|
||||
表 16-8 M1 复算规则(表 7-3 M1、D8')
|
||||
|
||||
---
|
||||
|
||||
## 4. M2 房间档案与房态
|
||||
|
||||
### 4.1 接口清单
|
||||
|
||||
| # | 方法 / 路径 | 权限点 | 关键行为 |
|
||||
|---|---|---|---|
|
||||
| 1 | `GET /apt/room/list` | `apt:room:list` | `building` 降级楼层前缀 + `warnings[]`;`roomStatus` 多选 |
|
||||
| 2 | `GET /apt/room/{id}` | `apt:room:query` | 分机绑定 / 在寓人员 / 最近保洁任务 |
|
||||
| 3 | `GET /apt/room/status-summary` | `apt:room:list` | 房态汇总卡片 |
|
||||
| 4 | `PUT /apt/room/{id}` | `apt:room:edit` | 仅本地属性;快照字段 `40904` |
|
||||
| 5 | `PUT /apt/room/{id}/status` | `apt:room:changeStatus` | 停用 / 恢复,`commandId` 幂等 |
|
||||
| 6 | `POST /apt/room` | `apt:room:add` | G-01/G-04 未定稿,恒 `40940` |
|
||||
|
||||
表 16-9 M2 接口清单(表 4-7 #1~#6)
|
||||
|
||||
### 4.2 房态与 state_version
|
||||
|
||||
| 动作 | `room_status` | `disabled_reason` | `state_version` | 在寓人员 |
|
||||
|---|---|---|---|---|
|
||||
| `DISABLE` | 置 `4` | 写入 `reason` | `+1` | 不改动、不停叫乘 |
|
||||
| `RESTORE` | 重算 | 清空 | 再 `+1` | 不改动 |
|
||||
| 重复 `commandId` | 不变 | 不变 | 不变 | 不变 |
|
||||
|
||||
表 16-10 停用 / 恢复语义(表 7-3 M2)
|
||||
|
||||
重算优先级:有效保洁任务 `PROCESSING` → `6`;`PENDING` → `3`;在寓人数 `0` → `1`;`in_person_count >= bed_count` → `2`;否则 `5`。汇总卡片 `cleaning` 合并状态码 `3` 与 `6`。
|
||||
|
||||
| 场景 | 错误码 | HTTP |
|
||||
|---|---|---|
|
||||
| 缺 `reason` / 非法 `action` / 空编辑体 | `40001` | 400 |
|
||||
| 改 `bedNumbers` / `roomFloor` / `sourceVersion` | `40904` | 409 |
|
||||
| 重复停用 / 恢复非停用房 | `40902` | 409 |
|
||||
| `state_version` 条件更新命中 0 行 | `40903` | 409 |
|
||||
| 新增房间 / 主数据全量重拉 | `40940` | 409 |
|
||||
|
||||
表 16-11 M2 幂等与错误码
|
||||
|
||||
> **本轮修复**:幂等键判断原先排在状态合法性之后,重复停用会错返 `40902`。已把 `commandId` 查询前置,并补 `duplicateDisableOnAlreadyDisabledRoomReturnsDuplicatedInsteadOfStateConflict` 回归用例;端到端 M2-8 复验通过。
|
||||
|
||||
---
|
||||
|
||||
## 5. 主数据下行 Mock 灌数与版本标记
|
||||
|
||||
### 5.1 版本标记与只读接口
|
||||
|
||||
| 项 | 实现 |
|
||||
|---|---|
|
||||
| 6 个域 | `APARTMENT` / `ROOM` / `PERSON` / `ROUTE` / `RULE` / `HOLIDAY` |
|
||||
| 固定标记 | `source='LOCAL'`、`source_version=0`、`state='APPLIED'`、`deleted=0` |
|
||||
| 只读接口 | `GET /apt/master/versions`、`GET /apt/master/versions/{domain}`(表 4-17 #1) |
|
||||
| 页面标识 | `localMock=true`、`sourceLabel="非平台下发"`、列表 `mockNotice` |
|
||||
| 域记录数 | `itemCount` 用固定表名子查询统计,禁止动态拼接表名 |
|
||||
| 全量重拉 | `POST /apt/master/{masterType}/resync` 恒 `40940`(表 4-17 #2,平台未就绪不做假成功) |
|
||||
| 权限点 | `hasAnyPermi('apt:ops:health,apt:master:version')`;3015 已显式关联超管 |
|
||||
| 生产护栏 | `apt.master-client.mock`(默认 `false`);非 `local` profile 开启即启动失败 |
|
||||
|
||||
表 16-12 版本标记与只读接口(表 9-16、表 4-17)
|
||||
|
||||
### 5.2 SQL 脚本与实库校验
|
||||
|
||||
| 脚本 | 实库结果 |
|
||||
|---|---|
|
||||
| `10_it2_columns.sql` | 补列 10 个(`apt_master_route` 4 / `gy_rooms` 6),列注释中文正确 |
|
||||
| `11_it2_seed.sql` | 交路 3 / 房间 5 / 人员 5 / 计划 2 / 版本 6 |
|
||||
| `11` 校验段 | `local_applied_domains=6`、`fake_platform_rows=0`、6 域明细均「非平台下发」 |
|
||||
| `12_it2_permissions.sql` | `grey_bound=0`、`version_permission_bound=1`、`apt_permission_count=0` |
|
||||
| 十六进制复核 | `xm` / `route_name` / `menu_name` / `COLUMN_COMMENT` 均为正确 UTF-8 字节 |
|
||||
|
||||
表 16-13 IT-2 SQL 实库执行与校验结果
|
||||
|
||||
### 5.3 中文编码缺陷与修复
|
||||
|
||||
首次实库执行时,Windows PowerShell 5.1 以 ASCII 文本管道把 SQL 中文替换成 `?`,库内 `xm` 实测为 `3F3F`,列注释与新增菜单名同样损坏。修复链条:
|
||||
|
||||
| 环节 | 修复 |
|
||||
|---|---|
|
||||
| `apply-it2-sql.ps1` | 改为 `.NET Process` + 原始 UTF-8 字节流写入 mysql `stdin`,彻底绕过 PowerShell 文本编码;保留 `-DryRun`、环境变量凭据回退、`MYSQL_PWD` 清理 |
|
||||
| `10_it2_columns.sql` | 增加可重复执行的 `MODIFY COLUMN` 注释修复段,校验 SELECT 输出 `COLUMN_COMMENT` |
|
||||
| `11_it2_seed.sql` | 交路 `ON DUPLICATE KEY UPDATE` 补齐 `route_name` / `start_station` / `end_station` / `stop_reason`,使重放可修复中文 |
|
||||
| 复验 | 重放后中文输出正常,HEX 复核全部为正确 UTF-8,计数不变 |
|
||||
|
||||
表 16-14 PowerShell 中文管道缺陷与修复
|
||||
|
||||
---
|
||||
|
||||
## 6. 验证结果
|
||||
|
||||
### 6.1 实际执行的验证
|
||||
|
||||
| 项 | 命令 / 脚本 | 结果 |
|
||||
|---|---|---|
|
||||
| 编译打包 | `mvn -B -ntp -pl ruoyi-admin -am package` | 7 模块 `BUILD SUCCESS`,`ruoyi-admin.jar` 重新生成 |
|
||||
| 全量单测 | 同上 | `Tests run: 79, Failures: 0, Errors: 0` |
|
||||
| 架构约束 | `AptMapperGyidArchTest`(3 例) | 4 个 Mapper XML 全部带 `gyid`、业务字段排序、乐观锁断言通过 |
|
||||
| SQL 静态校验 | `AptIt2SeedMarkersTest`(4 例) | 6 域标记、禁冒充平台、权限点登记通过 |
|
||||
| 实库执行 | `apply-it2-sql.ps1` | 3 脚本成功,校验计数符合预期(表 16-13) |
|
||||
| 端到端 | `verify-it2-m1m2.ps1` | **24/24 通过**(表 16-16;M0-5 校验模块配置导入与 springdoc 分组) |
|
||||
| DryRun | `apply-it2-sql.ps1 -DryRun` | 通过 |
|
||||
| 静态诊断 | `read_lints` | 改动文件 0 条 |
|
||||
|
||||
表 16-15 IT-2 验证执行清单
|
||||
|
||||
> 环境说明:验证码保持开启、`sys_config` 未改;验证码答案只读 Redis `database=1`;`.env` 的 `APT_TOKEN_SECRET` 不足 64 字节,脚本进程内生成临时 HS512 密钥;8080 已有实例,端到端独立使用 8099 端口并在结束时停止自建进程;所有路径均走 `/apt/**` 四个受管前缀。
|
||||
|
||||
### 6.2 端到端 24 项实测
|
||||
|
||||
| 用例 | 期望 | 实测 |
|
||||
|---|---|---|
|
||||
| M0-1 无 token | 401 / 40101 | 401 / 40101 |
|
||||
| M0-2 无权限 | 403 / 40301 | 403 / 40301 |
|
||||
| M0-3 跨 `gyid` | 403 / 40302 | 403 / 40302 |
|
||||
| M0-4 分页上限 | `pageSize=100` | `pageSize=100` |
|
||||
| M0-5 模块配置 + springdoc 分组 | `apt-defaults.yml` 导入后 `/apt/*` 路径可见 | HTTP 200 / `aptPaths=17` |
|
||||
| M1-1 列表与字段映射 | ≥3 行、`jch` 非空 | 3 行、`jch=北京南-济南西` |
|
||||
| M1-2 详情 | `JL-001` | `JL-001` |
|
||||
| M1-3 重复 `jlid` | 409 / 40901 | 409 / 40901 |
|
||||
| M1-4 缺 `reason` | 400 / 40001 | 400 / 40001 |
|
||||
| M1-5 复算校验 | `computedJcsj` 非空 | 非空(只算不落库) |
|
||||
| M1-6 启停与原因审计 | 200 / 200 | 200 / 200 |
|
||||
| M2-1 房间列表 | ≥5 行 | 5 行 |
|
||||
| M2-2 房态筛选 | 只返回 `4` | 1 行,全部 `4` |
|
||||
| M2-3 房态汇总 | `total≥5` | 5 |
|
||||
| M2-4 详情 | `roomNo=201` + 绑定列表 | 通过 |
|
||||
| M2-5 快照只读 | 409 / 40904 | 409 / 40904 |
|
||||
| M2-6 缺 `reason` | 400 / 40001 | 400 / 40001 |
|
||||
| M2-7 停用 | `status=4` / 版本 +1 | `4`,`v=3→4` |
|
||||
| M2-8 幂等 | `duplicated=true` / 版本不变 | `True`,`v=4` |
|
||||
| M2-9 停用在寓可查 | `status=4` + `livePersons` | 通过 |
|
||||
| M2-10 恢复重算 | 非 `4` / 版本再 +1 | `1`,`v=5` |
|
||||
| M2-11 新增禁用 | 409 / 40940 | 409 / 40940 |
|
||||
| M2-12 版本标记 | 6 域 `LOCAL/0/mock` | 6 域全通过 + `mockNotice` |
|
||||
| M2-13 重拉禁用 | 409 / 40940 | 409 / 40940 |
|
||||
|
||||
表 16-16 `verify-it2-m1m2.ps1` 24 项实测结果(表 7-7 步骤 4/5)
|
||||
|
||||
---
|
||||
|
||||
## 7. 口径偏离与待评审项
|
||||
|
||||
| # | 偏离 / 未决 | 依据 | 本轮处理 | 状态 |
|
||||
|---|---|---|---|---|
|
||||
| 16-1 | 契约冻结、`D5`、`D8'`/`D3`/`D7` 签字未完成 | `13` 表 13-12、IR-01 | 按用户显式推进「带条件开工」 | **P0 待签字** |
|
||||
| 16-2 | 技术基线 JDK 24 / Boot 4.1.0 ≠ 设计 JDK 1.8 / 2.5.15 | IR-01 | 沿用 IT-1 核准偏离 | 已登记 |
|
||||
| 16-3 | 表 4-17 #1 权威权限点 `apt:ops:health`,IT-2 种子为 `apt:master:version`(3015) | `04` 表 4-17、`07` 表 7-4 | `hasAnyPermi` 兼容,3015 关联超管并在 remark 登记 | 待评审 |
|
||||
| 16-4 | 表 4-17 #2 `resync` 本期恒 `40940`;表 4-7 #6 `add` 恒 `40940` | 表 9-16、G-01/G-04 | 明确拒绝,不做假成功 | 待评审 |
|
||||
| 16-5 | 表 13-12 验收第 6 项以人员 `xm` 为例,M4 不在 IT-2 范围 | 表 13-12 范围 | 房间侧实现 `40904`;`xm` 留待 M4 | 部分达成 |
|
||||
| 16-6 | `jch/qd/zd` ← `route_name/start_station/end_station`;`enabled` ← `state` | 表 4-5 | 映射层解决,未改 59 张表 | 已闭环 |
|
||||
| 16-7 | `gy_rooms` 补 6 列、`apt_master_route` 补 4 列 | 表 4-5 / 4-7 | `10` 幂等补列,不改主键/唯一键/索引 | 已闭环 |
|
||||
| 16-8 | 房间停用无 `enabled` 开关,直接置 `room_status=4` | 表 7-3 M2 | 领域服务条件更新 | 已闭环 |
|
||||
| 16-9 | `duty_manual_action.action_type` 复用 `STOP`/`CORRECT` | 表 3-1 列注释 | 未新造枚举值 | 待评审 |
|
||||
| 16-10 | 乐观锁冲突复用 `40903`(快照版本过期) | 表 4-4 | 条件更新命中 0 行即返回 | 待评审 |
|
||||
| 16-11 | 汇总 `cleaning` 合并状态码 `3` 与 `6` | 表 4-7 | 前端卡片口径 | 待评审 |
|
||||
| 16-12 | `building` 降级楼层前缀 + `warnings[]`;`AptTableDataInfo` 追加字段 | 表 4-7 约束 1、G-01 | 列表响应追加空数组,不破坏既有字段 | 待评审 |
|
||||
| 16-13 | 审计 `REQUIRES_NEW`、参数校验异常分派属 IT-1 遗留项 | `15` 表 15-15 | 本轮补齐并纳入回归 | 已闭环 |
|
||||
| 16-14 | 重复停用优先返回 `duplicated=true`(幂等先于状态检查) | 表 4-7 #5 L2 | 端到端 M2-8 暴露后修复 | 已闭环 |
|
||||
| 16-15 | `.env` 的 `APT_TOKEN_SECRET` 仅 39 字节 | `15` 表 15-16 | 脚本生成临时密钥,未写回 `.env` | 待用户修正 |
|
||||
| 16-16 | 表 9-16 的 20 接口契约样例 JSON 未落测试资源目录 | 表 9-16 | 本轮以 SQL 静态校验替代 | 待补 |
|
||||
| 16-17 | 前端页面待补 | 表 13-12 范围 | 已补齐 6 个 Vue 页面 + 4 个 API 文件 + 4 条 `C` 菜单(本文第 10 章);`mockNotice` / `localMock` 在版本台账页标「非平台下发」 | 已闭环 |
|
||||
| 16-18 | 端到端使用 8099 独立端口(8080 已有实例) | 环境事实 | 自建进程、结束即停 | 已登记 |
|
||||
| 16-19 | 前端落点采用单入口 `src/views/apt/**` + `sys_menu` 动态路由,而非设计期 `src/entries/apt` 双入口静态路由 | `docs/10` 表 2-3 差-7、`02` §2.1 | 实际上游 `RuoYi-Vue2-master` 为标准单入口(无 `entries/`、无 `pages` 配置),全部页面由 `getRouters` 下发;本期跟随实际上游,不改写设计期口径,待真建双入口时另行评审 | 已登记 |
|
||||
|
||||
表 16-17 IT-2 口径偏离与待评审项登记
|
||||
|
||||
---
|
||||
|
||||
## 8. 变更点、影响范围与后续衔接
|
||||
|
||||
### 8.1 变更点
|
||||
|
||||
| 类别 | 变更 | 影响 |
|
||||
|---|---|---|
|
||||
| 新增 Java | `apt/master` 交路 7 接口 + 版本只读;`apt/stay` 房间 6 接口;`AptMasterClientMockGuard` | 仅 `/apt/**` 受管前缀,RuoYi 原 `/system/**` 不受影响 |
|
||||
| 修改 Java | `AptAuditWriter`/`AptAuditAspect`、`AptInfraExceptionHandler`、`AptProperties`、`AptTableDataInfo` | 公寓端列表多 `warnings[]`;审计业务回滚不丢 |
|
||||
| 新增 SQL | `10` / `11` / `12` 三个幂等脚本 | 实库 `apt_rev01` 已执行;`sys_menu` 3015 关联超管 |
|
||||
| 新增脚本 | `apply-it2-sql.ps1`、`verify-it2-m1m2.ps1` | 可重放;端到端自启自停 |
|
||||
| 配置 | `application.yml` 增 `apt.master-client.mock`;`.env.example` 同步 | 默认关闭,生产启动护栏 |
|
||||
| 文档 | 本文 + `README` / `14` / `15` / CR-02 表 0-2 索引 | 不改变设计口径 |
|
||||
|
||||
表 16-18 IT-2 变更点与影响范围
|
||||
|
||||
### 8.2 后续衔接
|
||||
|
||||
| 阶段 | 待办 | 前置 |
|
||||
|---|---|---|
|
||||
| IT-3 / M3 | 叫乘闭环、STOP 幂等、`duty_manual_action` 与叫乘联动 | D8'/D7 签字 |
|
||||
| IT-5 / M4 | 人员主数据编辑、`xm` 快照只读 `40904` | 契约冻结 |
|
||||
| 前端 | `IT-3`~`IT-8` 的叫乘 / 人员 / 设备 / 语音 / 入住等页面(`04` 表 4-10 / 4-12 / 4-14 / 4-16 已给文件名) | 对应后端 Controller 落地后方可建页;`IT-9`~`IT-11` 账务域按表 13-29 仍不开放 |
|
||||
| 契约 | 表 9-16 的 20 接口请求样例 JSON → 落库断言 | 契约冻结 |
|
||||
| 环境 | 修正 `.env` 的 `APT_TOKEN_SECRET` 为合法 Base64 HS512 密钥 | 无 |
|
||||
| 治理 | 契约冻结、`D5`、`D8'`/`D3`/`D7` 签字并回填本报告 | **P0** |
|
||||
| 验证 | 扩展端到端覆盖表 7-7 步骤 6/7(保洁任务、叫乘 Mock) | IT-3 |
|
||||
|
||||
表 16-19 IT-2 后续衔接
|
||||
|
||||
---
|
||||
|
||||
## 9. 模块归置:`ruoyi-apt`(2026-11-11)
|
||||
|
||||
### 9.1 动因与归置清单
|
||||
|
||||
IT-0~IT-2 期间公寓端代码按「基座 → 框架 → 领域 → 接口」分别落在 4 个 RuoYi 上游模块中,跨模块引用与文档口径逐渐发散。
|
||||
本轮新建单一 Maven 模块 `ruoyi-apt`,把公寓端实现统一收拢到 `com.ruoyi.apt.**`,包路径与接口路径均不变。
|
||||
|
||||
| 原落点 | 内容 | 新落点 | 数量 |
|
||||
|---|---|---|---|
|
||||
| `ruoyi-common/src/main/java/com/ruoyi/apt` | 上下文、错误码、注解、分页 | `ruoyi-apt/src/main/java/com/ruoyi/apt/common` | 7 |
|
||||
| `ruoyi-framework/src/main/java/com/ruoyi/apt` | 拦截器、鉴权、异常、审计、配置、探针 | `ruoyi-apt/.../apt/framework`、`.../apt/infra` | 12 |
|
||||
| `ruoyi-system/src/main/java/com/ruoyi/apt` | 交路 / 房间 / 版本领域与服务、Mapper 接口 | `ruoyi-apt/.../apt/{master,stay,ops}` | 22 |
|
||||
| `ruoyi-admin/src/main/java/com/ruoyi/apt` | 4 个 Controller | `ruoyi-apt/.../apt/{master,stay,ops}/controller` | 4 |
|
||||
| `ruoyi-system/src/main/resources/mapper/apt` | 4 个 Mapper XML | `ruoyi-apt/src/main/resources/mapper/apt` | 4 |
|
||||
| `ruoyi-admin/src/test/java/com/ruoyi/apt` | 15 个测试(79 用例) | `ruoyi-apt/src/test/java/com/ruoyi/apt` | 15 |
|
||||
| `ruoyi-admin/src/main/resources/application.yml` | `apt.*`、springdoc 分组、日志级别 | `ruoyi-apt/src/main/resources/apt-defaults.yml` | 1 |
|
||||
|
||||
表 16-20 归置清单(共移动 64 个 Java/XML 文件并抽出 1 份配置)
|
||||
|
||||
### 9.2 职责范围与边界
|
||||
|
||||
| 纳入 | 不纳入 |
|
||||
|---|---|
|
||||
| 四前缀(`/apt/**` 等)全部 Controller、领域服务、Mapper 接口与 XML | RuoYi 原 `/system/**`、`/monitor/**`、`/tool/**` 后台能力 |
|
||||
| `AptContext` / 统一错误码 / 拦截器 / 401·403 处理器 / 审计切面 / `AptProperties` / Mock 启动护栏 | `SecurityConfig`(仍属 `ruoyi-framework`,按接口装配公寓端处理器) |
|
||||
| `apt-defaults.yml`:`apt.*`、springdoc 分组、`com.ruoyi.apt` 日志级别 | 数据源、Redis、token 等基础设施配置(仍在 `ruoyi-admin`) |
|
||||
| 前端静态资源挂载点 `src/main/resources/static/apt/` | Vue 前端源码:已落在独立工程 `dev/RuoYi-Vue2-master/src/views/apt/**`(API 在 `src/api/apt/**`,路由在 `src/router/index.js`);本期按实际上游单入口 + `sys_menu` 动态路由实现,见第 10 章;构建产物可输出到挂载点 |
|
||||
| 模块内 79 个 JUnit5/Mockito 用例 | DDL / 种子 / 权限点 SQL 与 PowerShell 验收脚本:保持 `dev/sql/apt_rev01`、`dev/scripts` 原位,不参与 Maven 打包 |
|
||||
|
||||
表 16-21 `ruoyi-apt` 职责范围与边界
|
||||
|
||||
### 9.3 结构定位、依赖与被依赖
|
||||
|
||||
| 方向 | 模块 | 说明 |
|
||||
|---|---|---|
|
||||
| **依赖** | `ruoyi-common` | 基础工具、`AjaxResult`、Security、Validation、PageHelper、fastjson2、Redis |
|
||||
| **依赖** | `ruoyi-framework` | Spring WebMVC、AspectJ、Druid、`AuthenticationEntryPointImpl`、`BaseController` |
|
||||
| **依赖(传递)** | `ruoyi-system` | 经 framework 传递,模块内不引用其业务类 |
|
||||
| **依赖** | 第三方 | `mybatis-spring-boot-starter`、`spring-tx`、`spring-boot-starter-test`(test) |
|
||||
| **被依赖** | `ruoyi-admin` | 启动模块显式声明,使 `ruoyi-apt.jar` 进入 classpath 与 fat jar |
|
||||
| **被运行时引用** | `ruoyi-framework` | `SecurityConfig` 只依赖 `AuthenticationEntryPoint` / `AccessDeniedHandler` 接口,按 bean 名 `aptAuthenticationEntryPoint` / `aptAccessDeniedHandler` 装配;**编译期不 import `com.ruoyi.apt.*`**,消除循环依赖 |
|
||||
| **无依赖** | `ruoyi-quartz`、`ruoyi-generator` | 与公寓端解耦 |
|
||||
|
||||
表 16-22 依赖与被依赖关系
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
ADMIN["ruoyi-admin<br/>启动 / fat jar"] --> APT["ruoyi-apt<br/>公寓端集中模块"]
|
||||
APT --> FRAME["ruoyi-framework"]
|
||||
APT --> COMMON["ruoyi-common"]
|
||||
FRAME --> SYS["ruoyi-system"]
|
||||
SYS --> COMMON
|
||||
ADMIN --> QUARTZ["ruoyi-quartz"]
|
||||
ADMIN --> GEN["ruoyi-generator"]
|
||||
QUARTZ --> COMMON
|
||||
GEN --> COMMON
|
||||
FRAME -.->|"运行时按 bean 名装配<br/>401/403 处理器"| APT
|
||||
```
|
||||
|
||||
图 16-2 Maven 反应堆中的 `ruoyi-apt` 定位(实线为编译期依赖,虚线为运行时装配)
|
||||
|
||||
### 9.4 构建识别与验证
|
||||
|
||||
| 调整点 | 内容 |
|
||||
|---|---|
|
||||
| 根 `pom.xml` | `<modules>` 增加 `ruoyi-apt`;`dependencyManagement` 登记 `${ruoyi.version}` |
|
||||
| `ruoyi-admin/pom.xml` | 新增 `ruoyi-apt` 依赖 |
|
||||
| `ruoyi-apt/pom.xml` | 声明 common / framework / mybatis / spring-tx / test 依赖 + Surefire 3.5.2 |
|
||||
| 包扫描 | `@SpringBootApplication`(`com.ruoyi`)、`@MapperScan("com.ruoyi.**.mapper")`、`typeAliasesPackage: com.ruoyi.**.domain` 均为通配,无需改包名 |
|
||||
| Mapper 资源 | `classpath*:mapper/**/*Mapper.xml` 通配加载模块内 4 个 XML |
|
||||
| 配置导入 | `spring.config.import: 'optional:classpath:apt-defaults.yml'`;springdoc `packages-to-scan` 由 `com.ruoyi.apt.**` 修正为 `com.ruoyi.apt` |
|
||||
| 架构测试 | `AptMapperGyidArchTest` 定位改为 `ruoyi-apt/src/main/resources/mapper/apt`,兼容模块根与反应堆根 |
|
||||
|
||||
表 16-23 构建与识别调整
|
||||
|
||||
| 验证 | 结果 |
|
||||
|---|---|
|
||||
| `mvn -pl ruoyi-admin -am clean package` | 7 模块 `BUILD SUCCESS`;反应堆顺序 `common → system → framework → apt → admin`,单向无环 |
|
||||
| 全量单测 | `Tests run: 79, Failures: 0, Errors: 0`(全部在 `ruoyi-apt` 模块执行) |
|
||||
| 端到端 | `verify-it2-m1m2.ps1` **24/24 通过**(新增 M0-5 校验 `apt-defaults.yml` 导入与 springdoc 分组,实测 `aptPaths=17`) |
|
||||
| 陈旧产物 | `clean` 后 4 个旧模块的 `target/classes/com/ruoyi/apt`、`mapper/apt` 残留为 0 |
|
||||
| 静态诊断 | 改动文件 lints 0 |
|
||||
|
||||
表 16-24 模块归置验证结果
|
||||
|
||||
> **构建提示**:迁移后必须 `mvn clean package`。首次只执行 `package` 时,旧模块 `target/classes` 残留的
|
||||
> `mapper/apt/AptAuditMapper.xml` 与 `ruoyi-apt.jar` 内同名资源同时被 `classpath*:` 命中,
|
||||
> MyBatis 抛 `Mapped Statements collection already contains value` 导致启动失败;`clean` 后消除。
|
||||
>
|
||||
> **配置修正**:springdoc `packages-to-scan` 原值 `com.ruoyi.apt.**` 是既有缺陷(分组 `paths` 恒为空),
|
||||
> 归置时一并改为包名 `com.ruoyi.apt`,端到端 M0-5 复验通过。
|
||||
|
||||
> 提交纪律:本轮未执行任何 `git commit` / `git push`;`dev/.env` 含真实口令,保持 `.gitignore` 忽略,不得进入提交记录。
|
||||
|
||||
---
|
||||
|
||||
## 10. 前端页面补齐(2026-11-11)
|
||||
|
||||
### 10.1 范围界定
|
||||
|
||||
「公寓端全部尚未实现的前端页面」按「是否有真实后端接口可对接」分为三类,本轮只补齐第一类;判据是 `16` 表 16-6 / 16-9 / 16-12 与 `04` 表 4-10~4-17 的 Controller 落地情况,而非设计文档中的页面命名。
|
||||
|
||||
| 类别 | 功能域 | 后端现状 | 本轮处理 |
|
||||
|---|---|---|---|
|
||||
| A 接口已就绪 | 交路、房间、主数据版本、连通性自检 | `IT-0`~`IT-2` 已交付 4 个 Controller | **建 4 个菜单页 + 2 个详情页** |
|
||||
| B 仅设计、Controller 未落地 | 叫乘 `jcxx`、人员 `person`、设备 `device`、语音 `voice`、上报 `report`、人脸、入住、值班台、报表 | `04` 已给 `.vue` 文件名与接口契约,`13` 排在 `IT-3`~`IT-8` | **不建页面**:无接口可对接,建页即等于伪造交互 |
|
||||
| C 明文延后(P2) | 消费 / 线下充值 / 菜品 `ledger` | `13` 表 13-29「不开 `/apt/ledger/**`、不建 `com.ruoyi.apt.ledger` 包、权限点置灰」 | **不建页面、不建菜单** |
|
||||
|
||||
表 16-25 前端页面补齐范围
|
||||
|
||||
> `docs/公寓端/ui/duty-console-v2.html` 是零依赖静态高保真值班台原型(假数据 + `localStorage`,不发任何 `/apt/**` 请求),
|
||||
> 与 Vue 工程无构建关系,本轮不改造、不迁移。
|
||||
|
||||
### 10.2 页面清单与接口对应
|
||||
|
||||
| 页面(`dev/RuoYi-Vue2-master/src/views/apt/`) | API 文件 | 对接接口 | 操作区 | 主要权限点 |
|
||||
|---|---|---|---|---|
|
||||
| `route/index.vue` 交路列表 | `api/apt/route.js` | `GET /apt/route/list`、`/{id}`、`/options`、`POST /apt/route`、`PUT /{id}`、`PUT /{id}/status`、`POST /{id}/recalc-check` | 查询、新增、修改、启停、详情、复算校验、导出、列显隐、分页 | `apt:route:list/query/add/edit/changeStatus` |
|
||||
| `route/detail.vue` 交路详情 | 同上 | `GET /apt/route/{id}` | 只读详情、刷新、返回 | `apt:route:query` |
|
||||
| `room/index.vue` 房间列表 | `api/apt/room.js` | `GET /apt/room/list`、`/{id}`、`/status-summary`、`PUT /{id}`、`PUT /{id}/status` | 查询、房态汇总卡片、修改、停用/恢复(`commandId` 幂等)、详情、导出、列显隐、分页 | `apt:room:list/query/edit/changeStatus` |
|
||||
| `room/detail.vue` 房间详情 | 同上 | `GET /apt/room/{id}` | 主档只读 + `bindings` / `livePersons` / `recentCleanTasks` 三 Tab | `apt:room:query` |
|
||||
| `master/version/index.vue` 版本台账 | `api/apt/master.js` | `GET /apt/master/versions`、`/versions/{domain}` | 前端筛选、只读详情、导出、`mockNotice` / `localMock` 标「非平台下发」 | `apt:master:version` / `apt:ops:health` |
|
||||
| `ops/connectivity/index.vue` 连通性自检 | `api/apt/ops.js` | `GET /apt/ops/connectivity`、`POST .../probe` | 目标 / 严格模式表单、只读检查、读写探针、结果表格、明细、导出 | `apt:ops:connectivity` / `apt:ops:health` |
|
||||
|
||||
表 16-26 页面、API 与接口对应(公共常量与工具在 `src/utils/apt.js`,禁用态按钮组件在 `src/components/AptDisabledAction/index.vue`)
|
||||
|
||||
### 10.3 与 RuoYi 页面规范的一致性
|
||||
|
||||
| 维度 | 采用方式 |
|
||||
|---|---|
|
||||
| 页面结构 | `.app-container` → `el-form` 查询区 → `el-row.mb8` 按钮区 → `el-table v-loading` → `pagination` → `el-dialog` 表单,与 `system/post/index.vue`、`system/user/index.vue` 同构 |
|
||||
| 布局 | `el-row :gutter` + `el-col :xs="24" :sm="12"`;弹窗 `width` + `:fullscreen="isMobile"`(`store.state.app.device`) |
|
||||
| 组件 | 全局 `Pagination` / `RightToolbar`(`storageKey` 记忆列显隐)/ `DictTag`;局部 `AptDisabledAction`;不引入第二套 UI 库 |
|
||||
| 主题配色 | 不写死色值:只用 Element 语义色(`primary` / `success` / `danger` / `warning` / `info`)与 `el-tag type`,跟随 `ThemePicker` 注入的 `--current-color` |
|
||||
| 表格与表单 | `dict-tag :options` 复用 RuoYi 字典结构(`value` / `label` / `raw.listClass`);`parseTime` / `resetForm` 全局方法;`label-width` 统一;`show-overflow-tooltip` 防溢出 |
|
||||
| 按钮与弹窗 | `v-hasPermi` 数组;`$modal.confirm` 二次确认、`msgSuccess` / `msgWarning` / `msgError`;`el-dialog append-to-body` + `dialog-footer` 的「确 定 / 取 消」 |
|
||||
| 加载状态 | 列表 `v-loading`、按钮 `:loading`、汇总独立 `v-loading`;所有 `catch` 复位,避免遮罩悬挂 |
|
||||
| 表单校验 | `rules` + `$refs.form.validate`;交路 `jcsj < kcsj`、`lysj <= kcsj` 前端预校验(对齐 `AptRouteServiceImpl.validate`);房间 `roomOrder >= 0` 与「本地属性至少一项」;`reason` 512 字上限与必填 |
|
||||
| 错误提示 | `src/utils/request.js` 错误分支增强:公寓端 `code/100` 映射 HTTP 4xx 时优先展示后端 `msg` + `data.reason` + `traceId`;`utils/apt.js` 提供 27 个错误码与 reason 的中文映射;页面用 `el-alert` 内联展示 |
|
||||
| 权限控制 | 菜单级 `sys_role_menu` → `getRouters`;按钮级 `v-hasPermi`;详情页 `dynamicRoutes.permissions` 过滤(前端隐藏不代替后端 `@PreAuthorize`) |
|
||||
| 响应式 | `xs/sm/md` 栅格、小屏弹窗全屏、房态汇总六卡换行、`collapse-tags`、RightToolbar 列显隐;沿用 `AppMain` 991px、`ResizeHandler` 992px、`ruoyi.scss` 768px 既有断点 |
|
||||
|
||||
表 16-27 页面规范对照
|
||||
|
||||
### 10.4 路由与菜单配置统一
|
||||
|
||||
菜单沿用 RuoYi 标准机制:后端 `getRouters` 下发 `C` 菜单 → `store/modules/permission.js` 的 `loadView('@/views/' + component)` 懒加载,与 `system/user` 完全同构;业务页面**不写进** `constantRoutes`,避免绕过菜单鉴权。
|
||||
|
||||
| `menu_id` | 菜单名 | `path` | `component` | 完整路由 | 种子 |
|
||||
|---|---|---|---|---|---|
|
||||
| 3101 | 交路管理 | `route` | `apt/route/index` | `/apt/route` | `13_it2_frontend_menus.sql` |
|
||||
| 3102 | 房间管理 | `room` | `apt/room/index` | `/apt/room` | 同上 |
|
||||
| 3103 | 主数据版本 | `version` | `apt/master/version/index` | `/apt/version` | 同上 |
|
||||
| 3104 | 连通性自检 | `connectivity` | `apt/ops/connectivity/index` | `/apt/connectivity` | 同上 |
|
||||
|
||||
表 16-28 `C` 菜单与组件路径(父目录 3000 `path='apt'`,`component` 为空时 RuoYi 回落 `Layout`)
|
||||
|
||||
两个详情页登记在 `src/router/index.js` 的 `dynamicRoutes`:`/apt/route-detail/index/:id`(`AptRouteDetail`,`permissions: ['apt:route:query']`,`activeMenu: '/apt/route'`)与 `/apt/room-detail/index/:id`(`AptRoomDetail`,`apt:room:query`),均 `hidden: true`,不建 `C` 菜单。
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
MENU["sys_menu<br/>3000 + 3101~3104<br/>13_it2_frontend_menus.sql"] -->|"getRouters"| PERM["permission.js<br/>filterAsyncRouter / loadView"]
|
||||
PERM --> VIEWS["src/views/apt/**<br/>4 个菜单页"]
|
||||
VIEWS -->|"$router.push"| HIDDEN["dynamicRoutes<br/>2 个隐藏详情页"]
|
||||
API["src/api/apt/**"] -->|"utils/request.js"| BACKEND["ruoyi-apt<br/>/apt/** Controller"]
|
||||
VIEWS --> API
|
||||
F["F 权限点 3001~3015"] -.->|"v-hasPermi"| VIEWS
|
||||
```
|
||||
|
||||
图 16-3 菜单 → 路由 → 页面 → 接口关系(实线为加载/调用,虚线为按钮级权限)
|
||||
|
||||
> **口径偏离 16-19**:`docs/10` 表 2-3(差-7)与 `02` §2.1 约定 `entry-apt` 使用前端静态路由表、`sys_menu` 仅作权限点载体。
|
||||
> 但本仓库实际上游 `RuoYi-Vue2-master` 是**标准单入口**(无 `src/entries/`、无 `vue.config.js` 的 `pages` 配置),
|
||||
> 所有 `views` 均由 `getRouters` 下发。本期选择跟随实际上游,不改 `docs/10` 的设计期表述;
|
||||
> 若后续真要落地双入口,需先做工程改造并另行评审,届时再同步本节。
|
||||
|
||||
### 10.5 未开放能力的诚实呈现
|
||||
|
||||
| 能力 | 页面呈现 | 后端事实 |
|
||||
|---|---|---|
|
||||
| 房间新增 | 禁用按钮 + tooltip | `POST /apt/room` 恒 `40940 ROOM_ADD_DISABLED` |
|
||||
| 交路 / 房间删除 | 禁用按钮 + tooltip | 后端无删除接口,业务上以「停用」代替 |
|
||||
| 交路 / 房间导入 | 禁用按钮 + tooltip | 后端无 `/importData`,主数据须走平台下行 |
|
||||
| 主数据重新同步 | 禁用按钮 + tooltip | `POST /apt/master/{masterType}/resync` 恒 `40940 MASTER_RESYNC_DISABLED` |
|
||||
| 导出 | **可用**,前端 CSV(UTF-8 BOM) | 后端未提供 `/export`,导出当前查询/筛选结果,不伪造后端调用 |
|
||||
|
||||
表 16-29 未开放能力与禁用态清单
|
||||
|
||||
### 10.6 验证
|
||||
|
||||
| 验证项 | 结果 |
|
||||
|---|---|
|
||||
| 生产构建 | `NODE_OPTIONS=--openssl-legacy-provider npm run build:prod`(Node 22.18.0)→ `DONE Build complete`,`exitCode=0`;仅既有 asset / entrypoint size 警告 |
|
||||
| 构建产物 | `dist/static/js` 命中 `/apt/route/list`、`/apt/room/status-summary`、`/apt/master/versions`、`/apt/ops/connectivity` |
|
||||
| SQL 重放 | `apply-it2-sql.ps1 -DryRun` 列出 `10`/`11`/`12`/**`13`** 四个文件;实库重放 `exitCode=0` |
|
||||
| 菜单树 | `M=1 / C=4 / F=15`;超管关联 `C` 菜单 `4`;置灰项 `3004~3006 / 3014` 关联数 `0`;M0 验收账号公寓权限 `0` |
|
||||
| 静态诊断 | `read_lints` 对 `RuoYi-Vue2-master/src` 全域 `totalCount: 0` |
|
||||
|
||||
表 16-30 前端补齐验证结果
|
||||
|
||||
> 本轮**未**新增后端接口、**未**改动 59 张业务表、**未**启用 P2 账务域;`sys_menu` 只新增 4 条 `C` 记录与超管关联,
|
||||
> 既有 `F` 权限点、置灰策略、M0 验收账号全部保持不变。
|
||||
|
||||
@@ -0,0 +1,128 @@
|
||||
# 17 第四轮开发(IT-4)交付说明:入住作业核心
|
||||
|
||||
> 版本:IT-4 / DV-3 后续 | 范围:`公寓端/11-人员入住作业流程` 的 CI-02 ~ CI-05 | 依据:`13-公寓端小步迭代开发计划` 表 13-14、CR-02 表 3-57 验收 18~20。
|
||||
|
||||
## 1. 范围与约束
|
||||
|
||||
**本期交付**:入住选项(N-39)、入住申请(N-40)、申请查询(N-41)、待审列表(N-42)、审核详情(N-43)、审核与办理入住(N-44)、审核期换房(N-45)、审核时间线(N-46)、入住与叫乘任务查询(N-47),以及 `#9 CHECKIN` 入队、`#7 matchVerdict` 落库与 `jcsj` 复算、`#8 TASK_ACK` 入队。
|
||||
|
||||
**明确不做**:账务冻结(40940)、退宿与退宿换房(IT-5)、设备下发与可见范围(IT-7)、`#7` 的 HTTP 拉取器(IT-6)。入住链路只到「任务就绪」,不产生叫乘执行动作。
|
||||
|
||||
**硬约束**:
|
||||
1. `gyid` 只来自部署环境注入(`AptContext`),任何接口不接受请求参数携带 `gyid`。
|
||||
2. 申请与审核都不写 `gy_jcxx.ryzt` / `finish_ly`;这两个字段只能经 `apt.duty.state` 语义写入。
|
||||
3. 平台回执不决定本地生效:`verdict` 只影响同步态展示,生效点恒为值班员审核。
|
||||
4. 59 张业务表不变,本期只做 `apt_local_task` 补列与字典扩展。
|
||||
|
||||
## 2. 交付清单
|
||||
|
||||
| 层 | 文件 | 说明 |
|
||||
| --- | --- | --- |
|
||||
| SQL | `dev/sql/apt_rev01/17_it4_columns.sql` | `apt_local_task` 补 27 列、2 个幂等唯一键、`checkin_state` 8 值 / `sync_state` 5 值 / `event_type` 增补 `ROOM_SWAP` |
|
||||
| SQL | `dev/sql/apt_rev01/18_it4_permissions.sql` | 启用 3005、新增 3202 页面与 3217~3219 权限点、超管关联 |
|
||||
| SQL | `dev/sql/apt_rev01/99_verify.sql` 第 14~19 段 | 增量列、字典、权限点、任务就绪、孤儿与泄漏校验 |
|
||||
| SQL 脚本 | `dev/scripts/apply-it4-sql.ps1` | 凭据取 `.env`,UTF-8 流式投喂,可重放 |
|
||||
| 后端 | `ruoyi-apt/.../stay/checkin/**` | domain / mapper / service / controller 共 20 个类 + 1 个 XML |
|
||||
| 后端测试 | `stay/checkin/AptCallTimeCalculatorTest`、`AptCheckinServiceTest`、`AptCheckinMatchServiceTest` | 28 个用例 |
|
||||
| 后端测试 | `framework/AptIt4SqlContractTest` | 5 个 SQL 契约用例 |
|
||||
| 前端 | `src/api/apt/checkin.js` | N-42~N-47 六个接口封装 |
|
||||
| 前端 | `src/views/apt/checkin/index.vue` | 台账 + 详情 + 审核 + 换房 + 时间线 + 叫乘任务 |
|
||||
| 前端 | `src/utils/apt.js` | 流程态 / 同步态 / 匹配态字典 + 40926~40932 文案 |
|
||||
|
||||
## 3. 接口说明
|
||||
|
||||
统一约定:`produces=application/json;charset=UTF-8`;列表分页参数 `pageNum/pageSize`,返回 `rows/total/warnings/traceId`;错误体为 `{code, reason, message, traceId}`。
|
||||
|
||||
### 3.1 设备侧(`/open/v1/**`,匿名 + 设备四要素)
|
||||
|
||||
| 编号 | 方法与路径 | 请求 | 响应 | 关键错误 |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| N-39 | `GET /open/v1/checkin/options?version=` | 版本号可空 | `version/serverTime/notModified/ttlSeconds/source/rooms[]/routes[]` | 40303 |
|
||||
| N-40 | `POST /open/v1/checkin/applications` | `deviceEventId, ryid, fjh, regId?, jlid?, cc?, jch?, source?, occurredAt?, verifiedAt?, featureVersion?` | `applyId/jcid/checkinState/syncState/origin/bizVersion/duplicated/warnings[]` | 40914 注册未确认、40927 特征版本落后、40929 核验超 5 分钟、40928 房间不可住、40932 已在住、40931 交路非法、40401 人员不存在 |
|
||||
| N-41 | `GET /open/v1/checkin/applications/{applyId}` | — | 申请单投影(含 `bizVersion`) | 40401 |
|
||||
|
||||
### 3.2 值班台(`/duty/checkin/applications`)
|
||||
|
||||
| 编号 | 方法与路径 | 权限点 | 请求 | 响应 | 关键错误 |
|
||||
| --- | --- | --- | --- | --- | --- |
|
||||
| N-42 | `GET /duty/checkin/applications?state=&workNo=&name=` | `duty:checkin:list` | `state` 缺省 `SUBMITTED` | 分页列表 | — |
|
||||
| N-43 | `GET /duty/checkin/applications/{applyId}` | `duty:checkin:list` | — | 申请单 + `roomCandidates[]` + `warnings[]`;首次查看把 `SUBMITTED` 条件迁移为 `REVIEWING` | 40401 |
|
||||
| N-44 | `POST /duty/checkin/applications/{applyId}/review` | `duty:checkin:review` | `verdict(APPROVE/APPROVE_WITH_ROOM_CHANGE/REJECT), expectedBizVersion, targetFjh?, reviewNote?, commandId?` | `checkinState/syncState/fjhFinal/checkedIn/uploadState/reportOutboxId/warnings[]` | 40926 版本或状态过期、40928 房间不可住、40001 驳回未填说明 |
|
||||
| N-45 | `POST /duty/checkin/applications/{applyId}/room-adjust` | `duty:checkin:adjust` | `targetFjh, expectedBizVersion, reason?, commandId?` | `fjhFinal/roomAdjustSeq/originRoomStatus/targetRoomStatus/sipBound/warnings[]` | 40926(含已入住 `ALREADY_CHECKED_IN`、同房 `ROOM_UNCHANGED`)、40928 |
|
||||
| N-46 | `GET /duty/checkin/applications/{applyId}/timeline` | `duty:checkin:list` | — | `checkinState/syncState/matchState/events[]{state,fromState,at,actor,commandId,note}` | 40401 |
|
||||
|
||||
### 3.3 管理端(`/apt/checkin`)
|
||||
|
||||
| 编号 | 方法与路径 | 权限点 | 响应 | 说明 |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| N-47 | `GET /apt/checkin/{jcid}/call-task` | `apt:checkin:query` | `applyId/jcid/checkinState/syncState/matchState/fjhFinal/jcsj/jcfs/taskReady/task{...}` | `task=null` 表示未就绪;查无此入住才返回 40401 |
|
||||
|
||||
## 4. 关键实现要点
|
||||
|
||||
### 4.1 状态机与事务边界
|
||||
|
||||
```
|
||||
SUBMITTED -(N-43 接单)-> REVIEWING -(N-44 APPROVE)-> APPROVED -(同事务)-> CHECKED_IN
|
||||
REVIEWING/APPROVED -(N-44 换房通过 / N-45)-> ROOM_ADJUSTED -(N-44 APPROVE)-> CHECKED_IN
|
||||
REVIEWING/APPROVED/ROOM_ADJUSTED -(N-44 REJECT)-> REJECTED(终态)
|
||||
```
|
||||
|
||||
`AptCheckinServiceImpl#checkIn` 一个事务内完成:条件占床(`state_version` 乐观锁 + `in_person_count < bed_count`)→ 房态重算 → `gy_jcxx` 建行(`call_mode` 按是否存在有效 SIP 绑定取 `SIP`/`TABLET`)→ `gygl_ly_event` 记 `CHECKIN` → 流程态迁 `CHECKED_IN` → `#9` 入队 → `sync_state=REPORTED` → 操作日志。任一步返回 0 行即抛异常整体回滚,不会出现「已占床但无叫乘记录」。
|
||||
|
||||
### 4.2 三条状态链相互独立
|
||||
|
||||
- `checkin_state`(流程态):只由 N-43/N-44/N-45 推进。
|
||||
- `sync_state`(同步态):`PENDING → REPORTED → MATCHED/UNMATCHED → TASK_READY`,只由出站与 `#7` 结论推进。
|
||||
- `match_state`(匹配态):只由 `#7` 结论写入,平台拒绝不影响本地已完成的入住事实。
|
||||
|
||||
### 4.3 叫乘时刻复算(D8 / R-48)
|
||||
|
||||
`AptCallTimeCalculator` 为纯函数:`jcsj = kcsj - advance`(节假日取 `holidayAdvanceMinutes`)、`fjsj = jcsj + 10min`、`jcbjsj = jcsj + 15min`、`ylysj = jcsj + lysjgz`(缺省 30)。不变式 `jcsj ≤ fjsj ≤ jcbjsj < kcsj` 不成立即 40931,不静默钳制;规则版本写入 `derived_rule_version`,规则升级不回溯。
|
||||
|
||||
`IAptCheckinMatchService#applyVerdict` 是 `#7` 结论的唯一落库入口:`MATCHED/LOCKED` 复算并置 `TASK_READY`、写 `gy_jcxx.jcsj`、入队 `#8 TASK_ACK`;`UNMATCHED/REJECTED` 保留本地要素、不生成任务、不清空既有任务;同结论重复提交幂等返回。
|
||||
|
||||
### 4.4 换房语义
|
||||
|
||||
审核期换房只变更意向房号(`fjh_final`)、`room_adjust_seq+1` 与留痕,**不动 `in_person_count`**——申请阶段床位并未占用,若此时 -1/+1 会释放他人床位。床位在 `checkIn` 时按 `fjh_final` 占用。已 `CHECKED_IN` 后换房返回 40926,走 IT-5 退宿换房。
|
||||
|
||||
### 4.5 幂等与并发
|
||||
|
||||
- 申请:`uk_lt_gyid_device_event (gyid, device_code, device_event_id)` + 捕获 `DuplicateKeyException` 回查,重复提交返回原 `applyId`。
|
||||
- 审核/换房:`biz_version` 条件更新,0 行即 40926;`room_adjust_seq` 单调递增供 `#9` 的 `bizId` 分段。
|
||||
- 出站:`idempotency_key = md5(gyId|bizType|bizId|bizVersion)`,命中 `uk_outbox_gyid_idem` 不产生第二条。
|
||||
|
||||
### 4.6 安全
|
||||
|
||||
`/open/v1/**` 仅设备四要素可入;`/duty/**` 走权限点 + `@AptAudit`;`/apt/**` 管理端只读。所有 SQL 显式带 `gyid`(架构测试 `AptMapperGyidArchTest` 强制)。
|
||||
|
||||
## 5. 部署与使用注意
|
||||
|
||||
1. **执行顺序**:`00_common.sql`(辅助存储过程已存在则跳过)→ `14/15/16`(IT-3)→ `17_it4_columns.sql` → `18_it4_permissions.sql` → `99_verify.sql`。可用 `powershell -ExecutionPolicy Bypass -File dev/scripts/apply-it4-sql.ps1`(失败即中断,可重复执行)。
|
||||
2. **CHECK 约束重建**:`17` 会先 `DROP CHECK` 再按新字典重建。若库中已有 `checkin_state` 为 `AUDITED` / `CANCELLED` 之外旧值的数据,重建会失败——上线前需先 `SELECT checkin_state, COUNT(*) FROM apt_local_task GROUP BY 1` 确认。
|
||||
3. **函数点激活**:执行后需重新登录(或清前端路由缓存)才能看到「入住审核」菜单;`duty:checkin:list` 由置灰变为可用。
|
||||
4. **配置**:无新增配置项。`#9`/`#8` 仅入 outbox,投递依赖既有上报器;未启用上报器时任务停在 `REPORTED`,属预期。
|
||||
5. **验收演示路径**:设备侧 `POST /open/v1/checkin/verify` 取 `ryid` → `POST /open/v1/checkin/applications` → 值班台打开详情(自动接单)→ 审核通过 → `SELECT jcid FROM apt_local_task` 取 `jcid` → 调 `IAptCheckinMatchService#applyVerdict(MATCHED)` → `GET /apt/checkin/{jcid}/call-task` 应返回 `taskReady=true` 与复算后的 `jcsj`。
|
||||
6. **回滚**:本模块只新增列与行,不回写主数据。回滚应用版本即可;`apt_local_task` 新增列可保留(均为可空或带默认值),`CHECK` 如需回退按 `17` 的反向语句执行。
|
||||
|
||||
## 6. 验收标准
|
||||
|
||||
| 验收点 | 判定方式 |
|
||||
| --- | --- |
|
||||
| 增量列与字典 | `99_verify.sql` 第 14/15 段:27 列、`checkin_state` 8 值、`sync_state` 5 值、`ROOM_SWAP` |
|
||||
| 权限点与菜单 | 第 16 段 5 行(3005/3202/3217~3219),`still_grey=0`,菜单树 M1/C6/F24 |
|
||||
| 任务就绪必须有 jcsj | 第 17 段 `it4_task_ready_without_jcsj = 0` |
|
||||
| 已入住必须有叫乘行 | 第 18 段 `it4_checked_in_orphan = 0` |
|
||||
| 未入住不得提前建行 | 第 19 段 `it4_checkin_leak = 0` |
|
||||
| 单测 | `AptCheckinServiceTest` 15 + `AptCheckinMatchServiceTest` 7 + `AptCallTimeCalculatorTest` 6 + `AptIt4SqlContractTest` 5,全绿 |
|
||||
| 前端可用 | `npm run build:prod` 通过;页面四类操作(详情/审核/换房/时间线)与 N-47 查询均可完成 |
|
||||
|
||||
## 7. 偏离与遗留登记
|
||||
|
||||
| 编号 | 事项 | 现状 | 理由 / 后续 |
|
||||
| --- | --- | --- | --- |
|
||||
| D-1 | N-42 分页参数 | 用 `pageNum/pageSize` 而非文档的 `cursor/limit` | 与 IT-1/IT-3 全站分页一致,避免两套分页组件;如需游标由 IT-6 统一改造 |
|
||||
| D-2 | N-45 允许 `REVIEWING` | 表 11-18 仅列 `APPROVED/ROOM_ADJUSTED` | 审核期直接换房是值班台主路径,等价于 N-44「换房后通过」的前半段,已限制不得跨越 `CHECKED_IN` |
|
||||
| D-3 | 审核期换房不动房态计数 | 表 11-18 列有 `gy_rooms` 变更 | 申请期床位未占用,-1/+1 会释放他人床位;床位在 `checkIn` 时占用 |
|
||||
| D-4 | `duty_manual_action` 未写 | 时间线取 `duty_operation_log`(`module=CHECKIN`) | 人工命令台账由 IT-5 命令层统一写入,避免两处语义 |
|
||||
| D-5 | `#7` 无 HTTP 拉取 | 只提供 `IAptCheckinMatchService` | 仓库无平台客户端;IT-6 接入时直接调用,逻辑与幂等已覆盖 |
|
||||
| D-6 | `jllx` 仅由 `LOCKED` 置 1 | 无「解锁」接口 | 解锁属 IT-6 `UNLOCK_MATCH` 命令 |
|
||||
@@ -0,0 +1,217 @@
|
||||
# 18 第五轮开发(IT-5)交付说明:叫乘执行与状态机
|
||||
|
||||
> 迭代来源:`13-公寓端小步迭代开发计划.md` 表 13-5 `IT-5`、表 13-15 验收标准
|
||||
> 里程碑:`M3`(叫乘信息管理),见 `07-实施计划与验收.md` 表 7-2 / 表 7-3
|
||||
> 完成日期:2026-11-11
|
||||
|
||||
## 1. 范围与约束
|
||||
|
||||
### 1.1 本期交付
|
||||
|
||||
| 项 | 内容 |
|
||||
| --- | --- |
|
||||
| 状态机唯一写入口 | `apt.duty.state`:`gy_jcxx` 的 `ryzt` / `finish_jc` / `finish_ly` / `stoped` 只有一处可写 |
|
||||
| 受控命令 | `STOP` / `RE_CALL` / `FORCE_FINISH` / `MARK_LEAVE` / `CANCEL`,全部先落 `duty_manual_action`(`commandId` 幂等) |
|
||||
| 叫乘台账 | `/apt/jcxx` 列表 / 详情 / 时间线 / 白名单修正 / 命令 / 状态分布(04 表 4-9 六个接口) |
|
||||
| 平板链路 | N-03 拉任务、N-05 ACK、N-04 结果上报;`TABLET_RESULT` 幂等 + 迟到记 `IGNORED` |
|
||||
| 最小 SIP 适配 | AMI 事件 → 状态机命令映射;平板不可用回落 SIP(CR-C23);30s 无入会转报警 |
|
||||
| 扫描任务 | 平板任务过期回收、补生成任务、SIP 超时;Quartz `aptDispatchTask.scan()` |
|
||||
| 前端 | `/apt/jcxx` 叫乘台账页(列表 + 详情抽屉 + 时间线 + 命令/修正弹窗) |
|
||||
|
||||
### 1.2 约束(红线)
|
||||
|
||||
1. **不新增契约**:不新增跨端接口编号、不新增 `bizType`、不新增 WS 消息名、不新增业务表(仍 59 张)。
|
||||
2. **管理端无「编辑状态」入口**:`PUT /apt/jcxx/{id}` 不存在;`correct` 请求体带 `ryzt` / `finishJc` / `finishLy` / `stoped` 一律 `40001 STATE_FIELD_READONLY`。
|
||||
3. **一条 `jcid` 只有一种事实来源**:由 `gy_jcxx.call_mode` 标记;平板链路**不发送 #24** 语音质量摘要。
|
||||
4. **平板链路只收识别结论**:`resultId` / `faceVerifyState` / `resultType` / `personCount`,不接收抓拍帧、人脸原图、比对帧。
|
||||
5. **实现依据取自已修订文档**:`03` 表 3-10 新增的平板/`RE_CALL`/`CANCEL` 迁移行、`05` 表 5-20 的 `STOP`(1,2)/`CANCEL`(0) 与「超窗口由平板上报」口径。
|
||||
|
||||
## 2. 交付清单
|
||||
|
||||
### 2.1 后端(`dev/RuoYi-Vue-master/ruoyi-apt`)
|
||||
|
||||
| 文件 | 说明 |
|
||||
| --- | --- |
|
||||
| `dispatcher` 域:`dispatch/domain/AptDutyCommand.java` | 命令请求(`commandId` / `command` / `reason` / `leaveType`) |
|
||||
| `dispatch/domain/AptCorrectCommand.java` | 修正请求;状态字段单独声明以便识别并拒收 |
|
||||
| `dispatch/domain/AptDutyCommandResult.java` | 命令结果(`accepted` / `duplicated` / `stateAfter` / `actionId`) |
|
||||
| `dispatch/domain/AptJcxxQuery.java` | 列表过滤条件 |
|
||||
| `dispatch/domain/AptStateSnapshot.java` | 状态快照(`isTerminal()` 判终态) |
|
||||
| `dispatch/mapper/AptDutyStateMapper.java` + `mapper/apt/AptDutyStateMapper.xml` | **唯一写入口**:9 条条件更新 + 会话/离寓事件插入 |
|
||||
| `dispatch/mapper/AptJcxxMapper.java` + `mapper/apt/AptJcxxMapper.xml` | 读侧 + 白名单修正 + 命令流水 + AMI 事件 |
|
||||
| `dispatch/service/AptDutyStateServiceImpl.java` | 状态机:未命中 → `40902` |
|
||||
| `dispatch/service/AptDutyCommandServiceImpl.java` | 命令层:幂等 → 前置校验 → 提交状态机 → 结果回写 + 审计 |
|
||||
| `dispatch/service/AptJcxxServiceImpl.java` | 列表 / 详情 / 时间线 / 修正 / 统计 |
|
||||
| `dispatch/service/AptDispatchScanServiceImpl.java` | 扫描任务;调度线程自建 `AptContext` |
|
||||
| `dispatch/controller/AptJcxxController.java` | `/apt/jcxx/**` 六个接口 + `@PreAuthorize` 权限点 |
|
||||
| `dispatch/tablet/domain/*` | `AptTabletTask`、`AptTabletResultCommand` |
|
||||
| `dispatch/tablet/mapper/AptTabletMapper.java` + `mapper/apt/AptTabletMapper.xml` | 任务/结果/outbox;只写 `dispatch_seq` 不写状态 |
|
||||
| `dispatch/tablet/service/AptTabletDispatchServiceImpl.java` | 生成 / 拉取 / ACK / 过期 |
|
||||
| `dispatch/tablet/service/AptTabletResultServiceImpl.java` | 结果幂等 + 终态映射 + #9/#12 入 outbox |
|
||||
| `dispatch/tablet/controller/AptTabletOpenController.java` | `/open/v1/tablet/**`(设备四要素鉴权) |
|
||||
| `voice/domain/AptSipEventCommand.java`、`voice/service/AptVoiceEventServiceImpl.java` | 最小 SIP 适配 + 回落判定 |
|
||||
| `com/ruoyi/quartz/task/AptDispatchTask.java` | Quartz 入口(**放在 `com.ruoyi.quartz.task` 包**,见 §4.7) |
|
||||
| `framework/config/AptProperties.java` | 新增 `features`(`tablet-call`、`voice-summary`)与 `dispatch`(5 个参数 + TTS) |
|
||||
| `resources/apt-defaults.yml` | 新增配置项与环境变量映射 |
|
||||
|
||||
### 2.2 SQL(`dev/sql/apt_rev01`)
|
||||
|
||||
| 文件 | 说明 |
|
||||
| --- | --- |
|
||||
| `19_it5_columns.sql` | `gy_jcxx` 补 12 列(11 个时间戳/标志位 + `jch`)、`duty_manual_action.reason`、动作枚举注释、2 个索引;全程幂等 |
|
||||
| `20_it5_permissions.sql` | 启用 `3004`、新增 `3203` 页面与 `3220/3221/3222` 权限点、超管关联、`sys_job` 103 叫乘扫描(默认停用) |
|
||||
| `99_verify.sql` | 追加第 20~26 段:增量列、权限点、平板字典 CHECK、终态一致性、已结束不回退、DONE 任务必有结果、平板无 #24 |
|
||||
|
||||
### 2.3 前端(`dev/RuoYi-Vue2-master`)
|
||||
|
||||
| 文件 | 说明 |
|
||||
| --- | --- |
|
||||
| `src/api/apt/jcxx.js` | 6 个接口封装;**无 update 方法** |
|
||||
| `src/views/apt/jcxx/index.vue` | 台账列表、状态分布、详情抽屉 + 时间线、命令弹窗、修正弹窗 |
|
||||
| `src/utils/apt.js` | 新增 `aptRyztOptions` / `aptCallModeOptions` / `aptDutyCommandOptions` / `aptTimelineSourceOptions` |
|
||||
|
||||
### 2.4 脚本与测试
|
||||
|
||||
| 文件 | 说明 |
|
||||
| --- | --- |
|
||||
| `dev/scripts/apply-it5-sql.ps1` | 复用 `.env` / `APT_DB_*`,按字节流喂 `mysql`,支持 `-DryRun` |
|
||||
| `ruoyi-apt/src/test/java/com/ruoyi/apt/dispatch/AptDutyStateServiceTest.java` | 6 例 |
|
||||
| `.../dispatch/AptDutyCommandServiceTest.java` | 7 例 |
|
||||
| `.../dispatch/AptJcxxServiceTest.java` | 9 例 |
|
||||
| `.../dispatch/AptTabletResultServiceTest.java` | 9 例 |
|
||||
| `.../framework/AptIt5SqlContractTest.java` | 5 例 |
|
||||
| `.../framework/AptDutyStateSingleWriterArchTest.java` | 3 例(架构约束) |
|
||||
|
||||
## 3. 接口说明
|
||||
|
||||
### 3.1 设备侧(`/open/v1/tablet/**`,设备四要素鉴权)
|
||||
|
||||
| 接口 | 行为 |
|
||||
| --- | --- |
|
||||
| `GET /open/v1/tablet/tasks?cursor&limit` | 按 `dispatch_seq` 升序返回 `WAITING`/`PULLED` 任务;含 `serverTime`、`clockSkewThresholdMs`、`signTimeoutSec`、`faceVerifyRequired`、TTS 模板 |
|
||||
| `POST /open/v1/tablet/tasks/{taskId}/ack` | 条件更新 `WAITING → PULLED`;未命中(重复/过期/已绑其他平板)返回 `40916` |
|
||||
| `POST /open/v1/tablet/results` | `resultId` 幂等;`(gyid, result_id)` 唯一键冲突时返回首次结果 |
|
||||
|
||||
要点:**拉取 ≠ 执行**,服务端不下发「立即呼叫」指令;平板按本地定时器在 `jcsj` 播放提示音。
|
||||
|
||||
### 3.2 管理端(`/apt/jcxx`,表 4-9)
|
||||
|
||||
| 接口 | 权限点 | 说明 |
|
||||
| --- | --- | --- |
|
||||
| `GET /apt/jcxx/list` | `apt:jcxx:list` | `ryid/rymc/fjh/cc/jlid/ryzt[]/finishJc/finishLy/stoped/isTempCall/jcsjFrom/jcsjTo` |
|
||||
| `GET /apt/jcxx/statistics` | `apt:jcxx:list` | 6 状态 + 已结束 + 总数;`date` 缺省为全量 |
|
||||
| `GET /apt/jcxx/{id}` | `apt:jcxx:query` | 主表 + 最近会话 + 录音索引 + 人工命令 |
|
||||
| `GET /apt/jcxx/{id}/timeline` | `apt:jcxx:query` | 5 类来源合并,按 `atMillis` 升序 |
|
||||
| `POST /apt/jcxx/{id}/correct` | `apt:jcxx:correct` | 白名单;改状态 `40001`;已离寓禁止改房间/交路 `40902` |
|
||||
| `POST /apt/jcxx/{id}/commands` | `apt:jcxx:changeStatus` | 5 命令;`commandId` 幂等;非法状态 `40902` |
|
||||
|
||||
### 3.3 内部服务(不暴露为接口)
|
||||
|
||||
- `IAptDutyStateService`:`callStart / answered / callFailed / stop / recall / forceFinish / markLeave / cancel`。
|
||||
- `IAptVoiceEventService.handle()`:AMI 事件 → 命令;`resolveCallMode()`:平板不可用回落 `SIP`。
|
||||
- `IAptDispatchScanService.scan()`:由 Quartz 调用。
|
||||
|
||||
## 4. 关键实现要点
|
||||
|
||||
### 4.1 状态机唯一写入口(DV-5)
|
||||
|
||||
- 全仓 `UPDATE gy_jcxx SET ryzt/finish_jc/finish_ly/stoped` **只出现在** `AptDutyStateMapper.xml`,由 `AptDutyStateSingleWriterArchTest` 静态守卫。
|
||||
- 每条 UPDATE 都带 `gyid + jcid + 期望态`,未命中返回 0 行 → 服务层 `40902 STATE_TRANSITION_ILLEGAL`;并发下不会出现「后写覆盖先写」。
|
||||
- 全部迁移递增 `biz_version`,为后续跨端版本对照与 outbox 幂等键提供依据。
|
||||
|
||||
### 4.2 双模式与事实来源唯一
|
||||
|
||||
- `call_mode='TABLET'` 的记录,`ryzt` 迁移只由 N-04 上报触发;**不做服务端定时自动迁移**(含签到窗口超时,由平板上报 `NO_ANSWER`)。
|
||||
- `call_mode='SIP'` 的 30s 无入会由扫描任务提交 `CALL_FAILED` 命令,仍是「提交命令」而非直写。
|
||||
- `resolveCallMode()` 在 `features.tablet-call=false` 或无 `ACTIVE` 平板时返回 `SIP`(CR-C23 回落)。
|
||||
|
||||
### 4.3 平板终态矩阵(表 5-20 逐条实现)
|
||||
|
||||
| 上报 | 状态机动作 | `applied_state` | 上行 |
|
||||
| --- | --- | --- | --- |
|
||||
| `ANSWERED` + `VERIFIED` | `ANSWERED` → `ryzt=3`、`finish_jc=1` | `APPLIED` | #9 |
|
||||
| `ANSWERED` + `UNVERIFIED`/`SKIPPED` | **不提交状态命令**(保持待确认)+ 复叫提示 | `APPLIED` | #9 + #12(`alarmSource=CALL`) |
|
||||
| `NO_ANSWER` / `FAILED` | `CALL_FAILED` → `ryzt=2` | `APPLIED` | #9 |
|
||||
| `CANCELLED` | `ryzt in (1,2)` → `STOP`;`ryzt=0` → `CANCEL` | `APPLIED` | #9 |
|
||||
| 迟到 / 重复 / 状态冲突 | 不回写、不重复上报 | `IGNORED` | — |
|
||||
|
||||
### 4.4 命令幂等与审计
|
||||
|
||||
- `commandId` → `duty_manual_action(action_id)` 唯一键;重复提交只置 `duplicated=1 / state='DUPLICATED'`,返回 `duplicated=true`,**不产生第二次迁移**。
|
||||
- 三层记录:`duty_manual_action`(命令意图与结果,可重试)、`duty_operation_log`(审计事实,`detail.jcid` 可回查)、`gy_jcxx` 状态列(事实)。
|
||||
- `STOP` 在 `finish_ly='1'` 上提交 → `40902`;`RE_CALL` 额外新增一行 `apt_call_session`(表 3-10 复叫语义)。
|
||||
|
||||
### 4.5 时间线装配
|
||||
|
||||
五路来源合并后按 `atMillis` 升序:状态时间戳(`jcsj`/`jcsj_s`/`jcbjsj_s`/`fjsj_s`/`hjxysj`/`lybjsj`/`sjlysj`)、`apt_call_event`(AMI)、`duty_manual_action`(人工命令)、`duty_operation_log`(审计,`JSON_EXTRACT(detail,'$.jcid')`)、`apt_tablet_call_result`(平板结果)。
|
||||
|
||||
### 4.6 平板派发
|
||||
|
||||
- `dispatch_seq` 单调:`MAX(dispatch_seq)+1` 逐条分配,同时回写 `gy_jcxx.dispatch_seq`;任务 `taskId = TT-{jcid}-{seq}`。
|
||||
- 过期只置 `EXPIRED`,不重派;`DONE` 任务必须存在结果行(`99_verify.sql` 第 25 段校验)。
|
||||
- 结果上行 outbox:`idempotencyKey = sha256(gyid|bizType|bizId|bizVersion)`,`bizType` 仅用 `TABLET_RESULT` / `DEVICE_ALARM`。
|
||||
|
||||
### 4.7 扫描任务与 Quartz 白名单
|
||||
|
||||
若依 `ScheduleUtils.whiteList` 只允许 `com.ruoyi.quartz.task` 前缀的 `invokeTarget`。为避免扩白名单,Job bean 仍放在该包(物理位于 `ruoyi-apt` 模块),委托 `IAptDispatchScanService`,因此 `ruoyi-quartz` 无需依赖 `ruoyi-apt`。
|
||||
扫描线程无 HTTP 上下文,`AptDispatchScanServiceImpl` 进入时用 `apt.gy-id` 建立 `AptContext`,`finally` 清理。
|
||||
|
||||
## 5. 部署与使用注意
|
||||
|
||||
1. **SQL 顺序**:`19_it5_columns.sql` → `20_it5_permissions.sql` →(可选)`99_verify.sql`;可用
|
||||
`powershell -ExecutionPolicy Bypass -File dev/scripts/apply-it5-sql.ps1`(先 `-DryRun` 自查)。
|
||||
2. **菜单/权限**:`3004 apt:jcxx:list` 由 IT-1 预置,本期改为启用;新增 `3203` 页面菜单,组件路径 `apt/jcxx/index` 必须与 `src/views/apt/jcxx/index.vue` 一致。
|
||||
3. **配置项**(`apt-defaults.yml`):`apt.features.tablet-call`、`apt.dispatch.sign-timeout-sec`(60)、`clock-skew-threshold-ms`(1000)、`sip-no-answer-seconds`(30)、`recall-seconds`(35)、`tablet-task-ttl-seconds`(900)。
|
||||
4. **定时任务**:`sys_job` 103 `aptDispatchTask.scan()`,cron `0 * * * * ?`,**默认停用**;需确认 `ScheduleConfig` 已启用后再手工启动。
|
||||
5. **设备侧**:`/open/v1/tablet/**` 复用 IT-3 的 HMAC + nonce + 时间窗校验,平板须携带 `X-Device-Code`;`apt_tablet_device.register_status` 必须是 `ACTIVE`。
|
||||
|
||||
### 5.1 执行记录(2026-11-11,`apt_rev01`)
|
||||
|
||||
按上述顺序实际执行完毕,凭据取自 `dev/.env`(`APT_DB_*`),未打印口令:
|
||||
|
||||
| 步骤 | 命令 | 结果 |
|
||||
| --- | --- | --- |
|
||||
| 0 | `apply-it5-sql.ps1 -DryRun` | 预检通过:目标 `127.0.0.1:3306/apt_rev01`,2 个脚本(111 / 97 行) |
|
||||
| 1 | `19_it5_columns.sql` | 成功:`gy_jcxx` 增量列 **12/12**、`duty_manual_action` 三列(`action_type` / `state` / `reason`)、索引 2 个(`idx_jcxx_gyid_mode_state`、`idx_tabletresult_gyid_time`)、状态字段非法值 0 行 |
|
||||
| 2 | `20_it5_permissions.sql` | 成功:菜单 **5 行**(`3004` 已启用 + `3203/3220/3221/3222`)、`3203` 组件路径 `apt/jcxx/index`、超管关联 5、菜单树 M=1 / C=7 / F=27、置灰残留 0 |
|
||||
| 3 | `99_verify.sql` | 第 20~26 段全部通过:增量列 12、权限点 5、平板 CHECK 3、`ryzt=3` 缺完成 0、已结束回退 0、DONE 无结果 0、平板 #24 泄漏 0 |
|
||||
|
||||
执行中发现并修复的问题(已回写脚本):`apt_add_column_if_missing` 的过程体只拼 `ALTER TABLE \`t\` ADD COLUMN `,`p_ddl` 必须自带列名;首版漏列名导致 `ERROR 1064 near '(3) ...'`,补齐列名后重放通过(脚本本身幂等,可直接重跑)。
|
||||
|
||||
## 6. 验收标准
|
||||
|
||||
### 6.1 与 07 表 7-3(M3)对应
|
||||
|
||||
| M3 验收项 | 落地 | 证据 |
|
||||
| --- | --- | --- |
|
||||
| 只读字段不可改,`PUT /apt/jcxx/{id}` 不存在 | `AptJcxxController` 无 PUT;`correct` 拒绝状态字段 | `AptJcxxServiceTest#correctRejectsStateFieldsWith40001` |
|
||||
| `STOP` 同 `commandId` 幂等 | `duty_manual_action` 唯一键 + `duplicated` 分支 | `AptDutyCommandServiceTest#sameCommandIdIsIdempotentAndDoesNotTransitionAgain` |
|
||||
| 对 `finish_ly='1'` 记录 `STOP` → `40902` | `checkAllowed` + 条件更新双保险 | `AptDutyCommandServiceTest#stopOnLeftRecordReturns40902` |
|
||||
| 时间线按时间升序 | 五路合并 + `atMillis` 排序 | `AptJcxxServiceTest#timelineMergesFourSourcesInAscendingOrder` |
|
||||
|
||||
### 6.2 与 13 表 13-15(IT-5)对应
|
||||
|
||||
| 验收点 | 证据 |
|
||||
| --- | --- |
|
||||
| `TABLET_RESULT` 重复不产生二次终态 | `AptTabletResultServiceTest#duplicateResultIdReturnsFirstResultWithoutTransition` |
|
||||
| `UNVERIFIED` 保持待确认 + 告警(不自动完成) | `#unverifiedKeepsStateAndRaisesAlarmWithoutVoiceSummary` |
|
||||
| `NO_ANSWER` → `ryzt=2` | `#noAnswerSubmitsCallFailed` |
|
||||
| 迟到结果 `IGNORED` | `#lateResultOnFinishedCallIsIgnored`、`#stateConflictDuringTransitionIsRecordedAsIgnored` |
|
||||
| 平板链路不发 #24 | 同上断言 + `99_verify.sql` 第 26 段 |
|
||||
| 状态字段单写入口 | `AptDutyStateSingleWriterArchTest`(3 例) |
|
||||
|
||||
### 6.3 回归
|
||||
|
||||
`mvn -o -pl ruoyi-apt -am test`:**189 例全部通过**(新增 39 例,覆盖 `dispatch` 4 类 + SQL 契约 + 架构约束);前端 `eslint` 无新增告警。
|
||||
|
||||
## 7. 偏离与遗留登记
|
||||
|
||||
| 编号 | 类型 | 内容 | 处理 |
|
||||
| --- | --- | --- | --- |
|
||||
| IT5-L1 | 文档补充 | `gy_jcxx` 缺 `jch` 列,但表 4-9 correct 白名单含「机次」 | `19_it5_columns.sql` 补列,`03` §3.2 表 3-8 待同步补记 |
|
||||
| IT5-L2 | 实现取舍 | 拉取响应 `clockSkewMs` 返回 `null`,只给 `serverTime` + 阈值 | 服务端没有设备时钟基准,避免伪造校准依据;平板按 `serverTime` 自行比对 |
|
||||
| IT5-L3 | 接口边界 | 未新增 AMI 接入端点与 Asterisk 连接,`IAptVoiceEventService` 仅供服务内部调用 | 归 IT-7(语音与运维);本期只保证映射与回落逻辑 |
|
||||
| IT5-L4 | 调度依赖 | `sys_job` 登记但默认停用,`ScheduleConfig` 是否启用未在本期验证 | 联调步骤 9 前确认,避免「任务存在但不跑」 |
|
||||
| IT5-L5 | 数据归日 | 平板结果 #9 的 `occurredAt` 取设备上报值,平台侧 `serverReceivedAt` 归日 | 与 IT-3 outbox 一致,沿用既有字段 |
|
||||
| IT5-L6 | 未联调 | 平板真机、HMAC 双向联调、断网续拉(cursor 重放)未做实机验证 | 待设备到位后补 `M5` 前联调,验收脚本已就绪 |
|
||||
| IT5-L7 | 遗留字段 | `11` 表 11-13 的 `regState` 仍含 `NOT_FOUND`,与 `10` 表 10-11 不同字典 | 待裁决后统一(本迭代未动) |
|
||||
+3
-1
@@ -20,7 +20,7 @@
|
||||
| `README.md` | 索引、编号约定、全局对应关系、一页结论、与 `docs/平台端/` 的编号对应 | 输出形式 |
|
||||
| `00-公寓端主要功能设计.md` | **需求基线**:14 项功能编号化 `A-01`~`A-14`、主责端 / 协同端 / 本期判定 | CR-02 输入 |
|
||||
| `01-功能边界.md` | 定位与职责、三端五维分界、**16 个功能域清单**(§0 为 v2 增量)、本期不做、待决策对边界的影响 | 文档一 + CR-02 |
|
||||
| `02-技术基线与工程结构.md` | 版本锁定、12 模块职责与依赖、前端双入口边界、分层与编码规范、路由与权限点 | 文档二 1~4 |
|
||||
| `02-技术基线与工程结构.md` | 版本锁定、12 模块职责与依赖、前端双入口边界、分层与编码规范、路由与权限点;**§2.5 实现层 `ruoyi-apt` 集中模块**:职责范围、结构定位、模块关系图(图 2-3)、构建识别与前端落地口径(单入口动态路由、偏离 16-19) | 文档二 1~4 |
|
||||
| `03-数据设计.md` | 表归属矩阵(**59 张口径**)、语音域字段与注册状态流水、命名分区、状态单写入口、`gyid` 隔离、逻辑删除与审计、缺口与建议 | 文档二 5 + CR-02 §6、§10 |
|
||||
| `04-接口设计.md` | 通用约定与错误码、分域接口清单、设备侧 `/open/v1/tablet/**`、四个核心域映射;§0 表 C-1~C-8 为 CR-02 增量接口与错误码(N-15~N-58、40913~40940) | 文档二 6 + CR-02 §3、§10~§14 |
|
||||
| `05-关键流程.md` | 叫乘执行(SIP / 平板双模式)、设备接入、语音与录音、主数据下行、上报 outbox 与续报、值班人工干预;**§9 两类叫乘实现方式的端到端流程**(触发条件 / 交互时序 / 状态上报 / 结果反馈)、**§10 入住作业流程索引**(F-K)、**§11 消费 / 充值 / 菜品管理索引**(F-L / F-M / F-N) | 文档二 7 + CR-02 §7、§11、§13、§14 |
|
||||
@@ -34,6 +34,7 @@
|
||||
| `13-公寓端小步迭代开发计划.md` | **实施排期设计稿(非设计变更)**:`dev/` 实测上游、`IT-0`~`IT-8` 迭代目标 / 范围 / 依赖 / 验收、里程碑 `MS-0`~`MS-5`、交付物 `DV-0`~`DV-8`、设计文档 × 代码模块对齐矩阵、6 项 P0 排期前提与 `IR-01`~`IR-14` 风险台账、跨迭代联调与回归基线、`IT-9`~`IT-11` 消费 / 充值 / 菜品衔接;表 13-1~13-32、图 13-1 | 开发排期与联调(**阶段 / 验收口径仍以 `07` 为准**) |
|
||||
| `14-第一轮开发(IT-0)交付说明.md` | **第一轮实现交付说明**:模块职责边界与依赖图、59 张表全量字段 / 主键 / 唯一键 / 索引设计、DDL 脚本与迁移顺序、自检接口的请求参数 / 返回结构 / 错误码约定、连接失败 / 超时 / 数据异常处理矩阵、20 项实测验证结果、口径偏离与后续衔接;表 14-1~14-23、图 14-1 | `IT-0` 落地与验收(代码在 `dev/RuoYi-Vue-master`、`dev/sql/apt_rev01`) |
|
||||
| `15-第二轮开发(IT-1)交付说明.md` | **第二轮实现交付说明**:运行时基座 M0 的四前缀治理与鉴权、统一错误码与表 4-4 HTTP 状态映射、审计切面落 `duty_operation_log`、分页上限 100、springdoc 分组、权限点种子与只读列表骨架、41 个单测与端到端 M0 5/5 验证结果、14 项口径偏离登记与后续衔接;表 15-1~15-17、图 15-1 | `IT-1` 落地与验收(代码在 `dev/RuoYi-Vue-master`、`dev/sql/apt_rev01`、`dev/scripts`) |
|
||||
| `16-第三轮开发(IT-2)交付说明.md` | **第三轮实现交付说明**:M1 交路 CRUD / 启停 / 复算、M2 房间档案 / 房态 / `state_version` / `commandId` 幂等、主数据下行 Mock 灌数与 `source='LOCAL'` 版本标记、IT-1 遗留项闭环;79 个单测与端到端 24/24 验证结果、SQL 实库校验与中文编码缺陷修复、18 项口径偏离登记;**第 9 章 `ruoyi-apt` 模块归置**(清单 / 职责边界 / 依赖与关系图 / 构建识别 / 验证)、**第 10 章前端页面补齐**(范围界定 / 页面与接口对应 / RuoYi 规范一致性 / 路由菜单统一 / 未开放能力 / 验证);表 16-1~16-30、图 16-1 / 16-2 / 16-3 | `IT-2` 落地与验收(代码在 `dev/RuoYi-Vue-master/ruoyi-apt`、`dev/RuoYi-Vue2-master/src/{api,views,router}`、`dev/sql/apt_rev01`、`dev/scripts`) |
|
||||
| `../设计变更/03-三端功能设计修订(CR-02).md` | **权威增量**:三端覆盖范围、交互协议、交互数据、模块与数据表、关键流程变更、施工单 | CR-02 |
|
||||
|
||||
## 1. 编号与引用约定
|
||||
@@ -108,6 +109,7 @@ flowchart LR
|
||||
M --> N["13 小步迭代开发计划(排期 / 联调)"]
|
||||
N --> O["14 第一轮开发 IT-0 交付说明(实现 / 验收)"]
|
||||
O --> P["15 第二轮开发 IT-1 交付说明(运行时基座 M0)"]
|
||||
P --> Q["16 第三轮开发 IT-2 交付说明(交路 / 房间 / 版本标记)"]
|
||||
```
|
||||
|
||||
图 0-1 阅读路径
|
||||
|
||||
@@ -29,6 +29,10 @@
|
||||
| v1.6 | 2026-11-10 | **补遗 §15**:把公寓端已完成的四项调整(**平板叫乘、人脸签到、消费、菜品管理**)在应用端 / 平台端同步落地,统一业务规则、交互流程、权限控制、异常处理,并给出**三端状态映射与数据同步机制**唯一权威表(表 3-66);同时新增平台端「以公寓为单位的分类统计 / 月·季·年报表 / 公寓排名」能力(`docs/平台端/10`,`PS-01`~`PS-05`)。新增裁决 CR-C36~CR-C42、流程 F-O / F-P / F-Q、决策点 Q-46~Q-50、验收 24~26、施工单 R-114~R-125;**变更点与影响范围**见 §15 表 3-63。跨端仍 20 个编号、契约 `v2-draft`、平台零回调、公寓本地库 **59 张**、不新增 `bizType`;统计能力全部落平台管理端 `/platform/v1/admin/stat/**`,新增 2 张 `pl_apt_stat_*` 属**平台库**(另计),统计结果不回写任何业务状态 |
|
||||
| v1.7 | 2026-11-10 | **非设计变更登记(索引同步)**:新增 `docs/公寓端/13-公寓端小步迭代开发计划.md`(v1.0,实施排期设计稿),以 `dev/` 的 RuoYi-Vue / Vue2 / MySQL 实测上游为物理起点,把 §11~§15 的设计成果切成 `IT-0`~`IT-8` 九个小步迭代(**P1 入住 + 叫乘核心闭环优先**)、里程碑 `MS-0`~`MS-5` 与交付物 `DV-0`~`DV-8`;**P2 消费 / 充值 / 菜品整体延后**为 `IT-9`~`IT-11`("设计已覆盖、实现延后",非删需求)。登记 6 项 P0 排期前提与 3 项口径偏离(表 13-4 / 表 13-6),须评审签字后方可执行。**变更点与影响范围**:新建 `公寓端/13` 1 篇,同步 `公寓端/00`、`公寓端/README.md`、`公寓端/07`、`公寓端/08`、`docs/README.md` 与本文表 0-2 / 0-3 索引;**不改动** §12~§15 任何权威表述,**不新增**裁决 `CR-C*` / 流程 `F-*` / 决策点 `Q-*` / 验收 / 施工单 `R-*` / `M7` / 阶段六 / `D-4` 等既有编号;跨端仍 20 个编号、契约 `v2-draft`、平台零回调、公寓本地库 **59 张表**、平台库累计新增 5 张(含 2 张 `pl_apt_stat_*`)、`apt.duty.state` 单写入口、统计结果不回写全部不变;阶段与验收仍以 `docs/10` §9、`公寓端/07` 表 7-1~7-8 为权威,`13` 篇内 `IT-*` / `MS-*` / `DV-*` / `IR-*` 编号不纳入本文体系 |
|
||||
| v1.8 | 2026-11-10 | **非设计变更登记(索引同步)**:新增 `docs/公寓端/15-第二轮开发(IT-1)交付说明.md`(v1.0),登记 `IT-1 运行时基座 M0` 的实现与验收——四前缀治理与 `/apt/**` 鉴权、`gyid` 隔离、统一错误码与表 4-4 HTTP 状态映射、401/403 处理器、审计切面落 `duty_operation_log`、分页上限 100、springdoc 分组、权限点种子与只读列表骨架;41 个单测全绿,真实进程端到端 M0 **5/5 通过**(`dev/scripts/verify-it1-m0.ps1`)。**变更点与影响范围**:新建 `公寓端/15` 1 篇与 `dev/scripts/verify-it1-m0.ps1` 1 个脚本,同步 `公寓端/README.md`、`公寓端/14` 表 14-23、`docs/README.md` 与本文表 0-2 索引;**不改动** §12~§15 任何权威表述,**不新增**裁决 `CR-C*` / 流程 `F-*` / 决策点 `Q-*` / 验收 / 施工单 `R-*` 等既有编号;跨端仍 20 个编号、契约 `v2-draft`、平台零回调、公寓本地库 **59 张表**、`apt.duty.state` 单写入口、统计结果不回写全部不变;`IT-*` / `DV-*` 仍为 `13` 篇内编号,不纳入本文体系;契约冻结签字与 `D5` 签字仍为 P0 待办 |
|
||||
| v1.9 | 2026-11-11 | **非设计变更登记(索引同步)**:新增 `docs/公寓端/16-第三轮开发(IT-2)交付说明.md`(v1.0),登记 `IT-2` M1 交路 / M2 房间 / 主数据下行 Mock 的实现与验收——交路 CRUD、启停原因审计、复算校验;房间档案、房态、`state_version` 条件更新与 `commandId` 幂等;`apt_master_version` 6 域 `source='LOCAL'` / `source_version=0` / `state='APPLIED'` 与只读接口 `/apt/master/versions`;IT-1 遗留项(审计 `REQUIRES_NEW`、参数校验异常分派)闭环。79 个单测全绿,`dev/sql/apt_rev01/10~12` 实库执行与校验通过,`dev/scripts/verify-it2-m1m2.ps1` 真实进程端到端 **23/23 通过**(本行为 v1.9 当时的历史口径;v2.0 新增 M0-5 后扩展为 24/24)。**变更点与影响范围**:新建 `公寓端/16` 1 篇与 `dev/scripts/apply-it2-sql.ps1`、`dev/scripts/verify-it2-m1m2.ps1` 2 个脚本,同步 `公寓端/README.md`、`公寓端/14` 表 14-23、`公寓端/15` 表 15-17、`docs/README.md` 与本文表 0-2 索引;**不改动** §12~§15 任何权威表述,**不新增**裁决 `CR-C*` / 流程 `F-*` / 决策点 `Q-*` / 验收 / 施工单 `R-*` 等既有编号;跨端仍 20 个编号、契约 `v2-draft`、平台零回调、公寓本地库 **59 张表**、`apt.duty.state` 单写入口、统计结果不回写全部不变;`IT-*` / `DV-*` 仍为 `13` 篇内编号,不纳入本文体系;契约冻结 / `D5` / `D8'` / `D3` / `D7` 签字仍为 P0 待办 |
|
||||
| v2.0 | 2026-11-11 | **非设计变更登记(实现层模块归置)**:新增 `dev/RuoYi-Vue-master/ruoyi-apt` Maven 模块,把 `IT-0`~`IT-2` 分散在 `ruoyi-common` / `ruoyi-framework` / `ruoyi-system` / `ruoyi-admin` 的 64 个公寓端文件(45 主类 + 15 测试 + 4 Mapper XML)统一收拢到 `com.ruoyi.apt.**`,并抽出 `apt-defaults.yml` 承载 `apt.*` / springdoc 分组 / 日志级别。根 `pom.xml` 的 `<modules>` 与 `<dependencyManagement>`、`ruoyi-admin/pom.xml` 依赖、`SecurityConfig` 按 Spring Security 接口 + bean 名装配(编译期零反向依赖)、`application.yml` 的 `spring.config.import` 同步调整;`@SpringBootApplication` / `@MapperScan("com.ruoyi.**.mapper")` / `classpath*:mapper/**/*Mapper.xml` 均为通配,无需改扫描包名。**验证**:`mvn -pl ruoyi-admin -am clean package` 7 模块 `BUILD SUCCESS`、79 个单测全绿、端到端 **24/24 通过**(含配置导入与 springdoc 分组校验)。**变更点与影响范围**:`公寓端/02` 新增 §2.5(职责 / 表 2-14 / 2-15 / 图 2-3)、`公寓端/16` 新增第 9 章并同步表 16-4 / 图 16-1,同步 `公寓端/README.md`、`公寓端/14` 表 14-2 注记、`公寓端/15` 表 15-4 注记、`docs/README.md` 与本文表 0-2 索引;**不改动** §12~§15 任何权威表述,**不新增**裁决 `CR-C*` / 流程 `F-*` / 决策点 `Q-*` / 验收 / 施工单 `R-*` 等既有编号;跨端仍 20 个编号、契约 `v2-draft`、平台零回调、公寓本地库 **59 张表**、`apt.duty.state` 单写入口、统计结果不回写全部不变;`IT-*` / `DV-*` 仍为 `13` 篇内编号;契约冻结 / `D5` / `D8'` / `D3` / `D7` 签字仍为 P0 待办 |
|
||||
|
||||
| v2.1 | 2026-11-11 | **非设计变更登记(前端页面补齐)**:在 `dev/RuoYi-Vue2-master` 补齐公寓端 4 个菜单页 + 2 个隐藏详情页(交路列表 / 详情、房间列表 / 详情、主数据版本台账、连通性自检),新建 `src/api/apt/{route,room,master,ops}.js`、`src/utils/apt.js`(状态 / 错误码映射与前端 CSV 导出)、`src/components/AptDisabledAction/index.vue`,增强 `src/utils/request.js` 的 4xx 错误提示;`src/router/index.js` 的 `dynamicRoutes` 增 2 条按权限过滤的详情路由;新增可重放 `dev/sql/apt_rev01/13_it2_frontend_menus.sql`(4 条 `C` 菜单 3101~3104)并纳入 `apply-it2-sql.ps1`。**范围**:只补齐 `IT-0`~`IT-2` 已有后端 Controller 的 4 个功能域;`IT-3`~`IT-8` 设计页面与 `IT-9`~`IT-11` P2 账务域按 `13` 表 13-29 不建页面、不建菜单。**验证**:`npm run build:prod` `exitCode=0`;`13` 实库重放后菜单树 `M=1 / C=4 / F=15`、超管关联 4、置灰项关联 0、M0 账号 0;lints 0。**变更点与影响范围**:`公寓端/02` §2.5 表 2-14 / 图 2-3 与新增「前端落地口径」段、`公寓端/16` 新增第 10 章(表 16-25~16-30、图 16-3)并同步表 16-1 / 16-17 / 16-19 / 16-21、两处 `README.md` 索引;**不改动** §12~§15 权威表述,**不新增**裁决 `CR-C*` / 流程 `F-*` / 决策点 `Q-*` / 验收 / 施工单 `R-*` 等既有编号;设计期 `docs/10` 表 2-3 的「双入口 + 静态路由」口径不改写,实现层偏离登记在 `公寓端/16` 偏离项 16-19;跨端仍 20 个编号、契约 `v2-draft`、平台零回调、公寓本地库 **59 张表**、`apt.duty.state` 单写入口、统计结果不回写全部不变;契约冻结 / `D5` / `D8'` / `D3` / `D7` 签字仍为 P0 待办 |
|
||||
|
||||
表 0-3 本文件图表编号规则
|
||||
|
||||
|
||||
Reference in new issue
Block a user