docs/:系统梳理、架构优化方案、CR-02 三端功能设计修订(含 §15 三端一致性同步与平台统计分析)、公寓端/应用端/平台端分册、公寓统计分析与排名报表、公寓端小步迭代开发计划(IT-0~IT-8) dev/:RuoYi-Vue-master(后端)与 RuoYi-Vue2-master(前端)官方上游基线,未改动
46 KiB
05 关键流程
追溯:
docs/10§7.7(语音链路拓扑)、§7.9 表 7-5(事件与状态迁移)、§7.11 表 7-7(自检与巡检)、 §6.2(上报信封)、§6.3 表 6-2(幂等/重试/对账)、§5.5 表 5-5(分机配置一致性)、§3.3(人工干预边界)。 流程中的状态迁移以03§3.2 表 3-10 为准。 v2 修订(CR-02,2026-11-09):8 条关键流程变更以docs/设计变更/03-三端功能设计修订(CR-02).md§7 为权威,见下文 §0;表 5-1 第 4 行的jcsj口径按 R-C9 同步纠正;§12 补遗(F-F 注册链路改判、F-J 人脸数据下发)以docs/公寓端/10为流程权威表述。
0. v2 流程变更索引(CR-02)
本节图表用独立编号
表 C-y,不占用本文件表 5-y序号;§1~§8 原流程继续有效,本节只列增量与改判。
表 C-1 本端流程变更落点(F-A~F-Q)
| 编号 | 流程 | 改动 | 涉及原章节 |
|---|---|---|---|
| F-A | 双模式与顺序派发 | §1 / §2 增 call_mode=TABLET 分支;按 jcsj 生成单调 dispatch_seq,平板按游标拉取 |
§1、§2、§3 |
| F-B | 平板结果回写 | 状态机新增 TABLET_RESULT 事件源;VERIFIED / UNVERIFIED / SKIPPED 分支;只提交命令 |
§2 |
| F-C | 换乘 | 本地重算时刻 + 换房联动 + apt_sip_binding 联动 + #8 / #9 上报 |
§1、§7 |
| F-D | 断网本地充值 / 扣补贴 | 离线额度校验、本地余额 CAS、恢复后先派 outbox 再拉 #7、冲正 | §6 |
| F-E | 上报历史与续报 | outbox 仍为队列,新增 apt_report_history / apt_report_retry_batch,续报复用原幂等键 |
§6 |
| F-F | 人员注册(v1.3 由 CR-C25 改判) | 签到终端 REG_APPLY → 值班台待办 → 值班员 CONFIRM(生成 ryid、入 apt_master_person)→ 并行双路:#9 上传平台 / FACE_ISSUE 下发公寓内设备;平台回执降级为同步回执,不再是生效前置 |
docs/公寓端/10 §4、§5 |
| F-G | 保洁 / 排班 / 考核 | 现场记录、班次与日终本地计算 | §7 |
| F-H | 设备报警分流 | 设备报警独立判定并落 apt_device_alarm,与叫乘 / 离寓报警分离 |
§3 |
| F-I | SIP 分机注册离线告警 | call_mode='SIP' 派发前按 jcid → fjh → apt_sip_binding → apt_sip_endpoint 解析房间主分机;注册态非 ONLINE(或 last_reg_at 超阈值)且持续超阈值时,按 alarm_event_key 去重写入 apt_device_alarm(alarmSource=DEVICE、alarmType=OFFLINE),推 device.alarm、#12 上报;不阻断叫乘,失败原因记 apt_call_session.hangup_cause。恢复时写新流水 + cleared_at + alarm.cleared,只追加不清零 |
§1、§3、§4 |
| F-J | 人脸数据下发管理(CR-02 §12) | 平台增量下载入库、签到设备全字段下发、消费 / 叫乘按 gy_sb.face_scope_* 隔离、TRANSIENT 离寓自动 FACE_ERASE、LONG_TERM 独立分区长期保留;三级版本与 hash 对账 + FACE_FULL_SYNC 兜底。与 F-F 的注册链路衔接 |
docs/公寓端/10 §3、§5~§10 |
| F-K | 人员入住作业流程(CR-02 §13) | 注册与签到 → 入住申请(房间 / 交路)→ 值班员审核与房间调整(CHECKED_IN)→ #9 CHECKIN 提报与平台运安匹配(#6 / #8 / #7)→ #7 拉取叫乘任务并复算 jcsj 进入叫乘;"已入住"为流程态 + 业务事实双重表达,不新增 gy_jcxx 状态字段 |
docs/公寓端/11 §2~§8、§10、本文件 §10 |
| F-L | 人员消费(CR-02 §14) | 终端按 PUBLISHED 食谱选菜并显示金额 → N-49 查补贴 / 现金额度 → "补贴优先、现金补足"双额度 CAS 扣减且一笔消费只记一条 CONSUME 流水 → #10 LEDGER_OFFLINE 上报 → 平台 platform-ledger 归日并更新人员账户 → #16 日对账置 RECONCILED;合计不足全额拒绝 |
docs/公寓端/12 §4、§7、本文件 §6(F-D)、§11 |
| F-M | 人员线下充值(CR-02 §14) | 扫公寓线下二维码(只识别公寓、非支付)→ 签到终端 N-52 提交现金充值申请(申请表不存金额)→ 管理员 N-54 二次确认 → apt.ledger.local 只增 xjye 并写 gy_ykt_xjczjl(channel=OFFLINE_CASH) → #10 同步平台;不建支付订单与回调 |
docs/公寓端/12 §5、§7、本文件 §6(F-D)、§11 |
| F-N | 公寓菜品管理(CR-02 §14) | 公寓管理员 N-57 发布阶段性食谱(平台库 YKT_MEALS 补列、recipe_version 单调)→ #4 recipes[] 下行 → 消费终端 N-48 按 version 主动拉取并缓存 → 点击查看菜品、加入选择菜单(确认前不落库);远程点菜仅留 N-58 入口,本期恒 40940 |
docs/公寓端/12 §6、§7、本文件 §11 |
口径纠正(R-C9 / CR-C06):jcsj 及其派生时刻恒由公寓按 apt_master_rule + apt_holiday 复算,平台不产出权威值;只有要素(kcsj / jcfs)与平台不一致时才以平台为准并告警。
三条不可违反规则不变:① 只经 apt.duty.state,任何新事件源(平板结果、换乘、报警)都只提交命令;② 条件更新带期望态;③ 已结束不回写。
补遗指针(CR-02 §11 / §12 / §13 / §14 / §15):F-A / F-B 两类叫乘实现方式的端到端流程(触发条件、交互时序、状态上报机制、结果反馈路径)见本文件 §9;§9 为流程权威表述,本节索引的 F-A
F-N 本端流程骨架不变。人员注册(F-F)与人脸数据下发(F-J)的流程权威表述见 **§10**;注册链路按 CR-C25 改判为"签到终端申请 → 值班员确认 → 入公寓服务系统 → 分别上传平台 / 下发设备",平台回执不再是注册生效前置。人员入住作业流程(F-K)见本文件 §10 章节指针与docs/公寓端/10§4、§3docs/公寓端/11唯一权威表述。消费 / 充值 / 菜品管理(F-L / F-M / F-N)见本文件 §11 章节指针与docs/公寓端/12唯一权威表述;三条流程共用 §6 的 F-D 账务闭环,不新造账务闭环。 三端一致性与平台统计(CR-02 §15):表 C-1 标题按全局流程编号扩至 F-A~F-Q,其中 F-A~F-N 本端流程骨架不变,新增F-O/F-P/F-Q为平台侧流程(见docs/平台端/06§0 表 C-1),本端不感知统计、不新增上报义务;三端状态映射与数据同步机制以 CR-02 §15 表 3-66 为唯一权威,四能力业务规则 / 交互 / 权限 / 异常三端对照见 §15 表 3-65。平台新增docs/平台端/10「公寓统计分析与排名报表」,统计结果不回写本端任何业务状态;#13ARCHIVE摘要仅按payload扩展分组计数(见docs/公寓端/09§0 表 C-9),不新增bizType与上报接口。
1. 计划下行与叫乘任务生成
sequenceDiagram
participant P as 平台端
participant M as apt-master-client
participant DB as 本地库
participant E as apt-dispatch
P->>M: GET /platform/v1/plans/duty(gyId, from, to)
M->>DB: 校验 apt_master_version 中 ROUTE/RULE 版本
alt 版本过期
M->>DB: 记 apt_master_version(FAILED, fail_reason)
M-->>P: 拒绝接收,触发全量重拉
else 版本一致
M->>DB: upsert gy_syn_jcxx(plan_key 幂等)
M->>DB: 更新 gy_syn_jcxx_status(watermark)
E->>DB: 按 apt_master_rule 复算 jcsj/fjsj/jcbjsj
E->>DB: 生成/更新 gy_jcxx(ryzt=0 待叫乘)
E->>M: 复算差异(超阈值告警)
M-->>P: POST /ack/tasks(accepted + computedCallTime)
end
图 5-1 计划下行与任务生成
表 5-1 步骤与失败处理
| 步骤 | 动作 | 幂等键 | 失败处理 | 依据 |
|---|---|---|---|---|
| 1 | 拉取计划 | gyId + planId + version |
网络失败退避重试(1s/5s/30s/2min/10min) | 表 6-2 重试行 |
| 2 | 版本校验 | apt_master_version(master_type, version_no) |
版本过期 → 拒绝任务 + 全量重拉 + 告警 | 表 5-2 第 2 行 |
| 3 | 落库计划快照 | gy_syn_jcxx.plan_key |
冲突则按 version 覆盖 |
docs/10 §5.2 |
| 4 | 本地复算 | gy_jcxx.jcid(= 公寓分配的任务业务键,不是"计划侧业务键";id 为代理键) |
要素(kcsj / jcfs)与平台不一致 → 以平台为准 + 告警;执行时刻 jcsj 及其派生恒以本地按规则快照复算为准(平台不产出权威 jcsj) |
D8'、R-C9 / R-C10、CR-02 CR-C06;表 5-2 第 6 行 |
| 5 | 回执 | taskId + version |
回执失败不影响执行(outbox 累积) | 表 6-1 #8 |
边界:公寓端不做"计划转换为任务"的规则定义(docs/10 表 4-1 任务生成行:平台 ● / 公寓 ○ 复算校验),
只做复算与回执。
2. 叫乘执行(任务 → AMI → 会议桥 → 事件 → 状态机)
sequenceDiagram
participant Q as Quartz(apt-dispatch)
participant S as apt.duty.state
participant V as apt.voice.event
participant A as apt.voice.ami
participant AST as Asterisk
participant DB as 本地库
Q->>Q: 到期扫描 gy_jcxx(ryzt=0, stoped=0, jcsj<=now)
Q->>S: command(CALL_START, jcid)
S->>DB: 条件更新 ryzt 0→1, jcsj_s=now(3)
Q->>V: originate(room, console)
V->>A: Originate PJSIP/room + PJSIP/console
A->>AST: AMI 命令
AST-->>A: OriginateResponse(Success/Failure)
A-->>V: 事件
alt Success
AST-->>A: ConfbridgeJoin(Conf-01, PJSIP/room)
A-->>V: 入会事件
V->>DB: 写 apt_call_session(state=JOINED_CONF, join_at)
V->>S: command(ANSWERED, jcid)
S->>DB: 条件更新 ryzt→3, hjxysj, finish_jc='1'
V->>DB: 生成 apt_tts_utterance + apt_recording 索引
else Failure
A-->>V: 失败原因
V->>S: command(CALL_FAILED, jcid)
S->>DB: 条件更新 ryzt→2, jcbjsj_s, is_jcbj='1'
V->>DB: 写 gy_bjxx(NO_ANSWER)
end
图 5-2 叫乘执行与状态回写
表 5-2 关键判定与口径(docs/10 §7.9)
| 判定 | 口径 | 落点 |
|---|---|---|
| 接通判定 | 用 ConfbridgeJoin,不是 Answer |
apt_call_session.join_at |
| 无应答超时 | 30s 内无 ConfbridgeJoin 且通道不存在 |
ryzt→2 + gy_bjxx(TIMEOUT) |
| 接通即断 | 入会后 < 3s Hangup |
判异常中断,触发复叫 + 告警 |
| 会议桥不可用 | ConfBridge 应用不存在或入会失败 |
直接转值班台兜底(/ws/duty 推送) |
| 挂断原因 | 16 正常 / 17 忙 / 18 无应答 / 19 不可达 / 21 拒绝,其余记"未知"+ 原值 |
apt_call_session.hangup_cause |
| 复叫 | 复叫判定 35s;接听后自动挂断 40s;喊话 30s | gy_jcxx.fjsj_s |
| 事件丢失兜底 | 每 5 分钟 core show channels concise 与在途会话比对 |
有库无通道 → HANGUP(UNKNOWN);有通道无库 → 孤儿通道告警 |
三条不可违反的规则:
- 只经状态机:
apt.voice.event不直接update gy_jcxx,只提交命令给apt.duty.state(docs/10表 4-4)。 - 条件更新:所有状态更新带
where id=? and ryzt=<期望值>,避免"先查后改"脏写(表 10-1 状态机多写行)。 - 已结束不回写:
finish_jc='1'后迟到事件只写apt_call_event(03§3.2 保护语义)。
3. 设备接入(注册 / 心跳 / 指令 ACK)
sequenceDiagram
participant D as 现场设备
participant G as apt.device.gateway
participant C as apt.device.command
participant DB as 本地库
D->>G: POST /open/v1/device/register(deviceCode + 激活码)
G->>DB: 写入 gy_sb(gyid + deviceCode 绑定)
G-->>D: 返回 secret(一机一密)+ serverTime
loop 每次心跳
D->>G: POST /open/v1/device/heartbeat(HMAC(secret, body))
G->>G: 校验时间窗 ±5min + nonce 去重 + gyid 绑定
G->>DB: upsert gy_sb_xt(version/ip/heartbeat_at/clock_skew_ms)
G->>C: 取待投递指令(priority, next_send_at)
C->>DB: state PENDING→SENT, sent_at
G-->>D: {serverTime, commands[]}
D->>G: POST /open/v1/device/command/ack(commandId, result)
G->>C: state SENT→ACKED, ack_at/ack_result
end
图 5-3 设备接入与指令闭环
表 5-3 与 docs/10 §7.2、§7.3 的对应与本期边界
| 能力 | 目标设计(docs/10) |
本期实现 | 未实现时的行为 |
|---|---|---|---|
| 注册认证 | 一机一密,替换全局口令 | 否(依赖固件与协议确认) | 保留口令模式开关;/open/** 仍为占位 |
| 心跳 | HMAC + 时间窗 + nonce 去重 | 否(同上) | 只落库(gy_sb_xt),不校验签名 |
| 指令 | 下发—ACK—重投—过期,P0 重投 5 次不过期 | 仅入队 | apt_device_command.state=PENDING,不发送 |
| 状态采集 | 在线/离线、版本、故障码,按小时聚合只报摘要 | 是(落库 + 摘要) | — |
| 离线告警 | 超阈值产生"设备离线"告警进盯控列表 | 是(gy_bjxx) |
— |
诚实的边界:在设备协议、固件 ACK 能力、连通性三项确认前,接口只写队列,不伪造 SENT/ACKED(04 §7 第 8 条)。
页面必须显示"已入队,待协议确认"。
4. 语音事件、录音索引与 TTS
flowchart TB
A["AMI 事件到达"] --> B{"事件类型"}
B -->|OriginateResponse| C["apt_call_session: CALLING→FAILED 或继续"]
B -->|Newstate| D["CALLING→RINGING, 记 ring_at"]
B -->|ConfbridgeJoin| E["RINGING→JOINED_CONF, 记 join_at"]
B -->|ConfbridgeLeave| F["JOINED_CONF→LEFT, 记 leave_at"]
B -->|Hangup| G["任意→HANGUP, 记 hangup_at/cause/duration"]
B -->|Disconnect| H["在途会话标 UNKNOWN, apt_ast_ami_session 记断连"]
E --> I["提交状态机命令 ANSWERED"]
E --> J["生成 apt_tts_utterance(seq 递增)"]
E --> K["录音:事件带 recordfile 则写 apt_recording(AVAILABLE)"]
K --> L{"无 recordfile"}
L -->|是| M["按文件名约定反查目录 → 有则 AVAILABLE,无则 MISSING + 告警"]
G --> N["提交状态机命令 HANGUP"]
图 5-4 事件到业务状态与媒体索引
表 5-4 录音与 TTS 的回写规则(docs/10 §7.9 录音/TTS 表)
| 能力 | 触发时机 | 成功判定 | 失败回写 | 本表落点 |
|---|---|---|---|---|
| 录音 | 房间侧入会(Asterisk 侧策略) | 事件带 recordfile 或目录存在文件 |
state=MISSING + 告警,不影响叫乘结论 |
apt_recording |
| TTS | 入会后、播放前 | Playback 成功且 PLAYING→DONE |
state=FAILED + 原因,可人工重播(source=TEST) |
apt_tts_utterance |
| 复叫 TTS | 复叫入会后 | 同上,seq 递增 |
同上 | 同上 |
| 清理 | 每日低峰(0 30 2 * * ?) |
先置 PURGED 再删文件 |
失败重试 + 告警 | apt_recording |
四条设计约束:
gy_jcxx.recordfile只读兼容:新会话只写apt_recording,不再拼逗号串(表 5-3 处理关系第 2 条)。- TTS 不依赖内存槽位:改用
apt_tts_utterance队列,避免conftts单槽位并发覆盖(表 10-3 TTS 行)。 - 录音不阻断叫乘:
MISSING只告警,不改变gy_jcxx状态。 - AMI 断开:在途会话标
UNKNOWN,由 5 分钟巡检判定终态(表 7-5AMI Disconnect行)。
5. 主数据下行与快照生效
flowchart LR
A["公寓端定时拉取(下行一律拉,平台不推)"] --> B["校验格式与 checksum"]
B --> C{"version > 本地?"}
C -->|否| D["丢弃 + 记日志(幂等)"]
C -->|是| E["事务:写快照 + apt_master_version(APPLIED)"]
E --> F{"apply_result"}
F -->|FAILED| G["保留旧快照 + 告警 + 不接收新任务"]
F -->|APPLIED| H["更新 apt_master_version.applied_at/expires_at"]
H --> I["通知依赖模块刷新缓存"]
I --> J{"过期未续?"}
J -->|是| K["仅降级:新计划不生效 + 告警(不阻断叫乘)"]
图 5-5 快照生效与过期降级
表 5-5 快照域的一致性要求(docs/10 表 5-1、表 5-2 第 2 行)
| 快照 | 版本键 | 生效方式 | 过期后果 |
|---|---|---|---|
| 公寓档案 | (gyid, APARTMENT, source, version) |
全量覆盖(单行) | 告警 |
| 房间基线 | (gyid, ROOM, source, version) |
全量覆盖(按 room_no upsert) |
新房间不生效 |
| 人员 | (gyid, PERSON, source, version) |
增量 upsert + deleted 标记 |
新人员无法叫乘(已有记录不受影响) |
| 交路 | (gyid, ROUTE, source, version) |
全量覆盖 | 新交路不生效,已生成任务照常执行 |
| 规则/节假日 | 同上 | 全量覆盖 | 保持最后已知版本,仅告警 |
三条原则:
- 快照只读:业务模块不得写
apt_master_*(03表 3-1)。 - 版本不一致拒绝任务,不是拒绝启动(
docs/10表 5-2 第 2 行)。 - 过期只降级不阻断:叫乘主链路必须能离线跑(表 7-6 第 1 行)。
6. 上报 outbox 与重试对账
sequenceDiagram
participant B as 业务模块
participant O as apt-report.outbox
participant DB as 本地库
participant P as 平台端
B->>O: enqueue(bizType, bizId, bizVersion, payload)
O->>DB: insert apt_report_outbox(watermark 自增, idempotencyKey)
loop 定时派发(按 watermark 升序)
O->>DB: 取 PENDING/FAILED 且 next_retry_at<=now(批量 ≤500)
O->>P: POST /platform/v1/report/**
alt 成功
O->>DB: state=SENT, sent_at, platform_recv_at
O->>DB: 更新 apt_report_watermark(acked_watermark)
else 失败
O->>DB: retry_count+1, next_retry_at=退避+抖动
O->>DB: 连续失败 → FAILED → DEAD + 告警
end
end
P-->>O: 日对账结果(count / sum / max watermark)
O->>DB: 差异写告警,人工触发 replay
图 5-6 outbox 派发与对账
表 5-6 可靠性机制(docs/10 表 6-2)
| 机制 | 设计 | 落点 |
|---|---|---|
| 幂等 | hash(gyid+bizType+bizId+bizVersion) 唯一 |
uk_outbox_idem |
| 重试 | 1s / 5s / 30s / 2min / 10min,上限 1 小时 + 抖动 | next_retry_at |
| 顺序 | 同 bizId 按 bizVersion 单调;乱序丢弃旧版本 |
派发前比对 biz_version |
| 断网 | 落本地库持续累积 | state=PENDING |
| 降级 | 积压超阈值只上报 P0 | 派发查询加 priority 过滤(biz_type 白名单) |
| 对账 | 日比对 count、sum(amount)、max(watermark) |
平台侧执行,公寓端接差异 |
本期边界:平台接收端未就绪时,outbox 只累积不发送(state 停在 PENDING),这也是可验证的:
联调前置条件满足后,把派发开关打开即可,不需要改业务代码。
7. 值班台人工干预
sequenceDiagram
participant U as 值班员(duty 入口)
participant C as apt-duty.command
participant S as apt.duty.state
participant DB as 本地库
U->>C: POST /duty/call/{jcid}/commands(commandId, STOP)
C->>DB: 校验权限点 + gyid
C->>DB: insert duty_manual_action(action_id 幂等, ACCEPTED)
C->>S: 提交状态机命令
alt 命令合法
S->>DB: 条件更新 gy_jcxx(ryzt/stoped/…)
S->>DB: duty_manual_action → DONE
S->>DB: duty_operation_log(谁/何时/对谁/做了什么)
C-->>U: accepted + stateAfter
else 状态不允许
S-->>C: 拒绝(APT_STATE_ILLEGAL)
C->>DB: duty_manual_action → FAILED + result
C-->>U: 409 + 原因
end
图 5-7 人工干预链路(docs/10 §2.5 结尾、§3.3 表 3-1)
表 5-7 干预动作与审计
| 动作 | 目标 | 允许的当前状态 | 审计 | 备注 |
|---|---|---|---|---|
STOP 停止叫乘 |
gy_jcxx |
ryzt in (1,2)、finish_ly='0' |
duty_operation_log + duty_manual_action |
— |
RE_CALL 复叫 |
gy_jcxx |
stoped='1' 或 ryzt=2 |
同上 | 生成新会话 |
FORCE_FINISH 强制结束 |
gy_jcxx |
finish_ly='0' |
同上 | 不置离寓 |
MARK_LEAVE 登记离寓 |
gy_jcxx + gygl_ly_event |
finish_ly='0' |
同上 | leave_type=MANUAL |
HANGUP 挂断 |
apt_call_session |
state in (CALLING,RINGING,JOINED_CONF) |
同上 | 表 6-3 #14 |
为什么必须两层表:duty_manual_action 记录"命令意图与结果"(可幂等、可重试、可追责),
duty_operation_log 记录"审计事实"(可查询、可导出、保留期独立)。两者不合并,原因是审计表可能被归档,
而命令表需要长期保留以支持重试与幂等判断(docs/10 §2.5 结尾)。
8. 启动自检与运行期巡检
表 5-8 自检项(docs/10 表 7-7 的落地)
| # | 检查项 | 判定 | 失败级别 | 落点 |
|---|---|---|---|---|
| 1 | AMI 可达与登录 | TCP + login() |
BLOCKED | apt_ast_ami_session / apt_ops_selfcheck |
| 2 | Asterisk 版本与能力 | core show version |
DEGRADED | 同上 |
| 3 | 会议桥存在 | Conf-01 可用 |
BLOCKED | 同上 |
| 4 | 拨号计划上下文 | from-internal 含 1901/1701 |
BLOCKED | 同上 |
| 5 | 值班台分机在册且注册 | CONSOLE 类型 + 注册状态 |
DEGRADED | apt_sip_endpoint |
| 6 | 台账与 Asterisk 一致 | pjsip show endpoints 比对 |
DEGRADED | apt_ast_drift |
| 7 | 录音目录可写与空间 | 试写 + 剩余 > 阈值 | DEGRADED | apt_ops_selfcheck |
| 8 | 录音播放地址可达 | recording.base-url 200 |
DEGRADED | 同上 |
| 9 | TTS 通道可用 | 试播 TEST |
DEGRADED | apt_tts_utterance |
| 10 | 串口可打开 | console.port |
DEGRADED | apt_ops_selfcheck |
| 11 | 时钟偏差 | NTP < 1s | DEGRADED | 同上 |
| 12 | AMI 事件滞后 | last_event_at 差 |
DEGRADED | apt_ast_ami_session |
可叫乘探针的判定:BLOCKED 项任一失败 → /apt/ops/health/call-ready 返回 callReady=false + 未就绪原因列表;
DEGRADED 项失败 → 仍 callReady=true,但响应带 degraded[](对应表 6-3 要点 4:"健康探针分两个")。
9. 叫乘两类实现方式的端到端业务流程
追溯:
docs/公寓端/00表 0-3(A-06 / A-07 / A-08)、docs/10§7.7(语音链路拓扑)、§7.9 表 7-5(事件到业务状态)、表 7-6(本地闭环)、docs/设计变更/03§7.1 F-A / §7.2 F-B、§10 F-I、docs/公寓端/04§0 表 C-2、docs/应用端/04表 4-12。 定位:本节是 A-06A-08 的流程权威表述。§1(任务生成)、§2(SIP 执行与状态机)、§4(语音事件与媒体)、§6(outbox)、§7(人工干预)的骨架不变,本节把"触发条件 → 交互流程 → 状态上报 → 结果反馈"串成两条端到端链路,并补齐此前未展开的平板本地定时播放环节。本节图表沿用本文件主序号表 5-95-21、图 5-8~5-9;§0 补遗使用独立的表 C-y,两者不混用。
9.1 方式对照与模式选择
表 5-9 两类叫乘方式对照
| 维度 | 第一类:SIP 语音叫乘 | 第二类:平板叫乘 |
|---|---|---|
| 执行主体 | Asterisk 主动发起呼叫(Originate),房间 SIP 终端接听 |
平板拉取任务后本地定时播放语音 |
| 触发 | 服务端 Quartz 到 jcsj 扫描,或值班员人工发起 |
服务端生成任务 + 平板拉取 + 平板本地到 jcsj |
| 应答 / 完成判据 | AMI ConfbridgeJoin(房间侧入会) |
平板刷脸签到 faceVerifyState=VERIFIED |
| 提示语音 | 入会后 Playback(tts),落 apt_tts_utterance |
平板本地合成 / 播放,语音文件不出公寓服务端 |
| 状态来源 | 业务系统依据 AMI 事件推断 | 平板上报叫乘结果 |
| 结果上报路径 | AMI → apt.voice.event → 状态机命令 → #8 / #9 / #24 |
平板 → POST /open/v1/tablet/results → apt.device.gateway → 状态机命令 → #9 |
| 关键表 | apt_call_session、apt_call_event、apt_recording |
apt_tablet_task、apt_tablet_call_result |
| 失败兜底 | 30s 无入会 → ryzt=2 + 复叫 35s;AMI 断连 5 分钟巡检比对 |
未刷脸 / 超时 → 复叫 + 告警;任务过期 40916 转人工 |
| 断网 | 本地闭环可用(docs/10 表 7-6) |
已缓存任务照常播放,结果本地排队恢复后续传 |
表 5-10 模式选择规则
| 规则 | 口径 |
|---|---|
gy_jcxx.call_mode |
由 #7 任务变更下行或本地房间配置确定,取值 SIP(默认)/ TABLET;一条任务只走一种方式,执行中不切换 |
| 回落 | #1 下发 features.tabletCall=false,或平板未激活 / 离线时,TABLET 一律回落 SIP 并记录回落原因 |
| 前置校验 | SIP 走 F-I 分机注册离线判定(docs/公寓端/00 §3.5),告警不阻断叫乘;TABLET 走平板在册与心跳校验 |
| 顺序派发 | 按 jcsj 升序生成 dispatch_seq,单公寓同一时刻只派发一条(CR-02 F-A 第 3 步) |
| 共用 | 两条链路共用 apt.duty.state 状态机、gy_jcxx 状态字段、apt_report_outbox 上行通道与 /ws/duty 反馈通道 |
9.2 第一类:SIP 语音叫乘(Asterisk 主动呼叫)
表 5-11 触发条件(全部满足才发起)
| # | 条件 | 不满足时 |
|---|---|---|
| 1 | gy_jcxx.call_mode='SIP' 且 ryzt=0、stoped=0、finish_jc='0' |
已结束任务不重复发起 |
| 2 | Quartz 到期扫描 jcsj <= now,或值班员 POST /duty/call/{jcid}/voice(duty:call:voice,L2 commandId) |
同 commandId 只生效一次 |
| 3 | jcid → fjh → apt_sip_binding(ROOM, is_primary=1, 生效区间有效) → apt_sip_endpoint 能解析到房间主分机,且 enabled=1、deleted=0、sync_state='SYNCED' |
绑定缺失记 apt_ast_drift;未收敛返回 40905 |
| 4 | AMI 可达、Conf-01 会议桥存在、from-internal 拨号计划就绪(表 5-8 自检项 1 / 3 / 4) |
BLOCKED → /apt/ops/health/call-ready 返回 callReady=false,转值班台兜底 |
| 5 | 分机注册态按 F-I 判定;离线只写 apt_device_alarm 并告警 |
不阻断,失败原因记 apt_call_session.hangup_cause |
图 5-8 SIP 语音叫乘端到端时序
sequenceDiagram
autonumber
participant Q as Quartz / 值班员命令
participant S as apt.duty.state
participant V as apt.voice.endpoint / event
participant A as apt.voice.ami
participant AST as Asterisk
participant T as 房间 SIP 终端
participant DB as 本地库
participant W as /ws/duty + outbox
Q->>S: command(CALL_START, jcid)
S->>DB: 条件更新 ryzt 0→1, jcsj_s=now(3)
S-->>W: state.changed(0→1)
V->>A: Originate PJSIP/room + PJSIP/console
A->>AST: AMI Originate
AST->>T: SIP INVITE(Asterisk 主动发起)
AST-->>A: OriginateResponse(Success)
T-->>AST: 接听并入会
AST-->>A: ConfbridgeJoin(Conf-01, PJSIP/room)
A-->>V: 事件(写 apt_call_event)
V->>DB: apt_call_session(state=JOINED_CONF, join_at)
V->>S: command(ANSWERED, jcid)
S->>DB: ryzt→3, hjxysj, finish_jc='1'
V->>DB: apt_tts_utterance(PENDING) + apt_recording 索引
AST->>T: Playback(tts) 播放提示语音
A-->>V: Playback 结果 / Hangup
V->>DB: 更新 apt_tts_utterance(DONE/FAILED) + apt_call_session(HANGUP)
S-->>W: state.changed(1→3) + session.changed
W->>DB: outbox enqueue(#8 回执 / #9 DUTY_RESULT / #24 VOICE_SUMMARY)
表 5-12 SIP 语音叫乘交互流程
| 步 | 主体 | 动作 | 落表 | 失败 / 补偿 |
|---|---|---|---|---|
| 1 | Quartz / 值班员命令 | 到 jcsj 触发,提交 CALL_START 命令 |
duty_manual_action(人工触发时) |
状态不允许 → APT_STATE_ILLEGAL |
| 2 | apt.duty.state |
where id=? and ryzt=0 条件更新 ryzt=1、jcsj_s |
gy_jcxx |
推 state.changed(0→1) |
| 3 | apt.voice.endpoint |
解析房间主分机,双路 Originate(房间 + 值班台) |
apt_sip_binding、apt_call_session(CALLING) |
解析失败按表 5-11 第 3 条 |
| 4 | apt.voice.ami → Asterisk |
发 AMI Originate,Asterisk 向房间 SIP 终端发 INVITE |
apt_call_event |
OriginateResponse.Failure → CALL_FAILED 分支(表 5-13、表 5-20) |
| 5 | 房间 SIP 终端 | 接听并入会(ConfbridgeJoin,会议号 Conf-01) |
apt_call_session(RINGING → JOINED_CONF) |
30s 无入会 → TIMEOUT |
| 6 | apt.voice.event |
依 AMI 事件判应答,提交 ANSWERED 命令 → 状态机置 ryzt=3、finish_jc='1'、hjxysj |
gy_jcxx、apt_call_event |
只提交命令,不直接 update gy_jcxx |
| 7 | apt.voice.media |
入会后 Playback(tts) 播放提示语音,生成录音索引与 TTS 播报单元 |
apt_tts_utterance、apt_recording |
FAILED / MISSING 只告警,不改叫乘结论 |
| 8 | apt.voice.event / apt-report |
Hangup 归档会话;终态经 #8 / #9 / #24 上行;值班台经 /ws/duty 反馈 |
apt_call_session、apt_report_outbox |
AMI 断连标 UNKNOWN,5 分钟巡检兜底 |
表 5-13 AMI 事件 → 业务状态 → 上报与反馈映射(沿用 docs/10 表 7-5、本文件 表 5-2)
| AMI 事件 / 兜底 | 业务判定 | 状态机命令 → gy_jcxx |
上行 | 值班台反馈 |
|---|---|---|---|---|
OriginateResponse.Success + Newstate |
呼叫中 / 振铃 | CALL_START(ryzt=1、jcsj_s) |
#8 回执(含 computedCallTime) |
session.changed + D1 起倒计时 |
ConfbridgeJoin(房间侧) |
应答 / 完成叫乘 | ANSWERED → ryzt=3、finish_jc='1'、hjxysj |
#9 DUTY_RESULT(ANSWERED)、#24 摘要 |
state.changed(1→3) + session.changed |
OriginateResponse.Failure / 30s 无入会 |
失败 / 无应答 | CALL_FAILED → ryzt=2、jcbjsj_s、is_jcbj='1' |
#9 + #12 ALARM |
alarm.raised(NO_ANSWER) + 复叫 35s |
入会后 < 3s Hangup |
异常中断 | 保持终态并触发复叫 | #9 + #12 | 告警 + 行置红 |
Hangup(正常) |
会话结束 | 不回写 gy_jcxx(已结束不回写) |
#24 摘要 | session.changed(HANGUP) |
AMI Disconnect |
在途会话 UNKNOWN |
不推定终态 | — | 5 分钟 core show channels concise 比对 |
| 录音 / TTS 失败 | 媒体异常 | 不改叫乘结论 | #24 recordingMissing |
notice.sync / 告警 |
"接听后播放提示语音完成叫乘"的落地口径:接通判据是
ConfbridgeJoin(房间侧入会),不是 SIPAnswer(docs/10§7.7 第 2 条、本文件 表 5-2)——Answer只代表摘机,不代表房间内人员能听到。入会即提交ANSWERED完成叫乘,随后Playback(tts)播放提示语音,apt_tts_utterance的DONE/FAILED与apt_recording.state不回退、不改写叫乘终态(沿用 §4 第 3 条"录音不阻断叫乘")。 "叫乘状态由业务系统依据 AMI 事件进行上报"的落地口径:apt.voice.ami收原始事件 →apt.voice.event依表 5-2 / 表 7-5 判业务状态 → 提交状态机命令(唯一写入口apt.duty.state)→ 条件更新gy_jcxx→apt-report经 #8 / #9 / #24 上行。AMI 事件本身既不直接写业务表,也不单独构成对外上报。
9.3 第二类:平板叫乘(拉取 + 本地定时播放 + 刷脸签到)
表 5-14 触发条件(按环节)
| 触发环节 | 条件 |
|---|---|
| 任务生成 | gy_jcxx.call_mode='TABLET'、ryzt=0、stoped=0;#1 下发 features.tabletCall=true;按 jcsj 升序生成 dispatch_seq,写 apt_tablet_task(WAITING) |
| 平板可拉取 | apt_tablet_device.register_status=ACTIVE、心跳在窗内;GET /open/v1/tablet/tasks?deviceCode&cursor&limit(N-03)按 dispatch_seq 顺序返回 |
| 本地播放 | 平板提前拉取并缓存任务,按任务中的 jcsj(预定时间点)由平板本地定时器触发播放;以心跳下发的 serverTime 校准本地时钟,clockSkewMs 超阈值时重拉并告警 |
| 刷脸签到 | 播放后进入签到窗口(signTimeoutSec,默认 60s,Q-29);刷脸 VERIFIED 即结束叫乘 |
| 结果上报 | POST /open/v1/tablet/results(N-04),resultId 幂等 + HMAC / 时间窗 / nonce |
拉取 ≠ 执行:服务端只生成任务,不向平板推送呼叫指令(平台不回调公寓、设备侧一律拉取,CR-C08);"到达预定时间点后播放语音"由平板本地完成。断网时已缓存任务仍可按
jcsj播放,结果写入平板本地队列,恢复后按resultId重传。
表 5-15 平板任务负载字段(N-03 响应 tasks[],沿用 CR-02 表 3-8 的 /open/v1/tablet/**)
| 字段 | 类型 | 说明 |
|---|---|---|
taskId / jcid / dispatchSeq |
string / string / long | 任务、叫乘任务、派发序号三层键 |
jcsj / expireAt |
datetime | 预定播放时刻(公寓本地复算值,CR-C06)与任务失效时刻 |
roomNo / ryid / personName |
string | 房间与人员 |
ttsTemplate / ttsText |
string | 提示语音模板与文本,平板本地合成 / 播放 |
faceVerifyRequired / signTimeoutSec |
boolean / int | 是否必须刷脸、签到窗口 |
serverTime / clockSkewMs |
datetime / long | 时钟校准(与 #14 心跳同源,见 docs/公寓端/09 表 9-11) |
cursor |
string | 拉取游标,单调递增 |
图 5-9 平板叫乘端到端时序
sequenceDiagram
autonumber
participant E as apt-dispatch
participant DB as 本地库
participant G as apt.device.gateway
participant T as 平板终端
participant U as 人员
participant S as apt.duty.state
participant W as /ws/duty + outbox
E->>DB: 按 jcsj 生成 apt_tablet_task(WAITING, dispatch_seq)
T->>G: GET /open/v1/tablet/tasks(cursor)【提前拉取】
G-->>T: tasks[](jcsj, ttsText, faceVerifyRequired, serverTime)
T->>G: POST /open/v1/tablet/tasks/{taskId}/ack(N-05)
G->>DB: apt_tablet_task(PULLED, pulled_at, pulled_by)
T->>T: 按 serverTime 校准,本地缓存任务
Note over T: 到达 jcsj(预定时间点)
T->>U: 本地播放提示语音
U->>T: 刷脸确认签到
alt 刷脸通过
T->>T: 生成结果(ANSWERED / VERIFIED / resultId)
else 未刷脸或超时
T->>T: 生成结果(UNVERIFIED / NO_ANSWER / resultId)
end
T->>G: POST /open/v1/tablet/results(N-04,HMAC + nonce)
G->>DB: 幂等校验 → apt_tablet_call_result(PENDING)
G->>S: 只提交状态机命令(不直改 gy_jcxx)
S->>DB: VERIFIED → ryzt=3 / finish_jc='1';否则 ryzt=2 + 复叫 + 告警
S-->>W: state.changed + tablet.result
W->>DB: outbox enqueue(#9 TABLET_RESULT)
表 5-16 平板叫乘交互流程
| 步 | 主体 | 动作 | 落表 | 失败 / 补偿 |
|---|---|---|---|---|
| 1 | apt-dispatch |
按 jcsj 生成任务 WAITING + 单调 dispatch_seq |
apt_tablet_task、gy_jcxx |
规则快照过期 → 40903 |
| 2 | 平板 | GET /open/v1/tablet/tasks(N-03,游标)提前拉取 |
— | 拉取失败按退避重试,不影响本地已缓存任务 |
| 3 | 平板 → apt.device.gateway |
POST /open/v1/tablet/tasks/{taskId}/ack(N-05) |
apt_tablet_task(PULLED) |
重复 ACK → 40916 |
| 4 | 平板 | 按 serverTime 校准本地时钟并缓存任务 |
平板本地 | 偏差超阈值重拉 + 告警 |
| 5 | 平板 | 到达 jcsj 本地播放提示语音 |
平板本地 | 无音频资源 → 本地降级提示并上报 FAILED |
| 6 | 人员 | 在签到窗口内通过平板刷脸确认签到 | 平板本地 | 未刷脸 / 超时 → UNVERIFIED / NO_ANSWER |
| 7 | 平板 | 生成 resultId 与结果(resultType + faceVerifyState + verifiedRyid) |
平板本地 | 只传识别结论,不传抓拍帧 / 人脸原图 / 比对帧;比对所需特征值按 docs/公寓端/10 的设备范围下发 |
| 8 | 平板 → apt.device.gateway |
POST /open/v1/tablet/results(N-04) |
apt_tablet_call_result |
HMAC / 时间窗 / nonce 校验;同 resultId 返回首次结果 |
| 9 | apt.device.gateway → apt.duty.state |
校验幂等后只提交状态机命令 | apt_tablet_call_result(PENDING) |
不直改 gy_jcxx;校验失败丢弃并告警 |
| 10 | apt.duty.state / apt-report |
按表 5-20 落终态,推 tablet.result + state.changed,#9 上报 TABLET_RESULT |
gy_jcxx、apt_report_outbox |
断网进 outbox,恢复后按原幂等键续报 |
表 5-17 平板侧可靠性口径
| 项 | 口径 |
|---|---|
| 定时 | 以任务 jcsj 为准由平板本地定时器触发;clockSkewMs > 1s 重拉校准(表 5-8 自检项 11) |
| 断网 | 已缓存任务照常播放;结果写平板本地队列,恢复后按 resultId 重传,幂等不产生第二次终态 |
| 重放 | 同一 taskId 只播放一次(可配重播次数,Q-29);重复拉取 / ACK 返回 40916 |
| 过期 | now > expireAt 或任务已被其他平板拉取 → 40916,置 EXPIRED 并转人工 |
| 人脸数据 | 平板叫乘结果只传 verifiedRyid 与 faceVerifyState,抓拍帧与人脸原图不上报、不上传平台;比对所需特征值按 docs/公寓端/10 的设备权限范围下发;人员主数据照片与特征值按 CR-C24 允许平台 ↔ 公寓双向同步(CR-02 §12) |
| 本期边界 | 本地定时与断网续传依赖终端固件能力;协议未确认前(50101)只在设计层描述,不伪造成已实现(§3 表 5-3「诚实的边界」) |
9.4 状态上报机制(两类方式统一)
表 5-18 状态来源 → 状态机 → 上行
| 环节 | SIP 语音叫乘 | 平板叫乘 | 共同约束 |
|---|---|---|---|
| 事实来源 | AMI 事件(apt.voice.ami) |
平板上报 TABLET_RESULT(apt.device.gateway) |
一条任务只有一种事实来源,由 gy_jcxx.call_mode 标记 |
| 业务判定 | apt.voice.event 按表 5-2 / docs/10 表 7-5 映射 |
按 faceVerifyState + resultType 映射 |
都不直接 UPDATE gy_jcxx |
| 状态落地 | 提交 CALL_START / ANSWERED / CALL_FAILED 命令 |
提交 ANSWERED / CALL_FAILED 命令 |
apt.duty.state 唯一写入口;where id=? and ryzt=<期望值>;已结束不回写 |
| 幂等 | session_id / event_seq |
resultId(UK (gyid, result_id)) |
迟到 / 重复结果记 IGNORED,不产生第二次终态 |
| 上行 | #8 回执、#9 DUTY_RESULT、#24 VOICE_SUMMARY |
#9 TABLET_RESULT、#8 回执(含 dispatchSeq)、#13 归档摘要 |
apt_report_outbox + idempotencyKey = hash(gyid+bizType+bizId+bizVersion);断网累积、serverReceivedAt 归日 |
| 状态字段 | ryzt / finish_jc / hjxysj / jcbjsj_s |
同左(语义一致) | 值班台与平台按同一套终态理解,不因实现方式分叉 |
三条不可违反规则(§2)继续适用。本节新增两条:
- 方式内事实来源唯一:SIP 任务不接受平板上报结果,平板任务不套用 AMI 事件推断;一条
jcid的终态只能由一种事件源触发。 - 跨端上报一律带
callMode:#9 / #24 的payload用SIP/TABLET分组,平台按方式统计;不新增bizType、不新增跨端接口编号、不改变v2-draft契约形态。
9.5 结果反馈路径
表 5-19 四条反馈路径
| # | 路径 | SIP 语音叫乘 | 平板叫乘 | 约束 |
|---|---|---|---|---|
| 1 | 值班台(端内) | /ws/duty state.changed(0→1、1→3)、session.changed;异常 alarm.raised / alarm.cleared |
state.changed + tablet.result;异常 alarm.raised |
D1 行状态、D5 会议桥占用、D6 设备状态;seq 单调 + 60s 兜底轮询(docs/应用端/04 表 4-12) |
| 2 | 平台(跨端) | #8 任务回执(含 computedCallTime)、#9 DUTY_RESULT、#24 语音质量摘要、#13 归档 |
#9 TABLET_RESULT、#8 回执(含 dispatchSeq)、#13 归档;不发 #24 语音摘要 |
公寓主动推、平台不回调;payload 带 callMode;断网 outbox + 续报(CR-02 F-E) |
| 3 | 本地留痕 | gy_jcxx、apt_call_session、apt_call_event、apt_recording、apt_tts_utterance |
gy_jcxx、apt_tablet_task、apt_tablet_call_result |
共用 duty_operation_log 审计与 apt_report_history 上报终态 |
| 4 | 异常兜底 | 30s 无入会 → gy_bjxx(NO_ANSWER) + 复叫 35s;接通即断 → 复叫 + 告警;AMI 断连 → UNKNOWN + 5 分钟巡检;会议桥不可用 → 值班台兜底 |
UNVERIFIED / SKIPPED → 复叫 + 告警(Q-22);NO_ANSWER → gy_bjxx(TIMEOUT);任务过期 40916 → 转人工;平板离线 → apt_device_alarm |
异常同样经状态机与 outbox 上报,不另设"人工填状态"入口 |
表 5-20 终态矩阵(两类方式共用一套 gy_jcxx 语义)
| 情形 | 事件 / faceVerifyState |
状态机命令 | gy_jcxx |
上行 | 值班台 |
|---|---|---|---|---|---|
| SIP 接通 | ConfbridgeJoin |
ANSWERED |
ryzt=3、finish_jc='1'、hjxysj |
#9 DUTY_RESULT + #24 |
state.changed(1→3) + session.changed |
| SIP 无应答 | 30s 无入会 / OriginateResponse.Failure |
CALL_FAILED |
ryzt=2、jcbjsj_s、is_jcbj='1' |
#9 + #12 | alarm.raised(NO_ANSWER) + 复叫 |
| 平板刷脸签到 | ANSWERED + VERIFIED |
ANSWERED |
ryzt=3、finish_jc='1' |
#9 TABLET_RESULT |
tablet.result + state.changed |
| 平板未刷脸 | ANSWERED + UNVERIFIED / SKIPPED |
保持待确认 + 复叫 | ryzt 不变(超窗口转 2) |
#9 + #12 | tablet.result + alarm.raised |
| 平板无应答 | NO_ANSWER / FAILED |
CALL_FAILED |
ryzt=2 |
#9 | alarm.raised + 复叫 |
| 任务取消 | CANCELLED |
STOP(值班台) |
stoped='1',ryzt 不变 |
#9 | state.changed |
| 迟到 / 重复结果 | 任意 | IGNORED |
不回写 | 不重复上报 | 只记留痕(applied_state=IGNORED) |
9.6 与既有章节的关系与待决策
- §1 任务生成、§2 SIP 状态机、§4 语音事件与媒体、§6 outbox、§7 人工干预继续有效;本节是两条链路的串联视图,不改任何状态字段写入口,也不改
docs/10表 7-5 的事件映射。 - CR-02 §7.1 F-A / §7.2 F-B 继续有效;本节补齐"平板本地定时播放"(表 5-14、5-15)与"结果反馈路径"(表 5-19、5-20)两个此前未展开的环节。
- 不新增跨端接口编号、
bizType、WS 消息名或数据表;TABLET_RESULT、device.alarm、state.changed等全部沿用既有契约。 - 本期边界:平板本地定时与断网续传依赖终端固件与设备协议确认(D6 /
50101),未确认前只作为设计定义。
表 5-21 新增决策点(沿用 docs/应用端/10 的决议记录格式)
| 编号 | 待决事项 | 未决默认口径 | 拍板时点 |
|---|---|---|---|
| Q-29 | 平板签到窗口 signTimeoutSec、语音重播次数与 clockSkewMs 阈值 |
60s / 1 次 / 1s | 阶段二契约冻结前 |
10. 人员入住作业流程(CR-02 §13 流程索引)
权威表述:
docs/公寓端/11-人员入住作业流程.md(CI-0111-35、图 11-1~11-3)。本节只给出与叫乘流程的衔接关系,不重复定义状态机、数据表与接口字段。CI-05、表 11-1
表 5-22 入住作业五环节与叫乘衔接
| 环节 | 主体 | 关键动作 | 与既有章节的关系 |
|---|---|---|---|
| CI-01 注册与签到 | 签到终端 / 值班台 | 扫脸核验;未注册先按 docs/公寓端/10 §4 完成注册并重新核验 |
复用 F-F 注册链路;不新增注册入口 |
| CI-02 入住申请 | 签到终端 → apt-stay |
选房间、交路(可确定时)提交申请;apt_local_task 建单并预分配 jcid |
申请阶段不建 gy_jcxx 行(§1 任务生成口径不变) |
| CI-03 值班员审核 | 值班台 → apt-stay |
审核、房间调整(仅审核期)、办理入住;checkin_state=CHECKED_IN 并写 gygl_ly_event(CHECKIN) |
房间调整复用 F-C 换房联动但不产生换乘单;状态字段仍只经 apt.duty.state |
| CI-04 提报与匹配 | apt-report / 平台 |
#9 CHECKIN 提报 → #6 运安计划 → #8 回执作匹配输入 → #7 响应体 matchVerdict[] |
匹配结论唯一合规载体是 #7(R-05);match_state 沿用正式五值 |
| CI-05 叫乘环节 | apt-dispatch |
#7 拉任务 → 按 apt_master_rule 复算 jcsj → 回 #8 → 按 jcsj + dispatch_seq 派发 |
派发后进入 §9 两类叫乘流程;jcsj 恒由公寓复算(CR-C06) |
三条衔接约束:① applyId ↔ jcid 一对一,gy_jcxx 沿用预分配 jcid;② 只有 CHECKED_IN 且有效在寓(finish_ly='0' AND sjlysj IS NULL)才生成叫乘任务,已离寓迟到任务记 IGNORED;③ "已入住"不新增 gy_jcxx 状态字段,流程态落 apt_local_task 补列(CR-C26)。本补遗不新增业务表(59 张不变)、不新增跨端编号、不新增 bizType。
11. 消费、充值与菜品管理(CR-02 §14 流程索引)
权威表述:
docs/公寓端/12-消费充值与菜品管理.md(CF-0112-34、图 12-1~12-4)。本节只给出与既有账务闭环(§6 F-D)及主数据下行(§5)的衔接关系,不重复定义状态机、数据表与接口字段。CF-03、表 12-1
表 5-23 三项流程与既有章节的衔接
| 流程 | 主体 | 关键动作 | 与既有章节的关系 |
|---|---|---|---|
| CF-01 人员消费 | 消费终端 → apt.ledger.local → apt-report |
按 PUBLISHED 食谱选菜并显示金额 → N-49 查补贴 / 现金额度 → "补贴优先、现金补足" → 一条 CONSUME 流水 → #10 上报 |
复用 §6 F-D 六步账务闭环与 F-E 上报历史;platform-ledger 唯一写主账 |
| CF-02 人员线下充值 | 签到终端 → 值班台 → apt.ledger.local |
扫码只识别公寓 → N-52 申请(申请表不存金额)→ 管理员 N-54 二次确认 → 只增 xjye → #10 同步 |
同样复用 F-D;不接线上支付,二维码不构成资金流;断网受 #1 offlineQuota 约束(Q-21 / Q-42) |
| CF-03 公寓菜品管理 | 公寓管理员 → platform.catering → apt.catering → 消费终端 |
N-57 发布阶段性食谱 → #4 recipes[] 下行 → N-48 按 version 主动拉取并缓存 → 点击查看菜品、加入选择菜单 |
属 §5 主数据下行的增量类型;食谱缓存只在终端本地,不落公寓本地业务表 |
三条衔接约束:① 三条流程共用 F-D 闭环与 #10 LEDGER_OFFLINE,bizId = flowId、幂等键复用、serverReceivedAt 归日不变;② 一笔消费只产生一条流水,allowanceAmount + cashAmount = abs(amount),不额外生成 ALLOWANCE_DEDUCT 以免平台 sum(amount) 双计;③ apt.ledger.local / platform-ledger 各自单写入口不变,本补遗不新增业务表(59 张不变)、不新增跨端编号、不新增 bizType。