Pārlūkot izejas kodu

pms 瑞鹰看板 生产动态简报

zhangcl 10 stundas atpakaļ
vecāks
revīzija
9b37dbe75c

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

@@ -33,6 +33,7 @@ import cn.iocoder.yudao.module.pms.dal.mysql.iotrydailyreportdetail.IotRyDailyRe
 import cn.iocoder.yudao.module.pms.service.iotprojectinfo.IotProjectInfoService;
 import cn.iocoder.yudao.module.pms.service.iotprojecttask.IotProjectTaskService;
 import cn.iocoder.yudao.module.pms.service.iotrydailyreport.IotRyDailyReportService;
+import cn.iocoder.yudao.module.system.controller.admin.dept.vo.dept.DeptListReqVO;
 import cn.iocoder.yudao.module.system.dal.dataobject.dept.DeptDO;
 import cn.iocoder.yudao.module.system.dal.dataobject.dict.DictDataDO;
 import cn.iocoder.yudao.module.system.service.dept.DeptService;
@@ -56,6 +57,7 @@ import java.time.LocalDateTime;
 import java.time.temporal.ChronoUnit;
 import java.util.*;
 import java.util.concurrent.atomic.AtomicReference;
+import java.util.stream.Collectors;
 import java.util.stream.Stream;
 
 import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.EXPORT;
@@ -285,6 +287,42 @@ public class IotRyDailyReportController {
         return success(new PageResult<>(buildRyDailyReports(pageResult.getList(), pageReqVO, "list"), pageResult.getTotal()));
     }
 
+    @GetMapping("/productionBriefs")
+    @Operation(summary = "瑞鹰看板 组合钻井修井日报生产动态简报")
+    @PreAuthorize("@ss.hasPermission('pms:iot-ry-daily-report:query')")
+    public CommonResult<List<IotRyDailyReportRespVO>> productionBriefs(@Valid IotRyDailyReportPageReqVO pageReqVO) {
+        // 根据查询参数筛选出 符合条件 的记录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);
+            }
+        }
+        // 不区分钻井 修井 查询全部日报后再组装
+        pageReqVO.setProjectClassification(StrUtil.EMPTY);
+        List<IotRyDailyReportDO> reports = iotRyDailyReportService.productionBriefs(pageReqVO);
+
+        return success(buildProductionBriefs(reports, pageReqVO));
+    }
+
     @GetMapping("/teamReports")
     @Operation(summary = "根据井号查询瑞鹰日报列表 按照队伍分组统计工作量")
     @PreAuthorize("@ss.hasPermission('pms:iot-ry-daily-report:query')")
@@ -427,6 +465,281 @@ public class IotRyDailyReportController {
         return success(resultMap);
     }
 
