Files
iot-device-management-service/docs/plans/2026-03-23-work-order-h5-design.md

176 lines
5.7 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.

# 工单处理 H5 页面 + 工单引擎对接 实施计划
> **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task.
**Goal:** 在前端项目中新增 H5 工单详情页(支持文字描述+拍照上传+提交完成),同时启用 IoT 工单引擎对接,实现告警→工单→企微通知→处理→结单的完整闭环。
**Architecture:** 企微卡片简单操作(确认/误报)直接回调处理,复杂操作(填描述+上传图片)通过 card_action.url 跳转 H5 详情页。H5 页面通过企微 OAuth2 获取用户身份做权限控制。后端新增工单处理 API每次操作同步更新告警状态 + IoT 工单 + 企微卡片三方状态。
**Tech Stack:** Vue 3, Ant Design Vue, 企微 JS-SDK/OAuth2, FastAPI, work_order_client
---
## 整体流程
```
边缘告警 → vsp-service → VLM复核
→ 调IoT创建工单拿到orderId
→ 存 alarm_event_extalarm_id ↔ orderId
→ 企微发工单卡片:
按钮:[确认处理] [误报忽略]
card_action.url → H5详情页
保安操作路径A简单
点[误报忽略] → 回调 → 更新告警+调IoT结单+卡片终态
保安操作路径B复杂
点[确认处理] → 回调 → 更新告警为处理中+卡片显示"处理中"
→ 去现场处理 → 点卡片进入H5详情页
→ 填描述+拍照 → 提交
→ 更新告警+调IoT结单+卡片终态
```
---
### Task 1: 后端 — 启用工单创建notify_dispatch
**Files:**
- Modify: `iot-device-management-service/app/services/notify_dispatch.py`
- Modify: `iot-device-management-service/app/main.py`(初始化 work_order_client
取消工单创建代码的注释VLM 复核通过后:
1.`wo_client.create_order()` 创建工单
2. 存 orderId 到 `alarm_event_ext`ext_type=WORK_ORDER
3. 企微卡片和群聊通知正常发送
---
### Task 2: 后端 — 卡片按钮回调启用工单结单
**Files:**
- Modify: `iot-device-management-service/app/routers/wechat_callback.py`
取消工单结单代码的注释:
- `ignore`(误报忽略)→ 调 `wo_client.auto_complete_order(orderId, "误报忽略")`
- `complete`(已处理)→ 调 `wo_client.auto_complete_order(orderId, "已处理完成")`
- `false`(标记误报)→ 调 `wo_client.auto_complete_order(orderId, "标记误报")`
---
### Task 3: 后端 — 卡片 card_action.url 改为 H5 工单页
**Files:**
- Modify: `iot-device-management-service/app/services/wechat_service.py`
`_alarm_detail_url` 方法改为指向 H5 工单详情页:
```python
def _alarm_detail_url(self, alarm_id: str) -> str:
if self._service_base_url:
return f"{self._service_base_url}/work-order?alarmId={alarm_id}"
return ""
```
同时卡片按钮从两步改为一步:
- [确认处理] — 回调更新状态为处理中
- [误报忽略] — 回调直接结单
去掉 `update_alarm_card_step2`(不再需要第二步卡片)。
---
### Task 4: 后端 — 新增工单处理 API
**Files:**
- Create: `iot-device-management-service/app/routers/work_order_api.py`
新增 3 个接口H5 页面调用):
```
GET /api/work-order/detail?alarmId={alarmId}
→ 返回:告警信息 + 工单状态 + 截图URL + 处理记录
POST /api/work-order/complete
Body: {alarmId, remark, imageUrl?}
→ 更新告警状态CLOSED + 调IoT结单 + 更新企微卡片
POST /api/work-order/reject
Body: {alarmId, remark?}
→ 更新告警状态FALSE + 调IoT结单 + 更新企微卡片
```
权限验证:通过企微 OAuth2 获取的 userid 校验是否为工单指派人。
---
### Task 5: 后端 — 图片上传接口
**Files:**
- Modify: `iot-device-management-service/app/routers/work_order_api.py`
```
POST /api/work-order/upload-image
Body: multipart/form-data图片文件
→ 上传到 COS → 返回图片 URL
```
供 H5 页面拍照上传使用。
---
### Task 6: 前端 — 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. 根据工单状态展示不同界面:
- 待处理:显示告警截图 + [确认处理] [误报忽略]
- 处理中:显示告警截图 + 处理表单(文字输入+拍照上传+提交)
- 已完成:显示告警截图 + 处理后照片 + 处理描述
页面组件:
- Ant DesignCard, Button, Input.TextArea, Upload, Image, Tag, Steps
- 拍照:`<input type="file" accept="image/*" capture="environment">`(调手机摄像头)
---
### Task 7: 前端 — 路由配置
**Files:**
- 前端路由添加 `/work-order` 路径(无需登录,通过企微 OAuth2 鉴权)
H5 页面不需要侧边栏和顶部导航,是独立的全屏页面。
可使用空布局blank layout或直接在路由中标记 `meta: { layout: 'blank' }`
---
### Task 8: 后端 — work_order_client 初始化启用
**Files:**
- Modify: `iot-device-management-service/app/main.py`
取消 `work_order_client` 初始化的注释,从 `.env` 读取配置启动。
服务器 `.env` 新增:
```
WORK_ORDER_ENABLED=true
WORK_ORDER_BASE_URL=http://192.168.0.104:48080
WORK_ORDER_APP_ID=alarm-system
WORK_ORDER_APP_SECRET=tQ3v5q1z2ZLu7hrU1yseaHwg1wJUcmF1
```
---
## 验证清单
- [ ] 边缘告警触发后自动创建 IoT 工单
- [ ] 企微卡片显示工单信息,点击跳转 H5 详情页
- [ ] 点"误报忽略"按钮 → 告警状态+IoT工单+卡片三方同步更新
- [ ] H5 页面能展示告警详情和工单状态
- [ ] H5 页面能填写描述+拍照上传+提交完成
- [ ] 提交后告警状态+IoT工单+卡片三方同步更新
- [ ] 非指派人打开 H5 页面显示无权限
- [ ] 工单已完成后 H5 页面显示处理结果(只读)