| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241 |
- node:internal/modules/run_main:107
- triggerUncaughtException(
- ^
- AssertionError [ERR_ASSERTION]: 外壳要有区状态读数
- at file:///E:/City-Lifeline-Cockpit-TvT/.scratch/cockpit-shell-panel-layout/verify/t37-area-limits.mjs:466:8
- at ModuleJob.run (node:internal/modules/esm/module_job:561:25)
- at async node:internal/modules/esm/loader:647:26
- at async asyncRunEntryPointWithESMLoader (node:internal/modules/run_main:101:5) {
- generatedMessage: false,
- code: 'ERR_ASSERTION',
- actual: '<!--\r\n' +
- ' 驾驶舱外壳:唯一 /cockpit 路由的全部内容。\r\n' +
- '\r\n' +
- ' 骨架与视觉参考《驾驶舱原型图-美化版》(切角面板 / 青色辉光 / 深空蓝底 / 全息地图壳),\r\n' +
- ' 但不锁 16:9:页面铺满视口,**中央一张图作为整个主体的背景铺满**,左右两栏浮在图上。\r\n' +
- '\r\n' +
- ' 语义按 ADR 0003 / 0007:四个一级模式、模式内 4 个二级面板同屏展示、无子视图切换。\r\n' +
- ' 一级模式只通过 uiStore.mode 切换,不新增路由、不重建外壳与地图节点。\r\n' +
- ' 范围与行业是全局筛选(filterStore),切换一级模式不得重置它们(验收第 ⑦ 条)。\r\n' +
- '-->\r\n' +
- '<template>\r\n' +
- ' <div class="cockpit-shell">\r\n' +
- ' <div class="cockpit-shell__atmosphere" aria-hidden="true"></div>\r\n' +
- '\r\n' +
- ' <header class="cockpit-shell__topbar">\r\n' +
- ' <div class="cockpit-shell__topbar-bg" aria-hidden="true"></div>\r\n' +
- ' <span class="cockpit-shell__wing is-left" aria-hidden="true"></span>\r\n' +
- ' <span class="cockpit-shell__wing is-right" aria-hidden="true"></span>\r\n' +
- '\r\n' +
- ' <div class="cockpit-shell__brand">\r\n' +
- ' <span class="cockpit-shell__mark" aria-hidden="true">\r\n' +
- ' <CockpitIcon name="brand" size="100%" />\r\n' +
- ' </span>\r\n' +
- ' <span class="cockpit-shell__brand-text">\r\n' +
- ' <strong>城市生命线驾驶舱系统</strong>\r\n' +
- ' <em>沅陵县 · 只读展示</em>\r\n' +
- ' </span>\r\n' +
- ' </div>\r\n' +
- '\r\n' +
- ' <nav class="cockpit-shell__modes" aria-label="一级模式">\r\n' +
- ' <button\r\n' +
- ' v-for="item in MODES"\r\n' +
- ' :key="item"\r\n' +
- ' type="button"\r\n' +
- ' class="cockpit-shell__mode"\r\n' +
- ` :class="{ 'is-active': item === mode }"\r\n` +
- ' :aria-pressed="item === mode"\r\n' +
- ' @click="uiStore.setMode(item)"\r\n' +
- ' >\r\n' +
- ' {{ modeLabel(item) }}\r\n' +
- ' </button>\r\n' +
- ' </nav>\r\n' +
- '\r\n' +
- ' <div class="cockpit-shell__top-meta">\r\n' +
- ' <!--\r\n' +
- ' 票 30:快速归位(回到目标城市预设视角)。\r\n' +
- ' 票 37:区内/区外文案不同 —— 区内是「归位」(已进区,只是回该视角);\r\n' +
- ' 区外是「归位/进入」(点它就进区并锁定,ADR 0009 R2-5)。\r\n' +
- ' -->\r\n' +
- ' <button\r\n' +
- ' type="button"\r\n' +
- ' class="cockpit-shell__chip cockpit-shell__home"\r\n' +
- ` :class="{ 'is-active': atHomeView }"\r\n` +
- ` :data-home-at="atHomeView ? 'yes' : 'no'"\r\n` +
- ` :data-area-locked="areaLocked ? 'yes' : 'no'"\r\n` +
- ' :title="homeTitle"\r\n' +
- ' :aria-label="areaBar.homeLabel"\r\n' +
- ' @click="returnHome()"\r\n' +
- ' >\r\n' +
- ' {{ areaBar.homeLabel }}\r\n' +
- ' </button>\r\n' +
- ' <!-- 票 37:只有区内才有「返回全球」(区外它没有意义,不占位置)。 -->\r\n' +
- ' <button\r\n' +
- ' v-if="areaBar.returnGlobal"\r\n' +
- ' type="button"\r\n' +
- ' class="cockpit-shell__chip cockpit-shell__return-global"\r\n' +
- ' data-return-global\r\n' +
- ' :title="`解除主场景区限位,回到自由全球视角(区内最远 ${Math.round(areaLimits.max)} m)`"\r\n' +
- ' @click="returnToGlobal()"\r\n' +
- ' >\r\n' +
- ' 返回全球\r\n' +
- ' </button>\r\n' +
- ' <!-- 票 04:配置三态 + 数据源,顶栏可演示;data-* 供走查断言。\r\n' +
- ' 票 32:这是开发期的诊断读数,生产形态不占顶栏(状态退到底部小字)。 -->\r\n' +
- ' <span\r\n' +
- ' v-if="configLoaded && uiDebug"\r\n' +
- ' class="cockpit-shell__config"\r\n' +
- ' :data-config-state="configView.state"\r\n' +
- ' :data-data-source="configView.dataSource"\r\n' +
- ' :data-source="configState.source"\r\n' +
- ' >\r\n' +
- ' <StatusTag :tone="configView.tone" :label="configView.label" />\r\n' +
- ' </span>\r\n' +
- ' <span class="cockpit-shell__chip">只读视图</span>\r\n' +
- ' <span class="cockpit-shell__clock">{{ clockText }}</span>\r\n' +
- ' <p v-if="uiDebug" class="cockpit-shell__meta">当前模式 {{ mode }}</p>\r\n' +
- ' </div>\r\n' +
- ' </header>\r\n' +
- '\r\n' +
- ' <!-- 全局筛选:作用于整个驾驶舱,切换一级模式不重置 -->\r\n' +
- ' <div class="cockpit-shell__scope">\r\n' +
- ' <div class="cockpit-shell__scope-left">\r\n' +
- ' <span class="cockpit-shell__scope-label">当前范围</span>\r\n' +
- ' <div class="cockpit-shell__chips">\r\n' +
- ' <button\r\n' +
- ' v-for="item in SCOPES"\r\n' +
- ' :key="item.key"\r\n' +
- ' type="button"\r\n' +
- ' class="cockpit-shell__chip cockpit-shell__scope-btn"\r\n' +
- ` :class="{ 'is-active': item.key === scope }"\r\n` +
- ' :aria-pressed="item.key === scope"\r\n' +
- ' :data-scope="item.key"\r\n' +
- ' @click="filterStore.setScope(item.key)"\r\n' +
- ' >\r\n' +
- ' {{ item.label }}\r\n' +
- ' </button>\r\n' +
- ' </div>\r\n' +
- '\r\n' +
- ' <span class="cockpit-shell__divider" aria-hidden="true"></span>\r\n' +
- '\r\n' +
- ' <span class="cockpit-shell__scope-label">行业</span>\r\n' +
- ' <div class="cockpit-shell__chips">\r\n' +
- ' <button\r\n' +
- ' v-for="item in INDUSTRIES"\r\n' +
- ' :key="item.key"\r\n' +
- ' type="button"\r\n' +
- ' class="cockpit-shell__chip cockpit-shell__industry-btn"\r\n' +
- ` :class="{ 'is-active': item.key === industry }"\r\n` +
- ' :aria-pressed="item.key === industry"\r\n' +
- ' :data-industry="item.key"\r\n' +
- ' @click="filterStore.setIndustry(item.key)"\r\n' +
- ' >\r\n' +
- ' {{ item.label }}\r\n' +
- ' </button>\r\n' +
- ' </div>\r\n' +
- '\r\n' +
- ' <span class="cockpit-shell__divider" aria-hidden="true"></span>\r\n' +
- '\r\n' +
- ' <!--\r\n' +
- ' 票 21:地面/管线视图(决策地图票 05 定的「全局视图条件」)。\r\n' +
- ' 它是全局条件,与范围/行业同级 —— 切换一级模式不重置它。\r\n' +
- ' -->\r\n' +
- ' <span class="cockpit-shell__scope-label">视图</span>\r\n' +
- ' <div class="cockpit-shell__chips">\r\n' +
- ' <button\r\n' +
- ' v-for="item in VIEW_MODE_OPTIONS"\r\n' +
- ' :key="item.key"\r\n' +
- ' type="button"\r\n' +
- ' class="cockpit-shell__chip cockpit-shell__view-btn"\r\n' +
- ` :class="{ 'is-active': item.key === viewMode }"\r\n` +
- ' :aria-pressed="item.key === viewMode"\r\n' +
- ' :data-view-mode="item.key"\r\n' +
- ' :title="item.hint"\r\n' +
- ' @click="switchViewMode(item.key)"\r\n' +
- ' >\r\n' +
- ' {{ item.label }}\r\n' +
- ' </button>\r\n' +
- ' </div>\r\n' +
- ' </div>\r\n' +
- '\r\n' +
- ' <div class="cockpit-shell__scope-right">\r\n' +
- ' <div\r\n' +
- ' class="cockpit-shell__status-summary"\r\n' +
- ` :class="{ 'is-open': statusPanelExpanded }"\r\n` +
- ` :data-status-expanded="statusPanelExpanded ? 'true' : 'false'"\r\n` +
- ' >\r\n' +
- ' <button\r\n' +
- ' type="button"\r\n' +
- ' class="cockpit-shell__status-toggle"\r\n' +
- ' data-status-toggle\r\n' +
- ' :aria-expanded="statusPanelExpanded"\r\n' +
- ' aria-controls="cockpit-status-details"\r\n' +
- ' @click="statusPanelExpanded = !statusPanelExpanded"\r\n' +
- ' >\r\n' +
- ' <i class="cockpit-shell__status-dot" :class="statusSummaryTone" aria-hidden="true"></i>\r\n' +
- ' <span data-status-summary>{{ statusSummaryText }}</span>\r\n' +
- ` <span class="cockpit-shell__status-chevron" aria-hidden="true">{{ statusPanelExpanded ? '⌃' : '⌄' }}</span>\r\n` +
- ' </button>\r\n' +
- ' <div\r\n' +
- ' id="cockpit-status-details"\r\n' +
- ' v-show="statusPanelExpanded"\r\n' +
- ' class="cockpit-shell__status-details"\r\n' +
- ' data-status-details\r\n' +
- ' >\r\n' +
- ' <!--\r\n' +
- ' 票 14(决策 02 的 Q24/Q25):地图摘要进入系统/筛选变化后**自动分批加载到完成**。\r\n' +
- ' 它作为状态详情的一行保留 `data-map-summary-*` 断言面;手动刷新按钮移到状态摘要\r\n' +
- ' 右侧独立位置,避免和范围/行业/视图选择争抢横向空间。\r\n' +
- ' -->\r\n' +
- ' <div\r\n' +
- ' class="cockpit-shell__map-summary"\r\n' +
- ' :data-map-summary-phase="mapSummaryView.phase"\r\n' +
- ' role="status"\r\n' +
- ' aria-label="地图摘要"\r\n' +
- ' >\r\n' +
- ' <i class="cockpit-shell__map-summary-dot" aria-hidden="true"></i>\r\n' +
- ' <span class="cockpit-shell__map-summary-text" data-map-summary-label :title="mapSummaryView.detail">\r\n' +
- ' {{ mapSummaryView.label }}\r\n' +
- ' </span>\r\n' +
- ' </div>\r\n' +
- '\r\n' +
- ' <!--\r\n' +
- ' 票 05:共享数据分区的状态板。验收第 6 条要的「只把受影响分区标为数据不可用、\r\n' +
- ' 保留已成功分区与地图骨架」在这里可见;每个分区带 data-section-* 供走查断言。\r\n' +
- ' 票 14(规格 09):real 与 mock **同构启动**——同一套分区语义对两种数据源都成立,\r\n' +
- ' real 的失败路径(不可达 / 未配地址)同样只标对应分区。\r\n' +
- ' -->\r\n' +
- ' <span class="cockpit-shell__scope-label">数据分区</span>\r\n' +
- ' <div class="cockpit-shell__sections" data-section-board>\r\n' +
- ' <SectionStateTag\r\n' +
- ' v-for="item in sharedSections"\r\n' +
- ' :key="item.name"\r\n' +
- ' :name="item.name"\r\n' +
- ' :section="item.section"\r\n' +
- ' :label="item.label"\r\n' +
- ' />\r\n' +
- ' </div>\r\n' +
- '\r\n' +
- ' <!--\r\n' +
- ' 票 17:定位反馈。点面板里的可定位对象时,只有三种结果值得说话 ——\r\n' +
- ' 点位不在已加载范围内、后端判定不可上图、地图还没就绪。\r\n' +
- ' 成功不给文字(地图自己会动、详情卡会开,再弹一句是噪音)。\r\n' +
- ' -->\r\n' +
- ' <span\r\n' +
- ' v-if="locateFeedback"\r\n' +
- ' class="cockpit-shell__chip cockpit-shell__locate"\r\n' +
- ' :data-locate-result="locateFeedback.result"\r\n' +
- ' role="status"\r\n' +
- ' >\r\n' +
- ' {{ locateFeedback.reasonText }}\r\n' +
- ' </span>\r\n' +
- '\r\n' +
- ' <span v-if="detailOpen && !introVisible && !fixedLocationReason && !anchorLayout.visible"\r\n' +
- ' '... 73408 more characters,
- expected: /data-area-state/,
- operator: 'match',
- diff: 'simple'
- }
- Node.js v24.20.0
|