fix: 统一字段命名为 camelCase 并修复详情 API

- models.rs: 将 inspectiontype/assignmentnumber 的 serde rename 改为
  inspectionType/assignmentNumber,与前端 TypeScript 接口保持一致
- models.rs: 为 WeatherDataBrief 添加 isFavorite 字段支持
- models.rs: WeatherData.is_favorite 添加 skip_deserializing 避免 POST
  请求解析失败,同时使用 default 处理数据库 NULL 值
- handlers/weather.rs: get_weather_details 支持 string 和 number 类型的
  id 参数解析
- IMPROVEMENTS.md: 新增第十三章记录本次对话经验(serde 配置、config
  路径解析、TOML 结构等)
This commit is contained in:
2026-04-17 20:47:00 +08:00
parent bdbba2cd60
commit 61b1174b30
6 changed files with 124 additions and 15 deletions

View File

@@ -562,7 +562,115 @@ fi
---
## 十二、付费功能系统
## 十三、本次对话经验总结
### 13.1 前后端字段命名一致性
**问题描述**
后端 Rust 使用 `#[serde(rename = "camelCase")]` 序列化 JSON 字段,前端 TypeScript 必须使用相同的 camelCase 命名才能正确解析。
**受影响字段**
| Rust 字段 | JSON 键 | 前端错误写法 | 前端正确写法 |
|-----------|---------|-------------|-------------|
| `is_favorite` | `isFavorite` | `is_favorite` | `isFavorite` |
| `inspection_type` | `inspectionType` | `inspection_type` | `inspectionType` |
| `assignment_number` | `assignmentNumber` | `assignment_number` | `assignmentNumber` |
**问题后果**
- 前端使用 snake_case 命名,接口返回的 camelCase 字段会是 `undefined`
- 详情页面显示 `undefined` 而非正确值
**验证方法**
```bash
# 搜索后端 serde rename 配置
grep -n 'rename = "' src/models.rs
```
**经验教训**
- API 接口字段命名应在前后端团队间统一约定
- 或让后端提供 JSON Schema / OpenAPI 文档
**参考**[LRN-20260417-015](file:///home/milky/Documents/ASD/.learnings/LEARNINGS.md#LRN-20260417-015)
---
### 13.2 serde 配置冲突
**问题描述**
`#[serde(skip_deserializing)]` 用于 POST 请求体解析(避免 id 字段),但在 SELECT 查询时会阻止字段被填充。
**错误配置**
```rust
#[serde(skip_deserializing)] // POST 时跳过,但 SELECT 时也跳过了
pub is_favorite: Option<bool>,
```
**正确配置**
```rust
#[serde(default)] // 缺失字段使用默认值
pub is_favorite: Option<bool>,
```
**经验教训**
- `skip_deserializing` 会导致数据库查询结果无法填充字段
- 对于需要同时支持上传和查询的字段,使用 `default`
**参考**[LRN-20260417-016](file:///home/milky/Documents/ASD/.learnings/LEARNINGS.md#LRN-20260417-016)
---
### 13.3 config crate 路径解析
**问题描述**
`File::with_name("config/default")` 查找文件相对于 `cargo run` 执行目录,而非 `CARGO_MANIFEST_DIR`。
**错误写法**
```rust
config::File::with_name("config/default") // 相对于 cwd
```
**正确写法**
```rust
let manifest_dir = std::env::var("CARGO_MANIFEST_DIR")
.map(PathBuf::from)
.expect("CARGO_MANIFEST_DIR not set");
let config_path = manifest_dir.join("config").join("default.toml");
```
**经验教训**
- 使用 `config` crate 的路径相关函数时注意基准目录
- 直接使用 `std::env::var("CARGO_MANIFEST_DIR")` 更可靠
**参考**[LRN-20260417-001](file:///home/milky/Documents/ASD/.learnings/LEARNINGS.md#LRN-20260417-001)
---
### 13.4 TOML 配置文件结构
**问题描述**
TOML 文件中的 `[development]` 等 section headers 与 `config` crate 的合并逻辑冲突。
**错误写法**
```toml
[development]
database_url = "..."
```
**正确写法**
```toml
database_url = "..."
environment = "development"
```
**经验教训**
- 保持 TOML 文件扁平结构,不使用 section headers
- 简化配置加载逻辑
**参考**[LRN-20260417-002](file:///home/milky/Documents/ASD/.learnings/LEARNINGS.md#LRN-20260417-002)
---
## 十四、付费功能系统
### 当前状态