diff --git a/doc/requirement/todo_lists.md b/doc/requirement/todo_lists.md index 58ba1830..97a01dcd 100644 --- a/doc/requirement/todo_lists.md +++ b/doc/requirement/todo_lists.md @@ -1,5 +1,9 @@ ## TODO Lists +### [2025-10-09] + +- [ ] (功能)模拟无人车平台,返回任务列表 + ### [2025-09-05] - [x] 模拟收到进出港航班信息,访问路由接口,获取路由信息并保存处理,同时发给前端显示路由 @@ -12,7 +16,7 @@ - [ ] 任务指定 - [ ] 无人车上行接口 - - [ ] 状态上报 + - [x] 状态上报 - [ ] 视频流 - [ ] 任务列表 - [ ] 任务执行状态 diff --git a/doc/requirement/数据中台SDK问题.md b/doc/requirement/数据中台SDK问题.md new file mode 100644 index 00000000..be49b74c --- /dev/null +++ b/doc/requirement/数据中台SDK问题.md @@ -0,0 +1,40 @@ +# 关于SDK的要了解的几个问题 + +## webService服务器的IP地址和端口号 +这个是数据中台服务的 IP 地址和端口?问谁可以获取到? + +## 调用路由接口需要的信息,从哪些事件获取? +包括: +inRunway :进港跑道编号 35 +outRunway:出港跑道编号 34 +contactCross:联络道口 F1 +seat:目的机位 138 + +文档中找到: +【动态航班机位分配变更事件(CRAFTSEAT)】中有机位信息 +【动态航班本站到达事件(ARR)】有到达信息 +【推出开车事件(AXOT)】有进出港标志 +【跑道号分配变更事件(RUNWAY)】有进出港标志和跑道信息 + +没有找到:联络道口信息 + +## 如何接收我们需要的事件? +receiveMessage()会接收所有的事件,还是会只返回我们需要的事件? +业务上是否需要进行接口申请和授权的流程? + +## 如何使用接收数据接口MessageResult receiveMessage()接口 +为了持续获取航班进出港事件,是不是需要持续调用这个接口?类似: + +```java +public void receiveLoop() { + while (true) { + Message message = receive(); // 接收消息 + + if (message != null) { + // 用新线程处理消息 + new Thread(() -> handleMessage(message)).start(); + } + } +} +``` + diff --git a/doc/working/20250110_任务清单接口设计方案.md b/doc/working/20250110_任务清单接口设计方案.md new file mode 100644 index 00000000..4034567e --- /dev/null +++ b/doc/working/20250110_任务清单接口设计方案.md @@ -0,0 +1,807 @@ +# 任务清单接口设计方案 + +**日期**: 2025-01-10 +**版本**: v1.0 +**目标**: 为无人车平台Mock服务增加任务清单接口 + +--- + +## 📋 需求背景 + +由无人车侧的平台(mock)提供一个单独的任务清单接口,可以返回无人车所有的可执行任务。然后,我们的应用请求这个接口,选择某个任务,下发给无人车去执行。 + +**核心概念**: 任务池/任务库 - 预定义的可执行任务模板清单 + +--- + +## 🎯 接口设计 + +### 接口信息 + +- **方法**: `GET /api/v1/missions/available` +- **认证**: Bearer Token (JWT) +- **响应**: `application/json; charset=utf-8` +- **功能**: 返回无人车平台的所有可执行任务清单 + +### 查询参数 + +| 参数名 | 类型 | 必填 | 描述 | 示例 | +|--------|------|------|------|------| +| missionType | string | 否 | 任务类型筛选 | PATROL_TRANSPORT, CARGO_TRANSPORT | +| priority | integer | 否 | 优先级筛选 | 1-5 | +| minBatteryLevel | integer | 否 | 最低电量要求 | 30 | +| limit | integer | 否 | 返回数量限制 | 10 | +| offset | integer | 否 | 分页偏移量 | 0 | + +### 请求头 + +| Header | 必填 | 示例 | 说明 | +|--------|------|------|------| +| Authorization | 是 | Bearer eyJhbGciOi... | JWT 鉴权令牌 | +| Content-Type | 是 | application/json | 固定为 JSON | +| Accept | 否 | application/json | 建议显式声明 | + +--- + +## 📦 数据结构设计 + +### 任务对象 (Mission) + +```json +{ + "missionId": "MISSION_TEMPLATE_001", + "missionName": "T1航站楼巡逻", + "missionType": "PATROL_TRANSPORT", + "description": "T1航站楼周边区域巡逻任务", + "priority": 3, + "estimatedDuration": 1800000, + "totalMileage": 2500.0, + "waypoints": [ + { + "waypointId": "WP_001", + "latitude": 36.354068, + "longitude": 120.083410, + "waypointType": "START", + "name": "T1航站楼东侧", + "altitude": 10.5, + "estimatedArrivalTime": null + }, + { + "waypointId": "WP_002", + "latitude": 36.355123, + "longitude": 120.084567, + "waypointType": "CHECKPOINT", + "name": "巡逻检查点A", + "altitude": 11.2, + "estimatedArrivalTime": null + }, + { + "waypointId": "WP_003", + "latitude": 36.356789, + "longitude": 120.085234, + "waypointType": "END", + "name": "T1航站楼北侧", + "altitude": 10.8, + "estimatedArrivalTime": null + } + ], + "requirements": { + "vehicleType": "UNMANNED", + "minBatteryLevel": 30, + "requiredSensors": ["GPS", "LIDAR", "CAMERA"], + "weatherConditions": "CLEAR | LIGHT_RAIN" + }, + "metadata": { + "createdTime": 1736175000000, + "createdBy": "system", + "tags": ["patrol", "security", "routine"], + "zone": "TERMINAL_1" + } +} +``` + +### 字段说明 + +#### 基础信息 +- `missionId` (string): 任务唯一标识 +- `missionName` (string): 任务名称 +- `missionType` (string): 任务类型 +- `description` (string): 任务描述 +- `priority` (integer): 优先级 1-5,数字越大优先级越高 + +#### 时间和里程 +- `estimatedDuration` (integer): 预计执行时长(毫秒) +- `totalMileage` (number): 预计总里程(米) + +#### 路径点 (waypoints) +- `waypointId` (string): 路径点ID +- `latitude` (number): 纬度 (WGS84) +- `longitude` (number): 经度 (WGS84) +- `waypointType` (string): 路径点类型 + - `START`: 起点 + - `CHECKPOINT`: 检查点 + - `WAYPOINT`: 普通路径点 + - `END`: 终点 +- `name` (string): 路径点名称 +- `altitude` (number, 可选): 海拔高度(米) +- `estimatedArrivalTime` (integer, 可选): 预计到达时间(毫秒,UTC) + +#### 任务要求 (requirements) +- `vehicleType` (string): 车辆类型要求 +- `minBatteryLevel` (integer): 最低电量要求 (0-100) +- `requiredSensors` (array): 必需的传感器列表 +- `weatherConditions` (string): 可执行天气条件 + +#### 元数据 (metadata) +- `createdTime` (integer): 创建时间(毫秒,UTC) +- `createdBy` (string): 创建者 +- `tags` (array): 标签列表 +- `zone` (string): 区域标识 + +--- + +## 📡 响应格式 + +### 成功响应 (200 OK) + +```json +{ + "code": 200, + "message": "success", + "timestamp": 1736175610000, + "data": { + "total": 5, + "missions": [ + { + "missionId": "MISSION_TEMPLATE_001", + "missionName": "T1航站楼巡逻", + "missionType": "PATROL_TRANSPORT", + "description": "T1航站楼周边区域巡逻任务", + "priority": 3, + "estimatedDuration": 1800000, + "totalMileage": 2500.0, + "waypoints": [...], + "requirements": {...}, + "metadata": {...} + }, + { + "missionId": "MISSION_TEMPLATE_002", + "missionName": "货物运输-仓库A到登机口B3", + "missionType": "CARGO_TRANSPORT", + "priority": 4, + "estimatedDuration": 900000, + "totalMileage": 1200.0, + "waypoints": [...], + "requirements": {...}, + "metadata": {...} + } + ] + } +} +``` + +### 错误响应 + +#### 401 未授权 +```json +{ + "code": 401, + "message": "Unauthorized: Invalid or expired token", + "timestamp": 1736175610000, + "data": null +} +``` + +#### 400 参数错误 +```json +{ + "code": 400, + "message": "Invalid parameter: missionType must be one of [PATROL_TRANSPORT, CARGO_TRANSPORT, PASSENGER_TRANSPORT]", + "timestamp": 1736175610000, + "data": null +} +``` + +--- + +## 🗂️ 任务类型定义 + +### 标准任务类型 + +| 任务类型 | 代码 | 描述 | +|---------|------|------| +| 巡逻运输 | PATROL_TRANSPORT | 定期巡逻和安全检查 | +| 货物运输 | CARGO_TRANSPORT | 货物运输和配送 | +| 客运服务 | PASSENGER_TRANSPORT | 旅客运输服务 | +| 应急响应 | EMERGENCY_RESPONSE | 应急事件响应 | +| 维护检查 | MAINTENANCE_INSPECTION | 设施维护和检查 | +| 清洁作业 | CLEANING_OPERATION | 清洁和环境维护 | + +--- + +## 🔧 实现方案 + +### 1. 数据存储结构 + +在 `mock_unmanned_vehicle.py` 中定义任务池: + +```python +# 可执行任务清单(任务模板库) +AVAILABLE_MISSIONS = [ + { + "missionId": "MISSION_TEMPLATE_001", + "missionName": "T1航站楼巡逻", + "missionType": "PATROL_TRANSPORT", + "description": "T1航站楼周边区域巡逻任务", + "priority": 3, + "estimatedDuration": 1800000, + "totalMileage": 2500.0, + "waypoints": [ + { + "waypointId": "WP_T1_001", + "latitude": 36.354068, + "longitude": 120.083410, + "waypointType": "START", + "name": "T1航站楼东侧", + "altitude": 10.5 + }, + { + "waypointId": "WP_T1_002", + "latitude": 36.355123, + "longitude": 120.084567, + "waypointType": "CHECKPOINT", + "name": "巡逻检查点A", + "altitude": 11.2 + }, + { + "waypointId": "WP_T1_003", + "latitude": 36.356789, + "longitude": 120.085234, + "waypointType": "END", + "name": "T1航站楼北侧", + "altitude": 10.8 + } + ], + "requirements": { + "vehicleType": "UNMANNED", + "minBatteryLevel": 30, + "requiredSensors": ["GPS", "LIDAR", "CAMERA"], + "weatherConditions": "CLEAR | LIGHT_RAIN" + }, + "metadata": { + "createdTime": 1736175000000, + "createdBy": "system", + "tags": ["patrol", "security", "routine"], + "zone": "TERMINAL_1" + } + }, + { + "missionId": "MISSION_TEMPLATE_002", + "missionName": "货物运输-仓库A到登机口B3", + "missionType": "CARGO_TRANSPORT", + "description": "从货物仓库A运输至B3登机口", + "priority": 4, + "estimatedDuration": 900000, + "totalMileage": 1200.0, + "waypoints": [ + { + "waypointId": "WP_CARGO_001", + "latitude": 36.352000, + "longitude": 120.082000, + "waypointType": "START", + "name": "货物仓库A", + "altitude": 9.5 + }, + { + "waypointId": "WP_CARGO_002", + "latitude": 36.353500, + "longitude": 120.083500, + "waypointType": "WAYPOINT", + "name": "运输通道中点", + "altitude": 10.0 + }, + { + "waypointId": "WP_CARGO_003", + "latitude": 36.355000, + "longitude": 120.085000, + "waypointType": "END", + "name": "B3登机口", + "altitude": 10.2 + } + ], + "requirements": { + "vehicleType": "UNMANNED", + "minBatteryLevel": 25, + "requiredSensors": ["GPS", "CAMERA"], + "weatherConditions": "CLEAR | LIGHT_RAIN | CLOUDY", + "maxCargoWeight": 500 + }, + "metadata": { + "createdTime": 1736175100000, + "createdBy": "system", + "tags": ["cargo", "logistics", "high-priority"], + "zone": "CARGO_AREA" + } + }, + { + "missionId": "MISSION_TEMPLATE_003", + "missionName": "T2航站楼接驳", + "missionType": "PASSENGER_TRANSPORT", + "description": "T2航站楼旅客接驳服务", + "priority": 5, + "estimatedDuration": 600000, + "totalMileage": 800.0, + "waypoints": [ + { + "waypointId": "WP_T2_001", + "latitude": 36.358000, + "longitude": 120.086000, + "waypointType": "START", + "name": "T2到达大厅", + "altitude": 11.0 + }, + { + "waypointId": "WP_T2_002", + "latitude": 36.359000, + "longitude": 120.087000, + "waypointType": "END", + "name": "T2出发大厅", + "altitude": 11.5 + } + ], + "requirements": { + "vehicleType": "UNMANNED", + "minBatteryLevel": 40, + "requiredSensors": ["GPS", "LIDAR", "CAMERA", "ULTRASONIC"], + "weatherConditions": "CLEAR | CLOUDY", + "maxPassengerCount": 4 + }, + "metadata": { + "createdTime": 1736175200000, + "createdBy": "system", + "tags": ["passenger", "shuttle", "high-priority"], + "zone": "TERMINAL_2" + } + }, + { + "missionId": "MISSION_TEMPLATE_004", + "missionName": "跑道周边应急巡查", + "missionType": "EMERGENCY_RESPONSE", + "description": "跑道周边区域应急巡查任务", + "priority": 5, + "estimatedDuration": 1200000, + "totalMileage": 3500.0, + "waypoints": [ + { + "waypointId": "WP_RUNWAY_001", + "latitude": 36.360000, + "longitude": 120.088000, + "waypointType": "START", + "name": "跑道17端", + "altitude": 8.0 + }, + { + "waypointId": "WP_RUNWAY_002", + "latitude": 36.365000, + "longitude": 120.090000, + "waypointType": "CHECKPOINT", + "name": "跑道中段检查点", + "altitude": 8.5 + }, + { + "waypointId": "WP_RUNWAY_003", + "latitude": 36.370000, + "longitude": 120.092000, + "waypointType": "END", + "name": "跑道35端", + "altitude": 9.0 + } + ], + "requirements": { + "vehicleType": "UNMANNED", + "minBatteryLevel": 50, + "requiredSensors": ["GPS", "LIDAR", "CAMERA", "THERMAL"], + "weatherConditions": "ANY", + "emergencyLightRequired": true + }, + "metadata": { + "createdTime": 1736175300000, + "createdBy": "system", + "tags": ["emergency", "runway", "critical"], + "zone": "RUNWAY_AREA" + } + }, + { + "missionId": "MISSION_TEMPLATE_005", + "missionName": "停机坪维护巡检", + "missionType": "MAINTENANCE_INSPECTION", + "description": "停机坪设施维护巡检", + "priority": 2, + "estimatedDuration": 2400000, + "totalMileage": 4200.0, + "waypoints": [ + { + "waypointId": "WP_APRON_001", + "latitude": 36.351000, + "longitude": 120.081000, + "waypointType": "START", + "name": "停机坪A1", + "altitude": 10.0 + }, + { + "waypointId": "WP_APRON_002", + "latitude": 36.352500, + "longitude": 120.082500, + "waypointType": "CHECKPOINT", + "name": "停机坪A5", + "altitude": 10.2 + }, + { + "waypointId": "WP_APRON_003", + "latitude": 36.354000, + "longitude": 120.084000, + "waypointType": "CHECKPOINT", + "name": "停机坪B2", + "altitude": 10.5 + }, + { + "waypointId": "WP_APRON_004", + "latitude": 36.355500, + "longitude": 120.085500, + "waypointType": "END", + "name": "停机坪B8", + "altitude": 10.8 + } + ], + "requirements": { + "vehicleType": "UNMANNED", + "minBatteryLevel": 35, + "requiredSensors": ["GPS", "CAMERA", "INSPECTION_TOOLS"], + "weatherConditions": "CLEAR | CLOUDY" + }, + "metadata": { + "createdTime": 1736175400000, + "createdBy": "system", + "tags": ["maintenance", "inspection", "routine"], + "zone": "APRON_AREA" + } + } +] + +# 任务类型枚举 +MISSION_TYPES = { + "PATROL_TRANSPORT": "巡逻运输", + "CARGO_TRANSPORT": "货物运输", + "PASSENGER_TRANSPORT": "客运服务", + "EMERGENCY_RESPONSE": "应急响应", + "MAINTENANCE_INSPECTION": "维护检查", + "CLEANING_OPERATION": "清洁作业" +} +``` + +### 2. 接口处理函数 + +```python +@app.route('/api/v1/missions/available', methods=['GET', 'OPTIONS']) +def get_available_missions(): + """ + 获取可执行任务清单 + + 查询参数: + - missionType: 任务类型筛选 + - priority: 优先级筛选 + - minBatteryLevel: 最低电量要求 + - limit: 返回数量限制 + - offset: 分页偏移量 + """ + # 处理 CORS 预检请求 + if request.method == 'OPTIONS': + return '', 200 + + try: + # 获取查询参数 + mission_type = request.args.get('missionType') + priority = request.args.get('priority', type=int) + min_battery = request.args.get('minBatteryLevel', type=int) + limit = request.args.get('limit', type=int, default=100) + offset = request.args.get('offset', type=int, default=0) + + # 筛选任务 + filtered_missions = AVAILABLE_MISSIONS.copy() + + # 按任务类型筛选 + if mission_type: + if mission_type not in MISSION_TYPES: + return jsonify({ + "code": 400, + "message": f"Invalid missionType. Must be one of {list(MISSION_TYPES.keys())}", + "timestamp": int(time.time() * 1000), + "data": None + }), 400 + filtered_missions = [m for m in filtered_missions if m["missionType"] == mission_type] + + # 按优先级筛选 + if priority is not None: + if priority < 1 or priority > 5: + return jsonify({ + "code": 400, + "message": "Invalid priority. Must be between 1 and 5", + "timestamp": int(time.time() * 1000), + "data": None + }), 400 + filtered_missions = [m for m in filtered_missions if m["priority"] == priority] + + # 按电量要求筛选 + if min_battery is not None: + if min_battery < 0 or min_battery > 100: + return jsonify({ + "code": 400, + "message": "Invalid minBatteryLevel. Must be between 0 and 100", + "timestamp": int(time.time() * 1000), + "data": None + }), 400 + filtered_missions = [ + m for m in filtered_missions + if m["requirements"]["minBatteryLevel"] <= min_battery + ] + + # 分页处理 + total = len(filtered_missions) + paginated_missions = filtered_missions[offset:offset + limit] + + # 构造响应 + response = { + "code": 200, + "message": "success", + "timestamp": int(time.time() * 1000), + "data": { + "total": total, + "limit": limit, + "offset": offset, + "missions": paginated_missions + } + } + + logging.info(f"返回 {len(paginated_missions)} 个可执行任务 (总数: {total})") + return jsonify(response), 200 + + except Exception as e: + logging.error(f"获取任务清单失败: {str(e)}") + return jsonify({ + "code": 500, + "message": f"Internal server error: {str(e)}", + "timestamp": int(time.time() * 1000), + "data": None + }), 500 +``` + +### 3. CORS 配置 + +确保在文件中已有 CORS 配置: + +```python +@app.after_request +def after_request(response): + """添加 CORS 头""" + response.headers.add('Access-Control-Allow-Origin', '*') + response.headers.add('Access-Control-Allow-Headers', 'Content-Type,Authorization,Accept,X-Request-Id') + response.headers.add('Access-Control-Allow-Methods', 'GET,POST,PUT,DELETE,OPTIONS') + return response +``` + +--- + +## 🧪 测试用例 + +### 1. 获取所有任务 + +```bash +curl -X GET "http://localhost:5000/api/v1/missions/available" \ + -H "Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9..." \ + -H "Accept: application/json" +``` + +### 2. 按任务类型筛选 + +```bash +curl -X GET "http://localhost:5000/api/v1/missions/available?missionType=CARGO_TRANSPORT" \ + -H "Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9..." \ + -H "Accept: application/json" +``` + +### 3. 按优先级筛选 + +```bash +curl -X GET "http://localhost:5000/api/v1/missions/available?priority=5" \ + -H "Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9..." \ + -H "Accept: application/json" +``` + +### 4. 按电量要求筛选 + +```bash +curl -X GET "http://localhost:5000/api/v1/missions/available?minBatteryLevel=50" \ + -H "Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9..." \ + -H "Accept: application/json" +``` + +### 5. 分页查询 + +```bash +curl -X GET "http://localhost:5000/api/v1/missions/available?limit=2&offset=0" \ + -H "Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9..." \ + -H "Accept: application/json" +``` + +### 6. 组合筛选 + +```bash +curl -X GET "http://localhost:5000/api/v1/missions/available?missionType=PATROL_TRANSPORT&priority=3&limit=10" \ + -H "Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9..." \ + -H "Accept: application/json" +``` + +--- + +## 📐 实施步骤 + +### Phase 1: 基础实现 ✅ + +1. 在 `mock_unmanned_vehicle.py` 中添加任务池数据结构(约200行) +2. 实现 `/api/v1/missions/available` 接口(约80行) +3. 添加基本的任务类型和优先级筛选 +4. 测试接口基本功能 + +### Phase 2: 增强功能 + +1. 添加更多样化的任务模板(不同区域、不同类型) +2. 实现高级筛选(按区域、按标签、按天气条件等) +3. 添加任务搜索功能(按名称、描述关键字) +4. 优化分页性能 + +### Phase 3: 集成与扩展 + +1. 与任务下发接口集成(下一步需求) +2. 添加任务状态管理(可执行、进行中、已完成) +3. 实现任务动态更新机制 +4. 添加任务执行统计和历史记录 + +--- + +## 🔗 与现有系统的集成 + +### 与 `/status` 接口的关系 + +- `/status` 接口:返回车辆当前正在执行的任务状态 +- `/missions/available` 接口:返回可供选择的任务清单 + +### 数据一致性 + +任务模板中的字段结构应与 `missionContext` 保持一致: + +```python +# 当任务被分配给车辆时,从任务模板创建任务实例 +def assign_mission_to_vehicle(vehicle_id, mission_template_id): + template = get_mission_template(mission_template_id) + + # 创建任务实例 + mission_instance = { + "missionId": f"{template['missionId']}_INSTANCE_{timestamp}", + "missionType": template["missionType"], + "startTime": int(time.time() * 1000), + "estimatedEndTime": int(time.time() * 1000) + template["estimatedDuration"], + "progress": 0.0, + "totalMileage": template["totalMileage"], + "waypoints": [ + {**wp, "status": "PENDING"} + for wp in template["waypoints"] + ] + } + + # 更新车辆数据 + vehicle_data["mission_id"] = mission_instance["missionId"] + vehicle_data["mission_type"] = mission_instance["missionType"] + vehicle_data["mission_start_time"] = mission_instance["startTime"] + + return mission_instance +``` + +--- + +## 📊 后续扩展方向 + +### 1. 任务下发接口 + +``` +POST /api/v1/vehicles/{vehicleId}/missions +``` + +用于将选中的任务分配给指定车辆。 + +### 2. 任务管理接口 + +``` +GET /api/v1/missions/{missionId} # 获取任务详情 +PUT /api/v1/missions/{missionId} # 更新任务 +DELETE /api/v1/missions/{missionId} # 删除任务 +POST /api/v1/missions # 创建新任务模板 +``` + +### 3. 任务执行控制 + +``` +POST /api/v1/vehicles/{vehicleId}/missions/{missionId}/pause # 暂停任务 +POST /api/v1/vehicles/{vehicleId}/missions/{missionId}/resume # 恢复任务 +POST /api/v1/vehicles/{vehicleId}/missions/{missionId}/cancel # 取消任务 +``` + +### 4. 任务统计与分析 + +``` +GET /api/v1/missions/statistics # 任务统计信息 +GET /api/v1/missions/history # 任务执行历史 +``` + +--- + +## ✅ 验收标准 + +1. **接口可访问性** + - [ ] 接口正常响应 200 状态码 + - [ ] 支持 CORS 跨域请求 + - [ ] JWT 认证正常工作 + +2. **数据完整性** + - [ ] 每个任务包含所有必需字段 + - [ ] 路径点数据完整且符合规范 + - [ ] 任务类型和状态枚举值正确 + +3. **筛选功能** + - [ ] 按任务类型筛选正常 + - [ ] 按优先级筛选正常 + - [ ] 按电量要求筛选正常 + - [ ] 多条件组合筛选正常 + +4. **分页功能** + - [ ] limit 和 offset 参数正常工作 + - [ ] total 字段返回正确的总数 + - [ ] 边界情况处理正确 + +5. **错误处理** + - [ ] 无效参数返回 400 错误 + - [ ] 未授权访问返回 401 错误 + - [ ] 服务器错误返回 500 错误 + - [ ] 错误消息清晰易懂 + +6. **性能要求** + - [ ] 响应时间 < 500ms + - [ ] 支持并发请求 + - [ ] 日志记录完整 + +--- + +## 📝 附录 + +### A. 坐标系统说明 + +所有坐标使用 **WGS84 坐标系**: +- 纬度范围: -90 ~ 90 +- 经度范围: -180 ~ 180 +- 青岛胶东国际机场参考中心: (120.0834104, 36.35406879) + +### B. 时间格式说明 + +所有时间戳使用 **毫秒级 UTC 时间**: +- 格式: Unix timestamp (milliseconds) +- 示例: 1736175610000 +- 转换: `int(time.time() * 1000)` + +### C. 参考文档 + +- 通用无人车运行状态API: `doc/requirement/universal_autonomous_vehicle_api_min_required.md` +- Mock服务主文件: `tools/mock_unmanned_vehicle.py` +- 项目说明文档: `CLAUDE.md` + +--- + +**文档结束**