diff --git a/viewsh-module-ops/viewsh-module-environment-biz/src/main/java/com/viewsh/module/ops/environment/service/inspection/InspectionAsyncHandler.java b/viewsh-module-ops/viewsh-module-environment-biz/src/main/java/com/viewsh/module/ops/environment/service/inspection/InspectionAsyncHandler.java
index cc739f8..b8cda87 100644
--- a/viewsh-module-ops/viewsh-module-environment-biz/src/main/java/com/viewsh/module/ops/environment/service/inspection/InspectionAsyncHandler.java
+++ b/viewsh-module-ops/viewsh-module-environment-biz/src/main/java/com/viewsh/module/ops/environment/service/inspection/InspectionAsyncHandler.java
@@ -27,18 +27,13 @@ public class InspectionAsyncHandler {
*/
@Async("ops-task-executor")
public void handleFailedInspection(Long recordId, Long areaId) {
- // 1. 归属判定
- try {
- inspectionAttributionService.determineAttribution(recordId, areaId);
- } catch (Exception e) {
- log.error("[handleFailedInspection] 归属判定异常: recordId={}, areaId={}", recordId, areaId, e);
- }
+ // 1. TODO 归属判定:待评分体系完善后启用 inspectionAttributionService.determineAttribution()
- // 2. 创建整改工单(不论归属判定结果,不合格即需整改)
+ // 2. 整改工单:已有活跃工单则升级优先级,否则新建
try {
inspectionRectificationService.createRectificationOrder(recordId, areaId);
} catch (Exception e) {
- log.error("[handleFailedInspection] 整改工单创建异常: recordId={}, areaId={}", recordId, areaId, e);
+ log.error("[handleFailedInspection] 整改工单处理异常: recordId={}, areaId={}", recordId, areaId, e);
}
}
diff --git a/viewsh-module-ops/viewsh-module-environment-biz/src/main/java/com/viewsh/module/ops/environment/service/inspection/InspectionRectificationServiceImpl.java b/viewsh-module-ops/viewsh-module-environment-biz/src/main/java/com/viewsh/module/ops/environment/service/inspection/InspectionRectificationServiceImpl.java
index 26312c8..5d975b6 100644
--- a/viewsh-module-ops/viewsh-module-environment-biz/src/main/java/com/viewsh/module/ops/environment/service/inspection/InspectionRectificationServiceImpl.java
+++ b/viewsh-module-ops/viewsh-module-environment-biz/src/main/java/com/viewsh/module/ops/environment/service/inspection/InspectionRectificationServiceImpl.java
@@ -1,49 +1,113 @@
package com.viewsh.module.ops.environment.service.inspection;
import com.viewsh.module.ops.dal.dataobject.area.OpsBusAreaDO;
+import com.viewsh.module.ops.dal.dataobject.workorder.OpsOrderDO;
import com.viewsh.module.ops.dal.mysql.area.OpsBusAreaMapper;
+import com.viewsh.module.ops.dal.mysql.workorder.OpsOrderMapper;
import com.viewsh.module.ops.environment.service.cleanorder.dto.CleanOrderAutoCreateReqDTO;
import com.viewsh.module.ops.environment.dal.dataobject.inspection.OpsInspectionRecordDO;
import com.viewsh.module.ops.environment.dal.mysql.inspection.OpsInspectionRecordMapper;
import com.viewsh.module.ops.environment.service.cleanorder.CleanOrderService;
import com.viewsh.module.ops.enums.PriorityEnum;
import com.viewsh.module.ops.enums.SourceTypeEnum;
+import com.viewsh.module.ops.enums.WorkOrderStatusEnum;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
+import java.util.Set;
+
/**
* 巡检整改工单 Service 实现
+ *
+ * 逻辑与客流阈值触发一致:
+ * 1. 查该区域有无活跃保洁工单(非终态)
+ * 2. 有排队中工单(PENDING/QUEUED)→ 升级优先级一级
+ * 3. 有已派发/已到达工单 → 保洁员已在处理中,不重复创建
+ * 4. 无活跃工单 → 新建整改工单
*/
@Service
@Validated
@Slf4j
public class InspectionRectificationServiceImpl implements InspectionRectificationService {
- /** 默认整改工单预计时长(分钟) */
private static final int DEFAULT_RECTIFICATION_DURATION_MINUTES = 30;
+ /** 可升级优先级的状态集合(仅排队中,尚未派发) */
+ private static final Set UPGRADABLE_STATUSES = Set.of(
+ WorkOrderStatusEnum.PENDING.getStatus(),
+ WorkOrderStatusEnum.QUEUED.getStatus()
+ );
+
@Resource
private CleanOrderService cleanOrderService;
@Resource
private OpsBusAreaMapper opsBusAreaMapper;
+ @Resource
+ private OpsOrderMapper opsOrderMapper;
+
@Resource
private OpsInspectionRecordMapper inspectionRecordMapper;
@Override
@Transactional(rollbackFor = Exception.class)
public Long createRectificationOrder(Long recordId, Long areaId) {
- // 1. 获取区域信息
+ // 1. 查该区域活跃保洁工单
+ OpsOrderDO activeOrder = opsOrderMapper.selectActiveCleanOrder(areaId);
+
+ if (activeOrder != null) {
+ return handleExistingOrder(activeOrder, recordId, areaId);
+ }
+
+ // 2. 无活跃工单 → 新建整改工单
+ return createNewOrder(recordId, areaId);
+ }
+
+ /**
+ * 已有活跃工单:排队中则升级优先级,已派发/已到达则静默
+ */
+ private Long handleExistingOrder(OpsOrderDO activeOrder, Long recordId, Long areaId) {
+ Long orderId = activeOrder.getId();
+ String status = activeOrder.getStatus();
+
+ if (UPGRADABLE_STATUSES.contains(status)) {
+ // 排队中 → 升级优先级一级
+ PriorityEnum result = cleanOrderService.upgradeOneLevelPriority(
+ orderId, "巡检不合格自动升级");
+
+ if (result != null) {
+ log.info("[createRectificationOrder] 已有工单优先级升级: recordId={}, orderId={}, newPriority={}",
+ recordId, orderId, result);
+ } else {
+ log.info("[createRectificationOrder] 已有工单已是P0封顶: recordId={}, orderId={}",
+ recordId, orderId);
+ }
+ } else {
+ // 已派发/已确认/已到达 → 保洁员已在处理中
+ log.info("[createRectificationOrder] 区域{}保洁员已在处理中(状态:{}),不重复创建: recordId={}, orderId={}",
+ areaId, status, recordId, orderId);
+ }
+
+ // 回写关联工单ID
+ updateGeneratedOrderId(recordId, orderId);
+ return orderId;
+ }
+
+ /**
+ * 新建整改工单
+ */
+ private Long createNewOrder(Long recordId, Long areaId) {
+ // 获取区域信息
OpsBusAreaDO area = opsBusAreaMapper.selectById(areaId);
String areaName = (area != null) ? area.getAreaName() : "未知区域";
int expectedDuration = (area != null && area.getStandardDuration() != null)
? area.getStandardDuration() : DEFAULT_RECTIFICATION_DURATION_MINUTES;
- // 2. 构建整改工单请求
+ // 构建请求
CleanOrderAutoCreateReqDTO createReq = new CleanOrderAutoCreateReqDTO();
createReq.setOrderType("CLEAN");
createReq.setSourceType(SourceTypeEnum.INSPECTION.getType());
@@ -55,18 +119,21 @@ public class InspectionRectificationServiceImpl implements InspectionRectificati
createReq.setCleaningType("SPOT");
createReq.setDifficultyLevel(3);
- // 3. 调用现有工单引擎创建工单
+ // 创建工单
Long orderId = cleanOrderService.createAutoCleanOrder(createReq);
log.info("[createRectificationOrder] 整改工单创建成功: recordId={}, areaId={}, orderId={}",
recordId, areaId, orderId);
- // 4. 回写 generated_order_id 到巡检记录
+ // 回写关联工单ID
+ updateGeneratedOrderId(recordId, orderId);
+ return orderId;
+ }
+
+ private void updateGeneratedOrderId(Long recordId, Long orderId) {
OpsInspectionRecordDO update = new OpsInspectionRecordDO();
update.setId(recordId);
update.setGeneratedOrderId(orderId);
inspectionRecordMapper.updateById(update);
-
- return orderId;
}
}
diff --git a/viewsh-module-ops/viewsh-module-ops-biz/src/main/java/com/viewsh/module/ops/dal/mysql/workorder/OpsOrderMapper.java b/viewsh-module-ops/viewsh-module-ops-biz/src/main/java/com/viewsh/module/ops/dal/mysql/workorder/OpsOrderMapper.java
index c64d919..f1454b9 100644
--- a/viewsh-module-ops/viewsh-module-ops-biz/src/main/java/com/viewsh/module/ops/dal/mysql/workorder/OpsOrderMapper.java
+++ b/viewsh-module-ops/viewsh-module-ops-biz/src/main/java/com/viewsh/module/ops/dal/mysql/workorder/OpsOrderMapper.java
@@ -4,6 +4,7 @@ import com.viewsh.framework.mybatis.core.mapper.BaseMapperX;
import com.viewsh.framework.mybatis.core.query.LambdaQueryWrapperX;
import com.viewsh.module.ops.controller.admin.workorder.vo.statistics.*;
import com.viewsh.module.ops.dal.dataobject.workorder.OpsOrderDO;
+import com.viewsh.module.ops.enums.WorkOrderStatusEnum;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
@@ -74,6 +75,23 @@ public interface OpsOrderMapper extends BaseMapperX {
.last("LIMIT 1"));
}
+ /**
+ * 查询区域内保洁类型的活跃工单(非终态,不限触发来源)
+ *
+ * @param areaId 区域ID
+ * @return 最近创建的活跃保洁工单,不存在返回 null
+ */
+ default OpsOrderDO selectActiveCleanOrder(Long areaId) {
+ return selectOne(new LambdaQueryWrapperX()
+ .eq(OpsOrderDO::getAreaId, areaId)
+ .eq(OpsOrderDO::getOrderType, "CLEAN")
+ .notIn(OpsOrderDO::getStatus,
+ WorkOrderStatusEnum.COMPLETED.getStatus(),
+ WorkOrderStatusEnum.CANCELLED.getStatus())
+ .orderByDesc(OpsOrderDO::getCreateTime)
+ .last("LIMIT 1"));
+ }
+
// ==================== 统计聚合查询 ====================
/**