Commit bdfee182 authored by Tong Li's avatar Tong Li

Merge remote-tracking branch 'origin/master'

# Conflicts:
#	src/main/java/com/aps/service/Algorithm/GeneticDecoder.java
parents 539b80b3 e931afa6
2026-03-25 23:38:18.378 | main | INFO | com.aps.ApsApplication | Starting ApsApplication using Java 17.0.18 on GJS-20250302HBH with PID 36188 (E:\ai\hyh.apsj\target\classes started by Administrator in E:\ai\hyh.apsj)
2026-03-25 23:38:18.382 | main | INFO | com.aps.ApsApplication | No active profile set, falling back to 1 default profile: "default"
2026-03-25 23:38:19.601 | main | INFO | org.apache.coyote.http11.Http11NioProtocol | Initializing ProtocolHandler ["http-nio-8181"]
2026-03-25 23:38:19.602 | main | INFO | org.apache.catalina.core.StandardService | Starting service [Tomcat]
2026-03-25 23:38:19.602 | main | INFO | org.apache.catalina.core.StandardEngine | Starting Servlet engine: [Apache Tomcat/9.0.83]
2026-03-25 23:38:19.686 | main | INFO | o.a.c.core.ContainerBase.[Tomcat].[localhost].[/] | Initializing Spring embedded WebApplicationContext
2026-03-25 23:38:20.545 | main | INFO | c.b.dynamic.datasource.DynamicRoutingDataSource | dynamic-datasource - add a datasource named [oracle] success
2026-03-25 23:38:20.546 | main | INFO | c.b.dynamic.datasource.DynamicRoutingDataSource | dynamic-datasource initial loaded [1] datasource,primary datasource named [oracle]
2026-03-25 23:38:20.941 | main | WARN | c.b.mybatisplus.core.injector.DefaultSqlInjector | class com.aps.entity.ApsTimeConfig ,Not found @TableId annotation, Cannot use Mybatis-Plus 'xxById' Method.
2026-03-25 23:38:21.654 | main | WARN | c.b.mybatisplus.core.injector.DefaultSqlInjector | class com.aps.entity.Algorithm.OrderMaterialRequirement ,Not found @TableId annotation, Cannot use Mybatis-Plus 'xxById' Method.
2026-03-25 23:38:21.717 | main | INFO | com.aps.controller.gantt.FileUploadController | 创建上传目录: E:\ai\hyh.apsj\uploads
2026-03-25 23:38:21.717 | main | INFO | com.aps.controller.gantt.FileUploadController | 创建上传目录: E:\ai\hyh.apsj\uploads
2026-03-25 23:38:22.388 | main | INFO | org.apache.coyote.http11.Http11NioProtocol | Starting ProtocolHandler ["http-nio-8181"]
2026-03-25 23:38:22.404 | main | INFO | com.aps.ApsApplication | Started ApsApplication in 4.45 seconds (JVM running for 5.14)
......@@ -58,7 +58,7 @@ public class GeneticDecoder {
private DiscreteParameterMatrixService discreteParameterMatrixService;
private String sceneId;
private boolean rebuildStructureForCurrentDecode = false;
private boolean rebuildStructureForCurrentDecode = true;
......@@ -1106,12 +1106,18 @@ public class GeneticDecoder {
int setupTime=0;
long machineId = machine.getId();
// 只有存在物料约束(或本次被强制要求重算 BOM)的工序,才需要联立求解“机台何时能排”和“物料何时可用”。
// targetFinishedOperationId != null 的工序通常由前置成品工序驱动,这里不再额外触发一轮 BOM 试算。
boolean needMaterialCheck = (operation.getMaterialRequirements()!=null&&operation.getMaterialRequirements().size()>0&&operation.getTargetFinishedOperationId()==null)||calbom;
needMaterialCheck=false;
// 正式落排后还要再做一次带提交的物料校验,把试算阶段推导出的 BOM 状态真正写回 chromosome。
boolean commitMaterialCheck = needMaterialCheck;
// baseEarliestStartTime:不考虑 BOM 推迟时的理论最早开工时间。
// candidateStartTime:固定点迭代时本轮尝试的开工时间。
// bomtime:按当前候选开工时间试算出来的物料最早可开工时间。
int baseEarliestStartTime = earliestStartTime;
int candidateStartTime = earliestStartTime;
int bomtime=0;
// 机台时间和物料时间可能会互相推动,最多迭代 maxSolveIterations 次来找收敛点。
int maxSolveIterations = Math.max(1, _globalParam.getMaterialSolveMaxIterations());
boolean converged = !needMaterialCheck;
Entry scheduledOperation = operation;
......@@ -1121,8 +1127,13 @@ public class GeneticDecoder {
MachineSchedulePreview machinePreview = null;
CopyOnWriteArrayList<ScheduleResultDetail> geneDetails=new CopyOnWriteArrayList<>();
// 固定点求解过程:
// 1. 先按 candidateStartTime 试排机台;
// 2. 再按试排结果试算物料/BOM 的最早可开工时间;
// 3. 如果物料时间继续把开工点往后推,就用新时间再次试排,直到收敛。
if(needMaterialCheck) {
for (int iteration = 0; iteration < maxSolveIterations; iteration++) {
// trial BOM 试算会在内部恢复快照,因此每轮都重新从最新 chromosome 中取对象,避免拿到旧引用。
Entry refreshedOperation = entryIndexById.get(operationId);
if (refreshedOperation != null) {
scheduledOperation = refreshedOperation;
......@@ -1138,13 +1149,15 @@ public class GeneticDecoder {
{
candidateStartTime = Math.max(candidateStartTime,lastGeneOnMachine.getEndTime());
}
// 0 884400
// 先在机台侧做一次“试排”,geneDetails 中会记录本轮临时占用的机台时间段。
machinePreview = buildMachinePreview(scheduledOperation, scheduledMachine, processingTime, processingTimeTotal,
candidateStartTime, lastGeneOnMachine, machineTasks, chromosome);
try {
//864000
// 物料侧只做试算,不提交最终状态;本轮只关心 BOM 约束会把开工时间推迟到哪里。
bomtime = EditOperationBOMTime(scheduledOperation,chromosome,machinePreview.getStartTime(),machineTasksCache, entryIndexById, scheduleIndexById, false);
} finally {
// buildMachinePreview 会临时锁住机台 availability,这里无论成功或异常都必须释放,
// 否则下一轮迭代会被本轮的试排残留状态污染。
Machine liveMachineAfterTrial = getMachineById(chromosome, machineId);
if (liveMachineAfterTrial != null) {
AddMachineAvailable(liveMachineAfterTrial, machinePreview.getGeneDetails());
......@@ -1153,7 +1166,9 @@ public class GeneticDecoder {
}
}
// 下一轮候选开工时间取“基准最早开工”和“物料最早可开工”两者中的较晚值。
int nextCandidateStartTime = Math.max(baseEarliestStartTime, bomtime);
// 如果物料时间已经不再把机台试排结果往后推,说明机台时间与物料时间达成一致。
if (nextCandidateStartTime <= machinePreview.getStartTime()) {
converged = true;
candidateStartTime = nextCandidateStartTime;
......@@ -1162,6 +1177,7 @@ public class GeneticDecoder {
candidateStartTime = nextCandidateStartTime;
}
// 固定点求解结束后,用收敛得到的候选开工时间作为正式排产的最早开工时间。
earliestStartTime = candidateStartTime;
Entry refreshedOperation = entryIndexById.get(operationId);
if (refreshedOperation != null) {
......@@ -1177,35 +1193,35 @@ public class GeneticDecoder {
lastGeneOnMachine = getLastMachineTask(machineTasks);
needMaterialCheck = false;
}
if(needMaterialCheck) {
int earliestStartTimeold=earliestStartTime;
if (_globalParam.is_smoothChangeOver()) {
Map<Integer, Object> reslte = calculateSetupTime(lastGeneOnMachine, operation, machine, earliestStartTime, processingTimeTotal, _globalParam.is_smoothChangeOverInWeek(), chromosome.getAllOperations());
// setupTime = (int) reslte.get(1);//换型时间
// int setupStartTime = (int) reslte.get(2);//换型开始时间
//earliestStartTime=(int)reslte.get(3);//上个任务的结束时间
earliestStartTime = (int) reslte.get(4);//最早开工时间
}
LocalDateTime startTime1 = baseTime.plus(earliestStartTime, ChronoUnit.SECONDS);
TimeSegment slot = machineCalculator.GetCurrentOrNextShift(machine, startTime1, "", false);
if(slot!=null)
{
earliestStartTime = slot.getStart().isAfter(startTime1)
?(int) ChronoUnit.SECONDS.between(baseTime, slot.getStart())
: earliestStartTime;
}
bomtime= EditOperationBOMTime(operation,chromosome,earliestStartTime,machineTasksCache, entryIndexById, scheduleIndexById, false);
earliestStartTime = Math.max(earliestStartTime, bomtime);
}
// 旧兜底单次试算路径:当前固定点迭代执行完后会把 needMaterialCheck 置为 false,
// 因此这段分支实际上不会再进入。先注释保留,后续若确认无用可直接删除,
// 或按真实意图改成 !converged 时的兜底处理。
// if(needMaterialCheck) {
// int earliestStartTimeold=earliestStartTime;
// if (_globalParam.is_smoothChangeOver()) {
//
// Map<Integer, Object> reslte = calculateSetupTime(lastGeneOnMachine, operation, machine, earliestStartTime, processingTimeTotal, _globalParam.is_smoothChangeOverInWeek(), chromosome.getAllOperations());
// // setupTime = (int) reslte.get(1);//换型时间
// // int setupStartTime = (int) reslte.get(2);//换型开始时间
// //earliestStartTime=(int)reslte.get(3);//上个任务的结束时间
// earliestStartTime = (int) reslte.get(4);//最早开工时间
// }
// LocalDateTime startTime1 = baseTime.plus(earliestStartTime, ChronoUnit.SECONDS);
//
// TimeSegment slot = machineCalculator.GetCurrentOrNextShift(machine, startTime1, "", false);
//
// if(slot!=null)
// {
// earliestStartTime = slot.getStart().isAfter(startTime1)
// ?(int) ChronoUnit.SECONDS.between(baseTime, slot.getStart())
// : earliestStartTime;
//
// }
// bomtime= EditOperationBOMTime(operation,chromosome,earliestStartTime,machineTasksCache, entryIndexById, scheduleIndexById, false);
//
//
// earliestStartTime = Math.max(earliestStartTime, bomtime);
// }
// machineTasks =chromosome.getResult().stream()
......@@ -1215,11 +1231,14 @@ public class GeneticDecoder {
//
// machineTasksCache.put(machine.getId(), machineTasks);
// 正式落排前,再取一次当前机台最后一道工序,保证换型计算基于最新排程结果。
if(machineTasks!=null&&machineTasks.size()>0&&_globalParam.is_smoothChangeOver())
{
lastGeneOnMachine=machineTasks.get(machineTasks.size()-1);
}
// 下面开始生成正式的 geneDetails。
// 与 buildMachinePreview 的区别是:这里得到的结果会继续向下写入 GAScheduleResult,成为真正排程结果。
if (_globalParam.is_smoothChangeOver()) {
//是否考虑换型时间
Map<Integer,Object> reslte = calculateSetupTime(lastGeneOnMachine, operation, machine,earliestStartTime,processingTimeTotal, _globalParam.is_smoothChangeOverInWeek(),chromosome.getAllOperations());
......@@ -1291,6 +1310,9 @@ public class GeneticDecoder {
// 准备工时 加入到加工时间里
// 后处理时间 相同任务的前一工序的结束时间+后处理时间 =当前工序最早开工时间
// 正式提交 BOM 校验:
// 1. 按最终 startTime 重新计算一次物料占用,并把状态真正写回;
// 2. 如果提交后的 BOM 时间仍然晚于 startTime,说明机台时间与物料时间没有收敛,需要直接报错。
if (commitMaterialCheck) {
int committedBomTime = EditOperationBOMTime(operation,chromosome,startTime,machineTasksCache, entryIndexById, scheduleIndexById, true);
bomtime = Math.max(bomtime, committedBomTime);
......@@ -1408,6 +1430,10 @@ public class GeneticDecoder {
}
}
/**
* 按当前候选开工时间做一次机台侧试排。
* 注意:该方法会临时占用 machine.availability 中对应的时段,调用方用完后必须配合 AddMachineAvailable 释放。
*/
private MachineSchedulePreview buildMachinePreview(Entry operation, Machine machine, double processingTime, int processingTimeTotal,
int earliestStartTime, GAScheduleResult lastGeneOnMachine,
CopyOnWriteArrayList<GAScheduleResult> machineTasks, Chromosome chromosome) {
......@@ -1417,6 +1443,7 @@ public class GeneticDecoder {
CopyOnWriteArrayList<ScheduleResultDetail> geneDetails;
if (_globalParam.is_smoothChangeOver()) {
// 先把换型时间、换型起点以及加工总时长修正到当前候选时间点。
Map<Integer,Object> reslte = calculateSetupTime(lastGeneOnMachine, operation, machine, previewStart, previewProcessingTotal, _globalParam.is_smoothChangeOverInWeek(),chromosome.getAllOperations());
setupTime=(int)reslte.get(1);
int setupStartTime=(int)reslte.get(2);
......@@ -1424,10 +1451,12 @@ public class GeneticDecoder {
previewProcessingTotal=(int)reslte.get(5);
if(setupTime==0)
{
// 没有换型占用时,直接查机台下一段可排的可用窗口。
geneDetails = machineCalculator.getNextAvailableTime(machine, previewStart, -1,
previewProcessingTotal, machineTasks, operation.getIsInterrupt()!=1, true,processingTime, operation.getQuantity(), true);
}else {
// 有换型占用时,需要把换型段和加工段一起拼成完整的试排结果。
CopyOnWriteArrayList<TimeSegment> AvailableTimeSegment = (CopyOnWriteArrayList<TimeSegment>) reslte.get(6);
Map<Integer,Object> result = machineCalculator.CreateScheduleResult(machine, previewProcessingTotal, previewStart,
AvailableTimeSegment, processingTime, operation.getQuantity(), operation.getIsInterrupt() != 1, setupTime, _globalParam.is_smoothChangeOverInWeek(), setupStartTime);
......@@ -1436,10 +1465,12 @@ public class GeneticDecoder {
geneDetails=(CopyOnWriteArrayList<ScheduleResultDetail>) result.get(2);
}
}else {
// 不考虑平滑换型时,只需要找加工段可用窗口。
geneDetails = machineCalculator.getNextAvailableTime(machine, previewStart, -1,
previewProcessingTotal, machineTasks, operation.getIsInterrupt()!=1, true,processingTime, operation.getQuantity(), true);
}
// geneDetails 可能跨多个班次/时段,开始时间取最小值,结束时间取最大值。
int startTime = geneDetails.stream()
.mapToInt(ScheduleResultDetail::getStartTime)
.min()
......@@ -1451,6 +1482,7 @@ public class GeneticDecoder {
return new MachineSchedulePreview(startTime, endTime, setupTime, geneDetails);
}
// 按机台缓存已排结果,避免固定点迭代期间反复全表扫描 chromosome.getResult()。
private CopyOnWriteArrayList<GAScheduleResult> getMachineTasks(long machineId, Chromosome chromosome,
Map<Long, CopyOnWriteArrayList<GAScheduleResult>> machineTasksCache) {
if (machineTasksCache.containsKey(machineId)) {
......@@ -1464,6 +1496,7 @@ public class GeneticDecoder {
return machineTasks;
}
// 当前机台最后一道已排工序,用于约束连续排程和换型起点。
private GAScheduleResult getLastMachineTask(CopyOnWriteArrayList<GAScheduleResult> machineTasks) {
if(machineTasks!=null&&machineTasks.size()>0)
{
......@@ -1472,6 +1505,7 @@ public class GeneticDecoder {
return null;
}
// trial BOM 恢复快照后,旧的 Machine 引用可能已经失效,因此统一从 chromosome 中重新取当前有效对象。
private Machine getMachineById(Chromosome chromosome, long machineId) {
return chromosome.getMachines().stream()
.filter(m -> m.getId() == machineId)
......@@ -1630,6 +1664,10 @@ public class GeneticDecoder {
}
/**
* 汇总当前工序的物料约束,返回所有原料/半成品中最晚满足的那个时刻。
* 返回值含义是“这道工序最早允许因物料而开工的秒数”。
*/
private int getOperationBOMTime(Entry currentOp, Chromosome chromosome) {
List<OrderMaterialRequirement> opboms= currentOp.getMaterialRequirements();
......@@ -1697,10 +1735,16 @@ public class GeneticDecoder {
return Math.max(rawTime, sfTime);
}
// 默认走正式提交路径,调用方不传 commitChanges 时认为要把物料状态真实写回。
private int EditOperationBOMTime(Entry currentOp, Chromosome chromosome,int earliestStartTime,Map<Long, CopyOnWriteArrayList<GAScheduleResult>> machineTasksCache,Map<Integer, Entry> entryIndexById,Map<Integer, GAScheduleResult> scheduleIndexById) {
return EditOperationBOMTime(currentOp, chromosome, earliestStartTime, machineTasksCache, entryIndexById, scheduleIndexById, true);
}
/**
* 按指定 earliestStartTime 重新计算当前工序的 BOM 可开工时间。
* commitChanges=true:正式提交,真实修改物料/订单/排程状态。
* commitChanges=false:只做试算,方法结束后恢复 chromosome 和相关索引缓存。
*/
private int EditOperationBOMTime(Entry currentOp, Chromosome chromosome,int earliestStartTime,Map<Long, CopyOnWriteArrayList<GAScheduleResult>> machineTasksCache,Map<Integer, Entry> entryIndexById,Map<Integer, GAScheduleResult> scheduleIndexById, boolean commitChanges) {
List<OrderMaterialRequirement> opboms= currentOp.getMaterialRequirements();
if(opboms==null)
......@@ -1709,20 +1753,24 @@ public class GeneticDecoder {
}
LocalDateTime earliestStartTime1=baseTime.plusSeconds(earliestStartTime);
if(commitChanges) {
// 正式提交模式:直接把当前开工时间对应的物料占用/供应结果写回业务对象。
materialRequirementService.EditOperationBOM(currentOp,chromosome,earliestStartTime1,this,machineTasksCache, entryIndexById, scheduleIndexById, baseTime, true);
return getOperationBOMTime(currentOp, chromosome);
}
// 试算模式:先复制一份完整状态,等 BOM 计算完成后再整体恢复。
TrialDecodeSnapshot snapshot = createTrialDecodeSnapshot(chromosome);
try {
materialRequirementService.EditOperationBOM(currentOp,chromosome,earliestStartTime1,this,machineTasksCache, entryIndexById, scheduleIndexById, baseTime, true);
return getOperationBOMTime(currentOp, chromosome);
} finally {
// 试算期间 materialRequirementService 可能会改动 machine/order/material/result,这里统一回滚。
restoreTrialDecodeSnapshot(snapshot, chromosome, machineTasksCache, entryIndexById, scheduleIndexById);
}
}
// 试算 BOM 会改动多类状态对象,因此先把排程求解会依赖的核心集合做一次深拷贝快照。
private TrialDecodeSnapshot createTrialDecodeSnapshot(Chromosome chromosome) {
TrialDecodeSnapshot snapshot = new TrialDecodeSnapshot();
snapshot.machines = ProductionDeepCopyUtil.deepCopyList(chromosome.getMachines(), Machine.class);
......@@ -1734,6 +1782,7 @@ public class GeneticDecoder {
return snapshot;
}
// 恢复试算前的 chromosome 状态,并同步重建几个按 id/机台组织的缓存索引。
private void restoreTrialDecodeSnapshot(TrialDecodeSnapshot snapshot, Chromosome chromosome,
Map<Long, CopyOnWriteArrayList<GAScheduleResult>> machineTasksCache,
Map<Integer, Entry> entryIndexById,
......@@ -2551,6 +2600,7 @@ public class GeneticDecoder {
return reslte;
}
// 释放试排阶段占用的机台 availability 段,避免临时状态污染下一轮排程/BOM 试算。
public void AddMachineAvailable(Machine machine, List<ScheduleResultDetail> geneDetails) {
if (geneDetails == null || geneDetails.isEmpty()) return;
......
......@@ -41,6 +41,7 @@ public class MachineCalculator {
/**
* 获取机器下一个可用时间窗口(考虑班次约束)
*/
// 从 proposedStartTime 开始查找机台下一段可排窗口;必要时会把命中的 availability 临时标记为已占用。
public CopyOnWriteArrayList<ScheduleResultDetail> getNextAvailableTime(Machine machine, int proposedStartTime,
int prevtime, int processingTime,
CopyOnWriteArrayList<GAScheduleResult> existingTasks,
......@@ -70,6 +71,7 @@ public class MachineCalculator {
return findAvailableSegments(machine, startTime, existingTasks, processingTime, isInterrupt);
}
// 基于已选可用时段组装排程结果,并把换型段/加工段对应的 availability 临时占用。
public Map<Integer,Object> CreateScheduleResult(
Machine machine, int processingTime, int proposedStartTime,CopyOnWriteArrayList<TimeSegment> timeSegments,
double oneTime,double quantity
......@@ -1289,6 +1291,7 @@ public class MachineCalculator {
return times;
}
// 把目标 availability 按本次排程切成“剩余可用段”和“本次已占用段”,并把占用段 key 回写到 geneDetails。
private CopyOnWriteArrayList<TimeSegment> RemoveMachineAvailable(Machine machine, ScheduleResultDetail geneDetails,TimeSegment targetSegment) {
......
......@@ -75,6 +75,7 @@ public class MaterialRequirementService {
private static final int cachetimeout = 60;
private static final int ORACLE_IN_BATCH_SIZE = 1000;
private String cacheKey="_MR_";
private String routingHeaderCacheKey=cacheKey+ "RoutingHeader";
private String routingsupportingCacheKey=cacheKey+ "Routingsupporting";
......@@ -100,22 +101,13 @@ public class MaterialRequirementService {
.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<RoutingHeader> routingHeaders = getRoutingHeadersByIds(routingIds);
List<Routingsupporting> routingsupportings=null;
// 查询并缓存Routingsupporting
LambdaQueryWrapper<Routingsupporting> routingsupportingwrapper = new LambdaQueryWrapper<>();
routingsupportingwrapper.in(Routingsupporting::getRoutingHeaderId, routingIds)
.eq(Routingsupporting::getIsdeleted, 0);
routingsupportings = routingsupportingMapper.selectList(routingsupportingwrapper);
routingsupportings = getRoutingsupportingsByRoutingHeaderIds(routingIds);
// 查询并缓存RoutingSupportingReplace
......@@ -126,10 +118,7 @@ public class MaterialRequirementService {
.distinct()
.collect(Collectors.toList());
LambdaQueryWrapper<RoutingSupportingReplace> routingsupportingreplacewrapper = new LambdaQueryWrapper<>();
routingsupportingreplacewrapper.in(RoutingSupportingReplace::getStrsupid, routingsupportingids)
.eq(RoutingSupportingReplace::getIsdeleted, 0);
replaces = routingSupportingReplaceMapper.selectList(routingsupportingreplacewrapper);
replaces = getRoutingSupportingReplacesByStrsupids(routingsupportingids);
}
List<Material> useMaterials=new ArrayList<>();
......@@ -279,11 +268,7 @@ if(Operations==null)
LambdaQueryWrapper<Routingsupporting> routingsupportingwrapper = new LambdaQueryWrapper<>();
routingsupportingwrapper.in(Routingsupporting::getRoutingHeaderId, routingIds)
.eq(Routingsupporting::getIsdeleted, 0);
routingsupportings1 = routingsupportingMapper.selectList(routingsupportingwrapper);
routingsupportings1 = getRoutingsupportingsByRoutingHeaderIds(routingIds);
if(routingsupportings1!=null&&routingsupportings1.size()>0)
{
routingsupportings.addAll(routingsupportings1);
......@@ -293,11 +278,7 @@ if(Operations==null)
.distinct()
.collect(Collectors.toList());
LambdaQueryWrapper<RoutingSupportingReplace> routingsupportingreplacewrapper = new LambdaQueryWrapper<>();
routingsupportingreplacewrapper.in(RoutingSupportingReplace::getStrsupid, routingsupportingids)
.eq(RoutingSupportingReplace::getIsdeleted, 0);
routingsupportingreplaces1 = routingSupportingReplaceMapper.selectList(routingsupportingreplacewrapper);
routingsupportingreplaces1 = getRoutingSupportingReplacesByStrsupids(routingsupportingids);
routingsupportingreplaces.addAll(routingsupportingreplaces1);
......@@ -1543,6 +1524,62 @@ if(demand==null)
return RoutingSupportingReplaces;
}
private List<RoutingHeader> getRoutingHeadersByIds(List<Integer> routingIds) {
if (CollectionUtils.isEmpty(routingIds)) {
return new ArrayList<>();
}
List<RoutingHeader> routingHeaders = new ArrayList<>();
for (List<Integer> batchIds : partitionList(routingIds, ORACLE_IN_BATCH_SIZE)) {
LambdaQueryWrapper<RoutingHeader> wrapper = new LambdaQueryWrapper<>();
wrapper.in(RoutingHeader::getId, batchIds);
routingHeaders.addAll(routingHeaderMapper.selectList(wrapper));
}
return routingHeaders;
}
private List<Routingsupporting> getRoutingsupportingsByRoutingHeaderIds(List<? extends Number> routingIds) {
if (CollectionUtils.isEmpty(routingIds)) {
return new ArrayList<>();
}
List<Routingsupporting> routingsupportings = new ArrayList<>();
for (List<? extends Number> batchIds : partitionList(routingIds, ORACLE_IN_BATCH_SIZE)) {
LambdaQueryWrapper<Routingsupporting> routingsupportingwrapper = new LambdaQueryWrapper<>();
routingsupportingwrapper.in(Routingsupporting::getRoutingHeaderId, batchIds)
.eq(Routingsupporting::getIsdeleted, 0);
routingsupportings.addAll(routingsupportingMapper.selectList(routingsupportingwrapper));
}
return routingsupportings;
}
private List<RoutingSupportingReplace> getRoutingSupportingReplacesByStrsupids(List<String> routingSupportingIds) {
if (CollectionUtils.isEmpty(routingSupportingIds)) {
return new ArrayList<>();
}
List<RoutingSupportingReplace> replaces = new ArrayList<>();
for (List<String> batchIds : partitionList(routingSupportingIds, ORACLE_IN_BATCH_SIZE)) {
LambdaQueryWrapper<RoutingSupportingReplace> routingsupportingreplacewrapper = new LambdaQueryWrapper<>();
routingsupportingreplacewrapper.in(RoutingSupportingReplace::getStrsupid, batchIds)
.eq(RoutingSupportingReplace::getIsdeleted, 0);
replaces.addAll(routingSupportingReplaceMapper.selectList(routingsupportingreplacewrapper));
}
return replaces;
}
private <T> List<List<T>> partitionList(List<T> source, int batchSize) {
List<List<T>> partitions = new ArrayList<>();
if (CollectionUtils.isEmpty(source) || batchSize <= 0) {
return partitions;
}
for (int i = 0; i < source.size(); i += batchSize) {
partitions.add(source.subList(i, Math.min(i + batchSize, source.size())));
}
return partitions;
}
private List<RoutingDetail> GetRoutingDetails(String sceneId) {
List<RoutingDetail> RoutingDetails=(List<RoutingDetail>)GlobalCacheUtil.get(sceneId+routingDetailCacheKey);
if(RoutingDetails==null)
......
......@@ -61,7 +61,7 @@
<!-- 针对你的包结构进行配置 -->
<!-- 1. 算法包(你最关心的) -->
<logger name="com.aps.service.Algorithm" level="DEBUG">
<logger name="com.aps.service.Algorithm" level="INFO">
<appender-ref ref="FILE"/>
</logger>
......@@ -81,7 +81,7 @@
</logger>
<!-- 5. Mapper层(SQL日志) -->
<logger name="com.aps.mapper" level="DEBUG">
<logger name="com.aps.mapper" level="INFO">
<appender-ref ref="FILE"/>
</logger>
......@@ -91,25 +91,25 @@
</logger>
<!-- 第三方框架日志控制 -->
<logger name="org.springframework" level="WARN"/>
<logger name="org.mybatis" level="WARN"/>
<logger name="com.zaxxer.hikari" level="WARN"/>
<logger name="org.springframework" level="INFO"/>
<logger name="org.mybatis" level="INFO"/>
<logger name="com.zaxxer.hikari" level="INFO"/>
<!-- 根据不同环境调整 -->
<springProfile name="dev">
<root level="DEBUG">
<root level="INFO">
<appender-ref ref="CONSOLE"/>
</root>
<logger name="com.aps" level="DEBUG"/>
<logger name="com.aps" level="INFO"/>
</springProfile>
<springProfile name="prod">
<root level="WARN">
<root level="INFO">
<appender-ref ref="FILE"/>
<appender-ref ref="ERROR_FILE"/>
</root>
<!-- 生产环境关闭DEBUG日志 -->
<logger name="com.aps.mapper" level="WARN"/>
<logger name="com.aps.mapper" level="INFO"/>
<logger name="com.aps.service.Algorithm" level="INFO"/>
</springProfile>
......
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