# 工单引擎对接 + H5 工单详情页 实施计划(v2) > **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task. **Goal:** 打通 告警→IoT工单→企微卡片→保安处理→H5提交→IoT结单→告警状态同步 的完整闭环。 **Architecture:** vsp-service 作为企微通知网关,IoT 平台作为工单状态权威源。告警触发后 vsp-service 调 IoT 创建工单,IoT 派单后回调 vsp-service 发企微卡片。保安通过卡片按钮做简单操作(确认/误报),通过 H5 详情页做复杂操作(描述+图片)。所有状态变更走 IoT → 回调 vsp-service 同步告警+卡片。 **Tech Stack:** Python/FastAPI, Vue 3/Ant Design Vue, 企微 JS-SDK/OAuth2, work_order_client (SHA256签名) --- ## IoT 平台开放接口(vsp-service 调用) | 接口 | 路径 | 必填参数 | 可选参数 | |------|------|---------|---------| | 创建工单 | `POST /open-api/.../create` | title, areaId | description, priority, alarmId, alarmType, cameraId, roiId, imageUrl, sourceType | | 确认工单 | `POST /open-api/.../confirm` | orderId | | | 工单提交 | `POST /open-api/.../submit` | orderId, result | resultImgUrls | | 误报标记 | `POST /open-api/.../false-alarm` | orderId | | | 自动完单 | `POST /open-api/.../auto-complete` | orderId | remark | ## vsp-service 提供给 IoT 的接口 | 接口 | 入参 | 用途 | |------|------|------| | `POST /api/wechat/notify/send-card` | alarmId, orderId, userIds[], title, areaName, cameraName, eventTime, level, snapshotUrl | IoT 派单后调用,发企微工单卡片 | | `POST /api/wechat/notify/sync-status` | alarmId, orderId, status(confirmed/completed/false_alarm/auto_resolved), operator, remark | IoT 状态变更后调用,同步告警+卡片 | ## 完整流程 ``` 边缘告警 → vsp-service VLM复核 → 调IoT /create(拿到orderId) → IoT自动派单 → IoT调 vsp-service /send-card → 发企微卡片 卡片按钮:[确认处理] [误报忽略] | 点击卡片整体 → H5详情页 点[确认处理]: → vsp-service 调 IoT /confirm → IoT 回调 /sync-status(status=confirmed) → 更新告警CONFIRMED + 卡片重绘"已接单,请点击卡片提交处理结果" 点[误报忽略]: → vsp-service 调 IoT /false-alarm → IoT 回调 /sync-status(status=false_alarm) → 更新告警FALSE + 卡片终态"已忽略" H5提交处理结果: → 上传图片到COS → 调 vsp-service → vsp-service 调 IoT /submit → IoT 回调 /sync-status(status=completed) → 更新告警CLOSED + 卡片终态"已处理" 边缘端告警自动解除: → vsp-service 调 IoT /auto-complete → IoT 回调 /sync-status(status=auto_resolved) → 更新告警 + 卡片终态"系统自动结单" ``` --- ### Task 1: work_order_client 补充 3 个新方法 **Files:** - Modify: `iot-device-management-service/app/services/work_order_client.py` 在现有 `create_order` 和 `auto_complete_order` 基础上,新增: - `confirm_order(orderId)` → `POST /confirm` - `submit_order(orderId, result, resultImgUrls=[])` → `POST /submit` - `false_alarm(orderId)` → `POST /false-alarm` 签名逻辑复用现有的 `_sign` 和 `_build_headers`。 --- ### Task 2: work_order_client 初始化启用 **Files:** - Modify: `iot-device-management-service/app/main.py` 取消 `work_order_client` 初始化的注释,从 `.env` 读取配置。 --- ### Task 3: notify_dispatch 启用工单创建 **Files:** - Modify: `iot-device-management-service/app/services/notify_dispatch.py` VLM 复核通过后: 1. 调 `wo_client.create_order()` 创建工单 2. 存 orderId 到 `alarm_event_ext`(ext_type=WORK_ORDER) 3. 企微通知正常发送(后续改为由 IoT 回调触发) --- ### Task 4: 新增 IoT 回调接口(send-card + sync-status) **Files:** - Create: `iot-device-management-service/app/routers/wechat_notify_api.py` - Modify: `iot-device-management-service/app/main.py`(注册路由) ``` POST /api/wechat/notify/send-card → 接收 IoT 派单通知 → 发企微工单卡片给指定 userIds POST /api/wechat/notify/sync-status → 接收 IoT 状态变更 → 更新告警状态 + 更新企微卡片 → status 映射: confirmed → 告警CONFIRMED + 卡片重绘"已接单,请点击卡片提交处理结果" completed → 告警CLOSED + 卡片终态"已处理" false_alarm → 告警FALSE + 卡片终态"已忽略" auto_resolved → 告警CLOSED + 卡片终态"系统自动结单" ``` --- ### Task 5: 卡片按钮回调改造(调 IoT 而非直接更新) **Files:** - Modify: `iot-device-management-service/app/routers/wechat_callback.py` 方案A严格模式: - 点[确认处理] → 调 IoT /confirm → 等 IoT 回调 sync-status 再更新 - 点[误报忽略] → 调 IoT /false-alarm → 等 IoT 回调 sync-status 再更新 卡片按钮简化为一步(去掉 step2 的第二轮按钮)。 --- ### Task 6: 卡片样式调整 + card_action.url **Files:** - Modify: `iot-device-management-service/app/services/wechat_service.py` 1. `_alarm_detail_url` 改为 H5 工单页:`/work-order?alarmId={alarm_id}` 2. 卡片按钮只保留 [确认处理] [误报忽略] 3. 确认后卡片重绘提示:"已接单,请点击卡片提交处理结果" 4. 去掉 `update_alarm_card_step2` 中的第二轮交互按钮 --- ### Task 7: 后端 — H5 工单处理 API **Files:** - Create: `iot-device-management-service/app/routers/work_order_api.py` - Modify: `iot-device-management-service/app/main.py`(注册路由) ``` GET /api/work-order/detail?alarmId={alarmId} → 返回告警信息 + orderId + 工单状态 + 截图URL POST /api/work-order/submit Body: {alarmId, result, resultImgUrls?} → 查 orderId → 调 IoT /submit → 等 IoT 回调同步状态 POST /api/work-order/upload-image Body: multipart/form-data → 上传到 COS → 返回永久 URL ``` --- ### Task 8: 前端 — H5 工单详情页 **Files:** - Create: `iot-device-management-frontend/apps/web-antd/src/views/work-order/index.vue` 页面逻辑: 1. 从 URL 参数获取 alarmId 2. 调 `/api/work-order/detail` 获取信息 3. 根据状态展示: - 待处理/处理中:告警截图 + 处理表单(文字输入+拍照+提交) - 已完成:告警截图 + 处理后照片 + 描述(只读) - 误报:显示"已标记误报" 拍照使用 ``。 --- ### Task 9: 前端 — 路由配置 **Files:** - 添加 `/work-order` 路由,使用空布局(无侧边栏无顶栏) - 不需要登录(通过企微 OAuth2 或 alarmId 鉴权) --- ## 验证清单 - [ ] 边缘告警 → VLM复核 → IoT工单创建成功 - [ ] IoT 回调 send-card → 企微卡片正确发送 - [ ] 点[确认处理] → 调IoT confirm → 回调更新告警+卡片 - [ ] 点[误报忽略] → 调IoT false-alarm → 回调更新告警+卡片终态 - [ ] H5 详情页展示告警信息和工单状态 - [ ] H5 提交描述+图片 → 调IoT submit → 回调更新告警+卡片终态 - [ ] 边缘端告警解除 → 调IoT auto-complete → 回调更新告警+卡片终态 - [ ] 所有配置通过 .env 控制,无硬编码密钥