Files
jcgl/docs/10-架构优化方案-三端拆分.md

56 KiB
Raw Permalink Blame History

10 架构优化方案:平台端 / 公寓端 / 应用端三端拆分

文档性质:架构设计方案(Design Only)。本文不含代码补丁、不含数据库变更脚本、不含配置修改,仅作为后续重构设计、评审与实施的输入。

0. 文档说明

表 0-1 文档信息

项 内容
文档编号 docs/10
文档名称 架构优化方案:平台端 / 公寓端 / 应用端三端拆分
适用范围 铁路行车公寓叫乘系统(YktVue 前端、yktgl 后端、docs 文档)
关联文档 01-系统总览、02-工程结构与分层、03-业务模块地图、04-核心业务流程、05-数据模型、06-接口清单、07-外部集成与定时任务、08-部署与配置、09-迭代指引与风险清单、frontend/*
约束条件 1)不改变“平台做核心业务与基础数据服务、公寓端做本地设备与任务执行、应用端做值班员操作界面”的总体定位;2)应用端与公寓端复用同一套代码与同一个数据库,不构成第三套服务或独立库;3)平台端不承担现场设备实时接入与控制;4)公寓端与应用端技术基线锁定为 RuoYi-Vue + Vue + MySQL(见 2.4),本基线不再讨论替代方案;5)公寓端直连本地 Asterisk,语音链路不经平台端中转
交付对象 架构评审、重构详细设计、试点实施与验收

表 0-2 修订记录

版本 日期 说明
v1.0 2026-11-07 首次形成:现状评估、目标架构、职责边界、模块划分、数据架构、接口契约方向、设备接入、部署运行、迁移路径、风险与优先级
v1.1 2026-11-07 细化公寓端:锁定 RuoYi-Vue + Vue + MySQL 技术基线;补齐应用端与公寓端的复用实现(2.5);新增语音模块清单与依赖方向(4.4);新增语音域数据设计(5.4)与分机配置一致性(5.5);新增数据库选型迁移分析(5.6);新增语音域接口清单(6.4);新增 Asterisk 链路设计(7.7–7.11);新增 Asterisk 部署运行(8.3);新增专项风险与决策点 D11–D16

表 0-3 本次修订(v1.1)涉及的小节与表号

类型 编号 内容
修订 表 0-1 约束条件补入技术基线与语音链路前提(第 4、5 条)
修订 表 1-1 追加 3 条与 AMI、会议桥、分机台账相关的现状事实
新增 2.4 / 表 2-2 三端技术基线(确定前提)
新增 2.5 / 图 2-3 / 表 2-3 应用端与公寓端的复用实现(工程结构、路由、权限、部署)
修订 3.2 公寓端“负责/不负责”补入语音、分机、事件三条职责
新增 3.4 / 表 3-2 语音链路上的三端分工
修订 表 4-3 公寓端模块清单追加 4 个语音模块
新增 4.4 / 图 4-1 / 表 4-4 语音相关模块与依赖方向
新增 5.4 / 表 5-3、5-4 语音域数据设计(含 MySQL 适配)
新增 5.5 / 表 5-5 分机配置在本地库与 Asterisk 之间的一致性机制
新增 5.6 / 表 5-6 ~ 5-9 数据库选型:KingbaseES → MySQL 的影响、迁移、双跑与平台端取舍
新增 6.4 / 表 6-3 公寓端语音域接口清单
新增 7.7 ~ 7.11 / 图 7-1 / 表 7-4 ~ 7-7 Asterisk 语音链路:拓扑、资源生命周期、事件跟踪、闭环边界、自检巡检
新增 8.3 / 表 8-3 ~ 8-5 Asterisk 与公寓端同机部署、端口防火墙、录音存储与清理
新增 10.3 / 表 10-3 语音与数据库专项风险
修订 表 10-2 追加待决策点 D11–D16
修订 表 11-1、11.3 落地顺序补入语音域治理与数据库切换两项
修订 附录 A/B/C/D 术语、图表索引、代码证据、维护约定同步更新

目录


1. 现状评估

本章只做定位与改造建议,不修改代码。表 1-1 是拆分设计所依据的代码与配置事实,表 1-2 是模块级归属判断。

1.1 现状事实基线

表 1-1 现状事实与拆分影响

事实 代码/配置证据 对拆分的影响
一套 jar 同时扮演“公寓端”和“中心端” JcglService 注册人员时转发 centerServerUrl + /yktgl/regist/addPersonInfo;JlGlService 从 centerServerUrl + /yktgl/jlgl/getMessageFromGy 拉交路 平台与公寓的边界已存在,但靠同一套接口“自调自”,必须先切出接口契约
公寓身份靠请求 IP 推断 ZdwhService.getGyIdByIp / getUniqueGyByIp,在 JcglController、6 个设备包、ExcelExportController、LoginController 等 25 处以上调用 目标架构下公寓身份应来自部署配置与认证上下文,IP 识别只作为兼容层
多公寓共用一套库 tl / sjt / dev 共用 10.32.209.76:54321/gygl,仅 prod 独立 与“公寓本地数据本地存”直接冲突,是数据归属改造重点
交路匹配只处理一个公寓 matchCallDutyUnderLock 仅处理 baseConfig.gyid 一实例多公寓时其他公寓永不自动匹配,本身说明“计划与匹配应上收平台”
叫乘执行与运安强绑定在同一进程 SynDataSchedule(每 5 分钟抓取 → 写 GY_SYN_JCXX → 触发匹配)与 WakeUpJob 同进程 目标是平台下发计划、公寓只执行、结果上报
设备认证是全局共享口令 baseConfig.devicePassword 在 6 个设备服务中被注入并原样下发心跳响应 公寓本地化后必须升级为一机一密/签名
设备指令一次性投递、无 ACK GY_SB_ZL 取最新一条后置 deleted=1(HeartBeatService) 弱网必丢指令,属公寓端必须解决的核心问题
餐饮直接改卡务余额 MealsService.updateMoney → JcglService.changeRemainder + JcglMapper.updateRemainder 餐饮归平台、账务在主账,二者必须走“记账接口”而非直接改余额
WebSocket 是进程内实现 JcWebsocket 用静态 Map<sessionId, endpoint>,sendMessage(message, gyid) 按 username 当 gyid 匹配 应用端与公寓端同进程可复用;但不能横向扩容,除非补广播
前端按部署硬编码公寓 public/config.js:apiRoot = window.location.host、`gyid = localStorage.getItem('gyid')
值班能力集中在单页 views/JcXx.vue(约 5294 行)承载盯控、入寓、换房、充值、人员、交路、设备状态、告警音、TTS 应用端应以此页为骨架做角色化拆分,而非另起一套
构建基线不稳 pom.xml 在 Boot 2.6.13 父工程下显式声明 spring-boot-starter-web:3.5.4、spring-boot-starter-data-redis:3.3.1 拆分前必须先修复,否则新工程无法验证
AMI 连接是单例且不重连 AsteriskAmiConfig 在 @Bean 内 login(),失败仅打印;AsteriskCallUtil.makeCall 仅在 IllegalStateException 时补登一次 语音链路必须在公寓端闭环并具备连接自愈,不能靠重启容器恢复
会议桥硬编码单实例 "Conf-01" 在 AsteriskCallUtil、JcglController、WakeUpJob 中硬编码 20 处以上;isConferenceBusy 以内存 recordlist + core show channels concise 判断 单会议桥是容量与串音约束,必须在设计层明确会议粒度
分机没有独立台账 分机只以 GY_ROOMS.sip_account 单列存在(RoomEntity.sip_account、JcglRoomMapper 可写),无注册状态、无中继、无绑定实体,sip_status 从未被写入 分机资源需独立建模,才具备增删改停用与状态跟踪能力

1.2 模块定位与目标归属

表 1-2 主要模块定位与目标归属

现状模块(包) 实际职责 目标归属 主要问题
jcgl(JcglService,约 4193 行) 入寓/离寓、叫乘状态机、房间推荐与房态、补助计算、交路匹配、归档、设备指令、WebSocket 推送 拆三份:任务执行与状态机 → 公寓端;补助规则与账务 → 平台端;盯控与人工干预 → 应用端 上帝类,跨 6 个领域,任一改动影响全链路
jlgl 交路模板 CRUD、叫乘时刻、Excel 上传、从中心拉取 平台端(交路主数据)+ 公寓端只读快照 与 centerServerUrl 双向调用语义不清,真源不明确
regist 人员资料、照片、增删改 平台端(人员主数据)+ 公寓端缓存 注册链路绕过本地直写“中心”,失败会整体回滚用户操作
recharge / pay / vendPayDevice 现金充值、消费扣款、余额变动 账务主账 → 平台端;公寓端保留本地流水与离线可用缓存 余额以“改字段”方式落在公寓库,无流水约束、无对账
MealsOrdering 菜品、订单、后厨、送餐、结算 平台端(餐饮业务) 直接调 JcglService.changeRemainder 改余额,跨端耦合最重
zdwh 公寓、房间、工种、节假日、餐补、IP→公寓 平台端(主数据)+ 公寓端本地缓存 房间是公寓资产却与平台主数据同库;IP 解析扩散全工程
syndata / ByxxResourceService 运安 SOAP 抓取、人员同步、财务汇总(getApartmentPersonDataByGyCode/ByWorkNo/ByTime、synFinanceData) 平台端(运安接入 + 分发 + 汇总接收) 部署在公寓实例内,每个公寓各自连运安并各自清空快照表
heartBeat + 6 个 *Device 包 设备心跳、指令下发、设备档案 公寓端(设备网关) 全局共享口令、指令一次性投递、无 ACK、无离线队列
quartz(WakeUpJob / SchedulerManager)+ AsteriskCallUtil 叫乘调度、AMI 会议桥、TTS、串口广播 公寓端 未配置持久化 JobStore(默认内存模式),重启只恢复未来任务;AMI/串口为本地资源,不能上收
schedule JcSchedule(漏叫提醒、超时离寓、归档)、SynDataSchedule(运安)、LeaveSnapshotCleanupSchedule 混合:提醒/归档/清理 → 公寓端;运安抓取 → 平台端 一个包内混着“本地执行”与“平台接入”两类任务
websockets 5 个端点,按 gyid 推送刷新/人员/充值/订单 公寓端 + 应用端共用 进程内状态,无订阅者身份校验
display 登录、RBAC、菜单、日志 平台端(全局账号与审计基线)+ 公寓端用 RuoYi 自有 RBAC 两套账号体系若不约定会出现“平台账号进不了公寓端、公寓账号看不到平台菜单”
xxtj / excel 日报、月报、补助/充值/消费统计与导出 平台端(跨公寓报表);公寓端保留本公寓运行报表 当前跨表统计在公寓库内执行,数据分散后无法汇总
kcgl 库存、出入库、物料 独立边界(可留平台或独立系统) 与叫乘主线弱相关,不应进入公寓端
test、/jcgl/yatest、/jcgl/driver/{id} 测试/演示入口 全部下线 生产暴露外部系统调用入口

1.3 与目标架构不一致的核心点

  1. “平台—公寓”未分层,只靠 centerServerUrl 字符串互调。注册、交路两条链路都是“同一套 Controller 既当设备接口又当中心接口”,无版本、无契约、无重试与幂等。
  2. 公寓身份靠 IP 推断且多公寓共享库。这是“一实例多公寓”的妥协设计,直接阻碍“公寓本地数据本地存”。
  3. 叫乘执行、设备接入、平台接入三者同进程。平台不可达会拖累叫乘主链路,叫乘高峰也会挤占同步线程(AsyncConfig 核心 10 / 最大 200 / 队列 10,队列极小)。
  4. 账务散落。余额在公寓库被直接更新,餐饮、售货机、充值三条链路各自改余额,缺少统一流水与对账口径。
  5. 设备通道不可靠。一次性投递 + 全局口令 + 无 ACK,是弱网现场最典型故障源。
  6. 状态机与视图耦合。ryzt 由设备上报、Quartz、AMI 事件、人工操作共同写入,缺少单一写入口;应用端与公寓端同库后风险被放大。

2. 目标架构

2.1 逻辑架构

图 2-1 目标逻辑架构

flowchart TB
    subgraph PLAT["平台端(现有 yktgl 收敛演进)"]
        P1["主数据服务:公寓/房间基线/人员/交路/时间规则/节假日/餐补"]
        P2["计划服务:运安 SOAP 接入 + 乘务计划 + 任务生成"]
        P3["账务服务:补助规则/余额主账/流水归集/对账"]
        P4["餐饮服务:菜品/订单/后厨/结算"]
        P5["权限与审计:账号/RBAC/操作审计/接口审计"]
        P6["报表与监控:跨公寓统计/设备在线率/执行质量"]
        P7["上报接收与对账中心:结果/流水/告警/水位"]
    end

    subgraph APT["公寓端(RuoYi 新建,一公寓一实例)"]
        A1["设备网关:注册/心跳/指令/事件/离线队列"]
        A2["叫乘执行引擎:Quartz + AMI + 串口广播 + TTS"]
        A3["本地主数据缓存:人员/交路/房间/规则快照"]
        A4["在寓与房态事实:入住/离寓/换房/保洁"]
        A5["本地账务缓存 + 消费受理"]
        A6["上报器:outbox + 幂等键 + 重试"]
        A7["值班 API + WebSocket 推送"]
        A8["本地运维:自检/日志/版本"]
    end

    subgraph DUTY["应用端(与公寓端同代码同库,同进程部署)"]
        D1["叫乘盯控台:任务/报警/应答/临叫/停止"]
        D2["房态与房间管理:选房/换房/停用/保洁"]
        D3["人工干预与审核:充值确认/资料修正/备注"]
    end

    subgraph EXT["外部"]
        E1["运安 SOAP"]
        E2["现场设备"]
        E3["Asterisk / 串口 / 话机"]
        E4["中心汇总/财务"]
    end

    DUTY -->|同进程领域调用| APT
    A2 --> E3
    A1 --> E2
    APT -->|下行拉取:主数据/计划/规则| PLAT
    APT -->|上行推送:结果/流水/告警/水位| PLAT
    PLAT --> E1
    PLAT --> E4

2.2 部署拓扑

图 2-2 部署拓扑

flowchart LR
    subgraph Center["中心机房"]
        LB["Nginx / 网关(TLS)"]
        PF1["平台端实例 A"]
        PF2["平台端实例 B"]
        PDB[("平台主库")]
        PRD[("Redis")]
        POS[("对象存储:照片/抓拍/录音")]
    end

    subgraph Apt1["公寓 A 现场"]
        N1["Nginx(公寓内网)"]
        S1["公寓端+应用端同进程实例"]
        DB1[("公寓本地库")]
        RD1[("本地 Redis")]
        AST1["Asterisk + 串口"]
        DEV1["叫乘屏/签到机/房间屏/消费机/售货机"]
        DUTY1["值班员浏览器"]
    end

    subgraph Apt2["公寓 B 现场(同构)"]
        S2["公寓端+应用端同进程实例"]
        DB2[("公寓本地库")]
    end

    LB --- PF1
    LB --- PF2
    PF1 --- PDB
    PF2 --- PDB
    PF1 --- PRD
    PF2 --- PRD
    PF1 --- POS

    N1 --- S1
    S1 --- DB1
    S1 --- RD1
    S1 --- AST1
    DEV1 --> N1
    DUTY1 --> N1
    S2 --- DB2

    S1 -->|出站 HTTPS 443| LB
    S2 -->|出站 HTTPS 443| LB

拓扑要点

  1. 平台端不进公寓内网:所有跨端流量由公寓端主动出站发起,规避现场 NAT/防火墙,并让平台与设备链路彻底解耦。
  2. 公寓端 = 部署单元 = 公寓隔离单元:一公寓一实例一库(或独立 schema),gyid 由部署参数固定。
  3. 应用端不新增进程与库:值班员访问 http://<公寓服务器>/duty,与公寓端同 JVM、同库、同 Nginx。
  4. 平台端可多实例;公寓端的 WebSocket 为进程内实现,因此公寓端须保持单实例(或先完成广播改造再扩容)。

2.3 三端调用关系与数据流

表 2-1 三端调用关系与数据流

调用方向 协议 触发方式 典型数据
应用端 → 公寓端 进程内 Service 调用 同步 人工干预、房态修改、审核动作
公寓端 → 平台端 HTTPS 主动拉取 定时(如 5 分钟)+ 变更通知 主数据增量、乘务计划、规则版本
公寓端 → 平台端 HTTPS 主动推送 近实时批量 + 重试 执行结果、账务流水、告警摘要、设备摘要、g'y'g水位
设备 → 公寓端 内网 HTTP(后续可评估 MQTT) 心跳 + 事件 指令取走、业务上报
平台端 → 运安 SOAP 定时 乘务计划
平台端 → 中心/财务 HTTPS 定时/按需 财务汇总、跨公寓人员查询
平台端 → 公寓端 不允许直连 — 仅落“待下发配置版本”,由公寓端拉取

3. 端职责边界

3.1 平台端

负责

  • 公寓档案、房间基线(gyid + room_no + 床位数)、人员主数据与照片、交路模板与叫乘时刻、时间规则、节假日、餐补/补助标准。
  • 运安计划的唯一入口(替代现状各公寓分别抓取),并将计划转换为叫乘任务/计划快照下发对应公寓。
  • 账务主账:补助发放规则、余额主账、消费/充值/补助流水归集、跨端对账。
  • 餐饮业务(菜品、订单、后厨、结算规则),但结算扣款必须经账务接口,不直接改公寓库余额。
  • 账号、角色、权限、操作审计、跨公寓报表、设备在线率与执行质量监控、告警汇总。
  • 接收各公寓执行结果与异常补偿请求,维护每公寓水位与对账结果。

不负责

  • 不接入现场设备、不下发设备指令、不持有设备心跳流水。
  • 不执行叫乘(不连 AMI、不控串口、不播 TTS)。
  • 不直连公寓本地库,不做跨库 JOIN。
  • 不承担房间实时房态(仅保留基线,实时占用以公寓端为准)。

3.2 公寓端

负责

  • 本公寓设备接入:注册、认证、心跳、指令队列、事件受理、离线缓存。
  • 本公寓叫乘执行全链路:任务创建、Quartz 调度、AMI 会议桥、TTS、串口广播、复叫/报警/停止、重启恢复与漏叫补偿。
  • 在寓事实与房态(GY_JCXX 语义)、换房、退房、保洁、超时离寓报警。
  • 本地主数据缓存与规则快照(人员照片、交路、时间规则、节假日),保证断网可叫乘。
  • 本地账务流水与离线消费受理(缓存余额),向平台归集。
  • 结果上报:执行结果、流水、告警摘要、设备摘要、归档摘要、水位。

不负责

  • 不直连运安(运安仅由平台接入),不维护跨公寓人员全集。
  • 不决定补助标准,不做跨公寓统计,不维护平台账号体系。
  • 不制定园区级设备策略(策略由平台配置,执行在公寓)。

3.3 应用端(与公寓端同代码同库)

负责

  • 叫乘盯控:任务列表、报警、应答确认、临时叫乘、房间/多房间喊话、停止叫乘、录音回放入口。
  • 房间与房态:选房、换房、停用/恢复、保洁开始/结束、在寓人员查看。
  • 人工干预与审核:充值确认、人员资料修正、交路人工指定与重置、备注与操作留痕。

不负责

  • 不直接改设备指令表、不直接改叫乘任务表(必须经公寓端领域服务)。
  • 不持有独立数据库,不引入第三套服务,不做独立鉴权中心。
  • 不承担跨公寓查询(跨公寓看平台端)。

表 3-1 应用端与公寓端的逻辑分工

维度 公寓端(执行域) 应用端(操作域)
表归属 现有 GY_JCXX、GY_SB*、GY_SYN_JCXX 等执行与设备表(可加 apt_* 前缀新表) 新增 DUTY_*:操作审计、人工干预记录、审核动作、备注、班次交接
写权限 仅执行引擎/设备网关写状态字段(ryzt、jcsj_s、finish_jc 等) 仅通过状态机服务写,禁止直连 Mapper 修改状态字段
部署形态 同一 JVM 内的 module-apartment 同一 JVM 内的 module-duty,依赖公寓端领域接口,禁止反向依赖
前端形态 同一前端工程的 apt 入口(设备/终端页) 同一前端工程的 duty 入口(值班员页),按角色裁剪路由与菜单
鉴权 设备用设备凭据;值班员用本地 RuoYi 账号 复用公寓端 RuoYi 账号 + 数据范围锁定 gyid

公寓隔离方式

  1. 部署期固定 apartment.gyId,服务启动即校验;gyid 不再从请求 IP 推断,getGyIdByIp 降级为旧设备兼容兜底并打告警。
  2. 库级隔离:一公寓一 schema/库 + 独立连接账号,账号仅对本库有 DML 权限,对平台库无任何权限。
  3. 请求级隔离:值班员登录后 gyid 写入会话与令牌声明,服务层用拦截器强制注入,业务 SQL 一律带 gyid 条件。
  4. 设备级隔离:设备注册时绑定 gyid + deviceCode,跨公寓 deviceCode 直接拒绝。

4. 领域与模块划分

4.1 能力归属

表 4-1 能力归属决策表(● 主责 ○ 参与/缓存 — 不参与)

能力 平台端 公寓端 应用端 协同说明
公寓/房间基线 ● ○ 缓存 — 房间物理属性(楼层/朝向/SIP/床位数)由公寓维护后上报,平台存基线
人员主数据/照片 ● ○ 缓存 — 平台是全量真源,公寓增量缓存 + 照片版本
交路模板/叫乘时刻 ● ○ 快照 — 公寓可上报“现场临时交路”,平台确认后版本化
时间规则/节假日/餐补 ● ○ 快照 — 按 gyid 差异化,必须版本化下发
运安计划接入 ● — — 公寓端不再持有 WSDL
任务生成(计划→叫乘时刻) ● ○ 复算校验 — 平台给“计划 + 规则版本”,公寓端本地复算并回执
叫乘任务执行 — ● — Quartz/AMI/串口/TTS 全在公寓端
叫乘状态机 — ● ○ 触发 唯一写入口在公寓端,应用端只发命令
入寓/离寓/换房/房态 — ● ○ 操作 应用端发起,公寓端校验与落库
设备接入/指令/心跳 — ● ○ 查看 应用端仅查询与触发“刷新”类指令
补助规则与发放 ● ○ 试用缓存 — 规则在平台,入住时由公寓端触发发放并上报
余额主账 ● ○ 缓存 — 公寓端本地记账 + 平台归集,日对账
消费受理(消费机/售货机) — ● — 现场必须离线可用
餐饮订单/后厨 ● ○ 代理 ○ 视图 公寓端只做终端接入与转发,业务在平台
报警与告警 ○ 汇总 ● 判定 ● 展示 判定阈值在公寓端,摘要上报平台
归档 — ● — 公寓本地归档 + 归档摘要上报
统计报表 ○ 跨公寓 ● 本公寓 ● 查看 公寓端出运行报表,平台出跨公寓报表
账号/RBAC/审计 ● 平台侧 ● 本地侧 ● 复用公寓侧 两套 RBAC 通过“人员—账号映射”打通,不合并表
库存 kcgl 独立 — — 不进入公寓端,避免污染现场部署

4.2 平台端模块清单

表 4-2 平台端模块清单

模块 职责 现状来源
platform.master 公寓、房间基线、工种、时间规则、节假日、餐补标准 zdwh
platform.person 人员主数据、照片、增量分发 regist + syndata 人员部分
platform.route 交路模板、叫乘时刻、停运调整、Excel 上传 jlgl
platform.plan 运安 SOAP 接入、计划快照、任务生成与下发 ByxxResourceService + SynDataSchedule
platform.ledger 补助规则、余额主账、流水归集、对账 recharge / pay 账务部分
platform.catering 菜品、订单、后厨、结算 MealsOrdering
platform.report 跨公寓报表、导出、执行质量 xxtj + excel
platform.ingest 上报接收、幂等、水位、重放、对账(新增) 新增
platform.iam 账号、角色、权限、审计 display
platform.ops 公寓注册、版本、健康度、配置下发版本(新增) 新增

4.3 公寓端模块清单

表 4-3 公寓端模块清单

模块 职责 现状来源
apt.device.gateway 统一设备入口:注册/认证/心跳/指令/事件 收敛 6 个 *Device 包
apt.device.command 指令队列:下发—ACK—重投—过期 替代 GY_SB_ZL 一次性投递
apt.device.catalog 设备档案、在线率、版本 heartBeat
apt.duty.engine 叫乘执行:Quartz、AMI、TTS、串口、复叫/报警/停止 quartz + AsteriskCallUtil
apt.duty.state 状态机唯一写入口(ryzt/finish_jc/finish_ly/stoped) 从 JcglService 抽取
apt.stay 入住、离寓、换房、在寓事实、房态重算 从 JcglService 抽取
apt.room 房间本地属性、推荐、停用、保洁 zdwh 房间部分 + clean
apt.ledger.local 本地余额缓存、离线消费、流水生成 pay / recharge 本地部分
apt.report.outbox 上报 outbox、幂等键、重试、水位(新增) 新增
apt.master.cache 主数据快照与版本校验 zdwh 缓存部分
apt.duty.view 应用端后端 API、WebSocket 推送、人工干预命令 从 JcglController 拆出
apt.ops 自检、时钟偏差、磁盘(抓拍/录音)、日志、版本 新增

5. 数据架构

5.1 数据分层与归属

表 5-1 数据分层、归属与同步方向

数据层 典型数据 归属 存储位置 同步方向
平台主数据 公寓、房间基线、人员、照片、交路、时间规则、节假日、餐补标准 平台 平台主库 + 对象存储 下行:平台 → 公寓(版本化增量)
平台计划数据 运安计划快照、生成的叫乘任务/时刻、变更与取消 平台 平台主库 下行:平台 → 公寓
公寓执行数据 GY_JCXX(在寓/叫乘事实)、GYGL_LY_EVENT、房态、保洁、报警 公寓 公寓本地库 本地强一致;摘要上行
设备数据 GY_SB、GY_SB_XT、指令队列、心跳 公寓 公寓本地库 仅上行摘要(在线率/版本/故障)
账务数据 补助明细、消费/充值流水、余额 主账平台 / 流水双记 平台主库 + 公寓本地缓存 流水上行;对账后余额快照下行
归档数据 GY_JCXX_HIS、离寓事件历史 公寓 公寓本地库 上行归档摘要
账号与审计 账号、角色、权限、操作审计 平台(平台侧)/ 公寓(本地侧) 各自库 人员—账号映射下行
汇总与报表 跨公寓统计、财务汇总 平台 平台主库/数仓 由上行数据加工

5.2 一致性策略

表 5-2 各场景一致性策略

场景 策略
公寓内业务(入住、离寓、房态、叫乘状态) 强一致:单库本地事务 + 状态机唯一入口
主数据/规则下发 最终一致 + 版本号:公寓端保存 masterVersion,版本不一致时拒绝接收任务并触发全量重拉
执行结果上报 最终一致 + 至少一次 + 幂等:outbox 表 + idempotencyKey,平台按 (gyid, bizType, bizId, bizVersion) 去重
账务 本地记账为准的最终一致:本地先落流水(离线可用),平台归集后按日对账,差异进入人工处理队列
余额 平台主账权威;公寓端缓存带“版本 + 最后对账日期”,超期未对账时限制高额操作(如大额充值与退款)
任务下发与执行 平台下发“计划 + 规则版本”,公寓端复算并回执 taskAck;不一致以平台为准并告警

5.3 同库边界防混乱

  1. 表归属清单(Ownership Matrix):每张表标注 owner=platform|apartment|duty、允许的写入模块、是否为上报源;越权写入纳入 Code Review 检查项。
  2. 命名分区:执行域沿用 GY_*(避免大规模迁移),应用域新增 DUTY_*(操作审计、人工干预、审核、交接班);报表/只读视图统一 V_*,禁止跨域直写。
  3. 模块依赖单向:module-duty → module-apartment → module-platform-client,禁止反向依赖;用 Maven 模块或架构约束测试固定。
  4. 禁止跨端 SQL 关联:不在公寓库写“需要平台数据才能算”的统计 SQL,一律先落到本地快照。
  5. gyid 强制注入:拦截器统一注入并校验,任何 SQL 缺 gyid 视为缺陷;新代码统一走上下文,不再逐处解析 IP。
  6. 状态字段单写入口:ryzt、finish_jc、finish_ly、stoped 仅允许 apt.duty.state 写入,设备上报、Quartz、AMI 事件、人工操作统一转为状态机命令。

6. 接口与集成

6.1 跨端接口清单

表 6-1 平台端与公寓端关键接口

# 方向 接口 用途 关键字段
1 下行 GET /platform/v1/master/apartments/{gyId} 公寓档案与能力开关 gyId、name、features[]、version
2 下行 GET /platform/v1/master/persons?gyId&cursor&version 人员增量(含照片版本) ryid、cardId、deptId、photoVersion、deleted
3 下行 GET /platform/v1/master/routes?gyId&from&to 交路模板与叫乘时刻 jlid、cc、kcsj、jcsj、lysj
4 下行 GET /platform/v1/master/rules?gyId 时间规则/节假日/餐补标准 zjjcsjgz、kjjcsjgz、lysjgz、holidays[]
5 下行 GET /platform/v1/master/rooms?gyId&version 房间基线(取决于决策点 D3) roomNo、bedNumbers
6 下行 GET /platform/v1/plans/duty?gyId&from&to 乘务计划(替代本地抓运安) planId、workno、trainNo、depTime、pickupMode
7 下行 GET /platform/v1/tasks/changes?gyId&cursor 任务变更/取消增量 taskId、op=UPSERT/CANCEL、version
8 上行 POST /platform/v1/ack/tasks 任务接收回执(含复算结果) taskId、accepted、computedCallTime、ruleVersion
9 上行 POST /platform/v1/report/duty-results 叫乘/入寓/离寓执行结果(批量) events[]:eventId、type、jcid、ryid、occurredAt、status
10 上行 POST /platform/v1/report/ledger 账务流水(消费/充值/补助) flowId、type、ryid、amount、balanceAfter、deviceCode
11 上行 POST /platform/v1/report/device-status 设备在线率/版本/故障摘要 onlineCount、offlineList[]、versions{}
12 上行 POST /platform/v1/report/alarms 叫乘/离寓报警摘要 alarmId、type、jcid、level
13 上行 POST /platform/v1/report/archive 归档摘要与数据量 period、archivedCount、from、to
14 上行 POST /platform/v1/heartbeat 公寓端存活、版本、水位、时钟偏差 gyId、appVersion、outboxWatermark、clockSkewMs
15 查询 GET /platform/v1/status/{gyId} 平台侧查看公寓健康度与积压 lastReportAt、pending、failed
16 补偿 POST /platform/v1/reconcile/run?gyId&date 触发日对账 返回差异清单
17 补偿 POST /platform/v1/replay 指定幂等键/区间重放 gyId、bizType、from、to

现状对应关系:getApartmentPersonDataByGyCode / ByWorkNo / ByTime、synFinanceData 是“中心被查询”的雏形;/yktgl/regist/addPersonInfo、/yktgl/jlgl/getMessageFromGy 是“中心被调用”的雏形。新接口应保留旧路径的兼容适配层,不直接改旧签名。

6.2 上报协议

信封结构(所有上行接口统一)

{
  "gyId": "TLXC",
  "appVersion": "1.0.0",
  "batchId": "uuid",
  "sentAt": "2026-11-07T10:00:00+08:00",
  "watermark": 102345,
  "items": [
    {
      "idempotencyKey": "hash(gyId+bizType+bizId+bizVersion)",
      "bizType": "DUTY_RESULT",
      "bizId": "JC20261107001",
      "bizVersion": 3,
      "occurredAt": "2026-11-07T09:58:12+08:00",
      "receivedAt": "2026-11-07T09:58:13+08:00",
      "payload": {}
    }
  ]
}

协议要点:

  1. occurredAt(现场发生时间)、receivedAt(公寓端入库时间)、serverReceivedAt(平台接收时间)三时间戳并存,用于处理时钟差异与迟到数据。
  2. idempotencyKey = hash(gyId + bizType + bizId + bizVersion):同一业务对象同一版本只生效一次;版本递增用于“更正上报”。
  3. watermark:公寓端本地自增序号,平台据此判断漏报/乱序并作为对账水位;现状 GY_SYN_JCXX_STATUS(0/1)可作为该思路的历史参照。
  4. 批量上限建议单批 ≤ 500 条、≤ 1MB,失败按条回报,避免整批重传。

6.3 幂等、重试、对账与失败处理

表 6-2 跨端可靠性机制

机制 设计
幂等 平台侧 (gyid, biz_type, biz_id, biz_version) 唯一约束;重复请求返回“已处理 + 原结果”
重试 指数退避(1s / 5s / 30s / 2min / 10min,上限 1 小时)+ 抖动;连续失败进入死信队列并触发公寓端告警
顺序 同一 bizId 按 bizVersion 单调;乱序到达丢弃旧版本并记录
对账 按日比对 count、sum(amount)、max(watermark) 三维;差异输出至“待人工处理”并可触发重放
补偿 平台支持“按区间重放”,公寓端支持“按 outbox 序号重发”,双侧均可主动发起
断网 outbox 落本地库(非内存),断网期间持续累积,恢复后按水位续传
平台不可用 不影响叫乘:下行使用本地快照(带版本与有效期),过期后仅降级“新计划不生效”并告警

7. 设备接入方案

7.1 接入形态

  1. 统一网关入口 /apt/dev/{deviceType}/register|heartbeat|event|command/ack,把现有 6 个 *Device 包的重复协议收敛为“网关 + 类型插件”(叫乘屏、签到机、房间屏、消费机、注册机、售货机)。
  2. 设备只连本公寓服务器,内网优先;公寓端不暴露公网入口。
  3. 协议保持现有 JSON 字段以兼容存量固件;新增字段一律可选并给默认值。

7.2 设备认证

表 7-1 设备认证阶段设计

阶段 机制
注册 deviceCode + 公寓激活码 首次绑定 gyid,生成一机一密(替换现状全局 baseConfig.devicePassword)
心跳 deviceCode + 时间戳 + nonce + HMAC(secret, body);校验时间窗(±5 分钟)与 nonce 去重,防重放
越权 deviceCode 与 gyid/房间不匹配直接拒绝并告警(现状仅校验存在性)
轮换 密钥支持在线轮换,旧密钥保留一个过渡期
过渡 存量设备保留“口令模式”开关,按公寓逐步切换为签名模式

7.3 心跳、指令与状态采集

表 7-2 心跳、指令与状态采集

能力 设计
心跳 设备上报版本、IP、房间号、配置版本;服务端返回 serverTime(校时)、apartmentName、configVersion、待执行指令列表
指令 下发—确认—重投:指令带 commandId + seq + expireAt,取走后置 DELIVERED,设备 ACK 后置 DONE;超时未 ACK 自动重投(上限 N 次),过期作废并告警(替代 deleted=1 一次性投递)
状态采集 设备上报在线/离线、软件版本、故障码、当前展示状态;公寓端按小时聚合,仅上报摘要
优先级 P0 叫乘相关(重投 5 次、不过期)、P1 房态刷新、P2 版本升级(可延后)
离线 设备离线超阈值产生“设备离线”告警,进入应用端盯控列表

7.4 告警处理

  1. 判定在公寓端:叫乘未应答、复叫未应答、叫乘结束未应答、超时未离寓、设备离线、AMI 不可用、串口异常、上报积压。
  2. 两级输出:本地即时告警(应用端弹窗/声响/TTS,走本地 WebSocket)与平台摘要上报(数量、类型、最近发生时间,不逐条上报)。
  3. 现有 GYGL_JGXX 与 is_jcbj / is_lybj 语义保留,作为本地告警事实表。

7.5 本地数据缓存

  1. 主数据缓存:人员(含照片)、交路、时间规则、节假日、房间属性,带 version + validUntil,过期只提示不阻断。
  2. 指令缓存:可靠队列(本地库表 + 状态机)。
  3. 事件缓存:设备事件先落本地(deviceCode + deviceEventId 幂等,沿用 GYGL_LY_EVENT 设计),再异步上报。
  4. 媒体缓存:离寓抓拍、录音本地保存 + 生命周期清理(沿用 leaveSnapshot.retentionDays / cleanupCron),平台只存索引并按需回捞。

7.6 上报边界

表 7-3 设备域数据上报与不上报

上报平台 不上报平台
设备清单与在线率摘要、版本分布、故障事件 原始心跳流水、每次指令明细
叫乘/复叫/应答/离寓执行结果(业务事件) AMI 通道事件、TTS 文本、串口字节流
报警摘要(类型、数量、时间) 每条报警的完整现场上下文
账务流水 余额中间态、实时读余额请求
归档摘要与对账水位 全量历史明细(按需回捞)

8. 部署与运行

8.1 部署建议

表 8-1 三端部署形态

端 形态 规模建议 关键依赖
平台端 无状态双实例 + Nginx + 平台主库(Kingbase/Oracle)+ Redis + 对象存储 2 实例起步;对外仅暴露 443 运安 WSDL、中心/财务系统
公寓端 + 应用端 单实例同进程,Nginx 前置,本地库 + 本地 Redis + Asterisk + 串口 1 公寓 1 实例;不允许水平扩容(WebSocket 进程内) 本地设备、AMI、串口、磁盘
前端 同一工程双入口:/apt(终端)、/duty(值班) 与公寓端同域部署,沿用 config.js 的 apiRoot = host 思路 —

隔离与网络:

  1. 一公寓一实例一库,Nginx 按公寓内网域名/端口区分;平台端不配置到公寓的路由。
  2. 跨端仅允许公寓 → 平台出站 HTTPS;平台侧以 gyId + 客户端证书/令牌双向认证。
  3. 反向代理必须透传真实 IP(兼容层仍需),并提前把 gyid 落到会话,逐步降低对 IP 的依赖。

8.2 非功能要求

表 8-2 非功能要求与实现要点

项 要求与做法
多公寓隔离 部署单元隔离 + 库隔离 + 设备绑定隔离 + 会话 gyid 强制注入;平台侧查询强制 gyId 参数并做权限校验
网络中断/弱网 叫乘主链路 100% 本地闭环(任务、AMI、设备、房态);下行快照带有效期;上行走 outbox 断点续传;补齐统一超时与熔断(现状 HttpRequest 无统一超时)
重复上报 幂等键 + 版本号 + 平台唯一约束;重复请求返回原结果,不产生二次账务
时钟差异 全端 NTP;心跳下发 serverTime;三时间戳并存;账务日切以平台时间为准;偏差 > 5s 在应用端显式告警
安全认证 设备一机一密 + HMAC;值班员走本地 RuoYi 会话 + 权限点;平台—公寓 mTLS 或双向令牌;数据库/AMI/设备口令外置到环境变量或配置中心并轮换
审计日志 三类审计:值班员操作审计(DUTY_*)、设备指令审计(下发/确认/重投/过期)、跨端接口审计(请求/响应摘要 + 幂等键 + 结果);保留期与查询入口在应用端可查
可观测性 指标:叫乘任务创建数与执行成功率、AMI 连接状态、会议桥占用、设备在线率、指令积压、outbox 积压、上报失败率、对账差异数、平台接口 P99;日志统一 SLF4J 并以 traceId / gyId 贯穿;健康检查区分“可叫乘”与“可上报”两个探针
容量与降级 归档与抓拍清理置于低峰;平台不可用时公寓端进入“离线模式”并横幅提示;上报积压超阈值时降级为仅上报 P0 事件

9. 迁移与实施路径

图 9-1 实施路径

flowchart LR
    S0["阶段零 基线修复"] --> S1["阶段一 现状梳理与边界确认"]
    S1 --> S2["阶段二 接口契约与数据模型设计"]
    S2 --> S3["阶段三 公寓端试点"]
    S3 --> S4["阶段四 多公寓推广"]
    S4 --> S5["阶段五 平台端收敛与旧逻辑下线"]
    S3 -.并行.-> S0

表 9-1 阶段零:基线修复(前置)

项 内容
目标 建立可信的编译、测试、安全基线,使后续拆分可验证
主要产出 修复 pom.xml 依赖版本错配;CI(编译 + 单测 + 关键 SQL 校验);口令与内网地址外置并轮换;关闭测试接口;补仓库根 .gitignore
验收标准 主干可稳定编译;测试可重复执行;仓库无明文口令
风险 版本修复可能暴露存量编译问题 → 单独分支验证,不与业务改动混提

表 9-2 阶段一:现状梳理与边界确认

项 内容
目标 锁定边界,不改业务逻辑
主要产出 表归属清单(每张 GY_* 表标注 owner 与写入模块);接口现状清单(jcgl/jlgl/regist/syndata/heartBeat 全量,标注设备用/值班用/中心用);JcglService 方法级职责地图(叫乘、房间、卡务、交路、归档五组);gyid 依赖点清单;待决策问题清单(见 10.2)
验收标准 任一表能回答“谁写、谁读、跨不跨端”;任一接口能回答目标归属;无悬空模块
风险 业务方对“房间属谁、余额属谁”认知不一致 → 安排两轮评审并签字定稿

表 9-3 阶段二:接口契约与数据模型设计

项 内容
目标 把第 5、6 章固化为可评审契约
主要产出 17 个跨端接口契约(含错误码、幂等语义、限流);上报信封与 outbox 表设计;主数据版本与快照表设计;任务下发/回执模型;平台主账与公寓流水模型;旧接口兼容适配层方案
验收标准 契约评审通过;Mock 服务完成“下行 → 复算 → 上报 → 对账”全链路联调;幂等与重试用例通过(重复投递、乱序、断网续传三类)
风险 契约反复变更 → 冻结版本号,变更走 v2 并保留 v1 至少两个公寓周期

表 9-4 阶段三:公寓端试点(1 个公寓)

项 内容
目标 单公寓端到端跑通,平台端仅提供主数据与计划
主要产出 RuoYi 公寓端骨架 + 设备网关 + 叫乘执行引擎 + 状态机 + outbox;应用端盯控台(从 JcXx.vue 抽取核心能力,先做“看 + 干预”);本地库 schema 与数据迁移脚本(机场只读双跑)
验收标准 断网 2 小时仍完成“入住 → 叫乘 → 复叫 → 报警 → 应答 → 离寓 → 归档”;恢复后 10 分钟内上报追平且对账零差异;叫乘准点率不低于现网;值班员操作步骤增加不超过 10% 且有记录
风险 RuoYi 与现有前端体验差异大 → 试点期保留旧值班台只读并行对照;固件不支持 ACK → 网关做“尽力确认”降级

表 9-5 阶段四:多公寓推广

项 内容
目标 复制到 3–5 个公寓,验证隔离能力与运维成本
主要产出 标准化部署包与一键初始化脚本(库/schema/配置/证书);公寓注册与版本管理;监控大盘(在线率、上报积压、对账差异);运维手册与故障预案
验收标准 单公寓部署 ≤ 4 小时;公寓间零串数据(跨 gyid 越权用例 100% 拦截);平台端可查看各公寓健康度与差异清单
风险 Oracle 存量公寓(byq/cc/dl/pj)SQL 兼容 → 试点避开或先做兼容层;网络质量差异 → 按公寓配置批量与重试参数

表 9-6 阶段五:平台端收敛与旧逻辑下线

项 内容
目标 平台端成为唯一业务与主数据入口,公寓端剥离平台职责
主要产出 syndata / ByxxResourceService / SynDataSchedule 从公寓端下线;regist 转发中心改为“本地写 + 上报”;jlgl 从中心拉取改为标准下行接口;xxtj / excel 跨公寓统计迁平台;getGyIdByIp 兼容层按公寓逐个关闭;kcgl、test、yatest、driver/{id} 明确处置
验收标准 公寓端不再连接运安与中心;平台端可独立出具跨公寓报表;旧接口调用量归零(按网关日志统计);回滚演练通过
风险 旧报表/旧终端仍依赖旧接口 → 提前一个周期盘点调用量,保留灰度通道

10. 风险与决策点

10.1 风险清单

表 10-1 风险与应对

风险 表现 应对建议
职责边界不清 房间归属、余额归属、餐饮是否碰余额反复讨论 阶段一产出归属矩阵并签字;争议项默认“业务在平台、事实在公寓”
数据不一致 平台余额与公寓缓存长期漂移;计划与任务时间不一致 日对账 + 水位 + 差异工单;规则版本化 + 公寓端复算回执
设备兼容 存量固件不支持签名/ACK;不同厂家协议差异 网关做协议适配层 + 能力协商(capabilities);保留口令模式开关;固件升级与网关改造解耦
双写/重复上报 迁移期新旧通道同时写;重试导致重复账务 迁移期用“影子上报”(只写不生效);幂等键 + 唯一约束兜底;账务类接口强制幂等
旧系统兼容 旧值班台、旧报表、旧终端依赖旧接口 网关级兼容层 + 调用量盘点 + 按公寓灰度下线
迁移回滚 新端上线后叫乘异常,需快速回退 数据只读双跑 → 按公寓粒度的切换开关 → 保留旧实例一个周期;回滚脚本与演练纳入验收
状态机多写 应用端与设备同时修改 ryzt 引发脏写 状态机唯一入口 + 条件更新(沿用 triggerLeaveAlarmIfPending 思路并推广)
时钟/时区 叫乘精确到秒,偏差导致误叫/漏叫 NTP 强约束 + serverTime 下发 + 偏差告警 + 三时间戳
单实例约束被忽视 公寓端为高可用随手扩容,导致 WebSocket/Quartz 重复执行 部署规范明确“公寓端单实例”;若必须扩容,先做推送广播 + Quartz 持久化 + 任务抢占
权限体系冲突 平台 GL_* 与 RuoYi sys_* 并存导致账号混乱 两套 RBAC 各自管理,用“人员—账号映射表”打通;值班员登录只走公寓端
构建基线不稳 pom.xml 版本错配导致新工程无法编译验证 阶段零修复依赖并建立 CI,先于一切拆分动作
安全暴露 测试接口、明文口令、全局设备口令 生产关闭 /test、/jcgl/yatest、/jcgl/driver/*;口令外置轮换;设备改一机一密

10.2 待决策点

表 10-2 待决策点与建议

# 决策点 建议
D1 餐饮归属 业务平台化;扣款走账务接口,禁止公寓端直接改余额(当前 MealsService 直改余额必须改)
D2 余额主账位置 平台主账 + 公寓缓存;离线消费允许本地记账并上报
D3 房间主数据归属 平台存基线(gyid + roomNo + 床位数),物理属性(楼层/朝向/SIP)公寓维护并上报
D4 运安接入位置 只在平台端接入;公寓端不再持有 WSDL(同时解除“通辽南”硬编码的多公寓障碍)
D5 是否保留“一实例多公寓” 目标架构下取消;存量多公寓共享库(tl/sjt 共用库)在阶段四拆分
D6 应用端是否独立前端工程 与公寓端同一工程双入口,按角色裁剪路由与菜单
D7 交路人工维护落点 平台维护模板,公寓可“应急新增”并上报确认
D8 叫乘时间以谁为准 平台下发“计划 + 规则版本”,公寓端复算执行,不一致告警
D9 Oracle 存量公寓 明确保留期与迁移批次,避免新端并行维护两套 SQL
D10 kcgl 库存边界 独立处置,不进入公寓端

11. 结论与优先级

11.1 总体结论

  1. 拆分方向可行,且现状已有雏形。centerServerUrl 的双向调用、getApartmentPersonData* / synFinanceData、GY_SYN_JCXX_STATUS 状态位,本质是“平台—公寓”关系未完成的形态;本次重构是把隐式关系显式化,而非推倒重建。
  2. 最大障碍不是技术选型,而是三件事:公寓身份(IP 推断 → 部署绑定)、数据归属(共享库 → 库隔离)、状态写入口分散(多写 → 单一状态机)。
  3. 公寓端用 RuoYi 新建是合理的。设备网关、执行引擎、上报器、值班 API 天然属于“管理后台 + 本地接入”形态,可复用 RBAC、定时任务、代码生成;但必须约定“RuoYi 管本地账号、平台管全局账号”,否则权限体系会打架。
  4. 应用端不独立是正确的。值班员的全部操作都必须落在公寓本地事实库上,独立服务只会带来跨服务事务与延迟;同代码同库 + 模块边界 + 状态机单入口足以支撑。
  5. 必须先做阶段零。pom.xml 依赖错配会让任何新工程无法建立可信基线,明文口令入库是安全红线;这两项不解决,拆分过程无法验收。

11.2 推荐落地顺序

表 11-1 优先级与落地顺序

优先级 事项 理由
P0-1 修复 pom.xml 版本错配;建立编译/单测/CI 基线 没有基线就没有“拆分正确性”
P0-2 口令与内网地址外置、轮换;关闭测试接口 安全红线,改造成本低
P0-3 产出表归属矩阵 + 接口归属清单 + JcglService 职责地图 后续所有设计的输入
P1-1 17 个跨端接口契约 + 上报信封 + outbox 模型 决定拆分能否落地
P1-2 公寓端设备网关(一机一密 + 指令 ACK + 离线队列) 现场稳定性收益最直接
P1-3 叫乘状态机单一入口 + 应用端盯控台(基于 JcXx.vue 抽取) 降低同库后脏写风险
P2-1 账务:平台主账 + 公寓流水 + 日对账;餐饮改走账务接口 数据一致性风险最高的一环
P2-2 运安接入上收平台,公寓端仅消费计划 解除多公寓匹配限制
P2-3 单公寓试点 → 多公寓推广 → 旧逻辑下线与回滚演练 控制现场风险

11.3 后续动作

  1. 以第 1、4、5 章为模板,产出《表归属矩阵》与《接口归属清单》两份工作底稿。
  2. 以第 6 章为蓝本,先冻结 v1 契约(含错误码与幂等语义),再进入任何编码。
  3. 以第 3.3 节为基础,明确“值班员可写字段白名单”,作为 Code Review 检查项。
  4. 本文落盘后,在 docs/README.md 与 docs/09-迭代指引与风险清单.md 中建立索引。

附录 A 术语表

表 A-1 术语表

术语 说明
平台端 提供主数据、运安计划、账务主账、餐饮、跨公寓报表与审计的中心服务
公寓端 部署在某公寓现场、负责设备接入与叫乘执行的本地服务(基于 RuoYi 新建)
应用端 与公寓端同代码同库、面向值班员的盯控与操作界面,不是独立服务或独立库
执行域 / 操作域 同一库内的两类数据与模块:执行域由执行引擎与设备网关写;操作域记录人工干预与审核
水位(watermark) 公寓端上报序号,用于判断漏报、乱序与对账进度
幂等键 同一业务对象同一版本仅生效一次的去重标识
快照版本 下行主数据/规则的版本号,公寓端据此判断是否过期
影子上报 迁移期只上报不生效的写入通道,用于验证新链路而不改变业务结果

附录 B 图表清单

表 B-1 图表索引

编号 名称 位置
表 0-1 文档信息 0 章
表 0-2 修订记录 0 章
表 1-1 现状事实与拆分影响 1.1
表 1-2 主要模块定位与目标归属 1.2
图 2-1 目标逻辑架构 2.1
图 2-2 部署拓扑 2.2
表 2-1 三端调用关系与数据流 2.3
表 3-1 应用端与公寓端的逻辑分工 3.3
表 4-1 能力归属决策表 4.1
表 4-2 平台端模块清单 4.2
表 4-3 公寓端模块清单 4.3
表 5-1 数据分层、归属与同步方向 5.1
表 5-2 各场景一致性策略 5.2
表 6-1 平台端与公寓端关键接口 6.1
表 6-2 跨端可靠性机制 6.3
表 7-1 设备认证阶段设计 7.2
表 7-2 心跳、指令与状态采集 7.3
表 7-3 设备域数据上报与不上报 7.6
表 8-1 三端部署形态 8.1
表 8-2 非功能要求与实现要点 8.2
图 9-1 实施路径 9 章
表 9-1 ~ 9-6 各阶段目标/产出/验收/风险 9 章
表 10-1 风险与应对 10.1
表 10-2 待决策点与建议 10.2
表 11-1 优先级与落地顺序 11.2

附录 C 代码证据索引

表 C-1 本文引用证据的代码位置

证据 位置 用途
注册转发中心 jcgl/service/JcglService.java(centerServerUrl + /yktgl/regist/addPersonInfo) 证明平台/公寓同源、需切接口契约
交路从中心拉取 jlgl/service/JlGlService.java(getMessageFromGy) 证明已有下行雏形
IP→公寓解析 zdwh/service/ZdwhService.java(getGyIdByIp / getUniqueGyByIp) 公寓身份改造对象
设备指令一次性投递 heartBeat/service/HeartBeatService.java 指令可靠性与 ACK 改造依据
设备全局口令 6 个 *Device 服务中的 baseConfig.devicePassword 一机一密改造依据
叫乘调度 quartz/SchedulerManager.java、quartz/WakeUpJob.java、schedule/WakeupJobRecoveryRunner.java 公寓端执行引擎范围
定时任务混合 schedule/JcSchedule.java、schedule/SynDataSchedule.java 任务上收/下沉划分依据
WebSocket 进程内实现 websockets/JcWebsocket.java 单实例约束与推送改造依据
餐饮改余额 MealsOrdering/service/MealsService.java(updateMoney) 餐饮与账务解耦依据
中心侧汇总接口 syndata/controller/SynPersonDataController.java(getApartmentPersonDataByGyCode / ByWorkNo / ByTime、synFinanceData) 平台化接口的现状参照
设备业务协议 callingDevice / checkInDevice / roomDevice / payDevice / registDevice / vendPayDevice 网关收敛范围
前端部署硬编码 YktVue/public/config.js、YktVue/vue.config.js 双入口前端与公寓绑定的依据
值班主页面 YktVue/src/views/JcXx.vue 应用端拆分骨架
构建依赖错配 yktgl/pom.xml 阶段零修复项
多公寓部署差异 yktgl/src/main/resources/application-*.yml 库隔离与 Profile 收敛依据

附录 D 文档维护约定

  1. 本文为设计方案,实施过程中若与代码现状出现偏差,以代码为准并同步更新本文,不得反向以文档为借口修改既有约定。
  2. 新增/调整端职责、模块划分、跨端接口时,同步更新第 3、4、6 章与附录 B 的图表清单。
  3. 每个迁移阶段结束,在第 9 章对应阶段表下追加“实际完成情况”与偏差说明。
  4. 决策点在 10.2 定稿后,从“待决策”移入正文对应章节,并保留决策时间与决策人。