docs(ops): 重构Ops领域文档结构,提取工单队列为公共基础设施文档
This commit is contained in:
@@ -11,7 +11,7 @@ Ops 领域是平台当前的第一阶段核心基本盘,主要处理由人执
|
||||
- 现场人员的排班与绩效数据基础收集。
|
||||
|
||||
**Ops 领域绝不负责:**
|
||||
- **设备底层协议解析**:Ops 不关心设备是 MQTT 还是 HTTP 报文,它只接收 IoT 领域转化后的标准“事件”。
|
||||
- **设备底层协议解析**:Ops 不关心设备是 MQTT 还是 HTTP 报文,它只接收 IoT 领域转化后的标准"事件"。
|
||||
- **硬件实时控制**:Ops 不直接发指令给设备,若工单需要反控设备,必须调用 IoT 领域的内部 API。
|
||||
- **财务计费结算**:Ops 只记录耗时和耗材,真正的结算和财务账单属于更上层的计费域。
|
||||
|
||||
@@ -20,24 +20,43 @@ Ops 领域是平台当前的第一阶段核心基本盘,主要处理由人执
|
||||
| 模块 | 状态 | 说明 |
|
||||
|------|------|------|
|
||||
| **基础工单状态机** | 🟢 已实现 | PENDING -> ACCEPT -> PROGRESS -> COMPLETED 闭环已通 |
|
||||
| **工单队列系统** | 🟢 已实现 | 基于 `OrderQueueStatusEnum` 的公共队列,支持 P0 打断机制 |
|
||||
| **抢单/派单基础逻辑** | 🟢 已实现 | 基础区域派单与并发抢单控制(基于 Redis)已上 |
|
||||
| **安保巡检路线** | 🟡 建设中 | 基础空间树复用完成,防作弊打卡待深化 |
|
||||
| **保洁耗材管理** | 🟡 建设中 | 耗材库存扣减与工单的事务一致性仍在打磨 |
|
||||
| **智能派单算法** | 🔴 规划中 | 下阶段迭代,基于位置与手头任务数的智能派发 |
|
||||
| **复杂异常流转** | 🔴 规划中 | 超时自动退回、不可抗力挂起的补偿机制待完善 |
|
||||
|
||||
## 三、下属核心文档阅读指引
|
||||
## 三、核心基础设施
|
||||
|
||||
### 3.1 工单状态机 (`WorkOrderStatusEnum`)
|
||||
所有 Ops 工单(保洁、安保、维修、客服)共享统一的状态流转:
|
||||
- `PENDING` (待分配) → `QUEUED` (排队中) → `DISPATCHED` (已推送) → `CONFIRMED` (已确认) → `ARRIVED` (已到岗) → `COMPLETED` (已完成)
|
||||
- 详见:[[01-工单生命周期与状态机.md]]
|
||||
|
||||
### 3.2 工单队列系统 (`OrderQueueStatusEnum`)
|
||||
**公共基础设施**,所有需要排队调度的工单类型(目前主要是保洁)都依赖此系统:
|
||||
- **队列状态**:`WAITING` (等待中) → `PROCESSING` (处理中) → `PAUSED` (暂停中) → `REMOVED` (已移除)
|
||||
- **核心能力**:P0 紧急任务可打断当前执行中的低优先级任务
|
||||
- **排序算法**:基于 `queueScore = 优先级分数 + 时间戳` 的复合排序
|
||||
- 详见:[[02-工单队列系统.md]]
|
||||
|
||||
## 四、下属核心文档阅读指引
|
||||
|
||||
在深入具体业务前,请按以下顺序阅读:
|
||||
|
||||
1. **[[01-工单生命周期与状态机.md]]**
|
||||
- 必读。这是所有 Ops 业务的底层底座,搞懂了状态机,就搞懂了代码里的核心 Enum 和边界校验。
|
||||
2. **[[02-保洁业务核心链路.md]]**
|
||||
- 偏向“抢单执行与过程留存”,重点看并发控制和防篡改。
|
||||
3. **[[03-安保业务核心链路.md]]**
|
||||
- 偏向“空间巡检与突发响应”,重点看基于空间的点位设计和告警强推。
|
||||
2. **[[02-工单队列系统.md]]**
|
||||
- 必读。理解工单如何在队列中排队、如何被 P0 紧急任务打断、如何计算优先级分数。
|
||||
3. **[[03-保洁业务核心链路.md]]**
|
||||
- 偏向"抢单执行与过程留存",重点看并发控制和防篡改。
|
||||
4. **[[04-安保业务核心链路.md]]**
|
||||
- 偏向"空间巡检与突发响应",重点看基于空间的点位设计和告警强推。
|
||||
5. **[[05-保洁巡检与归属判定链路.md]]**
|
||||
- 保洁特有的巡检业务,重点看基于停留时长的归属判定算法。
|
||||
|
||||
## 四、协作约束
|
||||
## 五、协作约束
|
||||
|
||||
- **状态机不可私增**:前端/移动端绝对禁止硬编码状态流转逻辑。所有合法状态流转必须由后端判断,任何新增状态必须先落文档。
|
||||
- **领域数据隔离**:Ops 模块查询设备信息时,允许在工单表冗余少数字段(如设备名、位置),禁止每次都跨模块 `JOIN` 设备表。
|
||||
- **领域数据隔离**:Ops 模块查询设备信息时,允许在工单表里冗余存储当时的设备名称和位置信息,禁止每次都跨模块 `JOIN` 设备表。
|
||||
@@ -1,6 +1,6 @@
|
||||
# 01-工单生命周期与状态机
|
||||
|
||||
工单(WorkOrder)是 Ops 领域的核心实体。本项目中的 Ops 不是传统的“手机 App 抢单”模式,而是**深度整合硬件(智能工牌 BADGE、感知信标 BEACON)**的物联网级调度系统。
|
||||
工单(WorkOrder)是 Ops 领域的核心实体。本项目中的 Ops 不是传统的“手机 App 抢单”模式,而是深度整合硬件(智能工牌 BADGE、感知信标 BEACON)的物联网级调度系统。
|
||||
|
||||
## 一、核心状态流转图 (WorkOrderStatusEnum)
|
||||
|
||||
|
||||
125
开发者文档/02-Ops领域/02-工单队列系统.md
Normal file
125
开发者文档/02-Ops领域/02-工单队列系统.md
Normal file
@@ -0,0 +1,125 @@
|
||||
# 02-工单队列系统
|
||||
|
||||
工单队列系统是 AIOT 平台 Ops 领域的**公共基础设施**,用于管理所有需要排队调度的工单(目前主要用于保洁业务)。
|
||||
|
||||
它解决了"多个工单如何有序分配给执行人员"以及"紧急任务如何插队"的核心问题。
|
||||
|
||||
## 一、队列状态机 (`OrderQueueStatusEnum`)
|
||||
|
||||
工单队列拥有独立于工单状态的**队列生命周期状态**:
|
||||
|
||||
```mermaid
|
||||
stateDiagram-v2
|
||||
[*] --> WAITING : 工单入队
|
||||
|
||||
WAITING --> PROCESSING : 派单引擎分配
|
||||
WAITING --> REMOVED : 工单取消
|
||||
|
||||
PROCESSING --> PAUSED : P0紧急任务打断/临时离线
|
||||
PROCESSING --> REMOVED : 工单完成
|
||||
|
||||
PAUSED --> PROCESSING : 恢复执行
|
||||
PAUSED --> REMOVED : 工单取消
|
||||
|
||||
REMOVED --> [*]
|
||||
```
|
||||
|
||||
### 队列状态与工单状态的映射关系
|
||||
|
||||
| 队列状态 (`OrderQueueStatusEnum`) | 工单状态 (`WorkOrderStatusEnum`) | 说明 |
|
||||
|----------------------------------|--------------------------------|------|
|
||||
| `WAITING` (等待中) | `QUEUED` (排队中) | 工单已进入队列,等待派单引擎分配 |
|
||||
| `PROCESSING` (处理中) | `DISPATCHED` / `CONFIRMED` / `ARRIVED` | 任务已下发,正在处理(包含已推送、已确认、已到岗任一状态) |
|
||||
| `PAUSED` (暂停中) | `PAUSED` (已暂停) | 任务暂停(如 P0 紧急任务打断、执行人员临时离线) |
|
||||
| `REMOVED` (已移除) | `COMPLETED` / `CANCELLED` | 任务已完成或已取消 |
|
||||
|
||||
## 二、队列数据结构 (`OrderQueueDTO`)
|
||||
|
||||
每条队列记录包含以下核心字段:
|
||||
|
||||
### 身份关联字段
|
||||
- `userId`:执行人员用户 ID
|
||||
- `opsOrderId`:关联的工单 ID
|
||||
- `deviceId`:智能工牌设备 ID(硬件强绑定,保洁业务特有)
|
||||
|
||||
### 优先级与排序字段
|
||||
- `priority`:优先级(`0=P0紧急`, `1=P1重要`, `2=P2普通`, `3=P3低优`)
|
||||
- `queueIndex`:队列顺序(1 表示最高优先级)
|
||||
- `queueScore`:**队列分数(核心排序算法)**
|
||||
- 计算公式:`优先级分数 + 时间戳`
|
||||
- P0: `0 + timestamp`
|
||||
- P1: `1000000 + timestamp`
|
||||
- P2: `2000000 + timestamp`
|
||||
- P3: `3000000 + timestamp`
|
||||
- **效果**:优先级高的排在前面,同优先级按入队时间排序
|
||||
|
||||
### 时间追踪字段
|
||||
- `enqueueTime`:入队时间
|
||||
- `dequeueTime`:出队时间(工单开始执行时间)
|
||||
- `pausedDuration`:累计暂停时长(秒)
|
||||
|
||||
## 三、优先级策略 (`PriorityEnum`)
|
||||
|
||||
系统支持 4 级优先级,P0 具有特殊打断能力:
|
||||
|
||||
| 优先级 | 描述 | 队列排序权重 | 可打断当前任务 |
|
||||
|--------|------|------------|--------------|
|
||||
| `P0` | 紧急任务(溢水、危险品泄漏、严重安全事故) | 0 | **是** (`canInterrupt=true`) |
|
||||
| `P1` | 重要任务(VIP 客户投诉、重要访客接待) | 1 | 否 |
|
||||
| `P2` | 普通任务(日常清洁超时、周期性保养) | 2 | 否 |
|
||||
| `P3` | 低优任务(日常巡检、例行清洁) | 3 | 否 |
|
||||
|
||||
### P0 紧急任务的打断机制
|
||||
当 P0 任务入队时,如果目标执行人员正在执行 P1/P2/P3 任务:
|
||||
1. 当前任务被强制暂停(`PROCESSING` -> `PAUSED`)
|
||||
2. P0 任务插队执行
|
||||
3. P0 完成后,被暂停的任务自动恢复(`PAUSED` -> `PROCESSING`)
|
||||
|
||||
## 四、队列核心操作 (`OrderQueueService`)
|
||||
|
||||
### 基础生命周期操作
|
||||
- `enqueue(opsOrderId, userId, priority, queueIndex)`:工单入队
|
||||
- `dequeue(queueId)` / `dequeueByOpsOrderId(opsOrderId)`:工单出队(完成/取消时)
|
||||
- `startExecution(queueId)`:开始执行(`WAITING` -> `PROCESSING`)
|
||||
- `pauseTask(queueId)`:暂停任务(`PROCESSING` -> `PAUSED`)
|
||||
- `resumeTask(queueId)`:恢复任务(`PAUSED` -> `PROCESSING`)
|
||||
|
||||
### 优先级动态调整
|
||||
- `adjustPriority(queueId, newPriority, reason)`:调整优先级(用于紧急插队)
|
||||
- `upgradeToUrgent(opsOrderId, reason)`:升级为 P0 紧急任务
|
||||
|
||||
### 查询接口
|
||||
- `getWaitingTasksByUserId(userId)`:获取用户的等待中任务(按 `queueScore` 排序)
|
||||
- `getInterruptedTasksByUserId(userId)`:获取用户的暂停任务(按暂停时间排序)
|
||||
- `getCurrentTaskByUserId(userId)`:获取用户当前执行的任务
|
||||
|
||||
## 五、使用场景
|
||||
|
||||
### 场景 1:保洁工单排队
|
||||
保洁工单进入队列后,系统按 `queueScore` 排序,依次推送给保洁员的智能工牌。
|
||||
|
||||
### 场景 2:紧急任务插队
|
||||
某区域发生溢水(P0 紧急),系统:
|
||||
1. 创建 P0 优先级工单并入队
|
||||
2. 查找距离最近的保洁员
|
||||
3. 如果该保洁员正在执行 P2 日常清洁,强制暂停当前任务
|
||||
4. 推送 P0 紧急任务到工牌
|
||||
5. 保洁员处理完 P0 后,自动恢复之前的 P2 任务
|
||||
|
||||
### 场景 3:动态优先级调整
|
||||
某 VIP 客户投诉(原 P2 任务),客服手动升级为 P1:
|
||||
- 调用 `adjustPriority` 修改队列记录的优先级
|
||||
- 重新计算 `queueScore`
|
||||
- 在下次派单时优先处理
|
||||
|
||||
## 六、与工单状态机的协作
|
||||
|
||||
队列系统与工单状态机是**正交**的:
|
||||
- **队列系统**:管理"工单在派单引擎中的排队生命周期"
|
||||
- **工单状态机**:管理"工单本身的业务状态流转"
|
||||
|
||||
一个工单可以同时拥有:
|
||||
- 队列状态:`PROCESSING`(正在队列中执行)
|
||||
- 工单状态:`CONFIRMED`(已确认接单)或 `ARRIVED`(已到岗)
|
||||
|
||||
当工单完成时,两者同步变为 `REMOVED`(队列)和 `COMPLETED`(工单)。
|
||||
73
开发者文档/02-Ops领域/03-保洁业务核心链路.md
Normal file
73
开发者文档/02-Ops领域/03-保洁业务核心链路.md
Normal file
@@ -0,0 +1,73 @@
|
||||
# 03-保洁业务核心链路
|
||||
|
||||
在 AIOT 平台中,保洁业务的核心是**基于智能工牌(BADGE)和工单队列(OrderQueue)的硬件级调度系统**。
|
||||
|
||||
保洁业务深度依赖 [[02-工单队列系统.md]] 提供的公共基础设施。
|
||||
|
||||
## 一、硬件联动:智能工牌(BADGE)
|
||||
|
||||
保洁业务与智能工牌深度绑定,实现"人到现场才能作业"的强约束:
|
||||
|
||||
1. **入队即推送**:工单入队后,系统通过 `OrderQueueService.enqueue` 将指令推送到保洁员的智能工牌(`deviceId`)
|
||||
2. **按键确认**:保洁员在工牌上按键确认后,队列状态从 `WAITING` 变为 `PROCESSING`,同时工单状态变为 `CONFIRMED`
|
||||
3. **信标打卡**:保洁员到达现场,工牌感应信标后,工单状态变为 `ARRIVED`
|
||||
4. **离线检测**:如果工牌离线(`CleanerStatusEnum.OFFLINE`),当前任务自动暂停(`PROCESSING` -> `PAUSED`)
|
||||
|
||||
## 二、保洁特有的队列使用方式
|
||||
|
||||
### 1. 并发抢单控制
|
||||
由于突发工单是广播的,抢单时的并发控制是红线:
|
||||
1. 移动端发起抢单请求
|
||||
2. 后端拦截,尝试获取 Redis 锁 `ops:ticket:grab:lock:{ticketId}`
|
||||
3. 锁获取成功后,校验工单当前状态是否仍为 `PENDING_DISPATCH`
|
||||
4. **并发数限制校验**:检查该保洁员当前处于 `IN_PROGRESS` 状态的工单是否超过配置上限(如最多只能同时进行 3 单任务)
|
||||
5. 校验通过,写入接单人信息,状态扭转为 `IN_PROGRESS`,释放锁
|
||||
|
||||
### 2. 执行反馈标准动作(防篡改)
|
||||
|
||||
保洁人员在现场执行完毕点击"完工"时,必须包含以下标准化材料的强制校验:
|
||||
|
||||
#### LBS 定位打卡校验
|
||||
- 点击完工时,必须随接口上报当前 GPS/WIFI 定位坐标
|
||||
- 后端计算该坐标与工单要求点位的距离,超过设定阈值(如 100 米)则拒绝完工
|
||||
|
||||
#### 清理前后对比照(核心证据)
|
||||
- 必须强制上传至少两张照片:【清理前】与【清理后】
|
||||
- **防篡改机制**:
|
||||
- 照片上传在移动端层面必须限制"只能当场拍照",禁止从相册挑选
|
||||
- 后端接收图片后,规划接入服务端统一打上不可逆的时间戳与定位水印
|
||||
|
||||
#### 耗材扣减(一致性难点)
|
||||
- 如果保洁使用了特殊耗材(如两瓶清洁剂),在完工时需同步勾选消耗量
|
||||
- 后端在处理 `COMPLETED` 状态跃迁时,需开启数据库事务,同步扣减库存域(Inventory)的数量
|
||||
- 若库存不足或发生死锁,工单完工事务必须一并回滚
|
||||
|
||||
## 三、队列与工单的完整流转示例
|
||||
|
||||
```
|
||||
1. 规则引擎生成保洁工单 -> 工单状态: PENDING
|
||||
2. 调度引擎分配保洁员 -> 工单状态: QUEUED, 队列状态: WAITING
|
||||
3. 推送至智能工牌 -> 工单状态: DISPATCHED
|
||||
4. 保洁员按键确认 -> 工单状态: CONFIRMED, 队列状态: PROCESSING
|
||||
5. 到达现场信标打卡 -> 工单状态: ARRIVED
|
||||
6. 作业完成 -> 工单状态: COMPLETED, 队列状态: REMOVED
|
||||
7. 系统自动检查该保洁员队列 -> 如有 WAITING 任务,继续推送
|
||||
```
|
||||
|
||||
## 四、保洁特有的状态流转
|
||||
|
||||
保洁业务在标准工单状态机基础上,增加了 `QUEUED`(排队中)状态:
|
||||
|
||||
```mermaid
|
||||
stateDiagram-v2
|
||||
[*] --> PENDING : 生成工单
|
||||
PENDING --> QUEUED : 进入派单队列
|
||||
QUEUED --> DISPATCHED : 推送到工牌
|
||||
DISPATCHED --> CONFIRMED : 按键确认
|
||||
CONFIRMED --> ARRIVED : 信标感应
|
||||
ARRIVED --> COMPLETED : 作业完成
|
||||
COMPLETED --> [*]
|
||||
```
|
||||
|
||||
- `QUEUED`:工单已进入 `OrderQueue`,等待按 `queueScore` 排序后分配
|
||||
- `DISPATCHED`:指令已推送到智能工牌,等待保洁员响应
|
||||
Reference in New Issue
Block a user