移动拆分工单修改

parent 582c9a94
......@@ -37,7 +37,7 @@ public class GlobalExceptionHandler {
@ResponseStatus(HttpStatus.BAD_REQUEST)
public R<Void> handleIllegalArgumentException(IllegalArgumentException e) {
log.debug("参数校验失败: {}", e.getMessage());
return R.failed(400, e.getMessage());
return R.failed(500, e.getMessage());
}
/**
......@@ -47,7 +47,7 @@ public class GlobalExceptionHandler {
@ResponseStatus(HttpStatus.BAD_REQUEST)
public R<Void> handleSceneGenerationException(SceneGenerationException e) {
log.debug("场景生成异常: {}", e.getMessage());
return R.failed(400, e.getMessage());
return R.failed(500, e.getMessage());
}
/**
......@@ -127,9 +127,9 @@ public class GlobalExceptionHandler {
log.debug("参数绑定异常: {}", e.getMessage());
FieldError fieldError = e.getBindingResult().getFieldError();
if (fieldError != null) {
return R.failed(400, Objects.requireNonNull(fieldError.getDefaultMessage()));
return R.failed(500, Objects.requireNonNull(fieldError.getDefaultMessage()));
}
return R.failed(400, "参数绑定失败");
return R.failed(500, "参数绑定失败");
}
/**
......@@ -139,7 +139,7 @@ public class GlobalExceptionHandler {
@ResponseStatus(HttpStatus.BAD_REQUEST)
public R<Void> handleMissingServletRequestParameterException(MissingServletRequestParameterException e) {
log.debug("请求参数缺失: {}", e.getMessage());
return R.failed(400, "缺少必要参数: " + e.getParameterName());
return R.failed(500, "缺少必要参数: " + e.getParameterName());
}
/**
......@@ -149,7 +149,7 @@ public class GlobalExceptionHandler {
@ResponseStatus(HttpStatus.BAD_REQUEST)
public R<Void> handleMethodArgumentTypeMismatchException(MethodArgumentTypeMismatchException e) {
log.debug("参数类型不匹配: {}", e.getMessage());
return R.failed(400, "参数类型不匹配: " + e.getName());
return R.failed(500, "参数类型不匹配: " + e.getName());
}
/**
......@@ -159,7 +159,7 @@ public class GlobalExceptionHandler {
@ResponseStatus(HttpStatus.BAD_REQUEST)
public R<Void> handleHttpMessageNotReadableException(HttpMessageNotReadableException e) {
log.debug("HTTP消息不可读: {}", e.getMessage());
return R.failed(400, "请求体格式错误");
return R.failed(500, "请求体格式错误");
}
/**
......
package com.aps.common.util;
import lombok.experimental.UtilityClass;
import lombok.extern.slf4j.Slf4j;
import java.math.BigDecimal;
import java.util.Optional;
@Slf4j
@UtilityClass
public class NumberUtils {
/**
* 安全地将对象转换为Double
*/
public static Double safeToDouble(Object obj) {
return safeToDouble(obj, 0.0);
}
/**
* 安全地将对象转换为Double,可指定默认值
*/
public static Double safeToDouble(Object obj, Double defaultValue) {
if (obj == null) {
return defaultValue;
}
if (obj instanceof Number) {
return ((Number) obj).doubleValue();
}
if (obj instanceof String) {
try {
String str = ((String) obj).trim();
return str.isEmpty() ? defaultValue : Double.parseDouble(str);
} catch (NumberFormatException e) {
log.warn("字符串转Double失败: {}, 使用默认值: {}", obj, defaultValue);
return defaultValue;
}
}
if (obj instanceof Boolean) {
return ((Boolean) obj) ? 1.0 : 0.0;
}
log.warn("不支持的数据类型: {}, 值: {}, 使用默认值: {}",
obj.getClass().getSimpleName(), obj, defaultValue);
return defaultValue;
}
/**
* 安全转换为BigDecimal
*/
public static BigDecimal safeToBigDecimal(Object obj, BigDecimal defaultValue) {
if (obj == null) {
return defaultValue;
}
try {
if (obj instanceof BigDecimal) {
return (BigDecimal) obj;
}
if (obj instanceof Number) {
return BigDecimal.valueOf(((Number) obj).doubleValue());
}
if (obj instanceof String) {
String str = ((String) obj).trim();
return str.isEmpty() ? defaultValue : new BigDecimal(str);
}
} catch (Exception e) {
log.warn("转换BigDecimal失败: {}, 使用默认值", obj, e);
}
return defaultValue;
}
/**
* 检查是否为有效数字
*/
public static boolean isValidDouble(Double value) {
return value != null && !value.isNaN() && !value.isInfinite();
}
}
\ No newline at end of file
package com.aps.common.util;
import com.aps.service.plan.SceneService;
import lombok.experimental.UtilityClass;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import java.time.LocalDateTime;
import java.time.OffsetDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.util.List;
import java.util.Map;
@Slf4j
@UtilityClass
public class ParamValidator {
// ========== 基本参数验证 ==========
public static void requireNonNull(Object value, String fieldName) {
if (value == null) {
throw new IllegalArgumentException(fieldName + "不能为空");
}
}
public static void requireNotBlank(String value, String fieldName) {
if (value == null || value.trim().isEmpty()) {
throw new IllegalArgumentException(fieldName + "不能为空");
}
}
public static void requireNotEmpty(List<?> list, String fieldName) {
if (list == null || list.isEmpty()) {
throw new IllegalArgumentException(fieldName + "不能为空");
}
}
public static void requirePositive(Number number, String fieldName) {
if (number == null) {
throw new IllegalArgumentException(fieldName + "不能为空");
}
if (number.doubleValue() <= 0) {
throw new IllegalArgumentException(fieldName + "必须大于0");
}
}
public static void requireNonNegative(Number number, String fieldName) {
if (number == null) {
throw new IllegalArgumentException(fieldName + "不能为空");
}
if (number.doubleValue() < 0) {
throw new IllegalArgumentException(fieldName + "不能为负数");
}
}
// ========== Map参数提取 ==========
public static String getString(Map<String, Object> params, String key, String fieldName) {
Object value = params.get(key);
requireNonNull(value, fieldName);
if (value instanceof String) {
String strValue = ((String) value).trim();
if (strValue.isEmpty()) {
throw new IllegalArgumentException(fieldName + "不能为空字符串");
}
return strValue;
}
throw new IllegalArgumentException(fieldName + "必须是字符串类型");
}
public static Integer getInteger(Map<String, Object> params, String key, String fieldName) {
Object value = params.get(key);
requireNonNull(value, fieldName);
try {
if (value instanceof Number) {
return ((Number) value).intValue();
} else if (value instanceof String) {
String str = ((String) value).trim();
if (str.isEmpty()) {
throw new IllegalArgumentException(fieldName + "不能为空字符串");
}
return Integer.parseInt(str);
} else {
throw new IllegalArgumentException(fieldName + "格式不正确,必须是数字或字符串");
}
} catch (NumberFormatException e) {
throw new IllegalArgumentException(fieldName + "格式不正确: " + value);
}
}
public static Long getLong(Map<String, Object> params, String key, String fieldName) {
Object value = params.get(key);
requireNonNull(value, fieldName);
try {
if (value instanceof Number) {
return ((Number) value).longValue();
} else if (value instanceof String) {
String str = ((String) value).trim();
if (str.isEmpty()) {
throw new IllegalArgumentException(fieldName + "不能为空字符串");
}
return Long.parseLong(str);
} else {
throw new IllegalArgumentException(fieldName + "格式不正确,必须是数字或字符串");
}
} catch (NumberFormatException e) {
throw new IllegalArgumentException(fieldName + "格式不正确: " + value);
}
}
public static Boolean getBoolean(Map<String, Object> params, String key, String fieldName) {
Object value = params.get(key);
requireNonNull(value, fieldName);
if (value instanceof Boolean) {
return (Boolean) value;
} else if (value instanceof String) {
String str = ((String) value).trim().toLowerCase();
if ("true".equals(str) || "1".equals(str) || "yes".equals(str)) {
return true;
} else if ("false".equals(str) || "0".equals(str) || "no".equals(str)) {
return false;
} else {
throw new IllegalArgumentException(fieldName + "格式不正确: " + value);
}
} else if (value instanceof Number) {
int intValue = ((Number) value).intValue();
if (intValue == 1) return true;
if (intValue == 0) return false;
throw new IllegalArgumentException(fieldName + "必须是0或1");
} else {
throw new IllegalArgumentException(fieldName + "格式不正确");
}
}
public static List<?> getList(Map<String, Object> params, String key, String fieldName) {
Object value = params.get(key);
requireNonNull(value, fieldName);
if (value instanceof List) {
return (List<?>) value;
}
throw new IllegalArgumentException(fieldName + "必须是列表类型");
}
public static LocalDateTime getDateTime(Map<String, Object> params, String key, String fieldName) {
String dateTimeStr = getString(params, key, fieldName);
return parseDateTime(dateTimeStr, fieldName);
}
// ========== 日期时间解析 ==========
public static LocalDateTime parseDateTime(String dateTimeStr, String fieldName) {
try {
if (dateTimeStr == null || dateTimeStr.trim().isEmpty()) {
throw new IllegalArgumentException(fieldName + "不能为空");
}
String trimmed = dateTimeStr.trim();
// 支持ISO格式(带时区)
if (trimmed.endsWith("Z") || trimmed.contains("+") || trimmed.contains("-")) {
try {
OffsetDateTime offsetDateTime = OffsetDateTime.parse(trimmed);
return offsetDateTime.toLocalDateTime();
} catch (DateTimeParseException e) {
// 继续尝试其他格式
}
}
// 尝试标准ISO格式
try {
return LocalDateTime.parse(trimmed);
} catch (DateTimeParseException e) {
// 继续尝试其他格式
}
// 尝试常用格式
DateTimeFormatter[] formatters = {
DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"),
DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm"),
DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss"),
DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss")
};
for (DateTimeFormatter formatter : formatters) {
try {
return LocalDateTime.parse(trimmed, formatter);
} catch (DateTimeParseException e) {
// 继续尝试下一个格式
}
}
throw new IllegalArgumentException(fieldName + "格式不正确: " + trimmed);
} catch (DateTimeParseException e) {
throw new IllegalArgumentException(fieldName + "格式不正确: " + dateTimeStr);
}
}
// ========== 批量参数验证 ==========
public static void validateSceneExists(SceneService sceneService, String sceneId) {
if (sceneId == null || sceneId.trim().isEmpty()) {
throw new IllegalArgumentException("场景ID不能为空");
}
if (sceneService == null) {
throw new IllegalArgumentException("sceneService不能为空");
}
if (sceneService.loadChromosomeFromFile(sceneId) == null) {
throw new RuntimeException("未找到对应的场景文件: " + sceneId);
}
}
public static Double[] convertToDoubleArray(List<?> sourceList, String fieldName) {
requireNotEmpty(sourceList, fieldName);
return sourceList.stream()
.map(item -> {
if (item instanceof Number) {
return ((Number) item).doubleValue();
} else if (item instanceof String) {
try {
return Double.parseDouble(((String) item).trim());
} catch (NumberFormatException e) {
throw new IllegalArgumentException(fieldName + "包含无效的数字: " + item);
}
} else {
throw new IllegalArgumentException(fieldName + "包含不支持的数据类型: " +
(item != null ? item.getClass().getSimpleName() : "null"));
}
})
.toArray(Double[]::new);
}
}
\ No newline at end of file
......@@ -134,6 +134,114 @@ public class SwaggerMapParamConfig {
"}"
));
break;
case "operationMove":
properties.put("SceneId", new StringSchema().description("场景ID").example("B571EF6682DB463AB2977B1055A74112"));
properties.put("opid", new StringSchema().description("操作ID").example(1));
properties.put("newStartTime", new StringSchema().description("新的开始时间").example("2025-11-03T07:36:00.000Z"));
properties.put("newMachineId", new StringSchema().description("新机器ID").example(3402));
examples.put("移动操作示例", createExample(
"将指定操作移动到新的时间和机器上",
"{\n" +
" \"SceneId\": \"B571EF6682DB463AB2977B1055A74112\",\n" +
" \"opid\": 1,\n" +
" \"newStartTime\": \"2025-11-03T07:36:00.000Z\",\n" +
" \"newMachineId\": 3402\n" +
"}"
));
break;
case "operationedit":
properties.put("sceneId", new StringSchema().description("场景ID").example("B571EF6682DB463AB2977B1055A74112"));
properties.put("operation", new StringSchema().description("操作对象"));
examples.put("编辑操作示例", createExample(
"编辑指定的操作",
"{\n" +
" \"SceneId\": \"B571EF6682DB463AB2977B1055A74112\",\n" +
" \"operation\": {}\n" +
"}"
));
break;
case "changebasetime":
properties.put("SceneId", new StringSchema().description("场景ID").example("B571EF6682DB463AB2977B1055A74112"));
properties.put("BaseTime", new StringSchema().description("基础时间").example("2025-11-03T07:36:00.000Z"));
examples.put("更改基准时间示例", createExample(
"更改场景的基准时间",
"{\n" +
" \"SceneId\": \"B571EF6682DB463AB2977B1055A74112\",\n" +
" \"BaseTime\": \"2025-11-03T07:36:00.000Z\"\n" +
"}"
));
break;
case "spiltOperation":
properties.put("sceneId", new StringSchema().description("场景ID").example("B571EF6682DB463AB2977B1055A74112"));
properties.put("opid", new StringSchema().description("操作ID").example(1));
properties.put("splitCounts", new StringSchema().description("拆分数量数组").example("[20000.0, 30000.0]"));
examples.put("拆分操作示例", createExample(
"按指定数量拆分操作",
"{\n" +
" \"SceneId\": \"B571EF6682DB463AB2977B1055A74112\",\n" +
" \"opid\": 2,\n" +
" \"splitCounts\": [20000, 30000]\n" +
"}"
));
break;
case "delOperation":
properties.put("sceneId", new StringSchema().description("场景ID").example("B571EF6682DB463AB2977B1055A74112"));
properties.put("opid", new StringSchema().description("操作ID").example(1));
examples.put("删除操作示例", createExample(
"删除指定操作",
"{\n" +
" \"SceneId\": \"B571EF6682DB463AB2977B1055A74112\",\n" +
" \"opid\": 1\n" +
"}"
));
break;
case "lockedOperation":
properties.put("sceneId", new StringSchema().description("场景ID").example("B571EF6682DB463AB2977B1055A74112"));
properties.put("opid", new StringSchema().description("操作ID").example(1));
properties.put("isLocked", new StringSchema().description("是否锁定").example(true));
examples.put("锁定操作示例", createExample(
"锁定或解锁指定操作",
"{\n" +
" \"SceneId\": \"B571EF6682DB463AB2977B1055A74112\",\n" +
" \"opid\": 1,\n" +
" \"isLocked\": true\n" +
"}"
));
break;
case "spiltOrder":
properties.put("sceneId", new StringSchema().description("场景ID").example("B571EF6682DB463AB2977B1055A74112"));
properties.put("orderid", new StringSchema().description("订单ID").example("fcc0892a-0483-4da7-8414-9ce98be36e53"));
properties.put("splitCounts", new StringSchema().description("拆分数量数组").example("[20000.0, 20000.0, 10000.0]"));
examples.put("拆分订单示例", createExample(
"按指定数量拆分订单",
"{\n" +
" \"SceneId\": \"B571EF6682DB463AB2977B1055A74112\",\n" +
" \"orderid\": \"fcc0892a-0483-4da7-8414-9ce98be36e53\",\n" +
" \"splitCounts\": [20000, 20000, 10000]\n" +
"}"
));
break;
case "orderMerge":
properties.put("sceneId", new StringSchema().description("场景ID").example("B571EF6682DB463AB2977B1055A74112"));
properties.put("sourceorderid", new StringSchema().description("源订单ID").example("5be078b725b34ade8b6638f74dad6b10"));
properties.put("targetorderid", new StringSchema().description("目标订单ID").example("2a0f23d2429f4e5da7b3929da75a803d"));
examples.put("合并订单示例", createExample(
"将源订单合并到目标订单",
"{\n" +
" \"sceneId\": \"B571EF6682DB463AB2977B1055A74112\",\n" +
" \"sourceorderid\": \"5be078b725b34ade8b6638f74dad6b10\",\n" +
" \"targetorderid\": \"2a0f23d2429f4e5da7b3929da75a803d\"\n" +
"}"
));
break;
}
if (!properties.isEmpty()) {
......@@ -177,6 +285,22 @@ public class SwaggerMapParamConfig {
case "getProductGantt":
return "获取资源甘特图请求参数";
case "operationMove":
return "移动操作请求参数";
case "operationedit":
return "编辑操作请求参数";
case "changebasetime":
return "更改基准时间请求参数";
case "spiltOperation":
return "拆分操作请求参数";
case "delOperation":
return "删除操作请求参数";
case "lockedOperation":
return "锁定操作请求参数";
case "spiltOrder":
return "拆分订单请求参数";
case "orderMerge":
return "合并订单请求参数";
default:
return "请求参数";
}
......
......@@ -33,6 +33,8 @@ public class GAScheduleResult {
private double ProcessingTime; // 绝对处理时间(分钟)
private int ChangeoverTime;
private int seq; //工序顺序
public int getFlowTime() {
return EndTime - StartTime;
};
......
......@@ -107,4 +107,5 @@ public class TaskVO {
}
\ No newline at end of file
package com.aps.entity;
import lombok.Data;
import com.baomidou.mybatisplus.annotation.TableName;
import java.io.Serializable;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import com.baomidou.mybatisplus.annotation.TableName;
import java.io.Serializable;
import java.math.BigDecimal;
import java.time.LocalDateTime;
@Data
public class RoutingDetail {
private Long id;
private LocalDateTime creationTime;
private BigDecimal creatorUserId;
private LocalDateTime lastModificationTime;
private BigDecimal lastModifierUserId;
private Short isDeleted;
private BigDecimal deleterUserId;
private LocalDateTime deletionTime;
private Long classId;
private Long routingHeaderId;
private String name;
private Long taskSeq;
private String description;
private String taskContent;
private Long resourceId;
private Short resourceType;
private BigDecimal runtime;
private BigDecimal setupTime;
private BigDecimal transportTime;
private Short checkTime;
private Short checkFlag;
private Short efficiencyValue;
private BigDecimal singleOut;
private Short isOutside;
private Long departmentId;
private Short isImportant;
private Long milestoneId;
private Long phaseId;
private Short status;
private String remark;
private String extend;
private Short outsideTime;
private Short performanceHours;
private String resourceCode;
private Short isImportantResources;
private Short schedulingWorkingHours;
private Short realWorkingHours;
private Short realRuntime;
private Short performanceWorkingHours;
private Short isParticipateIntime;
private String equipType;
private Long equipTypeId;
private String note;
private String fileId;
private Long measureUnit;
private String measureUnitName;
private Short afterProcessTime;
private Long isGeneral;
private Long canInterrupt;
private Long canStartEarly;
private Short previousStartTimeBegin;
private String code;
private String tool;
private int changeLineTime;
private Long preDetailId;
private Long connectType;
private Integer connectProperty;
private String connectTypeName;
private String connectPropertyName;
private String strSetupTime;
private Long isync;
private int constTime;
private String usable;
private BigDecimal leadTime;
private BigDecimal batchQty;
private BigDecimal minProductionQty;
private BigDecimal maxProductionQty;
private BigDecimal productionTakt;
private int preprocessingTime;
private int postprocessingTime;
private BigDecimal splitMinQty;
private BigDecimal splitMaxQty;
private Short equipmentConnectivity;
private Long id;
private LocalDateTime creationTime;
private BigDecimal creatorUserId;
private LocalDateTime lastModificationTime;
private BigDecimal lastModifierUserId;
private Short isDeleted;
private BigDecimal deleterUserId;
private LocalDateTime deletionTime;
private Long routingHeaderId;
private String name;
private Short taskSeq;
private Short runtime;
private Short setupTime;
private Short efficiencyValue;
private Short singleOut;
private Short isOutside;
private Short status;
private String remark;
private String extend;
private Short outsideTime;
private Short performanceHours;
private Short schedulingWorkingHours;
private Short realWorkingHours;
private Short realRuntime;
private Short performanceWorkingHours;
private String equipType;
private Long equipTypeId;
private Long canInterrupt;
private Short previousStartTimeBegin;
private Short changeLineTime;
private Long preDetailId;
private Long connectType;
private Long connectProperty;
private String connectTypeName;
private String connectPropertyName;
private BigDecimal constTime;
private BigDecimal increment;
private BigDecimal batchQty;
private BigDecimal minProductionQty;
private BigDecimal maxProductionQty;
private BigDecimal productionTakt;
private BigDecimal preprocessingTime;
private BigDecimal postprocessingTime;
private BigDecimal splitMinQty;
private BigDecimal splitMaxQty;
private Short equipmentConnectivity;
private Long singleOutUnitId;
private String singleOutUnitName;
private Long connectUnitId;
private String connectUnitName;
}
\ No newline at end of file
......@@ -16,7 +16,7 @@ public class Machine {
private List<Shift> shifts;
private List<MaintenanceWindow> maintenanceWindows;
private List<TimeSegment> availability;
private String code;
private List<Holiday> holidays;
private double actualWorkTime;
......
......@@ -38,6 +38,15 @@ public class GeneticDecoder {
private MachineCalculator machineCalculator;
private DiscreteParameterMatrixService discreteParameterMatrixService;
// 添加静态实例引用
private static DiscreteParameterMatrixService staticDiscreteParameterMatrixService;
// 设置静态服务实例的方法
public static void setDiscreteParameterMatrixService(DiscreteParameterMatrixService service) {
staticDiscreteParameterMatrixService = service;
}
public GeneticDecoder(GlobalParam globalParam,LocalDateTime baseTime, List<Machine> machines, List<Order> orders,
List<Material> materials, MachineSchedulerService machineScheduler) {
this.baseTime = baseTime;
......@@ -374,6 +383,7 @@ public class GeneticDecoder {
result.setOneTime(processingTime);
result.setQuantity(operation.getQuantity());
result.setTeardownTime(teardownTime);
if(existingResult!=null) {
result.setDesignatedStartTime(existingResult.getDesignatedStartTime());
......@@ -656,19 +666,15 @@ public class GeneticDecoder {
//离散参数
// prev.getDiscreteParameter()
setupTime = (prev.getProductId() != operation.getProductId())
? (int) discreteParameterMatrixService.getDiscreteParameterMatrixValue(prev, operation)
: 0;
if (staticDiscreteParameterMatrixService != null) {
setupTime = (int) staticDiscreteParameterMatrixService.getDiscreteParameterMatrixValue(prev, operation);
} else {
// 添加兜底处理,避免空指针异常
setupTime = 0;
}
if (setupTime > 0) {
}
}
return setupTime;
}
......
......@@ -53,7 +53,7 @@ public class ScheduleOperationService {
.indexOf(newMachineId) + 1;
if (machineOptionIndex == 0) {
throw new NoSuchElementException("Machine not found: " + newMachineId);
throw new NoSuchElementException("不能移动到该设备");
}
// 设置约束
......@@ -140,13 +140,13 @@ public class ScheduleOperationService {
// 添加新节点
OperatRels = IdGroupingWithDualSerial.addNode(OperatRels, targetGroupIndex, newId, newParentIds, newChildIds,targetOp.getExecId());
}
}
}
chromosome.setOperatRel(OperatRels);
//当前组的
groupResult = OperatRels.get(targetGroupIndex);
groupResult = OperatRels.get(targetGroupIndex);
nodeInfoList = groupResult.getNodeInfoList();
//全局ID
nodeInfoList = groupResult.getNodeInfoList();
//全局ID
int globalOpId = chromosome.getGlobalOpList().stream()
.mapToInt(GlobalOperationInfo::getGlobalOpId)
.max()
......@@ -163,7 +163,7 @@ public class ScheduleOperationService {
.filter(i -> OperationSequencing.get(i).equals(targetOp.GroupId)) // 过滤出值为1的索引
.skip(targetOp.Sequence-1) // 跳过第一个匹配项
.findFirst(); // 取第二个匹配项
int targetOpIndex= OperationIndex.getAsInt()+1;
int targetOpIndex= OperationIndex.getAsInt()+1;
for (NodeInfo nodeInfo : nodeInfoList) {
Entry entry = allOperations.stream()
.filter(o -> o.getId() == nodeInfo.getGlobalSerial())
......@@ -173,8 +173,8 @@ public class ScheduleOperationService {
{
//存在则修改顺和前后序
entry.setSequence(nodeInfo.getGroupSerial());
// entry.setPrevEntryIds(nodeInfo.getNewParentIds());
// entry.setNextEntryIds(nodeInfo.getNewChildIds());
// entry.setPrevEntryIds(nodeInfo.getNewParentIds());
// entry.setNextEntryIds(nodeInfo.getNewChildIds());
if(nodeInfo.getNewParentIds()!=null)
{
List<OperationDependency> OperationDependency=new ArrayList<>();
......@@ -183,7 +183,9 @@ public class ScheduleOperationService {
od.setPrevOperationId(id);
OperationDependency.add(od);
}
entry.setPrevEntryIds(OperationDependency);
if (entry != null) {
entry.setPrevEntryIds(OperationDependency);
}
}
if(nodeInfo.getNewChildIds()!=null)
{
......@@ -193,7 +195,9 @@ public class ScheduleOperationService {
od.setNextOperationId(id);
OperationDependency.add(od);
}
entry.setNextEntryIds(OperationDependency);
if (entry != null) {
entry.setNextEntryIds(OperationDependency);
}
}
GlobalOperationInfo info= chromosome.getGlobalOpList().stream()
.filter(t->t.getOp().getId()==entry.getId())
......@@ -215,8 +219,8 @@ public class ScheduleOperationService {
newOp.setId(nodeInfo.getGlobalSerial());
newOp.setSequence(nodeInfo.getGroupSerial());
newOp.setExecId(nodeInfo.getOriginalId());
// newOp.setPrevEntryIds(nodeInfo.getNewParentIds());
// newOp.setNextEntryIds(nodeInfo.getNewChildIds());
// newOp.setPrevEntryIds(nodeInfo.getNewParentIds());
// newOp.setNextEntryIds(nodeInfo.getNewChildIds());
if(nodeInfo.getNewParentIds()!=null)
{
List<OperationDependency> OperationDependency=new ArrayList<>();
......@@ -225,7 +229,7 @@ public class ScheduleOperationService {
od.setPrevOperationId(id);
OperationDependency.add(od);
}
entry.setPrevEntryIds(OperationDependency);
newOp.setPrevEntryIds(OperationDependency);
}
if(nodeInfo.getNewChildIds()!=null)
{
......@@ -235,7 +239,7 @@ public class ScheduleOperationService {
od.setNextOperationId(id);
OperationDependency.add(od);
}
entry.setNextEntryIds(OperationDependency);
newOp.setNextEntryIds(OperationDependency);
}
newOp.setQuantity(newids.get(nodeInfo.getOriginalId()));
newOp.setMainId(MainId);
......@@ -556,7 +560,9 @@ public class ScheduleOperationService {
od.setPrevOperationId(id);
OperationDependency.add(od);
}
entry.setPrevEntryIds(OperationDependency);
if (entry != null) {
entry.setPrevEntryIds(OperationDependency);
}
}
if(node.getNewChildIds()!=null)
{
......@@ -566,7 +572,9 @@ public class ScheduleOperationService {
od.setNextOperationId(id);
OperationDependency.add(od);
}
entry.setNextEntryIds(OperationDependency);
if (entry != null) {
entry.setNextEntryIds(OperationDependency);
}
}
GlobalOperationInfo info= chromosome.getGlobalOpList().stream()
.filter(t->t.getOp().getId()==entry.getId())
......
......@@ -38,9 +38,11 @@ public class DiscreteParameterMatrixServiceImpl extends ServiceImpl<DiscretePara
// 2. 获取基础数据
List<RoutingDiscreteParam> firstParams = lastEntry.getDiscreteParameter();
List<RoutingDiscreteParam> secondParams = entry.getDiscreteParameter();
// 检查参数列表是否为null
if (firstParams == null || secondParams == null) {
return 0.0;
}
if (firstParams.isEmpty() || secondParams.isEmpty()) {
return 0.0;
......
......@@ -22,6 +22,7 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.annotation.PostConstruct;
import java.io.IOException;
import java.math.BigDecimal;
import java.time.LocalDateTime;
......@@ -92,6 +93,12 @@ public class PlanResultService {
private LocalDateTime baseTime = LocalDateTime.of(2025, 11, 1, 0, 0, 0);
@PostConstruct
public void init() {
// 设置GeneticDecoder中的静态服务引用
GeneticDecoder.setDiscreteParameterMatrixService(_discreteParameterMatrixService);
}
public List<ScheduleChromosome> execute() {
try {
// 1. 读取数据
......@@ -397,6 +404,8 @@ order.setDueDate(LocalDateTime.of(2025, 12, 1,0,0,0));
// WriteScheduleSummary(chromosome);
_sceneService.saveChromosomeToFile(chromosome, SceneId);
return chromosome;
}
......@@ -1072,6 +1081,7 @@ private GlobalParam InitGlobalParam()
Machine machine=new Machine();
machine.setId(id);
machines.add(machine);
machine.setCode(ProdEquipments.stream().filter(t -> t.getEquipId() == id).findFirst().get().getEquipCode());
}
//节假日
List<MesHoliday> holidays= _MesHolidayService.list();
......@@ -1187,6 +1197,8 @@ private GlobalParam InitGlobalParam()
public List<com.aps.entity.Gantt.ResourceGanttVO> convertToResourceGanttVO1(Chromosome scheduleChromosome, List<Machine> machineList) {
List<com.aps.entity.Gantt.ResourceGanttVO> resourceGanttVOList = new ArrayList<>();
List<Entry> allOperations = scheduleChromosome.getAllOperations();
// 遍历所有机器资源
if (machineList != null) {
for (int i = 0; i < machineList.size(); i++) {
......@@ -1196,6 +1208,7 @@ private GlobalParam InitGlobalParam()
resourceGanttVO.setId(machine.getId());
resourceGanttVO.setName(machine.getId()+"号设备");
resourceGanttVO.setShift(convertToShiftVO(machine));
resourceGanttVO.setCode(machine.getCode());
// 转换任务列表
List<com.aps.entity.Gantt.TaskVO> taskVOList = new ArrayList<>();
if (scheduleChromosome.getResult() != null) {
......@@ -1208,8 +1221,13 @@ private GlobalParam InitGlobalParam()
machineGenes.sort((g1, g2) -> Integer.compare(g1.getStartTime(), g2.getStartTime()));
for (GAScheduleResult gene : machineGenes) {
Entry entry = allOperations.stream()
.filter(t -> t.getId() == gene.getOperationId()).findFirst().orElse(null);
com.aps.entity.Gantt.TaskVO taskVO = new com.aps.entity.Gantt.TaskVO();
// taskVO.setId(gene.getId()); // 临时处理
taskVO.setId(String.valueOf(gene.getOperationId()));
taskVO.setPlanId(gene.getOrderId()); // 默认值
// taskVO.setProductType(0); // 默认值
// taskVO.setProductName("产品"+gene.getProductId());
......@@ -1223,6 +1241,12 @@ private GlobalParam InitGlobalParam()
taskVO.setEquipCooling(0); // 默认值
taskVO.setEquipType(resourceGanttVO.getType());
taskVO.setEquipName(resourceGanttVO.getName());
if (entry != null) {
taskVO.setSeq(Math.toIntExact(entry.getTaskSeq())); // 使用工序ID
taskVO.setSeqName(entry.getRoutingDetailName());
}
// taskVO.setDuration(calculateDuration(
// scheduleChromosome.getBaseTime().plusMinutes(gene.getStartTime()),
// scheduleChromosome.getBaseTime().plusMinutes(gene.getEndTime()))); // 计算持续时间
......@@ -1232,7 +1256,6 @@ private GlobalParam InitGlobalParam()
taskVO.setShopId(machine.getId());
taskVO.setShopName(resourceGanttVO.getShopName());
taskVO.setStatus(0); // 默认值
taskVO.setDetailId((long) gene.getStartTime()); // 将productId和operationID组合为detailId
taskVO.setHeaderId(gene.getEndTime()); // 默认值
// taskVO.setHeaderName("工艺"+gene.getProductId()); // 默认值
......@@ -1316,7 +1339,7 @@ private GlobalParam InitGlobalParam()
for (int i = 0; i < genes.size(); i++) {
GAScheduleResult gene = genes.get(i);
com.aps.entity.Gantt.TaskVO taskVO = new com.aps.entity.Gantt.TaskVO();
taskVO.setId(gene.getOrderId()); // 生成唯一ID
taskVO.setId(String.valueOf(gene.getOperationId())); // 生成唯一ID
taskVO.setPlanId(String.valueOf(orderId));
taskVO.setProductType(0);
taskVO.setProductName("产品"+gene.getProductId());
......
......@@ -4,75 +4,61 @@
<!-- 通用查询映射结果 -->
<resultMap id="BaseResultMap" type="com.aps.entity.RoutingDetail">
<id column="id" property="id" />
<result column="creation_time" property="creationTime" />
<result column="creator_user_id" property="creatorUserId" />
<result column="last_modification_time" property="lastModificationTime" />
<result column="last_modifier_user_id" property="lastModifierUserId" />
<result column="is_deleted" property="isDeleted" />
<result column="deleter_user_id" property="deleterUserId" />
<result column="deletion_time" property="deletionTime" />
<result column="class_id" property="classId" />
<result column="routing_header_id" property="routingHeaderId" />
<result column="name" property="name" />
<result column="task_seq" property="taskSeq" />
<result column="description" property="description" />
<result column="task_content" property="taskContent" />
<result column="resource_id" property="resourceId" />
<result column="resource_type" property="resourceType" />
<result column="runtime" property="runtime" />
<result column="setup_time" property="setupTime" />
<result column="transport_time" property="transportTime" />
<result column="check_time" property="checkTime" />
<result column="check_flag" property="checkFlag" />
<result column="efficiency_value" property="efficiencyValue" />
<result column="single_out" property="singleOut" />
<result column="is_outside" property="isOutside" />
<result column="department_id" property="departmentId" />
<result column="is_important" property="isImportant" />
<result column="milestone_id" property="milestoneId" />
<result column="phase_id" property="phaseId" />
<result column="status" property="status" />
<result column="remark" property="remark" />
<result column="extend" property="extend" />
<result column="outside_time" property="outsideTime" />
<result column="performance_hours" property="performanceHours" />
<result column="resource_code" property="resourceCode" />
<result column="is_important_resources" property="isImportantResources" />
<result column="scheduling_working_hours" property="schedulingWorkingHours" />
<result column="real_working_hours" property="realWorkingHours" />
<result column="real_runtime" property="realRuntime" />
<result column="performance_working_hours" property="performanceWorkingHours" />
<result column="is_participate_intime" property="isParticipateIntime" />
<result column="equip_type" property="equipType" />
<result column="equip_type_id" property="equipTypeId" />
<result column="note" property="note" />
<result column="file_id" property="fileId" />
<result column="measure_unit" property="measureUnit" />
<result column="measure_unit_name" property="measureUnitName" />
<result column="after_process_time" property="afterProcessTime" />
<result column="is_general" property="isGeneral" />
<result column="can_interrupt" property="canInterrupt" />
<result column="can_start_early" property="canStartEarly" />
<result column="previous_start_time_begin" property="previousStartTimeBegin" />
<result column="code" property="code" />
<result column="tool" property="tool" />
<result column="change_line_time" property="changeLineTime" />
<result column="pre_detail_id" property="preDetailId" />
<result column="connect_type" property="connectType" />
<result column="connect_property" property="connectProperty" />
<result column="connect_type_name" property="connectTypeName" />
<result column="connect_property_name" property="connectPropertyName" />
<result column="str_setup_time" property="strSetupTime" />
<result column="isync" property="isync" />
<result column="const_time" property="constTime" />
<result column="usable" property="usable" />
<result column="lead_time" property="leadTime" />
<id column="ID" property="id" />
<result column="CREATION_TIME" property="creationTime" />
<result column="CREATOR_USER_ID" property="creatorUserId" />
<result column="LAST_MODIFICATION_TIME" property="lastModificationTime" />
<result column="LAST_MODIFIER_USER_ID" property="lastModifierUserId" />
<result column="IS_DELETED" property="isDeleted" />
<result column="DELETER_USER_ID" property="deleterUserId" />
<result column="DELETION_TIME" property="deletionTime" />
<result column="ROUTING_HEADER_ID" property="routingHeaderId" />
<result column="NAME" property="name" />
<result column="TASK_SEQ" property="taskSeq" />
<result column="RUNTIME" property="runtime" />
<result column="SETUP_TIME" property="setupTime" />
<result column="EFFICIENCY_VALUE" property="efficiencyValue" />
<result column="SINGLE_OUT" property="singleOut" />
<result column="IS_OUTSIDE" property="isOutside" />
<result column="STATUS" property="status" />
<result column="REMARK" property="remark" />
<result column="EXTEND" property="extend" />
<result column="OUTSIDE_TIME" property="outsideTime" />
<result column="PERFORMANCE_HOURS" property="performanceHours" />
<result column="SCHEDULING_WORKING_HOURS" property="schedulingWorkingHours" />
<result column="REAL_WORKING_HOURS" property="realWorkingHours" />
<result column="REAL_RUNTIME" property="realRuntime" />
<result column="PERFORMANCE_WORKING_HOURS" property="performanceWorkingHours" />
<result column="EQUIP_TYPE" property="equipType" />
<result column="EQUIP_TYPE_ID" property="equipTypeId" />
<result column="CAN_INTERRUPT" property="canInterrupt" />
<result column="PREVIOUS_START_TIME_BEGIN" property="previousStartTimeBegin" />
<result column="CHANGE_LINE_TIME" property="changeLineTime" />
<result column="PRE_DETAIL_ID" property="preDetailId" />
<result column="CONNECT_TYPE" property="connectType" />
<result column="CONNECT_PROPERTY" property="connectProperty" />
<result column="CONNECT_TYPE_NAME" property="connectTypeName" />
<result column="CONNECT_PROPERTY_NAME" property="connectPropertyName" />
<result column="CONST_TIME" property="constTime" />
<result column="INCREMENT" property="increment" />
<result column="BATCH_QTY" property="batchQty" />
<result column="MIN_PRODUCTION_QTY" property="minProductionQty" />
<result column="MAX_PRODUCTION_QTY" property="maxProductionQty" />
<result column="PRODUCTION_TAKT" property="productionTakt" />
<result column="PREPROCESSING_TIME" property="preprocessingTime" />
<result column="POSTPROCESSING_TIME" property="postprocessingTime" />
<result column="SPLIT_MIN_QTY" property="splitMinQty" />
<result column="SPLIT_MAX_QTY" property="splitMaxQty" />
<result column="EQUIPMENT_CONNECTIVITY" property="equipmentConnectivity" />
<result column="SINGLE_OUT_UNIT_ID" property="singleOutUnitId" />
<result column="SINGLE_OUT_UNIT_NAME" property="singleOutUnitName" />
<result column="CONNECT_UNIT_ID" property="connectUnitId" />
<result column="CONNECT_UNIT_NAME" property="connectUnitName" />
</resultMap>
<!-- 通用查询结果列 -->
<sql id="Base_Column_List">
id, creation_time, creator_user_id, last_modification_time, last_modifier_user_id, is_deleted, deleter_user_id, deletion_time, class_id, routing_header_id, name, task_seq, description, task_content, resource_id, resource_type, runtime, setup_time, transport_time, check_time, check_flag, efficiency_value, single_out, is_outside, department_id, is_important, milestone_id, phase_id, status, remark, extend, outside_time, performance_hours, resource_code, is_important_resources, scheduling_working_hours, real_working_hours, real_runtime, performance_working_hours, is_participate_intime, equip_type, equip_type_id, note, file_id, measure_unit, measure_unit_name, after_process_time, is_general, can_interrupt, can_start_early, previous_start_time_begin, code, tool, change_line_time, pre_detail_id, connect_type, connect_property, connect_type_name, connect_property_name, str_setup_time, isync, const_time, usable, lead_time
ID, CREATION_TIME, CREATOR_USER_ID, LAST_MODIFICATION_TIME, LAST_MODIFIER_USER_ID, IS_DELETED, DELETER_USER_ID, DELETION_TIME, ROUTING_HEADER_ID, NAME, TASK_SEQ, RUNTIME, SETUP_TIME, EFFICIENCY_VALUE, SINGLE_OUT, IS_OUTSIDE, STATUS, REMARK, EXTEND, OUTSIDE_TIME, PERFORMANCE_HOURS, SCHEDULING_WORKING_HOURS, REAL_WORKING_HOURS, REAL_RUNTIME, PERFORMANCE_WORKING_HOURS, EQUIP_TYPE, EQUIP_TYPE_ID, CAN_INTERRUPT, PREVIOUS_START_TIME_BEGIN, CHANGE_LINE_TIME, PRE_DETAIL_ID, CONNECT_TYPE, CONNECT_PROPERTY, CONNECT_TYPE_NAME, CONNECT_PROPERTY_NAME, CONST_TIME, INCREMENT, BATCH_QTY, MIN_PRODUCTION_QTY, MAX_PRODUCTION_QTY, PRODUCTION_TAKT, PREPROCESSING_TIME, POSTPROCESSING_TIME, SPLIT_MIN_QTY, SPLIT_MAX_QTY, EQUIPMENT_CONNECTIVITY, SINGLE_OUT_UNIT_ID, SINGLE_OUT_UNIT_NAME, CONNECT_UNIT_ID, CONNECT_UNIT_NAME
</sql>
</mapper>
\ No newline at end of file
</mapper>
......@@ -2,11 +2,15 @@ package com.aps.demo;
import com.aps.ApsApplication;
import com.aps.entity.Algorithm.Chromosome;
import com.aps.entity.basic.Machine;
import com.aps.service.plan.PlanResultService;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import java.util.ArrayList;
import java.util.List;
@SpringBootTest(classes = ApsApplication.class)
public class PlanResultServiceTest {
......@@ -17,16 +21,25 @@ public class PlanResultServiceTest {
public void testExecute2() {
// 这里需要一个有效的SceneId来测试
// 在实际测试中,您需要提供一个数据库中存在的SceneId
String sceneId = "7E99857F64A44780AF06C326CAEE9682";
String sceneId = "21DA0A695F2A4AA1B860ED43723F118A";
try {
Chromosome result = planResultService.execute2(sceneId);
System.out.println("执行成功,结果:" + (result != null ? "获得染色体对象" : "空结果"));
if (result != null) {
System.out.println("适应度: " + result.getFitness());
System.out.println("工序字符串: " + result.getOperationStr());
}
// Chromosome result = planResultService.execute2(sceneId);
// System.out.println("执行成功,结果:" + (result != null ? "获得染色体对象" : "空结果"));
//
// if (result != null) {
// System.out.println("适应度: " + result.getFitness());
// System.out.println("工序字符串: " + result.getOperationStr());
// }
List<Double> splitCounts = new ArrayList<>();
splitCounts.add(20000.0);
splitCounts.add(30000.0);
planResultService.SpiltOperation(sceneId,1,splitCounts.toArray(new Double[0]));
} catch (Exception e) {
System.err.println("执行过程中发生异常: " + e.getMessage());
e.printStackTrace();
......
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