Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
H
HYH.APSJ
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
佟礼
HYH.APSJ
Commits
b3dc1350
Commit
b3dc1350
authored
Mar 13, 2026
by
DESKTOP-VKRD9QF\Administration
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
插单
parent
6430785e
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
747 additions
and
42 deletions
+747
-42
ResourceGanttController.java
...ava/com/aps/controller/gantt/ResourceGanttController.java
+14
-2
GeneticDecoder.java
src/main/java/com/aps/service/Algorithm/GeneticDecoder.java
+1
-1
ScheduleOperationService.java
...a/com/aps/service/Algorithm/ScheduleOperationService.java
+215
-0
LanuchServiceImpl.java
src/main/java/com/aps/service/impl/LanuchServiceImpl.java
+68
-15
LockedOrderProcessorService.java
...ava/com/aps/service/plan/LockedOrderProcessorService.java
+349
-23
PlanResultService.java
src/main/java/com/aps/service/plan/PlanResultService.java
+100
-1
No files found.
src/main/java/com/aps/controller/gantt/ResourceGanttController.java
View file @
b3dc1350
...
...
@@ -400,11 +400,23 @@ public class ResourceGanttController {
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
(
"/ordermerge"
)
@Operation
(
summary
=
"订单合并"
,
description
=
"订单合并"
)
...
...
src/main/java/com/aps/service/Algorithm/GeneticDecoder.java
View file @
b3dc1350
...
...
@@ -282,7 +282,7 @@ if(finishedOrder==null||finishedOrder.size()==0)
public
void
decode
(
Chromosome
chromosome
)
{
List
<
OrderMaterialRequirement
>
orderMaterials
=
materialRequirementService
.
buildMultiLevelRequirementNetwork
(
chromosome
,
sceneId
,
baseTime
,
_globalParam
);
//
List<OrderMaterialRequirement> orderMaterials = materialRequirementService.buildMultiLevelRequirementNetwork(chromosome, sceneId, baseTime,_globalParam);
chromosome
.
setScenarioID
(
sceneId
);
if
(
_globalParam
.
isIsCheckSf
())
{
int
isnew
=
generateGlobalOpList
(
chromosome
);
...
...
src/main/java/com/aps/service/Algorithm/ScheduleOperationService.java
View file @
b3dc1350
package
com
.
aps
.
service
.
Algorithm
;
import
com.aps.common.util.ProductionDeepCopyUtil
;
import
com.aps.entity.*
;
import
com.aps.entity.Algorithm.*
;
import
com.aps.entity.Algorithm.IDAndChildID.GroupResult
;
import
com.aps.entity.Algorithm.IDAndChildID.NodeInfo
;
...
...
@@ -926,6 +927,220 @@ if(targetOp.getSequence()>1) {
redecode
(
chromosome
,
chromosome
.
getBaseTime
(),
globalParam
);
}
/**
* 插入新订单到排产中
* 将新订单排在指定订单后面
*
* @param chromosome 染色体对象
* @param afterOrderId 插入位置订单ID(新订单将排在此订单后面)
* @param newOrderId 新订单ID
* @param newLaunchOrder 新订单对象
* @param newProcessExecs 新订单的工序列表
* @param globalParam 全局参数
*/
public
void
InsertOrder
(
Chromosome
chromosome
,
String
afterOrderId
,
String
newOrderId
,
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
);
newOrder
.
setOrderCode
(
newLaunchOrder
.
getOrderCode
());
newOrder
.
setQuantity
(
newLaunchOrder
.
getQuantity
());
newOrder
.
setPriority
(
newLaunchOrder
.
getOrderPriority
()
!=
null
?
newLaunchOrder
.
getOrderPriority
()
:
1
);
newOrder
.
setMaterialId
(
newLaunchOrder
.
getMaterialId
());
newOrder
.
setMaterialCode
(
newLaunchOrder
.
getMaterialCode
());
newOrder
.
setMaterialName
(
newLaunchOrder
.
getMaterialName
());
newOrder
.
setStartDate
(
newLaunchOrder
.
getStartDate
());
newOrder
.
setDueDate
(
newLaunchOrder
.
getEndDate
());
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
();
newEntry
.
setExecId
(
processExec
.
getExecId
());
newEntry
.
setOrderId
(
newOrderId
);
newEntry
.
setOrderCode
(
newLaunchOrder
.
getOrderCode
());
newEntry
.
setGroupId
(
newGroupId
);
newEntry
.
setQuantity
(
newLaunchOrder
.
getQuantity
());
newEntry
.
setSequence
(
processExec
.
getTaskSeq
()
!=
null
?
processExec
.
getTaskSeq
().
intValue
()
:
1
);
newEntry
.
setNewCreate
(
true
);
newEntry
.
setState
(
2
);
// 设置工序相关信息
newEntry
.
setRoutingDetailId
(
processExec
.
getRoutingDetailId
());
// 使用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
());
}
newEntry
.
setChangeLineTime
(
processExec
.
getChangeLineTime
());
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
<>());
newEntrys
.
add
(
newEntry
);
}
// 3. 建立工序之间的依赖关系
for
(
int
i
=
0
;
i
<
newEntrys
.
size
();
i
++)
{
Entry
entry
=
newEntrys
.
get
(
i
);
if
(
i
==
0
)
{
// 第一道工序,没有前置工序
newIdList
.
add
(
entry
.
getExecId
());
newChildIdList
.
add
(
i
+
1
<
newEntrys
.
size
()
?
newEntrys
.
get
(
i
+
1
).
getExecId
()
:
""
);
}
else
if
(
i
==
newEntrys
.
size
()
-
1
)
{
// 最后一道工序,没有后续工序
newIdList
.
add
(
entry
.
getExecId
());
newChildIdList
.
add
(
""
);
}
else
{
// 中间工序
newIdList
.
add
(
entry
.
getExecId
());
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
<>();
for
(
int
id
:
nodeInfo
.
getNewParentIds
())
{
OperationDependency
od
=
new
OperationDependency
();
od
.
setPrevOperationId
(
id
);
dependencies
.
add
(
od
);
}
entry
.
setPrevEntryIds
(
dependencies
);
}
if
(
nodeInfo
.
getNewChildIds
()
!=
null
)
{
List
<
OperationDependency
>
dependencies
=
new
ArrayList
<>();
for
(
int
id
:
nodeInfo
.
getNewChildIds
())
{
OperationDependency
od
=
new
OperationDependency
();
od
.
setNextOperationId
(
id
);
dependencies
.
add
(
od
);
}
entry
.
setNextEntryIds
(
dependencies
);
}
// 添加到allOperations
chromosome
.
getAllOperations
().
add
(
entry
);
// 添加到全局操作列表
GlobalOperationInfo
info
=
new
GlobalOperationInfo
();
info
.
setGlobalOpId
(
globalOpId
);
info
.
setGroupId
(
entry
.
getGroupId
());
info
.
setSequence
(
entry
.
getSequence
());
info
.
setOp
(
entry
);
chromosome
.
getGlobalOpList
().
add
(
info
);
globalOpId
++;
// 添加默认的机器选择(第一个可选设备)
chromosome
.
getMachineSelection
().
add
(
1
);
}
}
// 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
);
}
}
else
{
// 如果找不到位置,就添加到末尾
for
(
int
i
=
0
;
i
<
newEntrys
.
size
();
i
++)
{
chromosome
.
getOperationSequencing
().
add
(
newGroupId
);
}
}
}
else
{
// 如果找不到afterOrder,就添加到末尾
for
(
int
i
=
0
;
i
<
newEntrys
.
size
();
i
++)
{
chromosome
.
getOperationSequencing
().
add
(
newGroupId
);
}
}
// 7. 重新解码,重新计算排产结果
redecode
(
chromosome
,
chromosome
.
getBaseTime
(),
globalParam
);
}
public
void
MergeOrder
(
Chromosome
chromosome
,
String
sourceorderId
,
String
targetorderId
,
GlobalParam
globalParam
)
{
List
<
Entry
>
allOperations
=
chromosome
.
getAllOperations
();
List
<
GlobalOperationInfo
>
globalOpList
=
chromosome
.
getGlobalOpList
();
...
...
src/main/java/com/aps/service/impl/LanuchServiceImpl.java
View file @
b3dc1350
...
...
@@ -115,12 +115,22 @@ public class LanuchServiceImpl implements LanuchService {
if
(
apsOrderIds
.
isEmpty
())
{
apsOrders
=
new
ArrayList
<>();
}
else
{
apsOrders
=
apsOrderService
.
lambdaQuery
()
.
eq
(
ApsOrder:
:
getIsdeleted
,
0
)
.
eq
(
ApsOrder:
:
getStatus
,
4
)
// .eq(ApsOrder::getCreatoruserid, username)
.
in
(
ApsOrder:
:
getId
,
apsOrderIds
)
.
list
();
// Oracle IN子句限制最多1000个值,需要分批查询
apsOrders
=
new
ArrayList
<>();
int
batchSize
=
1000
;
for
(
int
i
=
0
;
i
<
apsOrderIds
.
size
();
i
+=
batchSize
)
{
int
endIndex
=
Math
.
min
(
i
+
batchSize
,
apsOrderIds
.
size
());
List
<
String
>
batchIds
=
apsOrderIds
.
subList
(
i
,
endIndex
);
List
<
ApsOrder
>
batchOrders
=
apsOrderService
.
lambdaQuery
()
.
eq
(
ApsOrder:
:
getIsdeleted
,
0
)
.
eq
(
ApsOrder:
:
getStatus
,
4
)
// .eq(ApsOrder::getCreatoruserid, username)
.
in
(
ApsOrder:
:
getId
,
batchIds
)
.
list
();
apsOrders
.
addAll
(
batchOrders
);
}
}
if
(
CollectionUtils
.
isEmpty
(
apsOrders
))
{
throw
new
SceneGenerationException
(
"工单列表不能为空"
);
...
...
@@ -527,8 +537,37 @@ public class LanuchServiceImpl implements LanuchService {
}
launchOrder
.
setQuantity
(
order
.
getQuantity
());
launchOrder
.
setMaterialId
(
order
.
getMmid
());
launchOrder
.
setRoutingId
(
order
.
getRoutingid
());
launchOrder
.
setRoutingCode
(
order
.
getRoutingcode
());
// 处理routingId:如果ApsOrder中没有,则根据物料ID查询
if
(
order
.
getRoutingid
()
!=
null
)
{
launchOrder
.
setRoutingId
(
order
.
getRoutingid
());
launchOrder
.
setRoutingCode
(
order
.
getRoutingcode
());
}
else
{
// 根据物料ID查询工艺路线
if
(
order
.
getMmid
()
!=
null
&&
!
order
.
getMmid
().
trim
().
isEmpty
())
{
RoutingHeader
routingHeader
=
routingHeaderService
.
lambdaQuery
()
.
eq
(
RoutingHeader:
:
getMaterialId
,
order
.
getMmid
())
.
eq
(
RoutingHeader:
:
getIsDeleted
,
0
)
.
orderByDesc
(
RoutingHeader:
:
getCreationTime
)
.
last
(
"FETCH FIRST 1 ROWS ONLY"
)
.
one
();
if
(
routingHeader
!=
null
)
{
launchOrder
.
setRoutingId
(
routingHeader
.
getId
());
launchOrder
.
setRoutingCode
(
routingHeader
.
getCode
());
log
.
info
(
"订单 {} 的物料 {} 自动匹配工艺路线: ID={}, Code={}"
,
order
.
getCode
(),
order
.
getMmid
(),
routingHeader
.
getId
(),
routingHeader
.
getCode
());
}
else
{
log
.
warn
(
"订单 {} 的物料 {} 没有配置工艺路线"
,
order
.
getCode
(),
order
.
getMmid
());
// 这里可以选择抛出异常或设置默认值
throw
new
RuntimeException
(
"订单 "
+
order
.
getCode
()
+
" 的物料 "
+
order
.
getMmid
()
+
" 没有配置工艺路线"
);
}
}
else
{
log
.
error
(
"订单 {} 没有物料ID,无法查询工艺路线"
,
order
.
getCode
());
throw
new
RuntimeException
(
"订单 "
+
order
.
getCode
()
+
" 没有物料ID"
);
}
}
return
launchOrder
;
}
...
...
@@ -800,19 +839,33 @@ public class LanuchServiceImpl implements LanuchService {
}
public
List
<
RoutingDetail
>
getRoutingDetails
(
List
<
Long
>
routingHeaderIds
)
{
LambdaQueryWrapper
<
RoutingDetail
>
wrapper
=
new
LambdaQueryWrapper
<>();
wrapper
.
in
(
RoutingDetail:
:
getRoutingHeaderId
,
routingHeaderIds
)
.
eq
(
RoutingDetail:
:
getIsDeleted
,
0
)
// 添加 is_deleted=0 过滤条件
.
orderByAsc
(
RoutingDetail:
:
getTaskSeq
);
if
(
routingHeaderIds
.
isEmpty
())
{
return
new
ArrayList
<>();
}
// Oracle IN子句限制最多1000个值,需要分批查询
List
<
RoutingDetail
>
allRoutingDetails
=
new
ArrayList
<>();
int
batchSize
=
1000
;
for
(
int
i
=
0
;
i
<
routingHeaderIds
.
size
();
i
+=
batchSize
)
{
int
endIndex
=
Math
.
min
(
i
+
batchSize
,
routingHeaderIds
.
size
());
List
<
Long
>
batchIds
=
routingHeaderIds
.
subList
(
i
,
endIndex
);
LambdaQueryWrapper
<
RoutingDetail
>
wrapper
=
new
LambdaQueryWrapper
<>();
wrapper
.
in
(
RoutingDetail:
:
getRoutingHeaderId
,
batchIds
)
.
eq
(
RoutingDetail:
:
getIsDeleted
,
0
)
// 添加 is_deleted=0 过滤条件
.
orderByAsc
(
RoutingDetail:
:
getTaskSeq
);
List
<
RoutingDetail
>
routingDetails
=
routingDetailMapper
.
selectList
(
wrapper
);
List
<
RoutingDetail
>
batchDetails
=
routingDetailMapper
.
selectList
(
wrapper
);
allRoutingDetails
.
addAll
(
batchDetails
);
}
if
(
CollectionUtils
.
isEmpty
(
r
outingDetails
))
{
if
(
CollectionUtils
.
isEmpty
(
allR
outingDetails
))
{
log
.
error
(
"工艺下无工序信息: {}"
,
routingHeaderIds
);
throw
new
RuntimeException
(
"工艺下无工序信息: "
+
routingHeaderIds
);
}
return
r
outingDetails
;
return
allR
outingDetails
;
}
/**
...
...
src/main/java/com/aps/service/plan/LockedOrderProcessorService.java
View file @
b3dc1350
package
com
.
aps
.
service
.
plan
;
import
com.aps.common.util.ProductionDeepCopyUtil
;
import
com.aps.common.util.redis.RedisUtils
;
import
com.aps.entity.Algorithm.Chromosome
;
import
com.aps.entity.Algorithm.GAScheduleResult
;
import
com.aps.entity.Algorithm.GlobalOperationInfo
;
import
com.aps.entity.Algorithm.ScheduleResultDetail
;
import
com.aps.entity.ApsTimeConfig
;
import
com.aps.entity.Dispatch
;
...
...
@@ -72,12 +74,12 @@ public class LockedOrderProcessorService {
log
.
info
(
"锁定期范围: {} 到 {} (冻结期: {}秒)"
,
config
.
lockStartTime
,
config
.
lockEndTime
,
config
.
freezeSeconds
);
// 2. 从已下发场景获取锁定期工单
LockedOrdersData
lockedData
=
loadLockedOrdersFromScenes
(
config
,
chromosome
.
getBaseTime
());
LockedOrdersData
lockedData
=
loadLockedOrdersFromScenes
(
config
,
chromosome
.
getBaseTime
()
,
chromosome
.
getScenarioID
()
);
// 3. 如果无法从已下发场景获取,则从Dispatch表创建
if
(
lockedData
.
results
.
isEmpty
())
{
lockedData
=
createLockedOrdersFromDispatch
(
config
,
chromosome
.
getBaseTime
());
}
//
// 3. 如果无法从已下发场景获取,则从Dispatch表创建
//
if (lockedData.results.isEmpty()) {
//
lockedData = createLockedOrdersFromDispatch(config, chromosome.getBaseTime());
//
}
// 4. 添加锁定期工单到chromosome
addLockedOrdersToChromosome
(
chromosome
,
lockedData
,
config
);
...
...
@@ -116,7 +118,7 @@ public class LockedOrderProcessorService {
/**
* 从已下发场景加载锁定期工单
*/
private
LockedOrdersData
loadLockedOrdersFromScenes
(
LockPeriodConfig
config
,
LocalDateTime
newBaseTime
)
{
private
LockedOrdersData
loadLockedOrdersFromScenes
(
LockPeriodConfig
config
,
LocalDateTime
newBaseTime
,
String
newSceneId
)
{
LockedOrdersData
data
=
new
LockedOrdersData
();
try
{
...
...
@@ -144,7 +146,7 @@ public class LockedOrderProcessorService {
// 遍历每个场景,加载锁定期工单
for
(
String
sceneId
:
dispatchSceneIds
)
{
processSceneForLockedOrders
(
sceneId
,
frozenDispatches
,
config
,
newBaseTime
,
data
);
processSceneForLockedOrders
(
sceneId
,
frozenDispatches
,
config
,
newBaseTime
,
data
,
newSceneId
);
}
log
.
info
(
"从 {} 个已下发场景排产结果中获取到 {} 个锁定期工单"
,
dispatchSceneIds
.
size
(),
data
.
results
.
size
());
...
...
@@ -161,7 +163,7 @@ public class LockedOrderProcessorService {
*/
private
void
processSceneForLockedOrders
(
String
sceneId
,
List
<
Dispatch
>
allDispatches
,
LockPeriodConfig
config
,
LocalDateTime
newBaseTime
,
LockedOrdersData
data
)
{
LockedOrdersData
data
,
String
newSceneId
)
{
try
{
log
.
info
(
"处理场景: {}"
,
sceneId
);
...
...
@@ -194,13 +196,93 @@ public class LockedOrderProcessorService {
copyLockedOrders
(
dispatchChromosome
,
currentSceneDispatches
,
lockedOrderIds
,
dispatchBaseTime
,
newBaseTime
,
sceneId
,
data
,
config
);
//
匹配Entry信息
matchLockedEntries
(
dispatchChromosome
,
data
,
s
ceneId
);
//
直接从已下发场景匹配Entry信息,避免ID冲突
matchLockedEntries
FromDispatchScene
(
dispatchChromosome
,
data
,
sceneId
,
newS
ceneId
);
}
catch
(
Exception
ex
)
{
log
.
error
(
"处理场景 {} 的排产结果失败: {}"
,
sceneId
,
ex
.
getMessage
(),
ex
);
}
}
/**
* 直接从已下发场景匹配锁定期工单的Entry信息,避免ID冲突
*/
private
void
matchLockedEntriesFromDispatchScene
(
Chromosome
dispatchChromosome
,
LockedOrdersData
data
,
String
oldSceneId
,
String
newSceneId
)
{
if
(
dispatchChromosome
.
getAllOperations
()
==
null
)
{
return
;
}
log
.
info
(
"场景 {} 中有 {} 个Entry,开始匹配锁定期工单的Entry信息"
,
oldSceneId
,
dispatchChromosome
.
getAllOperations
().
size
());
for
(
GAScheduleResult
result
:
data
.
results
)
{
log
.
debug
(
"处理锁定期工单: ExecId={}, OperationId={}"
,
result
.
getExecId
(),
result
.
getOperationId
());
// 直接从已下发场景的allOperations中查找Entry
Entry
entry
=
dispatchChromosome
.
getAllOperations
().
stream
()
.
filter
(
e
->
e
.
getExecId
().
equals
(
result
.
getExecId
()))
.
findFirst
()
.
orElse
(
null
);
if
(
entry
!=
null
)
{
// 检查原始Entry的machineOptions
log
.
info
(
"原始Entry {} 的machineOptions数量: {}"
,
entry
.
getExecId
(),
entry
.
getMachineOptions
()
!=
null
?
entry
.
getMachineOptions
().
size
()
:
"null"
);
if
(
entry
.
getMachineOptions
()
!=
null
&&
!
entry
.
getMachineOptions
().
isEmpty
())
{
for
(
int
i
=
0
;
i
<
entry
.
getMachineOptions
().
size
();
i
++)
{
MachineOption
option
=
entry
.
getMachineOptions
().
get
(
i
);
log
.
info
(
" machineOption[{}]: machineId={}, equipCode={}, equipName={}"
,
i
,
option
.
getMachineId
(),
option
.
getEquipCode
(),
option
.
getEquipName
());
}
}
// 创建Entry副本,保持原有的machineOptions和设备信息
Entry
lockedEntry
;
try
{
lockedEntry
=
ProductionDeepCopyUtil
.
deepCopy
(
entry
);
log
.
info
(
"深拷贝后Entry {} 的machineOptions数量: {}, equipCode={}, equipName={}"
,
lockedEntry
.
getExecId
(),
lockedEntry
.
getMachineOptions
()
!=
null
?
lockedEntry
.
getMachineOptions
().
size
()
:
"null"
,
lockedEntry
.
getEquipCode
(),
lockedEntry
.
getEquipName
());
}
catch
(
Exception
e
)
{
log
.
error
(
"深拷贝Entry失败: {}"
,
e
.
getMessage
(),
e
);
lockedEntry
=
entry
;
// 失败时使用原始Entry
}
// 确保selectMachineID设置正确
lockedEntry
.
setSelectMachineID
(
result
.
getMachineId
());
// 修复:不再过滤machineOptions,保持原有的所有设备选项
// 原因:过滤machineOptions会导致在修改订单数量时,重新解码时无法正确处理
// 解码器会根据所有可用的machineOptions进行调度,而不是被限制在单一设备
// 这样可以避免因数量改变导致的时间冲突问题
log
.
info
(
"锁定期Entry {} 保留所有machineOptions: 数量={}, equipCode={}, equipName={}"
,
lockedEntry
.
getExecId
(),
lockedEntry
.
getMachineOptions
()
!=
null
?
lockedEntry
.
getMachineOptions
().
size
()
:
"null"
,
lockedEntry
.
getEquipCode
(),
lockedEntry
.
getEquipName
());
// 重要:更新sceneId为新场景ID,确保查询时能正确匹配
if
(
newSceneId
!=
null
)
{
String
originalSceneId
=
lockedEntry
.
getSceneId
();
lockedEntry
.
setSceneId
(
newSceneId
);
log
.
info
(
"更新锁定期Entry的sceneId: {} -> {}"
,
originalSceneId
,
newSceneId
);
}
data
.
entries
.
put
(
result
.
getExecId
(),
lockedEntry
);
log
.
info
(
"从场景 {} 匹配到锁定期Entry: ExecId={}, 设备ID={}, equipCode={}, equipName={}, machineOptions数量={}"
,
oldSceneId
,
result
.
getExecId
(),
result
.
getMachineId
(),
lockedEntry
.
getEquipCode
(),
lockedEntry
.
getEquipName
(),
lockedEntry
.
getMachineOptions
()
!=
null
?
lockedEntry
.
getMachineOptions
().
size
()
:
"null"
);
}
else
{
log
.
warn
(
"在场景 {} 中未找到工序 {} 对应的Entry"
,
oldSceneId
,
result
.
getExecId
());
}
}
log
.
info
(
"场景 {} 成功匹配 {} 个Entry信息"
,
oldSceneId
,
data
.
entries
.
size
());
}
/**
* 找出锁定期内的订单ID
*/
...
...
@@ -265,7 +347,7 @@ public class LockedOrderProcessorService {
// 深拷贝工单并转换时间
GAScheduleResult
lockedResult
=
copyGAScheduleResult
(
result
);
lockedResult
.
setIsLocked
(
true
);
lockedResult
.
setIsLocked
(
false
);
// 重要:标记为锁定工单,确保重新解码时不被清除
// 转换时间:从旧baseTime转换到新baseTime
LocalDateTime
prevStartTime
=
oldBaseTime
.
plusSeconds
(
result
.
getStartTime
());
...
...
@@ -402,7 +484,9 @@ public class LockedOrderProcessorService {
result
.
setBomTime
(
0
);
result
.
setDesignatedStartTime
(-
1
);
result
.
setLockStartTime
(
0
);
result
.
setForcedMachineId
(-
1L
);
// 关键修复:为dispatch工单设置forcedMachineId,确保重新解码时使用这个设备
// 这样dispatch工单的设备就不会被改变
result
.
setForcedMachineId
(
dispatch
.
getEquipId
());
// 创建GeneDetails
List
<
ScheduleResultDetail
>
geneDetails
=
new
ArrayList
<>();
...
...
@@ -429,19 +513,178 @@ public class LockedOrderProcessorService {
log
.
info
(
"成功添加 {} 个锁定期工单到调度结果中,result大小从{}变为{}"
,
data
.
results
.
size
(),
beforeSize
,
chromosome
.
getResult
().
size
());
// 1.5. 关键修复:将锁定期工单添加到ResultOld中,确保重新解码时能获取正确的设备ID
if
(
chromosome
.
getResultOld
()
==
null
)
{
chromosome
.
setResultOld
(
new
CopyOnWriteArrayList
<>());
}
// 深拷贝锁定期工单的GAScheduleResult到ResultOld
for
(
GAScheduleResult
result
:
data
.
results
)
{
try
{
GAScheduleResult
resultCopy
=
ProductionDeepCopyUtil
.
deepCopy
(
result
);
chromosome
.
getResultOld
().
add
(
resultCopy
);
log
.
info
(
"添加锁定期工单到ResultOld: OperationId={}, MachineId={}, IsLocked={}"
,
resultCopy
.
getOperationId
(),
resultCopy
.
getMachineId
(),
resultCopy
.
isIsLocked
());
}
catch
(
Exception
e
)
{
log
.
error
(
"深拷贝GAScheduleResult失败: {}"
,
e
.
getMessage
(),
e
);
chromosome
.
getResultOld
().
add
(
result
);
// 失败时使用原始对象
}
}
log
.
info
(
"成功添加 {} 个锁定期工单到ResultOld中"
,
data
.
results
.
size
());
// 2. 复制锁定期订单的Order对象
copyLockedOrderObjects
(
chromosome
,
data
,
config
);
// 3. 添加Entry到allOperations
// 3. 添加Entry到allOperations
,并重新分配ID避免冲突
if
(!
data
.
entries
.
isEmpty
()
&&
chromosome
.
getAllOperations
()
!=
null
)
{
int
beforeEntrySize
=
chromosome
.
getAllOperations
().
size
();
// 获取当前最大的Entry ID,避免ID冲突
int
maxExistingId
=
chromosome
.
getAllOperations
().
stream
()
.
mapToInt
(
Entry:
:
getId
)
.
max
()
.
orElse
(
0
);
int
nextAvailableId
=
maxExistingId
+
1
;
// 为锁定期Entry重新分配ID
for
(
Entry
lockedEntry
:
data
.
entries
.
values
())
{
int
oldId
=
lockedEntry
.
getId
();
lockedEntry
.
setId
(
nextAvailableId
);
// 更新对应的GAScheduleResult的operationId(包括result和resultOld)
int
finalNextAvailableId
=
nextAvailableId
;
// 更新result中的operationId
data
.
results
.
stream
()
.
filter
(
result
->
result
.
getOperationId
()
==
oldId
)
.
forEach
(
result
->
result
.
setOperationId
(
finalNextAvailableId
));
// 关键修复:同时更新resultOld中的operationId
if
(
chromosome
.
getResultOld
()
!=
null
)
{
chromosome
.
getResultOld
().
stream
()
.
filter
(
result
->
result
.
getOperationId
()
==
oldId
)
.
forEach
(
result
->
{
result
.
setOperationId
(
finalNextAvailableId
);
log
.
info
(
"更新ResultOld中的operationId: {} -> {}, ExecId={}"
,
oldId
,
finalNextAvailableId
,
result
.
getExecId
());
});
}
log
.
info
(
"锁定期Entry ID重新分配: {} -> {}, ExecId={}"
,
oldId
,
nextAvailableId
,
lockedEntry
.
getExecId
());
nextAvailableId
++;
}
chromosome
.
getAllOperations
().
addAll
(
data
.
entries
.
values
());
log
.
info
(
"成功添加 {} 个锁定期Entry到allOperations中,大小从{}变为{}"
,
data
.
entries
.
size
(),
beforeEntrySize
,
chromosome
.
getAllOperations
().
size
());
log
.
info
(
"成功添加 {} 个锁定期Entry到allOperations中,大小从{}变为{},ID范围: {}-{}"
,
data
.
entries
.
size
(),
beforeEntrySize
,
chromosome
.
getAllOperations
().
size
(),
maxExistingId
+
1
,
nextAvailableId
-
1
);
}
// 4. 确保锁定期设备存在
ensureLockedMachines
(
chromosome
,
data
.
machineIds
,
config
);
// 5. 将锁定期订单添加到operationSequencing中,确保它们会被解码处理
if
(!
data
.
entries
.
isEmpty
()
&&
chromosome
.
getOperationSequencing
()
!=
null
)
{
List
<
Integer
>
currentSequencing
=
new
ArrayList
<>(
chromosome
.
getOperationSequencing
());
// 获取所有锁定期订单的ID
Set
<
String
>
lockedOrderIds
=
data
.
entries
.
values
().
stream
()
.
map
(
Entry:
:
getOrderId
)
.
collect
(
Collectors
.
toSet
());
// 为每个锁定期订单添加其所有工序到排产序列
for
(
String
orderId
:
lockedOrderIds
)
{
// 找到该订单的所有工序,按sequence排序
List
<
Entry
>
orderEntries
=
data
.
entries
.
values
().
stream
()
.
filter
(
entry
->
orderId
.
equals
(
entry
.
getOrderId
()))
.
sorted
(
Comparator
.
comparing
(
Entry:
:
getSequence
))
.
collect
(
Collectors
.
toList
());
// 将每个工序的groupId添加到operationSequencing
for
(
Entry
entry
:
orderEntries
)
{
currentSequencing
.
add
(
entry
.
getGroupId
());
log
.
info
(
"添加锁定期工序到排产序列: OrderId={}, GroupId={}, Sequence={}"
,
orderId
,
entry
.
getGroupId
(),
entry
.
getSequence
());
}
}
chromosome
.
setOperationSequencing
(
currentSequencing
);
log
.
info
(
"更新operationSequencing,从{}个工序增加到{}个工序"
,
chromosome
.
getOperationSequencing
().
size
()
-
(
currentSequencing
.
size
()
-
chromosome
.
getOperationSequencing
().
size
()),
currentSequencing
.
size
());
}
// 6. 关键修复:将锁定期Entry添加到globalOpList中,确保重新解码时不会丢失
if
(!
data
.
entries
.
isEmpty
()
&&
chromosome
.
getGlobalOpList
()
!=
null
)
{
// 获取当前最大的globalOpId
int
maxGlobalOpId
=
chromosome
.
getGlobalOpList
().
stream
()
.
mapToInt
(
GlobalOperationInfo:
:
getGlobalOpId
)
.
max
()
.
orElse
(-
1
);
int
nextGlobalOpId
=
maxGlobalOpId
+
1
;
// 为每个锁定期Entry创建GlobalOperationInfo并添加到globalOpList
List
<
Entry
>
sortedEntries
=
data
.
entries
.
values
().
stream
()
.
sorted
(
Comparator
.
comparing
(
Entry:
:
getGroupId
)
.
thenComparing
(
Entry:
:
getSequence
))
.
collect
(
Collectors
.
toList
());
for
(
Entry
lockedEntry
:
sortedEntries
)
{
GlobalOperationInfo
info
=
new
GlobalOperationInfo
();
info
.
setGlobalOpId
(
nextGlobalOpId
);
info
.
setGroupId
(
lockedEntry
.
getGroupId
());
info
.
setSequence
(
lockedEntry
.
getSequence
());
info
.
setOp
(
lockedEntry
);
chromosome
.
getGlobalOpList
().
add
(
info
);
log
.
info
(
"添加锁定期Entry到globalOpList: GlobalOpId={}, EntryId={}, OrderCode={}, GroupId={}, Sequence={}, EquipCode={}"
,
nextGlobalOpId
,
lockedEntry
.
getId
(),
lockedEntry
.
getOrderCode
(),
lockedEntry
.
getGroupId
(),
lockedEntry
.
getSequence
(),
lockedEntry
.
getEquipCode
());
nextGlobalOpId
++;
}
log
.
info
(
"成功添加 {} 个锁定期Entry到globalOpList中,globalOpList大小变为{}"
,
sortedEntries
.
size
(),
chromosome
.
getGlobalOpList
().
size
());
}
// 7. 关键修复:同步更新machineSelection,确保长度与globalOpList一致
if
(!
data
.
entries
.
isEmpty
()
&&
chromosome
.
getMachineSelection
()
!=
null
)
{
List
<
Integer
>
machineSelection
=
chromosome
.
getMachineSelection
();
// 为每个锁定期Entry添加机器选择索引
// 锁定期工序的机器已经确定,所以机器选择索引设为1(表示使用machineOptions中的第一个,也是唯一的机器)
// 注意:machineSelection的索引是从1开始的,不是从0开始
List
<
Entry
>
sortedEntries
=
data
.
entries
.
values
().
stream
()
.
sorted
(
Comparator
.
comparing
(
Entry:
:
getGroupId
)
.
thenComparing
(
Entry:
:
getSequence
))
.
collect
(
Collectors
.
toList
());
for
(
Entry
lockedEntry
:
sortedEntries
)
{
// 锁定期工序的机器已经确定,machineSelection设为1(索引从1开始)
machineSelection
.
add
(
1
);
log
.
info
(
"添加锁定期Entry的机器选择: EntryId={}, OrderCode={}, EquipCode={}, MachineSelectionIndex=1"
,
lockedEntry
.
getId
(),
lockedEntry
.
getOrderCode
(),
lockedEntry
.
getEquipCode
());
}
log
.
info
(
"成功添加 {} 个锁定期Entry的机器选择到machineSelection中,machineSelection大小变为{}"
,
sortedEntries
.
size
(),
machineSelection
.
size
());
// 验证:确保machineSelection长度与globalOpList长度一致
if
(
chromosome
.
getGlobalOpList
().
size
()
!=
machineSelection
.
size
())
{
log
.
error
(
"警告:machineSelection长度({})与globalOpList长度({})不一致!"
,
machineSelection
.
size
(),
chromosome
.
getGlobalOpList
().
size
());
}
else
{
log
.
info
(
"验证通过:machineSelection长度({})与globalOpList长度({})一致"
,
machineSelection
.
size
(),
chromosome
.
getGlobalOpList
().
size
());
}
}
}
/**
...
...
@@ -466,6 +709,9 @@ public class LockedOrderProcessorService {
log
.
info
(
"需要复制的锁定期订单ID: {}"
,
lockedOrderIds
);
// 用于存储OrderId到新Order.id的映射
Map
<
String
,
Integer
>
orderIdToNewGroupId
=
new
HashMap
<>();
try
{
// 查询锁定期Dispatch记录
List
<
Dispatch
>
frozenDispatches
=
queryFrozenDispatches
(
config
);
...
...
@@ -478,10 +724,20 @@ public class LockedOrderProcessorService {
log
.
info
(
"锁定期Dispatch记录来自 {} 个场景: {}"
,
dispatchSceneIds
.
size
(),
dispatchSceneIds
);
// 从每个场景复制订单
// 从每个场景复制订单
,并收集Order ID映射
for
(
String
sceneId
:
dispatchSceneIds
)
{
copyOrdersFromScene
(
chromosome
,
sceneId
,
lockedOrderIds
);
Map
<
String
,
Integer
>
sceneMapping
=
copyOrdersFromScene
(
chromosome
,
sceneId
,
lockedOrderIds
);
orderIdToNewGroupId
.
putAll
(
sceneMapping
);
}
log
.
info
(
"Order ID映射: {}"
,
orderIdToNewGroupId
);
// 更新Entry的groupId
updateEntryGroupIds
(
data
,
orderIdToNewGroupId
);
// 更新GAScheduleResult的groupId
updateResultGroupIds
(
data
,
orderIdToNewGroupId
);
}
catch
(
Exception
e
)
{
log
.
error
(
"复制锁定期订单失败: {}"
,
e
.
getMessage
(),
e
);
}
...
...
@@ -489,16 +745,19 @@ public class LockedOrderProcessorService {
log
.
info
(
"成功复制锁定期订单到Orders列表,大小从{}变为{}"
,
beforeOrderSize
,
chromosome
.
getOrders
().
size
());
}
/**
* 从指定场景复制订单
* 从场景复制订单,并返回OrderId到新Order.id的映射
* @return Map<OrderId, 新Order.id>
*/
private
void
copyOrdersFromScene
(
Chromosome
chromosome
,
String
sceneId
,
Set
<
String
>
lockedOrderIds
)
{
private
Map
<
String
,
Integer
>
copyOrdersFromScene
(
Chromosome
chromosome
,
String
sceneId
,
Set
<
String
>
lockedOrderIds
)
{
Map
<
String
,
Integer
>
orderIdToNewGroupId
=
new
HashMap
<>();
try
{
log
.
info
(
"开始从场景 {} 加载Chromosome"
,
sceneId
);
Chromosome
dispatchChromosome
=
sceneService
.
loadChromosomeFromFile
(
sceneId
);
if
(
dispatchChromosome
==
null
)
{
log
.
warn
(
"场景 {} 加载失败,Chromosome为null"
,
sceneId
);
return
;
return
orderIdToNewGroupId
;
}
log
.
info
(
"场景 {} 加载成功,Orders数量: {}"
,
sceneId
,
...
...
@@ -506,7 +765,7 @@ public class LockedOrderProcessorService {
if
(
dispatchChromosome
.
getOrders
()
==
null
)
{
log
.
warn
(
"场景 {} 的Orders为null"
,
sceneId
);
return
;
return
orderIdToNewGroupId
;
}
// 筛选锁定期订单
...
...
@@ -516,15 +775,32 @@ public class LockedOrderProcessorService {
log
.
info
(
"场景 {} 中找到 {} 个匹配的锁定期订单"
,
sceneId
,
lockedOrders
.
size
());
// 获取当前最大的Order ID
int
maxOrderId
=
chromosome
.
getOrders
().
stream
()
.
mapToInt
(
Order:
:
getId
)
.
max
()
.
orElse
(
0
);
log
.
info
(
"当前最大Order ID: {}"
,
maxOrderId
);
// 复制订单(避免重复)
for
(
Order
lockedOrder
:
lockedOrders
)
{
boolean
exists
=
chromosome
.
getOrders
().
stream
()
.
anyMatch
(
order
->
lockedOrder
.
getOrderId
().
equals
(
order
.
getOrderId
()));
if
(!
exists
)
{
// 为dispatch工单分配新的Order ID
int
oldOrderId
=
lockedOrder
.
getId
();
int
newOrderId
=
++
maxOrderId
;
lockedOrder
.
setId
(
newOrderId
);
// 记录映射关系
orderIdToNewGroupId
.
put
(
lockedOrder
.
getOrderId
(),
newOrderId
);
log
.
info
(
"从场景 {} 复制锁定期订单: OrderId={}, OrderCode={}, 旧Order.id={}, 新Order.id={}"
,
sceneId
,
lockedOrder
.
getOrderId
(),
lockedOrder
.
getOrderCode
(),
oldOrderId
,
newOrderId
);
chromosome
.
getOrders
().
add
(
lockedOrder
);
log
.
info
(
"从场景 {} 复制锁定期订单: OrderId={}, OrderCode={}"
,
sceneId
,
lockedOrder
.
getOrderId
(),
lockedOrder
.
getOrderCode
());
}
else
{
log
.
warn
(
"订单 {} 已存在,跳过复制"
,
lockedOrder
.
getOrderId
());
}
...
...
@@ -532,6 +808,56 @@ public class LockedOrderProcessorService {
}
catch
(
Exception
ex
)
{
log
.
error
(
"从场景 {} 复制锁定期订单失败: {}"
,
sceneId
,
ex
.
getMessage
(),
ex
);
}
return
orderIdToNewGroupId
;
}
/**
* 更新Entry的groupId
*/
private
void
updateEntryGroupIds
(
LockedOrdersData
data
,
Map
<
String
,
Integer
>
orderIdToNewGroupId
)
{
if
(
orderIdToNewGroupId
.
isEmpty
())
{
return
;
}
log
.
info
(
"开始更新Entry的groupId,映射数量: {}"
,
orderIdToNewGroupId
.
size
());
for
(
Entry
entry
:
data
.
entries
.
values
())
{
String
orderId
=
entry
.
getOrderId
();
if
(
orderIdToNewGroupId
.
containsKey
(
orderId
))
{
int
oldGroupId
=
entry
.
getGroupId
();
int
newGroupId
=
orderIdToNewGroupId
.
get
(
orderId
);
entry
.
setGroupId
(
newGroupId
);
log
.
info
(
"更新Entry的groupId: ExecId={}, OrderId={}, 旧groupId={}, 新groupId={}"
,
entry
.
getExecId
(),
orderId
,
oldGroupId
,
newGroupId
);
}
}
log
.
info
(
"Entry的groupId更新完成"
);
}
/**
* 更新GAScheduleResult的groupId
*/
private
void
updateResultGroupIds
(
LockedOrdersData
data
,
Map
<
String
,
Integer
>
orderIdToNewGroupId
)
{
if
(
orderIdToNewGroupId
.
isEmpty
())
{
return
;
}
log
.
info
(
"开始更新GAScheduleResult的groupId,映射数量: {}"
,
orderIdToNewGroupId
.
size
());
for
(
GAScheduleResult
result
:
data
.
results
)
{
String
orderId
=
result
.
getOrderId
();
if
(
orderIdToNewGroupId
.
containsKey
(
orderId
))
{
int
oldGroupId
=
result
.
getGroupId
();
int
newGroupId
=
orderIdToNewGroupId
.
get
(
orderId
);
result
.
setGroupId
(
newGroupId
);
log
.
info
(
"更新GAScheduleResult的groupId: ExecId={}, OrderId={}, 旧groupId={}, 新groupId={}"
,
result
.
getExecId
(),
orderId
,
oldGroupId
,
newGroupId
);
}
}
log
.
info
(
"GAScheduleResult的groupId更新完成"
);
}
/**
...
...
src/main/java/com/aps/service/plan/PlanResultService.java
View file @
b3dc1350
...
...
@@ -98,6 +98,8 @@ public class PlanResultService {
@Autowired
private
OrderSortService
orderSortService
;
@Autowired
private
LanuchService
lanuchService
;
@Autowired
private
MaterialInfoMapper
materialInfoMapper
;
...
...
@@ -231,7 +233,8 @@ public class PlanResultService {
kpiCalculator
.
calculatekpi
();
// 添加锁定期工单到调度结果中
// lockedOrderProcessorService.addLockedOrdersToResult(chromosome);
// 这里会从 Dispatch 表加载锁定期工单,并添加到 chromosome.result 中
// lockedOrderProcessorService.addLockedOrdersToResult(chromosome);
_sceneService
.
saveChromosomeToFile
(
chromosome
,
SceneId
);
...
...
@@ -1240,6 +1243,17 @@ public class PlanResultService {
entry
.
setPriority
(
order
.
getActualPriority
());
});
}
// 更新调度结果中的数量(关键:处理锁定期工单)
List
<
GAScheduleResult
>
results
=
chromosome
.
getResult
();
if
(
results
!=
null
)
{
results
.
stream
()
.
filter
(
result
->
result
.
getOrderId
()
!=
null
&&
result
.
getOrderId
().
equals
(
order
.
getOrderId
()))
.
forEach
(
result
->
{
result
.
setQuantity
(
order
.
getQuantity
());
log
.
info
(
"更新调度结果中的订单数量: OrderId={}, 新数量={}"
,
order
.
getOrderId
(),
order
.
getQuantity
());
});
}
}
/**
...
...
@@ -1424,6 +1438,91 @@ public class PlanResultService {
_sceneService
.
saveChromosomeToFile
(
chromosome
,
SceneId
);
return
chromosome
;
}
/**
* 插单功能:在指定订单后插入新订单
* 步骤1:先将新订单数据插入数据库
* 步骤2:使用类似复制订单的方式将新订单加入排产
*
* @param SceneId 场景ID
* @param afterOrderId 插入位置订单ID(新订单将排在此订单后面)
* @param newOrderData 新订单数据
* @return 更新后的Chromosome
*/
public
Chromosome
InsertOrder
(
String
SceneId
,
String
afterOrderId
,
Map
<
String
,
Object
>
newOrderData
)
{
// 步骤1:调用LanuchService的insertOrder方法,将新订单插入数据库
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"
));
}
if
(
newOrderData
.
containsKey
(
"endDate"
))
{
endDate
=
LocalDateTime
.
parse
((
String
)
newOrderData
.
get
(
"endDate"
));
}
if
(
newOrderData
.
containsKey
(
"priority"
))
{
priority
=
((
Number
)
newOrderData
.
get
(
"priority"
)).
intValue
();
}
// 调用insertOrder插入数据库
R
<
String
>
insertResult
=
lanuchService
.
insertOrder
(
SceneId
,
orderCode
,
materialId
,
startDate
,
endDate
,
priority
,
quantity
);
// if (!insertResult.isSuccess()) {
// throw new RuntimeException("插单失败: " + insertResult.getMsg());
// }
//
// 从返回消息中提取新订单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={}, 工序数={}"
,
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
;
}
public
Chromosome
MergeOrder
(
String
SceneId
,
String
sourceorderId
,
String
targetorderId
)
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment