Prechádzať zdrojové kódy

Merge remote-tracking branch 'origin/master'

lipenghui 1 týždeň pred
rodič
commit
fef54003a2
13 zmenil súbory, kde vykonal 346 pridanie a 130 odobranie
  1. 3 0
      yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/iotattachment/vo/IotAttachmentPageReqVO.java
  2. 45 5
      yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/iotopeationfill/IotOpeationFillController.java
  3. 19 0
      yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/iotprojecttask/vo/IotProjectTaskPlatformVO.java
  4. 102 5
      yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/iotrddailyreport/IotRdDailyReportController.java
  5. 9 7
      yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/iotrydailyreport/IotRyDailyReportController.java
  6. 1 0
      yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/dal/mysql/iotattachment/IotAttachmentMapper.java
  7. 1 4
      yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/dal/mysql/iotopeationfill/IotOpeationFillMapper.java
  8. 88 93
      yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/job/IotOperationPlanJob.java
  9. 1 4
      yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/service/iotopeationfill/IotOpeationFillService.java
  10. 1 4
      yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/service/iotopeationfill/IotOpeationFillServiceImpl.java
  11. 65 6
      yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/service/iotrhdailyreport/IotRhDailyReportServiceImpl.java
  12. 8 1
      yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/service/iotrydailyreport/IotRyDailyReportServiceImpl.java
  13. 3 1
      yudao-module-pms/yudao-module-pms-biz/src/main/resources/mapper/static/IotOpeationFillMapper.xml

+ 3 - 0
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/iotattachment/vo/IotAttachmentPageReqVO.java

@@ -8,6 +8,7 @@ import lombok.ToString;
 import org.springframework.format.annotation.DateTimeFormat;
 
 import java.time.LocalDateTime;
+import java.util.Collection;
 
 import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
 
@@ -45,4 +46,6 @@ public class IotAttachmentPageReqVO extends PageParam {
     @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
     private LocalDateTime[] createTime;
 
+    @Schema(description = "业务主键id 集合", example = "3510,3610")
+    private Collection<Long> bizIds;
 }

+ 45 - 5
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/iotopeationfill/IotOpeationFillController.java

@@ -25,6 +25,7 @@ import cn.iocoder.yudao.module.pms.service.iotrhdailyreport.IotRhDailyReportServ
 import cn.iocoder.yudao.module.pms.service.iotrydailyreport.IotRyDailyReportService;
 import cn.iocoder.yudao.module.pms.service.yanfan.YfDeviceService;
 import cn.iocoder.yudao.module.system.service.dept.DeptService;
+import com.alibaba.fastjson.JSON;
 import com.aliyun.tea.utils.StringUtils;
 import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
 import lombok.extern.slf4j.Slf4j;
@@ -311,6 +312,33 @@ public class IotOpeationFillController {
                     .flatMap(vo -> vo.getDeviceInfoList().stream())
                     .collect(Collectors.toList());
 
+
+            // 1. 集合类型改为实体类列表
+            List<IotOpeationFillSaveReqVO > uniqueDeviceEntities = new ArrayList<>();
+
+            // 空值防护:先判断外层集合是否为null或空
+            if (createReqVO != null && !createReqVO.isEmpty()) {
+                uniqueDeviceEntities = createReqVO.stream()
+                        // 1. 过滤外层集合中:内部 deviceInfoList 为 null 的元素
+                        .filter(operationSaveInfo -> operationSaveInfo.getDeviceInfoList() != null)
+                        // 2. 展开内层集合(合并为一个流)
+                        .flatMap(operationSaveInfo -> operationSaveInfo.getDeviceInfoList().stream())
+                        // 3. 过滤内层元素:deviceInfo 为 null 或 deviceId 为 null 的情况
+                        .filter(deviceInfo -> deviceInfo != null && deviceInfo.getDeviceId() != null)
+                        // 4. 核心修改:提取 deviceId 并创建实体类对象(而非转 String)
+                        .map(deviceInfo -> {
+                            IotOpeationFillSaveReqVO saveReqVO = new IotOpeationFillSaveReqVO();
+                            saveReqVO.setDeviceId(deviceInfo.getDeviceId());
+                            saveReqVO.setCreateTime(deviceInfo.getCreateTime());
+                            return saveReqVO;
+                        })
+                        // 5. 去重:需重写实体类的 equals() 和 hashCode()(关键!)
+                        .distinct()
+                        // 6. 收集为实体类列表
+                        .collect(Collectors.toList());
+            }
+
+
             // 验证数据不为空
             if (CollectionUtils.isEmpty(allFillData)) {
                 return error(1, "设备数据不能为空");
@@ -339,10 +367,12 @@ public class IotOpeationFillController {
             generateDailyReports(logDOList, deptMap, createDate,userId);
 
             // 9. 批量更新工单填写状态
-            iotOpeationFillService.batchUpdateFill(allFillData);
+            int a = iotOpeationFillService.batchUpdateFill(uniqueDeviceEntities);
+
+
+                // 5. 更新填写状态
+                updateFillOrderStatus(orderId, userId, createDate);
 
-            // 5. 更新填写状态
-            updateFillOrderStatus(orderId, userId, createDate);
 
             return success(1);
 
@@ -681,7 +711,7 @@ public class IotOpeationFillController {
         Map<String, Object> reportData = BeanUtil.beanToMap(saveReqVO);
 
         for (IotDeviceRunLogDO log : deviceLogs) {
-            IotDeviceRunLogDO descDO = descMap.get(log.getPointName()); // 从缓存获取,无数据库交互
+            IotDeviceRunLogDO descDO = iotOpeationFillService.getDesc(log);
             if (descDO != null && reportData.containsKey(descDO.getPointName())) {
                 reportData.put(descDO.getPointName(), log.getFillContent());
             }
@@ -703,11 +733,20 @@ public class IotOpeationFillController {
         IotRyDailyReportSaveReqVO saveReqVO = new IotRyDailyReportSaveReqVO();
         Map<String, Object> reportData = BeanUtil.beanToMap(saveReqVO);
 
+        IotOpeationFillDO reportDO = new IotOpeationFillDO();
         for (IotDeviceRunLogDO log : deviceLogs) {
-            IotDeviceRunLogDO descDO = descMap.get(log.getPointName()); // 从缓存获取,无数据库交互
+            //IotDeviceRunLogDO descDO = descMap.get(log.getPointName()); // 从缓存获取,无数据库交互
+            IotDeviceRunLogDO descDO = iotOpeationFillService.getDesc(log);
             if (descDO != null && reportData.containsKey(descDO.getPointName())) {
                 reportData.put(descDO.getPointName(), log.getFillContent());
             }
+
+            reportDO.setDeviceId(log.getDeviceId());
+            reportDO.setCreateTime(log.getCreateTime());
+            IotOpeationFillDO fillDO1 = iotOpeationFillService.isReport(reportDO);
+            if(fillDO1.getDeviceCategoryId()==228){
+                reportData.put("projectClassification","2");
+            }
         }
 
         // 后续赋值和保存逻辑不变(建议日报也做批量保存,若存在多条设备)
@@ -715,6 +754,7 @@ public class IotOpeationFillController {
         finalReport.setDeptId(fillStatus.getDeptId());
         finalReport.setFillOrderCreateTime(createDate.atStartOfDay());
         finalReport.setCreator(String.valueOf(fillStatus.getUserId()));
+
         iotRyDailyReportService.createIotRyDailyReport(finalReport);
     }
 

+ 19 - 0
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/iotprojecttask/vo/IotProjectTaskPlatformVO.java

@@ -1,5 +1,6 @@
 package cn.iocoder.yudao.module.pms.controller.admin.iotprojecttask.vo;
 
+import cn.iocoder.yudao.module.pms.dal.dataobject.iotattachment.IotAttachmentDO;
 import cn.iocoder.yudao.module.pms.dal.dataobject.iotprojecttaskattrs.IotTaskAttrModelProperty;
 import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
 import io.swagger.v3.oas.annotations.media.Schema;
@@ -43,4 +44,22 @@ public class IotProjectTaskPlatformVO {
 
     @Schema(description = "关联井当日油耗", example = "12.3")
     private BigDecimal dailyFuel;
+
+    @Schema(description = "当日生产情况生产动态", example = "正常施工")
+    private String productionStatus;;
+
+    @Schema(description = "下步工作计划", example = "继续施工")
+    private String nextPlan;
+
+    @Schema(description = "外租情况")
+    private String externalRental;
+
+    @Schema(description = "故障情况")
+    private String malfunction;
+
+    @Schema(description = "故障误工h")
+    private BigDecimal faultDowntime;
+
+    @Schema(description = "附件列表")
+    private List<IotAttachmentDO> attachments;
 }

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

@@ -32,6 +32,7 @@ import cn.iocoder.yudao.module.pms.dal.dataobject.iotprojectinfo.IotProjectInfoD
 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.iotattachment.IotAttachmentMapper;
 import cn.iocoder.yudao.module.pms.dal.mysql.iotcarzhbd.IotCarZhbdMapper;
 import cn.iocoder.yudao.module.pms.enums.AttachmentCategoryEnum;
 import cn.iocoder.yudao.module.pms.enums.AttachmentTypeEnum;
@@ -69,6 +70,7 @@ import java.time.format.DateTimeFormatter;
 import java.time.format.DateTimeParseException;
 import java.time.temporal.ChronoUnit;
 import java.util.*;
+import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.stream.Collectors;
 
 import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.EXPORT;
@@ -115,6 +117,8 @@ public class IotRdDailyReportController {
     private ZHBDUtil zhbdUtil;
     @Resource
     private IotDailyReportFuelService iotDailyReportFuelService;
+    @Resource
+    private IotAttachmentMapper iotAttachmentMapper;
 
     @PostMapping("/create")
     @Operation(summary = "创建瑞都日报")
@@ -195,14 +199,46 @@ public class IotRdDailyReportController {
             dailyReportVO.setVirtualProject(project.getContractSubject());
         }
         // 查询当前日报是否已经绑定了油耗信息
+        // 兼容主井完工 关联井 没有完工的情况 查询关联井的油耗信息
         boolean hasFuels = false;
-        IotDailyReportFuelPageReqVO fuelPageReqVO = new IotDailyReportFuelPageReqVO();
+        /* IotDailyReportFuelPageReqVO fuelPageReqVO = new IotDailyReportFuelPageReqVO();
         fuelPageReqVO.setType("RD");
         fuelPageReqVO.setReportId(dailyReport.getId());
-        List<IotDailyReportFuelDO> reportFuels = iotDailyReportFuelService.getIotDailyReportFuels(fuelPageReqVO);
-        if (CollUtil.isNotEmpty(reportFuels)) {
+        List<IotDailyReportFuelDO> reportFuels = iotDailyReportFuelService.getIotDailyReportFuels(fuelPageReqVO); */
+
+        // 查询所有主井 关联井 油耗
+        Map<Long, List<IotDailyReportFuelDO>> reportedFuelsPair = new HashMap<>();
+        if (1 == dailyReport.getPlatformWell()) {
+            // 查询相同平台井组关联的 日报
+            IotRdDailyReportPageReqVO reportReqVO  = new IotRdDailyReportPageReqVO();
+            reportReqVO.setPlatformGroup(dailyReport.getPlatformGroup());
+            List<IotRdDailyReportDO> reports = iotRdDailyReportService.dailyReports(reportReqVO);
+            List<Long> reportIds = convertList(reports, IotRdDailyReportDO::getId);
+            // 兼容主井 完工 关联井未完工 的情况 查询关联井的油耗信息
+            IotDailyReportFuelPageReqVO fuelReqVO = new IotDailyReportFuelPageReqVO();
+            fuelReqVO.setType("RD");
+            fuelReqVO.setReportIds(reportIds);
+            List<IotDailyReportFuelDO> reportedFuels = iotDailyReportFuelService.getIotDailyReportFuels(fuelReqVO);
+            if (CollUtil.isNotEmpty(reportedFuels)) {
+                reportedFuels.forEach(fuel -> {
+                    if (reportedFuelsPair.containsKey(fuel.getReportId())) {
+                        List<IotDailyReportFuelDO> tempFuels = reportedFuelsPair.get(fuel.getReportId());
+                        tempFuels.add(fuel);
+                        reportedFuelsPair.put(fuel.getReportId(), tempFuels);
+                    } else {
+                        List<IotDailyReportFuelDO> tempFuels = new ArrayList<>();
+                        tempFuels.add(fuel);
+                        reportedFuelsPair.put(fuel.getReportId(), tempFuels);
+                    }
+                });
+            }
+        }
+
+        if (CollUtil.isNotEmpty(reportedFuelsPair)) {
             hasFuels = true;
-            dailyReportVO.setReportedFuels(reportFuels);
+            reportedFuelsPair.forEach((reportId, fuels) -> {
+                dailyReportVO.setReportedFuels(fuels);
+            });
         }
         // 查询施工工艺字典数据
         List<DictDataDO> rdTechniquesDicts = dictDataService.getDictDataListByDictType("rq_iot_project_technology_rd");
@@ -501,6 +537,31 @@ public class IotRdDailyReportController {
             IotRdDailyReportPageReqVO reportReqVO  = new IotRdDailyReportPageReqVO();
             reportReqVO.setPlatformGroup(dailyReport.getPlatformGroup());
             List<IotRdDailyReportDO> reports = iotRdDailyReportService.dailyReports(reportReqVO);
+            // 查询所有主井 关联井 附件
+            Map<Long, List<IotAttachmentDO>> reportAttachmentsPair = new HashMap<>();
+
+            if (CollUtil.isNotEmpty(reports)) {
+                List<Long> reportIds = convertList(reports, IotRdDailyReportDO::getId);
+                // 兼容主井 完工 关联井未完工 的情况 查询关联井的附件
+                IotAttachmentPageReqVO attachmentReqVO = new IotAttachmentPageReqVO();
+                attachmentReqVO.setBizIds(reportIds);
+                attachmentReqVO.setCategory(AttachmentCategoryEnum.DAILY_REPORT.getCode());
+                attachmentReqVO.setType(AttachmentTypeEnum.EXTERNAL_RENTAL.getCode());
+                List<IotAttachmentDO> reportsAttachments = iotAttachmentMapper.attachments(attachmentReqVO);
+                if (CollUtil.isNotEmpty(reportsAttachments)) {
+                    reportsAttachments.forEach(attachment -> {
+                        if (reportAttachmentsPair.containsKey(attachment.getBizId())) {
+                            List<IotAttachmentDO> tempAttachments = reportAttachmentsPair.get(attachment.getBizId());
+                            tempAttachments.add(attachment);
+                            reportAttachmentsPair.put(attachment.getBizId(), tempAttachments);
+                        } else {
+                            List<IotAttachmentDO> tempAttachments = new ArrayList<>();
+                            tempAttachments.add(attachment);
+                            reportAttachmentsPair.put(attachment.getBizId(), tempAttachments);
+                        }
+                    });
+                }
+            }
             // key任务id  value日报id
             Map<Long, Long> reportPair = new HashMap<>();
             // key任务id  value任务井对应日报当日油耗
@@ -532,6 +593,14 @@ public class IotRdDailyReportController {
                     }
                     platformVO.setTechniqueIds(report.getTechniqueIds());
                     platformVO.setExtProperty(report.getExtProperty());
+                    platformVO.setProductionStatus(report.getProductionStatus());
+                    platformVO.setNextPlan(report.getNextPlan());
+                    platformVO.setExternalRental(report.getExternalRental());
+                    platformVO.setMalfunction(report.getMalfunction());
+                    platformVO.setFaultDowntime(report.getFaultDowntime());
+                    if (reportAttachmentsPair.containsKey(report.getId())) {
+                        platformVO.setAttachments(reportAttachmentsPair.get(report.getId()));
+                    }
                     platformPair.put(report.getTaskId(), platformVO);
                 });
             }
@@ -554,7 +623,7 @@ public class IotRdDailyReportController {
                     }
                 });
             }
-            // 返回已经填报的油耗记录
+            // 如果主井已经 完工 则显示 首个关联井 的 生产动态 下步计划 ...
 
             List<IotProjectTaskPlatformVO> platforms = new ArrayList<>();
             if (CollUtil.isNotEmpty(tasks)) {
@@ -574,12 +643,21 @@ public class IotRdDailyReportController {
                             platform.setTechniqueIds(tempPlatform.getTechniqueIds());
                             platform.setTechniqueNames(tempPlatform.getTechniqueNames());
                             platform.setExtProperty(tempPlatform.getExtProperty());
+                            platform.setProductionStatus(tempPlatform.getProductionStatus());
+                            platform.setNextPlan(tempPlatform.getNextPlan());
+                            platform.setExternalRental(tempPlatform.getExternalRental());
+                            platform.setMalfunction(tempPlatform.getMalfunction());
+                            platform.setFaultDowntime(tempPlatform.getFaultDowntime());
+                            platform.setAttachments(tempPlatform.getAttachments());
                         }
                         platforms.add(platform);
                     }
                 });
                 dailyReportVO.setPlatforms(platforms);
             }
