// 【重要】必须使用 const Component 作为组件变量名 // ONEOS-web · 企业业务总台账搭建方案(交互汇报页) // 双维:业务总台账(七类业务×近12月业绩/成本/利润)+ 车辆运营明细台账(氢/电/ETC/运维) const Component = function () { const { useState, useMemo, useCallback, useEffect } = React; const antd = window.antd || {}; const { Table, Tag, Modal, Button, Space } = antd; const C_PRIMARY = '#0f766e'; const C_PRIMARY_L = '#14b8a6'; const C_HERO = '#0c1222'; const C_HERO_ACCENT = '#132337'; const C_PAGE = '#f1f5f9'; const C_CARD = '#ffffff'; const C_TEXT = '#0f172a'; const C_MUTED = '#64748b'; const C_LINE = 'rgba(15, 23, 42, 0.08)'; const C_BLUE = '#2563eb'; const C_AMBER = '#d97706'; const C_VIOLET = '#7c3aed'; const C_ROSE = '#e11d48'; const FONT = '-apple-system, BlinkMacSystemFont, "PingFang SC", "Helvetica Neue", "Segoe UI", sans-serif'; const AXHUB_PROTO_URL = 'https://axhub.im/ax11/a57ed3c0b68f7f6a/#g=1'; const AXHUB_BIZ_LEDGER_URL = 'https://axhub.im/ax11/7587168366793103/?g=1&id=358ccx&p=%E4%B8%9A%E5%8A%A1%E5%8F%B0%E8%B4%A6'; /** 统计双维:业务总台账(经营结果) + 车辆运营明细台账(发生明细) */ const ledgerDimensions = [ { id: 'bizTotal', label: '业务总台账', color: C_BLUE, role: '按业务线汇总', summary: '列表展示七类业务费用总计;每类按月份展示近 12 个月业绩、成本、利润(利润 = 业绩 − 成本)。', listItems: ['租赁业务', '自营业务', '氢费业务', '电费业务', 'ETC业务', '销售业务', '其他业务'], }, { id: 'vehicleOps', label: '车辆运营明细台账', color: C_PRIMARY, role: '按车辆归集明细', summary: '记录单车维度的氢费、电费、ETC、运维等发生额;归集后写入业务总台账对应业务线,避免重复录入。', listItems: ['车辆氢费明细', '电费明细(特来电)', 'ETC 明细', '运维维修/保养/年审等'], }, ]; /** 业务总台账 · 七类业务口径(列表列与按月汇总规则) */ const bizTotalLedgerTypes = [ { id: 'lease', label: '租赁业务', color: C_BLUE, period: '按月份 · 近 12 个月', perf: '租金、服务费', cost: '车辆成本、居间费', profit: '业绩 − 成本', drill: '业绩可钻取至业务员 → 项目/合同', writeBack: '租赁账单、收款确认;车辆成本来自运维/财务分摊', }, { id: 'self', label: '自营业务', color: C_VIOLET, period: '按月份 · 近 12 个月', perf: '自营明细表 ·「金额」列汇总', cost: '自营明细中:氢费、ETC 费用、薪资、人工报销、日社保服务费、日轮胎费用、车辆费用', profit: '业绩 − 成本', drill: '业绩可钻取至业务员 → 项目', writeBack: '自营明细 Excel 导入;氢/ETC 可与车辆明细勾稽', }, { id: 'h2', label: '氢费业务', color: C_PRIMARY, period: '按月份 · 近 12 个月', perf: '氢费营收(客户/业务员分摊)', cost: '加氢采购成本、站点费用等', profit: '业绩 − 成本', drill: '业绩 → 业务员 → 项目', writeBack: '车辆运营明细 · 车辆氢费明细归集', }, { id: 'apply', label: '电费业务', color: C_AMBER, period: '按月份 · 近 12 个月', perf: '充电营收(内外部车辆区分)', cost: '场地、损耗、手续费、内部车成本等', profit: '业绩 − 成本', drill: '业绩 → 业务员 → 项目', writeBack: '车辆运营明细 · 特来电导入电费明细', }, { id: 'etc', label: 'ETC业务', color: '#0891b2', period: '按月份 · 近 12 个月', perf: '通行等 ETC 营收', cost: 'ETC 通道/服务成本', profit: '业绩 − 成本', drill: '业绩 → 业务员 → 项目', writeBack: '车辆运营明细 · ETC 供应商抓取', }, { id: 'resale', label: '销售业务', color: C_ROSE, period: '按月份 · 近 12 个月', perf: '车辆销售合同结算金额', cost: '销售相关成本', profit: '业绩 − 成本', drill: '业绩 → 业务员 → 项目', writeBack: '销售合同与出库结算', }, { id: 'other', label: '其他业务', color: C_MUTED, period: '按月份 · 近 12 个月', perf: '其他收入项汇总', cost: '其他成本项汇总', profit: '业绩 − 成本', drill: '按配置是否可钻取', writeBack: '杂项业务单据', }, ]; const BIZ_LEDGER_CATS = [ { key: 'lease', groupTitle: '租赁业务', short: '租赁' }, { key: 'self', groupTitle: '自营业务', short: '自营' }, { key: 'h2', groupTitle: '氢费业务', short: '氢费' }, { key: 'apply', groupTitle: '电费业务', short: '电费' }, { key: 'etc', groupTitle: 'ETC业务', short: 'ETC' }, { key: 'resale', groupTitle: '销售业务', short: '销售' }, { key: 'other', groupTitle: '其他业务', short: '其他' }, ]; const BIZ_LEDGER_SOURCE_MAP = { lease: '业绩:租金、服务费(租赁账单);成本:车辆成本、居间费;利润 = 业绩 − 成本', self: '业绩:自营明细「金额」列;成本:氢费、ETC、薪资、人工报销、日社保服务费、日轮胎费、车辆费用;利润 = 业绩 − 成本', h2: '车辆运营明细 → 车辆氢费明细,按客户/业务员分摊计入氢费业务', apply: '车辆运营明细 → 特来电电费导入,区分内外部车辆', etc: '车辆运营明细 → ETC 供应商抓取,按车牌归集', resale: '销售合同与出库结算', other: '其他业务单据汇总', }; const fmtBizMoney = (n) => { if (n === null || n === undefined || n === '') return '—'; const x = Number(n); if (Number.isNaN(x) || x === 0) return '—'; return x.toLocaleString('zh-CN', { minimumFractionDigits: 2, maximumFractionDigits: 2 }); }; const BIZ_LEDGER_MAIN_ROWS = [ { key: 'm5', month: 5, monthLabel: '5月', rowType: 'month', selfPerf: 318520.5, selfCost: 256816.4, selfProfit: 61704.1, leasePerf: 542180, leaseCost: 328600, leaseProfit: 213580, resalePerf: 412000, resaleCost: 298000, resaleProfit: 114000, h2Perf: 128560, h2Cost: 77200, h2Profit: 51360, applyPerf: 18200, applyCost: 5400, applyProfit: 12800, etcPerf: 6800, etcCost: 3200, etcProfit: 3600, otherPerf: 9200, otherCost: 3100, otherProfit: 6100, }, { key: 'm6', month: 6, monthLabel: '6月', rowType: 'month', selfPerf: 295400, selfCost: 241200, selfProfit: 54200, leasePerf: 518900, leaseCost: 315200, leaseProfit: 203700, resalePerf: 380500, resaleCost: 275000, resaleProfit: 105500, h2Perf: 119800, h2Cost: 71800, h2Profit: 48000, applyPerf: 16800, applyCost: 5100, applyProfit: 11700, etcPerf: 6200, etcCost: 2900, etcProfit: 3300, otherPerf: 8600, otherCost: 2800, otherProfit: 5800, }, { key: 'hint12', month: 0, monthLabel: '…', rowType: 'month', selfPerf: null, leasePerf: null, resalePerf: null, h2Perf: null, applyPerf: null, etcPerf: null, otherPerf: null, }, { key: 'total', month: 13, monthLabel: '合计', rowType: 'total', selfPerf: 613920.5, selfCost: 498016.4, selfProfit: 115904.1, leasePerf: 1061080, leaseCost: 643800, leaseProfit: 417280, resalePerf: 792500, resaleCost: 573000, resaleProfit: 219500, h2Perf: 248360, h2Cost: 149000, h2Profit: 99360, applyPerf: 35000, applyCost: 10500, applyProfit: 24500, etcPerf: 13000, etcCost: 6100, etcProfit: 6900, otherPerf: 17800, otherCost: 5900, otherProfit: 11900, }, ]; const BIZ_SALES_BY_CAT = { h2: [ { key: 's1', salesperson: '尚建华', amount: 53915.2 }, { key: 's2', salesperson: '刘念念', amount: 44926 }, { key: 's3', salesperson: '谯云', amount: 19284 }, { key: 's4', salesperson: '董剑煜', amount: 10334.8 }, ], lease: [ { key: 'd1', ym: '2026-05', monthRowSpan: 2, deptName: '业务三部', salesperson: '尚建华', mainPerf: 227715.6, h2PerfCol: 53915.2, elecPerf: 7644, etcPerfCol: 2856, otherAmt: 3864 }, { key: 'd2', ym: '2026-05', monthRowSpan: 0, deptName: '业务三部', salesperson: '刘念念', mainPerf: 189763, h2PerfCol: 44926, elecPerf: 6370, etcPerfCol: 2380, otherAmt: 3220 }, ], self: [ { key: 'd3', ym: '2026-05', monthRowSpan: 2, deptName: '业务一部', salesperson: '陈思', mainPerf: 133777.4, h2PerfCol: 25872, elecPerf: 3822, etcPerfCol: 1428, otherAmt: 1932 }, { key: 'd4', ym: '2026-05', monthRowSpan: 0, deptName: '业务一部', salesperson: '周宁', mainPerf: 111481, h2PerfCol: 21560, elecPerf: 3185, etcPerfCol: 1190, otherAmt: 1610 }, ], }; const BIZ_PROJECT_ROWS = [ { key: 'p1', projectCode: 'PRJ-2026-001', projectName: '嘉兴冷链城配项目', plateNo: '沪A62261F', amount: 27280, bizDate: '2026-05-08', remark: '—' }, { key: 'p2', projectCode: 'PRJ-2026-018', projectName: '沪浙干线运输', plateNo: '粤AGP3649', amount: 27280, bizDate: '2026-05-15', remark: '—' }, { key: 'p3', projectCode: 'PRJ-2026-033', projectName: '园区短驳', plateNo: '苏ED32891', amount: 27280, bizDate: '2026-05-22', remark: '演示' }, ]; const sectionNav = [ { key: 'hero', label: '汇报总览' }, { key: 'dimensions', label: '双维统计' }, { key: 'bizTypes', label: '业务总台账' }, { key: 'mindmap', label: '车辆明细' }, { key: 'principles', label: '搭建原则' }, { key: 'domains', label: '明细搭建' }, { key: 'workflows', label: '环节样表' }, { key: 'links', label: '勾稽关系' }, { key: 'drill', label: '钻取路径' }, { key: 'samples', label: '样表索引' }, { key: 'summary', label: '决策要点' }, ]; const kpiStats = [ { label: '统计维度', value: '2', unit: '类', color: C_PRIMARY }, { label: '业务总台账', value: '7', unit: '业务线', color: C_BLUE }, { label: '按月展示', value: '12', unit: '个月', color: C_AMBER }, { label: '利润公式', value: '绩−成', unit: '统一', color: C_VIOLET }, ]; const renderProtoStatus = (status) => { if (status === 'done') return 原型已实现; if (status === 'partial') return 部分实现; return 待建设; }; /** 各环节:对照 Axhub / web 端原型路径与样表 key */ const ledgerWorkflows = { bizTotal: { color: C_BLUE, steps: [ { key: 'businessLedger', name: '业务总台账列表', status: 'done', protoPath: 'web端/数据分析/业务台账.jsx', sampleKey: 'businessLedger', flow: '七类业务 × 近12月业绩/成本/利润;仅业绩可钻取', link: 'Axhub 业务台账' }, { key: 'leaseRule', name: '租赁业务口径', status: 'done', protoPath: '租赁账单 + 成本分摊', sampleKey: 'leaseRent', flow: '业绩=租金+服务费;成本=车辆成本+居间费' }, { key: 'selfRule', name: '自营业务口径', status: 'partial', protoPath: '自营明细导入', sampleKey: 'selfImport', flow: '业绩=金额列;成本=氢费/ETC/薪资/报销/日社保/日轮胎/车辆费' }, ], }, lease: { color: C_BLUE, steps: [ { key: 'leaseProfit', name: '租赁·客户利润样表(参考)', status: 'partial', protoPath: '业务总台账·租赁业务列', sampleKey: 'lease', flow: '汇总层见业务总台账;本样表为客户维度参考' }, { key: 'leaseRent', name: '收入·租赁业务(租金/服务费)', status: 'partial', protoPath: 'web端/财务管理/租赁账单.jsx', sampleKey: 'leaseRent', flow: '合同账单确认后计入收入' }, { key: 'leaseH2Rollup', name: '收入·氢费(从车辆氢费取)', status: 'done', protoPath: 'web端/台账数据/车辆氢费明细.jsx', sampleKey: 'vehicleH2Detail', flow: '已对账氢费按客户/合同汇总' }, { key: 'leaseCost', name: '成本·车辆/居间费', status: 'partial', protoPath: '运维台账+财务', sampleKey: 'leaseCost', flow: '车辆成本、居间费分摊至客户' }, ], }, h2: { color: C_PRIMARY, steps: [ { key: 'h2detail', name: '氢费明细·车辆氢费明细', status: 'done', protoPath: 'web端/台账数据/车辆氢费明细.jsx', sampleKey: 'vehicleH2Detail', flow: '待保存 → 保存 → 未对账 → 完成对账 → 已对账' }, { key: 'h2customer', name: '氢费明细·按客户归集', status: 'done', protoPath: 'web端/数据分析/租赁客户氢费台账.jsx', sampleKey: 'leaseCustomerH2Sum', flow: '按加氢时间合并到对应客户;明细 Tab + 总计 Tab' }, { key: 'h2station', name: '加氢站账户·站点汇总', status: 'done', protoPath: 'web端/台账数据/氢费采购端汇总报表.jsx', sampleKey: 'h2PurchaseSummary', flow: '应付/已付/未付/开票/余额;金额可钻取' }, { key: 'h2stationPay', name: '加氢站·已付/充值钻取', status: 'done', protoPath: '氢费采购端汇总报表·钻取弹窗', sampleKey: 'h2PurchasePay', flow: '付款账单、充值明细、余额变更' }, { key: 'h2custAcct', name: '客户预充值·账户扣款', status: 'partial', protoPath: '能源账户(待统一入口)', sampleKey: 'h2Account', flow: '客户氢费扣款、充值导入、变更记录' }, ], }, electric: { color: C_AMBER, steps: [ { key: 'elecImport', name: '电费明细·特来电导入', status: 'partial', protoPath: '待建:电费明细页', sampleKey: 'electric', flow: '平台导出 CSV/Excel 后导入' }, { key: 'elecRevenue', name: '营收·外部车/租赁内部车', status: 'partial', protoPath: '—', sampleKey: 'electricRevenue', flow: '区分非库存外部车与租赁内部车' }, { key: 'elecCost', name: '成本·场地/损耗/手续费/自营内部车', status: 'partial', protoPath: '—', sampleKey: 'electricCost', flow: '成本分拆计入自营或站点' }, ], }, etc: { color: '#0891b2', steps: [ { key: 'etcFetch', name: 'ETC 明细·供应商抓取', status: 'partial', protoPath: '—', sampleKey: 'etc', flow: 'ETC 供应商网站自动扒取' }, { key: 'etcAcct', name: '客户 ETC 预充值账户', status: 'partial', protoPath: '—', sampleKey: 'etcAccount', flow: '预充值、实时扣费流水' }, ], }, ops: { color: C_PRIMARY_L, steps: [ { key: 'opsRepair', name: '维修明细', status: 'done', protoPath: 'web端/台账数据/车辆维修明细.jsx', sampleKey: 'opsRepair', flow: '待保存 → 确认提交(提交后锁定)' }, { key: 'opsMaintain', name: '保养明细', status: 'partial', protoPath: '车辆维修明细·类型=保养', sampleKey: 'opsMaintain', flow: '同维修页,类型区分' }, { key: 'opsAnnual', name: '年审明细', status: 'partial', protoPath: 'web端/运维管理/车辆业务/年审管理.jsx', sampleKey: 'opsAnnual', flow: '年审办理结果回写' }, { key: 'opsTire', name: '轮胎磨损明细', status: 'partial', protoPath: '—', sampleKey: 'opsTire', flow: '待建专用表或并入运维其他' }, { key: 'opsOther', name: '其他运维', status: 'partial', protoPath: '—', sampleKey: 'opsOther', flow: '杂项运维费用' }, ], }, safety: { color: C_ROSE, steps: [ { key: 'safetyClaim', name: '保险赔付', status: 'partial', protoPath: 'web端/安全管理/事故管理.jsx', sampleKey: 'safety', flow: '事故过程、责任、赔付金额' }, ], }, self: { color: C_VIOLET, steps: [ { key: 'selfImport', name: '自营明细导入', status: 'partial', protoPath: '—', sampleKey: 'selfImport', flow: 'Excel 导入自营收支' }, { key: 'selfDriver', name: '司机·工资/社保', status: 'partial', protoPath: '—', sampleKey: 'selfDriver', flow: '人力成本按月' }, { key: 'selfVehicle', name: '车辆·损耗/运维/氢电ETC', status: 'partial', protoPath: '车辆氢费明细+运维台账', sampleKey: 'self', flow: '氢电 ETC 从对应车辆明细取' }, ], }, }; /** 车辆运营明细台账分支(为业务总台账提供明细数据源) */ const ledgerBranches = [ { id: 'h2', label: '车辆运营·氢费', color: C_PRIMARY, tag: '能源', formula: '明细 → 客户归集 → 账户扣款', anchor: '加氢时间 · 车牌 · 客户', listShows: '氢费明细列表、加氢站账户余额、客户预充值账户', detailShows: '手动录入/导入明细;按加氢时间合并至客户;充值与变更记录', writeBack: '导入/录入明细;加氢站账户扣款;客户预充值账户扣款', sampleKey: 'h2', blocks: [ { title: '氢费明细', nodes: [ { label: '车辆氢费明细', note: '手动记录 / 导入;现有车辆氢费明细功能' }, { label: '客户归集', note: '自动按加氢时间合并到对应客户' }, ], }, { title: '加氢站账户', nodes: [ { label: '站点扣款', note: '加氢站产生的氢费从账户直接扣' }, { label: '充值导入', note: '充值记录导入、变更记录' }, ], }, { title: '客户预充值', nodes: [ { label: '客户扣款', note: '客户氢费从客户账户直接扣' }, { label: '充值导入', note: '充值记录导入、变更记录' }, ], }, ], }, { id: 'electric', label: '车辆运营·电费', color: C_AMBER, tag: '能源', formula: '特来电导出 → 导入 → 营收/成本分拆', anchor: '充电记录 · 车牌 · 内外部车辆', listShows: '电费明细、营收(外部车/租赁内部车)、成本(场地/损耗/手续费/自营内部车)', detailShows: '特来电平台导出后导入;区分外部非库存车与内部业务车辆', writeBack: 'Excel/CSV 导入;归集至业务总台账·电费业务', sampleKey: 'electric', blocks: [ { title: '电费明细', nodes: [{ label: '明细导入', note: '特来电平台手动导出后导入' }], }, { title: '营收', nodes: [ { label: '外部车辆', note: '非库存车辆' }, { label: '租赁业务内部车辆', note: '' }, ], }, { title: '成本', nodes: [ { label: '场地租金', note: '' }, { label: '损耗费', note: '' }, { label: '手续费', note: '' }, { label: '自营业务内部车辆', note: '' }, ], }, ], }, { id: 'etc', label: '车辆运营·ETC', color: '#0891b2', tag: '通行', formula: '供应商抓取 + 客户预充值实时扣', anchor: 'ETC 账户 · 客户 · 车牌', listShows: 'ETC 明细、客户 ETC 账户余额、扣费流水', detailShows: '供应商网站自动扒取;客户可预充值;费用实时扣取记录', writeBack: '爬取/同步明细;账户充值;归集至租赁与自营台账', sampleKey: 'etc', blocks: [ { title: 'ETC 明细', nodes: [{ label: '自动抓取', note: 'ETC 供应商网站自动扒取' }], }, { title: '账户', nodes: [ { label: '客户预充值', note: '客户可预充值 ETC 账户' }, { label: '实时扣费', note: '客户 ETC 费用有记录并实时扣取' }, ], }, ], }, { id: 'ops', label: '车辆运营·运维', color: C_PRIMARY_L, tag: '成本来源', formula: '多类明细 → 车辆/自营成本', anchor: '车牌 · 工单号 · 账期', listShows: '维修、保养、年审、轮胎磨损、其他运维明细', detailShows: '按类型分表;关联车辆与费用承担方(租赁/自营)', writeBack: '维修站派单、年审办理、保养记录入库', sampleKey: 'ops', blocks: [ { title: '明细类型', nodes: [ { label: '维修明细', note: '' }, { label: '保养明细', note: '' }, { label: '年审明细', note: '' }, { label: '轮胎磨损明细', note: '' }, { label: '其他', note: '' }, ], }, ], }, { id: 'safety', label: '安全台账', color: C_ROSE, tag: '风控', formula: '事故过程 → 责任 → 赔付', anchor: '事故单号 · 保单', listShows: '保险赔付记录、责任认定、赔付金额状态', detailShows: '事故发生过程、责任划分、保险赔付金额与进度', writeBack: '事故管理结案、保险理赔结果', sampleKey: 'safety', blocks: [ { title: '保险赔付', nodes: [ { label: '事故过程', note: '出现事故时的过程记录' }, { label: '责任', note: '责任认定' }, { label: '赔付金额', note: '保险赔付金额' }, ], }, ], }, ]; const crossLinks = [ { from: '车辆氢费明细', to: '业务总台账·氢费业务', rule: '按车牌/客户汇总业绩与成本', color: C_PRIMARY }, { from: '车辆氢费明细', to: '业务总台账·自营业务成本', rule: '自营明细氢费列勾稽', color: C_PRIMARY }, { from: '车辆电费明细', to: '业务总台账·电费业务', rule: '特来电导入后归集', color: C_AMBER }, { from: '车辆 ETC 明细', to: '业务总台账·ETC业务', rule: '供应商抓取归集', color: '#0891b2' }, { from: '运维各类明细', to: '业务总台账·租赁业务成本', rule: '车辆成本、居间相关分摊', color: C_PRIMARY_L }, { from: '租赁账单', to: '业务总台账·租赁业务业绩', rule: '租金、服务费计入业绩', color: C_BLUE }, { from: '自营明细导入', to: '业务总台账·自营业务', rule: '金额列=业绩;多列费用=成本', color: C_VIOLET }, ]; const principles = [ { id: 'two', title: '双维统计', desc: '「业务总台账」看七类业务按月业绩/成本/利润;「车辆运营明细台账」看单车发生额,向上归集,不重复记账。', icon: '维' }, { id: 'month12', title: '近 12 个月', desc: '业务总台账每类业务按月份展示近 12 个月三列(业绩、成本、利润),并支持年度筛选与合计行。', icon: '月' }, { id: 'profit', title: '统一利润公式', desc: '各类业务利润均为「业绩 − 成本」;租赁业绩来自租金+服务费,自营业绩来自自营明细金额列。', icon: '利' }, { id: 'hub', title: '明细归集不上浮重复', desc: '氢/电/ETC 先在车辆运营明细落账,再汇总进业务总台账对应业务线;账户层只管预充值与扣款轨迹。', icon: '枢' }, ]; const drillPaths = [ { id: 'd0', title: '业务部汇总:业绩 → 业务员 → 项目', scene: '业务台账', steps: ['年份+业务部', '七类业务×近12月', '业绩/成本/利润', '点击业绩', '业务员', '项目明细'], color: C_BLUE, }, { id: 'd1', title: '租赁利润:总览 → 收入项 → 车辆明细', scene: '租赁台账', steps: ['租赁台账汇总', '展开收入(租金/氢/电/ETC)', '点击氢费金额', '车辆氢费明细', '加氢订单/导入行'], color: C_BLUE, }, { id: 'd2', title: '氢费:明细 → 客户 → 账户', scene: '氢费台账', steps: ['氢费明细列表', '按加氢时间归集客户', '客户氢费汇总', '预充值账户余额', '充值/扣款变更记录'], color: C_PRIMARY, }, { id: 'd3', title: '电费:导入 → 营收/成本 → 车辆', scene: '电费台账', steps: ['特来电导出导入', '电费明细表', '筛选内部/外部车辆', '单车电费', '回写租赁收入·电费'], color: C_AMBER, }, { id: 'd4', title: 'ETC:抓取 → 账户 → 实时扣费', scene: 'ETC 台账', steps: ['供应商自动扒取', 'ETC 明细', '客户 ETC 账户', '预充值记录', '通行扣费流水'], color: '#0891b2', }, { id: 'd5', title: '运维:类型 → 工单 → 车辆成本', scene: '运维台账', steps: ['选择明细类型(维修/年审等)', '工单列表', '费用与承担方', '车辆运维成本', '进入租赁/自营成本'], color: C_PRIMARY_L, }, { id: 'd6', title: '安全:事故 → 责任 → 赔付', scene: '安全台账', steps: ['事故列表', '过程与责任认定', '保险赔付申请', '赔付金额确认', '归档至安全台账'], color: C_ROSE, }, { id: 'd7', title: '自营明细 → 业务总台账·自营业务', scene: '自营明细', steps: ['自营明细导入', '金额列汇总业绩', '成本列汇总', '业务总台账按月', '利润=业绩−成本'], color: C_VIOLET, }, ]; const sampleTables = { businessLedger: { title: '业务总台账列表(七类业务 × 近12月)', protoNote: 'Axhub 业务台账 · web端/数据分析/业务台账.jsx · 租赁/自营口径见「业务总台账」章节', columns: [], data: [], interactive: true, }, businessLedgerDrill: { title: '钻取 · 业务员业绩(第2层)', protoNote: '氢费/销售/电/ETC:业务员+业绩金额;自营/租赁:部门宽表含氢电ETC列', columns: [ { title: '业务员', dataIndex: 'salesperson', width: 88 }, { title: '业绩金额', dataIndex: 'amount', width: 96, align: 'right' }, { title: '说明', key: 'hint', render: () => '点击金额 → 项目' }, ], data: BIZ_SALES_BY_CAT.h2, }, lease: { title: '租赁台账 · 客户利润汇总', protoNote: '导图:收入−成本=利润;氢/电/ETC 从车辆明细归集', columns: [ { title: '客户', dataIndex: 'cust', width: 140, ellipsis: true }, { title: '租金', dataIndex: 'rent', width: 88, align: 'right' }, { title: '服务费', dataIndex: 'svc', width: 88, align: 'right' }, { title: '氢费收入', dataIndex: 'h2', width: 88, align: 'right' }, { title: '电费收入', dataIndex: 'elec', width: 88, align: 'right' }, { title: 'ETC收入', dataIndex: 'etc', width: 88, align: 'right' }, { title: '车辆成本', dataIndex: 'vcost', width: 88, align: 'right' }, { title: '居间费', dataIndex: 'broker', width: 80, align: 'right' }, { title: '利润', dataIndex: 'profit', width: 88, align: 'right' }, ], data: [{ key: '1', cust: '上海迅杰物流', rent: '380,000', svc: '40,000', h2: '128,560', elec: '18,200', etc: '6,800', vcost: '260,000', broker: '50,000', profit: '263,560' }], }, leaseRent: { title: '收入 · 租赁业务(租金/服务费)', columns: [ { title: '合同号', dataIndex: 'contract', width: 130, ellipsis: true }, { title: '客户', dataIndex: 'cust', width: 120, ellipsis: true }, { title: '账期', dataIndex: 'period', width: 88 }, { title: '租金(元)', dataIndex: 'rent', width: 96, align: 'right' }, { title: '服务费(元)', dataIndex: 'svc', width: 96, align: 'right' }, { title: '状态', dataIndex: 'st', width: 80 }, ], data: [{ key: '1', contract: 'LNZLHTSH2023071301', cust: '上海迅杰物流', period: '2026-05', rent: '35,000', svc: '5,000', st: '已确认' }], }, leaseCost: { title: '成本 · 车辆成本 / 居间费', columns: [ { title: '成本项', dataIndex: 'item', width: 100 }, { title: '车牌/客户', dataIndex: 'ref', width: 120, ellipsis: true }, { title: '金额(元)', dataIndex: 'amt', width: 96, align: 'right' }, { title: '来源台账', dataIndex: 'src', width: 100 }, ], data: [ { key: '1', item: '车辆成本', ref: '浙F06900F', amt: '12,500', src: '运维台账' }, { key: '2', item: '居间费', ref: '上海迅杰', amt: '8,000', src: '财务录入' }, ], }, vehicleH2Detail: { title: '车辆氢费明细(原型已实现)', protoNote: 'web端/台账数据/车辆氢费明细.jsx · 待保存/未对账/已对账', columns: [ { title: '状态', dataIndex: 'st', width: 72 }, { title: '加氢时间', dataIndex: 'time', width: 140 }, { title: '加氢站', dataIndex: 'station', width: 120, ellipsis: true }, { title: '客户', dataIndex: 'cust', width: 120, ellipsis: true }, { title: '车牌', dataIndex: 'plate', width: 100 }, { title: '加氢量', dataIndex: 'kg', width: 72, align: 'right' }, { title: '加氢单价', dataIndex: 'up', width: 80, align: 'right' }, { title: '加氢总价', dataIndex: 'amt', width: 88, align: 'right' }, { title: '承担方式', dataIndex: 'bear', width: 100 }, { title: '订单号', dataIndex: 'orderNo', width: 110, ellipsis: true }, ], data: [ { key: '1', st: '未对账', time: '2026-05-28 14:20:08', station: '嘉兴港区站', cust: '上海迅杰物流', plate: '浙F06900F', kg: '12.50', up: '70.00', amt: '875.00', bear: '客户承担', orderNo: 'H2260528001' }, { key: '2', st: '已对账', time: '2026-05-20 09:15:00', station: '平湖站', cust: '上海迅杰物流', plate: '浙F06900F', kg: '10.20', up: '68.00', amt: '693.60', bear: '客户承担', orderNo: 'H2260520008' }, ], }, leaseCustomerH2Detail: { title: '租赁客户氢费明细 Tab(原型已实现)', protoNote: 'web端/数据分析/租赁客户氢费台账.jsx', columns: [ { title: '业务员', dataIndex: 'sales', width: 80 }, { title: '客户', dataIndex: 'cust', width: 140, ellipsis: true }, { title: '日期', dataIndex: 'date', width: 96 }, { title: '车牌', dataIndex: 'plate', width: 100 }, { title: '加氢数量', dataIndex: 'kg', width: 80, align: 'right' }, { title: '加氢地点', dataIndex: 'loc', width: 140, ellipsis: true }, { title: '金额', dataIndex: 'amt', width: 88, align: 'right' }, ], data: [{ key: '1', sales: '张明辉', cust: '上海迅杰物流', date: '2026-05-28', plate: '浙F06900F', kg: '12.50', loc: '嘉兴港区加氢站', amt: '875.00' }], }, leaseCustomerH2Sum: { title: '租赁客户氢费总计 Tab(按客户×月)', columns: [ { title: '客户', dataIndex: 'cust', width: 180, ellipsis: true }, { title: '统计月份', dataIndex: 'month', width: 96 }, { title: '加氢数量合计', dataIndex: 'kg', width: 110, align: 'right' }, { title: '金额合计', dataIndex: 'amt', width: 110, align: 'right' }, ], data: [{ key: '1', cust: '上海迅杰物流有限公司', month: '2026-05', kg: '1,286.50', amt: '128,560.00' }], }, h2PurchaseSummary: { title: '氢费(采购端)汇总报表(原型已实现)', protoNote: 'web端/台账数据/氢费采购端汇总报表.jsx · 点击金额钻取', columns: [ { title: '地区', dataIndex: 'region', width: 80 }, { title: '加氢站全称', dataIndex: 'station', width: 160, ellipsis: true }, { title: '结算方式', dataIndex: 'settle', width: 72 }, { title: '加氢总量', dataIndex: 'kg', width: 88, align: 'right' }, { title: '应付总金额', dataIndex: 'payable', width: 100, align: 'right' }, { title: '已付总金额', dataIndex: 'paid', width: 100, align: 'right' }, { title: '未付总金额', dataIndex: 'unpaid', width: 100, align: 'right' }, { title: '当前余额', dataIndex: 'bal', width: 96, align: 'right' }, ], data: [{ key: '1', region: '浙江嘉兴', station: '嘉兴港区加氢站', settle: '月结', kg: '8,520', payable: '596,400', paid: '520,000', unpaid: '76,400', bal: '12,600' }], }, h2PurchasePay: { title: '钻取 · 已付总金额(账单+付款证明)', columns: [ { title: '加氢站', dataIndex: 'station', width: 140, ellipsis: true }, { title: '账单开始', dataIndex: 'start', width: 96 }, { title: '账单结束', dataIndex: 'end', width: 96 }, { title: '应付(元)', dataIndex: 'payable', width: 88, align: 'right' }, { title: '已付(元)', dataIndex: 'paid', width: 88, align: 'right' }, { title: '操作', key: 'op', width: 100, render: () => 付款凭据 }, ], data: [{ key: '1', station: '嘉兴港区加氢站', start: '2026-05-01', end: '2026-05-31', payable: '76,400', paid: '76,400' }], }, h2Account: { title: '氢费账户 · 加氢站 / 客户预充值', columns: [ { title: '账户类型', dataIndex: 'type', width: 100 }, { title: '主体', dataIndex: 'name', ellipsis: true }, { title: '余额(元)', dataIndex: 'bal', width: 100, align: 'right' }, { title: '最近充值', dataIndex: 'topup', width: 100 }, { title: '操作', key: 'op', width: 120, render: () => 充值/变更 }, ], data: [ { key: '1', type: '加氢站账户', name: '嘉兴港区加氢站', bal: '12,600.00', topup: '2026-05-20' }, { key: '2', type: '客户预充值', name: '上海迅杰物流', bal: '80,000.00', topup: '2026-05-15' }, ], }, electric: { title: '电费明细 · 特来电导入(待建页)', columns: [ { title: '充电时间', dataIndex: 'time', width: 140 }, { title: '车牌', dataIndex: 'plate', width: 100 }, { title: '车辆属性', dataIndex: 'attr', width: 120 }, { title: '电量(kWh)', dataIndex: 'kwh', width: 88, align: 'right' }, { title: '金额(元)', dataIndex: 'amt', width: 96, align: 'right' }, { title: '导入批次', dataIndex: 'batch', width: 96 }, ], data: [ { key: '1', time: '2026-05-27 09:10', plate: '浙F06900F', attr: '租赁业务内部车辆', kwh: '86', amt: '172.00', batch: 'TELD-202605' }, { key: '2', time: '2026-05-26 18:00', plate: '外协-苏E88888', attr: '外部车辆(非库存)', kwh: '40', amt: '80.00', batch: 'TELD-202605' }, ], }, electricRevenue: { title: '电费台账 · 营收分拆', columns: [ { title: '口径', dataIndex: 'type', width: 140 }, { title: '电量合计', dataIndex: 'kwh', width: 96, align: 'right' }, { title: '金额(元)', dataIndex: 'amt', width: 96, align: 'right' }, ], data: [ { key: '1', type: '外部车辆(非库存车辆)', kwh: '1,240', amt: '2,480' }, { key: '2', type: '租赁业务内部车辆', kwh: '5,680', amt: '11,360' }, ], }, electricCost: { title: '电费台账 · 成本分拆', columns: [ { title: '成本项', dataIndex: 'item', width: 120 }, { title: '金额(元)', dataIndex: 'amt', width: 96, align: 'right' }, { title: '备注', dataIndex: 'note', ellipsis: true }, ], data: [ { key: '1', item: '场地租金', amt: '18,000', note: '充电场地' }, { key: '2', item: '损耗费', amt: '2,400', note: '' }, { key: '3', item: '手续费', amt: '800', note: '' }, { key: '4', item: '自营业务内部车辆', amt: '4,200', note: '内部用电成本' }, ], }, etc: { title: 'ETC 明细 · 供应商抓取(待建)', columns: [ { title: '通行时间', dataIndex: 'time', width: 140 }, { title: '车牌', dataIndex: 'plate', width: 100 }, { title: '路段', dataIndex: 'road', ellipsis: true }, { title: '金额(元)', dataIndex: 'amt', width: 88, align: 'right' }, { title: '数据来源', dataIndex: 'src', width: 88 }, ], data: [{ key: '1', time: '2026-05-28 08:12', plate: '浙F06900F', road: '沪杭高速·嘉兴段', amt: '68.50', src: '自动扒取' }], }, etcAccount: { title: 'ETC · 客户预充值与扣费流水', columns: [ { title: '客户', dataIndex: 'cust', width: 140, ellipsis: true }, { title: '账户余额', dataIndex: 'bal', width: 96, align: 'right' }, { title: '流水类型', dataIndex: 'type', width: 80 }, { title: '金额(元)', dataIndex: 'amt', width: 88, align: 'right' }, { title: '时间', dataIndex: 'time', width: 140 }, ], data: [ { key: '1', cust: '上海迅杰物流', bal: '5,200', type: '预充值', amt: '+10,000', time: '2026-05-01 10:00' }, { key: '2', cust: '上海迅杰物流', bal: '5,131.5', type: '扣费', amt: '-68.50', time: '2026-05-28 08:12' }, ], }, opsRepair: { title: '运维 · 维修明细(原型已实现)', protoNote: 'web端/台账数据/车辆维修明细.jsx', columns: [ { title: '状态', dataIndex: 'st', width: 72 }, { title: '进修日期', dataIndex: 'date', width: 96 }, { title: '车牌', dataIndex: 'plate', width: 100 }, { title: '类型', dataIndex: 'type', width: 56 }, { title: '项目/材料', dataIndex: 'item', width: 140, ellipsis: true }, { title: '含税合计', dataIndex: 'amt', width: 88, align: 'right' }, ], data: [{ key: '1', st: '已提交', date: '2026-05-18', plate: '浙F06900F', type: '维修', item: '更换燃料电池冷却泵', amt: '3,200.00' }], }, opsMaintain: { title: '运维 · 保养明细', columns: [ { title: '进修日期', dataIndex: 'date', width: 96 }, { title: '车牌', dataIndex: 'plate', width: 100 }, { title: '保养项目', dataIndex: 'item', ellipsis: true }, { title: '金额(元)', dataIndex: 'amt', width: 88, align: 'right' }, ], data: [{ key: '1', date: '2026-05-10', plate: '沪BDB9161', item: '首保-机油三滤', amt: '1,280.00' }], }, opsAnnual: { title: '运维 · 年审明细', columns: [ { title: '年审单号', dataIndex: 'no', width: 120 }, { title: '车牌', dataIndex: 'plate', width: 100 }, { title: '办理状态', dataIndex: 'st', width: 88 }, { title: '费用(元)', dataIndex: 'amt', width: 88, align: 'right' }, { title: '到期日', dataIndex: 'exp', width: 96 }, ], data: [{ key: '1', no: 'NS202605008', plate: '沪BDB9161', st: '已完成', amt: '680.00', exp: '2027-06-04' }], }, opsTire: { title: '运维 · 轮胎磨损明细(待建)', columns: [ { title: '车牌', dataIndex: 'plate', width: 100 }, { title: '轮位', dataIndex: 'pos', width: 72 }, { title: '磨损描述', dataIndex: 'desc', ellipsis: true }, { title: '预估费用', dataIndex: 'amt', width: 88, align: 'right' }, ], data: [{ key: '1', plate: '浙F06900F', pos: '右后', desc: '花纹深度不足', amt: '2,400.00' }], }, opsOther: { title: '运维 · 其他', columns: [ { title: '摘要', dataIndex: 'desc', ellipsis: true }, { title: '车牌', dataIndex: 'plate', width: 100 }, { title: '金额(元)', dataIndex: 'amt', width: 88, align: 'right' }, ], data: [{ key: '1', desc: '拖车救援', plate: '粤AGP9827', amt: '800.00' }], }, safety: { title: '安全 · 保险赔付', columns: [ { title: '事故号', dataIndex: 'acc', width: 120 }, { title: '车牌', dataIndex: 'plate', width: 100 }, { title: '过程摘要', dataIndex: 'proc', width: 160, ellipsis: true }, { title: '责任', dataIndex: 'duty', width: 72 }, { title: '赔付金额', dataIndex: 'pay', width: 96, align: 'right' }, { title: '状态', dataIndex: 'st', width: 80 }, ], data: [{ key: '1', acc: 'SG202604012', plate: '粤AGP9827', proc: '追尾,已报保险', duty: '次责', pay: '45,000.00', st: '理赔中' }], }, selfImport: { title: '自营 · 明细导入', columns: [ { title: '导入批次', dataIndex: 'batch', width: 100 }, { title: '业务日期', dataIndex: 'date', width: 96 }, { title: '科目', dataIndex: 'subj', width: 100 }, { title: '金额(元)', dataIndex: 'amt', width: 96, align: 'right' }, ], data: [{ key: '1', batch: 'ZY-202605', date: '2026-05-31', subj: '运输收入', amt: '120,000.00' }], }, selfDriver: { title: '自营 · 司机工资/社保', columns: [ { title: '司机', dataIndex: 'driver', width: 88 }, { title: '月份', dataIndex: 'month', width: 80 }, { title: '工资(元)', dataIndex: 'wage', width: 96, align: 'right' }, { title: '社保(元)', dataIndex: 'ins', width: 96, align: 'right' }, ], data: [{ key: '1', driver: '王某某', month: '2026-05', wage: '12,000', ins: '3,200' }], }, self: { title: '自营 · 车辆成本汇总(氢/电/ETC 从车辆取)', columns: [ { title: '自营项目', dataIndex: 'proj', width: 120 }, { title: '损耗成本', dataIndex: 'loss', width: 88, align: 'right' }, { title: '运维成本', dataIndex: 'ops', width: 88, align: 'right' }, { title: '氢费', dataIndex: 'h2', width: 80, align: 'right' }, { title: '电费', dataIndex: 'elec', width: 80, align: 'right' }, { title: 'ETC', dataIndex: 'etc', width: 80, align: 'right' }, ], data: [{ key: '1', proj: '嘉兴自营一队', loss: '12,000', ops: '8,500', h2: '28,600', elec: '6,200', etc: '7,500' }], }, h2: { title: '氢费明细(简表)', columns: [ { title: '加氢时间', dataIndex: 'time', width: 140 }, { title: '车牌', dataIndex: 'plate', width: 100 }, { title: '客户', dataIndex: 'cust', ellipsis: true }, { title: '加氢量(kg)', dataIndex: 'kg', width: 88, align: 'right' }, { title: '加氢总价', dataIndex: 'amt', width: 96, align: 'right' }, ], data: [{ key: '1', time: '2026-05-28 14:20', plate: '浙F06900F', cust: '上海迅杰物流', kg: '12.5', amt: '875.00' }], }, h2Account: { title: '氢费账户(简表)', columns: [ { title: '账户类型', dataIndex: 'type', width: 100 }, { title: '主体', dataIndex: 'name', ellipsis: true }, { title: '余额(元)', dataIndex: 'bal', width: 100, align: 'right' }, ], data: [ { key: '1', type: '加氢站账户', name: '嘉兴港区加氢站', bal: '12,600.00' }, { key: '2', type: '客户预充值', name: '上海迅杰物流', bal: '80,000.00' }, ], }, ops: { title: '运维台账 · 分类型一览', columns: [ { title: '类型', dataIndex: 'type', width: 88 }, { title: '单号', dataIndex: 'no', width: 120 }, { title: '车牌', dataIndex: 'plate', width: 100 }, { title: '金额(元)', dataIndex: 'amt', width: 96, align: 'right' }, ], data: [ { key: '1', type: '维修', no: 'WX202605001', plate: '浙F06900F', amt: '3,200.00' }, { key: '2', type: '年审', no: 'NS202605008', plate: '沪BDB9161', amt: '680.00' }, ], }, }; const sampleCatalog = Object.keys(sampleTables).map((key) => { const t = sampleTables[key]; const wfBranch = Object.keys(ledgerWorkflows).find((bid) => (ledgerWorkflows[bid]?.steps || []).some((s) => s.sampleKey === key)); const branchLabel = wfBranch === 'bizTotal' ? '业务总台账' : (ledgerBranches.find((b) => b.id === wfBranch)?.label || '车辆运营明细'); return { key, title: t.title.replace(/(.*?)/g, '').slice(0, 28), branch: branchLabel, protoNote: t.protoNote }; }); const summaryPoints = [ '台账从两个维度统计:业务总台账(七类业务按月业绩/成本/利润)与车辆运营明细台账(单车氢/电/ETC/运维发生额)。', '租赁业务:业绩=租金+服务费,成本=车辆成本+居间费;自营业务:业绩=自营明细金额列,成本=氢费/ETC/薪资/人工报销/日社保/日轮胎/车辆费用。', '业务总台账列表已对照 Axhub「业务台账」与 web 端业务台账.jsx,支持业绩钻取;车辆明细样表覆盖氢费、运维等已实现模块。', '氢/电/ETC 先在车辆运营明细落账,再归集至业务总台账对应业务线,避免与租赁/自营口径重复录入。', ]; const [activeSection, setActiveSection] = useState('hero'); const [activeDomain, setActiveDomain] = useState('h2'); const [activeBizType, setActiveBizType] = useState('lease'); const [activeDrill, setActiveDrill] = useState('d0'); const [navOpen, setNavOpen] = useState(false); const [sampleOpen, setSampleOpen] = useState(false); const [sampleKey, setSampleKey] = useState('lease'); const [drillStep, setDrillStep] = useState(0); const [expandedMind, setExpandedMind] = useState(() => ledgerBranches.map((b) => b.id)); const [workflowBranch, setWorkflowBranch] = useState('bizTotal'); const [workflowStepIdx, setWorkflowStepIdx] = useState(0); const [bizView, setBizView] = useState('main'); const [bizCtx, setBizCtx] = useState({ month: null, monthLabel: '', catKey: '', catLabel: '', perf: null, salesperson: '', amount: null, deptDisplay: '浙江羚牛氢运(业务三部)', year: '2026', }); const workflowSteps = useMemo( () => ledgerWorkflows[workflowBranch]?.steps || [], [workflowBranch] ); const activeWorkflowStep = workflowSteps[workflowStepIdx] || workflowSteps[0]; const activeWorkflowSample = activeWorkflowStep ? (sampleTables[activeWorkflowStep.sampleKey] || sampleTables.vehicleH2Detail) : sampleTables.lease; const selectedDomain = useMemo( () => ledgerBranches.find((d) => d.id === activeDomain) || ledgerBranches[0], [activeDomain] ); const selectedBizType = useMemo( () => bizTotalLedgerTypes.find((t) => t.id === activeBizType) || bizTotalLedgerTypes[0], [activeBizType] ); const selectedDrill = useMemo( () => drillPaths.find((d) => d.id === activeDrill) || drillPaths[0], [activeDrill] ); const currentSample = sampleTables[sampleKey] || sampleTables.lease; const openSample = useCallback((key) => { setSampleKey(key); setSampleOpen(true); }, []); const selectDomain = useCallback((id) => { setActiveDomain(id); setWorkflowBranch(id); setWorkflowStepIdx(0); const el = document.getElementById('el-section-domains'); if (el?.scrollIntoView) el.scrollIntoView({ behavior: 'smooth', block: 'start' }); }, []); const toggleMindBranch = useCallback((id) => { setExpandedMind((prev) => ( prev.includes(id) ? prev.filter((x) => x !== id) : [...prev, id] )); }, []); const scrollToSection = useCallback((key) => { setActiveSection(key); setNavOpen(false); const el = document.getElementById(`el-section-${key}`); if (el?.scrollIntoView) el.scrollIntoView({ behavior: 'smooth', block: 'start' }); }, []); const goWorkflows = useCallback((branchId, stepIdx) => { setWorkflowBranch(branchId || 'bizTotal'); setWorkflowStepIdx(stepIdx == null ? 0 : stepIdx); scrollToSection('workflows'); }, [scrollToSection]); useEffect(() => { const ids = sectionNav.map((s) => s.key); const onScroll = () => { let found = 'hero'; ids.forEach((id) => { const node = document.getElementById(`el-section-${id}`); if (node) { const rect = node.getBoundingClientRect(); if (rect.top <= 120) found = id; } }); setActiveSection(found); }; window.addEventListener('scroll', onScroll, { passive: true }); return () => window.removeEventListener('scroll', onScroll); }, []); useEffect(() => { setDrillStep(0); }, [activeDrill]); useEffect(() => { setWorkflowStepIdx(0); }, [workflowBranch]); useEffect(() => { setBizView('main'); setBizCtx({ month: null, monthLabel: '', catKey: '', catLabel: '', perf: null, salesperson: '', amount: null, deptDisplay: '浙江羚牛氢运(业务三部)', year: '2026', }); }, [workflowStepIdx, workflowBranch]); const openBizPerfDrill = useCallback((row, catKey) => { if (row.rowType === 'total' || row.month === 0) return; const v = row[`${catKey}Perf`]; if (!v) return; const cat = BIZ_LEDGER_CATS.find((c) => c.key === catKey); setBizCtx((p) => ({ ...p, month: row.month, monthLabel: row.monthLabel, catKey, catLabel: cat?.groupTitle || catKey, perf: v, salesperson: '', amount: null, })); setBizView('sales'); }, []); const openBizProjectDrill = useCallback((salesperson, amount) => { setBizCtx((p) => ({ ...p, salesperson, amount })); setBizView('project'); }, []); const renderBizDrillExplain = () => { if (bizView === 'main') { return (
钻取说明 · 汇总层

