|
|
@@ -188,7 +188,7 @@ public class IotProjectTaskPlanServiceImpl implements IotProjectTaskPlanService
|
|
|
DeptDO selectedDept = deptService.getDept(pageReqVO.getDeptId());
|
|
|
if ("0".equals(selectedDept.getType())) {
|
|
|
// 选中集团 查询所有公司的汇总数据
|
|
|
- // result = statisticsByCompany(plans, pageReqVO);
|
|
|
+ result = statisticsByCompany(plans, pageReqVO);
|
|
|
} else if ("1".equals(selectedDept.getType())) {
|
|
|
// 选中公司 查询公司下所有项目部的汇总数据
|
|
|
result = statisticsByProjectDept(plans, pageReqVO);
|
|
|
@@ -214,6 +214,251 @@ public class IotProjectTaskPlanServiceImpl implements IotProjectTaskPlanService
|
|
|
return result;
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * 按专业公司维度 汇总 统计数据
|
|
|
+ * @param plans 月度计划工作量列表
|
|
|
+ * @param pageReqVO 包含根部门ID(如 156L为 集团 根部门,或其他公司级部门ID)
|
|
|
+ * @return 公司维度统计结果列表
|
|
|
+ */
|
|
|
+ private List<IotProjectTaskPlanStatisticsRespVO> statisticsByCompany(List<IotProjectTaskPlanDO> plans, IotProjectTaskPlanPageReqVO pageReqVO) {
|
|
|
+ List<IotProjectTaskPlanStatisticsRespVO> result = new ArrayList<>();
|
|
|
+
|
|
|
+ Set<Long> projectDeptIds = new HashSet<>();
|
|
|
+ // key公司id value公司级部门
|
|
|
+ Map<Long, DeptDO> companyDeptPair = new HashMap<>();
|
|
|
+ // key项目部id value项目部名称
|
|
|
+ Map<Long, DeptDO> projectDeptPair = new HashMap<>();
|
|
|
+ // key部门id value部门parentId
|
|
|
+ Map<Long, Long> teamProjectIdPair = new HashMap<>();
|
|
|
+ // key队伍id value队伍部门
|
|
|
+ Map<Long, DeptDO> teamDeptPair = new HashMap<>();
|
|
|
+
|
|
|
+ // key公司id value累计 注气量(万方)
|
|
|
+ Map<Long, BigDecimal> cumulativeGasInjectionPair = new HashMap<>();
|
|
|
+ // key公司id value累计 进尺(米)
|
|
|
+ Map<Long, BigDecimal> cumulativeFootagePair = new HashMap<>();
|
|
|
+ // key公司id value累计 井次(井) 修井 井下 连油 井次
|
|
|
+ Map<Long, BigDecimal> cumulativeWellCountPair = new HashMap<>();
|
|
|
+ // key公司id value累计 压裂(层) 瑞都压裂层 5#国压裂层
|
|
|
+ Map<Long, BigDecimal> cumulativeFracLayerPair = new HashMap<>();
|
|
|
+ // key公司id value业务类型
|
|
|
+ Map<Long, String> projectBusinessPair = new HashMap<>();
|
|
|
+
|
|
|
+ // 月度统计(公司 -> 年月 -> 统计值)
|
|
|
+ Map<Long, Map<String, MonthlyStats>> projectMonthStatsMap = new HashMap<>();
|
|
|
+
|
|
|
+ // 计划工作量 项目业务类型 key字典键值 value字典标签
|
|
|
+ Map<String, String> workloadPlanDictPair = new HashMap<>();
|
|
|
+
|
|
|
+ // key项目业务类型 value项目部id集合
|
|
|
+ Map<String, Set<Long>> projectBizPair = new HashMap<>();
|
|
|
+
|
|
|
+ // 队伍id 集合
|
|
|
+ Set<Long> teamIds = new HashSet<>();
|
|
|
+
|
|
|
+ // 查询3个专业公司的所有子部门 组装队伍与公司的关联关系
|
|
|
+ Set<Long> allRhChildDeptIds = deptService.getChildDeptIdListFromCache(157l);
|
|
|
+ Set<Long> allRyChildDeptIds = deptService.getChildDeptIdListFromCache(158l);
|
|
|
+ Set<Long> allRdChildDeptIds = deptService.getChildDeptIdListFromCache(163l);
|
|
|
+ Set<Long> allFiveChildDeptIds = deptService.getChildDeptIdListFromCache(388l);
|
|
|
+ // 公司ID -> 公司全部下属子部门集合
|
|
|
+ Map<Long, Set<Long>> companyAllChildDeptMap = new HashMap<>(4);
|
|
|
+ companyAllChildDeptMap.put(157L, allRhChildDeptIds);
|
|
|
+ companyAllChildDeptMap.put(158L, allRyChildDeptIds);
|
|
|
+ companyAllChildDeptMap.put(163L, allRdChildDeptIds);
|
|
|
+ companyAllChildDeptMap.put(388L, allFiveChildDeptIds);
|
|
|
+
|
|
|
+ // 以项目部为维度统计数据
|
|
|
+ // 找到所有项目部与队伍的对应关系
|
|
|
+ // 查询指定根部门下的所有子部门
|
|
|
+ Set<Long> allJtChildDeptIds = deptService.getChildDeptIdListFromCache(pageReqVO.getDeptId());
|
|
|
+ DeptListReqVO reqVO = new DeptListReqVO();
|
|
|
+ reqVO.setDeptIds(allJtChildDeptIds);
|
|
|
+ List<DeptDO> departments = deptService.getDeptList(reqVO);
|
|
|
+
|
|
|
+ // 查询 计划工作量 项目业务类型 项目业务(注气/钻井/修井/压裂/连油/井下)
|
|
|
+ List<DictDataDO> workloadPlanBizData = dictDataService.getDictDataListByDictType("rq_iot_workload_plan_biz");
|
|
|
+ if (CollUtil.isNotEmpty(workloadPlanBizData)) {
|
|
|
+ workloadPlanBizData.forEach(tech -> {
|
|
|
+ String label = tech.getLabel();
|
|
|
+ workloadPlanDictPair.put(tech.getValue(), label);
|
|
|
+ // 设置每个项目部的业务类型
|
|
|
+ String projectDeptIdsStr = tech.getRemark();
|
|
|
+ if (StrUtil.isNotBlank(projectDeptIdsStr)) {
|
|
|
+ // 数据格式 234,124,832
|
|
|
+ // 逗号分割、转Long、过滤空字符串、收集到Set
|
|
|
+ Set<Long> deptIdSet = StrUtil.splitTrim(projectDeptIdsStr, ",")
|
|
|
+ .stream()
|
|
|
+ .filter(StrUtil::isNotBlank)
|
|
|
+ .map(Long::valueOf)
|
|
|
+ .collect(Collectors.toSet());
|
|
|
+
|
|
|
+ // 存入map:存在则合并集合,不存在则新建
|
|
|
+ projectBizPair.computeIfAbsent(label, k -> new HashSet<>()).addAll(deptIdSet);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ // 构建项目部映射和父子部门关系
|
|
|
+ departments.forEach(dept -> {
|
|
|
+ if ("1".equals(dept.getType()) && dept.getStatus() == 0) {
|
|
|
+ // 公司
|
|
|
+ companyDeptPair.put(dept.getId(), dept);
|
|
|
+ }
|
|
|
+ if ("2".equals(dept.getType())) {
|
|
|
+ // 项目部
|
|
|
+ projectDeptIds.add(dept.getId());
|
|
|
+ projectDeptPair.put(dept.getId(), dept);
|
|
|
+ }
|
|
|
+ if ("3".equals(dept.getType())) {
|
|
|
+ // 队伍
|
|
|
+ teamIds.add(dept.getId());
|
|
|
+ teamDeptPair.put(dept.getId(), dept);
|
|
|
+ }
|
|
|
+ // 所有部门与上级部门的 id 对应关系
|
|
|
+ teamProjectIdPair.put(dept.getId(), dept.getParentId());
|
|
|
+
|
|
|
+ });
|
|
|
+ // 遍历 计划工作量列表 以公司为维度组装 工作量数据
|
|
|
+ plans.forEach(plan -> {
|
|
|
+ Long teamDeptId = plan.getDeptId();
|
|
|
+ BigDecimal gasInjection = ObjUtil.isNotEmpty(plan.getPlanGasInjection()) ? plan.getPlanGasInjection() : BigDecimal.ZERO;
|
|
|
+ BigDecimal footage = ObjUtil.isNotEmpty(plan.getPlanFootage()) ? plan.getPlanFootage() : BigDecimal.ZERO;
|
|
|
+ BigDecimal wellTrips = ObjUtil.isNotEmpty(plan.getPlanWellTrips()) ? plan.getPlanWellTrips() : BigDecimal.ZERO;
|
|
|
+ BigDecimal layers = ObjUtil.isNotEmpty(plan.getPlanLayers()) ? plan.getPlanLayers() : BigDecimal.ZERO;
|
|
|
+ String business = plan.getBusiness();
|
|
|
+ if (ObjUtil.isNotEmpty(teamDeptId) && teamProjectIdPair.containsKey(teamDeptId)) {
|
|
|
+ // 公司id
|
|
|
+ Long companyDeptId = 0l;
|
|
|
+ // 判断当前队伍所属的专业公司
|
|
|
+ if (allRhChildDeptIds.contains(teamDeptId)) {
|
|
|
+ // 瑞恒公司下的队伍
|
|
|
+ companyDeptId = 157l;
|
|
|
+ } else if (allRyChildDeptIds.contains(teamDeptId)) {
|
|
|
+ // 瑞鹰公司下的队伍
|
|
|
+ companyDeptId = 158l;
|
|
|
+ } else if (allRdChildDeptIds.contains(teamDeptId)) {
|
|
|
+ // 瑞都公司下的队伍
|
|
|
+ companyDeptId = 163l;
|
|
|
+ } else {
|
|
|
+ // 5#国的队伍
|
|
|
+ companyDeptId = 388l;
|
|
|
+ }
|
|
|
+ if (ObjUtil.isNotEmpty(companyDeptId) && (companyDeptId > 0)) {
|
|
|
+ // 累计注气量
|
|
|
+ cumulativeGasInjectionPair.compute(companyDeptId, (k, v) -> ObjUtil.isEmpty(v) ? gasInjection : v.add(gasInjection));
|
|
|
+ // 累计进尺
|
|
|
+ cumulativeFootagePair.compute(companyDeptId, (k, v) -> ObjUtil.isEmpty(v) ? footage : v.add(footage));
|
|
|
+ // 累计井次
|
|
|
+ cumulativeWellCountPair.compute(companyDeptId, (k, v) -> ObjUtil.isEmpty(v) ? wellTrips : v.add(wellTrips));
|
|
|
+ // 累计压裂层
|
|
|
+ cumulativeFracLayerPair.compute(companyDeptId, (k, v) -> ObjUtil.isEmpty(v) ? layers : v.add(layers));
|
|
|
+ // 工作量业务类型
|
|
|
+ if (StrUtil.isNotBlank(business) && workloadPlanDictPair.containsKey(business)) {
|
|
|
+ projectBusinessPair.put(companyDeptId, workloadPlanDictPair.get(business));
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 按照 年 月 汇总统计 计划工作量 如 2025-03
|
|
|
+ LocalDateTime startTime = plan.getStartTime();
|
|
|
+ if (ObjUtil.isNotEmpty(startTime)) {
|
|
|
+ // 提取出时间中的 年 月
|
|
|
+ Integer year = startTime.getYear();
|
|
|
+ Integer month = startTime.getMonthValue();
|
|
|
+ String uniqueKey = StrUtil.join("-", year, month);
|
|
|
+ // 统计各公司下包含的按照 yyyy-MM 统计的各项工作量
|
|
|
+ // 获取该公司的月度Map
|
|
|
+ Map<String, MonthlyStats> monthMap = projectMonthStatsMap.computeIfAbsent(companyDeptId, k -> new HashMap<>());
|
|
|
+ // 获取该年月的统计对象
|
|
|
+ MonthlyStats stats = monthMap.computeIfAbsent(uniqueKey, k -> new MonthlyStats());
|
|
|
+ // 累加
|
|
|
+ stats.gasInjection = stats.gasInjection.add(gasInjection);
|
|
|
+ stats.footage = stats.footage.add(footage);
|
|
|
+ stats.wellCount = stats.wellCount.add(wellTrips);
|
|
|
+ stats.fracLayer = stats.fracLayer.add(layers);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ // 组装查询时间区间内包含的 年 月
|
|
|
+ LocalDateTime[] startTimeArr = pageReqVO.getStartTime();
|
|
|
+ if (ObjUtil.isEmpty(startTimeArr)) {
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+ if (startTimeArr.length < 1) {
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+ List<String> allMonths = generateMonthRange(startTimeArr[0], startTimeArr[1]);
|
|
|
+
|
|
|
+ // 生成返回的数据列表集合
|
|
|
+ companyDeptPair.forEach((deptId, dept) -> {
|
|
|
+ IotProjectTaskPlanStatisticsRespVO statistics = new IotProjectTaskPlanStatisticsRespVO();
|
|
|
+ statistics.setCompanyId(deptId);
|
|
|
+ statistics.setCompanyName(dept.getName());
|
|
|
+ statistics.setSort(dept.getSort());
|
|
|
+ statistics.setType("1");
|
|
|
+ statistics.setCumulativeGasInjection(cumulativeGasInjectionPair.getOrDefault(deptId, BigDecimal.ZERO));
|
|
|
+ statistics.setCumulativeFootage(cumulativeFootagePair.getOrDefault(deptId, BigDecimal.ZERO));
|
|
|
+ statistics.setCumulativeWellCount(cumulativeWellCountPair.getOrDefault(deptId, BigDecimal.ZERO));
|
|
|
+ statistics.setCumulativeFracLayer(cumulativeFracLayerPair.getOrDefault(deptId, BigDecimal.ZERO));
|
|
|
+
|
|
|
+ // 设置每个公司的 业务类型
|
|
|
+ Set<Long> companyChildDepts = companyAllChildDeptMap.getOrDefault(deptId, Collections.emptySet());
|
|
|
+ List<String> bizNameList = projectBizPair.entrySet().stream()
|
|
|
+ .filter(entry -> CollUtil.isNotEmpty(entry.getValue())
|
|
|
+ && CollUtil.intersection(entry.getValue(), companyChildDepts).size() > 0)
|
|
|
+ .map(Map.Entry::getKey)
|
|
|
+ .distinct()
|
|
|
+ .collect(Collectors.toList());
|
|
|
+ String businessName = bizNameList.isEmpty() ? StrUtil.EMPTY : CollUtil.join(bizNameList, ",");
|
|
|
+ statistics.setBusiness(businessName);
|
|
|
+
|
|
|
+ // 处理月度明细
|
|
|
+ Map<String, MonthlyStats> existingMonthMap = projectMonthStatsMap.get(deptId);
|
|
|
+ List<IotProjectTaskPlanStatisticsItemRespVO> items = new ArrayList<>();
|
|
|
+ if (allMonths.isEmpty()) {
|
|
|
+ // 无时间范围时,仅输出已有的月度(兼容原逻辑)
|
|
|
+ if (CollUtil.isNotEmpty(existingMonthMap)) {
|
|
|
+ items = existingMonthMap.entrySet().stream()
|
|
|
+ .sorted(Map.Entry.comparingByKey())
|
|
|
+ .map(entry -> {
|
|
|
+ IotProjectTaskPlanStatisticsItemRespVO item = new IotProjectTaskPlanStatisticsItemRespVO();
|
|
|
+ item.setYearMonth(entry.getKey());
|
|
|
+ MonthlyStats ms = entry.getValue();
|
|
|
+ item.setCumulativeGasInjection(ms.gasInjection);
|
|
|
+ item.setCumulativeFootage(ms.footage);
|
|
|
+ item.setCumulativeWellCount(ms.wellCount);
|
|
|
+ item.setCumulativeFracLayer(ms.fracLayer);
|
|
|
+ return item;
|
|
|
+ })
|
|
|
+ .collect(Collectors.toList());
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ // ★ 补全所有月份
|
|
|
+ for (String month : allMonths) {
|
|
|
+ MonthlyStats stats = CollUtil.isNotEmpty(existingMonthMap) ? existingMonthMap.get(month) : null;
|
|
|
+ if (stats == null) {
|
|
|
+ stats = new MonthlyStats(); // 默认所有字段为 0
|
|
|
+ }
|
|
|
+ IotProjectTaskPlanStatisticsItemRespVO item = new IotProjectTaskPlanStatisticsItemRespVO();
|
|
|
+ item.setYearMonth(month);
|
|
|
+ item.setCumulativeGasInjection(stats.gasInjection);
|
|
|
+ item.setCumulativeFootage(stats.footage);
|
|
|
+ item.setCumulativeWellCount(stats.wellCount);
|
|
|
+ item.setCumulativeFracLayer(stats.fracLayer);
|
|
|
+ items.add(item);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!items.isEmpty()) {
|
|
|
+ statistics.setItems(items);
|
|
|
+ }
|
|
|
+
|
|
|
+ result.add(statistics);
|
|
|
+ });
|
|
|
+
|
|
|
+ return result;
|
|
|
+ }
|
|
|
|
|
|
/**
|
|
|
* 按项目部维度 汇总 统计数据
|