+
+            // 如果当前井id不存在集合 platforms 中 说明 主井已完工 关联井 未完工
+
             if (CollUtil.isEmpty(platforms)) {
                 List<IotProjectTaskPlatformVO> finishedPlatforms = new ArrayList<>();
                 // key任务井id   value任务井名称
@@ -641,6 +719,25 @@ public class IotRdDailyReportController {
                     });
                 }
                 dailyReportVO.setFinishedPlatforms(finishedPlatforms);
+            } else {
+                AtomicBoolean mainExist = new AtomicBoolean(false);
+                // 如果当前井id不存在集合 platforms 中 说明 主井已完工 关联井 未完工
+                platforms.forEach(platform -> {
+                    if (dailyReportVO.getId().equals(platform.getReportId())) {
+                        mainExist.set(true);
+                    }
+                });
+                if (!mainExist.get()) {
+                    // 主井不存在 需要显示 关联井的 主体信息 生产动态 计划 ...
+                    platforms.forEach(platform -> {
+                        dailyReportVO.setProductionStatus(platform.getProductionStatus());
+                        dailyReportVO.setNextPlan(platform.getNextPlan());
+                        dailyReportVO.setExternalRental(platform.getExternalRental());
+                        dailyReportVO.setMalfunction(platform.getMalfunction());
+                        dailyReportVO.setFaultDowntime(platform.getFaultDowntime());
+                        dailyReportVO.setAttachments(platform.getAttachments());
+                    });
+                }
             }
         }
         return dailyReportVO;

