docs(ops): 基于真实代码重写 Ops 文档,引入工牌(BADGE)与信标(BEACON)硬件调度逻辑
This commit is contained in:
@@ -1,65 +1,59 @@
|
||||
# 01-工单生命周期与状态机
|
||||
|
||||
工单(Ticket)是 Ops 领域流转的核心实体。所有的保洁、安保、维修任务,最终在底层都是一个工单。
|
||||
保证状态机的严谨和健壮,是 Ops 系统的第一要务。
|
||||
工单(WorkOrder)是 Ops 领域的核心实体。本项目中的 Ops 不是传统的“手机 App 抢单”模式,而是**深度整合硬件(智能工牌 BADGE、感知信标 BEACON)**的物联网级调度系统。
|
||||
|
||||
## 一、核心状态流转图
|
||||
## 一、核心状态流转图 (WorkOrderStatusEnum)
|
||||
|
||||
根据 `WorkOrderStatusEnum.java`,工单的完整状态流转如下:
|
||||
|
||||
```mermaid
|
||||
stateDiagram-v2
|
||||
[*] --> PENDING_DISPATCH : 创建工单
|
||||
|
||||
PENDING_DISPATCH --> PENDING_ACCEPT : 自动派单/人工指派
|
||||
PENDING_DISPATCH --> CANCELLED : 创建人取消
|
||||
|
||||
PENDING_ACCEPT --> IN_PROGRESS : 员工接单/抢单成功
|
||||
PENDING_ACCEPT --> PENDING_DISPATCH : 员工拒单/超时未接单(回退)
|
||||
|
||||
IN_PROGRESS --> COMPLETED : 执行完工(提交结果)
|
||||
IN_PROGRESS --> SUSPENDED : 遇到阻碍(挂起申请)
|
||||
[*] --> PENDING : 生成工单(待分配)
|
||||
|
||||
SUSPENDED --> IN_PROGRESS : 阻碍解除(继续执行)
|
||||
SUSPENDED --> TERMINATED : 无法修复/人工终止
|
||||
|
||||
COMPLETED --> VERIFIED : 验收通过(闭环)
|
||||
COMPLETED --> IN_PROGRESS : 验收驳回(打回重做)
|
||||
|
||||
VERIFIED --> [*]
|
||||
TERMINATED --> [*]
|
||||
PENDING --> QUEUED : 进入派单队列(保洁特有)
|
||||
PENDING --> DISPATCHED : 直接推送
|
||||
QUEUED --> DISPATCHED : 推送到智能工牌(已推送)
|
||||
|
||||
DISPATCHED --> CONFIRMED : 员工按键确认(已确认)
|
||||
DISPATCHED --> CANCELLED : 调度超时/撤回
|
||||
|
||||
CONFIRMED --> ARRIVED : 徽章感应到信标(已到岗)
|
||||
CONFIRMED --> PAUSED : 临时暂停
|
||||
|
||||
ARRIVED --> COMPLETED : 作业完成或丢失信号(已完成)
|
||||
ARRIVED --> PAUSED : 临时暂停
|
||||
|
||||
PAUSED --> ARRIVED : 恢复作业
|
||||
PAUSED --> CONFIRMED : 恢复作业(信标未感知)
|
||||
|
||||
PENDING --> CANCELLED : 取消
|
||||
CONFIRMED --> CANCELLED : 取消
|
||||
|
||||
COMPLETED --> [*]
|
||||
CANCELLED --> [*]
|
||||
```
|
||||
|
||||
## 二、状态说明与触发条件
|
||||
## 二、状态说明与底层硬件联动
|
||||
|
||||
| 状态枚举 | 状态名称 | 触发条件 / 操作者 | 核心业务校验 |
|
||||
|---------|----------|-----------------|--------------|
|
||||
| `PENDING_DISPATCH` | 待派单 | 系统创建 / 人工创建 | 判断触发源,决定是进入抢单池还是直接派单 |
|
||||
| `PENDING_ACCEPT` | 待接单 | 调度器派发给指定人/组 | 需记录派单超时时间,触发定时任务监控 |
|
||||
| `IN_PROGRESS` | 处理中 | 移动端点击“接单/抢单” | **并发控制**:校验此单是否已被他人抢走 |
|
||||
| `SUSPENDED` | 已挂起 | 移动端提交“挂起”并附原因 | 必须要求上传现场照片及挂起理由 |
|
||||
| `COMPLETED` | 已完工 | 移动端提交“完工” | 校验必填项(如对比照、耗材单、定位打卡) |
|
||||
| `VERIFIED` | 已验收 | 后台/主管点击“验收通过” | 触发最终的评价和绩效数据结算 |
|
||||
| `TERMINATED` | 已终止 | 管理员主动介入关闭 | 记录异常终止原因,解除相关设备锁定 |
|
||||
| `CANCELLED` | 已取消 | 派单前创建人主动撤销 | 只能在 `PENDING_DISPATCH` 阶段操作 |
|
||||
在本项目中,工单状态的变化直接对应了**物理硬件的事件 (EventDomainEnum)**。
|
||||
|
||||
## 三、异常分支与补偿机制(当前难点)
|
||||
| 状态码 (`status`) | 状态描述 | 触发源与硬件联动逻辑 |
|
||||
|-----------------|----------|----------------------|
|
||||
| `PENDING` | 待分配 | 规则引擎(`RULE`)、客服等触发生成工单。 |
|
||||
| `QUEUED` | 排队中 | **保洁特有**:已推荐保洁员,在队列中等待推送。 |
|
||||
| `DISPATCHED` | 已推送 | 调度器(`DISPATCH`)将指令下发到**智能工牌(`BADGE`)**。工牌可能震动或亮起。 |
|
||||
| `CONFIRMED` | 已确认 | 保洁员在智能工牌上**按下确认按钮**。此时触发状态流转。 |
|
||||
| `ARRIVED` | 已到岗 | **核心特性**:员工到达现场,工牌扫描/感应到现场的**感知信标(`BEACON`)**,自动流转为作业中。 |
|
||||
| `PAUSED` | 已暂停 | 员工临时离开信标区域或主动暂停。 |
|
||||
| `COMPLETED`| 已完成 | 作业完成(可通过工牌按键或离开信标一定时间自动结算)。 |
|
||||
| `CANCELLED`| 已取消 | 中途取消(可随时发起,除终态外)。 |
|
||||
|
||||
状态机在理想情况下是顺畅的,但在实际业务中会遇到各种异常,代码实现必须处理以下分支:
|
||||
## 三、业务判断约束 (代码级)
|
||||
|
||||
### 1. 超时自动退回(建设中)
|
||||
- **场景**:派单给保安 A,但 A 在 15 分钟内未点击接单(`PENDING_ACCEPT`)。
|
||||
- **处理**:定时任务扫描,将工单强行回退到 `PENDING_DISPATCH` 状态,触发重派或转派逻辑,并向主管发送告警。
|
||||
所有状态跃迁受限于枚举类中的硬性校验:
|
||||
1. `isCleaningBusinessStatus()`:`QUEUED`、`DISPATCHED`、`CONFIRMED` 属于保洁业务强相关的分发状态。
|
||||
2. `canConfirm()`:只有处于 `DISPATCHED`(已推送)状态的工单,才允许保洁员进行硬件按键确认。
|
||||
3. `canStartWorking()`:`CONFIRMED` 或 `DISPATCHED` 状态下,一旦感应到信标,都可以开始作业(兼容特殊直接到场场景)。
|
||||
4. `canComplete()`:必须先达到 `ARRIVED`(已到岗)状态,才允许扭转为 `COMPLETED`。
|
||||
|
||||
### 2. 抢单并发冲突(已实现)
|
||||
- **场景**:工单进入保洁抢单池,保洁 A 和 B 同时点击抢单。
|
||||
- **处理**:必须使用 Redis 分布式锁 `ops:ticket:grab:lock:{ticketId}`。只有一个能抢到并扭转为 `IN_PROGRESS`,另一个返回“手慢无”业务提示,**绝对禁止出现一单两人接**。
|
||||
|
||||
### 3. 验收驳回的数据隔离(规划中)
|
||||
- **场景**:主管验收发现保洁不合格,驳回工单(`COMPLETED` -> `IN_PROGRESS`)。
|
||||
- **处理**:原有的完工照片和记录必须被作为“历史快照”存档,不能被新的执行记录直接物理覆盖,以便追溯整个返工过程。
|
||||
|
||||
## 四、研发规约
|
||||
|
||||
1. **状态流转绝对由后端控制**:移动端只负责发指令(如 `POST /ticket/accept`),具体变成什么状态由后端 Service 内的流转逻辑决定,前端根据返回的新状态重新渲染。
|
||||
2. **禁止跨级流转**:如直接从 `PENDING_DISPATCH` 跳到 `COMPLETED`,除非是特殊的 Mock 测试接口。
|
||||
3. **状态日志**:任何状态的跃迁,必须在表 `ops_ticket_log` 中记录:原状态、新状态、操作人、操作时间和变更备注。这是后期扯皮的唯一证据。
|
||||
这保证了员工**必须亲自到达物理现场(信标打卡)**才能完成工单,杜绝了远程虚假完工。
|
||||
@@ -1,43 +1,46 @@
|
||||
# 02-保洁业务核心链路
|
||||
# 02-人员状态与派单调度
|
||||
|
||||
保洁业务是基于 Ops 底层工单状态机的具体特化场景。
|
||||
它的业务核心诉求是:**快速响应、防作弊、规范留存。**
|
||||
在 AIOT 平台中,保洁员/安保人员不仅在系统中有一个虚拟账号,更绑定了物理世界中的实体装备(智能工牌 BADGE)。因此,调度系统不仅要看软件逻辑,还要看硬件状态。
|
||||
|
||||
## 一、派单与抢单策略
|
||||
## 一、执行人员状态模型 (CleanerStatusEnum)
|
||||
|
||||
保洁任务大多具有“区域化”和“即时性”特点,调度策略与安保不同。
|
||||
执行人员(如保洁员)的状态通过 `CleanerStatusEnum` 严格定义,决定了他们能否接收新派单:
|
||||
|
||||
### 1. 派单策略
|
||||
- **指定派发**:针对例行保洁(如每日清晨大扫除),由系统固定排班直接生成 `PENDING_ACCEPT` 工单发给指定保洁员。
|
||||
- **区域虚拟池抢单(当前主力)**:
|
||||
- 针对突发保洁(如某洗手间漏水)。
|
||||
- 工单生成后进入 `PENDING_DISPATCH`。
|
||||
- 根据事发点位,向该楼层/区域关联的“保洁组”进行广播推送。
|
||||
- **智能调度(下阶段规划)**:未来将根据保洁员的实时定位距离、手头未完成工单数量进行加权打分,自动派给最优人选。
|
||||
1. **`IDLE` (空闲)**
|
||||
- 描述:当前无进行中的工单,可以接收新单。
|
||||
- `canAcceptNewOrder`:`true`。
|
||||
2. **`BUSY` (忙碌)**
|
||||
- 描述:工单进入 `CONFIRMED`(已确认接单)后,保洁员自动转为忙碌。
|
||||
- `canAcceptNewOrder`:`false`。
|
||||
- 退出条件:工单 `COMPLETED` 后,系统检查该员工的队列,若有任务则保持 `BUSY`,若无任务才转回 `IDLE`。
|
||||
3. **`PAUSED` (暂停)**
|
||||
- 描述:临时离开(如吃饭、休息),禁止派单。
|
||||
4. **`OFFLINE` (离线)**
|
||||
- 描述:**硬件强绑定**。如果员工随身佩戴的智能工牌离线或失去心跳,系统直接将其判定为 `OFFLINE`,杜绝向无响应设备派单。
|
||||
|
||||
### 2. 并发抢单逻辑
|
||||
由于突发工单是广播的,抢单时的并发控制是红线:
|
||||
1. 移动端发起抢单请求。
|
||||
2. 后端拦截,尝试获取 Redis 锁 `ops:ticket:grab:lock:{ticketId}`。
|
||||
3. 锁获取成功后,校验工单当前状态是否仍为 `PENDING_DISPATCH`。
|
||||
4. **并发数限制校验**:检查该保洁员当前处于 `IN_PROGRESS` 状态的工单是否超过配置上限(如最多只能同时进行 3 弹任务)。
|
||||
5. 校验通过,写入接单人信息,状态扭转为 `IN_PROGRESS`。释放锁。
|
||||
## 二、派单策略矩阵 (DispatchStrategyEnum)
|
||||
|
||||
## 二、执行反馈标准动作(防篡改)
|
||||
系统不支持“一刀切”的分配,而是根据不同的业务场景,提供丰富的策略(共 8 种):
|
||||
|
||||
保洁人员在现场执行完毕点击“完工”时,不能只是简单的状态更新,必须包含以下标准化材料的强制校验:
|
||||
### 1. 自动派单策略簇 (`isAuto() == true`)
|
||||
由调度算法自动推送到工牌:
|
||||
- **`AUTO` (自动派单)**:系统根据复合规则(优先级、区域、技能、工作量综合)自动分配。
|
||||
- **`AREA_PRIORITY` (区域优先)**:优先分配给负责该区域的人员(如固定楼层保洁)。
|
||||
- **`NEAREST` (最近距离)**:**LBS/信标定位强相关**。基于工牌实时上报的坐标,分配给距离事发点最近的人员。
|
||||
- **`SKILL_MATCH` (技能匹配)**:匹配人员标签(如需要“高空作业”或“特种维修”)。
|
||||
- **`WORKLOAD_BALANCE` (工作量平衡)**:平衡分配,避免旱的旱死涝的涝死。
|
||||
- **`ROUND_ROBIN` (轮询分配)**:按顺序轮流派发。
|
||||
|
||||
### 1. LBS 定位打卡校验
|
||||
- 点击完工时,必须随接口上报当前 GPS/WIFI 定位坐标。
|
||||
- 后端计算该坐标与工单要求点位的距离,超过设定阈值(如 100 米)则拒绝完工,防止“异地云完工”。
|
||||
### 2. 人工介入策略簇 (`requireManualIntervention() == true`)
|
||||
- **`MANUAL` (手动派单)**:管理员在后台指定。
|
||||
- **`GRAB` (抢单模式)**:放入工单池,允许相关人员主动抢单。
|
||||
|
||||
### 2. 清理前后对比照(核心证据)
|
||||
- 必须强制上传至少两张照片:【清理前】与【清理后】。
|
||||
- **防篡改机制**:
|
||||
- 照片上传在移动端层面必须限制“只能当场拍照”,禁止从相册挑选。
|
||||
- 后端接收图片后,规划接入服务端统一打上不可逆的时间戳与定位水印。
|
||||
## 三、事件领域架构 (EventDomainEnum)
|
||||
|
||||
### 3. 耗材扣减(一致性难点)
|
||||
- 如果保洁使用了特殊耗材(如两瓶清洁剂),在完工时需同步勾选消耗量。
|
||||
- 后端在处理 `COMPLETED` 状态跃迁时,需开启数据库事务,同步扣减库存域(Inventory)的数量。
|
||||
- 若库存不足或发生死锁,工单完工事务必须一并回滚,保证数据强一致性。
|
||||
后端的处理高度模块化和事件驱动,划分为 6 大领域:
|
||||
- **`RULE` (规则引擎)**:主要负责把 IoT 设备的原始异动转化为工单触发源。
|
||||
- **`DISPATCH` (调度)**:执行上述派单策略,决定“把任务给谁”。
|
||||
- **`BADGE` (工牌)**:处理向员工推送信令、接收员工确认按键的硬件交互。
|
||||
- **`BEACON` (信标)**:处理员工到达现场的物理打卡(信标感应)。
|
||||
- **`SYSTEM` (系统)**:底层基础流转。
|
||||
- **`PERFORMANCE` (绩效)**:工单完成后,计算结算时效与工作量。
|
||||
Reference in New Issue
Block a user