571 lines
17 KiB
Markdown
571 lines
17 KiB
Markdown
# Part 2: 架构演进史
|
||
|
||
本文档记录 Ops 业务运营模块从零开始到当前的完整演进历程,包括每个阶段的目标、成果、经验教训和技术债务。
|
||
|
||
---
|
||
|
||
## 2.1 阶段1:基础数据层(2025.12)
|
||
|
||
### 2.1.1 实施时间
|
||
|
||
2025年12月 - 2026年1月初
|
||
|
||
### 2.1.2 阶段目标
|
||
|
||
搭建工单管理系统的数据基础,创建所有必要的数据模型。
|
||
|
||
### 2.1.3 核心成果
|
||
|
||
**枚举类(10个)**:
|
||
|
||
| 枚举类 | 说明 |
|
||
|--------|------|
|
||
| `WorkOrderTypeEnum` | 工单类型(CLEAN、REPAIR、SECURITY、SERVICE) |
|
||
| `WorkOrderStatusEnum` | 工单状态(PENDING、ASSIGNED、ARRIVED、PAUSED、COMPLETED、CANCELLED) |
|
||
| `PriorityEnum` | 优先级(P0、P1、P2) |
|
||
| `CleanerStatusEnum` | 保洁员状态(IDLE、BUSY、PAUSED、OFFLINE) |
|
||
| `DispatchModeEnum` | 派单模式(AUTO、MANUAL) |
|
||
| `OperatorTypeEnum` | 操作人类型(SYSTEM、ADMIN、CLEANER、INSPECTOR) |
|
||
| `BadgeDeviceTypeEnum` | 设备类型(BADGE、BEACON) |
|
||
| `AreaTypeEnum` | 区域类型(PARK、BUILDING、FLOOR、FUNCTION) |
|
||
| `FunctionTypeEnum` | 功能类型(LOBBY、ELEVATOR、CORRIDOR、RESTROOM) |
|
||
| `EventDomainEnum` | 事件领域(DISPATCH、QUALITY、SYSTEM) |
|
||
|
||
**DO 实体类(10个)**:
|
||
|
||
| 实体类 | 说明 |
|
||
|--------|------|
|
||
| `OpsOrderDO` | 工单主表 |
|
||
| `OpsOrderCleanExtDO` | 保洁工单扩展表 |
|
||
| `OpsOrderEventDO` | 工单事件记录表 |
|
||
| `OpsOrderDispatchDO` | 派单决策记录表 |
|
||
| `OpsOrderQueueDO` | 工单队列表 |
|
||
| `CleanerStatusDO` | 保洁员状态表 |
|
||
| `CleanerPerformanceMonthlyDO` | 月度绩效汇总表 |
|
||
| `BadgeDeviceDO` | 工牌设备表 |
|
||
| `CleanEventLogDO` | 保洁事件日志表 |
|
||
| `BusAreaDO` | 业务区域表 |
|
||
|
||
**Mapper 接口(10个)**:
|
||
- `OpsOrderMapper`
|
||
- `OpsOrderEventMapper`
|
||
- `CleanerStatusMapper`
|
||
- `BadgeDeviceMapper`
|
||
- `OpsOrderCleanExtMapper`
|
||
- `OpsOrderDispatchMapper`
|
||
- `OpsOrderQueueMapper`
|
||
- `CleanerPerformanceMonthlyMapper`
|
||
- `CleanEventLogMapper`
|
||
- `BusAreaMapper`
|
||
|
||
**SQL 表结构**:
|
||
- 文件:`sql/mysql/aiot_ops_work_order.sql`
|
||
- 创建了所有工单相关的数据库表
|
||
|
||
### 2.1.4 遗留问题
|
||
|
||
- 无业务逻辑实现
|
||
- 无服务层和 Controller
|
||
- 无单元测试
|
||
|
||
---
|
||
|
||
## 2.2 阶段2:工单引擎(2026.01)
|
||
|
||
### 2.2.1 实施时间
|
||
|
||
2026年1月 - 2026年1月中旬
|
||
|
||
### 2.2.2 阶段目标
|
||
|
||
实现工单管理系统的核心业务逻辑,包括状态机、事件溯源、REST API。
|
||
|
||
### 2.2.3 核心成果
|
||
|
||
#### DTO 数据传输对象(11个)
|
||
|
||
**工单基础 DTO(ops-biz 模块)**:
|
||
- `OpsOrderCreateReqDTO` - 创建工单请求
|
||
- `OpsOrderUpdateReqDTO` - 更新工单请求
|
||
- `OpsOrderPageReqDTO` - 分页查询请求
|
||
- `OpsOrderAssignReqDTO` - 分配工单请求
|
||
- `OpsOrderCompleteReqDTO` - 完成工单请求
|
||
- `OpsOrderRespDTO` - 工单基本信息响应
|
||
- `OpsOrderDetailRespDTO` - 工单详细信息响应
|
||
- `OpsOrderEventRespDTO` - 工单事件记录响应
|
||
|
||
**保洁业务 DTO(environment-biz 模块)**:
|
||
- `CleanOrderAutoCreateReqDTO` - 保洁工单自动创建请求
|
||
- `CleanOrderPauseReqDTO` - 保洁工单暂停请求
|
||
- `CleanOrderResumeReqDTO` - 保洁工单恢复请求
|
||
|
||
#### 状态机核心实现
|
||
|
||
**`OrderStateMachine`** - 状态机引擎
|
||
|
||
```java
|
||
@Service
|
||
public class OrderStateMachine {
|
||
// 状态转换规则
|
||
private static final Map<WorkOrderStatusEnum, Set<WorkOrderStatusEnum>> TRANSITIONS = Map.of(
|
||
PENDING, Set.of(ASSIGNED, CANCELLED),
|
||
ASSIGNED, Set.of(ARRIVED, CANCELLED),
|
||
ARRIVED, Set.of(PAUSED, COMPLETED),
|
||
PAUSED, Set.of(ARRIVED, CANCELLED),
|
||
COMPLETED, Collections.emptySet(),
|
||
CANCELLED, Collections.emptySet()
|
||
);
|
||
|
||
@Transactional
|
||
public void transition(OpsOrderDO order, WorkOrderStatusEnum newStatus,
|
||
OperatorTypeEnum operatorType, Long operatorId, String remark);
|
||
}
|
||
```
|
||
|
||
**核心功能**:
|
||
- ✅ 状态转换规则验证
|
||
- ✅ 自动记录事件到 `ops_order_event` 表
|
||
- ✅ 通知所有注册的监听器
|
||
- ✅ 支持业务扩展(通过监听器模式)
|
||
|
||
**状态流转图**:
|
||
```
|
||
PENDING (待接单)
|
||
↓
|
||
ASSIGNED (已分配)
|
||
↓
|
||
ARRIVED (已到岗)
|
||
↓ ↘
|
||
PAUSED (已暂停) COMPLETED (已完成) [终态]
|
||
↓
|
||
ARRIVED (已恢复)
|
||
|
||
任何状态 → CANCELLED (已取消) [终态]
|
||
```
|
||
|
||
#### 事件与监听器
|
||
|
||
**`OrderStateChangedEvent`** - 状态变更事件
|
||
```java
|
||
@Data
|
||
@AllArgsConstructor
|
||
public class OrderStateChangedEvent {
|
||
private OpsOrderDO order;
|
||
private WorkOrderStatusEnum fromStatus;
|
||
private WorkOrderStatusEnum toStatus;
|
||
private OperatorTypeEnum operatorType;
|
||
private Long operatorId;
|
||
private String remark;
|
||
}
|
||
```
|
||
|
||
**`OrderStateChangeListener`** - 监听器接口
|
||
```java
|
||
@FunctionalInterface
|
||
public interface OrderStateChangeListener {
|
||
void onStateChanged(OrderStateChangedEvent event);
|
||
}
|
||
```
|
||
|
||
#### 工单服务层
|
||
|
||
**`OpsOrderService` 接口** - 10个核心方法
|
||
|
||
| 方法 | 说明 |
|
||
|------|------|
|
||
| `createOrder()` | 创建工单 |
|
||
| `updateOrder()` | 更新工单 |
|
||
| `deleteOrder()` | 删除工单 |
|
||
| `getOrder()` | 获取工单详情 |
|
||
| `getOrderPage()` | 分页查询工单 |
|
||
| `assignOrder()` | 分配工单给执行人 |
|
||
| `acceptOrder()` | 执行人接单 |
|
||
| `completeOrder()` | 完成工单 |
|
||
| `pauseOrder()` | 暂停工单 |
|
||
| `resumeOrder()` | 恢复工单 |
|
||
| `cancelOrder()` | 取消工单 |
|
||
|
||
#### REST API(11个)
|
||
|
||
| HTTP方法 | 路径 | 功能 | 权限 |
|
||
|---------|------|------|------|
|
||
| POST | `/ops/order/create` | 创建工单 | `ops:order:create` |
|
||
| PUT | `/ops/order/update` | 更新工单 | `ops:order:update` |
|
||
| DELETE | `/ops/order/delete` | 删除工单 | `ops:order:delete` |
|
||
| GET | `/ops/order/get` | 获取工单详情 | `ops:order:query` |
|
||
| GET | `/ops/order/page` | 分页查询工单 | `ops:order:query` |
|
||
| POST | `/ops/order/assign` | 分配工单 | `ops:order:assign` |
|
||
| POST | `/ops/order/accept` | 接单 | `ops:order:accept` |
|
||
| POST | `/ops/order/complete` | 完成工单 | `ops:order:complete` |
|
||
| POST | `/ops/order/pause` | 暂停工单 | `ops:order:pause` |
|
||
| POST | `/ops/order/resume` | 恢复工单 | `ops:order:resume` |
|
||
| POST | `/ops/order/cancel` | 取消工单 | `ops:order:cancel` |
|
||
|
||
#### 单元测试(26个)
|
||
|
||
**`OrderStateMachineTest`** - 10个测试用例
|
||
- 状态转换测试
|
||
- 非法转换测试
|
||
- 终态测试
|
||
|
||
**`OpsOrderServiceTest`** - 16个测试用例
|
||
- CRUD 操作测试
|
||
- 业务规则测试
|
||
- 异常场景测试
|
||
|
||
**测试结果**:
|
||
```bash
|
||
Tests run: 26, Failures: 0, Errors: 0, Skipped: 0
|
||
BUILD SUCCESS
|
||
```
|
||
|
||
**测试覆盖率**:
|
||
- 状态机核心逻辑:100%
|
||
- 工单服务业务规则:95%+
|
||
- 异常场景覆盖:完整
|
||
- 边界条件测试:完整
|
||
|
||
### 2.2.4 架构设计亮点
|
||
|
||
**1. 模块化分层设计**
|
||
```
|
||
viewsh-module-ops/
|
||
├── viewsh-module-ops-api/ # 契约层
|
||
├── viewsh-module-ops-biz/ # 核心业务层
|
||
│ ├── dal/ # 数据访问层
|
||
│ ├── service/ # 服务层
|
||
│ │ ├── order/ # 工单服务
|
||
│ │ ├── fsm/ # 状态机
|
||
│ │ └── event/ # 事件服务
|
||
├── viewsh-module-environment-biz/ # 保洁业务线
|
||
│ ├── service/
|
||
│ │ ├── cleanorder/ # 保洁工单服务
|
||
│ │ └── listener/ # 保洁状态监听器
|
||
└── viewsh-module-ops-server/ # 宿主层
|
||
└── controller/ # REST API
|
||
```
|
||
|
||
**2. 状态机模式**
|
||
- 集中管理状态转换规则
|
||
- 避免状态散落在各个业务方法
|
||
- 易于维护和扩展新状态
|
||
- 自动记录状态变更历史
|
||
|
||
**3. 监听器模式**
|
||
- 解耦核心引擎与业务逻辑
|
||
- 业务线可独立扩展
|
||
- 支持多监听器协同工作
|
||
- 符合开闭原则
|
||
|
||
**4. 事件溯源**
|
||
- 所有状态转换记录到 `ops_order_event` 表
|
||
- 支持完整的审计追溯
|
||
- 可用于状态重建和数据分析
|
||
|
||
### 2.2.5 技术债务
|
||
|
||
| 优先级 | 问题 | 改进方案 | 预估工作量 |
|
||
|-------|------|---------|-----------|
|
||
| P0 | 分页查询未实现 | 实现 selectPage | 2小时 |
|
||
| P1 | 异常处理过于简单 | 定义业务异常类体系 | 4小时 |
|
||
| P1 | 缺少参数校验单元测试 | 增加参数校验测试用例 | 3小时 |
|
||
| P2 | 日志打印不够详细 | 增加关键操作日志 | 2小时 |
|
||
| P2 | 缺少性能监控 | 集成 Micrometer 统计 | 4小时 |
|
||
|
||
---
|
||
|
||
## 2.3 阶段3:智能调度系统(2026.01 - 规划中)
|
||
|
||
### 2.3.1 实施计划
|
||
|
||
2026年1月 - 2026年2月
|
||
|
||
### 2.3.2 阶段目标
|
||
|
||
实现自动派单、优先级队列、紧急插队功能。
|
||
|
||
### 2.3.3 核心功能
|
||
|
||
**1. 保洁员状态管理**
|
||
|
||
**状态定义**:
|
||
- `IDLE` - 空闲(可接新单)
|
||
- `BUSY` - 忙碌(正在执行工单)
|
||
- `PAUSED` - 暂停(临时离开)
|
||
- `OFFLINE` - 离线(工牌离线)
|
||
|
||
**核心方法**:
|
||
- `updateStatus()` - 更新状态
|
||
- `handleHeartbeat()` - 处理工牌心跳
|
||
- `listAvailableCleaners()` - 查询可接单的保洁员
|
||
- `findNearbyCleaners()` - 查询附近的保洁员
|
||
|
||
**2. 优先级队列管理**
|
||
|
||
**Redis + MySQL 混合队列**:
|
||
- Redis Sorted Set:实时队列(高性能)
|
||
- MySQL:持久化存储(数据不丢失)
|
||
|
||
**队列状态**:
|
||
- `WAITING` - 等待中
|
||
- `PROCESSING` - 处理中
|
||
- `PAUSED` - 暂停中
|
||
- `REMOVED` - 已移除
|
||
|
||
**核心方法**:
|
||
- `enqueue()` - 入队
|
||
- `startExecution()` - 开始执行(WAITING → PROCESSING)
|
||
- `pauseTask()` - 暂停任务(PROCESSING → PAUSED)
|
||
- `resumeTask()` - 恢复任务(PAUSED → PROCESSING)
|
||
|
||
**3. 自动派单引擎**
|
||
|
||
**派单策略**:
|
||
- 区域优先策略(就近分配)
|
||
- 负载均衡策略(考虑当前任务数)
|
||
- 技能匹配策略(维修工单需要相应技能)
|
||
|
||
**核心方法**:
|
||
- `recommendAssignee()` - 推荐执行人员
|
||
- `autoDispatch()` - 自动派单
|
||
- `urgentDispatch()` - 紧急派单(可能打断)
|
||
|
||
**4. P0 紧急任务打断**
|
||
|
||
**打断条件**:
|
||
- 目标保洁员状态为 BUSY
|
||
- 新工单优先级为 P0
|
||
|
||
**打断流程**:
|
||
1. 查找附近的保洁员
|
||
2. 如果保洁员正在执行任务(BUSY)
|
||
3. 暂停当前任务(工单状态 + 队列状态同步变更)
|
||
4. 派发 P0 工单
|
||
5. P0 完成后,自动恢复被中断的任务
|
||
|
||
**5. IoT 设备集成**
|
||
|
||
**工牌设备集成**:
|
||
- 订阅设备状态变更事件
|
||
- 接收设备心跳消息
|
||
- 发送语音播报指令
|
||
|
||
**语音播报优化**:
|
||
- 自动去重(同一工单不重复播报)
|
||
- P0 紧急任务:高分贝警报 + 震动
|
||
- 普通/P1 任务:普通语音 + 震动
|
||
|
||
### 2.3.4 实施进度
|
||
|
||
**已完成 ✅**:
|
||
- 队列状态管理(WAITING、PROCESSING、PAUSED、REMOVED)
|
||
- 派单引擎实现(DispatchEngine)
|
||
- 保洁员状态管理
|
||
- P0 紧急任务打断机制
|
||
- 语音播报去重服务
|
||
|
||
**进行中 ⏳**:
|
||
- 工牌通知服务集成
|
||
- 消息队列集成(MQ)
|
||
- 定时任务(自动生成工单、绩效计算)
|
||
|
||
**待实施 📋**:
|
||
- 绩效评价系统
|
||
- 单元测试(派单逻辑、队列管理、紧急插队)
|
||
|
||
---
|
||
|
||
## 2.4 架构重构历程(2026.01.06)
|
||
|
||
### 2.4.1 背景
|
||
|
||
在阶段2和阶段3的实施过程中,发现了一些架构问题,需要进行重构。
|
||
|
||
### 2.4.2 问题识别
|
||
|
||
**问题1:DispatchEngine 职责不清晰**
|
||
|
||
- 接口定义了 13 个方法,但很多返回 null
|
||
- 派单引擎与队列服务的职责边界模糊
|
||
- `autoDispatch()` 实际只是调用 `orderQueueService.startExecution()`
|
||
|
||
**问题2:通用方法抽离不彻底**
|
||
|
||
- `OpsOrderService` 只有基础的 CRUD
|
||
- 暂停/恢复逻辑直接调用状态机,没有与队列联动
|
||
- 打断逻辑只在保洁业务层实现,其他业务线无法复用
|
||
|
||
**问题3:Listener 设计不明确**
|
||
|
||
- 监听器注册是全局的,无法区分业务类型
|
||
- 监听器之间没有优先级定义
|
||
- `CleanOrderStateChangeListener` 直接依赖注入 `CleanOrderService`,产生循环依赖风险
|
||
|
||
**问题4:状态与队列状态同步问题**
|
||
|
||
- 工单状态 (`WorkOrderStatusEnum`) 和队列状态 (`OrderQueueStatusEnum`) 是两个独立的状态机
|
||
- 两者之间的同步需要业务层手动保证
|
||
|
||
### 2.4.3 重构方案设计
|
||
|
||
**核心原则**:
|
||
1. 单一职责:每个组件只负责一个明确的职责
|
||
2. 开闭原则:通过接口和策略模式支持扩展
|
||
3. 依赖倒置:业务层依赖通用层的抽象接口
|
||
4. 清晰分层:通用能力下沉,业务能力上浮
|
||
|
||
**重新定义组件职责**:
|
||
|
||
**DispatchEngine(派单引擎)- 重新定位**:
|
||
- 职责:只负责"决策",推荐最合适的执行人员
|
||
- 不负责:状态管理、设备通知、业务逻辑
|
||
|
||
**OrderLifecycleManager(工单生命周期管理)- 新增**:
|
||
- 职责:统一管理工单状态和队列状态的同步变更
|
||
- 核心方法:`pauseOrder()`, `resumeOrder()`, `interruptOrder()`, `completeOrder()`
|
||
|
||
**OrderStateMachine(状态机)- 优化**:
|
||
- 职责:验证状态转换规则、记录事件
|
||
- 不触发:任何业务逻辑(移除监听器机制)
|
||
|
||
**OrderEventPublisher(事件发布器)- 新增**:
|
||
- 职责:发布工单状态变更事件
|
||
- 实现业务解耦
|
||
|
||
### 2.4.4 重构实施
|
||
|
||
**Phase 1: 基础重构**
|
||
|
||
| 任务 | 说明 | 状态 |
|
||
|------|------|------|
|
||
| 重构 DispatchEngine 接口和实现 | 纯决策层 | ✅ 完成 |
|
||
| 创建 OrderLifecycleManager | 生命周期管理 | ✅ 完成 |
|
||
| 重构 OrderStateMachine(移除监听器) | 纯状态管理 | ✅ 完成 |
|
||
| 创建 OrderEventPublisher | 事件发布器 | ✅ 完成 |
|
||
| 迁移暂停/恢复逻辑到 OrderLifecycleManager | 统一状态同步 | ✅ 完成 |
|
||
|
||
**Phase 2: 业务层改造**
|
||
|
||
| 任务 | 说明 | 状态 |
|
||
|------|------|------|
|
||
| 创建事件处理器替代监听器 | CleanOrderEventHandler | ✅ 完成 |
|
||
| 重构 CleanOrderService | 使用 OrderLifecycleManager | ✅ 完成 |
|
||
| 更新派单策略实现 | CleanerAreaPriorityStrategy | ✅ 完成 |
|
||
| 单元测试编写 | 测试用例 | 📋 待进行 |
|
||
|
||
**Phase 3: 优化与验证**
|
||
|
||
| 任务 | 说明 | 状态 |
|
||
|------|------|------|
|
||
| 性能优化 | - | ⏳ 待进行 |
|
||
| 集成测试 | - | ⏳ 待进行 |
|
||
| 文档更新 | - | ⏳ 待进行 |
|
||
|
||
### 2.4.5 收获与反思
|
||
|
||
**成功经验**:
|
||
|
||
1. **职责分离带来清晰度**
|
||
- DispatchEngine 专注于决策
|
||
- OrderLifecycleManager 统一管理状态同步
|
||
- 各组件职责清晰,易于理解和维护
|
||
|
||
2. **事件驱动架构提升扩展性**
|
||
- 业务方通过订阅事件处理自己的逻辑
|
||
- 新增业务类型只需实现事件处理器
|
||
- 核心引擎不需要修改
|
||
|
||
3. **兼容性保证平滑迁移**
|
||
- 保留旧实现作为兼容层
|
||
- 业务流程不中断
|
||
- 逐步迁移到新架构
|
||
|
||
**踩坑记录**:
|
||
|
||
1. **循环依赖问题**
|
||
- 问题:DispatchEngine 依赖 CleanOrderService,CleanOrderService 依赖 DispatchEngine
|
||
- 解决:使用 `@Lazy` 延迟注入
|
||
|
||
2. **状态同步复杂性**
|
||
- 问题:工单状态和队列状态需要保持一致
|
||
- 解决:引入 OrderLifecycleManager 统一管理
|
||
|
||
3. **监听器优先级**
|
||
- 问题:监听器之间没有优先级定义
|
||
- 解决:改为事件驱动,由业务方决定处理顺序
|
||
|
||
**改进建议**:
|
||
|
||
1. **从设计阶段就明确职责**
|
||
- 在编码前充分讨论组件职责
|
||
- 使用 UML 图展示组件关系
|
||
- 定期 Review 架构设计
|
||
|
||
2. **持续重构**
|
||
- 不要等技术债务积累太多
|
||
- 定期(每季度)进行架构 Review
|
||
- 及时重构不合理的设计
|
||
|
||
3. **完善测试**
|
||
- 单元测试覆盖核心逻辑
|
||
- 集成测试覆盖端到端流程
|
||
- 性能测试验证优化效果
|
||
|
||
---
|
||
|
||
## 2.5 版本对比
|
||
|
||
### 2.5.1 v1.0(阶段2完成)
|
||
|
||
**特点**:
|
||
- 状态机 + 监听器模式
|
||
- 基础工单 CRUD
|
||
- REST API
|
||
- 单元测试
|
||
|
||
**优点**:
|
||
- 功能完整
|
||
- 测试覆盖率高
|
||
- 监听器模式支持扩展
|
||
|
||
**缺点**:
|
||
- DispatchEngine 职责不清晰
|
||
- 通用方法抽离不彻底
|
||
- 状态同步需要手动保证
|
||
|
||
### 2.5.2 v2.0(架构重构)
|
||
|
||
**特点**:
|
||
- 纯决策层的派单引擎
|
||
- 统一的声明周期管理
|
||
- 事件驱动架构
|
||
- 兼容层保证平滑迁移
|
||
|
||
**优点**:
|
||
- 职责清晰
|
||
- 易于扩展
|
||
- 易于测试
|
||
- 向后兼容
|
||
|
||
**缺点**:
|
||
- 组件数量增加
|
||
- 学习曲线稍陡
|
||
|
||
---
|
||
|
||
## 2.6 关键里程碑
|
||
|
||
| 日期 | 里程碑 | 说明 |
|
||
|------|--------|------|
|
||
| 2025-12 | 阶段1完成 | 基础数据层 |
|
||
| 2026-01 | 阶段2完成 | 工单引擎、状态机、REST API |
|
||
| 2026-01-06 | 架构重构方案 | 重新定义组件职责 |
|
||
| 2026-01 | 阶段3规划 | 智能调度系统(部分完成) |
|
||
| 2026 Q2 | 安保条线 | 计划实施 |
|
||
| 2026 Q3 | 工程条线 | 计划实施 |
|
||
| 2026 Q4 | 客服条线 | 计划实施 |
|
||
|
||
---
|
||
|
||
**下一章**:[Part 3: 核心架构设计](./part3-核心架构设计.md)
|