/** * 看板全局配置模块。 * 这里集中维护日期、外链、接口注册和运行时状态,其他 JS 模块只读取这些常量。 * 新增业务接口时优先注册到 apiRegistry,再通过 core 模块的统一请求方法调用,避免在视图层散落接口地址和 token。 */ const TODAY = "2026-07-02"; const PREVIOUS_DAY = "2026-07-01"; const INDICATOR_MORE_URL = "https://psecc.cncecoa.com/webroot/decision/v10/entry/access/e6251c34-31ea-4a35-8269-b83074bd9c64?preview=true"; const ENTERPRISE_INDICATOR_MORE_URL = "https://psecc.cncecoa.com/webroot/decision/view/report?viewlet=%252F%25E6%2595%25B0%25E7%25A7%2591%25E5%2585%25AC%25E5%258F%25B8%252F%25E5%25AE%2589%25E8%25B4%25A8%25E9%2583%25A8%25E6%2595%25B0%25E6%258D%25AE%25E6%25BA%25AF%25E6%25BA%2590%252F%25E5%25AE%2589%25E5%2585%25A8%25E6%2595%25B0%25E6%258D%25AE%25E5%25B1%2595%25E7%25A4%25BA_%25E4%25BC%2581%25E4%25B8%259A%25E7%25BA%25A7.cpt&op=view&__parameters__=%257B%2522__pi__%2522%253Atrue%252C%2522fine_hyperlink%2522%253A%2522ec19fc0a-9bfe-44f8-ba96-8402ba9b7bf2%2522%257D&_=1777453619793"; const GROUP_USAGE_REPORT_URL = "https://lygcgs.com.cn:8078/QHSEDataExChange/res/report/%E6%95%B0%E6%8D%AE%E6%B2%BB%E7%90%86%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88%E5%8F%8A%E6%95%B0%E6%8D%AE%E5%88%86%E6%9E%90%E6%8A%A5%E5%91%8A.pdf"; const OFFICE_PREVIEW_BASE_URL = "https://view.officeapps.live.com/op/embed.aspx?src="; const REPORT_FILE_BASE_URL = "https://sggl.sedin.com.cn/res/report/"; const DATA_GOVERNANCE_API_BASE = "/qhse_webapi/api/DataGovernance"; /** * 接口注册表。 * 当前集团项目上线率卡片和“集团项目上线统计”弹窗依赖 projectMasterDataAnalysis。 * Header 中仅保留后端要求的 token 和 Accept,浏览器侧不主动写 Host/Cookie/Connection 等受限头。 */ const apiRegistry = { projectMasterDataAnalysis: { method: "GET", url: `${DATA_GOVERNANCE_API_BASE}/GetMetricMonitoringSituation`, headers: { token: "AF17168B-87BD-4GLY-1111-F0A0A1158F9B", Accept: "*/*" } }, groupMetricAnalysis: { method: "GET", url: `${DATA_GOVERNANCE_API_BASE}/GetGroupMetricAnalysis`, headers: { token: "AF17168B-87BD-4GLY-1111-F0A0A1158F9B", Accept: "*/*" } }, unitMetricMonitoring: { method: "GET", url: `${DATA_GOVERNANCE_API_BASE}/GetUnitMetricMonitoringSituation`, headers: { token: "AF17168B-87BD-4GLY-1111-F0A0A1158F9B", Accept: "*/*" } }, unitMetricAnalysis: { method: "GET", url: `${DATA_GOVERNANCE_API_BASE}/GetUnitMetricAnalysis`, headers: { token: "AF17168B-87BD-4GLY-1111-F0A0A1158F9B", Accept: "*/*" } }, projectMonitoring: { method: "GET", url: `${DATA_GOVERNANCE_API_BASE}/GetProjectMonitoringSituation`, headers: { token: "AF17168B-87BD-4GLY-1111-F0A0A1158F9B", Accept: "*/*" } } }; /** * 集团主数据接口运行态。 * rows 直接供弹窗表格读取,summary 供集团上线率卡片读取;二者必须成对更新。 * loaded/error/loading 用于视图层展示“接口数据/错误/加载中”的状态差异。 */ const projectMasterDataState = { loading: false, loaded: false, error: "", records: [], summary: null, keyMetricDatas: [], metricDatas: [], metricFieldMap: {}, trendCurve: null, unitAnalysises: [], projectAnalysises: [], unitMetricUsages: [], failProjects: [], metricAnalysis: null, metricAnalysisLoading: false, unitId: "", updatedAt: "" }; const unitMetricAnalysisState = { loading: false, error: "", field: "", unitId: "", data: null }; const projectMonitoringState = { loading: false, error: "", unitId: "", projectId: "", data: null }; /** * 单位一览表文件名映射。 * 弹窗“预览”按钮只通过单位简称查表,不直接拼猜文件名,避免单位顺序或文件命名变化时打开错误附件。 */ const usageReportFiles = {"\u516d\u5316\u5efa":"10\u3001\u516d\u5316\u5efa~\u4e3b\u6570\u636e\u9879\u76ee\u4e0eQHSE\u9879\u76ee\u4e00\u89c8\u88682026.6.3.xlsx","\u4e03\u5316\u5efa":"11\u3001\u4e03\u5316\u5efa~\u4e3b\u6570\u636e\u9879\u76ee\u4e0eQHSE\u9879\u76ee\u4e00\u89c8\u88682026.6.3.xlsx","\u4e5d\u5316\u5efa":"12\u3001\u4e5d\u5316\u5efa~\u4e3b\u6570\u636e\u9879\u76ee\u4e0eQHSE\u9879\u76ee\u4e00\u89c8\u88682026.6.3.xlsx","\u5341\u4e00\u5316\u5efa":"13\u3001\u5341\u4e00\u5316\u5efa~\u4e3b\u6570\u636e\u9879\u76ee\u4e0eQHSE\u9879\u76ee\u4e00\u89c8\u88682026.6.3.xlsx","\u5341\u4e09\u5316\u5efa":"14\u3001\u5341\u4e09\u5316\u5efa~\u4e3b\u6570\u636e\u9879\u76ee\u4e0eQHSE\u9879\u76ee\u4e00\u89c8\u88682026.6.3.xlsx","\u5341\u56db\u5316\u5efa":"15\u3001\u5341\u56db\u5316\u5efa~\u4e3b\u6570\u636e\u9879\u76ee\u4e0eQHSE\u9879\u76ee\u4e00\u89c8\u88682026.6.3.xlsx","\u5341\u516d\u5316\u5efa":"16\u3001\u5341\u516d\u5316\u5efa~\u4e3b\u6570\u636e\u9879\u76ee\u4e0eQHSE\u9879\u76ee\u4e00\u89c8\u88682026.6.3.xlsx","\u571f\u6728":"17\u3001\u571f\u6728~\u4e3b\u6570\u636e\u9879\u76ee\u4e0eQHSE\u9879\u76ee\u4e00\u89c8\u88682026.6.3.xlsx","\u88c5\u5907":"18\u3001\u88c5\u5907~\u4e3b\u6570\u636e\u9879\u76ee\u4e0eQHSE\u9879\u76ee\u4e00\u89c8\u88682026.6.3.xlsx","\u534e\u8c0a":"19\u3001\u534e\u8c0a~\u4e3b\u6570\u636e\u9879\u76ee\u4e0eQHSE\u9879\u76ee\u4e00\u89c8\u88682026.6.3.xlsx","\u5929\u8fb0":"1\u3001\u5929\u8fb0~\u4e3b\u6570\u636e\u9879\u76ee\u4e0eQHSE\u9879\u76ee\u4e00\u89c8\u88682026.6.3.xlsx","\u91cd\u673a":"21\u3001\u91cd\u673a~\u4e3b\u6570\u636e\u9879\u76ee\u4e0eQHSE\u9879\u76ee\u4e00\u89c8\u88682026.6.3.xlsx","\u5317\u5efa\u6295":"22\u3001\u5317\u5efa\u6295~\u4e3b\u6570\u636e\u9879\u76ee\u4e0eQHSE\u9879\u76ee\u4e00\u89c8\u88682026.6.3.xlsx","\u5357\u5efa\u6295":"23\u3001\u5357\u5efa\u6295~\u4e3b\u6570\u636e\u9879\u76ee\u4e0eQHSE\u9879\u76ee\u4e00\u89c8\u88682026.6.3.xlsx","\u57ce\u6295":"24\u3001\u57ce\u6295~\u4e3b\u6570\u636e\u9879\u76ee\u4e0eQHSE\u9879\u76ee\u4e00\u89c8\u88682026.6.3.xlsx","\u4ea4\u5efa":"25\u3001\u4ea4\u5efa~\u4e3b\u6570\u636e\u9879\u76ee\u4e0eQHSE\u9879\u76ee\u4e00\u89c8\u88682026.6.3.xlsx","\u897f\u5357":"27\u3001\u897f\u5357~\u4e3b\u6570\u636e\u9879\u76ee\u4e0eQHSE\u9879\u76ee\u4e00\u89c8\u88682026.6.3.xlsx","\u8d5b\u9f0e":"2\u3001\u8d5b\u9f0e~\u4e3b\u6570\u636e\u9879\u76ee\u4e0eQHSE\u9879\u76ee\u4e00\u89c8\u88682026.6.3.xlsx","\u4e1c\u534e":"3\u3001\u4e1c\u534e~\u4e3b\u6570\u636e\u9879\u76ee\u4e0eQHSE\u9879\u76ee\u4e00\u89c8\u88682026.6.3.xlsx","\u4e94\u73af":"4\u3001\u4e94\u73af~\u4e3b\u6570\u636e\u9879\u76ee\u4e0eQHSE\u9879\u76ee\u4e00\u89c8\u88682026.6.3.xlsx","\u534e\u9646":"5\u3001\u534e\u9646~\u4e3b\u6570\u636e\u9879\u76ee\u4e0eQHSE\u9879\u76ee\u4e00\u89c8\u88682026.6.3.xlsx","\u6210\u8fbe":"6\u3001\u6210\u8fbe~\u4e3b\u6570\u636e\u9879\u76ee\u4e0eQHSE\u9879\u76ee\u4e00\u89c8\u88682026.6.3.xlsx","\u4e8c\u5316\u5efa":"7\u3001\u4e8c\u5316\u5efa~\u4e3b\u6570\u636e\u9879\u76ee\u4e0eQHSE\u9879\u76ee\u4e00\u89c8\u88682026.6.3.xlsx","\u4e09\u5316\u5efa":"8\u3001\u4e09\u5316\u5efa~\u4e3b\u6570\u636e\u9879\u76ee\u4e0eQHSE\u9879\u76ee\u4e00\u89c8\u88682026.6.3.xlsx","\u56db\u5316\u5efa":"9\u3001\u56db\u5316\u5efa~\u4e3b\u6570\u636e\u9879\u76ee\u4e0eQHSE\u9879\u76ee\u4e00\u89c8\u88682026.6.3.xlsx"}; /** * 图表和状态标签共用色板。 * 图表模块只引用这里的语义色,不在 SVG 字符串中硬编码业务颜色。 */ const COLORS = { online: "#5d93ff", usage: "#5ee1b5", accuracy: "#ffc857", warning: "#ff5c66", cyan: "#49d6ff", muted: "#91b8d0" }; /** * 系统页签配置。 * URL 参数 type=1/2/3 会映射到 safety/quality/emergency,并影响可见页签与指标库。 */ const systemLabels = { safety: "安全", quality: "质量", emergency: "应急" }; const systemTypeMap = { 1: "safety", 2: "quality", 3: "emergency" }; /** * 从 URL 解析外部系统允许展示的页签。 * 支持 type、types、system、systems,也兼容纯查询串写法;非法值会回退为全部页签。 */ function getAllowedSystemsFromUrl() { const params = new URLSearchParams(window.location.search); const rawValue = params.get("type") || params.get("types") || params.get("system") || params.get("systems") || window.location.search.replace(/^\?/, ""); if (!rawValue) return Object.values(systemTypeMap); const allowed = rawValue .split(/[,\s,]+/) .map((item) => systemTypeMap[item.trim()]) .filter(Boolean); return allowed.length ? [...new Set(allowed)] : Object.values(systemTypeMap); } const allowedSystems = getAllowedSystemsFromUrl(); /** * 单页看板运行时状态。 * view 控制主区域层级,drillOpen/drillView 控制弹窗层级;事件模块只改 state,再统一触发 render。 */ const state = { view: "group", dimension: "all", system: "safety", enterpriseName: "", projectId: "", selectedIndicator: "", drillOpen: false, drillView: "trend", drillEnterpriseName: "", drillListType: "" };