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
d1745f27
Commit
d1745f27
authored
Sep 20, 2026
by
Tong Li
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
MP
parent
ea3cc142
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
21 changed files
with
1729 additions
and
411 deletions
+1729
-411
FlatParquetUtil.java
src/main/java/com/aps/common/util/FlatParquetUtil.java
+858
-31
MacroPlannerResultController.java
...java/com/aps/controller/MacroPlannerResultController.java
+321
-100
Material.java
src/main/java/com/aps/entity/basic/Material.java
+2
-0
MacroPlannerDataConverterRunner.java
...com/aps/macroplanner/MacroPlannerDataConverterRunner.java
+6
-0
MultiLevelBomTestRunner.java
...in/java/com/aps/macroplanner/MultiLevelBomTestRunner.java
+29
-26
MacroPlannerDataConverter.java
.../com/aps/macroplanner/data/MacroPlannerDataConverter.java
+31
-9
MultiLevelBomTestDataBuilder.java
...m/aps/macroplanner/data/MultiLevelBomTestDataBuilder.java
+5
-1
Operation.java
src/main/java/com/aps/macroplanner/data/Operation.java
+1
-1
OperationOutput.java
src/main/java/com/aps/macroplanner/data/OperationOutput.java
+12
-0
Product.java
src/main/java/com/aps/macroplanner/data/Product.java
+6
-0
SalesDemand.java
src/main/java/com/aps/macroplanner/data/SalesDemand.java
+7
-3
UnitOperation.java
src/main/java/com/aps/macroplanner/data/UnitOperation.java
+9
-0
UnitPeriod.java
src/main/java/com/aps/macroplanner/data/UnitPeriod.java
+12
-5
ResultWriter.java
src/main/java/com/aps/macroplanner/output/ResultWriter.java
+148
-40
OptimizationResult.java
...a/com/aps/macroplanner/output/dto/OptimizationResult.java
+25
-0
PeriodTaskResult.java
...ava/com/aps/macroplanner/output/dto/PeriodTaskResult.java
+16
-5
PispipResult.java
...in/java/com/aps/macroplanner/output/dto/PispipResult.java
+31
-1
SalesDemandResult.java
...va/com/aps/macroplanner/output/dto/SalesDemandResult.java
+5
-0
SupplyChainNode.java
...java/com/aps/macroplanner/output/dto/SupplyChainNode.java
+7
-0
UnitCapacityResult.java
...a/com/aps/macroplanner/output/dto/UnitCapacityResult.java
+14
-3
MacroPlannerProductNetworkService.java
...va/com/aps/service/MacroPlannerProductNetworkService.java
+184
-186
No files found.
src/main/java/com/aps/common/util/FlatParquetUtil.java
View file @
d1745f27
This diff is collapsed.
Click to expand it.
src/main/java/com/aps/controller/MacroPlannerResultController.java
View file @
d1745f27
This diff is collapsed.
Click to expand it.
src/main/java/com/aps/entity/basic/Material.java
View file @
d1745f27
...
...
@@ -33,6 +33,8 @@ public class Material {
*/
private
double
CurrentStock
;
private
Long
categoryId
=
1
l
;
/**
* 库存详情
*/
...
...
src/main/java/com/aps/macroplanner/MacroPlannerDataConverterRunner.java
View file @
d1745f27
...
...
@@ -4,6 +4,8 @@ import com.aps.ApsApplication;
import
com.aps.macroplanner.data.DataValidator
;
import
com.aps.macroplanner.data.MacroPlannerDataConverter
;
import
com.aps.macroplanner.data.TestDataBuilder
;
import
com.aps.macroplanner.output.ResultWriter
;
import
com.aps.macroplanner.output.dto.OptimizationResult
;
import
com.google.ortools.Loader
;
import
org.springframework.boot.SpringApplication
;
import
org.springframework.context.ApplicationContext
;
...
...
@@ -77,6 +79,10 @@ public class MacroPlannerDataConverterRunner {
optimizer
.
buildModel
();
optimizer
.
solve
();
ResultWriter
writer
=
new
ResultWriter
(
optimizer
.
getModel
(),
optimizer
.
getData
(),
1
);
OptimizationResult
result
=
writer
.
buildResult
(
"Default"
);
boolean
jsonPath
=
writer
.
saveResultToFile
(
"Default"
,
result
);
System
.
out
.
println
(
"===== MACROPLANNER DATA CONVERTER RUNNER END ====="
);
}
finally
{
SpringApplication
.
exit
(
ctx
);
...
...
src/main/java/com/aps/macroplanner/MultiLevelBomTestRunner.java
View file @
d1745f27
...
...
@@ -56,38 +56,41 @@ public class MultiLevelBomTestRunner {
// 通过 Spring 容器获取 service 实例 (static main 中 @Autowired 不会生效)
ApplicationContext
ctx
=
SpringApplication
.
run
(
ApsApplication
.
class
,
args
);
try
{
// MultiLevelBomTestDataBuilder data=new MultiLevelBomTestDataBuilder();
// data.init();
//
// MacroPlannerOptimizer optimizer = new MacroPlannerOptimizer(data);
// optimizer.buildModel();
// optimizer.solve("bom");
MpPispipResultPersistenceService
service
=
ctx
.
getBean
(
MpPispipResultPersistenceService
.
class
);
int
scale
=
100
;
BenchmarkDataBuilder
data
=
BenchmarkDataBuilder
.
forScale
(
scale
);
writeLog
(
"===== TEST RUNNER START "
+
scale
+
"====="
);
long
startTime
=
System
.
currentTimeMillis
();
MultiLevelBomTestDataBuilder
data
=
new
MultiLevelBomTestDataBuilder
();
data
.
init
();
writeLog
(
"Data loaded: "
+
data
.
getProducts
().
size
()
+
" products, "
+
data
.
getOperations
().
size
()
+
" operations"
);
long
startTime
=
System
.
currentTimeMillis
();
MacroPlannerOptimizer
optimizer
=
new
MacroPlannerOptimizer
(
data
);
optimizer
.
buildModel
();
optimizer
.
solve
(
String
.
valueOf
(
scale
));
// 构建结果并调用 save 入库
optimizer
.
solve
(
"bom"
);
ResultWriter
writer
=
new
ResultWriter
(
optimizer
.
getModel
(),
optimizer
.
getData
(),
startTime
);
OptimizationResult
result
=
writer
.
buildResult
(
String
.
valueOf
(
scale
)
);
boolean
jsonPath
=
writer
.
saveResultToFile
(
String
.
valueOf
(
scale
)
,
result
);
OptimizationResult
result
=
writer
.
buildResult
(
"bom"
);
boolean
jsonPath
=
writer
.
saveResultToFile
(
"bom"
,
result
);
writeLog
(
"PISPIP result saved: "
);
int
saved
=
service
.
save
(
String
.
valueOf
(
scale
),
result
);
writeLog
(
"PISPIP result saved: "
+
saved
);
// MpPispipResultPersistenceService service =
// ctx.getBean(MpPispipResultPersistenceService.class);
//
// int scale = 2000;
// BenchmarkDataBuilder data = BenchmarkDataBuilder.forScale(scale);
// writeLog("===== TEST RUNNER START " + scale + "=====");
//
// data.init();
// writeLog("Data loaded: " + data.getProducts().size() + " products, "
// + data.getOperations().size() + " operations");
//
// long startTime = System.currentTimeMillis();
// MacroPlannerOptimizer optimizer = new MacroPlannerOptimizer(data);
// optimizer.buildModel();
// optimizer.solve(String.valueOf(scale));
//
// // 构建结果并调用 save 入库
// ResultWriter writer = new ResultWriter(optimizer.getModel(), optimizer.getData(), startTime);
// OptimizationResult result = writer.buildResult(String.valueOf(scale));
// boolean jsonPath = writer.saveResultToFile(String.valueOf(scale), result);
//
// writeLog("PISPIP result saved: ");
// int saved = service.save(String.valueOf(scale), result);
// writeLog("PISPIP result saved: " + saved);
writeLog
(
"===== TEST RUNNER END ====="
);
}
catch
(
Exception
e
)
{
...
...
src/main/java/com/aps/macroplanner/data/MacroPlannerDataConverter.java
View file @
d1745f27
...
...
@@ -24,6 +24,7 @@ import com.aps.mapper.StockMapper;
import
com.aps.service.ApsTimeConfigService
;
import
com.aps.service.LanuchService
;
import
com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper
;
import
io.swagger.v3.oas.models.security.SecurityScheme
;
import
lombok.extern.slf4j.Slf4j
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.stereotype.Service
;
...
...
@@ -47,6 +48,7 @@ import java.util.Map;
import
java.util.Objects
;
import
java.util.Optional
;
import
java.util.Set
;
import
java.util.function.Function
;
import
java.util.stream.Collectors
;
/**
...
...
@@ -429,7 +431,7 @@ public class MacroPlannerDataConverter {
material
.
setName
(
m
.
getName
());
material
.
setMaxProduction
(
m
.
getMaxProduction
());
material
.
setMinProduction
(
m
.
getMinProduction
());
material
.
setCategoryId
(
m
.
getCategoryId
());
// 库存
List
<
Stock
>
materialStocks
=
stocksByMaterialId
.
getOrDefault
(
m
.
getId
(),
Collections
.
emptyList
());
if
(!
materialStocks
.
isEmpty
())
{
...
...
@@ -700,6 +702,7 @@ public class MacroPlannerDataConverter {
for
(
Material
m
:
ctx
.
materialByMaterialId
.
values
())
{
String
name
=
pickName
(
m
.
getName
(),
m
.
getCode
(),
m
.
getId
());
Product
p
=
new
Product
(
m
.
getCode
(),
name
,
m
.
getCode
());
p
.
setCategoryId
(
m
.
getCategoryId
());
products
.
add
(
p
);
ctx
.
productByMaterialId
.
put
(
m
.
getId
(),
p
);
}
...
...
@@ -842,6 +845,10 @@ public class MacroPlannerDataConverter {
int
hid
=
rd
.
getRoutingHeaderId
().
intValue
();
detailsByHeader
.
computeIfAbsent
(
hid
,
k
->
new
ArrayList
<>()).
add
(
rd
);
}
Map
<
Integer
,
PlanResource
>
prMap
=
ctx
.
planResources
.
stream
()
.
collect
(
Collectors
.
toMap
(
PlanResource:
:
getId
,
Function
.
identity
()));
Map
<
Integer
,
Equipinfo
>
equipMap
=
ctx
.
equipinfos
.
stream
()
.
collect
(
Collectors
.
toMap
(
Equipinfo:
:
getId
,
Function
.
identity
()));
detailsByHeader
.
values
().
forEach
(
list
->
list
.
sort
(
Comparator
.
comparing
(
rd
->
rd
.
getTaskSeq
()
==
null
?
Long
.
MAX_VALUE
:
rd
.
getTaskSeq
())));
...
...
@@ -887,13 +894,23 @@ public class MacroPlannerDataConverter {
unitOps
=
equips
.
stream
()
.
filter
(
e
->
e
.
getEquipId
()
!=
null
)
.
map
(
e
->
{
PlanResource
res
=
prMap
.
get
(
e
.
getEquipId
().
intValue
());
Integer
shopid
=
0
;
if
(
res
!=
null
)
{
Equipinfo
equip
=
equipMap
.
get
(
res
.
getReferenceId
());
if
(
equip
!=
null
)
{
shopid
=
equip
.
getShopId
();
}
}
String
unitId
=
"EQUIP_"
+
e
.
getEquipId
();
String
unitName
=
e
.
getName
();
double
capCoeff
=
(
e
.
getDuration
()
!=
null
)
?
e
.
getDuration
().
doubleValue
()/
3600
/
e
.
getOutputQuantity
().
doubleValue
()
:
1.0
;
boolean
lotSize
=
e
.
getOneBatchQuantity
()
!=
null
&&
e
.
getOneBatchQuantity
().
compareTo
(
BigDecimal
.
ZERO
)
>
0
;
double
lotSizeVal
=
lotSize
?
e
.
getOneBatchQuantity
().
doubleValue
()
:
0.0
;
return
new
UnitOperation
(
unitId
,
unitName
,
capCoeff
,
lotSize
,
lotSizeVal
,
1.0
);
return
new
UnitOperation
(
unitId
,
unitName
,
capCoeff
,
lotSize
,
lotSizeVal
,
1.0
,
shopid
);
})
.
collect
(
Collectors
.
toList
());
}
else
{
...
...
@@ -902,7 +919,7 @@ public class MacroPlannerDataConverter {
String
unitName
=
(
rd
.
getEquipTypeId
()
!=
null
?
rd
.
getEquipType
()
:
"DEFAULT"
);
double
capCoeff
=
(
rd
.
getRuntime
()
!=
null
)
?
rd
.
getRuntime
().
doubleValue
()
:
1.0
;
unitOps
=
Arrays
.
asList
(
new
UnitOperation
(
unitId
,
unitName
,
capCoeff
,
false
,
0.0
,
1.0
));
unitOps
=
Arrays
.
asList
(
new
UnitOperation
(
unitId
,
unitName
,
capCoeff
,
false
,
0.0
,
1.0
,
0
));
}
Operation
op
=
new
Operation
(
...
...
@@ -1014,7 +1031,7 @@ public class MacroPlannerDataConverter {
"采购-"
+
pickName
(
m
.
getName
(),
m
.
getId
())
+
(
mp
.
getSupplyName
()
!=
null
?
"-"
+
mp
.
getSupplyName
()
:
""
),
Collections
.
singletonList
(
new
UnitOperation
(
unitId
,
unitName
,
0.5
,
false
,
0.0
,
1.0
)),
new
UnitOperation
(
unitId
,
unitName
,
0.5
,
false
,
0.0
,
1.0
,
0
)),
new
OperationOutput
(
p
,
sp
),
1.0
,
leadTimeDays
);
operations
.
add
(
procureOp
);
...
...
@@ -1029,7 +1046,7 @@ public class MacroPlannerDataConverter {
"OP_PROCURE_"
+
m
.
getId
(),
"采购-"
+
pickName
(
m
.
getName
(),
m
.
getId
()),
Collections
.
singletonList
(
new
UnitOperation
(
unitId
,
"通用供应商"
,
0.5
,
false
,
0.0
,
1.0
)),
new
UnitOperation
(
unitId
,
"通用供应商"
,
0.5
,
false
,
0.0
,
1.0
,
0
)),
new
OperationOutput
(
p
,
sp
),
1.0
,
0
);
operations
.
add
(
procureOp
);
...
...
@@ -1143,9 +1160,12 @@ public class MacroPlannerDataConverter {
// 收集所有 unitId (遍历每个 Operation 的每个 UnitOperation)
Map
<
String
,
String
>
unitIds
=
new
HashMap
<>()
;
Map
<
String
,
Integer
>
unitShipIds
=
new
HashMap
<>()
;
for
(
Operation
op
:
operations
)
{
for
(
UnitOperation
uo
:
op
.
getUnitOperations
())
{
unitIds
.
put
(
uo
.
getUnitId
(),
uo
.
getUnitName
());
unitShipIds
.
put
(
uo
.
getUnitId
(),
uo
.
getShopId
());
}
}
...
...
@@ -1187,7 +1207,9 @@ public class MacroPlannerDataConverter {
int
workDays
=
calculateWorkDays
(
periodStart
,
periodEnd
);
periodMaxCapacity
=
DEFAULT_DAILY_HOURS
*
Math
.
max
(
1
,
workDays
);
}
unitPeriods
.
add
(
new
UnitPeriod
(
unitId
,
unitName
,
p
,
0.0
,
periodMaxCapacity
,
false
));
Integer
shopid
=
unitShipIds
.
get
(
unitId
);
unitPeriods
.
add
(
new
UnitPeriod
(
unitId
,
unitName
,
p
,
0.0
,
periodMaxCapacity
,
false
,
shopid
));
}
}
log
.
info
(
"构建 Period: {} (dimension={}, horizonEnd={}), UnitPeriod: {}"
,
...
...
@@ -1288,7 +1310,7 @@ public class MacroPlannerDataConverter {
}
else
{
// 无时间信息, 放入最后一个周期
salesDemands
.
add
(
new
SalesDemand
(
p
,
sp
,
lastPeriod
,
qty
,
priority
,
ado
.
getId
(),
ado
.
getCode
(),
pickName
(
ado
.
getMmcode
(),
p
.
getId
()),
ado
.
getEndtime
()==
null
?
ado
.
getDeliverytime
().
toLocalDate
():
ado
.
getEndtime
().
toLocalDate
()));
ado
.
getId
(),
ado
.
getCode
(),
pickName
(
ado
.
getMmcode
(),
p
.
getId
()),
ado
.
getEndtime
()==
null
?
ado
.
getDeliverytime
().
toLocalDate
():
ado
.
getEndtime
().
toLocalDate
()
,
p
.
getCategoryId
()
));
continue
;
}
...
...
@@ -1310,7 +1332,7 @@ public class MacroPlannerDataConverter {
if
(
overlapPeriods
.
isEmpty
())
{
salesDemands
.
add
(
new
SalesDemand
(
p
,
sp
,
lastPeriod
,
qty
,
priority
,
ado
.
getId
(),
ado
.
getCode
(),
pickName
(
ado
.
getMmcode
(),
p
.
getId
()),
ado
.
getEndtime
()==
null
?
ado
.
getDeliverytime
().
toLocalDate
():
ado
.
getEndtime
().
toLocalDate
()));
ado
.
getId
(),
ado
.
getCode
(),
pickName
(
ado
.
getMmcode
(),
p
.
getId
()),
ado
.
getEndtime
()==
null
?
ado
.
getDeliverytime
().
toLocalDate
():
ado
.
getEndtime
().
toLocalDate
()
,
p
.
getCategoryId
()
));
}
else
{
// 按重叠天数比例拆分需求量: 每期四舍五入取整, 最后一期补差保证总和等于总数
int
totalQty
=
(
int
)
Math
.
round
(
qty
);
...
...
@@ -1327,7 +1349,7 @@ public class MacroPlannerDataConverter {
allocated
+=
periodQty
;
}
salesDemands
.
add
(
new
SalesDemand
(
p
,
sp
,
per
,
periodQty
,
priority
,
ado
.
getId
(),
ado
.
getCode
(),
pickName
(
ado
.
getMmcode
(),
p
.
getId
()),
ado
.
getEndtime
()==
null
?
ado
.
getDeliverytime
().
toLocalDate
():
ado
.
getEndtime
().
toLocalDate
()));
ado
.
getId
(),
ado
.
getCode
(),
pickName
(
ado
.
getMmcode
(),
p
.
getId
()),
ado
.
getEndtime
()==
null
?
ado
.
getDeliverytime
().
toLocalDate
():
ado
.
getEndtime
().
toLocalDate
()
,
p
.
getCategoryId
()
));
}
}
}
...
...
src/main/java/com/aps/macroplanner/data/MultiLevelBomTestDataBuilder.java
View file @
d1745f27
...
...
@@ -47,10 +47,14 @@ public class MultiLevelBomTestDataBuilder extends TestDataBuilder {
// === 产品: 成品 P1, P2 + 半成品 S1 + 原材料 R1, R2 ===
Product
prodP1
=
new
Product
(
"P1"
,
"成品P1"
);
prodP1
.
setCategoryId
(
1
l
);
// Product prodP2 = new Product("P2", "成品P2");
Product
prodS1
=
new
Product
(
"S1"
,
"半成品S1"
);
prodS1
.
setCategoryId
(
12
l
);
Product
prodR1
=
new
Product
(
"R1"
,
"原材料R1"
);
prodR1
.
setCategoryId
(
3
l
);
Product
prodR2
=
new
Product
(
"R2"
,
"原材料R2"
);
prodR2
.
setCategoryId
(
4
l
);
products
.
addAll
(
Arrays
.
asList
(
prodP1
,
prodS1
,
prodR1
,
prodR2
));
// === 库存点: 每种产品一个库存点 ===
...
...
@@ -117,7 +121,7 @@ public class MultiLevelBomTestDataBuilder extends TestDataBuilder {
// === 初始库存: 全部从 0 开始 ===
initialInventories
.
add
(
new
InitialInventory
(
prodP1
,
spP1
,
0.0
));
// initialInventories.add(new InitialInventory(prodP2, spP2, 0.0));
initialInventories
.
add
(
new
InitialInventory
(
prodS1
,
spSemi
,
0.0
));
initialInventories
.
add
(
new
InitialInventory
(
prodS1
,
spSemi
,
4
0.0
));
initialInventories
.
add
(
new
InitialInventory
(
prodR1
,
spR1
,
0.0
));
initialInventories
.
add
(
new
InitialInventory
(
prodR2
,
spR2
,
0.0
));
...
...
src/main/java/com/aps/macroplanner/data/Operation.java
View file @
d1745f27
...
...
@@ -69,7 +69,7 @@ public class Operation {
boolean
hasLotSize
,
double
lotSize
,
double
qtpfactor
,
int
leadTimeDays
)
{
this
(
id
,
name
,
Arrays
.
asList
(
new
UnitOperation
(
unitId
,
""
,
capacityCoeff
,
hasLotSize
,
lotSize
,
qtpfactor
)),
Arrays
.
asList
(
new
UnitOperation
(
unitId
,
""
,
capacityCoeff
,
hasLotSize
,
lotSize
,
qtpfactor
,
0
)),
output
,
relativeDuration
,
leadTimeDays
);
}
...
...
src/main/java/com/aps/macroplanner/data/OperationOutput.java
View file @
d1745f27
...
...
@@ -18,9 +18,16 @@ public class OperationOutput {
private
final
Product
product
;
// 产出产品
private
final
StockingPoint
stockingPoint
;
// 产出到哪个库存点
public
final
double
factor
;
public
OperationOutput
(
Product
product
,
StockingPoint
stockingPoint
)
{
this
(
product
,
stockingPoint
,
1
);
}
public
OperationOutput
(
Product
product
,
StockingPoint
stockingPoint
,
double
factor
)
{
this
.
product
=
product
;
this
.
stockingPoint
=
stockingPoint
;
this
.
factor
=
factor
;
}
public
Product
getProduct
()
{
return
product
;
}
...
...
@@ -28,9 +35,14 @@ public class OperationOutput {
/** 便捷方法: 产品 ID */
public
String
getProductId
()
{
return
product
.
getId
();
}
public
String
getProductCode
()
{
return
product
.
getCode
();
}
/** 便捷方法: 库存点 ID */
public
String
getSpId
()
{
return
stockingPoint
.
getId
();
}
public
String
getSpName
()
{
return
stockingPoint
.
getName
();
}
@Override
public
String
toString
()
{
return
product
.
getId
()
+
"@"
+
stockingPoint
.
getId
();
...
...
src/main/java/com/aps/macroplanner/data/Product.java
View file @
d1745f27
...
...
@@ -8,6 +8,8 @@ public class Product {
private
final
String
name
;
private
final
String
code
;
private
Long
categoryId
;
public
Product
(
String
id
,
String
name
)
{
this
(
id
,
name
,
id
);
}
...
...
@@ -22,6 +24,10 @@ public class Product {
public
String
getName
()
{
return
name
;
}
public
String
getCode
()
{
return
code
;
}
public
Long
getCategoryId
()
{
return
categoryId
;
}
public
void
setCategoryId
(
Long
val
)
{
categoryId
=
val
;
}
@Override
public
String
toString
()
{
return
name
+
"1("
+
id
+
")"
;
...
...
src/main/java/com/aps/macroplanner/data/SalesDemand.java
View file @
d1745f27
...
...
@@ -18,6 +18,8 @@ public class SalesDemand {
private
final
LocalDate
demandOrderDate
;
private
final
Long
categoryId
;
public
SalesDemand
(
Product
product
,
StockingPoint
stockingPoint
,
Period
period
,
double
quantity
,
double
priority
)
{
this
(
product
,
stockingPoint
,
period
,
quantity
,
priority
,
null
,
null
);
...
...
@@ -25,12 +27,13 @@ public class SalesDemand {
public
SalesDemand
(
Product
product
,
StockingPoint
stockingPoint
,
Period
period
,
double
quantity
,
double
priority
,
String
demandOrderId
,
LocalDate
demandOrderDate
)
{
this
(
product
,
stockingPoint
,
period
,
quantity
,
priority
,
demandOrderId
,
null
,
null
,
demandOrderDate
);
this
(
product
,
stockingPoint
,
period
,
quantity
,
priority
,
demandOrderId
,
null
,
null
,
demandOrderDate
,
0
l
);
}
public
SalesDemand
(
Product
product
,
StockingPoint
stockingPoint
,
Period
period
,
double
quantity
,
double
priority
,
String
demandOrderId
,
String
orderCode
,
String
productCode
,
LocalDate
demandOrderDate
)
{
String
orderCode
,
String
productCode
,
LocalDate
demandOrderDate
,
Long
categoryId
)
{
this
.
product
=
product
;
this
.
stockingPoint
=
stockingPoint
;
this
.
period
=
period
;
...
...
@@ -40,6 +43,7 @@ public class SalesDemand {
this
.
orderCode
=
orderCode
;
this
.
productCode
=
productCode
;
this
.
demandOrderDate
=
demandOrderDate
;
this
.
categoryId
=
categoryId
;
}
public
Product
getProduct
()
{
return
product
;
}
...
...
@@ -50,7 +54,7 @@ public class SalesDemand {
public
String
getDemandOrderId
()
{
return
demandOrderId
;
}
public
String
getOrderCode
()
{
return
orderCode
;
}
public
String
getProductCode
()
{
return
productCode
;
}
public
Long
getCategoryId
()
{
return
categoryId
;
}
public
LocalDate
getDemandOrderDate
()
{
return
demandOrderDate
;
}
public
String
getKey
()
{
...
...
src/main/java/com/aps/macroplanner/data/UnitOperation.java
View file @
d1745f27
...
...
@@ -17,14 +17,21 @@ public class UnitOperation {
private
final
double
lotSize
;
// 批次大小
private
final
double
qtpfactor
;
// QuantityToProcessFactor
private
final
Integer
shopId
;
public
UnitOperation
(
String
unitId
,
String
unitName
,
double
capacityCoeff
,
boolean
hasLotSize
,
double
lotSize
,
double
qtpfactor
)
{
this
(
unitId
,
unitName
,
capacityCoeff
,
hasLotSize
,
lotSize
,
qtpfactor
,
0
);
}
public
UnitOperation
(
String
unitId
,
String
unitName
,
double
capacityCoeff
,
boolean
hasLotSize
,
double
lotSize
,
double
qtpfactor
,
Integer
shopId
)
{
this
.
unitId
=
unitId
;
this
.
unitName
=
unitName
;
this
.
capacityCoeff
=
capacityCoeff
;
this
.
hasLotSize
=
hasLotSize
;
this
.
lotSize
=
lotSize
;
this
.
qtpfactor
=
qtpfactor
;
this
.
shopId
=
shopId
;
}
public
String
getUnitId
()
{
return
unitId
;
}
...
...
@@ -35,6 +42,8 @@ public class UnitOperation {
public
double
getLotSize
()
{
return
lotSize
;
}
public
double
getQtpfactor
()
{
return
qtpfactor
;
}
public
Integer
getShopId
()
{
return
shopId
;
}
@Override
public
String
toString
()
{
return
unitId
+
"(产能"
+
capacityCoeff
+
"h/件"
+
...
...
src/main/java/com/aps/macroplanner/data/UnitPeriod.java
View file @
d1745f27
...
...
@@ -15,9 +15,11 @@ public class UnitPeriod {
private
final
boolean
hasMinCapacity
;
// 是否有最小产能约束
private
final
boolean
unlimited
;
// 产能是否无上限 (如原材料供应商)
private
final
Integer
shopId
;
/** 完整构造器 */
public
UnitPeriod
(
String
unitId
,
String
unitName
,
Period
period
,
double
minCapacity
,
double
maxCapacity
,
boolean
hasMinCapacity
,
boolean
unlimited
)
{
boolean
hasMinCapacity
,
boolean
unlimited
,
Integer
shopId
)
{
this
.
unitId
=
unitId
;
this
.
unitName
=
unitName
;
this
.
period
=
period
;
...
...
@@ -25,16 +27,19 @@ public class UnitPeriod {
this
.
maxCapacity
=
unlimited
?
Double
.
MAX_VALUE
:
maxCapacity
;
this
.
hasMinCapacity
=
hasMinCapacity
;
this
.
unlimited
=
unlimited
;
this
.
shopId
=
shopId
;
}
/** 有限产能构造器 (向后兼容) */
public
UnitPeriod
(
String
unitId
,
String
unitName
,
Period
period
,
double
minCapacity
,
double
maxCapacity
,
boolean
hasMinCapacity
)
{
this
(
unitId
,
unitName
,
period
,
minCapacity
,
maxCapacity
,
hasMinCapacity
,
false
);
this
(
unitId
,
unitName
,
period
,
minCapacity
,
maxCapacity
,
hasMinCapacity
,
false
,
0
);
}
/** 有限产能构造器 (向后兼容) */
public
UnitPeriod
(
String
unitId
,
String
unitName
,
Period
period
,
double
minCapacity
,
double
maxCapacity
,
boolean
hasMinCapacity
,
Integer
shopId
)
{
this
(
unitId
,
unitName
,
period
,
minCapacity
,
maxCapacity
,
hasMinCapacity
,
false
,
shopId
);
}
/** 无限产能便捷构造器 */
public
static
UnitPeriod
unlimited
(
String
unitId
,
String
unitName
,
Period
period
)
{
return
new
UnitPeriod
(
unitId
,
unitName
,
period
,
0
,
0
,
false
,
true
);
return
new
UnitPeriod
(
unitId
,
unitName
,
period
,
0
,
0
,
false
,
true
,
0
);
}
public
String
getUnitId
()
{
return
unitId
;
}
...
...
@@ -47,6 +52,8 @@ public class UnitPeriod {
public
boolean
hasMinCapacity
()
{
return
hasMinCapacity
;
}
public
boolean
isUnlimited
()
{
return
unlimited
;
}
public
Integer
getShopId
()
{
return
shopId
;
}
public
String
getKey
()
{
return
unitId
+
"_"
+
period
.
getIndex
();
}
...
...
src/main/java/com/aps/macroplanner/output/ResultWriter.java
View file @
d1745f27
This diff is collapsed.
Click to expand it.
src/main/java/com/aps/macroplanner/output/dto/OptimizationResult.java
View file @
d1745f27
...
...
@@ -27,9 +27,17 @@ public class OptimizationResult {
// ==================== 业务结果 ====================
private
final
List
<
PeriodTaskResult
>
periodTasks
=
new
ArrayList
<>();
private
final
List
<
PeriodTaskResult
.
OutputInfo
>
periodTaskOutputs
=
new
ArrayList
<>();
private
final
List
<
SalesDemandResult
>
salesDemands
=
new
ArrayList
<>();
private
List
<
SalesDemandResult
>
saleDemandSummaries
=
new
ArrayList
<>();
private
final
List
<
PispipResult
>
pispips
=
new
ArrayList
<>();
private
final
List
<
PispipResult
.
PispipSummarieResult
>
pispipSummaries
=
new
ArrayList
<>();
// ==================== 产品生产网络 ====================
private
ProductNetworkResult
productNetwork
;
...
...
@@ -38,6 +46,8 @@ public class OptimizationResult {
private
List
<
UnitCapacityResult
>
unitCapacities
;
private
List
<
UnitCapacityResult
.
UnitPeriodDetail
>
unitPeriodDetails
;
// ==================== 需求满足汇总 ====================
private
List
<
DemandSummaryResult
>
demandSummary
;
...
...
@@ -59,15 +69,30 @@ public class OptimizationResult {
public
void
setVersion
(
String
v
)
{
this
.
version
=
v
;
}
public
List
<
PeriodTaskResult
>
getPeriodTasks
()
{
return
periodTasks
;
}
public
List
<
PeriodTaskResult
.
OutputInfo
>
getPeriodTaskOutputs
()
{
return
periodTaskOutputs
;
}
public
List
<
SalesDemandResult
>
getSalesDemands
()
{
return
salesDemands
;
}
public
List
<
SalesDemandResult
>
getSaleSummarieDemands
()
{
return
saleDemandSummaries
;
}
public
void
setSaleSummarieDemands
(
List
<
SalesDemandResult
>
v
)
{
saleDemandSummaries
=
v
;
}
public
List
<
PispipResult
>
getPispips
()
{
return
pispips
;
}
public
List
<
PispipResult
.
PispipSummarieResult
>
getPispipSummaries
()
{
return
pispipSummaries
;
}
public
ProductNetworkResult
getProductNetwork
()
{
return
productNetwork
;
}
public
void
setProductNetwork
(
ProductNetworkResult
v
)
{
this
.
productNetwork
=
v
;
}
public
List
<
UnitCapacityResult
>
getUnitCapacities
()
{
return
unitCapacities
;
}
public
List
<
UnitCapacityResult
.
UnitPeriodDetail
>
getUnitPeriodDetails
()
{
return
unitPeriodDetails
;
}
public
void
setUnitCapacities
(
List
<
UnitCapacityResult
>
v
)
{
this
.
unitCapacities
=
v
;
}
public
void
setUnitPeriodDetails
(
List
<
UnitCapacityResult
.
UnitPeriodDetail
>
v
)
{
this
.
unitPeriodDetails
=
v
;
}
public
List
<
DemandSummaryResult
>
getDemandSummary
()
{
return
demandSummary
;
}
public
void
setDemandSummary
(
List
<
DemandSummaryResult
>
v
)
{
this
.
demandSummary
=
v
;
}
...
...
src/main/java/com/aps/macroplanner/output/dto/PeriodTaskResult.java
View file @
d1745f27
...
...
@@ -17,6 +17,7 @@ public class PeriodTaskResult {
private
String
operationId
;
private
String
operationName
;
private
String
unitId
;
private
String
unitName
;
private
int
periodIndex
;
private
String
periodStartDate
;
...
...
@@ -40,11 +41,21 @@ public class PeriodTaskResult {
// ==================== 内嵌类 ====================
/** 产出信息 */
// public static class OutputInfo {
// public String productId;
// public String spId;
// public double factor;
// }
@Data
public
static
class
OutputInfo
{
public
String
productId
;
public
String
productCode
;
public
String
spId
;
public
String
spName
;
public
double
factor
;
private
String
dataKey
;
private
int
periodIndex
;
private
String
periodStartDate
;
/** PTQty — 生产量 */
private
double
productionQty
;
}
}
\ No newline at end of file
src/main/java/com/aps/macroplanner/output/dto/PispipResult.java
View file @
d1745f27
...
...
@@ -16,7 +16,7 @@ public class PispipResult {
private
String
productId
;
private
String
productCode
;
private
String
spId
;
private
Long
categoryId
;
private
String
spName
;
private
int
periodIndex
;
private
String
periodStartDate
;
...
...
@@ -83,6 +83,36 @@ public class PispipResult {
/** 每个工序的产出明细 */
private
final
List
<
ProductionDetail
>
productionDetails
=
new
ArrayList
<>();
public
static
class
PispipSummarieResult
{
private
String
key
;
private
String
productId
;
private
String
productCode
;
private
String
spId
;
private
String
spName
;
private
Long
categoryId
;
public
String
getKey
()
{
return
key
;
}
public
void
setKey
(
String
v
)
{
this
.
key
=
v
;
}
public
String
getProductId
()
{
return
productId
;
}
public
void
setProductId
(
String
v
)
{
this
.
productId
=
v
;
}
public
String
getProductCode
()
{
return
productCode
;
}
public
void
setProductCode
(
String
v
)
{
this
.
productCode
=
v
;
}
public
String
getSpId
()
{
return
spId
;
}
public
void
setSpId
(
String
v
)
{
this
.
spId
=
v
;
}
public
String
getSpName
()
{
return
spName
;
}
public
void
setSpName
(
String
v
)
{
this
.
spName
=
v
;
}
public
Long
getCategoryId
()
{
return
categoryId
;
}
public
void
setCategoryId
(
Long
v
)
{
this
.
categoryId
=
v
;
}
}
// ==================== 内嵌类 ====================
/** 工序产出明细 */
...
...
src/main/java/com/aps/macroplanner/output/dto/SalesDemandResult.java
View file @
d1745f27
package
com
.
aps
.
macroplanner
.
output
.
dto
;
import
lombok.Data
;
import
java.util.ArrayList
;
import
java.util.List
;
...
...
@@ -8,6 +10,7 @@ import java.util.List;
*
* <p>每个销售需求在每个周期的满足量、缺口、优先级等。</p>
*/
@Data
public
class
SalesDemandResult
{
private
String
salesDemandId
;
...
...
@@ -33,6 +36,8 @@ public class SalesDemandResult {
/** 优先级 */
private
double
priority
;
private
Long
categoryId
;
/** 未完成原因分析 (仅当 unmetQty > 0 时有内容) */
private
final
List
<
String
>
unmetReasons
=
new
ArrayList
<>();
/** 风险分析 (即使满足也可能存在的供应链风险) */
...
...
src/main/java/com/aps/macroplanner/output/dto/SupplyChainNode.java
View file @
d1745f27
...
...
@@ -19,6 +19,9 @@ public class SupplyChainNode {
/** 产品 ID */
private
String
productId
;
public
String
productCode
;
/** 库存点 ID */
private
String
spId
;
...
...
@@ -148,6 +151,10 @@ public class SupplyChainNode {
public
String
getProductId
()
{
return
productId
;
}
public
void
setProductId
(
String
v
)
{
this
.
productId
=
v
;
}
public
String
getProductCode
()
{
return
productCode
;
}
public
void
setProductCode
(
String
v
)
{
this
.
productCode
=
v
;
}
public
String
getSpId
()
{
return
spId
;
}
public
void
setSpId
(
String
v
)
{
this
.
spId
=
v
;
}
...
...
src/main/java/com/aps/macroplanner/output/dto/UnitCapacityResult.java
View file @
d1745f27
package
com
.
aps
.
macroplanner
.
output
.
dto
;
import
lombok.Data
;
import
java.util.ArrayList
;
import
java.util.LinkedHashMap
;
import
java.util.List
;
...
...
@@ -20,6 +22,7 @@ import java.util.Map;
* <tr><td>periodTasks</td><td>该设备的生产任务明细 (PeriodTaskResult[])</td></tr>
* </table>
*/
@Data
public
class
UnitCapacityResult
{
/** 设备ID */
...
...
@@ -27,6 +30,8 @@ public class UnitCapacityResult {
private
String
unitName
;
private
Integer
shopId
;
/** 使用该设备的工序ID列表 */
private
List
<
String
>
operationIds
;
/** 全部周期最大可用产能合计 */
...
...
@@ -44,13 +49,19 @@ public class UnitCapacityResult {
private
double
overallUtilization
;
/** 各周期明细 */
private
final
List
<
UnitPeriodDetail
>
periodDetails
=
new
ArrayList
<>();
//
private final List<UnitPeriodDetail> periodDetails = new ArrayList<>();
// ==================== 内嵌类 ====================
/** 单周期产能明细 */
public
static
class
UnitPeriodDetail
{
/** 设备ID */
public
String
unitId
;
public
String
unitName
;
/** 周期索引 */
public
int
periodIndex
;
/** 周期起始日期 */
...
...
@@ -69,7 +80,7 @@ public class UnitCapacityResult {
public
double
production
;
/** 该周期内在该设备上执行的工序明细 */
public
final
List
<
UnitTaskInfo
>
tasks
=
new
ArrayList
<>();
//
public final List<UnitTaskInfo> tasks = new ArrayList<>();
}
/** 设备上的工序级生产明细 */
public
static
class
UnitTaskInfo
{
...
...
@@ -107,7 +118,7 @@ public class UnitCapacityResult {
public
double
getTotalProduction
()
{
return
totalProduction
;
}
public
void
setTotalProduction
(
double
v
)
{
this
.
totalProduction
=
v
;
}
public
List
<
UnitPeriodDetail
>
getPeriodDetails
()
{
return
periodDetails
;
}
//
public List<UnitPeriodDetail> getPeriodDetails() { return periodDetails; }
public
double
getTotalOverloaded
()
{
return
totalOverloaded
;
}
public
void
setTotalOverloaded
(
double
v
)
{
this
.
totalOverloaded
=
v
;
}
...
...
src/main/java/com/aps/service/MacroPlannerProductNetworkService.java
View file @
d1745f27
This diff is collapsed.
Click to expand it.
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