Commit 9d08cc4f authored by Tong Li's avatar Tong Li

Merge remote-tracking branch 'origin/master' into tl

# Conflicts:
#	src/main/java/com/aps/service/Algorithm/GeneticDecoder.java
#	src/main/java/com/aps/service/plan/PlanResultService.java
#	src/test/java/com/aps/demo/PlanResultServiceTest.java
parents 6abaed14 f0698511
...@@ -133,6 +133,28 @@ public class SwaggerMapParamConfig { ...@@ -133,6 +133,28 @@ public class SwaggerMapParamConfig {
)); ));
break; break;
case "insertOrder":
properties.put("sceneId", new StringSchema().description("场景ID").example("B571EF6682DB463AB2977B1055A74112"));
properties.put("orderCode", new StringSchema().description("订单编码").example("ORDER-2026-001"));
properties.put("materialId", new StringSchema().description("物料ID").example("MAT001"));
properties.put("startDate", new StringSchema().description("开始时间(ISO格式)").example("2026-03-10T08:00:00"));
properties.put("endDate", new StringSchema().description("结束时间(ISO格式)").example("2026-03-20T18:00:00"));
properties.put("priority", new StringSchema().description("优先级").example("1"));
properties.put("quantity", new StringSchema().description("数量").example("100.0"));
examples.put("插单示例", createExample(
"向现有场景添加新订单",
"{\n" +
" \"sceneId\": \"B571EF6682DB463AB2977B1055A74112\",\n" +
" \"orderCode\": \"ORDER-2026-001\",\n" +
" \"materialId\": \"MAT001\",\n" +
" \"startDate\": \"2026-03-10T08:00:00\",\n" +
" \"endDate\": \"2026-03-20T18:00:00\",\n" +
" \"priority\": 1,\n" +
" \"quantity\": 100.0\n" +
"}"
));
break;
case "getResourceGantt": case "getResourceGantt":
case "getProductGantt": case "getProductGantt":
......
...@@ -187,4 +187,30 @@ public class LanuchController { ...@@ -187,4 +187,30 @@ public class LanuchController {
return lanuchService.savePlan(sceneId); return lanuchService.savePlan(sceneId);
} }
/**
* 插单:向现有场景添加新订单
*/
@PostMapping("/insertOrder")
@Operation(summary = "插单", description = "向现有场景添加新订单,订单ID会自动生成UUID格式")
public R<String> insertOrder(@RequestBody Map<String, Object> params) {
String sceneId = (String) params.get("sceneId");
String orderCode = (String) params.get("orderCode");
String materialId = (String) params.get("materialId");
// 解析时间参数
String startDateStr = (String) params.get("startDate");
String endDateStr = (String) params.get("endDate");
java.time.LocalDateTime startDate = java.time.LocalDateTime.parse(startDateStr);
java.time.LocalDateTime endDate = java.time.LocalDateTime.parse(endDateStr);
// 解析优先级和数量
Integer priority = params.get("priority") != null ?
Integer.valueOf(params.get("priority").toString()) : 1;
Double quantity = params.get("quantity") != null ?
Double.valueOf(params.get("quantity").toString()) : 0.0;
return lanuchService.insertOrder(sceneId, orderCode, materialId,
startDate, endDate, priority, quantity);
}
} }
\ No newline at end of file
...@@ -400,10 +400,74 @@ public class ResourceGanttController { ...@@ -400,10 +400,74 @@ public class ResourceGanttController {
return R.ok("复制成功"); return R.ok("复制成功");
} }
@PostMapping("/orderInsert")
@Operation(summary = "订单插单", description = "在指定订单后插入新订单")
public R<String> insertOrder(@RequestBody Map<String, Object> params) {
log.info("insertOrder 请求参数: {}", params);
String sceneId = ParamValidator.getString(params, "sceneId", "场景ID");
String afterOrderId = ParamValidator.getString(params, "afterOrderId", "插入位置订单ID");
// 获取新订单信息
@SuppressWarnings("unchecked")
Map<String, Object> newOrderData = (Map<String, Object>) params.get("newOrder");
ParamValidator.validateSceneExists(sceneService, sceneId);
Chromosome result = planResultService.InsertOrder(sceneId, afterOrderId, newOrderData);
return R.ok("插单成功");
}
@PostMapping("/orderInsertAuto")
@Operation(
summary = "自动插单",
description = "创建新工单并按基准时间+冻结期自动排程。若锚点被占用,则占位工单及后续工单后移;若前面有空挡,新工单自动前移到设备最早可用时间",
requestBody = @io.swagger.v3.oas.annotations.parameters.RequestBody(
description = "自动插单参数",
required = true,
content = @io.swagger.v3.oas.annotations.media.Content(
mediaType = "application/json",
examples = {
@io.swagger.v3.oas.annotations.media.ExampleObject(
name = "自动插单示例",
summary = "基础示例",
value = "{\n" +
" \"sceneId\": \"B571EF6682DB463AB2977B1055A74112\",\n" +
" \"newOrder\": {\n" +
" \"orderCode\": \"AUTO_20260326_001\",\n" +
" \"materialId\": \"d5d0dd08-cfb5-2b45-85e9-aba470895423\",\n" +
" \"quantity\": 610000\n" +
" }\n" +
"}"
),
@io.swagger.v3.oas.annotations.media.ExampleObject(
name = "大批量示例",
summary = "大批量订单",
value = "{\n" +
" \"sceneId\": \"B571EF6682DB463AB2977B1055A74112\",\n" +
" \"newOrder\": {\n" +
" \"orderCode\": \"AUTO_20260326_002\",\n" +
" \"materialId\": \"cbd0dd08-49b1-0146-83bd-ec6185316c16\",\n" +
" \"quantity\": 1200000\n" +
" }\n" +
"}"
)
}
)
)
)
public R<String> insertOrderAuto(@RequestBody Map<String, Object> params) {
log.info("insertOrderAuto 请求参数: {}", params);
String sceneId = ParamValidator.getString(params, "sceneId", "场景ID");
@SuppressWarnings("unchecked")
Map<String, Object> newOrderData = (Map<String, Object>) params.get("newOrder");
ParamValidator.validateSceneExists(sceneService, sceneId);
planResultService.InsertOrderAuto(sceneId, newOrderData);
return R.ok("自动插单成功");
}
@PostMapping("/ordermerge") @PostMapping("/ordermerge")
...@@ -1015,7 +1079,7 @@ public class ResourceGanttController { ...@@ -1015,7 +1079,7 @@ public class ResourceGanttController {
) )
) )
public R<SupplyRelationResponse> getSupplyRelation(@RequestBody Map<String, Object> params) { public R<List<Object>> getSupplyRelation(@RequestBody Map<String, Object> params) {
log.info("getSupplyRelation 请求参数: {}", params); log.info("getSupplyRelation 请求参数: {}", params);
// 提取参数 // 提取参数
String sceneId = ParamValidator.getString(params, "sceneId", "场景ID"); String sceneId = ParamValidator.getString(params, "sceneId", "场景ID");
...@@ -1024,7 +1088,7 @@ public class ResourceGanttController { ...@@ -1024,7 +1088,7 @@ public class ResourceGanttController {
// 调用服务获取供给关系 // 调用服务获取供给关系
List<Object> data = planResultService.getSupplyRelation(sceneId, entryId, sceneService); List<Object> data = planResultService.getSupplyRelation(sceneId, entryId, sceneService);
return R.ok(SupplyRelationResponse.success(data)); return R.ok(data);
} }
......
...@@ -51,4 +51,6 @@ public class ScheduleResultDetail { ...@@ -51,4 +51,6 @@ public class ScheduleResultDetail {
public int getProcessingTime() { public int getProcessingTime() {
return EndTime - StartTime; // 绝对处理时间(分钟) return EndTime - StartTime; // 绝对处理时间(分钟)
} }
} }
...@@ -66,4 +66,6 @@ private Long issplit; ...@@ -66,4 +66,6 @@ private Long issplit;
private Long parentid; private Long parentid;
private Long statusOrtems; private Long statusOrtems;
private LocalDateTime actualEndTimeOrtems; private LocalDateTime actualEndTimeOrtems;
private String sceneId;
} }
\ No newline at end of file
...@@ -183,4 +183,9 @@ public class Order { ...@@ -183,4 +183,9 @@ public class Order {
private double changeoverCost; private double changeoverCost;
private int changeoverPriority; private int changeoverPriority;
/**
* 多级排序路径(用于精确字典序排序,避免浮点精度问题)
*/
private List<Integer> sortKey;
} }
\ No newline at end of file
...@@ -416,6 +416,15 @@ public class GeneticAlgorithm { ...@@ -416,6 +416,15 @@ public class GeneticAlgorithm {
chromosome.setResultOld(new CopyOnWriteArrayList<>()); chromosome.setResultOld(new CopyOnWriteArrayList<>());
} }
// 加载锁定工单到ResultOld
List<GAScheduleResult> lockedOrders = GlobalCacheUtil.get("locked_orders_" + sceneId);
if (lockedOrders != null && !lockedOrders.isEmpty()) {
chromosome.setResultOld(ProductionDeepCopyUtil.deepCopyList(lockedOrders, GAScheduleResult.class));
FileHelper.writeLogFile("将 " + lockedOrders.size() + " 个锁定工单加载到初始种群中");
} else {
chromosome.setResultOld(new CopyOnWriteArrayList<>());
}
decoder.decodeChromosomeWithCache(chromosome); decoder.decodeChromosomeWithCache(chromosome);
if (chromosome.getFitness() == 0) { if (chromosome.getFitness() == 0) {
chromosome.setFitness(_fitnessCalculator.calculateFitness(chromosome, _objectiveWeights)); chromosome.setFitness(_fitnessCalculator.calculateFitness(chromosome, _objectiveWeights));
......
...@@ -3,6 +3,7 @@ package com.aps.service; ...@@ -3,6 +3,7 @@ package com.aps.service;
import com.aps.common.util.R; import com.aps.common.util.R;
import com.aps.entity.*; import com.aps.entity.*;
import java.time.LocalDateTime;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
...@@ -67,4 +68,20 @@ public interface LanuchService { ...@@ -67,4 +68,20 @@ public interface LanuchService {
*/ */
R<String> savePlan(String sceneId); R<String> savePlan(String sceneId);
/**
* 插单功能:向现有场景添加新订单
* orderId 会在方法内部自动生成 UUID
*
* @param sceneId 场景ID
* @param orderCode 订单编码
* @param materialId 物料ID
* @param startDate 开始时间
* @param endDate 结束时间
* @param priority 优先级
* @param quantity 数量
* @return 结果
*/
R<String> insertOrder(String sceneId, String orderCode, String materialId,
LocalDateTime startDate, LocalDateTime endDate, Integer priority, Double quantity);
} }
\ No newline at end of file
...@@ -1169,6 +1169,13 @@ public class ChromosomeDataService { ...@@ -1169,6 +1169,13 @@ public class ChromosomeDataService {
config.setEntityName(entityName); config.setEntityName(entityName);
config.setDataSource(DataSourceType.FILE); config.setDataSource(DataSourceType.FILE);
config.setFieldName("Machines"); config.setFieldName("Machines");
}
// 特殊处理:当实体是Order时,映射到orders字段
else if ("order".equalsIgnoreCase(key)) {
config = new EntityConfig();
config.setEntityName(entityName);
config.setDataSource(DataSourceType.FILE);
config.setFieldName("orders");
} else { } else {
// 自动创建数据库配置(默认行为) // 自动创建数据库配置(默认行为)
config = createDefaultDbConfig(entityName); config = createDefaultDbConfig(entityName);
......
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