From 62efef0ab900327d7ec1223205412d0268fb3fb0 Mon Sep 17 00:00:00 2001 From: kkfluous Date: Thu, 20 Aug 2026 13:59:03 +0800 Subject: [PATCH] feat(energy): rebuild hydrogen BI board and drill-through --- design-qa.md | 47 + docker-compose.yml | 5 - src/app/modules.ts | 8 +- src/components/Shell.tsx | 38 +- src/modules/energy/ETCView.tsx | 113 +- src/modules/energy/ElectricDaily.tsx | 32 +- src/modules/energy/ElectricModule.tsx | 8 +- src/modules/energy/ElectricOverview.tsx | 28 +- src/modules/energy/EtcModule.tsx | 4 +- src/modules/energy/HydrogenBoardChrome.tsx | 97 + src/modules/energy/HydrogenDaily.tsx | 494 +- src/modules/energy/HydrogenModule.tsx | 36 +- src/modules/energy/HydrogenOverview.tsx | 314 +- src/modules/energy/HydrogenSettlement.tsx | 186 + src/modules/energy/HydrogenStationBoard.tsx | 544 ++ src/modules/energy/HydrogenView.tsx | 28 +- src/modules/energy/api.test.ts | 14 + src/modules/energy/api.ts | 149 +- .../components/SortableColumnHeader.tsx | 67 + .../energy/daily-range/DailyRangeControls.tsx | 208 +- .../energy/hydrogen-bi-v2/HydrogenBiV2App.tsx | 1649 ++++ .../energy/hydrogen-bi-v2/PrototypeBoard.tsx | 8075 +++++++++++++++++ src/modules/energy/hydrogen-bi-v2/api.ts | 46 + .../hydrogen-bi-v2/prototype-adapter.ts | 70 + .../hydrogen-bi-v2/prototype-download.ts | 12 + .../hydrogen-bi-v2/prototype-real-daily.tsx | 692 ++ .../hydrogen-bi-v2/prototype-real-drills.tsx | 869 ++ .../prototype-source/EnergyBiAccessGate.tsx | 73 + .../prototype-source/EnergyBiBoardApp.tsx | 5278 +++++++++++ .../prototype-source/annotation-source.json | 33 + .../prototype-source/data/aggregates.ts | 283 + .../prototype-source/data/mockBoard.ts | 182 + .../prototype-source/data/mockDaily.ts | 1044 +++ .../hydrogen-bi-v2/prototype-source/index.tsx | 50 + .../prototype-source/manifest.json | 44 + .../styles/energy-bi-board.css | 5018 ++++++++++ .../hydrogen-bi-v2/prototype-source/types.ts | 64 + .../prototype-station-daily.css | 905 ++ src/modules/energy/hydrogen-bi-v2/types.ts | 268 + .../components/DailyDetailTable.tsx | 375 + .../components/DailyKpiGrid.tsx | 123 + .../components/DailyTrendChart.tsx | 167 + .../components/StationDailyOverview.tsx | 39 + .../energy/hydrogen-daily/model.test.ts | 82 +- src/modules/energy/hydrogen-daily/model.ts | 173 +- .../components/DistributionCharts.tsx | 152 +- .../components/InsightCards.tsx | 180 +- .../components/KpiSection.tsx | 152 +- .../components/MonthlyCharts.tsx | 80 +- .../components/OverviewDrillDialog.tsx | 165 + .../components/OverviewDrillTreeDialog.tsx | 378 + .../components/OverviewHeader.tsx | 187 +- .../components/SummaryTables.tsx | 225 +- .../energy/hydrogen-overview/model.test.ts | 84 +- src/modules/energy/hydrogen-overview/model.ts | 225 +- src/modules/energy/styles/energy-bi-board.css | 4767 ++++++++++ src/modules/energy/types.ts | 189 +- src/server/hydrogen-db.ts | 12 +- src/server/routes/energy/electric.ts | 4 +- src/server/routes/energy/etc.ts | 45 + src/server/routes/energy/hydrogen-bi-v2.ts | 903 ++ .../routes/energy/hydrogen-daily-detail.ts | 153 + src/server/routes/energy/hydrogen-daily.ts | 31 +- .../routes/energy/hydrogen-overview-detail.ts | 271 + src/server/routes/energy/hydrogen-overview.ts | 159 +- .../routes/energy/hydrogen-settlement.ts | 119 + .../routes/energy/hydrogen-station-board.ts | 263 + src/server/routes/energy/index.ts | 12 + src/server/routes/energy/query-model.test.ts | 6 +- src/server/routes/energy/query-model.ts | 7 +- src/server/routes/energy/routes.test.ts | 932 +- tsconfig.json | 3 +- 72 files changed, 36773 insertions(+), 965 deletions(-) create mode 100644 design-qa.md create mode 100644 src/modules/energy/HydrogenBoardChrome.tsx create mode 100644 src/modules/energy/HydrogenSettlement.tsx create mode 100644 src/modules/energy/HydrogenStationBoard.tsx create mode 100644 src/modules/energy/api.test.ts create mode 100644 src/modules/energy/components/SortableColumnHeader.tsx create mode 100644 src/modules/energy/hydrogen-bi-v2/HydrogenBiV2App.tsx create mode 100644 src/modules/energy/hydrogen-bi-v2/PrototypeBoard.tsx create mode 100644 src/modules/energy/hydrogen-bi-v2/api.ts create mode 100644 src/modules/energy/hydrogen-bi-v2/prototype-adapter.ts create mode 100644 src/modules/energy/hydrogen-bi-v2/prototype-download.ts create mode 100644 src/modules/energy/hydrogen-bi-v2/prototype-real-daily.tsx create mode 100644 src/modules/energy/hydrogen-bi-v2/prototype-real-drills.tsx create mode 100644 src/modules/energy/hydrogen-bi-v2/prototype-source/EnergyBiAccessGate.tsx create mode 100644 src/modules/energy/hydrogen-bi-v2/prototype-source/EnergyBiBoardApp.tsx create mode 100644 src/modules/energy/hydrogen-bi-v2/prototype-source/annotation-source.json create mode 100644 src/modules/energy/hydrogen-bi-v2/prototype-source/data/aggregates.ts create mode 100644 src/modules/energy/hydrogen-bi-v2/prototype-source/data/mockBoard.ts create mode 100644 src/modules/energy/hydrogen-bi-v2/prototype-source/data/mockDaily.ts create mode 100644 src/modules/energy/hydrogen-bi-v2/prototype-source/index.tsx create mode 100644 src/modules/energy/hydrogen-bi-v2/prototype-source/manifest.json create mode 100644 src/modules/energy/hydrogen-bi-v2/prototype-source/styles/energy-bi-board.css create mode 100644 src/modules/energy/hydrogen-bi-v2/prototype-source/types.ts create mode 100644 src/modules/energy/hydrogen-bi-v2/prototype-station-daily.css create mode 100644 src/modules/energy/hydrogen-bi-v2/types.ts create mode 100644 src/modules/energy/hydrogen-daily/components/DailyDetailTable.tsx create mode 100644 src/modules/energy/hydrogen-daily/components/DailyKpiGrid.tsx create mode 100644 src/modules/energy/hydrogen-daily/components/DailyTrendChart.tsx create mode 100644 src/modules/energy/hydrogen-daily/components/StationDailyOverview.tsx create mode 100644 src/modules/energy/hydrogen-overview/components/OverviewDrillDialog.tsx create mode 100644 src/modules/energy/hydrogen-overview/components/OverviewDrillTreeDialog.tsx create mode 100644 src/modules/energy/styles/energy-bi-board.css create mode 100644 src/server/routes/energy/etc.ts create mode 100644 src/server/routes/energy/hydrogen-bi-v2.ts create mode 100644 src/server/routes/energy/hydrogen-daily-detail.ts create mode 100644 src/server/routes/energy/hydrogen-overview-detail.ts create mode 100644 src/server/routes/energy/hydrogen-settlement.ts create mode 100644 src/server/routes/energy/hydrogen-station-board.ts diff --git a/design-qa.md b/design-qa.md new file mode 100644 index 0000000..dbbf2bb --- /dev/null +++ b/design-qa.md @@ -0,0 +1,47 @@ +# Energy Hydrogen Board Design QA + +- Source of truth: `/tmp/energy-h2-bi-board-prototype-0818/index.html` +- Prototype archive: `/Users/kkfluous/Library/Containers/com.tencent.xinWeChat/Data/Documents/xwechat_files/wxid_1704407055112_3af8/msg/file/2026-08/energy-h2-bi-board-html.zip` +- Implementation: `http://localhost:3000/energy#hydrogen/overview` +- Desktop viewport: 1280 x 720 CSS px +- Mobile viewport checked for the daily flow: 390 x 844 CSS px + +## Compared States + +| State | Prototype | Implementation | Combined comparison | +| --- | --- | --- | --- | +| Global overview | `/var/tmp/proto-global-overview.png` | `/var/tmp/impl-global-overview-final.png` | `/var/tmp/compare-global-overview-final.png` | +| Global daily | `/var/tmp/proto-global-daily.png` | `/var/tmp/impl-global-daily-final.png` | `/var/tmp/compare-global-daily-final.png` | +| All stations | `/var/tmp/proto-station.png` | `/var/tmp/impl-station-final.png` | `/var/tmp/compare-station-final.png` | +| Station detail | `/var/tmp/proto-station-detail.png` | `/var/tmp/impl-station-detail-final.png` | `/var/tmp/compare-station-detail-final.png` | + +All desktop comparisons use the same viewport, pixel dimensions, navigation state, and side-by-side source/implementation input. + +## Interaction Evidence + +- Global overview KPI, month, region, station, customer, and insight entries open real ledger drill-down data. +- Global daily supports date presets, custom dates, all/Lingniu/external vehicle scopes, chart-to-date focus, and date -> station -> customer -> vehicle/source drill-down. +- Daily and station evidence tables provide Excel export where the prototype exposes an export command. +- All-station mode supports all/single station display, station selection, clickable daily KPI dialogs, and zero-activity stations. +- Station detail includes a continuous 10-day series with zero-filled late days, recent 7-day table, range trend, and 12-month customer quantity/fee matrices. +- Entering and leaving a station detail resets the page scroll position so the header and notice remain visible. +- A clean browser tab loaded the final overview with no console warnings or errors. +- Daily mobile flow has no body-level horizontal overflow; wide analytical tables retain intentional internal horizontal scrolling. + +## Iteration History + +1. P1: Station detail inherited the long station-list scroll position. Added deterministic scroll reset on enter and return. +2. P1: Daily drill stopped at station level. Implemented the prototype's full four-level drill and real ledger rows. +3. P1: Station KPI cards were static. Added the three prototype daily detail dialogs using continuous server-side daily summaries. +4. P2: Prototype state matrix was incomplete. Added global overview, global daily, all-station, single-station selector, and station detail states. +5. P2: Icons differed from the prototype. Replaced approximate icons with matching Lucide Fuel, Zap, Wallet, Calendar, Truck, Refresh, Download, and navigation icons. +6. P2: Recharts could measure a transitioning container at a negative size. Added minimum and initial dimensions and verified a clean reload. +7. P2: Station detail omitted dates without records. Zero-filled the requested range so delayed or absent reporting is visible rather than silently skipped. + +## Residual P3 + +- Prototype screenshots contain fixed mock dates and values; implementation screenshots use the current read-only database values. +- The prototype warning says opening balances are still calibrating. The implementation uses a truthful traceability notice because the live ledger does not expose that calibration state. +- Native date-picker popovers vary by operating system; the closed controls match the prototype hierarchy and icon roles. + +final result: passed diff --git a/docker-compose.yml b/docker-compose.yml index 6f235dc..b080be3 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -10,11 +10,6 @@ services: DB_USER: "oneos_db_prod" DB_PASSWORD: "adASHJcviqwjkbn23ngt1" DB_NAME: "ln_asset_management" - HYDROGEN_DB_HOST: "47.99.185.173" - HYDROGEN_DB_PORT: "3306" - HYDROGEN_DB_USER: "root" - HYDROGEN_DB_PASSWORD: "lnMysql." - HYDROGEN_DB_NAME: "ln_asset_management" MILEAGE_DB_HOST: "101.133.130.65" MILEAGE_DB_PORT: "3306" MILEAGE_DB_USER: "bi_reader_02" diff --git a/src/app/modules.ts b/src/app/modules.ts index 143c9d3..f5031e4 100644 --- a/src/app/modules.ts +++ b/src/app/modules.ts @@ -1,12 +1,12 @@ import { lazy } from 'react'; import { Activity, - BatteryCharging, Fuel, MapPinned, - Receipt, Route, Truck, + Wallet, + Zap, } from 'lucide-react'; import type { ModuleConfig } from '../components/Shell'; import { canAccessEnergy, canAccessScheduling } from '../shared/auth/roles'; @@ -49,8 +49,8 @@ const SCHEDULING_MODULE: ModuleConfig = { const ENERGY_MODULES: ModuleConfig[] = [ { id: 'hydrogen', label: '氢能', icon: Fuel, component: HydrogenModule }, - { id: 'electric', label: '电能', icon: BatteryCharging, component: ElectricModule }, - { id: 'etc', label: 'ETC', icon: Receipt, component: EtcModule }, + { id: 'electric', label: '电能', icon: Zap, component: ElectricModule }, + { id: 'etc', label: 'ETC', icon: Wallet, component: EtcModule }, ]; /** 根据主路径和角色生成导航;返回新数组,避免调用方修改静态注册表。 */ diff --git a/src/components/Shell.tsx b/src/components/Shell.tsx index fde3a0c..1fa6cc7 100644 --- a/src/components/Shell.tsx +++ b/src/components/Shell.tsx @@ -83,6 +83,9 @@ export function Shell({ modules }: { modules: ModuleConfig[] }) { const { user } = useAuth(); const activeLabel = flatModules.find((module) => module.id === activeModule)?.label ?? '业务看板'; + // 氢能经营看板已在模块内提供原型一致的标题与导航,避免桌面端重复显示全局面包屑。 + const showDesktopBreadcrumb = activeModule !== 'hydrogen'; + const isHydrogenPrototype = activeModule === 'hydrogen'; const watermarkText = useMemo(() => { const name = user?.userName || '未登录'; const time = new Date().toLocaleString('zh-CN', { year: 'numeric', month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit', second: '2-digit', hour12: false }).replace(/\//g, '-'); @@ -92,14 +95,16 @@ export function Shell({ modules }: { modules: ModuleConfig[] }) { return (
- {/* 全局水印 */} -
-
${watermarkText}`)}")`, - backgroundRepeat: 'repeat', - }} /> -
- {/* Web 侧边栏 (md 及以上) */} + {/* 氢费看板按原型交付;其他模块继续保留全局水印。 */} + {!isHydrogenPrototype ? ( +
+
${watermarkText}`)}")`, + backgroundRepeat: 'repeat', + }} /> +
+ ) : null} + {/* Web 侧边栏 (md 及以上):能源各模块使用同一套规格,以电能为基准。 */}