| | |
| | | import java.util.concurrent.atomic.AtomicInteger; |
| | | import java.util.stream.Collectors; |
| | | |
| | | import cn.hutool.core.collection.ListUtil; |
| | | import cn.hutool.core.util.IdUtil; |
| | | import com.alibaba.fastjson.JSONObject; |
| | | import com.alibaba.fastjson2.JSON; |
| | | import com.alibaba.nacos.common.utils.JacksonUtils; |
| | |
| | | /** |
| | | * 保存钣金车间统计 |
| | | */ |
| | | @Transactional |
| | | @Transactional( rollbackFor =Exception.class) |
| | | @Override |
| | | public void saveShopStat() { |
| | | try { |
| | | apsPlateProcessStatService.savePlateProcessStat(); |
| | | // 开始之前先删除所有历史数据 |
| | | // 定义该功能使用数据源为南通的工厂 |
| | | final String plant = "FORTUNA"; |
| | | final String major="BJ"; |
| | | // 查询相关数据 |
| | | ApsPlatePlan platePlan = new ApsPlatePlan(); |
| | | platePlan.setPlant(plant); |
| | | log.info("开始执行钣金计划大表"); |
| | | List<ApsPlatePlan> planList = apsPlatePlanMapper.selectApsPlatePlanList(platePlan); |
| | | |
| | | ApsShop apsShop = new ApsShop(); |
| | | apsShop.setPlantCode(plant); |
| | | List<ApsShop> shopList = shopMapper.selectApsShopList(apsShop); |
| | | |
| | | ApsStandardProcess process = new ApsStandardProcess(); |
| | | process.setPlant(plant); |
| | | process.setMajor(major); |
| | | |
| | | List<ApsStandardProcess> shopProcesses = standardProcessMapper.selectApsStandardProcessList(process); |
| | | |
| | | if (!planList.isEmpty() && !shopList.isEmpty() && !shopProcesses.isEmpty()) { |
| | | |
| | | log.info("钣金计划大表:删除所有历史数据"); |
| | | apsPlateProcessStatMapper.deleteAll(); |
| | | apsPlateProcessShopStatMapper.deleteAll(); |
| | | |
| | | // 定义该功能使用数据源为南通的工厂 |
| | | final String plant = "FORTUNA"; |
| | | final String major="钣金"; |
| | | // 查询相关数据 |
| | | ApsPlatePlan platePlan = new ApsPlatePlan(); |
| | | platePlan.setPlant(plant); |
| | | List<ApsPlatePlan> planList = apsPlatePlanMapper.selectApsPlatePlanList(platePlan); |
| | | |
| | | List<ApsPlateProcessStat> statList = apsPlateProcessStatMapper.selectApsPlateProcessStatList(new ApsPlateProcessStat()); |
| | | |
| | | ApsShop apsShop = new ApsShop(); |
| | | apsShop.setPlantCode(plant); |
| | | List<ApsShop> shopList = shopMapper.selectApsShopList(apsShop); |
| | | |
| | | ApsStandardProcess process = new ApsStandardProcess(); |
| | | process.setPlant(plant); |
| | | process.setMajor(major); |
| | | List<ApsStandardProcess> shopProcesses = standardProcessMapper.selectApsStandardProcessList(process); |
| | | if (planList.isEmpty() || shopList.isEmpty() || shopProcesses.isEmpty()) { |
| | | log.warn("计划列表、车间列表或工序列表为空,无法生成统计信息"); |
| | | return; |
| | | } |
| | | // 构建车间名称到工序名称的映射 |
| | | Map<String, List<String>> shopToProcessNames = shopProcesses.stream() |
| | | log.info("钣金计划大表:推算倒排钣金工序计划完工日期和计划开工时间"); |
| | | List<ApsPlateProcessStat> statList =apsPlateProcessStatService.computePlateProcessStat(); |
| | | // 构建车间名称到工序名称的映射 |
| | | Map<String, List<String>> shopToProcessNames = shopProcesses.stream().filter(x -> null!=x.getWorkShop()) |
| | | .collect(Collectors.groupingBy(ApsStandardProcess::getWorkShop, |
| | | Collectors.mapping(ApsStandardProcess::getProcessName, Collectors.toList()) |
| | | )); |
| | | // 批量插入统计数据 |
| | | log.info("钣金计划大表:计算每个工单中每个车间的开始、结束时间"); |
| | | List<ApsPlateProcessShopStat> statsToInsert = new ArrayList<>(); |
| | | for (ApsPlatePlan plan : planList) { |
| | | for (ApsShop shop : shopList) { |
| | | log.info("钣金计划大表V1:开始计算每个工单车间工时"); |
| | | planList.stream().parallel().forEach(plan -> { |
| | | shopList.stream().parallel().forEach(shop -> { |
| | | ApsPlateProcessShopStat stat = createShopStat(plan, shop, shopToProcessNames, statList); |
| | | statsToInsert.add(stat); |
| | | } |
| | | }); |
| | | }); |
| | | log.info("钣金计划大表:批量保存工序开工和完工时间"); |
| | | List<List<ApsPlateProcessStat>> processStatBatchList = ListUtil.split(statList, 1000); |
| | | processStatBatchList.stream().parallel().forEach(batch -> apsPlateProcessStatMapper.batchInsertPlateStat(batch)); |
| | | |
| | | |
| | | log.info("钣金计划大表:批量保存工单-车间时间信息"); |
| | | List<List<ApsPlateProcessShopStat>> shopStatBatchList = ListUtil.split(statsToInsert, 1000); |
| | | shopStatBatchList.stream().parallel().forEach(batch -> apsPlateProcessShopStatMapper.batchInsert(batch)); |
| | | }else { |
| | | if(shopProcesses.isEmpty()){ |
| | | log.error("钣金计划大表:未找到标准工序数据!"); |
| | | throw new RuntimeException("未找到标准工序数据!"); |
| | | } |
| | | // 批量插入以提高性能 |
| | | if (!statsToInsert.isEmpty()) { |
| | | int batchSize = 1000; |
| | | for (int i = 0; i < statsToInsert.size(); i += batchSize) { |
| | | int end = Math.min(i + batchSize, statsToInsert.size()); |
| | | List<ApsPlateProcessShopStat> batch = statsToInsert.subList(i, end); |
| | | apsPlateProcessShopStatMapper.batchInsert(batch); |
| | | } |
| | | if(shopList.isEmpty()){ |
| | | log.error("钣金计划大表:未找到车间数据!"); |
| | | throw new RuntimeException("未找到车间数据!"); |
| | | } |
| | | } catch (Exception e) { |
| | | log.error("保存钣金车间统计时发生异常", e); |
| | | throw new RuntimeException("保存钣金车间统计失败", e); |
| | | if(planList.isEmpty()){ |
| | | log.error("钣金计划大表:未找到工单数据!"); |
| | | throw new RuntimeException("未找到工单数据!"); |
| | | } |
| | | } |
| | | log.info("钣金计划大表:完成"); |
| | | } |
| | | |
| | | /** |
| | |
| | | stat.setWorkCenter(plan.getWorkCenter()); |
| | | stat.setProcessNumber(plan.getProcessNumber()); |
| | | try { |
| | | |
| | | |
| | | List<String> processNames = shopToProcessNames.getOrDefault(shopName, Collections.emptyList()); |
| | | if (!processNames.isEmpty()) { |
| | |
| | | } |
| | | } |
| | | } catch (Exception e) { |
| | | log.error("computer error:"+ JSONObject.toJSONString(stat)); |
| | | log.error("钣金计划大表 error:"+ JSONObject.toJSONString(stat)); |
| | | throw new RuntimeException("计算车间统计数据异常!"); |
| | | } |
| | | return stat; |
| | | } |
| | |
| | | List<SysDictData> documentStatusDic = DictUtils.getDictCache("aps_document_status"); |
| | | |
| | | // 构建结果列表 |
| | | planList.forEach( |
| | | planList.stream().parallel().forEach( |
| | | plan -> { |
| | | // 根据 docNo 获取对应的 shopStatList |
| | | List<ApsPlateProcessShopStat> shopStatList = shopStatesByDocNo.getOrDefault(plan.getDocumentNumber(), Collections.emptyList()); |