Commit 24ffe414 authored by Tong Li's avatar Tong Li

Merge remote-tracking branch 'origin/tl'

# Conflicts:
#	src/main/java/com/aps/entity/basic/Order.java
#	src/main/java/com/aps/service/impl/LanuchServiceImpl.java
parents 1b901fdf ae62deba
......@@ -117,25 +117,9 @@ public class ResourceGanttController {
}
@GetMapping("/getScene")
@Operation(summary = "获取所有场景ID", description = "获取所有场景ID")
public Chromosome getScene() {
// 调用 PlanResultService 获取 ScheduleChromosome 列表
Chromosome scheduleChromosomes = planResultService.execute1();
// 提取所有场景ID
return scheduleChromosomes;
}
@GetMapping("/getScene2")
@Operation(summary = "获取所有场景ID", description = "获取所有场景ID")
public Chromosome getScene2() {
// 调用 PlanResultService 获取 ScheduleChromosome 列表
Chromosome scheduleChromosomes = planResultService.execute2("B571EF6682DB463AB2977B1055A74112");
// 提取所有场景ID
return scheduleChromosomes;
}
@GetMapping("/SyncMaterials")
@Operation(summary = "更新物料信息缓存", description = "更新物料信息缓存")
......
......@@ -18,11 +18,10 @@ public class BOMBuildResult {
private List<Machine> newMachines;
public BOMBuildResult(List<OrderMaterialRequirement> materialRequirements, List<Order> childOrders,List<Entry> newentrys,List<Machine> newMachines) {
public BOMBuildResult(List<OrderMaterialRequirement> materialRequirements, List<Order> childOrders,List<Entry> newentrys) {
this.materialRequirements = materialRequirements;
this.childOrders = childOrders;
this.newentrys=newentrys;
this.newMachines=newMachines;
}
public List<OrderMaterialRequirement> getMaterialRequirements() {
......
......@@ -3,15 +3,14 @@ package com.aps.entity.Algorithm;
import com.aps.entity.Algorithm.IDAndChildID.GroupResult;
import com.aps.entity.basic.Entry;
import com.aps.entity.basic.Machine;
import com.aps.entity.basic.Material;
import com.aps.entity.basic.Order;
import lombok.Data;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import java.util.*;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.stream.Collectors;
......@@ -24,6 +23,8 @@ public class Chromosome {
private String ID = UUID.randomUUID().toString();
private Integer version=0;
/// <summary>
......@@ -41,28 +42,44 @@ public class Chromosome {
/// </summary>
private String geneStr;
public void setMachineSelection(List<Integer> val) {
machineSelection = val;
machineStr = machineSelection.stream()
.map(String::valueOf) // 将每个 Integer 转换为 String
public String getGeneStr() {
geneStr=getMachineStr()+"_"+getOperationStr();
return geneStr;
}
private Integer gsOrls=0;
public String getMachineStr() {
machineStr= Optional.ofNullable(machineSelection)
.orElse(Collections.emptyList())
.stream()
.map(String::valueOf) // Integer转String
.collect(Collectors.joining(","));
return machineStr;
}
public String getOperationStr() {
operationStr= Optional.ofNullable(operationSequencing)
.orElse(Collections.emptyList())
.stream()
.map(String::valueOf) // Integer转String
.collect(Collectors.joining(","));
geneStr=machineStr+ "_" +operationStr;
return operationStr;
}
/// <summary>
/// 工序排序部分(工件/订单ID)
/// </summary>
private List<Integer> operationSequencing;
public void setOperationSequencing(List<Integer> val) {
operationSequencing = val;
operationStr = operationSequencing.stream()
.map(String::valueOf) // 将每个 Integer 转换为 String
.collect(Collectors.joining(","));
geneStr=machineStr+ "_" +operationStr;
}
/// <summary>
/// 工序排序部分(工件/订单ID)
......@@ -74,15 +91,17 @@ public class Chromosome {
private List<GlobalOperationInfo> globalOpList;
private List<Entry> allOperations;
private List<Order> orders;
private CopyOnWriteArrayList<Entry> allOperations;
private CopyOnWriteArrayList<Order> orders;
private List<Machine> InitMachines;
private List<OrderMaterialRequirement> orderMaterials;
private List<GroupResult> OperatRel;
private CopyOnWriteArrayList<GroupResult> OperatRel;
private ObjectiveWeights objectiveWeights;
List<Material> materials;
/*
* 最早完工时间(最小化) 最小化总加工时间 最小总换型时间
*/
......@@ -147,7 +166,7 @@ public class Chromosome {
private String ScenarioName;
private LocalDateTime BaseTime ; // 当前基准时间
private List<Integer> reOrderids=new ArrayList<>();
//
// //最大设备利用率
......
......@@ -38,6 +38,8 @@ public class GAScheduleResult {
private int changeOverTime;
private int preTime;
private int seq; //工序顺序
private int bomTime;//物料齐套时间
private List<Integer> TargetFinishedOperationId;
public int getFlowTime() {
return EndTime - StartTime;
......
......@@ -23,7 +23,7 @@ public class OrderMaterialRequirement {
private String materialCode;
private String materialName;
private String materialTypeName;
private String bomId;
/**
* 物料类型
*/
......@@ -92,7 +92,35 @@ public class OrderMaterialRequirement {
/**
* 检验周期
*/
private Long checkLeadTime;
private Integer checkLeadTime;
/**
* 采购周期
*/
@TableField(exist = false)
private Integer purchaseTime;
/**
* 单价
*/
@TableField(exist = false)
private BigDecimal price;
@TableField(exist = false)
private List<OrderMaterialRequirement> replaceMaterial=new ArrayList<>();
@TableField(exist = false)
private double mainQty;
/**
* 物料需求数量
*/
@TableField(exist = false)
private double spentQty;
/**
* 计划数量
*/
@TableField(exist = false)
public double Quantity;
}
......@@ -15,7 +15,7 @@ private Long lastmodifieruserid;
private Long isdeleted;
private LocalDateTime deletiontime;
private Long deleteruserid;
private Long routingHeaderId;
private Integer routingHeaderId;
private Long routingDetailId;
private String materialId;
private String materialType;
......
package com.aps.entity;
import com.baomidou.mybatisplus.annotation.TableField;
import lombok.Data;
import java.math.BigDecimal;
......@@ -24,7 +25,7 @@ private String storeCode;
private String storeName;
private double total;
private Integer measureUnit;
private BigDecimal totalLock;
private double totalLock;
private BigDecimal cost;
private LocalDateTime productionDate;
private LocalDateTime expiryDate;
......@@ -37,4 +38,16 @@ private String supplierCode;
private String supplierName;
private Short warehousingUnitId;
private String warehousingUnitName;
/*已用库存数*/
@TableField(exist = false)
private double usedInventory;
/*可用库存数*/
@TableField(exist = false)
private double availableInventory;
public double getAvailableInventory(){
return total-totalLock-usedInventory;
};
}
\ No newline at end of file
......@@ -2,6 +2,7 @@ package com.aps.entity.basic;
import com.aps.entity.Algorithm.OperationDependency;
import com.aps.entity.Algorithm.OrderMaterialRequirement;
import com.aps.entity.RoutingDiscreteParam;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
......@@ -74,7 +75,7 @@ public class Entry {
/**
* 基因编号
*/
public Double Quantity;
public double Quantity;
/**
* 工序顺序
*/
......@@ -112,7 +113,10 @@ public class Entry {
/**
* 所需物料
*/
public List<MaterialRequirement> MaterialRequirements ; // 所需物料
public List<OrderMaterialRequirement> MaterialRequirements ; // 所需物料
/**
* 设备资源组
*/
......@@ -131,7 +135,7 @@ public class Entry {
/// </summary>
public List<Integer> TargetFinishedOperationId;
private boolean newCreate = false;
public boolean newCreate = false;
/// <summary>
/// 半成品最晚完工时间(即成品工序开始时间-1天)
......
package com.aps.service.Algorithm;
/**
* 作者:佟礼
* 时间:2026-01-27
*/
public class DataNode {
int id;
Integer time;
Integer groupId;
int no;
public DataNode(int id, Integer time, int groupId, int no) {
this.id = id;
this.time = time;
this.groupId = groupId;
this.no = no;
}
public int getGroupId() { return groupId; }
public long getTime() { return time; }
public int getNo() { return no; }
@Override
public String toString() {
return String.format("%d\t%d\t%d\t%d", id, time, groupId, no);
}
}
......@@ -14,7 +14,9 @@ import org.springframework.beans.factory.annotation.Autowired;
import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
/**
* 作者:佟礼
......@@ -44,8 +46,10 @@ public class GeneticAlgorithm {
private SceneService _sceneService;
private String sceneId;
public GeneticAlgorithm(GlobalParam globalParam,List<Machine> machines, List<Order> orders,
List<Material> materials, MachineSchedulerService machineScheduler,List<GroupResult> entryRel,MaterialRequirementService _materialRequirementService,SceneService sceneService) {
List<Material> materials, MachineSchedulerService machineScheduler,List<GroupResult> entryRel,MaterialRequirementService _materialRequirementService,SceneService sceneService,String _sceneId) {
this.machines = machines;
this.orders = orders;
this.materials = materials;
......@@ -54,7 +58,7 @@ public class GeneticAlgorithm {
_entryRel=entryRel;
materialRequirementService=_materialRequirementService;
_sceneService=sceneService;
sceneId=_sceneId;
}
public void Init(double[] customWeights, boolean pureNSGAIIMode) {
......@@ -124,7 +128,7 @@ public class GeneticAlgorithm {
{
best.setBaseTime(param.getBaseTime());
best.setOrderMaterials(orderMaterials);
best.setOperatRel(_entryRel);
// best.setOperatRel(_entryRel);
if(best.getInitMachines()==null)
{
......@@ -264,7 +268,7 @@ public class GeneticAlgorithm {
FileHelper.writeLogFile("迭代进化-----------结束-------");
best.setBaseTime(param.getBaseTime());
best.setOrderMaterials(orderMaterials);
best.setOperatRel(_entryRel);
// best.setOperatRel(_entryRel);
if(best.getInitMachines()==null)
{
......@@ -299,19 +303,16 @@ public class GeneticAlgorithm {
FileHelper.writeLogFile(String.format("排产-----------方案数量---%d-------",0 ));
return population;
}
// population = population.stream()
// .collect(Collectors.toMap(
// Chromosome::getGeneStr, // key:去重的字段(GeneStr)
// u -> u, // value:Chromosome对象
// (u1, u2) -> u1 // 重复时保留第一个元素
// ))
// .values() // 获取去重后的
// .stream()
// .collect(Collectors.toList());
population = population.stream()
.filter(chromosome -> chromosome != null && chromosome.getGeneStr() != null)
.collect(Collectors.toMap(
Chromosome::getGeneStr, // key:去重的字段(GeneStr)
u -> u, // value:Chromosome对象
(u1, u2) -> u1 // 重复时保留第一个元素
))
.values() // 获取去重后的
.stream()
.collect(Collectors.toList());
return population;
}
......@@ -372,8 +373,8 @@ return population;
{
FileHelper.writeLogFile("解码---------------"+population.size() );
GeneticDecoder decoder = new GeneticDecoder(_GlobalParam, param.getBaseTime(), machines, orders, materials, machineScheduler,orderMaterials);
boolean ismore=true;
GeneticDecoder decoder = new GeneticDecoder(_GlobalParam, param.getBaseTime(), machines, orders, materials, machineScheduler,materialRequirementService, sceneId);
boolean ismore=false;
if(ismore) {
CompletableFuture.allOf(population.stream()
.map(chromosome -> CompletableFuture.runAsync(() -> decode(decoder, chromosome, param, allOperations, globalOpList), decodeExecutor))
......@@ -382,7 +383,7 @@ return population;
} else {
if (population != null && population.size() > 0) {
population.parallelStream().forEach(chromosome -> {
population.forEach(chromosome -> {
decode(decoder, chromosome, param, allOperations, globalOpList);
});
}
......@@ -403,8 +404,11 @@ return population;
// 假设Machine类有拷贝方法,或使用MapStruct等工具进行映射
chromosome.setMachines(ProductionDeepCopyUtil.deepCopyList(machines,Machine.class)); // 简单拷贝,实际可能需要深拷贝
chromosome.setOrders(ProductionDeepCopyUtil.deepCopyList(new CopyOnWriteArrayList<>(orders), Order.class) ); // 简单拷贝,实际可能需要深拷贝
chromosome.setOperatRel(ProductionDeepCopyUtil.deepCopyList(new CopyOnWriteArrayList<>(_entryRel), GroupResult.class) ); // 简单拷贝,实际可能需要深拷贝
chromosome.setMaterials(ProductionDeepCopyUtil.deepCopyList(materials,Material.class)); // 简单拷贝,实际可能需要深拷贝
chromosome.setAllOperations(allOperations); // 简单拷贝,实际可能需要深拷贝
chromosome.setAllOperations(ProductionDeepCopyUtil.deepCopyList(new CopyOnWriteArrayList<>(allOperations), Entry.class) ); // 简单拷贝,实际可能需要深拷贝
chromosome.setGlobalOpList(globalOpList); // 简单拷贝,实际可能需要深拷贝
//chromosome.setObjectiveWeights(_objectiveWeights);
chromosome.setBaseTime(param.getBaseTime());
......@@ -417,4 +421,6 @@ return population;
}
}
}
......@@ -21,8 +21,10 @@ import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.*;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;
import java.util.concurrent.locks.ReentrantLock;
import java.util.stream.IntStream;
/**
* 作者:佟礼
......@@ -47,13 +49,17 @@ public class GeneticDecoder {
private GlobalParam _globalParam;
private MachineCalculator machineCalculator;
private List<OrderMaterialRequirement> orderMaterials;
private MaterialRequirementService materialRequirementService;
private DiscreteParameterMatrixService discreteParameterMatrixService;
private String sceneId;
public GeneticDecoder(GlobalParam globalParam,LocalDateTime baseTime, List<Machine> machines, List<Order> orders,
List<Material> materials, MachineSchedulerService machineScheduler, List<OrderMaterialRequirement> _orderMaterials) {
List<Material> materials, MachineSchedulerService machineScheduler, MaterialRequirementService _materialRequirementService,String _sceneId) {
this.baseTime = baseTime;
this.machines = machines;
this.orders = orders;
......@@ -62,7 +68,8 @@ public class GeneticDecoder {
this.machineScheduler = machineScheduler;
_globalParam=globalParam;
machineCalculator=new MachineCalculator(baseTime,machines,machineScheduler);
orderMaterials=_orderMaterials;
materialRequirementService=_materialRequirementService;
sceneId=_sceneId;
// this.orderMaxID = orders.stream().mapToInt(Order::getId).max().orElse(0);
}
......@@ -70,10 +77,9 @@ public class GeneticDecoder {
String cacheKey = createCacheKey(chromosome);
// FileHelper.writeLogFile("解码-----------开始-------"+chromosome.getID()+":"+cacheKey );
_allOperations=chromosome.getAllOperations();
if(orderMaterials!=null&&orderMaterials.size()>0&&_globalParam.isIsCheckSf()) {
CreateNewOpSequence(chromosome);
}
// _allOperations=chromosome.getAllOperations();
// 1. 创建缓存键
......@@ -130,9 +136,37 @@ public class GeneticDecoder {
return chromosome;
}
public void generateGlobalOpList(Chromosome chromosome) {
List<GlobalOperationInfo> globalOpList = new ArrayList<>();
int globalOpId = chromosome.getGlobalOpList()
.stream()
.mapToInt(GlobalOperationInfo::getGlobalOpId)
.max().orElse(0)+1;
CopyOnWriteArrayList<Entry> allOperations= chromosome.getAllOperations()
.stream()
.filter(t->t.isNewCreate()==true)
.collect(Collectors.toCollection(CopyOnWriteArrayList::new));
for (Entry op : allOperations) {
GlobalOperationInfo info = new GlobalOperationInfo();
info.setGlobalOpId(globalOpId);
info.setGroupId(op.getGroupId());
info.setSequence(op.getSequence());
info.setOp(op);
globalOpList.add(info);
globalOpId++;
}
Initialization initialization=new Initialization();
initialization.generateInitialSFPopulation(chromosome,globalOpList);
chromosome.getGlobalOpList().addAll(globalOpList);
}
private void CreateNewOpSequence(Chromosome chromosome)
{
//成品订单
List<Integer> finishedOrder = chromosome.getOrders().stream()
.filter(t-> t.getFinishOrderId()==null||t.getFinishOrderId().size()==0)
.map(Order::getId)
......@@ -147,8 +181,8 @@ if(finishedOrder==null||finishedOrder.size()==0)
List<Integer> oldSequence=chromosome.getOperationSequencing();
List<Integer> finalSequence = new ArrayList<>();
// 初始化两个结果数组
List<Integer> pfSequence = new ArrayList<>(); // 包含1/2的元素
Map<Integer, List<Integer>> sfSequence = new HashMap<>(); // 不包含1/2的元素
List<Integer> pfSequence = new ArrayList<>(); // 成品工序
Map<Integer, List<Integer>> sfSequence = new HashMap<>(); // 半成品工序
// 遍历原数组分类
for (int num : oldSequence) {
......@@ -173,7 +207,8 @@ if(finishedOrder==null||finishedOrder.size()==0)
scheduledCount = orderProcessCounter.get(num)+1;
}
int scheduledCount1=scheduledCount;
Entry entry=_allOperations.stream()
List<Entry> allOperations=chromosome.getAllOperations();
Entry entry=allOperations.stream()
.filter(t->t.GroupId==num&&t.getSequence()==scheduledCount1)
.findFirst().orElse(null);
if(entry!=null&&entry.getDependentOnOrderIds().size()>0)
......@@ -181,7 +216,7 @@ if(finishedOrder==null||finishedOrder.size()==0)
for (int order : entry.getDependentOnOrderIds()) {
for (int num1 : sfSequence.get(order)){
InsertSimSequence(orderProcessCounter,num1,finalSequence,sfSequence);
InsertSimSequence(orderProcessCounter,num1,finalSequence,sfSequence,allOperations);
}
}
......@@ -195,7 +230,7 @@ if(finishedOrder==null||finishedOrder.size()==0)
chromosome.setOperationSequencing(finalSequence);
}
private void InsertSimSequence(Map<Integer, Integer> orderProcessCounter,int orderid,List<Integer> finalSequence,Map<Integer, List<Integer>> sfSequence)
private void InsertSimSequence(Map<Integer, Integer> orderProcessCounter,int orderid,List<Integer> finalSequence,Map<Integer, List<Integer>> sfSequence,List<Entry> allOperations)
{
Random rnd = new Random();
int scheduledCount=1;
......@@ -204,7 +239,7 @@ if(finishedOrder==null||finishedOrder.size()==0)
scheduledCount = orderProcessCounter.get(orderid)+1;
}
int scheduledCount1=scheduledCount;
Entry entry=_allOperations.stream()
Entry entry=allOperations.stream()
.filter(t->t.GroupId==orderid&&t.getSequence()==scheduledCount1)
.findFirst().orElse(null);
......@@ -213,7 +248,7 @@ if(finishedOrder==null||finishedOrder.size()==0)
for (int order : entry.getDependentOnOrderIds()) {
for (int num1 : sfSequence.get(order)) {
InsertSimSequence(orderProcessCounter,num1,finalSequence,sfSequence);
InsertSimSequence(orderProcessCounter,num1,finalSequence,sfSequence,allOperations);
}
}
finalSequence.add(orderid);
......@@ -229,6 +264,15 @@ if(finishedOrder==null||finishedOrder.size()==0)
*/
public void decode(Chromosome chromosome) {
List<OrderMaterialRequirement> orderMaterials = materialRequirementService.buildMultiLevelRequirementNetwork(chromosome, sceneId, baseTime,_globalParam);
if(orderMaterials!=null&&orderMaterials.size()>0&&_globalParam.isIsCheckSf()) {
generateGlobalOpList(chromosome);
CreateNewOpSequence(chromosome);
}
List<GlobalOperationInfo> globalOpList=chromosome.getGlobalOpList();
List<Entry> allOperations=chromosome.getAllOperations();
_allOperations=chromosome.getAllOperations();
......@@ -343,6 +387,8 @@ if(finishedOrder==null||finishedOrder.size()==0)
// String lastDiscreteParameter = machineState.get(machineId);
int bomtime = getOperationBOMTime(currentOp,chromosome);
FileHelper.writeLogFile("工序:"+currentOp.getId() +"bomtime1:"+bomtime);
int prevendtime=prevtime;
prevtime = Math.max(prevtime, bomtime);
Machine machine = chromosome.getMachines().stream()
......@@ -353,12 +399,15 @@ if(finishedOrder==null||finishedOrder.size()==0)
// int changeoverTime =0; //(lastDiscreteParameter.isEmpty() ||
// lastDiscreteParameter.equals(currentOp.getDiscreteParameter())) ? 0 : 0;
int actualEndTime = processWithSingleMachine(currentOp, machine, processTime, prevtime,machineOption, chromosome);
int actualEndTime = processWithSingleMachine(currentOp, machine, processTime, prevtime,machineOption, chromosome,false,prevendtime);
orderProcessCounter.put(groupId, orderProcessCounter.get(groupId) + 1);
orderLastEndTime.put(groupId, actualEndTime);
// machineState.put(machineId, currentOp.getDiscreteParameter());
}
if(chromosome.getReOrderids()!=null&&chromosome.getReOrderids().size()>0) {
chromosome.getOperationSequencing().removeIf(t -> chromosome.getReOrderids().contains(t));
}
// 步骤4:计算调度指标
calculateScheduleResult(chromosome);
......@@ -368,7 +417,7 @@ if(finishedOrder==null||finishedOrder.size()==0)
private int processWithSingleMachine(Entry operation, Machine machine, double processingTime,
int prevOperationEndTime,OpMachine machineOption, Chromosome chromosome) {
int prevOperationEndTime,OpMachine machineOption, Chromosome chromosome,boolean calbom,int prevendtime) {
int processingTimeTotal=0;
int earliestStartTime = prevOperationEndTime;
if(operation.getConstTime()==1)//常数时间
......@@ -415,6 +464,7 @@ if(finishedOrder==null||finishedOrder.size()==0)
{
earliestStartTime = Math.max(earliestStartTime,existingResult.getDesignatedStartTime());
}
int setupTime=0;
CopyOnWriteArrayList<GAScheduleResult> machineTasks =chromosome.getResult().stream()
.filter(t -> t.getMachineId() == machine.getId())
......@@ -422,6 +472,30 @@ if(finishedOrder==null||finishedOrder.size()==0)
.collect(Collectors.toCollection(CopyOnWriteArrayList::new));
// _globalParam.set_smoothChangeOver(false);
CopyOnWriteArrayList<ScheduleResultDetail> geneDetails=new CopyOnWriteArrayList<>();
int bomtime=0;
if((operation.getMaterialRequirements()!=null&&operation.getTargetFinishedOperationId()==null)||calbom) {
int earliestStartTimeold=earliestStartTime;
if (_globalParam.is_smoothChangeOver()) {
Map<Integer, Object> reslte = calculateSetupTime(machineTasks, operation, machine, earliestStartTime, processingTimeTotal, _globalParam.is_smoothChangeOverInWeek(), "", null);
// setupTime = (int) reslte.get(1);//换型时间
// int setupStartTime = (int) reslte.get(2);//换型开始时间
//earliestStartTime=(int)reslte.get(3);//上个任务的结束时间
earliestStartTime = (int) reslte.get(4);//最早开工时间
}
bomtime= EditOperationBOMTime(operation,chromosome,earliestStartTime);
FileHelper.writeLogFile("工序:"+operation.getId() +"bomtime2:"+bomtime);
if(bomtime>prevendtime&&bomtime<earliestStartTimeold)
{
earliestStartTime=bomtime;
}
}
if (_globalParam.is_smoothChangeOver()) {
//是否考虑换型时间
Map<Integer,Object> reslte = calculateSetupTime(machineTasks, operation, machine,earliestStartTime,processingTimeTotal, _globalParam.is_smoothChangeOverInWeek(),"",null);
......@@ -493,9 +567,12 @@ if(finishedOrder==null||finishedOrder.size()==0)
// 准备工时 加入到加工时间里
// 后处理时间 相同任务的前一工序的结束时间+后处理时间 =当前工序最早开工时间
GAScheduleResult result=new GAScheduleResult();
GAScheduleResult result=new GAScheduleResult();
result.setGroupId(operation.getGroupId());
result.setOperationId(operation.getId());
result.setExecId(operation.getExecId());
......@@ -504,6 +581,7 @@ if(finishedOrder==null||finishedOrder.size()==0)
result.setProductId(operation.getProductId());
result.setProductName(operation.getProductName());
result.setProductCode(operation.getProductCode());
result.setTargetFinishedOperationId(operation.getTargetFinishedOperationId());
result.setMachineId(machine.getId());
result.setStartTime(startTime);
result.setEndTime(endTime);
......@@ -512,6 +590,7 @@ if(finishedOrder==null||finishedOrder.size()==0)
result.setChangeOverTime(setupTime);
result.setPreTime(preTime);
result.setTeardownTime(teardownTime);
result.setBomTime(bomtime);
if(existingResult!=null) {
if(existingResult.getLockStartTime()==1) {
result.setLockStartTime(existingResult.getLockStartTime());
......@@ -541,7 +620,9 @@ if(finishedOrder==null||finishedOrder.size()==0)
result.setGeneDetails(geneDetails);
// System.out.println("huanxingshijian="+result.getChangeOverTime()+"-------------------"+result.getOrderId()+"--------"+result.getExecId()+"---------"+prev.getOrderId()+"--------"+prev.getExecId());
chromosome.getResult().add(result);
chromosome.getResult().add(result);
// FileHelper.writeLogFile(" 结束 "+ConvertTime(startTime)+"--"+ConvertTime(endTime)+" "+operation.getGroupId()+" : "+operation.getId()+",处理时间: " + processingTime + ", 后处理: " + teardownTime +
// ", 前处理: " + preTime + ", 换型: " + setupTime+ ", 数量: " + operation.getQuantity()+ ", 设备: "+machine.getId()+ ", 是否可中断: "+operation.getIsInterrupt());
......@@ -619,14 +700,13 @@ if(finishedOrder==null||finishedOrder.size()==0)
private int getOperationBOMTime(Entry currentOp, Chromosome chromosome) {
if(orderMaterials==null)
List<OrderMaterialRequirement> opboms= currentOp.getMaterialRequirements();
if(opboms==null)
{
return 0;
}
List<OrderMaterialRequirement> opboms = orderMaterials.stream()
.filter(t -> t.getOrderId().equals(currentOp.getOrderId()) && t.getOperationId() == currentOp.getId())
.collect(Collectors.toList());
int rawTime = 0, sfTime = 0;
if (opboms != null && !opboms.isEmpty()) {
// 计算RawTime
......@@ -638,6 +718,7 @@ if(finishedOrder==null||finishedOrder.size()==0)
if (rawDateOpt.isPresent()) {
rawTime = (int) Duration.between(baseTime, rawDateOpt.get()).getSeconds();
}
}
// 计算SFTime
......@@ -648,6 +729,7 @@ if(finishedOrder==null||finishedOrder.size()==0)
if (!sfBoms.isEmpty()&&sfBoms.size()>0) {
for (OrderMaterialRequirement sf : sfBoms) {
for (int orderid : sf.getProductOrderID()) {
int sfTime1 = 0;
List<GAScheduleResult> result=chromosome.getResult();
......@@ -669,10 +751,183 @@ if(finishedOrder==null||finishedOrder.size()==0)
}
}
}
Optional<LocalDateTime> sfDateOpt = opboms.stream()
.filter(t -> !t.getMaterialTypeName().equals("MP")&&(t.getProductOrderID() == null || t.getProductOrderID().isEmpty()))
.map(OrderMaterialRequirement::getUseTime)
.max(LocalDateTime::compareTo);
if (sfDateOpt.isPresent()) {
sfTime =Math.max(sfTime, (int) Duration.between(baseTime, sfDateOpt.get()).getSeconds());
}
}
return Math.max(rawTime, sfTime);
}
private int EditOperationBOMTime(Entry currentOp, Chromosome chromosome,int earliestStartTime) {
List<OrderMaterialRequirement> opboms= currentOp.getMaterialRequirements();
if(opboms==null)
{
return 0;
}
LocalDateTime earliestStartTime1=baseTime.plusSeconds(earliestStartTime);
materialRequirementService.EditOperationBOM(currentOp,chromosome,earliestStartTime1,this);
return getOperationBOMTime(currentOp, chromosome);
}
public void EditorderOperation(Chromosome chromosome, int groupId,double needed){
List<Entry> orderOps = chromosome.getAllOperations().stream()
.filter(t -> t.getGroupId() == groupId)
.sorted(Comparator.comparing(Entry::getSequence))
.collect(Collectors.toList());
for (Entry currentOp : orderOps) {
if(currentOp.isNewCreate()) {
currentOp.setQuantity(needed);
}
GAScheduleResult existingResult = chromosome.getResult().stream()
.filter(r-> r.getOperationId() == currentOp.getId())
.findFirst().orElse(null);
Long machineId = existingResult.getMachineId();
MachineOption machineOption= currentOp.getMachineOptions().stream()
.filter(t->t.getMachineId().equals(machineId)).findFirst().orElse(null);
double processTime = machineOption.getProcessingTime();
OpMachine opMachine=new OpMachine();
opMachine.setGroupId(groupId);
opMachine.setSequence(currentOp.getSequence());
opMachine.setMachineId(machineId);
opMachine.setProcessingTime(machineOption.getProcessingTime());
opMachine.setRuntime(machineOption.getRuntime());
opMachine.setSingleOut(machineOption.getSingleOut());
Machine targetMachine = chromosome.getMachines().stream()
.filter(m -> m.getId() == machineId)
.findFirst()
.orElse(null);
int prevtime = 0;
//后处理时间
int teardownTime = currentOp.getTeardownTime();
if (!currentOp.getPrevEntryIds().isEmpty()) {
// 处理多个前工序
prevtime= CalPrevtime( prevtime, currentOp, chromosome, processTime, targetMachine);
}
// 上个离散参数
// String lastDiscreteParameter = machineState.get(machineId);
int bomtime = getOperationBOMTime(currentOp,chromosome);
int prevendtime=prevtime;
prevtime = Math.max(prevtime, bomtime);
Machine machine = chromosome.getMachines().stream()
.filter(m -> m.getId() == machineId)
.findFirst()
.orElse(null);
AddMachineAvailable(machine,existingResult.getGeneDetails());
chromosome.getResult().remove(existingResult);
int actualEndTime = processWithSingleMachine(currentOp, machine, processTime, prevtime,opMachine, chromosome,true,prevendtime);
}
}
public void DelOrder(Chromosome chromosome, int groupid,OrderMaterialRequirement orderMaterialRequirement) {
List<Entry> allOperations = chromosome.getAllOperations();
List<GlobalOperationInfo> globalOpList= chromosome.getGlobalOpList();
List<Order> orders = chromosome.getOrders();
List<GAScheduleResult> ScheduleResults = chromosome.getResult();
Order sourceorder=orders.stream()
.filter(o -> o.getId()==groupid )
.findFirst()
.orElseThrow(() -> new NoSuchElementException("Order not found: " + groupid));
List<Entry> sourceOps = allOperations.stream()
.filter(o -> o.getGroupId()==groupid )
.sorted(Comparator.comparing(Entry::getSequence))
.collect(Collectors.toList());
int GroupId=0;
chromosome.getReOrderids().add(groupid);
for (Entry entry : sourceOps) {
if(!entry.isNewCreate())
{
//原有订单不删除
//entry.setDependentOnOrderIds(new ArrayList<>());
entry.getTargetFinishedOperationId().remove(orderMaterialRequirement.getOperationId());
continue;
}
List<OrderMaterialRequirement> orderMaterialRequirements= entry.getMaterialRequirements().stream().filter(t-> !"MP".equals(t.getMaterialTypeName())
&& t.getProductOrderID() != null && !t.getProductOrderID().isEmpty()
).collect(Collectors.toList());
for (OrderMaterialRequirement mr:orderMaterialRequirements) {
List<Integer> orderids= mr.getProductOrderID();
if(orderids!=null&&orderids.size()>0) {
for (Integer orderid : orderids) {
DelOrder(chromosome, orderid,mr);
}
}
}
OptionalInt index = IntStream.range(0, allOperations.size())
.filter(h -> entry.getId()==allOperations.get(h).getId())
.findFirst();
allOperations.remove((int)index.orElse(0));
OptionalInt index1 = IntStream.range(0, globalOpList.size())
.filter(h -> entry.getId()==globalOpList.get(h).getOp().getId())
.findFirst();
globalOpList.remove((int)index1.orElse(0));
chromosome.getMachineSelection().remove((int)index1.orElse(0));
GAScheduleResult result =ScheduleResults.stream()
.filter(t -> t.getOperationId()==entry.getId()) // 过滤出值为1的索引
.findFirst().orElse(null);
Long machineId = result.getMachineId();
Machine machine = chromosome.getMachines().stream()
.filter(m -> m.getId() == machineId)
.findFirst()
.orElse(null);
AddMachineAvailable(machine,result.getGeneDetails());
ScheduleResults.remove(result);
}
AtomicInteger globalOpId = new AtomicInteger(0);
globalOpList.forEach(t-> {
t.setGlobalOpId(globalOpId.getAndIncrement());
});
// chromosome.getOperatRel().remove(GroupId-1);
orders.remove(sourceorder);
}
/**
* 计算在上一工序生产后什么时间可以开工
* @param details 工序详情列表
......@@ -989,6 +1244,34 @@ if(finishedOrder==null||finishedOrder.size()==0)
return reslte;
}
public void AddMachineAvailable(Machine machine, List<ScheduleResultDetail> geneDetails) {
if (geneDetails == null || geneDetails.isEmpty()) return;
List<String> keys= geneDetails.stream().
filter(t->t.getUsedSegment()==null||t.getUsedSegment().size()==0)
.map(ScheduleResultDetail::getKey)
.collect(Collectors.toList());
List<String> keys1= geneDetails.stream().
filter(t->t.getUsedSegment()!=null)
.flatMap(detail -> detail.getUsedSegment().stream())
.map(TimeSegment::getKey).collect(Collectors.toList());
if(keys1!=null&&keys1.size()>0) {
keys.addAll(keys1);
}
List<TimeSegment> toUpdate = machine.getAvailability().stream()
.filter(t -> keys.contains(t.getKey()))
.collect(Collectors.toList());
// 然后批量修改
toUpdate.forEach(t -> t.setUsed(false));
}
private void calculateScheduleResult(Chromosome chromosome) {
// 1. 最早完工时间(最小化)
......@@ -1014,11 +1297,12 @@ if(finishedOrder==null||finishedOrder.size()==0)
.distinct()
.sorted()
.collect(Collectors.toList());
Order order = orders.stream()
Order order = chromosome.getOrders().stream()
.filter(t->orderIds.contains(t.getOrderId()))
.max(Comparator.comparing(Order::getDueDate))
.orElse(null);
if(order.isNewCreate())
{continue;}
LocalDateTime dueDateTime=order.getDueDate();
......
......@@ -5,8 +5,10 @@ import com.aps.entity.Algorithm.*;
import com.aps.entity.basic.Entry;
import com.aps.entity.basic.GlobalParam;
import com.aps.entity.basic.MachineOption;
import com.aps.entity.basic.Order;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
......@@ -132,7 +134,11 @@ public class GeneticOperations {
// 重载,使用默认锦标赛大小3
public List<Chromosome> tournamentSelection(List<Chromosome> population) {
return tournamentSelection(population, param.getTournamentSize());
List<Chromosome> populationn= ProductionDeepCopyUtil.deepCopyList(tournamentSelection(population, param.getTournamentSize()),Chromosome.class);
populationn.parallelStream().forEach(t->DelOrder(t));
return populationn;
}
/**
......@@ -414,6 +420,49 @@ public class GeneticOperations {
return indexWeights.get(CommonCalculator.getOsIndex(indexWeights));
}
public void DelOrder(Chromosome chromosome) {
List<Entry> allOperations = chromosome.getAllOperations();
List<GlobalOperationInfo> globalOpList= chromosome.getGlobalOpList();
List<Order> orders = chromosome.getOrders();
List<Integer> OperationSequencing= chromosome.getOperationSequencing();
List<GAScheduleResult> ScheduleResults = chromosome.getResult();
List<Integer> newoorderids= orders.stream()
.filter(t->t.isNewCreate())
.map(Order::getId)
.sorted(Comparator.reverseOrder())
.collect(Collectors.toList());
if(newoorderids!=null&&newoorderids.size()>0) {
for (Integer id : newoorderids) {
List<Entry> sourceOps = allOperations.stream()
.filter(o -> o.getGroupId()==id)
.sorted(Comparator.comparing(Entry::getSequence))
.collect(Collectors.toList());
for (Entry entry : sourceOps) {
OptionalInt index1 = IntStream.range(0, globalOpList.size())
.filter(h -> entry.getId()==globalOpList.get(h).getOp().getId())
.findFirst();
globalOpList.remove((int)index1.orElse(0));
chromosome.getMachineSelection().remove((int)index1.orElse(0));
}
chromosome.getOperatRel().remove(id-1);
}
allOperations.removeIf(t ->newoorderids.contains(t.getGroupId()));
OperationSequencing.removeIf(t ->newoorderids.contains(t));
AtomicInteger globalOpId = new AtomicInteger(0);
globalOpList.forEach(t-> {
t.setGlobalOpId(globalOpId.getAndIncrement());
});
orders.removeIf(t ->newoorderids.contains(t.getId()));
}
}
}
......@@ -8,6 +8,7 @@ import com.aps.entity.Algorithm.ScheduleParams;
import com.aps.entity.basic.*;
import java.util.*;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
......@@ -25,6 +26,10 @@ public class Initialization {
private ObjectiveWeights _objectiveWeights = new ObjectiveWeights();
public Initialization() {
}
public Initialization(GlobalParam globalParam,List<Entry> allOperations,List<Order> _orders,List<Machine> _machines,ObjectiveWeights objectiveWeights) {
Initialization.allOperations = allOperations;
_globalParam= globalParam;
......@@ -66,14 +71,17 @@ int populationSize=param.getPopulationSize();
Chromosome chromo = new Chromosome(); // 初始化染色体
// chromo.setObjectiveWeights(_objectiveWeights);
// chromo.setInitMachines(ProductionDeepCopyUtil.deepCopyList(machines));
chromo.setOrders(orders);
chromo.setOrders(new CopyOnWriteArrayList<>(orders));
// 全局选择(GS):按GlobalOpId顺序生成MachineSelection
if (i < gsCount) {
chromo.setGsOrls(1);
generateGSChromosome(chromo,globalOpList); // 对应 C# GenerateGSChromosome
} else if (i < lsCount) {
chromo.setGsOrls(2);
// 局部选择(LS):按GlobalOpId顺序生成MachineSelection(仅负载计算范围不同)
generateLSChromosome(chromo,globalOpList);
} else {
chromo.setGsOrls(3);
// 随机选择(RS):按GlobalOpId顺序生成MachineSelection(仅机器选择随机)
generateRSChromosome(chromo,globalOpList);
}
......@@ -87,6 +95,31 @@ chromo.setOrders(orders);
return population;
}
public List<Chromosome> generateInitialSFPopulation(Chromosome chromo, List<GlobalOperationInfo> globalOpList) {
List<Chromosome> population = new ArrayList<>();
// 并行循环:对应 Parallel.For(0, PopulationSize, i => { ... })
if (chromo.getGsOrls()==1) {
generateGSChromosome(chromo,globalOpList); // 对应 C# GenerateGSChromosome
} else if (chromo.getGsOrls()==2) {
// 局部选择(LS):按GlobalOpId顺序生成MachineSelection(仅负载计算范围不同)
generateLSChromosome(chromo,globalOpList);
} else {
// 随机选择(RS):按GlobalOpId顺序生成MachineSelection(仅机器选择随机)
generateRSChromosome(chromo,globalOpList);
}
return population;
}
/**
* 全局选择(GS)生成染色体(按GlobalOpId顺序生成MachineSelection)
*/
......@@ -145,9 +178,17 @@ chromo.setOrders(orders);
osp.clear();
}
// 步骤2:打乱工序排序部分(OS)
chromosome.setOperationSequencing(shuffleWithPriority(os));
chromosome.setMachineSelection(ms);
if(chromosome.getOperationSequencing()!=null&&chromosome.getOperationSequencing().size()>0)
{
chromosome.getOperationSequencing().addAll(os);
chromosome.getMachineSelection().addAll(ms);
}else {
// 步骤2:打乱工序排序部分(OS)
chromosome.setOperationSequencing(shuffleWithPriority(os));
chromosome.setMachineSelection(ms);
}
return chromosome;
}
......@@ -215,9 +256,15 @@ chromo.setOrders(orders);
os.addAll(osp);
osp.clear();
}
chromosome.setOperationSequencing(shuffleWithPriority(os));
chromosome.setMachineSelection(ms);
if(chromosome.getOperationSequencing()!=null&&chromosome.getOperationSequencing().size()>0)
{
chromosome.getOperationSequencing().addAll(os);
chromosome.getMachineSelection().addAll(ms);
}else {
chromosome.setOperationSequencing(shuffleWithPriority(os));
chromosome.setMachineSelection(ms);
}
return chromosome;
}
......@@ -259,9 +306,15 @@ chromo.setOrders(orders);
os.addAll(osp);
osp.clear();
}
chromosome.setOperationSequencing(shuffleWithPriority(os));
chromosome.setMachineSelection(ms);
if(chromosome.getOperationSequencing()!=null&&chromosome.getOperationSequencing().size()>0)
{
chromosome.getOperationSequencing().addAll(os);
chromosome.getMachineSelection().addAll(ms);
}else {
chromosome.setOperationSequencing(shuffleWithPriority(os));
chromosome.setMachineSelection(ms);
}
return chromosome;
}
......
......@@ -4,10 +4,8 @@ import com.aps.common.util.GlobalCacheUtil;
import com.aps.common.util.SnowFlackIdWorker;
import com.aps.common.util.redis.RedisUtils;
import com.aps.entity.*;
import com.aps.entity.Algorithm.BOMBuildResult;
import com.aps.entity.Algorithm.*;
import com.aps.entity.Algorithm.IDAndChildID.GroupResult;
import com.aps.entity.Algorithm.OrderMaterial;
import com.aps.entity.Algorithm.OrderMaterialRequirement;
import com.aps.entity.basic.*;
import com.aps.mapper.RoutingHeaderMapper;
import com.aps.mapper.RoutingSupportingReplaceMapper;
......@@ -25,7 +23,11 @@ import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
/**
* 作者:佟礼
......@@ -36,22 +38,6 @@ public class MaterialRequirementService {
private List<Material> _materials;
private List<Entry> _allOperations;
private List<Machine> _Machines;
private List<GroupResult> _entryRel;
private List<RoutingHeader> headers;
private List<Routingsupporting> routingsupportings=new ArrayList<>();
private List<RoutingSupportingReplace> routingsupportingreplaces=new ArrayList<>();
List<RoutingDetail> allRoutingDetails=new ArrayList<>();
List<RoutingDetailEquip> allroutingDetailEquips=new ArrayList<>();
List<RoutingDetailConnect> allroutingDetailconnections=new ArrayList<>();
List<RoutingDiscreteParam> allroutingDiscreteParams=new ArrayList<>();
@Autowired
RoutingDetailConnectService routingDetailConnectService;
......@@ -59,7 +45,6 @@ public class MaterialRequirementService {
@Autowired
private RedisUtils redisUtils;
private List<Order> orders;
@Autowired
RoutingHeaderMapper routingHeaderMapper;
......@@ -81,70 +66,72 @@ public class MaterialRequirementService {
private LanuchService lanuchService;
private LocalDateTime baseTime ;
private MachineSchedulerService machineScheduler;
private GlobalParam globalParam;
public void init(List<Material> materials,List<Order> _orders,List<Entry> allOperations,List<GroupResult> entryRel,MachineSchedulerService _machineScheduler,List<Machine> machines,GlobalParam _GlobalParam)
{
orders = _orders;
_allOperations=allOperations;
_materials=materials;
_entryRel=entryRel;
machineScheduler=_machineScheduler;
_Machines=machines;
globalParam=_GlobalParam;
}
private Map<String, List<RoutingHeader>> routingHeaderCache = new HashMap<>();
private Map<String, List<Routingsupporting>> routingsupportingCache = new HashMap<>();
private Map<String, List<RoutingSupportingReplace>> routingSupportingReplaceCache = new HashMap<>();
private Map<String, List<RoutingDetail>> allRoutingDetailsCache=new HashMap<>();
private Map<String, List<RoutingDetailEquip>> allroutingDetailEquipsCache=new HashMap<>();
private Map<String,List<RoutingDetailConnect>> allroutingDetailconnectionsCache=new HashMap<>();
private Map<String, List<RoutingDiscreteParam>> allroutingDiscreteParamsCache=new HashMap<>();
private static final int cachetimeout = 60;
private String cacheKey="_MR_";
private String routingHeaderCacheKey=cacheKey+ "RoutingHeader";
private String routingsupportingCacheKey=cacheKey+ "Routingsupporting";
private String routingSupportingReplaceCacheKey=cacheKey+ "RoutingSupportingReplace";
private String routingDetailCacheKey=cacheKey+ "RoutingDetail";
private String routingDetailEquipCacheKey=cacheKey+ "RoutingDetailEquip";
private String routingDetailConnectCacheKey=cacheKey+ "RoutingDetailConnect";
private String routingDiscreteParamCacheKey=cacheKey+ "RoutingDiscreteParam";
private String materialsCacheKey=cacheKey+ "material";
public List<Long> preloadRoutingCache(String sceneId,List<Order> _orders,List<Material> materials,boolean isIsCheckSf) {
public Map<Integer,Object> preloadRoutingCache(String sceneId,LocalDateTime baseTime, List<Order> _orders,List<Material> materials,List<Entry> _allOperations,boolean isIsCheckSf) {
this.baseTime=baseTime;
Map<Integer,Object> reslte=new HashMap<>(2);
reslte.put(1,null);
reslte.put(2,null);
this._materials=materials;
List<Integer> routingIds= _orders.stream()
.filter(t->t.getRoutingId()!=null)
.map(Order::getRoutingId)
.distinct()
.collect(Collectors.toList());
List<RoutingHeader> routingHeaders=null;
if (!routingHeaderCache.containsKey(sceneId)) {
LambdaQueryWrapper<RoutingHeader> wrapper = new LambdaQueryWrapper<>();
wrapper.in(RoutingHeader::getId, routingIds);
// .eq(RoutingHeader::getIsDeleted, 0)
// .eq(RoutingHeader::getApprovalStatus, 1);
List<RoutingHeader> routingHeaders = routingHeaderMapper.selectList(wrapper);
routingHeaderCache.put(sceneId, routingHeaders);
}
routingHeaders = routingHeaderMapper.selectList(wrapper);
List<Routingsupporting> routingsupportings=null;
// 查询并缓存Routingsupporting
if (!routingsupportingCache.containsKey(sceneId)) {
LambdaQueryWrapper<Routingsupporting> routingsupportingwrapper = new LambdaQueryWrapper<>();
routingsupportingwrapper.in(Routingsupporting::getRoutingHeaderId, routingIds)
.eq(Routingsupporting::getIsdeleted, 0);
routingsupportings = routingsupportingMapper.selectList(routingsupportingwrapper);
routingsupportingCache.put(sceneId, routingsupportings);
}
// 查询并缓存RoutingSupportingReplace
List<Routingsupporting> cachedSupportings = routingsupportingCache.get(sceneId);
if (cachedSupportings != null && !cachedSupportings.isEmpty()) {
List<String> routingsupportingids = cachedSupportings.stream()
List<RoutingSupportingReplace> replaces=null;
if (routingsupportings != null && !routingsupportings.isEmpty()) {
List<String> routingsupportingids = routingsupportings.stream()
.map(Routingsupporting::getStrId)
.distinct()
.collect(Collectors.toList());
if (!routingSupportingReplaceCache.containsKey(sceneId)) {
LambdaQueryWrapper<RoutingSupportingReplace> routingsupportingreplacewrapper = new LambdaQueryWrapper<>();
routingsupportingreplacewrapper.in(RoutingSupportingReplace::getStrsupid, routingsupportingids)
.eq(RoutingSupportingReplace::getIsdeleted, 0);
List<RoutingSupportingReplace> replaces = routingSupportingReplaceMapper.selectList(routingsupportingreplacewrapper);
routingSupportingReplaceCache.put(sceneId, replaces);
}
replaces = routingSupportingReplaceMapper.selectList(routingsupportingreplacewrapper);
}
List<Material> useMaterials=new ArrayList<>();
Set<String> useMaterialids=new HashSet<>();
if(routingsupportings!=null&&routingsupportings.size()>0)
{
List<String> materialIds=new ArrayList<>();
......@@ -153,46 +140,106 @@ public class MaterialRequirementService {
List<Routingsupporting> MaterialRequirements = routingsupportings.stream()
.filter(t -> t.getRoutingHeaderId().equals(routingid))
.collect(Collectors.toList());
String orderId= order.getOrderId();
if(MaterialRequirements!=null)
{
List<OrderMaterialRequirement> materialRequirementList=new ArrayList<>();
for (Routingsupporting component : MaterialRequirements) {
// 查找物料(流式处理替代First)
String materialId= component.getMaterialId();
Material material = materials.stream()
.filter(m -> m.getId().equals(materialId))
List<Entry> Operations= _allOperations.stream()
.filter(t->t.getOrderId().equals(orderId))
.collect(Collectors.toList());
for (Entry operation : Operations) {
List<Routingsupporting> MaterialRequirement_entrys = routingsupportings.stream()
.filter(t -> t.getRoutingDetailId().equals(operation.getRoutingDetailId()))
.collect(Collectors.toList());
List<OrderMaterialRequirement> materialRequirementList=new ArrayList<>();
if(MaterialRequirement_entrys!=null) {
for (Routingsupporting component : MaterialRequirement_entrys) {
// 查找物料(流式处理替代First)
String materialId = component.getMaterialId();
Material material = materials.stream()
.filter(m -> m.getId().equals(materialId))
.findFirst()
.orElse(null);
if (material != null) {
if (!useMaterialids.contains(materialId)) {
useMaterials.add(material);
useMaterialids.add(materialId);
}
double allneeded = component.getSpentQty().doubleValue()/ component.getMainQty().doubleValue() * operation.Quantity;
OrderMaterialRequirement orderMaterialRequirement = CreateMaterialRequirement(material, orderId, "", operation,
allneeded,component.getSpentQty().doubleValue(), component.getMainQty().doubleValue(),operation.Quantity);
orderMaterialRequirement.setBomId(component.getStrId());
if (!material.getMaterialTypeName().equals("MP") && isIsCheckSf) {
materialIds.add(materialId);
}
materialRequirementList.add(orderMaterialRequirement);
}
}
}
operation.setMaterialRequirements(materialRequirementList);
}
}
}
if(replaces!=null&&replaces.size()>0) {
for (RoutingSupportingReplace routingSupportingReplace : replaces) {
String materialID1 = routingSupportingReplace.getMaterialid();
if (!useMaterialids.contains(materialID1)) {
Material material = _materials.stream()
.filter(m -> m.getId().equals(materialID1))
.findFirst()
.orElse(null);
if (material != null) {
OrderMaterialRequirement orderMaterial = new OrderMaterialRequirement();
orderMaterial.setRoutingDetailId(component.getRoutingDetailId());
orderMaterial.setMaterialCode(material.getCode());
orderMaterial.setMaterialName(material.getName());
orderMaterial.setMaterialTypeName(material.getMaterialTypeName());
orderMaterial.setMaterialId(material.getId());
materialRequirementList.add(orderMaterial);
if(!material.getMaterialTypeName().equals("MP")&&isIsCheckSf)
{
materialIds.add(materialId);
}
useMaterials.add(material);
useMaterialids.add(materialID1);
}
order.setMaterialRequirementList(materialRequirementList);
}
}
}
if(materialIds!=null&&materialIds.size()>0)
{
List<Long> routingIds1= preloadSfRoutingBomCache(materialIds, headers, routingsupportings, routingsupportingreplaces);
return preloadSfRoutingCache(sceneId,routingIds1);
Map<Integer,Object> reslte1=preloadSfRoutingBomCache(materialIds, routingHeaders, routingsupportings, replaces);
List<Long> routingIds1=(List<Long>) reslte1.get(1);
if(routingIds1!=null)
{
List<Long> equipids= preloadSfRoutingCache(sceneId,routingIds1);
reslte.put(1,equipids);
}
List<Material> useMaterials1=(List<Material>) reslte1.get(2);
if(useMaterials1!=null) {
for (Material m:useMaterials1) {
String materialID1= m.getId();
if(!useMaterialids.contains(materialID1)) {
useMaterials.add(m);
useMaterialids.add(materialID1);
}
}
}
reslte.put(2,useMaterials);
}
return null;
}
return null;
SaveBomCache(sceneId, routingHeaders, routingsupportings, replaces,useMaterials);
return reslte;
}
private List<Long> preloadSfRoutingBomCache(List<String> materialIDs,List<RoutingHeader> headers,List<Routingsupporting> routingsupportings,List<RoutingSupportingReplace> routingsupportingreplaces) {
private Map<Integer,Object> preloadSfRoutingBomCache(List<String> materialIDs,List<RoutingHeader> headers,List<Routingsupporting> routingsupportings,List<RoutingSupportingReplace> routingsupportingreplaces) {
Map<Integer,Object> reslte=new HashMap<>(2);
reslte.put(1,null);
reslte.put(2,null);
List<Material> useMaterials=new ArrayList<>();
Set<String> useMaterialids=new HashSet<>();
List<Long> routingIds=new ArrayList<>();
List<Long> routingIds1=new ArrayList<>();
Long routingId = 0l;
......@@ -251,21 +298,54 @@ public class MaterialRequirementService {
.filter(m -> m.getId().equals(materialID1))
.findFirst()
.orElse(null);
if (material != null&&!material.getMaterialTypeName().equals("MP")) {
materialIds.add(materialID1);
if (material != null) {
if(!useMaterialids.contains(materialID1)) {
useMaterials.add(material);
useMaterialids.add(materialID1);
}
if(!material.getMaterialTypeName().equals("MP")) {
materialIds.add(materialID1);
}
}
}
for (RoutingSupportingReplace routingSupportingReplace:routingsupportingreplaces1) {
String materialID1= routingSupportingReplace.getMaterialid();
if(!useMaterialids.contains(materialID1)) {
Material material = _materials.stream()
.filter(m -> m.getId().equals(materialID1))
.findFirst()
.orElse(null);
if (material != null) {
useMaterials.add(material);
useMaterialids.add(materialID1);
}
}
}
List<Long> routingIds2= preloadSfRoutingBomCache(materialIds, headers, routingsupportings, routingsupportingreplaces);
Map<Integer,Object> r1=preloadSfRoutingBomCache(materialIds, headers, routingsupportings, routingsupportingreplaces);
List<Long> routingIds2=(List<Long>) r1.get(1);
List<Material> useMaterials2=( List<Material>) r1.get(2);
if(routingIds2!=null)
{
routingIds.addAll(routingIds2);
}
if(useMaterials2!=null&&useMaterials2.size()>0) {
for (Material m:useMaterials2) {
String materialID1= m.getId();
if(!useMaterialids.contains(materialID1)) {
useMaterials.add(m);
useMaterialids.add(materialID1);
}
}
}
}
if(routingIds1!=null)
{
routingIds.addAll(routingIds1);
}
return routingIds;
reslte.put(1,routingIds);
reslte.put(2,useMaterials);
return reslte;
}
......@@ -275,35 +355,37 @@ public class MaterialRequirementService {
List<RoutingDetail> RoutingDetails = null;
List<RoutingDetailEquip> routingDetailEquips = null;
List<RoutingDetailConnect> connections = null;
if (routingIds == null || routingIds.size() == 0) {
List<RoutingDiscreteParam> routingDiscreteParams=null;
if (routingIds != null || routingIds.size() > 0) {
RoutingDetails = lanuchService.getRoutingDetails(routingIds);
if (RoutingDetails == null && RoutingDetails.size() == 0) {
return null;
}
allRoutingDetailsCache.put(sceneId, RoutingDetails);
routingDetailEquips = lanuchService.getRoutingDetailEquip(routingIds);
allroutingDetailEquipsCache.put(sceneId, routingDetailEquips);
LambdaQueryWrapper<RoutingDetailConnect> routingDetailConnectwrapper = new LambdaQueryWrapper<>();
routingDetailConnectwrapper.in(RoutingDetailConnect::getRoutingHeaderId, routingIds)
.eq(RoutingDetailConnect::getIsdeleted, 0); // 添加 isdeleted=0 过滤条件
connections = routingDetailConnectService.list(routingDetailConnectwrapper);
allroutingDetailconnectionsCache.put(sceneId, connections);
List<Long> routingDetailIds = RoutingDetails.stream()
.map(RoutingDetail::getId)
.distinct()
.collect(Collectors.toList());
List<RoutingDiscreteParam> routingDiscreteParams = _routingDiscreteParamService.lambdaQuery()
routingDiscreteParams = _routingDiscreteParamService.lambdaQuery()
.in(RoutingDiscreteParam::getRoutingDetailId, routingDetailIds)
.eq(RoutingDiscreteParam::getIsDeleted, 0)
.list();
allroutingDiscreteParamsCache.put(sceneId, routingDiscreteParams);
SaveDetailCache(sceneId,RoutingDetails,routingDetailEquips,connections,routingDiscreteParams);
if (routingDetailEquips != null && routingDetailEquips.size() > 0) {
......@@ -313,101 +395,95 @@ public class MaterialRequirementService {
.collect(Collectors.toList());
return equipIds;
}
}
return null;
}
/**
* 构建多级BOM需求网络
* @return 所有物料需求列表
*/
public List<OrderMaterialRequirement> buildMultiLevelRequirementNetwork(LocalDateTime _baseTime) {
* 构建多级BOM需求网络
* @return 所有物料需求列表
*/
public List<OrderMaterialRequirement> buildMultiLevelRequirementNetwork(Chromosome chromosome,String sceneId, LocalDateTime _baseTime,GlobalParam _globalParam) {
baseTime=_baseTime;
globalParam=_globalParam;
List<OrderMaterialRequirement> allRequirements = new ArrayList<>();
List<Order> childorders = new ArrayList<>();
List<Entry> _newEntrys = new ArrayList<>();
List<Machine> _newMachines = new ArrayList<>();
List<Integer> routingIds = _allOperations.stream()
.filter(t->t.getRoutingId()!=null)
.map(Entry::getRoutingId)
.distinct()
.collect(Collectors.toList());
if(routingIds.size()==0)
{
return null;
}
LambdaQueryWrapper<RoutingHeader> wrapper = new LambdaQueryWrapper<>();
wrapper.in(RoutingHeader::getId, routingIds)
.eq(RoutingHeader::getIsDeleted, 0)
.eq(RoutingHeader::getApprovalStatus, 1); // 添加 is_deleted=0 过滤条件
headers = routingHeaderMapper.selectList(wrapper);
LambdaQueryWrapper<Routingsupporting> routingsupportingwrapper = new LambdaQueryWrapper<>();
routingsupportingwrapper.in(Routingsupporting::getRoutingHeaderId, routingIds)
.eq(Routingsupporting::getIsdeleted, 0);
routingsupportings = routingsupportingMapper.selectList(routingsupportingwrapper);
if(routingsupportings==null||routingsupportings.size()==0)
{
return null;
}
List<String> routingsupportingids = routingsupportings.stream()
.map(Routingsupporting::getStrId)
.distinct()
.collect(Collectors.toList());
LambdaQueryWrapper<RoutingSupportingReplace> routingsupportingreplacewrapper = new LambdaQueryWrapper<>();
routingsupportingreplacewrapper.in(RoutingSupportingReplace::getStrsupid, routingsupportingids)
.eq(RoutingSupportingReplace::getIsdeleted, 0);
routingsupportingreplaces = routingSupportingReplaceMapper.selectList(routingsupportingreplacewrapper);
List<Entry> allOperations=chromosome.getAllOperations();
List<Order> orders=chromosome.getOrders();
Map<Integer, Integer> orderProcessCounter = allOperations.stream()
.collect(Collectors.groupingBy(Entry::getGroupId, Collectors.collectingAndThen(
Collectors.counting(), Long::intValue)))
.entrySet().stream()
.collect(Collectors.toMap(Map.Entry::getKey, e -> 0));
List<Integer> operationSequencing=chromosome.getOperationSequencing();
for (Integer groupId : operationSequencing)
{
Order demand=orders.stream().filter(t->t.getId()==groupId).findFirst().orElse(null);
for (Order demand : orders) {
// 跳过已有父订单的需求
if (demand.getFinishOrderId() != null && !demand.getFinishOrderId().isEmpty()) {
continue;
}
// 递归展开BOM层级(通过结果对象接收out参数数据)
BOMBuildResult result = buildOrderBOM(demand.getRoutingId(),"", demand.getOrderId(), demand.getOrderId(),
demand.getQuantity(), 0,demand,0);
allRequirements.addAll(result.getMaterialRequirements());
childorders.addAll(result.getChildOrders());
_newEntrys.addAll(result.getNewEntrys());
_newMachines.addAll(result.getNewMachines());
int scheduledCount = orderProcessCounter.get(groupId);
List<Entry> orderOps = allOperations.stream()
.filter(t -> t.getGroupId() == groupId)
.sorted(Comparator.comparing(Entry::getSequence))
.collect(Collectors.toList());
if (scheduledCount >= orderOps.size()) {
throw new IllegalStateException(String.format(
"订单%d的工序已全部调度(共%d道),无需重复处理!",
groupId, orderOps.size()));
}
Entry operation = orderOps.get(scheduledCount);
// 调用BuildOperationBOM方法(返回结果对象替代out参数)
BOMBuildResult operationResult = buildOperationSFBOM(operation.getOrderId(), "",
operation.getQuantity(), operation, 1,demand,sceneId,chromosome);
// // 合并物料需求和子订单
if(operationResult!=null) {
allRequirements.addAll(operationResult.getMaterialRequirements());
childorders.addAll(operationResult.getChildOrders());
_newEntrys.addAll(operationResult.getNewEntrys());
}
orderProcessCounter.put(groupId, orderProcessCounter.get(groupId) + 1);
}
// 将子订单添加到全局订单列表
if (orders != null) {
orders.addAll(childorders);
// _allOperations.addAll(_newEntrys);
_Machines.addAll(_newMachines);
// _allOperations.addAll(_newEntrys);
}
return allRequirements;
}
/**
* 构建订单BOM
* @param parent 父项ID
* @param materialID 物料ID
* @param mainorderId 主订单ID
* @param childorderId 子订单ID
* @param parentQuantity 父项数量(Java中用double替代decimal,若需高精度可用BigDecimal)
* @param parentQuantity 父项数量
* @param level 层级
* @return 包含物料需求列表和子订单列表的结果对象(替代C#的out参数)
* @return 包含物料需求列表和子订单列表的结果对象
*/
public BOMBuildResult buildOrderBOM(int parent, String materialID, String mainorderId,
String childorderId, double parentQuantity, int level,Order forder,int finishOpertionID) {
public BOMBuildResult buildOrderBOM(String sceneId,int parent, String materialID, String mainorderId,
String childorderId, double parentQuantity, int level,Order forder,int finishOpertionID,Chromosome chromosome) {
forder.setCreateBom(true);
List<RoutingHeader> headers=GetRoutingHeader(sceneId);
RoutingHeader routingHeaders= headers.stream()
.filter(t->t.getId()==parent|| t.getMaterialId().equals(materialID))
.findFirst()
......@@ -415,8 +491,7 @@ if(routingIds.size()==0)
List<RoutingHeader> headers1;
// 若未找到产品,返回空结果(根据业务可调整为抛出异常)
if (routingHeaders==null) {
return null;
}
List<OrderMaterialRequirement> materialRequirements = new ArrayList<>();
......@@ -425,6 +500,8 @@ if(routingIds.size()==0)
List<Machine> _newMachines = new ArrayList<>();
// 遍历产品的工序,递归构建工序BOM
List<Entry> _allOperations= chromosome.getAllOperations();
List<Entry> Operations= _allOperations.stream()
.filter(t->t.getOrderId().equals(childorderId))
.collect(Collectors.toList());
......@@ -444,110 +521,207 @@ if(routingIds.size()==0)
}
// 调用BuildOperationBOM方法(返回结果对象替代out参数)
BOMBuildResult operationResult = buildOperationBOM(mainorderId, childorderId,
parentQuantity, operation, level,forder);
parentQuantity, operation, level,forder,sceneId,chromosome);
// // 合并物料需求和子订单
if(operationResult!=null) {
materialRequirements.addAll(operationResult.getMaterialRequirements());
childorders2.addAll(operationResult.getChildOrders());
_newEntrys.addAll(operationResult.getNewEntrys());
_newMachines.addAll(operationResult.getNewMachines());
}
}
}
return new BOMBuildResult(materialRequirements, childorders2,_newEntrys,_newMachines);
return new BOMBuildResult(materialRequirements, childorders2,_newEntrys);
}
/**
* 构建工序BOM需求
* @param orderId 主订单ID
* @param childorderId 子订单ID
* @param parentQuantity 父项数量
* @param operation 工序对象
* @param level 层级
* @return 包含物料需求列表和子订单列表的结果对象(替代C#的out参数)
*/
public BOMBuildResult buildOperationBOM(String orderId, String childorderId, double parentQuantity,
Entry operation, int level,Order forder,String sceneId,Chromosome chromosome) {
List<OrderMaterialRequirement> materialRequirements = new ArrayList<>();
List<Order> _childorders = new ArrayList<>();
List<Entry> _newEntrys = new ArrayList<>();
List<Machine> _newMachines = new ArrayList<>();
private Map<Integer, Object> CreateChild(Order order,String materialID,int finishOpertionID)
{
String sceneId="";
Long routingIds=0l;
List<Routingsupporting> routingsupportings1=new ArrayList<>();
List<RoutingSupportingReplace> routingsupportingreplaces1 =new ArrayList<>();
RoutingHeader headers1= headers.stream()
.filter(t->t.getMaterialId().equals(materialID))
.findFirst().orElse(null);
if(headers1==null) {
LambdaQueryWrapper<RoutingHeader> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(RoutingHeader::getMaterialId, materialID)
.eq(RoutingHeader::getIsDeleted, 0);
// .eq(RoutingHeader::getApprovalStatus, 1); // 添加 is_deleted=0 过滤条件
headers1 = routingHeaderMapper.selectList(wrapper).stream().findFirst().orElse(null);
if(headers1!=null) {
headers.add(headers1);
routingIds=headers1.getId().longValue();
List<Routingsupporting> routingsupportings=GetRoutingsupportings(sceneId);
LambdaQueryWrapper<Routingsupporting> routingsupportingwrapper = new LambdaQueryWrapper<>();
routingsupportingwrapper.in(Routingsupporting::getRoutingHeaderId, routingIds)
.eq(Routingsupporting::getIsdeleted, 0);
List<Routingsupporting> MaterialRequirements= routingsupportings.stream()
.filter(t->t.getRoutingDetailId().equals(operation.getRoutingDetailId()))
.collect(Collectors.toList());
List<Order> orders=chromosome.getOrders();
if (MaterialRequirements != null&&MaterialRequirements.size()>0) {
List<Material> _materials= GetMaterials(sceneId);
for (Routingsupporting component : MaterialRequirements) {
routingsupportings1 = routingsupportingMapper.selectList(routingsupportingwrapper);
routingsupportings.addAll(routingsupportings1);
double allneeded = component.getSpentQty().doubleValue()/ component.getMainQty().doubleValue() * parentQuantity;
double needed = allneeded;
List<String> routingsupportingids = routingsupportings1.stream()
.filter(t->t.getStrId()!=null)
.map(Routingsupporting::getStrId)
.distinct()
.collect(Collectors.toList());
// 查找物料(流式处理替代First)
Material material = _materials.stream()
.filter(m -> m.getId().equals(component.getMaterialId()))
.findFirst()
.orElse(null);
if (material == null) {
return null;
}
if(routingsupportingids.size()>0)
{
LambdaQueryWrapper<RoutingSupportingReplace> routingsupportingreplacewrapper = new LambdaQueryWrapper<>();
routingsupportingreplacewrapper.in(RoutingSupportingReplace::getStrsupid, routingsupportingids)
.eq(RoutingSupportingReplace::getIsdeleted, 0);
OrderMaterialRequirement orderMaterial= CreateMaterialRequirement(material,orderId,childorderId,operation,allneeded,component.getSpentQty().doubleValue(), component.getMainQty().doubleValue() , parentQuantity);
orderMaterial.setLevel(level);
orderMaterial.setBomId(component.getStrId());
materialRequirements.add(orderMaterial);
if (!orderMaterial.getMaterialTypeName().equals("MP") ) {
// 处理半成品/成品的现有订单
List<Order> orders2 = orders.stream()
.filter(t -> t.getMaterialId().equals(orderMaterial.getMaterialId()) && t.getSYQuantity() > 0)
.sorted(Comparator.comparing(Order::getDueDate))
.collect(Collectors.toList());
if (!orders2.isEmpty()) {
for (Order order : orders2) {
if (order.getFinishOrderId() == null) {
order.setFinishOrderId(new ArrayList<>());
order.setTargetFinishedOperationId(new ArrayList<>());
}
order.getFinishOrderId().add(forder.getId());
order.getTargetFinishedOperationId().add(operation.getId());
orderMaterial.getProductOrderID().add(order.getId());
double useq = Math.min(needed, order.getSYQuantity());
needed -= useq;
order.setSYQuantity(order.getSYQuantity() - useq);
//防止已经生成过一次
if (!order.isCreateBom()) {
// 递归构建BOM
int l = level + 1;
BOMBuildResult childResult = buildOrderBOM(sceneId,0, orderMaterial.getMaterialId(),
orderId, order.getOrderId(),
order.getQuantity(), l,order,operation.getId(),chromosome);
// materialRequirements.addAll(childResult.getMaterialRequirements());
_childorders.addAll(childResult.getChildOrders());
_newEntrys.addAll(childResult.getNewEntrys());
operation.getDependentOnOrderIds().add(order.getId());
}
if (needed <= 0) {
break;
}
}
}
routingsupportingreplaces1 = routingSupportingReplaceMapper.selectList(routingsupportingreplacewrapper);
// 更新已配和缺件数量
orderMaterial.setYpQty(allneeded - needed);
orderMaterial.setQjQty(needed);
routingsupportingreplaces.addAll(routingsupportingreplaces1);
if (needed > 0&&globalParam.isIsCheckSf()) {
// 创建新的子订单
Order childorder = new Order();
String OrderId = UUID.randomUUID().toString().replace("-", "");
childorder.setOrderId(OrderId);
childorder.setMaterialId(orderMaterial.getMaterialId());
childorder.setMaterialCode(orderMaterial.getMaterialCode());
childorder.setMaterialName(orderMaterial.getMaterialTypeName());
childorder.setOrderCode("M_"+orderMaterial.getMaterialCode());
childorder.setQuantity((int) orderMaterial.getQjQty());
childorder.setFinishOrderId(new ArrayList<>());
childorder.getFinishOrderId().add(forder.getId());
childorder.setNewCreate(true);
childorder.setTargetFinishedOperationId(new ArrayList<>());
childorder.getTargetFinishedOperationId().add(operation.getId());
childorder.setSerie(forder.getSerie());
childorder.setStartDate(forder.getStartDate());
childorder.setDueDate(forder.getDueDate());
childorder.setPriority(forder.getPriority());
childorder.setActualPriority(forder.getActualPriority());
Map<Integer, Object> list= CreateChild(sceneId,childorder,orderMaterial.getMaterialId(), operation.getId(),chromosome);
if(list==null)
{
continue;
}
_childorders.add(childorder);
List<Entry> newentrys=(List<Entry>)list.get(1);
_newEntrys.addAll(newentrys);
orderMaterial.getProductOrderID().add(childorder.getId());
operation.getDependentOnOrderIds().add(childorder.getId());
// 递归构建BOM
int l = level + 1;
BOMBuildResult childResult = buildOrderBOM(sceneId,0, orderMaterial.getMaterialId(),
orderId, childorder.getOrderId(),
childorder.getQuantity(), l,childorder,0,chromosome);
// materialRequirements.addAll(childResult.getMaterialRequirements());
_childorders.addAll(childResult.getChildOrders());
_newEntrys.addAll(childResult.getNewEntrys());
}
}
}
}
else {
routingIds=headers1.getId().longValue();
}
if(headers1==null)
{
return null;
}
operation.setMaterialRequirements(materialRequirements);
return new BOMBuildResult(materialRequirements, _childorders,_newEntrys);
}
private Map<Integer, Object> CreateChild(String sceneId, Order order,String materialID,int finishOpertionID,Chromosome chromosome)
{
Long routingIds=0l;
List<RoutingHeader> headers=GetRoutingHeader(sceneId);
RoutingHeader headers1= headers.stream()
.filter(t->t.getMaterialId().equals(materialID))
.findFirst().orElse(null);
if(headers1==null)
{
return null;
}
routingIds=headers1.getId().longValue();
Long headersid=routingIds;
List<RoutingDetail> allRoutingDetails=GetRoutingDetails(sceneId);
List<RoutingDetail> RoutingDetails= allRoutingDetails.stream()
.filter(t->t.getRoutingHeaderId()==headersid)
.filter(t->t.getRoutingHeaderId().equals(headersid))
.collect(Collectors.toList());
List<RoutingDetailEquip> routingDetailEquips=null;
List<RoutingDetailConnect> connections=null;
if(RoutingDetails==null||RoutingDetails.size()==0) {
RoutingDetails = lanuchService.getRoutingDetails(headers1.getId());
allRoutingDetails.addAll(RoutingDetails);
routingDetailEquips = lanuchService.getRoutingDetailEquip(headers1.getId(), headers1.getCode());
allroutingDetailEquips.addAll(routingDetailEquips);
LambdaQueryWrapper<RoutingDetailConnect> routingDetailConnectwrapper = new LambdaQueryWrapper<>();
routingDetailConnectwrapper.eq(RoutingDetailConnect::getRoutingHeaderId, routingIds)
.eq(RoutingDetailConnect::getIsdeleted, 0); // 添加 isdeleted=0 过滤条件
connections = routingDetailConnectService.list(routingDetailConnectwrapper);
allroutingDetailconnections.addAll(connections);
return null;
}
if(routingDetailEquips==null)
{
routingDetailEquips= allroutingDetailEquips.stream()
.filter(t->t.getRoutingHeaderId()==headersid)
List<RoutingDetailEquip> allroutingDetailEquips=GetRoutingDetailEquips(sceneId);
List<RoutingDetailEquip> routingDetailEquips= allroutingDetailEquips.stream()
.filter(t->t.getRoutingHeaderId().equals(headersid))
.collect(Collectors.toList());
}
order.setRoutingId(headers1.getId());
order.setRoutingCode(headers1.getCode());
ProdLaunchOrder prodOrderMain= convertToLaunchOrder(order,"");
ProdLaunchOrder prodOrderMain= convertToLaunchOrder(order,sceneId);
List<RoutingDetailEquip> finalRoutingDetailEquips = routingDetailEquips;
Integer departmentId = headers1.getDepartmentId() != null ? headers1.getDepartmentId() : null;
List<ProdProcessExec> processExecList = RoutingDetails.stream()
.map(detail -> lanuchService.createProcessExec(prodOrderMain, detail, sceneId, finalRoutingDetailEquips, departmentId))
.collect(Collectors.toList());
List<Equipinfo> equipinfoList = equipinfoService.lambdaQuery().eq(Equipinfo::getIsdeleted, 0).list();
List<Equipinfo> equipinfoList=GetEquipinfos();
List<ProdEquipment> ProdEquipmentList= lanuchService.batchInsertEquipMent(routingDetailEquips, sceneId,processExecList,false,equipinfoList);
......@@ -558,12 +732,12 @@ if(routingIds.size()==0)
ProdProcessExec::getExecId,
(existing, replacement) -> existing)); // 处理重复key的情况
if(connections==null)
{
List<RoutingDetailConnect> allroutingDetailconnections=GetRoutingDetailConnect(sceneId);
connections= allroutingDetailconnections.stream()
.filter(t->t.getRoutingHeaderId()==headersid)
.filter(t->t.getRoutingHeaderId().equals(headersid))
.collect(Collectors.toList());
}
List<ProdOrderProcess> ProdOrderProcesslist= connections.stream()
.map(connection -> lanuchService.createProcessRelation(prodOrderMain, connection, sceneId, routingDetailIdToExecIdMap))
......@@ -573,52 +747,29 @@ if(routingIds.size()==0)
.map(RoutingDetail::getId)
.distinct()
.collect(Collectors.toList());
List<RoutingDiscreteParam> allroutingDiscreteParams=GetRoutingDiscreteParam(sceneId);
List<RoutingDiscreteParam> routingDiscreteParams= allroutingDiscreteParams.stream()
.filter(t->routingDetailIds.contains(t.getRoutingDetailId()))
.collect(Collectors.toList());
if(routingDiscreteParams==null||routingDiscreteParams.size()==0) {
routingDiscreteParams = _routingDiscreteParamService.lambdaQuery()
.in(RoutingDiscreteParam::getRoutingDetailId, routingDetailIds)
.eq(RoutingDiscreteParam::getIsDeleted, 0)
.list();
allroutingDiscreteParams.addAll(routingDiscreteParams);
}
List<Order> ProdLaunchOrders=new ArrayList<>();
ProdLaunchOrders.add(order);
Map<Integer, Object> list=_routingDataService.CreateEntry( sceneId, ProdEquipmentList, ProdLaunchOrders, routingDiscreteParams, ProdOrderProcesslist, processExecList,_entryRel,finishOpertionID );
List<Machine> machines=new ArrayList<>();
List<Machine> allmachines = (List<Machine>) GlobalCacheUtil.get("machines");
if (allmachines == null || allmachines.size() == 0) {
Map<Integer, Object> list=_routingDataService.CreateEntry( sceneId, ProdEquipmentList, ProdLaunchOrders, routingDiscreteParams, ProdOrderProcesslist, processExecList,chromosome.getOperatRel(),finishOpertionID );
allmachines = (List<Machine>) redisUtils.get("machines");
if (allmachines == null || allmachines.size() == 0) {
List<Long> equipIds = ProdEquipmentList.stream()
.map(ProdEquipment::getEquipId)
.distinct() // 提取Exec_ID
.collect(Collectors.toList());
machines=allmachines.stream().filter(t->equipIds.contains(t.getId())).collect(Collectors.toList());
}
}
if (machines == null || machines.size() == 0) {
machines= _routingDataService.InitCalendarToAllMachines(sceneId,ProdEquipmentList,machineScheduler, globalParam.isIsUseCalendar());
}
if(list.get(1)!=null)
{
_allOperations.addAll((List<Entry>)list.get(1));
_entryRel=(List<GroupResult>)list.get(2);
chromosome.getAllOperations().addAll(new CopyOnWriteArrayList((List<Entry>)list.get(1)) );
chromosome.setOperatRel(new CopyOnWriteArrayList((List<GroupResult>)list.get(2)));
}
Map<Integer, Object> rest=new HashMap<>();
rest.put(1,list.get(1));
rest.put(2,machines);
return rest;
}
......@@ -661,130 +812,44 @@ if(routingIds.size()==0)
* @param level 层级
* @return 包含物料需求列表和子订单列表的结果对象(替代C#的out参数)
*/
public BOMBuildResult buildOperationBOM(String orderId, String childorderId, double parentQuantity,
Entry operation, int level,Order forder) {
public BOMBuildResult buildOperationSFBOM(String orderId, String childorderId, double parentQuantity,
Entry operation, int level,Order forder,String sceneId,Chromosome chromosome) {
List<OrderMaterialRequirement> materialRequirements = new ArrayList<>();
List<Order> _childorders = new ArrayList<>();
List<Entry> _newEntrys = new ArrayList<>();
List<Machine> _newMachines = new ArrayList<>();
List<Routingsupporting> MaterialRequirements= routingsupportings.stream()
.filter(t->t.getRoutingDetailId().equals(operation.getRoutingDetailId()))
.collect(Collectors.toList());
if (MaterialRequirements != null&&MaterialRequirements.size()>0) {
for (Routingsupporting component : MaterialRequirements) {
List<OrderMaterialRequirement> MaterialRequirements= operation.getMaterialRequirements();
List<Order> orders=chromosome.getOrders();
if (MaterialRequirements != null&&MaterialRequirements.size()>0) {
for (OrderMaterialRequirement orderMaterial : MaterialRequirements) {
double allneeded = parentQuantity * component.getMainQty().doubleValue();
double allneeded = parentQuantity * orderMaterial.getRequiredQuantity();
double needed = allneeded;
// 查找物料(流式处理替代First)
Material material = _materials.stream()
.filter(m -> m.getId().equals(component.getMaterialId()))
.findFirst()
.orElse(null);
if (material == null) {
return null;
}
OrderMaterialRequirement orderMaterial= MaterialStock(material,"",orderId,childorderId,operation,allneeded,needed);
double useStock=0;
if(orderMaterial!=null) {
useStock = orderMaterial.getUseStock();
materialRequirements.add(orderMaterial);
orderMaterial.setLevel(level);
}
orderMaterial.setMaterialCode(component.getMaterialNumber());
orderMaterial.setMaterialName(component.getMaterialName());
needed -= useStock;
if (needed <= 0) {
orderMaterial.setYpQty(allneeded - needed);
orderMaterial.setQjQty(needed);
continue;
}
if (!orderMaterial.getMaterialTypeName().equals("MP") ) {
List<RoutingSupportingReplace> routingsupportingreplaces2 = routingsupportingreplaces.stream().filter(t->t.getStrsupid().equals(component.getStrId())&&t.getMaterialid()!=component.getMaterialId()).collect(Collectors.toList());
if (routingsupportingreplaces2 != null && routingsupportingreplaces2.size() > 1)
{
for (RoutingSupportingReplace rsr:routingsupportingreplaces2) {
OrderMaterialRequirement orderMaterial1= MaterialStock(null,rsr.getMaterialid(),orderId,childorderId,operation,allneeded,needed);
if(orderMaterial1!=null) {
useStock = orderMaterial1.getUseStock();
needed -= useStock;
orderMaterial.setUseStock(orderMaterial.getUseStock()+useStock);
orderMaterial.getReplaceMaterial().add(orderMaterial1);
if (needed <= 0) {
break;
}
}
}
}
if (needed <= 0) {
orderMaterial.setYpQty(allneeded - needed);
orderMaterial.setQjQty(needed);
continue;
}
MaterialInTransit(material,"",orderMaterial,needed);
// 处理半成品/成品的现有订单
// 为什么要先找现有订单,绑定上,因为要把它排在成品工单前面,才能有时间
List<Order> orders2 = orders.stream()
.filter(t -> t.getMaterialId().equals(orderMaterial.getMaterialId()) && t.getSYQuantity() > 0)
.sorted(Comparator.comparing(Order::getDueDate))
.collect(Collectors.toList());
needed -= orderMaterial.getUseTransit();
if (!orders2.isEmpty()) {
for (Order order : orders2) {
if (order.getFinishOrderId() == null) {
order.setFinishOrderId(new ArrayList<>());
order.setTargetFinishedOperationId(new ArrayList<>());
}
order.getFinishOrderId().add(forder.getId());
order.getTargetFinishedOperationId().add(operation.getId());
if (routingsupportingreplaces2 != null && routingsupportingreplaces2.size() > 1)
{
for (RoutingSupportingReplace rsr:routingsupportingreplaces2) {
OrderMaterialRequirement orderMaterial1= orderMaterial.getReplaceMaterial().stream()
.filter(t->t.getMaterialId().equals(rsr.getMaterialid()))
.findFirst()
.orElse(null);
MaterialInTransit(null,rsr.getMaterialid(),orderMaterial1,needed);
needed -= orderMaterial1.getUseTransit();
LocalDateTime earliestTime= orderMaterial.getArrivalTime().compareTo(orderMaterial1.getArrivalTime())>0?orderMaterial.getArrivalTime():orderMaterial1.getArrivalTime();
orderMaterial.setArrivalTime(earliestTime);
orderMaterial.setUseTransit(orderMaterial.getUseTransit()+orderMaterial1.getUseTransit());
if (needed <= 0) {
break;
}
}
}
if (needed <= 0) {
orderMaterial.setYpQty(allneeded - needed);
orderMaterial.setQjQty(needed);
continue;
}
if (needed > 0) {
orderMaterial.setYpQty(allneeded - needed);
orderMaterial.setQjQty(needed);
if (material.getMaterialTypeName().equals("MP") ) {
// 处理原材料采购时间
orderMaterial.setPurchaseStartTime(baseTime);
// 采购结束时间 = 采购开始时间 + 采购提前期(天)
LocalDateTime purchaseEndTime = baseTime.plusDays(material.getPurchaseLeadTime());
orderMaterial.setPurchaseEndTime(purchaseEndTime);
} else {
// 处理半成品/成品的现有订单
List<Order> orders2 = orders.stream()
.filter(t -> t.getMaterialId().equals(material.getId()) && t.getSYQuantity() > 0)
.sorted(Comparator.comparing(Order::getDueDate))
.collect(Collectors.toList());
if (!orders2.isEmpty()) {
for (Order order : orders2) {
if (order.getFinishOrderId() == null) {
order.setFinishOrderId(new ArrayList<>());
order.setTargetFinishedOperationId(new ArrayList<>());
}
order.getFinishOrderId().add(forder.getId());
order.getTargetFinishedOperationId().add(operation.getId());
orderMaterial.getProductOrderID().add(order.getId());
orderMaterial.getProductOrderID().add(order.getId());
double useq = Math.min(needed, order.getSYQuantity());
needed -= useq;
......@@ -795,13 +860,12 @@ if(routingIds.size()==0)
// 递归构建BOM
int l = level + 1;
BOMBuildResult childResult = buildOrderBOM(0, material.getId(),
BOMBuildResult childResult = buildOrderBOM(sceneId,0, orderMaterial.getMaterialId(),
orderId, order.getOrderId(),
order.getQuantity(), l,order,operation.getId());
order.getQuantity(), l,order,operation.getId(),chromosome);
materialRequirements.addAll(childResult.getMaterialRequirements());
_childorders.addAll(childResult.getChildOrders());
_newEntrys.addAll(childResult.getNewEntrys());
_newMachines.addAll(childResult.getNewMachines());
operation.getDependentOnOrderIds().add(order.getId());
}
......@@ -821,10 +885,10 @@ if(routingIds.size()==0)
String OrderId = UUID.randomUUID().toString().replace("-", "");
childorder.setOrderId(OrderId);
childorder.setMaterialId(material.getId());
childorder.setMaterialCode(material.getCode());
childorder.setMaterialName(material.getName());
childorder.setOrderCode(material.getCode());
childorder.setMaterialId(orderMaterial.getMaterialId());
childorder.setMaterialCode(orderMaterial.getMaterialCode());
childorder.setMaterialName(orderMaterial.getMaterialTypeName());
childorder.setOrderCode("M_"+orderMaterial.getMaterialCode());
childorder.setQuantity((int) orderMaterial.getQjQty());
childorder.setFinishOrderId(new ArrayList<>());
childorder.getFinishOrderId().add(forder.getId());
......@@ -839,7 +903,7 @@ if(routingIds.size()==0)
childorder.setActualPriority(forder.getActualPriority());
Map<Integer, Object> list= CreateChild(childorder,material.getId(), operation.getId());
Map<Integer, Object> list= CreateChild(sceneId,childorder,orderMaterial.getMaterialId(), operation.getId(),chromosome);
if(list==null)
{
continue;
......@@ -847,20 +911,307 @@ if(routingIds.size()==0)
_childorders.add(childorder);
List<Entry> newentrys=(List<Entry>)list.get(1);
_newEntrys.addAll(newentrys);
_newMachines.addAll((List<Machine>)list.get(2));
orderMaterial.getProductOrderID().add(childorder.getId());
operation.getDependentOnOrderIds().add(childorder.getId());
// 递归构建BOM
int l = level + 1;
BOMBuildResult childResult = buildOrderBOM(0, material.getId(),
BOMBuildResult childResult = buildOrderBOM(sceneId,0, orderMaterial.getMaterialId(),
orderId, childorder.getOrderId(),
childorder.getQuantity(), l,childorder,0);
childorder.getQuantity(), l,childorder,0,chromosome);
materialRequirements.addAll(childResult.getMaterialRequirements());
_childorders.addAll(childResult.getChildOrders());
_newEntrys.addAll(childResult.getNewEntrys());
_newMachines.addAll(childResult.getNewMachines());
}
}
}
}
return new BOMBuildResult(materialRequirements, _childorders,_newEntrys);
}
private OrderMaterialRequirement MaterialStock(Material material,String materialId,String orderId, String childorderId, Entry operation,double allneeded, double needed,LocalDateTime earliestStartTime ) {
OrderMaterialRequirement orderMaterial = new OrderMaterialRequirement();
orderMaterial.setOrderId(orderId);
orderMaterial.setOperationId(operation.getId());
orderMaterial.setChildOrderId(StringUtils.isBlank(childorderId) ? orderId : childorderId);
orderMaterial.setRequiredQuantity(allneeded);
double availableNow = material.getCurrentStock();
orderMaterial.setMaterialCode(material.getCode());
orderMaterial.setMaterialName(material.getName());
orderMaterial.setMaterialTypeName(material.getMaterialTypeName());
orderMaterial.setMaterialId(material.getId());
// orderMaterial.setCheckLeadTime(material.getCkeckLeadTime());
double useStock=0;
// 扣减现有库存
List<Stock> stocks= material.getMaterialStocks().stream()
.filter(t->t.getExpiryDate().compareTo(earliestStartTime)>=0&&t.getAvailableInventory()>0)
.collect(Collectors.toList());
if(stocks!=null)
{
for (Stock s:stocks) {
double useStock1 = Math.min(needed,s.getAvailableInventory());
needed -=useStock1;
useStock+=useStock1;
s.setUsedInventory(s.getUsedInventory()+useStock1);
if(needed==0)
{
break;
}
}
}
orderMaterial.setUseStock(useStock);
return orderMaterial;
}
private OrderMaterialRequirement CreateMaterialRequirement(Material material,String orderId, String childorderId, Entry operation,double need,double spentQty,double mainQty,double qty) {
OrderMaterialRequirement orderMaterial = new OrderMaterialRequirement();
orderMaterial.setOrderId(orderId);
orderMaterial.setOperationId(operation.getId());
orderMaterial.setChildOrderId(StringUtils.isBlank(childorderId) ? orderId : childorderId);
orderMaterial.setMaterialCode(material.getCode());
orderMaterial.setMaterialName(material.getName());
orderMaterial.setMaterialTypeName(material.getMaterialTypeName());
orderMaterial.setMaterialId(material.getId());
orderMaterial.setCheckLeadTime(0);
orderMaterial.setPurchaseTime(0);
orderMaterial.setRequiredQuantity(need);
orderMaterial.setSpentQty(spentQty);
orderMaterial.setMainQty(mainQty);
orderMaterial.setQuantity(qty);
List<MaterialPurchase> materialPurchaseList=material.getMaterialPurchases();
if(materialPurchaseList!=null&&materialPurchaseList.size()>0)
{
Optional<MaterialPurchase> maxItem = materialPurchaseList.stream()
// 按purchaseCycle+inspectionCycle降序排序
.max((o1, o2) -> {
// 计算第一个对象的和(空值处理,避免空指针)
int sum1 = (o1.getPurchaseCycle() == null ? 0 : o1.getPurchaseCycle())
+ (o1.getInspectionCycle() == null ? 0 : o1.getInspectionCycle());
// 计算第二个对象的和
int sum2 = (o2.getPurchaseCycle() == null ? 0 : o2.getPurchaseCycle())
+ (o2.getInspectionCycle() == null ? 0 : o2.getInspectionCycle());
return Integer.compare(sum1, sum2);
});
if (maxItem.isPresent()) {
MaterialPurchase result = maxItem.get();
orderMaterial.setCheckLeadTime(result.getPurchaseCycle());
orderMaterial.setPurchaseTime(result.getInspectionCycle());
}
}
orderMaterial.setUseTime(baseTime.plusDays(orderMaterial.getPurchaseTime()+orderMaterial.getCheckLeadTime()));
return orderMaterial;
}
/**
* 构建工序BOM需求
* @param operation 工序对象
* @return 包含物料需求列表和子订单列表的结果对象(替代C#的out参数)
*/
public void EditOperationBOM(Entry operation,Chromosome chromosome,LocalDateTime earliestStartTime,GeneticDecoder coder) {
List<OrderMaterialRequirement> materialRequirements = new ArrayList<>();
String sceneId=chromosome.getScenarioID();
Random rnd = new Random();
List<OrderMaterialRequirement> MaterialRequirements= operation.getMaterialRequirements();
MaterialRequirements = MaterialRequirements.stream()
.sorted((a, b) -> {
// 定义判断条件:是否满足 非MP + 生产订单ID非空非空串
boolean aMatch = !"MP".equals(a.getMaterialTypeName())
&& a.getProductOrderID() != null && !a.getProductOrderID().isEmpty();
boolean bMatch = !"MP".equals(b.getMaterialTypeName())
&& b.getProductOrderID() != null && !b.getProductOrderID().isEmpty();
// 排序规则:满足的排前面,不满足的排后面;都满足/都不满足则保持原序
if (aMatch && !bMatch) return -1; // a满足b不满足,a在前
if (!aMatch && bMatch) return 1; // a不满足b满足,b在前
return 0; // 同状态,保持原序
})
.collect(Collectors.toList());
List<Material> materials=chromosome.getMaterials();
List<OrderMaterialRequirement> remove=new ArrayList<>();
if (MaterialRequirements != null&&MaterialRequirements.size()>0) {
for (OrderMaterialRequirement orderMaterial : MaterialRequirements) {
double allneeded = orderMaterial.getSpentQty()/ orderMaterial.getMainQty() * operation.getQuantity();
double needed = allneeded;
orderMaterial.setRequiredQuantity(needed);
// 查找物料(流式处理替代First)
Material material = materials.stream()
.filter(m -> m.getId().equals(orderMaterial.getMaterialId()))
.findFirst()
.orElse(null);
if (material == null) {
return ;
}
double useStock=0;
List<Stock> stocks= material.getMaterialStocks().stream()
.filter(t->t.getExpiryDate().compareTo(earliestStartTime)>=0&&t.getAvailableInventory()>0)
.collect(Collectors.toList());
if(stocks!=null)
{
for (Stock s:stocks) {
double useStock1 = Math.min(needed,s.getAvailableInventory());
needed -=useStock1;
useStock+=useStock1;
s.setUsedInventory(s.getUsedInventory()+useStock1);
if(needed==0)
{
break;
}
}
}
if (needed <= 0) {
orderMaterial.setYpQty(allneeded - needed);
orderMaterial.setQjQty(needed);
remove.add(orderMaterial);
continue;
}
List<RoutingSupportingReplace> routingsupportingreplaces= GetRoutingSupportingReplaces(sceneId);
List<RoutingSupportingReplace> routingsupportingreplaces2=null;
if (routingsupportingreplaces != null && routingsupportingreplaces.size() > 1) {
routingsupportingreplaces2 = routingsupportingreplaces.
stream()
.filter(t -> t.getStrsupid().equals(orderMaterial.getBomId())
&& t.getMaterialid() != orderMaterial.getMaterialId())
.collect(Collectors.toList());
if (routingsupportingreplaces2 != null && routingsupportingreplaces2.size() > 1) {
for (RoutingSupportingReplace rsr : routingsupportingreplaces2) {
Material material1 = materials.stream()
.filter(m -> m.getId().equals(rsr.getMaterialid()))
.findFirst()
.orElse(null);
if (material1 == null) {
break;
}
OrderMaterialRequirement orderMaterial1 = MaterialStock(material1, rsr.getMaterialid(), orderMaterial.getOrderId(), orderMaterial.getChildOrderId(), operation, allneeded, needed, earliestStartTime);
if (orderMaterial1 != null) {
useStock = orderMaterial1.getUseStock();
needed -= useStock;
orderMaterial.setUseStock(orderMaterial.getUseStock() + useStock);
orderMaterial.getReplaceMaterial().add(orderMaterial1);
if (needed <= 0) {
break;
}
}
}
}
}
if (needed <= 0) {
orderMaterial.setYpQty(allneeded - needed);
orderMaterial.setQjQty(needed);
remove.add(orderMaterial);
continue;
}
MaterialInTransit(material,"",orderMaterial,needed,earliestStartTime);
needed -= orderMaterial.getUseTransit();
if (routingsupportingreplaces2 != null && routingsupportingreplaces2.size() > 1)
{
for (RoutingSupportingReplace rsr:routingsupportingreplaces2) {
OrderMaterialRequirement orderMaterial1= orderMaterial.getReplaceMaterial().stream()
.filter(t->t.getMaterialId().equals(rsr.getMaterialid()))
.findFirst()
.orElse(null);
Material material1 = materials.stream()
.filter(m -> m.getId().equals(orderMaterial1.getMaterialId()))
.findFirst()
.orElse(null);
if (material1 == null) {
break;
}
MaterialInTransit(material1,rsr.getMaterialid(),orderMaterial1,needed,earliestStartTime);
needed -= orderMaterial1.getUseTransit();
LocalDateTime earliestTime= orderMaterial.getArrivalTime().compareTo(orderMaterial1.getArrivalTime())>0?orderMaterial.getArrivalTime():orderMaterial1.getArrivalTime();
orderMaterial.setArrivalTime(earliestTime);
orderMaterial.setUseTransit(orderMaterial.getUseTransit()+orderMaterial1.getUseTransit());
if (needed <= 0) {
break;
}
}
}
if (needed <= 0) {
orderMaterial.setYpQty(allneeded - needed);
orderMaterial.setQjQty(needed);
remove.add(orderMaterial);
continue;
}
if (needed > 0) {
orderMaterial.setYpQty(allneeded - needed);
orderMaterial.setQjQty(needed);
if (material.getMaterialTypeName().equals("MP") ) {
// 处理原材料采购时间
orderMaterial.setPurchaseStartTime(baseTime);
// 采购结束时间 = 采购开始时间 + 采购提前期(天)
List<MaterialPurchase> materialPurchaseList=material.getMaterialPurchases();
if(materialPurchaseList!=null&&materialPurchaseList.size()>0) {
int randomSeq = rnd.nextInt(materialPurchaseList.size());
MaterialPurchase result = materialPurchaseList.get(randomSeq);
orderMaterial.setCheckLeadTime(result.getPurchaseCycle());
orderMaterial.setPurchaseTime(result.getInspectionCycle());
LocalDateTime purchaseEndTime = baseTime.plusDays(orderMaterial.getPurchaseTime() + orderMaterial.getCheckLeadTime());
orderMaterial.setPurchaseEndTime(purchaseEndTime);
}
} else {
// 处理半成品/成品的现有订单
List<Integer> orderids= orderMaterial.getProductOrderID();
if(orderids!=null&&orderids.size()>0) {
for (Integer orderid : orderids) {
coder.EditorderOperation(chromosome, orderid, needed);
}
}else {
List<MaterialPurchase> materialPurchaseList=material.getMaterialPurchases();
if(materialPurchaseList!=null&&materialPurchaseList.size()>0) {
int randomSeq = rnd.nextInt(materialPurchaseList.size());
MaterialPurchase result = materialPurchaseList.get(randomSeq);
orderMaterial.setCheckLeadTime(result.getPurchaseCycle());
orderMaterial.setPurchaseTime(result.getInspectionCycle());
LocalDateTime purchaseEndTime = baseTime.plusDays(orderMaterial.getPurchaseTime() + orderMaterial.getCheckLeadTime());
orderMaterial.setPurchaseEndTime(purchaseEndTime);
}
}
}
}
// 计算预计可用时间
......@@ -881,44 +1232,25 @@ if(routingIds.size()==0)
}
}
return new BOMBuildResult(materialRequirements, _childorders,_newEntrys,_newMachines);
}
private OrderMaterialRequirement MaterialStock(Material material,String materialId,String orderId, String childorderId, Entry operation,double allneeded, double needed ) {
OrderMaterialRequirement orderMaterial = new OrderMaterialRequirement();
orderMaterial.setOrderId(orderId);
orderMaterial.setOperationId(operation.getId());
orderMaterial.setChildOrderId(StringUtils.isBlank(childorderId) ? orderId : childorderId);
orderMaterial.setRequiredQuantity(allneeded);
if (material == null) {
material = _materials.stream()
.filter(m -> m.getId().equals(materialId))
.findFirst()
.orElse(null);
if (material == null) {
return null;
if (remove != null&&remove.size()>0) {
//删除先删排产结果,然后记录orderID,到排产方案里,最后一起删除
for (OrderMaterialRequirement mr:remove) {
List<Integer> orderids= mr.getProductOrderID();
if(orderids!=null&&orderids.size()>0) {
for (Integer orderid : orderids) {
coder.DelOrder(chromosome, orderid,mr);
}
}
}
MaterialRequirements.removeAll(remove);
}
double availableNow = material.getCurrentStock();
orderMaterial.setMaterialCode(material.getCode());
orderMaterial.setMaterialName(material.getName());
orderMaterial.setMaterialTypeName(material.getMaterialTypeName());
orderMaterial.setMaterialId(material.getId());
orderMaterial.setCheckLeadTime(material.getCkeckLeadTime());
}
// 扣减现有库存
double useStock = Math.min(needed, availableNow);
material.setCurrentStock(material.getCurrentStock() - useStock);
orderMaterial.setUseStock(useStock);
return orderMaterial;
}
private void MaterialInTransit(Material material,String materialId, OrderMaterialRequirement orderMaterial, double needed ){
private void MaterialInTransit(Material material,String materialId, OrderMaterialRequirement orderMaterial, double needed,LocalDateTime earliestStartTime ){
// 处理在途物料
double accumulated = 0;
......@@ -932,11 +1264,11 @@ if(routingIds.size()==0)
if (material == null) {
return ;
}
}
// 按到货时间排序在途物料
Long CkeckLeadTime= material.getCkeckLeadTime();
List<MaterialSupply> sortedInTransit = material.getInTransit().stream()
.filter(t -> t.getQuantity() > 0)
.filter(t -> t.getQuantity() > 0&&t.getArrivalTime().compareTo(earliestStartTime.plusDays(-CkeckLeadTime))<=0 )
.sorted(Comparator.comparing(MaterialSupply::getArrivalTime))
.collect(Collectors.toList());
......@@ -955,14 +1287,181 @@ if(routingIds.size()==0)
orderMaterial.setArrivalTime(earliestTime);
}
public void clearCache() {
routingHeaderCache.clear();
routingsupportingCache.clear();
routingSupportingReplaceCache.clear();
// 清空其他缓存集合(如allRoutingDetails等)
allRoutingDetailsCache.clear();
allroutingDetailEquipsCache.clear();
allroutingDetailconnectionsCache.clear();
allroutingDiscreteParamsCache.clear();
private void SaveBomCache(String sceneId,List<RoutingHeader> routingHeaders,List<Routingsupporting> routingsupportings,List<RoutingSupportingReplace> replaces,List<Material> useMaterials)
{
redisUtils.set(sceneId+routingHeaderCacheKey,routingHeaders);
GlobalCacheUtil.put(sceneId+routingHeaderCacheKey,routingHeaders, cachetimeout, TimeUnit.MINUTES);
redisUtils.set(sceneId+routingsupportingCacheKey,routingsupportings);
GlobalCacheUtil.put(sceneId+routingsupportingCacheKey,routingsupportings, cachetimeout, TimeUnit.MINUTES);
redisUtils.set(sceneId+routingSupportingReplaceCacheKey,replaces);
GlobalCacheUtil.put(sceneId+routingSupportingReplaceCacheKey,replaces, cachetimeout, TimeUnit.MINUTES);
redisUtils.set(sceneId+materialsCacheKey,useMaterials);
GlobalCacheUtil.put(sceneId+materialsCacheKey,useMaterials, cachetimeout, TimeUnit.MINUTES);
}
private void SaveDetailCache(String sceneId,List<RoutingDetail> RoutingDetails,List<RoutingDetailEquip> routingDetailEquips,List<RoutingDetailConnect> connections,List<RoutingDiscreteParam> routingDiscreteParams)
{
redisUtils.set(sceneId+routingDetailCacheKey,RoutingDetails);
GlobalCacheUtil.put(sceneId+routingDetailCacheKey,RoutingDetails, cachetimeout, TimeUnit.MINUTES);
redisUtils.set(sceneId+routingDetailEquipCacheKey,routingDetailEquips);
GlobalCacheUtil.put(sceneId+routingDetailEquipCacheKey,routingDetailEquips, cachetimeout, TimeUnit.MINUTES);
redisUtils.set(sceneId+routingDetailConnectCacheKey,connections);
GlobalCacheUtil.put(sceneId+routingDetailConnectCacheKey,connections, cachetimeout, TimeUnit.MINUTES);
redisUtils.set(sceneId+routingDiscreteParamCacheKey,routingDiscreteParams);
GlobalCacheUtil.put(sceneId+routingDiscreteParamCacheKey,routingDiscreteParams, cachetimeout, TimeUnit.MINUTES);
}
private List<RoutingHeader> GetRoutingHeader(String sceneId) {
List<RoutingHeader> RoutingHeaders=(List<RoutingHeader>)GlobalCacheUtil.get(sceneId+routingHeaderCacheKey);
if(RoutingHeaders==null)
{
RoutingHeaders=(List<RoutingHeader>)redisUtils.get(sceneId+routingHeaderCacheKey);
if(RoutingHeaders!=null)
{
GlobalCacheUtil.put(sceneId+routingHeaderCacheKey,RoutingHeaders, cachetimeout, TimeUnit.MINUTES);
}
}
return RoutingHeaders;
}
private List<Routingsupporting> GetRoutingsupportings(String sceneId) {
List<Routingsupporting> Routingsupportings=(List<Routingsupporting>)GlobalCacheUtil.get(sceneId+routingsupportingCacheKey);
if(Routingsupportings==null)
{
Routingsupportings=(List<Routingsupporting>)redisUtils.get(sceneId+routingsupportingCacheKey);
if(Routingsupportings!=null)
{
GlobalCacheUtil.put(sceneId+routingsupportingCacheKey,Routingsupportings, cachetimeout, TimeUnit.MINUTES);
}
}
return Routingsupportings;
}
private List<RoutingSupportingReplace> GetRoutingSupportingReplaces(String sceneId) {
List<RoutingSupportingReplace> RoutingSupportingReplaces=(List<RoutingSupportingReplace>)GlobalCacheUtil.get(sceneId+routingSupportingReplaceCacheKey);
if(RoutingSupportingReplaces==null)
{
RoutingSupportingReplaces=(List<RoutingSupportingReplace>)redisUtils.get(sceneId+routingSupportingReplaceCacheKey);
if(RoutingSupportingReplaces!=null)
{
GlobalCacheUtil.put(sceneId+routingSupportingReplaceCacheKey,RoutingSupportingReplaces, cachetimeout, TimeUnit.MINUTES);
}
}
return RoutingSupportingReplaces;
}
private List<RoutingDetail> GetRoutingDetails(String sceneId) {
List<RoutingDetail> RoutingDetails=(List<RoutingDetail>)GlobalCacheUtil.get(sceneId+routingDetailCacheKey);
if(RoutingDetails==null)
{
RoutingDetails=(List<RoutingDetail>)redisUtils.get(sceneId+routingDetailCacheKey);
if(RoutingDetails!=null)
{
GlobalCacheUtil.put(sceneId+routingDetailCacheKey,RoutingDetails, cachetimeout, TimeUnit.MINUTES);
}
}
return RoutingDetails;
}
private List<RoutingDetailEquip> GetRoutingDetailEquips(String sceneId) {
List<RoutingDetailEquip> RoutingDetailEquips=(List<RoutingDetailEquip>)GlobalCacheUtil.get(sceneId+routingDetailEquipCacheKey);
if(RoutingDetailEquips==null)
{
RoutingDetailEquips=(List<RoutingDetailEquip>)redisUtils.get(sceneId+routingDetailEquipCacheKey);
if(RoutingDetailEquips!=null)
{
GlobalCacheUtil.put(sceneId+routingDetailEquipCacheKey,RoutingDetailEquips, cachetimeout, TimeUnit.MINUTES);
}
}
return RoutingDetailEquips;
}
private List<RoutingDetailConnect> GetRoutingDetailConnect(String sceneId) {
List<RoutingDetailConnect> RoutingDetailConnects=(List<RoutingDetailConnect>)GlobalCacheUtil.get(sceneId+routingDetailConnectCacheKey);
if(RoutingDetailConnects==null)
{
RoutingDetailConnects=(List<RoutingDetailConnect>)redisUtils.get(sceneId+routingDetailConnectCacheKey);
if(RoutingDetailConnects!=null)
{
GlobalCacheUtil.put(sceneId+routingDetailConnectCacheKey,RoutingDetailConnects, cachetimeout, TimeUnit.MINUTES);
}
}
return RoutingDetailConnects;
}
private List<RoutingDiscreteParam> GetRoutingDiscreteParam(String sceneId) {
List<RoutingDiscreteParam> RoutingDiscreteParams=(List<RoutingDiscreteParam>)GlobalCacheUtil.get(sceneId+routingDiscreteParamCacheKey);
if(RoutingDiscreteParams==null)
{
RoutingDiscreteParams=(List<RoutingDiscreteParam>)redisUtils.get(sceneId+routingDiscreteParamCacheKey);
if(RoutingDiscreteParams!=null)
{
GlobalCacheUtil.put(sceneId+routingDiscreteParamCacheKey,RoutingDiscreteParams, cachetimeout, TimeUnit.MINUTES);
}
}
return RoutingDiscreteParams;
}
private List<Material> GetMaterials(String sceneId) {
List<Material> materials=(List<Material>)GlobalCacheUtil.get(sceneId+materialsCacheKey);
if(materials==null)
{
materials=(List<Material>)redisUtils.get(sceneId+materialsCacheKey);
if(materials!=null)
{
GlobalCacheUtil.put(sceneId+materialsCacheKey,materials, cachetimeout, TimeUnit.MINUTES);
}
}
return materials;
}
private List<Equipinfo> GetEquipinfos() {
List<Equipinfo> equipinfoList=(List<Equipinfo>)GlobalCacheUtil.get("equipinfo");
if(equipinfoList==null)
{
equipinfoList = equipinfoService.lambdaQuery().eq(Equipinfo::getIsdeleted, 0).list();
GlobalCacheUtil.put("equipinfo",equipinfoList, cachetimeout, TimeUnit.MINUTES);
}
return equipinfoList;
}
public void clearCache(String sceneId) {
redisUtils.del(sceneId+routingHeaderCacheKey);
GlobalCacheUtil.remove(sceneId+routingHeaderCacheKey);
redisUtils.del(sceneId+routingsupportingCacheKey);
GlobalCacheUtil.remove(sceneId+routingsupportingCacheKey);
redisUtils.del(sceneId+routingSupportingReplaceCacheKey);
GlobalCacheUtil.remove(sceneId+routingSupportingReplaceCacheKey);
redisUtils.del(sceneId+routingDetailCacheKey);
GlobalCacheUtil.remove(sceneId+routingDetailCacheKey);
redisUtils.del(sceneId+routingDetailEquipCacheKey);
GlobalCacheUtil.remove(sceneId+routingDetailEquipCacheKey);
redisUtils.del(sceneId+routingDetailConnectCacheKey);
GlobalCacheUtil.remove(sceneId+routingDetailConnectCacheKey);
redisUtils.del(sceneId+routingDiscreteParamCacheKey);
GlobalCacheUtil.remove(sceneId+routingDiscreteParamCacheKey);
}
}
package com.aps.service.Algorithm;
import com.aps.common.util.GlobalCacheUtil;
import com.aps.common.util.SnowFlackIdWorker;
import com.aps.common.util.redis.RedisUtils;
import com.aps.entity.*;
import com.aps.entity.Algorithm.BOMBuildResult;
import com.aps.entity.Algorithm.IDAndChildID.GroupResult;
import com.aps.entity.Algorithm.OrderMaterial;
import com.aps.entity.Algorithm.OrderMaterialRequirement;
import com.aps.entity.basic.*;
import com.aps.mapper.RoutingHeaderMapper;
import com.aps.mapper.RoutingSupportingReplaceMapper;
import com.aps.mapper.RoutingsupportingMapper;
import com.aps.service.*;
import com.aps.service.impl.LanuchServiceImpl;
import com.aps.service.plan.MachineSchedulerService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
/**
* 作者:佟礼
* 时间:2025-12-08
*/
@Service
public class MaterialRequirementServicebf {
private List<Material> _materials;
private List<Entry> _allOperations;
private List<Machine> _Machines;
private List<GroupResult> _entryRel;
private List<RoutingHeader> headers;
private List<Routingsupporting> routingsupportings=new ArrayList<>();
private List<RoutingSupportingReplace> routingsupportingreplaces=new ArrayList<>();
List<RoutingDetail> allRoutingDetails=new ArrayList<>();
List<RoutingDetailEquip> allroutingDetailEquips=new ArrayList<>();
List<RoutingDetailConnect> allroutingDetailconnections=new ArrayList<>();
List<RoutingDiscreteParam> allroutingDiscreteParams=new ArrayList<>();
@Autowired
RoutingDetailConnectService routingDetailConnectService;
@Autowired
private RedisUtils redisUtils;
private List<Order> orders;
@Autowired
RoutingHeaderMapper routingHeaderMapper;
@Autowired
RoutingSupportingReplaceMapper routingSupportingReplaceMapper;
@Autowired
RoutingsupportingMapper routingsupportingMapper;
@Autowired
RoutingDataService _routingDataService;
@Autowired
private EquipinfoService equipinfoService;
@Autowired
private RoutingDiscreteParamService _routingDiscreteParamService;
@Autowired
private LanuchService lanuchService;
private LocalDateTime baseTime ;
private MachineSchedulerService machineScheduler;
private GlobalParam globalParam;
public void init(List<Material> materials,List<Order> _orders,List<Entry> allOperations,List<GroupResult> entryRel,MachineSchedulerService _machineScheduler,List<Machine> machines,GlobalParam _GlobalParam)
{
orders = _orders;
_allOperations=allOperations;
_materials=materials;
_entryRel=entryRel;
machineScheduler=_machineScheduler;
_Machines=machines;
globalParam=_GlobalParam;
}
private static final int cachetimeout = 60;
private String cacheKey="_MR_";
private String routingHeaderCacheKey=cacheKey+ "RoutingHeader";
private String routingsupportingCacheKey=cacheKey+ "Routingsupporting";
private String routingSupportingReplaceCacheKey=cacheKey+ "RoutingSupportingReplace";
private String routingDetailCacheKey=cacheKey+ "RoutingDetail";
private String routingDetailEquipCacheKey=cacheKey+ "RoutingDetailEquip";
private String routingDetailConnectCacheKey=cacheKey+ "RoutingDetailConnect";
private String routingDiscreteParamCacheKey=cacheKey+ "RoutingDiscreteParam";
public Map<Integer,Object> preloadRoutingCache(String sceneId,List<Order> _orders,List<Material> materials,boolean isIsCheckSf) {
Map<Integer,Object> reslte=new HashMap<>(2);
reslte.put(1,null);
reslte.put(2,null);
this._materials=materials;
List<Integer> routingIds= _orders.stream()
.filter(t->t.getRoutingId()!=null)
.map(Order::getRoutingId)
.distinct()
.collect(Collectors.toList());
List<RoutingHeader> routingHeaders=null;
LambdaQueryWrapper<RoutingHeader> wrapper = new LambdaQueryWrapper<>();
wrapper.in(RoutingHeader::getId, routingIds);
// .eq(RoutingHeader::getIsDeleted, 0)
// .eq(RoutingHeader::getApprovalStatus, 1);
routingHeaders = routingHeaderMapper.selectList(wrapper);
List<Routingsupporting> routingsupportings=null;
// 查询并缓存Routingsupporting
LambdaQueryWrapper<Routingsupporting> routingsupportingwrapper = new LambdaQueryWrapper<>();
routingsupportingwrapper.in(Routingsupporting::getRoutingHeaderId, routingIds)
.eq(Routingsupporting::getIsdeleted, 0);
routingsupportings = routingsupportingMapper.selectList(routingsupportingwrapper);
// 查询并缓存RoutingSupportingReplace
List<RoutingSupportingReplace> replaces=null;
if (routingsupportings != null && !routingsupportings.isEmpty()) {
List<String> routingsupportingids = routingsupportings.stream()
.map(Routingsupporting::getStrId)
.distinct()
.collect(Collectors.toList());
LambdaQueryWrapper<RoutingSupportingReplace> routingsupportingreplacewrapper = new LambdaQueryWrapper<>();
routingsupportingreplacewrapper.in(RoutingSupportingReplace::getStrsupid, routingsupportingids)
.eq(RoutingSupportingReplace::getIsdeleted, 0);
replaces = routingSupportingReplaceMapper.selectList(routingsupportingreplacewrapper);
}
List<Material> useMaterials=new ArrayList<>();
Set<String> useMaterialids=new HashSet<>();
if(routingsupportings!=null&&routingsupportings.size()>0)
{
List<String> materialIds=new ArrayList<>();
for (Order order : _orders) {
Integer routingid=order.getRoutingId();
List<Routingsupporting> MaterialRequirements = routingsupportings.stream()
.filter(t -> t.getRoutingHeaderId().equals(routingid))
.collect(Collectors.toList());
if(MaterialRequirements!=null)
{
List<OrderMaterialRequirement> materialRequirementList=new ArrayList<>();
for (Routingsupporting component : MaterialRequirements) {
// 查找物料(流式处理替代First)
String materialId= component.getMaterialId();
Material material = materials.stream()
.filter(m -> m.getId().equals(materialId))
.findFirst()
.orElse(null);
if (material != null) {
if(!useMaterialids.contains(materialId)) {
useMaterials.add(material);
useMaterialids.add(materialId);
}
// OrderMaterialRequirement orderMaterial = new OrderMaterialRequirement();
// orderMaterial.setRoutingDetailId(component.getRoutingDetailId());
// orderMaterial.setMaterialCode(material.getCode());
// orderMaterial.setMaterialName(material.getName());
// orderMaterial.setMaterialTypeName(material.getMaterialTypeName());
// orderMaterial.setMaterialId(material.getId());
// materialRequirementList.add(orderMaterial);
if(!material.getMaterialTypeName().equals("MP")&&isIsCheckSf)
{
materialIds.add(materialId);
}
}
// order.setMaterialRequirementList(materialRequirementList);
}
}
}
if(replaces!=null&&replaces.size()>0) {
for (RoutingSupportingReplace routingSupportingReplace : replaces) {
String materialID1 = routingSupportingReplace.getMaterialid();
if (!useMaterialids.contains(materialID1)) {
Material material = _materials.stream()
.filter(m -> m.getId().equals(materialID1))
.findFirst()
.orElse(null);
if (material != null) {
useMaterials.add(material);
useMaterialids.add(materialID1);
}
}
}
}
if(materialIds!=null&&materialIds.size()>0)
{
Map<Integer,Object> reslte1=preloadSfRoutingBomCache(materialIds, routingHeaders, routingsupportings, replaces);
List<Long> routingIds1=(List<Long>) reslte1.get(1);
if(routingIds1!=null)
{
List<Long> equipids= preloadSfRoutingCache(sceneId,routingIds1);
reslte.put(1,equipids);
}
List<Material> useMaterials1=(List<Material>) reslte1.get(2);
if(useMaterials1!=null) {
for (Material m:useMaterials1) {
String materialID1= m.getId();
if(!useMaterialids.contains(materialID1)) {
useMaterials.add(m);
useMaterialids.add(materialID1);
}
}
}
reslte.put(2,useMaterials);
}
}
SaveBomCache(sceneId, routingHeaders, routingsupportings, replaces);
return reslte;
}
private Map<Integer,Object> preloadSfRoutingBomCache(List<String> materialIDs,List<RoutingHeader> headers,List<Routingsupporting> routingsupportings,List<RoutingSupportingReplace> routingsupportingreplaces) {
Map<Integer,Object> reslte=new HashMap<>(2);
reslte.put(1,null);
reslte.put(2,null);
List<Material> useMaterials=new ArrayList<>();
Set<String> useMaterialids=new HashSet<>();
List<Long> routingIds=new ArrayList<>();
List<Long> routingIds1=new ArrayList<>();
Long routingId = 0l;
List<Routingsupporting> routingsupportings1 = new ArrayList<>();
List<RoutingSupportingReplace> routingsupportingreplaces1 = new ArrayList<>();
for (String materialID:materialIDs) {
RoutingHeader headers1 = headers.stream()
.filter(t -> t.getMaterialId().equals(materialID))
.findFirst().orElse(null);
if (headers1 == null) {
LambdaQueryWrapper<RoutingHeader> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(RoutingHeader::getMaterialId, materialID)
.eq(RoutingHeader::getIsDeleted, 0);
// .eq(RoutingHeader::getApprovalStatus, 1); // 添加 is_deleted=0 过滤条件
headers1 = routingHeaderMapper.selectList(wrapper).stream().findFirst().orElse(null);
if (headers1 != null) {
headers.add(headers1);
routingId = headers1.getId().longValue();
routingIds.add(routingId);
}
}else {
routingIds1.add(headers1.getId().longValue());
}
}
if (routingIds != null&&routingIds.size()>0) {
LambdaQueryWrapper<Routingsupporting> routingsupportingwrapper = new LambdaQueryWrapper<>();
routingsupportingwrapper.in(Routingsupporting::getRoutingHeaderId, routingIds)
.eq(Routingsupporting::getIsdeleted, 0);
routingsupportings1 = routingsupportingMapper.selectList(routingsupportingwrapper);
routingsupportings.addAll(routingsupportings1);
List<String> routingsupportingids = routingsupportings1.stream()
.map(Routingsupporting::getStrId)
.distinct()
.collect(Collectors.toList());
LambdaQueryWrapper<RoutingSupportingReplace> routingsupportingreplacewrapper = new LambdaQueryWrapper<>();
routingsupportingreplacewrapper.in(RoutingSupportingReplace::getStrsupid, routingsupportingids)
.eq(RoutingSupportingReplace::getIsdeleted, 0);
routingsupportingreplaces1 = routingSupportingReplaceMapper.selectList(routingsupportingreplacewrapper);
routingsupportingreplaces.addAll(routingsupportingreplaces1);
List<String> materialIds=new ArrayList<>();
for (Routingsupporting routingsupporting:routingsupportings1) {
String materialID1= routingsupporting.getMaterialId();
Material material = _materials.stream()
.filter(m -> m.getId().equals(materialID1))
.findFirst()
.orElse(null);
if (material != null) {
if(!useMaterialids.contains(materialID1)) {
useMaterials.add(material);
useMaterialids.add(materialID1);
}
if(!material.getMaterialTypeName().equals("MP")) {
materialIds.add(materialID1);
}
}
}
for (RoutingSupportingReplace routingSupportingReplace:routingsupportingreplaces1) {
String materialID1= routingSupportingReplace.getMaterialid();
if(!useMaterialids.contains(materialID1)) {
Material material = _materials.stream()
.filter(m -> m.getId().equals(materialID1))
.findFirst()
.orElse(null);
if (material != null) {
useMaterials.add(material);
useMaterialids.add(materialID1);
}
}
}
Map<Integer,Object> r1=preloadSfRoutingBomCache(materialIds, headers, routingsupportings, routingsupportingreplaces);
List<Long> routingIds2=(List<Long>) r1.get(1);
List<Material> useMaterials2=( List<Material>) r1.get(2);
if(routingIds2!=null)
{
routingIds.addAll(routingIds2);
}
if(useMaterials2!=null&&useMaterials2.size()>0) {
for (Material m:useMaterials2) {
String materialID1= m.getId();
if(!useMaterialids.contains(materialID1)) {
useMaterials.add(m);
useMaterialids.add(materialID1);
}
}
}
}
if(routingIds1!=null)
{
routingIds.addAll(routingIds1);
}
reslte.put(1,routingIds);
reslte.put(2,useMaterials);
return reslte;
}
private List<Long> preloadSfRoutingCache(String sceneId,List<Long> routingIds) {
List<RoutingDetail> RoutingDetails = null;
List<RoutingDetailEquip> routingDetailEquips = null;
List<RoutingDetailConnect> connections = null;
List<RoutingDiscreteParam> routingDiscreteParams=null;
if (routingIds != null || routingIds.size() > 0) {
RoutingDetails = lanuchService.getRoutingDetails(routingIds);
if (RoutingDetails == null && RoutingDetails.size() == 0) {
return null;
}
routingDetailEquips = lanuchService.getRoutingDetailEquip(routingIds);
LambdaQueryWrapper<RoutingDetailConnect> routingDetailConnectwrapper = new LambdaQueryWrapper<>();
routingDetailConnectwrapper.in(RoutingDetailConnect::getRoutingHeaderId, routingIds)
.eq(RoutingDetailConnect::getIsdeleted, 0); // 添加 isdeleted=0 过滤条件
connections = routingDetailConnectService.list(routingDetailConnectwrapper);
List<Long> routingDetailIds = RoutingDetails.stream()
.map(RoutingDetail::getId)
.distinct()
.collect(Collectors.toList());
routingDiscreteParams = _routingDiscreteParamService.lambdaQuery()
.in(RoutingDiscreteParam::getRoutingDetailId, routingDetailIds)
.eq(RoutingDiscreteParam::getIsDeleted, 0)
.list();
SaveDetailCache(sceneId,RoutingDetails,routingDetailEquips,connections,routingDiscreteParams);
if (routingDetailEquips != null && routingDetailEquips.size() > 0) {
List<Long> equipIds = routingDetailEquips.stream()
.map(RoutingDetailEquip::getEquipId)
.distinct() // 提取Exec_ID
.collect(Collectors.toList());
return equipIds;
}
}
return null;
}
/**
* 构建多级BOM需求网络
* @return 所有物料需求列表
*/
public List<OrderMaterialRequirement> buildMultiLevelRequirementNetwork(String sceneId,LocalDateTime _baseTime) {
baseTime=_baseTime;
List<OrderMaterialRequirement> allRequirements = new ArrayList<>();
List<Order> childorders = new ArrayList<>();
List<Entry> _newEntrys = new ArrayList<>();
List<Machine> _newMachines = new ArrayList<>();
List<Integer> routingIds = _allOperations.stream()
.filter(t->t.getRoutingId()!=null)
.map(Entry::getRoutingId)
.distinct()
.collect(Collectors.toList());
if(routingIds.size()==0)
{
return null;
}
for (Order demand : orders) {
// 跳过已有父订单的需求
if (demand.getFinishOrderId() != null && !demand.getFinishOrderId().isEmpty()) {
continue;
}
// 递归展开BOM层级(通过结果对象接收out参数数据)
BOMBuildResult result = buildOrderBOM(demand.getRoutingId(),"", demand.getOrderId(), demand.getOrderId(),
demand.getQuantity(), 0,demand,0);
allRequirements.addAll(result.getMaterialRequirements());
childorders.addAll(result.getChildOrders());
_newEntrys.addAll(result.getNewEntrys());
_newMachines.addAll(result.getNewMachines());
}
// 将子订单添加到全局订单列表
if (orders != null) {
orders.addAll(childorders);
// _allOperations.addAll(_newEntrys);
_Machines.addAll(_newMachines);
}
return allRequirements;
}
/**
* 构建订单BOM
* @param parent 父项ID
* @param materialID 物料ID
* @param mainorderId 主订单ID
* @param childorderId 子订单ID
* @param parentQuantity 父项数量(Java中用double替代decimal,若需高精度可用BigDecimal)
* @param level 层级
* @return 包含物料需求列表和子订单列表的结果对象(替代C#的out参数)
*/
public BOMBuildResult buildOrderBOM(int parent, String materialID, String mainorderId,
String childorderId, double parentQuantity, int level,Order forder,int finishOpertionID) {
forder.setCreateBom(true);
RoutingHeader routingHeaders= headers.stream()
.filter(t->t.getId()==parent|| t.getMaterialId().equals(materialID))
.findFirst()
.orElse(null);
List<RoutingHeader> headers1;
// 若未找到产品,返回空结果(根据业务可调整为抛出异常)
if (routingHeaders==null) {
return null;
}
List<OrderMaterialRequirement> materialRequirements = new ArrayList<>();
List<Order> childorders2 = new ArrayList<>();
List<Entry> _newEntrys = new ArrayList<>();
List<Machine> _newMachines = new ArrayList<>();
// 遍历产品的工序,递归构建工序BOM
List<Entry> Operations= _allOperations.stream()
.filter(t->t.getOrderId().equals(childorderId))
.collect(Collectors.toList());
if (Operations != null) {
for (Entry operation : Operations) {
if(finishOpertionID!=0)
{
if(operation.getTargetFinishedOperationId()==null)
{
operation.setTargetFinishedOperationId(new ArrayList<>());
}
operation.getTargetFinishedOperationId().add(finishOpertionID);
}
// 调用BuildOperationBOM方法(返回结果对象替代out参数)
BOMBuildResult operationResult = buildOperationBOM(mainorderId, childorderId,
parentQuantity, operation, level,forder);
// // 合并物料需求和子订单
if(operationResult!=null) {
materialRequirements.addAll(operationResult.getMaterialRequirements());
childorders2.addAll(operationResult.getChildOrders());
_newEntrys.addAll(operationResult.getNewEntrys());
_newMachines.addAll(operationResult.getNewMachines());
}
}
}
return new BOMBuildResult(materialRequirements, childorders2,_newEntrys);
}
private Map<Integer, Object> CreateChild(Order order,String materialID,int finishOpertionID)
{
String sceneId="";
Long routingIds=0l;
List<Routingsupporting> routingsupportings1=new ArrayList<>();
List<RoutingSupportingReplace> routingsupportingreplaces1 =new ArrayList<>();
RoutingHeader headers1= headers.stream()
.filter(t->t.getMaterialId().equals(materialID))
.findFirst().orElse(null);
if(headers1==null) {
LambdaQueryWrapper<RoutingHeader> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(RoutingHeader::getMaterialId, materialID)
.eq(RoutingHeader::getIsDeleted, 0);
// .eq(RoutingHeader::getApprovalStatus, 1); // 添加 is_deleted=0 过滤条件
headers1 = routingHeaderMapper.selectList(wrapper).stream().findFirst().orElse(null);
if(headers1!=null) {
headers.add(headers1);
routingIds=headers1.getId().longValue();
LambdaQueryWrapper<Routingsupporting> routingsupportingwrapper = new LambdaQueryWrapper<>();
routingsupportingwrapper.in(Routingsupporting::getRoutingHeaderId, routingIds)
.eq(Routingsupporting::getIsdeleted, 0);
routingsupportings1 = routingsupportingMapper.selectList(routingsupportingwrapper);
routingsupportings.addAll(routingsupportings1);
List<String> routingsupportingids = routingsupportings1.stream()
.filter(t->t.getStrId()!=null)
.map(Routingsupporting::getStrId)
.distinct()
.collect(Collectors.toList());
if(routingsupportingids.size()>0)
{
LambdaQueryWrapper<RoutingSupportingReplace> routingsupportingreplacewrapper = new LambdaQueryWrapper<>();
routingsupportingreplacewrapper.in(RoutingSupportingReplace::getStrsupid, routingsupportingids)
.eq(RoutingSupportingReplace::getIsdeleted, 0);
routingsupportingreplaces1 = routingSupportingReplaceMapper.selectList(routingsupportingreplacewrapper);
routingsupportingreplaces.addAll(routingsupportingreplaces1);
}
}
}
else {
routingIds=headers1.getId().longValue();
}
if(headers1==null)
{
return null;
}
Long headersid=routingIds;
List<RoutingDetail> RoutingDetails= allRoutingDetails.stream()
.filter(t->t.getRoutingHeaderId()==headersid)
.collect(Collectors.toList());
List<RoutingDetailEquip> routingDetailEquips=null;
List<RoutingDetailConnect> connections=null;
if(RoutingDetails==null||RoutingDetails.size()==0) {
RoutingDetails = lanuchService.getRoutingDetails(headers1.getId());
allRoutingDetails.addAll(RoutingDetails);
routingDetailEquips = lanuchService.getRoutingDetailEquip(headers1.getId(), headers1.getCode());
allroutingDetailEquips.addAll(routingDetailEquips);
LambdaQueryWrapper<RoutingDetailConnect> routingDetailConnectwrapper = new LambdaQueryWrapper<>();
routingDetailConnectwrapper.eq(RoutingDetailConnect::getRoutingHeaderId, routingIds)
.eq(RoutingDetailConnect::getIsdeleted, 0); // 添加 isdeleted=0 过滤条件
connections = routingDetailConnectService.list(routingDetailConnectwrapper);
allroutingDetailconnections.addAll(connections);
}
if(routingDetailEquips==null)
{
routingDetailEquips= allroutingDetailEquips.stream()
.filter(t->t.getRoutingHeaderId()==headersid)
.collect(Collectors.toList());
}
order.setRoutingId(headers1.getId());
order.setRoutingCode(headers1.getCode());
ProdLaunchOrder prodOrderMain= convertToLaunchOrder(order,"");
List<RoutingDetailEquip> finalRoutingDetailEquips = routingDetailEquips;
List<ProdProcessExec> processExecList = RoutingDetails.stream()
.map(detail -> lanuchService.createProcessExec(prodOrderMain, detail, sceneId, finalRoutingDetailEquips,0))
.collect(Collectors.toList());
List<Equipinfo> equipinfoList = equipinfoService.lambdaQuery().eq(Equipinfo::getIsdeleted, 0).list();
List<ProdEquipment> ProdEquipmentList= lanuchService.batchInsertEquipMent(routingDetailEquips, sceneId,processExecList,false,equipinfoList);
Map<String, String> routingDetailIdToExecIdMap = processExecList.stream()
.collect(Collectors.toMap(
exec -> exec.getRoutingDetailId() + "_" + exec.getOrderId(), // 复合键:工序ID_订单ID
ProdProcessExec::getExecId,
(existing, replacement) -> existing)); // 处理重复key的情况
if(connections==null)
{
connections= allroutingDetailconnections.stream()
.filter(t->t.getRoutingHeaderId()==headersid)
.collect(Collectors.toList());
}
List<ProdOrderProcess> ProdOrderProcesslist= connections.stream()
.map(connection -> lanuchService.createProcessRelation(prodOrderMain, connection, sceneId, routingDetailIdToExecIdMap))
.collect(Collectors.toList());
List<Long> routingDetailIds = RoutingDetails.stream()
.map(RoutingDetail::getId)
.distinct()
.collect(Collectors.toList());
List<RoutingDiscreteParam> routingDiscreteParams= allroutingDiscreteParams.stream()
.filter(t->routingDetailIds.contains(t.getRoutingDetailId()))
.collect(Collectors.toList());
if(routingDiscreteParams==null||routingDiscreteParams.size()==0) {
routingDiscreteParams = _routingDiscreteParamService.lambdaQuery()
.in(RoutingDiscreteParam::getRoutingDetailId, routingDetailIds)
.eq(RoutingDiscreteParam::getIsDeleted, 0)
.list();
allroutingDiscreteParams.addAll(routingDiscreteParams);
}
List<Order> ProdLaunchOrders=new ArrayList<>();
ProdLaunchOrders.add(order);
Map<Integer, Object> list=_routingDataService.CreateEntry( sceneId, ProdEquipmentList, ProdLaunchOrders, routingDiscreteParams, ProdOrderProcesslist, processExecList,_entryRel,finishOpertionID );
List<Machine> machines=new ArrayList<>();
List<Machine> allmachines = (List<Machine>) GlobalCacheUtil.get("machines");
if (allmachines == null || allmachines.size() == 0) {
allmachines = (List<Machine>) redisUtils.get("machines");
if (allmachines == null || allmachines.size() == 0) {
List<Long> equipIds = ProdEquipmentList.stream()
.map(ProdEquipment::getEquipId)
.distinct() // 提取Exec_ID
.collect(Collectors.toList());
machines=allmachines.stream().filter(t->equipIds.contains(t.getId())).collect(Collectors.toList());
}
}
if (machines == null || machines.size() == 0) {
machines= _routingDataService.InitCalendarToAllMachines(sceneId,ProdEquipmentList,machineScheduler, globalParam.isIsUseCalendar());
}
if(list.get(1)!=null)
{
_allOperations.addAll((List<Entry>)list.get(1));
_entryRel=(List<GroupResult>)list.get(2);
}
Map<Integer, Object> rest=new HashMap<>();
rest.put(1,list.get(1));
rest.put(2,machines);
return rest;
}
private ProdLaunchOrder convertToLaunchOrder(Order order, String sceneId) {
try {
ProdLaunchOrder launchOrder = new ProdLaunchOrder();
launchOrder.setOrderId(order.getOrderId());
launchOrder.setSceneId(sceneId);
launchOrder.setSerie(order.getSerie());
launchOrder.setCreateUser("GA");
launchOrder.setMaterialCode(order.getMaterialCode());
launchOrder.setMaterialName(order.getMaterialName());
// launchOrder.setStartDate(order.get);
launchOrder.setEndDate(order.getDueDate());
// launchOrder.setOrderPriority(order.getPrioritry());
launchOrder.setOrderPriority(order.getPriority());
launchOrder.setQuantity(order.getQuantity());
launchOrder.setMaterialId(order.getMaterialId());
launchOrder.setRoutingId(order.getRoutingId());
launchOrder.setRoutingCode("");
return launchOrder;
} catch (Exception e) {
return null;
}
}
/**
* 构建工序BOM需求
* @param orderId 主订单ID
* @param childorderId 子订单ID
* @param parentQuantity 父项数量
* @param operation 工序对象
* @param level 层级
* @return 包含物料需求列表和子订单列表的结果对象(替代C#的out参数)
*/
public BOMBuildResult buildOperationBOM(String orderId, String childorderId, double parentQuantity,
Entry operation, int level,Order forder) {
List<OrderMaterialRequirement> materialRequirements = new ArrayList<>();
List<Order> _childorders = new ArrayList<>();
List<Entry> _newEntrys = new ArrayList<>();
List<Machine> _newMachines = new ArrayList<>();
List<Routingsupporting> MaterialRequirements= routingsupportings.stream()
.filter(t->t.getRoutingDetailId().equals(operation.getRoutingDetailId()))
.collect(Collectors.toList());
if (MaterialRequirements != null&&MaterialRequirements.size()>0) {
for (Routingsupporting component : MaterialRequirements) {
double allneeded = parentQuantity * component.getMainQty().doubleValue();
double needed = allneeded;
// 查找物料(流式处理替代First)
Material material = _materials.stream()
.filter(m -> m.getId().equals(component.getMaterialId()))
.findFirst()
.orElse(null);
if (material == null) {
return null;
}
OrderMaterialRequirement orderMaterial= MaterialStock(material,"",orderId,childorderId,operation,allneeded,needed);
double useStock=0;
if(orderMaterial!=null) {
useStock = orderMaterial.getUseStock();
materialRequirements.add(orderMaterial);
orderMaterial.setLevel(level);
}
orderMaterial.setMaterialCode(component.getMaterialNumber());
orderMaterial.setMaterialName(component.getMaterialName());
needed -= useStock;
if (needed <= 0) {
orderMaterial.setYpQty(allneeded - needed);
orderMaterial.setQjQty(needed);
continue;
}
List<RoutingSupportingReplace> routingsupportingreplaces2 = routingsupportingreplaces.stream().filter(t->t.getStrsupid().equals(component.getStrId())&&t.getMaterialid()!=component.getMaterialId()).collect(Collectors.toList());
if (routingsupportingreplaces2 != null && routingsupportingreplaces2.size() > 1)
{
for (RoutingSupportingReplace rsr:routingsupportingreplaces2) {
OrderMaterialRequirement orderMaterial1= MaterialStock(null,rsr.getMaterialid(),orderId,childorderId,operation,allneeded,needed);
if(orderMaterial1!=null) {
useStock = orderMaterial1.getUseStock();
needed -= useStock;
orderMaterial.setUseStock(orderMaterial.getUseStock()+useStock);
orderMaterial.getReplaceMaterial().add(orderMaterial1);
if (needed <= 0) {
break;
}
}
}
}
if (needed <= 0) {
orderMaterial.setYpQty(allneeded - needed);
orderMaterial.setQjQty(needed);
continue;
}
MaterialInTransit(material,"",orderMaterial,needed);
needed -= orderMaterial.getUseTransit();
if (routingsupportingreplaces2 != null && routingsupportingreplaces2.size() > 1)
{
for (RoutingSupportingReplace rsr:routingsupportingreplaces2) {
OrderMaterialRequirement orderMaterial1= orderMaterial.getReplaceMaterial().stream()
.filter(t->t.getMaterialId().equals(rsr.getMaterialid()))
.findFirst()
.orElse(null);
MaterialInTransit(null,rsr.getMaterialid(),orderMaterial1,needed);
needed -= orderMaterial1.getUseTransit();
LocalDateTime earliestTime= orderMaterial.getArrivalTime().compareTo(orderMaterial1.getArrivalTime())>0?orderMaterial.getArrivalTime():orderMaterial1.getArrivalTime();
orderMaterial.setArrivalTime(earliestTime);
orderMaterial.setUseTransit(orderMaterial.getUseTransit()+orderMaterial1.getUseTransit());
if (needed <= 0) {
break;
}
}
}
if (needed <= 0) {
orderMaterial.setYpQty(allneeded - needed);
orderMaterial.setQjQty(needed);
continue;
}
if (needed > 0) {
orderMaterial.setYpQty(allneeded - needed);
orderMaterial.setQjQty(needed);
if (material.getMaterialTypeName().equals("MP") ) {
// 处理原材料采购时间
orderMaterial.setPurchaseStartTime(baseTime);
// 采购结束时间 = 采购开始时间 + 采购提前期(天)
LocalDateTime purchaseEndTime = baseTime.plusDays(material.getPurchaseLeadTime());
orderMaterial.setPurchaseEndTime(purchaseEndTime);
} else {
// 处理半成品/成品的现有订单
List<Order> orders2 = orders.stream()
.filter(t -> t.getMaterialId().equals(material.getId()) && t.getSYQuantity() > 0)
.sorted(Comparator.comparing(Order::getDueDate))
.collect(Collectors.toList());
if (!orders2.isEmpty()) {
for (Order order : orders2) {
if (order.getFinishOrderId() == null) {
order.setFinishOrderId(new ArrayList<>());
order.setTargetFinishedOperationId(new ArrayList<>());
}
order.getFinishOrderId().add(forder.getId());
order.getTargetFinishedOperationId().add(operation.getId());
orderMaterial.getProductOrderID().add(order.getId());
double useq = Math.min(needed, order.getSYQuantity());
needed -= useq;
order.setSYQuantity(order.getSYQuantity() - useq);
//防止已经生成过一次
if (!order.isCreateBom()) {
// 递归构建BOM
int l = level + 1;
BOMBuildResult childResult = buildOrderBOM(0, material.getId(),
orderId, order.getOrderId(),
order.getQuantity(), l,order,operation.getId());
materialRequirements.addAll(childResult.getMaterialRequirements());
_childorders.addAll(childResult.getChildOrders());
_newEntrys.addAll(childResult.getNewEntrys());
_newMachines.addAll(childResult.getNewMachines());
operation.getDependentOnOrderIds().add(order.getId());
}
if (needed <= 0) {
break;
}
}
}
// 更新已配和缺件数量
orderMaterial.setYpQty(allneeded - needed);
orderMaterial.setQjQty(needed);
if (needed > 0&&globalParam.isIsCheckSf()) {
// 创建新的子订单
Order childorder = new Order();
String OrderId = UUID.randomUUID().toString().replace("-", "");
childorder.setOrderId(OrderId);
childorder.setMaterialId(material.getId());
childorder.setMaterialCode(material.getCode());
childorder.setMaterialName(material.getName());
childorder.setOrderCode(material.getCode());
childorder.setQuantity((int) orderMaterial.getQjQty());
childorder.setFinishOrderId(new ArrayList<>());
childorder.getFinishOrderId().add(forder.getId());
childorder.setNewCreate(true);
childorder.setTargetFinishedOperationId(new ArrayList<>());
childorder.getTargetFinishedOperationId().add(operation.getId());
childorder.setSerie(forder.getSerie());
childorder.setStartDate(forder.getStartDate());
childorder.setDueDate(forder.getDueDate());
childorder.setPriority(forder.getPriority());
childorder.setActualPriority(forder.getActualPriority());
Map<Integer, Object> list= CreateChild(childorder,material.getId(), operation.getId());
if(list==null)
{
continue;
}
_childorders.add(childorder);
List<Entry> newentrys=(List<Entry>)list.get(1);
_newEntrys.addAll(newentrys);
_newMachines.addAll((List<Machine>)list.get(2));
orderMaterial.getProductOrderID().add(childorder.getId());
operation.getDependentOnOrderIds().add(childorder.getId());
// 递归构建BOM
int l = level + 1;
BOMBuildResult childResult = buildOrderBOM(0, material.getId(),
orderId, childorder.getOrderId(),
childorder.getQuantity(), l,childorder,0);
materialRequirements.addAll(childResult.getMaterialRequirements());
_childorders.addAll(childResult.getChildOrders());
_newEntrys.addAll(childResult.getNewEntrys());
_newMachines.addAll(childResult.getNewMachines());
}
}
}
// 计算预计可用时间
LocalDateTime arrivalTime = orderMaterial.getArrivalTime();
LocalDateTime purchaseEndTime = orderMaterial.getPurchaseEndTime();
LocalDateTime useTime = null;
if (arrivalTime == null) {
useTime = purchaseEndTime;
} else {
if (purchaseEndTime != null && purchaseEndTime.isAfter(arrivalTime)) {
useTime = purchaseEndTime;
} else {
useTime = arrivalTime;
}
}
orderMaterial.setUseTime(useTime);
}
}
return new BOMBuildResult(materialRequirements, _childorders,_newEntrys);
}
private OrderMaterialRequirement MaterialStock(Material material,String materialId,String orderId, String childorderId, Entry operation,double allneeded, double needed ) {
OrderMaterialRequirement orderMaterial = new OrderMaterialRequirement();
orderMaterial.setOrderId(orderId);
orderMaterial.setOperationId(operation.getId());
orderMaterial.setChildOrderId(StringUtils.isBlank(childorderId) ? orderId : childorderId);
orderMaterial.setRequiredQuantity(allneeded);
double availableNow = material.getCurrentStock();
orderMaterial.setMaterialCode(material.getCode());
orderMaterial.setMaterialName(material.getName());
orderMaterial.setMaterialTypeName(material.getMaterialTypeName());
orderMaterial.setMaterialId(material.getId());
// orderMaterial.setCheckLeadTime(material.getCkeckLeadTime());
// 扣减现有库存
double useStock = Math.min(needed, availableNow);
material.setCurrentStock(material.getCurrentStock() - useStock);
orderMaterial.setUseStock(useStock);
return orderMaterial;
}
private void MaterialInTransit(Material material,String materialId, OrderMaterialRequirement orderMaterial, double needed ){
// 处理在途物料
double accumulated = 0;
LocalDateTime earliestTime = LocalDateTime.of(2000,1,1,0,0,0);
double useTransit = 0;
if (material == null) {
material = _materials.stream()
.filter(m -> m.getId().equals(materialId))
.findFirst()
.orElse(null);
if (material == null) {
return ;
}
}
// 按到货时间排序在途物料
List<MaterialSupply> sortedInTransit = material.getInTransit().stream()
.filter(t -> t.getQuantity() > 0)
.sorted(Comparator.comparing(MaterialSupply::getArrivalTime))
.collect(Collectors.toList());
for (MaterialSupply supply : sortedInTransit) {
double useq = Math.min(needed, supply.getQuantity());
useTransit += useq;
needed -= useq;
supply.setQuantity(supply.getQuantity() - useq);
earliestTime=earliestTime.compareTo(supply.getArrivalTime())>0?earliestTime:supply.getArrivalTime();
if (needed <= 0) {
break;
}
}
orderMaterial.setUseTransit(useTransit);
orderMaterial.setArrivalTime(earliestTime);
}
private void SaveBomCache(String sceneId,List<RoutingHeader> routingHeaders,List<Routingsupporting> routingsupportings,List<RoutingSupportingReplace> replaces)
{
redisUtils.set(sceneId+routingHeaderCacheKey,routingHeaders);
GlobalCacheUtil.put(sceneId+routingHeaderCacheKey,routingHeaders, cachetimeout, TimeUnit.MINUTES);
redisUtils.set(sceneId+routingsupportingCacheKey,routingsupportings);
GlobalCacheUtil.put(sceneId+routingsupportingCacheKey,routingsupportings, cachetimeout, TimeUnit.MINUTES);
redisUtils.set(sceneId+routingSupportingReplaceCacheKey,replaces);
GlobalCacheUtil.put(sceneId+routingSupportingReplaceCacheKey,replaces, cachetimeout, TimeUnit.MINUTES);
}
private void SaveDetailCache(String sceneId,List<RoutingDetail> RoutingDetails,List<RoutingDetailEquip> routingDetailEquips,List<RoutingDetailConnect> connections,List<RoutingDiscreteParam> routingDiscreteParams)
{
redisUtils.set(sceneId+routingDetailCacheKey,RoutingDetails);
GlobalCacheUtil.put(sceneId+routingDetailCacheKey,RoutingDetails, cachetimeout, TimeUnit.MINUTES);
redisUtils.set(sceneId+routingDetailEquipCacheKey,routingDetailEquips);
GlobalCacheUtil.put(sceneId+routingDetailEquipCacheKey,routingDetailEquips, cachetimeout, TimeUnit.MINUTES);
redisUtils.set(sceneId+routingDetailConnectCacheKey,connections);
GlobalCacheUtil.put(sceneId+routingDetailConnectCacheKey,connections, cachetimeout, TimeUnit.MINUTES);
redisUtils.set(sceneId+routingDiscreteParamCacheKey,routingDiscreteParams);
GlobalCacheUtil.put(sceneId+routingDiscreteParamCacheKey,routingDiscreteParams, cachetimeout, TimeUnit.MINUTES);
}
private List<RoutingHeader> GetRoutingHeader(String sceneId) {
List<RoutingHeader> RoutingHeaders=(List<RoutingHeader>)GlobalCacheUtil.get(sceneId+routingHeaderCacheKey);
if(RoutingHeaders==null)
{
RoutingHeaders=(List<RoutingHeader>)redisUtils.get(sceneId+routingHeaderCacheKey);
if(RoutingHeaders!=null)
{
GlobalCacheUtil.put(sceneId+routingHeaderCacheKey,RoutingHeaders, cachetimeout, TimeUnit.MINUTES);
}
}
return RoutingHeaders;
}
private List<Routingsupporting> GetRoutingsupportings(String sceneId) {
List<Routingsupporting> Routingsupportings=(List<Routingsupporting>)GlobalCacheUtil.get(sceneId+routingsupportingCacheKey);
if(Routingsupportings==null)
{
Routingsupportings=(List<Routingsupporting>)redisUtils.get(sceneId+routingsupportingCacheKey);
if(Routingsupportings!=null)
{
GlobalCacheUtil.put(sceneId+routingsupportingCacheKey,Routingsupportings, cachetimeout, TimeUnit.MINUTES);
}
}
return Routingsupportings;
}
private List<RoutingSupportingReplace> GetRoutingSupportingReplaces(String sceneId) {
List<RoutingSupportingReplace> RoutingSupportingReplaces=(List<RoutingSupportingReplace>)GlobalCacheUtil.get(sceneId+routingSupportingReplaceCacheKey);
if(RoutingSupportingReplaces==null)
{
RoutingSupportingReplaces=(List<RoutingSupportingReplace>)redisUtils.get(sceneId+routingSupportingReplaceCacheKey);
if(RoutingSupportingReplaces!=null)
{
GlobalCacheUtil.put(sceneId+routingSupportingReplaceCacheKey,RoutingSupportingReplaces, cachetimeout, TimeUnit.MINUTES);
}
}
return RoutingSupportingReplaces;
}
private List<RoutingDetail> GetRoutingDetails(String sceneId) {
List<RoutingDetail> RoutingDetails=(List<RoutingDetail>)GlobalCacheUtil.get(sceneId+routingDetailCacheKey);
if(RoutingDetails==null)
{
RoutingDetails=(List<RoutingDetail>)redisUtils.get(sceneId+routingDetailCacheKey);
if(RoutingDetails!=null)
{
GlobalCacheUtil.put(sceneId+routingDetailCacheKey,RoutingDetails, cachetimeout, TimeUnit.MINUTES);
}
}
return RoutingDetails;
}
private List<RoutingDetailEquip> GetRoutingDetailEquips(String sceneId) {
List<RoutingDetailEquip> RoutingDetailEquips=(List<RoutingDetailEquip>)GlobalCacheUtil.get(sceneId+routingDetailEquipCacheKey);
if(RoutingDetailEquips==null)
{
RoutingDetailEquips=(List<RoutingDetailEquip>)redisUtils.get(sceneId+routingDetailEquipCacheKey);
if(RoutingDetailEquips!=null)
{
GlobalCacheUtil.put(sceneId+routingDetailEquipCacheKey,RoutingDetailEquips, cachetimeout, TimeUnit.MINUTES);
}
}
return RoutingDetailEquips;
}
private List<RoutingDetailConnect> GetRoutingDetailConnect(String sceneId) {
List<RoutingDetailConnect> RoutingDetailConnects=(List<RoutingDetailConnect>)GlobalCacheUtil.get(sceneId+routingDetailConnectCacheKey);
if(RoutingDetailConnects==null)
{
RoutingDetailConnects=(List<RoutingDetailConnect>)redisUtils.get(sceneId+routingDetailConnectCacheKey);
if(RoutingDetailConnects!=null)
{
GlobalCacheUtil.put(sceneId+routingDetailConnectCacheKey,RoutingDetailConnects, cachetimeout, TimeUnit.MINUTES);
}
}
return RoutingDetailConnects;
}
private List<RoutingDiscreteParam> GetRoutingDiscreteParam(String sceneId) {
List<RoutingDiscreteParam> RoutingDiscreteParams=(List<RoutingDiscreteParam>)GlobalCacheUtil.get(sceneId+routingDiscreteParamCacheKey);
if(RoutingDiscreteParams==null)
{
RoutingDiscreteParams=(List<RoutingDiscreteParam>)redisUtils.get(sceneId+routingDiscreteParamCacheKey);
if(RoutingDiscreteParams!=null)
{
GlobalCacheUtil.put(sceneId+routingDiscreteParamCacheKey,RoutingDiscreteParams, cachetimeout, TimeUnit.MINUTES);
}
}
return RoutingDiscreteParams;
}
public void clearCache(String sceneId) {
redisUtils.del(sceneId+routingHeaderCacheKey);
GlobalCacheUtil.remove(sceneId+routingHeaderCacheKey);
redisUtils.del(sceneId+routingsupportingCacheKey);
GlobalCacheUtil.remove(sceneId+routingsupportingCacheKey);
redisUtils.del(sceneId+routingSupportingReplaceCacheKey);
GlobalCacheUtil.remove(sceneId+routingSupportingReplaceCacheKey);
redisUtils.del(sceneId+routingDetailCacheKey);
GlobalCacheUtil.remove(sceneId+routingDetailCacheKey);
redisUtils.del(sceneId+routingDetailEquipCacheKey);
GlobalCacheUtil.remove(sceneId+routingDetailEquipCacheKey);
redisUtils.del(sceneId+routingDetailConnectCacheKey);
GlobalCacheUtil.remove(sceneId+routingDetailConnectCacheKey);
redisUtils.del(sceneId+routingDiscreteParamCacheKey);
GlobalCacheUtil.remove(sceneId+routingDiscreteParamCacheKey);
}
}
......@@ -597,7 +597,7 @@ if(targetOp.getSequence()>1) {
OperatRels = IdGroupingWithDualSerial.addNode(OperatRels, targetGroupIndex, newId, newParentIds, newChildIds,targetOp.getExecId());
}
}
chromosome.setOperatRel(OperatRels);
chromosome.setOperatRel(new CopyOnWriteArrayList<>(OperatRels) );
//当前组的
groupResult = OperatRels.get(targetGroupIndex);
......@@ -799,7 +799,7 @@ if(targetOp.getSequence()>1) {
// 添加新数据
OperatRels = IdGroupingWithDualSerial.addNewDataWithIsolatedGroup(OperatRels, newIdList, newChildIdList);
chromosome.setOperatRel(OperatRels);
chromosome.setOperatRel(new CopyOnWriteArrayList<>(OperatRels) );
//全局ID
int globalOpId = chromosome.getGlobalOpList().stream()
.mapToInt(GlobalOperationInfo::getGlobalOpId)
......@@ -986,7 +986,7 @@ if(targetOp.getSequence()>1) {
List<GroupResult> OperatRels = chromosome.getOperatRel();
OperatRels = IdGroupingWithDualSerial.deleteNodeByGlobalSerial(OperatRels, opId);
chromosome.setOperatRel(OperatRels);
chromosome.setOperatRel(new CopyOnWriteArrayList<>(OperatRels) );
Entry targetOp = allOperations.stream()
.filter(o -> o.getId() == opId)
.findFirst()
......@@ -1184,7 +1184,7 @@ if(targetOp.getSequence()>1) {
chromosome.setMachines(ProductionDeepCopyUtil.deepCopyList(chromosome.getInitMachines(),Machine.class) );
GeneticDecoder decoder = new GeneticDecoder(globalParam,baseTime, chromosome.getMachines(),
chromosome.getOrders(), null, machineScheduler,chromosome.getOrderMaterials());
chromosome.getOrders(), null, machineScheduler,null,chromosome.getScenarioID());
chromosome.setResultOld(ProductionDeepCopyUtil.deepCopyList(chromosome.getResult(),GAScheduleResult.class));
chromosome.getResult().clear();
......
package com.aps.service.Algorithm;
import java.util.*;
import java.util.stream.Collectors;
/**
* 作者:佟礼
* 时间:2026-01-27
*/
public class TestSortService {
public void test() {
List<DataNode> list = new ArrayList<>();
// 初始化数据
list.add(new DataNode(1, 18000, 1, 1));
list.add(new DataNode(2, 882000, 1, 2));
list.add(new DataNode(3, 2260078, 2, 1));
list.add(new DataNode(4, 2695678, 2, 2));
list.add(new DataNode(5, 0, 3, 1));
list.add(new DataNode(6, 950400, 3, 2));
list.add(new DataNode(7, 0, 4, 1));
list.add(new DataNode(8, 18000, 4, 2));
list.add(new DataNode(9, 3419998, 5, 1));
list.add(new DataNode(10, 1022646, 5, 2));
// 1. 预处理:计算每个 groupId 对应的最小时间(作为该组的排位基准)
Map<Integer, Long> groupMinTimeMap = list.stream()
.collect(Collectors.groupingBy(
DataNode::getGroupId,
Collectors.mapping(DataNode::getTime, Collectors.minBy(Long::compare))
))
.entrySet().stream()
.collect(Collectors.toMap(Map.Entry::getKey, e -> e.getValue().orElse(0L)));
// 2. 执行排序
list.sort((a, b) -> {
// 首先比较所属组的基准时间
long minTimeA = groupMinTimeMap.get(a.getGroupId());
long minTimeB = groupMinTimeMap.get(b.getGroupId());
if (minTimeA != minTimeB) {
return Long.compare(minTimeA, minTimeB);
}
// 如果基准时间相同(比如 group3 和 group4 都是 0),则按 groupId 排序(可选)
if (a.getGroupId() != b.getGroupId()) {
return Integer.compare(a.getGroupId(), b.getGroupId());
}
// 同一组内,按 no 升序
return Integer.compare(a.getNo(), b.getNo());
});
// 输出结果
System.out.println("ID\ttime\tgroupid\tno");
list.forEach(System.out::println);
}
public static List<DataNode> customSort(List<DataNode> dataList) {
// 按groupId分组
Map<Integer, List<DataNode>> groupMap = dataList.stream()
.collect(Collectors.groupingBy(data -> data.groupId));
// 对每个组内的数据按no升序排序
groupMap.values().forEach(group ->
group.sort(Comparator.comparingInt(data -> data.no))
);
// 计算每个组的最小时间(用于组间排序)
Map<Integer, Long> groupMinTime = new HashMap<>();
for (Map.Entry<Integer, List<DataNode>> entry : groupMap.entrySet()) {
long minTime = entry.getValue().stream()
.mapToLong(data -> data.time)
.min()
.orElse(Long.MAX_VALUE);
groupMinTime.put(entry.getKey(), minTime);
}
// 将组按最小时间排序,然后展开
return groupMap.entrySet().stream()
.sorted(Map.Entry.comparingByValue((list1, list2) ->
Long.compare(groupMinTime.get(list1.get(0).groupId),
groupMinTime.get(list2.get(0).groupId))))
.flatMap(entry -> entry.getValue().stream())
.collect(Collectors.toList());
}
// 更简洁的写法
public static List<DataNode> customSort2(List<DataNode> dataList) {
// 按groupId分组并在组内按no排序
Map<Integer, List<DataNode>> groupMap = dataList.stream()
.collect(Collectors.groupingBy(
data -> data.groupId,
Collectors.collectingAndThen(
Collectors.toList(),
list -> {
list.sort(Comparator.comparingInt(d -> d.no));
return list;
}
)
));
// 将组转为列表并按组内最小时间排序
List<List<DataNode>> sortedGroups = new ArrayList<>(groupMap.values());
sortedGroups.sort(Comparator.comparing(
group -> group.stream().mapToLong(d -> d.time).min().orElse(Long.MAX_VALUE)
));
// 展开所有组
return sortedGroups.stream()
.flatMap(List::stream)
.collect(Collectors.toList());
}
public static List<DataNode> sortData(List<DataNode> data) {
// 步骤1: 找出每个groupid的最小time
Map<Integer, Integer> groupMinTime = data.stream()
.collect(Collectors.groupingBy(
item -> item.groupId,
Collectors.mapping(item -> item.time,
Collectors.collectingAndThen(
Collectors.toList(),
list -> list.stream().min(Integer::compareTo).orElse(0)
))
));
// 步骤2: 按照以下规则排序
List<DataNode> sorted = new ArrayList<>(data);
sorted.sort((a, b) -> {
int aMinTime = groupMinTime.get(a.groupId);
int bMinTime = groupMinTime.get(b.groupId);
// 首先按照group的最小time排序
if (aMinTime != bMinTime) {
return Integer.compare(aMinTime, bMinTime);
}
// 如果group最小time相同,按groupid排序
if (a.groupId != b.groupId) {
return Integer.compare(a.groupId, b.groupId);
}
// 同一个group内,按no排序
return Integer.compare(a.no, b.no);
});
return sorted;
}
public void test1() {
// 创建测试数据
List<DataNode> originalData = Arrays.asList(
new DataNode(1, 18000, 1, 1),
new DataNode(2, 882000, 1, 2),
new DataNode(3, 2260078, 2, 1),
new DataNode(4, 2695678, 2, 2),
new DataNode(5, 0, 3, 1),
new DataNode(6, 950400, 3, 2),
new DataNode(7, 0, 4, 1),
new DataNode(8, 18000, 4, 2),
new DataNode(9, 3419998, 5, 1),
new DataNode(10, 1022646, 5, 2)
);
System.out.println("排序前:");
originalData.forEach(System.out::println);
System.out.println("\n排序后:");
List<DataNode> sortedData = sortData(originalData);
sortedData.forEach(System.out::println);
}
}
......@@ -31,6 +31,7 @@ import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.*;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
......@@ -131,124 +132,8 @@ public class PlanResultService {
public Chromosome execute1() {
try {
//List<ScheduleResultDetail> details=new ArrayList<>();
// ScheduleResultDetail detail1=new ScheduleResultDetail();
//
// detail1.setOneTime(100);//单件工时
//
//
// ScheduleResultDetail detail2=new ScheduleResultDetail();
//
// detail2.setOneTime(200);//单件工时
// details.add(detail1);
// details.add(detail2);
// mergeSegmentsWithDifferentOneTime(details, 50);
// 1. 读取数据
List<Machine> machines = loadData("machines.json", Machine.class);
List<Product> products = loadData("products.json", Product.class);
List<Order> orders = loadData("orders.json", Order.class);
// 设置机器信息到班次中
for (Machine machine : machines) {
if (machine.getShifts() != null) {
for (Shift shift : machine.getShifts()) {
shift.setMachineId(machine.getId());
shift.setMachineName(machine.getName());
}
}
// 调试:打印机器和班次信息
System.out.println("Machine: " + machine.getId() + ", Name: " + machine.getName());
if (machine.getShifts() != null) {
for (Shift shift : machine.getShifts()) {
System.out.println(" Shift: " + shift.getStartTime() + " - " + shift.getEndTime() +
", Status: " + shift.getStatus() +
", MachineId: " + shift.getMachineId() +
", MachineName: " + shift.getMachineName());
}
}
}
ScheduleParams param = new ScheduleParams();
param.setBaseTime(LocalDateTime.of(2025, 11, 1, 0, 0, 0));
// List<MesHoliday> holidays= _MesHolidayService.list();
// 创建节假日
// 将节假日添加到所有设备中
// addHolidaysToAllMachines(machines);
// 3. 创建调度服务
MachineSchedulerService machineScheduler = new MachineSchedulerService(
param.getBaseTime());
// 4. 初始化机器时间线
for (Machine machine : machines) {
MachineTimeline timeline = machineScheduler.getOrCreateTimeline(machine);
machine.setAvailability(timeline.getSegments());
}
// 3. 构建订单-工序数据
List<Entry> allOperations = new ArrayList<>();
Random rnd = new Random(); // 注意:此处变量声明但未使用,可根据实际需求保留或移除
int id = 1;
for (Order order : orders) {
order.setDueDate(LocalDateTime.of(2025, 12, 1,0,0,0));
// 假设products是一个List<Product>,根据Product的Id查找对应的产品
Product product = products.stream()
.filter(p -> p.getId() == order.getProductId())
.findFirst()
.orElseThrow(() -> new IllegalArgumentException("未找到对应产品: " + order.getProductId()));
int sequence = 1;
for (Operation o : product.getOperations()) { // 假设Product类有getOperations()方法返回工序列表
Entry entry = new Entry();
entry.setId(id);
// entry.setGroupId(order.getId());
entry.setSequence(sequence);
entry.setMachineOptions(o.getMachineOptions()); // 假设Operation类有获取机器选项的方法
entry.setPriority(order.getPriority());
entry.setQuantity(order.getQuantity());
// entry.setMaterialRequirements(o.getMaterialRequirements()); // 假设Operation类有获取物料需求的方法
if (sequence != 1) {
OperationDependency od=new OperationDependency();
od.setPrevOperationId(id - 1);
entry.getPrevEntryIds().add(od); // 假设Entry类有getPrevEntryIds()返回List<Integer>
}
allOperations.add(entry);
sequence++;
id++;
}
}
GlobalParam globalParam=new GlobalParam();
// 5. 执行调度算法
param.initAdaptiveParams(allOperations.size());
GeneticAlgorithm scheduler =new GeneticAlgorithm(globalParam,machines,orders,null,machineScheduler,null,materialRequirementService,_sceneService); //new GeneticAlgorithm(products, machines, orders, machineScheduler);
Chromosome Chromosomes =scheduler.Run(param,allOperations);
WriteScheduleSummary(Chromosomes);
ScheduleOperationService ScheduleOperation=new ScheduleOperationService();
LocalDateTime ds= LocalDateTime.of(2025, 12, 7, 23, 59);
// ScheduleOperation.moveOperation(Chromosomes,3, (int)ChronoUnit.SECONDS.between(param.getBaseTime(), ds),(Long)2,param.getBaseTime(), globalParam);
WriteScheduleSummary(Chromosomes);
return Chromosomes;
} catch (Exception e) {
throw new RuntimeException("调度执行失败", e);
}
}
public Chromosome execute2(String SceneId) {
try {
......@@ -288,13 +173,15 @@ order.setDueDate(LocalDateTime.of(2025, 12, 1,0,0,0));
Map<Long,Double> machineIds=(Map<Long,Double>)list.get(3);
// List<Long> equipIDs= materialRequirementService.preloadRoutingCache(SceneId,orders,Materials,globalParam.isIsCheckSf());
Map<Integer,Object> reslte=materialRequirementService.preloadRoutingCache(SceneId,param.getBaseTime(), orders,Materials,entrys,globalParam.isIsCheckSf());
List<Long> equipIDs=(List<Long>) reslte.get(1);
List<Material> Materials1=(List<Material>) reslte.get(2);
Set machineIds1=machineIds.keySet();
// if(equipIDs!=null&&equipIDs.size()>0)
// {
// machineIds1.addAll(equipIDs);
// }
List<Long> machineIds1=machineIds.keySet().stream().collect(Collectors.toList());
if(equipIDs!=null&&equipIDs.size()>0)
{
machineIds1.addAll(equipIDs);
}
machines= machines.stream().filter(t->machineIds1.contains(t.getId())).collect(Collectors.toList());
......@@ -316,7 +203,7 @@ order.setDueDate(LocalDateTime.of(2025, 12, 1,0,0,0));
// 5. 执行调度算法
GeneticAlgorithm scheduler =new GeneticAlgorithm(globalParam,machines,orders,Materials,machineScheduler,entryRel,materialRequirementService,_sceneService); //new GeneticAlgorithm(products, machines, orders, machineScheduler);
GeneticAlgorithm scheduler =new GeneticAlgorithm(globalParam,machines,orders,Materials1,machineScheduler,entryRel,materialRequirementService,_sceneService,SceneId); //new GeneticAlgorithm(products, machines, orders, machineScheduler);
param.initAdaptiveParams(entrys.size());
double[] customWeights = new double[] { 0.4, 0.1, 0.1, 0.1, 0.3 }; // 延迟时间权重提升到0.5
//完工时间、总流程时间、总换型时间、机器负载标准差、延迟时间
......@@ -327,7 +214,7 @@ order.setDueDate(LocalDateTime.of(2025, 12, 1,0,0,0));
kpiCalculator.calculatekpi();
_sceneService.saveChromosomeToFile(chromosome, SceneId);
// WriteScheduleSummary(chromosome);
WriteScheduleSummary(chromosome);
return chromosome;
......@@ -871,7 +758,7 @@ order.setDueDate(LocalDateTime.of(2025, 12, 1,0,0,0));
machines= machines.stream().filter(t->machineIds.contains(t.getId())).collect(Collectors.toList());
// 5. 执行调度算法
GeneticAlgorithm scheduler =new GeneticAlgorithm(globalParam,machines,orders,Materials,machineScheduler,entryRel,materialRequirementService,_sceneService); //new GeneticAlgorithm(products, machines, orders, machineScheduler);
GeneticAlgorithm scheduler =new GeneticAlgorithm(globalParam,machines,orders,Materials,machineScheduler,entryRel,materialRequirementService,_sceneService,SceneId); //new GeneticAlgorithm(products, machines, orders, machineScheduler);
param.initAdaptiveParams(entrys.size());
double[] customWeights = new double[] { 0.4, 0.1, 0.1, 0.1, 0.3 }; // 延迟时间权重提升到0.5
//完工时间、总流程时间、总换型时间、机器负载标准差、延迟时间
......@@ -881,7 +768,7 @@ order.setDueDate(LocalDateTime.of(2025, 12, 1,0,0,0));
kpiCalculator.calculatekpi();
chromosomes.setScenarioID(SceneId);
chromosomes.setBaseTime(param.getBaseTime());
chromosomes.setOperatRel(entryRel);
chromosomes.setOperatRel(new CopyOnWriteArrayList<>(entryRel));
// 保存chromosomes到文件
_sceneService.saveChromosomeToFile(chromosomes, SceneId);
......@@ -920,21 +807,30 @@ order.setDueDate(LocalDateTime.of(2025, 12, 1,0,0,0));
for (GAScheduleResult job : sortedJobs) {
StringBuilder sb = new StringBuilder();
String TargetFinishedOperationIds="";
if(job.getTargetFinishedOperationId()!=null)
{
TargetFinishedOperationIds= job.getTargetFinishedOperationId().stream()
.map(String::valueOf) // 把每个Integer转成String
.collect(Collectors.joining(","));
}
sb.append(String.format(
"[%d-%d]:[%s-%s] Order %d,OrderID %s, Machine %d, Operation %d, Batch %.1f, processingTime %.1f, 前处理 %d, 后处理 %d, 离散参数 %d",
"[%d-%d]:[%s-%s] Order %d,OrderID %s, Machine %d, Operation %d, Batch %.1f, processingTime %.1f, 前处理 %d, 后处理 %d, 离散参数 %d, bomtime %s,TargetOperationId %s",
job.getStartTime(),
job.getEndTime(),
ConvertTime(job.getStartTime()),
ConvertTime(job.getEndTime()),
job.getGroupId(),
job.getOrderId(),
job.getOrderId(),
job.getMachineId(),
job.getOperationId(),
job.getQuantity(),
job.getProcessingTime(),
job.getPreTime(),
job.getTeardownTime(),
job.getChangeOverTime()
job.getChangeOverTime(),
ConvertTime(job.getBomTime()),
TargetFinishedOperationIds
));
// 追加基因详情
......@@ -1365,6 +1261,8 @@ private GlobalParam InitGlobalParam()
material.setId(m.getId());
material.setMaterialType(m.getMaterialType());
material.setMaterialTypeName(m.getMaterialTypeName());
material.setCode(m.getCode());
material.setName(m.getName());
material.setCkeckLeadTime(m.getInspectDuration());
material.setPurchaseLeadTime(m.getPurchaseDuration());
......
......@@ -10,8 +10,8 @@ spring:
pathmatch:
matching-strategy: ant_path_matcher # Spring Boot 2.6+ 需要这个配置
redis:
host: 192.168.0.181
port: 6380
host: 39.100.88.40
port: 6379
timeout: 120000
database: 10
password: redis@228!
......@@ -55,7 +55,7 @@ spring:
# Oracle数据源
oracle:
driver-class-name: oracle.jdbc.OracleDriver
url: jdbc:oracle:thin:@//192.168.0.181:1522/ORCLPDB1 # ORCL为你的Oracle实例名
url: jdbc:oracle:thin:@//39.100.78.207:7002/ORCLPDB1 # ORCL为你的Oracle实例名
username: mes # 替换为你的Oracle用户名
password: root_mes123456 # 替换为你的Oracle密码
# sqlserver:
......
package com.aps.demo;
import com.aps.entity.Algorithm.GAScheduleResult;
import com.aps.entity.DiscreteParameterDuration;
import com.aps.entity.RoutingDiscreteParam;
import com.aps.entity.basic.Entry;
import com.aps.entity.basic.Machine;
import com.aps.service.DiscreteParameterDurationService;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.ApplicationContext;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
@SpringBootTest
public class DiscreteParameterDurationTest {
// 使用依赖注入而不是直接new
@Autowired
private DiscreteParameterDurationService calculator;
@Autowired
private ApplicationContext applicationContext;
@Test
public void testChangeoverRules() {
System.out.println("=== 离散参数换型时间计算测试 ===\n");
// 1. 创建测试数据
List<GAScheduleResult> existingGenes = createTestTasks();
List<Entry> allOperations = createTestOperations();
Machine machine = createMachine();
List<DiscreteParameterDuration> parameterDurations = createParameterConfigs();
// 2. 测试场景1:工作时间长规则
testWorkingDurationRule(existingGenes, allOperations, machine, parameterDurations);
// 3. 测试场景2:绝对工作时间长规则
testAbsoluteDurationRule(existingGenes, allOperations, machine, parameterDurations);
// 4. 测试场景3:工作最大间隔规则
testMaxIntervalRule(existingGenes, allOperations, machine, parameterDurations);
// 5. 测试场景4:工单数量规则
testOrderCountRule(existingGenes, allOperations, machine, parameterDurations);
// 6. 测试场景5:累计数量规则
testAccumulatedQuantityRule(existingGenes, allOperations, machine, parameterDurations);
// 7. 测试场景6:参数切换换型
testParameterChangeoverRule(existingGenes, allOperations, machine, parameterDurations);
}
/**
* 测试场景1:工作时间长规则
* 规则:工作时间超过7200秒(2小时)需要换型
*/
private void testWorkingDurationRule(List<GAScheduleResult> existingGenes,
List<Entry> allOperations,
Machine machine,
List<DiscreteParameterDuration> parameterDurations) {
System.out.println("=== 测试场景1:工作时间长规则 ===");
// 创建一个新的任务D
Entry taskD = createOperation("TaskD", "001");
taskD.setId(4);
taskD.setExecId("D");
// 计算换型时间
double changeoverTime = calculator.calculateChangeoverTime(
existingGenes, taskD, machine, allOperations, 36000); // 10小时后
System.out.println("场景描述:A(2h)+B(2h)+C(2h)累计6小时 > 2小时阈值");
System.out.println("任务D需要的换型时间:" + changeoverTime + "分钟");
System.out.println("预期结果:需要换型\n");
}
/**
* 测试场景2:绝对工作时间长规则
* 规则:绝对工作时间超过14400秒(4小时)需要换型
*/
private void testAbsoluteDurationRule(List<GAScheduleResult> existingGenes,
List<Entry> allOperations,
Machine machine,
List<DiscreteParameterDuration> parameterDurations) {
System.out.println("=== 测试场景2:绝对工作时间长规则 ===");
Entry taskD = createOperation("TaskD", "001");
taskD.setId(4);
taskD.setExecId("D");
double changeoverTime = calculator.calculateChangeoverTime(
existingGenes, taskD, machine, allOperations, 21600); // 6小时后
System.out.println("场景描述:从A开始到现在6小时 > 4小时阈值");
System.out.println("任务D需要的换型时间:" + changeoverTime + "分钟");
System.out.println("预期结果:需要换型\n");
}
/**
* 测试场景3:工作最大间隔规则
* 规则:任务间隔超过7200秒(2小时)需要换型
*/
private void testMaxIntervalRule(List<GAScheduleResult> existingGenes,
List<Entry> allOperations,
Machine machine,
List<DiscreteParameterDuration> parameterDurations) {
System.out.println("=== 测试场景3:工作最大间隔规则 ===");
Entry taskD = createOperation("TaskD", "001");
taskD.setId(4);
taskD.setExecId("D");
// 设置任务D的开始时间在C之后3小时
double changeoverTime = calculator.calculateChangeoverTime(
existingGenes, taskD, machine, allOperations, 28800); // 8小时后(C结束2小时后)
System.out.println("场景描述:C在6h结束,D在8h开始,间隔2小时=阈值");
System.out.println("任务D需要的换型时间:" + changeoverTime + "分钟");
System.out.println("预期结果:不需要换型(刚好等于阈值)\n");
}
/**
* 测试场景4:工单数量规则
* 规则:连续生产3个任务需要换型
*/
private void testOrderCountRule(List<GAScheduleResult> existingGenes,
List<Entry> allOperations,
Machine machine,
List<DiscreteParameterDuration> parameterDurations) {
System.out.println("=== 测试场景4:工单数量规则 ===");
Entry taskD = createOperation("TaskD", "001");
taskD.setId(4);
taskD.setExecId("D");
double changeoverTime = calculator.calculateChangeoverTime(
existingGenes, taskD, machine, allOperations, 21600);
System.out.println("场景描述:A(1)+B(2)+C(3)+D(4)=连续4个相同参数任务");
System.out.println("任务D需要的换型时间:" + changeoverTime + "分钟");
System.out.println("预期结果:需要换型\n");
}
/**
* 测试场景5:累计数量规则
* 规则:累计数量达到3000个需要换型
*/
private void testAccumulatedQuantityRule(List<GAScheduleResult> existingGenes,
List<Entry> allOperations,
Machine machine,
List<DiscreteParameterDuration> parameterDurations) {
System.out.println("=== 测试场景5:累计数量规则 ===");
Entry taskD = createOperation("TaskD", "001");
taskD.setId(4);
taskD.setExecId("D");
// 修正:使用Double类型
taskD.setQuantity(1000.0);
double changeoverTime = calculator.calculateChangeoverTime(
existingGenes, taskD, machine, allOperations, 21600);
System.out.println("场景描述:A(1000)+B(1000)+C(8000)累计10000个 > 3000阈值");
System.out.println("任务D需要的换型时间:" + changeoverTime + "分钟");
System.out.println("预期结果:需要换型\n");
}
/**
* 测试场景6:参数切换换型
* 规则:参数001切换到002需要换型
*/
private void testParameterChangeoverRule(List<GAScheduleResult> existingGenes,
List<Entry> allOperations,
Machine machine,
List<DiscreteParameterDuration> parameterDurations) {
System.out.println("=== 测试场景6:参数切换换型规则 ===");
// 创建参数不同的任务D
Entry taskD = createOperation("TaskD", "002"); // 参数从001变为002
taskD.setId(4);
taskD.setExecId("D");
double changeoverTime = calculator.calculateChangeoverTime(
existingGenes, taskD, machine, allOperations, 21600);
System.out.println("场景描述:A/B/C使用参数001,D使用参数002");
System.out.println("任务D需要的换型时间:" + changeoverTime + "分钟");
System.out.println("预期结果:需要换型(参数变化)\n");
}
/**
* 创建测试任务(基于您的JSON数据)
*/
private List<GAScheduleResult> createTestTasks() {
List<GAScheduleResult> tasks = new ArrayList<>();
// 任务A:0-7200秒(2小时),数量1000
tasks.add(createTask("A", 0, 7200, 1, 1000.0));
// 任务B:7200-14400秒(2小时),数量1000
tasks.add(createTask("B", 7200, 14400, 1, 1000.0));
// 任务C:14400-21600秒(2小时),数量8000
tasks.add(createTask("C", 14400, 21600, 1, 8000.0));
return tasks;
}
/**
* 创建测试工序
*/
private List<Entry> createTestOperations() {
List<Entry> operations = new ArrayList<>();
// 任务A
Entry taskA = createOperation("TaskA", "001");
taskA.setId(1);
taskA.setExecId("A");
// 修正:使用Double类型
taskA.setQuantity(1000.0);
operations.add(taskA);
// 任务B
Entry taskB = createOperation("TaskB", "001");
taskB.setId(2);
taskB.setExecId("B");
taskB.setQuantity(1000.0);
operations.add(taskB);
// 任务C
Entry taskC = createOperation("TaskC", "001");
taskC.setId(3);
taskC.setExecId("C");
taskC.setQuantity(8000.0);
operations.add(taskC);
return operations;
}
/**
* 创建测试设备
*/
private Machine createMachine() {
Machine machine = new Machine();
machine.setId(1L); // Machine的ID可能是Long类型
machine.setName("设备A");
return machine;
}
/**
* 创建参数配置
*/
private List<DiscreteParameterDuration> createParameterConfigs() {
List<DiscreteParameterDuration> configs = new ArrayList<>();
// 工作时间长规则:2小时=7200秒
configs.add(createConfig("001", "WorkingDuration", null,
new BigDecimal("7200.0"), new BigDecimal("30.0")));
// 绝对工作时间长规则:4小时=14400秒
configs.add(createConfig("001", "AbsoluteDuration", null,
new BigDecimal("14400.0"), new BigDecimal("30.0")));
// 工作最大间隔规则:2小时=7200秒
configs.add(createConfig("001", "MaxInterval", null,
new BigDecimal("7200.0"), new BigDecimal("30.0")));
// 工单数量规则:3个任务
configs.add(createConfig("001", "OrderCount", null,
new BigDecimal("3.0"), new BigDecimal("30.0")));
// 累计数量规则:3000个
configs.add(createConfig("001", "AccumulatedQuantity", null,
new BigDecimal("3000.0"), new BigDecimal("30.0")));
// 参数切换换型:参数001切换到002需要30分钟
configs.add(createConfig("001", null, "002",
null, new BigDecimal("30.0")));
return configs;
}
/**
* 创建GAScheduleResult任务
*/
private GAScheduleResult createTask(String execId, int startTime, int endTime,
int machineId, Double quantity) {
GAScheduleResult task = new GAScheduleResult();
task.setExecId(execId);
task.setStartTime(startTime);
task.setEndTime(endTime);
task.setMachineId(machineId);
//task.setChangeoverTime(0);
// 注意:GAScheduleResult的quantity字段也需要是Double类型
// 如果GAScheduleResult的quantity是BigDecimal,需要转换
// task.setQuantity(new BigDecimal(quantity.toString()));
return task;
}
/**
* 创建Entry工序
*/
private Entry createOperation(String name, String parameterId) {
Entry entry = new Entry();
// 添加离散参数
List<RoutingDiscreteParam> discreteParams = new ArrayList<>();
RoutingDiscreteParam param = new RoutingDiscreteParam();
param.setGroupId("参数组一");
param.setParameterId(parameterId);
discreteParams.add(param);
entry.setDiscreteParameter(discreteParams);
return entry;
}
/**
* 创建参数配置
*/
private DiscreteParameterDuration createConfig(String parameterId, String exp1,
String exp2, BigDecimal measureduration,
BigDecimal duration) {
DiscreteParameterDuration config = new DiscreteParameterDuration();
config.setId(java.util.UUID.randomUUID().toString());
config.setCreationtime(LocalDateTime.now());
config.setCreatoruserid(1L);
config.setLastmodificationtime(LocalDateTime.now());
config.setLastmodifieruserid(1L);
config.setIsdeleted(0L);
config.setGroupid("参数组一");
config.setGroupname("参数组一");
config.setParameterid(parameterId);
config.setParametername("参数" + parameterId);
config.setExp1(exp1);
config.setExp2(exp2);
if (measureduration != null) {
config.setMeasureduration(measureduration.longValue());
}
if (duration != null) {
config.setDuration(duration);
}
config.setUnit("分钟");
config.setUnitid(1L);
config.setMeasureunit("秒");
config.setMeasureunitid(2L);
return config;
}
/**
* 测试数据验证方法
*/
@Test
public void testDataValidation() {
System.out.println("=== 测试数据验证 ===");
List<DiscreteParameterDuration> configs = createParameterConfigs();
printConfigInfo(configs);
// 验证数据类型
for (DiscreteParameterDuration config : configs) {
System.out.printf("配置验证 - ID: %s, 参数ID: %s, 规则类型: %s%n",
config.getId(), config.getParameterid(), config.getExp1());
System.out.printf(" 阈值: %s %s, 换型时间: %s %s%n",
config.getMeasureduration(), config.getMeasureunit(),
config.getDuration(), config.getUnit());
System.out.println(" 数据类型验证通过 ✓");
}
}
/**
* 边界条件测试
*/
@Test
public void testBoundaryConditions() {
System.out.println("=== 边界条件测试 ===");
// 测试1:刚好达到阈值
testBoundaryScenario("刚好达到阈值", 7200.0, 7200.0);
// 测试2:刚好超过阈值
testBoundaryScenario("刚好超过阈值", 7201.0, 7200.0);
// 测试3:刚好低于阈值
testBoundaryScenario("刚好低于阈值", 7199.0, 7200.0);
}
private void testBoundaryScenario(String scenario, Double actual, Double threshold) {
System.out.printf("场景: %s, 实际值: %s, 阈值: %s%n", scenario, actual, threshold);
if (actual >= threshold) {
System.out.println(" 结果: 需要换型 ✓");
} else {
System.out.println(" 结果: 不需要换型 ✓");
}
}
/**
* 辅助方法:打印配置信息
*/
private void printConfigInfo(List<DiscreteParameterDuration> configs) {
System.out.println("=== 当前配置信息 ===");
for (DiscreteParameterDuration config : configs) {
System.out.printf("参数: %s, 规则: %s, 阈值: %s, 换型时间: %s%n",
config.getParameterid(),
config.getExp1(),
config.getMeasureduration() != null ? config.getMeasureduration() + config.getMeasureunit() : "N/A",
config.getDuration() != null ? config.getDuration() + config.getUnit() : "N/A");
}
System.out.println();
}
}
\ No newline at end of file
......@@ -8,6 +8,7 @@ import com.aps.entity.Gantt.ProductGanttVO;
import com.aps.entity.basic.Machine;
import com.aps.entity.basic.MaintenanceWindow;
import com.aps.service.Algorithm.NSGAIIUtils;
import com.aps.service.Algorithm.TestSortService;
import com.aps.service.plan.PlanResultService;
import com.aps.service.plan.SceneService;
import org.junit.jupiter.api.Test;
......@@ -35,15 +36,16 @@ public class PlanResultServiceTest {
// Chromosome chromosome= planResultService.moveChromosome("qwerty",3);
// planResultService.execute2("B7881EF032044B9BA4F6007875510B70");
// NSGAIIUtils nsgaiiUtils=new NSGAIIUtils();
// TestSortService sortService=new TestSortService();
// sortService.test1();
// nsgaiiUtils.Test();
planResultService.execute2("0DCB1301C57C48B68154789B0FAB8B98");
planResultService.execute2("83D729F5E0694F25A71614B1991D7457");
// planResultService.execute2("726D4C1A712B4B1393175BD44B775B66");
// planResultService.execute2("265F24B6DF3C40E4B17D193B0CC8AAF2");
// LocalDateTime t= LocalDateTime.of(2026, 02, 14, 1, 25, 52);
// List<Integer> opids=new ArrayList<>();//BCA6FA43FFA444D3952CF8F6E1EA291B
// opids.add(7);
// planResultService.Move("27065EA0ECD14A81B7FAAFEF52273F93",opids,t,1265l,0);
// planResultService.Move("27065EA0ECD14A81B7FAAFEF52273F93",opids,t,1265l,0);
// planResultService.Redecode("27065EA0ECD14A81B7FAAFEF52273F93");
// planResultService.Redecode("CA71321FE55B4437A3900315692F9220");
// planResultService.Drag("27065EA0ECD14A81B7FAAFEF52273F93",opids,6,false,0l);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment