function kpiCard(label, value, unit, desc, trend, widthPercent, tone = "up") { /** * 集团级页面渲染模块。 * 负责集团总览、集团上线率卡片、企业分析、指标分析和集团上线统计弹窗。 */ return `
${trend ? `
${trend}
` : ""}
${label}
${value}${unit}
${desc}
`; } function clickableKpiCard(label, value, unit, desc, action, widthPercent, trend = "") { return `
${trend ? `
${trend}
` : ""}
${label}
${value}${unit}
${desc}
`; } /** * 集团项目上线率卡片。 * 数值只来自集团监控接口,接口失败时显示错误状态。 */ function onlineKpiCard(summary) { const trendText = projectMasterDataState.loading ? "加载中" : `${toSafeNumber(summary.onlineRate).toFixed(2)}%`; const statusText = projectMasterDataState.error ? `接口请求失败:${projectMasterDataState.error}` : "上线项目/申请不用/应使用项目/项目总数"; return `
${trendText}
集团项目上线率
${summary.proInfoText || `${summary.onlineActual}/${summary.noNeedProjectCount}/${summary.onlineExpected}`}
${statusText}
`; } /** * 面包屑渲染。 * 根据 state.view 组合集团、企业、项目、指标穿透层级,并附带当前维度和系统,方便用户确认筛选上下文。 */ function renderBreadcrumbs() { const parts = [`集团总览`]; if (state.view === "enterprise" || state.view === "project") { parts.push(`›${state.enterpriseName}`); } if (state.view === "project") { const projectName = projectMonitoringState.data?.MetricProjectInfo?.ProjectShortName || projectMonitoringState.data?.MetricProjectInfo?.ProjectName || "项目明细"; parts.push(`›${projectName}`); } if (state.view === "indicatorTrend" || state.view === "indicatorEnterprise" || state.view === "indicatorProject") { const indicator = getSelectedIndicator(); parts.push(`›${indicator.name}`); } if (state.view === "indicatorProject") { parts.push(`›${state.enterpriseName}`); } parts.push(`当前维度:${dimLabel()}`); parts.push(`当前系统:${systemLabel()}`); breadcrumbs.innerHTML = parts.join(""); } /** * 全局主渲染入口。 * 事件模块只改 state,然后调用 render;这里集中决定当前应该渲染哪个视图,避免分散刷新局部 DOM。 */ function render() { applySystemVisibility(); document.querySelectorAll("[data-dim]").forEach((button) => { button.classList.toggle("active", button.dataset.dim === state.dimension); }); document.querySelectorAll("[data-system]").forEach((button) => { button.classList.toggle("active", button.dataset.system === state.system); }); renderBreadcrumbs(); updateDataDateDisplay(); if (state.view === "group") renderGroupView(); if (state.view === "enterprise") renderEnterpriseView(); if (state.view === "project") renderProjectView(); if (state.view === "indicatorTrend") app.innerHTML = renderIndicatorTrendView(); if (state.view === "indicatorProject") app.innerHTML = renderIndicatorProjectView(); renderDrillModal(); } /** * 集团总览主视图。 * 顶部卡片展示集团汇总,中部图表支持企业下钻,底部指标区支持指标穿透和集团报告预览。 */ function renderGroupView() { const summary = groupSummary(); const indicators = getWarningIndicators(); const analysisIndicators = projectMasterDataState.metricDatas.length ? projectMasterDataState.metricDatas : indicators; const activeEnterprises = getGroupEnterpriseModels(); app.innerHTML = `
${onlineKpiCard(summary)} ${clickableKpiCard("预立项项目数", fmtNumber(summary.preProjectTotal), "个", "点击查看集团项目上线统计。", "group-online-stats", clamp(summary.preProjectTotal / 2, 0, 100))} ${clickableKpiCard("待建项目数", fmtNumber(summary.pendingTotal), "个", "点击查看集团项目上线统计。", "group-online-stats", clamp(summary.pendingTotal, 0, 100))} ${clickableKpiCard("未达标项目数", fmtNumber(summary.belowStandardProjects), "个", "指标使用率低于 80% 的项目。", "below-standard-projects", clamp(100 - summary.belowStandardProjects, 0, 100))} ${clickableKpiCard("项目指标使用率", fmtPercent(summary.usageRate), "", "点击查看单位项目指标使用情况。", "group-unit-metric-usages", summary.usageRate)} ${kpiCard("项目指标准确率", fmtPercent(summary.accuracyRate), "", "", "", summary.accuracyRate)}
${renderFocusIndicators(indicators.slice(0, 8), 0, { highlightHigh: false })}

集团三率趋势曲线

近 7 日集团上线率、使用率、准确率变化。
上线 使用 准确
${renderGroupTrendChart(activeEnterprises)}

企业分析

按${dimLabel()}展示${systemLabel()}系统的企业上线率、使用率、准确率。点击企业柱子下钻到企业看板。
上线率 使用率 准确率
${activeEnterprises.length ? renderGroupedRateChart(activeEnterprises, "enterprise", { height: 132 }) : '
暂无企业分析数据
'}

集团在建项目使用分析报告

指标分析

${renderIndicatorAnalysis(analysisIndicators)}
`; } /** * 顶部重点指标条。 * 每张指标卡都带 data-indicator,事件代理会据此打开指标趋势或企业内项目穿透弹窗。 */ function renderFocusIndicators(items, offset, options = {}) { const highlightHigh = options.highlightHigh !== false; return items.map((item, index) => `
${item.name}
指标使用率:${item.usageRate}% 使用项目数:${item.projects}
`).join(""); } /** * 指标分析中的迷你进度条。 * value 控制条宽,displayValue 控制右侧展示文案,便于同一组件同时展示百分比和项目数量。 */ function miniRate(label, value, color, displayValue = `${Math.round(value)}%`) { return `
${label} ${displayValue}
`; } /** * 集团指标分析列表。 * 以项目覆盖量、使用率、准确率三条迷你进度条展示指标风险,用于快速挑出需要穿透的指标。 */ function renderIndicatorAnalysis(indicators) { const maxProjects = Math.max(...indicators.map((item) => item.projects), 1); return `
${indicators.slice(0, 8).map((item) => { return `
${item.name}
${miniRate("项目", Math.round((item.projects / maxProjects) * 100), COLORS.online, item.projects)} ${miniRate("使用", item.usageRate, COLORS.usage)} ${miniRate("准确", indicatorAccuracy(item), COLORS.accuracy)}
`; }).join("")}
`; } /** * 企业指标分析列表。 * 与集团指标列表共用展示结构,但风险文案更偏整改和跟踪,用于企业页面的责任短板展示。 */ function renderEnterpriseIndicatorAnalysis(items) { const maxProjects = Math.max(...items.map((item) => item.projects), 1); return `
${items.map((item) => { return `
${item.name}
${miniRate("项目", Math.round((item.projects / maxProjects) * 100), COLORS.online, item.projects)} ${miniRate("使用", item.usageRate, COLORS.usage)} ${miniRate("准确", item.accuracyRate, COLORS.accuracy)}
`; }).join("")}
`; } /** * 集团上线统计弹窗表格。 * 表格行统一从 getProjectMasterRecords 读取接口数据。 * 国际、生态单位在这里加 green-row,高亮规则集中在表格渲染层。 */ function renderUsageReportTable(list) { const rows = getProjectMasterRecords(); const summary = getProjectMasterSummary(); const statusText = projectMasterDataState.loading ? `
正在获取接口数据...
` : projectMasterDataState.error ? `
接口请求失败:${projectMasterDataState.error}
` : ""; if (!rows.length) { return `${statusText}
暂无集团项目上线统计数据
`; } const bodyRows = rows.map((row) => ({ unit: row.name, cells: [ row.onlineAutoTotal, row.onlineReportedTotal, fmtFixedPercent(row.onlineRate || projectMasterOnlineRate(row), 2), row.total, row.linkedTotal, row.preProjectTotal, row.pendingTotal, Math.max(row.total - row.linkedTotal - row.preProjectTotal - row.pendingTotal, 0), row.noNeedTotal, row.noNeedCompletedTotal, row.noNeedStoppedTotal, row.noNeedRestrictedTotal, row.masterProjectCount ], webUrl: resolveProjectMasterWebUrl(row) })); return ` ${statusText}
${bodyRows.map((row) => { const unit = row.unit || ""; const rowClass = [ unit.includes("国际") || unit.includes("生态") ? "green-row" : "" ].filter(Boolean).join(" "); const unitCell = /^https?:\/\//i.test(row.webUrl) ? `${unit}` : unit; return ` ${row.cells.map((cell) => ``).join("")} `; }).join("")} ${["onlineAutoTotal", "onlineReportedTotal"].map((key) => ``).join("")}
企业简称 上线项目数 上线率 应使用项目数 申请不用 主数据项目数
自动取值 定期填报 总数 已关联项目 预立项项目 待建项目 条件受限 总数 已完工 停缓建 条件受限
${unitCell}${cell}
合计${rows.reduce((sum, row) => sum + toSafeNumber(row[key]), 0)}${fmtFixedPercent(summary.onlineRate, 2)} ${rows.reduce((sum, row) => sum + toSafeNumber(row.total), 0)} ${rows.reduce((sum, row) => sum + toSafeNumber(row.linkedTotal), 0)} ${summary.preProjectTotal} ${summary.pendingTotal} ${rows.reduce((sum, row) => sum + Math.max(row.total - row.linkedTotal - row.preProjectTotal - row.pendingTotal, 0), 0)} ${summary.noNeedProjectCount} ${rows.reduce((sum, row) => sum + toSafeNumber(row.noNeedCompletedTotal), 0)} ${rows.reduce((sum, row) => sum + toSafeNumber(row.noNeedStoppedTotal), 0)} ${rows.reduce((sum, row) => sum + toSafeNumber(row.noNeedRestrictedTotal), 0)} ${rows.reduce((sum, row) => sum + toSafeNumber(row.masterProjectCount), 0)}
`; } function renderBelowStandardProjectListModal() { const enterprise = state.enterpriseName ? getEnterprise(state.enterpriseName) : null; const rows = getBelowStandardProjects(enterprise); const title = enterprise ? `${enterprise.name} · 未达标项目清单` : "集团未达标项目清单"; if (!rows.length) { return `

${title}

当前暂无指标使用率低于 80% 的项目。
`; } return `

${title}

点击项目行进入项目级看板。
${rows.map(({ enterprise: item, project }) => ` `).join("")}
单位 项目名称 指标使用率 是否上线 最近更新 责任人
${item.name} ${project.name} ${fmtPercent(project.usageRate)} ${project.created ? '已上线' : '未上线'} ${project.lastUpdate} ${project.owner}
`; } function renderUnitMetricUsageModal() { const rows = getUnitMetricUsageRecords(); if (!rows.length) { return `

项目指标使用率

当前暂无单位项目指标使用数据。
`; } return `

项目指标使用率

${rows.map((row) => { const unitName = row.abbreviation || row.unitName || ""; const webUrl = resolveUnitMetricUsageWebUrl(row); const unitCell = /^https?:\/\//i.test(webUrl) ? `${unitName}` : unitName; return ` `; }).join("")}
单位简称 QHSE在建项目数 活跃项目数 使用率 日期
${unitCell} ${row.qhseTotal} ${row.activeNum} ${fmtPercent(row.usageRate)} ${formatApiDate(row.date)}
`; } /** * “集团项目上线统计”弹窗内容。 * 弹窗标题由 core 模块 renderDrillModal 设置,这里只负责面板主体和表格。 */ function renderGroupOnlineStatsModal() { return `

集团项目上线统计

${renderUsageReportTable()}
`; }