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
9fab7eca
Commit
9fab7eca
authored
Mar 26, 2026
by
DESKTOP-VKRD9QF\Administration
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
插单修改
parent
a84189b4
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
505 additions
and
53 deletions
+505
-53
ResourceGanttController.java
...ava/com/aps/controller/gantt/ResourceGanttController.java
+52
-0
ScheduleOperationService.java
...a/com/aps/service/Algorithm/ScheduleOperationService.java
+364
-0
PlanResultService.java
src/main/java/com/aps/service/plan/PlanResultService.java
+89
-53
No files found.
src/main/java/com/aps/controller/gantt/ResourceGanttController.java
View file @
9fab7eca
...
@@ -418,6 +418,58 @@ public class ResourceGanttController {
...
@@ -418,6 +418,58 @@ public class ResourceGanttController {
return
R
.
ok
(
"插单成功"
);
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"
)
@Operation
(
summary
=
"订单合并"
,
description
=
"订单合并"
)
@Operation
(
summary
=
"订单合并"
,
description
=
"订单合并"
)
public
R
<
String
>
orderMerge
(
@RequestBody
Map
<
String
,
Object
>
params
)
{
public
R
<
String
>
orderMerge
(
@RequestBody
Map
<
String
,
Object
>
params
)
{
...
...
src/main/java/com/aps/service/Algorithm/ScheduleOperationService.java
View file @
9fab7eca
...
@@ -12,6 +12,7 @@ import org.apache.commons.lang3.StringUtils;
...
@@ -12,6 +12,7 @@ import org.apache.commons.lang3.StringUtils;
import
org.springframework.context.annotation.ScopeMetadata
;
import
org.springframework.context.annotation.ScopeMetadata
;
import
javax.xml.transform.Result
;
import
javax.xml.transform.Result
;
import
java.math.BigDecimal
;
import
java.time.LocalDateTime
;
import
java.time.LocalDateTime
;
import
java.util.*
;
import
java.util.*
;
import
java.util.concurrent.CopyOnWriteArrayList
;
import
java.util.concurrent.CopyOnWriteArrayList
;
...
@@ -1186,6 +1187,369 @@ if(targetOp.getSequence()>1) {
...
@@ -1186,6 +1187,369 @@ if(targetOp.getSequence()>1) {
globalParam
.
setIsCheckSf
(
originalIsCheckSf
);
globalParam
.
setIsCheckSf
(
originalIsCheckSf
);
}
}
public
void
InsertOrderAuto
(
Chromosome
chromosome
,
String
newOrderId
,
ProdLaunchOrder
newLaunchOrder
,
List
<
ProdProcessExec
>
newProcessExecs
,
List
<
ProdEquipment
>
newProdEquipments
,
LocalDateTime
anchorTime
,
GlobalParam
globalParam
)
{
List
<
Order
>
orders
=
chromosome
.
getOrders
();
List
<
GroupResult
>
OperatRels
=
chromosome
.
getOperatRel
();
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
());
int
maxOrderId
=
orders
.
stream
().
mapToInt
(
Order:
:
getId
).
max
().
orElse
(
0
)
+
1
;
newOrder
.
setId
(
maxOrderId
);
orders
.
add
(
newOrder
);
int
maxGroupId
=
OperatRels
.
size
();
int
newGroupId
=
maxGroupId
+
1
;
List
<
Entry
>
newEntrys
=
new
ArrayList
<>();
List
<
String
>
newIdList
=
new
ArrayList
<>();
List
<
String
>
newChildIdList
=
new
ArrayList
<>();
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
.
setTaskSeq
(
processExec
.
getTaskSeq
());
newEntry
.
setState
(
2
);
newEntry
.
setRoutingDetailId
(
processExec
.
getRoutingDetailId
());
newEntry
.
setRoutingId
(
processExec
.
getRoutingId
());
newEntry
.
setRoutingCode
(
processExec
.
getRoutingCode
());
newEntry
.
setRoutingName
(
processExec
.
getRoutingName
());
newEntry
.
setRoutingDetailName
(
processExec
.
getRoutingDetailName
());
newEntry
.
setProductId
(
newLaunchOrder
.
getMaterialId
());
newEntry
.
setProductCode
(
newLaunchOrder
.
getMaterialCode
());
newEntry
.
setProductName
(
newLaunchOrder
.
getMaterialName
());
if
(
processExec
.
getDepartmentId
()
!=
null
)
{
newEntry
.
setDepartmentId
(
processExec
.
getDepartmentId
());
}
newEntry
.
setIsInterrupt
(
processExec
.
getCanInterrupt
());
// 这里保留资源组ID(设备类型)
newEntry
.
setEquipTypeID
(
processExec
.
getMachineId
());
if
(
processExec
.
getRuntime
()
!=
null
)
{
newEntry
.
setRuntime
(
processExec
.
getRuntime
());
}
if
(
processExec
.
getSingleOut
()
!=
null
)
{
newEntry
.
setSingleOut
(
processExec
.
getSingleOut
());
}
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
());
// 与InitEntrys对齐:machineOptions来源于ProdEquipment(execId -> equipId)
List
<
MachineOption
>
machineOptions
=
newProdEquipments
.
stream
()
.
filter
(
pe
->
pe
.
getExecId
()
!=
null
&&
pe
.
getExecId
().
equals
(
processExec
.
getExecId
()))
.
map
(
pe
->
{
MachineOption
mo
=
new
MachineOption
();
mo
.
setMachineId
(
pe
.
getEquipId
());
// 真实设备ID
mo
.
setRuntime
(
pe
.
getRuntime
()
!=
null
?
pe
.
getRuntime
()
:
BigDecimal
.
ZERO
);
mo
.
setSingleOut
(
pe
.
getSingleOut
()
!=
null
?
pe
.
getSingleOut
()
:
BigDecimal
.
ONE
);
mo
.
setEquipCode
(
pe
.
getEquipCode
());
mo
.
setEquipName
(
pe
.
getEquipName
());
mo
.
setResourceCode
(
pe
.
getResourceCode
());
mo
.
setProcessingTime
(
pe
.
getSpeed
()
!=
null
?
pe
.
getSpeed
()
:
0
d
);
return
mo
;
})
.
collect
(
Collectors
.
toList
());
if
(
machineOptions
.
isEmpty
())
{
throw
new
RuntimeException
(
"自动插单失败:工序["
+
processExec
.
getExecId
()
+
"]没有可用设备"
);
}
newEntry
.
setMachineOptions
(
machineOptions
);
newEntry
.
setSelectMachineID
(
null
);
// 后面按bestSeq回填
newEntrys
.
add
(
newEntry
);
}
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
());
}
}
OperatRels
=
IdGroupingWithDualSerial
.
addNewDataWithIsolatedGroup
(
OperatRels
,
newIdList
,
newChildIdList
);
chromosome
.
setOperatRel
(
new
CopyOnWriteArrayList
<>(
OperatRels
));
int
globalOpId
=
chromosome
.
getGlobalOpList
().
stream
()
.
mapToInt
(
GlobalOperationInfo:
:
getGlobalOpId
)
.
max
()
.
orElse
(
0
)
+
1
;
GroupResult
newGroupResult
=
OperatRels
.
get
(
OperatRels
.
size
()
-
1
);
List
<
NodeInfo
>
nodeInfoList
=
newGroupResult
.
getNodeInfoList
();
Entry
firstEntry
=
null
;
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
);
}
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
);
int
bestSeq
=
calcBestMachineSeq
(
entry
,
chromosome
,
anchorTime
);
chromosome
.
getMachineSelection
().
add
(
bestSeq
);
entry
.
setSelectMachineID
(
entry
.
getMachineOptions
().
get
(
bestSeq
-
1
).
getMachineId
());
if
(
entry
.
getSequence
()
==
1
)
{
firstEntry
=
entry
;
}
globalOpId
++;
}
}
for
(
int
i
=
0
;
i
<
newEntrys
.
size
();
i
++)
{
chromosome
.
getOperationSequencing
().
add
(
newGroupId
);
}
int
firstOperationId
=
firstEntry
!=
null
?
firstEntry
.
getId
()
:
-
1
;
boolean
originalIsCheckSf
=
globalParam
.
isIsCheckSf
();
globalParam
.
setIsCheckSf
(
false
);
// 第一次解码
if
(
anchorTime
!=
null
&&
firstEntry
!=
null
)
{
firstEntry
.
setDesignatedStartTime
(
anchorTime
);
}
redecode
(
chromosome
,
chromosome
.
getBaseTime
(),
globalParam
);
// 第二次调整:锚点占位后推 + 新工单前移
if
(
anchorTime
!=
null
&&
firstOperationId
>
0
)
{
GAScheduleResult
firstResult
=
chromosome
.
getResult
().
stream
()
.
filter
(
r
->
r
.
getOperationId
()
==
firstOperationId
)
.
findFirst
()
.
orElse
(
null
);
if
(
firstResult
!=
null
)
{
long
machineId
=
firstResult
.
getMachineId
();
int
anchorSeconds
=
(
int
)
java
.
time
.
temporal
.
ChronoUnit
.
SECONDS
.
between
(
chromosome
.
getBaseTime
(),
anchorTime
);
int
firstDuration
=
Math
.
max
(
1
,
firstResult
.
getEndTime
()
-
firstResult
.
getStartTime
());
List
<
GAScheduleResult
>
machineOldResults
=
chromosome
.
getResult
().
stream
()
.
filter
(
r
->
r
.
getMachineId
()
==
machineId
)
.
filter
(
r
->
r
.
getGroupId
()
!=
firstResult
.
getGroupId
())
.
sorted
(
Comparator
.
comparingInt
(
GAScheduleResult:
:
getStartTime
))
.
collect
(
Collectors
.
toList
());
GAScheduleResult
pivot
=
machineOldResults
.
stream
()
.
filter
(
r
->
r
.
getStartTime
()
<=
anchorSeconds
&&
r
.
getEndTime
()
>
anchorSeconds
)
.
findFirst
()
.
orElse
(
null
);
if
(
pivot
==
null
)
{
pivot
=
machineOldResults
.
stream
()
.
filter
(
r
->
r
.
getStartTime
()
>=
anchorSeconds
)
.
findFirst
()
.
orElse
(
null
);
}
GAScheduleResult
prev
=
machineOldResults
.
stream
()
.
filter
(
r
->
r
.
getEndTime
()
<=
anchorSeconds
)
.
reduce
((
a
,
b
)
->
b
)
.
orElse
(
null
);
int
newDesignatedStart
;
if
(
pivot
!=
null
)
{
if
(
pivot
.
getStartTime
()
<=
anchorSeconds
&&
pivot
.
getEndTime
()
>
anchorSeconds
)
{
newDesignatedStart
=
pivot
.
getStartTime
();
}
else
{
newDesignatedStart
=
prev
!=
null
?
prev
.
getEndTime
()
:
0
;
}
}
else
{
newDesignatedStart
=
prev
!=
null
?
prev
.
getEndTime
()
:
0
;
}
if
(
newDesignatedStart
<
0
)
{
newDesignatedStart
=
0
;
}
Entry
firstEntryRef
=
chromosome
.
getAllOperations
().
stream
()
.
filter
(
e
->
e
.
getId
()
==
firstOperationId
)
.
findFirst
()
.
orElse
(
null
);
if
(
firstEntryRef
!=
null
)
{
firstEntryRef
.
setDesignatedStartTime
(
chromosome
.
getBaseTime
().
plusSeconds
(
newDesignatedStart
));
}
GAScheduleResult
firstLock
=
chromosome
.
getResult
().
stream
()
.
filter
(
r
->
r
.
getOperationId
()
==
firstOperationId
)
.
findFirst
()
.
orElse
(
null
);
if
(
firstLock
!=
null
)
{
firstLock
.
setDesignatedStartTime
(
newDesignatedStart
);
firstLock
.
setLockStartTime
(
1
);
}
if
(
pivot
!=
null
)
{
int
pivotStart
=
pivot
.
getStartTime
();
List
<
GAScheduleResult
>
needShift
=
machineOldResults
.
stream
()
.
filter
(
r
->
r
.
getStartTime
()
>=
pivotStart
)
.
collect
(
Collectors
.
toList
());
for
(
GAScheduleResult
oldResult
:
needShift
)
{
oldResult
.
setDesignatedStartTime
(
oldResult
.
getStartTime
()
+
firstDuration
);
oldResult
.
setLockStartTime
(
1
);
}
}
redecode
(
chromosome
,
chromosome
.
getBaseTime
(),
globalParam
);
}
}
globalParam
.
setIsCheckSf
(
originalIsCheckSf
);
}
private
int
calcBestMachineSeq
(
Entry
entry
,
Chromosome
chromosome
,
LocalDateTime
anchorTime
)
{
List
<
MachineOption
>
rawOptions
=
entry
.
getMachineOptions
();
if
(
rawOptions
==
null
||
rawOptions
.
isEmpty
())
{
throw
new
RuntimeException
(
"工序无可选设备: "
+
entry
.
getExecId
());
}
// 只保留当前排产设备池中的设备
Set
<
Long
>
availableMachineIds
=
chromosome
.
getMachines
().
stream
()
.
map
(
Machine:
:
getId
)
.
collect
(
Collectors
.
toSet
());
List
<
MachineOption
>
options
=
rawOptions
.
stream
()
.
filter
(
o
->
availableMachineIds
.
contains
(
o
.
getMachineId
()))
.
collect
(
Collectors
.
toList
());
if
(
options
.
isEmpty
())
{
throw
new
RuntimeException
(
"工序无可用设备(不在当前排产设备池): "
+
entry
.
getExecId
());
}
Map
<
Long
,
Integer
>
machineEnd
=
chromosome
.
getResult
().
stream
()
.
collect
(
Collectors
.
groupingBy
(
GAScheduleResult:
:
getMachineId
,
Collectors
.
collectingAndThen
(
Collectors
.
maxBy
(
Comparator
.
comparingInt
(
GAScheduleResult:
:
getEndTime
)),
o
->
o
.
map
(
GAScheduleResult:
:
getEndTime
).
orElse
(
0
)
)
));
int
anchorSec
=
0
;
if
(
anchorTime
!=
null
&&
chromosome
.
getBaseTime
()
!=
null
)
{
anchorSec
=
(
int
)
java
.
time
.
temporal
.
ChronoUnit
.
SECONDS
.
between
(
chromosome
.
getBaseTime
(),
anchorTime
);
if
(
anchorSec
<
0
)
{
anchorSec
=
0
;
}
}
int
bestIdx
=
0
;
double
bestScore
=
Double
.
MAX_VALUE
;
for
(
int
i
=
0
;
i
<
options
.
size
();
i
++)
{
MachineOption
op
=
options
.
get
(
i
);
int
ready
=
Math
.
max
(
anchorSec
,
machineEnd
.
getOrDefault
(
op
.
getMachineId
(),
0
));
double
duration
;
if
(
entry
.
getConstTime
()
==
1
)
{
duration
=
Math
.
max
(
0
d
,
op
.
getProcessingTime
());
}
else
{
double
runtime
=
op
.
getRuntime
()
!=
null
?
op
.
getRuntime
().
doubleValue
()
:
0
d
;
double
singleOut
=
op
.
getSingleOut
()
!=
null
?
op
.
getSingleOut
().
doubleValue
()
:
1
d
;
if
(
singleOut
<=
0
)
{
singleOut
=
1
d
;
}
duration
=
runtime
/
singleOut
*
entry
.
getQuantity
();
}
double
score
=
ready
+
duration
;
if
(
score
<
bestScore
)
{
bestScore
=
score
;
bestIdx
=
i
;
}
}
// 注意:这里返回的是在rawOptions中的序号(machineSelection要求按entry.machineOptions顺序)
Long
bestMachineId
=
options
.
get
(
bestIdx
).
getMachineId
();
int
rawIndex
=
IntStream
.
range
(
0
,
rawOptions
.
size
())
.
filter
(
i
->
rawOptions
.
get
(
i
).
getMachineId
()
==
bestMachineId
)
.
findFirst
()
.
orElse
(
0
);
return
rawIndex
+
1
;
}
public
void
MergeOrder
(
Chromosome
chromosome
,
String
sourceorderId
,
String
targetorderId
,
GlobalParam
globalParam
)
{
public
void
MergeOrder
(
Chromosome
chromosome
,
String
sourceorderId
,
String
targetorderId
,
GlobalParam
globalParam
)
{
List
<
Entry
>
allOperations
=
chromosome
.
getAllOperations
();
List
<
Entry
>
allOperations
=
chromosome
.
getAllOperations
();
List
<
GlobalOperationInfo
>
globalOpList
=
chromosome
.
getGlobalOpList
();
List
<
GlobalOperationInfo
>
globalOpList
=
chromosome
.
getGlobalOpList
();
...
...
src/main/java/com/aps/service/plan/PlanResultService.java
View file @
9fab7eca
...
@@ -1340,74 +1340,110 @@ public class PlanResultService {
...
@@ -1340,74 +1340,110 @@ public class PlanResultService {
return
releasedCount
;
return
releasedCount
;
}
}
public
Chromosome
InsertOrderAuto
(
String
sceneId
,
Map
<
String
,
Object
>
newOrderData
)
{
private
long
countMachineAvailabilitySegments
(
Chromosome
chromosome
,
Long
machineId
)
{
if
(
newOrderData
==
null
)
{
if
(
chromosome
==
null
||
machineId
==
null
||
chromosome
.
getInitMachines
()
==
null
)
{
throw
new
RuntimeException
(
"newOrder 不能为空"
);
return
0
;
}
}
return
chromosome
.
getInitMachines
().
stream
()
String
orderCode
=
String
.
valueOf
(
newOrderData
.
get
(
"orderCode"
));
.
filter
(
Objects:
:
nonNull
)
String
materialId
=
String
.
valueOf
(
newOrderData
.
get
(
"materialId"
));
.
filter
(
m
->
m
.
getId
()
==
machineId
)
Object
qtyObj
=
newOrderData
.
get
(
"quantity"
);
.
findFirst
()
if
(
orderCode
==
null
||
orderCode
.
trim
().
isEmpty
())
{
.
map
(
m
->
m
.
getAvailability
()
==
null
?
0L
:
(
long
)
m
.
getAvailability
().
size
())
throw
new
RuntimeException
(
"orderCode 不能为空"
);
.
orElse
(
0L
);
}
}
if
(
materialId
==
null
||
materialId
.
trim
().
isEmpty
())
{
throw
new
RuntimeException
(
"materialId 不能为空"
);
}
if
(
qtyObj
==
null
)
{
throw
new
RuntimeException
(
"quantity 不能为空"
);
}
Double
quantity
=
Double
.
valueOf
(
String
.
valueOf
(
qtyObj
));
private
long
countMachineUsedMaintenanceSegments
(
Chromosome
chromosome
,
Long
machineId
)
{
// 1. 创建新订单(沿用现有创建逻辑)
if
(
chromosome
==
null
||
machineId
==
null
||
chromosome
.
getInitMachines
()
==
null
)
{
R
<
String
>
insertResp
=
lanuchService
.
insertOrder
(
sceneId
,
orderCode
,
materialId
,
null
,
null
,
1
,
quantity
);
return
0
;
String
insertMsg
=
insertResp
!=
null
?
insertResp
.
getData
()
:
null
;
if
(
insertMsg
==
null
||
insertMsg
.
trim
().
isEmpty
())
{
throw
new
RuntimeException
(
"创建订单失败:未返回订单ID"
);
}
}
return
chromosome
.
getInitMachines
().
stream
()
String
newOrderId
=
insertMsg
;
.
filter
(
Objects:
:
nonNull
)
if
(
insertMsg
.
contains
(
"订单ID:"
))
{
.
filter
(
m
->
m
.
getId
()
==
machineId
)
newOrderId
=
insertMsg
.
substring
(
insertMsg
.
indexOf
(
"订单ID:"
)
+
5
).
trim
();
.
findFirst
()
}
.
map
(
m
->
m
.
getAvailability
()
==
null
?
0L
:
m
.
getAvailability
().
stream
()
.
filter
(
Objects:
:
nonNull
)
.
filter
(
seg
->
seg
.
getType
()
==
SegmentType
.
MAINTENANCE
&&
seg
.
isUsed
())
.
count
())
.
orElse
(
0L
);
}
private
long
countMachineUsedSegments
(
Chromosome
chromosome
,
Long
machineId
,
SegmentType
type
)
{
// 2. 读取场景排产结果
if
(
chromosome
==
null
||
machineId
==
null
||
chromosome
.
getInitMachines
()
==
null
)
{
Chromosome
chromosome
=
_sceneService
.
loadChromosomeFromFile
(
sceneId
);
return
0
;
if
(
chromosome
==
null
)
{
throw
new
RuntimeException
(
"场景不存在或排产结果未初始化"
);
}
}
return
chromosome
.
getInitMachines
().
stream
()
// 3. 查询新订单及其工序
.
filter
(
Objects:
:
nonNull
)
ProdLaunchOrder
newLaunchOrder
=
_prodLaunchOrderService
.
lambdaQuery
()
.
filter
(
m
->
m
.
getId
()
==
machineId
)
.
eq
(
ProdLaunchOrder:
:
getSceneId
,
sceneId
)
.
findFirst
()
.
eq
(
ProdLaunchOrder:
:
getOrderId
,
newOrderId
)
.
map
(
m
->
m
.
getAvailability
()
==
null
?
0L
:
m
.
getAvailability
().
stream
()
.
one
();
.
filter
(
Objects:
:
nonNull
)
if
(
newLaunchOrder
==
null
)
{
.
filter
(
TimeSegment:
:
isUsed
)
throw
new
RuntimeException
(
"新订单不存在:"
+
newOrderId
);
.
filter
(
seg
->
type
==
null
||
seg
.
getType
()
==
type
)
}
.
count
())
.
orElse
(
0L
);
}
private
String
machineSegmentSnapshot
(
Chromosome
chromosome
,
Long
machineId
,
int
limit
)
{
List
<
ProdProcessExec
>
newProcessExecs
=
_prodProcessExecService
.
lambdaQuery
()
if
(
chromosome
==
null
||
machineId
==
null
||
chromosome
.
getInitMachines
()
==
null
)
{
.
eq
(
ProdProcessExec:
:
getSceneId
,
sceneId
)
return
"[]"
;
.
eq
(
ProdProcessExec:
:
getOrderId
,
newOrderId
)
.
orderByAsc
(
ProdProcessExec:
:
getTaskSeq
)
.
list
();
if
(
newProcessExecs
==
null
||
newProcessExecs
.
isEmpty
())
{
throw
new
RuntimeException
(
"新订单没有工序:"
+
newOrderId
);
}
}
Machine
machine
=
chromosome
.
getInitMachines
().
stream
()
// 3.1 查询新工序对应设备(与InitEntrys对齐:execId -> prod_equipment)
List
<
String
>
execIds
=
newProcessExecs
.
stream
()
.
map
(
ProdProcessExec:
:
getExecId
)
.
filter
(
Objects:
:
nonNull
)
.
filter
(
Objects:
:
nonNull
)
.
filter
(
m
->
m
.
getId
()
==
machineId
)
.
distinct
()
.
findFirst
()
.
collect
(
Collectors
.
toList
());
.
orElse
(
null
);
List
<
ProdEquipment
>
newProdEquipments
=
execIds
.
isEmpty
()
?
new
ArrayList
<>()
:
_prodEquipmentService
.
lambdaQuery
()
.
eq
(
ProdEquipment:
:
getSceneId
,
sceneId
)
.
in
(
ProdEquipment:
:
getExecId
,
execIds
)
.
list
();
if
(
machine
==
null
||
machine
.
getAvailability
()
==
null
||
machine
.
getAvailability
()
.
isEmpty
())
{
if
(
newProdEquipments
==
null
||
newProdEquipments
.
isEmpty
())
{
return
"[]"
;
throw
new
RuntimeException
(
"自动插单失败:新工单未生成可选设备,请检查PROD_EQUIPMENT"
)
;
}
}
return
machine
.
getAvailability
().
stream
()
// 4. 计算锚点时间:基准时间 + 冻结期
.
filter
(
Objects:
:
nonNull
)
LocalDateTime
baseTime
=
chromosome
.
getBaseTime
();
.
sorted
(
Comparator
.
comparing
(
TimeSegment:
:
getStart
))
LambdaQueryWrapper
<
ApsTimeConfig
>
queryWrapper
=
new
LambdaQueryWrapper
<>();
.
limit
(
Math
.
max
(
limit
,
1
))
ApsTimeConfig
apsTimeConfig
=
apsTimeConfigMapper
.
selectOne
(
queryWrapper
);
.
map
(
seg
->
String
.
format
(
"%s|used=%s|%s~%s"
,
seg
.
getType
(),
seg
.
isUsed
(),
seg
.
getStart
(),
seg
.
getEnd
()))
long
freezeSeconds
=
0L
;
.
collect
(
Collectors
.
joining
(
"; "
));
if
(
apsTimeConfig
!=
null
&&
apsTimeConfig
.
getFreezeDate
()
!=
null
)
{
freezeSeconds
=
apsTimeConfig
.
getFreezeDate
().
longValue
();
}
if
(
apsTimeConfig
!=
null
&&
apsTimeConfig
.
getBaseTime
()
!=
null
)
{
baseTime
=
apsTimeConfig
.
getBaseTime
();
}
LocalDateTime
anchorTime
=
baseTime
.
plusSeconds
(
Math
.
max
(
freezeSeconds
,
0L
));
// 5. 自动插单(占位后推 + 空挡前移)
GlobalParam
globalParam
=
InitGlobalParam
();
ScheduleOperationService
scheduleOperation
=
new
ScheduleOperationService
(
materialRequirementService
,
this
);
scheduleOperation
.
InsertOrderAuto
(
chromosome
,
newOrderId
,
newLaunchOrder
,
newProcessExecs
,
newProdEquipments
,
anchorTime
,
globalParam
);
// 6. 保存
WriteScheduleSummary
(
chromosome
);
_sceneService
.
saveChromosomeToFile
(
chromosome
,
sceneId
);
return
chromosome
;
}
}
public
Chromosome
Move
(
String
SceneId
,
List
<
Integer
>
opId
,
LocalDateTime
newStartTime
,
public
Chromosome
Move
(
String
SceneId
,
List
<
Integer
>
opId
,
LocalDateTime
newStartTime
,
...
...
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