# 羚牛 BI 报表服务实现计划 ## Context 基于 AI Studio 生成的前端原型(`-V1.0`),构建连接真实 MySQL 数据库的 BI 报表服务。前端复用 React+Vite+Tailwind 代码,后端使用 Hono + TypeScript,替换 mock 数据为真实数据库查询结果。 **数据库**: `192.168.130.111:3306/lingniu_prod3` (root/lingniu#2024) --- ## 项目结构 ``` ln-bi/ ├── package.json ├── tsconfig.json ├── vite.config.ts ├── .env # 数据库连接配置 ├── src/ │ ├── server/ │ │ ├── index.ts # Hono 服务入口 │ │ ├── db.ts # MySQL 连接池(mysql2) │ │ ├── routes/ │ │ │ └── vehicles.ts # 车辆数据 API 路由 │ │ └── types.ts # 后端类型定义 │ ├── App.tsx # 前端主组件(改造自 -V1.0) │ ├── api.ts # 前端 API 调用层 │ ├── types.ts # 前端共享类型 │ ├── main.tsx │ └── index.css └── index.html ``` --- ## 实现步骤 ### Step 1: 项目初始化 1. 在 `ln-bi/` 初始化项目,安装依赖: - **前端**: react, react-dom, lucide-react, motion, tailwindcss, vite, @vitejs/plugin-react, @tailwindcss/vite - **后端**: hono, @hono/node-server, mysql2, dotenv - **开发**: typescript, tsx, @types/node, @types/react, @types/react-dom, concurrently 2. 配置 `tsconfig.json`、`vite.config.ts`(含 API 代理到后端) 3. 创建 `.env` 文件(数据库连接信息) 4. 配置 `package.json` scripts: - `dev:server` — tsx 启动后端 - `dev:client` — vite 启动前端 - `dev` — concurrently 同时启动前后端 ### Step 2: 后端 — 数据库连接与查询 **关键文件**: `src/server/db.ts`, `src/server/routes/vehicles.ts` 1. 创建 MySQL 连接池(mysql2/promise) 2. 实现主查询 API `GET /api/vehicles`,执行用户提供的 SQL,返回所有营运车辆数据 3. 后端对原始数据做聚合计算,返回前端需要的结构: - `GET /api/vehicles/summary` — 总览统计(总资产、运营数、库存数等) - `GET /api/vehicles/list` — 车辆列表(支持分页/过滤) - `GET /api/vehicles/by-type` — 按车型分组汇总 - `GET /api/vehicles/by-batch` — 按批次分组汇总(如果数据库有批次字段) - `GET /api/vehicles/inventory-analysis` — 库存分析(按区域分布) **数据映射**(SQL 字段 → 前端字段): | SQL 字段 | 前端字段 | 说明 | |---------|---------|------| | 车牌号 | plateNumber | 车牌 | | 车辆型号Label | type | 车型分类(4.5T/18T/49T等) | | 车辆品牌Label + 车辆型号Label | model | 品牌车型组合 | | 省/市 | location | 区域(映射为嘉兴/广东/北京/新疆/其他) | | 车辆租赁状态Label | status | Operating/Inventory/Abnormal | | 车辆归属状态Label | ownership | Self/Leased/Public/Hanging | | 合同编码 | batch | 批次信息(或从其他字段推断) | **注意**: 省/市需映射为前端的 5 大区域(嘉兴、广东、北京、新疆、其他)。归属状态、租赁状态需根据字典值映射为英文枚举。 ### Step 3: 后端 — Hono 服务 **关键文件**: `src/server/index.ts` 1. 创建 Hono app,挂载车辆路由 2. 添加 CORS 中间件(开发时前端在不同端口) 3. 监听端口 3001 4. 错误处理中间件 ### Step 4: 前端改造 **关键文件**: `src/App.tsx`, `src/api.ts` 1. 从 `-V1.0/src/App.tsx` 复制前端代码 2. 创建 `src/api.ts` — 封装 fetch 调用后端 API 3. 改造 `App.tsx`: - 删除 `MOCK_VEHICLES` 和 `SUMMARY` 常量 - 删除 `getProcessedData`、`getProcessedDataByBatch`、`getInventoryAnalysisData` 纯前端聚合函数(改为后端聚合) - 添加 `useEffect` + `useState` 从 API 获取数据 - 添加 loading 状态和错误处理 - 保留所有 UI 组件和交互逻辑不变 4. 保留主题切换、展开/折叠、模态框等交互功能 5. 车牌号弹窗改为调用 API 按条件查询 ### Step 5: Vite 代理配置 在 `vite.config.ts` 中配置 `/api` 代理到后端 `http://localhost:3001`,开发时无需 CORS。 --- ## 暂不实现(后续补充) 以下统计指标当前 SQL 未覆盖,先用 0 或占位: - 本周新增 / 本周移除 - 待交车数量 - 本周交付 / 本周归还 / 本周替换 - 批次信息(需确认数据库中对应字段) --- ## 验证方案 1. `npm run dev` 同时启动前后端 2. 访问 `http://localhost:3000` 查看页面 3. 检查浏览器 Network 面板确认 API 调用正常 4. 对比前端显示数据与数据库查询结果是否一致 5. 测试交互功能:主题切换、展开折叠、车牌号弹窗、按型号/批次视图切换