- API 路由统一: 移除 /api/h5/,统一 /api/pms/ 入口 - 二进制改名: api-server -> pms-api(与服务名一致) - nginx: 合并 /api/ + /pms/api/ 为 /api/pms/ - 新增 docs/API.md 接口文档 - 后端: CabinetDetail 增加 rssi/pow_fail/address/soc 等字段 - Redis 管道批量读取仓体实时数据(SOC/电压/电流/功率) - DB: 所有 TIMESTAMP 列改为 DATETIME(修复类型不匹配) - 用户管理: 新增创建时间/修改时间列,状态改用 Switch - 角色管理/用户管理: 操作按钮改为图标 - PC 设备详情: 基本信息补全 RSSI/ICCID/电源/地址 - PC 卡片: 通道统计改用 Lucide 图标,颜色统一 - PC 二维码: canvas 渲染,含编号文字,支持右键下载 - H5: 按 uni-app 规范修正导航(navigateTo 替代 reLaunch) - H5: 详情页加返回导航条 - H5: 扫码支持摄像头(jsQR)+ ?id= 参数 - H5: 底部 tabBar 在所有页面常显 - H5: 首页统计改为 6 项(设备/通道/空闲/充电/充满/故障) - H5: 下拉刷新 / 上拉加载 - 产品首页: 添加业务联系 - 文档: 清理过时文件,补充缺失规范章节
9.8 KiB
9.8 KiB
API 接口文档
充电柜矩阵系统(PMS)接口规范。PC 管理端与 H5 用户端共用同一套 API。
基础信息
- 测试环境:
https://test.anzhizhichong.com/pms/api/ - 正式环境:
https://app.anzhizhichong.com/pms/api/ - 认证方式:Bearer Token(JWT)
- 响应格式:
{ "code": 0, "data": ..., "message": "ok" }
统一端点清单
| 方法 | 路径 | 说明 | 权限 |
|---|---|---|---|
| POST | /api/auth/login |
登录 | 免认证 |
| GET | /api/auth/logout |
登出 | 需认证 |
| GET | /api/auth/me |
当前用户信息 | 需认证 |
| GET | /api/dashboard |
仪表盘数据 | 需认证 |
| GET | /api/cabinets |
设备列表(含 RSSI) | device:view |
| POST | /api/cabinets |
批量创建柜子 | device:create |
| GET | /api/cabinets/:id |
设备详情(含仓板+仓体) | device:view |
| PUT | /api/cabinets/:id |
更新柜子 | device:edit |
| DELETE | /api/cabinets/:id |
删除柜子 | device:delete |
| GET | /api/cabinets/abstract/:abstract_id |
扫码查设备(免认证) | 免认证 |
| GET | /api/cabinets/scan/:abstract_id |
扫码验证(需认证) | 需认证 |
| GET | /api/cabinets/filter |
设备列表(管理端) | 需认证 |
| GET | /api/cabinets/realtime-status |
设备实时状态 | 需认证 |
| GET | /api/compartments/:id |
仓体/通道详情 | 需认证 |
| POST | /api/charge/start |
开始充电 | charge:start |
| POST | /api/charge/stop |
停止充电 | charge:stop |
| POST | /api/door/open |
开门 | device:door:unlock |
| GET | /api/organizations |
组织列表 | org:view |
| POST | /api/organizations |
创建组织 | org:create |
| GET | /api/organizations/:org_id/projects |
项目列表 | 需认证 |
| GET | /api/charge-records |
充电记录 | charge_record:view |
| GET | /api/energy-stats/summary |
能耗统计 | 需认证 |
认证接口
POST /api/auth/login
请求:
{
"phone": "13800138000",
"password": "admin123"
}
响应:
{
"code": 0,
"data": {
"token": "eyJ0eXAi...",
"user": {
"id": 1,
"name": "管理员",
"phone": "13800138000",
"role_level": 2,
"organization_id": null,
"permissions": ["device:view", "device:create", "..."]
}
},
"message": "登录成功"
}
角色等级: 1=普通用户,2=超级管理员
H5 专用接口
GET /api/dashboard
H5 首页仪表盘数据。支持 org_id 参数按组织过滤。
响应:
{
"code": 0,
"data": {
"online_cabinets": 68,
"charging_count": 214,
"idle_channels": 722,
"fault_channels": 0,
"full_count": 0,
"today_charge_count": 0,
"today_energy_kwh": 0,
"today_charge_hours": 0,
"alerts": [],
"projects": [
{ "id": 1, "name": "无锡太湖新城换电站", "cabinet_count": 2, "charging": 16, "idle": 56, "fault": 0 }
]
}
}
GET /api/cabinets
设备列表,支持 project_id 和 org_id 过滤。响应包含实时 RSSI。
响应字段:
{
"id": 1,
"abstract_id": "10-00000001",
"name": "太湖新城换电柜A",
"status": 1,
"project_id": 1,
"rssi": 85,
"channel_count": 36,
"idle_count": 30,
"charging_count": 6,
"full_count": 0,
"fault_count": 0
}
GET /api/cabinets/abstract/:abstract_id
扫码入口,免认证。通过二维码中的抽象ID查找设备。
响应:
{
"code": 0,
"data": {
"id": 1,
"abstract_id": "10-00000001",
"imei": "864720562557021",
"iccid": "8986012520983901841",
"name": "太湖新城换电柜A",
"status": 1,
"cabin_boards": [
{
"id": 1,
"board_id": 1,
"status": 0,
"compartments": [
{ "id": 1, "channel_id": 1, "status": 0 }
]
}
]
}
}
GET /api/compartments/:id
仓体/通道详情,含实时 BMS 数据和充电记录。
响应字段:
voltage— mV(整数)current— mA(整数)power— mW(整数)energy— Wh(整数)soc— %(0-100)soh— %(0-100)cell_voltages— mV 数组
POST /api/charge/start
请求: { "compartment_id": 123 }
POST /api/charge/stop
请求: { "compartment_id": 123 }
POST /api/door/open
请求: { "compartment_id": 123 }
GET /api/cabinets/scan/:abstract_id
扫码验证,需认证。验证当前用户是否有权访问该设备。
数据单位规范
核心原则:所有数值字段使用整数存储,禁止浮点类型 (f32/f64/DECIMAL/FLOAT)
| 字段 | 类型 | 单位 | 说明 |
|---|---|---|---|
energy |
i64 | Wh | 充电量,不存小数 |
voltage |
i64 | mV | 电池组总电压 |
current |
i64 | mA | 电流,正=充电 负=放电 |
power |
i64 | mW | 功率 |
soc / soh |
i64 | % | 电量百分比 / 健康度 |
max_temperature |
i64 | 0.1°C | 25.3°C → 253 |
rssi |
i64 | dBm | 信号强度 |
温度转换: 前端显示时除以10加小数点(25.3°C → 253)
TCP 设备通讯协议
通信规则
- TCP 长连接,无需 PING 包
- 空闲 1 分钟上报,充电 15 秒上报
- 超时 5000ms
- JSON 去空格回车省流量,LF 处理粘包
dev_id:IMEI(10进制),sub_device_id:485 IDmsg_id:自增会话 ID- 全局通道号:
dev_id-sub_device_id-通道号(如123456789012345-01-6)
签名机制
- 设备首次连接调
auth_str接口获取8位安全码(仅一次) sign = SHA256(dev_id + auth_str + timestamp).substring(56, 63)- 时间戳秒级,平台校验±60秒
指令清单
| 动作 | 方向 | id格式 | 说明 |
|---|---|---|---|
login |
设备→平台 | 无 | 登录(含sign+timestamp) |
auth_str |
设备→平台 | 无 | 获取安全码(仅首次) |
status_post |
设备→平台 | 无 | 定时上报(rssi+status字典) |
pow_fail |
设备→平台 | 无 | 电源掉电上报 |
bat_in |
设备→平台 | IMEI-仓控板-通道 |
电池插入 |
bat_out |
设备→平台 | IMEI-仓控板-通道 |
电池拔出 |
on |
双向 | IMEI-仓控板-通道 |
开始充电 |
off |
双向 | IMEI-仓控板-通道 |
停止供电 |
open |
平台→设备 | IMEI |
开门 |
pow_on |
平台→设备 | IMEI |
接触器合闸 |
pow_off |
平台→设备 | IMEI |
接触器分闸 |
reset |
平台→设备 | IMEI 或 IMEI-仓控板 |
重启整柜或仓控板 |
指令详情
login(设备→平台)
{"act":"login","msg_id":1,"dev_id":"123456789012345","sign":"abc12345","timestamp":1719800000,"h_ver":"1.0.0","s_ver":"1.0.0"}
// 响应:{"suc":1,"msg_id":1,"cell":6}
auth_str(设备→平台)
{"act":"auth_str","msg_id":2,"dev_id":"123456789012345","ccid":"89860000000000000000"}
// 响应:{"suc":1,"msg_id":2,"data":{"auth_str":"abcd1234"}}
status_post(设备→平台)
{"act":"status_post","msg_id":10,"dev_id":"123456789012345","rssi":85,
"status":{"123456789012345-01":"000100020003000400050006"}}
// 响应:{"suc":1,"msg_id":10}
bat_in / bat_out(设备→平台)
{"act":"bat_in","msg_id":20,"id":"123456789012345-01-6","bms":{"soc":45,"voltage":52.3}}
{"act":"bat_out","msg_id":21,"id":"123456789012345-01-6"}
on / off(双向)
// 平台→设备:开始充电
{"act":"on","msg_id":30,"id":"123456789012345-01-6"}
// 设备→平台:充电开始确认
{"act":"on","msg_id":30,"id":"123456789012345-01-6"}
open(平台→设备)
{"act":"open","msg_id":40,"id":"123456789012345"}
// 错误码63 = 门锁故障
reset(平台→设备)
// 重启整柜
{"act":"reset","msg_id":60,"id":"123456789012345"}
// 重启仓控板
{"act":"reset","msg_id":61,"id":"123456789012345-01"}
充电结束原因
| 平台收到 | 判断原因 |
|---|---|
off (设备→平台) |
normal — 正常充满 |
off (平台→设备) |
user_stop — 用户手动停止 |
bat_out |
normal — 电池拔出 |
bat_in (通道已有电池) |
forced — 新电池插入强制结束 |
| 超时未响应 | timeout — 通信超时 |
Redis 实时状态存储
层级结构
device:{imei} # 设备级 Hash
├─ online = "1" # 在线标记(TTL 300秒)
├─ rssi = "85" # 信号强度
├─ pow_fail_dc = "0/1" # 直流停电
└─ device:{imei}:board:{board_idx} # 板级 Hash
├─ status_hex = "00010002..." # 原始hex状态
└─ device:{imei}:board:{board_idx}:ch:{0-5} # 通道级 Hash
├─ on = "0/1" # 充电中
├─ full = "0/1" # 充满
├─ fault = "0/1" # 故障
└─ hex = "00010002" # 原始hex
BMS 字段
| 字段 | 类型 | 单位 | 说明 |
|---|---|---|---|
soc |
i64 | % | 电池电量百分比 |
soh |
i64 | % | 电池健康度百分比 |
voltage |
i64 | mV | 电池组总电压 |
current |
i64 | mA | 电流 |
power |
i64 | mW | 功率 |
energy |
i64 | Wh | 累计充电量 |
cell_voltages |
i64[] | mV | 单体电芯电压数组 |
权限码列表
| 权限码 | 说明 |
|---|---|
device:view |
查看设备 |
device:create |
创建设备 |
device:edit |
编辑设备 |
device:delete |
删除设备 |
device:door:unlock |
开门 |
charge:start |
开始充电 |
charge:stop |
停止充电 |
charge_record:view |
查看充电记录 |
org:view |
查看组织 |
org:create |
创建组织 |
org:edit |
编辑组织 |