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
6c2d7167
Commit
6c2d7167
authored
May 18, 2026
by
DESKTOP-VKRD9QF\Administration
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
策略优化
parent
ecfe8236
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
335 additions
and
159 deletions
+335
-159
LanuchController.java
src/main/java/com/aps/controller/LanuchController.java
+51
-5
UserStrategyRuleService.java
src/main/java/com/aps/service/UserStrategyRuleService.java
+2
-0
UserStrategyRuleServiceImpl.java
...ava/com/aps/service/impl/UserStrategyRuleServiceImpl.java
+42
-3
PlanResultService.java
src/main/java/com/aps/service/plan/PlanResultService.java
+21
-151
ScheduleStrategyService.java
...in/java/com/aps/service/plan/ScheduleStrategyService.java
+219
-0
No files found.
src/main/java/com/aps/controller/LanuchController.java
View file @
6c2d7167
...
...
@@ -71,21 +71,43 @@ public class LanuchController {
*/
@PostMapping
(
"/schedule"
)
@Operation
(
summary
=
"运算"
)
public
R
<
String
>
schedule
(
@RequestBody
Map
<
String
,
String
>
params
)
{
String
sceneId
=
params
.
get
(
"sceneId"
);
public
R
<
String
>
schedule
(
@RequestBody
Map
<
String
,
Object
>
params
)
{
String
sceneId
=
getStringParam
(
params
,
"sceneId"
);
if
(
sceneId
==
null
||
sceneId
.
trim
().
isEmpty
())
{
throw
new
IllegalArgumentException
(
"场景ID不能为空"
);
}
// 如果需要处理时间字段,可以从params中获取并转换
// 例如:开始时间、结束时间等
String
startTimeStr
=
params
.
get
(
"startTime"
);
String
endTimeStr
=
params
.
get
(
"endTime"
);
String
startTimeStr
=
getStringParam
(
params
,
"startTime"
);
String
endTimeStr
=
getStringParam
(
params
,
"endTime"
);
// 在这里可以添加时间格式转换逻辑
// 根据不同格式解析时间字符串
Chromosome
scheduleChromosomes
=
planResultService
.
execute2
(
sceneId
);
// 这些参数前端可以不传;不传时后端会根据 sceneId 找场景创建人,再查这个人的策略。
Long
userId
=
getLongParam
(
params
,
"userId"
);
Long
baseRuleId
=
getLongParam
(
params
,
"baseRuleId"
);
if
(
baseRuleId
==
null
)
{
baseRuleId
=
getLongParam
(
params
,
"referenceId"
);
}
String
userRuleId
=
getStringParam
(
params
,
"userRuleId"
);
String
id
=
getStringParam
(
params
,
"id"
);
if
(
id
!=
null
)
{
int
index
=
id
.
indexOf
(
":"
);
if
(
index
>
0
&&
index
<
id
.
length
()
-
1
)
{
String
source
=
id
.
substring
(
0
,
index
);
String
ruleId
=
id
.
substring
(
index
+
1
);
// 前端如果传的是组合 id:USER:用户策略ID 走用户策略;GLOBAL:基础策略ID 走全局策略。
if
(
"USER"
.
equalsIgnoreCase
(
source
)
&&
userRuleId
==
null
)
{
userRuleId
=
ruleId
;
}
else
if
(
"GLOBAL"
.
equalsIgnoreCase
(
source
)
&&
baseRuleId
==
null
)
{
baseRuleId
=
parseLongParam
(
"id"
,
ruleId
);
}
}
}
Chromosome
scheduleChromosomes
=
planResultService
.
execute2
(
sceneId
,
userId
,
baseRuleId
,
userRuleId
);
return
R
.
ok
(
"排产计算成功"
,
"排产计算成功"
);
}
...
...
@@ -218,4 +240,28 @@ public class LanuchController {
return
lanuchService
.
insertOrder
(
sceneId
,
orderCode
,
materialId
,
startDate
,
endDate
,
priority
,
quantity
);
}
private
String
getStringParam
(
Map
<
String
,
?>
params
,
String
key
)
{
if
(
params
==
null
||
params
.
get
(
key
)
==
null
)
{
return
null
;
}
String
value
=
String
.
valueOf
(
params
.
get
(
key
)).
trim
();
return
value
.
isEmpty
()
?
null
:
value
;
}
private
Long
getLongParam
(
Map
<
String
,
?>
params
,
String
key
)
{
String
value
=
getStringParam
(
params
,
key
);
return
parseLongParam
(
key
,
value
);
}
private
Long
parseLongParam
(
String
key
,
String
value
)
{
if
(
value
==
null
||
value
.
trim
().
isEmpty
())
{
return
null
;
}
try
{
return
Long
.
valueOf
(
value
.
trim
());
}
catch
(
NumberFormatException
e
)
{
throw
new
IllegalArgumentException
(
key
+
"必须是数字"
);
}
}
}
src/main/java/com/aps/service/UserStrategyRuleService.java
View file @
6c2d7167
...
...
@@ -19,4 +19,6 @@ public interface UserStrategyRuleService extends IService<UserStrategyRule> {
List
<
Map
<
String
,
Object
>>
getStrategyOptions
(
Long
userId
);
List
<
StrategyScheduling
>
getEffectiveForwardScheduling
(
Long
userId
,
Long
baseRuleId
,
String
sceneId
);
List
<
StrategyScheduling
>
getEffectiveForwardScheduling
(
Long
userId
,
Long
baseRuleId
,
String
sceneId
,
String
userRuleId
);
}
src/main/java/com/aps/service/impl/UserStrategyRuleServiceImpl.java
View file @
6c2d7167
...
...
@@ -37,7 +37,7 @@ public class UserStrategyRuleServiceImpl extends ServiceImpl<UserStrategyRuleMap
String
source
=
getSource
(
params
);
String
ruleId
=
getRuleId
(
params
);
String
userRuleId
=
"USER"
.
equalsIgnoreCase
(
source
)
?
ruleId
:
getString
(
params
,
"userRuleId"
);
Long
baseRuleId
=
"GLOBAL"
.
equalsIgnoreCase
(
source
)
?
toLong
(
ruleId
)
:
getLong
(
params
,
"baseRuleId"
);
Long
baseRuleId
=
resolveBaseRuleId
(
params
,
source
,
ruleId
);
UserStrategyRule
selectedUserRule
=
findUserRuleById
(
userRuleId
,
userId
);
if
(
selectedUserRule
!=
null
)
{
...
...
@@ -63,7 +63,7 @@ public class UserStrategyRuleServiceImpl extends ServiceImpl<UserStrategyRuleMap
String
source
=
getSource
(
params
);
String
ruleId
=
getRuleId
(
params
);
String
userRuleId
=
"USER"
.
equalsIgnoreCase
(
source
)
?
ruleId
:
getString
(
params
,
"userRuleId"
);
Long
baseRuleId
=
"GLOBAL"
.
equalsIgnoreCase
(
source
)
?
toLong
(
ruleId
)
:
getLong
(
params
,
"baseRuleId"
);
Long
baseRuleId
=
resolveBaseRuleId
(
params
,
source
,
ruleId
);
UserStrategyRule
userRule
=
null
;
if
(
StringUtils
.
hasText
(
userRuleId
))
{
...
...
@@ -116,7 +116,7 @@ public class UserStrategyRuleServiceImpl extends ServiceImpl<UserStrategyRuleMap
String
source
=
getSource
(
params
);
String
ruleId
=
getRuleId
(
params
);
String
userRuleId
=
"USER"
.
equalsIgnoreCase
(
source
)
?
ruleId
:
getString
(
params
,
"userRuleId"
);
Long
baseRuleId
=
"GLOBAL"
.
equalsIgnoreCase
(
source
)
?
toLong
(
ruleId
)
:
getLong
(
params
,
"baseRuleId"
);
Long
baseRuleId
=
resolveBaseRuleId
(
params
,
source
,
ruleId
);
UserStrategyRule
userRule
=
null
;
if
(
StringUtils
.
hasText
(
userRuleId
))
{
...
...
@@ -224,10 +224,23 @@ public class UserStrategyRuleServiceImpl extends ServiceImpl<UserStrategyRuleMap
@Override
public
List
<
StrategyScheduling
>
getEffectiveForwardScheduling
(
Long
userId
,
Long
baseRuleId
,
String
sceneId
)
{
return
getEffectiveForwardScheduling
(
userId
,
baseRuleId
,
sceneId
,
null
);
}
@Override
public
List
<
StrategyScheduling
>
getEffectiveForwardScheduling
(
Long
userId
,
Long
baseRuleId
,
String
sceneId
,
String
userRuleId
)
{
// 1. 如果 /lanuch/schedule 明确带了 userRuleId,就优先使用这条刚保存的用户策略。
UserStrategyRule
selectedUserRule
=
findUserRuleByIdOptionalUser
(
userRuleId
,
userId
);
if
(
selectedUserRule
!=
null
)
{
return
parseForwardScheduling
(
selectedUserRule
.
getForwardScheduling
());
}
// 2. 没有明确 userRuleId 时,按 userId/baseRuleId 找当前用户可用的策略。
UserStrategyRule
userRule
=
findUserRule
(
userId
,
baseRuleId
);
if
(
userRule
!=
null
)
{
return
parseForwardScheduling
(
userRule
.
getForwardScheduling
());
}
// 3. 用户没有自定义策略时,回退到基础/全局策略,保证排产还能继续跑。
StrategyRule
globalRule
=
findGlobalRule
(
baseRuleId
);
return
globalRule
==
null
?
new
ArrayList
<
StrategyScheduling
>()
:
parseForwardScheduling
(
globalRule
.
getForwardScheduling
());
}
...
...
@@ -238,6 +251,7 @@ public class UserStrategyRuleServiceImpl extends ServiceImpl<UserStrategyRuleMap
return
null
;
}
// 同一个用户可能有多条策略:默认策略优先,其次取最近修改的一条。
rules
.
sort
(
Comparator
.
comparing
((
UserStrategyRule
rule
)
->
rule
.
getIsDefault
()
==
null
?
0L
:
rule
.
getIsDefault
(),
Comparator
.
reverseOrder
())
.
thenComparing
(
rule
->
rule
.
getLastmodificationtime
()
==
null
?
LocalDateTime
.
MIN
:
rule
.
getLastmodificationtime
(),
Comparator
.
reverseOrder
()));
...
...
@@ -256,6 +270,22 @@ public class UserStrategyRuleServiceImpl extends ServiceImpl<UserStrategyRuleMap
return
rule
;
}
private
UserStrategyRule
findUserRuleByIdOptionalUser
(
String
userRuleId
,
Long
userId
)
{
if
(!
StringUtils
.
hasText
(
userRuleId
))
{
return
null
;
}
UserStrategyRule
rule
=
this
.
getById
(
userRuleId
);
if
(
rule
==
null
||
isDeleted
(
rule
.
getIsdeleted
()))
{
return
null
;
}
// 如果能解析到 userId,则校验策略归属,避免误用其他用户的策略。
if
(
userId
!=
null
&&
!
userId
.
equals
(
rule
.
getUserid
()))
{
return
null
;
}
return
rule
;
}
private
List
<
UserStrategyRule
>
findUserRules
(
Long
userId
,
Long
baseRuleId
)
{
if
(
userId
==
null
)
{
return
null
;
...
...
@@ -362,6 +392,15 @@ public class UserStrategyRuleServiceImpl extends ServiceImpl<UserStrategyRuleMap
return
toLong
(
String
.
valueOf
(
params
.
get
(
key
)));
}
private
Long
resolveBaseRuleId
(
Map
<
String
,
Object
>
params
,
String
source
,
String
ruleId
)
{
if
(
"GLOBAL"
.
equalsIgnoreCase
(
source
))
{
return
toLong
(
ruleId
);
}
Long
baseRuleId
=
getLong
(
params
,
"baseRuleId"
);
// 前端保存策略时传的是 referenceId,这里兼容成基础策略 ID。
return
baseRuleId
==
null
?
getLong
(
params
,
"referenceId"
)
:
baseRuleId
;
}
private
String
getString
(
Map
<
String
,
Object
>
params
,
String
key
)
{
if
(
params
==
null
||
params
.
get
(
key
)
==
null
)
{
return
null
;
...
...
src/main/java/com/aps/service/plan/PlanResultService.java
View file @
6c2d7167
This diff is collapsed.
Click to expand it.
src/main/java/com/aps/service/plan/ScheduleStrategyService.java
0 → 100644
View file @
6c2d7167
package
com
.
aps
.
service
.
plan
;
import
com.aps.common.util.DateGroupUtil
;
import
com.aps.entity.Algorithm.OrderSortRule
;
import
com.aps.entity.ProdSceneConfig
;
import
com.aps.entity.StrategyScheduling
;
import
com.aps.entity.basic.Order
;
import
com.aps.service.ProdSceneConfigService
;
import
com.aps.service.UserStrategyRuleService
;
import
lombok.extern.slf4j.Slf4j
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.stereotype.Service
;
import
java.util.ArrayList
;
import
java.util.Collections
;
import
java.util.Comparator
;
import
java.util.HashSet
;
import
java.util.List
;
import
java.util.Locale
;
import
java.util.Set
;
import
java.util.stream.Collectors
;
/**
* 排产策略服务:负责读取当前排产要使用的策略,并把策略转换成订单排序规则。
*/
@Slf4j
@Service
public
class
ScheduleStrategyService
{
@Autowired
private
UserStrategyRuleService
userStrategyRuleService
;
@Autowired
private
ProdSceneConfigService
prodSceneConfigService
;
/**
* 获取本次排产实际使用的用户。
* 前端传 userId 时直接使用;没传时从场景创建人 createUser 反查。
*/
public
Long
resolveScheduleUserId
(
String
sceneId
,
Long
userId
)
{
if
(
userId
!=
null
)
{
return
userId
;
}
try
{
ProdSceneConfig
sceneConfig
=
prodSceneConfigService
==
null
?
null
:
prodSceneConfigService
.
getById
(
sceneId
);
return
parseLongSafely
(
sceneConfig
==
null
?
null
:
sceneConfig
.
getCreateUser
());
}
catch
(
Exception
e
)
{
log
.
warn
(
"读取场景用户失败,sceneId={}"
,
sceneId
,
e
);
return
null
;
}
}
/**
* 读取 /userStrategyRule/save 保存的用户策略;没有用户策略时由 UserStrategyRuleService 兜底全局策略。
*/
public
List
<
StrategyScheduling
>
loadEffectiveForwardScheduling
(
Long
userId
,
Long
baseRuleId
,
String
sceneId
,
String
userRuleId
)
{
try
{
List
<
StrategyScheduling
>
schedulings
=
userStrategyRuleService
.
getEffectiveForwardScheduling
(
userId
,
baseRuleId
,
sceneId
,
userRuleId
);
return
schedulings
==
null
?
Collections
.
emptyList
()
:
schedulings
;
}
catch
(
Exception
e
)
{
log
.
warn
(
"读取排产策略失败,使用默认优先级排序,sceneId={}, userId={}, baseRuleId={}, userRuleId={}"
,
sceneId
,
userId
,
baseRuleId
,
userRuleId
,
e
);
return
Collections
.
emptyList
();
}
}
public
OrderSortRule
createMultiConditionRule
(
List
<
Order
>
orders
)
{
return
createMultiConditionRule
(
orders
,
Collections
.
emptyList
());
}
/**
* 把 forwardScheduling 中 value=true 的策略项按 sort 顺序转换成 OrderSortRule。
* 如果用户策略和全局策略都没有可用项,则回退到原来的 priority 升序。
*/
public
OrderSortRule
createMultiConditionRule
(
List
<
Order
>
orders
,
List
<
StrategyScheduling
>
strategySchedulings
)
{
OrderSortRule
rule
=
new
OrderSortRule
();
rule
.
setEnabled
(
true
);
List
<
OrderSortRule
.
SortCondition
>
conditions
=
new
ArrayList
<>();
try
{
Set
<
String
>
fields
=
new
HashSet
<>();
List
<
StrategyScheduling
>
selecteds
=
strategySchedulings
==
null
?
Collections
.
emptyList
()
:
strategySchedulings
.
stream
()
.
filter
(
StrategyScheduling:
:
isValue
)
.
sorted
(
Comparator
.
comparingInt
(
StrategyScheduling:
:
getSort
))
.
collect
(
Collectors
.
toList
());
int
sequence
=
1
;
for
(
StrategyScheduling
strategy
:
selecteds
)
{
OrderSortRule
.
SortCondition
condition
=
buildSortConditionFromStrategy
(
orders
,
strategy
,
sequence
,
fields
);
if
(
condition
!=
null
)
{
conditions
.
add
(
condition
);
fields
.
add
(
condition
.
getFieldName
());
sequence
++;
}
}
}
catch
(
Exception
e
)
{
log
.
warn
(
"策略排序条件生成失败,使用默认优先级排序"
,
e
);
conditions
.
clear
();
}
if
(
conditions
.
isEmpty
())
{
conditions
.
add
(
createSortCondition
(
1
,
"priority"
,
false
));
}
rule
.
setConditions
(
conditions
);
return
rule
;
}
/**
* 单个策略项到排序字段的映射。
* 例如 deliveryDate -> dueDate/groupDueDate,startDate -> startDate/groupStartDate。
*/
private
OrderSortRule
.
SortCondition
buildSortConditionFromStrategy
(
List
<
Order
>
orders
,
StrategyScheduling
strategy
,
int
sequence
,
Set
<
String
>
fields
)
throws
Exception
{
if
(
strategy
==
null
||
strategy
.
getName
()
==
null
)
{
return
null
;
}
String
name
=
normalizeStrategyName
(
strategy
.
getName
());
int
amplitude
=
strategy
.
getAmplitude
();
switch
(
name
)
{
case
"customerduedate"
:
case
"customerdue_date"
:
case
"customer_due_date"
:
case
"deliverydate"
:
case
"delivery_date"
:
case
"duedate"
:
case
"due_date"
:
{
String
fieldName
=
"dueDate"
;
// amplitude > 0 表示按 N 天跨度分组排序;amplitude <= 0 表示直接按真实交期排序。
if
(
amplitude
>
0
)
{
DateGroupUtil
.
calculateGroupDueDate
(
orders
,
"dueDate"
,
"groupDueDate"
,
amplitude
);
fieldName
=
"groupDueDate"
;
}
return
createSortCondition
(
sequence
,
fieldName
,
false
);
}
case
"startddate"
:
case
"startd_date"
:
case
"startdate"
:
case
"start_date"
:
{
String
fieldName
=
"startDate"
;
// 开始日期策略同样支持按 amplitude 天数分组。
if
(
amplitude
>
0
)
{
DateGroupUtil
.
calculateGroupDueDate
(
orders
,
"startDate"
,
"groupStartDate"
,
amplitude
);
fieldName
=
"groupStartDate"
;
}
return
createSortCondition
(
sequence
,
fieldName
,
false
);
}
case
"gatheringseries"
:
case
"gathering_series"
:
case
"serie"
:
case
"series"
:
return
fields
.
contains
(
"serie"
)
?
null
:
createSortCondition
(
sequence
,
"serie"
,
false
);
case
"minimumwopriority"
:
case
"minimum_wo_priority"
:
case
"min_wo_priority"
:
case
"priority"
:
case
"priority_asc"
:
return
fields
.
contains
(
"priority"
)
?
null
:
createSortCondition
(
sequence
,
"priority"
,
false
);
case
"maximumwopriority"
:
case
"maximum_wo_priority"
:
case
"max_wo_priority"
:
case
"priority_desc"
:
return
fields
.
contains
(
"priority"
)
?
null
:
createSortCondition
(
sequence
,
"priority"
,
true
);
case
"materialrise"
:
case
"material_rise"
:
case
"materialcode"
:
case
"material_code"
:
return
fields
.
contains
(
"materialCode"
)
?
null
:
createSortCondition
(
sequence
,
"materialCode"
,
false
);
case
"planrise"
:
case
"plan_rise"
:
case
"ordercode_asc"
:
case
"order_code_asc"
:
return
fields
.
contains
(
"orderCode"
)
?
null
:
createSortCondition
(
sequence
,
"orderCode"
,
false
);
case
"plandrop"
:
case
"plan_drop"
:
case
"ordercode_desc"
:
case
"order_code_desc"
:
return
fields
.
contains
(
"orderCode"
)
?
null
:
createSortCondition
(
sequence
,
"orderCode"
,
true
);
case
"minimizetoolchangeovers"
:
case
"minimize_tool_changeovers"
:
case
"minimizechangeover"
:
case
"minimize_changeover"
:
return
fields
.
contains
(
"minimize_changeover"
)
?
null
:
createSortCondition
(
sequence
,
"minimize_changeover"
,
false
);
default
:
log
.
warn
(
"跳过不支持的排产策略项: {}"
,
strategy
.
getName
());
return
null
;
}
}
private
Long
parseLongSafely
(
String
value
)
{
if
(
value
==
null
||
value
.
trim
().
isEmpty
())
{
return
null
;
}
try
{
return
Long
.
valueOf
(
value
.
trim
());
}
catch
(
NumberFormatException
e
)
{
return
null
;
}
}
private
String
normalizeStrategyName
(
String
name
)
{
return
name
==
null
?
""
:
name
.
trim
().
replace
(
"-"
,
"_"
).
replace
(
" "
,
"_"
).
toLowerCase
(
Locale
.
ROOT
);
}
private
OrderSortRule
.
SortCondition
createSortCondition
(
int
sequence
,
String
fieldName
,
boolean
reverse
)
{
OrderSortRule
.
SortCondition
condition
=
new
OrderSortRule
.
SortCondition
();
condition
.
setSequence
(
sequence
);
condition
.
setFieldName
(
fieldName
);
condition
.
setReverse
(
reverse
);
return
condition
;
}
}
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