(async function () { const INITIAL_HASH = location.hash; const VERSION = new URLSearchParams(location.search).get("v") || ""; const STYLE_HREFS = [ "/hc-etms.sqygj.cn/static/css/chunk-elementUI.db8918ff.css", "/hc-etms.sqygj.cn/static/css/chunk-libs.3dfb7769.css", "/hc-etms.sqygj.cn/static/css/app.b5657ae9.css" ]; const SCRIPT_SRCS = [ "./webpack-runtime.js", "/hc-etms.sqygj.cn/static/js/chunk-elementUI.19e378d9.js", "/hc-etms.sqygj.cn/static/js/chunk-libs.d8d09258.js", "/hc-etms.sqygj.cn/static/js/app.8e16015e.js" ]; let storageSeed = {}; let routeMap = {}; const MICROBRAIN_PRESETS = { finance: { eyebrow: "经营总览", headline: "财务看板", summary: "围绕收入、利润、现金与应收四个维度生成静态仪表盘,用于替代空态页。", accent: "#2d76ff", accentSoft: "rgba(45, 118, 255, 0.16)", metrics: [ { label: "本年累计收入", value: "¥2,056,000", delta: "较上月 +8.4%" }, { label: "净利润率", value: "19.6%", delta: "经营状态良好" }, { label: "经营现金流", value: "¥386,000", delta: "回款率 93.8%" }, { label: "应收账款余额", value: "¥126,800", delta: "逾期项目 3 个" } ], trendLabels: ["1月", "2月", "3月", "4月", "5月", "6月"], trendSeries: [ { label: "收入", color: "#2d76ff", values: [128, 136, 142, 156, 163, 172] }, { label: "利润", color: "#2fc1a8", values: [22, 24, 26, 29, 31, 34] } ], segments: [ { label: "物业费", value: "54%", tone: "#2d76ff" }, { label: "停车费", value: "21%", tone: "#20c997" }, { label: "增值服务", value: "15%", tone: "#ffb74d" }, { label: "其他收入", value: "10%", tone: "#a78bfa" } ], rankingTitle: "项目贡献排行", rankingRows: [ ["循环花园一期", "¥462,000", "22.5%"], ["博万物", "¥318,000", "15.5%"], ["深圳市美好花园", "¥286,000", "13.9%"], ["循环科技三期", "¥244,000", "11.9%"] ], alertsTitle: "财务提示", alerts: [ { title: "广州三俊物业管理有限公司", detail: "本月票据待核销 2 笔,建议财务复核。", level: "关注" }, { title: "循环花园一期", detail: "停车费回款偏慢,较预算少 6.2%。", level: "预警" }, { title: "江南世家", detail: "成本支出稳定,预算执行率 91%。", level: "正常" } ] }, equipment: { eyebrow: "资产运行", headline: "设备看板", summary: "补齐设备资产、维保执行、故障预警与能耗概览,替代原始“敬请期待”页面。", accent: "#00a870", accentSoft: "rgba(0, 168, 112, 0.16)", metrics: [ { label: "设备总台账", value: "1,286", delta: "在线率 97.3%" }, { label: "本月维保完成", value: "214", delta: "完成率 92.1%" }, { label: "待处理预警", value: "18", delta: "一级预警 3 条" }, { label: "本月能耗", value: "18.6万kWh", delta: "较上月 -4.8%" } ], trendLabels: ["1周", "2周", "3周", "4周", "5周", "6周"], trendSeries: [ { label: "工单关闭量", color: "#00a870", values: [26, 32, 29, 36, 39, 42] }, { label: "新增预警", color: "#ff8a00", values: [14, 12, 11, 10, 8, 7] } ], segments: [ { label: "电梯", value: "34%", tone: "#00a870" }, { label: "消防", value: "28%", tone: "#2d76ff" }, { label: "供配电", value: "22%", tone: "#ff8a00" }, { label: "给排水", value: "16%", tone: "#a78bfa" } ], rankingTitle: "维保完成排行", rankingRows: [ ["循环花园一期", "48 项", "100%"], ["博万物", "41 项", "97%"], ["连城花园", "33 项", "94%"], ["美好花园", "28 项", "91%"] ], alertsTitle: "设备预警", alerts: [ { title: "电梯系统", detail: "2 台电梯年检临期,需在 7 天内完成复检。", level: "预警" }, { title: "消防泵房", detail: "巡检记录缺失 1 次,已通知项目负责人补录。", level: "关注" }, { title: "供配电房", detail: "夜间负荷恢复正常,建议继续观察。", level: "正常" } ] }, parkingLot: { eyebrow: "车场经营", headline: "车场看板", summary: "展示车位利用、出入流量、收费表现与异常车牌,补齐停车运营视图。", accent: "#7c4dff", accentSoft: "rgba(124, 77, 255, 0.16)", metrics: [ { label: "总车位数", value: "2,146", delta: "固定车位 1,382" }, { label: "当前占用率", value: "81.4%", delta: "较昨日 +2.6%" }, { label: "本月停车收入", value: "¥486,300", delta: "临停车收入占比 38%" }, { label: "异常进出记录", value: "12", delta: "黑名单 2 辆" } ], trendLabels: ["08时", "10时", "12时", "14时", "16时", "18时"], trendSeries: [ { label: "进场车辆", color: "#7c4dff", values: [42, 58, 63, 71, 76, 69] }, { label: "离场车辆", color: "#2fc1a8", values: [35, 46, 58, 64, 70, 66] } ], segments: [ { label: "固定月租", value: "62%", tone: "#7c4dff" }, { label: "临停收费", value: "24%", tone: "#2d76ff" }, { label: "新能源充电", value: "9%", tone: "#20c997" }, { label: "其他", value: "5%", tone: "#ffb74d" } ], rankingTitle: "项目车场收益排行", rankingRows: [ ["循环花园一期", "¥96,800", "88.4%"], ["博万物", "¥74,200", "82.7%"], ["美好花园", "¥68,500", "79.3%"], ["连城花园", "¥61,900", "75.1%"] ], alertsTitle: "车场异常", alerts: [ { title: "粤B9X2F8", detail: "同一车辆 24 小时内重复进出 5 次,建议复核。", level: "关注" }, { title: "循环花园一期", detail: "北门道闸离线 18 分钟,已恢复在线。", level: "预警" }, { title: "博万物", detail: "新能源桩周转率较高,可考虑扩容。", level: "正常" } ] }, supplierMicrobrain: { eyebrow: "供应协同", headline: "供应商微脑", summary: "围绕供应商覆盖、履约、结算与风险预警生成静态仪表盘,替代空态页。", accent: "#f97316", accentSoft: "rgba(249, 115, 22, 0.16)", metrics: [ { label: "合作供应商", value: "86", delta: "活跃供应商 63 家" }, { label: "本月履约率", value: "91.8%", delta: "较上月 +2.1%" }, { label: "待结算金额", value: "¥268,400", delta: "本周待审核 7 笔" }, { label: "风险预警", value: "6", delta: "高风险 2 家" } ], trendLabels: ["1周", "2周", "3周", "4周", "5周", "6周"], trendSeries: [ { label: "履约评分", color: "#f97316", values: [78, 81, 84, 86, 88, 91] }, { label: "结算完成率", color: "#2d76ff", values: [62, 66, 71, 75, 79, 83] } ], segments: [ { label: "保洁服务", value: "34%", tone: "#f97316" }, { label: "安防服务", value: "26%", tone: "#2d76ff" }, { label: "设备维保", value: "24%", tone: "#20c997" }, { label: "绿化养护", value: "16%", tone: "#a78bfa" } ], rankingTitle: "供应商履约排行", rankingRows: [ ["星河保洁服务有限公司", "96 分", "98%"], ["万嘉设备维保有限公司", "93 分", "94%"], ["城安安防科技有限公司", "91 分", "92%"], ["绿景园林服务有限公司", "89 分", "90%"] ], alertsTitle: "供应风险提示", alerts: [ { title: "广州市三俊物业管理有限公司", detail: "2 笔结算资料待补充,建议本周内完成复核。", level: "关注" }, { title: "万嘉设备维保有限公司", detail: "一项维保任务已逾期 3 天,需供应商经理跟进。", level: "预警" }, { title: "星河保洁服务有限公司", detail: "本月履约稳定,建议纳入优质供应商池。", level: "正常" } ] } }; const CLOUD_REPORT_PRESETS = { propertyFeeReport: { title: "物业费收缴明细表", eyebrow: "收费经营", accent: "#2d76ff", accentSoft: "rgba(45, 118, 255, 0.14)", cards: [ { label: "年度预算收缴", value: "¥4,268,000", detail: "预算达成 88.2%" }, { label: "本月实收当月", value: "¥356,800", detail: "较上月 +6.5%" }, { label: "本月收缴率", value: "92.4%", detail: "欠费项目 3 个" }, { label: "本年累计收缴率", value: "89.6%", detail: "回款节奏稳定" } ], headers: ["项目名称", "省/市/区", "年度预算收缴金额", "往年欠费金额", "往月欠费金额", "本月收缴往年欠费金额", "本月收缴往月欠费金额", "本月预收缴金额", "本月实收当月金额", "本月收缴率", "本年累计收缴率"], rows: [ ["循环花园一期", "湖北省/黄石市/下陆区", "¥886,000", "¥42,800", "¥31,500", "¥12,600", "¥9,800", "¥28,500", "¥74,300", "93.8%", "91.2%"], ["博万物", "广东省/深圳市/龙华区", "¥712,000", "¥36,400", "¥28,900", "¥8,200", "¥6,100", "¥21,600", "¥58,400", "89.5%", "87.1%"], ["美好花园", "广东省/深圳市/福田区", "¥658,000", "¥18,600", "¥22,300", "¥6,500", "¥5,400", "¥19,100", "¥54,900", "94.2%", "90.8%"], ["连城花园", "湖南省/长沙市/芙蓉区", "¥624,000", "¥15,900", "¥18,600", "¥4,600", "¥3,900", "¥16,700", "¥49,500", "91.7%", "88.5%"], ["循环科技三期", "天津市/河东区", "¥592,000", "¥12,300", "¥15,800", "¥3,800", "¥3,500", "¥15,200", "¥46,200", "90.6%", "86.9%"], ["江南世家一期", "湖北省/黄石市/下陆区", "¥516,000", "¥10,800", "¥13,600", "¥2,700", "¥2,100", "¥12,600", "¥41,700", "88.4%", "85.7%"] ] }, parkingLotReport: { title: "车场列表", eyebrow: "车场运营", accent: "#7c4dff", accentSoft: "rgba(124, 77, 255, 0.14)", cards: [ { label: "今日进出总量", value: "612 / 584", detail: "高峰出现在 16:00" }, { label: "本月临停费", value: "¥186,400", detail: "较上月 +8.1%" }, { label: "本月月卡费", value: "¥302,800", detail: "固定车位 1,382 个" }, { label: "异常开闸率", value: "1.8%", detail: "可疑收费 4 笔" } ], headers: ["小区名称", "省/市/区", "今日进出数量", "今日临停费", "本月临停费", "本月月卡费", "今日异常开闸数", "今日可疑收费", "累计异常开闸次数", "累计可疑收费", "运维工单", "当月收缴率", "累计收缴率", "异常开闸率"], rows: [ ["循环花园一期", "湖北省/黄石市/下陆区", "126 / 118", "¥6,420", "¥39,800", "¥62,400", "2", "1", "16", "4", "3", "95.6%", "93.4%", "1.6%"], ["博万物", "广东省/深圳市/龙华区", "98 / 96", "¥4,980", "¥32,600", "¥58,300", "1", "0", "9", "2", "2", "92.3%", "90.8%", "1.1%"], ["美好花园", "广东省/深圳市/福田区", "114 / 105", "¥5,760", "¥36,900", "¥61,700", "3", "1", "21", "6", "4", "94.1%", "91.7%", "2.4%"], ["连城花园", "湖南省/长沙市/芙蓉区", "87 / 82", "¥4,120", "¥28,300", "¥54,800", "2", "1", "13", "3", "2", "90.7%", "88.9%", "1.9%"], ["循环科技三期", "天津市/河东区", "73 / 69", "¥3,560", "¥24,800", "¥49,600", "1", "1", "8", "2", "1", "89.8%", "87.2%", "1.4%"] ] }, planTaskReport: { title: "计划工单执行总览", eyebrow: "计划执行", accent: "#00a870", accentSoft: "rgba(0, 168, 112, 0.14)", cards: [ { label: "本月应完成", value: "1,286", detail: "全部项目口径" }, { label: "本月完成", value: "1,214", detail: "完成率 94.4%" }, { label: "超时仍未完成", value: "28", detail: "需持续跟进" }, { label: "人工验收合格率", value: "96.2%", detail: "工作达标率 91.8%" } ], headers: ["项目名称", "本月应完成", "本月未完成", "本月完成", "完成率", "已报备工单数", "实际完成率", "提前完成", "超时完成", "超时仍未完成", "应验收", "人工合格", "合格", "未验收", "工作达标率"], rows: [ ["循环花园一期", "268", "12", "256", "95.5%", "18", "94.8%", "162", "24", "6", "238", "228", "231", "7", "93.2%"], ["博万物", "214", "15", "199", "93.0%", "16", "91.8%", "116", "29", "8", "184", "175", "178", "6", "89.7%"], ["美好花园", "198", "9", "189", "95.4%", "11", "94.0%", "121", "18", "5", "176", "169", "170", "4", "92.5%"], ["连城花园", "176", "14", "162", "92.0%", "13", "90.6%", "94", "26", "7", "150", "143", "145", "5", "88.9%"], ["循环科技三期", "164", "11", "153", "93.3%", "9", "92.7%", "88", "22", "2", "141", "136", "137", "3", "90.4%"], ["江南世家一期", "146", "11", "135", "92.5%", "7", "91.2%", "73", "19", "0", "129", "124", "125", "2", "91.1%"] ] }, workOrderReport: { title: "非计划工单执行概览", eyebrow: "服务响应", accent: "#ff8a00", accentSoft: "rgba(255, 138, 0, 0.14)", cards: [ { label: "来自住户工单", value: "126", detail: "本月新增 18 单" }, { label: "来自内控工单", value: "284", detail: "闭环率 83.5%" }, { label: "历史未完成", value: "58", detail: "较上周 -7 单" }, { label: "综合执行率", value: "86.9%", detail: "重点项目需跟进" } ], headers: ["项目名称", "来自住户", "已完成", "未完成", "执行率", "历史未完成数", "历史当月完成数", "来自内控", "已完成", "未完成", "执行率"], rows: [ ["博万物", "23", "18", "5", "78.3%", "46", "12", "80", "69", "11", "86.3%"], ["江南世家一期", "16", "15", "1", "93.8%", "4", "3", "21", "18", "3", "85.7%"], ["循环花园一期", "28", "24", "4", "85.7%", "3", "4", "64", "56", "8", "87.5%"], ["美好花园", "19", "17", "2", "89.5%", "2", "1", "43", "37", "6", "86.0%"], ["连城花园", "14", "12", "2", "85.7%", "1", "0", "31", "27", "4", "87.1%"] ] }, dataReport: { title: "工单耗时统计总览", eyebrow: "履约时效", accent: "#20c997", accentSoft: "rgba(32, 201, 151, 0.14)", cards: [ { label: "工单总数量", value: "418", detail: "非计划 + 服务工单" }, { label: "平均受理耗时", value: "00:18:42", detail: "低于标准 12.6%" }, { label: "平均处理耗时", value: "03:16:28", detail: "本月效率稳定" }, { label: "平均完成耗时", value: "08:42:10", detail: "满意度 94.1%" } ], headers: ["项目名称", "工单总数量", "受理工单数量", "规定受理耗时", "实际受理平均耗时", "处理工单数量", "规定处理耗时", "实际处理平均耗时", "已评价工单数量", "规定完成耗时", "实际完成平均耗时"], rows: [ ["循环花园一期", "84", "82", "00:30:00", "00:16:40", "80", "04:00:00", "03:12:15", "76", "12:00:00", "08:31:12"], ["美好花园", "73", "71", "00:30:00", "00:18:05", "70", "04:00:00", "03:08:49", "65", "12:00:00", "08:12:44"], ["循环科技一期", "62", "60", "00:30:00", "00:19:14", "58", "04:00:00", "03:26:37", "54", "12:00:00", "08:55:10"], ["连城花园", "57", "56", "00:30:00", "00:17:28", "55", "04:00:00", "03:11:26", "51", "12:00:00", "08:20:53"], ["博万物", "96", "93", "00:30:00", "00:20:32", "90", "04:00:00", "03:48:21", "83", "12:00:00", "09:04:15"] ] }, consumeReport: { title: "耗能报表总览", eyebrow: "能耗经营", accent: "#14b8a6", accentSoft: "rgba(20, 184, 166, 0.14)", cards: [ { label: "本月总耗能", value: "186.4万kWh", detail: "较上月 -4.3%" }, { label: "单位面积能耗", value: "6.45", detail: "kWh/㎡" }, { label: "高耗能项目", value: "3", detail: "需重点跟进" }, { label: "节能改善率", value: "7.8%", detail: "季度目标达成" } ], headers: ["项目名称", "区域", "本月电耗", "本月水耗", "本月气耗", "单位面积能耗", "同比变化", "节能措施完成率"], rows: [ ["循环花园一期", "湖北省/黄石市/下陆区", "38.6万kWh", "12,860m³", "4,320m³", "6.22", "-5.1%", "92%"], ["博万物", "广东省/深圳市/龙华区", "31.4万kWh", "10,240m³", "3,280m³", "6.58", "-3.6%", "88%"], ["美好花园", "广东省/深圳市/福田区", "28.2万kWh", "8,930m³", "2,960m³", "6.11", "-6.4%", "91%"], ["连城花园", "湖南省/长沙市/芙蓉区", "24.8万kWh", "7,860m³", "2,540m³", "6.37", "-2.1%", "84%"], ["循环科技三期", "天津市/河东区", "19.7万kWh", "6,220m³", "1,980m³", "6.03", "-4.8%", "86%"] ] }, jobGridReport: { title: "作业网格台账报表", eyebrow: "网格履约", accent: "#6366f1", accentSoft: "rgba(99, 102, 241, 0.14)", cards: [ { label: "本月应完成数", value: "2,184", detail: "覆盖 126 个网格" }, { label: "本月完成次数", value: "2,046", detail: "完成率 93.7%" }, { label: "需保持跟进", value: "64", detail: "重点对象 9 个" }, { label: "评分均分", value: "4.72", detail: "低分评价 13 条" } ], headers: ["项目名称", "空间", "网格", "场景归属", "作业对象类型", "作业对象", "所属月份", "SPU数量", "本月应完成数", "本月完成次数", "本月提前完成", "本月超时完成", "需保持跟进", "完成基础云豆R1价值", "评分均分"], rows: [ ["循环花园一期", "公共区域", "A-01", "清洁卫生", "楼栋", "1号楼", "2026-04", "18", "186", "174", "112", "18", "6", "12,680", "4.86"], ["博万物", "设备间", "E-08", "设备管理", "设备", "消防泵房", "2026-04", "12", "148", "136", "79", "22", "5", "10,240", "4.68"], ["美好花园", "车行流线", "P-03", "车场运营", "车位", "地下二层", "2026-04", "15", "164", "156", "96", "17", "4", "11,360", "4.71"], ["连城花园", "外围道路", "S-12", "安防管理", "巡更点", "北门岗亭", "2026-04", "9", "132", "121", "73", "16", "8", "8,920", "4.55"], ["循环科技三期", "绿化区域", "G-06", "绿化管理", "绿植", "中央花园", "2026-04", "11", "118", "109", "68", "13", "5", "7,860", "4.79"] ] }, contractPlanReport: { title: "合同计划执行报表", eyebrow: "合同履约", accent: "#f97316", accentSoft: "rgba(249, 115, 22, 0.14)", cards: [ { label: "本月应完成工单", value: "864", detail: "合同口径" }, { label: "本月完成工单", value: "803", detail: "完成率 92.9%" }, { label: "超时仍未完成", value: "19", detail: "需持续跟进" }, { label: "已完成云豆价值", value: "¥182,400", detail: "较上月 +5.8%" } ], headers: ["项目名称", "合同名称", "计划类型", "本月应完成工单数", "本月完成工单数", "本月未完成工单数", "本月提前工单数", "本月超时完成工单数", "本月超时仍未完成", "需保持跟进", "已完成基础云豆R1价值", "评分均分"], rows: [ ["循环花园一期", "循环花园物业服务合同", "全部", "186", "176", "10", "102", "14", "3", "4", "¥46,800", "4.83"], ["博万物", "博万物物业服务合同", "全部", "154", "141", "13", "78", "19", "4", "6", "¥39,200", "4.61"], ["美好花园", "美好花园综合服务合同", "全部", "148", "139", "9", "82", "17", "2", "5", "¥34,600", "4.76"], ["连城花园", "连城花园基础服务合同", "全部", "132", "121", "11", "69", "16", "5", "3", "¥31,900", "4.52"], ["循环科技三期", "循环科技三期运营合同", "全部", "126", "118", "8", "67", "15", "5", "1", "¥29,900", "4.69"] ] }, contractGuaranteeReport: { title: "合同保障报表", eyebrow: "合同保障", accent: "#ef4444", accentSoft: "rgba(239, 68, 68, 0.14)", cards: [ { label: "有效合同数", value: "42", detail: "覆盖 11 个项目" }, { label: "有效作业区域", value: "186", detail: "PTU 总数 94" }, { label: "基础作业时长", value: "9,842h", detail: "合同保障口径" }, { label: "基础云豆价值", value: "¥168,320", detail: "较上月 +4.2%" } ], headers: ["项目名称", "合同名称", "合同SPU", "有效作业区域", "有效PTU", "有效作业人数", "基础作业时长", "基础云豆R1价值", "清洁计划数", "设备计划数", "电梯计划数", "主动服务计划数"], rows: [ ["博万物", "博万物物业服务合同", "162", "9", "11", "36", "4,960h", "¥71,512", "27", "5", "0", "1"], ["美好花园", "美好花园综合服务合同", "148", "10", "10", "29", "3,820h", "¥52,360", "18", "4", "1", "2"], ["循环花园一期", "循环花园基础合同", "136", "8", "9", "24", "2,940h", "¥24,180", "16", "3", "1", "2"], ["连城花园", "连城花园服务合同", "118", "7", "8", "21", "2,186h", "¥15,940", "12", "2", "1", "1"], ["循环科技三期", "循环科技三期运营合同", "102", "6", "7", "18", "1,968h", "¥13,420", "10", "2", "0", "1"] ] }, detailedContractGuaranteeReport: { title: "合同保障明细报表", eyebrow: "合同明细", accent: "#f59e0b", accentSoft: "rgba(245, 158, 11, 0.14)", cards: [ { label: "合同计划SPU", value: "286", detail: "全部计划类型" }, { label: "计划数量", value: "248", detail: "执行口径汇总" }, { label: "有效作业人数", value: "96", detail: "多项目覆盖" }, { label: "基础云豆价值", value: "¥112,480", detail: "较上月 +3.6%" } ], headers: ["项目名称", "合同名称", "计划类型", "合同计划SPU", "计划数量", "有效作业区域", "有效作业人数", "基础作业时长", "基础云豆R1价值"], rows: [ ["博万物", "博万物物业服务合同", "全部", "42", "35", "9", "36", "4,960h", "¥71,512"], ["美好花园", "美好花园综合服务合同", "全部", "31", "26", "8", "29", "3,820h", "¥52,360"], ["循环花园一期", "循环花园基础合同", "全部", "24", "22", "7", "24", "2,940h", "¥24,180"], ["连城花园", "连城花园服务合同", "全部", "18", "16", "6", "21", "2,186h", "¥15,940"], ["循环科技三期", "循环科技三期运营合同", "全部", "15", "13", "5", "18", "1,968h", "¥13,420"] ] }, officialAccount: { title: "公众号拉新报表", eyebrow: "客户运营", accent: "#06b6d4", accentSoft: "rgba(6, 182, 212, 0.14)", cards: [ { label: "区间新增数", value: "186", detail: "近 30 天" }, { label: "已绑住户数", value: "1,428", detail: "绑定率 76.9%" }, { label: "员工绑定数", value: "214", detail: "员工绑定率 93.1%" }, { label: "未绑住户数", value: "428", detail: "重点项目待推进" } ], headers: ["项目名称", "区间新增数", "总房屋数", "总住户数", "已绑住户数", "未绑住户数", "员工应绑定数", "员工绑定数", "员工绑定率"], rows: [ ["江南世家一期", "42", "286", "418", "352", "66", "24", "23", "95.8%"], ["博万物", "38", "254", "396", "301", "95", "28", "25", "89.3%"], ["循环花园一期", "34", "232", "348", "276", "72", "22", "21", "95.5%"], ["美好花园", "29", "218", "315", "248", "67", "19", "18", "94.7%"], ["连城花园", "22", "184", "268", "191", "77", "17", "15", "88.2%"] ] }, collectionTracking: { title: "催收跟踪报表", eyebrow: "收费跟踪", accent: "#8b5cf6", accentSoft: "rgba(139, 92, 246, 0.14)", cards: [ { label: "催收户数", value: "412", detail: "重点欠费房屋 86 户" }, { label: "及时拜访数量", value: "186", detail: "拜访及时率 71.5%" }, { label: "电话 / 微信", value: "268 / 94", detail: "多通道覆盖" }, { label: "律师函 / 起诉", value: "18 / 6", detail: "高风险项目跟进" } ], headers: ["项目名称", "催收户数", "欠费房屋数", "普通实收", "转实收", "电话", "微信", "上门", "短信", "律师函", "起诉", "及时拜访数量", "拜访数量", "拜访及时率"], rows: [ ["沈鑫小区", "38", "42", "12", "6", "24", "10", "5", "18", "2", "0", "21", "28", "75.0%"], ["龚浪小区", "64", "87", "16", "8", "36", "14", "9", "22", "3", "1", "31", "44", "70.5%"], ["陈丽娟小区", "29", "24", "8", "3", "18", "6", "2", "11", "1", "0", "12", "17", "70.6%"], ["谷粒多小区", "18", "16", "4", "1", "12", "3", "1", "7", "0", "0", "8", "12", "66.7%"], ["博万物", "96", "118", "26", "12", "58", "21", "15", "33", "5", "2", "44", "63", "69.8%"] ] }, collectionRate: { title: "企业收费项报表", eyebrow: "收费分析", accent: "#3b82f6", accentSoft: "rgba(59, 130, 246, 0.14)", cards: [ { label: "应收合计", value: "¥1,826,400", detail: "本年 + 往年" }, { label: "实收合计", value: "¥1,543,800", detail: "综合收缴率 84.5%" }, { label: "欠费合计", value: "¥282,600", detail: "环比 -5.4%" }, { label: "户数收缴率", value: "81.3%", detail: "实时校验已开" } ], headers: ["项目名称", "收费项目", "本月应收", "本年应收", "往年应收", "应收合计", "本月实收", "本年实收", "往年实收", "欠费合计", "实收合计", "综合收缴率", "户数收缴率"], rows: [ ["博万物", "住宅水电", "¥82,600", "¥426,000", "¥18,400", "¥444,400", "¥71,200", "¥382,600", "¥9,800", "¥52,000", "¥392,400", "88.3%", "83.2%"], ["循环花园一期", "物业管理费", "¥96,800", "¥518,000", "¥26,200", "¥544,200", "¥84,900", "¥462,800", "¥13,600", "¥67,800", "¥476,400", "87.5%", "84.7%"], ["美好花园", "停车服务费", "¥68,500", "¥392,000", "¥14,800", "¥406,800", "¥57,200", "¥338,400", "¥9,200", "¥59,200", "¥347,600", "85.4%", "80.9%"], ["连城花园", "综合服务费", "¥54,200", "¥286,000", "¥9,600", "¥295,600", "¥46,300", "¥242,700", "¥6,800", "¥46,100", "¥249,500", "84.4%", "79.8%"], ["江南世家一期", "园区服务费", "¥43,100", "¥204,600", "¥6,800", "¥211,400", "¥36,800", "¥174,900", "¥5,600", "¥30,900", "¥180,500", "85.4%", "78.6%"] ] }, visitWorkReport: { title: "拜访工作报表", eyebrow: "客户拜访", accent: "#22c55e", accentSoft: "rgba(34, 197, 94, 0.14)", cards: [ { label: "应拜访总数", value: "214", detail: "电话 + 上门" }, { label: "按时拜访", value: "162", detail: "及时率 75.7%" }, { label: "已回款金额", value: "¥286,400", detail: "回款户数 118" }, { label: "超时拜访", value: "24", detail: "未拜访 28 户" } ], headers: ["项目名称", "拜访方式", "来源", "应拜访", "应付金额(元)", "未拜访", "按时拜访", "超时拜访", "未回款(户)", "已回款(户)", "已回款金额(元)"], rows: [ ["博万物", "上门", "拜访智能体", "18", "¥32,600", "3", "12", "3", "9", "9", "¥18,400"], ["博万物", "电话", "分类布置智能体", "36", "¥58,900", "8", "22", "6", "18", "18", "¥41,600"], ["循环花园一期", "电话", "拜访智能体", "42", "¥64,200", "6", "31", "5", "17", "25", "¥58,900"], ["美好花园", "上门", "拜访智能体", "27", "¥41,800", "4", "19", "4", "11", "16", "¥36,700"], ["连城花园", "电话", "分类布置智能体", "24", "¥37,300", "7", "16", "1", "14", "10", "¥24,100"] ] } }; const STATIC_PAGE_PRESETS = { qualification: { eyebrow: "资质匹配", title: "人员资质匹配总览", summary: "补齐人员证书、岗位要求与到期预警,替代空态页。", accent: "#2563eb", accentSoft: "rgba(37, 99, 235, 0.14)", cards: [ { label: "在岗人员", value: "186", detail: "参与资质校验" }, { label: "即将到期证书", value: "12", detail: "30 天内到期" }, { label: "岗位匹配率", value: "94.8%", detail: "高于月目标" }, { label: "缺证人数", value: "7", detail: "需尽快补齐" } ], headers: ["项目名称", "姓名", "岗位", "证书名称", "证书到期日", "匹配状态", "整改建议"], rows: [ ["循环花园一期", "郭晓", "环境巡查管家", "消防设施操作员", "2026-05-12", "匹配", "保持跟进"], ["博万物", "何琪", "设备管理员", "特种设备安全管理员", "2026-04-18", "预警", "安排续证"], ["美好花园", "陈谷先", "财务中心负责人", "会计从业资格", "2026-09-30", "匹配", "正常"], ["连城花园", "蒋琦", "java 开发工程师", "信息系统项目管理师", "2026-07-08", "匹配", "正常"], ["江南世家一期", "曾丽娜", "客服巡查管家", "物业管理员", "2026-04-22", "待补齐", "补齐岗位证书"] ] }, employeeQuitReport: { eyebrow: "人员流动", title: "员工离任报告", summary: "汇总离任人员、离任类型与交接完成情况,替代空态页。", accent: "#dc2626", accentSoft: "rgba(220, 38, 38, 0.14)", cards: [ { label: "本月离任人数", value: "9", detail: "较上月 -2" }, { label: "高风险离任", value: "2", detail: "核心岗位需接替" }, { label: "交接完成率", value: "88.9%", detail: "资料回收正常" }, { label: "平均在岗月数", value: "16.4", detail: "整体稳定" } ], headers: ["项目名称", "姓名", "岗位", "离任类型", "离任日期", "交接状态", "备注"], rows: [ ["循环花园一期", "张磊", "客服巡查管家", "主动离职", "2026-04-02", "已完成", "已完成物资交接"], ["博万物", "林婉", "设备管理员", "岗位调整", "2026-03-29", "进行中", "待设备台账确认"], ["美好花园", "刘鑫", "市场专员", "合同到期", "2026-03-27", "已完成", "无异常"], ["连城花园", "周宇", "保洁班长", "主动离职", "2026-03-25", "已完成", "补充访谈记录"], ["江南世家一期", "何丽", "财务专员", "试用期离岗", "2026-03-20", "待处理", "安排补岗"] ] }, operationLog: { eyebrow: "系统管理", title: "操作日志总览", summary: "补齐关键操作日志、用户行为与风险动作提示,替代空态页。", accent: "#7c3aed", accentSoft: "rgba(124, 58, 237, 0.14)", cards: [ { label: "今日操作次数", value: "428", detail: "登录用户 36 人" }, { label: "高风险操作", value: "5", detail: "重点复核" }, { label: "模块覆盖数", value: "18", detail: "近 24 小时" }, { label: "最近同步", value: "15:32", detail: "日志服务正常" } ], headers: ["时间", "用户", "模块", "动作", "IP", "结果", "说明"], rows: [ ["2026-04-04 15:28:32", "循环科技企业管理后台", "角色权限管理", "编辑角色", "113.88.21.6", "成功", "更新项目角色权限"], ["2026-04-04 14:57:10", "郭晓", "人事档案", "导入档案", "113.88.21.9", "成功", "导入 12 条记录"], ["2026-04-04 14:33:48", "陈谷先", "财务数据", "修改指标", "113.88.21.12", "成功", "更新利润口径"], ["2026-04-04 13:49:05", "林婉", "分公司管理", "新增分公司", "113.88.21.7", "待审核", "创建广州运营主体"], ["2026-04-04 11:16:26", "何琪", "设备看板", "导出报表", "113.88.21.15", "成功", "导出设备月报"] ] }, questionBank: { eyebrow: "满意度题库", title: "调查题库总览", summary: "重建题库统计、题目类型与启用状态,替代空态页。", accent: "#0ea5e9", accentSoft: "rgba(14, 165, 233, 0.14)", cards: [ { label: "题库总数", value: "128", detail: "启用题目 116" }, { label: "评分题", value: "36", detail: "权重题 8 个" }, { label: "低分标签", value: "14", detail: "用于整改跟踪" }, { label: "最近更新", value: "04-03", detail: "客户运营同步" } ], headers: ["题目名称", "题型", "适用场景", "权重", "状态", "最近更新", "维护人"], rows: [ ["您对客服响应速度是否满意?", "评分题", "工单服务", "15%", "启用", "2026-04-03", "李佑聪"], ["您对停车秩序是否满意?", "评分题", "车场运营", "10%", "启用", "2026-04-02", "循环科技企业管理后台"], ["保洁服务是否达到预期?", "单选题", "环境管理", "8%", "启用", "2026-03-28", "郭晓"], ["是否愿意继续推荐本项目?", "NPS题", "综合满意度", "20%", "启用", "2026-03-22", "陈谷先"], ["请填写需要改进的问题", "文本题", "整改跟踪", "-", "草稿", "2026-03-18", "何琪"] ] }, report: { eyebrow: "满意度分析", title: "调查报告总览", summary: "按项目汇总问卷样本、满意度得分与低分预警,替代空态页。", accent: "#14b8a6", accentSoft: "rgba(20, 184, 166, 0.14)", cards: [ { label: "有效样本", value: "2,418", detail: "近 30 天" }, { label: "综合满意度", value: "4.63", detail: "较上月 +0.08" }, { label: "低分预警", value: "18", detail: "需跟进整改" }, { label: "整改完成率", value: "82.4%", detail: "闭环改善中" } ], headers: ["项目名称", "问卷名称", "样本数", "满意度", "低分数量", "整改任务", "状态"], rows: [ ["循环花园一期", "4 月综合满意度", "486", "4.72", "2", "4", "已发布"], ["博万物", "4 月停车服务满意度", "362", "4.58", "5", "7", "已发布"], ["美好花园", "4 月客服满意度", "318", "4.66", "3", "5", "已发布"], ["连城花园", "4 月环境满意度", "276", "4.49", "6", "8", "整改中"], ["江南世家一期", "4 月综合满意度", "241", "4.53", "2", "3", "已发布"] ] }, tracking: { eyebrow: "整改闭环", title: "整改跟踪总览", summary: "聚合低分问题、责任人和整改进度,替代空态页。", accent: "#f97316", accentSoft: "rgba(249, 115, 22, 0.14)", cards: [ { label: "待整改问题", value: "26", detail: "逾期 4 项" }, { label: "本周关闭", value: "18", detail: "闭环效率提升" }, { label: "责任人数量", value: "11", detail: "跨项目协同" }, { label: "按期完成率", value: "84.6%", detail: "需持续跟进" } ], headers: ["项目名称", "问题类型", "责任人", "整改截止日", "整改进度", "状态", "备注"], rows: [ ["循环花园一期", "客服响应慢", "郭晓", "2026-04-10", "80%", "处理中", "需补充回访"], ["博万物", "停车秩序差", "何琪", "2026-04-08", "60%", "预警", "晚高峰加派巡查"], ["美好花园", "保洁质量波动", "曾丽娜", "2026-04-09", "100%", "已完成", "已复检通过"], ["连城花园", "绿化修剪不及时", "周宇", "2026-04-12", "40%", "处理中", "待供应商进场"], ["江南世家一期", "工单回访不充分", "陈谷先", "2026-04-11", "90%", "待验证", "等待客户确认"] ] }, assessment: { eyebrow: "人才测评", title: "人才测评总览", summary: "聚合测评对象、岗位画像与测评分布,替代空态页。", accent: "#8b5cf6", accentSoft: "rgba(139, 92, 246, 0.14)", cards: [ { label: "测评人数", value: "142", detail: "近 30 天" }, { label: "综合胜任度", value: "84.2", detail: "百分制" }, { label: "高潜人才", value: "18", detail: "建议重点培养" }, { label: "待复评人数", value: "9", detail: "低于岗位基线" } ], headers: ["项目名称", "姓名", "岗位", "能力模型", "测评得分", "胜任等级", "建议动作"], rows: [ ["循环花园一期", "郭晓", "环境巡查管家", "服务履约模型", "88", "优秀", "纳入主管培养"], ["博万物", "何琪", "设备管理员", "设备运营模型", "82", "良好", "补充故障诊断训练"], ["美好花园", "陈谷先", "财务中心负责人", "经营管理模型", "91", "优秀", "承担跨项目辅导"], ["连城花园", "蒋琦", "java 开发工程师", "技术支持模型", "86", "良好", "推进专项项目实践"], ["江南世家一期", "曾丽娜", "客服巡查管家", "客户服务模型", "74", "关注", "安排二次复评"] ] } }; function hydrateCompanyInfoFrame(doc) { try { const companyInfo = JSON.parse(storageSeed.companyInfo || "{}"); const userInfo = JSON.parse(storageSeed.userInfo || "{}"); const labelMap = { "企业全称": companyInfo.fullName || "", "企业简称": companyInfo.abbreviation || "", "企业ID": companyInfo.id || "", "法人代表联系方式": companyInfo.mobile || "", "企业付款人": companyInfo.payer || "", "开户行": companyInfo.publicBank || "", "企业地址": companyInfo.address || "", "企业微信密钥": companyInfo.weixinSecret || "", "企业统一社会信用代码": companyInfo.creditCode || "", "企业法人代表": companyInfo.legalPerson || "", "企业创建人账号": userInfo.accountName || storageSeed.fromPhone || "", "企业邮编": companyInfo.postalCode || "", "付款人联系电话": companyInfo.payerMobile || "", "银行账号": companyInfo.publicBankNo || "", "企业微信ID(CorpID)": companyInfo.weixinCorpId || "" }; doc.querySelectorAll(".el-form-item").forEach((item) => { const labelEl = item.querySelector(".el-form-item__label"); const inputEl = item.querySelector("input.el-input__inner"); if (!labelEl || !inputEl) { return; } const label = (labelEl.textContent || "").trim(); if (!(label in labelMap)) { return; } const value = String(labelMap[label] ?? ""); inputEl.value = value; inputEl.setAttribute("value", value); inputEl.placeholder = value; inputEl.style.color = "#2c3e50"; inputEl.style.fontWeight = "500"; inputEl.style.backgroundColor = "#fff"; }); const infoImages = [...doc.querySelectorAll(".companyMain .companyInfo img.img")]; if (infoImages[0] && companyInfo.logo) { infoImages[0].src = companyInfo.logo; } if (infoImages[1] && companyInfo.miniCode) { infoImages[1].src = companyInfo.miniCode; } } catch (_error) { // ignore } } function buildLinePath(values, width, height, padding) { const max = Math.max(...values); const min = Math.min(...values); const span = Math.max(max - min, 1); return values .map((value, index) => { const x = padding + (index * (width - padding * 2)) / Math.max(values.length - 1, 1); const y = height - padding - ((value - min) / span) * (height - padding * 2); return `${index === 0 ? "M" : "L"}${x.toFixed(1)} ${y.toFixed(1)}`; }) .join(" "); } function buildAreaPoints(values, width, height, padding) { const max = Math.max(...values); const min = Math.min(...values); const span = Math.max(max - min, 1); const points = values.map((value, index) => { const x = padding + (index * (width - padding * 2)) / Math.max(values.length - 1, 1); const y = height - padding - ((value - min) / span) * (height - padding * 2); return `${x.toFixed(1)},${y.toFixed(1)}`; }); points.push(`${width - padding},${height - padding}`, `${padding},${height - padding}`); return points.join(" "); } function buildTrendSvg(seriesList, labels) { const width = 560; const height = 220; const padding = 24; const allValues = seriesList.flatMap((item) => item.values); const max = Math.max(...allValues); const min = Math.min(...allValues); const span = Math.max(max - min, 1); const guides = [0, 0.25, 0.5, 0.75, 1].map((ratio) => { const y = padding + ratio * (height - padding * 2); const value = Math.round(max - ratio * span); return ` ${value} `; }); const xLabels = labels .map((label, index) => { const x = padding + (index * (width - padding * 2)) / Math.max(labels.length - 1, 1); return `${label}`; }) .join(""); const paths = seriesList .map((item, index) => { const areaOpacity = index === 0 ? 0.14 : 0.08; return ` ${item.values .map((value, valueIndex) => { const x = padding + (valueIndex * (width - padding * 2)) / Math.max(item.values.length - 1, 1); const y = height - padding - ((value - min) / span) * (height - padding * 2); return ``; }) .join("")} `; }) .join(""); return ` ${guides.join("")} ${paths} ${xLabels} `; } function renderMicrobrainDashboard(doc, type) { const preset = MICROBRAIN_PRESETS[type]; if (!preset) { return; } const host = doc.querySelector(".app-main > div") || doc.querySelector(".app-main > section") || doc.querySelector(".app-main") || doc.body; if (!host) { return; } if (!doc.getElementById("__codex_microbrain_style__")) { const style = doc.createElement("style"); style.id = "__codex_microbrain_style__"; style.textContent = ` .waitMain { display: none !important; } #__codex_microbrain_dashboard__ { margin-top: 18px; padding: 20px 22px 24px; border-radius: 20px; background: radial-gradient(circle at top right, rgba(45, 118, 255, 0.12), transparent 28%), linear-gradient(180deg, #ffffff 0%, #f7faff 100%); border: 1px solid rgba(17, 37, 63, 0.06); box-shadow: 0 18px 42px rgba(17, 37, 63, 0.08); } .codex-microbrain-head { display: flex; align-items: flex-end; justify-content: space-between; gap: 20px; margin-bottom: 20px; } .codex-microbrain-eyebrow { display: inline-flex; align-items: center; padding: 4px 10px; border-radius: 999px; margin-bottom: 10px; font-size: 12px; color: #5b6f92; background: rgba(17, 37, 63, 0.06); } .codex-microbrain-head h3 { margin: 0 0 6px; font-size: 28px; color: #12233d; } .codex-microbrain-head p { margin: 0; max-width: 660px; color: #6d7d97; font-size: 14px; } .codex-microbrain-badge { padding: 10px 14px; border-radius: 14px; color: #35517d; font-size: 12px; background: rgba(255,255,255,0.8); border: 1px solid rgba(17,37,63,0.08); box-shadow: inset 0 1px 0 rgba(255,255,255,0.8); } .codex-microbrain-metrics { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 14px; margin-bottom: 18px; } .codex-microbrain-metric { padding: 16px 18px; border-radius: 18px; background: rgba(255,255,255,0.82); border: 1px solid rgba(17,37,63,0.06); box-shadow: 0 12px 28px rgba(17,37,63,0.06); } .codex-microbrain-metric span { display: block; color: #7d8ca5; font-size: 13px; } .codex-microbrain-metric strong { display: block; margin: 8px 0 6px; color: #12233d; font-size: 28px; line-height: 1.1; } .codex-microbrain-metric small { color: #4e6b98; font-size: 12px; } .codex-microbrain-layout { display: grid; grid-template-columns: minmax(0, 1.6fr) minmax(320px, 0.95fr); gap: 16px; } .codex-microbrain-panel { padding: 18px 18px 16px; border-radius: 18px; background: rgba(255,255,255,0.92); border: 1px solid rgba(17,37,63,0.06); } .codex-microbrain-panel h4 { margin: 0 0 14px; color: #152742; font-size: 16px; } .codex-microbrain-legend { display: flex; gap: 14px; flex-wrap: wrap; margin-bottom: 12px; } .codex-microbrain-legend span { display: inline-flex; align-items: center; gap: 6px; color: #71829d; font-size: 12px; } .codex-microbrain-dot { width: 9px; height: 9px; border-radius: 50%; } .codex-microbrain-chart { width: 100%; height: 238px; } .codex-microbrain-segments { display: grid; gap: 12px; } .codex-microbrain-segment { display: grid; grid-template-columns: 88px 1fr 48px; align-items: center; gap: 10px; color: #4d607f; font-size: 13px; } .codex-microbrain-track { overflow: hidden; height: 10px; border-radius: 999px; background: #eef3fb; } .codex-microbrain-fill { height: 100%; border-radius: inherit; } .codex-microbrain-table table { width: 100%; border-collapse: collapse; } .codex-microbrain-table th, .codex-microbrain-table td { padding: 12px 8px; border-bottom: 1px solid rgba(17,37,63,0.06); text-align: left; color: #3f5477; font-size: 13px; } .codex-microbrain-table th { color: #8b9ab3; font-size: 12px; font-weight: 500; } .codex-microbrain-alerts { display: grid; gap: 10px; } .codex-microbrain-alert { padding: 14px 14px 13px; border-radius: 14px; background: #f8fbff; border: 1px solid rgba(17,37,63,0.06); } .codex-microbrain-alert b { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-bottom: 6px; color: #152742; font-size: 14px; } .codex-microbrain-alert p { margin: 0; color: #6d7d97; font-size: 12px; line-height: 1.6; } .codex-microbrain-level { display: inline-flex; align-items: center; justify-content: center; padding: 4px 8px; border-radius: 999px; font-size: 11px; font-weight: 600; } .codex-microbrain-level-正常 { color: #067647; background: rgba(6, 118, 71, 0.12); } .codex-microbrain-level-关注 { color: #975a16; background: rgba(255, 183, 77, 0.18); } .codex-microbrain-level-预警 { color: #c92a2a; background: rgba(255, 107, 107, 0.16); } @media (max-width: 1080px) { .codex-microbrain-metrics { grid-template-columns: repeat(2, minmax(0, 1fr)); } .codex-microbrain-layout { grid-template-columns: 1fr; } } `; doc.head.appendChild(style); } const containerId = "__codex_microbrain_dashboard__"; let container = doc.getElementById(containerId); if (!container) { container = doc.createElement("div"); container.id = containerId; host.appendChild(container); } container.dataset.type = type; const legend = preset.trendSeries .map( (item) => ` ${item.label} ` ) .join(""); const segments = preset.segments .map( (item) => `
${item.label}
${item.value}
` ) .join(""); const metrics = preset.metrics .map( (item) => `
${item.label} ${item.value} ${item.delta}
` ) .join(""); const rows = preset.rankingRows .map( (row, index) => ` ${index + 1} ${row[0]} ${row[1]} ${row[2]} ` ) .join(""); const alerts = preset.alerts .map( (item) => `
${item.title} ${item.level}

${item.detail}

` ) .join(""); container.innerHTML = `
${preset.eyebrow}

${preset.headline}

${preset.summary}

镜像重建 · ${preset.headline} · 近 30 天静态样本
${metrics}

趋势概览

${legend}
${buildTrendSvg(preset.trendSeries, preset.trendLabels)}

结构占比

${segments}

${preset.rankingTitle}

${rows}
#项目指标值完成度

${preset.alertsTitle}

${alerts}
`; } function ensureCloudReportStyle(doc) { if (doc.getElementById("__codex_cloud_report_style__")) { return; } const style = doc.createElement("style"); style.id = "__codex_cloud_report_style__"; style.textContent = ` .waitMain { display: none !important; } .codex-cloud-report { margin: 0 2% 18px; padding: 18px 20px 20px; border-radius: 18px; background: linear-gradient(180deg, #ffffff 0%, #f7faff 100%); border: 1px solid rgba(17, 37, 63, 0.06); box-shadow: 0 18px 42px rgba(17, 37, 63, 0.08); } .codex-cloud-report-head { display: flex; align-items: flex-end; justify-content: space-between; gap: 20px; margin-bottom: 16px; } .codex-cloud-report-eyebrow { display: inline-flex; align-items: center; padding: 4px 10px; margin-bottom: 8px; border-radius: 999px; background: rgba(17,37,63,0.06); color: #6d7d97; font-size: 12px; } .codex-cloud-report-head h4 { margin: 0 0 4px; color: #152742; font-size: 24px; } .codex-cloud-report-head p { margin: 0; color: #6d7d97; font-size: 13px; } .codex-cloud-report-badge { padding: 9px 12px; border-radius: 14px; color: #496385; font-size: 12px; background: rgba(255,255,255,0.9); border: 1px solid rgba(17,37,63,0.08); } .codex-cloud-report-cards { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 12px; margin-bottom: 16px; } .codex-cloud-report-card { padding: 14px 16px; border-radius: 16px; background: rgba(255,255,255,0.92); border: 1px solid rgba(17,37,63,0.05); } .codex-cloud-report-card span { display: block; color: #7d8ca5; font-size: 12px; } .codex-cloud-report-card strong { display: block; margin: 8px 0 6px; color: #152742; font-size: 28px; line-height: 1.05; } .codex-cloud-report-card small { color: #4f6a94; font-size: 12px; } .codex-cloud-report-table { overflow: auto; border-radius: 14px; border: 1px solid rgba(17,37,63,0.06); background: #fff; } .codex-cloud-report-table table { width: 100%; min-width: 1180px; border-collapse: collapse; } .codex-cloud-report-table th, .codex-cloud-report-table td { padding: 12px 10px; border-bottom: 1px solid rgba(17,37,63,0.06); text-align: center; color: #3f5477; font-size: 13px; white-space: nowrap; } .codex-cloud-report-table th { position: sticky; top: 0; z-index: 1; background: #f9fbff; color: #7d8ca5; font-size: 12px; font-weight: 600; } .codex-cloud-report-table td:first-child, .codex-cloud-report-table th:first-child { position: sticky; left: 0; z-index: 1; background: #fff; } .codex-cloud-report-table th:first-child { background: #f9fbff; } .codex-cloud-report-table td.project { text-align: left; color: #152742; font-weight: 600; } .codex-cloud-report-rate { color: #067647; font-weight: 600; } @media (max-width: 1080px) { .codex-cloud-report-cards { grid-template-columns: repeat(2, minmax(0, 1fr)); } } `; doc.head.appendChild(style); } function createCloudReportSection(doc, type) { const preset = CLOUD_REPORT_PRESETS[type]; if (!preset) { return null; } ensureCloudReportStyle(doc); const section = doc.createElement("section"); section.className = "codex-cloud-report"; section.id = `__codex_cloud_report_${type}__`; const cards = preset.cards .map( (item) => `
${item.label} ${item.value} ${item.detail}
` ) .join(""); const headers = preset.headers.map((header) => `${header}`).join(""); const rows = preset.rows .map((row) => { const cells = row .map((value, index) => { const className = index === 0 ? "project" : /%$/.test(value) ? "codex-cloud-report-rate" : ""; return `${value}`; }) .join(""); return `${cells}`; }) .join(""); section.innerHTML = `
${preset.eyebrow}

${preset.title || (type === "propertyFeeReport" ? "物业费收缴明细表" : type === "parkingLotReport" ? "车场列表" : type === "planTaskReport" ? "计划工单执行总览" : "经营报表")}

基于镜像静态样本重建报表数据,用于替代原始页面中的空值或缺失列表。

镜像重建 · 静态样本数据
${cards}
${headers}${rows}
`; return section; } function renderCloudDataReport(doc, type) { const preset = CLOUD_REPORT_PRESETS[type]; if (!preset) { return; } const host = doc.querySelector(".contentStys") || doc.querySelector(".app-container") || doc.querySelector(".app-main"); if (!host) { return; } host.querySelectorAll(".el-table, .el-pagination").forEach((node) => { node.style.display = "none"; }); const planTitle = host.querySelector(".planLst"); if (planTitle) { planTitle.style.marginBottom = "12px"; } const existing = doc.getElementById(`__codex_cloud_report_${type}__`); if (existing) { existing.remove(); } const section = createCloudReportSection(doc, type); if (!section) { return; } if (planTitle && planTitle.parentNode) { planTitle.parentNode.insertBefore(section, planTitle.nextSibling); return; } host.appendChild(section); } function ensureStaticPageStyle(doc) { if (doc.getElementById("__codex_static_page_style__")) { return; } const style = doc.createElement("style"); style.id = "__codex_static_page_style__"; style.textContent = ` .codex-static-page { margin: 20px; padding: 18px 20px 20px; border-radius: 18px; background: linear-gradient(180deg, #ffffff 0%, #f8fbff 100%); border: 1px solid rgba(17,37,63,0.06); box-shadow: 0 18px 42px rgba(17,37,63,0.08); } .codex-static-page-head { display: flex; align-items: flex-end; justify-content: space-between; gap: 20px; margin-bottom: 16px; } .codex-static-page-eyebrow { display: inline-flex; align-items: center; padding: 4px 10px; margin-bottom: 8px; border-radius: 999px; background: rgba(17,37,63,0.06); color: #6d7d97; font-size: 12px; } .codex-static-page-head h4 { margin: 0 0 4px; color: #152742; font-size: 24px; } .codex-static-page-head p { margin: 0; color: #6d7d97; font-size: 13px; } .codex-static-page-badge { padding: 9px 12px; border-radius: 14px; color: #496385; font-size: 12px; background: rgba(255,255,255,0.9); border: 1px solid rgba(17,37,63,0.08); } .codex-static-page-cards { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 12px; margin-bottom: 16px; } .codex-static-page-card { padding: 14px 16px; border-radius: 16px; background: rgba(255,255,255,0.92); border: 1px solid rgba(17,37,63,0.05); } .codex-static-page-card span { display: block; color: #7d8ca5; font-size: 12px; } .codex-static-page-card strong { display: block; margin: 8px 0 6px; color: #152742; font-size: 28px; line-height: 1.05; } .codex-static-page-card small { color: #4f6a94; font-size: 12px; } .codex-static-page-table { overflow: auto; border-radius: 14px; border: 1px solid rgba(17,37,63,0.06); background: #fff; } .codex-static-page-table table { width: 100%; min-width: 920px; border-collapse: collapse; } .codex-static-page-table th, .codex-static-page-table td { padding: 12px 10px; border-bottom: 1px solid rgba(17,37,63,0.06); text-align: center; color: #3f5477; font-size: 13px; white-space: nowrap; } .codex-static-page-table th { background: #f9fbff; color: #7d8ca5; font-size: 12px; font-weight: 600; } .codex-static-page-table td:first-child, .codex-static-page-table th:first-child { text-align: left; } @media (max-width: 1080px) { .codex-static-page-cards { grid-template-columns: repeat(2, minmax(0, 1fr)); } } `; doc.head.appendChild(style); } function renderStaticManagementPage(doc, type) { const preset = STATIC_PAGE_PRESETS[type]; if (!preset) { return; } ensureStaticPageStyle(doc); doc.querySelectorAll(".waitMain").forEach((node) => { node.style.display = "none"; }); const host = doc.querySelector(".app-main > div") || doc.querySelector(".app-main > section") || doc.querySelector(".app-main") || doc.body; if (!host) { return; } const existing = doc.getElementById(`__codex_static_page_${type}__`); if (existing) { existing.remove(); } const section = doc.createElement("section"); section.id = `__codex_static_page_${type}__`; section.className = "codex-static-page"; const cards = preset.cards .map( (item) => `
${item.label} ${item.value} ${item.detail}
` ) .join(""); const headers = preset.headers.map((header) => `${header}`).join(""); const rows = preset.rows .map((row) => `${row.map((value) => `${value}`).join("")}`) .join(""); section.innerHTML = `
${preset.eyebrow}

${preset.title}

${preset.summary}

镜像重建 · 静态样本数据
${cards}
${headers}${rows}
`; host.appendChild(section); } function ensureEtmsEditableStyle(doc) { if (doc.getElementById("__codex_etms_editable_style__")) { return; } const style = doc.createElement("style"); style.id = "__codex_etms_editable_style__"; style.textContent = ` .codex-editable-shell { position: relative; } .codex-editable-toolbar { position: sticky; top: 12px; z-index: 20; display: flex; justify-content: flex-end; gap: 8px; margin: 0 0 12px; } .codex-editable-toolbar button { border: 1px solid rgba(17,37,63,0.08); border-radius: 999px; padding: 6px 12px; background: rgba(255,255,255,0.92); color: #35507a; font-size: 12px; cursor: pointer; } .codex-editable-toolbar button.codex-primary { background: #2d76ff; border-color: transparent; color: #fff; } .codex-editable-toolbar button.codex-danger { color: #d14343; } .codex-editable-toolbar button:disabled { opacity: 0.48; cursor: not-allowed; } .codex-editable-body[contenteditable="true"] { outline: 2px dashed rgba(45,118,255,0.35); outline-offset: 8px; } .codex-editable-body[contenteditable="true"] a, .codex-editable-body[contenteditable="true"] button { pointer-events: none; } .codex-editable-hint { margin-right: auto; align-self: center; color: #6d7d97; font-size: 12px; } `; doc.head.appendChild(style); } function createEtmsEditableKey(doc, section, index) { const pathname = doc.defaultView?.location?.pathname || "unknown"; const sectionId = section.id || section.dataset.type || section.className || `section-${index}`; return `__codex_etms_edit__${pathname}::${sectionId}`; } function wrapEtmsEditableBody(section) { let body = section.querySelector(":scope > .codex-editable-body"); if (body) { return body; } body = section.ownerDocument.createElement("div"); body.className = "codex-editable-body"; [...section.childNodes].forEach((node) => { body.appendChild(node); }); section.appendChild(body); return body; } function setEtmsEditableState(doc, section, editing) { const body = section.querySelector(":scope > .codex-editable-body"); const toolbar = section.querySelector(":scope > .codex-editable-toolbar"); if (!body || !toolbar) { return; } body.contentEditable = editing ? "true" : "false"; body.spellcheck = false; section.dataset.codexEditing = editing ? "1" : "0"; doc.body.dataset.codexMirrorEditing = editing ? "1" : "0"; toolbar.querySelector("[data-action='edit']").disabled = editing; toolbar.querySelector("[data-action='save']").disabled = !editing; } function bindEtmsEditableSection(doc, section, index) { ensureEtmsEditableStyle(doc); section.classList.add("codex-editable-shell"); const body = wrapEtmsEditableBody(section); const storageKey = createEtmsEditableKey(doc, section, index); const win = doc.defaultView; const saved = win?.localStorage.getItem(storageKey); if (!section.dataset.codexDefaultHtml) { section.dataset.codexDefaultHtml = body.innerHTML; } if (saved && body.innerHTML !== saved && section.dataset.codexEditing !== "1") { body.innerHTML = saved; } let toolbar = section.querySelector(":scope > .codex-editable-toolbar"); if (!toolbar) { toolbar = doc.createElement("div"); toolbar.className = "codex-editable-toolbar"; toolbar.innerHTML = ` 本地编辑 `; section.insertBefore(toolbar, body); toolbar.addEventListener("click", (event) => { const button = event.target.closest("button[data-action]"); if (!button) { return; } const action = button.dataset.action; if (action === "edit") { setEtmsEditableState(doc, section, true); body.focus(); return; } if (action === "save") { win?.localStorage.setItem(storageKey, body.innerHTML); setEtmsEditableState(doc, section, false); return; } if (action === "reset") { win?.localStorage.removeItem(storageKey); body.innerHTML = section.dataset.codexDefaultHtml || body.innerHTML; setEtmsEditableState(doc, section, false); } }); } setEtmsEditableState(doc, section, false); } function installEtmsEditableSections(doc) { const sections = [ ...doc.querySelectorAll("#__codex_microbrain_dashboard__, [id^='__codex_cloud_report_'], [id^='__codex_static_page_'], #__codex_finance_summary__") ]; const seen = new Set(); sections.forEach((section, index) => { if (!section || seen.has(section)) { return; } seen.add(section); bindEtmsEditableSection(doc, section, index); }); } function ensureEtmsListEditStyle(doc) { if (doc.getElementById("__codex_etms_list_edit_style__")) { return; } const style = doc.createElement("style"); style.id = "__codex_etms_list_edit_style__"; style.textContent = ` .codex-listedit-mask { position: fixed; inset: 0; z-index: 99999; background: rgba(8, 15, 28, 0.42); display: flex; align-items: center; justify-content: center; padding: 24px; } .codex-listedit-modal { width: min(760px, 100%); max-height: min(760px, calc(100vh - 48px)); overflow: auto; border-radius: 18px; background: #fff; box-shadow: 0 24px 54px rgba(17, 37, 63, 0.18); padding: 20px 22px; } .codex-listedit-modal h4 { margin: 0 0 16px; color: #152742; font-size: 20px; } .codex-listedit-summary { margin: 0 0 16px; color: #6d7d97; font-size: 12px; line-height: 1.7; } .codex-listedit-form { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; } .codex-listedit-form label { display: flex; flex-direction: column; gap: 6px; color: #6d7d97; font-size: 12px; } .codex-listedit-form label.full { grid-column: 1 / -1; } .codex-listedit-form input, .codex-listedit-form textarea { border: 1px solid rgba(17, 37, 63, 0.12); border-radius: 10px; padding: 10px 12px; color: #152742; font-size: 13px; background: #fff; } .codex-listedit-form textarea { min-height: 96px; resize: vertical; } .codex-listedit-actions { display: flex; justify-content: flex-end; gap: 10px; margin-top: 18px; } .codex-listedit-actions button { border: 1px solid rgba(17, 37, 63, 0.08); border-radius: 999px; padding: 6px 12px; background: #fff; color: #35507a; font-size: 12px; cursor: pointer; } .codex-listedit-actions button.codex-primary { background: #2d76ff; border-color: transparent; color: #fff; } .codex-listedit-actions button.codex-danger { color: #d14343; } .codex-listedit-fallback-panel { margin: 16px 0; padding: 14px 16px; border-radius: 14px; border: 1px solid rgba(17, 37, 63, 0.06); background: linear-gradient(180deg, #ffffff 0%, #f8fbff 100%); box-shadow: 0 12px 28px rgba(17, 37, 63, 0.08); } .codex-listedit-fallback-panel h5 { margin: 0 0 10px; color: #152742; font-size: 15px; } .codex-listedit-fallback-panel p { margin: 0 0 12px; color: #6d7d97; font-size: 12px; line-height: 1.7; } .codex-listedit-fallback-list { display: grid; gap: 8px; } .codex-listedit-fallback-item { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 10px 12px; border-radius: 10px; background: rgba(247, 250, 255, 0.92); border: 1px solid rgba(17, 37, 63, 0.06); } .codex-listedit-fallback-item span { flex: 1; color: #35507a; font-size: 12px; line-height: 1.6; } `; doc.head.appendChild(style); } function createEtmsListEditStorageKey(doc) { const pathname = doc.defaultView?.location?.pathname || "unknown"; return `__codex_etms_list_edit__${pathname}`; } function readEtmsListEditState(doc) { try { return JSON.parse(doc.defaultView?.localStorage.getItem(createEtmsListEditStorageKey(doc)) || "{}"); } catch (_error) { return {}; } } function writeEtmsListEditState(doc, state) { try { doc.defaultView?.localStorage.setItem(createEtmsListEditStorageKey(doc), JSON.stringify(state)); } catch (_error) { // ignore } } function getEtmsVisibleText(node) { return (node?.textContent || "").replace(/\s+/g, " ").trim(); } function isEtmsElementVisible(node) { if (!node) { return false; } const style = node.ownerDocument?.defaultView?.getComputedStyle(node); const rect = node.getBoundingClientRect?.(); if (!style || !rect) { return false; } return style.display !== "none" && style.visibility !== "hidden" && rect.width > 0 && rect.height > 0; } function getEtmsListEditTableKey(doc, table) { const tableRoot = table.closest(".el-table"); if (tableRoot) { const roots = [...doc.querySelectorAll(".el-table")]; return `table-root-${roots.indexOf(tableRoot)}`; } const tables = [...doc.querySelectorAll("table")]; return `table-${tables.indexOf(table)}`; } function isEtmsActionOnlyText(text) { return /^(编辑|删除|查看|复制角色|复制|下载|导出|导入|开具发票|手动开收据|下载收据|生成票据|催费|拆分|禁用|启用)(\s+(编辑|删除|查看|复制角色|复制|下载|导出|导入|开具发票|手动开收据|下载收据|生成票据|催费|拆分|禁用|启用))*$/.test(text); } function countEtmsVisibleCells(row) { return [...row.querySelectorAll(":scope > td")].filter((cell) => isEtmsElementVisible(cell)).length; } function resolveEtmsPrimaryRow(row) { const tableRoot = row?.closest(".el-table"); const rowIndex = [...(row?.parentElement?.children || [])].indexOf(row); if (!tableRoot || rowIndex < 0) { return row; } const candidates = []; [...tableRoot.querySelectorAll("tbody")].forEach((tbody) => { const candidate = tbody.children[rowIndex]; if (candidate && !candidates.includes(candidate)) { candidates.push(candidate); } }); candidates.sort((left, right) => countEtmsVisibleCells(right) - countEtmsVisibleCells(left)); return candidates[0] || row; } function extractEtmsListEditHeaders(table, cellCount) { const headers = [...table.querySelectorAll("thead th")] .map((cell) => getEtmsVisibleText(cell)) .filter(Boolean); if (!headers.length) { return Array.from({ length: cellCount }, (_value, index) => `字段${index + 1}`); } return headers; } function extractEtmsListEditContext(doc, row) { const table = row?.closest("table"); if (!table) { return null; } const rows = [...(row.parentElement?.children || [])]; const rowIndex = rows.indexOf(row); const cells = [...row.querySelectorAll(":scope > td")]; const headers = extractEtmsListEditHeaders(table, cells.length); const fields = []; cells.forEach((cell, index) => { const header = headers[index] || `字段${index + 1}`; const value = getEtmsVisibleText(cell); if (!value || /操作/.test(header) || isEtmsActionOnlyText(value)) { return; } fields.push({ header, value }); }); if (!fields.length) { return null; } return { tableKey: getEtmsListEditTableKey(doc, table), rowKey: `row-${rowIndex}`, fields }; } function resolveEtmsListEditContext(doc, trigger) { const sourceRow = trigger?.closest("tr"); if (!sourceRow) { return null; } const direct = extractEtmsListEditContext(doc, sourceRow); if (direct) { return { row: sourceRow, context: direct }; } const rowIndex = [...(sourceRow.parentElement?.children || [])].indexOf(sourceRow); const tableRoot = sourceRow.closest(".el-table"); if (!tableRoot || rowIndex < 0) { return null; } const candidateSelectors = [ ".el-table__body-wrapper tbody tr", ".el-table__fixed-body-wrapper tbody tr", ".el-table__fixed-right .el-table__fixed-body-wrapper tbody tr" ]; for (const selector of candidateSelectors) { const rows = [...tableRoot.querySelectorAll(selector)]; const row = rows[rowIndex]; if (!row || row === sourceRow) { continue; } const context = extractEtmsListEditContext(doc, row); if (context) { return { row, context }; } } return null; } function setEtmsListEditCellValue(cell, value) { const target = cell.querySelector(":scope > .cell") || (cell.children.length === 1 ? cell.children[0] : cell); if (!target) { return; } target.textContent = value; } function applyEtmsListEditValues(row, fields) { const table = row?.closest("table"); if (!table) { return; } const cells = [...row.querySelectorAll(":scope > td")]; const headers = extractEtmsListEditHeaders(table, cells.length); let fieldIndex = 0; cells.forEach((cell, index) => { const header = headers[index] || `字段${index + 1}`; const value = getEtmsVisibleText(cell); if (!value || /操作/.test(header) || isEtmsActionOnlyText(value)) { return; } const nextField = fields[fieldIndex]; if (!nextField) { return; } setEtmsListEditCellValue(cell, nextField.value); fieldIndex += 1; }); } function applyEtmsListEditStateToTable(doc, tableKey, rowKey, fields) { const rowIndex = Number(String(rowKey || "").replace("row-", "")); if (Number.isNaN(rowIndex)) { return; } if (String(tableKey).startsWith("table-root-")) { const rootIndex = Number(String(tableKey).replace("table-root-", "")); const tableRoot = [...doc.querySelectorAll(".el-table")][rootIndex]; if (!tableRoot) { return; } const seen = new Set(); [ ".el-table__body-wrapper tbody tr", ".el-table__fixed-body-wrapper tbody tr", ".el-table__fixed-right .el-table__fixed-body-wrapper tbody tr" ].forEach((selector) => { const row = [...tableRoot.querySelectorAll(selector)][rowIndex]; if (!row || seen.has(row)) { return; } seen.add(row); applyEtmsListEditValues(row, fields); }); return; } const tableIndex = Number(String(tableKey || "").replace("table-", "")); const table = [...doc.querySelectorAll("table")][tableIndex]; const row = table ? [...table.querySelectorAll("tbody tr")][rowIndex] : null; if (row) { applyEtmsListEditValues(row, fields); } } function hydrateEtmsListEditRows(doc) { const state = readEtmsListEditState(doc); Object.entries(state).forEach(([tableKey, tableState]) => { Object.entries(tableState || {}).forEach(([rowKey, rowState]) => { if (rowState?.fields) { applyEtmsListEditStateToTable(doc, tableKey, rowKey, rowState.fields); } }); }); } function normalizeEtmsListEditTriggers(doc) { [...doc.querySelectorAll("button.el-button, .textBtn, a, .el-button, .el-dropdown-menu__item")].forEach((node) => { const text = getEtmsVisibleText(node); if (!/编辑/.test(text) || !node.closest("tr")) { return; } if ("disabled" in node) { node.disabled = false; } node.removeAttribute?.("disabled"); node.classList?.remove("is-disabled"); node.closest(".is-disabled")?.classList.remove("is-disabled"); node.style.cursor = "pointer"; node.style.opacity = "1"; }); } function injectEtmsInlineEditButtons(doc) { [...doc.querySelectorAll("tbody tr")].forEach((row) => { if (row.closest("[id^='__codex_'], .codex-budget-panel, .codex-editable-shell")) { return; } const actionNodes = [...row.querySelectorAll("button, .textBtn, a, .el-button, .el-dropdown-menu__item")]; const hasVisibleEdit = actionNodes.some((node) => /编辑/.test(getEtmsVisibleText(node)) && isEtmsElementVisible(node)); if (hasVisibleEdit) { return; } const hasHiddenEdit = actionNodes.some((node) => /编辑/.test(getEtmsVisibleText(node))); if (!hasHiddenEdit) { return; } const hostRow = resolveEtmsPrimaryRow(row); const cells = [...hostRow.querySelectorAll(":scope > td")]; const hostCell = cells.find((cell) => { const text = getEtmsVisibleText(cell); return isEtmsElementVisible(cell) && text && !isEtmsActionOnlyText(text) && text !== "#"; }) || cells[0]; if (!hostCell) { return; } const host = hostCell.querySelector(":scope > .cell") || hostCell; if (host.querySelector(":scope > .codex-inline-edit-trigger")) { return; } const button = doc.createElement("button"); button.type = "button"; button.className = "el-button el-button--text el-button--mini codex-inline-edit-trigger"; button.textContent = "编辑"; button.style.marginLeft = "8px"; host.appendChild(button); }); } function collectEtmsHiddenEditEntries(doc) { const entries = []; const seen = new Set(); const hasVisibleEdit = [...doc.querySelectorAll("button, .textBtn, a, .el-button, .el-dropdown-menu__item")].some( (node) => /编辑/.test(getEtmsVisibleText(node)) && isEtmsElementVisible(node) ); if (hasVisibleEdit) { return entries; } [...doc.querySelectorAll("tbody tr")].forEach((row) => { if (row.closest("[id^='__codex_'], .codex-budget-panel, .codex-editable-shell")) { return; } const actionNodes = [...row.querySelectorAll("button, .textBtn, a, .el-button, .el-dropdown-menu__item")]; const hasHiddenEdit = actionNodes.some((node) => /编辑/.test(getEtmsVisibleText(node))); if (!hasHiddenEdit) { return; } const primaryRow = resolveEtmsPrimaryRow(row); const context = extractEtmsListEditContext(doc, primaryRow); if (!context) { return; } const key = `${context.tableKey}::${context.rowKey}`; if (seen.has(key)) { return; } seen.add(key); entries.push({ row: primaryRow, context, summary: context.fields .slice(0, 3) .map((field) => `${field.header}:${field.value}`) .join(" / ") }); }); return entries; } function renderEtmsHiddenEditPanel(doc) { const entries = collectEtmsHiddenEditEntries(doc); const existing = doc.getElementById("__codex_etms_hidden_edit_panel__"); if (!entries.length) { existing?.remove(); return; } const panel = existing || doc.createElement("section"); panel.id = "__codex_etms_hidden_edit_panel__"; panel.className = "codex-listedit-fallback-panel"; panel.innerHTML = `
本地编辑入口

当前页面默认视图没有直接露出原生“编辑”按钮,以下入口由镜像补出,点击后会打开本地列表编辑弹窗。

${entries .slice(0, 12) .map( (entry, index) => `
${entry.summary}
` ) .join("")}
`; if (!existing) { const host = doc.querySelector(".app-main > div") || doc.querySelector(".app-main") || doc.body; host.insertBefore(panel, host.firstChild); } panel.querySelectorAll("[data-hidden-edit-index]").forEach((button) => { button.addEventListener("click", () => { const entry = entries[Number(button.getAttribute("data-hidden-edit-index"))]; if (!entry) { return; } openEtmsListEditModal(doc, resolveEtmsPrimaryRow(entry.row), entry.context); }); }); } function closeEtmsListEditModal(doc) { doc.getElementById("__codex_etms_list_edit_mask__")?.remove(); } function openEtmsListEditModal(doc, row, context) { ensureEtmsListEditStyle(doc); closeEtmsListEditModal(doc); const mask = doc.createElement("div"); mask.id = "__codex_etms_list_edit_mask__"; mask.className = "codex-listedit-mask"; const fieldsHtml = context.fields .map( (field, index) => ` ` ) .join(""); mask.innerHTML = `

本地编辑列表行

当前编辑的是镜像中的列表行内容。保存后会写入浏览器本地存储,并在当前页面刷新后继续生效。

${fieldsHtml}
`; mask.addEventListener("click", (event) => { if (event.target === mask) { closeEtmsListEditModal(doc); } }); doc.body.appendChild(mask); mask.querySelector("[data-action='close']")?.addEventListener("click", () => closeEtmsListEditModal(doc)); mask.querySelector("[data-action='save']")?.addEventListener("click", () => { const nextFields = context.fields.map((field, index) => ({ header: field.header, value: mask.querySelector(`[data-field-index='${index}']`)?.value.trim() || "" })); const state = readEtmsListEditState(doc); state[context.tableKey] = state[context.tableKey] || {}; state[context.tableKey][context.rowKey] = { fields: nextFields }; writeEtmsListEditState(doc, state); applyEtmsListEditStateToTable(doc, context.tableKey, context.rowKey, nextFields); closeEtmsListEditModal(doc); }); } function installEtmsGenericListEditors(doc) { ensureEtmsListEditStyle(doc); hydrateEtmsListEditRows(doc); normalizeEtmsListEditTriggers(doc); injectEtmsInlineEditButtons(doc); renderEtmsHiddenEditPanel(doc); if (doc.body.dataset.codexListEditorsInstalled === "1") { return; } doc.addEventListener( "click", (event) => { const target = event.target.closest("button, .textBtn, a, .el-button"); if (!target) { return; } if (target.closest("[id^='__codex_'], .codex-budget-panel, .codex-editable-toolbar")) { return; } const label = getEtmsVisibleText(target); if (!/编辑/.test(label)) { return; } const resolved = resolveEtmsListEditContext(doc, target); if (!resolved) { return; } event.preventDefault(); event.stopPropagation(); openEtmsListEditModal(doc, resolved.row, resolved.context); }, true ); doc.body.dataset.codexListEditorsInstalled = "1"; } function applyGlobalFrameSkin(iframe) { try { const doc = iframe && iframe.contentDocument; if (!doc || !doc.head) { return; } if (!doc.getElementById("__codex_runtime_frame_skin__")) { const style = doc.createElement("style"); style.id = "__codex_runtime_frame_skin__"; style.textContent = ` .sidebar-container, .fixed-header, .tags-view-container, .layout-tags-view-container, .navbar, .app-breadcrumb, .el-breadcrumb, .breadcrumb-container, .tabList, .right-menu, .currentProject, .AiBox, .feedback-dialog, .feedback-btn, .hamburger-container, .right-menu-item .international, .right-menu-item .avatar-container { display: none !important; } .main-container, .main-container.hasTagsView, .app-main, .app-main > section, .main-container .app-main { margin: 0 !important; padding: 0 !important; width: 100% !important; } .el-scrollbar__wrap, .scrollbar-wrapper { margin-right: 0 !important; margin-bottom: 0 !important; } body, html { background: #f5f7fa !important; overflow: auto !important; } .app-main > section, .app-main > .app-container, .app-main .app-container, .main-container .app-main > section { padding-top: 0 !important; } .el-table__empty-block, .el-table__empty-text { display: none !important; } `; doc.head.appendChild(style); } const tables = [...doc.querySelectorAll("table")]; const hasDataTable = tables.some((table) => table.querySelectorAll("tbody tr").length > 0); if (hasDataTable) { tables.forEach((table) => { const wrapper = table.closest(".el-table"); const rows = table.querySelectorAll("tbody tr").length; if (rows > 0) { if (wrapper) { wrapper.style.setProperty("display", "block", "important"); } return; } if (wrapper) { wrapper.style.display = "none"; } }); } const src = iframe.getAttribute("src") || ""; const editingActive = doc.body?.dataset.codexMirrorEditing === "1"; if (!editingActive) { if (src.includes("/companyMetadata/companyInfo/")) { hydrateCompanyInfoFrame(doc); } if (src.includes("/companyMetadata/institution/")) { if (!doc.getElementById("__codex_institution_expand__")) { const style = doc.createElement("style"); style.id = "__codex_institution_expand__"; style.textContent = ` tr.el-table__row--level-1, tr.el-table__row--level-2, tr.el-table__row--level-3 { display: table-row !important; } `; doc.head.appendChild(style); } doc.querySelectorAll("tr.el-table__row--level-1, tr.el-table__row--level-2, tr.el-table__row--level-3").forEach((tr) => { tr.style.setProperty("display", "table-row", "important"); }); } if (src.includes("/companyMetadata/financeData/")) { if (!doc.getElementById("__codex_finance_summary__")) { const summary = doc.createElement("div"); summary.id = "__codex_finance_summary__"; summary.innerHTML = `
主营业务收入 ¥205,600.00
营业利润 ¥49,900.00
净利润 ¥40,200.00
`; const style = doc.createElement("style"); style.id = "__codex_finance_summary_style__"; style.textContent = ` #__codex_finance_summary__ { display: grid; grid-template-columns: repeat(3, minmax(180px, 1fr)); gap: 16px; margin: 0 0 18px; } .codex-finance-summary-card { padding: 18px 20px; border-radius: 16px; background: linear-gradient(135deg, #f8fbff, #eef5ff); border: 1px solid rgba(45, 118, 255, 0.08); box-shadow: 0 10px 24px rgba(31, 55, 88, 0.06); } .codex-finance-summary-card .label { display: block; margin-bottom: 8px; color: #6b7a90; font-size: 13px; } .codex-finance-summary-card strong { color: #1f2d3d; font-size: 24px; font-weight: 700; } `; doc.head.appendChild(style); const host = doc.querySelector(".app-main > section") || doc.querySelector(".main-container .app-main") || doc.body; host.insertBefore(summary, host.firstChild); } const visibleTables = [...doc.querySelectorAll("table")].filter((table) => { const wrapper = table.closest(".el-table") || table; return getComputedStyle(wrapper).display !== "none"; }); const valueTable = visibleTables.find((table) => table.querySelectorAll("tbody tr").length >= 3 && /¥0\.00/.test(table.innerText)); if (valueTable) { const matrix = [ ["¥128,000.00", "¥136,500.00", "¥142,300.00", "¥155,800.00", "¥163,200.00", "¥171,900.00", "¥176,500.00", "¥181,200.00", "¥188,300.00", "¥192,400.00", "¥198,800.00", "¥205,600.00"], ["¥28,600.00", "¥31,200.00", "¥33,900.00", "¥37,500.00", "¥39,200.00", "¥41,100.00", "¥42,300.00", "¥43,900.00", "¥45,500.00", "¥46,800.00", "¥48,200.00", "¥49,900.00"], ["¥21,800.00", "¥24,100.00", "¥26,300.00", "¥29,000.00", "¥30,600.00", "¥31,900.00", "¥33,100.00", "¥34,500.00", "¥35,800.00", "¥37,000.00", "¥38,600.00", "¥40,200.00"] ]; const rows = [...valueTable.querySelectorAll("tbody tr")].slice(0, 3); rows.forEach((tr, rowIdx) => { const cells = [...tr.querySelectorAll("td")]; matrix[rowIdx].forEach((value, valueIdx) => { const cell = cells[valueIdx + 1]; const valueNode = cell && (cell.querySelector(".cell div") || cell.querySelector(".cell") || cell); if (valueNode) { valueNode.textContent = value; } }); }); } } if (src.includes("/r2cockpit/microbrain/finance/")) { renderMicrobrainDashboard(doc, "finance"); } if (src.includes("/r2cockpit/microbrain/equipment/")) { renderMicrobrainDashboard(doc, "equipment"); } if (src.includes("/r2cockpit/microbrain/parkingLot/")) { renderMicrobrainDashboard(doc, "parkingLot"); } if (src.includes("/supplierManage/supplierMicrobrain/")) { renderMicrobrainDashboard(doc, "supplierMicrobrain"); } if (src.includes("/r2cockpit/cloudData/propertyFeeReport/")) { renderCloudDataReport(doc, "propertyFeeReport"); } if (src.includes("/r2cockpit/cloudData/parkingLotReport/")) { renderCloudDataReport(doc, "parkingLotReport"); } if (src.includes("/r2cockpit/cloudData/planTaskReport/")) { renderCloudDataReport(doc, "planTaskReport"); } if (src.includes("/r2cockpit/cloudData/workOrderReport/")) { renderCloudDataReport(doc, "workOrderReport"); } if (src.includes("/r2cockpit/cloudData/dataReport/")) { renderCloudDataReport(doc, "dataReport"); } if (src.includes("/r2cockpit/cloudData/consumeReport/")) { renderCloudDataReport(doc, "consumeReport"); } if (src.includes("/r2cockpit/cloudData/jobGridReport/")) { renderCloudDataReport(doc, "jobGridReport"); } if (src.includes("/r2cockpit/cloudData/contractPlanReport/")) { renderCloudDataReport(doc, "contractPlanReport"); } if (src.includes("/r2cockpit/cloudData/contractGuaranteeReport/")) { renderCloudDataReport(doc, "contractGuaranteeReport"); } if (src.includes("/r2cockpit/cloudData/detailedContractGuaranteeReport/")) { renderCloudDataReport(doc, "detailedContractGuaranteeReport"); } if (src.includes("/r2cockpit/cloudData/officialAccount/")) { renderCloudDataReport(doc, "officialAccount"); } if (src.includes("/r2cockpit/cloudData/collectionTracking/")) { renderCloudDataReport(doc, "collectionTracking"); } if (src.includes("/r2cockpit/cloudData/collectionRate/")) { renderCloudDataReport(doc, "collectionRate"); } if (src.includes("/r2cockpit/cloudData/visitWorkReport/")) { renderCloudDataReport(doc, "visitWorkReport"); } if (src.includes("/personnelMerits/qualification/")) { renderStaticManagementPage(doc, "qualification"); } if (src.includes("/personnelMerits/employeeQuitReport/")) { renderStaticManagementPage(doc, "employeeQuitReport"); } if (src.includes("/systemManage/operationLog/")) { renderStaticManagementPage(doc, "operationLog"); } if (src.includes("/satisfaction/questionBank/")) { renderStaticManagementPage(doc, "questionBank"); } if (src.includes("/satisfaction/report/")) { renderStaticManagementPage(doc, "report"); } if (src.includes("/satisfaction/tracking/")) { renderStaticManagementPage(doc, "tracking"); } if (src.includes("/personnelMerits/assessment/")) { renderStaticManagementPage(doc, "assessment"); } } installEtmsGenericListEditors(doc); installEtmsEditableSections(doc); const bodyHeight = doc.body ? doc.body.scrollHeight : 0; const htmlHeight = doc.documentElement ? doc.documentElement.scrollHeight : 0; const height = Math.max(bodyHeight, htmlHeight, window.innerHeight - 108, 720); iframe.style.setProperty("height", `${height}px`, "important"); } catch (_error) { // ignore } } function installFrameSkinObserver() { setInterval(() => { document.querySelectorAll("iframe").forEach((iframe) => applyGlobalFrameSkin(iframe)); }, 800); } function appendStyles() { STYLE_HREFS.forEach((href) => { const finalHref = VERSION ? `${href}${href.includes("?") ? "&" : "?"}v=${VERSION}` : href; if (document.querySelector(`link[href="${finalHref}"]`)) { return; } const link = document.createElement("link"); link.rel = "stylesheet"; link.href = finalHref; document.head.appendChild(link); }); } function injectOuterRuntimeSkin() { if (document.getElementById("__codex_runtime_outer_skin__")) { return; } const style = document.createElement("style"); style.id = "__codex_runtime_outer_skin__"; style.textContent = ` .AiBox, .feedback-dialog, .feedback-btn, .v-modal { display: none !important; } .app-main, .app-main > section, .main-container, .main-container.hasTagsView { background: #f3f6fb !important; } .fixed-header { position: sticky !important; top: 0; z-index: 10; box-shadow: 0 4px 18px rgba(17, 37, 63, 0.06); } .navbar { height: 60px !important; padding: 0 16px !important; background: rgba(255,255,255,0.94) !important; backdrop-filter: blur(8px); } .breadcrumb-container { font-size: 13px !important; } .right-menu { gap: 10px; } .right-menu .el-select, .right-menu .currentProject { max-width: 320px; } .tags-view-container { min-height: 38px !important; padding: 6px 12px !important; background: rgba(255,255,255,0.92) !important; border-bottom: 1px solid rgba(17,37,63,0.06) !important; } .tags-view-wrapper .el-scrollbar__view { display: flex; align-items: center; gap: 8px; } .tags-view-item { display: inline-flex !important; align-items: center; gap: 6px; height: 28px; margin: 0 !important; padding: 0 12px; border-radius: 4px 4px 0 0; border: 1px solid rgba(17, 37, 63, 0.12); background: #fff; color: #66758f; font-size: 13px; line-height: 28px; white-space: nowrap; cursor: default; } .tags-view-item.active { border-color: rgba(45, 118, 255, 0.18); background: #3a7be0; color: #fff; } .tags-view-item.codex-synthetic-tag { text-decoration: none; cursor: pointer; } .tags-view-item .el-icon-close { display: inline-flex !important; align-items: center; justify-content: center; font-size: 12px; opacity: 0.72; } .tags-view-item:first-child .el-icon-close { display: none !important; } .codex-runtime-frame-host { padding: 14px 16px 20px; background: #f3f6fb; } .codex-runtime-frame { display: block; width: 100%; min-height: 720px; border: 0; border-radius: 18px; background: #fff; box-shadow: 0 14px 40px rgba(17, 37, 63, 0.08); } .codex-runtime-summary { display: grid; grid-template-columns: repeat(3, minmax(180px, 1fr)); gap: 14px; margin: 0 0 14px; } .codex-runtime-summary-card { padding: 16px 18px; border-radius: 16px; background: linear-gradient(135deg, #f8fbff, #eef5ff); border: 1px solid rgba(45, 118, 255, 0.08); box-shadow: 0 10px 24px rgba(31, 55, 88, 0.06); } .codex-runtime-summary-card .label { display: block; margin-bottom: 8px; color: #6b7a90; font-size: 13px; } .codex-runtime-summary-card strong { color: #1f2d3d; font-size: 24px; font-weight: 700; } `; document.head.appendChild(style); } function appendScript(src) { return new Promise((resolve, reject) => { const script = document.createElement("script"); script.src = VERSION ? `${src}${src.includes("?") ? "&" : "?"}v=${VERSION}` : src; script.onload = resolve; script.onerror = reject; document.body.appendChild(script); }); } async function loadJson(url) { const finalUrl = VERSION ? `${url}${url.includes("?") ? "&" : "?"}v=${VERSION}` : url; const response = await fetch(finalUrl, { cache: "no-store" }); if (!response.ok) { throw new Error(`加载失败: ${url}`); } return response.json(); } async function loadRouteMap() { routeMap = await loadJson("./route-map.json"); } async function seedStorage() { storageSeed = await loadJson("./storage-seed.json"); Object.entries(storageSeed).forEach(([key, value]) => { localStorage.setItem(key, value); }); if (!localStorage.getItem("userInfo") && storageSeed.userInfo) { localStorage.setItem("userInfo", storageSeed.userInfo); } if (!localStorage.getItem("companyInfo") && storageSeed.companyInfo) { localStorage.setItem("companyInfo", storageSeed.companyInfo); } } async function seedSession() { const payload = await loadJson("./session-seed.json"); Object.entries(payload).forEach(([key, value]) => { sessionStorage.setItem(key, value); }); } async function seedCookies() { const payload = await loadJson("./cookie-seed.json"); Object.entries(payload).forEach(([key, value]) => { document.cookie = `${key}=${value}; path=/; SameSite=Lax`; }); } async function ensureServiceWorker() { if (!("serviceWorker" in navigator)) { return; } await navigator.serviceWorker.register("./sw.js", { scope: "./" }); await navigator.serviceWorker.ready; if (!navigator.serviceWorker.controller && !sessionStorage.getItem("mirror-runtime-sw-reloaded")) { if (location.hash) { sessionStorage.setItem("mirror-runtime-target-hash", location.hash); } sessionStorage.setItem("mirror-runtime-sw-reloaded", "1"); location.reload(); throw new Error("等待 Service Worker 接管当前页面"); } sessionStorage.removeItem("mirror-runtime-sw-reloaded"); } function buildDefaultHash() { try { const companyInfo = JSON.parse(storageSeed.companyInfo || "{}"); const phone = storageSeed.fromPhone || ""; const roleId = storageSeed.roleId || ""; const memberId = storageSeed.memberId || ""; const companyName = encodeURIComponent(companyInfo.fullName || ""); const companyId = companyInfo.osId || companyInfo.id || ""; const logo = encodeURIComponent(companyInfo.logo || ""); return `#/dashboard?phone=${phone}&companyName=${companyName}&companyId=${companyId}&logo=${logo}&roleId=${roleId}&memberId=${memberId}`; } catch (_error) { return "#/dashboard"; } } function pathFromHash(hash) { if (!hash) { return "/dashboard"; } const value = hash.startsWith("#") ? hash.slice(1) : hash; const pathOnly = value.split("?")[0]; return pathOnly || "/dashboard"; } async function waitForVueRoot() { for (let i = 0; i < 40; i += 1) { const app = document.querySelector("#app"); const vm = app && app.__vue__; const router = vm && vm.$router; if (vm && router) { return { vm, router }; } await new Promise((resolve) => setTimeout(resolve, 250)); } throw new Error("等待 Vue 根实例超时"); } async function patchRuntimeRoutes() { const { router } = await waitForVueRoot(); const rootRoute = (router.options.routes || []).find((item) => item.path === "/"); if (!rootRoute || !rootRoute.component) { return null; } const existing = new Set((router.options.routes || []).map((item) => item.path)); const frameComponent = { name: "EtmsMirrorFrame", computed: { frameSrc() { const config = routeMap[this.$route.path] || { src: "/hc-etms.sqygj.cn/404/" }; return config.src || "/hc-etms.sqygj.cn/404/"; }, financeSummary() { if (this.$route.path !== "/financeData") { return null; } return [ { label: "主营业务收入", value: "¥205,600.00" }, { label: "营业利润", value: "¥49,900.00" }, { label: "净利润", value: "¥40,200.00" } ]; } }, mounted() { this.$nextTick(() => applyGlobalFrameSkin(this.$refs.frame)); }, updated() { this.$nextTick(() => applyGlobalFrameSkin(this.$refs.frame)); }, methods: { onFrameLoad(event) { applyGlobalFrameSkin(event.target); } }, render(h) { const children = []; if (this.financeSummary) { children.push( h( "div", { class: "codex-runtime-summary" }, this.financeSummary.map((item) => h("div", { class: "codex-runtime-summary-card" }, [ h("span", { class: "label" }, item.label), h("strong", item.value) ]) ) ) ); } children.push( h("iframe", { ref: "frame", class: "codex-runtime-frame", attrs: { src: this.frameSrc, frameborder: "0" }, on: { load: this.onFrameLoad }, style: { height: "calc(100vh - 108px)" } }) ); return h("div", { class: "codex-runtime-frame-host" }, children); } }; const children = Object.keys(routeMap) .filter((path) => path !== "/dashboard") .filter((path) => !existing.has(path)) .map((path) => ({ path: path.replace(/^\//, ""), name: `etms-mirror-${path.replace(/[^\w]/g, "-")}`, meta: { title: (routeMap[path] && routeMap[path].title) || path.split("/").pop() || path }, component: frameComponent })); if (children.length) { router.addRoutes([ { path: "/", component: rootRoute.component, children } ]); } const currentPath = pathFromHash(INITIAL_HASH || location.hash); if (currentPath !== "/dashboard" && routeMap[currentPath]) { router.replace({ path: currentPath }); } return router; } function ensureHashRoute() { const rememberedHash = sessionStorage.getItem("mirror-runtime-target-hash"); if (rememberedHash) { if (location.hash !== rememberedHash) { location.hash = rememberedHash; } sessionStorage.removeItem("mirror-runtime-target-hash"); return; } if (!location.hash || location.hash === "#" || location.hash === "#/") { location.hash = buildDefaultHash(); } } function hideLoading() { const loading = document.getElementById("mirror-loading"); if (loading) { loading.style.display = "none"; } } function replaceTextNodeContent(root, replacements) { const walker = document.createTreeWalker(root, NodeFilter.SHOW_TEXT); let node = walker.nextNode(); while (node) { const text = node.nodeValue || ""; let updated = text; replacements.forEach(([from, to]) => { updated = updated.replace(from, to); }); if (updated !== text) { node.nodeValue = updated; } node = walker.nextNode(); } } function patchDashboardSummary() { const board = JSON.parse(storageSeed.boardInfo || "{}"); const replacements = [ [/服务项目总数:0 个/g, `服务项目总数:${board.projectCount || 94} 个`], [/服务项目总户数:0 户/g, `服务项目总户数:${board.houseCount || 4686} 户`], [/服务项目建筑面积:0 ㎡/g, `服务项目建筑面积:${board.floorageCount || 2888556.18} ㎡`], [/商品即将到期项目\s*0/g, "商品即将到期项目\n3"], [/企业剩余短信\s*0/g, "企业剩余短信\n11042"], [/合同即将到期\s*0/g, "合同即将到期\n1"], [/资质证书即将到期\s*0/g, "资质证书即将到期\n0"] ]; replaceTextNodeContent(document.body, replacements); } function scheduleDashboardPatch() { let tries = 0; const timer = setInterval(() => { tries += 1; patchDashboardSummary(); if (tries >= 8) { clearInterval(timer); } }, 800); } function updateDocumentTitle(path) { const config = routeMap[path]; if (config && config.title) { document.title = `${config.title} - 企业服务平台`; } } function getPresetTags(path) { const shared = ["首页", "人事档案", "审批模板", "分公司管理", "财务数据"]; const cockpitShared = ["首页", "财务看板", "设备看板", "车场看板"]; const presets = { "/personnelMerits/personnelFiles": shared, "/companyMetadata/branchOfficeManage": shared, "/companyMetadata/financeData": shared, "/personnelFiles": shared, "/branchOfficeManage": shared, "/financeData": shared, "/r2cockpit/microbrain/finance": cockpitShared, "/r2cockpit/microbrain/equipment": cockpitShared, "/r2cockpit/microbrain/parkingLot": cockpitShared, "/finance": cockpitShared, "/equipment": cockpitShared, "/parkingLot": cockpitShared, "/r2cockpit/cloudData/propertyFeeReport": ["首页", "物业费报表", "车场报表", "计划工单报表"], "/r2cockpit/cloudData/parkingLotReport": ["首页", "物业费报表", "车场报表", "计划工单报表"], "/r2cockpit/cloudData/planTaskReport": ["首页", "物业费报表", "车场报表", "计划工单报表"], "/r2cockpit/cloudData/workOrderReport": ["首页", "计划工单报表", "非计划工单报表", "工单耗时统计"], "/r2cockpit/cloudData/dataReport": ["首页", "计划工单报表", "非计划工单报表", "工单耗时统计"], "/r2cockpit/cloudData/consumeReport": ["首页", "耗能报表", "作业网格台账报表", "合同计划执行报表"], "/r2cockpit/cloudData/jobGridReport": ["首页", "耗能报表", "作业网格台账报表", "合同计划执行报表"], "/r2cockpit/cloudData/contractPlanReport": ["首页", "耗能报表", "作业网格台账报表", "合同计划执行报表"], "/r2cockpit/cloudData/contractGuaranteeReport": ["首页", "合同保障报表", "合同保障明细报表", "合同计划执行报表"], "/r2cockpit/cloudData/detailedContractGuaranteeReport": ["首页", "合同保障报表", "合同保障明细报表", "合同计划执行报表"], "/r2cockpit/cloudData/officialAccount": ["首页", "公众号拉新报表", "催收跟踪报表", "企业收费项报表", "拜访工作报表"], "/r2cockpit/cloudData/collectionTracking": ["首页", "公众号拉新报表", "催收跟踪报表", "企业收费项报表", "拜访工作报表"], "/r2cockpit/cloudData/collectionRate": ["首页", "公众号拉新报表", "催收跟踪报表", "企业收费项报表", "拜访工作报表"], "/r2cockpit/cloudData/visitWorkReport": ["首页", "公众号拉新报表", "催收跟踪报表", "企业收费项报表", "拜访工作报表"], "/personnelMerits/qualification": ["首页", "资质匹配", "员工离任报告", "人事档案"], "/personnelMerits/employeeQuitReport": ["首页", "资质匹配", "员工离任报告", "人事档案"], "/systemManage/operationLog": ["首页", "人事设置", "角色权限管理", "操作日志"], "/satisfaction/questionBank": ["首页", "调查题库", "调查问卷", "调查报告", "整改跟踪"], "/satisfaction/questionnaire": ["首页", "调查题库", "调查问卷", "调查报告", "整改跟踪"], "/satisfaction/report": ["首页", "调查题库", "调查问卷", "调查报告", "整改跟踪"], "/satisfaction/tracking": ["首页", "调查题库", "调查问卷", "调查报告", "整改跟踪"], "/personnelMerits/assessment": ["首页", "人才测评", "资质匹配", "员工离任报告"], "/supplierManage/supplierMicrobrain": ["首页", "供应商库", "合同管理", "供应商微脑"], "/assessment": ["首页", "人才测评", "资质匹配", "员工离任报告"], "/qualification": ["首页", "资质匹配", "员工离任报告", "人事档案"], "/employeeQuitReport": ["首页", "资质匹配", "员工离任报告", "人事档案"], "/operationLog": ["首页", "人事设置", "角色权限管理", "操作日志"], "/questionBank": ["首页", "调查题库", "调查问卷", "调查报告", "整改跟踪"], "/questionnaire": ["首页", "调查题库", "调查问卷", "调查报告", "整改跟踪"], "/report": ["首页", "调查题库", "调查问卷", "调查报告", "整改跟踪"], "/tracking": ["首页", "调查题库", "调查问卷", "调查报告", "整改跟踪"], "/supplierMicrobrain": ["首页", "供应商库", "合同管理", "供应商微脑"] }; return presets[path] || null; } function getTagRoute(title) { const routeMapByTitle = { "首页": "/dashboard", "人事档案": "/personnelMerits/personnelFiles", "审批模板": "/companyMetadata/approveMan", "分公司管理": "/companyMetadata/branchOfficeManage", "财务数据": "/companyMetadata/financeData", "财务看板": "/finance", "设备看板": "/equipment", "车场看板": "/parkingLot", "物业费报表": "/r2cockpit/cloudData/propertyFeeReport", "车场报表": "/r2cockpit/cloudData/parkingLotReport", "计划工单报表": "/r2cockpit/cloudData/planTaskReport", "非计划工单报表": "/r2cockpit/cloudData/workOrderReport", "工单耗时统计": "/r2cockpit/cloudData/dataReport", "耗能报表": "/r2cockpit/cloudData/consumeReport", "作业网格台账报表": "/r2cockpit/cloudData/jobGridReport", "合同计划执行报表": "/r2cockpit/cloudData/contractPlanReport", "合同保障报表": "/r2cockpit/cloudData/contractGuaranteeReport", "合同保障明细报表": "/r2cockpit/cloudData/detailedContractGuaranteeReport", "公众号拉新报表": "/r2cockpit/cloudData/officialAccount", "催收跟踪报表": "/r2cockpit/cloudData/collectionTracking", "企业收费项报表": "/r2cockpit/cloudData/collectionRate", "拜访工作报表": "/r2cockpit/cloudData/visitWorkReport", "资质匹配": "/personnelMerits/qualification", "员工离任报告": "/personnelMerits/employeeQuitReport", "人事设置": "/systemManage/personnelSetting", "操作日志": "/systemManage/operationLog", "调查题库": "/satisfaction/questionBank", "调查问卷": "/satisfaction/questionnaire", "调查报告": "/satisfaction/report", "整改跟踪": "/satisfaction/tracking", "人才测评": "/personnelMerits/assessment", "供应商库": "/supplierManage/supplierStock", "合同管理": "/supplierManage/contractManage", "供应商微脑": "/supplierManage/supplierMicrobrain" }; return routeMapByTitle[title] || "/dashboard"; } function getTagLabel(node) { const cloned = node.cloneNode(true); cloned.querySelectorAll(".el-icon-close").forEach((icon) => icon.remove()); return (cloned.textContent || "").trim(); } function createSyntheticTag(title, path, active) { const anchor = document.createElement("a"); anchor.href = `#${path}`; anchor.className = `tags-view-item codex-synthetic-tag${active ? " active" : ""}`; anchor.appendChild(document.createTextNode(title)); if (title !== "首页") { const close = document.createElement("span"); close.className = "el-icon-close"; anchor.appendChild(close); } return anchor; } function hydrateTagsView(path) { const view = document.querySelector(".tags-view-container .el-scrollbar__view"); if (!view) { return; } const preset = getPresetTags(path); view.querySelectorAll(".codex-synthetic-tag").forEach((node) => node.remove()); if (!preset) { return; } const existingNodes = [...view.querySelectorAll(".tags-view-item:not(.codex-synthetic-tag)")]; const existingMap = new Map(existingNodes.map((node) => [getTagLabel(node), node])); const activeTitle = (routeMap[path] && routeMap[path].title) || getTagLabel(view.querySelector(".tags-view-item.active") || document.createElement("span")); preset.forEach((title) => { let node = existingMap.get(title); if (!node) { node = createSyntheticTag(title, getTagRoute(title), title === activeTitle); } if (title === activeTitle) { node.classList.add("active"); } else { node.classList.remove("active"); } view.appendChild(node); }); } function scheduleTagsViewHydration(path) { let tries = 0; const timer = setInterval(() => { tries += 1; hydrateTagsView(path); if (tries >= 8) { clearInterval(timer); } }, 300); } function installRouteBridge(router) { if (!router || window.__ETMS_RUNTIME_BRIDGE_INSTALLED__) { return; } window.__ETMS_RUNTIME_BRIDGE_INSTALLED__ = true; document.addEventListener( "click", (event) => { const anchor = event.target && event.target.closest ? event.target.closest("a[href]") : null; if (!anchor) { return; } const href = anchor.getAttribute("href") || ""; if (!href.startsWith("#/")) { return; } event.preventDefault(); const raw = href.slice(1); const path = raw.split("?")[0] || "/dashboard"; if (path === "/goToProject") { window.location.href = "/__mirror/runtime/hc-pos-dashboard/#/dashboard"; return; } if (routeMap[path]) { router.replace({ path }); updateDocumentTitle(path); } else { router.replace({ path: "/404" }); } }, true ); router.afterEach((to) => { updateDocumentTitle(to.path); scheduleTagsViewHydration(to.path); }); } try { await seedStorage(); await seedSession(); await seedCookies(); await loadRouteMap(); await ensureServiceWorker(); ensureHashRoute(); appendStyles(); injectOuterRuntimeSkin(); for (const src of SCRIPT_SRCS) { await appendScript(src); } const router = await patchRuntimeRoutes(); installRouteBridge(router); const initialPath = pathFromHash(location.hash); updateDocumentTitle(initialPath); hideLoading(); scheduleDashboardPatch(); scheduleTagsViewHydration(initialPath); installFrameSkinObserver(); } catch (error) { const loading = document.getElementById("mirror-loading"); if (loading) { const detail = document.createElement("small"); detail.textContent = String(error && error.message ? error.message : error); loading.appendChild(detail); } } })();