Files
smart-project/docs/api.md
Jesxion ba5d65d438 feat: 完成API详细设计+数据库表结构(隐患/施工日志/AI分析)
- docs/api.md: 补充隐患随手拍(5个端点)、施工日志(3个端点)、AI分析(2个端点)
- docs/database.md: 全面重写,MySQL+project_id隔离,新增projects/hazards/construction_logs/ai_analysis_results四张表
- SPEC.md: 更新至v0.2.1
2026-04-14 16:44:21 +08:00

923 lines
21 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 后台 API 接口设计
> 状态: 设计中(设备推送协议已确认,待服务器部署地址)
---
## 0. 设备数据推送协议(厂家 → 后台)
> 数据流向:厂家系统 → 我们的后台 API统一入口 `/input/post/call`
### 0.1 认证接口
```
POST /input/auth/fetch
```
**请求体**:
```json
{
"appid": "项目专用appidTBD",
"secret": "项目专用secretTBD"
}
```
**响应** (200):
```json
{
"code": 200,
"data": {
"appid": "xxx",
"access_token": "eyJhbGci...",
"expires_in": 7200
}
}
```
> `access_token` 有效期 2 小时,后续调用统一推送接口时需在 Header 携带 `Authorization: Bearer <access_token>`
### 0.2 统一推送接口
厂家所有数据通过此接口推送,`path` 指定具体业务接口:
```
POST /input/post/call
Authorization: Bearer <access_token>
```
**请求体**:
```json
{
"path": "/towercranedataservice/pushRealTimeInfo",
"data": { /* */ }
}
```
---
### 0.3 塔吊接口towercranedataservice
#### 3.1 基础信息 `pushBasicInfo`
| 参数 | 类型 | 必须 | 说明 |
|------|------|------|------|
| deviceSN | C50 | 是 | 设备序列号 |
| deviceID | C50 | 否 | 设备ID |
| deviceAuthCode | C50 | 否 | 设备授权码 |
| monitorDateTime | C50 | 是 | 数据发送时间 yyyy-MM-dd HH:mm:ss |
| craneType | C1 | 是 | 塔机类型0动臂吊/1塔头平臂吊/2平头平臂吊 |
| weightSet/windSpeedSet/rangeSet/heightSet/angleSet/obliguitySet/gpsSet/idSet/multiFunSet | C1 | 是 | 各功能配置0未配置/1已配置 |
| bodyHeight | N5.2 | 是 | 塔身高度(m) |
| topHeight | N5.2 | 是 | 塔顶高度 |
| magnification | N4 | 是 | 绳索倍率 |
| frontArmLength | N5.2 | 是 | 前臂长 0.00~99.99m |
| backArmLength | N5.2 | 是 | 尾臂长 |
| maxWeight | N5.2 | 是 | 最大吊重 0.00~99.99t |
| ratedWindSpeed | N5.2 | 是 | 额定风速 0.00~36.90m/s |
| ratedWindLevel | N2 | 是 | 额定风级 0~12级 |
| minRange/maxRange | N5.2 | 是 | 最小/最大变幅 |
| maxHeight | N6.2 | 是 | 最大高度 0.00~655.35m |
| maxAngle | N5.2 | 是 | 最大角度 0.0~540.0° |
| minAngle | N6.1 | 是 | 最小角度 -540.0°~0.0° |
| ratedObliguity | N4.2 | 是 | 额定倾角 0.00~9.99° |
#### 3.2 实时数据 `pushRealTimeInfo`
| 参数 | 类型 | 必须 | 说明 |
|------|------|------|------|
| deviceSN | C50 | 是 | 设备序列号 |
| monitorDateTime | C50 | 是 | 数据发送时间 |
| name | C20 | 是 | 操作人员姓名 |
| idNo | C20 | 是 | 操作人员身份证号 |
| multiple | N2 | 是 | 倍率 0~655% |
| moment | N10.2 | 是 | 力矩百分比 0.00~655.35% |
| weight | N5.2 | 是 | 载重 0.00~99.99t |
| windSpeed | N5.2 | 是 | 风速 0.00~36.90m/s |
| windLevel | N2 | 是 | 风级 0~12级 |
| rrange | N5.2 | 是 | 幅度 0.00~99.99m |
| height | N6.2 | 是 | 高度 0.00~655.35m |
| angle | N5.1 | 是 | 角度 0.0~359.9° |
| obliguity | N4.2 | 是 | 倾角 -9.99~9.99° |
#### 3.3 工作循环 `pushworkCycleInfo`
记录每次吊装作业的完整数据字段包含workStartDateTime/workEndDateTime/workWeight/workMaxTorqueRange/workMaxTorque/workMaxWindSpeed/workMaxHeight/workMaxForce 等。
#### 3.4 报警信息 `pushAlarmInfo`
| 参数 | 类型 | 必须 | 说明 |
|------|------|------|------|
| deviceSN | C50 | 是 | 设备序列号 |
| alarmDateTime | C20 | 是 | 警报时间 |
| warnType | C20 | 是 | 报警类型A:高度 B:力矩 C:碰撞 D:风速 E:幅度 F:回转 G:倾角 H:重量 |
| momentAlarm/collideAlarm/windSpeedAlarm/heightAlarm/rangeAlarm/angleAlarm/obliguityAlarm/weightAlarm | C1 | 是 | 各报警状态0正常/1报警/2预警 |
| weight | N5.2 | 是 | 报警时刻载重 |
| windSpeed | N5.2 | 是 | 报警时刻风速 |
| range | N5.2 | 是 | 报警时刻幅度 |
| height | N6.2 | 是 | 报警时刻高度 |
| tiltAngle | N4.2 | 是 | 倾角 |
### 0.4 升降机接口elevatordataservice
#### 4.1 基础信息 `pushBasicInfo`
| 参数 | 类型 | 必须 | 说明 |
|------|------|------|------|
| deviceSN | C50 | 是 | 设备序列号 |
| monitorDateTime | C50 | 是 | 数据发送时间 |
| craneType | C1 | 是 | 升降机类型1单笼/2双笼 |
| idExist/peopleExist/weightExist/speedExist/heightExist/floorExist/obliguityXExist/obliguityYExist/windExist/gpsExist/wirelessExist/topExist/antiDropExist | C1 | 是 | 各功能配置 |
| ratedPeople | N2 | 是 | 额定运载人数 1~20 |
| ratedWeight | N4.2 | 是 | 额定载重 0.00~9.99t |
| ratedUpSpeed/ratedDownSpeed | N4.2 | 是 | 额定上/下行速度 |
| ratedHeight | N5.1 | 是 | 额定高度 0.0~999.9m |
| ratedObliguityX/ratedObliguityY | N4.2 | 是 | 额定X/Y轴倾角 |
| ratedWindSpeed | N5.2 | 是 | 额定风速 |
| ratedWindLevel | N2 | 是 | 额定风级 |
#### 4.2 实时数据 `pushRealTimeInfo`
| 参数 | 类型 | 必须 | 说明 |
|------|------|------|------|
| deviceSN | C50 | 是 | 设备序列号 |
| monitorDateTime | C50 | 是 | 数据发送时间 |
| name | C25 | 是 | 操作人员姓名 |
| idNo | C18 | 是 | 身份证号 |
| realtimeWeight | N4.2 | 是 | 实时载重 0.00~9.99t |
| realtimeSpeed | N4.2 | 是 | 实时运行速度 |
| realtimeHeight | N5.1 | 是 | 实时高度 0.0~999.9m |
| realtimeDipX/realtimeDipY | N4.2 | 是 | 实时X/Y倾角 |
| outDoorStatus | C1 | 是 | 笼门状态0全部关闭/1全部打开/2内笼门打开/3外笼门打开 |
#### 4.3 工作循环 `pushWorkCycleInfo`
记录每次运行的完整数据字段包含maxPeople/maxWeight/maxSpeed/startHeight/endHeight 等。
#### 4.4 报警信息 `pushAlarmInfo`
| 参数 | 类型 | 必须 | 说明 |
|------|------|------|------|
| deviceSN | C50 | 是 | 设备序列号 |
| alarmDateTime | C20 | 是 | 警报时间 |
| alarmType | C20 | 是 | 报警类型A:高度 B:速度 C:载重 D:人数 E:倾角 F:门状态 G:防坠器 |
| alarmFloor | N3 | 是 | 报警楼层 0~100 |
| alarmHeight | N5.2 | 是 | 报警高度 |
| alarmSpeed | N4.2 | 是 | 报警速度 |
| alarmWeight | N4.2 | 是 | 报警载重 |
| alarmDipX/alarmDipY | N4.2 | 是 | 报警X/Y倾角 |
| outDoorStatus | C1 | 是 | 报警时笼门状态 |
---
## 1. API 概览H5 客户端 → 后台 API
- **Base URL**: `https://api.example.com/v1`(部署时配置)
- **认证**: `Authorization: Bearer <jwt_token>`
- **数据格式**: JSON
- **字符编码**: UTF-8
---
## 2. 认证接口
### 2.1 登录
```
POST /auth/login
```
**请求体**:
```json
{
"username": "string",
"password": "string"
}
```
**响应** (200):
```json
{
"token": "eyJhbGciOiJIUzI1NiIs...",
"expires_at": "2026-04-15T11:00:00Z",
"user": {
"id": 1,
"username": "admin",
"role": "admin"
}
}
```
---
## 3. 设备接口
### 3.1 获取设备台账列表
```
GET /devices
```
**Query 参数**:
| 参数 | 类型 | 说明 |
|------|------|------|
| type | string | 设备类型: `tower_crane` / `elevator` / 空(全部) |
| status | string | 在线状态: `online` / `offline` / 空(全部) |
| page | int | 页码,默认 1 |
| page_size | int | 每页数量,默认 20 |
**响应** (200):
```json
{
"total": 100,
"page": 1,
"page_size": 20,
"items": [
{
"id": "device_001",
"name": "1号塔吊",
"type": "tower_crane",
"model": "QTZ500",
"location": "A区施工现场",
"status": "online",
"last_seen": "2026-04-14T10:30:00Z",
"install_date": "2026-01-15"
}
]
}
```
### 3.2 获取设备实时数据
```
GET /devices/{device_id}/realtime
```
**响应** (200):
```json
{
"device_id": "device_001",
"timestamp": "2026-04-14T10:30:00Z",
"data": {
// 塔吊
"load": 45.2, // 当前载重 (kN)
"range": 30.5, // 回转幅度 (m)
"height": 85.0, // 起升高度 (m)
"wind_speed": 5.2, // 风速 (m/s)
"torque": 320.5, // 力矩 (kN·m)
"angle": 120.5, // 回转角度 (°)
// 升降机
"speed": 1.2, // 升降速度 (m/s)
"floor": 12, // 当前楼层
"door_status": "closed"
}
}
```
### 3.3 获取设备历史数据
```
GET /devices/{device_id}/history
```
**Query 参数**:
| 参数 | 类型 | 说明 |
|------|------|------|
| start | datetime | 开始时间 ISO8601 |
| end | datetime | 结束时间 ISO8601 |
| metric | string | 指标字段名(可选,默认全量) |
| page | int | 页码 |
| page_size | int | 每页数量,默认 100 |
**响应** (200):
```json
{
"device_id": "device_001",
"total": 1000,
"items": [
{
"timestamp": "2026-04-14T10:00:00Z",
"load": 44.8,
"range": 30.2,
"height": 84.8
}
]
}
```
---
## 4. 预警接口
### 4.1 获取预警列表
```
GET /alerts
```
**Query 参数**:
| 参数 | 类型 | 说明 |
|------|------|------|
| device_id | string | 设备ID可选 |
| level | string | 预警级别: `warning` / `danger` / 空(全部) |
| status | string | 处理状态: `unread` / `handled` / `ignored` / 空(全部) |
| page | int | 页码 |
| page_size | int | 每页数量,默认 20 |
**响应** (200):
```json
{
"total": 50,
"unread_count": 3,
"items": [
{
"id": "alert_001",
"device_id": "device_001",
"device_name": "1号塔吊",
"level": "danger",
"message": "载重超限: 当前45.2kN超过额定值40kN",
"metric": "load",
"value": 45.2,
"created_at": "2026-04-14T10:25:00Z",
"status": "unread"
}
]
}
```
### 4.2 获取预警详情
```
GET /alerts/{alert_id}
```
### 4.3 处理预警
```
POST /alerts/{alert_id}/handle
```
**请求体**:
```json
{
"action": "handled",
"note": "已现场确认,正常作业"
}
```
### 4.4 忽略预警
```
POST /alerts/{alert_id}/ignore
```
---
## 5. OSS 文件接口
> OSS 配置(开发测试): Bucket=`jesxion-ai-studio`, Region=`oss-cn-beijing`
### 5.1 获取上传凭证(预签名 URL
```
POST /oss/upload-token
```
**请求体**:
```json
{
"filename": "report_2026_04.pdf",
"content_type": "application/pdf"
}
```
**响应** (200):
```json
{
"upload_url": "https://bucket.oss-cn-beijing.aliyuncs.com/...",
"object_key": "reports/2026/04/report_xxx.pdf",
"expires_at": "2026-04-14T11:00:00Z"
}
```
### 5.2 获取文件下载链接
```
GET /oss/download-url
```
**Query 参数**:
| 参数 | 类型 | 说明 |
|------|------|------|
| object_key | string | OSS 对象路径 |
**响应** (200):
```json
{
"download_url": "https://bucket.oss-cn-beijing.aliyuncs.com/...?Signature=...",
"expires_at": "2026-04-14T12:00:00Z"
}
```
---
## 6. 通用响应格式
**成功**:
```json
{
"code": 0,
"message": "success",
"data": {}
}
```
**错误**:
```json
{
"code": 1001,
"message": "设备不存在",
"detail": "device_id: device_999 不在系统中"
}
```
**HTTP 状态码**:
| 状态码 | 说明 |
|--------|------|
| 200 | 成功 |
| 400 | 参数错误 |
| 401 | 未认证 |
| 403 | 无权限 |
| 404 | 资源不存在 |
| 500 | 服务器内部错误 |
---
## 7. 隐患随手拍接口
### 7.1 上报隐患
```
POST /v1/hazards
```
**请求体**:
```json
{
"category": "fall",
"severity": "general",
"description": "A区2楼临边防护缺失",
"photos": ["reports/2026/04/hazard_001_1.jpg", "reports/2026/04/hazard_001_2.jpg"],
"gps_lat": 34.7652,
"gps_lng": 113.6241
}
```
| 字段 | 类型 | 必填 | 说明 |
|------|------|------|------|
| category | string | 是 | 隐患类别代码 |
| severity | string | 是 | 严重程度: `general` / `serious` / `major` |
| description | string | 是 | 隐患描述2~500字 |
| photos | string[] | 否 | 照片 OSS object_key 列表(先调用 5.1 获取上传凭证) |
| gps_lat | decimal | 否 | GPS 纬度 |
| gps_lng | decimal | 否 | GPS 经度 |
**自动填充**(无需传入,后台从 JWT Token 解析):
- `reporter_id` — 上报人用户 ID
- `reporter_role` — 上报人身份
- `project_id` — 所属项目 ID中间件注入
- `status``pending`
- `reported_at` → 当前服务器时间
**响应** (201):
```json
{
"code": 0,
"message": "success",
"data": {
"id": "hazard_001",
"status": "pending",
"reported_at": "2026-04-14T14:30:00Z"
}
}
```
---
### 7.2 隐患列表
```
GET /v1/hazards
```
**Query 参数**:
| 参数 | 类型 | 说明 |
|------|------|------|
| status | string | 状态: `pending` / `assigned` / `resolved` / 空(全部) |
| category | string | 隐患类别代码 / 空(全部) |
| severity | string | 严重程度: `general` / `serious` / `major` / 空(全部) |
| start_date | date | 筛选开始日期 YYYY-MM-DD |
| end_date | date | 筛选结束日期 YYYY-MM-DD |
| page | int | 页码,默认 1 |
| page_size | int | 每页数量,默认 20最大 100 |
**响应** (200):
```json
{
"code": 0,
"message": "success",
"data": {
"total": 25,
"page": 1,
"page_size": 20,
"items": [
{
"id": "hazard_001",
"category": "fall",
"category_name": "高处坠落",
"severity": "general",
"severity_name": "一般",
"description": "A区2楼临边防护缺失",
"photo_count": 2,
"gps_lat": 34.7652,
"gps_lng": 113.6241,
"status": "pending",
"reporter": {
"id": 3,
"username": "zhangsan",
"role": "安全员"
},
"reporter_role": "安全员",
"reported_at": "2026-04-14T14:30:00Z",
"assignee": null,
"resolved_at": null
}
]
}
}
```
**说明**:
- 自动按 `project_id` 过滤(中间件注入)
- 结果按 `reported_at` 倒序
---
### 7.3 隐患详情
```
GET /v1/hazards/:id
```
**响应** (200):
```json
{
"code": 0,
"message": "success",
"data": {
"id": "hazard_001",
"category": "fall",
"category_name": "高处坠落",
"severity": "general",
"severity_name": "一般",
"description": "A区2楼临边防护缺失",
"photos": [
"https://jesxion-ai-studio.oss-cn-beijing.aliyuncs.com/reports/2026/04/hazard_001_1.jpg?Signature=...",
"https://jesxion-ai-studio.oss-cn-beijing.aliyuncs.com/reports/2026/04/hazard_001_2.jpg?Signature=..."
],
"gps_lat": 34.7652,
"gps_lng": 113.6241,
"status": "assigned",
"reporter": {
"id": 3,
"username": "zhangsan",
"role": "安全员"
},
"reported_at": "2026-04-14T14:30:00Z",
"assignee": {
"id": 5,
"username": "lisi",
"role": "安全负责人"
},
"assigned_at": "2026-04-14T15:00:00Z",
"resolved_at": null,
"resolve_note": null
}
}
```
**说明**:
- 照片返回完整预签名下载 URL有效 1 小时)
- `resolve_note``resolved` 状态时有值
---
### 7.4 认领隐患
```
POST /v1/hazards/:id/assign
```
**前置条件**: 隐患状态为 `pending`
**请求体**: 空对象 `{}`(操作人从 JWT Token 解析)
**自动填充**:
- `assignee_id` — 认领人用户 ID
- `assignee_role` — 认领人身份
- `status``assigned`
- `assigned_at` → 当前服务器时间
**响应** (200):
```json
{
"code": 0,
"message": "success",
"data": {
"id": "hazard_001",
"status": "assigned",
"assigned_at": "2026-04-14T15:00:00Z"
}
}
```
**错误**:
- `400` 隐患状态不是 `pending`(已认领或已处理)
---
### 7.5 处理完成
```
POST /v1/hazards/:id/resolve
```
**前置条件**: 隐患状态为 `assigned`
**请求体**:
```json
{
"note": "已重新安装防护栏"
}
```
| 字段 | 类型 | 必填 | 说明 |
|------|------|------|------|
| note | string | 否 | 处理说明0~500字 |
**自动填充**:
- `resolver_id` — 处理人用户 ID
- `resolver_role` — 处理人身份
- `status``resolved`
- `resolved_at` → 当前服务器时间
**响应** (200):
```json
{
"code": 0,
"message": "success",
"data": {
"id": "hazard_001",
"status": "resolved",
"resolved_at": "2026-04-14T16:00:00Z"
}
}
```
**错误**:
- `400` 隐患状态不是 `assigned`(未认领或已处理)
---
## 8. 施工日志接口
### 8.1 新建日志
```
POST /v1/logs
```
**请求体**:
```json
{
"date": "2026-04-14",
"part": "A区主体结构",
"content": "3层混凝土浇筑钢筋绑扎",
"workers": 28,
"equipment": ["tower_crane", "elevator"],
"photos": ["logs/2026/04/log_001_1.jpg"],
"safety_note": "临边作业已挂安全网",
"note": "下午2点停电1小时"
}
```
| 字段 | 类型 | 必填 | 说明 |
|------|------|------|------|
| date | date | 是 | 日志日期 YYYY-MM-DD |
| part | string | 是 | 施工部位2~100字 |
| content | text | 是 | 作业内容2~2000字 |
| workers | int | 是 | 人员出勤人数1~9999 |
| equipment | string[] | 否 | 设备运行类型: `tower_crane` / `elevator` |
| photos | string[] | 否 | 现场照片 OSS object_key 列表 |
| safety_note | text | 否 | 安全问题描述0~1000字 |
| note | text | 否 | 备注0~500字 |
**自动填充**:
- `author_id` — 撰写人用户 ID
- `author_role` — 撰写人身份
- `project_id` — 所属项目 ID
- `created_at` → 当前服务器时间
**响应** (201):
```json
{
"code": 0,
"message": "success",
"data": {
"id": "log_001",
"created_at": "2026-04-14T17:00:00Z"
}
}
```
---
### 8.2 日志列表
```
GET /v1/logs
```
**Query 参数**:
| 参数 | 类型 | 说明 |
|------|------|------|
| start_date | date | 筛选开始日期 YYYY-MM-DD |
| end_date | date | 筛选结束日期 YYYY-MM-DD |
| page | int | 页码,默认 1 |
| page_size | int | 每页数量,默认 20最大 100 |
**响应** (200):
```json
{
"code": 0,
"message": "success",
"data": {
"total": 30,
"page": 1,
"page_size": 20,
"items": [
{
"id": "log_001",
"date": "2026-04-14",
"part": "A区主体结构",
"content": "3层混凝土浇筑钢筋绑扎...",
"workers": 28,
"equipment": ["tower_crane", "elevator"],
"photo_count": 1,
"safety_note": "临边作业已挂安全网",
"author": {
"id": 3,
"username": "zhangsan",
"role": "安全员"
},
"created_at": "2026-04-14T17:00:00Z"
}
]
}
}
```
**说明**:
- 自动按 `project_id` 过滤
- `content` 列表页截断至 200 字
- 结果按 `date` 倒序
---
### 8.3 日志详情
```
GET /v1/logs/:id
```
**响应** (200):
```json
{
"code": 0,
"message": "success",
"data": {
"id": "log_001",
"date": "2026-04-14",
"part": "A区主体结构",
"content": "3层混凝土浇筑钢筋绑扎",
"workers": 28,
"equipment": ["tower_crane", "elevator"],
"equipment_names": ["塔吊", "升降机"],
"photos": [
"https://jesxion-ai-studio.oss-cn-beijing.aliyuncs.com/logs/2026/04/log_001_1.jpg?Signature=..."
],
"safety_note": "临边作业已挂安全网",
"note": "下午2点停电1小时",
"author": {
"id": 3,
"username": "zhangsan",
"role": "安全员"
},
"created_at": "2026-04-14T17:00:00Z"
}
}
```
**说明**:
- 照片返回完整预签名下载 URL有效 1 小时)
- `equipment_names` 为中文设备名称数组
---
## 9. AI 智能分析接口
### 9.1 分析结果列表
```
GET /v1/ai/analyses
```
**Query 参数**:
| 参数 | 类型 | 说明 |
|------|------|------|
| device_id | string | 设备ID / 空(全部) |
| analysis_type | string | 分析类型: `personnel_safety` / `equipment_anomaly` / `environmental_risk` / 空(全部) |
| start_date | datetime | 筛选开始时间 ISO8601 |
| end_date | datetime | 筛选结束时间 ISO8601 |
| page | int | 页码,默认 1 |
| page_size | int | 每页数量,默认 20最大 100 |
**响应** (200):
```json
{
"code": 0,
"message": "success",
"data": {
"total": 15,
"page": 1,
"page_size": 20,
"items": [
{
"id": "ai_001",
"device_id": "device_001",
"device_name": "1号塔吊",
"analysis_type": "personnel_safety",
"analysis_type_name": "人员安全",
"confidence": 0.92,
"description": "检测到人员靠近吊装区域,触发区域入侵告警",
"triggered_at": "2026-04-14T10:25:00Z"
}
]
}
}
```
**说明**:
- 自动按 `project_id` 过滤(中间件注入)
- 结果按 `triggered_at` 倒序
- `confidence` 为 0.00~1.00 小数
---
### 9.2 分析结果详情
```
GET /v1/ai/analyses/:id
```
**响应** (200):
```json
{
"code": 0,
"message": "success",
"data": {
"id": "ai_001",
"device_id": "device_001",
"device_name": "1号塔吊",
"analysis_type": "personnel_safety",
"analysis_type_name": "人员安全",
"confidence": 0.92,
"description": "检测到人员靠近吊装区域,触发区域入侵告警",
"suggestion": "建议立即疏散人员,后续加强吊装区域围挡和警示标志",
"triggered_at": "2026-04-14T10:25:00Z",
"created_at": "2026-04-14T10:25:05Z"
}
}
```
---
## 10. 待确认
- [x] 预警推送机制 → 轮询(前端每 30s
- [x] JWT 有效期 → 7 天
- [x] JWT Secret 管理 → 环境变量 `JWT_SECRET_KEY`
- [x] OSS 配置 → Bucket=`jesxion-ai-studio`, Region=`oss-cn-beijing`
- [x] 数据库 → SQLiteMVP
- [x] 设备推送协议 → 河南三农统一推送接口appid/secret 部署时配置)
- [ ] 后台 API 公网部署地址(阿里云服务器,部署时配置)