+ 9 - 7
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/iotrydailyreport/IotRyDailyReportController.java

@@ -322,19 +322,21 @@ public class IotRyDailyReportController {
             // 按施工队伍统计 钻井日报 施工井数 完工井数
             List<IotRyDailyReportTaskCountVO> deptTasks = iotRyDailyReportService.countTasksByDept();
             // 修井日报 不存在既填写钻井日报 又填写修井日报的队伍
-            List<IotRyDailyReportTaskCountVO> repairDeptTasks = iotRyDailyReportService.countRepairTasksByDept(pageReqVO);
+            if (ObjUtil.isNotEmpty(pageReqVO.getCreateTime())) {
+                List<IotRyDailyReportTaskCountVO> repairDeptTasks = iotRyDailyReportService.countRepairTasksByDept(pageReqVO);
+                if (CollUtil.isNotEmpty(repairDeptTasks)) {
+                    repairDeptTasks.forEach(task -> {
+                        totalTasksPair.put(task.getDeptId(), task.getTotalTaskCount());
+                        completedTasksPair.put(task.getDeptId(), task.getCompletedTaskCount());
+                    });
+                }
+            }
             if (CollUtil.isNotEmpty(deptTasks)) {
                 deptTasks.forEach(task -> {
                     totalTasksPair.put(task.getDeptId(), task.getTotalTaskCount());
                     completedTasksPair.put(task.getDeptId(), task.getCompletedTaskCount());
                 });
             }
-            if (CollUtil.isNotEmpty(repairDeptTasks)) {
-                repairDeptTasks.forEach(task -> {
-                    totalTasksPair.put(task.getDeptId(), task.getTotalTaskCount());
-                    completedTasksPair.put(task.getDeptId(), task.getCompletedTaskCount());
-                });
-            }
         });
         // 2. 拼接数据
         return BeanUtils.toBean(reports, IotRyDailyReportRespVO.class, (reportVO) -> {

+ 1 - 0
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/dal/mysql/iotattachment/IotAttachmentMapper.java

@@ -35,6 +35,7 @@ public interface IotAttachmentMapper extends BaseMapperX<IotAttachmentDO> {
         return selectList(new LambdaQueryWrapperX<IotAttachmentDO>()
                 .eqIfPresent(IotAttachmentDO::getCategory, reqVO.getCategory())
                 .eqIfPresent(IotAttachmentDO::getBizId, reqVO.getBizId())
+                .inIfPresent(IotAttachmentDO::getBizId, reqVO.getBizIds())
                 .eqIfPresent(IotAttachmentDO::getType, reqVO.getType())
                 .likeIfPresent(IotAttachmentDO::getFilename, reqVO.getFilename())
                 .eqIfPresent(IotAttachmentDO::getFileType, reqVO.getFileType())

+ 1 - 4
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/dal/mysql/iotopeationfill/IotOpeationFillMapper.java

@@ -5,10 +5,7 @@ import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
 import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
 import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnore;
 import cn.iocoder.yudao.module.pms.controller.admin.iotmodeltemplateattrs.vo.IotModelTemplateAttrsRespVO;
-import cn.iocoder.yudao.module.pms.controller.admin.iotopeationfill.vo.IotOpeationFillPageReqVO;
-import cn.iocoder.yudao.module.pms.controller.admin.iotopeationfill.vo.IotOpeationFillPageVO;
-import cn.iocoder.yudao.module.pms.controller.admin.iotopeationfill.vo.IotOpeationFillRespVO;
-import cn.iocoder.yudao.module.pms.controller.admin.iotopeationfill.vo.IotOpeationFillSaveReqVO;
+import cn.iocoder.yudao.module.pms.controller.admin.iotopeationfill.vo.*;
 import cn.iocoder.yudao.module.pms.controller.admin.vo.DeviceVO;
 import cn.iocoder.yudao.module.pms.controller.admin.vo.IotDeviceRespVO;
 import cn.iocoder.yudao.module.pms.dal.dataobject.IotDeviceDO;

+ 88 - 93
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/job/IotOperationPlanJob.java

@@ -57,7 +57,7 @@ import static cn.iocoder.yudao.module.pms.framework.config.MultiThreadConfigurat
  * @date 2025/5/11 10:26
  * @description
  */
-@Component
+/*@Component*/
 @Slf4j
 public class IotOperationPlanJob implements JobHandler {
 
@@ -202,107 +202,102 @@ public class IotOperationPlanJob implements JobHandler {
         //判断是否为瑞恒特殊计划
         if(plan.getId()==153L){
             unNormalTeamInPlan(plan);
-        }
-
-        //4、根据设备ID生成子表数据
-        List<IotOpeationFillDO> deviceList = iotOpeationFillMapper.getFillDevices(devIdList);
-        List<Integer> idList = deviceList.stream().map(IotOpeationFillDO::getUserId).collect(Collectors.toList());
-        List<IotOpeationFillOrderDO> orderList1 = orderList.stream()
-                .filter(obj -> idList.contains(obj.getUserId()))
-                .collect(Collectors.toList());
-
-
-
-        Set<Long> ryIdList = new HashSet<>();
-        if(plan.getIsReport()==1){//日报
-            //瑞鹰
-            ryIdList =  deptService.getChildDeptIdListFromCache(158L);
-            ryIdList.add(158L);
-
-            List<IotOpeationFillOrderDO> zxjOrderList = new ArrayList<>();
-
-            for (IotOpeationFillOrderDO orderDO:orderList1) {
-                IotDeviceRunLogDO runLogDO = new IotDeviceRunLogDO();
-                runLogDO.setDeptId(orderDO.getDeptId());
-                //获取队伍类型
-                IotDeviceRunLogDO teamType = iotOpeationFillMapper.getTeamType(runLogDO);
-
-                //如果是钻井队伍,则日报工单责任人更新为技术员
-                //修井队伍不变
-                if(teamType!=null&&teamType.getPointCode().equals("zj")){
-                    //获取技术员信息
-                    AdminUserDO userInfo = iotOpeationFillMapper.getUserInfo(runLogDO);
-                    if(userInfo!=null){
-                        orderDO.setUserName(userInfo.getUsername());
-                        orderDO.setUserId(new BigDecimal(userInfo.getId()).intValue());
-                        orderDO.setMobile(userInfo.getMobile());
-                    }
-                    zxjOrderList.add(orderDO);
-                }else if(teamType!=null&&teamType.getPointCode().equals("xj")){
-                    zxjOrderList.add(orderDO);
-                }
-            }
+        }else{
+            //4、根据设备ID生成子表数据
+            List<IotOpeationFillDO> deviceList = iotOpeationFillMapper.getFillDevices(devIdList);
+            List<Integer> idList = deviceList.stream().map(IotOpeationFillDO::getUserId).collect(Collectors.toList());
+            List<IotOpeationFillOrderDO> orderList1 = orderList.stream()
+                    .filter(obj -> idList.contains(obj.getUserId()))
+                    .collect(Collectors.toList());
 
 
-            // 按dept_id去重,保留第一个出现的元素
-            List<IotOpeationFillOrderDO> distinctOrderList = zxjOrderList.stream()
-                    .collect(Collectors.toMap(
-                            IotOpeationFillOrderDO::getDeptId,
-                            order -> {
-                                order.setId(null); // 关键:重置ID,避免与已有数据冲突
-                                return order;
-                            },
-                            (existing, replacement) -> existing
-                    ))
-                    .values()
-                    .stream()
-                    .collect(Collectors.toList());
-            //插入工单主表
-            iotOpeationFillOrderMapper.insertBatch(distinctOrderList);
-            //发送钉钉消息
-            sendDingMessage(distinctOrderList);
 
-            boolean ryContain = ryIdList.contains(plan.getDeptId());
-            //瑞鹰日报插入
-            ryReportInsert(plan,distinctOrderList,ryContain);
+            Set<Long> ryIdList = new HashSet<>();
+            if(plan.getIsReport()==1){//日报
+                //瑞鹰
+                ryIdList =  deptService.getChildDeptIdListFromCache(158L);
+                ryIdList.add(158L);
+
+                List<IotOpeationFillOrderDO> zxjOrderList = new ArrayList<>();
+
+                for (IotOpeationFillOrderDO orderDO:orderList1) {
+                    IotDeviceRunLogDO runLogDO = new IotDeviceRunLogDO();
+                    runLogDO.setDeptId(orderDO.getDeptId());
+                    //获取队伍类型
+                    IotDeviceRunLogDO teamType = iotOpeationFillMapper.getTeamType(runLogDO);
+
+                    //如果是钻井队伍,则日报工单责任人更新为技术员
+                    //修井队伍不变
+                    if(teamType!=null&&teamType.getPointCode().equals("zj")){
+                        //获取技术员信息
+                        AdminUserDO userInfo = iotOpeationFillMapper.getUserInfo(runLogDO);
+                        if(userInfo!=null){
+                            orderDO.setUserName(userInfo.getUsername());
+                            orderDO.setUserId(new BigDecimal(userInfo.getId()).intValue());
+                            orderDO.setMobile(userInfo.getMobile());
+                        }
+                        zxjOrderList.add(orderDO);
+                    }else if(teamType!=null&&teamType.getPointCode().equals("xj")){
+                        zxjOrderList.add(orderDO);
+                    }
+                }
 
-        }else{
 
-            //插入工单主表
-            iotOpeationFillOrderMapper.insertBatch(orderList1);
-            //瑞都
-            ryIdList =  deptService.getChildDeptIdListFromCache(163L);
-            ryIdList.add(163L);
-            Set<Long> rhIdList = new HashSet<>();
-            rhIdList =  deptService.getChildDeptIdListFromCache(157L);//瑞恒
-            rhIdList.add(157L);
-            boolean exist = ryIdList.contains(plan.getDeptId());
-            if(!exist){
-                boolean rhContain = rhIdList.contains(plan.getDeptId());
-                //瑞恒日报插入
-                rhReportInsert(plan, orderList1, rhContain);
-            }
-            //发送钉钉消息
-            sendDingMessage(orderList1);
-            //正常工单设备
-            for (IotOpeationFillDO device:deviceList) {
-                for (IotOpeationFillOrderDO order:orderList1) {
-                    if(device.getUserId().intValue()==order.getUserId().intValue()){
-                        device.setOrderId(order.getId());
+                // 按dept_id去重,保留第一个出现的元素
+                List<IotOpeationFillOrderDO> distinctOrderList = zxjOrderList.stream()
+                        .collect(Collectors.toMap(
+                                IotOpeationFillOrderDO::getDeptId,
+                                order -> {
+                                    order.setId(null); // 关键:重置ID,避免与已有数据冲突
+                                    return order;
+                                },
+                                (existing, replacement) -> existing
+                        ))
+                        .values()
+                        .stream()
+                        .collect(Collectors.toList());
+                //插入工单主表
+                iotOpeationFillOrderMapper.insertBatch(distinctOrderList);
+                //发送钉钉消息
+                sendDingMessage(distinctOrderList);
+
+                boolean ryContain = ryIdList.contains(plan.getDeptId());
+                //瑞鹰日报插入
+                ryReportInsert(plan,distinctOrderList,ryContain);
+
+            }else{
+
+                //插入工单主表
+                iotOpeationFillOrderMapper.insertBatch(orderList1);
+                //瑞都
+                ryIdList =  deptService.getChildDeptIdListFromCache(163L);
+                ryIdList.add(163L);
+                Set<Long> rhIdList = new HashSet<>();
+                rhIdList =  deptService.getChildDeptIdListFromCache(157L);//瑞恒
+                rhIdList.add(157L);
+                boolean exist = ryIdList.contains(plan.getDeptId());
+                if(!exist){
+                    boolean rhContain = rhIdList.contains(plan.getDeptId());
+                    //瑞恒日报插入
+                    rhReportInsert(plan, orderList1, rhContain);
+                }
+                //发送钉钉消息
+                sendDingMessage(orderList1);
+                //正常工单设备
+                for (IotOpeationFillDO device:deviceList) {
+                    for (IotOpeationFillOrderDO order:orderList1) {
+                        if(device.getUserId().intValue()==order.getUserId().intValue()){
+                            device.setOrderId(order.getId());
+                        }
                     }
                 }
+                //插入子表
+                for (IotOpeationFillDO re:deviceList) {
+                    re.setDeviceId(re.getId());
+                }
+                iotOpeationFillMapper.insertFill(deviceList);
             }
-            //插入子表
-            for (IotOpeationFillDO re:deviceList) {
-                re.setDeviceId(re.getId());
-            }
-            iotOpeationFillMapper.insertFill(deviceList);
         }
-
-
-
-
-
     }
 
     private void sendDingMessage(List<IotOpeationFillOrderDO> orderList1) {

+ 1 - 4
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/service/iotopeationfill/IotOpeationFillService.java

@@ -3,10 +3,7 @@ package cn.iocoder.yudao.module.pms.service.iotopeationfill;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnore;
 import cn.iocoder.yudao.module.pms.controller.admin.iotmodeltemplateattrs.vo.IotModelTemplateAttrsRespVO;
-import cn.iocoder.yudao.module.pms.controller.admin.iotopeationfill.vo.IotOpeationFillPageReqVO;
-import cn.iocoder.yudao.module.pms.controller.admin.iotopeationfill.vo.IotOpeationFillPageVO;
-import cn.iocoder.yudao.module.pms.controller.admin.iotopeationfill.vo.IotOpeationFillRespVO;
-import cn.iocoder.yudao.module.pms.controller.admin.iotopeationfill.vo.IotOpeationFillSaveReqVO;
+import cn.iocoder.yudao.module.pms.controller.admin.iotopeationfill.vo.*;
 import cn.iocoder.yudao.module.pms.controller.admin.vo.IotDeviceRespVO;
 import cn.iocoder.yudao.module.pms.dal.dataobject.iotcountdata.IotCountDataDO;
 import cn.iocoder.yudao.module.pms.dal.dataobject.iotdevicecountdata.IotDeviceCountData;

+ 1 - 4
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/service/iotopeationfill/IotOpeationFillServiceImpl.java

@@ -1,10 +1,7 @@
 package cn.iocoder.yudao.module.pms.service.iotopeationfill;
 
 import cn.iocoder.yudao.module.pms.controller.admin.iotmodeltemplateattrs.vo.IotModelTemplateAttrsRespVO;
-import cn.iocoder.yudao.module.pms.controller.admin.iotopeationfill.vo.IotOpeationFillPageReqVO;
-import cn.iocoder.yudao.module.pms.controller.admin.iotopeationfill.vo.IotOpeationFillPageVO;
-import cn.iocoder.yudao.module.pms.controller.admin.iotopeationfill.vo.IotOpeationFillRespVO;
-import cn.iocoder.yudao.module.pms.controller.admin.iotopeationfill.vo.IotOpeationFillSaveReqVO;
+import cn.iocoder.yudao.module.pms.controller.admin.iotopeationfill.vo.*;
 import cn.iocoder.yudao.module.pms.controller.admin.vo.IotDeviceRespVO;
 import cn.iocoder.yudao.module.pms.dal.dataobject.IotDeviceDO;
 import cn.iocoder.yudao.module.pms.dal.dataobject.iotcountdata.IotCountDataDO;

+ 65 - 6
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/service/iotrhdailyreport/IotRhDailyReportServiceImpl.java

@@ -69,6 +69,7 @@ import java.time.format.DateTimeParseException;
 import java.time.temporal.ChronoUnit;
 import java.util.*;
 import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.concurrent.atomic.AtomicReference;
 import java.util.stream.Collectors;
 
@@ -124,10 +125,7 @@ public class IotRhDailyReportServiceImpl implements IotRhDailyReportService {
     public Long createIotRhDailyReport(IotRhDailyReportSaveReqVO createReqVO) {
         // 插入
         IotRhDailyReportDO iotRhDailyReport = BeanUtils.toBean(createReqVO, IotRhDailyReportDO.class);
-        // 设置 日报填写状态 审核状态
-        iotRhDailyReport.setStatus(1);
-        // 设置 日报审批状态为 审批中 auditStatus = 10
-        iotRhDailyReport.setAuditStatus(10);
+
         LocalDateTime reportDate = createReqVO.getFillOrderCreateTime();
         if (ObjUtil.isEmpty(reportDate)) {
             throw exception(IOT_RH_DAILY_REPORT_NO_DATE);
@@ -136,6 +134,21 @@ public class IotRhDailyReportServiceImpl implements IotRhDailyReportService {
         if (ObjUtil.isEmpty(deptId)) {
             throw exception(IOT_RH_DAILY_REPORT_NO_DEPT);
         }
+
+        DeptDO currentDept = deptService.getDept(deptId);
+        // 队伍下设备非施工状态,新增时需要向填报人发送 消息提醒
+        // 查询当前队伍下的设备的施工状态 如果是非施工,就需要向 日报 创建人发送钉钉消息
+        List<DeptDO> teams = new ArrayList<>();
+        teams.add(currentDept);
+        // 查询增压机状态为非施工的小队
+        List<IotDeviceDO> teamStatusL = iotOpeationFillMapper.selectDevStatusBatch(teams);
+        System.out.println("无施工设备的队伍:" + currentDept.getName());
+
+        // 设置 日报填写状态 审核状态
+        iotRhDailyReport.setStatus(1);
+        // 设置 日报审批状态为 审批中 auditStatus = 10
+        iotRhDailyReport.setAuditStatus(10);
+
         // 根据日报的 施工队伍 deptId 查询队伍所在的 项目 任务
         // 根据日报的施工状态 更新 对应任务的 状态
         Long taskId = Long.MIN_VALUE;
@@ -258,7 +271,18 @@ public class IotRhDailyReportServiceImpl implements IotRhDailyReportService {
         String yesterdayDateStr = StrUtil.EMPTY;
         LocalDateTime yesterday = reportDate.minusDays(1);
         yesterdayDateStr = LocalDateTimeUtil.format(yesterday, DatePattern.NORM_DATE_PATTERN);
+
+        // 标识是否是设备无施工状态的设备队伍
+        AtomicBoolean noDeviceTeam = new AtomicBoolean(false);
+
         if (ObjUtil.isEmpty(existReport)) {
+
+            // 新增日报记录 如果是 无施工设备的队伍 status auditStatus 需要单独处理
+            if (CollUtil.isNotEmpty(teamStatusL)) {
+                iotRhDailyReport.setStatus(0);
+                iotRhDailyReport.setAuditStatus(0);
+            }
+
             // 今天下午4点
             LocalDateTime today4pm = reportDate.withHour(16).withMinute(0).withSecond(0).withNano(0);
             // 昨天下午4点
@@ -325,16 +349,51 @@ public class IotRhDailyReportServiceImpl implements IotRhDailyReportService {
             // 根据日报关联任务车辆油耗 计算总油耗 后保存日报
             iotRhDailyReportMapper.updateById(iotRhDailyReport);
 
+            if (CollUtil.isNotEmpty(teamStatusL)) {
+                // 说明队伍下的设备类别为非施工状态,需要向 日报填报人发送 消息提醒
+                Set<Long> targetUserIds = new HashSet<>();
+                targetUserIds.add(Long.valueOf(iotRhDailyReport.getCreator()));
+                System.out.println("日报创建人:" + iotRhDailyReport.getCreator());
+                Map<Long, AdminUserRespDTO> users = adminUserApi.getUserMap(targetUserIds);
+                // 给多个用户发送 相同 的 提醒消息
+                if (CollUtil.isNotEmpty(users)) {
+                    // 生成消息提醒标题 部门名称-井号
+                    String msgTitle = currentDept.getName();
+                    if (StrUtil.isNotBlank(wellName)) {
+                        msgTitle = StrUtil.join("-", msgTitle, wellName);
+                    }
+                    CountDownLatch latch = new CountDownLatch(users.size());
+                    String finalMsgTitle = msgTitle;
+                    users.forEach((userId, user) -> {
+                        pmsThreadPoolTaskExecutor.execute(() -> {
+                            try {
+                                String mobile = user.getMobile();
+                                // 没有手机号也发送站内信消息
+                                if (StrUtil.isNotBlank(finalMsgTitle)) {
+                                    noDeviceTeam.set(true);
+                                    System.out.println("向日报创建人发送消息");
+                                    pmsMessage.sendMessage(iotRhDailyReport.getId(), finalMsgTitle, PmsConstants.RH_DAILY_REPORT,
+                                            userId, mobile);
+                                }
+                            } finally {
+                                latch.countDown();
+                            }
+                        });
+                    });
+                }
+            }
+
         } else {
             // 修改现有记录
             iotRhDailyReport.setId(existReport.getId());
+            iotRhDailyReport.setCreator(existReport.getCreator());
             iotRhDailyReportMapper.updateById(iotRhDailyReport);
         }
         // 只要保存了记录就要发送审批提醒到 提交人对应的项目经理 角色 项目部日报审批RH
         // 根据日报的 deptId 查询上级项目部经理 角色的审批人 发送站内信 钉钉提醒
         // 此时需要判断下当前队伍下有无增压机,如果 ‘当前队伍下无增压机’ 或 ‘增压机的状态不是施工’ 需要新增空白记录 向填报人推送消息。
         // 暂时添加判断条件 创建人 是 null 的话 不发送 站内信及钉钉消息
-        if (StrUtil.isNotBlank(iotRhDailyReport.getCreator())) {
+        if (StrUtil.isNotBlank(iotRhDailyReport.getCreator()) && !noDeviceTeam.get()) {
 
             DeptDO dept = deptService.getDept(deptId);
             Long parentId = dept.getParentId();
@@ -447,7 +506,6 @@ public class IotRhDailyReportServiceImpl implements IotRhDailyReportService {
         Map<Long, BigDecimal> capacityPair = new HashMap<>();
         // 找到当前小队下的 电驱增压机 分类下设备的产能 计算 运行时效
         DictTypeDO dictType = dictTypeService.getDictType("rq_iot_charger_device_category");
-        AtomicReference<BigDecimal> capacity = new AtomicReference<>(BigDecimal.ZERO);
         if (ObjUtil.isNotEmpty(dictType)) {
             if (StrUtil.isNotBlank(dictType.getRemark())) {
                 IotDevicePageReqVO capacityReqVO = new IotDevicePageReqVO();
@@ -457,6 +515,7 @@ public class IotRhDailyReportServiceImpl implements IotRhDailyReportService {
                 if (CollUtil.isNotEmpty(capacityDevices)) {
                     // 解析每个设备的 扩展属性 找出 已经设置 了产能的设备并提取值
                     capacityDevices.forEach(device -> {
+                        AtomicReference<BigDecimal> capacity = new AtomicReference<>(BigDecimal.ZERO);
                         if (StrUtil.isNotBlank(device.getTemplateJson())) {
                             Gson gson = new Gson();
                             Type listType = new TypeToken<List<IotDeviceProperty>>(){}.getType();

+ 8 - 1
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/service/iotrydailyreport/IotRyDailyReportServiceImpl.java

@@ -115,7 +115,7 @@ public class IotRyDailyReportServiceImpl implements IotRyDailyReportService {
         if (ObjUtil.isEmpty(createReqVO.getDeptId())) {
             throw exception(IOT_RH_DAILY_REPORT_NO_DEPT);
         }
-        if ((StrUtil.isBlank(createReqVO.getProjectClassification())||"1".equals(createReqVO.getProjectClassification()))
+        if ((StrUtil.isBlank(createReqVO.getProjectClassification()) || "1".equals(createReqVO.getProjectClassification()))
                 && ObjUtil.isEmpty(createReqVO.getCurrentDepth())) {
             // 钻井类型日报必须 填写当前井深
             throw exception(IOT_RY_DAILY_REPORT_CURRENT_DEPTH_NOT_EXISTS);
@@ -227,6 +227,13 @@ public class IotRyDailyReportServiceImpl implements IotRyDailyReportService {
         if (ObjUtil.isNotEmpty(parentId)) {
             DataPermissionUtils.executeIgnore(() -> {
                 DeptDO projectDept = deptService.getDept(parentId);
+                // 当前部门的上级部门如果 不是项目部 再向上找一级 煤层气 项目
+                if (!"2".equals(projectDept.getType())) {
+                    DeptDO newLevelDept = deptService.getDept(projectDept.getParentId());
+                    // 将 newLevelDept 对象 关键字段赋值给 projectDept
+                    projectDept.setId(newLevelDept.getId());
+                    projectDept.setType(newLevelDept.getType());
+                }
                 // 查找队伍上级项目部 拥有‘项目部日报审批RY’角色 的审批人 如果查找不到 则使用 瑞鹰国际 下拥有‘项目部日报审批RY’角色的审批人
                 if (ObjUtil.isNotEmpty(projectDept) && "2".equals(projectDept.getType())) {
                     // 查询项目部下具有 项目部日报审批RY 角色的人员 如果查找不到 查询 瑞鹰国际下 拥有‘项目部日报审批RY’角色的审批人

+ 3 - 1
yudao-module-pms/yudao-module-pms-biz/src/main/resources/mapper/static/IotOpeationFillMapper.xml

@@ -395,7 +395,8 @@
         )
         ORDER BY
         CASE WHEN device_code IS NULL OR device_code = '' THEN 1 ELSE 0 END ASC,
-        CAST(SUBSTRING(device_code, 3) AS UNSIGNED) ASC
+        CAST(SUBSTRING(device_code, 3) AS UNSIGNED) ASC,
+        a.id ASC
     </select>
 
 
@@ -1253,6 +1254,7 @@
         </foreach>
         AND asset_class IN (159, 160, 122, 106, 157, 158, 191)
         AND device_status != 'sg'
+        and deleted = 0
         GROUP BY dept_id -- 确保每个部门只返回1条记录(若多个设备,取任意1条)
         -- 可选:如需指定返回某条设备(如最新/最早),可加排序:
         -- ORDER BY create_time DESC -- 按创建时间倒序(取最新)