Mobile-first responsive entry under bottom nav. Phase 1: front-end prototype with mocked data — backend deferred. Mirrors three FineBI dashboards (TPqB / GBSp / 0iqP) restructured into 氢能/电能 tabs. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
265 lines
12 KiB
Markdown
265 lines
12 KiB
Markdown
# 能源管理模块设计
|
||
|
||
在底部导航增加「能源管理」入口,集中展示加氢/充电的成本与用量数据。当前阶段**只做前端原型,数据全部走前端 mock**,后端接入留作下一阶段。
|
||
|
||
## 业务背景
|
||
|
||
参考 FineBI 既有的三张大屏:
|
||
|
||
| BI 链接 | 标题 | 内容 |
|
||
|---------|------|------|
|
||
| `link/0iqP` | 氢气管理(氢费统计) | 年/月/日加氢量与加氢费 KPI、加氢业务区域分布、Top5 加氢站、各区域占比 |
|
||
| `link/GBSp` | 加氢站氢量每日汇总 | 每日加氢量与环比,下钻到站点级带单价 |
|
||
| `link/TPqB` | 龙王路停车场充电站每日充电汇总 | 每日充电量(度) + 充电费用(元) |
|
||
|
||
这些大屏目前只在桌面浏览器里好看,移动端体验较差,且与现有应用风格割裂。新模块的目标是把核心信息按「移动优先 + 双端响应」重新组织进当前 BI App 的底部导航,让一线运营在手机上也能秒级抓取关键能耗指标。
|
||
|
||
## 用户故事
|
||
|
||
- 作为运营人员,进 App 底部 Tab 「能源管理」,第一屏立刻能看到本年/本月/今日的加氢量与加氢费。
|
||
- 作为运营人员,能切换查看「氢能」和「电能」两类业务。
|
||
- 作为氢能业务方,能看到每日加氢明细,并下钻到站点级别(站名 + 单价)。
|
||
- 作为电能业务方,能看到龙王路充电站每日充电量与充电费。
|
||
|
||
## 范围
|
||
|
||
### 在范围内
|
||
- 新模块 `src/modules/energy/`,遵循 mileage 模块的目录骨架
|
||
- `EnergyModule` 顶级组件 + 二级 Tab(氢能 / 电能)
|
||
- 氢能下:总览(KPI + Top5 横柱 + 区域占比环)+ 每日(明细表带下钻)
|
||
- 电能下:mini KPI 头 + 每日明细表
|
||
- 全前端 mock 数据,数据值从 BI 截图取真实样本,文件 `mock.ts`
|
||
- 双端响应(mobile + web)
|
||
- 在 `App.tsx` 的 `BASE_MODULES` 注册(登录即可见)
|
||
|
||
### 不在范围内
|
||
- 后端接入、真实数据库表设计(下一期)
|
||
- 中国地图(加氢业务区域分布)— 工作量与依赖(高德/echarts-geo)大,后续单独立项
|
||
- iframe 嵌入 FineBI(已否决)
|
||
- 角色权限门禁(暂不需要)
|
||
- 数据导出 / CSV
|
||
- 站点详情页 / 区域详情页
|
||
|
||
## 模块注册(App.tsx)
|
||
|
||
```ts
|
||
import { Truck, Route, Activity, Zap } from 'lucide-react';
|
||
import EnergyModule from './modules/energy/EnergyModule';
|
||
|
||
const BASE_MODULES: ModuleConfig[] = [
|
||
{ id: 'assets', label: '资产管理', icon: Truck, component: AssetsModule },
|
||
{ id: 'mileage', label: '里程管理', icon: Route, component: MileageModule },
|
||
{ id: 'energy', label: '能源管理', icon: Zap, component: EnergyModule },
|
||
];
|
||
```
|
||
|
||
并在 `Shell.tsx` 的 `PATH_MAP` 加 `'/energy': 'energy'`。`#energy` hash 由 Shell 已有逻辑兜底。
|
||
|
||
## 页面结构
|
||
|
||
```
|
||
EnergyModule
|
||
├── 顶部 sticky sub-nav: [氢能] [电能] ← motion layoutId 滑块动画
|
||
│
|
||
├── 氢能 view (HydrogenView)
|
||
│ ├── 内层 sticky tab: [总览] [每日]
|
||
│ ├── HydrogenOverview
|
||
│ │ ├── 数据时间提示条:「数据自 2025-01-01 起,每 5 分钟更新」
|
||
│ │ ├── KPI 网格(移动 2×2 / 桌面 1×4)
|
||
│ │ ├── Top5 加氢站横柱图
|
||
│ │ └── 各区域加氢占比环形图
|
||
│ └── HydrogenDaily
|
||
│ ├── 日期速选 6 选 1:当天 / 本周 / 本月 / 本季度 / 最近7天 / 最近30天
|
||
│ ├── 客户类型 2 选 1:外部 / 羚牛
|
||
│ ├── 合计行(pin 在表头下)
|
||
│ └── 表格:日期 → 加氢量(Kg) → 环比%(日期行可展开为站点级)
|
||
│
|
||
└── 电能 view (ElectricView)
|
||
├── 数据时间提示条:「龙王路停车场充电站,期初 2025-01-01,手工导入每日更新」
|
||
├── 横向 mini KPI 头(3 列:累计 / 本月 / 今日)
|
||
├── 客户类型 2 选 1:外部 / 羚牛
|
||
└── 表格:月份/日期 → 充电电量(度) → 充电费用(元)(月份组可展开为日级)
|
||
```
|
||
|
||
## 文件结构
|
||
|
||
```
|
||
src/modules/energy/
|
||
├── EnergyModule.tsx # 顶级容器 + 氢能/电能 切换
|
||
├── HydrogenView.tsx # 含「总览/每日」二级 Tab
|
||
├── HydrogenOverview.tsx # KPI + Top5 + 区域占比
|
||
├── HydrogenDaily.tsx # 加氢量明细表
|
||
├── ElectricView.tsx # 充电汇总表
|
||
├── mock.ts # 所有 mock 数据
|
||
└── types.ts # 共享类型
|
||
```
|
||
|
||
参照 `src/modules/mileage/` 风格。**没有 api.ts**(后端先不接)。
|
||
|
||
## 数据形状(mock.ts / types.ts)
|
||
|
||
```ts
|
||
// types.ts
|
||
export type CustomerType = 'external' | 'lingniu'; // 外部 / 羚牛
|
||
export type DateQuickPick = 'today' | 'thisWeek' | 'thisMonth' | 'thisQuarter' | 'last7' | 'last30';
|
||
|
||
export interface HydrogenKpi {
|
||
yearKg: number; // 年加氢量 Kg
|
||
yearFee: number; // 年加氢费 元
|
||
ourYearKg: number; // 我方年加氢量
|
||
ourYearFee: number; // 我方年加氢费
|
||
customerYearKg: number; // 客户产生年加氢量
|
||
monthKg: number;
|
||
monthFee: number;
|
||
todayKg: number;
|
||
todayFee: number;
|
||
lingniuBornKg: number; // 累计羚牛承担量
|
||
lingniuBornFee: number; // 累计羚牛承担费
|
||
}
|
||
|
||
export interface HydrogenStation {
|
||
name: string;
|
||
kg: number;
|
||
fee: number;
|
||
}
|
||
|
||
export interface HydrogenRegionShare {
|
||
region: string;
|
||
kg: number;
|
||
share: number; // 0-1
|
||
}
|
||
|
||
export interface HydrogenStationRow {
|
||
name: string;
|
||
pricePerKg: number; // 单价 元/Kg
|
||
kg: number;
|
||
chainPct: number; // 环比 -1..+1
|
||
}
|
||
|
||
export interface HydrogenDailyRow {
|
||
date: string; // 'YYYY-MM-DD'
|
||
totalKg: number;
|
||
chainPct: number;
|
||
stations: HydrogenStationRow[];
|
||
}
|
||
|
||
export interface ElectricKpi {
|
||
totalKwh: number;
|
||
totalFee: number;
|
||
monthKwh: number;
|
||
monthFee: number;
|
||
todayKwh: number;
|
||
todayFee: number;
|
||
todayChainPct: number;
|
||
}
|
||
|
||
export interface ElectricDailyRow {
|
||
date: string; // 'YYYY-MM-DD'
|
||
kwh: number;
|
||
fee: number;
|
||
chainPct: number; // 环比,用于趋势箭头
|
||
}
|
||
|
||
export interface ElectricMonthGroup {
|
||
month: string; // 'YYYY-MM'
|
||
kwh: number;
|
||
fee: number;
|
||
rows: ElectricDailyRow[];
|
||
}
|
||
```
|
||
|
||
`mock.ts` 提供:
|
||
- `hydrogenKpi`:取自 0iqP 的 362.43T / ¥1066.46 万 / 10.03 万 等真实样本
|
||
- `hydrogenStationsTop5`:5 家站,名字取自 GBSp 截图
|
||
- `hydrogenRegionShare`:约 8-12 个区域条目
|
||
- `hydrogenDaily`:约 30 天数据,前 7 天每天 3-4 个站点;剩余天只有汇总 + 1-2 站点
|
||
- `electricKpi`:取自 TPqB 合计 817,632.24 度 / ¥151,542.92
|
||
- `electricMonthly`:以月为顶级 group,含每日明细,至少覆盖 2026-04 起若干天
|
||
|
||
数字均做轻微抖动,但保留量级与百分比,避免与 BI 大屏数字"完全一致"误导。
|
||
|
||
## 视觉规范
|
||
|
||
### 通用
|
||
- 容器:`min-h-screen bg-[#F8F9FB] text-gray-800 font-sans p-3 md:p-6` + `max-w-6xl mx-auto`
|
||
- 横屏:保留 `landscape:pb-0 landscape:h-full landscape:flex-1 landscape:overflow-hidden`
|
||
- 卡片:`bg-white rounded-2xl border border-slate-100 shadow-sm`
|
||
- sub-nav:`bg-white px-4 py-2 rounded-2xl border border-slate-100 shadow-sm` + sticky top 0
|
||
- Tab active 用 `motion.div layoutId="..."` 下划线动画(沿用 mileage 模式)
|
||
- 主色:`text-blue-600 / bg-blue-50`
|
||
- 正向:`text-emerald-500 / bg-emerald-50`
|
||
- 负向:`text-red-500 / bg-red-50`
|
||
- 警示:`text-amber-500 / bg-amber-50`
|
||
|
||
### 氢能总览
|
||
- KPI 卡:4 张主角卡,顺序固定
|
||
1. 年加氢量(青蓝渐变 `from-cyan-50 to-blue-50`)+ 主数 `362.43T` + 分解两行(我方 / 客户产生)
|
||
2. 年加氢费(蓝紫渐变 `from-blue-50 to-violet-50`)+ 主数 `¥1066.46万` + 分解(我方)
|
||
3. 累计羚牛承担(蜜橙渐变 `from-amber-50 to-orange-50`)+ 主数 `¥10.03万` + 分解(量 / 费)
|
||
4. 本月/今日合并卡(浅灰)+ 左半月度 + 右半今日,文字主数 `text-2xl md:text-3xl`
|
||
- 卡左上 lucide icon:`Fuel` / `Wallet` / `Coins` / `CalendarClock`
|
||
- KPI 主数移动端 `text-2xl font-bold`,桌面 `md:text-3xl`,分解行 `text-[11px] text-slate-500 font-bold`
|
||
- Top5 加氢站:横向柱状(recharts BarChart `layout="vertical"`),柱子蓝→青渐变,柱左侧带数字徽章 1-5,柱右端贴 `XX,XXX Kg · XX%`,`<ResponsiveContainer width="100%" height={240}>`
|
||
- 区域占比环形:recharts PieChart,外环切片,中心圆心放年合计 `362.43T`,下方两列图例(移动单列、桌面双列)
|
||
|
||
### 氢能每日表
|
||
- 日期速选:6 个 pill 一行,可横向滚动,激活态 `bg-blue-50 text-blue-600 border-blue-200`
|
||
- 客户类型:2 列等宽 segmented control(背景 `bg-slate-100 rounded-xl`,激活态白底+阴影)
|
||
- 合计行:`bg-blue-50/50 text-blue-600` 粗体
|
||
- 主行 = 日期:左侧 `▶` 折叠图标 + 日期;展开后子行内缩进 `pl-6`,子行内容 = 站名 - 单价 元/Kg
|
||
- 环比 pill 双端共用样式:
|
||
- 上 `↑` 绿底 `bg-emerald-50 text-emerald-600`
|
||
- 下 `↓` 红底 `bg-red-50 text-red-600`
|
||
- 持平 `–` 灰底 `bg-slate-100 text-slate-500`
|
||
- 圆角 `rounded-full px-2 py-0.5 text-[11px] font-bold`
|
||
- 移动 3 列(日期 / 量 / 环比),桌面 4 列加站价列(站点级行用网格而非缩进)
|
||
|
||
### 电能
|
||
- mini KPI 头:3 卡横排(移动也保持横排,不堆叠),每卡上排 `¥金额` 主数(`text-xl md:text-2xl`),下排 `XXX 度` 副数 + 今日卡再加 pill 环比
|
||
- 月份组:`▶` + `2026-04` + 该月合计 `度 / 元`;展开后是日级行
|
||
- 月份组 active 时背景 `bg-blue-50/30`
|
||
- 行的趋势图标 → 与氢能页用同一 pill 组件(保证视觉一致)
|
||
|
||
## 响应式行为
|
||
|
||
| 区域 | 移动 (<md) | 桌面 (≥md) |
|
||
|------|-----------|-----------|
|
||
| 顶部 sub-nav (氢/电) | sticky 满宽 | sticky 满宽,左对齐 |
|
||
| 氢能内层 sub-tab | 紧贴 sub-nav 下 | 同 |
|
||
| 氢能总览 KPI 网格 | `grid-cols-2` | `md:grid-cols-4` |
|
||
| Top5 横柱 + 区域占比 | 上下叠 `grid-cols-1` | `md:grid-cols-2 gap-4` |
|
||
| 每日氢能表 | 3 列:日期/量/环比 | 4 列:日期/站价/量/环比,站点级行同样 4 列 |
|
||
| 电能 mini KPI 头 | 横排 3 卡(gap 紧凑) | 3 卡(gap 宽松) |
|
||
| 电能表格 | 3 列 | 4-5 列(可加客户类型 / 趋势火花线,留作后期) |
|
||
| 容器宽度上限 | 100% | `max-w-6xl mx-auto` |
|
||
| recharts 图 | `<ResponsiveContainer width="100%">` | 同 |
|
||
|
||
## 组件复用
|
||
|
||
- 内层 sub-nav 抄 `MileageModule.tsx` 的 sticky tab 实现(含 motion 滑块)
|
||
- segmented control(客户类型 / 日期速选)抄 mileage 已有的实现
|
||
- 表格行 chevron 折叠抄 assets 模块里现有展开行的写法
|
||
- 环比 pill 单独抽 `<TrendBadge value={number} />` 共用组件,放在 `src/modules/energy/HydrogenDaily.tsx` 顶端 export
|
||
|
||
## 边界与开放点
|
||
|
||
1. **`氢费`字面口径**:用户原始描述「每日氢费」,但 BI GBSp 实际只有加氢量+环比,单价在站点级。本期采纳 BI 的口径——表格只展示量+环比+单价(嵌入站名),费汇总放氢能总览的 KPI 卡。
|
||
2. **数据时间**:mock 用 2026-04-28 为「今天」(`currentDate` 取自 user 自动 memory)。`今日加氢` 在 0Kg 时显示 `0` 而非 `--`,避免误判为缺失。
|
||
3. **空态**:mock 数据已写满,UI 仍要支持 `rows.length === 0` 时显示「暂无数据」灰文 + 图标。
|
||
4. **未来后端接入**:mock 文件命名 `mock.ts`,不放在 `api.ts`;后期添加 `api.ts` 时同名 export,UI 切到 `useEffect + fetch` 即可。
|
||
5. **icon 选型**:`Zap` 作为模块底栏 icon。备选 `Fuel` / `Battery`。
|
||
6. **lucide 大小**:底部 nav 沿用 `Icon size={20}`。
|
||
|
||
## 验收标准
|
||
|
||
- [ ] 底部 nav 多出「能源管理」Tab,icon Zap,登录后可见
|
||
- [ ] 进入后默认在「氢能 → 总览」
|
||
- [ ] 氢能总览 4 张 KPI 卡数据正确、移动 2×2 / 桌面 1×4
|
||
- [ ] Top5 横柱 + 区域占比环 双端可见,柱图站名不被截断
|
||
- [ ] 切换到「氢能 → 每日」,日期速选/客户类型 toggle 工作(前端筛选 mock 即可)
|
||
- [ ] 点开任意日期行能展开站点级行,环比 pill 颜色正确
|
||
- [ ] 切到电能 Tab,3 张 mini KPI + 月份分组表,月份能展开日级行
|
||
- [ ] 横屏不出现底部 nav 遮挡内容
|
||
- [ ] `npm run lint` 通过
|
||
- [ ] 不引入新依赖(recharts / lucide-react / motion 已有)
|