Ver Fonte

pms 瑞鹰设备利用率

zhangcl há 4 horas atrás
pai
commit
8e633951c5

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

@@ -155,4 +155,7 @@ public class IotRyDailyReportPageReqVO extends PageParam {
 
     @Schema(description = "部门id集合", example = "[123,223]")
     private Collection<Long> deptIds;
+
+    @Schema(description = "施工状态集合", example = "[dt,zx]")
+    private Collection<String> statuses;
 }

+ 281 - 2
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/stat/IotStaticController.java

@@ -40,6 +40,7 @@ import cn.iocoder.yudao.module.pms.dal.dataobject.iotcountdata.IotCountDataDO;
 import cn.iocoder.yudao.module.pms.dal.dataobject.iotmainworkorder.IotMainWorkOrderDO;
 import cn.iocoder.yudao.module.pms.dal.dataobject.iotoutbound.IotOutboundDO;
 import cn.iocoder.yudao.module.pms.dal.dataobject.iotrhdailyreport.IotRhDailyReportDO;
+import cn.iocoder.yudao.module.pms.dal.dataobject.iotrydailyreport.IotRyDailyReportDO;
 import cn.iocoder.yudao.module.pms.dal.dataobject.iotsapstock.IotSapStockDO;
 import cn.iocoder.yudao.module.pms.dal.dataobject.maintain.IotMaintainDO;
 import cn.iocoder.yudao.module.pms.dal.mysql.IotDeviceMapper;
@@ -1537,20 +1538,20 @@ public class IotStaticController {
                     Integer currentTeamNum = teamIds.size();
                     rateVo.setTeamCount(currentTeamNum);
                     rateVo.setCumulativeDays(currentTeamNum * daysCount);
+                    double rate = 0.0;
                     // 匹配出当前项目部下 日报数量
                     if (projectReportPair.containsKey(projectDeptId)) {
                         Integer reportCount = projectReportPair.getOrDefault(projectDeptId, 0);
                         rateVo.setConstructionDays(reportCount);
                         // 当前项目部 设备利用率 公式 reportCount/(currentTeamNum*daysCount)
                         // 计算设备利用率(处理除数为0的情况)
-                        double rate = 0.0;
                         if (currentTeamNum > 0 && daysCount > 0) {
                             rate = new BigDecimal((double) reportCount / (currentTeamNum * daysCount))
                                     .setScale(4, RoundingMode.HALF_UP)  // 保留4位小数,四舍五入
                                     .doubleValue();;
                         }
-                        rateVo.setUtilizationRate(rate); // 存储计算结果
                     }
+                    rateVo.setUtilizationRate(rate); // 存储计算结果
                     rates.add(rateVo);
                 });
             }
@@ -1701,5 +1702,283 @@ public class IotStaticController {
         return success(rates);
     }
 
