/** * 配置与数据源的词汇 + 「状态 → 视觉键」映射(票 04,纯函数、可脱浏览器断言)。 * * 和 domain/statusTones.js 一样:这里只决定「状态叫什么、用哪个色键、标签怎么写」, * 不做业务判断,也不碰网络。配置服务(services/cockpitConfig.js)反过来依赖这里的常量。 */ /** 配置加载三态(票 04 验收:成功 / 失败 / 缺失都要能演示)。 */ export const CONFIG_STATE = { READY: 'ready', MISSING: 'missing', FAILED: 'failed', } /** 数据源两态:默认 mock,真实接口必须由部署配置显式开启。 */ export const DATA_SOURCE = { MOCK: 'mock', REAL: 'real', } /** 前端是否自带只读 token;REST 免鉴权后该值恒为 `none`(ADR 0005 修订),保留供状态视图判断。 */ export const CREDENTIAL = { CONFIG: 'config', NONE: 'none', } /** * 把配置加载结果映射成顶栏标签用的视图模型。 * @param {object} state services/cockpitConfig.js 的加载结果 * @returns {{state: string, tone: string, label: string, detail: string, dataSource: string}} */ export function configStatusView(state) { const current = state || {} const config = current.config || {} const dataSource = config.dataSource === DATA_SOURCE.REAL ? DATA_SOURCE.REAL : DATA_SOURCE.MOCK if (current.state === CONFIG_STATE.READY) { return { state: CONFIG_STATE.READY, dataSource, tone: 'lv4', label: `配置就绪 · 数据源 ${dataSource}`, // ADR 0005 修订(2026-09-28):驾驶舱 REST 免鉴权,接口安全由网络层内网隔离保障。 detail: dataSource === DATA_SOURCE.REAL ? '接口免鉴权(内网隔离)' : '', } } if (current.state === CONFIG_STATE.FAILED) { return { state: CONFIG_STATE.FAILED, dataSource, tone: 'lv1', label: '配置载入失败 · 数据不可用', detail: current.error || '', } } return { state: CONFIG_STATE.MISSING, dataSource, tone: 'neutral', label: '配置缺失 · 用内置默认(mock)', detail: current.url ? `尝试过 ${current.url}` : '', } } /** 数据不可用分区统一文案(票 05 起各分区据此渲染,票 04 只定义措辞,避免各处自造)。 */ export const DATA_UNAVAILABLE_LABEL = '数据不可用' /** * 请求失败原因 → 是否属于「凭据类失败」(这类失败按 ADR 0005 只标数据不可用,绝不跳登录页)。 * @param {string} reason services/cockpitApi.js 的 REQUEST_REASON */ export function isCredentialFailure(reason) { return reason === 'unauthorized' || reason === 'no-credential' }