Sfoglia il codice sorgente

pms 瑞都看板 施工简报 异常警示

zhangcl 17 ore fa
parent
commit
7db07c2074

+ 9 - 0
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/iotmainworkorder/IotMainWorkOrderController.java

@@ -5,6 +5,7 @@ import cn.hutool.core.collection.CollectionUtil;
 import cn.hutool.core.date.DatePattern;
 import cn.hutool.core.date.LocalDateTimeUtil;
 import cn.hutool.core.util.ObjUtil;
+import cn.hutool.core.util.StrUtil;
 import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog;
 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
 import cn.iocoder.yudao.framework.common.pojo.PageParam;
@@ -429,6 +430,14 @@ public class IotMainWorkOrderController {
         List<IotMainWorkOrderRespVO> sortedOrders = buildSortedMainWorkOrders(orders);
         if (CollUtil.isNotEmpty(sortedOrders)) {
             sortedOrders.forEach(order -> {
+                // 工单名称 去掉多语言
+                // 设备名称 去掉多语言标识
+                String orderName = order.getName();
+                if (StrUtil.isNotBlank(orderName) && orderName.contains("~~")) {
+                    // 截取首次~~之前的部分
+                    String processedName = orderName.substring(0, orderName.indexOf("~~"));
+                    order.setName(processedName);
+                }
                 // 工单类型 label
                 if (order.getType() == 1) {
                     order.setTypeName("计划生成");

+ 48 - 0
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/iotrddailyreport/IotRdDailyReportController.java

@@ -975,6 +975,54 @@ public class IotRdDailyReportController {
         return success(resultMap);
     }
 
+    @GetMapping("/abnormalAlert")
+    @Operation(summary = "瑞都日报 看板 异常警示")
+    @PreAuthorize("@ss.hasPermission('pms:iot-rd-daily-report:query')")
+    public CommonResult<List<IotRdDailyReportAbnormalRespVO>> abnormalAlert(@Valid IotRdDailyReportPageReqVO pageReqVO) {
+        Map<String, Object> resultMap = new HashMap<>();
+        // 根据查询参数筛选出 符合条件 的记录id 再传入 分页查询
+        Set<Long> projectIds = new HashSet<>();
+        Set<Long> taskIds = new HashSet<>();
+        if (StrUtil.isNotBlank(pageReqVO.getContractName())) {
+            IotProjectInfoPageReqVO reqVO = new IotProjectInfoPageReqVO();
+            reqVO.setContractName(pageReqVO.getContractName());
+            List<IotProjectInfoDO> projects = iotProjectInfoService.getIotProjectInfos(reqVO);
+            if (CollUtil.isNotEmpty(projects)) {
+                projects.forEach(project -> {
+                    projectIds.add(project.getId());
+                });
+                pageReqVO.setProjectIds(projectIds);
+            }
+        }
+        if (StrUtil.isNotBlank(pageReqVO.getTaskName())) {
+            IotProjectTaskPageReqVO reqVO = new IotProjectTaskPageReqVO();
+            reqVO.setSearchKey(pageReqVO.getTaskName());
+            List<IotProjectTaskDO> tasks = iotProjectTaskService.projectTasks(reqVO);
+            if (CollUtil.isNotEmpty(tasks)) {
+                tasks.forEach(task -> {
+                    taskIds.add(task.getId());
+                });
+                pageReqVO.setTaskIds(taskIds);
+            }
+        }
+        List<IotRdDailyReportAbnormalRespVO> result = iotRdDailyReportService.abnormalAlert(pageReqVO);
+        return success(result);
+    }
+
+    @GetMapping("/constructionBriefing")
+    @Operation(summary = "瑞都日报 看板 施工简报")
+    @PreAuthorize("@ss.hasPermission('pms:iot-rd-daily-report:query')")
+    public CommonResult<Map<String, Object>> constructionBriefing(@Valid IotRdDailyReportPageReqVO pageReqVO) {
+        // 查询昨日 和 前天的日报数据
+        List<IotRdDailyReportBriefRespVO> result = new ArrayList<>();
+        Map<String, Object> resultMap = new HashMap<>();
+        List<IotRdDailyReportBriefRespVO> statistics = iotRdDailyReportService.constructionBriefing(pageReqVO);
+        result.addAll(statistics);
+        resultMap.put("list", result);
+        resultMap.put("total", result.size());
+        return success(resultMap);
+    }
+
     @GetMapping("/teamReports")
     @Operation(summary = "根据井号查询瑞都日报列表 按照队伍分组统计工作量")
     @PreAuthorize("@ss.hasPermission('pms:iot-rd-daily-report:query')")

+ 22 - 0
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/iotrddailyreport/vo/IotRdDailyReportAbnormalRespVO.java

@@ -0,0 +1,22 @@
+package cn.iocoder.yudao.module.pms.controller.admin.iotrddailyreport.vo;
+
+import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
+import com.alibaba.excel.annotation.ExcelProperty;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+@Schema(description = "管理后台 - 瑞都日报 异常警示 Response VO")
+@Data
+@ExcelIgnoreUnannotated
+public class IotRdDailyReportAbnormalRespVO {
+
+    // 异常警示
+    @Schema(description = "数量")
+    @ExcelProperty("数量")
+    private Integer count;
+
+    @Schema(description = "异常名称")
+    @ExcelProperty("异常名称")
+    private String name;
+
+}

+ 168 - 0
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/iotrddailyreport/vo/IotRdDailyReportBriefRespVO.java

@@ -0,0 +1,168 @@
+package cn.iocoder.yudao.module.pms.controller.admin.iotrddailyreport.vo;
+
+import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
+import com.alibaba.excel.annotation.ExcelProperty;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
+import java.util.List;
+
+@Schema(description = "管理后台 - 瑞都日报 简报 Response VO")
+@Data
+@ExcelIgnoreUnannotated
+public class IotRdDailyReportBriefRespVO {
+
+    @Schema(description = "主键id", requiredMode = Schema.RequiredMode.REQUIRED, example = "13853")
+    private Long id;
+
+    @Schema(description = "项目部id", example = "125")
+    private Long deptId;
+
+    @Schema(description = "项目部id", example = "125")
+    private Long projectDeptId;
+
+    @Schema(description = "项目部名称", example = "西南压裂项目部")
+    @ExcelProperty("项目部名称")
+    private String projectDeptName;
+
+    @Schema(description = "队伍名称", example = "压裂二队")
+    @ExcelProperty("队伍名称")
+    private String deptName;
+
+    @Schema(description = "队伍id", example = "125")
+    private Long teamId;
+
+    @Schema(description = "队伍名称", example = "HY-A1")
+    @ExcelProperty("队伍名称")
+    private String teamName;
+
+    @Schema(description = "部门类型(公司级1 项目部2 队伍3)", example = "1")
+    private String type;
+
+    @Schema(description = "任务id", example = "15678")
+    private Long taskId;
+
+    @Schema(description = "甲方")
+    @ExcelProperty("甲方")
+    private String manufactureName;
+
+    @Schema(description = "井号")
+    @ExcelProperty("井号")
+    private String wellName;
+
+    @Schema(description = "使用设备 设备编码-名称 多个逗号分隔")
+    @ExcelProperty("使用设备")
+    private String deviceNames;
+
+    @Schema(description = "施工周期 天")
+    @ExcelProperty("施工周期(D)")
+    private String period;
+
+    @Schema(description = "施工状态")
+    private String rdStatus;
+
+    @Schema(description = "施工状态")
+    @ExcelProperty("施工状态")
+    private String rdStatusLabel;
+
+    @Schema(description = "施工工艺 多个逗号分隔")
+    @ExcelProperty("施工工艺")
+    private String techniques;
+
+    @Schema(description = "施工简要")
+    @ExcelProperty("施工简要")
+    private String productionBrief;
+
+    @Schema(description = "总工作量")
+    @ExcelProperty("总工作量")
+    private BigDecimal workloadDesign;
+
+    @Schema(description = "已完成工作量")
+    private BigDecimal finishedWorkload;
+
+    @Schema(description = "任务创建时间")
+    private LocalDateTime createTime;
+
+    @Schema(description = "油耗L")
+    @ExcelProperty("油耗L")
+    private BigDecimal totalDailyFuel;
+
+    @Schema(description = "排序", example = "1")
+    private Integer sort;
+
+    @Schema(description = "工作量明细")
+    private List<IotRdDailyReportStatisticsItemVO> items;
+
+    // 汇总统计 工作量
+    @Schema(description = "桥塞(个数)")
+    @ExcelProperty("桥塞(个数)")
+    private BigDecimal cumulativeBridgePlug;
+    @Schema(description = "趟数")
+    @ExcelProperty("趟数")
+    private BigDecimal cumulativeRunCount;
+    @Schema(description = "井数")
+    @ExcelProperty("井数")
+    private BigDecimal cumulativeWorkingWell;
+    @Schema(description = "小时H")
+    @ExcelProperty("小时H")
+    private BigDecimal cumulativeHourCount;
+    @Schema(description = "水方量(方)")
+    @ExcelProperty("水方量(方)")
+    private BigDecimal cumulativeWaterVolume;
+    @Schema(description = "段数  累计施工-层")
+    @ExcelProperty("段数")
+    private BigDecimal cumulativeWorkingLayers;
+    @Schema(description = "台次 当日仪表/混砂")
+    private BigDecimal cumulativeMixSand;
+    @Schema(description = "台次 当日泵车台次")
+    private BigDecimal cumulativePumpTrips;
+
+    @Schema(description = "台次 泵车台次 仪表/混砂")
+    @ExcelProperty("台次")
+    private BigDecimal taici;
+
+    @Schema(description = "连油井数")
+    @ExcelProperty("连油井数")
+    private Integer lyWellCount;
+    @Schema(description = "压裂井数")
+    @ExcelProperty("压裂井数")
+    private Integer ylWellCount;
+
+    // 上一天 汇总统计 工作量
+    @Schema(description = "桥塞(个数)")
+    @ExcelProperty("桥塞(个数)")
+    private BigDecimal yesterdayBridgePlug;
+    @Schema(description = "趟数")
+    @ExcelProperty("趟数")
+    private BigDecimal yesterdayRunCount;
+    @Schema(description = "井数")
+    @ExcelProperty("井数")
+    private BigDecimal yesterdayWorkingWell;
+    @Schema(description = "小时H")
+    @ExcelProperty("小时H")
+    private BigDecimal yesterdayHourCount;
+    @Schema(description = "水方量(方)")
+    @ExcelProperty("水方量(方)")
+    private BigDecimal yesterdayWaterVolume;
+    @Schema(description = "段数  累计施工-层")
+    @ExcelProperty("段数")
+    private BigDecimal yesterdayWorkingLayers;
+    @Schema(description = "台次 当日仪表/混砂")
+    private BigDecimal yesterdayMixSand;
+    @Schema(description = "台次 当日泵车台次")
+    private BigDecimal yesterdayPumpTrips;
+    @Schema(description = "油耗L")
+    @ExcelProperty("油耗L")
+    private BigDecimal yesterdayFuel;
+    @Schema(description = "台次 泵车台次 仪表/混砂")
+    @ExcelProperty("台次")
+    private BigDecimal yesterdayTaici;
+    @Schema(description = "施工状态")
+    @ExcelProperty("施工状态")
+    private String yesterdayStatus;
+    @Schema(description = "生产动态")
+    @ExcelProperty("生产动态")
+    private String yesterdayProduct;
+}

+ 17 - 4
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/service/iotrddailyreport/IotRdDailyReportService.java

@@ -1,10 +1,7 @@
 package cn.iocoder.yudao.module.pms.service.iotrddailyreport;
 
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
-import cn.iocoder.yudao.module.pms.controller.admin.iotrddailyreport.vo.IotRdDailyReportPageReqVO;
-import cn.iocoder.yudao.module.pms.controller.admin.iotrddailyreport.vo.IotRdDailyReportPolylineVO;
-import cn.iocoder.yudao.module.pms.controller.admin.iotrddailyreport.vo.IotRdDailyReportSaveReqVO;
-import cn.iocoder.yudao.module.pms.controller.admin.iotrddailyreport.vo.IotRdDailyReportStatisticsRespVO;
+import cn.iocoder.yudao.module.pms.controller.admin.iotrddailyreport.vo.*;
 import cn.iocoder.yudao.module.pms.dal.dataobject.iotrddailyreport.IotRdDailyReportDO;
 
 import javax.validation.Valid;
@@ -160,4 +157,20 @@ public interface IotRdDailyReportService {
      * @return 瑞都日报分页
      */
     PageResult<IotRdDailyReportDO> wellReports(IotRdDailyReportPageReqVO pageReqVO);
+
+    /**
+     * 瑞都日报 看板 施工简报
+     *
+     * @param pageReqVO 无分页查询
+     * @return 瑞都日报施工简报 列表
+     */
+    List<IotRdDailyReportBriefRespVO> constructionBriefing(IotRdDailyReportPageReqVO pageReqVO);
+
+    /**
+     * 瑞都日报 看板 异常警示
+     *
+     * @param pageReqVO 无分页查询
+     * @return 瑞都日报施工简报 列表
+     */
+    List<IotRdDailyReportAbnormalRespVO> abnormalAlert(IotRdDailyReportPageReqVO pageReqVO);
 }

+ 395 - 2
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/service/iotrddailyreport/IotRdDailyReportServiceImpl.java

@@ -13,12 +13,15 @@ import cn.iocoder.yudao.module.pms.controller.admin.iotdailyreportfuel.vo.IotDai
 import cn.iocoder.yudao.module.pms.controller.admin.iotprojectinfo.vo.IotProjectInfoPageReqVO;
 import cn.iocoder.yudao.module.pms.controller.admin.iotprojecttask.vo.IotProjectTaskPageReqVO;
 import cn.iocoder.yudao.module.pms.controller.admin.iotrddailyreport.vo.*;
+import cn.iocoder.yudao.module.pms.controller.admin.vo.IotDevicePageReqVO;
+import cn.iocoder.yudao.module.pms.dal.dataobject.IotDeviceDO;
 import cn.iocoder.yudao.module.pms.dal.dataobject.iotattachment.IotAttachmentDO;
 import cn.iocoder.yudao.module.pms.dal.dataobject.iotdailyreportfuel.IotDailyReportFuelDO;
 import cn.iocoder.yudao.module.pms.dal.dataobject.iotprojectinfo.IotProjectInfoDO;
 import cn.iocoder.yudao.module.pms.dal.dataobject.iotprojecttask.IotProjectTaskDO;
 import cn.iocoder.yudao.module.pms.dal.dataobject.iotprojecttaskattrs.IotTaskAttrModelProperty;
 import cn.iocoder.yudao.module.pms.dal.dataobject.iotrddailyreport.IotRdDailyReportDO;
+import cn.iocoder.yudao.module.pms.dal.mysql.IotDeviceMapper;
 import cn.iocoder.yudao.module.pms.dal.mysql.iotattachment.IotAttachmentMapper;
 import cn.iocoder.yudao.module.pms.dal.mysql.iotdailyreportfuel.IotDailyReportFuelMapper;
 import cn.iocoder.yudao.module.pms.dal.mysql.iotprojectinfo.IotProjectInfoMapper;
@@ -62,7 +65,8 @@ import java.util.stream.Collectors;
 
 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
-import static cn.iocoder.yudao.module.pms.enums.ErrorCodeConstant.*;
+import static cn.iocoder.yudao.module.pms.enums.ErrorCodeConstant.IOT_PROJECT_TASK_NOT_EXISTS;
+import static cn.iocoder.yudao.module.pms.enums.ErrorCodeConstant.IOT_RD_DAILY_REPORT_NOT_EXISTS;
 import static cn.iocoder.yudao.module.pms.framework.config.MultiThreadConfiguration.PMS_THREAD_POOL_TASK_EXECUTOR;
 
 /**
@@ -98,7 +102,8 @@ public class IotRdDailyReportServiceImpl implements IotRdDailyReportService {
     private ThreadPoolTaskExecutor pmsThreadPoolTaskExecutor;
     @Resource
     private PmsMessage pmsMessage;
-
+    @Resource
+    private IotDeviceMapper iotDeviceMapper;
     @Resource
     private IotDailyReportFuelMapper iotDailyReportFuelMapper;
 
@@ -2382,4 +2387,392 @@ public class IotRdDailyReportServiceImpl implements IotRdDailyReportService {
         return new PageResult<>(page.getRecords(), page.getTotal());
     }
 
+    @Override
+    public List<IotRdDailyReportBriefRespVO> constructionBriefing(IotRdDailyReportPageReqVO pageReqVO) {
+        // 瑞都施工简报 查询昨天 和前天的日报数据 井 队伍 项目部
+        // 瑞都所有子部门
+        Set<Long> ids = new HashSet<>();
+        ids = deptService.getChildDeptIdListFromCache(163l);
+        DeptListReqVO reqVO = new DeptListReqVO();
+        reqVO.setDeptIds(ids);
+        List<DeptDO> depts = deptService.getDeptList(reqVO);
+        // 筛选队伍与项目部的对应关系
+        // key部门id   value部门parentId
+        Map<Long, Long> teamProjectIdPair = new HashMap<>();
+        Set<Long> projectDeptIds = new HashSet<>();
+        // key项目部id    value项目部名称
+        Map<Long, DeptDO> projectDeptPair = new HashMap<>();
+        // key队伍id    value队伍名称
+        Map<Long, DeptDO> teamDeptPair = new HashMap<>();
+        depts.forEach(dept -> {
+            if ("2".equals(dept.getType())) {
+                projectDeptIds.add(dept.getId());
+                projectDeptPair.put(dept.getId(), dept);
+            }
+            if ("3".equals(dept.getType())) {
+                teamDeptPair.put(dept.getId(), dept);
+                teamProjectIdPair.put(dept.getId(), dept.getParentId());
+            }
+        });
+        // 查询 昨天 和 前天 创建的日报
+        LocalDateTime nowDate = LocalDateTime.now();
+        LocalDateTime yesterday = nowDate.minusDays(1);
+        LocalDateTime beforeYesterday = nowDate.minusDays(2);
+        String yesterdayStr = LocalDateTimeUtil.format(yesterday, DatePattern.NORM_DATE_PATTERN);
+        String beforeYesterdayStr = LocalDateTimeUtil.format(beforeYesterday, DatePattern.NORM_DATE_PATTERN);
+        IotRdDailyReportPageReqVO reportReqVO = new IotRdDailyReportPageReqVO();
+        // 查询昨天的数据
+        LocalDateTime[] createTime = new LocalDateTime[2];
+        createTime[0] = LocalDateTimeUtil.parse(StrUtil.join(" ", yesterdayStr, "00:00:00"), DatePattern.NORM_DATETIME_PATTERN);
+        createTime[1] = LocalDateTimeUtil.parse(StrUtil.join(" ", yesterdayStr, "23:59:59"), DatePattern.NORM_DATETIME_PATTERN);
+        reportReqVO.setCreateTime(createTime);
+        List<IotRdDailyReportDO> dailyReports = iotRdDailyReportMapper.dailyReports(reportReqVO);
+
+        // 查询前天的日报数据
+        createTime[0] = LocalDateTimeUtil.parse(StrUtil.join(" ", beforeYesterdayStr, "00:00:00"), DatePattern.NORM_DATETIME_PATTERN);
+        createTime[1] = LocalDateTimeUtil.parse(StrUtil.join(" ", beforeYesterdayStr, "23:59:59"), DatePattern.NORM_DATETIME_PATTERN);
+        reportReqVO.setCreateTime(createTime);
+        List<IotRdDailyReportDO> beforeYesterdayDailyReports = iotRdDailyReportMapper.dailyReports(reportReqVO);
+
+        // 包含昨天 前天的日报对应的任务id集合
+        Set<Long> taskIds = new HashSet<>();
+        Set<Long> deviceIds = new HashSet<>();
+        Map<Long, String> taskWellPair = new HashMap<>();
+        //  施工工艺 key字典键值     value字典标签
+        Map<String, String> techniqueDictPair = new HashMap<>();
+        //  施工状态 key字典键值     value字典标签
+        Map<String, String> rdStatusDictPair = new HashMap<>();
+        //  key设备id     value设备编码-名称
+        Map<Long, String> deviceIdCodeNamePair = new HashMap<>();
+        // 前天的日报 与 昨天日报通过 任务井 taskId 对应
+        if (CollUtil.isNotEmpty(beforeYesterdayDailyReports)) {
+            beforeYesterdayDailyReports.forEach(report -> {
+                // 收集所有 日报对应的任务井
+                taskIds.add(report.getTaskId());
+                if (CollUtil.isNotEmpty(report.getDeviceIds())) {
+                    deviceIds.addAll(report.getDeviceIds());
+                }
+            });
+        }
+        // 瑞都日报按井为维度生成 所以每个日报与井是一一对应的
+        if (CollUtil.isNotEmpty(dailyReports)) {
+            dailyReports.forEach(report -> {
+                // 收集所有 日报对应的任务井
+                taskIds.add(report.getTaskId());
+                if (CollUtil.isNotEmpty(report.getDeviceIds())) {
+                    deviceIds.addAll(report.getDeviceIds());
+                }
+            });
+        }
+        if (CollUtil.isNotEmpty(taskIds)) {
+            IotProjectTaskPageReqVO taskReqVO = new IotProjectTaskPageReqVO();
+            taskReqVO.setTaskIds(new ArrayList<>(taskIds));
+            List<IotProjectTaskDO> tasks = iotProjectTaskMapper.selectList(taskReqVO);
+            if (CollUtil.isNotEmpty(tasks)) {
+                tasks.forEach(task -> {
+                    taskWellPair.put(task.getId(), task.getWellName());
+                });
+            }
+        }
+        // 查询施工工艺字典数据
+        List<DictDataDO> rdTechniques = dictDataService.getDictDataListByDictType("rq_iot_project_technology_rd");
+        if (CollUtil.isNotEmpty(rdTechniques)) {
+            rdTechniques.forEach(tech -> {
+                techniqueDictPair.put(tech.getValue(), tech.getLabel());
+            });
+        }
+        // 查询施工状态字典数据
+        List<DictDataDO> rdStatuses = dictDataService.getDictDataListByDictType("rdStatus");
+        if (CollUtil.isNotEmpty(rdStatuses)) {
+            rdStatuses.forEach(tech -> {
+                rdStatusDictPair.put(tech.getValue(), tech.getLabel());
+            });
+        }
+
+        // 查询所有 设备信息
+        IotDevicePageReqVO deviceReqVO = new IotDevicePageReqVO();
+        deviceReqVO.setDeviceIds(new ArrayList<>(deviceIds));
+        List<IotDeviceDO> devices = iotDeviceMapper.selectListAlone(deviceReqVO);
+        if (CollUtil.isNotEmpty(devices)) {
+            devices.forEach(device -> {
+                deviceIdCodeNamePair.put(device.getId(), StrUtil.join("——", device.getDeviceCode(), device.getDeviceName()));
+            });
+        }
+        // key任务井id   value施工状态
+        Map<Long, String> beforeYesterdayStatus = new HashMap<>();
+        // key任务井id   value前天的施工动态
+        Map<Long, String> beforeYesterdayProduct = new HashMap<>();
+        // 上个工作日的 工作量
+        Map<Long, BigDecimal> beforeYestBridgePlugPair = new HashMap<>();
+        Map<Long, BigDecimal> beforeYestRunCountPair = new HashMap<>();
+        Map<Long, BigDecimal> beforeYestHourCountPair = new HashMap<>();
+        Map<Long, BigDecimal> beforeYestWaterVolumePair = new HashMap<>();
+        Map<Long, BigDecimal> beforeYestPumpTripsPair = new HashMap<>();
+        Map<Long, BigDecimal> beforeYestLayersPair = new HashMap<>();
+        Map<Long, BigDecimal> beforeYestMixSandPair = new HashMap<>();
+        Map<Long, BigDecimal> beforeYestFuelPair = new HashMap<>();
+        if (CollUtil.isNotEmpty(beforeYesterdayDailyReports)) {
+            beforeYesterdayDailyReports.forEach(report -> {
+                // 前天的日报施工数据  通过 任务井 与 昨天 的日报关联
+                if (rdStatusDictPair.containsKey(report.getRdStatus())) {
+                    beforeYesterdayStatus.put(report.getTaskId(), rdStatusDictPair.get(report.getRdStatus()));
+                }
+                beforeYesterdayProduct.put(report.getTaskId(), report.getProductionStatus());
+                // 设置前天的工作量数据
+                beforeYestFuelPair.put(report.getTaskId(), report.getDailyFuel());
+                // 工作量属性集合
+                List<IotTaskAttrModelProperty> workloadAttrs = report.getExtProperty();
+                // 暂存不同单位的工作量属性值
+                BigDecimal tempTotalBridgePlug = BigDecimal.ZERO;               // 桥塞(个数)
+                BigDecimal tempTotalRunCount = BigDecimal.ZERO;                 // 趟数
+                BigDecimal tempTotalCumulativeWorkingWell = BigDecimal.ZERO;    // 井数
+                BigDecimal tempTotalHourCount = BigDecimal.ZERO;                // 小时H
+                BigDecimal tempTotalWaterVolume = BigDecimal.ZERO;              // 水方量(方)
+                BigDecimal tempTotalPumpTrips = BigDecimal.ZERO;
+                BigDecimal tempTotalCumulativeWorkingLayers = BigDecimal.ZERO;  // 段数  累计施工-层
+                BigDecimal tempTotalMixSand = BigDecimal.ZERO;                  // 台次 当日泵车台次 当日仪表/混砂
+                if (CollUtil.isNotEmpty(workloadAttrs)) {
+                    for (IotTaskAttrModelProperty attr : workloadAttrs) {
+                        String unit = attr.getUnit();   // 工作量单位
+                        String actualValueStr = attr.getActualValue();  // 工作量属性的实际值
+                        // 处理实际值:避免null或非数字字符串导致的异常
+                        BigDecimal actualValue = BigDecimal.ZERO;
+                        if (StrUtil.isNotBlank(actualValueStr)) {  // 假设使用Hutool的StrUtil,或自行判断null/空
+                            try {
+                                actualValue = new BigDecimal(actualValueStr);
+                            } catch (NumberFormatException e) {
+                                // 若字符串格式错误,默认按0处理(可根据业务调整)
+                                actualValue = BigDecimal.ZERO;
+                            }
+                            if ("个数".equals(unit)) {
+                                tempTotalBridgePlug = tempTotalBridgePlug.add(actualValue);
+                            }
+                            if ("趟数".equals(unit)) {
+                                tempTotalRunCount = tempTotalRunCount.add(actualValue);
+                            }
+                            if ("小时".equals(unit)) {
+                                tempTotalHourCount = tempTotalHourCount.add(actualValue);
+                            }
+                            if ("天数".equals(unit)) {
+                                // 将 actualValue 换算成 H
+                                BigDecimal hours = actualValue.multiply(new BigDecimal("24"));
+                                tempTotalHourCount = tempTotalHourCount.add(hours);
+                            }
+                            if ("方".equals(unit)) {
+                                tempTotalWaterVolume = tempTotalWaterVolume.add(actualValue);
+                            }
+                            if ("段数".equals(unit)) {
+                                // 累计施工层
+                                tempTotalCumulativeWorkingLayers = tempTotalCumulativeWorkingLayers.add(actualValue);
+                            }
+                            if ("台次".equals(unit) && "当日泵车台次".equals(attr.getName())) {
+                                tempTotalPumpTrips = tempTotalPumpTrips.add(actualValue);
+                            }
+                            if ("台次".equals(unit) && ("当日仪表/混砂".equals(attr.getName())
+                                    || "当日混砂".equals(attr.getName()) || "当日仪表".equals(attr.getName()))) {
+                                tempTotalMixSand = tempTotalMixSand.add(actualValue);
+                            }
+                        }
+                    }
+                }
+                beforeYestBridgePlugPair.put(report.getTaskId(), tempTotalBridgePlug);
+                beforeYestRunCountPair.put(report.getTaskId(), tempTotalRunCount);
+                beforeYestHourCountPair.put(report.getTaskId(), tempTotalHourCount);
+                beforeYestWaterVolumePair.put(report.getTaskId(), tempTotalWaterVolume);
+                beforeYestLayersPair.put(report.getTaskId(), tempTotalCumulativeWorkingLayers);
+                beforeYestPumpTripsPair.put(report.getTaskId(), tempTotalPumpTrips);
+                beforeYestMixSandPair.put(report.getTaskId(), tempTotalMixSand);
+            });
+        }
+
+        // key日报id  value日报设备
+        Map<Long, String> reportDevicesPair = new HashMap<>();
+        List<IotRdDailyReportBriefRespVO> reportBriefs = new ArrayList<>();
+        if (CollUtil.isNotEmpty(dailyReports)) {
+            dailyReports.forEach(report -> {
+                // 设置每个日报对应的设备编码-名称 逗号分隔
+                IotRdDailyReportBriefRespVO reportBrief = new IotRdDailyReportBriefRespVO();
+                if (rdStatusDictPair.containsKey(report.getRdStatus())) {
+                    reportBrief.setRdStatus(rdStatusDictPair.get(report.getRdStatus()));
+                }
+                if (teamDeptPair.containsKey(report.getDeptId())) {
+                    reportBrief.setDeptName(teamDeptPair.get(report.getDeptId()).getName());
+                }
+                if (teamProjectIdPair.containsKey(report.getDeptId())) {
+                    Long parentId = teamProjectIdPair.get(report.getDeptId());
+                    if (projectDeptPair.containsKey(parentId)) {
+                        reportBrief.setProjectDeptName(projectDeptPair.get(parentId).getName());
+                    }
+                }
+                if (taskWellPair.containsKey(report.getTaskId())) {
+                    reportBrief.setWellName(taskWellPair.get(report.getTaskId()));
+                }
+                // 设置每个 日报 的设备编码-名称 字符串
+                Set<Long> thisDeviceIds = report.getDeviceIds();
+                String thisDeviceNames = Optional.ofNullable(thisDeviceIds)
+                        .filter(CollUtil::isNotEmpty)
+                        .map(devIds -> devIds.stream()
+                                .map(deviceIdCodeNamePair::get)
+                                .filter(Objects::nonNull)
+                                .filter(StrUtil::isNotBlank)
+                                .collect(Collectors.joining(",")))
+                        .orElse(""); // 如果为空,返回空字符串
+                reportBrief.setDeviceNames(thisDeviceNames);
+                Set<Long> thisTechniqueIds = report.getTechniqueIds();
+                String thisTechniqueNames = Optional.ofNullable(thisTechniqueIds)
+                        .filter(CollUtil::isNotEmpty)
+                        .map(techniqueIds -> techniqueIds.stream()
+                                .map(String::valueOf)  // 将 Long 转为 String
+                                .map(techniqueDictPair::get)  // 从字典获取名称
+                                .filter(Objects::nonNull)  // 过滤空值
+                                .filter(StrUtil::isNotBlank)  // 过滤空白值
+                                .collect(Collectors.joining(",")))  // 用逗号连接
+                        .orElse("");  // 如果为空,返回空字符串
+
+                reportBrief.setTechniques(thisTechniqueNames);
+                reportBrief.setProductionBrief(report.getProductionStatus());
+                reportBrief.setTotalDailyFuel(report.getDailyFuel());
+                // 工作量属性集合
+                List<IotTaskAttrModelProperty> workloadAttrs = report.getExtProperty();
+                // 暂存不同单位的工作量属性值
+                BigDecimal tempTotalBridgePlug = BigDecimal.ZERO;               // 桥塞(个数)
+                BigDecimal tempTotalRunCount = BigDecimal.ZERO;                 // 趟数
+                BigDecimal tempTotalCumulativeWorkingWell = BigDecimal.ZERO;    // 井数
+                BigDecimal tempTotalHourCount = BigDecimal.ZERO;                // 小时H
+                BigDecimal tempTotalWaterVolume = BigDecimal.ZERO;              // 水方量(方)
+                BigDecimal tempTotalPumpTrips = BigDecimal.ZERO;
+                BigDecimal tempTotalCumulativeWorkingLayers = BigDecimal.ZERO;  // 段数  累计施工-层
+                BigDecimal tempTotalMixSand = BigDecimal.ZERO;                  // 台次 当日泵车台次 当日仪表/混砂
+                if (CollUtil.isNotEmpty(workloadAttrs)) {
+                    for (IotTaskAttrModelProperty attr : workloadAttrs) {
+                        String unit = attr.getUnit();   // 工作量单位
+                        String actualValueStr = attr.getActualValue();  // 工作量属性的实际值
+                        // 处理实际值:避免null或非数字字符串导致的异常
+                        BigDecimal actualValue = BigDecimal.ZERO;
+                        if (StrUtil.isNotBlank(actualValueStr)) {  // 假设使用Hutool的StrUtil,或自行判断null/空
+                            try {
+                                actualValue = new BigDecimal(actualValueStr);
+                            } catch (NumberFormatException e) {
+                                // 若字符串格式错误,默认按0处理(可根据业务调整)
+                                actualValue = BigDecimal.ZERO;
+                            }
+                            if ("个数".equals(unit)) {
+                                tempTotalBridgePlug = tempTotalBridgePlug.add(actualValue);
+                            }
+                            if ("趟数".equals(unit)) {
+                                tempTotalRunCount = tempTotalRunCount.add(actualValue);
+                            }
+                            if ("小时".equals(unit)) {
+                                tempTotalHourCount = tempTotalHourCount.add(actualValue);
+                            }
+                            if ("天数".equals(unit)) {
+                                // 将 actualValue 换算成 H
+                                BigDecimal hours = actualValue.multiply(new BigDecimal("24"));
+                                tempTotalHourCount = tempTotalHourCount.add(hours);
+                            }
+                            if ("方".equals(unit)) {
+                                tempTotalWaterVolume = tempTotalWaterVolume.add(actualValue);
+                            }
+                            if ("段数".equals(unit)) {
+                                // 累计施工层
+                                tempTotalCumulativeWorkingLayers = tempTotalCumulativeWorkingLayers.add(actualValue);
+                            }
+                            if ("台次".equals(unit) && "当日泵车台次".equals(attr.getName())) {
+                                tempTotalPumpTrips = tempTotalPumpTrips.add(actualValue);
+                            }
+                            if ("台次".equals(unit) && ("当日仪表/混砂".equals(attr.getName())
+                                    || "当日混砂".equals(attr.getName()) || "当日仪表".equals(attr.getName()))) {
+                                tempTotalMixSand = tempTotalMixSand.add(actualValue);
+                            }
+                        }
+                    }
+                }
+                reportBrief.setCumulativeBridgePlug(tempTotalBridgePlug);
+                reportBrief.setCumulativeRunCount(tempTotalRunCount);
+                reportBrief.setCumulativeHourCount(tempTotalHourCount);
+                reportBrief.setCumulativeWaterVolume(tempTotalWaterVolume);
+                reportBrief.setCumulativeWorkingLayers(tempTotalCumulativeWorkingLayers);
+                reportBrief.setCumulativePumpTrips(tempTotalPumpTrips);
+                reportBrief.setCumulativeMixSand(tempTotalMixSand);
+                // 设置上一天的 工作量数据
+                if (beforeYestBridgePlugPair.containsKey(report.getTaskId())) {
+                    reportBrief.setYesterdayBridgePlug(beforeYestBridgePlugPair.get(report.getTaskId()));
+                }
+                if (beforeYestRunCountPair.containsKey(report.getTaskId())) {
+                    reportBrief.setYesterdayRunCount(beforeYestRunCountPair.get(report.getTaskId()));
+                }
+                if (beforeYestHourCountPair.containsKey(report.getTaskId())) {
+                    reportBrief.setYesterdayHourCount(beforeYestHourCountPair.get(report.getTaskId()));
+                }
+                if (beforeYestWaterVolumePair.containsKey(report.getTaskId())) {
+                    reportBrief.setYesterdayWaterVolume(beforeYestWaterVolumePair.get(report.getTaskId()));
+                }
+                if (beforeYestLayersPair.containsKey(report.getTaskId())) {
+                    reportBrief.setYesterdayWorkingLayers(beforeYestLayersPair.get(report.getTaskId()));
+                }
+                if (beforeYestPumpTripsPair.containsKey(report.getTaskId())) {
+                    reportBrief.setYesterdayPumpTrips(beforeYestPumpTripsPair.get(report.getTaskId()));
+                }
+                if (beforeYestMixSandPair.containsKey(report.getTaskId())) {
+                    reportBrief.setYesterdayMixSand(beforeYestMixSandPair.get(report.getTaskId()));
+                }
+                if (beforeYesterdayStatus.containsKey(report.getTaskId())) {
+                    reportBrief.setYesterdayStatus(beforeYesterdayStatus.get(report.getTaskId()));
+                }
+                if (beforeYesterdayProduct.containsKey(report.getTaskId())) {
+                    reportBrief.setYesterdayProduct(beforeYesterdayProduct.get(report.getTaskId()));
+                }
+                reportBriefs.add(reportBrief);
+            });
+        }
+        return reportBriefs;
+    }
+
+    @Override
+    public List<IotRdDailyReportAbnormalRespVO> abnormalAlert(IotRdDailyReportPageReqVO pageReqVO) {
+        List<IotRdDailyReportAbnormalRespVO> result = new ArrayList<>();
+        // 查询指定时间范围内的异常警示信息
+        // 待命 物资 三方 维修 人员 甲方 异常 天气 井口
+        IotRdDailyReportPageReqVO reportReqVO = new IotRdDailyReportPageReqVO();
+        List<IotRdDailyReportDO> dailyReports = iotRdDailyReportMapper.dailyReports(reportReqVO);
+        //  施工状态 key字典键值     value字典标签
+        Map<String, String> rdStatusDictPair = new HashMap<>();
+        Map<String, Set<Long>> abnormalReportPair = new HashMap<>();
+        if (CollUtil.isNotEmpty(dailyReports)) {
+            // 查询施工状态字典数据
+            List<DictDataDO> rdStatuses = dictDataService.getDictDataListByDictType("rdStatus");
+            if (CollUtil.isNotEmpty(rdStatuses)) {
+                rdStatuses.forEach(tech -> {
+                    // 筛选出停待状态 的施工状态
+                    if ("TD".equals(tech.getRemark())) {
+                        rdStatusDictPair.put(tech.getValue(), tech.getLabel());
+                    }
+                });
+            }
+            dailyReports.forEach(report -> {
+                if (rdStatusDictPair.containsKey(report.getRdStatus())) {
+                    String statusLabel = rdStatusDictPair.get(report.getRdStatus());
+                    if (abnormalReportPair.containsKey(statusLabel)) {
+                        Set<Long> tempIds = abnormalReportPair.get(statusLabel);
+                        tempIds.add(report.getId());
+                        abnormalReportPair.put(statusLabel, tempIds);
+                    } else {
+                        Set<Long> tempIds = new HashSet<>();
+                        tempIds.add(report.getId());
+                        abnormalReportPair.put(statusLabel, tempIds);
+                    }
+                }
+            });
+        }
+        if (CollUtil.isNotEmpty(abnormalReportPair)) {
+            abnormalReportPair.forEach((statusLabel, reportIds) -> {
+                IotRdDailyReportAbnormalRespVO resp = new IotRdDailyReportAbnormalRespVO();
+                resp.setName(statusLabel);
+                resp.setCount(reportIds.size());
+                result.add(resp);
+            });
+        }
+        return result;
+    }
+
 }