feat(platform): surface source readiness on dashboard
This commit is contained in:
@@ -174,6 +174,146 @@ test('exposes AMap operations shortcuts when map key is configured', async () =>
|
||||
})
|
||||
} as Response;
|
||||
}
|
||||
if (path.includes('/api/ops/source-readiness')) {
|
||||
return {
|
||||
ok: true,
|
||||
json: async () => ({
|
||||
data: {
|
||||
totalVehicles: 1033,
|
||||
onlineVehicles: 208,
|
||||
kafkaLag: 0,
|
||||
activeConnections: 1234,
|
||||
redisOnlineKeys: 368,
|
||||
platformRelease: 'platform-dashboard-test',
|
||||
sources: [
|
||||
{
|
||||
protocol: 'GB32960',
|
||||
role: '整车与氢能实时数据主来源',
|
||||
online: 73,
|
||||
total: 340,
|
||||
onlineRate: 21.47,
|
||||
missingVehicles: 693,
|
||||
severity: 'warning',
|
||||
status: '覆盖不足',
|
||||
evidence: '在线 73/340,缺失车辆 693,Kafka Lag 0',
|
||||
action: '核对现代和交投平台转发清单。',
|
||||
acceptance: '缺失来源车辆下降,单源车辆可解释。',
|
||||
vehiclesHash: '#/vehicles?protocol=GB32960&missingProtocol=GB32960',
|
||||
realtimeHash: '#/realtime?protocol=GB32960&online=online',
|
||||
historyHash: '#/history-query?protocol=GB32960&tab=raw&includeFields=true',
|
||||
alertHash: '#/alert-events?protocol=GB32960'
|
||||
},
|
||||
{
|
||||
protocol: 'JT808',
|
||||
role: '位置、总里程和设备在线主来源',
|
||||
online: 174,
|
||||
total: 424,
|
||||
onlineRate: 41.04,
|
||||
missingVehicles: 609,
|
||||
severity: 'warning',
|
||||
status: '覆盖不足',
|
||||
evidence: '在线 174/424,缺失车辆 609,Kafka Lag 0',
|
||||
action: '补齐手机号绑定和注册缺失车辆。',
|
||||
acceptance: '未知 VIN 注册下降,位置与里程持续可查。',
|
||||
vehiclesHash: '#/vehicles?protocol=JT808&missingProtocol=JT808',
|
||||
realtimeHash: '#/realtime?protocol=JT808&online=online',
|
||||
historyHash: '#/history-query?protocol=JT808&tab=raw&includeFields=true',
|
||||
alertHash: '#/alert-events?protocol=JT808'
|
||||
},
|
||||
{
|
||||
protocol: 'YUTONG_MQTT',
|
||||
role: '宇通派生工况与燃料电池补充来源',
|
||||
online: 11,
|
||||
total: 50,
|
||||
onlineRate: 22,
|
||||
missingVehicles: 983,
|
||||
severity: 'ok',
|
||||
status: '生产可用',
|
||||
evidence: '在线 11/50,缺失车辆 983,Kafka Lag 0',
|
||||
action: '保持实时、轨迹、RAW 和统计链路巡检。',
|
||||
acceptance: '车辆服务可回查实时、轨迹和 RAW 证据。',
|
||||
vehiclesHash: '#/vehicles?protocol=YUTONG_MQTT&missingProtocol=YUTONG_MQTT',
|
||||
realtimeHash: '#/realtime?protocol=YUTONG_MQTT&online=online',
|
||||
historyHash: '#/history-query?protocol=YUTONG_MQTT&tab=raw&includeFields=true',
|
||||
alertHash: '#/alert-events?protocol=YUTONG_MQTT'
|
||||
}
|
||||
]
|
||||
},
|
||||
traceId: 'trace-test',
|
||||
timestamp: 1783094400000
|
||||
})
|
||||
} as Response;
|
||||
}
|
||||
if (path.includes('/api/ops/source-readiness')) {
|
||||
return {
|
||||
ok: true,
|
||||
json: async () => ({
|
||||
data: {
|
||||
totalVehicles: 1033,
|
||||
onlineVehicles: 208,
|
||||
kafkaLag: 0,
|
||||
activeConnections: 1234,
|
||||
redisOnlineKeys: 368,
|
||||
platformRelease: 'platform-dashboard-test',
|
||||
sources: [
|
||||
{
|
||||
protocol: 'GB32960',
|
||||
role: '整车与氢能实时数据主来源',
|
||||
online: 73,
|
||||
total: 340,
|
||||
onlineRate: 21.47,
|
||||
missingVehicles: 693,
|
||||
severity: 'warning',
|
||||
status: '覆盖不足',
|
||||
evidence: '在线 73/340,缺失车辆 693,Kafka Lag 0',
|
||||
action: '核对现代和交投平台转发清单。',
|
||||
acceptance: '缺失来源车辆下降,单源车辆可解释。',
|
||||
vehiclesHash: '#/vehicles?protocol=GB32960&missingProtocol=GB32960',
|
||||
realtimeHash: '#/realtime?protocol=GB32960&online=online',
|
||||
historyHash: '#/history-query?protocol=GB32960&tab=raw&includeFields=true',
|
||||
alertHash: '#/alert-events?protocol=GB32960'
|
||||
},
|
||||
{
|
||||
protocol: 'JT808',
|
||||
role: '位置、总里程和设备在线主来源',
|
||||
online: 174,
|
||||
total: 424,
|
||||
onlineRate: 41.04,
|
||||
missingVehicles: 609,
|
||||
severity: 'warning',
|
||||
status: '覆盖不足',
|
||||
evidence: '在线 174/424,缺失车辆 609,Kafka Lag 0',
|
||||
action: '补齐手机号绑定和注册缺失车辆。',
|
||||
acceptance: '未知 VIN 注册下降,位置与里程持续可查。',
|
||||
vehiclesHash: '#/vehicles?protocol=JT808&missingProtocol=JT808',
|
||||
realtimeHash: '#/realtime?protocol=JT808&online=online',
|
||||
historyHash: '#/history-query?protocol=JT808&tab=raw&includeFields=true',
|
||||
alertHash: '#/alert-events?protocol=JT808'
|
||||
},
|
||||
{
|
||||
protocol: 'YUTONG_MQTT',
|
||||
role: '宇通派生工况与燃料电池补充来源',
|
||||
online: 11,
|
||||
total: 50,
|
||||
onlineRate: 22,
|
||||
missingVehicles: 983,
|
||||
severity: 'ok',
|
||||
status: '生产可用',
|
||||
evidence: '在线 11/50,缺失车辆 983,Kafka Lag 0',
|
||||
action: '保持实时、轨迹、RAW 和统计链路巡检。',
|
||||
acceptance: '车辆服务可回查实时、轨迹和 RAW 证据。',
|
||||
vehiclesHash: '#/vehicles?protocol=YUTONG_MQTT&missingProtocol=YUTONG_MQTT',
|
||||
realtimeHash: '#/realtime?protocol=YUTONG_MQTT&online=online',
|
||||
historyHash: '#/history-query?protocol=YUTONG_MQTT&tab=raw&includeFields=true',
|
||||
alertHash: '#/alert-events?protocol=YUTONG_MQTT'
|
||||
}
|
||||
]
|
||||
},
|
||||
traceId: 'trace-test',
|
||||
timestamp: 1783094400000
|
||||
})
|
||||
} as Response;
|
||||
}
|
||||
return {
|
||||
ok: true,
|
||||
json: async () => ({
|
||||
@@ -297,6 +437,76 @@ test('shows global alert pressure from notification plan in topbar', async () =>
|
||||
})
|
||||
} as Response;
|
||||
}
|
||||
if (path.includes('/api/ops/source-readiness')) {
|
||||
return {
|
||||
ok: true,
|
||||
json: async () => ({
|
||||
data: {
|
||||
totalVehicles: 1033,
|
||||
onlineVehicles: 208,
|
||||
kafkaLag: 0,
|
||||
activeConnections: 1234,
|
||||
redisOnlineKeys: 368,
|
||||
platformRelease: 'platform-dashboard-test',
|
||||
sources: [
|
||||
{
|
||||
protocol: 'GB32960',
|
||||
role: '整车与氢能实时数据主来源',
|
||||
online: 73,
|
||||
total: 340,
|
||||
onlineRate: 21.47,
|
||||
missingVehicles: 693,
|
||||
severity: 'warning',
|
||||
status: '覆盖不足',
|
||||
evidence: '在线 73/340,缺失车辆 693,Kafka Lag 0',
|
||||
action: '核对现代和交投平台转发清单。',
|
||||
acceptance: '缺失来源车辆下降,单源车辆可解释。',
|
||||
vehiclesHash: '#/vehicles?protocol=GB32960&missingProtocol=GB32960',
|
||||
realtimeHash: '#/realtime?protocol=GB32960&online=online',
|
||||
historyHash: '#/history-query?protocol=GB32960&tab=raw&includeFields=true',
|
||||
alertHash: '#/alert-events?protocol=GB32960'
|
||||
},
|
||||
{
|
||||
protocol: 'JT808',
|
||||
role: '位置、总里程和设备在线主来源',
|
||||
online: 174,
|
||||
total: 424,
|
||||
onlineRate: 41.04,
|
||||
missingVehicles: 609,
|
||||
severity: 'warning',
|
||||
status: '覆盖不足',
|
||||
evidence: '在线 174/424,缺失车辆 609,Kafka Lag 0',
|
||||
action: '补齐手机号绑定和注册缺失车辆。',
|
||||
acceptance: '未知 VIN 注册下降,位置与里程持续可查。',
|
||||
vehiclesHash: '#/vehicles?protocol=JT808&missingProtocol=JT808',
|
||||
realtimeHash: '#/realtime?protocol=JT808&online=online',
|
||||
historyHash: '#/history-query?protocol=JT808&tab=raw&includeFields=true',
|
||||
alertHash: '#/alert-events?protocol=JT808'
|
||||
},
|
||||
{
|
||||
protocol: 'YUTONG_MQTT',
|
||||
role: '宇通派生工况与燃料电池补充来源',
|
||||
online: 11,
|
||||
total: 50,
|
||||
onlineRate: 22,
|
||||
missingVehicles: 983,
|
||||
severity: 'ok',
|
||||
status: '生产可用',
|
||||
evidence: '在线 11/50,缺失车辆 983,Kafka Lag 0',
|
||||
action: '保持实时、轨迹、RAW 和统计链路巡检。',
|
||||
acceptance: '车辆服务可回查实时、轨迹和 RAW 证据。',
|
||||
vehiclesHash: '#/vehicles?protocol=YUTONG_MQTT&missingProtocol=YUTONG_MQTT',
|
||||
realtimeHash: '#/realtime?protocol=YUTONG_MQTT&online=online',
|
||||
historyHash: '#/history-query?protocol=YUTONG_MQTT&tab=raw&includeFields=true',
|
||||
alertHash: '#/alert-events?protocol=YUTONG_MQTT'
|
||||
}
|
||||
]
|
||||
},
|
||||
traceId: 'trace-test',
|
||||
timestamp: 1783094400000
|
||||
})
|
||||
} as Response;
|
||||
}
|
||||
return {
|
||||
ok: true,
|
||||
json: async () => ({
|
||||
@@ -537,6 +747,76 @@ test('dashboard exposes vehicle data center capability matrix', async () => {
|
||||
});
|
||||
vi.spyOn(globalThis, 'fetch').mockImplementation(async (input) => {
|
||||
const path = String(input);
|
||||
if (path.includes('/api/ops/source-readiness')) {
|
||||
return {
|
||||
ok: true,
|
||||
json: async () => ({
|
||||
data: {
|
||||
totalVehicles: 1033,
|
||||
onlineVehicles: 208,
|
||||
kafkaLag: 0,
|
||||
activeConnections: 1234,
|
||||
redisOnlineKeys: 368,
|
||||
platformRelease: 'platform-dashboard-test',
|
||||
sources: [
|
||||
{
|
||||
protocol: 'GB32960',
|
||||
role: '整车与氢能实时数据主来源',
|
||||
online: 73,
|
||||
total: 340,
|
||||
onlineRate: 21.47,
|
||||
missingVehicles: 693,
|
||||
severity: 'warning',
|
||||
status: '覆盖不足',
|
||||
evidence: '在线 73/340,缺失车辆 693,Kafka Lag 0',
|
||||
action: '核对现代和交投平台转发清单。',
|
||||
acceptance: '缺失来源车辆下降,单源车辆可解释。',
|
||||
vehiclesHash: '#/vehicles?protocol=GB32960&missingProtocol=GB32960',
|
||||
realtimeHash: '#/realtime?protocol=GB32960&online=online',
|
||||
historyHash: '#/history-query?protocol=GB32960&tab=raw&includeFields=true',
|
||||
alertHash: '#/alert-events?protocol=GB32960'
|
||||
},
|
||||
{
|
||||
protocol: 'JT808',
|
||||
role: '位置、总里程和设备在线主来源',
|
||||
online: 174,
|
||||
total: 424,
|
||||
onlineRate: 41.04,
|
||||
missingVehicles: 609,
|
||||
severity: 'warning',
|
||||
status: '覆盖不足',
|
||||
evidence: '在线 174/424,缺失车辆 609,Kafka Lag 0',
|
||||
action: '补齐手机号绑定和注册缺失车辆。',
|
||||
acceptance: '未知 VIN 注册下降,位置与里程持续可查。',
|
||||
vehiclesHash: '#/vehicles?protocol=JT808&missingProtocol=JT808',
|
||||
realtimeHash: '#/realtime?protocol=JT808&online=online',
|
||||
historyHash: '#/history-query?protocol=JT808&tab=raw&includeFields=true',
|
||||
alertHash: '#/alert-events?protocol=JT808'
|
||||
},
|
||||
{
|
||||
protocol: 'YUTONG_MQTT',
|
||||
role: '宇通派生工况与燃料电池补充来源',
|
||||
online: 11,
|
||||
total: 50,
|
||||
onlineRate: 22,
|
||||
missingVehicles: 983,
|
||||
severity: 'ok',
|
||||
status: '生产可用',
|
||||
evidence: '在线 11/50,缺失车辆 983,Kafka Lag 0',
|
||||
action: '保持实时、轨迹、RAW 和统计链路巡检。',
|
||||
acceptance: '车辆服务可回查实时、轨迹和 RAW 证据。',
|
||||
vehiclesHash: '#/vehicles?protocol=YUTONG_MQTT&missingProtocol=YUTONG_MQTT',
|
||||
realtimeHash: '#/realtime?protocol=YUTONG_MQTT&online=online',
|
||||
historyHash: '#/history-query?protocol=YUTONG_MQTT&tab=raw&includeFields=true',
|
||||
alertHash: '#/alert-events?protocol=YUTONG_MQTT'
|
||||
}
|
||||
]
|
||||
},
|
||||
traceId: 'trace-test',
|
||||
timestamp: 1783094400000
|
||||
})
|
||||
} as Response;
|
||||
}
|
||||
if (path.includes('/api/ops/health')) {
|
||||
return {
|
||||
ok: true,
|
||||
@@ -651,6 +931,7 @@ test('dashboard exposes vehicle data center capability matrix', async () => {
|
||||
|
||||
await renderDashboard();
|
||||
expect(screen.getByText('车辆服务作业台')).toBeInTheDocument();
|
||||
expect(screen.getByText('数据源到车辆服务就绪度')).toBeInTheDocument();
|
||||
expect(screen.getByText('地图运营能力')).toBeInTheDocument();
|
||||
expect(screen.getByText('数据流转作业链')).toBeInTheDocument();
|
||||
expect(screen.getByText('车联网场景导航')).toBeInTheDocument();
|
||||
@@ -658,6 +939,11 @@ test('dashboard exposes vehicle data center capability matrix', async () => {
|
||||
expect(screen.getByText('服务端 API')).toBeInTheDocument();
|
||||
expect(screen.getByText('安全代理')).toBeInTheDocument();
|
||||
expect(screen.getByText('安全码暴露')).toBeInTheDocument();
|
||||
expect(screen.getByText('GB32960')).toBeInTheDocument();
|
||||
expect(screen.getByText('JT808')).toBeInTheDocument();
|
||||
expect(screen.getByText('YUTONG_MQTT')).toBeInTheDocument();
|
||||
expect(screen.getByText('整车与氢能实时数据主来源')).toBeInTheDocument();
|
||||
expect(screen.getByText('在线 73/340,缺失车辆 693,Kafka Lag 0')).toBeInTheDocument();
|
||||
expect(screen.getByText('协议接入')).toBeInTheDocument();
|
||||
expect(screen.getByText('统一解析')).toBeInTheDocument();
|
||||
expect(screen.getByText('实时投影')).toBeInTheDocument();
|
||||
@@ -698,6 +984,18 @@ test('dashboard exposes vehicle data center capability matrix', async () => {
|
||||
expect(writeText).toHaveBeenCalledWith(expect.stringContaining('【车辆数据中台数据流转图】'));
|
||||
expect(writeText).toHaveBeenCalledWith(expect.stringContaining('03. 实时投影 / Redis KV'));
|
||||
|
||||
fireEvent.click(screen.getAllByRole('button', { name: '实时' })[0]);
|
||||
expect(window.location.hash).toBe('#/realtime?protocol=GB32960&online=online');
|
||||
cleanup();
|
||||
|
||||
await renderDashboard();
|
||||
fireEvent.click(screen.getAllByRole('button', { name: 'RAW' })[0]);
|
||||
expect(window.location.hash.startsWith('#/history-query')).toBe(true);
|
||||
expect(new URLSearchParams(window.location.hash.split('?')[1] ?? '').get('protocol')).toBe('GB32960');
|
||||
expect(new URLSearchParams(window.location.hash.split('?')[1] ?? '').get('includeFields')).toBe('true');
|
||||
cleanup();
|
||||
|
||||
await renderDashboard();
|
||||
fireEvent.click(screen.getByRole('button', { name: '地图运营 实时监控' }));
|
||||
expect(window.location.hash).toBe('#/map?online=online');
|
||||
cleanup();
|
||||
|
||||
Reference in New Issue
Block a user