Files
DataGovernanceDashboard/res/js/indexV2.config.js
T
2026-06-22 10:48:35 +08:00

377 lines
23 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* 看板全局配置模块。
* 这里集中维护日期、外链、接口注册、兜底数据和运行时状态,其他 JS 模块只读取这些常量。
* 新增业务接口时优先注册到 apiRegistry,再通过 core 模块的统一请求方法调用,避免在视图层散落接口地址和 token。
*/
const TODAY = "2026-04-27";
const PREVIOUS_DAY = "2026-04-26";
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/";
/**
* 接口注册表。
* 当前集团项目上线率卡片和“集团项目上线统计”弹窗依赖 projectMasterDataAnalysis。
* Header 中仅保留后端要求的 token 和 Accept,浏览器侧不主动写 Host/Cookie/Connection 等受限头。
*/
const apiRegistry = {
projectMasterDataAnalysis: {
method: "GET",
url: "https://qhse.cncecoa.com/qhse_webapi/api/Common/GetProjectMasterDataAnalysis?unitId=",
headers: {
token: "AF17168B-87BD-4GLY-1111-F0A0A1158F9B",
Accept: "*/*"
}
}
};
/**
* 本地兜底表头和行数据。
* 接口加载失败或跨域被拦截时仍展示旧 Excel 口径,避免主卡片和弹窗空白。
*/
const usageReportHeaders = ["\u5e8f\u53f7", "\u5355\u4f4d", "\u4e3b\u6570\u636e\u9879\u76ee\u603b\u6570", "\u7533\u8bf7QHSE\u672a\u5efa\u9879\u76ee\u6570", "QHSE\u9879\u76ee\u603b\u6570\u6570", "QHSE\u4e0e\u4e3b\u6570\u636e\u5173\u8054\u9879\u76ee\u6570", "QHSE\u9879\u76ee\u5173\u8054\u4e0d\u5230\u4e3b\u6570\u636e\u9879\u76ee\u6570"];
const projectMasterDataHeaders = ["序号", "单位", "主数据项目数", "申请不用项目数", "QHSE使用项目数", "已关联", "待建", "预立项", "上报日期"];
const usageReportRows = [["1","\u5929\u8fb0","67","34","42","33","9"],["2","\u8d5b\u9f0e","33","3","52","30","22"],["3","\u4e1c\u534e","40","11","33","29","4"],["4","\u4e94\u73af","51","22","29","29","0"],["5","\u534e\u9646","38","4","34","34","0"],["6","\u6210\u8fbe","24","6","19","18","1"],["7","\u4e8c\u5316\u5efa","234","78","166","156","10"],["8","\u4e09\u5316\u5efa","167","36","151","131","20"],["9","\u56db\u5316\u5efa","117","46","84","71","13"],["10","\u516d\u5316\u5efa","263","90","199","173","26"],["11","\u4e03\u5316\u5efa","24","4","22","20","2"],["12","\u4e5d\u5316\u5efa","36","19","19","17","2"],["13","\u5341\u4e00\u5316\u5efa","69","17","57","52","5"],["14","\u5341\u4e09\u5316\u5efa","90","27","70","63","7"],["15","\u5341\u56db\u5316\u5efa","74","1","78","73","5"],["16","\u5341\u516d\u5316\u5efa","177","78","110","99","11"],["17","\u571f\u6728","42","11","33","31","2"],["18","\u88c5\u5907","14","5","9","9","0"],["19","\u534e\u8c0a","9","2","9","7","2"],["20","\u56fd\u9645","1","0","1","1","0"],["21","\u91cd\u673a","51","10","44","41","3"],["22","\u5317\u5efa\u6295","18","5","16","13","3"],["23","\u5357\u5efa\u6295","83","24","60","59","1"],["24","\u57ce\u6295","12","4","12","8","4"],["25","\u4ea4\u5efa","21","5","27","16","11"],["26","\u751f\u6001","31","0","31","31","0"],["27","\u897f\u5357","9","2","18","7","11"],["\u5408\u8ba1","","1795","544","1425","1251","174"]];
/**
* 集团主数据接口运行态。
* rows 直接供弹窗表格读取,summary 供集团上线率卡片读取;二者必须成对更新。
* loaded/error/loading 用于视图层展示“接口数据/兜底数据/加载中”的状态差异。
*/
const projectMasterDataState = {
loading: false,
loaded: false,
error: "",
rows: usageReportRows,
summary: null,
updatedAt: ""
};
/**
* 单位一览表文件名映射。
* 弹窗“预览”按钮只通过单位简称查表,不直接拼猜文件名,避免单位顺序或文件命名变化时打开错误附件。
*/
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"
};
/**
* 企业级模拟基础数据。
* 企业/项目/指标多层页面都会从这里派生统计值;真实接口只接入集团主数据时,仍保留该数据支撑其他模块演示。
*/
const enterprises = [
{
name: "天辰公司",
owner: "张海",
stats: {
all: { projectCount: 40, onlineRate: 92, usageRate: 84, accuracyRate: 88, warningProjects: 4, warningItems: 39 },
new: { projectCount: 7, onlineRate: 86, usageRate: 78, accuracyRate: 82, warningProjects: 2, warningItems: 8 }
},
trend: { online: [88, 89, 90, 90, 91, 92, 92], usage: [78, 79, 80, 81, 82, 83, 84], accuracy: [84, 84, 85, 86, 86, 87, 88] }
},
{
name: "赛鼎公司",
owner: "刘明",
stats: {
all: { projectCount: 28, onlineRate: 83, usageRate: 69, accuracyRate: 70, warningProjects: 6, warningItems: 39 },
new: { projectCount: 6, onlineRate: 72, usageRate: 58, accuracyRate: 63, warningProjects: 4, warningItems: 12 }
},
trend: { online: [80, 80, 81, 82, 82, 83, 83], usage: [64, 64, 65, 66, 67, 68, 69], accuracy: [73, 72, 72, 71, 70, 70, 70] }
},
{
name: "东华公司",
owner: "王斌",
stats: {
all: { projectCount: 32, onlineRate: 88, usageRate: 76, accuracyRate: 79, warningProjects: 5, warningItems: 39 },
new: { projectCount: 3, onlineRate: 85, usageRate: 67, accuracyRate: 72, warningProjects: 2, warningItems: 7 }
},
trend: { online: [85, 85, 86, 86, 87, 88, 88], usage: [72, 72, 73, 74, 75, 76, 76], accuracy: [78, 78, 78, 79, 79, 79, 79] }
},
{
name: "五环公司",
owner: "赵宁",
stats: {
all: { projectCount: 24, onlineRate: 86, usageRate: 72, accuracyRate: 75, warningProjects: 4, warningItems: 32 },
new: { projectCount: 0, onlineRate: 0, usageRate: 0, accuracyRate: 0, warningProjects: 0, warningItems: 0 }
},
trend: { online: [82, 83, 84, 85, 85, 86, 86], usage: [68, 69, 70, 70, 71, 72, 72], accuracy: [72, 73, 74, 74, 74, 75, 75] }
},
{
name: "华陆公司",
owner: "陈哲",
stats: {
all: { projectCount: 25, onlineRate: 91, usageRate: 81, accuracyRate: 86, warningProjects: 3, warningItems: 28 },
new: { projectCount: 2, onlineRate: 90, usageRate: 74, accuracyRate: 80, warningProjects: 1, warningItems: 4 }
},
trend: { online: [89, 89, 90, 90, 91, 91, 91], usage: [76, 77, 78, 79, 80, 80, 81], accuracy: [83, 84, 84, 85, 85, 86, 86] }
},
{
name: "成达公司",
owner: "李强",
stats: {
all: { projectCount: 13, onlineRate: 95, usageRate: 88, accuracyRate: 90, warningProjects: 1, warningItems: 16 },
new: { projectCount: 0, onlineRate: 0, usageRate: 0, accuracyRate: 0, warningProjects: 0, warningItems: 0 }
},
trend: { online: [93, 93, 94, 94, 95, 95, 95], usage: [84, 85, 86, 86, 87, 88, 88], accuracy: [88, 88, 89, 89, 90, 90, 90] }
},
{
name: "二建",
owner: "周亮",
stats: {
all: { projectCount: 112, onlineRate: 84, usageRate: 73, accuracyRate: 80, warningProjects: 9, warningItems: 42 },
new: { projectCount: 13, onlineRate: 79, usageRate: 66, accuracyRate: 70, warningProjects: 5, warningItems: 10 }
},
trend: { online: [82, 82, 83, 83, 84, 84, 84], usage: [68, 69, 70, 71, 72, 73, 73], accuracy: [78, 78, 79, 79, 80, 80, 80] }
},
{
name: "三建",
owner: "孙越",
stats: {
all: { projectCount: 130, onlineRate: 78, usageRate: 64, accuracyRate: 66, warningProjects: 14, warningItems: 48 },
new: { projectCount: 12, onlineRate: 75, usageRate: 58, accuracyRate: 61, warningProjects: 7, warningItems: 13 }
},
trend: { online: [75, 75, 76, 76, 77, 78, 78], usage: [61, 61, 62, 62, 63, 64, 64], accuracy: [68, 67, 67, 66, 66, 66, 66] }
},
{
name: "四建",
owner: "马骏",
stats: {
all: { projectCount: 71, onlineRate: 87, usageRate: 78, accuracyRate: 82, warningProjects: 6, warningItems: 24 },
new: { projectCount: 5, onlineRate: 82, usageRate: 74, accuracyRate: 76, warningProjects: 2, warningItems: 6 }
},
trend: { online: [85, 85, 86, 86, 87, 87, 87], usage: [74, 75, 76, 76, 77, 78, 78], accuracy: [79, 80, 80, 81, 81, 82, 82] }
},
{
name: "六建",
owner: "韩伟",
stats: {
all: { projectCount: 192, onlineRate: 84, usageRate: 61, accuracyRate: 60, warningProjects: 22, warningItems: 55 },
new: { projectCount: 22, onlineRate: 78, usageRate: 52, accuracyRate: 56, warningProjects: 10, warningItems: 18 }
},
trend: { online: [81, 82, 82, 83, 83, 84, 84], usage: [58, 58, 59, 60, 60, 61, 61], accuracy: [63, 62, 62, 61, 61, 60, 60] }
},
{
name: "十一建",
owner: "郑一",
stats: {
all: { projectCount: 62, onlineRate: 89, usageRate: 77, accuracyRate: 78, warningProjects: 5, warningItems: 21 },
new: { projectCount: 5, onlineRate: 84, usageRate: 70, accuracyRate: 70, warningProjects: 2, warningItems: 5 }
},
trend: { online: [86, 87, 87, 88, 88, 89, 89], usage: [73, 74, 75, 76, 76, 77, 77], accuracy: [76, 76, 77, 77, 78, 78, 78] }
},
{
name: "十四建",
owner: "沈涛",
stats: {
all: { projectCount: 64, onlineRate: 82, usageRate: 68, accuracyRate: 69, warningProjects: 8, warningItems: 35 },
new: { projectCount: 9, onlineRate: 76, usageRate: 57, accuracyRate: 62, warningProjects: 5, warningItems: 9 }
},
trend: { online: [80, 80, 81, 81, 82, 82, 82], usage: [65, 65, 66, 67, 67, 68, 68], accuracy: [72, 71, 70, 70, 69, 69, 69] }
},
{
name: "十六建",
owner: "蒋峰",
stats: {
all: { projectCount: 81, onlineRate: 85, usageRate: 71, accuracyRate: 73, warningProjects: 7, warningItems: 31 },
new: { projectCount: 6, onlineRate: 80, usageRate: 65, accuracyRate: 67, warningProjects: 3, warningItems: 6 }
},
trend: { online: [82, 83, 83, 84, 84, 85, 85], usage: [67, 68, 69, 69, 70, 71, 71], accuracy: [75, 74, 74, 73, 73, 73, 73] }
},
{
name: "装备科技",
owner: "何平",
stats: {
all: { projectCount: 1, onlineRate: 100, usageRate: 100, accuracyRate: 100, warningProjects: 0, warningItems: 2 },
new: { projectCount: 0, onlineRate: 0, usageRate: 0, accuracyRate: 0, warningProjects: 0, warningItems: 0 }
},
trend: { online: [100, 100, 100, 100, 100, 100, 100], usage: [100, 100, 100, 100, 100, 100, 100], accuracy: [100, 100, 100, 100, 100, 100, 100] }
},
{
name: "南投",
owner: "梁旭",
stats: {
all: { projectCount: 29, onlineRate: 74, usageRate: 55, accuracyRate: 66, warningProjects: 6, warningItems: 18 },
new: { projectCount: 2, onlineRate: 70, usageRate: 50, accuracyRate: 55, warningProjects: 1, warningItems: 3 }
},
trend: { online: [72, 72, 73, 73, 74, 74, 74], usage: [53, 53, 54, 54, 55, 55, 55], accuracy: [66, 66, 66, 66, 66, 66, 66] }
},
{
name: "交建",
owner: "秦毅",
stats: {
all: { projectCount: 26, onlineRate: 80, usageRate: 69, accuracyRate: 72, warningProjects: 4, warningItems: 17 },
new: { projectCount: 2, onlineRate: 75, usageRate: 60, accuracyRate: 62, warningProjects: 1, warningItems: 2 }
},
trend: { online: [78, 78, 79, 79, 80, 80, 80], usage: [66, 67, 67, 68, 68, 69, 69], accuracy: [71, 71, 72, 72, 72, 72, 72] }
},
{
name: "生态",
owner: "郭晨",
stats: {
all: { projectCount: 17, onlineRate: 76, usageRate: 62, accuracyRate: 64, warningProjects: 5, warningItems: 22 },
new: { projectCount: 1, onlineRate: 70, usageRate: 55, accuracyRate: 55, warningProjects: 1, warningItems: 3 }
},
trend: { online: [73, 74, 74, 75, 75, 76, 76], usage: [59, 60, 60, 61, 61, 62, 62], accuracy: [66, 65, 65, 64, 64, 64, 64] }
}
];
/**
* 当前准确率口径尚未接入正式数据,统一置 0,避免不同层级出现不一致的模拟准确率。
*/
enterprises.forEach((enterprise) => {
["all", "new"].forEach((dimension) => {
enterprise.stats[dimension].accuracyRate = 0;
});
enterprise.trend.accuracy = [0, 0, 0, 0, 0, 0, 0];
});
/**
* 系统页签配置。
* 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();
/**
* 各业务系统的重点指标池。
* 集团页指标卡、指标分析面板、指标穿透弹窗都从当前系统对应数组取数。
*/
const warningIndicatorMap = {
safety: [
{ name: "专职安全管理人员(含分包)总数", projects: 150, enterprises: 18, usageRate: 72 },
{ name: "特种作业人员数量", projects: 138, enterprises: 16, usageRate: 74 },
{ name: "危大工程进行中个数", projects: 121, enterprises: 15, usageRate: 69 },
{ name: "重大风险", projects: 116, enterprises: 14, usageRate: 76 },
{ name: "较大风险", projects: 104, enterprises: 13, usageRate: 68 },
{ name: "高风险作业许可进行中数量", projects: 98, enterprises: 12, usageRate: 71 },
{ name: "专项培训", projects: 92, enterprises: 12, usageRate: 66 },
{ name: "三级安全教育培训人次", projects: 86, enterprises: 11, usageRate: 70 }
],
quality: [
{ name: "项目质量管理人数", projects: 136, enterprises: 17, usageRate: 70 },
{ name: "人员报验数", projects: 128, enterprises: 16, usageRate: 68 },
{ name: "培训人次", projects: 112, enterprises: 15, usageRate: 73 },
{ name: "技术交底人次", projects: 105, enterprises: 14, usageRate: 71 },
{ name: "企业及分支机构检查数", projects: 96, enterprises: 13, usageRate: 65 },
{ name: "项目质量检查数", projects: 91, enterprises: 12, usageRate: 69 },
{ name: "施工方案企业审批总数", projects: 83, enterprises: 11, usageRate: 63 },
{ name: "施工方案项目审批总数", projects: 80, enterprises: 11, usageRate: 66 }
],
emergency: [
{ name: "应急预案备案", projects: 118, enterprises: 16, usageRate: 69 },
{ name: "应急演练记录", projects: 111, enterprises: 15, usageRate: 64 },
{ name: "应急物资台账", projects: 103, enterprises: 14, usageRate: 67 },
{ name: "应急队伍配置", projects: 96, enterprises: 13, usageRate: 70 },
{ name: "重大风险告警", projects: 88, enterprises: 12, usageRate: 62 },
{ name: "专项应急培训", projects: 81, enterprises: 11, usageRate: 66 },
{ name: "应急联络人员", projects: 76, enterprises: 10, usageRate: 71 },
{ name: "现场处置方案", projects: 72, enterprises: 10, usageRate: 63 },
{ name: "应急响应记录", projects: 66, enterprises: 9, usageRate: 60 },
{ name: "复盘整改闭环", projects: 61, enterprises: 8, usageRate: 58 }
]
};
/**
* 项目明细页字段模板。
* buildIndicatorRows 会结合项目使用率和滞后天数生成“是否启用、三日值、是否预警”等派生字段。
*/
const indicatorTemplates = [
{ name: "预警项数", field: "warningCount", base: 48 },
{ name: "参建人数", field: "participants", base: 215 },
{ name: "在施危大工程数", field: "dangerWorks", base: 3 },
{ name: "安全技术交底数", field: "safetyDisclosure", base: 69 },
{ name: "三级安全教育培训数", field: "safetyTraining", base: 555 },
{ name: "专项培训数", field: "specialTraining", base: 25 },
{ name: "特种作业培训数", field: "specialWorkTraining", base: 3 },
{ name: "项目总监人数", field: "directorCount", base: 1 },
{ name: "项目专职人数", field: "fulltimeCount", base: 5 },
{ name: "项目安全监护人数", field: "guardianCount", base: 2 },
{ name: "在岗执业注册师", field: "registeredEngineer", base: 4 },
{ name: "A证人员", field: "certA", base: 1 },
{ name: "B证人员", field: "certB", base: 2 },
{ name: "C证人员", field: "certC", base: 4 },
{ name: "特种作业人员", field: "specialWorkers", base: 57 },
{ name: "项目安全领导小组会议数", field: "safetyMeeting", base: 2 },
{ name: "项目安全例会数", field: "regularMeeting", base: 21 },
{ name: "项目负责人带班检查次数", field: "leaderInspection", base: 3 },
{ name: "项目专项检查次数", field: "specialInspection", base: 46 },
{ name: "项目专业检查次数", field: "professionInspection", base: 132 }
];
/**
* 项目名称池。
* generateProjects 用企业简称加这些后缀生成稳定项目名,保证同一企业在不同渲染中项目顺序一致。
*/
const projectNamePool = [
"精细化工材料项目",
"煤炭深加工基地项目",
"全场系统工程",
"新材料园区工程",
"装置检修项目",
"安全提升改造工程",
"数字化施工项目",
"生产运行保障项目",
"罐区扩能工程",
"绿色低碳改造项目",
"配套管廊工程",
"污水处理优化项目",
"储运系统升级项目",
"消防能力提升项目",
"基础设施完善项目",
"智能工地试点项目",
"综合楼建设项目",
"设备更新项目"
];
/**
* 单页看板运行时状态。
* view 控制主区域层级,drillOpen/drillView 控制弹窗层级;事件模块只改 state,再统一触发 render。
*/
const state = {
view: "group",
dimension: "all",
system: "safety",
enterpriseName: "",
projectId: "",
selectedIndicator: "",
drillOpen: false,
drillView: "trend",
drillEnterpriseName: "",
drillListType: ""
};