列表口径:七类业务(租赁、自营、氢费、电费、ETC、销售、其他)各展示近 12 个月业绩、成本、利润;利润 = 业绩 − 成本。

如何钻取:点击「业绩」列蓝色金额(合计行、省略行不可点)。租赁/自营进入业务员宽表;其余业务进入业务员列表,再点金额看项目。

租赁:业绩=租金+服务费,成本=车辆成本+居间费。自营:业绩=自营明细金额列,成本=氢费/ETC/薪资/人工报销/日社保/日轮胎/车辆费用。

原型对照:Axhub · 业务台账

); } if (bizView === 'sales') { const isSelfLease = bizCtx.catKey === 'self' || bizCtx.catKey === 'lease'; return (
钻取说明 · 第 2 层({bizCtx.monthLabel} / {bizCtx.catLabel} / 业绩 {fmtBizMoney(bizCtx.perf)})
{isSelfLease ? (

如何钻取:展示所选业务部下各业务员的主业绩及氢费/电费/ETC/其他列;点击「{bizCtx.catKey === 'lease' ? '租赁' : '自营'}业绩」蓝色金额进入项目明细。

) : (

如何钻取:按业务员拆分该单元格业绩;点击「业绩金额」进入项目明细(项目编号、车牌、业务日期)。

)}

数据来源:{BIZ_LEDGER_SOURCE_MAP[bizCtx.catKey] || '业务单据归集'}

); } return (
钻取说明 · 第 3 层(业务员 {bizCtx.salesperson})

展示内容:该业务员在 {bizCtx.catLabel} 下的项目/合同维度业绩构成(项目编号、名称、车牌、金额、业务日期)。

数据来源:合同/项目主数据 + 对应业务线结算单;氢费/电/ETC 类项目可关联车辆明细行。

); }; const renderBusinessLedgerDrillDemo = () => { const perfLink = (v, row, catKey) => { if (row.rowType === 'total' || !v) return fmtBizMoney(v); return ( ); }; const mainColumns = [ { title: '月份', dataIndex: 'monthLabel', width: 72, fixed: 'left', align: 'center', render: (t, r) => (r.rowType === 'total' ? {t} : t), }, ...BIZ_LEDGER_CATS.map((cat) => ({ title: cat.groupTitle, align: 'center', children: [ { title: '业绩', dataIndex: `${cat.key}Perf`, width: 92, align: 'right', render: (v, row) => perfLink(v, row, cat.key) }, { title: '成本', dataIndex: `${cat.key}Cost`, width: 92, align: 'right', render: fmtBizMoney }, { title: '利润', dataIndex: `${cat.key}Profit`, width: 92, align: 'right', render: fmtBizMoney }, ], })), ]; const salesSimpleColumns = [ { title: '业务员', dataIndex: 'salesperson', width: 100 }, { title: '业绩金额', dataIndex: 'amount', width: 120, align: 'right', render: (v, r) => ( ), }, { title: '说明', key: 'hint', render: () => 点击金额 → 项目明细 }, ]; const isSelfLease = bizCtx.catKey === 'self' || bizCtx.catKey === 'lease'; const mainTitle = bizCtx.catKey === 'lease' ? '租赁业绩' : '自营业绩'; const selfLeaseColumns = [ { title: '月份', dataIndex: 'ym', width: 88, align: 'center', onCell: (r) => ({ rowSpan: r.monthRowSpan }) }, { title: '业务部门', dataIndex: 'deptName', width: 108 }, { title: '业务人员', dataIndex: 'salesperson', width: 88 }, { title: mainTitle, dataIndex: 'mainPerf', width: 112, align: 'right', render: (v, r) => ( v ? ( ) : fmtBizMoney(v) ), }, { title: '氢费业绩', dataIndex: 'h2PerfCol', width: 100, align: 'right', render: fmtBizMoney }, { title: '电费业绩', dataIndex: 'elecPerf', width: 100, align: 'right', render: fmtBizMoney }, { title: 'ETC业绩', dataIndex: 'etcPerfCol', width: 96, align: 'right', render: fmtBizMoney }, { title: '其他', dataIndex: 'otherAmt', width: 88, align: 'right', render: fmtBizMoney }, ]; const projectColumns = [ { title: '项目编号', dataIndex: 'projectCode', width: 120 }, { title: '项目名称', dataIndex: 'projectName', ellipsis: true }, { title: '车牌号', dataIndex: 'plateNo', width: 100 }, { title: '业绩金额', dataIndex: 'amount', width: 108, align: 'right', render: fmtBizMoney }, { title: '业务日期', dataIndex: 'bizDate', width: 100 }, { title: '备注', dataIndex: 'remark', width: 72 }, ]; const salesRows = BIZ_SALES_BY_CAT[bizCtx.catKey] || BIZ_SALES_BY_CAT.h2; return (
{bizView !== 'main' ? ( <> ) : null} {bizView === 'project' ? ( <> {bizCtx.salesperson} · 项目 ) : null}
{bizView !== 'main' ? ( ) : null}
{bizView === 'main' ? `${bizCtx.year}年 业务部汇总台账` : null} {bizView === 'sales' && isSelfLease ? `浙江羚牛氢能业务员${bizCtx.catKey === 'lease' ? '租赁' : '自营'}业务汇总(${bizCtx.year}-${String(bizCtx.month).padStart(2, '0')})` : null} {bizView === 'sales' && !isSelfLease ? `业务员业绩 — ${bizCtx.monthLabel} / ${bizCtx.catLabel}` : null} {bizView === 'project' ? `项目明细 — ${bizCtx.salesperson} / ${bizCtx.catLabel}` : null}
业务部:{bizCtx.deptDisplay} · 年份 {bizCtx.year} · 按月近 12 个月(演示含省略行)
{renderBizDrillExplain()} ); }; const css = ` *,*::before,*::after{box-sizing:border-box} .el-plan{font-family:${FONT};color:${C_TEXT};background:${C_PAGE};min-height:100vh;line-height:1.5;-webkit-font-smoothing:antialiased} .el-nav{position:sticky;top:0;z-index:100;background:rgba(255,255,255,.94);backdrop-filter:saturate(180%) blur(12px);border-bottom:1px solid ${C_LINE}} .el-nav-inner{max-width:1240px;margin:0 auto;padding:0 20px;height:56px;display:flex;align-items:center;gap:12px} .el-brand{display:flex;align-items:center;gap:10px;font-weight:800;font-size:14px;flex-shrink:0} .el-brand-mark{width:34px;height:34px;border-radius:10px;background:linear-gradient(135deg,${C_PRIMARY},${C_PRIMARY_L});color:#fff;display:flex;align-items:center;justify-content:center;font-size:11px;font-weight:800} .el-nav-links{display:flex;gap:4px;flex:1;overflow-x:auto;scrollbar-width:none} .el-nav-link{padding:7px 12px;border-radius:999px;font-size:12px;font-weight:500;color:${C_MUTED};cursor:pointer;border:none;background:transparent;white-space:nowrap} .el-nav-link:hover{color:${C_TEXT};background:rgba(15,118,110,.08)} .el-nav-link.is-active{color:${C_PRIMARY};background:rgba(15,118,110,.12);font-weight:700} .el-nav-toggle{display:none;margin-left:auto;padding:8px 12px;border-radius:8px;border:1px solid ${C_LINE};background:#fff;cursor:pointer;font-size:12px} .el-hero{position:relative;background:${C_HERO};color:#fff;padding:56px 20px 64px;overflow:hidden} .el-hero::before{content:"";position:absolute;inset:0;background:radial-gradient(ellipse 70% 50% at 80% 10%,rgba(20,184,166,.22),transparent 55%);pointer-events:none} .el-hero-inner{position:relative;max-width:1240px;margin:0 auto} .el-hero-tag{display:inline-block;padding:4px 10px;border-radius:999px;font-size:11px;font-weight:700;background:rgba(20,184,166,.15);border:1px solid rgba(45,212,191,.35);color:#5eead4;margin-bottom:14px} .el-hero-title{font-size:clamp(26px,4.5vw,40px);font-weight:800;line-height:1.2;margin:0 0 12px;max-width:820px} .el-hero-desc{font-size:clamp(14px,2.2vw,16px);color:rgba(255,255,255,.75);max-width:760px;margin:0 0 20px;line-height:1.65} .el-hero-actions{display:flex;flex-wrap:wrap;gap:10px} .el-btn{padding:10px 18px;border-radius:10px;font-size:13px;font-weight:700;cursor:pointer;border:none} .el-btn-primary{background:linear-gradient(135deg,${C_PRIMARY_L},${C_PRIMARY});color:#fff;box-shadow:0 4px 20px rgba(20,184,166,.35)} .el-btn-ghost{background:rgba(255,255,255,.08);color:#fff;border:1px solid rgba(255,255,255,.2)} .el-kpi-row{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:14px;margin-top:-32px;position:relative;z-index:2;padding:0 20px;max-width:1240px;margin-left:auto;margin-right:auto} .el-kpi{background:${C_CARD};border-radius:14px;padding:18px 16px;border:1px solid ${C_LINE};box-shadow:0 8px 30px rgba(15,23,42,.06)} .el-kpi-val{font-size:26px;font-weight:800} .el-kpi-unit{font-size:13px;font-weight:600;opacity:.7;margin-left:2px} .el-kpi-label{font-size:12px;color:${C_MUTED};margin-top:6px} .el-main{max-width:1240px;margin:0 auto;padding:40px 20px 72px} .el-section{margin-bottom:52px;scroll-margin-top:72px} .el-section-head{margin-bottom:22px} .el-section-tag{font-size:11px;font-weight:800;letter-spacing:.08em;color:${C_PRIMARY};margin-bottom:6px} .el-section-title{font-size:clamp(20px,3vw,26px);font-weight:800;margin:0 0 8px} .el-section-desc{font-size:14px;color:${C_MUTED};margin:0;max-width:720px;line-height:1.6} .el-root-hub{text-align:center;margin-bottom:24px} .el-root-pill{display:inline-flex;padding:14px 28px;border-radius:16px;background:linear-gradient(135deg,${C_HERO},${C_HERO_ACCENT});color:#fff;font-size:18px;font-weight:800;box-shadow:0 12px 40px rgba(15,23,42,.2)} .el-mind-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(280px,1fr));gap:14px} .el-mind-card{background:#fff;border:1px solid ${C_LINE};border-radius:14px;overflow:hidden;transition:box-shadow .2s} .el-mind-card.is-active{box-shadow:0 12px 32px rgba(15,23,42,.1)} .el-mind-card-head{width:100%;text-align:left;padding:14px 16px;border:none;background:#fff;cursor:pointer;display:flex;align-items:center;justify-content:space-between;gap:8px} .el-mind-card-head h4{margin:0;font-size:15px;font-weight:800} .el-mind-card-body{padding:0 16px 14px;border-top:1px dashed ${C_LINE}} .el-mind-block{margin-top:12px} .el-mind-block-title{font-size:11px;font-weight:800;color:${C_MUTED};text-transform:uppercase;letter-spacing:.05em;margin-bottom:8px} .el-mind-node{display:flex;flex-wrap:wrap;align-items:baseline;gap:6px;padding:8px 10px;border-radius:8px;background:#f8fafc;margin-bottom:6px;font-size:13px} .el-mind-node-label{font-weight:600} .el-mind-node-note{font-size:12px;color:${C_MUTED}} .el-mind-link{font-size:11px;font-weight:700;color:${C_PRIMARY};cursor:pointer;border:none;background:transparent;padding:0} .el-principle-grid{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:14px} .el-principle-card{background:#fff;border:1px solid ${C_LINE};border-radius:14px;padding:18px} .el-principle-icon{width:40px;height:40px;border-radius:12px;background:rgba(15,118,110,.1);color:${C_PRIMARY};display:flex;align-items:center;justify-content:center;font-weight:800;margin-bottom:12px} .el-principle-card h4{margin:0 0 8px;font-size:15px;font-weight:800} .el-principle-card p{margin:0;font-size:13px;color:${C_MUTED};line-height:1.55} .el-domain-layout{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1.05fr);gap:18px} .el-domain-tabs{display:flex;flex-direction:column;gap:8px} .el-domain-tab{width:100%;text-align:left;padding:12px 14px;border-radius:12px;border:1px solid ${C_LINE};background:#fff;cursor:pointer} .el-domain-tab.is-active{box-shadow:0 8px 22px rgba(15,23,42,.1);transform:translateX(4px)} .el-domain-tab-name{font-size:14px;font-weight:700} .el-domain-tab-formula{font-size:11px;color:${C_MUTED};margin-top:4px} .el-domain-detail{background:#fff;border:1px solid ${C_LINE};border-radius:16px;padding:22px;position:sticky;top:76px} .el-domain-meta{display:grid;grid-template-columns:1fr 1fr;gap:12px;margin:16px 0} .el-domain-meta dt{font-size:11px;font-weight:700;color:${C_MUTED};margin-bottom:4px} .el-domain-meta dd{margin:0;font-size:13px;line-height:1.5} .el-link-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:12px} .el-link-card{background:#fff;border:1px solid ${C_LINE};border-radius:12px;padding:14px 16px;border-left:4px solid ${C_PRIMARY}} .el-link-arrow{font-size:12px;color:${C_MUTED};margin:6px 0} .el-link-rule{font-size:13px;font-weight:600;color:${C_TEXT}} .el-drill-layout{display:grid;grid-template-columns:minmax(0,.95fr) minmax(0,1.05fr);gap:18px} .el-drill-item{padding:14px 16px;border-radius:12px;border:1px solid ${C_LINE};background:#fff;cursor:pointer;margin-bottom:8px} .el-drill-item.is-active{box-shadow:0 8px 24px rgba(15,23,42,.08)} .el-drill-panel{background:#fff;border:1px solid ${C_LINE};border-radius:16px;padding:22px} .el-drill-step{padding:8px 14px;border-radius:999px;font-size:12px;font-weight:600;border:1px solid ${C_LINE};background:#f8fafc;color:${C_MUTED};cursor:pointer;margin:0 6px 8px 0;display:inline-block} .el-drill-step.is-active{color:#fff;border-color:transparent} .el-sample-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:14px} .el-sample-card{background:#fff;border:1px solid ${C_LINE};border-radius:14px;padding:16px;cursor:pointer} .el-sample-card:hover{border-color:rgba(15,118,110,.35);box-shadow:0 8px 22px rgba(15,23,42,.06)} .el-workflow-layout{display:grid;grid-template-columns:minmax(0,280px) minmax(0,1fr);gap:18px;align-items:start} .el-workflow-steps{display:flex;flex-direction:column;gap:8px;max-height:520px;overflow-y:auto;padding-right:4px} .el-workflow-step{width:100%;text-align:left;padding:12px 14px;border-radius:12px;border:1px solid ${C_LINE};background:#fff;cursor:pointer} .el-workflow-step.is-active{box-shadow:0 8px 22px rgba(15,23,42,.1)} .el-workflow-step-name{font-size:13px;font-weight:700;margin-bottom:4px} .el-workflow-step-flow{font-size:11px;color:${C_MUTED};line-height:1.45} .el-workflow-step-path{font-size:10px;color:${C_PRIMARY};margin-top:6px;word-break:break-all} .el-workflow-preview{background:#fff;border:1px solid ${C_LINE};border-radius:16px;padding:18px;overflow:hidden} .el-workflow-preview-head{display:flex;flex-wrap:wrap;align-items:flex-start;justify-content:space-between;gap:10px;margin-bottom:12px} .el-workflow-preview-title{margin:0;font-size:16px;font-weight:800} .el-proto-banner{padding:10px 14px;border-radius:10px;background:#eff6ff;border:1px solid #bfdbfe;font-size:12px;color:#1e40af;margin-bottom:12px;line-height:1.5} .el-dim-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(280px,1fr));gap:16px} .el-dim-card{background:${C_CARD};border-radius:14px;padding:20px;border:1px solid ${C_LINE};box-shadow:0 1px 3px rgba(15,23,42,.06)} .el-dim-list{margin:0;padding-left:18px;font-size:13px;line-height:1.7;color:${C_TEXT}} .el-biz-type-layout{display:grid;grid-template-columns:minmax(140px,200px) 1fr;gap:16px} @media(max-width:768px){.el-biz-type-layout{grid-template-columns:1fr}} .el-biz-type-tabs{display:flex;flex-direction:column;gap:6px} .el-biz-type-tab{text-align:left;padding:10px 12px;border-radius:10px;border:1px solid ${C_LINE};background:#fff;cursor:pointer;font-size:13px;font-weight:600;color:${C_MUTED}} .el-biz-type-tab.is-active{background:rgba(15,118,110,.08);color:${C_TEXT};font-weight:800} .el-biz-type-detail{background:${C_CARD};border-radius:14px;padding:20px;border:1px solid ${C_LINE}} .el-biz-drill-shell{border:1px solid ${C_LINE};border-radius:12px;overflow:hidden;background:#fff} .el-biz-drill-toolbar{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:10px 14px;background:#f8fafc;border-bottom:1px solid ${C_LINE};flex-wrap:wrap} .el-biz-drill-breadcrumb{display:flex;align-items:center;flex-wrap:wrap;gap:4px;font-size:13px} .el-biz-crumb{border:none;background:transparent;color:${C_MUTED};cursor:pointer;padding:4px 8px;border-radius:6px;font-size:13px;font-weight:600} .el-biz-crumb:hover{color:${C_BLUE};background:rgba(37,99,235,.08)} .el-biz-crumb.is-active{color:${C_BLUE};background:rgba(37,99,235,.12)} .el-biz-crumb-sep{color:#cbd5e1;font-size:12px} .el-biz-table-title{text-align:center;font-size:16px;font-weight:800;padding:14px 12px 4px;color:${C_TEXT}} .el-biz-filter-hint{text-align:center;font-size:12px;color:${C_MUTED};margin-bottom:10px} .el-biz-ledger-table .ant-table-thead>tr>th{background:#f8fafc!important;font-size:12px} .el-biz-perf-link{border:none;background:transparent;padding:0;color:${C_BLUE};font-weight:700;cursor:pointer;text-decoration:underline;text-underline-offset:2px;font-variant-numeric:tabular-nums} .el-biz-perf-link:hover{color:#1d4ed8} .el-biz-drill-explain{margin:0;padding:14px 16px;background:linear-gradient(180deg,#f0fdf4 0%,#f8fafc 100%);border-top:1px solid ${C_LINE};font-size:13px;line-height:1.65;color:#334155} .el-biz-drill-explain-title{font-size:12px;font-weight:800;color:${C_PRIMARY};letter-spacing:.04em;margin-bottom:8px;text-transform:uppercase} .el-biz-drill-explain p{margin:0 0 8px} .el-biz-drill-explain p:last-child{margin-bottom:0} .el-biz-drill-explain a{color:${C_PRIMARY};font-weight:600} .el-summary{background:linear-gradient(135deg,${C_HERO},${C_HERO_ACCENT});border-radius:18px;padding:28px;color:#fff} .el-summary ul{margin:0;padding:0;list-style:none;display:flex;flex-direction:column;gap:12px} .el-summary li{font-size:14px;line-height:1.6;color:rgba(255,255,255,.9);display:flex;gap:10px} .el-summary li::before{content:"✓";color:#5eead4;font-weight:800} .el-footer{text-align:center;padding:24px;font-size:12px;color:${C_MUTED}} @media(max-width:1024px){ .el-principle-grid,.el-kpi-row,.el-link-grid{grid-template-columns:repeat(2,minmax(0,1fr))} .el-domain-layout,.el-drill-layout,.el-workflow-layout{grid-template-columns:1fr} .el-domain-detail{position:static} .el-workflow-steps{max-height:none} } @media(max-width:640px){ .el-nav-toggle{display:block} .el-nav-links{display:none;position:absolute;top:56px;left:0;right:0;background:#fff;flex-direction:column;padding:12px 16px;border-bottom:1px solid ${C_LINE}} .el-nav-links.is-open{display:flex} .el-principle-grid,.el-kpi-row,.el-sample-grid,.el-mind-grid,.el-link-grid{grid-template-columns:1fr} .el-domain-meta{grid-template-columns:1fr} } `; return (
总账 企业台账 · 双维汇报
业务总台账 + 车辆运营明细 · 双维统计

ONE-OS 企业业务总台账

台账从两个维度统计:业务总台账 展示七类业务按月业绩/成本/利润; 车辆运营明细台账 记录单车氢/电/ETC/运维发生额并向上归集。已对照 {' '} Axhub 业务台账 {' '} 与 web 端已实现模块,支持业绩钻取演示。

{kpiStats.map((k) => (
{k.value} {k.unit}
{k.label}
))}
TWO DIMENSIONS

台账统计的两个维度

老板看「业务总台账」掌握各业务线经营结果;财务/运营看「车辆运营明细」掌握单车发生额,二者通过归集规则勾稽。

{ledgerDimensions.map((dim) => (

{dim.label}

{dim.role}

{dim.summary}

    {dim.listItems.map((item) => (
  • {item}
  • ))}
{dim.id === 'bizTotal' ? ( ) : ( )}
))}
BUSINESS LEDGER

业务总台账 · 七类业务口径

列表按月份展示近 12 个月业绩、成本、利润。下列为各类业务的取数规则(租赁、自营已按最新口径固化)。

{bizTotalLedgerTypes.map((t) => ( ))}

{selectedBizType.label}

{selectedBizType.period}

业绩来源
{selectedBizType.perf}
成本来源
{selectedBizType.cost}
利润计算
{selectedBizType.profit}
钻取
{selectedBizType.drill}
数据回写
{selectedBizType.writeBack}
{selectedBizType.id === 'lease' ? ( ) : null} {selectedBizType.id === 'self' ? ( ) : null} {['h2', 'apply', 'etc'].includes(selectedBizType.id) ? ( ) : null}
VEHICLE OPS

车辆运营明细台账

氢费、电费、ETC、运维等按车牌/客户记录发生明细,归集后写入业务总台账对应业务线,避免重复录入。

车辆运营明细台账
{ledgerBranches.map((branch) => { const open = expandedMind.includes(branch.id); return (
{open ? (
{branch.blocks.map((block) => (
{block.title}
{block.nodes.map((node) => (
{node.label} {node.note ? {node.note} : null} {node.linkId ? ( ) : null}
))}
))}
) : null}
); })}
PRINCIPLES

搭建原则(提炼自导图)

{principles.map((p) => (
{p.icon}

{p.title}

{p.desc}

))}
LEDGERS

车辆明细域:显示内容与回写

{ledgerBranches.map((d) => ( ))}

{selectedDomain.label}

{selectedDomain.tag}

{selectedDomain.formula}

建档锚点
{selectedDomain.anchor}
列表展示
{selectedDomain.listShows}
详情结构
{selectedDomain.detailShows}
数据回写
{selectedDomain.writeBack}
本域业务环节(对照原型)
{(ledgerWorkflows[selectedDomain.id]?.steps || []).map((step, idx) => (
{step.name} {renderProtoStatus(step.status)}
{step.flow}
{step.protoPath}
))}
WORKFLOW SAMPLES

各环节台账样表(内嵌预览)

先选统计维度:业务总台账(七类业务汇总)或车辆运营明细(单车发生额)。绿色 Tag 为已实现模块。

{ledgerBranches.map((b) => ( ))}
{workflowSteps.map((step, idx) => ( ))}

{activeWorkflowSample.title}

{activeWorkflowSample.protoNote ? (
{activeWorkflowSample.protoNote} {activeWorkflowStep?.sampleKey === 'businessLedger' ? ( {' '} · {' '} 打开 Axhub 业务台账原型 ) : null}
) : activeWorkflowStep?.protoPath ? (
原型路径:{activeWorkflowStep.protoPath}
) : null} {activeWorkflowStep?.sampleKey === 'businessLedger' ? ( renderBusinessLedgerDrillDemo() ) : (
)}
DRILL-DOWN

钻取路径(业务总账 / 车辆明细)

点击步骤序号高亮当前层级,演示「点哪里、看到什么」。

{drillPaths.map((path) => (
setActiveDrill(path.id)} onKeyDown={(e) => { if (e.key === 'Enter') setActiveDrill(path.id); }} >

{path.title}

{path.scene}

))}

