From e3882e1c2f96002923c2e2701cc9b2188bd4e8d7 Mon Sep 17 00:00:00 2001 From: lzh Date: Thu, 5 Mar 2026 20:40:36 +0800 Subject: [PATCH] =?UTF-8?q?fix(ops):=20code=20review=20=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E5=B7=A1=E6=A3=80=E6=A8=A1=E5=9D=976=E9=A1=B9=E9=97=AE?= =?UTF-8?q?=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. @Async 指定 ops-task-executor 线程池,避免使用默认线程池 2. 归属判定无工单/无标准时长时标记为 ATTRIBUTION_NORMAL(3),不再静默跳过 3. 补充 completionSeconds 字段语义注释和 standardDuration 单位转换说明 4. 整改工单默认时长 30 提取为 DEFAULT_RECTIFICATION_DURATION_MINUTES 常量 5. SQL 补充 idx_generated_order_id 和 idx_template_id 索引 Co-Authored-By: Claude Opus 4.6 --- sql/mysql/aiot_ops_inspection.sql | 6 +++-- .../inspection/InspectionAsyncHandler.java | 2 +- .../InspectionAttributionServiceImpl.java | 26 +++++++++++++------ .../InspectionRectificationServiceImpl.java | 5 +++- 4 files changed, 27 insertions(+), 12 deletions(-) diff --git a/sql/mysql/aiot_ops_inspection.sql b/sql/mysql/aiot_ops_inspection.sql index 7b4e1b4..6e771cc 100644 --- a/sql/mysql/aiot_ops_inspection.sql +++ b/sql/mysql/aiot_ops_inspection.sql @@ -45,7 +45,8 @@ CREATE TABLE `ops_inspection_record` ( `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号', PRIMARY KEY (`id`), KEY `idx_area_id` (`area_id`), - KEY `idx_inspector_id` (`inspector_id`) + KEY `idx_inspector_id` (`inspector_id`), + KEY `idx_generated_order_id` (`generated_order_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='巡检主记录'; -- ---------------------------- @@ -65,5 +66,6 @@ CREATE TABLE `ops_inspection_record_item` ( `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除', `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号', PRIMARY KEY (`id`), - KEY `idx_record_id` (`record_id`) + KEY `idx_record_id` (`record_id`), + KEY `idx_template_id` (`template_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='巡检明细'; 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 40bcc1b..cc739f8 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 @@ -25,7 +25,7 @@ public class InspectionAsyncHandler { /** * 异步处理不合格巡检的后续逻辑 */ - @Async + @Async("ops-task-executor") public void handleFailedInspection(Long recordId, Long areaId) { // 1. 归属判定 try { diff --git a/viewsh-module-ops/viewsh-module-environment-biz/src/main/java/com/viewsh/module/ops/environment/service/inspection/InspectionAttributionServiceImpl.java b/viewsh-module-ops/viewsh-module-environment-biz/src/main/java/com/viewsh/module/ops/environment/service/inspection/InspectionAttributionServiceImpl.java index e185b3d..ceaa680 100644 --- a/viewsh-module-ops/viewsh-module-environment-biz/src/main/java/com/viewsh/module/ops/environment/service/inspection/InspectionAttributionServiceImpl.java +++ b/viewsh-module-ops/viewsh-module-environment-biz/src/main/java/com/viewsh/module/ops/environment/service/inspection/InspectionAttributionServiceImpl.java @@ -26,6 +26,8 @@ public class InspectionAttributionServiceImpl implements InspectionAttributionSe private static final int ATTRIBUTION_PERSONAL = 1; /** 归属判定:突发状况(停留时长达标) */ private static final int ATTRIBUTION_EMERGENCY = 2; + /** 归属判定:正常(合格巡检,无需判定) */ + private static final int ATTRIBUTION_NORMAL = 3; @Resource private OpsInspectionRecordMapper inspectionRecordMapper; @@ -47,23 +49,26 @@ public class InspectionAttributionServiceImpl implements InspectionAttributionSe .last("LIMIT 1")); if (lastOrder == null) { - log.warn("[determineAttribution] 区域 {} 无已完成工单,跳过归属判定: recordId={}", areaId, recordId); + log.warn("[determineAttribution] 区域 {} 无已完成工单,标记为正常: recordId={}", areaId, recordId); + updateAttributionResult(recordId, null, null, ATTRIBUTION_NORMAL); return; } // 2. 获取保洁员实际停留时长(秒) + // completionSeconds 记录的是工单从开始到完成的耗时,即实际作业时长 Integer stayDurationSeconds = lastOrder.getCompletionSeconds(); if (stayDurationSeconds == null) { stayDurationSeconds = 0; } - // 3. 获取区域标准时长(分钟 → 秒) + // 3. 获取区域标准时长(standardDuration 单位为分钟,转换为秒) OpsBusAreaDO area = opsBusAreaMapper.selectById(areaId); if (area == null || area.getStandardDuration() == null) { - log.warn("[determineAttribution] 区域 {} 无标准时长配置,跳过归属判定: recordId={}", areaId, recordId); + log.warn("[determineAttribution] 区域 {} 无标准时长配置,标记为正常: recordId={}", areaId, recordId); + updateAttributionResult(recordId, lastOrder.getId(), stayDurationSeconds, ATTRIBUTION_NORMAL); return; } - int standardDurationSeconds = area.getStandardDuration() * 60; + int standardDurationSeconds = area.getStandardDuration() * 60; // 分钟 → 秒 // 4. 判定归属 // T_stay >= clean_threshold → 突发状况(保洁员已做到位,不扣分) @@ -73,15 +78,20 @@ public class InspectionAttributionServiceImpl implements InspectionAttributionSe : ATTRIBUTION_PERSONAL; log.info("[determineAttribution] 归属判定完成: recordId={}, areaId={}, lastOrderId={}, " + - "stayDuration={}s, standardDuration={}s, result={}", + "stayDuration={}s, standardDuration={}s({}min), result={}", recordId, areaId, lastOrder.getId(), - stayDurationSeconds, standardDurationSeconds, attributionResult); + stayDurationSeconds, standardDurationSeconds, area.getStandardDuration(), attributionResult); // 5. 回写巡检记录 + updateAttributionResult(recordId, lastOrder.getId(), stayDurationSeconds, attributionResult); + } + + private void updateAttributionResult(Long recordId, Long lastOrderId, + Integer stayDuration, int attributionResult) { OpsInspectionRecordDO update = new OpsInspectionRecordDO(); update.setId(recordId); - update.setLastOrderId(lastOrder.getId()); - update.setStayDuration(stayDurationSeconds); + update.setLastOrderId(lastOrderId); + update.setStayDuration(stayDuration); update.setAttributionResult(attributionResult); inspectionRecordMapper.updateById(update); } 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 5b8cb8e..7cb8557 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 @@ -22,6 +22,9 @@ import org.springframework.validation.annotation.Validated; @Slf4j public class InspectionRectificationServiceImpl implements InspectionRectificationService { + /** 默认整改工单预计时长(分钟) */ + private static final int DEFAULT_RECTIFICATION_DURATION_MINUTES = 30; + @Resource private CleanOrderService cleanOrderService; @@ -38,7 +41,7 @@ public class InspectionRectificationServiceImpl implements InspectionRectificati OpsBusAreaDO area = opsBusAreaMapper.selectById(areaId); String areaName = (area != null) ? area.getAreaName() : "未知区域"; int expectedDuration = (area != null && area.getStandardDuration() != null) - ? area.getStandardDuration() : 30; + ? area.getStandardDuration() : DEFAULT_RECTIFICATION_DURATION_MINUTES; // 2. 构建整改工单请求 CleanOrderAutoCreateReqDTO createReq = new CleanOrderAutoCreateReqDTO();