9.1 KiB
9.1 KiB
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 配置项
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 一次叫乘的时序
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 第 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. 排障入口
- 叫乘没响:看 Quartz 任务是否存在(
SchedulerManager日志)→ AMI 连接 → 会议桥是否忙 → 房间sip_account是否为空 → 任务时间是否已过期被跳过。 - 叫乘响了但状态不变:看 AMI 事件(Join/Hangup)是否被正确匹配通道 →
GY_JCXX.ryzt/recordfile。 - 运安计划没进来:看 5 分钟任务日志、
GY_SYN_JCXX_STATUS、JWDATA_SYNC_LOG、WSDL 可达性。 - 匹配不上:核对
GY_YKT_RY.card_id与GY_SYN_JCXX.workno,以及人员是否在有效在寓状态、jllx是否被人工锁定。 - 离寓报错:看抓拍配置
leaveSnapshot.*、事件幂等记录、GYGL_LY_EVENT。 - 设备指令不下发:看
GY_SB是否有该设备、心跳是否带deviceCode、指令是否已被置deleted=1。