{selectedDrill.title}

{selectedDrill.steps.map((step, idx) => ( setDrillStep(idx)} onKeyDown={(e) => { if (e.key === 'Enter') setDrillStep(idx); }} > {idx + 1}. {step} ))}

当前层级:{selectedDrill.steps[drillStep]}

SAMPLES

样表索引(24+)

快速跳转任意样表;与「环节样表」区数据一致。

{sampleCatalog.map((item) => (
openSample(item.key)} onKeyDown={(e) => { if (e.key === 'Enter') openSample(item.key); }} > {item.branch}

{item.title}

{item.protoNote ?

{item.protoNote}

: null}

点击查看 →

))}

向老板汇报的要点

    {summaryPoints.map((pt) => (
  • {pt}
  • ))}
setSampleOpen(false)} footer={} width={Math.min(1100, typeof window !== 'undefined' ? window.innerWidth - 32 : 1100)} centered destroyOnClose > {currentSample.protoNote ? (

{currentSample.protoNote} {sampleKey === 'businessLedger' ? ( {' '} · {' '} Axhub 业务台账 ) : null}

) : null} {sampleKey === 'businessLedger' ? ( renderBusinessLedgerDrillDemo() ) : ( <>

列表层样表;汇总数字需可点击钻取至下行明细(车辆/客户/账户)。字段与 Axhub 原型保持一致处已标注路径。

)} ); }; export default Component;