+    /**
+     * 瑞鹰 设备利用率 按项目部统计
+     * @return
+     */
+    @GetMapping("/ry/device/utilizationRate")
+    @PermitAll
+    public CommonResult<List<ProjectUtilizationRateVo>> ryUtilizationRate(IotRyDailyReportPageReqVO reqVO) {
+        if (ObjUtil.isEmpty(reqVO.getCreateTime())) {
+            throw exception(IOT_DAILY_REPORT_TIME_NOT_EXISTS);
+        }
+        if (reqVO.getCreateTime().length < 2) {
+            throw exception(IOT_DAILY_REPORT_TIME_NOT_EXISTS);
+        }
+        // 各项目部的设备利用率集合
+        List<ProjectUtilizationRateVo> rates = new ArrayList<>();
+        // 查询瑞恒 158l 所有项目部
+        Set<Long> childDeptIds = deptService.getChildDeptIdListFromCache(158l);
+        Map<Long, DeptDO> allDeptPair = deptService.getDeptMap(childDeptIds);
+        Set<String> projectDeptNames = new HashSet<>();
+        Set<Long> projectDeptIds = new HashSet<>();
+        // key项目部id   value项目部名称
+        Map<Long, String> projectPair = new HashMap<>();
+        // key项目部id   value项目部包含的队伍id集合
+        Map<Long, Set<Long>> projectTeamPair = new HashMap<>();
+        if (CollUtil.isNotEmpty(allDeptPair)) {
+            allDeptPair.forEach((deptId, dept) -> {
+                if (dept.getName().contains("项目部") ) {
+                    projectDeptIds.add(deptId);
+                    projectDeptNames.add(dept.getName());
+                    projectPair.put(deptId, dept.getName());
+                }
+            });
+            // 遍历所有部门
+            allDeptPair.forEach((deptId, dept) -> {
+                // 找出每个项目部下的队伍
+                if (projectPair.containsKey(dept.getParentId())) {
+                    // 获得当前部门的上级项目部
+                    projectPair.forEach((projectDeptId, projectDept) -> {
+                        if (projectDeptId.equals(dept.getParentId())) {
+                            if (projectTeamPair.containsKey(projectDeptId)) {
+                                Set<Long> teamIds = projectTeamPair.get(projectDeptId);
+                                teamIds.add(deptId);
+                                projectTeamPair.put(projectDeptId, teamIds);
+                            } else {
+                                Set<Long> teamIds = new HashSet<>();
+                                teamIds.add(deptId);
+                                projectTeamPair.put(projectDeptId, teamIds);
+                            }
+                        }
+                    });
+                }
+            });
+        }
+        // 查询出指定时间区间内 已经填写的日报数量
+        // 瑞鹰区分 钻井 修井 日报
+        // 钻井:日报状态 过滤掉 ‘等停dt’    修井:日报状态过滤掉 ‘等停dt’、‘整修zx’
+        List<String> statuses = new ArrayList<>();
+        statuses.add("dt");
+        statuses.add("zx");
+        reqVO.setStatuses(statuses);
+        List<IotRyDailyReportDO> dailyReports = iotRyDailyReportMapper.dailyReports(reqVO);
+        // key项目部id     value项目部包含的队伍指定时间区域内日报数量
+        Map<Long, Integer> projectReportPair = new HashMap<>();
+        if (CollUtil.isNotEmpty(dailyReports)) {
+            // 整理出每个项目部下的队伍填报的日报数量
+            dailyReports.forEach(report -> {
+                if (CollUtil.isNotEmpty(projectTeamPair)) {
+                    projectTeamPair.forEach((projectDeptId, teamDeptIds) -> {
+                        if (teamDeptIds.contains(report.getDeptId())) {
+                            if (projectReportPair.containsKey(projectDeptId)) {
+                                Integer tempCount = projectReportPair.get(projectDeptId);
+                                projectReportPair.put(projectDeptId, ++tempCount);
+                            } else {
+                                projectReportPair.put(projectDeptId, 1);
+                            }
+                        }
+                    });
+                }
+
+            });
+            // 计算指定时间区间内包含的天数
+            long daysCount;
+            if (ObjUtil.isNotEmpty(reqVO.getCreateTime()) && reqVO.getCreateTime().length >= 2) {
+                LocalDateTime start = reqVO.getCreateTime()[0];
+                LocalDateTime end = reqVO.getCreateTime()[1];
+                if (ObjUtil.isNotEmpty(start) && ObjUtil.isNotEmpty(end) && !end.isBefore(start)) {
+                    // 使用ChronoUnit.DAYS.between计算天数差,并+1包含首尾两天
+                    daysCount = ChronoUnit.DAYS.between(
+                            start.toLocalDate(),
+                            end.toLocalDate()
+                    ) + 1;
+                } else {
+                    daysCount = 0L;
+                }
+            } else {
+                daysCount = 0L;
+            }
+            // 计算每个项目部的设备利用率
+            if (CollUtil.isNotEmpty(projectTeamPair)) {
+                projectTeamPair.forEach((projectDeptId, teamIds) -> {
+                    ProjectUtilizationRateVo rateVo = new ProjectUtilizationRateVo();
+                    rateVo.setProjectDeptId(projectDeptId);
+                    if (projectPair.containsKey(projectDeptId)) {
+                        rateVo.setProjectDeptName(projectPair.get(projectDeptId));
+                    }
+                    // 遍历每个项目部 获取每个项目部下队伍数量
+                    Integer currentTeamNum = teamIds.size();
+                    rateVo.setTeamCount(currentTeamNum);
+                    rateVo.setCumulativeDays(currentTeamNum * daysCount);
+                    double rate = 0.0;
+                    // 匹配出当前项目部下 日报数量
+                    if (projectReportPair.containsKey(projectDeptId)) {
+                        Integer reportCount = projectReportPair.getOrDefault(projectDeptId, 0);
+                        rateVo.setConstructionDays(reportCount);
+                        // 当前项目部 设备利用率 公式 reportCount/(currentTeamNum*daysCount)
+                        // 计算设备利用率(处理除数为0的情况)
+                        if (currentTeamNum > 0 && daysCount > 0) {
+                            rate = new BigDecimal((double) reportCount / (currentTeamNum * daysCount))
+                                    .setScale(4, RoundingMode.HALF_UP)  // 保留4位小数,四舍五入
+                                    .doubleValue();;
+                        }
+                    }
+                    rateVo.setUtilizationRate(rate); // 存储计算结果
+                    rates.add(rateVo);
+                });
+            }
+        }
+        rates.sort(Comparator.comparingDouble(ProjectUtilizationRateVo::getUtilizationRate).reversed());
+        return success(rates);
+    }
+
+    /**
+     * 瑞鹰 设备利用率 按 队伍 统计
+     * @return
+     */
+    @GetMapping("/ry/device/teamUtilizationRate")
+    @PermitAll
+    public CommonResult<List<TeamUtilizationRateVo>> ryTeamUtilizationRate(IotRyDailyReportPageReqVO reqVO) {
+        if (ObjUtil.isEmpty(reqVO.getCreateTime())) {
+            throw exception(IOT_DAILY_REPORT_TIME_NOT_EXISTS);
+        }
+        if (reqVO.getCreateTime().length < 2) {
+            throw exception(IOT_DAILY_REPORT_TIME_NOT_EXISTS);
+        }
+        // 必须传递 项目部id 查询队伍数据
+        if (ObjUtil.isEmpty(reqVO.getDeptId())) {
+            throw exception(IOT_DAILY_REPORT_DEPT_NOT_EXISTS);
+        }
+
+        // 指定项目部的各队伍设备利用率集合
+        List<TeamUtilizationRateVo> rates = new ArrayList<>();
+
+        // 查询指定项目部下的 队伍集合
+        DeptListReqVO deptReqVO = new DeptListReqVO();
+        deptReqVO.setDeptId(reqVO.getDeptId());
+        List<DeptDO> projectTeams = deptService.getDeptListByParentId(deptReqVO);
+        // 指定项目部下的 队伍id集合
+        Set<Long> projectTeamIds = new HashSet<>();
+        if (CollUtil.isNotEmpty(projectTeams)) {
+            projectTeams.forEach(team -> {
+                projectTeamIds.add(team.getId());
+            });
+        }
+
+        Map<Long, DeptDO> allDeptPair = deptService.getDeptMap(projectTeamIds);
+
+        Set<String> projectDeptNames = new HashSet<>();
+        Set<Long> projectDeptIds = new HashSet<>();
+        // key项目部id   value项目部名称
+        Map<Long, String> projectPair = new HashMap<>();
+        // key队伍id   value队伍名称
+        Map<Long, String> teamPair = new HashMap<>();
+        // key项目部id   value项目部包含的队伍id集合
+        Map<Long, Set<Long>> projectTeamPair = new HashMap<>();
+        // key队伍id   value队伍日报数量
+        Map<Long, Long> teamReportCountPair = new HashMap<>();
+        if (CollUtil.isNotEmpty(allDeptPair)) {
+            allDeptPair.forEach((deptId, dept) -> {
+                if (dept.getName().contains("项目部") ) {
+                    projectDeptIds.add(deptId);
+                    projectDeptNames.add(dept.getName());
+                    projectPair.put(deptId, dept.getName());
+                }
+                teamPair.put(deptId, dept.getName());
+            });
+            // 遍历所有部门
+            allDeptPair.forEach((deptId, dept) -> {
+                // 找出每个项目部下的队伍
+                if (projectPair.containsKey(dept.getParentId())) {
+                    // 获得当前部门的上级项目部
+                    projectPair.forEach((projectDeptId, projectDept) -> {
+                        if (projectDeptId.equals(dept.getParentId())) {
+                            if (projectTeamPair.containsKey(projectDeptId)) {
+                                Set<Long> teamIds = projectTeamPair.get(projectDeptId);
+                                teamIds.add(deptId);
+                                projectTeamPair.put(projectDeptId, teamIds);
+                            } else {
+                                Set<Long> teamIds = new HashSet<>();
+                                teamIds.add(deptId);
+                                projectTeamPair.put(projectDeptId, teamIds);
+                            }
+                        }
+                    });
+                }
+            });
+        }
+        if (CollUtil.isNotEmpty(projectTeamIds)) {
+            // 查询出指定时间区间内 指定队伍id集合 已经填写的日报数量
+            reqVO.setDeptIds(projectTeamIds);
+            // 瑞鹰区分 钻井 修井 日报
+            // 钻井:日报状态 过滤掉 ‘等停dt’    修井:日报状态过滤掉 ‘等停dt’、‘整修zx’
+            List<String> statuses = new ArrayList<>();
+            statuses.add("dt");
+            statuses.add("zx");
+            reqVO.setStatuses(statuses);
+            List<IotRyDailyReportDO> dailyReports = iotRyDailyReportMapper.dailyReports(reqVO);
+            // 筛选出每个队伍的日报
+            if (CollUtil.isNotEmpty(dailyReports)) {
+                // 整理出每个项队伍填报的日报数量
+                dailyReports.forEach(report -> {
+                    if (teamReportCountPair.containsKey(report.getDeptId())) {
+                        Long tempCount = teamReportCountPair.get(report.getDeptId());
+                        teamReportCountPair.put(report.getDeptId(), ++tempCount);
+                    } else {
+                        teamReportCountPair.put(report.getDeptId(), 1l);
+                    }
+                });
+                // 计算指定时间区间内包含的天数
+                long daysCount;
+                if (ObjUtil.isNotEmpty(reqVO.getCreateTime()) && reqVO.getCreateTime().length >= 2) {
+                    LocalDateTime start = reqVO.getCreateTime()[0];
+                    LocalDateTime end = reqVO.getCreateTime()[1];
+                    if (ObjUtil.isNotEmpty(start) && ObjUtil.isNotEmpty(end) && !end.isBefore(start)) {
+                        // 使用ChronoUnit.DAYS.between计算天数差,并+1包含首尾两天
+                        daysCount = ChronoUnit.DAYS.between(
+                                start.toLocalDate(),
+                                end.toLocalDate()
+                        ) + 1;
+                    } else {
+                        daysCount = 0L;
+                    }
+                } else {
+                    daysCount = 0L;
+                }
+                // 计算每个队伍的设备利用率
+                if (CollUtil.isNotEmpty(projectTeamIds)) {
+                    projectTeamIds.forEach(teamId -> {
+                        TeamUtilizationRateVo rateVo = new TeamUtilizationRateVo();
+                        rateVo.setProjectDeptId(reqVO.getDeptId());
+                        rateVo.setTeamId(teamId);
+                        rateVo.setCumulativeDays(daysCount);
+                        if (teamPair.containsKey(teamId)) {
+                            rateVo.setTeamName(teamPair.get(teamId));
+                        }
+                        // 匹配出当前小队 日报数量
+                        Long reportCount = 0l;
+                        if (teamReportCountPair.containsKey(teamId)) {
+                            reportCount = teamReportCountPair.getOrDefault(teamId, 0l);
+                            rateVo.setConstructionDays(reportCount);
+                        }
+                        // 当前小队 设备利用率 公式 reportCount/daysCount
+                        // 计算设备利用率(处理除数为0的情况)
+                        double rate = 0.0;
+                        if (reportCount > 0 && daysCount > 0) {
+                            rate = new BigDecimal((double) reportCount /  daysCount)
+                                    .setScale(4, RoundingMode.HALF_UP)  // 保留4位小数,四舍五入
+                                    .doubleValue();;
+                        }
+                        rateVo.setUtilizationRate(rate); // 存储计算结果
+                        rates.add(rateVo);
+                    });
+                }
+            }
+        }
+        rates.sort(Comparator.comparingDouble(TeamUtilizationRateVo::getUtilizationRate).reversed());
+        return success(rates);
+    }
+
 }
 

