index.js 4.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. /**
  2. * 契约化 mock 的注册入口(票 05)。
  3. *
  4. * 为什么要有这一层而不是让页面直接 import `contractMocks.js`:
  5. * 「注册」与「样例数据」分开——页面只调用 `ensureCockpitMocks()`,
  6. * 换样例(走查要演示 401/空/过期)不改页面代码。
  7. *
  8. * 场景覆盖(走查与人工演示都用同一套开关,无需改代码重新构建):
  9. * `window.__COCKPIT_MOCK_SCENARIO__` = `success`(默认)| `empty` | `degraded` | `stale` | `failed` | `unauthorized`
  10. * 票 09 追加 `point-statuses`:后端六态 + 未关联设备 + 一个前端不认识的状态,全部可上图。
  11. * 它只影响 `/map-snapshot` 的样例内容,不改默认场景的任何数字(票 07/08 的断言依赖那些数)。
  12. * 票 10 追加 `point-detail-order`:设备卡片逆状态优先级排列,验「顺序由后端返回顺序决定」。
  13. * 票 11 追加 `equipment-partial`:设备详情**分区级部分失败**(档案/工单/图片各自 FAILED,
  14. * 指标/预警/报警照常 SUCCESS),验「任一分区失败不遮盖其它成功分区」。它与 `failed` 不同:
  15. * `failed` 是端点整体读不到(`data` 为 null),那是"详情没取到"而不是"取到了但有坏块"。
  16. * 票 12 追加 `work-order-timeline`:四张工单各一条独立时间线(一路推进 / 待验收回退处理中 /
  17. * 延期中旁路 / 已取消四种形状都齐),验状态时间线与「验收驳回是回退动作而不是独立终态」。
  18. * 追加 `work-order-timeline-failed`:**只有时间线分区失败**、工单列表照常成功 ——
  19. * 验「轨迹没取到」与「这张工单没有动作记录」是两句不同的话。
  20. * 票 45 追加 `device-layer-overlap-degraded`:11 台设备同坐标(K=11 > maxFan=10),
  21. * 验「本屏显示 10 台 / 其余见清单」降级形态与预警模式的状态过滤。
  22. * 票 17 追加 `infrastructure-partial`:应急保障的「防护目标」段没取到,其余段照常画 ——
  23. * 验「一段没取到」与「这一段确实没有对象」是两句不同的话。
  24. * 票 18 追加 `monitoring-no-devices`:运行监测的在线率**分母为 0**
  25. * (后端回 `state=EMPTY` + `value="0.0000"`)—— 验「没有可算的设备」不被画成「在线率 0.0%」。
  26. * 注意这些场景名只被**它自己那族的 builder** 认;别的端点认不出就照 `success` 走
  27. * (所以 `monitoring-no-devices` 不会把地图或基础设施打空)。
  28. * `window.__COCKPIT_MOCK_ONLY__` = 只让这一个路径走上面的异常样例,其余保持成功
  29. * (票 05 验收第 6 条要的正是「只把**受影响分区**标为数据不可用」)
  30. * `window.__COCKPIT_MOCK_PREFIX__` = 同上,按路径前缀选中一族接口(如 `/equipments/`)
  31. * `window.__COCKPIT_MOCK_MAP__` = 地图摘要分页的现场覆盖(票 08):
  32. * `{ pageSize, snapshotAt, expireAfterPage }`
  33. * —— 例如 `{ pageSize: 2, expireAfterPage: 1 }` 演示「取完第 1 页后快照失效」
  34. *
  35. * 注册是幂等的:重复调用只覆盖,不叠加。
  36. */
  37. import {
  38. getMockTransportPaths,
  39. registerMockTransport,
  40. resetMockTransportsForTest,
  41. } from '../services/cockpitApi.js'
  42. import { registerCockpitMocks } from './contractMocks.js'
  43. /** 只读全局开关(走查用;生产不会设这些键)。 */
  44. function readScenario() {
  45. if (typeof globalThis === 'undefined') return {}
  46. return {
  47. scenario: globalThis.__COCKPIT_MOCK_SCENARIO__ || 'success',
  48. onlyPath: globalThis.__COCKPIT_MOCK_ONLY__ || '',
  49. prefix: globalThis.__COCKPIT_MOCK_PREFIX__ || '',
  50. mapSnapshot: globalThis.__COCKPIT_MOCK_MAP__ || {},
  51. // 票 18:运行监测的现场覆盖(`{ pageSize }`)。后端页大小默认 500,而样例只有 8 条,
  52. // 压不小就演示不出台账的渐进加载(走查 B 组靠它)。
  53. monitoring: globalThis.__COCKPIT_MOCK_MONITORING__ || {},
  54. }
  55. }
  56. /** 注册全部契约化 mock(幂等)。返回本次生效的场景,便于走查/排查。 */
  57. export function ensureCockpitMocks(overrides = {}) {
  58. const global = readScenario()
  59. const scenario = overrides.scenario || global.scenario
  60. const onlyPath = overrides.onlyPath || global.onlyPath
  61. const prefix = overrides.prefix || global.prefix
  62. const mapSnapshot = overrides.mapSnapshot || global.mapSnapshot
  63. const monitoring = overrides.monitoring || global.monitoring
  64. const result = registerCockpitMocks({
  65. scenario,
  66. onlyPath,
  67. prefix,
  68. mapSnapshot,
  69. monitoring,
  70. handlers: { registerMockTransport, getMockTransportPaths, resetMockTransportsForTest },
  71. })
  72. return result
  73. }