Files
ln-bi/README.md
T
dsh-agent 507bc90ed2 refactor(stage5): 合并重复实现,移除失效的演示能力
Excel 导出(原先 4 份各自拼装 workbook)
- 新增 src/shared/xlsx.ts 作为唯一实现:文件名统一 .xlsx、sheet 名截断到 31 字符,
  对外提供 buildAoaSheet / buildJsonSheet / writeWorkbook / exportAoaSheet / exportJsonSheet。
  只收敛"组装与写出"这一层,各调用方仍自行决定列宽、冻结与数字格式,导出样式不变。
- 迁移 assets(内联 json_to_sheet + writeFile)、mileage/xlsx-export、
  hydrogen 的两份 helper(prototype-download.ts 与 download-xls.js,均已删除)。

高德地图(原先 2 份近乎逐行复制)
- 新增 src/shared/amap.ts:SDK 版本、插件列表、安全码注入、底图参数、
  控件位置与热力图色带只在此处定义;两个画布只保留各自的半径/透明度。
- 图例渐变条原先把同一组色值又写了一遍,改为复用 shared 的常量,图例与地图不会漂移。

数值格式化
- 两个下钻视图各自复制了同样的 formatNumber/format(共 42 处调用),
  统一到 hydrogen/model/display-format.ts 的 formatFixed;默认路径与既有行为逐字一致。
- 原 display-format.ts 里的 finiteNumber/formatNumber/formatScaled 无任何生产调用方,
  只被自己的测试引用;改为 formatFixed + blankForMissing 显式选项,
  既保留了"真零 vs 不可用"的区分能力,也不再留无人使用的导出。测试同步重写。

失效的演示能力
- Blur / DemoModeProvider 恒为 enabled=false,等于永久 no-op:
  移除 13 个文件里 50 处 <Blur> 包裹(渲染结果不变)、删除 components/Blur.tsx
  与 Shell 中的 Provider,调用方直接渲染原表达式。

未做(刻意)
- src/lib/cn.ts 不引入 tailwind-merge:全仓只有 2 处调用,不值得新增传递依赖。已在文档说明。

架构守护新增 2 条:只有 shared/amap.ts 可加载高德 SDK;
modules/** 不得再出现 book_new / book_append_sheet / writeFile(。

lint / test(137) / build 全绿,可达性仍为 0 未引用文件。
2026-09-11 10:28:32 +08:00

88 lines
3.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# LN-BI
羚牛业务数据的统一 BI Web 应用。React 19 + Vite 前端,Hono 后端,单进程同时提供 API 与静态页面。
## 入口
| 入口 | 模块 | 路由 |
| --- | --- | --- |
| 资产 BI | 资产管理、里程管理、车辆/加氢热力图、智能调度 | `/asset` |
| 能源 BI | 氢费 BI、电能、ETC | `/energy` |
| 隐藏页 | 充电记录导入(需能源角色) | `/ele/import` |
| 隐藏页 | 用户反馈管理 | `/admin/feedback` |
| 独立入口 | 氢能经营看板(与 `/energy` 内同一组件) | `/energy/hydrogen-board` |
页面内部用 Hash 保存子页面状态,例如 `/energy#hydrogen/overview`。入口兼容逻辑见 `src/app/routing.ts`
## 快速开始
需要 Node.js 22 与 npm。
```bash
npm ci
cp .env.local.example .env.local # 填入数据库等连接配置,切勿提交
npm run dev:local # 只读本地预览:前端 127.0.0.1:8115API 127.0.0.1:3001
```
`dev:local` 会强制 `DB_READ_ONLY=1``HYDROGEN_DB_READ_ONLY=1``MILEAGE_REPORT_AUTO_ARCHIVE=0`
`DEV_BYPASS_AUTH=1`,并且**不启动建表与定时任务**,适合看真实数据而不写库。不要把它暴露到公网。
常规开发(前端 3000,后端 3001,`/api` 由 Vite 代理):
```bash
npm run dev
```
## 命令
| 命令 | 说明 |
| --- | --- |
| `npm run dev` | 前后端开发模式 |
| `npm run dev:local` | 只读本地预览(免登录,禁写库) |
| `npm run lint` | 类型检查(`tsc --noEmit` |
| `npm test` | Node 内置测试运行器 |
| `npm run build` | 生成 `dist` |
| `npm start` | 生产式启动(需先 build,且必须提供环境变量) |
发布门禁是 `lint` + `test` + `build` 三者同时通过(CI 见 `woodpecker.yml`)。
## 目录
```
src/
├── app/ 应用外壳:路由解析、导航注册
├── auth/ 前端认证状态与注入
├── components/ 跨模块 UIShell、反馈、通用控件)
├── modules/ 前端业务域(每个域自带 api / model / components / css
│ ├── assets/ 资产管理
│ ├── mileage/ 里程(monitoring / statistics / daily-report
│ ├── scheduling/智能调度
│ ├── energy/ 能源(hydrogen / electric / etc
│ ├── ele/ 电能数据导入
│ ├── admin/ 反馈后台
│ └── *-heatmap/ 两类热力图
├── shared/ 前后端共享的叶子层(角色常量、跨端 DTO、日期区间、Excel、高德接入)
└── server/
├── config.ts 环境变量集中读取 + 启动期校验
├── app.ts 应用装配(无副作用,便于测试)
├── index.ts 进程启动
├── local.ts 只读预览启动
├── db/ MySQL / PostgreSQL 连接
├── middleware/认证、只读
├── auth/ 登录(SSO 换票 / 固定密码)、权限
└── routes/ 按业务域的 HTTP 路由
```
## 架构约定
分层规则、依赖方向与「新增一个模块该放哪」见 [`docs/ARCHITECTURE.md`](docs/ARCHITECTURE.md)。
其中 6 条硬规则由 `src/architecture.test.ts` 断言,违反即测试失败。
## 部署注意事项
- `JWT_SECRET` **必须**在运行环境注入且不少于 32 字符;SSO 模式下缺失时服务会拒绝启动。
镜像内不再内置默认密钥(历史默认值等同于公开密钥,可被离线伪造令牌)。
- 数据库口令、Harbor 凭据、OSS / OneOS / 高德密钥一律通过环境变量或 CI Secret 注入,
仓库内不保留真实值。历史提交中出现过的凭据都需要轮换。
- 生产环境请显式设置 `NODE_ENV=production``DEV_BYPASS_AUTH=0`;后者会绕过全部认证。