feat(ops): 巡检统计接口(合格率、不合格热点区域 TOP10)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
lzh
2026-03-05 20:13:13 +08:00
parent 743875e65e
commit f70402587d
5 changed files with 145 additions and 0 deletions

View File

@@ -0,0 +1,22 @@
package com.viewsh.module.ops.environment.controller.admin.inspection.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
import static com.viewsh.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
@Schema(description = "管理后台 - 巡检统计查询 Request VO")
@Data
public class InspectionStatsReqVO {
@Schema(description = "区域ID可选不传则统计全部区域", example = "1")
private Long areaId;
@Schema(description = "时间范围")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime[] createTime;
}

View File

@@ -0,0 +1,48 @@
package com.viewsh.module.ops.environment.controller.admin.inspection.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
@Schema(description = "管理后台 - 巡检统计 Response VO")
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class InspectionStatsRespVO {
@Schema(description = "总巡检次数", example = "100")
private Long totalCount;
@Schema(description = "合格次数", example = "85")
private Long passedCount;
@Schema(description = "不合格次数", example = "15")
private Long failedCount;
@Schema(description = "合格率(百分比)", example = "85.00")
private Double passRate;
@Schema(description = "不合格热点区域(按不合格次数降序)")
private List<AreaFailStat> hotSpotAreas;
@Schema(description = "区域不合格统计")
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public static class AreaFailStat {
@Schema(description = "区域ID", example = "1")
private Long areaId;
@Schema(description = "不合格次数", example = "5")
private Long failedCount;
}
}

View File

@@ -2,6 +2,8 @@ package com.viewsh.module.ops.environment.service.inspection;
import com.viewsh.framework.common.pojo.PageResult;
import com.viewsh.module.ops.environment.controller.admin.inspection.vo.InspectionRecordPageReqVO;
import com.viewsh.module.ops.environment.controller.admin.inspection.vo.InspectionStatsReqVO;
import com.viewsh.module.ops.environment.controller.admin.inspection.vo.InspectionStatsRespVO;
import com.viewsh.module.ops.environment.controller.admin.inspection.vo.InspectionSubmitReqVO;
import com.viewsh.module.ops.environment.dal.dataobject.inspection.OpsInspectionRecordDO;
@@ -27,4 +29,12 @@ public interface InspectionRecordService {
*/
PageResult<OpsInspectionRecordDO> getRecordPage(InspectionRecordPageReqVO pageReqVO);
/**
* 获得巡检统计(合格率、不合格热点区域)
*
* @param reqVO 统计查询条件
* @return 巡检统计
*/
InspectionStatsRespVO getInspectionStats(InspectionStatsReqVO reqVO);
}

View File

@@ -1,8 +1,11 @@
package com.viewsh.module.ops.environment.service.inspection;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.viewsh.framework.common.pojo.PageResult;
import com.viewsh.framework.mybatis.core.query.LambdaQueryWrapperX;
import com.viewsh.module.ops.environment.controller.admin.inspection.vo.InspectionRecordPageReqVO;
import com.viewsh.module.ops.environment.controller.admin.inspection.vo.InspectionStatsReqVO;
import com.viewsh.module.ops.environment.controller.admin.inspection.vo.InspectionStatsRespVO;
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;
@@ -17,7 +20,10 @@ import org.springframework.transaction.support.TransactionSynchronization;
import org.springframework.transaction.support.TransactionSynchronizationManager;
import org.springframework.validation.annotation.Validated;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.List;
import java.util.Map;
/**
* 巡检记录 Service 实现
@@ -95,4 +101,56 @@ public class InspectionRecordServiceImpl implements InspectionRecordService {
.orderByDesc(OpsInspectionRecordDO::getId));
}
@Override
public InspectionStatsRespVO getInspectionStats(InspectionStatsReqVO reqVO) {
// 1. 构建基础查询条件
LambdaQueryWrapperX<OpsInspectionRecordDO> baseWrapper = new LambdaQueryWrapperX<OpsInspectionRecordDO>()
.eqIfPresent(OpsInspectionRecordDO::getAreaId, reqVO.getAreaId())
.betweenIfPresent(OpsInspectionRecordDO::getCreateTime, reqVO.getCreateTime());
// 2. 总数 & 合格数
long totalCount = inspectionRecordMapper.selectCount(baseWrapper);
long passedCount = inspectionRecordMapper.selectCount(new LambdaQueryWrapperX<OpsInspectionRecordDO>()
.eqIfPresent(OpsInspectionRecordDO::getAreaId, reqVO.getAreaId())
.betweenIfPresent(OpsInspectionRecordDO::getCreateTime, reqVO.getCreateTime())
.eq(OpsInspectionRecordDO::getResultStatus, RESULT_STATUS_PASSED));
long failedCount = totalCount - passedCount;
// 3. 合格率
double passRate = totalCount > 0
? BigDecimal.valueOf(passedCount * 100.0 / totalCount).setScale(2, RoundingMode.HALF_UP).doubleValue()
: 0.0;
// 4. 不合格热点区域按不合格次数降序取前10
QueryWrapper<OpsInspectionRecordDO> groupWrapper = new QueryWrapper<>();
groupWrapper.select("area_id AS areaId", "COUNT(*) AS failedCount");
groupWrapper.eq("result_status", RESULT_STATUS_FAILED);
groupWrapper.eq("deleted", false);
if (reqVO.getAreaId() != null) {
groupWrapper.eq("area_id", reqVO.getAreaId());
}
if (reqVO.getCreateTime() != null && reqVO.getCreateTime().length == 2) {
groupWrapper.between("create_time", reqVO.getCreateTime()[0], reqVO.getCreateTime()[1]);
}
groupWrapper.groupBy("area_id");
groupWrapper.orderByDesc("failedCount");
groupWrapper.last("LIMIT 10");
List<Map<String, Object>> maps = inspectionRecordMapper.selectMaps(groupWrapper);
List<InspectionStatsRespVO.AreaFailStat> hotSpots = maps.stream()
.map(m -> InspectionStatsRespVO.AreaFailStat.builder()
.areaId(((Number) m.get("areaId")).longValue())
.failedCount(((Number) m.get("failedCount")).longValue())
.build())
.toList();
return InspectionStatsRespVO.builder()
.totalCount(totalCount)
.passedCount(passedCount)
.failedCount(failedCount)
.passRate(passRate)
.hotSpotAreas(hotSpots)
.build();
}
}

View File

@@ -62,4 +62,11 @@ public class InspectionController {
return success(BeanUtils.toBean(pageResult, InspectionRecordRespVO.class));
}
@GetMapping("/record/stats")
@Operation(summary = "获得巡检统计(合格率、不合格热点区域)")
@PreAuthorize("@ss.hasPermission('ops:inspection:query')")
public CommonResult<InspectionStatsRespVO> getInspectionStats(@Valid InspectionStatsReqVO reqVO) {
return success(inspectionRecordService.getInspectionStats(reqVO));
}
}