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
2f9e7b36
Commit
2f9e7b36
authored
Sep 21, 2026
by
Tong Li
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
MP-计划时间,周期类型-关联计划周期表,根据计划周期页面的周期类型,增加了年和季度的计算维度
parent
29be9769
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
120 additions
and
27 deletions
+120
-27
MacroPlannerDataConverterRunner.java
...com/aps/macroplanner/MacroPlannerDataConverterRunner.java
+1
-1
DataValidator.java
src/main/java/com/aps/macroplanner/data/DataValidator.java
+4
-4
MacroPlannerDataConverter.java
.../com/aps/macroplanner/data/MacroPlannerDataConverter.java
+112
-19
ResultWriter.java
src/main/java/com/aps/macroplanner/output/ResultWriter.java
+3
-3
No files found.
src/main/java/com/aps/macroplanner/MacroPlannerDataConverterRunner.java
View file @
2f9e7b36
...
...
@@ -30,7 +30,7 @@ import org.springframework.context.ApplicationContext;
public
class
MacroPlannerDataConverterRunner
{
public
static
void
main
(
String
[]
args
)
{
String
sceneId
=
(
args
.
length
>
0
)
?
args
[
0
]
:
""
;
String
sceneId
=
(
args
.
length
>
0
)
?
args
[
0
]
:
"
ff8a2f2b-e134-4ec2-8e2e-b77e830c9e64
"
;
System
.
out
.
println
(
"===== MACROPLANNER DATA CONVERTER RUNNER START ====="
);
System
.
out
.
println
(
"SceneId: "
+
sceneId
);
...
...
src/main/java/com/aps/macroplanner/data/DataValidator.java
View file @
2f9e7b36
...
...
@@ -232,7 +232,7 @@ public class DataValidator {
Set
<
String
>
opIds
=
new
HashSet
<>();
for
(
Operation
op
:
data
.
getOperations
())
opIds
.
add
(
op
.
getId
());
int
maxPeriodIdx
=
data
.
getPeriods
().
size
()
-
1
;
//
int maxPeriodIdx = data.getPeriods().size() - 1;
// 销售需求
for
(
SalesDemand
sd
:
data
.
getSalesDemands
())
{
...
...
@@ -242,9 +242,9 @@ public class DataValidator {
if
(!
spIds
.
contains
(
sd
.
getStockingPoint
().
getId
()))
{
errors
.
add
(
"销售需求引用不存在的库存点: "
+
sd
.
getStockingPoint
().
getId
());
}
if
(
sd
.
getPeriod
().
getIndex
()
>
maxPeriodIdx
)
{
errors
.
add
(
"销售需求引用不存在的周期: "
+
sd
.
getPeriod
().
getIndex
());
}
//
if (sd.getPeriod().getIndex() > maxPeriodIdx) {
//
errors.add("销售需求引用不存在的周期: " + sd.getPeriod().getIndex());
//
}
if
(
sd
.
getQuantity
()
<
0
)
{
errors
.
add
(
"销售需求数量不能为负: "
+
sd
.
getProduct
().
getId
()
+
" P"
+
sd
.
getPeriod
().
getIndex
());
}
...
...
src/main/java/com/aps/macroplanner/data/MacroPlannerDataConverter.java
View file @
2f9e7b36
...
...
@@ -6,6 +6,7 @@ import com.aps.macroplanner.scene.MacroSceneContext;
import
com.aps.entity.basic.Material
;
import
com.aps.entity.basic.MaterialSupply
;
import
com.aps.mapper.EquipShiftCapacityMapper
;
import
com.aps.service.PlanPeriodService
;
import
com.baomidou.mybatisplus.extension.plugins.pagination.Page
;
import
com.fasterxml.jackson.core.type.TypeReference
;
import
com.fasterxml.jackson.databind.ObjectMapper
;
...
...
@@ -34,7 +35,9 @@ import java.time.Duration;
import
java.time.DayOfWeek
;
import
java.time.LocalDate
;
import
java.time.LocalDateTime
;
import
java.time.format.DateTimeFormatter
;
import
java.time.temporal.ChronoUnit
;
import
java.time.temporal.WeekFields
;
import
java.util.ArrayList
;
import
java.util.Arrays
;
import
java.util.Collections
;
...
...
@@ -126,7 +129,7 @@ public class MacroPlannerDataConverter {
@Autowired
private
LanuchService
lanuchService
;
@Autowired
private
ApsTimeConfigService
apsTimeConfig
Service
;
private
PlanPeriodService
planPeriod
Service
;
// ==================== 公开入口 ====================
...
...
@@ -169,23 +172,23 @@ public class MacroPlannerDataConverter {
// 0. 读取时间配置, 计算 horizonEnd
// endCount = 期数 (与 periodDimension 结合决定实际天数)
LambdaQueryWrapper
<
ApsTimeConfig
>
wrapper
=
new
LambdaQueryWrapper
<
ApsTimeConfig
>();
if
(
sceneId
!=
null
&&
!
sceneId
.
isEmpty
())
{
// wrapper.eq(ApsTimeConfig::getMpSceneId,sceneId);
}
ApsTimeConfig
timeConfig
=
apsTimeConfigService
.
getOne
(
wrapper
);
ctx
.
baseTime
=
LocalDateTime
.
of
(
2026
,
9
,
28
,
0
,
0
,
0
);
LambdaQueryWrapper
<
PlanPeriod
>
wrapper
=
new
LambdaQueryWrapper
<
PlanPeriod
>();
wrapper
.
eq
(
PlanPeriod:
:
getIsplan
,
1
);
wrapper
.
eq
(
PlanPeriod:
:
getIsdeleted
,
0
);
wrapper
.
eq
(
PlanPeriod:
:
getMpSceneId
,
sceneId
);
PlanPeriod
timeConfig
=
planPeriodService
.
getOne
(
wrapper
);
ctx
.
periodDimension
=
"WEEK"
;
if
(
timeConfig
!=
null
&&
timeConfig
.
getPeriodDimension
()
!=
null
&&
!
timeConfig
.
getPeriodDimension
().
trim
().
isEmpty
())
{
ctx
.
periodDimension
=
timeConfig
.
getPeriodDimension
().
trim
().
toUpperCase
();
if
(
timeConfig
!=
null
&&
timeConfig
.
getTimeunit
()
!=
null
&&
!
timeConfig
.
getTimeunit
().
trim
().
isEmpty
())
{
ctx
.
baseTime
=
timeConfig
.
getBasetime
();
ctx
.
periodDimension
=
toPeriodType
(
timeConfig
.
getTimeunitid
().
toString
())
;
}
int
periodCount
=
DEFAULT_PERIOD_COUNT
;
if
(
timeConfig
!=
null
&&
timeConfig
.
get
EndCount
()
!=
null
)
{
int
ec
=
timeConfig
.
get
EndCount
().
intValue
();
if
(
timeConfig
!=
null
&&
timeConfig
.
get
Future
()
!=
null
)
{
int
ec
=
timeConfig
.
get
Future
().
intValue
();
if
(
ec
>
0
)
{
periodCount
=
ec
;
}
...
...
@@ -198,7 +201,6 @@ public class MacroPlannerDataConverter {
log
.
info
(
"排产周期: dimension={}, periodCount={}, baseTime={}, horizonEnd={}"
,
ctx
.
periodDimension
,
periodCount
,
ctx
.
baseTime
,
ctx
.
horizonEnd
);
// 1. 需求订单 (ApsDemandOrder, 按 deliverytime 时间范围过滤)
// 1. 需求订单 (ApsDemandOrder, 按 deliverytime 时间范围过滤)
ctx
.
apsDemandOrders
=
apsDemandOrderMapper
.
selectList
(
new
LambdaQueryWrapper
<
ApsDemandOrder
>().
eq
(
ApsDemandOrder:
:
getIsdeleted
,
0
)
...
...
@@ -651,12 +653,38 @@ public class MacroPlannerDataConverter {
// 自然月: 从 baseDate 所在月的1号开始, periodCount 个月后
LocalDate
monthStart
=
baseDate
.
withDayOfMonth
(
1
);
return
monthStart
.
plusMonths
(
periodCount
);
case
"YEAR"
:
// 自然年: 从 baseDate 所在月的1号开始, periodCount 个月后
LocalDate
yearStart
=
baseDate
.
withDayOfYear
(
1
);
return
yearStart
.
plusYears
(
periodCount
);
case
"QUARTER"
:
// 自然季度: 从 baseDate 所在季度的首月1号开始, periodCount 个季度后
int
month
=
baseDate
.
getMonthValue
();
// 计算当前属于第几季度(1~4),整数除法自动取整
int
quarter
=
(
month
-
1
)
/
3
+
1
;
// 计算该季度的首月月份
int
quarterStartMonth
=
(
quarter
-
1
)
*
3
+
1
;
// 构造季度起始日期(首月1号)
LocalDate
quarterStart
=
baseDate
.
withMonth
(
quarterStartMonth
).
withDayOfMonth
(
1
);
// 加上 periodCount 个季度(每个季度3个月)
return
quarterStart
.
plusMonths
((
long
)
periodCount
*
3
);
case
"DAY"
:
default
:
return
baseDate
.
plusDays
(
periodCount
);
}
}
public
static
String
toPeriodType
(
String
code
)
{
switch
(
code
)
{
case
"2"
:
return
"WEEK"
;
case
"3"
:
return
"MONTH"
;
case
"4"
:
return
"QUARTER"
;
case
"5"
:
return
"YEAR"
;
case
"1"
:
default
:
return
"DAY"
;
}
}
/**
* 计算给定日期范围内的有效工作日数 (不含周日)。
*/
...
...
@@ -1144,6 +1172,8 @@ public class MacroPlannerDataConverter {
String
dimension
=
ctx
.
periodDimension
;
LocalDate
horizonEnd
=
ctx
.
horizonEnd
;
// 按维度创建 Period
switch
(
dimension
)
{
case
"WEEK"
:
...
...
@@ -1152,6 +1182,12 @@ public class MacroPlannerDataConverter {
case
"MONTH"
:
createMonthPeriods
(
baseDate
,
periodCount
,
horizonEnd
);
break
;
case
"YEAR"
:
createYearPeriods
(
baseDate
,
periodCount
,
horizonEnd
);
break
;
case
"QUARTER"
:
createQuarterPeriods
(
baseDate
,
periodCount
,
horizonEnd
);
break
;
case
"DAY"
:
default
:
createDayPeriods
(
baseDate
,
periodCount
);
...
...
@@ -1219,7 +1255,9 @@ public class MacroPlannerDataConverter {
/** DAY 维度: 每天一个 Period */
private
void
createDayPeriods
(
LocalDate
baseDate
,
int
periodCount
)
{
for
(
int
i
=
0
;
i
<
periodCount
;
i
++)
{
periods
.
add
(
new
Period
(
i
,
formatDayName
(
baseDate
.
plusDays
(
i
)),
1.0
,
baseDate
.
plusDays
(
i
)));
int
index
=
Integer
.
parseInt
(
baseDate
.
plusDays
(
i
).
format
(
DateTimeFormatter
.
BASIC_ISO_DATE
));
periods
.
add
(
new
Period
(
index
,
formatDayName
(
baseDate
.
plusDays
(
i
)),
1.0
,
baseDate
.
plusDays
(
i
)));
}
}
...
...
@@ -1233,8 +1271,10 @@ public class MacroPlannerDataConverter {
if
(
weekEnd
.
isAfter
(
horizonEnd
))
{
weekEnd
=
horizonEnd
;
}
int
index
=
Integer
.
parseInt
(
ws
.
format
(
DateTimeFormatter
.
BASIC_ISO_DATE
));
long
durationDays
=
ChronoUnit
.
DAYS
.
between
(
ws
,
weekEnd
);
periods
.
add
(
new
Period
(
i
,
"W"
+
(
i
+
1
)
+
"("
+
ws
+
")"
,
(
double
)
durationDays
,
ws
));
periods
.
add
(
new
Period
(
i
ndex
,
formatWeekName
(
ws
)
,
(
double
)
durationDays
,
ws
));
}
}
...
...
@@ -1248,17 +1288,70 @@ public class MacroPlannerDataConverter {
monthEnd
=
horizonEnd
;
}
long
durationDays
=
java
.
time
.
temporal
.
ChronoUnit
.
DAYS
.
between
(
monthStart
,
monthEnd
);
periods
.
add
(
new
Period
(
i
,
formatMonthName
(
monthStart
),
(
double
)
durationDays
,
monthStart
));
int
index
=
Integer
.
parseInt
(
monthStart
.
format
(
DateTimeFormatter
.
BASIC_ISO_DATE
));
periods
.
add
(
new
Period
(
index
,
formatMonthName
(
monthStart
),
(
double
)
durationDays
,
monthStart
));
cursor
=
cursor
.
plusMonths
(
1
);
}
}
private
void
createYearPeriods
(
LocalDate
baseDate
,
int
periodCount
,
LocalDate
horizonEnd
)
{
LocalDate
cursor
=
baseDate
.
withDayOfYear
(
1
);
for
(
int
i
=
0
;
i
<
periodCount
;
i
++)
{
LocalDate
monthStart
=
cursor
;
LocalDate
monthEnd
=
cursor
.
plusYears
(
1
);
if
(
monthEnd
.
isAfter
(
horizonEnd
))
{
monthEnd
=
horizonEnd
;
}
long
durationDays
=
java
.
time
.
temporal
.
ChronoUnit
.
DAYS
.
between
(
monthStart
,
monthEnd
);
int
index
=
Integer
.
parseInt
(
monthStart
.
format
(
DateTimeFormatter
.
BASIC_ISO_DATE
));
periods
.
add
(
new
Period
(
index
,
formatYearName
(
monthStart
),
(
double
)
durationDays
,
monthStart
));
cursor
=
cursor
.
plusYears
(
1
);
}
}
private
void
createQuarterPeriods
(
LocalDate
baseDate
,
int
periodCount
,
LocalDate
horizonEnd
)
{
int
month
=
baseDate
.
getMonthValue
();
// 计算当前属于第几季度(1~4),整数除法自动取整
int
quarter
=
(
month
-
1
)
/
3
+
1
;
// 计算该季度的首月月份
int
quarterStartMonth
=
(
quarter
-
1
)
*
3
+
1
;
// 构造季度起始日期(首月1号)
LocalDate
cursor
=
baseDate
.
withMonth
(
quarterStartMonth
).
withDayOfMonth
(
1
);
for
(
int
i
=
0
;
i
<
periodCount
;
i
++)
{
LocalDate
monthStart
=
cursor
;
LocalDate
monthEnd
=
cursor
.
plusMonths
(
3
);
if
(
monthEnd
.
isAfter
(
horizonEnd
))
{
monthEnd
=
horizonEnd
;
}
long
durationDays
=
java
.
time
.
temporal
.
ChronoUnit
.
DAYS
.
between
(
monthStart
,
monthEnd
);
int
index
=
Integer
.
parseInt
(
monthStart
.
format
(
DateTimeFormatter
.
BASIC_ISO_DATE
));
periods
.
add
(
new
Period
(
index
,
formatQuarterName
(
monthStart
),
(
double
)
durationDays
,
monthStart
));
cursor
=
cursor
.
plusMonths
(
3
);
}
}
private
static
String
formatDayName
(
LocalDate
date
)
{
return
String
.
format
(
"D%02d(%02d-%02d)"
,
date
.
getDayOfYear
(),
date
.
getMonthValue
(),
date
.
getDayOfMonth
());
return
String
.
format
(
"D-%02d(%02d-%02d)"
,
date
.
getDayOfYear
(),
date
.
getMonthValue
(),
date
.
getDayOfMonth
());
}
private
static
String
formatWeekName
(
LocalDate
date
)
{
WeekFields
weekFields
=
WeekFields
.
ISO
;
int
weekNo
=
date
.
get
(
weekFields
.
weekOfMonth
());
return
String
.
format
(
"W-%02d(%02d-%02d)"
,
date
.
getDayOfYear
(),
date
.
getMonthValue
(),
weekNo
);
}
private
static
String
formatMonthName
(
LocalDate
date
)
{
return
String
.
format
(
"M%d-%02d"
,
date
.
getYear
(),
date
.
getMonthValue
());
return
String
.
format
(
"M-%d-%02d"
,
date
.
getYear
(),
date
.
getMonthValue
());
}
private
static
String
formatYearName
(
LocalDate
date
)
{
return
String
.
format
(
"Y-%d"
,
date
.
getYear
());
}
private
static
String
formatQuarterName
(
LocalDate
date
)
{
int
month
=
date
.
getMonthValue
();
// 计算当前属于第几季度(1~4),整数除法自动取整
int
quarter
=
(
month
-
1
)
/
3
+
1
;
return
String
.
format
(
"Q-%d-%d"
,
date
.
getYear
(),
quarter
);
}
// ---------- 步骤8: SalesDemand (从订单推导) ----------
...
...
src/main/java/com/aps/macroplanner/output/ResultWriter.java
View file @
2f9e7b36
...
...
@@ -231,9 +231,9 @@ public class ResultWriter {
writeLog
(
"writeBomStructure"
);
writeBomStructure
(
sceneId
);
// 工序×物料×周期消耗量持久化
writeLog
(
"writeOperationDemands"
);
List
<
OperationDemandResult
>
opDemands
=
buildOperationDemandResults
();
parquetUtil
.
write
(
opDemands
,
getOptimizationOperationDemand
(
sceneId
),
OperationDemandResult
.
class
);
//
writeLog("writeOperationDemands");
//
List<OperationDemandResult> opDemands = buildOperationDemandResults();
//
parquetUtil.write(opDemands, getOptimizationOperationDemand(sceneId), OperationDemandResult.class);
return
true
;
// try {
...
...
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