初始提交:三端设计文档与 dev 代码基线
docs/:系统梳理、架构优化方案、CR-02 三端功能设计修订(含 §15 三端一致性同步与平台统计分析)、公寓端/应用端/平台端分册、公寓统计分析与排名报表、公寓端小步迭代开发计划(IT-0~IT-8) dev/:RuoYi-Vue-master(后端)与 RuoYi-Vue2-master(前端)官方上游基线,未改动
This commit is contained in:
commit
329e27b515
723 files changed
+99917
No files matched your search
@@ -0,0 +1,110 @@
|
||||
# 01 系统总览
|
||||
|
||||
## 1. 业务定位
|
||||
|
||||
`yktgl` 是铁路行车公寓的**叫乘(叫班)管理系统**。公寓为值乘机车的乘务员提供住宿,系统负责把“入住—叫乘—出乘—离寓”串起来,并对接机务运安系统的乘务计划,确保乘务员按时出乘。
|
||||
|
||||
核心业务闭环:
|
||||
|
||||
1. 乘务员到寓,在设备或值班端完成**入寓登记**,分配房间与床位,读取/生成叫乘计划(开车时间、叫乘时间、复叫时间、叫乘结束时间)。
|
||||
2. 到点自动**叫乘**:通过电话/广播(Asterisk 会议桥 + TTS)呼叫房间和值班台;未应答触发**复叫**,仍未应答触发**报警**。
|
||||
3. 乘务员**应答**后记录应答时间,结束本次叫乘。
|
||||
4. 乘务员**离寓**(刷卡/人脸/值班端操作),释放房间床位,写离寓时间与归档标记。
|
||||
5. 卡务侧完成**补助发放、余额、消费、现金充值**;管理端提供房间、人员、交路、统计报表、设备心跳与指令。
|
||||
|
||||
## 2. 使用角色
|
||||
|
||||
| 角色 | 使用入口 | 主要动作 |
|
||||
| --- | --- | --- |
|
||||
| 公寓值班员 | Web 管理端(`YktVue`) | 入寓/离寓登记、叫乘监控与人工干预、换房、房间状态、充值审核 |
|
||||
| 公寓管理员 | Web 管理端 | 人员、交路、房间、设备、报表、用户权限 |
|
||||
| 乘务员 | 公寓设备(叫乘屏/签到机/房间屏/消费机/售货机) | 自助登记、查询、应答、消费、充值 |
|
||||
| 保洁人员 | 房间设备/管理端 | 开始/结束保洁 |
|
||||
| 运安系统 | SOAP / HTTP | 下发乘务计划、人员资料 |
|
||||
| 中心服务器 | HTTP | 汇总公寓人员、财务数据 |
|
||||
|
||||
## 3. 运行形态
|
||||
|
||||
系统同时支持两种部署语义,但代码是同一套:
|
||||
|
||||
- **公寓端**:每套公寓一套服务(或同一服务按 IP 区分公寓),连接本地 Asterisk、串口控制台、各类设备。
|
||||
- **中心/汇总端**:通过 `/synData/*`、`/excel/*` 提供人员与财务数据汇总;部分环境由中心下发交路。
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
subgraph 公寓现场
|
||||
DEV[叫乘屏/签到机/房间屏/消费机/售货机]
|
||||
WEB[值班员浏览器 YktVue]
|
||||
PHONE[电话/广播终端]
|
||||
CONSOLE[串口控制台]
|
||||
end
|
||||
|
||||
subgraph 应用服务器
|
||||
APP[Spring Boot yktgl<br/>context /yktgl :8081]
|
||||
WS[WebSocket 服务]
|
||||
QZ[Quartz / @Scheduled]
|
||||
REDIS[(Redis Session)]
|
||||
DB[(KingbaseES gygl)]
|
||||
end
|
||||
|
||||
subgraph 外部系统
|
||||
AST[Asterisk AMI / Conf-01]
|
||||
BYXX[机务运安 SOAP]
|
||||
CENTER[中心服务器 HTTP]
|
||||
end
|
||||
|
||||
DEV -->|HTTP 心跳/业务| APP
|
||||
WEB -->|HTTP + WebSocket| APP
|
||||
APP --- WS
|
||||
APP --- QZ
|
||||
APP --- REDIS
|
||||
APP --- DB
|
||||
QZ -->|呼叫| AST
|
||||
AST --> PHONE
|
||||
AST --> CONSOLE
|
||||
APP -->|WSDL PbResource| BYXX
|
||||
APP <-->|人员/财务| CENTER
|
||||
```
|
||||
|
||||
## 4. 技术栈
|
||||
|
||||
| 层次 | 选型 | 说明 |
|
||||
| --- | --- | --- |
|
||||
| 运行时 | Java 8、Spring Boot 2.6.13 | 继承 `spring-boot-starter-parent`;`pom.xml` 未声明 packaging(默认 jar),入口继承 `SpringBootServletInitializer`,也可改为 WAR 部署到外部 Tomcat |
|
||||
| Web | Spring MVC、Spring WebSocket | `@ServerEndpoint` + `ServerEndpointExporter` |
|
||||
| 持久化 | MyBatis-Plus 3.1.0、PageHelper 1.4.1 | Mapper XML 位于 `classpath:mapper/**/*.xml` |
|
||||
| 数据库 | KingbaseES 8(`kingbase8` 8.6.0) | URL 形如 `jdbc:kingbase8://host:54321/gygl?currentSchema=gygl`;SQL 大量使用 Oracle 兼容写法(`TO_DATE`、`NVL`、`ROWNUM`、`MERGE`、`LISTAGG`、`sysdate`) |
|
||||
| 缓存/会话 | Redis + Spring Session | `@EnableRedisHttpSession`,默认 30 分钟 |
|
||||
| 调度 | Quartz(内存模式)+ Spring `@Scheduled` | 叫乘任务用 Quartz,补偿/清理用 `@Scheduled` |
|
||||
| 电话 | asterisk-java `3.38.0-zfjia` + jSerialComm | AMI 控制会议桥,串口控制广播/话机 |
|
||||
| 文档 | Springfox Swagger 2.9.2 | 仅扫描 `jlgl.controller` |
|
||||
| 报表 | Apache POI 4.1.2 | `/excel/*` 导出 |
|
||||
| 其他 | fastjson2、Guava、Reflections、JNA | JSON、工具、类扫描、本地库调用 |
|
||||
|
||||
> 注意:`pom.xml` 中 `spring-boot-starter-web` 显式写了 `3.5.4`、`spring-boot-starter-data-redis` 写了 `3.3.1`,与 Boot 2.6.13 / Java 8 不匹配。见 [09-迭代指引与风险清单.md](09-迭代指引与风险清单.md)。
|
||||
|
||||
## 5. 多公寓识别(重要约束)
|
||||
|
||||
同一套后端服务多个公寓时,公寓身份由请求来源 IP 决定:
|
||||
|
||||
- 入口:`ZdwhService.getUniqueGyByIp(request)` / `getGyIdByIp(request)`。
|
||||
- 解析顺序:设备表(`GY_SB`)中的 IP → 公寓字典 `GY_GYZD.ip`。
|
||||
- 若同一 IP 命中多个公寓,直接拒绝,避免写错公寓数据。
|
||||
- 业务代码中 `gyid` 不能信任前端传入;入住、房间、充值等写操作均由服务端重新解析或校验。
|
||||
|
||||
相关配置:`baseConfig.gyid`、`baseConfig.gymc` 作为单公寓/默认值兜底;各 Profile 不同。
|
||||
|
||||
## 6. 关键设计约束(迭代时不要破坏)
|
||||
|
||||
1. **房间占用以有效在寓明细为准**:`live_person`、`person_name` 由 `GY_JCXX` 中 `finish_ly='0' AND sjlysj IS NULL` 的记录实时重算,不能仅做 ±1 计数。
|
||||
2. **交路快照与匹配分离**:运安计划先整表落到 `GY_SYN_JCXX`(快照),再由匹配流程写入 `GY_JCXX`;匹配有全局锁和状态位,避免抓取/推送并发写坏数据。
|
||||
3. **叫乘任务可恢复**:Quartz 任务按 `ryid + 类型` 建键,应用重启后由 `WakeupJobRecoveryRunner` 从库中恢复未来任务。
|
||||
4. **设备指令一次性投递**:指令写入设备指令表,心跳时下发,下发后置 `deleted=1`。
|
||||
5. **事务内不做外部副作用**:WebSocket 推送、创建 Quartz 任务等放在事务提交后(`afterCurrentTransactionCommits`)。
|
||||
6. **离寓有证据链**:人脸离寓会保存抓拍快照、写 `GYGL_LY_EVENT`,并以 `deviceEventId` 做幂等。
|
||||
|
||||
## 7. 与前端/设备的关系
|
||||
|
||||
- Web 管理端 `YktVue` 通过 `/yktgl/*` 接口与 WebSocket 交互;后端也会把旧构建产物放在 `src/main/resources/static` 下(历史遗留,见风险清单)。
|
||||
- 设备通过各自的心跳接口注册,通过业务接口上报事件;服务端通过 WebSocket 向值班端推送刷新与人员信息。
|
||||
- 叫乘执行不经过设备,而是直接走 Asterisk 电话/广播链路。
|
||||
@@ -0,0 +1,167 @@
|
||||
# 02 工程结构与分层
|
||||
|
||||
## 1. 目录结构
|
||||
|
||||
仓库根目录:
|
||||
|
||||
```
|
||||
jcgl/
|
||||
├── yktgl/ # 后端(Spring Boot / Maven)
|
||||
│ ├── pom.xml
|
||||
│ └── src/
|
||||
│ ├── main/
|
||||
│ │ ├── java/org/example/yktgl/...
|
||||
│ │ └── resources/
|
||||
│ │ ├── application.yml / application-*.yml
|
||||
│ │ ├── mapper/**/*.xml
|
||||
│ │ ├── wsdl/PbResource.wsdl
|
||||
│ │ ├── db/ # 手工升级脚本
|
||||
│ │ └── static/ # 历史前端构建产物
|
||||
│ └── test/java/...
|
||||
├── YktVue/ # Vue 前端
|
||||
└── docs/ # 本文档目录
|
||||
```
|
||||
|
||||
后端 Java 包(`org.example.yktgl`):
|
||||
|
||||
| 包 | 职责 |
|
||||
| --- | --- |
|
||||
| `jcgl` | 叫乘核心:入寓/离寓、叫乘执行、房间、交路匹配、补助、卡余额、统计联动 |
|
||||
| `jlgl` | 交路维护:交路 CRUD、叫乘时刻、上传、跨公寓同步、车次查询 |
|
||||
| `regist` | 人员资料与注册:注册查询、照片、人员增删改 |
|
||||
| `recharge` | 现金充值:设备发起、值班端处理、余额变动、补助入账 |
|
||||
| `pay` | 消费:设备余额查询与扣款、消费明细 |
|
||||
| `MealsOrdering` | 食堂/餐食订单与消费 |
|
||||
| `kcgl` | 库存/出入库/物料/成品/文件(扩展业务) |
|
||||
| `display` | 登录、用户、角色、权限、菜单、部门、日志 |
|
||||
| `excel` | 各类报表导出(POI) |
|
||||
| `xxtj` | 信息统计:日报、进出情况、月报、补助统计 |
|
||||
| `zdwh` | 字典/基础资料:公寓、房间、工种、节假日、餐补标准;IP→公寓解析 |
|
||||
| `syndata` | 运安/中心数据同步、同步日志、人员同步服务 |
|
||||
| `heartBeat` | 设备心跳、设备指令、设备信息 |
|
||||
| `callingDevice` / `checkInDevice` / `roomDevice` / `payDevice` / `registDevice` / `vendPayDevice` | 各类设备的接入层(心跳 + 业务) |
|
||||
| `clean` | 房间保洁 |
|
||||
| `jgxxgl` | 叫乘报警/警示信息查询 |
|
||||
| `quartz` | Quartz 工具、任务管理、叫乘任务 `WakeUpJob` |
|
||||
| `schedule` | `@Scheduled` 补偿任务与启动恢复 |
|
||||
| `websockets` | 各类 WebSocket 端点 |
|
||||
| `common` | 通用返回体、验证码、工具、Session/WebSocket 配置 |
|
||||
| `config` | 异步线程池、RestTemplate、Swagger |
|
||||
| `util` | 日期、字符串工具 |
|
||||
| `test` | 测试/演示接口(生产应限制) |
|
||||
|
||||
## 2. 分层约定与调用链
|
||||
|
||||
典型调用链:
|
||||
|
||||
```
|
||||
Controller(参数/鉴权/协议编解码)
|
||||
→ Service(业务编排、事务、状态机)
|
||||
→ Mapper 接口(MyBatis)
|
||||
→ mapper/**/*.xml(SQL)
|
||||
→ KingbaseES
|
||||
```
|
||||
|
||||
实际代码中的偏差:
|
||||
|
||||
- 部分 Controller 直接调用 Mapper(如设备心跳、字典查询)。
|
||||
- 设备接入层通常只有一个 Service,同时承担协议解析与业务调用。
|
||||
- `JcglService` 体量过大,承担了叫乘、房间、人员、补助、同步、归档等多类职责;迭代时应优先“新增小服务 + 复用其中方法”,避免继续膨胀。
|
||||
|
||||
### 请求与返回
|
||||
|
||||
- 统一返回 `common/entity/Result` 或 `ResultData`,包含成功标志、消息、数据。
|
||||
- 设备接口多返回 `ResultData`;Web 接口多返回 `Result`。
|
||||
- 部分统计接口直接返回 `JSONObject`(如 `/synData/synPersonData`)。
|
||||
|
||||
### 事务与异常
|
||||
|
||||
- 写操作使用 `@Transactional`;捕获异常后调用 `TransactionAspectSupport.currentTransactionStatus().setRollbackOnly()` 再返回失败。
|
||||
- 叫乘任务创建、WebSocket 推送等副作用通过 `afterCurrentTransactionCommits(...)` 延迟到提交后,避免“事务回滚但消息已发/任务已建”。
|
||||
- 大量 `try/catch` 将异常转成 `Result.failure(message)`,同时写业务日志;排查时需同时看 `GY_LOGS` / 同步日志 / `System.out`。
|
||||
|
||||
## 3. 启动流程
|
||||
|
||||
入口:`YktglApplication`
|
||||
|
||||
```java
|
||||
@EnableTransactionManagement
|
||||
@SpringBootApplication
|
||||
@EnableScheduling
|
||||
public class YktglApplication extends SpringBootServletInitializer
|
||||
```
|
||||
|
||||
启动关键动作:
|
||||
|
||||
1. Spring 容器初始化,激活 `spring.profiles.active`(默认 `local`)。
|
||||
2. `SessionConfig` 开启 Redis HttpSession。
|
||||
3. `WebSocketConfig` 注册 `ServerEndpointExporter`,扫描 `@ServerEndpoint`(`websockets/*`)。
|
||||
4. `ServerStartupListener` 在启动时做初始化(端口/环境相关)。
|
||||
5. `WakeupJobRecoveryRunner` 监听 `ApplicationReadyEvent`,从 `GY_JCXX` 恢复未来叫乘任务。
|
||||
6. `@Scheduled` 任务开始运行(见 07)。
|
||||
|
||||
## 4. 配置与 Profile
|
||||
|
||||
- 主配置:`application.yml`,只保留通用项与 `active: local`。
|
||||
- 环境配置:`application-{byq,cc,dev,dl,local,pj,prod,sjt,tl}.yml`,各自定义端口、数据源、Redis、公寓、AMI、串口等。
|
||||
- 自定义前缀:`baseConfig.*`(公寓、中心地址、同步白名单、设备密码、服务器 OS)、`callcontrol.*`(AMI、录音、串口)。
|
||||
|
||||
详细字段见 [08-部署与配置.md](08-部署与配置.md)。
|
||||
|
||||
## 5. 公共组件速查
|
||||
|
||||
| 组件 | 位置 | 用途 |
|
||||
| --- | --- | --- |
|
||||
| `Result` / `ResultData` | `common/entity` | 统一返回体 |
|
||||
| `CaptchaUtil` / `CaptchaResult` | `common` | 登录验证码 |
|
||||
| `IpUtil` | `common/utils` | 取真实客户端 IP |
|
||||
| `HttpRequest` | `common/utils` | 内部 HTTP 调用(运安人员接口等) |
|
||||
| `MD5Util` / `PasswordEncoder` | `common/utils` | 口令处理 |
|
||||
| `MyBatisUtils` | `common/utils` | MyBatis 辅助 |
|
||||
| `SpringUtils` | `common/utils` | 静态获取 Bean |
|
||||
| `AsyncConfig` | `config` | 异步线程池(核心 10、最大 200、队列 10) |
|
||||
| `RestTemplateConfig` | `config` | HTTP 客户端 |
|
||||
| `SwaggerConfig` | `config` | 仅扫描 `jlgl.controller` |
|
||||
| `QuartzUtils` / `SchedulerManager` | `quartz` | 任务创建/取消/重建 |
|
||||
| `CallDutyMatchLock` | `jcgl/service` | 交路抓取与匹配的互斥锁(DB 行锁 + 租约) |
|
||||
| `AsteriskCallUtil` | `jcgl/service` | AMI 呼叫、会议桥、录音、挂断 |
|
||||
| `JcWebsocket` 等 | `websockets` | 按公寓/房间推送 |
|
||||
|
||||
## 6. 测试现状
|
||||
|
||||
`src/test/java` 下已有部分单元/切片测试(录音控制器、当前在寓交路 SQL、最近同步时间、人员同步等),但工程 `target/` 为空,未见完整构建/测试产物。迭代前建议先补齐可重复的构建与测试基线。
|
||||
|
||||
## 7. 关键文件索引
|
||||
|
||||
> 行号为当前版本近似位置,改动后请以方法名检索。
|
||||
|
||||
| 文件 | 关注内容 |
|
||||
| --- | --- |
|
||||
| `jcgl/service/JcglService.java` | 叫乘/入住/离寓/房间/补助/同步/归档主逻辑(约 4192 行) |
|
||||
| ├─ 559–1010 | 房间列表、推荐、房态修改、入住提交、离寓提交 |
|
||||
| ├─ 1320–1450 | `processCallDuty` / `processTempCallDuty` 状态上报 |
|
||||
| ├─ 1700–2150 | 远程同步、交路匹配、提醒补偿 |
|
||||
| ├─ 2400–2510 | `ryzt` 状态更新与校验 |
|
||||
| ├─ 2640–2800 | 按开车时间与时间规则计算叫乘时刻 |
|
||||
| ├─ 3065–3175 | 刷脸离寓 |
|
||||
| ├─ 3600–3700 | 房间校验、时间线校验 |
|
||||
| └─ 3880–4192 | 停止叫乘、录音、归档 |
|
||||
| `jcgl/controller/JcglController.java` | `/jcgl` 全部 Web/设备接口入口 |
|
||||
| `jcgl/service/AsteriskCallUtil.java` | AMI 连接、呼叫、会议桥、TTS、录音、挂断 |
|
||||
| `jcgl/service/CallDutyMatchLock.java` | 同步/匹配互斥锁 |
|
||||
| `jcgl/service/ByxxResourceService.java` | 运安 WSDL 调用与快照写入 |
|
||||
| `quartz/SchedulerManager.java` | 叫乘任务创建/取消/重建 |
|
||||
| `quartz/WakeUpJob.java` | 单个叫乘任务执行 |
|
||||
| `quartz/QuartzUtils.java` | Quartz 基础设施 |
|
||||
| `schedule/JcSchedule.java` | 漏叫提醒、超时离寓、归档 |
|
||||
| `schedule/SynDataSchedule.java` | 运安抓取/人员同步 |
|
||||
| `schedule/WakeupJobRecoveryRunner.java` | 启动恢复任务 |
|
||||
| `mapper/jcgl/JcglMapper.xml` | 叫乘核心 SQL(表结构事实来源之一) |
|
||||
| `mapper/jcgl/JcglRoomMapper.xml` | 房间 SQL 与推荐逻辑 |
|
||||
| `mapper/jcgl/LeaveEventMapper.xml` | 离寓事件 |
|
||||
| `mapper/heartBeat/HeartBeatMapper.xml` | 设备、心跳、指令 |
|
||||
| `mapper/recharge/RechargeMapper.xml` | 充值申请/余额/补助 |
|
||||
| `heartBeat/service/HeartBeatService.java` | 指令写入与设备维护 |
|
||||
| `zdwh/service/ZdwhService.java` | IP→公寓、字典 |
|
||||
| `websockets/JcWebsocket.java` | 叫乘实时推送 |
|
||||
| `application.yml` / `application-*.yml` | 运行配置 |
|
||||
@@ -0,0 +1,97 @@
|
||||
# 03 业务模块地图
|
||||
|
||||
## 1. 模块总表
|
||||
|
||||
| 模块(包) | 入口 | 核心服务 | 一句话职责 | 主要数据表 |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| `jcgl` | `JcglController` `/jcgl`、`RecordingController` | `JcglService`(4192 行)、`AsteriskCallUtil`、`ByxxResourceService`、`CallDutyMatchLock` | 叫乘主流程、入寓/离寓、房间、补助、交路匹配、归档 | `GY_JCXX`、`GY_JCXX_HIS`、`GY_ROOMS`、`GY_SYN_JCXX`、`GY_YKT_*`、`GYGL_LY_EVENT` |
|
||||
| `jlgl` | `JlGlController` `/jlgl` | `JlGlService` | 交路模板维护、叫乘时刻、上传/同步、车次查询 | `GYGL_JLXX`、`GYGL_JLXX_TY`、`GYGL_JLXX_LOGS`、`GY_GYZD` |
|
||||
| `regist` | `RegistController` `/regist` | `RegistService` | 人员注册信息、照片、人员资料增删改 | `GY_YKT_RY`、人员照片表 |
|
||||
| `recharge` | `RechargeController` `/recharge` | `RechargeService` | 现金充值申请/处理、余额与补助入账 | `GY_YKT_CASH_REQUEST`、`GY_YKT_REMAINDER`、`GY_YKT_XJCZJL`、`GY_YKT_ALLOWANCE` |
|
||||
| `pay` | `PayController` `/pay` | `PayService` | 消费扣款、消费明细与统计 | `GY_YKT_CONSUME`、`GY_YKT_REMAINDER` |
|
||||
| `MealsOrdering` | `MealsController` `/Meals` | `MealsService` | 餐食/订单、房间送餐、消费 | 餐食/订单相关表 |
|
||||
| `kcgl` | `kcglController` `/kcgl` | `kcglService` | 库存、出入库、物料、成品、PDF 文件 | 库存/出入库相关表 |
|
||||
| `display` | `/auth`、`/user`、`/role`、`/permission`、`/menu`、`/dept` | `SysUserService` 等 | 登录、会话、RBAC、菜单、部门、日志 | `GL_YH`、`GL_JS`、`GL_QX`、`GL_CD`、`GL_YH_JS`、`GL_JS_QX`、`GY_LOGS` |
|
||||
| `excel` | `ExcelExportController` `/excel` | 直接查询/POI | 叫乘、日报、补助、充值、消费等 Excel 导出 | 只读多表 |
|
||||
| `xxtj` | `xxtjController` `/xxtj` | `XxTjService` | 报警次数、进出情况、日报、月报、补助统计 | 只读多表 |
|
||||
| `zdwh` | `ZdwhController` `/Zdwh` | `ZdwhService` | 公寓/房间/工种/节假日/餐补字典;IP→公寓 | `GY_GYZD`、`GY_ROOMS`、`GY_GZZD`、`GY_JRB`、`GY_JBXX` |
|
||||
| `syndata` | `/synData`、`/jwDataLog` | `SynDataService`、`DriverPersonSyncService`、`JwDataLogService` | 运安人员、公寓人员、财务数据;同步日志 | `GY_YKT_RY`、`GY_JCXX`、`GY_YKT_REMAINDER`、同步日志表 |
|
||||
| `heartBeat` | `HeartBeatController` `/heartBeat` | `HeartBeatService` | 设备注册、心跳、指令下发、版本/配置 | `GY_SB`、`GY_SB_XT`、设备指令表 |
|
||||
| `callingDevice` | `/callingDevice` | `CallingDeviceService` | 叫乘屏心跳/业务 | `GY_SB` |
|
||||
| `checkInDevice` | `/checkInDevice` | `CheckInDeviceService` | 签到机心跳/业务 | `GY_SB` |
|
||||
| `roomDevice` | `/roomDevice` | `RoomDeviceService` | 房间屏心跳/应答/保洁 | `GY_SB` |
|
||||
| `payDevice` | `/payDevice` | `PayDeviceService` | 消费机心跳/消费 | `GY_SB` |
|
||||
| `registDevice` | `/registDevice` | `RegistDeviceHeartBeatService` | 注册机心跳 | `GY_SB` |
|
||||
| `vendPayDevice` | `/vendPayDevice` | `VendPayDeviceService` | 售货机支付/退款 | 订单、余额 |
|
||||
| `clean` | `CleanController` `/clean` | `CleanService` | 开始/结束保洁、保洁记录 | `GY_ROOMS`、保洁记录 |
|
||||
| `jgxxgl` | `JgXxGlController` `/jgxxgl` | `JgXxGlService` | 报警/警示信息查询 | `GYGL_JGXX` |
|
||||
| `quartz` | — | `SchedulerManager`、`WakeUpJob` | 叫乘/复叫/叫乘结束任务 | Quartz 内存 JobStore |
|
||||
| `schedule` | — | 各 `@Scheduled` | 漏叫补偿、超时离寓、归档、运安同步、快照清理 | 多表 |
|
||||
| `websockets` | `/websocket/*` | — | 值班端/房间端实时推送 | — |
|
||||
|
||||
## 2. 模块依赖关系
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
DEV[设备接入层<br/>calling/checkIn/room/pay/regist/vend] --> CORE[jcgl 核心服务]
|
||||
WEB[Web 控制器<br/>jcgl/jlgl/regist/recharge/pay/xxtj/excel] --> CORE
|
||||
CORE --> JL[jlgl 交路]
|
||||
CORE --> ZD[zdwh 字典/IP→公寓]
|
||||
CORE --> HB[heartBeat 设备指令]
|
||||
CORE --> WS[websockets 推送]
|
||||
CORE --> QZ[quartz 叫乘任务]
|
||||
QZ --> AST[AsteriskCallUtil]
|
||||
SYNC[syndata / ByxxResourceService] --> CORE
|
||||
CORE --> CARD[卡务: recharge/pay/Meals]
|
||||
ALL[全部模块] --> DISP[display 登录/RBAC/日志]
|
||||
```
|
||||
|
||||
关键耦合点:
|
||||
|
||||
- **`jcgl` 是事实上的“领域服务层”**,其他模块大量直接调用 `JcglService`(如 `pay` 调 `checkRemainder`/`isHoliday`,`regist` 调 `processPersonDeviceInstructions`,`recharge` 调余额与补助)。
|
||||
- **`zdwh` 提供公寓上下文**,几乎所有写操作都依赖 `getGyIdByIp` / `getUniqueGyByIp`。
|
||||
- **`heartBeat` 提供设备指令通道**,叫乘、入住、充值、人员变更都会写入指令。
|
||||
- **`websockets` 只负责推送**,业务状态不以其为准。
|
||||
|
||||
## 3. 按业务视角分组
|
||||
|
||||
### 3.1 叫乘与住宿(核心)
|
||||
|
||||
- 入寓登记:`submit_rydj` / `processCheckInRegistration`
|
||||
- 叫乘执行:`processCallDuty`、`processTempCallDuty`、`WakeUpJob`、`AsteriskCallUtil`
|
||||
- 房间:`getRoomList`、`getRoomRecommendations`、`modifyRoomStatus`、`exchangeRoom`
|
||||
- 离寓:`processCheckOutRegistration`、`handleCheckOut`、`submit_ccly`
|
||||
- 交路匹配:`synCallDutyInfo`、`synUnMatchJcXx`、`matchCallDutyUnderLock`
|
||||
- 归档:`syncJcXxData`
|
||||
|
||||
### 3.2 卡务与消费
|
||||
|
||||
- 补助:`getAllowanceInfo`、`getTrainAllowanceInfo`、`changeRemainder`、`insert_allowance`
|
||||
- 余额:`checkRemainder`、`remakeRemainder`
|
||||
- 消费:`PayService`、`VendPayDeviceService`、`MealsService.updateMoney`
|
||||
- 充值:`RechargeService`(设备申请 + 值班端确认)
|
||||
|
||||
### 3.3 基础资料与管理
|
||||
|
||||
- 人员:`regist` + `syndata`(运安/中心)
|
||||
- 交路:`jlgl`
|
||||
- 公寓/房间/工种/节假日:`zdwh`
|
||||
- 用户/角色/权限/菜单:`display`
|
||||
|
||||
### 3.4 统计与导出
|
||||
|
||||
- 页面统计:`xxtj`(日报、月报、补助统计)
|
||||
- Excel:`excel`(叫乘明细、日报、补助、充值、消费及汇总)
|
||||
|
||||
## 4. 模块边界与迭代建议
|
||||
|
||||
| 场景 | 建议落点 | 说明 |
|
||||
| --- | --- | --- |
|
||||
| 叫乘规则(时间/次数/优先级) | `JcglService` + `quartz` | 先改状态机与任务生成,再改执行器 |
|
||||
| 新的设备类型 | 新建 `xxxDevice` 包 | 复用 `heartBeat` 指令与 `GY_SB` |
|
||||
| 新报表 | `xxtj` 或 `excel` | 统计 SQL 放对应 Mapper XML |
|
||||
| 新的卡务规则 | `recharge` / `pay` | 余额变动必须与明细同事务 |
|
||||
| 交路来源新增 | `syndata` + `jlgl` | 统一落到快照表再匹配 |
|
||||
| 管理端新功能 | `display` + 对应业务模块 | 权限走 RBAC 表 |
|
||||
|
||||
> `kcgl`(库存)与叫乘主线关系较弱,更像同工程内的扩展业务;迭代叫乘时通常无需改动。
|
||||
@@ -0,0 +1,294 @@
|
||||
# 04 核心业务流程
|
||||
|
||||
本文按“人”和“房间”两条主线梳理:人从入寓到离寓,房间从占用到释放;同时说明叫乘任务如何被创建、执行和补偿。
|
||||
|
||||
## 1. 入寓登记
|
||||
|
||||
入口有两类:
|
||||
|
||||
- 设备端:`POST /jcgl/processCheckInRegistration`(签到机)
|
||||
- 值班端:`POST /jcgl/submitAll` → `JcglService.submit_rydj`
|
||||
|
||||
### 1.1 设备端查询/建档(`processCheckInRegistration`)
|
||||
|
||||
| code | 行为 |
|
||||
| --- | --- |
|
||||
| 1 | 按 `ryid` 查询当前在寓记录、离寓快照、人员资料,返回给设备;用于设备判断“是否已入住/是否可入住” |
|
||||
| 2 | 由人员资料 + 选择的交路(`jlid`)或班次构造入住信息,通过 WebSocket `{"lx":"ry","content":...}` 推送值班端确认;房间号仅作为协议字段,不在此步写库 |
|
||||
| 3 | 按 `id` 查询指定记录 |
|
||||
|
||||
> 设备端只负责“采集 + 推送”,真正的写入统一走值班端确认后的 `submit_rydj`。
|
||||
|
||||
### 1.2 值班端提交(`submit_rydj`,`@Transactional`)
|
||||
|
||||
按顺序执行:
|
||||
|
||||
1. **重复入住校验**:`isExistCallDutyInfo(ryid, gyid)`,已有在寓记录直接失败。
|
||||
2. **房间校验**:按 `gyid + room_no` 精确查房,房间不存在/状态不可入住/床位已满则失败。
|
||||
3. **交路处理**:
|
||||
- `jllx='0'` 表示按交路入住。
|
||||
- 若传了 `jlid`(固定交路),从交路表取车次、机车号、起点、到达车次/时间,回填到入住记录。
|
||||
- 若 `cc` 包含“便乘/驻在”,`jllx='1'`,不生成标准叫乘;否则调用 `populateJcXxByJlXx` 生成叫乘时间。
|
||||
4. **开车日期校验**:有车次时必须传 `kcrq`,且格式为 `yyyy-MM-dd`。
|
||||
5. **补助计算**:
|
||||
- 固定交路:`getTrainAllowanceInfo(cc, sfffcb, gyid, jlid)`。
|
||||
- 非固定交路:`getAllowanceInfo(gz, sfffcb, sjrysj, gyid)`(按工种、是否发补助、入住时间规则)。
|
||||
- `changeRemainder` 生成/更新余额与补助明细;节假日可能跳过余额与补助写入。
|
||||
6. **写入住记录**:`insertJcxx`,`ryzt='0'`、`finish_ly='0'`、`sjrysj=入住时间`,并记录房间号。
|
||||
7. **设备指令**:
|
||||
- 向签到机下发指令 `5`;
|
||||
- 向房间设备下发指令 `1`(刷新房间屏)。
|
||||
8. **占用重算**:`room_rydj` → `refreshRoomOccupancy`,从有效在寓明细重算 `live_person`、`person_name`,再按床位计算房态。
|
||||
9. **余额/补助落账**:非节假日执行 `updateRemainder` + `insert_allowance`。
|
||||
10. **叫乘任务**:固定交路且 `sfjc='1'` 且非便乘/驻在时,事务提交后创建 `WakeUpJob`,并置 `is_yaxx='1'`。
|
||||
11. **推送**:WebSocket `{"lx":"refresh"}`。
|
||||
|
||||
失败时统一回滚并写业务日志。
|
||||
|
||||
### 1.3 房间推荐(`getRoomRecommendations`)
|
||||
|
||||
- 仅对“可入住”的房间给出推荐顺序;
|
||||
- 排序依据:**同行房间**(同车次/同批人)→ **历史房间**(该人员曾住过);
|
||||
- 推荐结果不作为最终校验,提交时仍由房间状态与床位兜底。
|
||||
|
||||
## 2. 叫乘状态机
|
||||
|
||||
### 2.1 人员状态 `ryzt`
|
||||
|
||||
| 值 | 含义 | 进入方式 |
|
||||
| --- | --- | --- |
|
||||
| `0` | 待叫乘/未叫乘 | 入住初始化、重置交路、任务取消 |
|
||||
| `1` | 叫乘中(已叫/复叫) | 任务执行、设备上报 status=1/2 |
|
||||
| `2` | 叫乘报警(未应答) | 报警任务、设备上报 status=3 |
|
||||
| `3` | 已应答,待离寓 | 应答(status=5)或通话结束 |
|
||||
| `4` | 离寓报警(超时未离寓) | 超时检查、设备上报 status=4 |
|
||||
| `5` | 正在通话 | Asterisk 接通后临时状态 |
|
||||
| `-1` | 查询用合成状态(未匹配/特殊行) | SQL 构造,不落库 |
|
||||
|
||||
```mermaid
|
||||
stateDiagram-v2
|
||||
state "0 待叫乘" as S0
|
||||
state "1 叫乘中" as S1
|
||||
state "2 叫乘报警" as S2
|
||||
state "3 已应答待离寓" as S3
|
||||
state "4 离寓报警" as S4
|
||||
state "5 通话中" as S5
|
||||
|
||||
[*] --> S0
|
||||
S0 --> S1: JC 任务 / 设备 status=1
|
||||
S1 --> S1: FJ 复叫 / status=2
|
||||
S1 --> S5: 电话接通
|
||||
S5 --> S3: 挂断 / 应答
|
||||
S1 --> S2: 未应答 / status=3
|
||||
S2 --> S3: 人工应答 / status=5
|
||||
S3 --> S4: 超时未离寓
|
||||
S3 --> [*]: 办理离寓
|
||||
S4 --> [*]: 办理离寓
|
||||
```
|
||||
|
||||
配套字段:
|
||||
|
||||
- `jcsj_s` / `fjsj_s` / `jcbjsj_s`:实际叫乘/复叫/报警时间。
|
||||
- `hjxysj`:呼叫应答时间。
|
||||
- `finish_jc`:叫乘是否结束(`1` 结束)。
|
||||
- `finish_ly`:是否离寓(`1` 离寓)。
|
||||
- `stoped`:是否人工停止叫乘。
|
||||
- `is_jcbj` / `is_lybj`:叫乘报警/离寓报警标记。
|
||||
|
||||
### 2.2 设备上报(`processCallDuty`)
|
||||
|
||||
设备 POST `/jcgl/processCallDuty`,`status` 语义:
|
||||
|
||||
| status | 动作 |
|
||||
| --- | --- |
|
||||
| 1 | 开始叫乘:`ryzt=1`、记录 `jcsj_s` |
|
||||
| 2 | 开始复叫:记录 `fjsj_s`(状态保持叫乘中) |
|
||||
| 3 | 叫乘报警:若原状态 < 2 则 `ryzt=2`,`is_jcbj=1`,记录 `jcbjsj_s`,写报警记录 |
|
||||
| 4 | 离寓报警:`triggerLeaveAlarm`(条件更新,防重复),写报警记录 |
|
||||
| 5 | 呼叫应答:`ryzt=3`、`hjxysj`、`finish_jc=1`、`stoped=0` |
|
||||
|
||||
临时叫乘走 `/jcgl/processTempCallDuty`,语义相同,但会额外刷新对应房间设备。
|
||||
|
||||
### 2.3 自动叫乘(Quartz)
|
||||
|
||||
入住/修改交路时为一个人创建 **3 个一次性任务**:
|
||||
|
||||
| 任务 | 触发时间 | 行为 |
|
||||
| --- | --- | --- |
|
||||
| `JC` | `jcsj` | 开始叫乘:状态置 1,TTS 呼叫值班台 + 房间;未接通则按规则转报警 |
|
||||
| `FJ` | `fjsj`(叫乘 +10 分钟) | 复叫:再次呼叫;仍未接通转报警 |
|
||||
| `JCJS` | `jcbjsj`(叫乘 +15 分钟) | 叫乘结束:挂断会议桥、状态置 2、写报警记录 |
|
||||
|
||||
任务键:`ryid + "JC"/"FJ"/"JCJS"`,组:`gyid + fjh`;同一房间/车次会合并为一个执行组,组长优先呼叫。任务执行前会校验 `jcid/fjh/时间` 是否仍与库中一致,避免过期任务误叫。
|
||||
|
||||
补偿:
|
||||
|
||||
- `SchedulerManager` 统一创建/取消/重建;
|
||||
- `WakeupJobRecoveryRunner` 在应用启动后恢复未来任务;
|
||||
- 会议桥忙时延迟 60 秒再试;
|
||||
- 人工“停止叫乘”会取消任务、挂断通话、置 `stoped=1`。
|
||||
|
||||
### 2.4 叫乘时间规则
|
||||
|
||||
叫乘时间统一由**开车时间 + 本地时间规则**计算(运安下发的 `jcsj` 仅保留读取,不作为最终依据):
|
||||
|
||||
- 规则来自 `GY_SJGZ`(按 `gyid + 单位`):
|
||||
- `zjjcsjgz`:站接叫乘提前分钟数;
|
||||
- `kjjcsjgz`:库出叫乘提前分钟数;
|
||||
- `lysjgz`:离寓时间规则。
|
||||
- `站接`:`jcsj = kcsj - zjjcsjgz`;`库出`:`jcsj = kcsj - kjjcsjgz`。
|
||||
- `fjsj = jcsj + 10 分钟`;`jcbjsj = jcsj + 15 分钟`;`ylysj = jcsj + lysjgz`。
|
||||
- 若计算出的叫乘时间已过期:只发 TTS 提醒,不生成报警记录(`adjustPastCallDutyTimes`)。
|
||||
|
||||
## 3. 运安交路同步与匹配
|
||||
|
||||
### 3.1 推送式同步(`POST /jcgl/synCallDutyInfo`)
|
||||
|
||||
1. 校验来源 IP 是否在 `baseConfig.synJcXxIp` 白名单。
|
||||
2. 解析 JSON 快照,校验 `id`、`workno`、`deptime` 必填,`id` 唯一。
|
||||
3. 获取 `CallDutyMatchLock.tryAcquireSync()`(数据库协调行 + 租约),避免与抓取/匹配并发。
|
||||
4. `TRUNCATE GY_SYN_JCXX` → 批量插入 → `GY_SYN_JCXX_STATUS='1'`。
|
||||
5. 事务提交后释放锁;返回 `{code,message,result}`。
|
||||
|
||||
### 3.2 主动抓取(`ByxxResourceService.fetchJlXX`)
|
||||
|
||||
1. 获取同步锁。
|
||||
2. 加载 `classpath:/wsdl/PbResource.wsdl`,创建 SOAP 客户端。
|
||||
3. 清空 `GY_SYN_JCXX`。
|
||||
4. 调用运安 `getDriverPlanByTimeStr(start, end)`,把司机 1–4 的计划分别写入快照。
|
||||
5. 更新同步状态为 `1`,记录日志。
|
||||
|
||||
> `mergeSynJcXx` 已停用:历史数据存在同一 `id` 对应多名司机,按 `id` MERGE 会重复匹配。
|
||||
|
||||
### 3.3 匹配(`/jcgl/synUnMatchJcXx` → `matchCallDutyUnderLock`)
|
||||
|
||||
前置条件:`GY_SYN_JCXX_STATUS='1'`(同步完成),且配置了 `baseConfig.gyid`(匹配只处理该公寓)。
|
||||
|
||||
流程:
|
||||
|
||||
1. 获取数据库行锁,串行匹配。
|
||||
2. 查询 `jllx='0'` 的有效在寓记录,跳过人工锁定交路的记录;若配置不允许“叫乘完成后变更交路”,则跳过已完成叫乘且未离寓的人员。
|
||||
3. 以人员 `card_id`(工号)匹配 `GY_SYN_JCXX.workno`。
|
||||
4. 命中且交路有变化:按开车时间 + 本地规则重算叫乘/复叫/报警/离寓时间,更新当前入住记录,取消并重建 3 个 Quartz 任务;事务提交后写“交路变更/首次自动匹配/重新匹配”事件日志并 TTS 提醒。
|
||||
5. 命中但交路未变:检查任务是否齐全,缺失则补建。
|
||||
6. 未命中且该人有开车时间:清空交路与时间、取消任务、TTS 通知本人。
|
||||
7. 汇总写同步日志,WebSocket `"all"` 刷新。
|
||||
|
||||
### 3.4 归档
|
||||
|
||||
`POST /jcgl/syncJcXxData`:
|
||||
|
||||
- 条件:`finish_ly='1' AND sjlysj <= sysdate - 7`,且属于当前公寓。
|
||||
- 分批 500 条:复制到 `GY_JCXX_HIS` → 从 `GY_JCXX` 删除。
|
||||
- 统计冲突/无效条数并写日志。
|
||||
- 每日 00:00 也有自动归档任务。
|
||||
|
||||
## 4. 离寓
|
||||
|
||||
### 4.1 刷脸离寓(`processCheckOutRegistration`)
|
||||
|
||||
| code | 行为 |
|
||||
| --- | --- |
|
||||
| 1 | 按 `ryid + gyid` 查询在寓记录与人员资料,返回离寓页面数据 |
|
||||
| 2 | 刷脸离寓:校验事件幂等 → 保存抓拍 → 更新离寓字段 → 写离寓事件 → 更新房间 → 推送刷新 |
|
||||
|
||||
code=2 的关键点:
|
||||
|
||||
1. **幂等**:`deviceCode + deviceEventId` 已存在则直接返回“已经处理”;缺失事件号时只记录日志、不阻断(兼容旧设备)。
|
||||
2. **抓拍**:Base64 只接受 JPEG;按 `leaveSnapshot` 配置保存到本地目录,生成 `/yktgl/photo/leave-snapshots/...` URL;未开启抓拍时按 `requiredForDevice` 决定是否报错。
|
||||
3. **服务评分**:请求可带 `kffwpf/jcfwpf/stfwpf`,写入离寓记录。
|
||||
4. **事件证据**:`recordLeaveEvent` 写 `GYGL_LY_EVENT`(类型 `FACE`,含 `deviceEventId`、`snapshotUrl`、操作人、备注)。
|
||||
5. **提交离寓**:`submit_ccly` → 更新 `GY_JCXX`(`finish_ly=1`、`sjlysj`)→ `room_ccly` 释放房间 → 房间设备刷新 → `remakeRemainder` 处理余额(如退补助)。
|
||||
6. **失败回滚**:异常时删除已保存快照并回滚事务。
|
||||
|
||||
### 4.2 值班端离寓
|
||||
|
||||
`POST /jcgl/handleCheckOut` 走同一套 `submit_ccly`,离寓类型记为 `MANUAL`,无设备事件号与抓拍。
|
||||
|
||||
### 4.3 超时未离寓
|
||||
|
||||
`JcSchedule` 每 15 秒检查:`finish_jc='1'`、`ryzt='3'`、`ylysj <= now`、未触发过的记录 → `triggerLeaveAlarm`(条件更新 `ryzt=4`、`lybjsj`、`is_lybj=1`)→ 写报警记录。
|
||||
|
||||
## 5. 房间与保洁
|
||||
|
||||
### 5.1 房态
|
||||
|
||||
| `room_status` | 含义 | 计算/设置 |
|
||||
| --- | --- | --- |
|
||||
| `1` | 空闲 | 结束保洁、恢复可入住 |
|
||||
| `2` | 住满 | `live_person >= bed_numbers` |
|
||||
| `3` | 待清扫 | 空房(`live_person=0`),退房后的默认状态 |
|
||||
| `4` | 不能入住 | 人工设置(要求房间无人) |
|
||||
| `5` | 未满 | `0 < live_person < bed_numbers` |
|
||||
| `6` | 保洁中 | 保洁开始;结束后回到 `1` |
|
||||
|
||||
约束:
|
||||
|
||||
- 房间占用始终由 `GY_JCXX` 有效在寓明细重算,不直接 ±1。
|
||||
- 入住校验会重新计算房态,拒绝 `4`(不能入住)、`6`(保洁中)、满员房间。
|
||||
- 保洁中不允许直接改房态;需先结束保洁。
|
||||
|
||||
### 5.2 换房(`/jcgl/exchangeRoom`)
|
||||
|
||||
1. 校验新房间可入住;
|
||||
2. 校验人员当前房间未变化(防并发);
|
||||
3. 更新入住记录 `fjh`;
|
||||
4. 重算旧房、新房占用;
|
||||
5. 向两个房间设备下发刷新指令。
|
||||
|
||||
## 6. 卡务:补助、充值、消费
|
||||
|
||||
### 6.1 补助
|
||||
|
||||
- 入住时按规则计算补助,写 `GY_YKT_ALLOWANCE` 并更新 `GY_YKT_REMAINDER` 的补助余额。
|
||||
- 固定交路按车次查固定补助;非固定交路按工种/时间规则。
|
||||
- 节假日策略:`isHoliday()` 命中时不发补助、不入账。
|
||||
|
||||
### 6.2 现金充值(`RechargeService`)
|
||||
|
||||
设备协议 `code`:
|
||||
|
||||
| code | 行为 |
|
||||
| --- | --- |
|
||||
| 1 | 查询余额 |
|
||||
| 2 | 创建充值申请(`GY_YKT_CASH_REQUEST`,状态 `PENDING`),WebSocket `"cz"` 通知值班端 |
|
||||
| 3 | 查询申请状态 |
|
||||
| 4 | 取消申请(`CANCELLED`) |
|
||||
|
||||
值班端处理 `/recharge/handleRecharge`:
|
||||
|
||||
- 金额必须 `> 0` 且 `< 100`,最多 2 位小数;
|
||||
- 通过条件更新把申请从 `PENDING` 置为 `COMPLETED`(与取消互斥);
|
||||
- 更新余额、写充值记录、向设备下发指令 `6`。
|
||||
|
||||
### 6.3 消费
|
||||
|
||||
- 消费机:`PayService`,code 1 查余额,code 2 扣款;节假日金额按 0 处理;“内部人员”可透支。
|
||||
- 售货机:`VendPayDeviceService`,code 1 查余额,code 2 下单扣款,code 3 查询结果/退款;退款时恢复余额并标记 `refunded=1`。
|
||||
- 所有扣款都写 `GY_YKT_CONSUME`,并与余额更新同事务。
|
||||
|
||||
## 7. 设备心跳与指令
|
||||
|
||||
1. 设备按类型调用 `/callingDevice/heartbeat`、`/checkInDevice/heartbeat`、`/roomDevice/heartbeat`、`/payDevice/heartbeat`、`/registDevice/heartbeat`、`/vendPayDevice/heartbeat`。
|
||||
2. 心跳上报:`deviceCode`、`versionName`、`deviceType`、`ip`、`deviceUpdateState`、`lastUserUpdateTime`、`lastDeviceConfigUpdateTime`、`roomNumber` 等。
|
||||
3. 服务端返回:`devicePassword`、`apartmentName`、`serverTime`、`updateState`、`apkUrl`、指令列表。
|
||||
4. 指令写入设备指令表,心跳时取走并置 `deleted=1`(一次性投递)。
|
||||
5. 叫乘/入住/离寓/充值/人员变更都会产生指令。
|
||||
|
||||
## 8. 流程与代码位置对照
|
||||
|
||||
| 流程 | 主要方法 |
|
||||
| --- | --- |
|
||||
| 入住提交 | `JcglService.submit_rydj` |
|
||||
| 设备入住 | `JcglService.processCheckInRegistration` |
|
||||
| 叫乘上报 | `JcglService.processCallDuty` / `processTempCallDuty` |
|
||||
| 叫乘执行 | `quartz/WakeUpJob`、`quartz/SchedulerManager` |
|
||||
| 电话/会议桥 | `jcgl/service/AsteriskCallUtil` |
|
||||
| 离寓 | `JcglService.processCheckOutRegistration` / `submit_ccly` |
|
||||
| 交路推送 | `JcglService.synCallDutyInfo` |
|
||||
| 交路匹配 | `JcglService.matchCallDutyUnderLock` |
|
||||
| 运安抓取 | `ByxxResourceService.fetchJlXX` |
|
||||
| 归档 | `JcglService.syncJcXxData` |
|
||||
| 房间 | `JcglService.getRoomRecommendations` / `modifyRoomStatus` / `exchangeRoom` |
|
||||
| 充值 | `RechargeService` |
|
||||
| 消费 | `PayService` / `VendPayDeviceService` |
|
||||
@@ -0,0 +1,244 @@
|
||||
# 05 数据模型
|
||||
|
||||
> 数据库为 KingbaseES 8,默认 schema `gygl`。表名大小写混用(`GY_JCXX`、`gy_rooms`、`GYGL_JLXX`),SQL 中需按现有写法保持一致。
|
||||
> 本文只列核心表与关键字段;完整字段以 `src/main/resources/mapper/**/*.xml` 为准。
|
||||
|
||||
## 1. 核心关系图
|
||||
|
||||
```mermaid
|
||||
erDiagram
|
||||
GY_YKT_RY ||--o{ GY_JCXX : "ryid/card_id"
|
||||
GY_JCXX }o--|| GY_ROOMS : "gyid + fjh"
|
||||
GY_JCXX ||--o{ GYGL_LY_EVENT : "jcid"
|
||||
GY_JCXX }o--o| GYGL_JLXX : "jlid"
|
||||
GY_JCXX ||--o| GY_JCXX_HIS : "归档"
|
||||
GY_YKT_RY ||--o| GY_YKT_REMAINDER : "ryid"
|
||||
GY_YKT_REMAINDER ||--o{ GY_YKT_ALLOWANCE : "补助"
|
||||
GY_YKT_REMAINDER ||--o{ GY_YKT_CONSUME : "消费"
|
||||
GY_YKT_REMAINDER ||--o{ GY_YKT_XJCZJL : "现金充值"
|
||||
GY_YKT_CASH_REQUEST ||--o| GY_YKT_XJCZJL : "完成充值"
|
||||
GY_SYN_JCXX }o--|| GY_SYN_JCXX_STATUS : "同步状态"
|
||||
GY_GYZD ||--o{ GY_ROOMS : "gyid"
|
||||
GY_GYZD ||--o{ GY_SB : "gyid"
|
||||
GY_SB ||--o| GY_SB_XT : "devicecode"
|
||||
```
|
||||
|
||||
## 2. 住宿与叫乘
|
||||
|
||||
### 2.1 `GY_JCXX`(当前在寓/叫乘记录,核心表)
|
||||
|
||||
| 分组 | 字段 | 说明 |
|
||||
| --- | --- | --- |
|
||||
| 主键 | `jcid` | 入住记录 ID |
|
||||
| 产生方式 | —(无来源列) | `gy_jcxx` 行由入寓登记当场创建(`submit_rydj` → `insertJcxx`),**不是**平台下发;平台只对其补全 `kcsj` / `jcfs` |
|
||||
| 人员 | `ryid`、`card_id`、`rymc`、`rydw`、`gzzh`、`depotid` | 人员工号/卡号/姓名/单位/工资账号 |
|
||||
| 公寓 | `gyid`、`gymc` | 公寓 |
|
||||
| 房间 | `fjh` | 房间号(与 `GY_ROOMS.room_no` 对应) |
|
||||
| 交路 | `jlid`、`cc`、`jch`、`cclx`、`qd`、`ddcc`、`ddsj` | 交路 ID、车次、机车号、接车方式、起点、到达车次/时间 |
|
||||
| 时间 | `kcsj`、`jcsj`、`fjsj`、`jcbjsj` | 开车、叫乘、复叫、叫乘结束(计划) |
|
||||
| 实际时间 | `jcsj_s`、`fjsj_s`、`jcbjsj_s`、`hjxysj`、`lybjsj` | 实际叫乘/复叫/报警/应答/离寓报警 |
|
||||
| 入住离寓 | `yrysj`、`sjrysj`、`ylysj`、`sjlysj` | 预定/实际入住、预定/实际离寓 |
|
||||
| 状态 | `ryzt`、`finish_jc`、`finish_ly`、`stoped`、`jllx` | 见状态字典 |
|
||||
| 报警 | `is_jcbj`、`is_lybj`、`alarm_event_key` | 叫乘/离寓报警标记、报警事件键 |
|
||||
| 通知去重 | `route_notice_key`、`call_timeout_notice_key`、`missed_call_notice_key` | 防止重复提醒 |
|
||||
| 离寓证据 | `leave_type`、`leave_event_id`、`leave_remark`、`leave_snapshot_url` | 冗余自 `GYGL_LY_EVENT`,便于查询 |
|
||||
| 其他 | `is_yaxx`、`yappsj`、`is_tempCall`、`recordfile`、`cblx`、`cbje`、`sfffcb` | 运安匹配标记、临时叫乘、录音文件、补助标识 |
|
||||
|
||||
有效在寓判定:`finish_ly='0' AND sjlysj IS NULL`。
|
||||
|
||||
### 2.2 `GY_JCXX_HIS`
|
||||
|
||||
与 `GY_JCXX` 同构的历史归档表;另有 `ly_event_id` 等证据字段。归档条件:已离寓且 `sjlysj <= sysdate - 7`。
|
||||
|
||||
### 2.3 `GY_ROOMS`
|
||||
|
||||
| 字段 | 说明 |
|
||||
| --- | --- |
|
||||
| `gyid`、`room_no` | 公寓 + 房间号(联合定位) |
|
||||
| `room_floor`、`room_dir`、`room_face`、`is_edge`、`is_next_floor`、`next_floor` | 楼层/朝向/相邻关系(用于推荐与排序) |
|
||||
| `room_status` | 房态,见下表 |
|
||||
| `bed_numbers` | 床位数 |
|
||||
| `room_type`、`room_dept`、`room_order` | 房型/所属部门/排序 |
|
||||
| `live_person`、`person_name` | 当前人数/姓名串(实时重算) |
|
||||
| `sip_account` | 房间 SIP 账号(叫乘呼叫用) |
|
||||
| `bjkssj` | 保洁开始时间 |
|
||||
|
||||
| `room_status` | 含义 |
|
||||
| --- | --- |
|
||||
| `1` | 空闲 |
|
||||
| `2` | 住满 |
|
||||
| `3` | 待清扫 |
|
||||
| `4` | 不能入住 |
|
||||
| `5` | 未满 |
|
||||
| `6` | 保洁中 |
|
||||
|
||||
### 2.4 `GYGL_LY_EVENT`(离寓事件证据)
|
||||
|
||||
| 字段 | 说明 |
|
||||
| --- | --- |
|
||||
| `id` | 事件 ID |
|
||||
| `jcid`、`gyid`、`ryid`、`fjh` | 关联入住记录 |
|
||||
| `leave_type` | `FACE` / `MANUAL` 等 |
|
||||
| `device_code`、`device_event_id` | 设备与事件号(`device_code + device_event_id` 幂等) |
|
||||
| `snapshot_url`、`remark`、`operator_id`、`operator_name` | 抓拍、备注、操作人 |
|
||||
| `occurred_at`、`received_at` | 发生/接收时间 |
|
||||
|
||||
### 2.5 `GYGL_JLXX`(交路模板)
|
||||
|
||||
`id`、`jch`、`cc`、`qd`、`kcsj`、`jcsj`、`cclx`、`ddcc`、`ddsj`、`rysj`、`lysj`、`sfpc`、`bz`、`qr_fcd`、`qr_gy`、`lrsj`、`gyid`、`gymc`、`flag_send`、`bzje`。
|
||||
|
||||
关联:
|
||||
|
||||
- `GYGL_JLXX_TY`:交路停运/调整时间段(`gyid`、`cc`、`kssj`、`jssj`)。
|
||||
- `GYGL_JLXX_LOGS`:交路操作日志。
|
||||
- 交路叫乘时刻不单独建表:`getJlXxJcsjList` 由 `GYGL_JLXX` 的 `kcsj`(开车时刻)、`jcsj`(叫乘时刻)、`lysj`(离寓时刻)结合传入的开车日期 `kcrq` 计算得出,`fjsj = jcsj + 10 分钟`、`jcbjsj = jcsj + 15 分钟`。
|
||||
|
||||
## 3. 运安同步
|
||||
|
||||
### 3.1 `GY_SYN_JCXX`(运安计划快照)
|
||||
|
||||
`GY_SYN_JCXX` 是**运安计划快照**,即“匹配要素表”(提供 `kcsj` / `jcfs` / `jch`),**不是叫乘任务的生成源**——它不承载任务、不承载状态、不承载版本。匹配键为 `ryid`(工号)+ `cc`(车次)+ `kcsj` 归日。它是整表快照(`ByxxResourceService` 先清空再写入),任何本地写入都会被下次同步覆盖,因此**不得在其中写本地占位行**。
|
||||
|
||||
| 字段 | 说明 |
|
||||
| --- | --- |
|
||||
| `id` | 计划 ID(`jobid|taskdicid`) |
|
||||
| `ryid`、`ryxm`、`sfzh`、`sjh` | 司机工号/姓名/身份证/手机 |
|
||||
| `jch`、`cx`、`cc` | 机车号、车型、车次 |
|
||||
| `kcsj` | 开车时间(匹配后据此本地计算叫乘时间) |
|
||||
| `jhxl`、`jhcqdd`、`jcfs` | 计划线路、机车缺勤地点、接车方式 |
|
||||
| `h1` | 派班室/公寓辅助字段 |
|
||||
| `write_time` | 写入时间 |
|
||||
|
||||
### 3.2 `GY_SYN_JCXX_STATUS`
|
||||
|
||||
单行/少量行状态表,表示快照是否可用于匹配:`0` 未同步/同步中,`1` 同步完成。
|
||||
|
||||
### 3.3 `GY_SYN_JCXX_HIS`
|
||||
|
||||
同步快照历史(按需保留/排查用)。
|
||||
|
||||
### 3.4 `GY_CALL_DUTY_MATCH_LOCK`
|
||||
|
||||
交路抓取/推送/匹配的协调锁表。使用固定协调行(如 `__SYNC_JCXX__`)持有租约,避免多实例/多线程同时 TRUNCATE 与匹配。
|
||||
|
||||
### 3.5 `JWDATA_SYNC_LOG` / 同步日志
|
||||
|
||||
记录运安抓取、推送、匹配结果与异常,页面 `/jwDataLog/*` 查询。
|
||||
|
||||
## 4. 人员与卡务
|
||||
|
||||
### 4.1 `GY_YKT_RY`(人员)
|
||||
|
||||
`ryid`、`card_id`、`gzzh`、`xm`、`dw`、`depotid`、`gwmc`、`gzmcnew`、`sjh`、`sfzh`、`xb`、`mz`、`zm`、`deleted`、`gxsj`、`photoUrl`。
|
||||
|
||||
- `deleted='1'` 为逻辑删除,查询普遍带 `nvl(deleted,'0') != '1'`。
|
||||
- `gzmcnew` 是岗位归类,用于补助规则与“内部人员”判断。
|
||||
|
||||
### 4.2 `GY_YKT_RY_ZP`
|
||||
|
||||
人员照片(`ryid` + `photoBase64` BLOB)。
|
||||
|
||||
### 4.3 `GY_YKT_REMAINDER`(卡余额)
|
||||
|
||||
`ryid`、`xm`、`xjye`(现金余额)、`knye`(卡内余额/可用余额)、`xfze`(消费总额)、`bzze`(补助总额)、`xfxjje`(现金消费额)、`xfbzje`(补助消费额)。
|
||||
|
||||
### 4.4 `GY_YKT_ALLOWANCE`(补助明细)
|
||||
|
||||
`ryid`、`gyid`、`cblx`(补助类型)、`cbje`(金额)、`sfffcb`、`ryzt`、`fjh`、`jlid`、`yrysj`、`sjrysj`、`ylysj` 等。
|
||||
|
||||
### 4.5 `GY_YKT_CONSUME`(消费明细)
|
||||
|
||||
`tid`(交易号)、`ryid`、`xm`、`xfje`、`xfsj`、`gyid`、`knye`、`xjye`、`xfze`、`bzze`、`xfxjje`、`xfbzje`、`deviceCode`、`xfly`(消费来源)、`is_jrxf`(节假日消费)。
|
||||
|
||||
### 4.6 `GY_YKT_XJCZJL`(现金充值记录)
|
||||
|
||||
充值流水,关联现金充值申请。
|
||||
|
||||
### 4.7 `GY_YKT_CASH_REQUEST`(现金充值申请)
|
||||
|
||||
| 字段 | 说明 |
|
||||
| --- | --- |
|
||||
| `id` | 申请 ID |
|
||||
| `ryid`、`gyid`、`device_code` | 人员/公寓/设备 |
|
||||
| `request_state` | `PENDING` / `CANCELLED` / `COMPLETED` |
|
||||
| `created_at`、`updated_at` | 创建/更新时间 |
|
||||
|
||||
> 申请表本身不存金额;金额由设备/值班端在处理时传入,校验后写入充值流水与余额。
|
||||
|
||||
状态流转:`PENDING → COMPLETED`(值班端处理)或 `PENDING → CANCELLED`(设备取消),两者通过条件更新互斥。
|
||||
|
||||
### 4.8 `GY_YKT_BTJS` / `GY_YKT_BTBJ`
|
||||
|
||||
补助结算/补助报警相关表,配合补助统计与异常检查。
|
||||
|
||||
## 5. 设备
|
||||
|
||||
### 5.1 `GY_SB`(设备)
|
||||
|
||||
`DEVICECODE`、`GYID`、`LX`(类型)、`jrsj`、`gxsj`、`ip`、`fjh`(房间号)。
|
||||
|
||||
### 5.2 `GY_SB_XT`(设备心跳/系统信息)
|
||||
|
||||
`devicecode`、版本、`deviceType`、`ip`、`deviceUpdateState`、`lastUserUpdateTime`、`lastDeviceConfigUpdateTime`、心跳时间等。
|
||||
|
||||
### 5.3 `GY_SB_ZL`(设备指令/版本)
|
||||
|
||||
`id`、`devicecode`、`updateState`、`generatedTime`、`apkurl`、`deleted`。
|
||||
|
||||
- 业务代码写入指令后,设备心跳时按 `devicecode + deleted='0'` 取**最新一条**返回,并置 `deleted='1'`。
|
||||
- 因此一次心跳只消费一条指令;多条指令会随多次心跳依次下发。
|
||||
|
||||
## 6. 基础资料与统计
|
||||
|
||||
| 表 | 说明 |
|
||||
| --- | --- |
|
||||
| `GY_GYZD` | 公寓字典(`gyid`、`gymc`、`ip` 等) |
|
||||
| `GY_GZZD` | 工种字典 |
|
||||
| `GY_JRB` | 节假日日历 |
|
||||
| `GY_JBXX` | 基本/班次信息 |
|
||||
| `GY_SJGZ` | 时间规则:`lysjgz`、`zjjcsjgz`、`kjjcsjgz`(按公寓 + 单位)。这三个字段是**叫乘时刻的派生参数**,不是叫乘时刻本身:站接时 `jcsj = kcsj − zjjcsjgz`;库出时 `jcsj = kcsj − kjjcsjgz`;`ylysj = jcsj + lysjgz`;`fjsj = jcsj + 10 分钟`、`jcbjsj = jcsj + 15 分钟`(与接车方式无关)。改规则只影响之后新算的任务,**不回溯**已算出的任务 |
|
||||
| `GY_BJCSTJ`、`GY_BJXX` | 报警次数/报警信息 |
|
||||
| `GYGL_JGXX` | 叫乘/离寓警示记录(`gyid`、`fssj`、`xx_cc`、`xx_sj`、`xx_ryid`、`xx_ry`、`xxlx`、`xxms`) |
|
||||
| `GY_JDQKHZ` | 进出情况汇总 |
|
||||
| `GY_RTJB`、`GY_YTJB` | 日报/月报 |
|
||||
| `GY_LOGS`、`GL_LOGS` | 业务/登录日志 |
|
||||
| `GY_ZBY` | 值班员信息 |
|
||||
|
||||
## 7. 权限与用户
|
||||
|
||||
`GL_YH`(用户)、`GL_JS`(角色)、`GL_QX`(权限)、`GL_CD`(菜单)、`GL_YH_JS`(用户-角色)、`GL_JS_QX`(角色-权限);另有 `SYS_USER`、`SYS_USER_ROLE`(历史/兼容)。
|
||||
|
||||
## 8. 库存扩展(kcgl)
|
||||
|
||||
`GYGL_KCGL_*`:仓库、供应商、物料、成品、入库单/出库单、盘点单、领料单、价格系数等;与叫乘主线弱相关。
|
||||
|
||||
## 9. 状态字典汇总
|
||||
|
||||
| 字段 | 取值 |
|
||||
| --- | --- |
|
||||
| `GY_JCXX.ryzt` | 0 待叫乘;1 叫乘中;2 叫乘报警;3 已应答待离寓;4 离寓报警;5 通话中;-1 查询合成 |
|
||||
| `GY_JCXX.finish_jc` | 0 未结束;1 已结束 |
|
||||
| `GY_JCXX.finish_ly` | 0 在寓;1 已离寓 |
|
||||
| `GY_JCXX.jllx` | 0 **可参与运安匹配**(交路未定,等待匹配);1 **已由本地确定**(固定交路入住、人工指定或调整后置位),**不参与运安匹配**。注意:1 不是“非标准/便乘/驻在”的分类标签,而是**匹配开关 + 锁定标志**;`/resetJllx` 置回 0 使其重新进入匹配池 |
|
||||
| `GY_ROOMS.room_status` | 1 空闲;2 住满;3 待清扫;4 不能入住;5 未满;6 保洁中 |
|
||||
| `GY_YKT_CASH_REQUEST.request_state` | PENDING / CANCELLED / COMPLETED |
|
||||
| `GY_JCXX.leave_type` | FACE / MANUAL 等 |
|
||||
| 同步状态 | 0 未完成;1 完成 |
|
||||
|
||||
## 10. 升级脚本
|
||||
|
||||
`yktgl/src/main/resources/db/manual/` 下为手工执行的 Kingbase 脚本,按文件名日期顺序执行:
|
||||
|
||||
| 脚本 | 作用 |
|
||||
| --- | --- |
|
||||
| `V20260921_01__leave_snapshot_evidence_kingbase.sql` | 离寓抓拍证据字段/表 |
|
||||
| `V20260922_01__call_duty_notice_dedup_kingbase.sql` | 叫乘提醒去重键 |
|
||||
| `V20261008_01__syn_jcxx_write_time_kingbase.sql` | 快照写入时间 |
|
||||
| `V20261008_02__call_duty_match_lock_kingbase.sql` | 匹配锁表与协调行 |
|
||||
| `V20261009_01__jcxx_history_archive_kingbase.sql` | 历史归档字段/索引 |
|
||||
| `V20261023_01__cash_request_state_kingbase.sql` | 现金充值申请状态 |
|
||||
| `V20261029_01__reconcile_tlxc_room_occupancy.sql` | 通辽公寓房间占用校对(含 preview 版本) |
|
||||
|
||||
另有 `db/GY_SYN_JCXX_STATUS.sql` 初始化同步状态表。
|
||||
|
||||
> 这些脚本不在应用启动时自动执行,升级需人工按序执行并校验。执行前务必备份。
|
||||
@@ -0,0 +1,227 @@
|
||||
# 06 接口清单
|
||||
|
||||
## 1. 通用约定
|
||||
|
||||
- 基础路径:`http://host:8081/yktgl`(`server.servlet.context-path`)。
|
||||
- 返回体:
|
||||
- `Result`:`{code/flag, message, data}`(Web 接口常用)
|
||||
- `ResultData`:设备接口常用
|
||||
- 少数接口直接返回 `JSONObject` 或字符串。
|
||||
- 公寓上下文:绝大多数写接口通过客户端 IP 解析 `gyid`;少数接口显式接收 `gyid`,但服务端仍会校验。
|
||||
- **方法约束宽松**:大量接口用 `@RequestMapping`,GET/POST 都可访问,部分写操作也能用 GET 触发。新增接口建议明确 `@GetMapping`/`@PostMapping`。
|
||||
- 字符集:JSON 为 UTF-8;设备请求体常为单行 JSON。
|
||||
|
||||
## 2. 叫乘核心 `/jcgl`
|
||||
|
||||
| 方法 | 路径 | 用途 | 目标架构承接 |
|
||||
| --- | --- | --- | --- |
|
||||
| ALL | `/getJcxxByRyid` | 按人员/记录查叫乘信息 | — |
|
||||
| ALL | `/getEmployeeArriveInfo` | 按单位查人员到达信息 | — |
|
||||
| POST | `/getJcXx` | 条件查询在寓/叫乘列表 | — |
|
||||
| POST | `/resetJllx` | 重置交路类型 | `UNLOCK_MATCH`(解锁后回到运安匹配池),由 `apt:jcxx:lockMatch` 权限点管控 |
|
||||
| GET | `/getLatestSyncTime` | 当前公寓最近同步时间 | — |
|
||||
| GET | `/getSjgz` | 时间规则(叫乘/离寓提前量) | — |
|
||||
| ALL | `/getJlxxList` | 按车次/机车号查交路 | — |
|
||||
| ALL | `/getRoomList` | 房间列表 | — |
|
||||
| GET | `/getRoomRecommendations` | 入住房间推荐 | — |
|
||||
| ALL | `/modifyRoomStatus` | 设置不能入住/恢复可入住 | — |
|
||||
| ALL | `/submitAll` | 提交入寓登记(`submit_rydj`) | — |
|
||||
| ALL | `/updateMeal3` | 更新第三餐补助 | — |
|
||||
| ALL | `/getBtje_info` | 按入住时间查补助金额 | — |
|
||||
| ALL | `/getBtje_infoMeal3` | 第三餐补助信息 | — |
|
||||
| ALL | `/getRyxx` | 按人员查资料 | — |
|
||||
| ALL | `/getRyxxByRyId` | 按人员查资料(含公寓上下文) | — |
|
||||
| ALL | `/remakeRemainder` | 重算余额/补助 | — |
|
||||
| ALL | `/modifyJcXx` | 修改叫乘信息并重建任务 | `POST /apt/jcxx/{jcid}/commands` 的 `ASSIGN_ELEMENT`(换交路/车次/开车时刻/接车方式)+ `ADJUST_TIME`(只调 jcsj)。语义差异:旧接口一次可改多个字段且不区分“要素”与“时刻”,新接口强制 reason、commandId 幂等、并把 jllx 置 1 锁定 |
|
||||
| POST | `/getJcXxFromGy` | 从公寓端获取叫乘信息 | **方向违反“平台不回调公寓、下行一律拉”**——依据是 `docs/backend/10-架构优化方案-三端拆分.md` **表 5-1 第 4 行**(“平台端 → 公寓端|不允许直连|仅落‘待下发配置版本’,由公寓端拉取”)与**表 8-4「出站 443/tcp」行**(“单向出站,平台侧不回调”)。能力由公寓端 #8 上行(要素登记)+ #7 响应体(核验结论)反向承接;**阶段五下线**,前置条件见 `docs/backend/10` 表 9-6 修订后文字(本清单 R-08) |
|
||||
| ALL | `/getZbyList` | 值班员列表 | — |
|
||||
| ALL | `/getGzList` | 工种列表 | — |
|
||||
| POST | `/modifyRyXx` | 修改人员资料 | — |
|
||||
| POST | `/deleteRyXx` | 删除人员 | — |
|
||||
| ALL | `/isHoliday` | 是否节假日 | — |
|
||||
| ALL | `/getGyOptions` | 按单位取公寓选项 | — |
|
||||
| POST | `/synCallDutyInfo` | 运安计划推送(整表快照) | 运安快照写入入口;目标架构在平台侧由 #6 下行替代,公寓端不再直连运安(`docs/backend/10` 表 9-6) |
|
||||
| POST | `/processCheckInRegistration` | 设备入寓登记(code 1/2/3) | — |
|
||||
| POST | `/processCheckOutRegistration` | 设备离寓(code 1/2) | — |
|
||||
| POST | `/processCallDuty` | 叫乘设备状态上报(status 1–5) | — |
|
||||
| POST | `/processTempCallDuty` | 临时叫乘状态上报 | — |
|
||||
| ALL | `/getCcJcXx` | 按车次聚合叫乘信息 | — |
|
||||
| ALL | `/getCcJcXx_Ls` | 历史车次叫乘信息 | — |
|
||||
| ALL | `/getCallDutyInfoByDeviceCode` | 叫乘屏按设备码取人员 | — |
|
||||
| ALL | `/getTempCallDutyInfoByDeviceCode` | 临时叫乘屏取人员 | — |
|
||||
| ALL | `/getSynJcXx` | 分页查运安快照 | — |
|
||||
| ALL | `/getRzXx` | 入住信息 | — |
|
||||
| ALL | `/getRemoteSynJcXx` | 远程同步(当前为桩实现,返回空成功) | — |
|
||||
| ALL | `/synUnMatchJcXx` | 触发交路匹配 | — |
|
||||
| POST | `/syncJcXxData` | 手工归档 7 天前已离寓记录 | — |
|
||||
| ALL | `/handleTempCalling` | 临时叫乘(人工) | — |
|
||||
| ALL | `/handleRoomCall2` / `/handleRoomCallEnd2` | 房间呼叫/结束(新版) | — |
|
||||
| ALL | `/handleRoomCall` / `/handleRoomCallEnd` | 房间呼叫/结束(旧版) | — |
|
||||
| ALL | `/handleMultiRoomCall` / `/handleMultiRoomCallEnd` | 多房间呼叫/结束 | — |
|
||||
| ALL | `/handleCheckOut` | 值班端办理离寓 | — |
|
||||
| ALL | `/cancelTrainAssignment` | 取消交路并清理任务 | — |
|
||||
| ALL | `/getWslRyXx` | 未匹配人员信息 | — |
|
||||
| ALL | `/getRyFjXx` | 人员房间信息 | — |
|
||||
| ALL | `/exchangeRoom` | 换房 | — |
|
||||
| ALL | `/handleStopCalling` | 停止叫乘(需报警事件键) | — |
|
||||
| ALL | `/yatest` | 运安 SOAP 连通性测试 | — |
|
||||
| ALL | `/ya/list` | 触发运安计划抓取 | — |
|
||||
| ALL | `/driver/{driverId}` | 查询运安司机信息 | — |
|
||||
| GET | `/getRecordingConfig` | 录音回放配置(RecordingController) | — |
|
||||
|
||||
## 3. 交路 `/jlgl`
|
||||
|
||||
| 路径 | 用途 |
|
||||
| --- | --- |
|
||||
| `/addJlXx` | 新增交路 |
|
||||
| `/modifyJlXx` | 修改交路 |
|
||||
| `/getJlXxList` | 交路列表 |
|
||||
| `/getJlXxJcsjList` | 交路及叫乘时刻 |
|
||||
| `/delJlXx`、`/deleteJlXx` | 删除交路 |
|
||||
| `/uploadJlXx` | Excel 上传交路 |
|
||||
| `/getMessageFromGy`、`/getMessageFromFcd` | 从公寓/发车点获取信息 |
|
||||
| `/getGyXxList`、`/getTyXxList` | 公寓/停运信息 |
|
||||
| `/addTySjList` | 新增停运时间 |
|
||||
| `/confirmJlXx` | 交路确认 |
|
||||
| `/getTrainNumberInfo` | 车次信息 |
|
||||
|
||||
## 4. 人员与注册 `/regist`
|
||||
|
||||
| 方法 | 路径 | 用途 |
|
||||
| --- | --- | --- |
|
||||
| POST | `/registPersonInfo` | 设备注册协议(code 1 拍照、2 查/更新照片、3 按 ID 查、4 批量增量) |
|
||||
| POST | `/addPersonInfo` | 新增人员(写真 + 照片表) |
|
||||
| ALL | `/getPersonelInfo` | 按手机号/姓名查人员 |
|
||||
| POST | `/updatePersonelInfo` | 修改人员并下发设备指令 |
|
||||
| ALL | `/deletePersonelInfo` | 逻辑删除人员并清理照片 |
|
||||
|
||||
## 5. 充值 `/recharge`
|
||||
|
||||
| 路径 | 用途 |
|
||||
| --- | --- |
|
||||
| `/processCashRecharge` | 设备充值协议(code 1–4) |
|
||||
| `/handleRecharge` | 值班端处理充值 |
|
||||
| `/autoRecharge` | 自动补助入账(对应定时器已停用) |
|
||||
| `/getAllowance` | 补助查询 |
|
||||
| `/getRechargeInfo` | 充值记录 |
|
||||
| `/getRechargeStatisInfo` | 充值统计 |
|
||||
| `/getAllowanceStatis` | 补助统计 |
|
||||
|
||||
## 6. 消费 `/pay`
|
||||
|
||||
| 路径 | 用途 |
|
||||
| --- | --- |
|
||||
| `/processPayment` | 设备消费协议(code 1 查余额、2 扣款) |
|
||||
| `/getConsumDetailInfo` | 消费明细 |
|
||||
| `/getCashConsumeStatisInfo` | 现金消费统计 |
|
||||
| `/getAllowanceConsumeStatisInfo` | 补助消费统计 |
|
||||
| `/getConsumeStatis` | 消费汇总 |
|
||||
|
||||
## 7. 设备接入
|
||||
|
||||
| 基础路径 | 接口 | 用途 |
|
||||
| --- | --- | --- |
|
||||
| `/callingDevice` | `POST /heartbeat` | 叫乘屏心跳 |
|
||||
| `/checkInDevice` | `POST /heartbeat` | 签到机心跳 |
|
||||
| `/roomDevice` | `POST /heartbeat` | 房间屏心跳 |
|
||||
| `/payDevice` | `POST /heartbeat` | 消费机心跳 |
|
||||
| `/registDevice` | `POST /heartbeat` | 注册机心跳 |
|
||||
| `/vendPayDevice` | `POST /heartbeat`、`POST /processPayment` | 售货机心跳/支付 |
|
||||
| `/heartBeat` | `/getDeviceInfo`、`/getDeviceStatusInfo`、`/modifyDeviceInfo`、`/modifyApkVersion` | 管理端设备查询/维护 |
|
||||
|
||||
### 7.1 心跳请求字段(常见)
|
||||
|
||||
`deviceCode`、`versionName`、`deviceType`、`ip`、`deviceUpdateState`、`lastUserUpdateTime`、`lastDeviceConfigUpdateTime`、`roomNumber`。
|
||||
|
||||
### 7.2 心跳响应字段
|
||||
|
||||
`devicePassword`、`apartmentName`、`serverTime`、`updateState`、`apkUrl`、指令列表。
|
||||
|
||||
### 7.3 设备业务协议
|
||||
|
||||
| 场景 | code/status | 说明 |
|
||||
| --- | --- | --- |
|
||||
| 入寓登记 | code 1/2/3 | 查询/提交/按 ID 查询 |
|
||||
| 离寓 | code 1/2 | 查询/刷脸离寓 |
|
||||
| 叫乘 | status 1–5 | 开始/复叫/叫乘报警/离寓报警/应答 |
|
||||
| 临时叫乘 | status 1–5 | 同上,另刷新房间设备 |
|
||||
| 充值 | code 1–4 | 查余额/申请/查状态/取消 |
|
||||
| 消费 | code 1/2 | 查余额/扣款 |
|
||||
| 售货机 | code 1/2/3 | 查余额/下单/结果或退款 |
|
||||
| 注册 | code 1–4 | 拍照/查询/按 ID/批量增量 |
|
||||
| 保洁 | — | 开始/结束保洁(`/clean`) |
|
||||
|
||||
## 8. 管理后台
|
||||
|
||||
### 8.1 登录与权限
|
||||
|
||||
| 路径 | 用途 |
|
||||
| --- | --- |
|
||||
| `/auth/getCaptcha`、`/auth/captchaImage` | 验证码 |
|
||||
| `/auth/login` | 登录 |
|
||||
| `/auth/logon` | 注册/开通 |
|
||||
| `/auth/logout` | 退出 |
|
||||
| `/auth/getInfo` | 当前用户信息 |
|
||||
| `/auth/getMenuInfo` | 用户菜单 |
|
||||
| `/user/*` | 用户增删改查、改密、启停 |
|
||||
| `/role/*` | 角色与角色权限 |
|
||||
| `/permission/*` | 权限树与权限维护 |
|
||||
| `/menu/*` | 菜单维护 |
|
||||
| `/dept/*` | 部门树、公寓部门树 |
|
||||
|
||||
### 8.2 基础资料 `/Zdwh`
|
||||
|
||||
时间规则、公寓、房间、节假日、餐补标准的新增/修改/删除/查询;公寓与房间资料是入住与推荐的基础。
|
||||
|
||||
### 8.3 统计与导出
|
||||
|
||||
| 路径 | 用途 |
|
||||
| --- | --- |
|
||||
| `/xxtj/getBjcs` | 报警次数 |
|
||||
| `/xxtj/getJdqk` | 进出情况 |
|
||||
| `/xxtj/getRtjb` | 日报 |
|
||||
| `/xxtj/getYtjb` | 月报 |
|
||||
| `/xxtj/getDailyApartmentReport`、`/getDailyApartmentReportFull` | 公寓日报 |
|
||||
| `/xxtj/getApartmentAllowanceStatis` | 补助统计 |
|
||||
| `/excel/exportJcXxExcell` | 叫乘明细 |
|
||||
| `/excel/exportDailyApartmentReport` | 日报 |
|
||||
| `/excel/exportJcXxExcellOld` | 旧版叫乘明细 |
|
||||
| `/excel/exportAllowanceExcell` | 补助明细 |
|
||||
| `/excel/exportRechargeExcell` | 充值明细 |
|
||||
| `/excel/exportConsumeExcell` | 消费明细 |
|
||||
| `/excel/exportRechargeStatisExcell` | 充值统计 |
|
||||
| `/excel/exportAllowanceStatisExcell` | 补助统计 |
|
||||
| `/excel/exportCashConsumeStatisExcell` | 现金消费统计 |
|
||||
| `/excel/exportAllowanceConsumeStatisExcell` | 补助消费统计 |
|
||||
|
||||
### 8.4 其他
|
||||
|
||||
| 路径 | 用途 |
|
||||
| --- | --- |
|
||||
| `/clean/startCleaning`、`/endCleaning`、`/getRoomCleanInfo` | 保洁 |
|
||||
| `/jgxxgl/getJgXx` | 报警/警示查询 |
|
||||
| `/Meals/*` | 餐食、订单、房间、餐次列表 |
|
||||
| `/kcgl/*` | 库存/出入库/物料/成品/文件 |
|
||||
| `/synData/*` | 运安/公寓人员、财务数据 |
|
||||
| `/jwDataLog/getSynJcXxIsOffline` | 同步状态/是否离线 |
|
||||
| `/websocket/{username}`、`/jcwebsocket/{username}`、`/jlwebsocket/{username}`、`/rlywebsocket/{username}`、`/MealsWebsocket/{username}` | WebSocket 端点 |
|
||||
|
||||
## 9. WebSocket 消息
|
||||
|
||||
| 消息 | 含义 |
|
||||
| --- | --- |
|
||||
| `{"lx":"refresh"}` | 叫乘/房间/人员数据刷新 |
|
||||
| `{"lx":"ry","content":...}` | 入寓人员信息推送值班端 |
|
||||
| `{"lx":"zcxx","photoBase64":...,"deviceCode":...,"zcid":...}` | 注册拍照 |
|
||||
| `{"lx":"xgxx","content":...,"newPhotoBase64":...}` | 人员资料/照片更新 |
|
||||
| `{"lx":"cz"}` | 充值申请提醒 |
|
||||
|
||||
`JcWebsocket.sendMessage(message, gyid)` 会按公寓路由;`gyid="all"` 表示广播。
|
||||
|
||||
## 10. 接口扩展建议
|
||||
|
||||
1. 新接口明确 HTTP 方法,避免用 `@RequestMapping` 触发写操作。
|
||||
2. 统一返回体,不在 Controller 里拼 `JSONObject`。
|
||||
3. 前端传入的 `gyid` 只能作为提示,服务端必须重新解析/校验。
|
||||
4. 设备协议新增字段时保持向后兼容:旧字段可缺省,新增字段给默认值。
|
||||
5. 接口文档以本清单为基线,最终以 `JcglController` 等源码为准;Swagger 目前只扫描 `jlgl.controller`,覆盖不全。
|
||||
@@ -0,0 +1,210 @@
|
||||
# 07 外部集成与定时任务
|
||||
|
||||
## 1. Asterisk 电话/广播链路
|
||||
|
||||
### 1.1 角色
|
||||
|
||||
- 叫乘执行者:`AsteriskCallUtil`。
|
||||
- 连接方式:Asterisk Manager Interface(AMI),使用定制版 `asterisk-java 3.38.0-zfjia`。
|
||||
- 会议桥:`Conf-01`。
|
||||
- 呼叫对象:
|
||||
- 值班台:`Local/1701@from-internal`(`callcontrol.ami.console`,默认 1009/1010)。
|
||||
- 房间:房间 `sip_account`(`GY_ROOMS.sip_account`)经 `Local/1901@from-internal` 呼入。
|
||||
- 串口:`callcontrol.console.*`(默认 `COM1`、9600),用于广播/话机控制。
|
||||
|
||||
### 1.2 配置项
|
||||
|
||||
```yaml
|
||||
callcontrol:
|
||||
ami:
|
||||
host: 127.0.0.1
|
||||
port: 7058
|
||||
user: ${AMI_USER}
|
||||
pwd: ${AMI_PASSWORD}
|
||||
console: 1010
|
||||
callduration: 180
|
||||
console:
|
||||
port: COM1
|
||||
baudrate: 9600
|
||||
recording:
|
||||
base-url: ... # 录音回放地址
|
||||
```
|
||||
|
||||
### 1.3 一次叫乘的时序
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant Q as Quartz WakeUpJob
|
||||
participant S as JcglService
|
||||
participant A as AsteriskCallUtil
|
||||
participant AMI as Asterisk AMI
|
||||
participant C as 值班台
|
||||
participant R as 房间话机
|
||||
|
||||
Q->>S: 触发 JC/FJ/JCJS
|
||||
S->>A: makeWakeup(人员, 房间SIP)
|
||||
A->>A: 组装 TTS 文本
|
||||
A->>AMI: 呼叫 1701(值班台)
|
||||
A->>AMI: 呼叫 1901 + 房间 SIP
|
||||
AMI->>C: 接通
|
||||
AMI->>R: 接通并加入 Conf-01
|
||||
A->>AMI: 播放 TTS
|
||||
R-->>A: ConfbridgeJoin / Answered
|
||||
A->>S: ryzt=5(通话中)→ 挂断后 ryzt=3(待离寓)
|
||||
```
|
||||
|
||||
### 1.4 TTS 文案
|
||||
|
||||
> 尊敬的{姓名},{公寓名称}提醒您,您值乘的{车次}次,接车方式是{接车方式},开车时间{开车时间},现在时间{当前时间},请您携带好随身物品,准备出乘。
|
||||
|
||||
车次、接车方式、时间会做口语化格式化(`formatTrainCodeForSpeech` / `formatPickupModeForSpeech` / `formatTrainTimeForSpeech`)。
|
||||
|
||||
### 1.5 超时与挂断
|
||||
|
||||
| 常量 | 值 | 说明 |
|
||||
| --- | --- | --- |
|
||||
| `CALL_TIMEOUT_MS` | 30 秒 | 呼叫无应答超时 |
|
||||
| `WAKEUP_ANSWERED_AUTO_HANGUP_SECONDS` | 40 秒 | 叫乘接通后自动挂断 |
|
||||
| `SHOUT_CALL_ANSWERED_AUTO_HANGUP_SECONDS` | 30 秒 | 广播/喊话接通后自动挂断 |
|
||||
|
||||
事件监听:
|
||||
|
||||
- `ConfbridgeJoinEvent`:入会,记录通道与接通。
|
||||
- `ConfbridgeLeaveEvent`:离会,清理跟踪。
|
||||
- `NewCallerIdEvent`:回填通道/主叫。
|
||||
- `HangupEvent`:挂断,若已接通且需跟踪则置 `ryzt=3`;未接通则进入未应答处理(转报警/复叫)。
|
||||
|
||||
录音:接通后记录录音文件名,追加到 `GY_JCXX.recordfile`;`/jcgl/getRecordingConfig` 返回回放地址。
|
||||
|
||||
### 1.6 停止/挂断
|
||||
|
||||
- `stopWakeupCall` / `stopWakeupCallAsync`:挂断该人员所有跟踪通道、值班台/房间通道、`Conf-01`。
|
||||
- `hangupTrackedCallsByRyid`:只挂断跟踪到的通道。
|
||||
- `isConferenceBusy`:会议桥占用时任务延迟 60 秒。
|
||||
|
||||
## 2. 机务运安(BYXX)SOAP
|
||||
|
||||
### 2.1 接入方式
|
||||
|
||||
- WSDL:`classpath:/wsdl/PbResource.wsdl`。
|
||||
- 生成客户端:`byxx.resource.PbResource_Service` / `PbResource`。
|
||||
- 服务实现:`ByxxResourceService`。
|
||||
|
||||
### 2.2 主要操作
|
||||
|
||||
| 操作 | 用途 |
|
||||
| --- | --- |
|
||||
| `getLocoHomeList` | 机务段列表 |
|
||||
| `getDriverInfoBySectionCode` | 按段获取司机资料 |
|
||||
| `getDriverInfoByWorkNo` | 按工号获取司机 |
|
||||
| `getDriverPlanByTimeStr` | 按时间段获取乘务计划(叫乘快照来源) |
|
||||
|
||||
### 2.3 计划字段映射
|
||||
|
||||
| 运安字段 | 快照字段 |
|
||||
| --- | --- |
|
||||
| `jobid + taskdicid` | `id` |
|
||||
| `driver1..driver4` | `ryid`(一条计划拆成最多 4 条人员记录) |
|
||||
| `plantrainnum` | `cc` |
|
||||
| `model + loco` | `jch` |
|
||||
| `dispmancode` | `h1` |
|
||||
| `plandeptime` | `kcsj` |
|
||||
| `plancalltime` | `jcsj`(仅保留,最终叫乘时间按本地规则重算) |
|
||||
| `plandepstation` | `jhcqdd` |
|
||||
| `jobType`(0 库出,其他站接) | `jcfs` |
|
||||
|
||||
### 2.4 调度
|
||||
|
||||
- 每 5 分钟抓取一次(`SynDataSchedule.getSynDataJob`),窗口约 4 小时。
|
||||
- 每 5 天同步一次人员(`SyncPersonData`,仅 `T` 开头机务段)。
|
||||
- 抓取/匹配共用 `CallDutyMatchLock`,防止并发清表。
|
||||
- **匹配只处理 `baseConfig.gyid` 配置的公寓**;一实例多公寓部署时,其他公寓不会自动匹配,需改造或拆实例。
|
||||
|
||||
### 2.5 已知限制
|
||||
|
||||
- `mergeSynJcXx` 已停用(同 `id` 多司机导致 MERGE 重复)。
|
||||
- `getRemoteSynJcXx` 为桩实现,未恢复远程 HTTP 同步。
|
||||
- WSDL 地址与派班室/公寓编码硬编码(“通辽南公寓”“通辽南派班室”),多公寓部署需参数化。
|
||||
|
||||
## 3. 中心服务器 HTTP
|
||||
|
||||
| 场景 | 地址/配置 | 说明 |
|
||||
| --- | --- | --- |
|
||||
| 人员资料拉取 | `http://10.32.112.153:52411/api/users?pagenum=N` | `SynDataService.personData`,分页拉取机务人员 |
|
||||
| 人员变更推送 | `/synData/modifyPersonData` | 运安推送人员增量 |
|
||||
| 公寓人员查询 | `/synData/getApartmentPersonData*` | 按公寓/工号/时间查询在寓人员 |
|
||||
| 财务数据 | `/synData/synFinanceData` | 按 IP 解析公寓后返回余额数据 |
|
||||
| 照片/静态资源 | `baseConfig.centerServerUrl` / `serverUrl` | 人员照片 URL 前缀 |
|
||||
|
||||
中心同步使用 `HttpRequest`(内部封装),未见超时/重试统一配置,排障时需关注网络与超时。
|
||||
|
||||
## 4. WebSocket
|
||||
|
||||
| 端点 | 用途 |
|
||||
| --- | --- |
|
||||
| `/websocket/{username}` | 通用推送(历史) |
|
||||
| `/jcwebsocket/{username}` | 叫乘主界面刷新/人员信息 |
|
||||
| `/jlwebsocket/{username}` | 交路界面 |
|
||||
| `/rlywebsocket/{username}` | 人员/入住相关 |
|
||||
| `/MealsWebsocket/{username}` | 餐食订单 |
|
||||
|
||||
关键消息见 [06-接口清单.md](06-接口清单.md) 第 9 节。服务端推送按 `gyid` 路由,`"all"` 广播。
|
||||
|
||||
## 5. Quartz 叫乘任务
|
||||
|
||||
| 项 | 说明 |
|
||||
| --- | --- |
|
||||
| Job 类 | `quartz/WakeUpJob` |
|
||||
| 调度管理 | `quartz/SchedulerManager` |
|
||||
| JobKey | `ryid + "JC"` / `"FJ"` / `"JCJS"` |
|
||||
| TriggerGroup | `gyid + fjh` |
|
||||
| 触发方式 | 一次性 cron,精确到秒 |
|
||||
| 优先级 | JC=1、FJ=2、JCJS=3 |
|
||||
| 并发控制 | `@DisallowConcurrentExecution` |
|
||||
| 参数 | `JobParas`(人员、房间、车次、时间、jcid 等) |
|
||||
| 执行前校验 | `jcid/fjh/叫乘时间` 与库中一致才执行,否则跳过 |
|
||||
| 合并执行 | 同房间/同车次合并为一个执行组,组长先叫 |
|
||||
| 会议桥忙 | 延迟 60 秒 |
|
||||
| 恢复 | `WakeupJobRecoveryRunner` 在 `ApplicationReadyEvent` 后恢复未来任务 |
|
||||
|
||||
失败处理:
|
||||
|
||||
- 任务内部异常写业务日志,不抛到 Quartz。
|
||||
- `JCJS` 挂断会议桥、置 `ryzt=2`、写报警记录。
|
||||
- 人工停止叫乘会取消该人员全部任务。
|
||||
|
||||
## 6. Spring `@Scheduled` 清单
|
||||
|
||||
| 类.方法 | Cron | 作用 | 状态 |
|
||||
| --- | --- | --- | --- |
|
||||
| `JcSchedule.notifyMissedCallWarnings` | `5 * * * * ?`(每分钟第 5 秒) | 超时未叫乘分级提醒(第 1/10/15 分钟) | 启用 |
|
||||
| `JcSchedule.triggerOverdueLeaveAlarms` | `15 * * * * ?`(每分钟第 15 秒) | 已应答但超时未离寓报警 | 启用 |
|
||||
| `JcSchedule.syncJcXxData` | `0 0 0 * * ?`(Asia/Shanghai) | 归档已离寓满 7 天记录 | 启用 |
|
||||
| `SynDataSchedule.getSynDataJob` | `0 */5 * * * ?` | 运安抓取 + 记录同步时间 + 触发匹配 | 启用 |
|
||||
| `SynDataSchedule.synPersonDataJob` | `30 0 0 */5 * ?` | 每 5 天同步运安人员 | 启用 |
|
||||
| `LeaveSnapshotCleanupSchedule.cleanupExpiredLeaveSnapshots` | `${leaveSnapshot.cleanupCron:0 30 2 * * ?}` | 清理过期离寓抓拍 | 启用 |
|
||||
| `RechargeSchedule.*` | — | 自动补助/充值 | 全部注释停用 |
|
||||
| `JlSchedule.*` | — | 交路定时同步 | 注释停用 |
|
||||
| `LogSchedule.*` | — | 日志清理 | 注释停用 |
|
||||
|
||||
## 7. 并发控制与幂等
|
||||
|
||||
| 机制 | 位置 | 说明 |
|
||||
| --- | --- | --- |
|
||||
| 交路同步锁 | `CallDutyMatchLock` + `GY_CALL_DUTY_MATCH_LOCK` | 抓取/推送/匹配互斥,事务提交后释放 |
|
||||
| 同步状态位 | `GY_SYN_JCXX_STATUS` | 只有 `1` 才能匹配 |
|
||||
| 设备事件幂等 | `GYGL_LY_EVENT(device_code, device_event_id)` | 刷脸离寓重复请求直接返回已处理 |
|
||||
| 报警去重 | `triggerLeaveAlarmIfPending` 条件更新 | 同一次入住只触发一次离寓报警 |
|
||||
| 提醒去重 | `route_notice_key` / `call_timeout_notice_key` / `missed_call_notice_key` | 同一节点只提醒一次 |
|
||||
| 充值互斥 | `GY_YKT_CASH_REQUEST` 条件更新 | 完成与取消只能成功一个 |
|
||||
| 房间占用 | `refreshRoomOccupancy` + 有效在寓明细 | 防止计数漂移 |
|
||||
| 任务过期校验 | `WakeUpJob` 执行前比对库中数据 | 防止旧任务误叫 |
|
||||
|
||||
## 8. 排障入口
|
||||
|
||||
1. **叫乘没响**:看 Quartz 任务是否存在(`SchedulerManager` 日志)→ AMI 连接 → 会议桥是否忙 → 房间 `sip_account` 是否为空 → 任务时间是否已过期被跳过。
|
||||
2. **叫乘响了但状态不变**:看 AMI 事件(Join/Hangup)是否被正确匹配通道 → `GY_JCXX.ryzt` / `recordfile`。
|
||||
3. **运安计划没进来**:看 5 分钟任务日志、`GY_SYN_JCXX_STATUS`、`JWDATA_SYNC_LOG`、WSDL 可达性。
|
||||
4. **匹配不上**:核对 `GY_YKT_RY.card_id` 与 `GY_SYN_JCXX.workno`,以及人员是否在有效在寓状态、`jllx` 是否被人工锁定。
|
||||
5. **离寓报错**:看抓拍配置 `leaveSnapshot.*`、事件幂等记录、`GYGL_LY_EVENT`。
|
||||
6. **设备指令不下发**:看 `GY_SB` 是否有该设备、心跳是否带 `deviceCode`、指令是否已被置 `deleted=1`。
|
||||
@@ -0,0 +1,191 @@
|
||||
# 08 部署与配置
|
||||
|
||||
## 1. 构建与运行
|
||||
|
||||
### 1.1 环境要求
|
||||
|
||||
| 组件 | 要求 |
|
||||
| --- | --- |
|
||||
| JDK | 8 |
|
||||
| Maven | 3.6+ |
|
||||
| 数据库 | KingbaseES 8(部分 Profile 仍接 Oracle) |
|
||||
| 缓存 | Redis(Session) |
|
||||
| 电话 | Asterisk + AMI 账号 + 会议桥 `Conf-01` |
|
||||
| 串口 | 广播/话机控制串口(默认 `COM1`,Linux 下为 `/dev/ttyS0` 等) |
|
||||
| 文件 | 照片、离寓抓拍、录音的可读写目录 |
|
||||
|
||||
### 1.2 构建
|
||||
|
||||
```bash
|
||||
cd yktgl
|
||||
mvn clean package -DskipTests
|
||||
```
|
||||
|
||||
- `pom.xml` 未声明 `<packaging>`,默认生成 jar。
|
||||
- 入口继承 `SpringBootServletInitializer`,如需部署到外部 Tomcat,可改为 `<packaging>war</packaging>` 并排除内嵌容器。
|
||||
- 构建前注意 `pom.xml` 中 Boot 3.x 依赖版本与 Boot 2.6.13 的兼容问题(见 09)。
|
||||
|
||||
### 1.3 启动
|
||||
|
||||
```bash
|
||||
java -jar yktgl-0.0.1-SNAPSHOT.jar --spring.profiles.active=prod
|
||||
```
|
||||
|
||||
或:
|
||||
|
||||
```bash
|
||||
java -Dspring.profiles.active=prod -jar yktgl-0.0.1-SNAPSHOT.jar
|
||||
```
|
||||
|
||||
默认端口 `8081`,上下文路径 `/yktgl`。
|
||||
|
||||
## 2. Profile 对照
|
||||
|
||||
| Profile | 公寓 `gyid` / `gymc` | 数据源 | 备注 |
|
||||
| --- | --- | --- | --- |
|
||||
| `local` | `TMXC` 图们行车公寓 | Kingbase `127.0.0.1:54321/gygl` | 本机调试,Redis/AMI/串口均本机 |
|
||||
| `dev` | 未启用(注释为 `TLXC`) | Kingbase `10.32.209.76:54321/gygl` | 开发环境 |
|
||||
| `prod` | `TLNXC` 通辽南行车公寓 | Kingbase `10.33.165.41:54321/gygl` | 生产 |
|
||||
| `tl` | `TLXC` 通辽行车公寓 | Kingbase `10.32.209.76:54321/gygl` | 通辽 |
|
||||
| `sjt` | `SJTXC` 苏家屯行车公寓 | Kingbase `10.32.209.76:54321/gygl` | 苏家屯 |
|
||||
| `byq` | `BYQXC` 鲅鱼圈行车公寓 | Oracle `10.32.116.45/db3` | 仍在 Oracle |
|
||||
| `cc` | `SJTXC` 苏家屯行车公寓 | Oracle `10.32.5.175/rlxt` | 仍在 Oracle,注意与 `sjt` 同名不同库 |
|
||||
| `dl` | `DLXC` 大连行车公寓 | Oracle `10.32.116.45/db3` | 仍在 Oracle |
|
||||
| `pj` | `PJXC` 盘锦行车公寓 | Oracle `10.32.116.45/db3` | 仍在 Oracle |
|
||||
|
||||
> 所有 Profile 中的数据库口令、AMI 口令、`devicePassword` 目前均为明文,且已提交到仓库。生产使用前应改为环境变量/配置中心,并轮换口令。
|
||||
|
||||
## 3. 关键配置项
|
||||
|
||||
### 3.1 服务
|
||||
|
||||
| 配置 | 说明 |
|
||||
| --- | --- |
|
||||
| `server.port` | 默认 8081 |
|
||||
| `server.servlet.context-path` | `/yktgl` |
|
||||
| `spring.profiles.active` | 默认 `local` |
|
||||
| `spring.mvc.pathmatch.matching-strategy` | `ant_path_matcher`(兼容 Springfox) |
|
||||
|
||||
### 3.2 数据源与连接池
|
||||
|
||||
| 配置 | 说明 |
|
||||
| --- | --- |
|
||||
| `spring.datasource.url` | Kingbase 需带 `currentSchema=gygl` |
|
||||
| `spring.datasource.driver-class-name` | `com.kingbase8.Driver` |
|
||||
| `spring.datasource.hikari.*` | 最小空闲 5、最大 15、连接超时 60s、最大生命周期 600s |
|
||||
|
||||
### 3.3 Redis / Session
|
||||
|
||||
| 配置 | 说明 |
|
||||
| --- | --- |
|
||||
| `spring.redis.host/port` | Redis 地址 |
|
||||
| `spring.session.store-type` | `redis` |
|
||||
| `spring.session.timeout` | 默认 30m |
|
||||
|
||||
### 3.4 公寓与业务开关 `baseConfig`
|
||||
|
||||
| 配置 | 说明 |
|
||||
| --- | --- |
|
||||
| `gyid` / `gymc` | 当前公寓(单公寓/默认兜底) |
|
||||
| `centerServerUrl` | 中心服务器地址(照片前缀等) |
|
||||
| `serverUrl` | 服务自身地址 |
|
||||
| `synJcXxIp` | 运安推送来源 IP 白名单(逗号分隔) |
|
||||
| `devicePassword` | 设备心跳返回的设备密码 |
|
||||
| `centralPhoneIp` | 中心电话 IP |
|
||||
| `serverOS` | `windows` / `linux`,影响照片与抓拍路径 |
|
||||
| `modifyyasj` | 是否允许调整运安叫乘时间 |
|
||||
| `allowRouteChangeAfterCompletedCall` | 默认 `true`;叫乘完成后是否允许运安匹配继续变更交路 |
|
||||
| `syncMatchWaitSeconds` | 默认 900;抓取/匹配等待同步锁的最长秒数 |
|
||||
| `fjgydbs` | 分公寓/终端所属公寓段的交互标识(按需配置) |
|
||||
|
||||
### 3.5 电话与录音 `callcontrol`
|
||||
|
||||
| 配置 | 说明 |
|
||||
| --- | --- |
|
||||
| `callcontrol.ami.host/port` | AMI 地址 |
|
||||
| `callcontrol.ami.user/pwd` | AMI 账号 |
|
||||
| `callcontrol.ami.console` | 值班台分机/控制台号 |
|
||||
| `callcontrol.ami.callduration` | 呼叫时长上限(秒) |
|
||||
| `callcontrol.console.port/baudrate/...` | 串口参数 |
|
||||
| `callcontrol.recording.base-url` | 录音回放根地址;为空时默认 `http://<ami.host>/conf/` |
|
||||
| `RECORDING_BASE_URL` | 环境变量覆盖录音地址 |
|
||||
|
||||
### 3.6 离寓抓拍 `leaveSnapshot`
|
||||
|
||||
| 配置 | 默认 | 说明 |
|
||||
| --- | --- | --- |
|
||||
| `enabled` | `true` | 是否保存抓拍 |
|
||||
| `requiredForDevice` | `false` | 设备未传抓拍是否失败(兼容旧设备) |
|
||||
| `retentionDays` | `7` | 保留天数 |
|
||||
| `cleanupCron` | `0 30 2 * * ?` | 每日清理 |
|
||||
| `rootDirectory` | 见 Profile | 抓拍保存目录 |
|
||||
| `urlPrefix` | `/yktgl/photo/leave-snapshots` | 访问前缀 |
|
||||
|
||||
### 3.7 静态资源与文件
|
||||
|
||||
| 配置 | 说明 |
|
||||
| --- | --- |
|
||||
| `spring.web.resources.static-locations` | `classpath:/static/` + 文件目录(Linux 常见 `/home/gygl/resouce/`) |
|
||||
| 人员照片 | `.../resouce/photo/{ryid}.png`(代码中写死,Windows 为 `C:\project_doc\resouce\photo\`) |
|
||||
| 离寓抓拍 | `.../resouce/photo/leave-snapshots/{gyid}/{eventId}.jpg` |
|
||||
|
||||
> 照片路径在 `RegistService` 中按 `serverOS` 硬编码,迁移环境时需同步修改代码或改为配置项。
|
||||
|
||||
## 4. 数据库升级
|
||||
|
||||
手工脚本位于 `yktgl/src/main/resources/db/`,按日期顺序执行:
|
||||
|
||||
1. `GY_SYN_JCXX_STATUS.sql`(首次部署)
|
||||
2. `manual/V20260921_01__leave_snapshot_evidence_kingbase.sql`
|
||||
3. `manual/V20260922_01__call_duty_notice_dedup_kingbase.sql`
|
||||
4. `manual/V20261008_01__syn_jcxx_write_time_kingbase.sql`
|
||||
5. `manual/V20261008_02__call_duty_match_lock_kingbase.sql`
|
||||
6. `manual/V20261009_01__jcxx_history_archive_kingbase.sql`
|
||||
7. `manual/V20261023_01__cash_request_state_kingbase.sql`
|
||||
8. `manual/V20261029_01__reconcile_tlxc_room_occupancy_preview.sql`(先预览)
|
||||
9. `manual/V20261029_01__reconcile_tlxc_room_occupancy.sql`(确认后执行)
|
||||
|
||||
注意:
|
||||
|
||||
- 脚本不会随应用启动自动执行。
|
||||
- 执行前备份;先跑 preview 核对影响行数。
|
||||
- 若数据库仍为 Oracle,需确认脚本语法是否兼容(现有 manual 脚本以 Kingbase 为主)。
|
||||
|
||||
## 5. 多公寓部署
|
||||
|
||||
两种方式:
|
||||
|
||||
1. **一套服务一个公寓**:通过 `baseConfig.gyid/gymc` 指定;设备 IP 仍参与解析。
|
||||
2. **一套服务多个公寓**:依赖 `GY_SB.ip` / `GY_GYZD.ip` 做 IP→公寓映射;同一 IP 命中多个公寓会直接拒绝。
|
||||
|
||||
部署检查:
|
||||
|
||||
- 每个公寓的设备 IP 必须唯一归属。
|
||||
- 反向代理必须透传真实客户端 IP(`X-Forwarded-For`),否则所有请求会被识别为代理 IP。
|
||||
- WebSocket 需允许 `Upgrade`/`Connection` 头,并适当延长超时。
|
||||
|
||||
## 6. 上线检查清单
|
||||
|
||||
- [ ] JDK 8、时区 `Asia/Shanghai`、服务器时间与 NTP 同步(叫乘精确到秒)。
|
||||
- [ ] Kingbase 可连,schema `gygl` 正确,升级脚本已执行。
|
||||
- [ ] Redis 可连,Session 能写入。
|
||||
- [ ] `baseConfig.gyid/gymc` 与当前公寓一致。
|
||||
- [ ] `synJcXxIp` 包含运安推送源 IP。
|
||||
- [ ] `devicePassword` 与设备端一致。
|
||||
- [ ] Asterisk AMI 可连,`Conf-01` 存在,值班台/房间分机可呼通。
|
||||
- [ ] 串口设备可打开(Linux 检查权限与设备名)。
|
||||
- [ ] 照片/抓拍目录存在且可写,静态资源映射正确。
|
||||
- [ ] 反向代理透传真实 IP,WebSocket 可升级。
|
||||
- [ ] 启动日志无 Mapper/Bean 初始化错误;`WakeupJobRecoveryRunner` 已恢复任务。
|
||||
- [ ] 用一个测试人员走通:入住 → 叫乘 → 应答 → 离寓 → 归档。
|
||||
|
||||
## 7. 运行期维护
|
||||
|
||||
| 事项 | 建议 |
|
||||
| --- | --- |
|
||||
| 日志 | 现有 `System.out` 与业务日志混杂,建议接入统一日志文件与轮转 |
|
||||
| 归档 | 每日 00:00 自动归档 7 天前离寓记录;数据量大时关注执行耗时 |
|
||||
| 抓拍清理 | 每日 02:30 清理过期抓拍;确认磁盘余量 |
|
||||
| 同步 | 运安每 5 分钟抓取;观察 `JWDATA_SYNC_LOG` 与同步状态 |
|
||||
| 备份 | 数据库 + 照片/抓拍目录 + 录音目录 |
|
||||
| 口令 | 尽快外置并轮换数据库/AMI/设备口令 |
|
||||
@@ -0,0 +1,94 @@
|
||||
# 09 迭代指引与风险清单
|
||||
|
||||
## 1. 技术债与风险
|
||||
|
||||
### P0:会直接影响构建/上线
|
||||
|
||||
| 项 | 现状 | 影响 | 建议 |
|
||||
| --- | --- | --- | --- |
|
||||
| Spring Boot 依赖版本错配 | `pom.xml` 在 Boot 2.6.13 父工程下显式声明 `spring-boot-starter-web:3.5.4`、`spring-boot-starter-data-redis:3.3.1` | 可能拉入 Spring 6 / Jakarta 依赖,与 `javax.servlet` 代码不兼容,导致编译/运行失败 | 删除显式版本,交给父工程管理;或统一升到 Boot 3 + Jakarta(大改造)。先跑一次 `mvn clean test` 确认基线 |
|
||||
| 明文口令与内部地址入库 | 各 `application-*.yml` 含数据库口令、AMI 口令、`devicePassword`、内网 IP | 已推送到远端,存在泄露风险 | 轮换口令;改用环境变量/配置中心;生产库最小权限 |
|
||||
| 无根级 `.gitignore` | 仓库根目录没有 `.gitignore`,仅有 `YktVue/.gitignore` | 易误提交构建产物、日志、数据转储 | 在仓库根补充 `.gitignore`(target、logs、*.log、node_modules、dist、本地配置) |
|
||||
| 构建/测试基线不明 | `target/` 为空,测试未运行,无 CI 配置 | 无法判断改动是否破坏现有功能 | 建立 CI:编译 + 单测 + 关键 SQL 校验 |
|
||||
|
||||
### P1:影响正确性与可维护性
|
||||
|
||||
| 项 | 现状 | 影响 | 建议 |
|
||||
| --- | --- | --- | --- |
|
||||
| `JcglService` 过大 | 约 4192 行,混合叫乘、房间、补助、交路、归档、设备指令 | 改动风险高、冲突多、难测试 | 按“叫乘执行 / 房间 / 卡务 / 交路匹配 / 归档”拆服务,先抽只读逻辑与纯函数 |
|
||||
| 交路 MERGE 停用 | `mergeSynJcXx` 因同 `id` 多司机被注释 | 快照与历史数据可能长期不一致 | 改为 `id + ryid` 唯一键后恢复,并加数据清理脚本 |
|
||||
| 远程同步为桩 | `/jcgl/getRemoteSynJcXx` 直接返回成功 | 调用方误以为已同步 | 恢复实现或明确返回“未启用” |
|
||||
| 部分定时任务停用 | `RechargeSchedule`、`JlSchedule`、`LogSchedule` 全部注释 | 自动补助、交路同步、日志清理不生效 | 明确替代方案;若不再需要则删除代码 |
|
||||
| 写接口用 `@RequestMapping` | 大量写操作接受 GET | 易被误触发、难做权限/审计 | 新接口强制 POST;存量逐步收敛 |
|
||||
| 异常被吞 | 大量 `catch` 返回 `Result.failure`,仅写日志 | 故障定位困难、事务边界不清 | 统一异常处理与错误码;关键路径保留堆栈 |
|
||||
| 日志不规范 | `System.out.println` 与业务日志混用 | 无法集中检索/轮转 | 统一 SLF4J + 文件轮转;敏感信息脱敏 |
|
||||
| 硬编码 | 公寓名“通辽南公寓/通辽南派班室”、照片路径、内网 IP、中心地址 | 多公寓/迁移环境需改代码 | 抽到配置或字典表 |
|
||||
| 交路匹配只覆盖单公寓 | `matchCallDutyUnderLock` 只处理 `baseConfig.gyid` 配置的公寓 | 一实例多公寓时,其他公寓不会自动匹配交路 | 明确部署形态;如需一实例多公寓,把 `gyid` 改为循环/列表并逐公寓加锁 |
|
||||
| 房态语义不一致 | `selectRoomRecommendations` 与前端允许 `3`(待清扫)、`6`(保洁中);`validateRoomForCheckIn` 也允许 `6` | 保洁中的房间可能被入住 | 确认业务规则;若不允许,收紧 SQL 与校验 |
|
||||
| 备份文件/旧构建 | `RoomLook copy.vue`、`JcXx.vue.bak_mojibake`、`resources/static` 下旧前端与 `.gz` | 干扰阅读、增大仓库 | 清理或移入 `legacy/` |
|
||||
|
||||
### P2:体验与稳健性
|
||||
|
||||
| 项 | 说明 |
|
||||
| --- | --- |
|
||||
| `processCallDuty` 空值判断顺序 | `ryid.equals("") || ryid == null` 在 `ryid=null` 时会先 NPE;应改为 `StringUtils.isBlank` |
|
||||
| `h1.concat(...)` 结果未赋值 | `ByxxResourceService` 中拼接公寓编码无效,`h1` 实际未追加 `housecode` |
|
||||
| `syncJlXX` 返回 `null` | `/jcgl/ya/list` 永远返回空数据,容易误判 |
|
||||
| `personData` 空数组 | `jsonArray.getJSONObject(0)` 未判空,上游无数据时异常 |
|
||||
| 时间字符串 | 全链路用字符串 + `TO_DATE`,格式/时区问题只能在运行期暴露 |
|
||||
| IP→公寓 | 依赖真实客户端 IP;反向代理未透传时会识别错误 |
|
||||
| 设备照片/抓拍 | Base64 体积大,需关注请求体大小、内存与磁盘 |
|
||||
| 测试接口暴露 | `/test/*`、`/jcgl/yatest`、`/jcgl/driver/{id}` 可访问外部系统,生产应限制 |
|
||||
|
||||
## 2. 改动落点速查
|
||||
|
||||
| 需求 | 先看 | 可能要改 |
|
||||
| --- | --- | --- |
|
||||
| 调整叫乘/复叫/报警时间 | `GY_SJGZ`、`modifyJcXxBySynJcXx`、`populateJcXxByJlXx` | `JcglService`、`WakeUpJob`、`SchedulerManager` |
|
||||
| 改叫乘提醒节点 | `JcglService.notifyMissedCallWarnings`、`selectMissedCallWarnings` | `JcSchedule`、SQL |
|
||||
| 改叫乘语音内容 | `AsteriskCallUtil.makeWakeup` | TTS 文案、格式化函数 |
|
||||
| 改房间状态规则 | `getRoomStatus`、`validateRoomForCheckIn`、`modifyRoomStatus` | `JcglRoomMapper.xml`、前端 `Room.vue` |
|
||||
| 改房间推荐 | `selectRoomRecommendations` | 推荐 SQL、`getRoomRecommendations` |
|
||||
| 新增设备类型 | `heartBeat`、`GY_SB`、`GY_SB_XT` | 新建 `xxxDevice` 包、心跳控制器 |
|
||||
| 改设备指令 | `HeartBeatService.addDeviceInstructionInfo*` | 各业务调用点 |
|
||||
| 改入住补助 | `getAllowanceInfo`、`getTrainAllowanceInfo`、`changeRemainder` | `GY_YKT_*` 表、节假日规则 |
|
||||
| 改充值/消费 | `RechargeService`、`PayService`、`VendPayDeviceService` | 余额与明细同事务 |
|
||||
| 改交路维护 | `JlGlService`、`GYGL_JLXX` | 上传模板、同步接口 |
|
||||
| 改运安同步 | `ByxxResourceService`、`SynDataSchedule` | WSDL、字段映射、锁 |
|
||||
| 改匹配规则 | `matchCallDutyUnderLock` | 工号匹配、时间重算、任务重建 |
|
||||
| 改离寓/抓拍 | `processCheckOutRegistration`、`leaveSnapshot.*` | `GYGL_LY_EVENT`、文件目录 |
|
||||
| 新增报表 | `xxtj` / `excel` | 对应 Mapper XML |
|
||||
| 改权限/菜单 | `display`、`GL_*` | 登录、RBAC、菜单 |
|
||||
| 改公寓识别 | `ZdwhService.getUniqueGyByIp` | `GY_SB`、`GY_GYZD`、代理配置 |
|
||||
|
||||
## 3. 建议的迭代顺序
|
||||
|
||||
1. **建立基线**:修复 pom 版本错配,确保能编译;跑通现有测试;加 CI。
|
||||
2. **安全整改**:口令外置与轮换;生产关闭测试接口;补根 `.gitignore`;清理备份文件。
|
||||
3. **稳定性**:统一日志与异常;关键路径加监控(叫乘任务创建数、AMI 连接、同步状态、快照积压)。
|
||||
4. **结构治理**:拆分 `JcglService`;把硬编码公寓/路径/地址配置化;收敛写接口 HTTP 方法。
|
||||
5. **业务增强**:恢复并测试 `mergeSynJcXx`、远程同步;完善多公寓参数化;补叫乘/入住/离寓的集成测试。
|
||||
6. **数据治理**:归档与索引优化;房间占用对账;历史数据清理。
|
||||
|
||||
## 4. 待确认问题
|
||||
|
||||
建议与业务/现场逐条确认,确认后回写本文档:
|
||||
|
||||
1. **保洁中(`room_status=6`)房间是否允许入住?** 当前推荐 SQL、入住校验、前端都允许,但 `modifyRoomStatus` 又禁止修改保洁中房间。
|
||||
2. **待清扫(`3`)房间是否应出现在推荐列表?** 当前会出现,可能影响值班员选房效率。
|
||||
3. **便乘/驻在是否完全不叫乘?** 当前 `jllx=1` 且跳过任务;是否符合现场?
|
||||
4. **运安下发的 `jcsj` 是否彻底弃用?** 当前仅保留读取,最终按本地规则重算。
|
||||
5. **远程同步是否还需要?** `getRemoteSynJcXx` 目前是桩。
|
||||
6. **多公寓部署形态**:一公寓一实例,还是一实例多公寓?影响 IP 映射、同步任务与锁。
|
||||
7. **刷脸抓拍是否强制?** `requiredForDevice=false` 目前兼容旧设备,何时切为 `true`?
|
||||
8. **Oracle Profile(byq/cc/dl/pj)是否继续维护?** 若迁移 Kingbase,需要同步 SQL 兼容性。
|
||||
9. **叫乘任务恢复范围**:应用重启后恢复未来任务,是否也要补偿“重启期间已错过”的任务?当前只恢复未来任务,错过由提醒任务兜底。
|
||||
10. **归档保留策略**:`GY_JCXX_HIS` 保留多久?是否需要冷备/清理?
|
||||
|
||||
## 5. 文档维护约定
|
||||
|
||||
- 本文档以代码为准;接口、表、状态码变更时同步更新对应章节。
|
||||
- 新增模块时,在 [03-业务模块地图.md](03-业务模块地图.md) 增加一行,并在 [06-接口清单.md](06-接口清单.md) 补接口。
|
||||
- 新增表/字段时,在 [05-数据模型.md](05-数据模型.md) 补字段与状态字典。
|
||||
- 新增外部依赖/定时任务时,在 [07-外部集成与定时任务.md](07-外部集成与定时任务.md) 补时序与排障点。
|
||||
- 每次迭代结束,把已解决的风险从本清单移除,并在提交说明中引用相关文档章节。
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,451 @@
|
||||
# 11 既有数据库结构分析(KingbaseES)
|
||||
|
||||
> 文档性质:现状实证分析(Analysis Only)。本文所有结论来自对 `db/gygl.sql` 的结构解析与对已导入实例的只读查询(全部为 `SELECT`),**不含**数据库变更、DDL 执行、配置修改。改造建议仅为设计输入,需评审后另行排期。
|
||||
|
||||
## 0. 文档说明
|
||||
|
||||
表 0-1 采集信息
|
||||
|
||||
| 项 | 内容 |
|
||||
| --- | --- |
|
||||
| 数据来源 | `db/gygl.sql`(Navicat 导出,源库 `10.33.165.41:54321/gygl`,导出时间 2026-11-07 14:34) |
|
||||
| 校验实例 | 本机 KingbaseES 导入库,`jdbc:kingbase8://127.0.0.1:54321/gygl` |
|
||||
| 采集方式 | JDBC 只读查询(information_schema / pg_catalog / pg_stat_user_tables)+ dump 文本解析 |
|
||||
| 库与 schema | 数据库 `gygl`,业务 schema `gygl`,表 owner 均为 `system` |
|
||||
| 规模 | 40 张表、524 个字段、schema 总容量 117 MB、495,772 行数据 |
|
||||
| 关联文档 | `05-数据模型.md`(表语义与状态码)、`09-迭代指引与风险清单.md`(技术债)、`10-架构优化方案-三端拆分.md`(目标归属) |
|
||||
|
||||
> 样本口径提醒:本机实例的数据是导出快照,业务数据只覆盖 2 个公寓(见 3.9)。行数、分布用于判断**结构缺陷**,不作为生产容量基线;容量测算需在生产库重跑附录 A 的 SQL。
|
||||
|
||||
## 1. 实例与库级特征
|
||||
|
||||
表 1-1 库级参数(实测)
|
||||
|
||||
| 参数 | 实测值 | 结构影响 |
|
||||
| --- | --- | --- |
|
||||
| 版本 | `KingbaseES V009R001C010`(`server_version` 报 12.1) | 兼容 PG 12 协议;JDBC 9.0.0 驱动可直连 |
|
||||
| 兼容模式 | `database_mode = oracle` | 出现 `sys.date`、`sys_guid()`、`sysdate()`、`dual` 表等 Oracle 兼容对象 |
|
||||
| 空串语义 | `ora_input_emptystr_isnull = on` | **写入 `""` 存成 `NULL`**,读取恒为 `NULL`;见 3.4 |
|
||||
| 字符集 | `UTF8` | 中文数据无乱码风险 |
|
||||
| MAC 扩展 | schema `sysmac`(8 张表,248 kB) | 金仓安全版强制访问控制扩展;上线前需确认是否启用策略 |
|
||||
| 对象种类 | 视图 0、触发器 0、函数 0、分区表 0 | **业务逻辑全部在 Java 侧**,库内无任何约束性逻辑 |
|
||||
|
||||
表 1-2 schema 分布
|
||||
|
||||
| schema | 表数 | 容量 | 说明 |
|
||||
| --- | --- | --- | --- |
|
||||
| `gygl` | 40 | 117 MB | 全部业务表 |
|
||||
| `sysmac` | 8 | 248 kB | 金仓安全版 MAC 元数据(空表) |
|
||||
| `sys_hm` | 3 | 128 kB | 金仓自带 |
|
||||
| `sys` | 1 | 40 kB | 金仓自带 |
|
||||
|
||||
结论:**这是一个"纯存储库"**——没有主键、没有索引、没有外键、没有触发器、没有存储过程。数据完整性、唯一性、顺序性、并发控制全部由应用代码承担,这也是下一章几乎所有缺陷的共同根因。
|
||||
|
||||
## 2. 表清单与规模
|
||||
|
||||
图 2-1 数据域与表簇
|
||||
|
||||
```mermaid
|
||||
graph LR
|
||||
A[公寓主数据<br/>gy_jbxx / gy_gyzd / gy_sjgz / gy_jcsj / gy_jrb] --> B[房间<br/>gy_rooms]
|
||||
B --> C[叫乘执行<br/>gy_jcxx / gy_jcxx_his<br/>gy_bjxx / gy_bjcstj]
|
||||
D[交路同步<br/>gy_syn_jcxx / _his / _status] --> C
|
||||
E[人员与卡<br/>gy_ykt_ry / gy_ykt_ry_zp] --> C
|
||||
F[账务<br/>gy_ykt_remainder / _allowance / _consume / _btbj / _btjs] --> E
|
||||
G[设备<br/>gy_sb / gy_device / gy_sb_xt / gy_sb_zl / _his] --> C
|
||||
H[权限<br/>gl_yh / gl_js / gl_qx / gl_cd / gl_yh_js / gl_js_qx]
|
||||
I[日志<br/>gy_logs / gy_operation_log]
|
||||
```
|
||||
|
||||
表 2-1 业务表清单(按数据域)
|
||||
|
||||
| 表 | 行数 | 大小 | 列数 | 含 gyid | 现职责 |
|
||||
| --- | --- | --- | --- | --- | --- |
|
||||
| `gy_jbxx` | 9 | 16 kB | 26 | ✔ | 公寓基础信息(面积、床位、负责人、热水/燃气方式) |
|
||||
| `gy_gyzd` | 37 | 16 kB | 8 | ✔ | 公寓字典(网关地址、机器号、IP) |
|
||||
| `gy_gzzd` | 17 | 16 kB | 3 | — | 工种字典 + 客货类型 |
|
||||
| `gy_sjgz` | 17 | 16 kB | 10 | ✔ | 时间规则(入住/离寓/叫乘基准) |
|
||||
| `gy_jcsj` | 7 | 16 kB | 3 | — | 叫乘时刻表(`cb/kssj/jssj`,均为字符) |
|
||||
| `gy_jrb` | 2 | 16 kB | 6 | — | 节假日 |
|
||||
| `gy_rooms` | 197 | 64 kB | 22 | ✔ | 房间基线 + 房态 + 分机 + 报警起点(三类语义混装) |
|
||||
| `gy_jcxx` | 3,541 | 1.5 MB | **70** | ✔ | 叫乘执行主表(上帝表,见 3.5) |
|
||||
| `gy_jcxx_his` | 32,505 | 12 MB | **70** | ✔ | 叫乘归档表 |
|
||||
| `gy_bjxx` | 2,490 | 304 kB | 7 | ✔ | 报警记录(开始/结束时间) |
|
||||
| `gy_bjcstj` | 0 | 8 kB | 12 | — | 补叫统计(**未使用**) |
|
||||
| `gy_jdqkhz` | 1 | 16 kB | 9 | ✔ | 房间年度/月度汇总(近似废表) |
|
||||
| `gy_rtjb` | 0 | 8 kB | 7 | ✔ | 日报(**未使用**) |
|
||||
| `gy_call_duty_match_lock` | 38 | 8 kB | 1 | ✔ | 单列行锁表,用 `gyid` 做悲观锁 |
|
||||
| `gy_syn_jcxx` | 1,139 | 384 kB | 15 | — | 运安交路快照 |
|
||||
| `gy_syn_jcxx_his` | 2,291 | 376 kB | 12 | — | 交路归档 |
|
||||
| `gy_syn_jcxx_status` | 1 | 8 kB | 2 | — | 同步状态/水位(单行开关) |
|
||||
| `gy_ykt_ry` | 1,349 | 336 kB | 27 | — | 人员与卡主数据 |
|
||||
| `gy_ykt_ry_zp` | 100 | **27 MB** | 2 | — | 照片(BLOB 存库) |
|
||||
| `gy_ykt_remainder` | 1,253 | 224 kB | 12 | — | 余额(补助/现金/消费/补助总额) |
|
||||
| `gy_ykt_allowance` | 34,182 | 4.2 MB | 11 | ✔ | 补助发放流水 |
|
||||
| `gy_ykt_consume` | 35 | 16 kB | 19 | ✔ | 消费流水 |
|
||||
| `gy_ykt_btbj` | 5 | 16 kB | 8 | ✔ | 补助标准(早/正/节假日) |
|
||||
| `gy_ykt_btjs` | 5 | 16 kB | 7 | — | 补助计算规则 |
|
||||
| `gy_sb` | 148 | 48 kB | 8 | ✔ | 设备台账 v1(`devicecode/lx`) |
|
||||
| `gy_device` | 92 | 48 kB | 18 | ✔ | 设备台账 v2(`device_code/device_type`,RuoYi 风格) |
|
||||
| `gy_sb_xt` | 246 | 64 kB | 9 | ✔ | 设备心跳与版本状态 |
|
||||
| `gy_sb_zl` | **129,665** | 11 MB | 6 | — | 设备指令队列(**与历史同表**) |
|
||||
| `gy_sb_zl_his` | 0 | 8 kB | 6 | — | 指令历史(**从未使用**) |
|
||||
| `gy_logs` | **285,914** | **56 MB** | 7 | ✔ | 运行日志(无清理策略) |
|
||||
| `gy_operation_log` | 0 | 8 kB | 6 | — | 操作审计(**从未写入**) |
|
||||
| `gy_file` | 1 | 16 kB | 6 | — | 文件登记 |
|
||||
|
||||
表 2-2 支撑表清单
|
||||
|
||||
| 表 | 行数 | 列数 | 说明 |
|
||||
| --- | --- | --- | --- |
|
||||
| `gl_yh` / `gl_js` / `gl_qx` / `gl_cd` / `gl_yh_js` / `gl_js_qx` | 17 / 4 / 48 / 45 / 16 / 58 | 18 / 6 / 9 / 9 / 2 / 2 | 自研 RBAC(用户/角色/权限/菜单及关联) |
|
||||
| `gen_table` / `gen_table_column` | 18 / 279 | 21 / 22 | **RuoYi 代码生成器元数据残留** |
|
||||
|
||||
容量结构:`gy_logs` 占 48%、`gy_ykt_ry_zp` 占 23%、`gy_jcxx_his` 占 10%、`gy_sb_zl` 占 9%——四张表吃掉全库 90%。其中两张(日志、指令)是纯追加、无清理的表。
|
||||
|
||||
## 3. 结构缺陷诊断
|
||||
|
||||
表 3-1 约束与索引现状(全库实测)
|
||||
|
||||
| 指标 | 数量 | 说明 |
|
||||
| --- | --- | --- |
|
||||
| 主键 | **0** | 40 张表无一有主键 |
|
||||
| 唯一约束 | **0** | 唯一性完全依赖应用层判断 |
|
||||
| 外键 | **0** | 关联完整性靠代码,无 DB 兜底 |
|
||||
| 索引 | **0** | 含隐式主键索引在内,`pg_indexes` 计数为 0 |
|
||||
| 序列 | 64 | 仅 4 个被列默认值引用,其余 60 个为**孤儿序列** |
|
||||
| 表注释 | 3/40 | 仅 `gen_table`、`gen_table_column`、`gy_device` 有 |
|
||||
| 列注释 | 60/524 | 其中仅 5 条属于业务表(`gy_jcxx` 3 条、`gy_syn_jcxx` 1 条、`gy_gzzd` 1 条) |
|
||||
| 非空约束 | 5 处 | 仅 `gy_ykt_ry.ryid`、`gy_call_duty_match_lock.gyid`、`gy_syn_jcxx_status.id/sync_status`、`gy_device.device_code` |
|
||||
|
||||
### 3.1 无主键、无索引的连锁后果
|
||||
|
||||
1. **每次按 `devicecode` / `ryid` / `jcid` 查询都是全表扫描**。`gy_sb_zl` 12.9 万行、`gy_logs` 28.6 万行,心跳与指令链路是高频路径,随运行时间线性劣化。
|
||||
2. **重复数据无法阻断**。实测 `gy_jcxx` 3,541 行中 `jcid` 只有 3,540 个不同值——已存在 1 组重复 `jcid`,且没有任何机制能阻止再次发生。
|
||||
3. **更新语义不可靠**。`update ... where jcid=?` 命中多行时,MyBatis 返回的影响行数与业务预期不符,容易被误判为"成功"。
|
||||
4. **分页与排序无稳定基准**。无主键导致同一秒内多行顺序不确定,翻页可能重复或漏行。
|
||||
5. **归档与对账无法定位单行**。`gy_jcxx` → `gy_jcxx_his` 的搬迁只能按业务键或不带条件批量搬,出错后难以精确回滚。
|
||||
|
||||
### 3.2 类型体系混乱
|
||||
|
||||
表 3-2 字段类型分布(524 列)
|
||||
|
||||
| 类型 | 列数 | 占比 | 风险 |
|
||||
| --- | --- | --- | --- |
|
||||
| `varcharbyte`(金仓特有) | **276** | 53% | **全部未指定长度**(`character_maximum_length` 为 NULL),任何超长/脏数据都能写入 |
|
||||
| `numeric` | 82 | 16% | 未指定精度标度,金额列与计数列同型,无精度约束 |
|
||||
| `varchar` | 78 | 15% | 有长度,但风格与 `varcharbyte` 混用 |
|
||||
| `timestamp` | 68 | 13% | 含 `Oracle DATE`(`sys.date`)映射,秒级精度 |
|
||||
| `bpchar` | 11 | 2% | 定长字符(`'0'/'1'` 标记) |
|
||||
| `text` / `int8` / `int4` / `bytea` | 9 | 2% | LOB(`nclob`/`blob`)、自增主键 |
|
||||
|
||||
**同一字段名在不同表里类型不一致,共 12 组**:
|
||||
|
||||
| 字段 | 类型变体 | 涉及表数 | 直接后果 |
|
||||
| --- | --- | --- | --- |
|
||||
| `id` | `numeric` / `varchar` / `varcharbyte` | 14 | 跨表 `join`、`union` 需隐式转换;索引即便补上也难生效 |
|
||||
| `deleted` | `numeric` / `varcharbyte` | 4 | 逻辑删除写法不统一(`=0` 与 `='0'` 混用) |
|
||||
| `gyid` | `varchar(64)` / `varcharbyte` | 17 | 长度与比较语义不一致,`gyid='TLXC'` 在不同表可能命中/不命中 |
|
||||
| `kssj` / `jssj` | `timestamp` / `varcharbyte` | 3 / 3 | 同一含义的时间一半能比较、一半是字符串 |
|
||||
| `sort` | `int4` / `numeric` | 4 | — |
|
||||
| `lx` / `cb` / `name` / `dwmc` / `room_no` / `table_id` | 各 2 种 | — | — |
|
||||
|
||||
### 3.3 时间字段三种存法并存
|
||||
|
||||
| 存法 | 示例 | 问题 |
|
||||
| --- | --- | --- |
|
||||
| `timestamp`(含 `sys.date`) | `kcsj`、`jcsj`、`fjsj`、`sjrysj`、`scbzsj` | 正常,但秒级精度、无时区字段 |
|
||||
| **字符串** `varcharbyte` | `gy_jcxx.yrysj`(预期入住时间)、`gy_jcxx.ddsj`、`gy_jcsj.kssj/jssj`、`gy_jbxx.zrsj/sjsj` | 无法做范围比较、无法排序、格式靠约定;共 13 处 |
|
||||
| 冗余列并存 | `jcsj` 与 `jcsj_s`、`fjsj` 与 `fjsj_s`、`jcbjsj` 与 `jcbjsj_s` | 同一时刻两列,靠代码保证同步,无约束 |
|
||||
|
||||
### 3.4 Oracle 空串语义(高危)
|
||||
|
||||
实例参数 `ora_input_emptystr_isnull = on`,实测验证:
|
||||
|
||||
- `select count(*) from gy_jcxx where bz = ''` → **0**
|
||||
- `select count(*) from gy_jcxx where bz is null` → **3541**(全表)
|
||||
|
||||
含义:业务代码写 `""` 入库后变成 `NULL`;反过来读出的 `NULL` 在 Java 侧可能是 `null` 也可能是 `""`,取决于取值方式。表现为:前端显示`undefined`、`StringUtils.isBlank` 与 `!= null` 判断在不同层得到不同结论、`where col <> ''` 恒不命中。三端拆分后跨库/跨端传输时这个语义差异会被放大。
|
||||
|
||||
### 3.5 `gy_jcxx` 上帝表
|
||||
|
||||
单表 **70 列**,同时承载 7 类语义:
|
||||
|
||||
| 语义组 | 代表列 |
|
||||
| --- | --- |
|
||||
| 车次与交路 | `jch`、`cc`、`cdw`、`kcsj`、`jlid`、`cclx`、`qd`、`ddcc`、`depotid` |
|
||||
| 叫乘状态机 | `ryzt`、`jcsj`、`fjsj`、`jcbjsj`、`sjrysj`、`lybjsj`、`scbzsj` |
|
||||
| 入住/离寓 | `yrysj`、`sjrysj`、`ylysj`、`sjlysj`、`flag_send`、`tbsj_gytofcd`、`tbsj_fcdtogy` |
|
||||
| 补助与餐饮 | `cblx`、`cbje`、`sfffcb`、`dayallowance`、`is_meal3`、`isoverday` |
|
||||
| 服务评分 | `kffwpf`、`stfwpf`、`jcfwpf`、`zm` |
|
||||
| 报警与提醒去重 | `is_yaxx`、`is_jcbj`、`is_lybj`、`route_notice_key`、`call_timeout_notice_key`、`missed_call_notice_key` |
|
||||
| 设备与录音 | `finish_sb`、`recordfile`、`hjxysj`、`fjhold` |
|
||||
|
||||
后 8 列(`business_id`、`ly_type`、`ly_event_id`、`ly_remark`、`ly_snapshot_url`、`route_notice_key`、`call_timeout_notice_key`、`missed_call_notice_key`)明显是后期追加,且 `ly_*` 属于"离寓事件"子域、`*_notice_key` 属于"通知去重"子域——表已演化为多子域的物理合并点。`gy_jcxx_his` 同步复制了这 70 列(但 `yappsj` 类型从 `sys.date` 漂移为 `timestamp`),归档表与主表已出现结构漂移。
|
||||
|
||||
### 3.6 设备台账双轨
|
||||
|
||||
表 3-4 两套设备表
|
||||
|
||||
| 项 | `gy_sb`(v1) | `gy_device`(v2) |
|
||||
| --- | --- | --- |
|
||||
| 行数 | 148 | 92 |
|
||||
| 命名风格 | 全小写无下划线:`devicecode`/`lx`/`fjh` | 下划线 + RuoYi 审计列:`device_code`/`device_type`/`create_by` |
|
||||
| 类型编码 | `lx`:3=134、1=4、5=3、6=3、2=2、空=2 | `device_type`:3=80、1=3、5=3、6=3、99=2、2=1 |
|
||||
| 附加字段 | `gxsj`、`gymc` | `online_status`、`last_heartbeat`、`firmware_version`、`del_flag` |
|
||||
| 关系 | — | `device_code` 与 `gy_sb.devicecode` **交集 92 行 = 完全子集** |
|
||||
|
||||
即:v2 的 92 个 `device_code` **全部能在 v1 中找到**(交集恰为 92),而 v1 仍有 148 行未被 v2 覆盖。两张表**同时在线、同时被读**,无外键、无同步机制。设备在线率、版本、故障统计存在两个数据源,"当前是否在线"取决于读哪张表。
|
||||
|
||||
### 3.7 指令队列与历史同表,且积压
|
||||
|
||||
表 3-5 `gy_sb_zl` 实测分布
|
||||
|
||||
| `deleted` | 行数 | 涉及设备数 | 时间范围 |
|
||||
| --- | --- | --- | --- |
|
||||
| `0`(未消费/未删除) | 72,088 | 96 | 2025-08-26 ~ 2026-11-07 |
|
||||
| `1`(已消费) | 57,577 | 172 | 2025-08-26 ~ 2026-11-07 |
|
||||
|
||||
其中 **`deleted='0'` 且生成时间超过 1 天的记录有 71,723 条**——占未消费量的 99.5%。这说明:"取最新一条 → 置 `deleted=1`"的消费方式(见 `HeartBeatService`/设备服务)在多数情况下没有闭环:要么设备从未取走,要么取了没回写成功。同时该表 12.9 万行、零索引,每次取指令都是全表扫描 + 排序。
|
||||
|
||||
### 3.8 日志表无清理
|
||||
|
||||
`gy_logs` 28.6 万行 / 56 MB,`eventtime` 跨度 2025-05 ~ 2026-11。按 `lx` 分布:
|
||||
|
||||
| `lx` | 行数 |
|
||||
| --- | --- |
|
||||
| 运安叫乘同步汇总 | 238,386 |
|
||||
| 刷脸离寓事件号缺失 / 请求 / 完成 / 抓拍缺失 | 7,655 / 7,655 / 7,649 / 7,649 |
|
||||
| 运安叫乘同步跳过 | 4,472 |
|
||||
| 运安定时抓取完成 | 3,470 |
|
||||
| 自动叫乘任务未创建 | 2,369 |
|
||||
| 叫乘时间延后 | 2,258 |
|
||||
| 注册机心跳异常 | 1,797 |
|
||||
| 超时未叫乘提醒 | 857 |
|
||||
| 其余(匹配异常、登录、启动恢复等) | ~1,400 |
|
||||
|
||||
按月看,"运安叫乘同步汇总"稳定在 **每月约 4.4 万条**(2026-05 ~ 09 均在 40,980 ~ 44,640 之间)。这是"每 5 分钟 × 每公寓写一条汇总日志"的直接结果——**一条业务无异常的流水日志,占了全库 87% 的日志行数**。该表无归档、无分区、无索引,年增约 53 万行。
|
||||
|
||||
### 3.9 主数据与租户键(`gyid`)不一致
|
||||
|
||||
17 张表带 `gyid`,但各表的取值域互不匹配:
|
||||
|
||||
| 观测点 | 实测值 |
|
||||
| --- | --- |
|
||||
| `gy_jbxx`(公寓基础信息) | **9** 个:SYXC、SYNDC、SJTXC、SYXXC、DDXC、DSQXC、BYQXC、DLXC、DLBDC |
|
||||
| `gy_call_duty_match_lock`(行锁表) | **37** 个业务 gyid + 1 个伪 gyid `__SYNC_JCXX__` |
|
||||
| `gy_rooms`(房间) | **6** 个:TLXC 102、THXC 56、PJXC 35、TLNXC 2、CCXDC 1、**空 1** |
|
||||
| `gy_jcxx`(叫乘) | **2** 个:THXC 2,110、TLXC 1,431 |
|
||||
| `gy_sb.lx` 为空 / `gy_rooms.gyid` 为空 | 各存在 1~2 行 |
|
||||
|
||||
三个结论:
|
||||
1. **主数据严重缺失**:系统实际服务的 gyid 至少 37 个,但只有 9 个在 `gy_jbxx` 有基础信息,31 个公寓缺面积/床位/负责人/时间规则来源。
|
||||
2. **租户键可空**:`gy_rooms` 有 1 行 `gyid` 为 `NULL`(很可能是代码写入 `""` 后被 Oracle 空串语义转成 `NULL`),这类行在按租户过滤时会被全局漏掉或全局命中。
|
||||
3. **行锁表用 `gyid` 当锁键**并塞入 `__SYNC_JCXX__` 这种伪租户,说明"公寓"与"同步任务"两个概念共用了一张锁表——三端拆分后必须把锁的粒度从"字符串键"改为"业务对象 + 版本"。
|
||||
|
||||
> 样本库只覆盖 THXC / TLXC 两个公寓的叫乘数据,属于导出时的数据裁剪(或该公寓数据被迁移过),不代表生产分布;但 `gyid` 的**取值域不一致**是结构性问题,与数据量无关。
|
||||
|
||||
### 3.10 RuoYi 残留与孤儿序列
|
||||
|
||||
- `gen_table`(18 行)、`gen_table_column`(279 行)是 RuoYi 代码生成器的元数据表,业务上完全不用,却占据 40 张表中的 2 张。
|
||||
- 64 个序列中只有 4 个被列默认值引用:`gen_table_table_id_seq`、`gen_table_column_column_id_seq`、`gy_device_device_id_seq`、`seq_gy_allowance`。其余 60 个指向**已不存在的表**:`sys_user_*`、`sys_role_*`、`sys_menu_*`、`sys_dept_*`、`sys_job_*`、`t_oa_*`、`t_role_*`、`ykt_account_id_seq`、`ykt_consume_flow_id_seq`、`gygl_consumer_terminal_device_id_seq` 等。
|
||||
|
||||
这组序列是"库曾经跑过一版 RuoYi/其他业务系统、后来表被删但序列没删"的直接证据。对三端拆分的意义:**新公寓端选 RuoYi 并不是引入新范式,而是回到这条被中断过的路线上**,因此必须明确"沿用还是重建"权限表(现状 `gl_*` 是自研 RBAC,与 RuoYi `sys_*` 完全不同构)。
|
||||
|
||||
### 3.11 照片以 BLOB 入库
|
||||
|
||||
`gy_ykt_ry_zp`:100 行 / 27 MB / 平均 281.3 KB / 最大 547,778 字节,列类型 `blob`(`bytea`)。同时 `gy_ykt_ry.photourl` 又存了一份路径,代码里还有按 `serverOS` 硬编码的文件目录(`C:\project_doc\resouce\photo\` 与 `/home/gygl/resouce/photo/`)。**同一张照片有"库内 BLOB + 本地磁盘路径"两条真相**,且备份策略完全不同(逻辑备份含 BLOB,磁盘目录不在备份范围)。
|
||||
|
||||
### 3.12 审计与统计表空置
|
||||
|
||||
`gy_operation_log`(操作审计)0 行、`gy_bjcstj`(补叫统计)0 行、`gy_rtjb`(日报)0 行、`gy_sb_zl_his`(指令历史)0 行。四张表有结构无数据——**设计了但没有接线**。其中操作审计的缺失,与"值班员可改叫乘状态但无留痕"的风险直接相关。
|
||||
|
||||
## 4. 数据质量实证
|
||||
|
||||
表 4-1 抽样核对结果
|
||||
|
||||
| 检查项 | 结果 | 判读 |
|
||||
| --- | --- | --- |
|
||||
| `gy_jcxx` 主键候选 `jcid` | 3,541 行 / 3,540 个不同值 | 存在 1 组重复,无约束可阻断 |
|
||||
| `gy_jcxx.kcsj` 为空 | 367 / 3,541(10.4%) | 开车时间缺失仍可入库,下游按时间排序/提醒会漏 |
|
||||
| `gy_jcxx.ryzt` 分布 | 3=2,373、0=582、5=225、4=171、2=134、1=56 | `-1` 未出现;状态分布偏向"已完成/在寓",缺失败态样本 |
|
||||
| `gy_jcxx.jllx` 分布 | 1=2,224、0=1,317 | 两值区分,但字段无注释、无字典表 |
|
||||
| `gy_ykt_remainder` | 1,253 行 / 1,253 个 `ryid`,无重复 | 当前无重复,但无唯一约束保障 |
|
||||
| `gy_rooms` 房态分布 | 3=68、1=58、4=32、2=32、5=7 | `room_status=6` 从未出现(字典有 6 值,实际只用 5 值) |
|
||||
| `gy_sb_xt` 心跳 | 246 行,`updatestate` 全为 0 | 更新状态位从未被置位,与 3.7 的指令积压互相印证 |
|
||||
| `gy_sb_zl.id` / `gy_logs.id` | 12.9 万 / 28.6 万,全部唯一 | 应用层 UUID 生成正确,纯靠代码保证 |
|
||||
|
||||
账务三表口径无法自洽(实测合计):
|
||||
|
||||
| 表 | 口径 | 合计 |
|
||||
| --- | --- | --- |
|
||||
| `gy_ykt_allowance` | 补助发放流水 | 552,295.00 元 |
|
||||
| `gy_ykt_consume` | 消费流水 | 265.10 元 |
|
||||
| `gy_ykt_remainder` | 当前余额(补助/现金/消费/补助总额) | 补助余额 1,228.00 元,现金余额 0.00 元 |
|
||||
|
||||
补助累计 55.2 万元的规模,与仅 265 元的消费流水、1,228 元的当前余额之间,**缺少任何可对账的中间口径**(无期初、无结转、无冲正、无对账批次)。这不能简单判定为"数据错误",但可以确定:**当前结构下无法证明账是对的**。
|
||||
|
||||
## 5. 表归属矩阵(对接文档 10 第 5 章)
|
||||
|
||||
表 5-1 40 张表的目标归属与改造动作
|
||||
|
||||
| 表 | 行数 | 目标端 | 改造动作 |
|
||||
| --- | --- | --- | --- |
|
||||
| `gy_jbxx` | 9 | 平台 | 升为公寓主数据,补全 37 个 gyid,版本化下发 |
|
||||
| `gy_gyzd` | 37 | 平台 | 主数据(网关/机器号/IP),下发只读 |
|
||||
| `gy_gzzd` | 17 | 平台 | 主数据(工种/客货类型) |
|
||||
| `gy_sjgz` | 17 | 平台 | 时间规则收敛为平台唯一口径,下发 |
|
||||
| `gy_jcsj` | 7 | 平台 | 计划数据 |
|
||||
| `gy_jrb` | 2 | 平台 | 主数据 |
|
||||
| `gy_rooms` | 197 | 平台 + 公寓 + 值班 | **拆三份**:房间基线(平台)/ 房态(公寓)/ 分机与报警起点(公寓) |
|
||||
| `gy_jcxx` | 3,541 | 公寓 | **拆表**:叫乘任务 / 入住离寓 / 通知去重键,见 6.4 |
|
||||
| `gy_jcxx_his` | 32,505 | 公寓 + 归档 | 按月分区;修正与主表的类型漂移 |
|
||||
| `gy_bjxx` | 2,490 | 公寓 | 保留,补主键与 `gyid+时间` 索引 |
|
||||
| `gy_bjcstj` | 0 | — | 退役(无数据无代码写入) |
|
||||
| `gy_jdqkhz` | 1 | 平台 | 转报表视图或退役 |
|
||||
| `gy_rtjb` | 0 | — | 退役 |
|
||||
| `gy_call_duty_match_lock` | 38 | 公寓 | 换为行级锁表(含 `locked_at`/`owner`)或 DB advisory lock |
|
||||
| `gy_syn_jcxx` | 1,139 | 平台 | 运安抓取上收平台,公寓只收下行计划 |
|
||||
| `gy_syn_jcxx_his` | 2,291 | 平台 | 归档分区 |
|
||||
| `gy_syn_jcxx_status` | 1 | 平台 | 改为 watermark 表(含 `last_success_at`/`cursor`) |
|
||||
| `gy_ykt_ry` | 1,349 | 平台 | 人员/卡主数据,公寓本地缓存 |
|
||||
| `gy_ykt_ry_zp` | 100 | 平台 | 迁对象存储,表只留 URL 与校验和 |
|
||||
| `gy_ykt_remainder` | 1,253 | 平台主账 + 公寓缓存 | 双记:本地流水 + 平台主账,日对账 |
|
||||
| `gy_ykt_allowance` | 34,182 | 平台 | 补助流水归平台,公寓不上报原始流水 |
|
||||
| `gy_ykt_consume` | 35 | 平台(餐饮)/ 公寓(其他) | 按消费来源拆分归属 |
|
||||
| `gy_ykt_btbj` | 5 | 平台 | 补助标准主数据 |
|
||||
| `gy_ykt_btjs` | 5 | 平台 | 补助规则主数据 |
|
||||
| `gy_sb` | 148 | 公寓 | **合并到 `gy_device`**,命名归一 |
|
||||
| `gy_device` | 92 | 公寓 | 保留为唯一设备台账,补 `(gyid, device_code)` 唯一 |
|
||||
| `gy_sb_xt` | 246 | 公寓 | 保留;心跳改 upsert,加 `last_heartbeat` 索引 |
|
||||
| `gy_sb_zl` | 129,665 | 公寓 | **拆队列 / 历史**,见 6.4 |
|
||||
| `gy_sb_zl_his` | 0 | 公寓 | 改分区表承接指令历史 |
|
||||
| `gy_logs` | 285,914 | 公寓 | 按月分区 + 保留期;"同步汇总"降为采样 |
|
||||
| `gy_operation_log` | 0 | 公寓 + 值班 | 启用,按端打标 |
|
||||
| `gy_file` | 1 | 平台 | 对象存储索引 |
|
||||
| `gl_*`(6 张) | 17/4/48/45/16/58 | 平台 | 统一账号与权限;公寓端沿用 RuoYi `sys_*` 或适配 `gl_*`,二者只能留一套 |
|
||||
| `gen_table` / `gen_table_column` | 18 / 279 | — | 退役,目标库不携带 |
|
||||
|
||||
## 6. 目标结构建议(设计输入,未执行)
|
||||
|
||||
### 6.1 命名与边界
|
||||
|
||||
1. 保留 schema `gygl`,用**表名前缀**表达归属:`PLT_`(平台主数据/计划)、`APT_`(公寓执行事实)、`DUTY_`(值班操作)、`ARC_`(归档)。
|
||||
2. 现有 `gy_*` 表在迁移期保留原名,新增列/新表用新前缀,避免一次性重命名带来的全量改代码。
|
||||
3. 权限表二选一:若公寓端采用 RuoYi,则 `gl_*` 只作为平台端兼容视图存在,不再有第二份可写副本。
|
||||
|
||||
### 6.2 主键与索引基线
|
||||
|
||||
表 6-1 必补约束与索引(按优先级)
|
||||
|
||||
| 表 | 建议主键 / 唯一 | 建议索引 |
|
||||
| --- | --- | --- |
|
||||
| `gy_jcxx` / `gy_jcxx_his` | `jcid` | `(gyid, kcsj)`、`(gyid, ryzt)` |
|
||||
| `gy_rooms` | `(gyid, room_no)` | `(gyid, room_status)` |
|
||||
| `gy_ykt_ry` | `ryid` | `(card_id)`、`(gzzh)` |
|
||||
| `gy_ykt_remainder` | `ryid` | `(cardid)` |
|
||||
| `gy_ykt_allowance` | `tid` | `(gyid, czsj)`、`(ryid, czsj)` |
|
||||
| `gy_ykt_consume` | `tid` | `(gyid, xfsj)`、`(orderid)` |
|
||||
| `gy_device` | `(gyid, device_code)` | `(ip_addr)`、`(last_heartbeat)` |
|
||||
| `gy_sb_xt` | `devicecode` | `(gyid, heartbeattime)` |
|
||||
| `gy_sb_zl` | `id` | `(devicecode, deleted, generatedtime)` —— 取指令的主路径 |
|
||||
| `gy_logs` | `id` | `(eventtime)` + 按月分区 |
|
||||
| `gy_bjxx` | `id` | `(gyid, kssj)` |
|
||||
| `gy_syn_jcxx` | `id` | `(kcsj)`、`(jch, cc)` |
|
||||
| `gy_jbxx` / `gy_gyzd` / `gy_sjgz` | `gyid` | — |
|
||||
| `gl_yh` / `gl_js` / `gl_qx` / `gl_cd` | 各自首列 | 关联表 `(user_id)/(role_id)` |
|
||||
| `gy_call_duty_match_lock` | `gyid` | — |
|
||||
|
||||
### 6.3 类型归一规则
|
||||
|
||||
表 6-2 类型目标
|
||||
|
||||
| 现类型 | 目标 | 规则 |
|
||||
| --- | --- | --- |
|
||||
| `varcharbyte`(无长度) | `varchar(n)` | 按实测最大长度 + 30% 余量定 n;标识类统一 `varchar(32/64)` |
|
||||
| 业务时间(`kssj`/`jssj`/`ddsj`/`yrysj`…) | `timestamp(3)` | 禁止再新增字符串时间;迁移时按 `YYYY-MM-DD HH24:MI:SS` 解析,解析失败行单独落错误表 |
|
||||
| `sys.date` | `timestamp(0)` | 保持秒精度,避免与 `timestamp(6)` 混比 |
|
||||
| 金额(`bzje`/`xfje`/`knye`/`xjye`/`xfze`/`bzze`) | `numeric(12,2)` | 统一两位小数,禁止 `numeric` 裸用 |
|
||||
| 布尔标记(`deleted`/`sfjc`/`finish_*`/`is_*`/`stoped`) | `char(1)` + `CHECK IN ('0','1')` | 或 `boolean`;**同一字段名全库只允许一种表示** |
|
||||
| `id`(`numeric` vs `varchar`) | `varchar(32)` 或 `bigint` | 每张表内自洽即可,但跨表引用必须同型 |
|
||||
| `blob` 照片 | 移出库 | 表内只留 `photo_url` + `sha256` + `size` |
|
||||
|
||||
### 6.4 拆表与归档
|
||||
|
||||
1. **`gy_jcxx` 三分**:
|
||||
- `APT_JC_TASK`:任务与状态机(`jcid/ryid/jch/cc/kcsj/jcsj/fjsj/jcbjsj/ryzt`)
|
||||
- `APT_JC_STAY`:入住离寓(`yrysj/sjrysj/ylysj/sjlysj/ly_*`/`flag_send`)
|
||||
- `APT_JC_NOTICE`:通知去重键(`route_notice_key/call_timeout_notice_key/missed_call_notice_key`)→ 或并入通用 `NOTICE_KEY` 表
|
||||
- 物理上不再是 70 列宽表,写入口从"多处 update 同一行"变为"三个子域各自写自己的表",`JcglService` 的 4193 行才有可能拆开。
|
||||
2. **`gy_sb_zl` 拆队列/历史**:`APT_DEV_CMD`(只保留未消费,带 `status/attempt/expire_at`)+ `ARC_DEV_CMD`(消费即搬走),队列表行数应稳定在"在线设备数 × 个位数"量级,当前 7.1 万条积压即为异常基线。
|
||||
3. **`gy_logs` 分区**:按月 `RANGE` 分区,保留 3 个月热数据;"运安叫乘同步汇总"改为只记异常与抽样,预计日志量下降 90%。
|
||||
4. **`gy_jcxx_his` / `gy_syn_jcxx_his` / `gy_sb_zl_his`** 统一进 `ARC_` 分区族,保留期与合规要求对齐。
|
||||
|
||||
### 6.5 迁移时的兼容陷阱
|
||||
|
||||
1. `varcharbyte` 无长度 → 转 `varchar(n)` 前必须先跑 `select max(length(col))` 全量核对,否则截断报错会中断迁移。
|
||||
2. `ora_input_emptystr_isnull=on` → 迁移前后同一份数据 `''` 与 `NULL` 的判断结果不同;迁移脚本与校验 SQL 都要用 `coalesce(col,'')` 口径。
|
||||
3. `gen_table_column` 里记录的 `is_pk` 全为 RuoYi 生成器推断值,**不能当作主键依据**——实测全库主键为 0,该字段不代表真实约束。
|
||||
4. 60 个孤儿序列不要随库迁移,目标库从 0 重建,否则序列起始值会带来 ID 跳号与冲突排查成本。
|
||||
5. Oracle 兼容模式与金仓安全版 MAC 策略需在目标环境确认(`database_mode`、`sysmac` 是否启用),二者会改变 SQL 行为与权限模型。
|
||||
|
||||
## 7. 与三端拆分方案的衔接
|
||||
|
||||
表 7-1 结构缺陷 → 方案措施
|
||||
|
||||
| 本次实测缺陷 | 对应章节 | 方案措施 |
|
||||
| --- | --- | --- |
|
||||
| 零主键零索引零外键(3.1) | 阶段零 基线修复 | 先补 `(gyid, 业务键)` 唯一约束与查询索引,再谈拆分 |
|
||||
| 同名不同型 12 组(3.2) | 5 数据架构 / 6 接口契约 | 契约层强制类型规范;`gyid` 统一 `varchar(64)` |
|
||||
| 空串即 NULL(3.4) | 6 接口契约 | 上报信封中 `null` 与 `""` 语义显式化,服务端统一 `coalesce` |
|
||||
| `gy_jcxx` 70 列(3.5) | 4 领域与模块划分 | 拆三子域,状态机唯一写入口 |
|
||||
| 双设备台账(3.6) | 7 设备接入 | 设备主数据唯一化,`gy_device` 为准,`gy_sb` 合并 |
|
||||
| 指令积压 7.1 万(3.7) | 7.4 指令下发-ACK-重投 | 队列化 + ACK + 过期作废 + 优先级 |
|
||||
| 日志月增 4.4 万(3.8) | 8 部署与运行 | 分区 + 保留期 + 异常化 |
|
||||
| `gyid` 取值域不一致(3.9) | 3 端职责边界 | 公寓主数据上收,租户键非空 + 外键校验 |
|
||||
| RuoYi 残留与孤儿序列(3.10) | 阶段一 新公寓端脚手架 | 明确权限表归属,目标库不携带 `gen_*` 与孤儿序列 |
|
||||
| 照片双真相(3.11) | 5.3 数据归属 | 统一对象存储 + 校验和 |
|
||||
| 审计表空置(3.12) | 10 风险 | 值班操作留痕纳入验收项 |
|
||||
| 账务不可对账(4 节) | 5.2 一致性策略 | 主账在平台 + 本地流水 + 日对账 |
|
||||
|
||||
## 8. 待现场确认
|
||||
|
||||
1. **生产库是否真的没有索引**:本机导入库与 dump 均为 0,但需要在生产 DBA 侧执行 `\d+ gygl.gy_jcxx` 复核(导出工具理论上会带索引,需排除导出裁剪)。
|
||||
2. **37 个 gyid 与 9 个 `gy_jbxx` 的差集**:是"未登记"还是"已停用"?决定主数据补录范围。
|
||||
3. **样本库只有 2 个公寓的叫乘数据**:确认是导出裁剪、数据迁移,还是这两个公寓曾单独部署。
|
||||
4. **`gy_sb_zl` 积压 7.1 万条的成因**:设备端未取、网关未转发,还是消费后回写失败?需查 2026-10 之后的设备侧日志。
|
||||
5. **Oracle 存量公寓**:`ojdbc8` 依赖存在,确认是否存在仍直连 Oracle 的部署环境。
|
||||
6. **金仓安全版 MAC 是否启用**:`sysmac` schema 为空表,若启用策略会影响后续新增表的授权模型。
|
||||
|
||||
## 附录 A 采集 SQL(可复现)
|
||||
|
||||
```sql
|
||||
-- 库级
|
||||
select version(), current_setting('server_encoding');
|
||||
select name, setting from pg_settings where name in ('database_mode','ora_input_emptystr_isnull');
|
||||
select nspname, count(*) from pg_class c join pg_namespace n on n.oid=c.relnamespace
|
||||
where c.relkind='r' group by 1;
|
||||
|
||||
-- 约束与索引
|
||||
select count(*) from pg_indexes where schemaname='gygl';
|
||||
select constraint_type, count(*) from information_schema.table_constraints
|
||||
where table_schema='gygl' group by 1;
|
||||
select count(*) from pg_class c join pg_namespace n on n.oid=c.relnamespace
|
||||
where c.relkind='S' and n.nspname='gygl';
|
||||
|
||||
-- 类型与注释
|
||||
select udt_name, count(*), sum(case when character_maximum_length is null then 1 else 0 end)
|
||||
from information_schema.columns where table_schema='gygl' group by 1 order by 2 desc;
|
||||
select column_name, count(distinct udt_name) from information_schema.columns
|
||||
where table_schema='gygl' group by 1 having count(distinct udt_name)>1;
|
||||
|
||||
-- 规模与分布
|
||||
select relname, n_live_tup, pg_size_pretty(pg_total_relation_size(relid))
|
||||
from pg_stat_user_tables order by pg_total_relation_size(relid) desc;
|
||||
select count(*), count(distinct jcid), count(distinct gyid), min(kcsj), max(kcsj) from gygl.gy_jcxx;
|
||||
select deleted, count(*), min(generatedtime), max(generatedtime) from gygl.gy_sb_zl group by 1;
|
||||
select count(*) from gygl.gy_sb_zl where deleted='0' and generatedtime < now() - interval '1 day';
|
||||
select to_char(eventtime,'YYYY-MM'), count(*) from gygl.gy_logs group by 1 order by 1;
|
||||
```
|
||||
|
||||
> 本轮对实例的全部操作均为 `SELECT`,未执行任何 DDL/DML;分析用临时脚本仅存在于本机临时目录。
|
||||
@@ -0,0 +1,52 @@
|
||||
# 叫乘管理系统 梳理文档
|
||||
|
||||
本目录是对既有代码的结构化梳理,目的是为后续迭代提供统一的“地图”:知道每个业务落在哪个包/页面、数据怎么流转、接口和外部系统怎么对接、改动时应该看哪些文件。
|
||||
|
||||
> 后端:`yktgl/`;前端:`YktVue/`,见 [frontend/](../frontend/README.md)。
|
||||
> 梳理基准:`main` 分支提交 `135a192`(2026-11-07)。
|
||||
|
||||
## 文档索引
|
||||
|
||||
| 文档 | 内容 | 适用场景 |
|
||||
| --- | --- | --- |
|
||||
| [01-系统总览.md](01-系统总览.md) | 业务定位、角色、运行形态、技术栈、关键设计约束 | 新人入门、方案评审 |
|
||||
| [02-工程结构与分层.md](02-工程结构与分层.md) | 目录/包结构、分层约定、启动流程、公共组件 | 找代码、定落点 |
|
||||
| [03-业务模块地图.md](03-业务模块地图.md) | 各业务模块职责、控制器、服务、依赖关系 | 评估改动影响面 |
|
||||
| [04-核心业务流程.md](04-核心业务流程.md) | 入住、叫乘、复叫、报警、应答、离寓、房间、交路同步、卡务 | 改业务逻辑前必读 |
|
||||
| [05-数据模型.md](05-数据模型.md) | 核心表、字段语义、状态码、归档与锁 | 写 SQL / 改表 / 排查数据 |
|
||||
| [06-接口清单.md](06-接口清单.md) | Web 接口与设备接口清单、协议枚举 | 联调、接口扩展 |
|
||||
| [07-外部集成与定时任务.md](07-外部集成与定时任务.md) | Asterisk AMI、运安 SOAP、中心 HTTP、WebSocket、Quartz/@Scheduled | 排障、集成改造 |
|
||||
| [08-部署与配置.md](08-部署与配置.md) | Profile、数据库/Redis、资源目录、升级脚本 | 部署、环境切换 |
|
||||
| [09-迭代指引与风险清单.md](09-迭代指引与风险清单.md) | 技术债、改动落点速查、待确认问题、迭代建议 | 排期、评审 |
|
||||
| [10-架构优化方案-三端拆分.md](10-架构优化方案-三端拆分.md) | 平台端/公寓端/应用端拆分:现状评估、目标架构、职责边界、模块与数据归属、接口契约、设备接入、部署与迁移路径;含公寓端细化(RuoYi-Vue + MySQL 技术基线、应用端复用实现、语音域 Asterisk/AMI/分机/录音与配置收敛对账)及 KingbaseES→MySQL 选型与迁移 | 架构评审、重构设计 |
|
||||
| [11-既有数据库结构分析.md](11-既有数据库结构分析.md) | 实测库级参数、40 表清单与规模、零主键零索引等结构缺陷、数据质量实证、表归属矩阵、类型归一与拆表建议 | 库设计评审、迁移改造 |
|
||||
|
||||
## 前端文档
|
||||
|
||||
前端梳理独立成册,入口见 [frontend/README.md](../frontend/README.md):
|
||||
|
||||
| 文档 | 内容 |
|
||||
| --- | --- |
|
||||
| [frontend/01-前端总览与技术栈.md](../frontend/01-前端总览与技术栈.md) | 四类界面、运行拓扑、技术栈、全局变量 |
|
||||
| [frontend/02-工程结构与请求链路.md](../frontend/02-工程结构与请求链路.md) | 启动装配、登录守卫、axios、API 与后端映射 |
|
||||
| [frontend/03-路由与页面职责.md](../frontend/03-路由与页面职责.md) | 13 条路由、入口关系、遗留页面 |
|
||||
| [frontend/04-核心页面拆解-JcXx.md](../frontend/04-核心页面拆解-JcXx.md) | 值班台布局、状态、操作、时间规则、轮询 |
|
||||
| [frontend/05-实时通信与语音告警.md](../frontend/05-实时通信与语音告警.md) | WebSocket/SIP、消息协议、告警与 TTS 队列 |
|
||||
| [frontend/06-食堂与自助终端模块.md](../frontend/06-食堂与自助终端模块.md) | 自助登记、点餐/结算/后厨/保洁、选房与房间维护 |
|
||||
| [frontend/07-构建部署与风险清单.md](../frontend/07-构建部署与风险清单.md) | 构建、环境、部署要点、测试基线、P0/P1/P2 风险 |
|
||||
|
||||
## 建议阅读路径
|
||||
|
||||
- **第一次接触项目**:01 → 02 → 03 → 04;再看前端 01 → 02 → 04。
|
||||
- **要接一个需求**:03 定位模块 → 04 看流程 → 09 查落点与风险 → 06/05 查接口和表;涉及页面时读前端 04/05。
|
||||
- **线上排障**:07(外部依赖/定时任务)→ 04(状态机)→ 05(数据与状态码)→ 08(配置);前端问题读前端 05/07。
|
||||
- **准备重构**:02(分层)→ 09(技术债与建议)→ 10(三端拆分方案)→ 11(既有库结构分析);前端读前端 02/04/07。
|
||||
|
||||
## 快速事实
|
||||
|
||||
- 后端:Spring Boot 2.6.13 + Java 8,默认 jar 打包(可改 WAR),上下文路径 `/yktgl`,默认端口 `8081`。
|
||||
- 数据库:KingbaseES 8(兼容 Oracle 语法),Redis 存 Session。
|
||||
- 多公寓:同一套代码通过“客户端 IP → 公寓”解析 `gyid`,不依赖前端传参。
|
||||
- 核心链路:设备/网页入寓登记 → 生成叫乘计划(Quartz 三个任务)→ 叫乘/复叫/报警/应答 → 离寓归档。
|
||||
- 最大单体:后端 `jcgl/service/JcglService.java`(约 4192 行);前端 `src/views/JcXx.vue`(5294 行)。
|
||||
- 前端:Vue 2.6 + Element UI,生产静态与接口同域 `/yktgl`;登录无真实 token,公寓 `gyid` 由后端按客户端 IP 解析。
|
||||
Reference in new issue
Block a user