charging-cabinet/tasks/001-server-skeleton.md
2026-07-02 05:38:01 +08:00

7.3 KiB
Raw Blame 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

-- 组织表
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路由

注册以下基础路由:

// 健康检查
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无合理理由