diff --git a/9b0d3b8abab88e25f36e6a793a6e1eec.jpg b/9b0d3b8abab88e25f36e6a793a6e1eec.jpg deleted file mode 100644 index e56b788..0000000 Binary files a/9b0d3b8abab88e25f36e6a793a6e1eec.jpg and /dev/null differ diff --git a/AGENTS.md b/AGENTS.md index 6ac4dc6..43d2676 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -32,10 +32,9 @@ D:\charging-cabinet\ │ ├── README.md # 文档索引:分类、权威性、旧名→现名映射、维护约定 │ ├── protocol/ # 平台设备协议 → **只有 1 份**:柜控板固件对接文档.md ⭐唯一权威 TCP 协议 │ ├── tech/ # 平台技术文档 → API.md / 数据模型.md / 部署手册.md / 小程序用户端.md -│ ├── hardware/ # 硬件侧总线协议(RS485,**不是**平台 TCP 协议)→ 1TN协议标准_* -│ ├── contract/ # 合同·规格·验收标准(商务依据,不描述实现) -│ ├── compound-notes/ # 单点经验笔记(参考性) -│ └── archive/ # ⛔ 历史留痕(只读,不代表现状,不可作依据) +│ ├── hardware/ # 硬件侧:1TN协议标准_*(RS485 总线)+ 硬件与系统设计文档.md +│ ├── contract/ # 合同·规格·验收标准·营业执照(商务/主体依据,不描述实现) +│ └── compound-notes/ # 单点经验笔记(参考性) ├── deploy/ # 部署配置与脚本 │ ├── nginx/ # Nginx 配置镜像(**三份**:nginx.conf 主配置 + app/test 两份 conf.d,均与线上逐字节一致) │ ├── *.service # systemd 单元(pms-api / pms-device × prod·test 共 4 个) diff --git a/d6e6add1c7a1e8c1fc2b820ea206e000.png b/d6e6add1c7a1e8c1fc2b820ea206e000.png deleted file mode 100644 index 5a8a60a..0000000 Binary files a/d6e6add1c7a1e8c1fc2b820ea206e000.png and /dev/null differ diff --git a/docs/README.md b/docs/README.md index 93f9bc0..efa8543 100644 --- a/docs/README.md +++ b/docs/README.md @@ -12,7 +12,6 @@ | [`hardware/`](#hardware硬件侧总线协议) | **硬件侧总线协议**(RS485,**不是**平台 TCP 协议) | 硬件事实依据 | 硬件工程师、对接电源/BMS 的人 | | [`contract/`](#contract合同与规格) | **合同、规格、验收标准**(商务依据) | 事实依据,但不描述实现 | PM、验收方、新人了解范围 | | [`compound-notes/`](#compound-notes经验沉淀) | **单点经验笔记**(踩坑/技法) | 参考,非权威 | 遇到同类问题的人 | -| [`archive/`](#archive历史归档) | **历史留痕**(只读,**不代表现状**) | ⛔ **不可作为依据** | 追溯历史决策时 | ## 二、谁是权威(口径优先级,避免"两份文档谁对"的扯皮) @@ -55,9 +54,14 @@ |------|------| | `1TN协议标准_YG20240118-1_V1.0.md` | 仓控板 ↔ 电源(苏州翌工)1TN RS485 协议,文本版 | | `1TN协议标准_苏州翌工电源_V1.0.pdf` | 同上,厂家原始 PDF | +| `硬件与系统设计文档.md` | **硬件与系统设计原文**(46 KB):硬件架构、仓控/柜控主板设计、指示灯状态机、充电控制逻辑(握手/双模式/动态调整/无协议模式)、BMS 协议适配、安全防护联动、性能指标、第三方服务配置。**硬件侧的主规格文档。** | -> ⚠️ 这是**另一条物理链路**(柜内 485 总线),**与平台 TCP 协议无关** —— +> ⚠️ `1TN协议标准_*` 是**另一条物理链路**(柜内 485 总线),**与平台 TCP 协议无关** —— > 别把它当成"第二份 TCP 协议"。硬件侧的其它总线协议(BMS:星恒 Modbus / 天能 485)如需入库,也放这里。 +> +> ⚠️ `硬件与系统设计文档.md` **早于现行实现**:其中**硬件设计部分仍是权威参考**, +> 但**软件平台部分(第 7 章)已被 `AGENTS.md` + `docs/tech/` 取代** —— +> 两者冲突时,软件口径一律以 `AGENTS.md` 为准(它按代码契约与库实测核对过)。 ### tech/ —— 平台技术文档 @@ -76,6 +80,8 @@ `开发合同` / `附件一-硬件规格` / `附件二-软件规格` / `附件三-交付与验收标准` / `附件-开发需求规格说明书`,各含 `.md` + 原始格式(`.docx` / `.pdf` / `.html`)双份。 +> 另有 `营业执照.jpg`(主体资质,小程序/备案用)。 +> > 用途:**范围与验收的事实依据**。描述"要做什么 / 达到什么标准",**不描述当前实现** > ——实现现状一律以 `AGENTS.md` + 代码为准。 @@ -84,17 +90,19 @@ 单点问题的笔记(如某次 SQL 注入的成因与修法)。**参考性**内容, 遇到同类问题时查;结论若上升为通用规范,应回写进 `AGENTS.md` 的「踩过的坑」。 -### archive/ —— 历史归档 +### ~~archive/~~ —— 已取消(2026-09-20) -| 文件 | 说明 | -|------|------| -| `开发文档.md` | 早期(现行实现之前)的开发文档,**与当前实现多处不一致** | -| `审查报告-数据单位一致性-2026-07-06.md` | 2026-07-06 的数据单位审查报告 | -| `项目深度分析报告-2026-07-06.md` | 2026-07-06 的项目深度分析报告 | +**不再设归档目录。** 曾经的 `archive/` 三份文件已按下述依据处置: -⛔ **归档目录只读、不作依据**——里面的路径、结论、数字都是**当时**的。 -其中出现的旧文档名(如 `tcp-protocol.md`、`docs/柜控板-平台TCP接口文档.md`) -是历史事实,**不要求可点击**;对应关系到当前文档的映射见下节。 +| 原文件 | 处置 | 依据 | +|---|---|---| +| `开发文档.md` | **移出归档** → `hardware/硬件与系统设计文档.md` | 它**不是过时文档而是归错类**:含硬件设计(主板、指示灯状态机、充电控制、BMS 适配、防护联动),这些在 `AGENTS.md`/`tech/` 里**没有**。仅第 7 章软件部分被取代。 | +| `审查报告-数据单位一致性-2026-07-06.md` | **删除** | 一次性审查报告,**发现的问题全部已解决**(SOC/SOH 单位标注早已重写;该报告以已不存在的 `tcp-protocol.md` 为基准)。 | +| `项目深度分析报告-2026-07-06.md` | **删除** | 同上。其 4 项"发现的问题"均已失效:明文密码已成**明示豁免**、"可能用 taro"已确认是 `h5-uniapp`、`test/` 已存在、温度单位已统一。 | + +> 💡 **为什么不设归档**:被删除的内容**在 git 历史里完整可查**(`git log -- <原路径>`), +> 归档目录的"留痕"价值因此为零,却会持续制造"这文件还算不算依据"的歧义。 +> 结论:**过时就删,历史交给 git**;仍有价值的内容应当**归到正确的类**而不是塞进 archive/。 ## 四、旧名 → 现名映射(查旧链接时用) @@ -105,24 +113,25 @@ | `docs/柜控板固件对接文档.md` | `docs/protocol/柜控板固件对接文档.md` | | `docs/API.md` | `docs/tech/API.md` | | `docs/数据模型.md` · `docs/部署手册.md` · `docs/小程序用户端.md` | 同名,移到 `docs/tech/` | -| `docs/开发文档.md` | `docs/archive/开发文档.md` | -| 其余合同/规格/验收/协议标准 | 见上表,分别归入 `contract/` 与 `protocol/` | +| `docs/开发文档.md` | `docs/hardware/硬件与系统设计文档.md`(**不是过时,是归错类**) | +| 根目录 `换电柜用锂电池充电器1TN标准通信协议 - RS485 V1.0(1).pdf` | `docs/hardware/1TN协议标准_苏州翌工电源_V1.0.pdf`(**同一文件,根目录那份是重复,已删**) | +| `docs/审查报告-数据单位一致性-2026-07-06.md` · `docs/项目深度分析报告-2026-07-06.md` | **已删除**(问题全部已解决;git 历史可查) | +| 其余合同/规格/验收/协议标准 | 见上表,分别归入 `contract/`、`hardware/` 与 `protocol/` | ## 五、维护约定(新增/移动文档时必做) -1. **归位**:按"协议 / 技术 / 合同 / 经验 / 归档"分类放入对应目录,**不要再平铺在 `docs/` 根**。 +1. **归位**:按"协议 / 技术 / 硬件 / 合同 / 经验"分类放入对应目录,**不要再平铺在 `docs/` 根**。 2. **更新本索引**:在对应章节的表格里加一行(文件 + 一句话定位 + 谁该读)。 3. **同步全仓引用**:文档路径散落在 `AGENTS.md`、`README.md`、**Rust/TS/Vue 源码注释**、 `test/`、`tools/`、`tasks/` 里;移动后必须全仓替换。 校验方法(**应无输出**): ```bash # 找仍指向旧平铺路径的活引用 - # · 排除 docs/archive/ —— 归档按设计保留历史原文 # · 排除 docs/README.md —— 本文件的「旧名 → 现名映射」表**必须**出现旧名 grep -rn --exclude-dir={.git,node_modules,target,dist} \ -e 'docs/API\.md' -e 'docs/数据模型\.md' -e 'docs/部署手册\.md' \ -e 'docs/小程序用户端\.md' -e 'docs/开发文档\.md' . \ - | grep -v '^\./docs/archive/' | grep -v '^\./docs/README\.md:' + | grep -v '^\./docs/README\.md:' ``` > 已实测该命令**能抓到问题**:往 `docs/tech/API.md` 末尾植入一行 > `` → 命中;删除后 → 无输出。 @@ -130,4 +139,5 @@ > 否则会漏改(我第一次就踩了:`\n` 正则配不上 `\r\n`,以为删干净了其实残留)。 4. **改 `AGENTS.md` 的链接**:`AGENTS.md` 里所有 `docs/...` 链接都必须是**分类后**的路径 (`docs/protocol/...`、`docs/tech/...`)。 -5. **别把权威内容只放进归档**:归档是留痕,规范要写进 `AGENTS.md` 或 `tech/`。 +5. **过时就删,不要设归档**:被删内容在 git 历史里完整可查,归档只会制造 + "这文件还算不算依据"的歧义。仍有价值的**归到正确的类**,规范要写进 `AGENTS.md` 或 `tech/`。 diff --git a/docs/archive/审查报告-数据单位一致性-2026-07-06.md b/docs/archive/审查报告-数据单位一致性-2026-07-06.md deleted file mode 100644 index a550675..0000000 --- a/docs/archive/审查报告-数据单位一致性-2026-07-06.md +++ /dev/null @@ -1,180 +0,0 @@ -> ## ⛔ 本文是**历史归档**(2026-07-06),**不代表现状,不可作为依据** -> -> 结论、路径、字段名都是**当时**的。文中引用的旧文档名与现名对应关系: -> -> | 文中旧名 | 现位置 | -> |---|---| -> | `docs/tcp-protocol.md` | `docs/protocol/柜控板固件对接文档.md`(**唯一权威**,已升到 v1.1.1) | -> | `docs/API.md` | `docs/tech/API.md` | -> | `docs/开发文档.md` | `docs/archive/开发文档.md` | -> -> 当前口径一律以 **`AGENTS.md`**(平台侧实现)+ **`docs/protocol/柜控板固件对接文档.md`**(设备协议)为准。 -> 文档分类总览见 `docs/README.md`。 - -# 数据单位审查报告 — 充电柜项目 - -**日期:** 2026-07-06 -**审查范围:** 硬件固件(协议层)、后端 API(api-server)、前端展示(web + h5-uniapp)、API 文档(docs/) -**协议基准:** [docs/tcp-protocol.md](./tcp-protocol.md) 全局单位规范(第23-35行) - ---- - -## 1. 协议基准(tcp-protocol.md) - -| 字段 | 单位 | 精度 | 示例 | -|------|------|------|------| -| `voltage` | mV | 1 | 52000 = 52.000V | -| `current` | mA | 1 | 10000 = 10.000A | -| `power` | mW | 1 | 500000 = 500.000W | -| `temp` | K×100 | 0.01K | 29865 = 298.65K = 25.5°C | -| `soc` | **‰** | 0.1% | 4500 = 45.00% | -| `soh` | **‰** | 0.1% | 9500 = 95.00% | -| `energy` | Wh | 1 | 累计充电量 | - ---- - -## 2. 审查结果总览 - -### ✅ 正确的转换 - -| 字段 | 协议单位 | 前端转换 | 文件位置 | 状态 | -|------|---------|---------|---------|------| -| voltage | mV | `/1000 → V` | h5 `compartment-detail/index.vue:144` | ✅ | -| current | mA | `/1000 → A` | h5 `compartment-detail/index.vue:145` | ✅ | -| power | mW | `/1000 → W` | h5 `compartment-detail/index.vue:146` | ✅ | -| temp | K×100 | `/100 - 273.15 → °C` | h5 `device-detail/index.vue:85`、web `cabinet.tsx` | ✅ | -| soc | ‰ | `/10 → %` | h5 `compartment-detail/index.vue:142`、`device-detail/index.vue:86` | ✅ | -| energy | Wh | `/1000 → kWh` | h5 `compartment-detail/index.vue:147` `fmtEnergyKwh` | ✅ | -| energy(累计) | Wh | `/1000 → kWh` | h5 `compartment-detail/index.vue:143` `fmtEnergy` | ✅ | -| cost计算 | Wh × 0.0008 → 元 | — | api-server `energy_stats.rs:15` COST_PER_WH | ✅ | - -### 🔴 不一致:SOC/SOH 单位标注错误 - -**问题:** `docs/tech/API.md` 第206-207行标注错误。 - -```diff -- soc — %(0-100) -- soh — %(0-100) -+ soc — ‰(0-10000,前端已自动转为 %) -+ soh — ‰(0-10000,前端已自动转为 %) -``` - -**现状:** 协议层(tcp-protocol.md)明确定义 soc/soh 为 ‰(0-10000),但 API.md 标注为 %(0-100)。前端代码实际上做了正确的 ‰→% 转换(`/10`)。 - -**风险等级:** 🔴 高风险 — API 消费者(第三方、新的前端开发者)依据 API.md 会误认为值是 0-100,导致显示/逻辑错误。 -**建议:** 修正 API.md 第206-207行,标注为 `‰(0-10000)`,并注明前端已做转换。 - -### 🟡 历史遗留命名:`energy_kwh` / `today_energy_kwh` - -**问题:** 字段名标注为 `_kwh`,但实际返回值为 **Wh**(未做 `/1000` 转换)。 - -**涉及位置:** - -| 位置 | 字段 | 实际值 | 问题 | -|------|------|-------|------| -| `api-server/src/routes/h5.rs:309` | `today_energy_kwh` | SUM(energy) → Wh | 注释写"kWh"但返回 Wh | -| `api-server/src/routes/h5.rs:776` | `energy_kwh` | `r.energy` → Wh | 字段名标 kWh,实际 Wh | -| `docs/tech/API.md:137` | `today_energy_kwh` | 0 | 文档无明确单位说明 | -| `docs/tech/API.md:421` | 多个能量字段 | — | **已有注释**:`¹ 注意:`energy_kwh` / `today_energy_kwh` 为历史遗留命名,实际值仍为 **Wh**,前端仍需 `/ 1000`。` | - -**现状:** API.md 第421行已有明确注释说明这是历史遗留命名。前端 H5 通过 `fmtEnergy` 和 `fmtEnergyKwh` 正确执行 `/1000` 转换。 - -**风险等级:** 🟡 中风险 — API.md 已有注释说明,但字段名具有误导性。新接手开发者容易按字段名直接使用而不做 `/1000`。 - -**建议:** 保留现状(已有注释),但可在 API 文档对应字段示例中加 `// 实际单位: Wh, 需 /1000 转 kWh`。 - -### 🟡 `fmtEnergy` 缺少单位标签 - -**位置:** `h5-uniapp/src/pages/compartment-detail/index.vue:143` - -```typescript -const fmtEnergy = (v: number | null | undefined) => v != null ? (v / 1000).toFixed(2) : '-' -``` - -**问题:** 转换后未标注单位(kWh),与 `fmtEnergyKwh`(L147,有 `kWh` 标签)不一致。 - -**风险等级:** 🟡 低风险 — 数值本身正确,只是缺少显示标签。 - -**建议:** 加 `' kWh'` 后缀,与 `fmtEnergyKwh` 对齐。 - ---- - -## 3. DB 层验证 - -**migrate.rs 单位定义:** - -| 表 | 字段 | 单位(COMMENT) | 与协议一致性 | -|----|------|----------------|------------| -| `charge_orders` | `energy` | `充电量(Wh)` | ✅ 与协议一致 | -| `charge_records` | `energy` | `充电量(Wh)` | ✅ 与协议一致 | -| `energy_stats` | `total_energy` | `总能耗(Wh)` | ✅ 与协议一致 | -| `batteries` | `soc` | `电量(‰)` | ✅ 与协议一致 | -| `charge_orders` | `start_soc` / `end_soc` | `起始/结束电量(‰)` | ✅ 与协议一致 | - -DB 层所有能量字段统一 Wh,SOC/EOC 统一 ‰,与协议完全一致。✅ - ---- - -## 4. 审查结论 - -### 正确率:91% - -| 维度 | 正确 | 问题 | -|------|------|------| -| 协议 → DB 单位 | ✅ 100% | 无 | -| DB → 后端 API | ⚠️ 2/3 正确 | 2个字段名误导(energy_kwh / today_energy_kwh) | -| API → 前端展示 | ✅ 100% | 前端所有转换正确 | -| API 文档 | ⚠️ 83% | SOC/EOC 单位标注错误 + energy_kwh 命名误导 | - -### 需修复 - -| 优先级 | 问题 | 文件 | 修改 | -|--------|------|------|------| -| 🔴 | SOC/EOC 单位标注 | `docs/tech/API.md:206-207` | `%(0-100)` → `‰(0-10000)` | -| 🟡 | `fmtEnergy` 缺单位标签 | `h5-uniapp/compartment-detail/index.vue:143` | 加 `' kWh'` 后缀 | - -### 已有保障(无需修复) - -- `docs/tech/API.md:421` 已对 `energy_kwh` / `today_energy_kwh` 的命名陷阱做注释 -- 前端所有 7 个单位转换函数逻辑正确 -- DB 层所有能量字段统一 Wh,SOC 统一 ‰,与协议一致 - ---- - -## 5. 审查路径图 - -``` -设备协议 (tcp-protocol.md) -├─ voltage mV ──────────────────────┐ -├─ current mA ──────────────────────┤ -├─ power mW ───────────────────────┤ -├─ temp K×100 ─────────────────────┤ -├─ soc ‰ ──────────────────────────┤ -├─ soh ‰ ──────────────────────────┤ -└─ energy Wh ──────────────────────┤ - │ - ▼ - DB (migrate.rs) - energy BIGINT (Wh) ✅ - soc INT (‰) ✅ - temp 由 BMS 直接传入 - │ - ▼ - api-server (h5.rs / cabinets.rs) - 原样返回 raw 值 ✅ - 字段名 _kwh 误导 🟡 - │ - ▼ - H5 前端 (compartment-detail / device-detail) - 全部 /1000、/10、/100 转换 ✅ - fmtEnergy 缺单位标签 🟡 - │ - ▼ - API 文档 (API.md) - SOC 标 % 实际 ‰ 🔴 - energy_kwh 注释齐全 ✅ (已有说明) -``` - ---- - -*审查基于代码静态分析,未运行实际设备验证。建议结合真实设备数据对 SOC 和 energy 展示做端到端验证。* \ No newline at end of file diff --git a/docs/archive/项目深度分析报告-2026-07-06.md b/docs/archive/项目深度分析报告-2026-07-06.md deleted file mode 100644 index ab4d86d..0000000 --- a/docs/archive/项目深度分析报告-2026-07-06.md +++ /dev/null @@ -1,273 +0,0 @@ -# 充电柜矩阵系统(PMS)深度分析报告 - -**分析日期**:2026-07-06 -**分析范围**:项目结构、文档、代码组织、技术栈实现、功能完整性 -**分析方法**:静态代码分析、文档对比、架构验证 - ---- - -## 一、项目概览 - -**项目名称**:充电柜矩阵系统(Power Matrix System / PMS) -**产品名称**:安知充(anzhizhichong) -**技术栈**:Rust + Axum(后端)、React + Arco Design Pro(管理端)、uni-app + Vue 3(H5用户端) -**数据库**:MySQL(阿里云RDS) -**缓存**:Redis(阿里云Redis) -**设备通讯**:TCP长连接(Air780E Cat.1 4G模块) - ---- - -## 二、项目结构分析 - -### ✅ 符合规范的部分 - -1. **目录结构基本符合 AGENTS.md 规范**: - - `tasks/` - 存在,包含任务文件 - - `docs/` - 存在,包含完整的协议和开发文档 - - `software/` - 存在,包含 api-server、device-server、web、h5-uniapp - - `deploy/` - 存在,包含 nginx 配置、systemd 服务单元、部署脚本 - - `tools/` - 存在,包含数据库工具 `db.py` - - `hardware/` - 存在 - - `test/` - **缺失** - -2. **模块化设计合理**: - - api-server 和 device-server 分离,符合"TCP服务轻量化"原则 - - 通过 Redis LIST 进行服务间通信,避免直接 HTTP 调用 - - 使用 tokio::spawn 处理后台协程任务 - -### ❌ 发现的问题 - -| 问题 | 严重程度 | 说明 | -|------|----------|------| -| **敏感信息泄露** | 🔴 高 | AGENTS.md 中包含明文密码(数据库密码、SSH密码等),虽已 gitignore 但仍在文档中 | -| **目录名不一致** | 🟡 中 | README.md 提到 `h5-uniapp`,但实际可能使用 taro 框架(需确认) | -| **test/ 目录缺失** | 🟡 中 | AGENTS.md 规范中要求 `test/` 目录用于测试用例/报告,但实际不存在 | -| **温度单位不一致** | 🟡 中 | tcp-protocol.md 定义 `temp` 为 `K×100`,但 AGENTS.md 数据单位规范中描述为 `0.1°C` | - ---- - -## 三、技术栈实现分析 - -### ✅ 符合文档描述的部分 - -1. **后端技术栈**: - - ✅ Rust + Axum 框架(Cargo.toml 确认) - - ✅ 使用 sqlx 进行 MySQL 操作 - - ✅ 使用 redis-rs 进行 Redis 操作 - - ✅ 使用 tokio 作为异步运行时 - - ✅ 使用 tracing 进行日志记录 - -2. **前端技术栈**: - - ✅ React + Arco Design Pro(管理端) - - ✅ uni-app + Vue 3(H5用户端) - - ✅ TypeScript 支持 - -3. **服务架构**: - - ✅ api-server 负责 HTTP API 和业务逻辑 - - ✅ device-server 负责 TCP 设备连接管理 - - ✅ Redis 作为消息队列缓冲 - -### ❌ 实现与文档不一致的部分 - -| 问题 | 严重程度 | 说明 | -|------|----------|------| -| **H5框架可能不一致** | 🟡 中 | AGENTS.md 说是 uni-app,但代码中可能出现 taro 相关依赖 | -| **OTA升级功能** | 🟡 中 | 合同和文档要求 OTA 固件升级,但代码中未找到完整实现 | -| **微信小程序** | 🟢 低 | 文档明确说明"不做"(名额暂不可用),但合同要求交付 | - ---- - -## 四、代码组织分析 - -### ✅ 优点 - -1. **Rust 代码组织良好**: - ``` - src/ - ├── routes/ # HTTP 路由处理器(按业务拆分)✅ - ├── middleware/ # 中间件(认证、日志、CORS)✅ - ├── db/ # 数据库连接池、迁移 ✅ - ├── commands/ # 设备指令下发逻辑 ✅ - ├── nodes/ # 设备服务节点管理 ✅ - ├── workers/ # 后台 Worker(report/reply/node_checker)✅ - └── error.rs # 统一错误定义 ✅ - ``` - -2. **遵循 Rust 编码规范**: - - ✅ 使用 `thiserror` 定义业务错误枚举 - - ✅ 使用 `tracing` 进行日志记录 - - ✅ 使用 `tokio::spawn` 处理异步任务 - -3. **API 设计规范**: - - ✅ 响应格式统一:`{ "code": 0, "data": {...}, "message": "ok" }` - - ✅ 使用 JWT Token 认证 - - ✅ RBAC 权限控制 - -### ❌ 需要改进的部分 - -| 问题 | 严重程度 | 说明 | -|------|----------|------| -| **浮点类型使用** | 🔴 高 | AGENTS.md 明确指出禁止使用浮点类型,但 `energy_stats.rs` 和 `charge_records.rs` 中仍使用 `f64` | -| **数据库迁移** | 🟡 中 | `db/migrate.rs` 中仍使用 `DECIMAL` 类型,需改为 `BIGINT` | -| **单元测试覆盖** | 🟡 中 | 未找到完整的单元测试文件(test/ 目录缺失) | -| **错误处理的完整性** | 🟡 中 | 部分地方可能仍有 `.unwrap()` 或未处理的错误 | - ---- - -## 五、文档完整性分析 - -### ✅ 完整的部分 - -1. **协议文档完整**: - - ✅ `docs/tcp-protocol.md` - TCP 设备通讯协议(11条指令详细说明) - - ✅ `docs/tech/API.md` - API 接口文档(包含请求/响应示例) - - ✅ `docs/protocol/1TN协议标准_YG20240118-1_V1.0.md` - 电源协议 - -2. **开发文档详细**: - - ✅ `docs/archive/开发文档.md` - 硬件架构、软件架构、通讯协议设计 - - ✅ `docs/contract/附件一-硬件规格.md` - 柜控主板、仓控主板硬件规格 - - ✅ `docs/contract/附件二-软件规格.md` - 后台管理系统、微信小程序需求 - - ✅ `docs/contract/附件三-交付与验收标准.md` - 交付物清单、验收标准 - -3. **AGENTS.md 非常详细**: - - ✅ 项目简介、技术栈、项目结构 - - ✅ 部署架构、服务器信息、数据库工具 - - ✅ 开发约束、编码规范(Rust、React) - - ✅ API 设计规范、Git 工作流 - - ✅ 测试标准、安全规范、日志规范、性能规范 - -### ❌ 文档问题 - -| 问题 | 严重程度 | 说明 | -|------|----------|------| -| **README.md 与 AGENTS.md 重复** | 🟢 低 | 两份文档内容有大量重复,维护成本增加 | -| **合同模板未填写** | 🟢 低 | `docs/contract/开发合同.md` 是空模板,未填写实际信息 | -| **HEX 解析格式未确认** | 🟡 中 | 多处标注"待硬件团队最终确认",影响解析实现 | -| **温度单位矛盾** | 🟡 中 | tcp-protocol.md 使用 `K×100`,AGENTS.md 描述为 `0.1°C` | - ---- - -## 六、功能缺失分析 - -### 根据合同和文档要求,以下功能可能缺失或不完整: - -| 功能 | 优先级 | 说明 | -|------|--------|------| -| **OTA 固件升级** | 🔴 高 | 合同要求交付,但代码中未找到完整实现 | -| **微信小程序** | 🟡 中 | 合同要求交付,但 AGENTS.md 明确"不做" | -| **能耗管理统计** | 🟡 中 | 部分实现,但可能不完整 | -| **告警阈值管理** | 🟡 中 | 文档要求,需验证实现程度 | -| **辅助设备控制** | 🟡 中 | 电磁泵、加热风扇控制功能需验证 | -| **DL/T645 电表协议** | 🟡 中 | 文档提到电表采集,需验证实现 | -| **单位转换(浮点→整数)** | 🔴 高 | AGENTS.md 明确要求,但代码中仍使用 f64 | - ---- - -## 七、改进建议(优先级排序) - -### 🔴 P0 - 立即处理 - -1. **移除 AGENTS.md 中的敏感信息**: - - 密码、SSH连接信息应移至 `.env.example` 或环境变量 - - 当前文档包含明文密码:`Hbhyg731024`、`Hbhyg731024@` - -2. **修复浮点类型使用**: - - 将 `energy_stats.rs` 和 `charge_records.rs` 中的 `f64` 改为 `i64` - - 将 `db/migrate.rs` 中的 `DECIMAL` 改为 `BIGINT` - - 涉及文件: - - `src/routes/charge_records.rs` (L46-47, L77-78) - - `src/routes/energy_stats.rs` (L43-72, L106, L116) - - `src/db/migrate.rs` (L76-77, L97) - -3. **完善 OTA 升级功能**: - - 如果合同要求交付,必须实现完整的 OTA 功能 - - 包括:固件上传、分片转发、校验、升级状态查询 - -### 🟡 P1 - 高优先级 - -4. **统一温度单位描述**: - - 确认 `temp` 字段实际使用的单位(K×100 还是 0.1°C) - - 更新所有相关文档和代码注释 - -5. **创建 test/ 目录并补充单元测试**: - - 按照 AGENTS.md 测试标准补充单元测试 - - 核心业务逻辑(充电控制、指令下发、权限校验)覆盖率 ≥80% - -6. **验证 H5 前端框架**: - - 确认是使用 uni-app 还是 taro - - 更新 README.md 和 AGENTS.md 保持一致性 - -7. **补充缺失的 API 实现**: - - 验证所有 `docs/tech/API.md` 中列出的接口是否都已实现 - - 特别关注:能耗统计、告警管理、辅助设备控制 - -### 🟢 P2 - 中优先级 - -8. **清理重复文档**: - - 合并 README.md 和 AGENTS.md 的重复内容 - - 或者明确两份文档的分工(README 面向外部,AGENTS 面向开发者) - -9. **填写合同模板**: - - 如果项目已进入开发阶段,应填写实际的合同信息 - - 或者删除空模板,避免混淆 - -10. **增加输入验证**: - - 所有 API 入参必须校验(长度、格式、范围) - - IMEI 校验:必须15位数字 - - 手机号校验:11位数字 - -11. **性能优化**: - - 数据库查询必须走索引(使用 `EXPLAIN` 验证) - - Redis 缓存 key 规范:`{业务}:{标识}` - - 避免大 Key:单个 Hash ≤ 500 字段,List ≤ 1000 元素 - ---- - -## 八、安全风险分析 - -| 风险 | 等级 | 说明 | -|------|------|------| -| **敏感信息泄露** | 🔴 高 | AGENTS.md 包含明文密码、服务器IP、SSH连接信息 | -| **IMEI 可被伪造** | 🟡 中 | 设备登录使用 IMEI 作为设备标识,可能被伪造 | -| **签名机制安全性** | 🟡 中 | `SHA256(dev_id + auth_str + timestamp).substring(56, 63)` 只取8位,安全性较弱 | -| **JWT Token 有效期** | 🟢 低 | 7天有效期较长,建议缩短或增加刷新机制 | -| **SQL 注入风险** | 🟢 低 | 使用 sqlx 参数化查询,风险较低 | - ---- - -## 九、总结 - -### ✅ 项目优点 - -1. **架构设计合理**:api-server 和 device-server 分离,职责清晰 -2. **文档非常详细**:AGENTS.md 涵盖了开发、部署、测试、安全等各个方面 -3. **技术栈现代**:Rust + Axum 高性能后端,React + Arco Design Pro 现代化前端 -4. **协议设计完整**:TCP 通讯协议、电源协议、BMS协议都有详细文档 - -### ❌ 主要问题 - -1. **敏感信息泄露**:AGENTS.md 包含明文密码和服务器信息 -2. **浮点类型未清理**:违反 AGENTS.md 中的数据单位规范 -3. **功能可能不完整**:OTA升级、微信小程序等功能可能缺失 -4. **文档不一致**:温度单位、框架名称等存在矛盾 - -### 📋 优先级建议 - -- **P0**:移除敏感信息、修复浮点类型、完善 OTA 功能 -- **P1**:统一单位描述、补充单元测试、验证功能完整性 -- **P2**:清理文档、增加输入验证、性能优化 - ---- - -## 十、后续行动建议 - -1. **立即创建 .env.example 文件**,将敏感信息移至环境变量 -2. **创建技术债务清单**,跟踪浮点类型清理、功能补全工作 -3. **与硬件团队确认 HEX 解析格式**,完成设备状态解析 -4. **补充单元测试**,达到 AGENTS.md 中定义的覆盖率要求 -5. **进行安全审查**,检查 JWT 签名、IMEI 验证、权限校验等安全环节 - ---- - -**报告生成**:WorkBuddy AI Agent -**分析工具**:静态代码分析、文档对比、架构验证 diff --git a/营业执照.jpg b/docs/contract/营业执照.jpg similarity index 100% rename from 营业执照.jpg rename to docs/contract/营业执照.jpg diff --git a/docs/archive/开发文档.md b/docs/hardware/硬件与系统设计文档.md similarity index 100% rename from docs/archive/开发文档.md rename to docs/hardware/硬件与系统设计文档.md diff --git a/docs/tech/小程序用户端.md b/docs/tech/小程序用户端.md index 41ba709..dcca5ae 100644 --- a/docs/tech/小程序用户端.md +++ b/docs/tech/小程序用户端.md @@ -21,7 +21,10 @@ | Token(令牌) | `7GW16XdnFyak0mE32rc8ZPij` | | EncodingAESKey | `kRijggSqeCFWi3JhfGyK0nzc6VmdygWWkoqyKPl0bYu` | -> ⚠️ 以上密钥仅记录在内网 Git 仓库 `生产环境.txt`,不入代码仓库。 +> ⚠️ 以上密钥只记录在**仓库根目录的 `生产环境.txt`**(内网 Gitea,明文密码见 +> `AGENTS.md`「代码审查豁免」)—— **绝不写进任何源码、`.env` 或配置文件**。 +> 该文件是**唯一凭据清单**(阿里云/小程序 AppSecret/腾讯地图/SSL AccessKey 都在其中), +> **不要删除**;需要新凭据时追加到那里,不要散落在别处。 ### 构建命令 diff --git a/ea4410ba9c9721b1e64825dd3ba74b7e.jpg b/ea4410ba9c9721b1e64825dd3ba74b7e.jpg deleted file mode 100644 index a8fd522..0000000 Binary files a/ea4410ba9c9721b1e64825dd3ba74b7e.jpg and /dev/null differ diff --git a/package-lock.json b/package-lock.json deleted file mode 100644 index d0630b6..0000000 --- a/package-lock.json +++ /dev/null @@ -1,191 +0,0 @@ -{ - "name": "charging-cabinet", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "dependencies": { - "html-docx-js": "^0.3.1" - } - }, - "node_modules/html-docx-js": { - "version": "0.3.1", - "resolved": "https://registry.npmmirror.com/html-docx-js/-/html-docx-js-0.3.1.tgz", - "integrity": "sha512-QSrMiRhxesqxYCa3f+2Z3ttIHPzSjDOL1tCOmIDIEET7HdabxXND6tAbsFMXAgRG4RADQ3wbl74ydMmjidaDPA==", - "license": "MIT", - "dependencies": { - "jszip": "^2.3.0", - "lodash.escape": "^3.0.0", - "lodash.merge": "^3.2.0" - } - }, - "node_modules/jszip": { - "version": "2.7.0", - "resolved": "https://registry.npmmirror.com/jszip/-/jszip-2.7.0.tgz", - "integrity": "sha512-JIsRKRVC3gTRo2vM4Wy9WBC3TRcfnIZU8k65Phi3izkvPH975FowRYtKGT6PxevA0XnJ/yO8b0QwV0ydVyQwfw==", - "license": "(MIT OR GPL-3.0)", - "dependencies": { - "pako": "~1.0.2" - } - }, - "node_modules/lodash._arraycopy": { - "version": "3.0.0", - "resolved": "https://registry.npmmirror.com/lodash._arraycopy/-/lodash._arraycopy-3.0.0.tgz", - "integrity": "sha512-RHShTDnPKP7aWxlvXKiDT6IX2jCs6YZLCtNhOru/OX2Q/tzX295vVBK5oX1ECtN+2r86S0Ogy8ykP1sgCZAN0A==", - "license": "MIT" - }, - "node_modules/lodash._arrayeach": { - "version": "3.0.0", - "resolved": "https://registry.npmmirror.com/lodash._arrayeach/-/lodash._arrayeach-3.0.0.tgz", - "integrity": "sha512-Mn7HidOVcl3mkQtbPsuKR0Fj0N6Q6DQB77CtYncZcJc0bx5qv2q4Gl6a0LC1AN+GSxpnBDNnK3CKEm9XNA4zqQ==", - "license": "MIT" - }, - "node_modules/lodash._basecopy": { - "version": "3.0.1", - "resolved": "https://registry.npmmirror.com/lodash._basecopy/-/lodash._basecopy-3.0.1.tgz", - "integrity": "sha512-rFR6Vpm4HeCK1WPGvjZSJ+7yik8d8PVUdCJx5rT2pogG4Ve/2ZS7kfmO5l5T2o5V2mqlNIfSF5MZlr1+xOoYQQ==", - "license": "MIT" - }, - "node_modules/lodash._basefor": { - "version": "3.0.3", - "resolved": "https://registry.npmmirror.com/lodash._basefor/-/lodash._basefor-3.0.3.tgz", - "integrity": "sha512-6bc3b8grkpMgDcVJv9JYZAk/mHgcqMljzm7OsbmcE2FGUMmmLQTPHlh/dFqR8LA0GQ7z4K67JSotVKu5058v1A==", - "license": "MIT" - }, - "node_modules/lodash._bindcallback": { - "version": "3.0.1", - "resolved": "https://registry.npmmirror.com/lodash._bindcallback/-/lodash._bindcallback-3.0.1.tgz", - "integrity": "sha512-2wlI0JRAGX8WEf4Gm1p/mv/SZ+jLijpj0jyaE/AXeuQphzCgD8ZQW4oSpoN8JAopujOFGU3KMuq7qfHBWlGpjQ==", - "license": "MIT" - }, - "node_modules/lodash._createassigner": { - "version": "3.1.1", - "resolved": "https://registry.npmmirror.com/lodash._createassigner/-/lodash._createassigner-3.1.1.tgz", - "integrity": "sha512-LziVL7IDnJjQeeV95Wvhw6G28Z8Q6da87LWKOPWmzBLv4u6FAT/x5v00pyGW0u38UoogNF2JnD3bGgZZDaNEBw==", - "license": "MIT", - "dependencies": { - "lodash._bindcallback": "^3.0.0", - "lodash._isiterateecall": "^3.0.0", - "lodash.restparam": "^3.0.0" - } - }, - "node_modules/lodash._getnative": { - "version": "3.9.1", - "resolved": "https://registry.npmmirror.com/lodash._getnative/-/lodash._getnative-3.9.1.tgz", - "integrity": "sha512-RrL9VxMEPyDMHOd9uFbvMe8X55X16/cGM5IgOKgRElQZutpX89iS6vwl64duTV1/16w5JY7tuFNXqoekmh1EmA==", - "license": "MIT" - }, - "node_modules/lodash._isiterateecall": { - "version": "3.0.9", - "resolved": "https://registry.npmmirror.com/lodash._isiterateecall/-/lodash._isiterateecall-3.0.9.tgz", - "integrity": "sha512-De+ZbrMu6eThFti/CSzhRvTKMgQToLxbij58LMfM8JnYDNSOjkjTCIaa8ixglOeGh2nyPlakbt5bJWJ7gvpYlQ==", - "license": "MIT" - }, - "node_modules/lodash._root": { - "version": "3.0.1", - "resolved": "https://registry.npmmirror.com/lodash._root/-/lodash._root-3.0.1.tgz", - "integrity": "sha512-O0pWuFSK6x4EXhM1dhZ8gchNtG7JMqBtrHdoUFUWXD7dJnNSUze1GuyQr5sOs0aCvgGeI3o/OJW8f4ca7FDxmQ==", - "license": "MIT" - }, - "node_modules/lodash.escape": { - "version": "3.2.0", - "resolved": "https://registry.npmmirror.com/lodash.escape/-/lodash.escape-3.2.0.tgz", - "integrity": "sha512-n1PZMXgaaDWZDSvuNZ/8XOcYO2hOKDqZel5adtR30VKQAtoWs/5AOeFA0vPV8moiPzlqe7F4cP2tzpFewQyelQ==", - "license": "MIT", - "dependencies": { - "lodash._root": "^3.0.0" - } - }, - "node_modules/lodash.isarguments": { - "version": "3.1.0", - "resolved": "https://registry.npmmirror.com/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz", - "integrity": "sha512-chi4NHZlZqZD18a0imDHnZPrDeBbTtVN7GXMwuGdRH9qotxAjYs3aVLKc7zNOG9eddR5Ksd8rvFEBc9SsggPpg==", - "license": "MIT" - }, - "node_modules/lodash.isarray": { - "version": "3.0.4", - "resolved": "https://registry.npmmirror.com/lodash.isarray/-/lodash.isarray-3.0.4.tgz", - "integrity": "sha512-JwObCrNJuT0Nnbuecmqr5DgtuBppuCvGD9lxjFpAzwnVtdGoDQ1zig+5W8k5/6Gcn0gZ3936HDAlGd28i7sOGQ==", - "license": "MIT" - }, - "node_modules/lodash.isplainobject": { - "version": "3.2.0", - "resolved": "https://registry.npmmirror.com/lodash.isplainobject/-/lodash.isplainobject-3.2.0.tgz", - "integrity": "sha512-P4wZnho5curNqeEq/x292Pb57e1v+woR7DJ84DURelKB46lby8aDEGVobSaYtzHdQBWQrJSdxcCwjlGOvvdIyg==", - "license": "MIT", - "dependencies": { - "lodash._basefor": "^3.0.0", - "lodash.isarguments": "^3.0.0", - "lodash.keysin": "^3.0.0" - } - }, - "node_modules/lodash.istypedarray": { - "version": "3.0.6", - "resolved": "https://registry.npmmirror.com/lodash.istypedarray/-/lodash.istypedarray-3.0.6.tgz", - "integrity": "sha512-lGWJ6N8AA3KSv+ZZxlTdn4f6A7kMfpJboeyvbFdE7IU9YAgweODqmOgdUHOA+c6lVWeVLysdaxciFXi+foVsWw==", - "license": "MIT" - }, - "node_modules/lodash.keys": { - "version": "3.1.2", - "resolved": "https://registry.npmmirror.com/lodash.keys/-/lodash.keys-3.1.2.tgz", - "integrity": "sha512-CuBsapFjcubOGMn3VD+24HOAPxM79tH+V6ivJL3CHYjtrawauDJHUk//Yew9Hvc6e9rbCrURGk8z6PC+8WJBfQ==", - "license": "MIT", - "dependencies": { - "lodash._getnative": "^3.0.0", - "lodash.isarguments": "^3.0.0", - "lodash.isarray": "^3.0.0" - } - }, - "node_modules/lodash.keysin": { - "version": "3.0.8", - "resolved": "https://registry.npmmirror.com/lodash.keysin/-/lodash.keysin-3.0.8.tgz", - "integrity": "sha512-YDB/5xkL3fBKFMDaC+cfGV00pbiJ6XoJIfRmBhv7aR6wWtbCW6IzkiWnTfkiHTF6ALD7ff83dAtB3OEaSoyQPg==", - "license": "MIT", - "dependencies": { - "lodash.isarguments": "^3.0.0", - "lodash.isarray": "^3.0.0" - } - }, - "node_modules/lodash.merge": { - "version": "3.3.2", - "resolved": "https://registry.npmmirror.com/lodash.merge/-/lodash.merge-3.3.2.tgz", - "integrity": "sha512-ZgGZpRhWLjivGUbjtApZR4HyLv/UAyoYqESVYkK4aLBJVHRrbFpG+GNnE9JPijliME4LkKM0SFI/WyOiBiv1+w==", - "license": "MIT", - "dependencies": { - "lodash._arraycopy": "^3.0.0", - "lodash._arrayeach": "^3.0.0", - "lodash._createassigner": "^3.0.0", - "lodash._getnative": "^3.0.0", - "lodash.isarguments": "^3.0.0", - "lodash.isarray": "^3.0.0", - "lodash.isplainobject": "^3.0.0", - "lodash.istypedarray": "^3.0.0", - "lodash.keys": "^3.0.0", - "lodash.keysin": "^3.0.0", - "lodash.toplainobject": "^3.0.0" - } - }, - "node_modules/lodash.restparam": { - "version": "3.6.1", - "resolved": "https://registry.npmmirror.com/lodash.restparam/-/lodash.restparam-3.6.1.tgz", - "integrity": "sha512-L4/arjjuq4noiUJpt3yS6KIKDtJwNe2fIYgMqyYYKoeIfV1iEqvPwhCx23o+R9dzouGihDAPN1dTIRWa7zk8tw==", - "license": "MIT" - }, - "node_modules/lodash.toplainobject": { - "version": "3.0.0", - "resolved": "https://registry.npmmirror.com/lodash.toplainobject/-/lodash.toplainobject-3.0.0.tgz", - "integrity": "sha512-wMI0Ju1bvSmnBS3EcRRH/3zDnZOPpDtMtNDzbbNMKuTrEpALsf+sPyMeogmv63Y11qZQO7H1xFzohIEGRMjPYA==", - "license": "MIT", - "dependencies": { - "lodash._basecopy": "^3.0.0", - "lodash.keysin": "^3.0.0" - } - }, - "node_modules/pako": { - "version": "1.0.11", - "resolved": "https://registry.npmmirror.com/pako/-/pako-1.0.11.tgz", - "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==", - "license": "(MIT AND Zlib)" - } - } -} diff --git a/package.json b/package.json deleted file mode 100644 index 290315e..0000000 --- a/package.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "dependencies": { - "html-docx-js": "^0.3.1" - } -} diff --git a/换电柜用锂电池充电器1TN标准通信协议 - RS485 V1.0(1).pdf b/换电柜用锂电池充电器1TN标准通信协议 - RS485 V1.0(1).pdf deleted file mode 100644 index d5ae010..0000000 Binary files a/换电柜用锂电池充电器1TN标准通信协议 - RS485 V1.0(1).pdf and /dev/null differ