From dec8951aae400e54f6ee83a8f95867dba9da8af1 Mon Sep 17 00:00:00 2001 From: zhanghl <253316343@qq.com> Date: 星期五, 23 五月 2025 17:17:33 +0800 Subject: [PATCH] [钣金计划大表] 优化:焊缝统计导出Excel样式 --- aps-modules/aps-core/src/main/java/com/aps/core/service/impl/ApsGasPipingRouteStatServiceImpl.java | 325 ++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 files changed, 304 insertions(+), 21 deletions(-) diff --git a/aps-modules/aps-core/src/main/java/com/aps/core/service/impl/ApsGasPipingRouteStatServiceImpl.java b/aps-modules/aps-core/src/main/java/com/aps/core/service/impl/ApsGasPipingRouteStatServiceImpl.java index 99c75aa..248f120 100644 --- a/aps-modules/aps-core/src/main/java/com/aps/core/service/impl/ApsGasPipingRouteStatServiceImpl.java +++ b/aps-modules/aps-core/src/main/java/com/aps/core/service/impl/ApsGasPipingRouteStatServiceImpl.java @@ -6,10 +6,12 @@ import com.aps.common.core.utils.uuid.IdUtils; import com.aps.common.security.utils.SecurityUtils; import com.aps.core.domain.*; +import com.aps.core.domain.ApsPlate.ApsPlateStandardRequireError; import com.aps.core.mapper.*; import com.aps.core.service.IApsGasMaterialUsageService; import com.aps.core.service.IApsGasPipingRouteStatService; import com.aps.core.service.IApsStandardProcessService; +import com.aps.core.mapper.ApsPlateStandardRequireErrorMapper; import jakarta.servlet.http.HttpServletResponse; import lombok.extern.slf4j.Slf4j; import org.apache.poi.ss.usermodel.*; @@ -58,6 +60,9 @@ @Autowired private IApsStandardProcessService apsStandardProcessService; + + @Autowired + private ApsPlateStandardRequireErrorMapper apsPlateStandardRequireErrorMapper; /** * 鏌ヨ姘斾綋绠¤矾浜ц兘璐熻浇缁熻 @@ -1117,6 +1122,12 @@ // 澶勭悊鎵嬪伐姘斾綋宸ュ崟鏁版嵁 - 浣跨敤鑱斿悎鏌ヨ鑾峰彇鎵�鏈夌浉鍏虫暟鎹� List<Map<String, Object>> moDataList = apsGasPipingRouteStatMapper.selectMoRouteData(); + // 鑾峰彇鎵�鏈夌殑MO鏁版嵁锛岀敤浜庢鏌ュ摢浜汳O娌℃湁鍏宠仈鍒板伐鑹鸿矾绾� + List<Map<String, Object>> allMoData = apsGasPipingRouteStatMapper.selectAllMoData(); + + // 璁板綍宸插叧鑱斿伐鑹鸿矾绾跨殑MO缂栧彿 + Set<String> processedMoSet = new HashSet<>(); + // 鎸夊伐鍗曞彿鍒嗙粍锛屼究浜庡鐞嗗悓涓�宸ュ崟鐨勪笉鍚屽伐搴� Map<String, List<Map<String, Object>>> moGroups = moDataList.stream() .collect(Collectors.groupingBy(data -> data.get("work_order_no").toString())); @@ -1124,6 +1135,9 @@ // 澶勭悊姣忎釜宸ュ崟鐨勫伐鑹鸿矾绾� for (String workOrderNo : moGroups.keySet()) { List<Map<String, Object>> workOrderData = moGroups.get(workOrderNo); + + // 鏍囪璇ュ伐鍗曞凡澶勭悊 + processedMoSet.add(workOrderNo); // 鎸夊伐搴忓彿鎺掑簭 workOrderData.sort((a, b) -> { @@ -1202,6 +1216,36 @@ statList.addAll(processList); } + } + + // 澶勭悊娌℃湁鍏宠仈鍒板伐鑹鸿矾绾跨殑MO鏁版嵁 + List<ApsPlateStandardRequireError> errorList = new ArrayList<>(); + for (Map<String, Object> moData : allMoData) { + String workOrderNo = moData.get("mo").toString(); + // 濡傛灉璇ュ伐鍗曟病鏈夎澶勭悊杩囷紝璇存槑娌℃湁鍏宠仈鍒板伐鑹鸿矾绾� + if (!processedMoSet.contains(workOrderNo)) { + ApsPlateStandardRequireError error = ApsPlateStandardRequireError.builder() + .id(Long.valueOf(IdUtils.fastSimpleUUID().hashCode())) + .batchNumber(batchNumber) + .requireId(IdUtil.getSnowflakeNextId()) + .docNum(workOrderNo) + .itemNum(moData.get("material_code").toString()) + .orgCode(moData.get("factory").toString()) + .message("鏍囧噯宸ヨ壓璺嚎涓嶅瓨鍦�") + .delFlag("0") + .build(); + + // 璁剧疆鍩虹被灞炴�� + error.setCreateBy(SecurityUtils.getUsername()); + error.setCreateTime(truncateToSeconds(DateUtils.getNowDate())); + + errorList.add(error); + } + } + + // 鎵归噺鎻掑叆寮傚父鏁版嵁 + if (!errorList.isEmpty()) { + apsPlateStandardRequireErrorMapper.batchInsert(errorList); } // 鎵归噺鎻掑叆鏁版嵁 @@ -1445,9 +1489,61 @@ // 鏌ヨ鍘熷鏁版嵁锛堜笉渚濊禆鏁版嵁搴撹仛鍚堬級 List<Map<String, Object>> rawData = apsGasPipingRouteStatMapper.selectRawStatData(queryParams); + // 濡傛灉娌℃湁鏌ヨ鍒板師濮嬫暟鎹紝浣嗛渶瑕佽繑鍥炴墍鏈夊伐搴�/杞﹂棿鐨勬暟鎹� if (rawData.isEmpty()) { + // 鍒涘缓娌℃湁鏃堕棿闄愬埗鐨勫熀纭�鏌ヨ鍙傛暟 + Map<String, Object> baseParams = new HashMap<>(queryParams); + baseParams.remove("yearStart"); + baseParams.remove("monthStart"); + baseParams.remove("yearEnd"); + baseParams.remove("monthEnd"); + + // 鐩存帴浠巃ps_gas_piping_route_stat琛ㄦ煡璇㈡墍鏈夊彲鑳界殑宸ュ簭鍜岃溅闂� + List<Map<String, Object>> baseData = apsGasPipingRouteStatMapper.selectBaseStatData(baseParams); + + // 涓烘瘡涓伐搴�/杞﹂棿鍒涘缓鍩轰簬鏃堕棿鐨勭┖鏁版嵁 + for (Map<String, Object> data : baseData) { + String rowGroupValue = getStringValue(data, rowGroupBy); + if (rowGroupValue == null || rowGroupValue.trim().isEmpty()) continue; + + Map<String, Object> rowEntry = new HashMap<>(); + Map<String, Object> rowDetail = new HashMap<>(); + + // 娣诲姞鍩烘湰淇℃伅 + String plant = getStringValue(data, "plant"); + String major = getStringValue(data, "major"); + String workshop = getStringValue(data, "workshop"); + + if (groupByPlant) rowDetail.put("plant", plant); + if (groupByMajor) rowDetail.put("major", major); + if (groupByWorkshop) rowDetail.put("workshop", workshop); + + // 澶勭悊宸ュ簭鍚嶇О - 濡傛灉rowGroupBy涓簑orkshop锛岄渶瑕佹坊鍔爌rocessName瀛楁 + if ("workshop".equals(rowGroupBy)) { + String processName = getStringValue(data, "processName"); + rowDetail.put("processName", processName != null ? processName : ""); + } + + // 涓烘瘡涓椂闂寸偣鍒涘缓闆跺�兼暟鎹� + List<Map<String, Object>> timeDataList = new ArrayList<>(); + for (String timePoint : timePoints) { + Map<String, Object> pointData = new HashMap<>(); + pointData.put("planDay", timePoint); + pointData.put("requireTimes", BigDecimal.ZERO); + pointData.put("designTimes", BigDecimal.ZERO); + pointData.put("capacityLoad", BigDecimal.ZERO); + timeDataList.add(pointData); + } + + rowDetail.put("timeData", timeDataList); + rowEntry.put(rowGroupValue, rowDetail); + plantTable.add(rowEntry); + } + result.put("plantTable", plantTable); result.put("timePoints", timePoints); + result.put("rowGroupBy", rowGroupBy); + return result; } @@ -1455,29 +1551,20 @@ // 浣跨敤缁勫悎key鏉ュ疄鐜板缁村害鍒嗙粍锛堝姩鎬乺owGroupBy瀛楁 + 鍙�夌殑宸ュ巶/涓撲笟/杞﹂棿锛� Map<String, Map<String, Object>> groupInfoMap = new HashMap<>(); Map<String, Map<String, BigDecimal>> groupTimeDataMap = new HashMap<>(); + // 瀛樺偍姣忎釜groupKey瀵瑰簲鐨刾rocessName闆嗗悎 + Map<String, Set<String>> groupProcessNamesMap = new HashMap<>(); // 閬嶅巻鍘熷鏁版嵁锛屾寜澶氱淮搴﹀垎缁勮繘琛岃仛鍚� for (Map<String, Object> data : rawData) { - // 杩囨护宸ュ簭鍚嶇О涓虹┖鐨勬暟鎹� - String processName = getStringValue(data, "processName"); - if (processName == null || processName.trim().isEmpty()) { - log.warn("璺宠繃澶勭悊锛氬伐搴忓悕绉颁负绌�"); - continue; - } - - // 杩囨护杞﹂棿涓虹┖鐨勬暟鎹� - String workshop = getStringValue(data, "workshop"); - if (workshop == null || workshop.trim().isEmpty()) { - log.warn("璺宠繃澶勭悊锛氳溅闂翠负绌猴紝宸ュ簭鍚嶇О={}", processName); - continue; - } - // 鑾峰彇琛屽垎缁勫瓧娈靛�� String rowGroupValue = getStringValue(data, rowGroupBy); - if (rowGroupValue == null) { - log.warn("璺宠繃澶勭悊锛歿} 瀛楁鍊间负null", rowGroupBy); + if (rowGroupValue == null || rowGroupValue.trim().isEmpty()) { + log.warn("璺宠繃澶勭悊锛歿} 瀛楁鍊间负绌�", rowGroupBy); continue; } + + // 鑾峰彇宸ュ簭鍚嶇О锛堢敤浜庢棩蹇楀拰鍚庣画澶勭悊锛� + String processName = getStringValue(data, "processName"); // 澶勭悊寮�宸ユ棩鏈� Date processPlanStartDay = (Date) data.get("processPlanStartDay"); @@ -1489,6 +1576,7 @@ // 鏋勫缓鍒嗙粍閿� - 鍩轰簬row鍒嗙粍瀛楁鍜屽彲閫夌殑鍏朵粬缁村害 String plant = getStringValue(data, "plant"); String major = getStringValue(data, "major"); + String workshop = getStringValue(data, "workshop"); StringBuilder groupKeyBuilder = new StringBuilder(rowGroupValue); @@ -1514,6 +1602,14 @@ groupInfo.put("workshop", workshop); groupInfo.put("processName", processName); groupInfoMap.put(groupKey, groupInfo); + } + + // 鏀堕泦processName + if (processName != null && !processName.trim().isEmpty()) { + if (!groupProcessNamesMap.containsKey(groupKey)) { + groupProcessNamesMap.put(groupKey, new HashSet<>()); + } + groupProcessNamesMap.get(groupKey).add(processName); } // 璁$畻鏃堕棿鐐筀ey @@ -1562,8 +1658,17 @@ rowDetail.put("workshop", groupInfo.get("workshop")); } - // 淇濈暀宸ュ簭鍚嶇О淇℃伅锛屼互渚垮墠绔睍绀� - if (!"processName".equals(rowGroupBy)) { + // 澶勭悊processName - 濡傛灉rowGroupBy涓簑orkshop锛屽垯灏嗘墍鏈塸rocessName鐢ㄥ垎鍙疯繛鎺� + if ("workshop".equals(rowGroupBy)) { + Set<String> processNames = groupProcessNamesMap.getOrDefault(groupKey, new HashSet<>()); + if (!processNames.isEmpty()) { + String joinedProcessNames = String.join(";", processNames); + rowDetail.put("processName", joinedProcessNames); + } else { + rowDetail.put("processName", groupInfo.get("processName")); + } + } else if (!"processName".equals(rowGroupBy)) { + // 淇濈暀宸ュ簭鍚嶇О淇℃伅锛屼互渚垮墠绔睍绀� rowDetail.put("processName", groupInfo.get("processName")); } @@ -1574,13 +1679,13 @@ for (String timePoint : timePoints) { Map<String, Object> pointData = new HashMap<>(); pointData.put("planDay", timePoint); - pointData.put("designTimes", 0); // 璁捐宸ユ椂鏆傛椂缁�0 // 鑾峰彇璇ユ椂闂寸偣鐨勯渶姹傚伐鏃讹紝濡傛灉涓嶅瓨鍦ㄥ垯璁句负0 BigDecimal requireTimes = timeMap.getOrDefault(timePoint, BigDecimal.ZERO); pointData.put("requireTimes", requireTimes); - // 璁$畻浜ц兘璐熻嵎锛堟殏鏃朵负0锛� + // 璁捐宸ユ椂鍜屼骇鑳借礋鑽风◢鍚庤绠� + pointData.put("designTimes", 0); pointData.put("capacityLoad", 0); timeDataList.add(pointData); @@ -1590,11 +1695,189 @@ rowEntry.put(rowGroupValue, rowDetail); plantTable.add(rowEntry); } - + + // 鍦ㄨ繑鍥炲墠鏌ヨ璁捐浜ц兘鏁版嵁骞惰绠椾骇鑳借礋鑽� + for (Map<String, Object> rowEntry : plantTable) { + for (String rowKey : rowEntry.keySet()) { + Map<String, Object> rowDetail = (Map<String, Object>) rowEntry.get(rowKey); + List<Map<String, Object>> timeDataList = (List<Map<String, Object>>) rowDetail.get("timeData"); + + // 鑾峰彇鍩烘湰淇℃伅 + String plant = rowDetail.containsKey("plant") ? (String) rowDetail.get("plant") : null; + String major = rowDetail.containsKey("major") ? (String) rowDetail.get("major") : null; + String workshop = rowDetail.containsKey("workshop") ? (String) rowDetail.get("workshop") : null; + + // 澶勭悊涓嶅悓鐨剅owGroupBy鎯呭喌 + if ("workshop".equals(rowGroupBy) && rowDetail.containsKey("processName")) { + // 鎯呭喌1: 鎸墂orkshop鑱氬悎锛岄渶瑕佹媶鍒唒rocessName瀛楁 + String processNamesStr = (String) rowDetail.get("processName"); + String[] processNames = processNamesStr.split(";"); + + // 浼樺寲鏌ヨ - 鍒涘缓缂撳瓨锛屾寜鏈堜唤缂撳瓨鏌ヨ缁撴灉 + // Key: year-month-processName, Value: 鏌ヨ缁撴灉鍒楄〃 + Map<String, List<ApsGasPipelineCapacityPlan>> capacityPlanCache = new HashMap<>(); + + // 閬嶅巻姣忎釜鏃堕棿鐐� + for (Map<String, Object> timeData : timeDataList) { + String planDay = (String) timeData.get("planDay"); + BigDecimal requireTimes = new BigDecimal(timeData.get("requireTimes").toString()); + BigDecimal totalDesignTimes = BigDecimal.ZERO; + + // 鎷嗗垎骞存湀鏃� + String[] dateParts = planDay.split("-"); + String year = dateParts[0]; + String month = dateParts[1]; + // 缁熶竴month鏍煎紡涓烘暣鏁板瓧绗︿覆锛屽幓鎺夊墠瀵奸浂 + month = String.valueOf(Integer.parseInt(month)); + String yearMonth = year + "-" + month; + + // 绱姞澶氫釜宸ュ簭鐨勮璁′骇鑳� + for (String processName : processNames) { + // 鏋勫缓缂撳瓨閿� + String cacheKey = yearMonth + "-" + processName.trim(); + + // 浠庣紦瀛樿幏鍙栨垨鏌ヨ鏁版嵁 + List<ApsGasPipelineCapacityPlan> capacityPlans; + if (capacityPlanCache.containsKey(cacheKey)) { + capacityPlans = capacityPlanCache.get(cacheKey); + } else { + // 浣跨敤涓撶敤鏌ヨ鏂规硶鏌ヨ璁捐浜ц兘鏁版嵁 + // 鎸夋枃妗h姹傦細鏍规嵁process_name鍜宲lant鍘籥ps_gas_pipeline_capacity_plan琛ㄤ腑鏌ヨ + capacityPlans = apsGasPipelineCapacityPlanMapper.selectDesignCapacityForInterface2( + processName.trim(), year, month, major, plant); + + // 灏嗙粨鏋滃瓨鍏ョ紦瀛� + capacityPlanCache.put(cacheKey, capacityPlans); + } + + // 绱姞璁捐浜ц兘鍊� + for (ApsGasPipelineCapacityPlan plan : capacityPlans) { + if ("day".equalsIgnoreCase(timeGranularity)) { + // 鏃ョ矑搴︿娇鐢ㄦ棩浜у嚭鏁伴噺 + if (plan.getDayProduceAllNum() != null) { + totalDesignTimes = totalDesignTimes.add(plan.getDayProduceAllNum()); + } + } else { + // 鏈堢矑搴︿娇鐢ㄦ湀浜у嚭鎬绘暟閲� + if (plan.getMonthProduceAllNum() != null) { + totalDesignTimes = totalDesignTimes.add(plan.getMonthProduceAllNum()); + } + } + } + } + + // 鏇存柊璁捐宸ユ椂 + timeData.put("designTimes", totalDesignTimes); + + // 璁$畻浜ц兘璐熻嵎 = 闇�姹備骇鑳�/璁捐浜ц兘脳100% + if (totalDesignTimes.compareTo(BigDecimal.ZERO) > 0) { + BigDecimal capacityLoad = requireTimes + .divide(totalDesignTimes, 2, RoundingMode.HALF_UP) + .multiply(new BigDecimal(100)); + timeData.put("capacityLoad", capacityLoad); + } else { + timeData.put("capacityLoad", 0); + } + } + } else { + // 鎯呭喌2: 鎸塸rocessName鎴栧叾浠栧瓧娈佃仛鍚� + String processName = rowDetail.containsKey("processName") ? + (String) rowDetail.get("processName") : rowKey; + + // 浼樺寲鏌ヨ - 鍒涘缓缂撳瓨锛屾寜鏈堜唤缂撳瓨鏌ヨ缁撴灉 + Map<String, List<ApsGasPipelineCapacityPlan>> capacityPlanCache = new HashMap<>(); + + // 閬嶅巻姣忎釜鏃堕棿鐐� + for (Map<String, Object> timeData : timeDataList) { + String planDay = (String) timeData.get("planDay"); + BigDecimal requireTimes = new BigDecimal(timeData.get("requireTimes").toString()); + + // 鎷嗗垎骞存湀鏃� + String[] dateParts = planDay.split("-"); + String year = dateParts[0]; + String month = dateParts[1]; + // 缁熶竴month鏍煎紡涓烘暣鏁板瓧绗︿覆锛屽幓鎺夊墠瀵奸浂 + month = String.valueOf(Integer.parseInt(month)); + String yearMonth = year + "-" + month; + + // 鏋勫缓缂撳瓨閿� + String cacheKey = yearMonth + "-" + processName; + + // 浠庣紦瀛樿幏鍙栨垨鏌ヨ鏁版嵁 + List<ApsGasPipelineCapacityPlan> capacityPlans; + if (capacityPlanCache.containsKey(cacheKey)) { + capacityPlans = capacityPlanCache.get(cacheKey); + } else { + // 浣跨敤涓撶敤鏌ヨ鏂规硶鏌ヨ璁捐浜ц兘鏁版嵁 + // 鎸夋枃妗h姹傦細鏍规嵁process_name鍜宲lant鍘籥ps_gas_pipeline_capacity_plan琛ㄤ腑鏌ヨ + capacityPlans = apsGasPipelineCapacityPlanMapper.selectDesignCapacityForInterface2( + processName, year, month, major, plant); + + // 灏嗙粨鏋滃瓨鍏ョ紦瀛� + capacityPlanCache.put(cacheKey, capacityPlans); + } + + // 绱姞璁捐浜ц兘鍊� + BigDecimal totalDesignTimes = BigDecimal.ZERO; + for (ApsGasPipelineCapacityPlan plan : capacityPlans) { + if ("day".equalsIgnoreCase(timeGranularity)) { + // 鏃ョ矑搴︿娇鐢ㄦ棩浜у嚭鏁伴噺 + if (plan.getDayProduceAllNum() != null) { + totalDesignTimes = totalDesignTimes.add(plan.getDayProduceAllNum()); + } + } else { + // 鏈堢矑搴︿娇鐢ㄦ湀浜у嚭鎬绘暟閲� + if (plan.getMonthProduceAllNum() != null) { + totalDesignTimes = totalDesignTimes.add(plan.getMonthProduceAllNum()); + } + } + } + + // 鏇存柊璁捐宸ユ椂 + timeData.put("designTimes", totalDesignTimes); + + // 璁$畻浜ц兘璐熻嵎 = 闇�姹備骇鑳�/璁捐浜ц兘脳100% + if (totalDesignTimes.compareTo(BigDecimal.ZERO) > 0) { + BigDecimal capacityLoad = requireTimes + .divide(totalDesignTimes, 2, RoundingMode.HALF_UP) + .multiply(new BigDecimal(100)); + timeData.put("capacityLoad", capacityLoad); + } else { + timeData.put("capacityLoad", 0); + } + } + } + } + } + result.put("plantTable", plantTable); result.put("timePoints", timePoints); result.put("rowGroupBy", rowGroupBy); + // 鏍规嵁鏂囨。娉ㄦ剰鐐�3锛屾坊鍔犳帓搴忛�昏緫 + if (!plantTable.isEmpty()) { + // 瀵硅仛鍚堢粨鏋滆繘琛屾帓搴� + Collections.sort(plantTable, (map1, map2) -> { + String key1 = map1.keySet().iterator().next(); + String key2 = map2.keySet().iterator().next(); + + // 棣栧厛鎸塺owGroupBy鎺掑簭锛坧rocessName鎴杦orkshop锛� + int result1 = key1.compareTo(key2); + if (result1 != 0) { + return result1; + } + + // 濡傛灉rowGroupBy鐩稿悓锛屽啀鎸塸lant鎺掑簭 + Map<String, Object> detail1 = (Map<String, Object>) map1.get(key1); + Map<String, Object> detail2 = (Map<String, Object>) map2.get(key2); + + String plant1 = detail1.containsKey("plant") ? (String) detail1.get("plant") : ""; + String plant2 = detail2.containsKey("plant") ? (String) detail2.get("plant") : ""; + + return plant1.compareTo(plant2); + }); + } + return result; } -- Gitblit v1.9.3