|
@@ -0,0 +1,222 @@
|
|
|
+package com.rongwei.rwapsserver.aps.taskassigning;
|
|
|
+
|
|
|
+import cn.hutool.core.util.StrUtil;
|
|
|
+import com.rongwei.rwapsserver.aps.domain.*;
|
|
|
+import com.rongwei.rwapsserver.aps.util.ApsException;
|
|
|
+import com.rongwei.rwapsserver.aps.vo.ProductionScheduleRetVo;
|
|
|
+import lombok.extern.slf4j.Slf4j;
|
|
|
+import org.springframework.stereotype.Service;
|
|
|
+
|
|
|
+import java.time.LocalDateTime;
|
|
|
+import java.time.ZoneId;
|
|
|
+import java.util.*;
|
|
|
+import java.util.concurrent.ConcurrentHashMap;
|
|
|
+import java.util.stream.Collectors;
|
|
|
+
|
|
|
+@Slf4j
|
|
|
+@Service
|
|
|
+public class TaskAssignApsServiceImpl implements TaskAssignApsService{
|
|
|
+ @Override
|
|
|
+ public ProductionScheduleRetVoTa productionSchedule(ProductionScheduleVoTa productionScheduleVo) throws Exception {
|
|
|
+ log.info("*************** 排程开始:"+productionScheduleVo.getProductionScheduleId()+" *******************");
|
|
|
+ // 排程结果对象
|
|
|
+ ProductionScheduleRetVo productionScheduleRetVo = new ProductionScheduleRetVo();
|
|
|
+ // 排程校验
|
|
|
+ if(productionScheduleVo.getRoamTime() == null || productionScheduleVo.getRoamTime().size() == 0){
|
|
|
+ throw new ApsException("缺少全局流转时间配置");
|
|
|
+ }
|
|
|
+ // optaplanner 求解器数据装配
|
|
|
+ List<ProductionProcessesTa> otherThproces = new ArrayList<>();
|
|
|
+ List<ProductionProcessesTa> otherNotThproces = new ArrayList<>();
|
|
|
+ ApsSolutionTa apsSolution = getPreApsSolution(productionScheduleVo,otherThproces);
|
|
|
+ // 判断是否有非锁定的工序
|
|
|
+ boolean hasSchedulePro = false;
|
|
|
+ for (ProductionProcessesTa productionProcesses : apsSolution.getProcessesList()) {
|
|
|
+ if(!productionProcesses.getIfLock()){
|
|
|
+ hasSchedulePro = true;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if(!hasSchedulePro){
|
|
|
+ throw new ApsException("没有可排程的工序");
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ private ApsSolutionTa getPreApsSolution(ProductionScheduleVoTa productionScheduleVo,List<ProductionProcessesTa> otherThproces){
|
|
|
+ ApsSolutionTa unsolvedCloudBalance = new ApsSolutionTa();
|
|
|
+ // 排程全局配置
|
|
|
+ ApsOverallConfig apsOverallConfig = new ApsOverallConfig();
|
|
|
+ // 排程计划开始时间
|
|
|
+ Date startDate = productionScheduleVo.getApsPlanStartDate();
|
|
|
+ LocalDateTime startTime = startDate.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
|
|
|
+ apsOverallConfig.setStartTimeLong(startDate.getTime());
|
|
|
+ apsOverallConfig.setStartTime(startTime);
|
|
|
+ // 排程全局配置
|
|
|
+ apsOverallConfig.setRoamTime(productionScheduleVo.getRoamTime());
|
|
|
+ apsOverallConfig.setWashingtime(productionScheduleVo.getWashingtime());
|
|
|
+ apsOverallConfig.setStandingtime(productionScheduleVo.getStandingtime());
|
|
|
+ apsOverallConfig.setClosealloynames(productionScheduleVo.getClosealloynames());
|
|
|
+ apsOverallConfig.setFurnaceInstallations(productionScheduleVo.getFurnaceInstallations());
|
|
|
+ apsOverallConfig.setMergeFurnaces(productionScheduleVo.getMergeFurnaces());
|
|
|
+ apsOverallConfig.setLooseness(productionScheduleVo.getLooseness());
|
|
|
+ apsOverallConfig.setStandingyield(productionScheduleVo.getStandingyield());
|
|
|
+ // 铸轧连续兼容配置
|
|
|
+ apsOverallConfig.setApsNochangeRollerDos(productionScheduleVo.getApsNochangeRollerDos());
|
|
|
+ unsolvedCloudBalance.setStartTime(startTime);
|
|
|
+
|
|
|
+ // 根据前道、后道工序ID,转换为前道、后道工序对象
|
|
|
+ Map<String,ProductionProcessesTa> idMaps = new HashMap<>();
|
|
|
+ for (ProductionProcessesTa process : productionScheduleVo.getProcesses()) {
|
|
|
+ idMaps.put(String.join(",",process.getId()),process);
|
|
|
+ }
|
|
|
+ /*List<ProductionProcessesTa> thList = apsService.thProcessMerge(productionScheduleVo,otherThproces);
|
|
|
+ productionScheduleVo.setProcesses(thList);*/
|
|
|
+ for (ProductionProcessesTa process : productionScheduleVo.getProcesses()) {
|
|
|
+ // 全局配置设置
|
|
|
+ if(process.getApsOverallConfig() == null){
|
|
|
+ process.setApsOverallConfig(apsOverallConfig);
|
|
|
+ }else{
|
|
|
+ // 铸轧连续兼容配置
|
|
|
+ process.getApsOverallConfig().setApsNochangeRollerDos(productionScheduleVo.getApsNochangeRollerDos());
|
|
|
+ }
|
|
|
+ process.getApsOverallConfig().setApsAnnealingDifferences(productionScheduleVo.getApsAnnealingDifferences());
|
|
|
+ process.getApsOverallConfig().setMiddifference(productionScheduleVo.getMiddifference());
|
|
|
+ process.getApsOverallConfig().setFurnacedifference(productionScheduleVo.getFurnacedifference());
|
|
|
+ process.getApsOverallConfig().setWeightdifference(productionScheduleVo.getWeightdifference());
|
|
|
+ process.getApsOverallConfig().setMidweightdifference(productionScheduleVo.getMidweightdifference());
|
|
|
+
|
|
|
+ if(StrUtil.isBlank(process.getTaskType())){
|
|
|
+ process.setTaskType("processes");
|
|
|
+ }
|
|
|
+ process.setMergeRooprocess(new ArrayList<>());
|
|
|
+ process.setApsStatus("CH");
|
|
|
+ process.setOrderId(process.getProduceOrder().get(0).getId());
|
|
|
+ process.setTotalSinglerollweight(process.getSinglerollweight());
|
|
|
+ process.setTotalVolumeWidth(process.getVolumeWidth());
|
|
|
+ // 前道工序
|
|
|
+ if(process.getPreviousProcessesIds() != null && process.getPreviousProcessesIds().size()>0){
|
|
|
+ List<ProductionProcessesTa> pres = new ArrayList<>();
|
|
|
+ for (String previousProcessesId : process.getPreviousProcessesIds()) {
|
|
|
+ for (ProductionProcessesTa productionScheduleVoProcess : productionScheduleVo.getProcesses()) {
|
|
|
+ if(productionScheduleVoProcess.getId().equals(previousProcessesId)){
|
|
|
+ pres.add(productionScheduleVoProcess);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+ if(pres != null && pres.size()>0){
|
|
|
+ process.setPreviousProcesses(pres);
|
|
|
+ }
|
|
|
+ // 前道工序历史备份
|
|
|
+ List<String> oldpreids = new ArrayList<>();
|
|
|
+ oldpreids.addAll(process.getPreviousProcessesIds());
|
|
|
+ process.setOldPreviousProcessesIds(oldpreids);
|
|
|
+ }
|
|
|
+ // 后道工序
|
|
|
+ if(process.getNextProcessesIds() != null && process.getNextProcessesIds().size()>0){
|
|
|
+ List<ProductionProcessesTa> nexts = new ArrayList<>();
|
|
|
+ /*for (String nextId : process.getNextProcessesIds()) {
|
|
|
+ nexts.add(idMaps.get(nextId));
|
|
|
+ }*/
|
|
|
+ for (String previousProcessesId : process.getNextProcessesIds()) {
|
|
|
+ for (ProductionProcessesTa nextprocess : productionScheduleVo.getProcesses()) {
|
|
|
+ if(nextprocess.getId().equals(previousProcessesId)){
|
|
|
+ nexts.add(nextprocess);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+ if(nexts != null && nexts.size()>0){
|
|
|
+ process.setNextProcesses(nexts);
|
|
|
+ }
|
|
|
+ // 后道工序历史备份
|
|
|
+ List<String> oldnextids = new ArrayList<>();
|
|
|
+ oldnextids.addAll(process.getNextProcessesIds());
|
|
|
+ process.setOldNextProcessesIds(oldnextids);
|
|
|
+ }
|
|
|
+ // 默认批次为1
|
|
|
+ if(process.getProducePcNum() == null){
|
|
|
+ process.setProducePcNum(1);
|
|
|
+ }
|
|
|
+ // 单位批次生产时间
|
|
|
+ if(process.getUnitProduceTime() == null){
|
|
|
+ process.setUnitProduceTime((int)(Math.ceil((double)process.getProduceTime()/process.getProducePcNum())));
|
|
|
+ }
|
|
|
+ process.setVolumeMetalAndState(process.getVolumeMetal() + (process.getVolumeMetalstate() == null ? "" : process.getVolumeMetalstate()) + process.getProcessType());
|
|
|
+ // 可选设备初始化
|
|
|
+ if(process.getOptionalEquipments() != null){
|
|
|
+ List<EquipmentTa> providedEq = new ArrayList<>();
|
|
|
+ for (EquipmentTa equipment : productionScheduleVo.getEquipmentList()) {
|
|
|
+ if(process.getOptionalEquipments().contains(equipment.getId())){
|
|
|
+ providedEq.add(equipment);
|
|
|
+ }
|
|
|
+ if(StrUtil.isNotBlank(process.getEquipmentId())){
|
|
|
+ if(process.getEquipmentId().equals(equipment.getId())){
|
|
|
+ process.setEquipment(equipment);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if(providedEq.size() == 0){
|
|
|
+ throw new ApsException("500","坯料计划号:"+process.getProduceOrder().get(0).getOrderNo()+"作业名称:"+ process.getProcessName() + ",可选设备不能为空");
|
|
|
+ }
|
|
|
+ process.setOptionalProviderEquipments(providedEq);
|
|
|
+ }
|
|
|
+ // 铸轧机熔炉分组
|
|
|
+ List<EquipmentTa> zzrls = productionScheduleVo.getEquipmentList().stream().filter(v->StrUtil.isNotBlank(v.getEquassociated())).collect(Collectors.toList());
|
|
|
+ Map<String, List<EquipmentTa>> equass = zzrls.stream().collect(Collectors.groupingBy(EquipmentTa::getEquassociated));
|
|
|
+ process.setEquass(equass);
|
|
|
+
|
|
|
+ // 上机时间和下机时间如果为null,设置为0
|
|
|
+ if(process.getPrepressworkmin() == null){
|
|
|
+ process.setPrepressworkmin(0);
|
|
|
+ }
|
|
|
+ if(process.getCutfinishmin() == null){
|
|
|
+ process.setCutfinishmin(0);
|
|
|
+ }
|
|
|
+ // 锁定工序处理
|
|
|
+ if(process.getIfLock() && process.getOptionalProviderEquipments().size()>0){
|
|
|
+ process.setIfLock(false);
|
|
|
+ int ai = -1;
|
|
|
+ if(process.getOptionalProviderEquipments().get(0).getEquipmentRunTimes() != null
|
|
|
+ && process.getOptionalProviderEquipments().get(0).getEquipmentRunTimes().size()>0){
|
|
|
+ for (int i = 0; i < process.getOptionalProviderEquipments().get(0).getEquipmentRunTimes().size(); i++) {
|
|
|
+ EquipmentRunTime equipmentRunTime = process.getOptionalProviderEquipments().get(0).getEquipmentRunTimes().get(i);
|
|
|
+ if(equipmentRunTime.getStartRunTime().compareTo(process.getStartTime()) == 0 && equipmentRunTime.getEndRunTime().compareTo(process.getEndTime()) == 0){
|
|
|
+ ai = i;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if(ai>-1){
|
|
|
+ process.getOptionalProviderEquipments().get(0).getEquipmentRunTimes().remove(ai);
|
|
|
+ }
|
|
|
+ // 锁定工序的设备即可选设备
|
|
|
+ process.setEquipment(process.getOptionalProviderEquipments().get(0));
|
|
|
+ process.setIfLock(true);
|
|
|
+ }
|
|
|
+ // 特殊冲突约束Map初始化
|
|
|
+ process.setConflictRoptions(new ConcurrentHashMap<>());
|
|
|
+ // 唯一作业ID设值
|
|
|
+ process.setUniqueBsProcessesId(process.getBsProcessesId().get(0));
|
|
|
+ }
|
|
|
+ // 设备占用时间段合并处理
|
|
|
+ /*for (Equipment equipment : productionScheduleVo.getEquipmentList()) {
|
|
|
+ if(equipment.getId().equals("07a5e263a79c47b48c6ff3ea6152e611")){
|
|
|
+ int a = 1;
|
|
|
+ }
|
|
|
+ apsService.equipmentRunTimeMerge(equipment,productionScheduleVo.getFurnaceInstallations());
|
|
|
+ }*/
|
|
|
+ // 设备列表初始化
|
|
|
+ unsolvedCloudBalance.setEquipmentList(productionScheduleVo.getEquipmentList());
|
|
|
+
|
|
|
+ /*List<ProductionProcessesTa> productionProcesses = sortProcess(productionScheduleVo.getProcesses());
|
|
|
+ // 工序任务初始化
|
|
|
+ unsolvedCloudBalance.setProcessesList(productionProcesses);*/
|
|
|
+
|
|
|
+// sortProcess(productionScheduleVo.getProcesses(),0);
|
|
|
+ unsolvedCloudBalance.setProcessesList(productionScheduleVo.getProcesses());
|
|
|
+ return unsolvedCloudBalance;
|
|
|
+ }
|
|
|
+}
|