docs/:系统梳理、架构优化方案、CR-02 三端功能设计修订(含 §15 三端一致性同步与平台统计分析)、公寓端/应用端/平台端分册、公寓统计分析与排名报表、公寓端小步迭代开发计划(IT-0~IT-8) dev/:RuoYi-Vue-master(后端)与 RuoYi-Vue2-master(前端)官方上游基线,未改动
16 KiB
04 核心页面拆解:JcXx 值班控制台
src/views/JcXx.vue 5294 行,模板 1–1389,脚本 1390–4532,样式 4533 之后。它是整个系统的操作中枢,下面按“布局 → 状态 → 列表 → 操作 → 时间规则 → 轮询 → 历史 → 陷阱”拆解。
1. 页面布局
┌─────────────────────────────────────────────────────────────────────┐
│ 跑马灯(当前告警/呼叫提示) │ 大时钟 │ 房间信息 设备信息 人员维护 │
│ 机车号 车次 房间号 姓名 [查询][重置] │ │ 交路管理 历史数据 退出 │
│ │ │ 语音临叫 喊话临叫 停止呼叫 停止报警 │
├─────────────────────────────────────────────────────────────────────┤
│ Tab:机务人员和客运人员 / 其他人员 │
│ 叫乘列表(状态、到寓时间、单位、机车号、姓名、房间号、车次、开车/叫乘/ │
│ 复叫/应离寓时间、接车方式、暂停报警) │
├─────────────────────────────────────────────────────────────────────┤
│ 底部:在寓汇总 / 值班信息 │
└─────────────────────────────────────────────────────────────────────┘
弹窗:历史叫乘、离寓抓拍、设备信息、未刷脸、换房、交路、待确认交路、
新增/修改交路、修改叫乘、入寓登记、人员维护、现金充值、交接班、
房间选择、房间维护、多房间喊话、出乘确认、广播确认、临叫确认、
停止呼叫确认、运安离线告警、交路及叫乘提醒
| 区域 | 行号 | 说明 |
|---|---|---|
| 顶部卡片 | 4–176 | 左:跑马灯 + 4 个查询框;中:每秒刷新的大时钟;右:功能按钮 |
| 列表卡片 | 178–241 | 两个 Tab(仅视觉)、主表格 |
| 主表格 | 183–240 | height=600、row-style=setRowStyle、单选高亮 |
| 底部栏 | 1178–1191 | 在寓人数汇总、值班信息 |
| 业务弹窗 | 244–1378 | 见第 7 节 |
主表格列:序号、状态、到寓时间、单位、机车号、姓名、房间号、出发车次、开车时间、叫乘时间、复叫时间、叫乘日期、应离寓时间、接车方式、操作(暂停报警)。
2. 页面状态
data() 从 1406 行开始,核心字段:
| 字段 | 行号 | 用途 |
|---|---|---|
gyid |
1453 | 当前公寓;created() 中取 localStorage.gyid 或全局 gyid |
apiRoot |
1459 | WebSocket 主机名 |
jcxxList |
1542 | 主列表数据 |
selectedRow |
1470 | 当前选中行,所有行操作的入参 |
JcXxQueryParams |
1546 | 查询条件:gyid/jch/cc/fjh/rymc/begindt/enddt |
LsJcXxQueryParams |
1555 | 历史查询:增加 historyTimeType/pageNum/pageSize |
sjgzConfig |
1631 | 时间规则 {kjjcsjgz,zjjcsjgz,lysjgz} |
dismissedAlarmEvents |
1430 | 已处理告警事件 key 集合,防止重复响铃 |
alarmVoiceActive |
1428 | 报警音是否正在播放 |
syncSpeechQueue / syncSpeechCurrent |
1627 起 | TTS 播报队列 |
activeTempCalls |
1644 | 本页面发起的临叫房间及类型(voice/speech) |
callListRequestVersion |
1429 | 列表请求版本号,防止旧响应覆盖新数据 |
created()(JcXx.vue:1726)设置 gyid 与查询参数,加载交路列表与当前时间;mounted()(:1784)启动 WebSocket、SIP、字典、列表、时间规则和 4 个定时器。
3. 列表与状态
3.1 状态码映射
表格“状态”列(JcXx.vue:194):
ryzt |
显示 | 含义 | 行颜色 |
|---|---|---|---|
0 |
待叫乘 | 尚未到叫乘时间 | 黄色 #FFF200 |
1 |
正在呼叫 | 正在叫乘/通话建立中 | 绿色 #00FF00 |
2 |
叫乘报警 | 叫乘未应答 | 红色 #F56C6C |
3 |
待离寓 | 已叫乘完成,等待离寓 | 浅绿 #B3E19D |
4 |
离寓报警 | 超时应离寓 | 红色 #F56C6C |
5 |
正在通话 | 语音通道已建立 | 绿色 #00FF00 |
| 其他 | 已入寓 | 正常在寓 | 默认 |
3.2 行样式与跑马灯
setRowStyle(row)(JcXx.vue:3723)按以下优先级返回样式,并在渲染函数里直接修改 this.message:
ryzt=0且missedCallTaskWarning=1:黄色 + 闪烁动画,提示“叫乘时间已过”;ryzt=1/5:绿色;ryzt=2/4:红色;- 本页发起的临叫:绿色,提示“正在喊话/语音临叫”;
jllx=1:浅蓝#d9ecff;ryzt=3:浅绿;ryzt=0:黄色;- 其他:默认。
问题:setRowStyle 是纯函数位,却在渲染期间写 this.message,会触发额外的渲染与响应式更新;表格行数多时可能造成卡顿或“跑马灯内容错行”。修改行样式逻辑时建议把消息计算移出渲染函数。
3.3 接车方式显示
cclx 为“站接”显示站接;“库接/库出”统一显示“库出”;其他为空。
4. 操作矩阵
所有行级操作都要求先选中行(selectedRow),点击行时还会向 SIP 发送一次注册状态(JcXx.vue:3231)。
| 操作 | 入口 | 处理方法 | 后端接口 | 说明 |
|---|---|---|---|---|
| 查询/重置 | 顶部 | getJcXxList / resetForm |
/jcgl/getCcJcXx |
输入即查询;重置只清 4 个文本条件 |
| 取消叫乘 | 顶部 | openCancelTrainAssignment |
/jcgl/cancelTrainAssignment |
二次确认;成功后停报警、刷新列表 |
| 修改叫乘 | 行/弹窗 | handleModifyJcXx → handleUpdateJcXxConfirm |
/jcgl/modifyJcXx |
编辑表单与表格行分离,避免后端拒绝时已改表格 |
| 出乘 | 弹窗 | handleCheckOut → handleCheckOutConfirm |
/jcgl/handleCheckOut |
确认后不可修改 |
| 暂停报警 | 行内按钮 | handleStopCalling |
/jcgl/handleStopCalling |
仅 ryzt=2/4 有效;成功后把事件 key 加入已忽略集合 |
| 停止报警 | 顶部 | stopCurrentAlarm |
同上 | 先校验选中行必须是 2/4 |
| 语音临叫 | 顶部 | handleCalling → handleRoomCallConfirm |
SIP + /jcgl/handleRoomCall |
需 SIP 已连接;callmethod=1 |
| 喊话临叫(单房间) | 顶部 | handleCallingOld → handleRoomCallConfirm |
SIP + /jcgl/handleRoomCall2 |
选中行时 callmethod=2 |
| 喊话临叫(多房间) | 顶部 | confirmMultiCall |
/jcgl/handleMultiRoomCall |
未选中行时弹出多选房间;记录 lastCalledRooms |
| 停止呼叫 | 顶部 | handleRoomCallEnd |
/jcgl/handleMultiRoomCallEnd 或 /jcgl/handleRoomCallEnd(2) |
优先停止多房间,否则停止当前行 |
| 换房间 | 弹窗 | handleChangeRoom → exchangeRoomConfirm |
/jcgl/getRyFjXx、/jcgl/exchangeRoom |
先列出同房间人员,再逐人设置新房间 |
| 入寓登记 | 弹窗 | finalCheck |
/jcgl/submitAll |
校验房间/开车日期后提交;成功后关弹窗刷新 |
| 人员维护 | 顶部 | handleUpdateRyXx |
/jcgl/getRyxxByRyId、/jcgl/modifyRyXx、/jcgl/deleteRyXx |
支持刷脸照片上传/替换 |
| 现金充值 | WebSocket 触发 | handleRechargeConfirm |
/recharge/handleRecharge |
收到 cz 消息弹窗;cz_cancel 可按 id 关闭 |
| 交路管理 | 顶部 | handleJlGlClick |
/jcgl/getJlxxList |
打开交路列表,可新增/修改/删除/导入 |
| 待确认交路 | 交路弹窗 | handdleDqrButton → handleConfirmJlXxClick |
/jlgl/confirmJlXx |
按勾选 id 批量确认 |
| 历史数据 | 顶部 | handleLsSjClick → loadLsJcXx |
/jcgl/getCcJcXx_Ls |
分页 + 滚动加载;可回放录音 |
| 设备信息 | 顶部 | handleDeviceStatus |
/heartBeat/getDeviceStatusInfo |
离线设备整行标红 |
| 导出 Excel | 定时 | exportJcXxExcell |
/excel/exportJcXxExcell |
每 10 分钟自动下载一次 |
| 退出 | 顶部 | handleLogout |
— | 关 WS、清定时器、清本地登录信息 |
4.1 临叫的 SIP 前置动作
handleRoomCallConfirm(JcXx.vue:4263)在调用后端前先向 SIP 发送:
{
"reqAct": {
"type": "call_make",
"actId": "actid_12121212",
"params": ["sip:1001@10.32.100.166"]
}
}
- 目标 SIP 地址、
actId都是硬编码; 语音临叫按钮在sipclient.connected == 0时禁用,但喊话临叫没有同样保护;- SIP 发送失败不会阻断后端调用,前后端状态可能不一致。
5. 时间规则与校验
5.1 规则来源
getSjgzConfig()(JcXx.vue:3782)调用 /jcgl/getSjgz,取第一条:
| 字段 | 默认 | 含义 |
|---|---|---|
kjjcsjgz |
150 | 库出/库接提前叫乘分钟数 |
zjjcsjgz |
120 | 站接提前叫乘分钟数 |
lysjgz |
30 | 叫乘后到应离寓的分钟数 |
接口失败时页面回退到同一组默认值并提示。
5.2 计算关系
test()(修改叫乘,JcXx.vue:3901)与 calculateJlxxTime()(交路新增,:3998):
叫乘时间 jcsj = 开车时间 kcsj − 规则分钟(站接 zjjcsjgz,库出/库接/未选 kjjcsjgz)
复叫时间 fjsj = jcsj + 10 分钟
报警时间 jcbjsj = fjsj + 5 分钟
应离寓 ylysj = jcsj + lysjgz(默认 30 分钟)
注意:交路新增表单里的字段叫 lysj,修改叫乘表单里叫 ylysj,两者复用同一套计算,但字段名不同。
5.3 合法性校验
validateCallDutyTimeline(JcXx.vue:3852)要求:
- 五个时间全部存在且格式正确(
yyyy-MM-dd HH:mm[:ss]); - 严格满足
kcsj > ylysj > jcbjsj > fjsj > jcsj; kcsj − jcsj < 24 小时。
handleJcsjChange(:3870)在手工修改叫乘时间时重算后三个时间,并要求当前开车时间仍然合法。
5.4 修改叫乘的提交
handleUpdateJcXxConfirm(JcXx.vue:3335)先规范化 5 个时间字段、再校验时间线,最后提交;00000 关闭弹窗刷新列表,11111 只弹错误不关闭。
6. 轮询与自动行为
mounted() 注册的定时器:
| 定时器 | 周期 | 动作 | 副作用 |
|---|---|---|---|
latestSyncTimeTimer |
30 s | loadLatestSyncTime → /jcgl/getLatestSyncTime |
更新底部“最近同步时间” |
minuteTimer |
10 min | getJcXxList |
刷新列表并触发告警音/TTS 调度 |
fiveMinuteTimer |
10 min | exportJcXxExcell |
自动下载 Excel 到浏览器 |
threeMinuteTimer |
10 min | getSynJcXxIsOffline |
运安离线时弹窗并播放离线报警音 |
currentDateTimer |
1 s | 更新 currentDate |
大时钟 |
getJcXxList(JcXx.vue:2262)用 callListRequestVersion 防止旧响应覆盖:
const requestVersion = ++this.callListRequestVersion
getJcXxList(params).then(res => {
if (requestVersion !== this.callListRequestVersion) return
this.jcxxList = res.data
this.syncAlarmVoice(this.jcxxList)
...
})
handleStopCalling 成功后主动 ++callListRequestVersion,使所有在途响应失效,避免“刚停掉的报警又被旧数据拉响”。
退出/离开页面时 destroyed(JcXx.vue:1740)清理全部定时器、队列和语音;但 jlwebsocketclose() / jcwebsocketclose() 被直接调用,而这两个方法内部会执行 location.reload(),因此路由离开本页会触发整页刷新(详见 05、07)。
7. 弹窗清单
| 弹窗 | 行号 | 绑定 | 说明 |
|---|---|---|---|
| 历史叫乘信息 | 244–413 | visible_jcxx_ls |
查询、分页、录音回放、离寓抓拍 |
| 刷脸离寓抓拍 | 415–426 | visible_leaveSnapshot |
图片预览 |
| 设备信息 | 428–484 | visible_sbxx |
离线设备标红 |
| 未刷脸人员 | 486–496 | visible_wslRy |
入口按钮当前被注释 |
| 换房间 | 498–518 | visible_hfj |
逐人选择新房间 |
| 交路信息 | 521–584 | visible_jlxx |
列表、增删改、导入、确认 |
| 待确认交路信息 | 595–642 | visible_jlqrxx |
批量确认 |
| 新增/修改交路 | 644–779 | visible_jlxx_add |
时间自动计算 |
| 修改叫乘信息 | 781–898 | visible_jcxx |
5 个时间 + 车次选择 |
| 入寓登记信息 | 900–988 | visible_rydj |
刷脸照片、房间选择 |
| 人员维护 | 990–1118 | visible_ryxxwh |
查询、编辑、照片 |
| 现金充值 | 1120–1176 | visible_xjcz |
金额 0–100,WebSocket 触发 |
| 交接班 | 1192–1205 | visible_login |
登录表单(当前值班台不使用) |
| 房间选择 | 1207–1210 | visible_room |
内嵌 Room.vue |
| 房间维护 | 1212–1215 | visible_roomLook |
内嵌 RoomLook.vue |
| 多房间喊话 | 1222–1258 | dialogMultiCallVisible |
房间多选 |
| 出乘确认 | 1260–1282 | dialog1Visible |
不可撤销提示 |
| 广播确认 | 1284–1301 | dialog2Visible |
所有公共区域呼叫 |
| 临叫确认 | 1303–1317 | dialogCallVisible |
语音/喊话文案动态 |
| 停止呼叫确认 | 1319–1333 | dialogCallEndVisible |
— |
| 运安离线报警 | 1335–1344 | visible_synJcXxIsOffline |
同步异常提示 |
| 交路及叫乘提醒 | 1347–1378 | syncDialogVisible |
分组提醒、10 秒自动关闭、TTS |
8. 历史数据与录音
handleLsSjClick(JcXx.vue:4312)打开弹窗后getLsJcXx。loadLsJcXx(reset)(:4326)每次取 100 条,lsJcxxList.length < count时允许继续加载;滚动到底部触发下一页。- 历史查询支持按“入寓时间/离寓时间”切换,日期输入兼容
8、815、0815、081530等简写(2300 行附近)。 - 录音:
getRecordingConfig()获取基地址,splitRecordFiles/getRecordAudioUrl/playRecordVoice处理recordfile逗号分隔的多段录音。 - 离寓抓拍:
leaveSnapshotPreviewUrl显示照片,加载失败时显示占位。
9. 代码级陷阱
| 陷阱 | 位置 | 影响 |
|---|---|---|
setRowStyle 内改 this.message |
:3723 | 渲染期副作用,列表大时卡顿/提示错乱 |
formatTime 定义两次 |
:2276、:3153 | 后者覆盖前者,易误用 |
destroyed 调用 *websocketclose() |
:1743–1744 | 方法内 location.reload(),离开页面即刷新 |
WebSocket onclose 无条件 location.reload() |
:2086、:2198 | 后端重启/网络抖动会导致页面反复刷新 |
| 自动导出每 10 分钟 | :1792 | 值班机持续产生下载文件,可能占满磁盘 |
| 临叫 SIP 目标硬编码 | :4272 | 换 SIP 账号/网段必须改代码 |
| 语音临叫依赖 SIP 连接,喊话不依赖 | :153、:157 | 两条路径的前置条件不一致 |
handleUpdateJcXxConfirm 只处理 00000/11111 |
:3353 | 其他错误码无提示 |
handleTabClick 空实现 |
:3779 | 两个 Tab 不改变数据,仅是视觉分组 |
handleDelete 使用未安装的 $modal |
:3034 | 该删除入口不可用 |
10. 修改落点速查
| 需求 | 修改位置 |
|---|---|
| 增加列表列/状态 | 模板 183–240;状态映射 :194 |
| 改行颜色/闪烁规则 | setRowStyle :3723 |
| 增加行操作按钮 | 模板 234–239 + 新方法 |
| 改查询条件 | JcXxQueryParams :1546、顶部模板 21–46 |
| 改时间计算 | test :3901、calculateJlxxTime :3998、buildFollowUpTimes :3808 |
| 改临叫/停止逻辑 | handleCalling*、handleRoomCall* :4194–4310 |
| 改告警/TTS | syncAlarmVoice :2742、enqueueSyncNotice :2765、playNextSyncSpeech :2917 |
| 改轮询周期 | mounted :1790–1793 |
| 改历史查询 | loadLsJcXx :4326、历史弹窗 244–413 |