+    private List<IotRyDailyReportRespVO> buildProductionBriefs(List<IotRyDailyReportDO> reports, IotRyDailyReportPageReqVO pageReqVO) {
+        if (CollUtil.isEmpty(reports)) {
+            return Collections.emptyList();
+        }
+        // 设备部门信息
+        Map<Long, DeptDO> deptMap = deptService.getDeptMap(convertList(reports, IotRyDailyReportDO::getDeptId));
+        // key项目id   value项目合同号
+        Map<Long, String> projectPair = new HashMap<>();
+        //  key任务id     value任务井号
+        Map<Long, String> taskPair = new HashMap<>();
+        //  key任务id     value任务施工区域
+        Map<Long, String> taskLocationPair = new HashMap<>();
+        // key任务id   value设计井深
+        Map<Long, BigDecimal> taskExtPropertyPair = new HashMap<>();
+        // key任务id   value额定生产时间
+        Map<Long, BigDecimal> taskRatedProductionTimePair = new HashMap<>();
+        // key任务id   value套生段产管尺寸
+        Map<Long, String> taskCasingPipeSizePair = new HashMap<>();
+        // key任务id   value井控级别
+        Map<Long, String> taskWellControlLevelPair = new HashMap<>();
+        // key任务id   value施工工艺
+        Map<Long, String> taskTechniquePair = new HashMap<>();
+        // key任务id   value主设备数量
+        Map<Long, Integer> taskDeviceNumPair = new HashMap<>();
+        // key任务id   value井别
+        Map<Long, String> taskWellCategoryPair = new HashMap<>();
+        // key任务id   value设计井身结构
+        Map<Long, String> taskWellStructPair = new HashMap<>();
+        // key部门id  value设备型号编号
+        AtomicReference<Map<Long, String>> equipmentTypePair = new AtomicReference<>(new HashMap<>());
+        // key施工队伍id    value最近完工日期
+        Map<Long, LocalDateTime> latestWellDoneTimePair = new HashMap<>();
+        // key施工队伍id    value施工井数量
+        Map<Long, Integer> totalTasksPair = new HashMap<>();
+        // key施工队伍id    value完工井数量
+        Map<Long, Integer> completedTasksPair = new HashMap<>();
+        // key非生产时间原因数据字典value   value非生产时间原因数据字典label
+        Map<String, String> nptReasonPair = new HashMap<>();
+        // 钻井 key施工状态数据字典value   value施工状态数据字典label
+        Map<String, String> constructStatusPair = new HashMap<>();
+        // 修井 key施工状态数据字典value   value施工状态数据字典label
+        Map<String, String> repairStatusPair = new HashMap<>();
+        // key日报id   value生产动态明细
+        Map<Long, List<IotRyDailyReportDetailRespVO>> reportDetailsPair = new HashMap<>();
+
+        // 钻井 施工状态 字典数据
+        List<DictDataDO> rigStatusDictData = dictDataService.getDictDataListByDictType("rigStatus");
+        // 修井 施工状态 字典数据
+        List<DictDataDO> repairStatusDictData = dictDataService.getDictDataListByDictType("repairStatus");
+        // 非生产时间原因 字典数据
+        List<DictDataDO> nptReasonDictData = dictDataService.getDictDataListByDictType("ryNptReason");
+
+        if (CollUtil.isNotEmpty(nptReasonDictData)) {
+            nptReasonDictData.forEach(data -> {
+                nptReasonPair.put(data.getValue(), data.getLabel());
+            });
+        }
+        // 钻井施工状态
+        if (CollUtil.isNotEmpty(rigStatusDictData)) {
+            rigStatusDictData.forEach(data -> {
+                constructStatusPair.put(data.getValue(), data.getLabel());
+            });
+        }
+        // 修井施工状态
+        if (CollUtil.isNotEmpty(repairStatusDictData)) {
+            repairStatusDictData.forEach(data -> {
+                repairStatusPair.put(data.getValue(), data.getLabel());
+            });
+        }
+
+        // 查询瑞鹰下所有部门 施工队伍及对应的项目部
+        Set<Long> deptIds = deptService.getChildDeptIdListFromCache(158l);
+        DeptListReqVO deptReqVO = new DeptListReqVO();
+        deptReqVO.setDeptIds(deptIds);
+        List<DeptDO> departments = deptService.getDeptList(deptReqVO);
+        Map<Long, String> projectNamePair = new HashMap<>();
+        Set<Long> teamIds = new HashSet<>();
+        // key队伍id   value项目部id
+        Map<Long, Long> teamProjectPair = new HashMap<>();
+        // key队伍id   value项目部名称
+        Map<Long, String> teamProjectNamePair = new HashMap<>();
+        // 项目部排序值
+        Map<Long, Integer> projectSortPair = new HashMap<>();
+        // 队伍排序值
+        Map<Long, Integer> teamSortPair = new HashMap<>();
+        // 找到每个施工队伍的上级部门
+        if (CollUtil.isNotEmpty(departments)) {
+            departments.forEach(dept -> {
+                if ("2".equals(dept.getType())) {
+                    projectNamePair.put(dept.getId(), dept.getName());
+                    projectSortPair.put(dept.getId(), dept.getSort());
+                }
+                if ("3".equals(dept.getType())) {
+                    teamIds.add(dept.getId());
+                    teamProjectPair.put(dept.getId(), dept.getParentId());
+                    teamSortPair.put(dept.getId(), dept.getSort());
+                }
+            });
+            if (CollUtil.isNotEmpty(teamProjectPair)) {
+                teamProjectPair.forEach((teamId, projectDeptId) -> {
+                    if (projectNamePair.containsKey(projectDeptId)) {
+                        teamProjectNamePair.put(teamId, projectNamePair.get(projectDeptId));
+                    }
+                });
+            }
+        }
+
+        // 查询施工队伍属于钻井或修井
+        Set<Long> zjDeptIds = new HashSet<>();
+        Set<Long> xjDeptIds = new HashSet<>();
+        IotDeptTypePageReqVO deptTypeReqVO = new IotDeptTypePageReqVO();
+        List<IotDeptTypeDO> deptTypes = iotDeptTypeMapper.selectList(deptTypeReqVO);
+        if (CollUtil.isNotEmpty(deptTypes)) {
+            deptTypes.forEach(deptType -> {
+                if ("zj".equals(deptType.getType())) {
+                    zjDeptIds.add(deptType.getDeptId());
+                }
+                if ("xj".equals(deptType.getType())) {
+                    xjDeptIds.add(deptType.getDeptId());
+                }
+            });
+        }
+
+        // 查询每个日报的生产动态明细
+        IotRyDailyReportDetailPageReqVO detailReqVO = new IotRyDailyReportDetailPageReqVO();
+        detailReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
+        detailReqVO.setReportIds(convertList(reports, IotRyDailyReportDO::getId));
+        PageResult<IotRyDailyReportDetailDO> reportDetailsPage = iotRyDailyReportDetailMapper.selectPage(detailReqVO);
+        List<IotRyDailyReportDetailDO> reportDetails = reportDetailsPage.getList();
+        if (CollUtil.isNotEmpty(reportDetails)) {
+            // 设置每个日报的生产动态明细
+            reportDetails.forEach(detail -> {
+                if (reportDetailsPair.containsKey(detail.getReportId())) {
+                    List<IotRyDailyReportDetailRespVO> tempDetails = reportDetailsPair.get(detail.getReportId());
+                    tempDetails.add(BeanUtils.toBean(detail, IotRyDailyReportDetailRespVO.class));
+                    reportDetailsPair.put(detail.getReportId(), tempDetails);
+                } else {
+                    List<IotRyDailyReportDetailRespVO> tempDetails = new ArrayList<>();
+                    tempDetails.add(BeanUtils.toBean(detail, IotRyDailyReportDetailRespVO.class));
+                    reportDetailsPair.put(detail.getReportId(), tempDetails);
+                }
+            });
+        }
+        DataPermissionUtils.executeIgnore(() -> {
+            // 查询日报关联的项目信息
+            IotProjectInfoPageReqVO reqVO = new IotProjectInfoPageReqVO();
+            reqVO.setProjectIds(convertList(reports, IotRyDailyReportDO::getProjectId));
+            List<IotProjectInfoDO> projects = iotProjectInfoService.getIotProjectInfos(reqVO);
+            if (CollUtil.isNotEmpty(projects)) {
+                projects.forEach(project -> {
+                    projectPair.put(project.getId(), project.getContractName());
+                });
+            }
+            // 查询日报关联的任务信息
+            IotProjectTaskPageReqVO taskReqVO = new IotProjectTaskPageReqVO();
+            taskReqVO.setTaskIds(convertList(reports, IotRyDailyReportDO::getTaskId));
+            List<IotProjectTaskDO> tasks = iotProjectTaskService.projectTasks(taskReqVO);
+            if (CollUtil.isNotEmpty(tasks)) {
+                tasks.forEach(task -> {
+                    taskPair.put(task.getId(), task.getWellName());
+                    taskLocationPair.put(task.getId(), task.getLocation());
+                    taskTechniquePair.put(task.getId(), task.getTechnique());
+                    taskDeviceNumPair.put(task.getId(), task.getDeviceIds().size());
+                });
+            }
+            // 查询当前日报所属施工队伍中包含 井架 的型号
+            equipmentTypePair.set(iotRyDailyReportService.queryEquipmentType(convertList(reports, IotRyDailyReportDO::getDeptId)));
+            // 查询当前日报所属部门的 上井次完井时间 已经绑定任务的情况下
+            List<IotRyDailyReportDO> latestWellDoneTimes = iotRyDailyReportService.latestWellDoneTimes(null);
+            if (CollUtil.isNotEmpty(latestWellDoneTimes)) {
+                latestWellDoneTimes.forEach(time -> {
+                    latestWellDoneTimePair.put(time.getDeptId(), time.getConstructionStartDate());
+                });
+            }
+            // 按施工队伍统计 钻井日报 施工井数 完工井数
+            List<IotRyDailyReportTaskCountVO> deptTasks = iotRyDailyReportService.countTasksByDept();
+            // 修井日报 不存在既填写钻井日报 又填写修井日报的队伍
+            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());
+                });
+            }
+        });
+
+        List<IotRyDailyReportRespVO> resultList =BeanUtils.toBean(reports, IotRyDailyReportRespVO.class, (reportVO) -> {
+            // 油耗 精确到 2位小数
+            if (reportVO.getDailyFuel().compareTo(BigDecimal.ZERO) > 0) {
+                BigDecimal fuel = reportVO.getDailyFuel()
+                        .divide(BigDecimal.valueOf(1), 2, RoundingMode.HALF_UP);
+                reportVO.setDailyFuel(fuel);
+            }
+            // 将 ‘生产配合’ 的值赋值给 ‘其他非生产时间’
+            if (reportVO.getRelocationTime().compareTo(BigDecimal.ZERO) > 0) {
+                reportVO.setOtherProductionTime(reportVO.getRelocationTime());
+            }
+            // 计算非生产时效
+            BigDecimal sumNpt = calculateNonProductTime(reportVO);
+            // 非生产时间加和
+            reportVO.setNonProductionTime(sumNpt);
+            reportVO.setNonProductionRate(sumNpt.divide(BigDecimal.valueOf(24), 4, RoundingMode.HALF_UP ));
+
+            // 日报生成日期 格式化时间为 yyyy-MM-dd
+            if (ObjUtil.isNotEmpty(reportVO.getCreateTime())) {
+                reportVO.setCreateTimeStr(LocalDateTimeUtil.format(reportVO.getCreateTime(), DatePattern.NORM_DATE_PATTERN));
+            }
+            // 上井次完井时间 格式化时间为 yyyy-MM-dd
+            if (ObjUtil.isNotEmpty(reportVO.getLatestWellDoneTime())) {
+                reportVO.setLatestWellDoneTimeStr(LocalDateTimeUtil.format(reportVO.getLatestWellDoneTime(), DatePattern.NORM_DATE_PATTERN));
+            }
+            // 2.1 拼接部门信息
+            findAndThen(deptMap, reportVO.getDeptId(), dept -> reportVO.setDeptName(dept.getName()));
+            // 队伍排序值
+            findAndThen(teamSortPair, reportVO.getDeptId(), sort -> reportVO.setTeamSort(sort));
+            // 设置项目部排序值
+            if (teamProjectPair.containsKey(reportVO.getDeptId())) {
+                Long projectDeptId = teamProjectPair.get(reportVO.getDeptId());
+                if (projectSortPair.containsKey(projectDeptId)) {
+                    reportVO.setProjectSort(projectSortPair.get(projectDeptId));
+                }
+            }
+            // 设置 钻井 or 修井
+            if (zjDeptIds.contains(reportVO.getDeptId())) {
+                reportVO.setProjectClassification("钻井");
+            }
+            if (xjDeptIds.contains(reportVO.getDeptId())) {
+                reportVO.setProjectClassification("修井");
+            }
+            // 主设备数量
+            findAndThen(taskDeviceNumPair, reportVO.getTaskId(), deviceNum -> reportVO.setDeviceNum(deviceNum));
+            // 项目部名称
+            findAndThen(teamProjectNamePair, reportVO.getDeptId(), projectName -> reportVO.setProjectName(projectName));
+            // 2.2 日报关联的项目信息
+            findAndThen(projectPair, reportVO.getProjectId(), contractName -> reportVO.setContractName(contractName));
+            // 2.3 日报关联的任务信息
+            findAndThen(taskPair, reportVO.getTaskId(), taskName -> reportVO.setTaskName(taskName));
+            // 日报关联的任务施工地点
+            findAndThen(taskLocationPair, reportVO.getTaskId(), location -> reportVO.setLocation(location));
+            // 2.7 上井次完井时间
+            findAndThen(latestWellDoneTimePair, reportVO.getDeptId(), latestWellDoneTime -> reportVO.setLatestWellDoneTime(latestWellDoneTime));
+            // 2.8 总施工井数 完工井数
+            findAndThen(totalTasksPair, reportVO.getDeptId(), totalTaskCount -> reportVO.setTotalConstructionWells(totalTaskCount));
+            findAndThen(completedTasksPair, reportVO.getDeptId(), completedTaskCount -> reportVO.setCompletedWells(completedTaskCount));
+            // 钻井 施工状态 数据字典
+            findAndThen(constructStatusPair, reportVO.getRigStatus(), statusLabel -> {
+                if ("钻井".equals(reportVO.getProjectClassification())) {
+                    reportVO.setConstructionStatusName(statusLabel);
+                }
+            });
+            // 修井 施工状态 数据字典
+            findAndThen(repairStatusPair, reportVO.getRepairStatus(), statusLabel -> {
+                if ("修井".equals(reportVO.getProjectClassification())) {
+                    reportVO.setConstructionStatusName(statusLabel);
+                }
+            });
+        });
+
+        // 2. 拼接数据
+        return resultList.stream()
+                .sorted(Comparator.comparing(IotRyDailyReportRespVO::getProjectClassification,
+                                Comparator.comparingInt(s -> "钻井".equals(s) ? 0 : 1))  // 1. 钻井在前
+                        .thenComparing(IotRyDailyReportRespVO::getProjectSort)     // 2. 项目部排序升序
+                        .thenComparing(IotRyDailyReportRespVO::getTeamSort))       // 3. 队伍排序升序
+                .collect(Collectors.toList());
+    }
+
     /**
      * 瑞恒日报分页 设置关联查询信息
      * @param reports

+ 29 - 0
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/iotrydailyreport/vo/IotRyDailyReportBriefRespVO.java

@@ -0,0 +1,29 @@
+package cn.iocoder.yudao.module.pms.controller.admin.iotrydailyreport.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 IotRyDailyReportBriefRespVO {
+
+    @Schema(description = "部门名称")
+    @ExcelProperty("施工队伍")
+    private String teamName;
+
+    @Schema(description = "项目部名称")
+    @ExcelProperty("项目部名称")
+    private String projectName;
+
+    @Schema(description = "项目类别(钻井 修井 注氮 酸化压裂... )")
+    private String projectClassification;
+
+    @Schema(description = "排序值")
+    private Integer sort;
+
+    @Schema(description = "生产日报摘要")
+    private IotRyDailyReportRespVO dailyReport;
+}

+ 12 - 0
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/iotrydailyreport/vo/IotRyDailyReportRespVO.java

@@ -346,4 +346,16 @@ public class IotRyDailyReportRespVO {
 
     @Schema(description = "当前日报可以选择的任务井集合")
     private Map<Long, String> wellNamePair;
+
+    @Schema(description = "项目部名称")
+    private String projectName;
+
+    @Schema(description = "主设备数量")
+    private Integer deviceNum;
+
+    @Schema(description = "项目部排序值")
+    private Integer projectSort;
+
+    @Schema(description = "施工队伍排序值")
+    private Integer teamSort;
 }

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

@@ -206,4 +206,12 @@ public interface IotRyDailyReportService {
      * @return 瑞鹰日报 非生产时效分析 列表
      */
     List<IotRyDailyReportNptStatisticsRespVO> nptStatistics(IotRyDailyReportPageReqVO pageReqVO);
+
+    /**
+     * 瑞鹰看板 组合钻井修井日报生产动态简报
+     *
+     * @param pageReqVO 无分页查询
+     * @return 组合钻井修井日报生产动态简报 列表
+     */
+    List<IotRyDailyReportDO> productionBriefs(IotRyDailyReportPageReqVO pageReqVO);
 }

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

@@ -1133,6 +1133,17 @@ public class IotRyDailyReportServiceImpl implements IotRyDailyReportService {
         return result;
     }
 
+    @Override
+    public List<IotRyDailyReportDO> productionBriefs(IotRyDailyReportPageReqVO pageReqVO) {
+        pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
+        PageResult<IotRyDailyReportDO> pageResult = iotRyDailyReportMapper.selectPage(pageReqVO);
+        if (ObjUtil.isNotEmpty(pageResult)) {
+            List<IotRyDailyReportDO> reports = pageResult.getList();
+            return reports;
+        }
+        return Collections.emptyList();
+    }
+
     private List<IotDeviceDO> devices() {
         // 查询 瑞鹰158l 所有存在设备的队伍
         // 查询 瑞鹰 下所有部门