diff --git a/viewsh-module-ops/viewsh-module-environment-biz/src/main/java/com/viewsh/module/ops/environment/controller/admin/inspection/vo/InspectionRecordRespVO.java b/viewsh-module-ops/viewsh-module-environment-biz/src/main/java/com/viewsh/module/ops/environment/controller/admin/inspection/vo/InspectionRecordRespVO.java new file mode 100644 index 0000000..fac3b1c --- /dev/null +++ b/viewsh-module-ops/viewsh-module-environment-biz/src/main/java/com/viewsh/module/ops/environment/controller/admin/inspection/vo/InspectionRecordRespVO.java @@ -0,0 +1,39 @@ +package com.viewsh.module.ops.environment.controller.admin.inspection.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.time.LocalDateTime; + +@Schema(description = "管理后台 - 巡检记录 Response VO") +@Data +public class InspectionRecordRespVO { + + @Schema(description = "巡检记录ID", example = "1024") + private Long id; + + @Schema(description = "区域ID", example = "1") + private Long areaId; + + @Schema(description = "巡检员用户ID", example = "100") + private Long inspectorId; + + @Schema(description = "位置是否异常(0正常 1异常)", example = "0") + private Integer isLocationException; + + @Schema(description = "巡检结果(0不合格 1合格)", example = "1") + private Integer resultStatus; + + @Schema(description = "备注", example = "检查完成") + private String remark; + + @Schema(description = "归属判定结果(1个人责任 2突发状况 3正常)", example = "3") + private Integer attributionResult; + + @Schema(description = "整改工单ID", example = "2048") + private Long generatedOrderId; + + @Schema(description = "创建时间") + private LocalDateTime createTime; + +} diff --git a/viewsh-module-ops/viewsh-module-environment-biz/src/main/java/com/viewsh/module/ops/environment/controller/admin/inspection/vo/InspectionSubmitItemVO.java b/viewsh-module-ops/viewsh-module-environment-biz/src/main/java/com/viewsh/module/ops/environment/controller/admin/inspection/vo/InspectionSubmitItemVO.java new file mode 100644 index 0000000..1458422 --- /dev/null +++ b/viewsh-module-ops/viewsh-module-environment-biz/src/main/java/com/viewsh/module/ops/environment/controller/admin/inspection/vo/InspectionSubmitItemVO.java @@ -0,0 +1,22 @@ +package com.viewsh.module.ops.environment.controller.admin.inspection.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotNull; +import lombok.Data; + +@Schema(description = "管理后台 - 巡检提交明细项 VO") +@Data +public class InspectionSubmitItemVO { + + @Schema(description = "模板检查项ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") + @NotNull(message = "模板检查项ID不能为空") + private Long templateId; + + @Schema(description = "是否合格", requiredMode = Schema.RequiredMode.REQUIRED, example = "true") + @NotNull(message = "是否合格不能为空") + private Boolean isPassed; + + @Schema(description = "备注", example = "地面有明显污渍") + private String remark; + +} diff --git a/viewsh-module-ops/viewsh-module-environment-biz/src/main/java/com/viewsh/module/ops/environment/controller/admin/inspection/vo/InspectionSubmitReqVO.java b/viewsh-module-ops/viewsh-module-environment-biz/src/main/java/com/viewsh/module/ops/environment/controller/admin/inspection/vo/InspectionSubmitReqVO.java new file mode 100644 index 0000000..6f94e81 --- /dev/null +++ b/viewsh-module-ops/viewsh-module-environment-biz/src/main/java/com/viewsh/module/ops/environment/controller/admin/inspection/vo/InspectionSubmitReqVO.java @@ -0,0 +1,31 @@ +package com.viewsh.module.ops.environment.controller.admin.inspection.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotEmpty; +import jakarta.validation.constraints.NotNull; +import lombok.Data; + +import java.util.List; + +@Schema(description = "管理后台 - 提交巡检结果 Request VO") +@Data +public class InspectionSubmitReqVO { + + @Schema(description = "区域ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024") + @NotNull(message = "区域ID不能为空") + private Long areaId; + + @Schema(description = "位置是否异常(0正常 1异常)", requiredMode = Schema.RequiredMode.REQUIRED, example = "0") + @NotNull(message = "位置异常标志不能为空") + private Integer isLocationException; + + @Schema(description = "备注", example = "卫生间地面有污渍") + private String remark; + + @Schema(description = "巡检明细项列表", requiredMode = Schema.RequiredMode.REQUIRED) + @NotEmpty(message = "巡检明细项不能为空") + @Valid + private List items; + +} diff --git a/viewsh-module-ops/viewsh-module-environment-biz/src/main/java/com/viewsh/module/ops/environment/service/inspection/InspectionRecordService.java b/viewsh-module-ops/viewsh-module-environment-biz/src/main/java/com/viewsh/module/ops/environment/service/inspection/InspectionRecordService.java new file mode 100644 index 0000000..0e70d99 --- /dev/null +++ b/viewsh-module-ops/viewsh-module-environment-biz/src/main/java/com/viewsh/module/ops/environment/service/inspection/InspectionRecordService.java @@ -0,0 +1,19 @@ +package com.viewsh.module.ops.environment.service.inspection; + +import com.viewsh.module.ops.environment.controller.admin.inspection.vo.InspectionSubmitReqVO; + +/** + * 巡检记录 Service 接口 + */ +public interface InspectionRecordService { + + /** + * 提交巡检结果 + * + * @param submitReqVO 提交请求 + * @param inspectorId 巡检员用户ID + * @return 巡检记录ID + */ + Long submitInspection(InspectionSubmitReqVO submitReqVO, Long inspectorId); + +} diff --git a/viewsh-module-ops/viewsh-module-environment-biz/src/main/java/com/viewsh/module/ops/environment/service/inspection/InspectionRecordServiceImpl.java b/viewsh-module-ops/viewsh-module-environment-biz/src/main/java/com/viewsh/module/ops/environment/service/inspection/InspectionRecordServiceImpl.java new file mode 100644 index 0000000..422d558 --- /dev/null +++ b/viewsh-module-ops/viewsh-module-environment-biz/src/main/java/com/viewsh/module/ops/environment/service/inspection/InspectionRecordServiceImpl.java @@ -0,0 +1,83 @@ +package com.viewsh.module.ops.environment.service.inspection; + +import com.viewsh.module.ops.environment.controller.admin.inspection.vo.InspectionSubmitItemVO; +import com.viewsh.module.ops.environment.controller.admin.inspection.vo.InspectionSubmitReqVO; +import com.viewsh.module.ops.environment.dal.dataobject.inspection.OpsInspectionRecordDO; +import com.viewsh.module.ops.environment.dal.dataobject.inspection.OpsInspectionRecordItemDO; +import com.viewsh.module.ops.environment.dal.mysql.inspection.OpsInspectionRecordItemMapper; +import com.viewsh.module.ops.environment.dal.mysql.inspection.OpsInspectionRecordMapper; +import jakarta.annotation.Resource; +import lombok.extern.slf4j.Slf4j; +import org.springframework.scheduling.annotation.Async; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.validation.annotation.Validated; + +import java.util.List; + +/** + * 巡检记录 Service 实现 + */ +@Service +@Validated +@Slf4j +public class InspectionRecordServiceImpl implements InspectionRecordService { + + /** 巡检结果:合格 */ + private static final int RESULT_STATUS_PASSED = 1; + /** 巡检结果:不合格 */ + private static final int RESULT_STATUS_FAILED = 0; + + @Resource + private OpsInspectionRecordMapper inspectionRecordMapper; + + @Resource + private OpsInspectionRecordItemMapper inspectionRecordItemMapper; + + @Override + @Transactional(rollbackFor = Exception.class) + public Long submitInspection(InspectionSubmitReqVO submitReqVO, Long inspectorId) { + // 1. 判定巡检结果:任一项不合格 → 整体不合格 + boolean allPassed = submitReqVO.getItems().stream() + .allMatch(InspectionSubmitItemVO::getIsPassed); + int resultStatus = allPassed ? RESULT_STATUS_PASSED : RESULT_STATUS_FAILED; + + // 2. 保存巡检主记录 + OpsInspectionRecordDO record = OpsInspectionRecordDO.builder() + .areaId(submitReqVO.getAreaId()) + .inspectorId(inspectorId) + .isLocationException(submitReqVO.getIsLocationException()) + .resultStatus(resultStatus) + .remark(submitReqVO.getRemark()) + .build(); + inspectionRecordMapper.insert(record); + + // 3. 批量保存巡检明细 + List items = submitReqVO.getItems().stream() + .map(itemVO -> OpsInspectionRecordItemDO.builder() + .recordId(record.getId()) + .templateId(itemVO.getTemplateId()) + .isPassed(itemVO.getIsPassed()) + .remark(itemVO.getRemark()) + .build()) + .toList(); + inspectionRecordItemMapper.insertBatch(items); + + // 4. 不合格时异步触发归属判定(Task 6 实现) + if (resultStatus == RESULT_STATUS_FAILED) { + triggerAttributionAsync(record.getId(), submitReqVO.getAreaId()); + } + + return record.getId(); + } + + /** + * 异步触发归属判定(Task 6 实现完整逻辑) + */ + @Async + public void triggerAttributionAsync(Long recordId, Long areaId) { + log.info("[triggerAttributionAsync] 巡检不合格,触发归属判定: recordId={}, areaId={}", recordId, areaId); + // TODO: Task 6 实现 InspectionAttributionService 归属判定逻辑 + } + +} diff --git a/viewsh-module-ops/viewsh-module-ops-api/src/main/java/com/viewsh/module/ops/enums/ErrorCodeConstants.java b/viewsh-module-ops/viewsh-module-ops-api/src/main/java/com/viewsh/module/ops/enums/ErrorCodeConstants.java index 6d60cce..6ff826d 100644 --- a/viewsh-module-ops/viewsh-module-ops-api/src/main/java/com/viewsh/module/ops/enums/ErrorCodeConstants.java +++ b/viewsh-module-ops/viewsh-module-ops-api/src/main/java/com/viewsh/module/ops/enums/ErrorCodeConstants.java @@ -22,4 +22,8 @@ public interface ErrorCodeConstants { ErrorCode DEVICE_TYPE_ALREADY_BOUND = new ErrorCode(1_020_002_002, "该区域已绑定{},一个区域只能绑定一个"); ErrorCode DEVICE_RELATION_NOT_FOUND = new ErrorCode(1_020_002_003, "设备关联关系不存在"); + // ========== 巡检模块 1-020-003-000 ============ + ErrorCode INSPECTION_TEMPLATE_NOT_FOUND = new ErrorCode(1_020_003_000, "巡检模板不存在"); + ErrorCode INSPECTION_RECORD_NOT_FOUND = new ErrorCode(1_020_003_001, "巡检记录不存在"); + } diff --git a/viewsh-module-ops/viewsh-module-ops-server/src/main/java/com/viewsh/module/ops/controller/admin/inspection/InspectionController.java b/viewsh-module-ops/viewsh-module-ops-server/src/main/java/com/viewsh/module/ops/controller/admin/inspection/InspectionController.java index 7e8b693..3f9793c 100644 --- a/viewsh-module-ops/viewsh-module-ops-server/src/main/java/com/viewsh/module/ops/controller/admin/inspection/InspectionController.java +++ b/viewsh-module-ops/viewsh-module-ops-server/src/main/java/com/viewsh/module/ops/controller/admin/inspection/InspectionController.java @@ -1,9 +1,12 @@ package com.viewsh.module.ops.controller.admin.inspection; import com.viewsh.framework.common.pojo.CommonResult; +import com.viewsh.framework.security.core.util.SecurityFrameworkUtils; import com.viewsh.module.ops.environment.controller.admin.inspection.vo.DetectedBeaconVO; +import com.viewsh.module.ops.environment.controller.admin.inspection.vo.InspectionSubmitReqVO; import com.viewsh.module.ops.environment.controller.admin.inspection.vo.LocationVerifyResultVO; import com.viewsh.module.ops.environment.service.inspection.InspectionLocationService; +import com.viewsh.module.ops.environment.service.inspection.InspectionRecordService; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.tags.Tag; @@ -29,6 +32,9 @@ public class InspectionController { @Resource private InspectionLocationService inspectionLocationService; + @Resource + private InspectionRecordService inspectionRecordService; + @PostMapping("/verify-location") @Operation(summary = "蓝牙位置校验") @Parameter(name = "areaId", description = "区域ID", required = true) @@ -39,4 +45,12 @@ public class InspectionController { return success(inspectionLocationService.verifyLocation(areaId, detectedBeacons)); } + @PostMapping("/submit") + @Operation(summary = "提交巡检结果") + @PreAuthorize("@ss.hasPermission('ops:inspection:create')") + public CommonResult submitInspection(@Valid @RequestBody InspectionSubmitReqVO submitReqVO) { + Long inspectorId = SecurityFrameworkUtils.getLoginUserId(); + return success(inspectionRecordService.submitInspection(submitReqVO, inspectorId)); + } + }