charging-cabinet/tasks/001-server-skeleton.md

222 lines
7.3 KiB
Markdown
Raw Normal View History

# 任务001后端骨架
## 目标
搭建Rust + Axum后端项目骨架连接MySQL和Redis建立基础路由框架。
## 技术栈
- Rust + Axum + Tokio
- MySQL (sqlx)
- Redis (redis crate)
## 数据库连接
```
MySQL: 10.8.0.252:3306 (root / Hbhyg731024@)
Redis: 10.8.0.252:6379 (password: Hbhyg731024@, db: 5)
```
**注意:** 不要动现有的 `AZZCWeChat*` 数据库,新建 `pms_dev` 库。
## 项目结构
```
software/server/
├── Cargo.toml
├── src/
│ ├── main.rs # 启动入口
│ ├── config.rs # 配置管理
│ ├── db/
│ │ ├── mod.rs # MySQL连接池
│ │ └── migrate.rs # 数据库迁移(建表)
│ ├── redis.rs # Redis连接
│ ├── routes/
│ │ ├── mod.rs # 路由注册
│ │ └── health.rs # 健康检查接口
│ ── error.rs # 统一错误处理
```
## 数据库表
创建 `pms_dev`执行以下建表SQL
```sql
-- 组织表
CREATE TABLE organizations (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(100) NOT NULL COMMENT '组织名称',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-- 项目表
CREATE TABLE projects (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
organization_id BIGINT NOT NULL,
name VARCHAR(100) NOT NULL COMMENT '项目名称',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
FOREIGN KEY (organization_id) REFERENCES organizations(id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-- 充电柜表
CREATE TABLE cabinets (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
project_id BIGINT,
abstract_id VARCHAR(20) NOT NULL UNIQUE COMMENT '平台抽象ID如10-00000000',
imei VARCHAR(15) NOT NULL UNIQUE COMMENT '4G模块IMEI',
auth_str VARCHAR(8) COMMENT '签名安全码',
name VARCHAR(100) COMMENT '柜子名称',
status TINYINT DEFAULT 0 COMMENT '0离线 1在线',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
FOREIGN KEY (project_id) REFERENCES projects(id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-- 仓控板表
CREATE TABLE cabin_boards (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
cabinet_id BIGINT NOT NULL,
board_id TINYINT NOT NULL COMMENT '仓控板ID 1-6',
status TINYINT DEFAULT 0,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
FOREIGN KEY (cabinet_id) REFERENCES cabinets(id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-- 仓体表
CREATE TABLE compartments (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
cabin_board_id BIGINT NOT NULL,
channel_id TINYINT NOT NULL COMMENT '通道ID 1-6',
status TINYINT DEFAULT 0 COMMENT '0空闲 1充电中 2故障 3禁用',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
FOREIGN KEY (cabin_board_id) REFERENCES cabin_boards(id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-- 用户表
CREATE TABLE users (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
phone VARCHAR(11) NOT NULL UNIQUE COMMENT '手机号',
name VARCHAR(50) COMMENT '姓名',
password VARCHAR(100) NOT NULL,
role TINYINT DEFAULT 0 COMMENT '0普通 1企业管理员 2总管理员',
organization_id BIGINT,
status TINYINT DEFAULT 1 COMMENT '0禁用 1启用',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
FOREIGN KEY (organization_id) REFERENCES organizations(id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-- 充电记录表
CREATE TABLE charge_records (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
compartment_id BIGINT NOT NULL,
cabinet_id BIGINT NOT NULL,
start_time TIMESTAMP,
end_time TIMESTAMP,
energy DECIMAL(10,2) COMMENT '充电量kWh',
max_temperature DECIMAL(5,1) COMMENT '最高温度',
status TINYINT DEFAULT 0 COMMENT '0正常 1异常 2手动停止',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (compartment_id) REFERENCES compartments(id),
FOREIGN KEY (cabinet_id) REFERENCES cabinets(id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-- 设备日志表
CREATE TABLE device_logs (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
cabinet_id BIGINT NOT NULL,
log_type TINYINT NOT NULL COMMENT '1状态上报 2故障 3告警 4停电',
content TEXT COMMENT '日志内容JSON',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (cabinet_id) REFERENCES cabinets(id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-- 能耗统计表
CREATE TABLE energy_stats (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
cabinet_id BIGINT NOT NULL,
stat_date DATE NOT NULL,
total_energy DECIMAL(10,2) COMMENT '总能耗kWh',
charge_count INT DEFAULT 0 COMMENT '充电次数',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (cabinet_id) REFERENCES cabinets(id),
UNIQUE KEY uk_cabinet_date (cabinet_id, stat_date)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-- 操作日志表
CREATE TABLE operation_logs (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
user_id BIGINT NOT NULL,
action VARCHAR(100) NOT NULL COMMENT '操作动作',
target_type VARCHAR(50) COMMENT '操作对象类型',
target_id BIGINT COMMENT '操作对象ID',
detail TEXT COMMENT '操作详情',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (user_id) REFERENCES users(id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
```
## API路由
注册以下基础路由:
```rust
// 健康检查
GET /api/health → 返回 {"status": "ok"}
// 认证
POST /api/auth/login → 登录
POST /api/auth/logout → 登出
// 组织管理
GET /api/organizations → 组织列表
POST /api/organizations → 创建组织
PUT /api/organizations/:id → 更新组织
DELETE /api/organizations/:id → 删除组织
// 项目管理
GET /api/projects → 项目列表
POST /api/projects → 创建项目
PUT /api/projects/:id → 更新项目
DELETE /api/projects/:id → 删除项目
// 设备管理
GET /api/cabinets → 柜子列表
POST /api/cabinets → 添加柜子支持批量IMEI
PUT /api/cabinets/:id → 更新柜子
DELETE /api/cabinets/:id → 删除柜子
POST /api/cabinets/:id/regenerate-auth → 重新生成auth_str
// 充电记录
GET /api/charge-records → 充电记录列表
GET /api/charge-records/export → 导出充电记录
// 设备日志
GET /api/device-logs → 设备日志列表
// 能耗管理
GET /api/energy-stats → 能耗统计
// 用户管理
GET /api/users → 用户列表
POST /api/users → 创建用户
PUT /api/users/:id → 更新用户
PUT /api/users/:id/reset-password → 重置密码
// 操作日志
GET /api/operation-logs → 操作日志列表
```
## 质量约束
1. 完成代码后执行 `cargo check`,必须零报错、零警告
2. 分层拆分单函数≤80行命名语义化完整注释
3. 所有外部IO/网络请求异常捕获禁止裸panic
4. 分支逻辑全覆盖,不遗漏兜底分支
5. 常量抽离不使用废弃API
6. Rust内存安全合理管理所有权禁用unsafe无合理理由