功能(设备ID调试): 添加调试埋点与文档以定位设备ID缺失问题
创建调试环境配置文件与调试会话记录文档,在前端页面、票据面板以及后端公共接口的设备ID解析各阶段添加调试埋点,收集原始设备数据与处理后的结果,用于验证相关假设以定位设备ID不显示的根因。
This commit is contained in:
@@ -0,0 +1,2 @@
|
||||
DEBUG_SERVER_URL=http://127.0.0.1:7777/event
|
||||
DEBUG_SESSION_ID=device-id-missing
|
||||
@@ -0,0 +1,28 @@
|
||||
# Debug Session: device-id-missing
|
||||
- **Status**: [OPEN]
|
||||
- **Issue**: 数据记录中的设备 ID 当前全部未显示,界面只看到“机器ID:”后没有具体值。
|
||||
- **Debug Server**: http://127.0.0.1:7777/event
|
||||
- **Log File**: .dbg/trae-debug-log-device-id-missing.ndjson
|
||||
|
||||
## Reproduction Steps
|
||||
1. 使用售票机完成一次售票。
|
||||
2. 使用闸机完成一次进站或出站。
|
||||
3. 打开后台或票据时间线页面查看“机器ID”字段。
|
||||
4. 观察“机器ID:”后方是否为空。
|
||||
|
||||
## Hypotheses & Verification
|
||||
| ID | Hypothesis | Likelihood | Effort | Evidence |
|
||||
|----|------------|------------|--------|----------|
|
||||
| A | 后端接口返回的事件对象里根本没有 `device` / `detail.device` 字段 | High | Low | Pending |
|
||||
| B | 前端格式化函数读到了值,但后续字符串拼接或编码问题把值丢掉了 | High | Low | Pending |
|
||||
| C | 售票与检票两类事件的数据结构不同,当前前端只兼容了其中一类 | Med | Low | Pending |
|
||||
| D | 设备端 Lua 确实上报了 ID,但服务端在写库或对外返回时被覆盖成空串 | Med | Med | Pending |
|
||||
| E | 页面实际运行的不是当前工作区这份前端代码,导致本地修改未生效 | Med | Med | Pending |
|
||||
|
||||
## Log Evidence
|
||||
- 2026-07-10: 已启动 Debug Server `http://127.0.0.1:7777/event`
|
||||
- 2026-07-10: 已在 `[public.js]` 的票据时间线组装处添加 A/C 埋点
|
||||
- 2026-07-10: 已在 `[index.js]` 与 `[ticket-board.html]` 的设备 ID 格式化处添加 B 埋点
|
||||
|
||||
## Verification Conclusion
|
||||
[Pending]
|
||||
+94
-2
@@ -694,8 +694,39 @@ router.get('/tickets/:id', async (req, res, next) => {
|
||||
};
|
||||
|
||||
const formattedEvents = events.map(e => {
|
||||
// #region debug-point A:public-ticket-event-raw
|
||||
(() => {
|
||||
const fs = require('fs');
|
||||
let u = 'http://127.0.0.1:7777/event';
|
||||
let s = 'device-id-missing';
|
||||
try {
|
||||
const env = fs.readFileSync('.dbg/device-id-missing.env', 'utf8');
|
||||
u = env.match(/DEBUG_SERVER_URL=(.+)/)?.[1] || u;
|
||||
s = env.match(/DEBUG_SESSION_ID=(.+)/)?.[1] || s;
|
||||
} catch {}
|
||||
fetch(u, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({
|
||||
sessionId: s,
|
||||
runId: 'pre-fix',
|
||||
hypothesisId: 'A',
|
||||
location: 'server/routes/public.js:696',
|
||||
msg: '[DEBUG] public ticket event raw',
|
||||
data: {
|
||||
type: e?.type || '',
|
||||
action: e?.action || '',
|
||||
ticket_id: e?.ticket_id || '',
|
||||
device: e?.device ?? null,
|
||||
detail_device: e?.detail?.device ?? null
|
||||
},
|
||||
ts: Date.now()
|
||||
})
|
||||
}).catch(() => {});
|
||||
})();
|
||||
// #endregion
|
||||
if (e.type === 'sale') {
|
||||
return {
|
||||
const mapped = {
|
||||
type: 'sale',
|
||||
ts: e.ts,
|
||||
station_name: e.station_name || nameFor(e.station_code),
|
||||
@@ -708,6 +739,36 @@ router.get('/tickets/:id', async (req, res, next) => {
|
||||
trips_total: e.trips_total ?? 0,
|
||||
amount: e.cost ?? 0
|
||||
};
|
||||
// #region debug-point A:public-ticket-event-sale-mapped
|
||||
(() => {
|
||||
const fs = require('fs');
|
||||
let u = 'http://127.0.0.1:7777/event';
|
||||
let s = 'device-id-missing';
|
||||
try {
|
||||
const env = fs.readFileSync('.dbg/device-id-missing.env', 'utf8');
|
||||
u = env.match(/DEBUG_SERVER_URL=(.+)/)?.[1] || u;
|
||||
s = env.match(/DEBUG_SESSION_ID=(.+)/)?.[1] || s;
|
||||
} catch {}
|
||||
fetch(u, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({
|
||||
sessionId: s,
|
||||
runId: 'pre-fix',
|
||||
hypothesisId: 'A',
|
||||
location: 'server/routes/public.js:701',
|
||||
msg: '[DEBUG] public sale event mapped',
|
||||
data: {
|
||||
ticket_id: mapped.ticket_id || '',
|
||||
device: mapped.device ?? null,
|
||||
station_code: mapped.station_code || ''
|
||||
},
|
||||
ts: Date.now()
|
||||
})
|
||||
}).catch(() => {});
|
||||
})();
|
||||
// #endregion
|
||||
return mapped;
|
||||
} else if (e.type === 'status') {
|
||||
return {
|
||||
type: 'status',
|
||||
@@ -720,11 +781,42 @@ router.get('/tickets/:id', async (req, res, next) => {
|
||||
trips_remaining: e.trips_remaining ?? e.rides_remaining ?? null
|
||||
};
|
||||
} else if (e.type === 'check') {
|
||||
return {
|
||||
const mapped = {
|
||||
...e,
|
||||
station_name: e.station_name || nameFor(e.station_code),
|
||||
station_en: e.station_code ? enNameFor(e.station_code) : (e.station_en || '')
|
||||
};
|
||||
// #region debug-point C:public-ticket-event-check-mapped
|
||||
(() => {
|
||||
const fs = require('fs');
|
||||
let u = 'http://127.0.0.1:7777/event';
|
||||
let s = 'device-id-missing';
|
||||
try {
|
||||
const env = fs.readFileSync('.dbg/device-id-missing.env', 'utf8');
|
||||
u = env.match(/DEBUG_SERVER_URL=(.+)/)?.[1] || u;
|
||||
s = env.match(/DEBUG_SESSION_ID=(.+)/)?.[1] || s;
|
||||
} catch {}
|
||||
fetch(u, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({
|
||||
sessionId: s,
|
||||
runId: 'pre-fix',
|
||||
hypothesisId: 'C',
|
||||
location: 'server/routes/public.js:718',
|
||||
msg: '[DEBUG] public check event mapped',
|
||||
data: {
|
||||
ticket_id: mapped.ticket_id || '',
|
||||
action: mapped.action || '',
|
||||
device: mapped.device ?? null,
|
||||
station_code: mapped.station_code || ''
|
||||
},
|
||||
ts: Date.now()
|
||||
})
|
||||
}).catch(() => {});
|
||||
})();
|
||||
// #endregion
|
||||
return mapped;
|
||||
}
|
||||
return e;
|
||||
});
|
||||
|
||||
@@ -350,6 +350,29 @@ createApp({
|
||||
const action = getTicketEventAction(ev);
|
||||
let deviceId = String(ev?.device || ev?.device_id || ev?.detail?.device || ev?.detail?.device_id || ev?.["设备编号"] || ev?.["机器ID"] || '---').trim();
|
||||
const dStr = deviceId.toLowerCase();
|
||||
|
||||
// #region debug-point B:index-ticket-device-before-map
|
||||
fetch('http://127.0.0.1:7777/event', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({
|
||||
sessionId: 'device-id-missing',
|
||||
runId: 'pre-fix',
|
||||
hypothesisId: 'B',
|
||||
location: 'web/index.js:351',
|
||||
msg: '[DEBUG] admin ticket formatter raw device',
|
||||
data: {
|
||||
type,
|
||||
action,
|
||||
raw_device: ev?.device ?? null,
|
||||
raw_device_id: ev?.device_id ?? null,
|
||||
raw_detail_device: ev?.detail?.device ?? null,
|
||||
resolved_before_map: deviceId
|
||||
},
|
||||
ts: Date.now()
|
||||
})
|
||||
}).catch(() => {});
|
||||
// #endregion
|
||||
|
||||
if (dStr === 'gate') {
|
||||
deviceId = '闸机';
|
||||
@@ -364,6 +387,26 @@ createApp({
|
||||
deviceId = '售票机';
|
||||
}
|
||||
}
|
||||
|
||||
// #region debug-point B:index-ticket-device-after-map
|
||||
fetch('http://127.0.0.1:7777/event', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({
|
||||
sessionId: 'device-id-missing',
|
||||
runId: 'pre-fix',
|
||||
hypothesisId: 'B',
|
||||
location: 'web/index.js:373',
|
||||
msg: '[DEBUG] admin ticket formatter mapped device',
|
||||
data: {
|
||||
type,
|
||||
action,
|
||||
mapped_device: deviceId
|
||||
},
|
||||
ts: Date.now()
|
||||
})
|
||||
}).catch(() => {});
|
||||
// #endregion
|
||||
const timeStr = formatTime(ev?.ts || ev?.["时间戳"]);
|
||||
|
||||
if (type === 'sale' || type === '售票') {
|
||||
|
||||
@@ -322,6 +322,29 @@
|
||||
const stationEn = event.station_en || event['站点英文'] || '';
|
||||
let deviceId = String(event.device || event.device_id || event.detail?.device || event.detail?.device_id || event['设备编号'] || event['机器ID'] || '').trim();
|
||||
const dStr = deviceId.toLowerCase();
|
||||
|
||||
// #region debug-point B:ticket-board-device-before-map
|
||||
fetch('http://127.0.0.1:7777/event', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({
|
||||
sessionId: 'device-id-missing',
|
||||
runId: 'pre-fix',
|
||||
hypothesisId: 'B',
|
||||
location: 'web/ticket-board.html:323',
|
||||
msg: '[DEBUG] public ticket formatter raw device',
|
||||
data: {
|
||||
type,
|
||||
action,
|
||||
raw_device: event.device ?? null,
|
||||
raw_device_id: event.device_id ?? null,
|
||||
raw_detail_device: event.detail?.device ?? null,
|
||||
resolved_before_map: deviceId
|
||||
},
|
||||
ts: Date.now()
|
||||
})
|
||||
}).catch(() => {});
|
||||
// #endregion
|
||||
|
||||
if (dStr === 'gate') {
|
||||
deviceId = '闸机';
|
||||
@@ -338,6 +361,26 @@
|
||||
deviceId = '售票机';
|
||||
}
|
||||
}
|
||||
|
||||
// #region debug-point B:ticket-board-device-after-map
|
||||
fetch('http://127.0.0.1:7777/event', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({
|
||||
sessionId: 'device-id-missing',
|
||||
runId: 'pre-fix',
|
||||
hypothesisId: 'B',
|
||||
location: 'web/ticket-board.html:345',
|
||||
msg: '[DEBUG] public ticket formatter mapped device',
|
||||
data: {
|
||||
type,
|
||||
action,
|
||||
mapped_device: deviceId
|
||||
},
|
||||
ts: Date.now()
|
||||
})
|
||||
}).catch(() => {});
|
||||
// #endregion
|
||||
|
||||
if (stationEn && deviceId) return `${stationEn} (${deviceId})`;
|
||||
if (deviceId) return `设备:${deviceId}`;
|
||||
|
||||
Reference in New Issue
Block a user