+ 12 - 0
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/dal/mysql/iotrydailyreport/IotRyDailyReportMapper.java

@@ -1,5 +1,6 @@
 package cn.iocoder.yudao.module.pms.dal.mysql.iotrydailyreport;
 
+import cn.hutool.core.collection.CollUtil;
 import cn.hutool.core.util.ObjUtil;
 import cn.hutool.core.util.StrUtil;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
@@ -15,6 +16,7 @@ import org.apache.ibatis.annotations.Select;
 import java.math.BigDecimal;
 import java.time.LocalDateTime;
 import java.time.format.DateTimeFormatter;
+import java.util.Collection;
 import java.util.List;
 import java.util.Objects;
 
@@ -173,6 +175,16 @@ public interface IotRyDailyReportMapper extends BaseMapperX<IotRyDailyReportDO>
                 .orderByDesc(IotRyDailyReportDO::getCreateTime)
                 .orderByAsc(IotRyDailyReportDO::getId);
 
+        // 处理 statuses 条件:当 statuses 有值时,查询 rigStatus 或 repairStatus 不在 statuses 中的数据
+        Collection<String> statuses = reqVO.getStatuses();
+        if (CollUtil.isNotEmpty(statuses)) { // 判断集合非空
+            queryWrapper.and(wrapper -> wrapper
+                    .notIn(IotRyDailyReportDO::getRigStatus, statuses) // rigStatus 不在集合中
+                    .or() // 或
+                    .notIn(IotRyDailyReportDO::getRepairStatus, statuses) // repairStatus 不在集合中
+            );
+        }
+
         // 单独处理 projectClassification 条件
         if ("1".equals(projectClassification)) {
             // 当值为 "1" 时,查询 project_classification 为 "1" 或空字符串的记录