插单

parent 31b15e01
......@@ -931,7 +931,7 @@ if(targetOp.getSequence()>1) {
/**
* 插入新订单到排产中
* 将新订单排在指定订单后面
*
*
* @param chromosome 染色体对象
* @param afterOrderId 插入位置订单ID(新订单将排在此订单后面)
* @param newOrderId 新订单ID
......@@ -940,13 +940,13 @@ if(targetOp.getSequence()>1) {
* @param globalParam 全局参数
*/
public void InsertOrder(Chromosome chromosome, String afterOrderId, String newOrderId,
ProdLaunchOrder newLaunchOrder, List<ProdProcessExec> newProcessExecs,
GlobalParam globalParam) {
ProdLaunchOrder newLaunchOrder, List<ProdProcessExec> newProcessExecs,
GlobalParam globalParam) {
List<Entry> allOperations = chromosome.getAllOperations();
List<Order> orders = chromosome.getOrders();
List<GroupResult> OperatRels = chromosome.getOperatRel();
// 1. 创建新的Order对象
Order newOrder = new Order();
newOrder.setOrderId(newOrderId);
......@@ -961,25 +961,25 @@ if(targetOp.getSequence()>1) {
newOrder.setRoutingId(newLaunchOrder.getRoutingId());
newOrder.setRoutingCode(newLaunchOrder.getRoutingCode());
newOrder.setSerie(newLaunchOrder.getSerie());
newOrder.setNewCreate(true);
// 获取当前最大的Order ID
int maxOrderId = orders.stream()
.mapToInt(Order::getId)
.max()
.orElse(0) + 1;
newOrder.setId(maxOrderId);
orders.add(newOrder);
// 2. 创建新订单的Entry对象
int maxGroupId = OperatRels.size();
int newGroupId = maxGroupId + 1;
List<Entry> newEntrys = new ArrayList<>();
List<String> newIdList = new ArrayList<>();
List<String> newChildIdList = new ArrayList<>();
// 从ProdProcessExec创建Entry
for (ProdProcessExec processExec : newProcessExecs) {
Entry newEntry = new Entry();
......@@ -989,17 +989,38 @@ if(targetOp.getSequence()>1) {
newEntry.setGroupId(newGroupId);
newEntry.setQuantity(newLaunchOrder.getQuantity());
newEntry.setSequence(processExec.getTaskSeq() != null ? processExec.getTaskSeq().intValue() : 1);
newEntry.setNewCreate(true);
newEntry.setTaskSeq(processExec.getTaskSeq()); // 设置taskSeq字段
newEntry.setState(2);
// 设置工序相关信息
newEntry.setRoutingDetailId(processExec.getRoutingDetailId());
newEntry.setRoutingId(processExec.getRoutingId());
newEntry.setRoutingCode(processExec.getRoutingCode());
newEntry.setRoutingName(processExec.getRoutingName());
newEntry.setRoutingDetailName(processExec.getRoutingDetailName());
// 设置产品相关信息
newEntry.setProductId(newLaunchOrder.getMaterialId());
newEntry.setProductCode(newLaunchOrder.getMaterialCode());
newEntry.setProductName(newLaunchOrder.getMaterialName());
// 设置部门信息
if (processExec.getDepartmentId() != null) {
newEntry.setDepartmentId(processExec.getDepartmentId());
}
// 设置中断属性
newEntry.setIsInterrupt(processExec.getCanInterrupt());
// 设置设备类型信息
newEntry.setEquipTypeID(processExec.getMachineId());
// 使用runtime字段
if (processExec.getRuntime() != null) {
newEntry.setRuntime(processExec.getRuntime());
}
newEntry.setPriority(newLaunchOrder.getOrderPriority() != null ? newLaunchOrder.getOrderPriority() : 1);
// 设置其他时间相关字段
if (processExec.getSetupTime() != null) {
newEntry.setSetupTime(processExec.getSetupTime());
......@@ -1008,23 +1029,24 @@ if(targetOp.getSequence()>1) {
newEntry.setConstTime(processExec.getConstTime());
newEntry.setPreTime(processExec.getPreprocessingTime());
newEntry.setTeardownTime(processExec.getPostprocessingTime());
// 设置设备相关信息
newEntry.setEquipTypeName(processExec.getEquipTypeName());
newEntry.setEquipTypeCode(processExec.getEquipTypeCode());
// 设置设备选项(从数据库加载或使用默认值)
// 这里需要根据实际情况设置MachineOptions
// 暂时使用空列表,后续在redecode时会重新计算
// 设备配置将在后面从插入位置的订单复制,这里先设置为空列表
newEntry.setMachineOptions(new ArrayList<>());
// 设置默认选中的设备ID(将在后面从插入位置订单复制)
newEntry.setSelectMachineID(null);
newEntrys.add(newEntry);
}
// 3. 建立工序之间的依赖关系
for (int i = 0; i < newEntrys.size(); i++) {
Entry entry = newEntrys.get(i);
if (i == 0) {
// 第一道工序,没有前置工序
newIdList.add(entry.getExecId());
......@@ -1039,31 +1061,31 @@ if(targetOp.getSequence()>1) {
newChildIdList.add(newEntrys.get(i + 1).getExecId());
}
}
// 4. 添加新数据到OperatRels
OperatRels = IdGroupingWithDualSerial.addNewDataWithIsolatedGroup(OperatRels, newIdList, newChildIdList);
chromosome.setOperatRel(new CopyOnWriteArrayList<>(OperatRels));
// 5. 更新全局ID和Entry信息
int globalOpId = chromosome.getGlobalOpList().stream()
.mapToInt(GlobalOperationInfo::getGlobalOpId)
.max()
.orElse(0) + 1;
GroupResult newGroupResult = OperatRels.get(OperatRels.size() - 1);
List<NodeInfo> nodeInfoList = newGroupResult.getNodeInfoList();
for (NodeInfo nodeInfo : nodeInfoList) {
Entry entry = newEntrys.stream()
.filter(t -> t.getExecId().equals(nodeInfo.getOriginalId()))
.findFirst()
.orElse(null);
if (entry != null) {
entry.setId(nodeInfo.getGlobalSerial());
entry.setGroupId(newGroupId);
entry.setSequence(nodeInfo.getGroupSerial());
// 设置前置和后续工序依赖
if (nodeInfo.getNewParentIds() != null) {
List<OperationDependency> dependencies = new ArrayList<>();
......@@ -1074,7 +1096,7 @@ if(targetOp.getSequence()>1) {
}
entry.setPrevEntryIds(dependencies);
}
if (nodeInfo.getNewChildIds() != null) {
List<OperationDependency> dependencies = new ArrayList<>();
for (int id : nodeInfo.getNewChildIds()) {
......@@ -1084,10 +1106,10 @@ if(targetOp.getSequence()>1) {
}
entry.setNextEntryIds(dependencies);
}
// 添加到allOperations
chromosome.getAllOperations().add(entry);
// 添加到全局操作列表
GlobalOperationInfo info = new GlobalOperationInfo();
info.setGlobalOpId(globalOpId);
......@@ -1096,30 +1118,30 @@ if(targetOp.getSequence()>1) {
info.setOp(entry);
chromosome.getGlobalOpList().add(info);
globalOpId++;
// 添加默认的机器选择(第一个可选设备)
chromosome.getMachineSelection().add(1);
}
}
// 6. 将新订单插入到指定订单后面的位置
// 6. 将新订单插入到指定订单后面的位置,并使用相同的设备配置
List<Entry> afterOrderOps = allOperations.stream()
.filter(o -> o.getOrderId().equals(afterOrderId))
.sorted(Comparator.comparing(Entry::getSequence))
.collect(Collectors.toList());
if (!afterOrderOps.isEmpty()) {
Entry lastOpOfAfterOrder = afterOrderOps.get(afterOrderOps.size() - 1);
List<Integer> operationSequencing = chromosome.getOperationSequencing();
// 找到afterOrder最后一道工序在operationSequencing中的位置
OptionalInt operationIndex = IntStream.range(0, operationSequencing.size())
.filter(i -> operationSequencing.get(i).equals(lastOpOfAfterOrder.getGroupId()))
.findFirst();
if (operationIndex.isPresent()) {
int insertPosition = operationIndex.getAsInt() + 1;
// 在该位置后插入新订单的所有工序
for (int i = 0; i < newEntrys.size(); i++) {
chromosome.getOperationSequencing().add(insertPosition + i, newGroupId);
......@@ -1130,17 +1152,40 @@ if(targetOp.getSequence()>1) {
chromosome.getOperationSequencing().add(newGroupId);
}
}
// 使用插入位置订单的设备配置来更新新订单的工序
// 这样可以确保新订单使用相同的生产线和设备
for (int i = 0; i < newEntrys.size() && i < afterOrderOps.size(); i++) {
Entry newEntry = newEntrys.get(i);
Entry referenceEntry = afterOrderOps.get(i);
// 复制设备配置
if (referenceEntry.getMachineOptions() != null && !referenceEntry.getMachineOptions().isEmpty()) {
newEntry.setMachineOptions(new ArrayList<>(referenceEntry.getMachineOptions()));
newEntry.setSelectMachineID(referenceEntry.getSelectMachineID());
newEntry.setEquipCode(referenceEntry.getEquipCode());
newEntry.setEquipName(referenceEntry.getEquipName());
}
}
} else {
// 如果找不到afterOrder,就添加到末尾
for (int i = 0; i < newEntrys.size(); i++) {
chromosome.getOperationSequencing().add(newGroupId);
}
}
// 临时设置isCheckSf为false,避免CreateNewOpSequence重新生成operationSequencing
boolean originalIsCheckSf = globalParam.isIsCheckSf();
globalParam.setIsCheckSf(false);
// 7. 重新解码,重新计算排产结果
redecode(chromosome, chromosome.getBaseTime(), globalParam);
// 恢复isCheckSf的原始值
globalParam.setIsCheckSf(originalIsCheckSf);
}
public void MergeOrder(Chromosome chromosome, String sourceorderId,String targetorderId, GlobalParam globalParam) {
List<Entry> allOperations = chromosome.getAllOperations();
List<GlobalOperationInfo> globalOpList= chromosome.getGlobalOpList();
......
......@@ -219,7 +219,7 @@ public class PlanResultService {
.collect(Collectors.toList());
ApsTimeConfig timeConfig = apsTimeConfigService.getOne(new LambdaQueryWrapper<>());
// 4.5 在排产前标记锁定期工单占用的设备时间段
// lockedOrderProcessorService.markLockedOrdersOccupiedTime(machines, timeConfig.getBaseTime());
lockedOrderProcessorService.markLockedOrdersOccupiedTime(machines, timeConfig.getBaseTime());
// 5. 执行调度算法
GeneticAlgorithm scheduler =new GeneticAlgorithm(globalParam,machines,orders,Materials1,materialIds,machineScheduler,entryRel,materialRequirementService,_sceneService,SceneId); //new GeneticAlgorithm(products, machines, orders, machineScheduler);
......@@ -234,7 +234,7 @@ public class PlanResultService {
// 添加锁定期工单到调度结果中
// 这里会从 Dispatch 表加载锁定期工单,并添加到 chromosome.result 中
// lockedOrderProcessorService.addLockedOrdersToResult(chromosome);
lockedOrderProcessorService.addLockedOrdersToResult(chromosome);
_sceneService.saveChromosomeToFile(chromosome, SceneId);
......@@ -1443,7 +1443,7 @@ public class PlanResultService {
* 插单功能:在指定订单后插入新订单
* 步骤1:先将新订单数据插入数据库
* 步骤2:使用类似复制订单的方式将新订单加入排产
*
*
* @param SceneId 场景ID
* @param afterOrderId 插入位置订单ID(新订单将排在此订单后面)
* @param newOrderData 新订单数据
......@@ -1454,11 +1454,11 @@ public class PlanResultService {
String orderCode = (String) newOrderData.get("orderCode");
String materialId = (String) newOrderData.get("materialId");
Double quantity = ((Number) newOrderData.get("quantity")).doubleValue();
LocalDateTime startDate = null;
LocalDateTime endDate = null;
Integer priority = 1;
if (newOrderData.containsKey("startDate")) {
startDate = LocalDateTime.parse((String) newOrderData.get("startDate"));
}
......@@ -1468,11 +1468,11 @@ public class PlanResultService {
if (newOrderData.containsKey("priority")) {
priority = ((Number) newOrderData.get("priority")).intValue();
}
// 调用insertOrder插入数据库
R<String> insertResult = lanuchService.insertOrder(SceneId, orderCode, materialId,
startDate, endDate, priority, quantity);
R<String> insertResult = lanuchService.insertOrder(SceneId, orderCode, materialId,
startDate, endDate, priority, quantity);
// if (!insertResult.isSuccess()) {
// throw new RuntimeException("插单失败: " + insertResult.getMsg());
// }
......@@ -1480,44 +1480,45 @@ public class PlanResultService {
// 从返回消息中提取新订单ID
String message = insertResult.getData();
String newOrderId = message.substring(message.indexOf("订单ID: ") + 6);
log.info("新订单已插入数据库,订单ID: {}", newOrderId);
// 步骤2:使用类似SpiltOrder的方式,将新订单加入排产
// 这里需要重新加载场景,因为数据库已经有新订单了
// 然后使用类似复制的逻辑,将新订单排在afterOrderId后面
GlobalParam globalParam = new GlobalParam();
Chromosome chromosome = _sceneService.loadChromosomeFromFile(SceneId);
// 从数据库加载新插入的订单及其工序
ProdLaunchOrder newLaunchOrder = _prodLaunchOrderService.lambdaQuery()
.eq(ProdLaunchOrder::getSceneId, SceneId)
.eq(ProdLaunchOrder::getOrderId, newOrderId)
.one();
if (newLaunchOrder == null) {
throw new RuntimeException("未找到新插入的订单: " + newOrderId);
}
// 加载新订单的工序
List<ProdProcessExec> newProcessExecs = _prodProcessExecService.lambdaQuery()
.eq(ProdProcessExec::getSceneId, SceneId)
.eq(ProdProcessExec::getOrderId, newOrderId)
.orderBy(true, true, ProdProcessExec::getTaskSeq)
.list();
if (newProcessExecs.isEmpty()) {
throw new RuntimeException("新订单没有工序: " + newOrderId);
}
log.info("加载新订单: OrderId={}, OrderCode={}, 工序数={}",
log.info("加载新订单: OrderId={}, OrderCode={}, 工序数={}",
newOrderId, newLaunchOrder.getOrderCode(), newProcessExecs.size());
// 调用ScheduleOperationService的方法将新订单加入排产
// 设备配置将从插入位置的订单复制,不需要单独加载
ScheduleOperationService scheduleOperation = new ScheduleOperationService(materialRequirementService, this);
scheduleOperation.InsertOrder(chromosome, afterOrderId, newOrderId, newLaunchOrder, newProcessExecs, globalParam);
WriteScheduleSummary(chromosome);
_sceneService.saveChromosomeToFile(chromosome, SceneId);
return chromosome;
......
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