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
1dd2520c
Commit
1dd2520c
authored
Nov 03, 2025
by
DESKTOP-VKRD9QF\Administration
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
设备日历和运算
parent
fee62722
Hide whitespace changes
Inline
Side-by-side
Showing
118 changed files
with
13398 additions
and
152 deletions
+13398
-152
pom.xml
pom.xml
+7
-12
schedule_log.txt
schedule_log.txt
+7780
-0
ApsApplication.java
src/main/java/com/aps/ApsApplication.java
+5
-5
DatabaseTester.java
src/main/java/com/aps/DatabaseTester.java
+1
-1
FileHelper.java
src/main/java/com/aps/common/util/FileHelper.java
+20
-0
JsonFileReader.java
src/main/java/com/aps/common/util/JsonFileReader.java
+36
-0
R.java
src/main/java/com/aps/common/util/R.java
+118
-0
SwaggerConfig.java
src/main/java/com/aps/config/SwaggerConfig.java
+27
-0
DepartmentController.java
src/main/java/com/aps/controller/DepartmentController.java
+2
-2
MaterialInfoController.java
src/main/java/com/aps/controller/MaterialInfoController.java
+43
-0
MesShiftWorkSchedController.java
.../java/com/aps/controller/MesShiftWorkSchedController.java
+18
-0
PlanResourceController.java
src/main/java/com/aps/controller/PlanResourceController.java
+18
-0
RoutingHeaderController.java
...main/java/com/aps/controller/RoutingHeaderController.java
+38
-0
ScheduleController.java
src/main/java/com/aps/controller/ScheduleController.java
+120
-0
ScheduleResultController.java
...ain/java/com/aps/controller/ScheduleResultController.java
+152
-0
ScheduleResultController1.java
...in/java/com/aps/controller/ScheduleResultController1.java
+166
-0
CodeGeneratorController.java
...ller/codeGeneratorController/CodeGeneratorController.java
+13
-13
PlanSchedulerController.java
...java/com/aps/controller/plan/PlanSchedulerController.java
+46
-0
Department.java
src/main/java/com/aps/entity/Department.java
+1
-1
Equipinfo.java
src/main/java/com/aps/entity/Equipinfo.java
+139
-0
EquipmentScheduleState.java
src/main/java/com/aps/entity/EquipmentScheduleState.java
+27
-0
PlanResourceTaskGanttVO.java
...in/java/com/aps/entity/Gantt/PlanResourceTaskGanttVO.java
+38
-0
PlanResourceTaskGanttVO1.java
...n/java/com/aps/entity/Gantt/PlanResourceTaskGanttVO1.java
+35
-0
SimpleEquipinfo.java
src/main/java/com/aps/entity/Gantt/SimpleEquipinfo.java
+26
-0
SimpleEquipinfo1.java
src/main/java/com/aps/entity/Gantt/SimpleEquipinfo1.java
+27
-0
MaterialInfo.java
src/main/java/com/aps/entity/MaterialInfo.java
+9
-9
MesShiftWorkSched.java
src/main/java/com/aps/entity/MesShiftWorkSched.java
+107
-0
Mpsplannedorder.java
src/main/java/com/aps/entity/Mpsplannedorder.java
+23
-0
PlanResource.java
src/main/java/com/aps/entity/PlanResource.java
+41
-0
RoutingDetail.java
src/main/java/com/aps/entity/RoutingDetail.java
+77
-0
RoutingDetailEquip.java
src/main/java/com/aps/entity/RoutingDetailEquip.java
+132
-0
RoutingHeader.java
src/main/java/com/aps/entity/RoutingHeader.java
+147
-0
RoutingStep.java
src/main/java/com/aps/entity/RoutingStep.java
+62
-0
GenVO.java
src/main/java/com/aps/entity/Schedule/GenVO.java
+21
-0
HolidayDTO.java
src/main/java/com/aps/entity/Schedule/HolidayDTO.java
+16
-0
MachineVO.java
src/main/java/com/aps/entity/Schedule/MachineVO.java
+22
-0
PlanResourceTaskGanttVO.java
...java/com/aps/entity/Schedule/PlanResourceTaskGanttVO.java
+38
-0
ScheduleRequest.java
src/main/java/com/aps/entity/Schedule/ScheduleRequest.java
+23
-0
ScheduleResponse.java
src/main/java/com/aps/entity/Schedule/ScheduleResponse.java
+26
-0
ScheduleResult.java
src/main/java/com/aps/entity/Schedule/ScheduleResult.java
+18
-0
ScheduleResultList.java
...main/java/com/aps/entity/Schedule/ScheduleResultList.java
+18
-0
ScheduledTask.java
src/main/java/com/aps/entity/ScheduledTask.java
+23
-0
Gene.java
src/main/java/com/aps/entity/basic/Gene.java
+21
-0
GeneDetail.java
src/main/java/com/aps/entity/basic/GeneDetail.java
+10
-0
Holiday.java
src/main/java/com/aps/entity/basic/Holiday.java
+31
-0
Machine.java
src/main/java/com/aps/entity/basic/Machine.java
+64
-0
MachineOption.java
src/main/java/com/aps/entity/basic/MachineOption.java
+13
-0
MachineTimeline.java
src/main/java/com/aps/entity/basic/MachineTimeline.java
+81
-0
MaintenanceWindow.java
src/main/java/com/aps/entity/basic/MaintenanceWindow.java
+57
-0
Operation.java
src/main/java/com/aps/entity/basic/Operation.java
+28
-0
Order.java
src/main/java/com/aps/entity/basic/Order.java
+23
-0
Product.java
src/main/java/com/aps/entity/basic/Product.java
+17
-0
ScheduleChromosome.java
src/main/java/com/aps/entity/basic/ScheduleChromosome.java
+130
-0
SegmentType.java
src/main/java/com/aps/entity/basic/SegmentType.java
+7
-0
Shift.java
src/main/java/com/aps/entity/basic/Shift.java
+74
-0
TimeSegment.java
src/main/java/com/aps/entity/basic/TimeSegment.java
+46
-0
DatabaseConfig.java
...va/com/aps/entity/codeGeneratorEntity/DatabaseConfig.java
+1
-1
GenerateRequest.java
...a/com/aps/entity/codeGeneratorEntity/GenerateRequest.java
+2
-2
CodeGenerator.java
src/main/java/com/aps/generator/CodeGenerator.java
+3
-3
CodeGenerator1.java
src/main/java/com/aps/generator/CodeGenerator1.java
+5
-5
DepartmentMapper.java
src/main/java/com/aps/mapper/DepartmentMapper.java
+2
-2
EquipinfoMapper.java
src/main/java/com/aps/mapper/EquipinfoMapper.java
+16
-0
MaterialInfoMapper.java
src/main/java/com/aps/mapper/MaterialInfoMapper.java
+2
-2
MesShiftWorkSchedMapper.java
src/main/java/com/aps/mapper/MesShiftWorkSchedMapper.java
+16
-0
MpsplannedorderMapper.java
src/main/java/com/aps/mapper/MpsplannedorderMapper.java
+16
-0
PlanResourceMapper.java
src/main/java/com/aps/mapper/PlanResourceMapper.java
+16
-0
RoutingDetailEquipMapper.java
src/main/java/com/aps/mapper/RoutingDetailEquipMapper.java
+16
-0
RoutingDetailMapper.java
src/main/java/com/aps/mapper/RoutingDetailMapper.java
+16
-0
RoutingHeaderMapper.java
src/main/java/com/aps/mapper/RoutingHeaderMapper.java
+16
-0
RoutingStepMapper.java
src/main/java/com/aps/mapper/RoutingStepMapper.java
+16
-0
DepartmentService.java
src/main/java/com/aps/service/DepartmentService.java
+3
-3
EquipinfoService.java
src/main/java/com/aps/service/EquipinfoService.java
+16
-0
MaterialInfoService.java
src/main/java/com/aps/service/MaterialInfoService.java
+3
-3
MesShiftWorkSchedService.java
src/main/java/com/aps/service/MesShiftWorkSchedService.java
+16
-0
MpsplannedorderService.java
src/main/java/com/aps/service/MpsplannedorderService.java
+16
-0
PlanResourceService.java
src/main/java/com/aps/service/PlanResourceService.java
+16
-0
RoutingDetailEquipService.java
src/main/java/com/aps/service/RoutingDetailEquipService.java
+16
-0
RoutingDetailService.java
src/main/java/com/aps/service/RoutingDetailService.java
+16
-0
RoutingHeaderService.java
src/main/java/com/aps/service/RoutingHeaderService.java
+16
-0
RoutingStepService.java
src/main/java/com/aps/service/RoutingStepService.java
+16
-0
ScheduleService.java
src/main/java/com/aps/service/ScheduleService.java
+24
-0
CodeGeneratorService.java
...ps/service/codeGeneratorService/CodeGeneratorService.java
+7
-2
DatabaseConfigService.java
...s/service/codeGeneratorService/DatabaseConfigService.java
+2
-2
DatabaseService.java
...com/aps/service/codeGeneratorService/DatabaseService.java
+87
-0
DepartmentServiceImpl.java
...main/java/com/aps/service/impl/DepartmentServiceImpl.java
+5
-5
EquipinfoServiceImpl.java
src/main/java/com/aps/service/impl/EquipinfoServiceImpl.java
+20
-0
MaterialInfoServiceImpl.java
...in/java/com/aps/service/impl/MaterialInfoServiceImpl.java
+5
-5
MesShiftWorkSchedServiceImpl.java
...va/com/aps/service/impl/MesShiftWorkSchedServiceImpl.java
+20
-0
MpsplannedorderServiceImpl.java
...java/com/aps/service/impl/MpsplannedorderServiceImpl.java
+20
-0
PlanResourceServiceImpl.java
...in/java/com/aps/service/impl/PlanResourceServiceImpl.java
+20
-0
RoutingDetailEquipServiceImpl.java
...a/com/aps/service/impl/RoutingDetailEquipServiceImpl.java
+20
-0
RoutingDetailServiceImpl.java
...n/java/com/aps/service/impl/RoutingDetailServiceImpl.java
+20
-0
RoutingHeaderServiceImpl.java
...n/java/com/aps/service/impl/RoutingHeaderServiceImpl.java
+20
-0
RoutingStepServiceImpl.java
...ain/java/com/aps/service/impl/RoutingStepServiceImpl.java
+20
-0
ScheduleServiceImpl.java
src/main/java/com/aps/service/impl/ScheduleServiceImpl.java
+243
-0
AlgorithmScheduler6.java
src/main/java/com/aps/service/plan/AlgorithmScheduler6.java
+1003
-0
MachineSchedulerService.java
...in/java/com/aps/service/plan/MachineSchedulerService.java
+382
-0
PlanSchedulerService.java
src/main/java/com/aps/service/plan/PlanSchedulerService.java
+123
-0
SwaggerConfig.java
src/main/java/com/example/config/SwaggerConfig.java
+0
-34
TestController.java
src/main/java/com/example/controller/TestController.java
+0
-25
application.yml
src/main/resources/application.yml
+14
-7
machines.json
src/main/resources/machines.json
+85
-0
DepartmentMapper.xml
src/main/resources/mapper/DepartmentMapper.xml
+3
-3
EquipinfoMapper.xml
src/main/resources/mapper/EquipinfoMapper.xml
+71
-0
MaterialInfoMapper.xml
src/main/resources/mapper/MaterialInfoMapper.xml
+3
-3
MesShiftWorkSchedMapper.xml
src/main/resources/mapper/MesShiftWorkSchedMapper.xml
+35
-0
MpsplannedorderMapper.xml
src/main/resources/mapper/MpsplannedorderMapper.xml
+28
-0
PlanResourceMapper.xml
src/main/resources/mapper/PlanResourceMapper.xml
+42
-0
RoutingDetailEquipMapper.xml
src/main/resources/mapper/RoutingDetailEquipMapper.xml
+38
-0
RoutingDetailMapper.xml
src/main/resources/mapper/RoutingDetailMapper.xml
+78
-0
RoutingHeaderMapper.xml
src/main/resources/mapper/RoutingHeaderMapper.xml
+74
-0
RoutingStepMapper.xml
src/main/resources/mapper/RoutingStepMapper.xml
+32
-0
orders.json
src/main/resources/orders.json
+29
-0
products.json
src/main/resources/products.json
+120
-0
code-generator.html
src/main/resources/static/code-generator.html
+1
-1
entity.java.vm
src/main/resources/templates/entity.java.vm
+15
-0
Demo1ApplicationTests.java
src/test/java/com/aps/demo/Demo1ApplicationTests.java
+1
-1
MachineSchedulerTest.java
src/test/java/com/aps/demo/MachineSchedulerTest.java
+103
-0
No files found.
pom.xml
View file @
1dd2520c
...
@@ -8,7 +8,7 @@
...
@@ -8,7 +8,7 @@
<version>
2.7.18
</version>
<version>
2.7.18
</version>
<relativePath/>
<!-- lookup parent from repository -->
<relativePath/>
<!-- lookup parent from repository -->
</parent>
</parent>
<groupId>
com.
example
</groupId>
<groupId>
com.
aps
</groupId>
<artifactId>
java-test
</artifactId>
<artifactId>
java-test
</artifactId>
<version>
0.0.1-SNAPSHOT
</version>
<version>
0.0.1-SNAPSHOT
</version>
<name>
demo2
</name>
<name>
demo2
</name>
...
@@ -73,16 +73,11 @@
...
@@ -73,16 +73,11 @@
<version>
10.2.1.jre8
</version>
<version>
10.2.1.jre8
</version>
</dependency>
</dependency>
<!-- S
wagger
-->
<!-- S
pringDoc OpenAPI
-->
<dependency>
<dependency>
<groupId>
io.springfox
</groupId>
<groupId>
org.springdoc
</groupId>
<artifactId>
springfox-swagger2
</artifactId>
<artifactId>
springdoc-openapi-ui
</artifactId>
<version>
2.9.2
</version>
<version>
1.7.0
</version>
</dependency>
<dependency>
<groupId>
io.springfox
</groupId>
<artifactId>
springfox-swagger-ui
</artifactId>
<version>
2.9.2
</version>
</dependency>
</dependency>
<dependency>
<dependency>
...
@@ -120,8 +115,8 @@
...
@@ -120,8 +115,8 @@
<artifactId>
maven-compiler-plugin
</artifactId>
<artifactId>
maven-compiler-plugin
</artifactId>
<version>
3.11.0
</version>
<version>
3.11.0
</version>
<configuration>
<configuration>
<source>
9
</source>
<source>
8
</source>
<target>
9
</target>
<target>
8
</target>
<encoding>
${project.build.sourceEncoding}
</encoding>
<encoding>
${project.build.sourceEncoding}
</encoding>
<annotationProcessorPaths>
<annotationProcessorPaths>
<path>
<path>
...
...
schedule_log.txt
0 → 100644
View file @
1dd2520c
This source diff could not be displayed because it is too large. You can
view the blob
instead.
src/main/java/com/
example/Demo1
Application.java
→
src/main/java/com/
aps/Aps
Application.java
View file @
1dd2520c
package
com
.
example
;
package
com
.
aps
;
import
org.mybatis.spring.annotation.MapperScan
;
import
org.mybatis.spring.annotation.MapperScan
;
...
@@ -7,11 +7,11 @@ import org.springframework.boot.autoconfigure.SpringBootApplication;
...
@@ -7,11 +7,11 @@ import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
@SpringBootApplication
@MapperScan
(
"com.
example
.mapper"
)
// 扫描Mapper接口
@MapperScan
(
"com.
aps
.mapper"
)
// 扫描Mapper接口
public
class
Demo1
Application
{
public
class
Aps
Application
{
public
static
void
main
(
String
[]
args
)
{
public
static
void
main
(
String
[]
args
)
{
SpringApplication
.
run
(
Demo1
Application
.
class
,
args
);
SpringApplication
.
run
(
Aps
Application
.
class
,
args
);
}
}
}
}
\ No newline at end of file
src/main/java/com/
example
/DatabaseTester.java
→
src/main/java/com/
aps
/DatabaseTester.java
View file @
1dd2520c
package
com
.
example
;
package
com
.
aps
;
import
org.springframework.boot.CommandLineRunner
;
import
org.springframework.boot.CommandLineRunner
;
import
org.springframework.stereotype.Component
;
import
org.springframework.stereotype.Component
;
...
...
src/main/java/com/aps/common/util/FileHelper.java
0 → 100644
View file @
1dd2520c
package
com
.
aps
.
common
.
util
;
import
java.io.FileWriter
;
import
java.io.IOException
;
import
java.io.PrintWriter
;
import
java.time.LocalDateTime
;
import
java.time.format.DateTimeFormatter
;
public
class
FileHelper
{
private
static
final
String
LOG_FILE_PATH
=
"schedule_log.txt"
;
public
static
void
writeLogFile
(
String
message
)
{
try
(
PrintWriter
writer
=
new
PrintWriter
(
new
FileWriter
(
LOG_FILE_PATH
,
true
)))
{
String
timestamp
=
LocalDateTime
.
now
().
format
(
DateTimeFormatter
.
ofPattern
(
"yyyy-MM-dd HH:mm:ss"
));
writer
.
println
(
"["
+
timestamp
+
"] "
+
message
);
}
catch
(
IOException
e
)
{
System
.
err
.
println
(
"Failed to write log: "
+
e
.
getMessage
());
}
}
}
\ No newline at end of file
src/main/java/com/aps/common/util/JsonFileReader.java
0 → 100644
View file @
1dd2520c
package
com
.
aps
.
common
.
util
;
import
com.fasterxml.jackson.databind.ObjectMapper
;
import
com.fasterxml.jackson.databind.SerializationFeature
;
import
com.fasterxml.jackson.datatype.jsr310.JavaTimeModule
;
import
java.io.IOException
;
import
java.io.InputStream
;
import
java.nio.charset.StandardCharsets
;
import
java.util.List
;
import
java.util.Scanner
;
public
class
JsonFileReader
{
public
static
<
T
>
List
<
T
>
readListFromResources
(
String
fileName
,
Class
<
T
>
clazz
)
throws
IOException
{
// 1. 从classpath读取文件
try
(
InputStream
inputStream
=
JsonFileReader
.
class
.
getClassLoader
().
getResourceAsStream
(
fileName
))
{
if
(
inputStream
==
null
)
{
throw
new
IOException
(
"File not found in resources: "
+
fileName
);
}
// 使用Scanner替代readAllBytes以兼容Java 8
Scanner
scanner
=
new
Scanner
(
inputStream
,
StandardCharsets
.
UTF_8
.
name
()).
useDelimiter
(
"\\A"
);
String
jsonContent
=
scanner
.
hasNext
()
?
scanner
.
next
()
:
""
;
// 2. 配置ObjectMapper支持Java 8时间API
ObjectMapper
objectMapper
=
new
ObjectMapper
();
objectMapper
.
registerModule
(
new
JavaTimeModule
());
objectMapper
.
disable
(
SerializationFeature
.
WRITE_DATES_AS_TIMESTAMPS
);
// 3. 反序列化JSON到对象列表
return
objectMapper
.
readValue
(
jsonContent
,
objectMapper
.
getTypeFactory
().
constructCollectionType
(
List
.
class
,
clazz
));
}
}
}
\ No newline at end of file
src/main/java/com/aps/common/util/R.java
0 → 100644
View file @
1dd2520c
package
com
.
aps
.
common
.
util
;
import
com.fasterxml.jackson.annotation.JsonFormat
;
import
io.swagger.v3.oas.annotations.media.Schema
;
import
lombok.*
;
import
lombok.experimental.Accessors
;
import
java.io.Serializable
;
import
java.time.LocalDateTime
;
@Builder
@ToString
@Accessors
(
chain
=
true
)
@AllArgsConstructor
public
class
R
<
T
>
implements
Serializable
{
private
static
final
long
serialVersionUID
=
1L
;
@Schema
(
description
=
"code码,通常为0为正常,500为异常,其它code码见异常对照表,为规范code码报错异常操作。所有异常报错码以数据表映射相关"
)
@Getter
@Setter
private
int
code
=
0
;
@Getter
@Setter
@Schema
(
description
=
"返回code码为0 时, 默认为success,其它的情况为具体的消息"
)
private
String
msg
=
"success"
;
@Getter
@Setter
@Schema
(
description
=
"业务返回具体的数据"
,
example
=
"示例值有很多,不一一列举"
)
private
T
data
;
@Getter
@Setter
@Schema
(
description
=
"接口返回时间,默认带有毫秒数值,用于数据排查问题"
)
@JsonFormat
(
pattern
=
"yyyy-MM-dd HH:mm:ss SSS"
)
private
LocalDateTime
timestamp
=
LocalDateTime
.
now
();
public
static
<
T
>
R
<
T
>
ok
()
{
return
restResult
(
null
,
0
,
"success"
);
}
public
static
<
T
>
R
<
T
>
ok
(
T
data
)
{
return
restResult
(
data
,
0
,
"success"
);
}
public
static
<
T
>
R
<
T
>
ok
(
T
data
,
String
msg
)
{
return
restResult
(
data
,
0
,
msg
);
}
public
static
<
T
>
R
<
T
>
failed
()
{
return
restResult
(
null
,
1
,
"error"
);
}
public
static
<
T
>
R
<
T
>
failed
(
String
msg
)
{
return
restResult
(
null
,
1
,
msg
);
}
public
static
<
T
>
R
<
T
>
failed
(
T
data
)
{
return
restResult
(
data
,
1
,
"error"
);
}
public
static
<
T
>
R
<
T
>
failed
(
T
data
,
String
msg
)
{
return
restResult
(
data
,
1
,
msg
);
}
public
static
<
T
>
R
<
T
>
failed
(
int
code
,
String
msg
)
{
return
restResult
(
null
,
code
,
msg
);
}
public
static
<
T
>
R
<
T
>
failed
(
T
data
,
int
code
)
{
return
restResult
(
data
,
code
,
null
);
}
public
static
<
T
>
R
<
T
>
failed
(
T
data
,
int
code
,
String
msg
)
{
return
restResult
(
data
,
code
,
msg
);
}
public
R
()
{
super
();
}
public
R
(
T
data
)
{
super
();
this
.
data
=
data
;
}
public
R
(
T
data
,
String
msg
)
{
super
();
this
.
data
=
data
;
this
.
msg
=
msg
;
}
public
R
(
Throwable
e
)
{
super
();
this
.
msg
=
e
.
getMessage
();
this
.
code
=
1
;
}
private
static
<
T
>
R
<
T
>
restResult
(
T
data
,
int
code
,
String
msg
)
{
R
<
T
>
apiResult
=
new
R
<>();
apiResult
.
setCode
(
code
);
apiResult
.
setData
(
data
);
apiResult
.
setMsg
(
msg
);
return
apiResult
;
}
/**
* 判断是否成功
*
* @return
*/
public
boolean
is
()
{
return
this
.
code
==
0
;
}
}
\ No newline at end of file
src/main/java/com/aps/config/SwaggerConfig.java
0 → 100644
View file @
1dd2520c
package
com
.
aps
.
config
;
import
io.swagger.v3.oas.models.OpenAPI
;
import
io.swagger.v3.oas.models.info.Info
;
import
io.swagger.v3.oas.models.info.Contact
;
import
io.swagger.v3.oas.models.info.License
;
import
org.springframework.context.annotation.Bean
;
import
org.springframework.context.annotation.Configuration
;
@Configuration
public
class
SwaggerConfig
{
@Bean
public
OpenAPI
customOpenAPI
()
{
return
new
OpenAPI
()
.
info
(
new
Info
()
.
title
(
"Demo2 API 文档"
)
.
version
(
"1.0.0"
)
.
description
(
"多数据库项目接口文档"
)
.
contact
(
new
Contact
()
.
name
(
"APS Team"
)
.
email
(
"contact@example.com"
))
.
license
(
new
License
()
.
name
(
"Apache 2.0"
)
.
url
(
"http://www.apache.org/licenses/LICENSE-2.0.html"
)));
}
}
\ No newline at end of file
src/main/java/com/
example
/controller/DepartmentController.java
→
src/main/java/com/
aps
/controller/DepartmentController.java
View file @
1dd2520c
package
com
.
example
.
controller
;
package
com
.
aps
.
controller
;
import
org.springframework.web.bind.annotation.RequestMapping
;
import
org.springframework.web.bind.annotation.RequestMapping
;
import
org.springframework.web.bind.annotation.RestController
;
import
org.springframework.web.bind.annotation.RestController
;
...
@@ -15,4 +15,4 @@ import org.springframework.web.bind.annotation.RestController;
...
@@ -15,4 +15,4 @@ import org.springframework.web.bind.annotation.RestController;
@RequestMapping
(
"/department"
)
@RequestMapping
(
"/department"
)
public
class
DepartmentController
{
public
class
DepartmentController
{
}
}
\ No newline at end of file
src/main/java/com/
example
/controller/MaterialInfoController.java
→
src/main/java/com/
aps
/controller/MaterialInfoController.java
View file @
1dd2520c
package
com
.
example
.
controller
;
package
com
.
aps
.
controller
;
import
com.
example
.entity.MaterialInfo
;
import
com.
aps
.entity.MaterialInfo
;
import
com.
example
.service.MaterialInfoService
;
import
com.
aps
.service.MaterialInfoService
;
import
io.swagger.
annotations.Api
;
import
io.swagger.
v3.oas.annotations.tags.Tag
;
import
io.swagger.
annotations.Api
Operation
;
import
io.swagger.
v3.oas.annotations.
Operation
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.web.bind.annotation.RequestMapping
;
import
org.springframework.web.bind.annotation.*
;
import
org.springframework.web.bind.annotation.RestController
;
import
java.util.List
;
import
java.util.List
;
...
@@ -20,19 +19,25 @@ import java.util.List;
...
@@ -20,19 +19,25 @@ import java.util.List;
*/
*/
@RestController
@RestController
@RequestMapping
(
"/materialInfo"
)
@RequestMapping
(
"/materialInfo"
)
@
Api
(
tags
=
"测试
接口"
)
@
Tag
(
name
=
"test"
,
description
=
"物料信息相关
接口"
)
public
class
MaterialInfoController
{
public
class
MaterialInfoController
{
@Autowired
@Autowired
MaterialInfoService
materialInfoService
;
MaterialInfoService
materialInfoService
;
@ApiOperation
(
value
=
"获取物料列表"
,
notes
=
"返回所有用物料据"
,
httpMethod
=
"GET"
)
@RequestMapping
(
"/test"
)
@Operation
(
summary
=
"获取单个物料信息"
,
description
=
"返回第一个物料数据"
)
@GetMapping
(
"/test"
)
public
MaterialInfo
test
(){
public
MaterialInfo
test
(){
List
<
MaterialInfo
>
list
=
materialInfoService
.
list
();
List
<
MaterialInfo
>
list
=
materialInfoService
.
list
();
// 检查列表是否为空,避免IndexOutOfBoundsException
if
(
list
==
null
||
list
.
isEmpty
())
{
return
null
;
// 自定义异常
}
return
list
.
get
(
0
);
return
list
.
get
(
0
);
}
}
}
}
\ No newline at end of file
src/main/java/com/aps/controller/MesShiftWorkSchedController.java
0 → 100644
View file @
1dd2520c
package
com
.
aps
.
controller
;
import
org.springframework.web.bind.annotation.RequestMapping
;
import
org.springframework.web.bind.annotation.RestController
;
/**
* <p>
* 班次表 前端控制器
* </p>
*
* @author MyBatis-Plus
* @since 2025-10-10
*/
@RestController
@RequestMapping
(
"/mesShiftWorkSched"
)
public
class
MesShiftWorkSchedController
{
}
\ No newline at end of file
src/main/java/com/aps/controller/PlanResourceController.java
0 → 100644
View file @
1dd2520c
package
com
.
aps
.
controller
;
import
org.springframework.web.bind.annotation.RequestMapping
;
import
org.springframework.web.bind.annotation.RestController
;
/**
* <p>
* 前端控制器
* </p>
*
* @author MyBatis-Plus
* @since 2025-10-10
*/
@RestController
@RequestMapping
(
"/planResource"
)
public
class
PlanResourceController
{
}
\ No newline at end of file
src/main/java/com/aps/controller/RoutingHeaderController.java
0 → 100644
View file @
1dd2520c
package
com
.
aps
.
controller
;
import
com.aps.entity.MaterialInfo
;
import
com.aps.entity.RoutingHeader
;
import
com.aps.service.MaterialInfoService
;
import
com.aps.service.RoutingHeaderService
;
import
io.swagger.v3.oas.annotations.tags.Tag
;
import
io.swagger.v3.oas.annotations.Operation
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.web.bind.annotation.GetMapping
;
import
org.springframework.web.bind.annotation.RequestMapping
;
import
org.springframework.web.bind.annotation.RestController
;
import
java.util.List
;
/**
* <p>
* 前端控制器
* </p>
*
* @author MyBatis-Plus
* @since 2025-10-09
*/
@RestController
@RequestMapping
(
"/routingHeader"
)
@Tag
(
name
=
"测试接口"
,
description
=
"工艺相关接口"
)
public
class
RoutingHeaderController
{
@Autowired
RoutingHeaderService
routingHeaderService
;
@Operation
(
summary
=
"获取工艺列表"
,
description
=
"返回所有工艺数据"
)
@GetMapping
(
"/test"
)
public
RoutingHeader
test
(){
return
routingHeaderService
.
list
().
get
(
0
);
}
}
\ No newline at end of file
src/main/java/com/aps/controller/ScheduleController.java
0 → 100644
View file @
1dd2520c
package
com
.
aps
.
controller
;
import
com.aps.entity.*
;
import
com.aps.mapper.EquipinfoMapper
;
import
com.aps.mapper.MpsplannedorderMapper
;
import
com.aps.mapper.RoutingDetailMapper
;
import
com.aps.mapper.RoutingHeaderMapper
;
import
com.aps.service.*
;
import
io.swagger.v3.oas.annotations.tags.Tag
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.web.bind.annotation.GetMapping
;
import
org.springframework.web.bind.annotation.RequestMapping
;
import
org.springframework.web.bind.annotation.RestController
;
import
java.util.ArrayList
;
import
java.util.List
;
import
java.util.Set
;
import
java.util.stream.Collectors
;
@RestController
@RequestMapping
(
"/schedule"
)
@Tag
(
name
=
"调度任务"
,
description
=
"调度任务相关接口"
)
public
class
ScheduleController
{
@Autowired
private
ScheduleService
schedulerService
;
@Autowired
private
MpsplannedorderService
orderService
;
@Autowired
private
RoutingHeaderService
processService
;
@Autowired
private
RoutingDetailService
operationService
;
@Autowired
private
RoutingDetailEquipService
operationEquipService
;
@Autowired
private
EquipinfoService
equipmentService
;
@GetMapping
(
"/run"
)
public
List
<
ScheduledTask
>
runScheduling
()
{
try
{
// 获取routingid为'SY1102507-0056202车间-21号线'和'SY1102507-0060202车间-21号线'的待调度工单
List
<
Mpsplannedorder
>
orders
=
orderService
.
lambdaQuery
()
.
in
(
Mpsplannedorder:
:
getRoutingid
,
"SY1102507-0056202车间-21号线"
,
"SY1102507-0060202车间-21号线"
)
.
list
();
if
(
orders
.
isEmpty
())
{
return
new
ArrayList
<>();
}
// 提取所需的工艺ID列表
Set
<
String
>
routingIds
=
orders
.
stream
()
.
map
(
Mpsplannedorder:
:
getRoutingid
)
.
collect
(
Collectors
.
toSet
());
// 根据工单获取相关工艺
List
<
RoutingHeader
>
processes
=
processService
.
lambdaQuery
()
.
in
(
RoutingHeader:
:
getCode
,
routingIds
)
.
list
();
if
(
processes
.
isEmpty
())
{
throw
new
RuntimeException
(
"未找到相关工艺信息"
);
}
// 提取工艺ID用于后续查询
Set
<
Integer
>
processIds
=
processes
.
stream
()
.
map
(
RoutingHeader:
:
getId
)
.
collect
(
Collectors
.
toSet
());
// 根据工艺获取相关工序
List
<
RoutingDetail
>
operations
=
operationService
.
lambdaQuery
()
.
in
(
RoutingDetail:
:
getRoutingHeaderId
,
processIds
)
.
orderByAsc
(
RoutingDetail:
:
getTaskSeq
)
.
list
();
if
(
operations
.
isEmpty
())
{
throw
new
RuntimeException
(
"未找到相关工序信息"
);
}
// 提取工序ID用于后续查询
Set
<
Integer
>
operationIds
=
operations
.
stream
()
.
map
(
RoutingDetail:
:
getId
)
.
collect
(
Collectors
.
toSet
());
// 获取相关工序设备关系
List
<
RoutingDetailEquip
>
operationEquipments
=
operationEquipService
.
lambdaQuery
()
.
in
(
RoutingDetailEquip:
:
getRoutingDetailId
,
operationIds
)
.
list
();
if
(
operationEquipments
.
isEmpty
())
{
throw
new
RuntimeException
(
"未找到工序设备关系信息"
);
}
// 提取设备ID用于后续查询
Set
<
Integer
>
equipmentIds
=
operationEquipments
.
stream
()
.
map
(
RoutingDetailEquip:
:
getEquipId
)
.
collect
(
Collectors
.
toSet
());
// 获取相关设备
List
<
Equipinfo
>
equipments
=
equipmentService
.
lambdaQuery
()
.
in
(
Equipinfo:
:
getId
,
equipmentIds
)
.
list
();
// 添加空值检查
if
(
orders
==
null
||
processes
==
null
||
operations
==
null
||
operationEquipments
==
null
||
equipments
==
null
)
{
throw
new
RuntimeException
(
"获取调度数据失败,存在空数据"
);
}
List
<
ScheduledTask
>
result
=
schedulerService
.
scheduleOrders
(
orders
,
processes
,
operations
,
operationEquipments
,
equipments
);
return
result
;
}
catch
(
Exception
e
)
{
throw
new
RuntimeException
(
"调度执行失败: "
+
e
.
getMessage
(),
e
);
}
}
}
\ No newline at end of file
src/main/java/com/aps/controller/ScheduleResultController.java
0 → 100644
View file @
1dd2520c
package
com
.
aps
.
controller
;
import
com.aps.common.util.R
;
import
com.aps.entity.*
;
import
com.aps.entity.Gantt.PlanResourceTaskGanttVO
;
import
com.aps.entity.Gantt.SimpleEquipinfo
;
import
com.aps.service.*
;
import
io.swagger.v3.oas.annotations.tags.Tag
;
import
io.swagger.v3.oas.annotations.Operation
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.web.bind.annotation.GetMapping
;
import
org.springframework.web.bind.annotation.RequestMapping
;
import
org.springframework.web.bind.annotation.RestController
;
import
java.time.LocalDateTime
;
import
java.util.ArrayList
;
import
java.util.List
;
import
java.util.Set
;
import
java.util.stream.Collectors
;
@RestController
@RequestMapping
(
"/ganttest"
)
@Tag
(
name
=
"甘特图"
,
description
=
"甘特图相关接口"
)
public
class
ScheduleResultController
{
@Autowired
private
ScheduleService
schedulerService
;
@Autowired
private
MpsplannedorderService
orderService
;
@Autowired
private
RoutingHeaderService
processService
;
@Autowired
private
RoutingDetailService
operationService
;
@Autowired
private
RoutingDetailEquipService
operationEquipService
;
@Autowired
private
EquipinfoService
equipmentService
;
@Operation
(
summary
=
"资源甘特图"
,
description
=
"资源甘特图"
)
@GetMapping
(
"/resource"
)
public
R
<
PlanResourceTaskGanttVO
>
runScheduling
()
{
try
{
// 获取routingid为'SY1102507-0056202车间-21号线'和'SY1102507-0060202车间-21号线'的待调度工单
List
<
Mpsplannedorder
>
orders
=
orderService
.
lambdaQuery
()
.
in
(
Mpsplannedorder:
:
getRoutingid
,
"SY1102507-0056202车间-21号线"
,
"SY1102507-0060202车间-21号线"
)
.
list
();
if
(
orders
.
isEmpty
())
{
// 当没有订单时,返回空的甘特图VO
PlanResourceTaskGanttVO
ganttVO
=
new
PlanResourceTaskGanttVO
()
.
setTasks
(
new
ArrayList
<>())
.
setResources
(
new
ArrayList
<>())
.
setEarliestTaskStartTime
(
LocalDateTime
.
of
(
2025
,
6
,
1
,
0
,
0
,
0
))
.
setLastTaskAssignmentTime
(
LocalDateTime
.
of
(
2025
,
12
,
1
,
0
,
0
,
0
));
return
R
.
ok
(
ganttVO
);
}
// 提取所需的工艺ID列表
Set
<
String
>
routingIds
=
orders
.
stream
()
.
map
(
Mpsplannedorder:
:
getRoutingid
)
.
collect
(
Collectors
.
toSet
());
// 根据工单获取相关工艺
List
<
RoutingHeader
>
processes
=
processService
.
lambdaQuery
()
.
in
(
RoutingHeader:
:
getCode
,
routingIds
)
.
list
();
if
(
processes
.
isEmpty
())
{
return
R
.
failed
(
"未找到相关工艺信息"
);
}
// 提取工艺ID用于后续查询
Set
<
Integer
>
processIds
=
processes
.
stream
()
.
map
(
RoutingHeader:
:
getId
)
.
collect
(
Collectors
.
toSet
());
// 根据工艺获取相关工序
List
<
RoutingDetail
>
operations
=
operationService
.
lambdaQuery
()
.
in
(
RoutingDetail:
:
getRoutingHeaderId
,
processIds
)
.
orderByAsc
(
RoutingDetail:
:
getTaskSeq
)
.
list
();
if
(
operations
.
isEmpty
())
{
return
R
.
failed
(
"未找到相关工序信息"
);
}
// 提取工序ID用于后续查询
Set
<
Integer
>
operationIds
=
operations
.
stream
()
.
map
(
RoutingDetail:
:
getId
)
.
collect
(
Collectors
.
toSet
());
// 获取相关工序设备关系
List
<
RoutingDetailEquip
>
operationEquipments
=
operationEquipService
.
lambdaQuery
()
.
in
(
RoutingDetailEquip:
:
getRoutingDetailId
,
operationIds
)
.
list
();
if
(
operationEquipments
.
isEmpty
())
{
return
R
.
failed
(
"未找到工序设备关系信息"
);
}
// 提取设备ID用于后续查询
Set
<
Integer
>
equipmentIds
=
operationEquipments
.
stream
()
.
map
(
RoutingDetailEquip:
:
getEquipId
)
.
collect
(
Collectors
.
toSet
());
// 获取相关设备
List
<
Equipinfo
>
equipments
=
equipmentService
.
lambdaQuery
()
.
in
(
Equipinfo:
:
getId
,
equipmentIds
)
.
list
();
// 添加空值检查
if
(
orders
==
null
||
processes
==
null
||
operations
==
null
||
operationEquipments
==
null
||
equipments
==
null
)
{
return
R
.
failed
(
"获取调度数据失败,存在空数据"
);
}
List
<
ScheduledTask
>
result
=
schedulerService
.
scheduleOrders
(
orders
,
processes
,
operations
,
operationEquipments
,
equipments
);
// 转换设备信息为简要信息,并关联相关任务
List
<
SimpleEquipinfo
>
simpleEquipinfos
=
equipments
.
stream
()
.
map
(
equip
->
{
// 查找与该设备关联的任务
List
<
ScheduledTask
>
equipTasks
=
result
.
stream
()
.
filter
(
task
->
task
.
getEquipId
()
!=
null
&&
task
.
getEquipId
().
equals
(
equip
.
getId
()))
.
collect
(
Collectors
.
toList
());
return
new
SimpleEquipinfo
()
.
setId
(
equip
.
getId
())
.
setEquipId
(
equip
.
getEquipId
())
.
setEquipName
(
equip
.
getEquipName
())
.
setTasks
(
equipTasks
);
})
.
collect
(
Collectors
.
toList
());
// 设置甘特图VO的最早时间为2025年6月1日,最晚时间为2025年12月1日
PlanResourceTaskGanttVO
ganttVO
=
new
PlanResourceTaskGanttVO
()
.
setTasks
(
result
)
.
setResources
(
simpleEquipinfos
)
.
setEarliestTaskStartTime
(
LocalDateTime
.
of
(
2025
,
6
,
1
,
0
,
0
,
0
))
.
setLastTaskAssignmentTime
(
LocalDateTime
.
of
(
2025
,
12
,
1
,
0
,
0
,
0
));
return
R
.
ok
(
ganttVO
);
}
catch
(
Exception
e
)
{
return
R
.
failed
(
"调度执行失败: "
+
e
.
getMessage
());
}
}
}
\ No newline at end of file
src/main/java/com/aps/controller/ScheduleResultController1.java
0 → 100644
View file @
1dd2520c
package
com
.
aps
.
controller
;
import
com.aps.common.util.R
;
import
com.aps.entity.Gantt.PlanResourceTaskGanttVO1
;
import
com.aps.entity.Gantt.SimpleEquipinfo1
;
import
com.aps.entity.Mpsplannedorder
;
import
com.aps.entity.RoutingDetail
;
import
com.aps.entity.RoutingDetailEquip
;
import
com.aps.entity.RoutingHeader
;
import
com.aps.entity.ScheduledTask
;
import
com.aps.entity.Equipinfo
;
import
com.aps.service.ScheduleService
;
import
com.aps.service.MpsplannedorderService
;
import
com.aps.service.RoutingHeaderService
;
import
com.aps.service.RoutingDetailService
;
import
com.aps.service.RoutingDetailEquipService
;
import
com.aps.service.EquipinfoService
;
import
io.swagger.v3.oas.annotations.tags.Tag
;
import
io.swagger.v3.oas.annotations.Operation
;
import
io.swagger.v3.oas.annotations.responses.ApiResponse
;
import
io.swagger.v3.oas.annotations.responses.ApiResponses
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.web.bind.annotation.GetMapping
;
import
org.springframework.web.bind.annotation.RequestMapping
;
import
org.springframework.web.bind.annotation.RestController
;
import
java.time.LocalDateTime
;
import
java.util.ArrayList
;
import
java.util.List
;
import
java.util.Set
;
import
java.util.stream.Collectors
;
@RestController
@RequestMapping
(
"/ganttest"
)
@Tag
(
name
=
"甘特图"
,
description
=
"甘特图相关API"
)
public
class
ScheduleResultController1
{
@Autowired
private
ScheduleService
schedulerService
;
@Autowired
private
MpsplannedorderService
orderService
;
@Autowired
private
RoutingHeaderService
processService
;
@Autowired
private
RoutingDetailService
operationService
;
@Autowired
private
RoutingDetailEquipService
operationEquipService
;
@Autowired
private
EquipinfoService
equipmentService
;
@GetMapping
(
"/resourcetest"
)
@Operation
(
summary
=
"资源甘特图"
,
description
=
"获取资源甘特图数据"
)
@ApiResponses
({
@ApiResponse
(
responseCode
=
"200"
,
description
=
"成功返回甘特图数据"
),
@ApiResponse
(
responseCode
=
"500"
,
description
=
"内部服务器错误"
)
})
public
R
<
PlanResourceTaskGanttVO1
>
runScheduling
()
{
try
{
// 获取routingid为'SY1102507-0056202车间-21号线'和'SY1102507-0060202车间-21号线'的待调度工单
List
<
Mpsplannedorder
>
orders
=
orderService
.
lambdaQuery
()
.
in
(
Mpsplannedorder:
:
getRoutingid
,
"SY1102507-0056202车间-21号线"
,
"SY1102507-0060202车间-21号线"
)
.
list
();
if
(
orders
.
isEmpty
())
{
// 当没有订单时,返回空的甘特图VO
PlanResourceTaskGanttVO1
ganttVO
=
new
PlanResourceTaskGanttVO1
()
.
setResources
(
new
ArrayList
<>())
.
setEarliestTaskStartTime
(
LocalDateTime
.
of
(
2025
,
6
,
1
,
0
,
0
,
0
))
.
setLastTaskAssignmentTime
(
LocalDateTime
.
of
(
2025
,
12
,
1
,
0
,
0
,
0
));
return
R
.
ok
(
ganttVO
);
}
// 提取所需的工艺ID列表
Set
<
String
>
routingIds
=
orders
.
stream
()
.
map
(
Mpsplannedorder:
:
getRoutingid
)
.
collect
(
Collectors
.
toSet
());
// 根据工单获取相关工艺
List
<
RoutingHeader
>
processes
=
processService
.
lambdaQuery
()
.
in
(
RoutingHeader:
:
getCode
,
routingIds
)
.
list
();
if
(
processes
.
isEmpty
())
{
return
R
.
failed
(
"未找到相关工艺信息"
);
}
// 提取工艺ID用于后续查询
Set
<
Integer
>
processIds
=
processes
.
stream
()
.
map
(
RoutingHeader:
:
getId
)
.
collect
(
Collectors
.
toSet
());
// 根据工艺获取相关工序
List
<
RoutingDetail
>
operations
=
operationService
.
lambdaQuery
()
.
in
(
RoutingDetail:
:
getRoutingHeaderId
,
processIds
)
.
orderByAsc
(
RoutingDetail:
:
getTaskSeq
)
.
list
();
if
(
operations
.
isEmpty
())
{
return
R
.
failed
(
"未找到相关工序信息"
);
}
// 提取工序ID用于后续查询
Set
<
Integer
>
operationIds
=
operations
.
stream
()
.
map
(
RoutingDetail:
:
getId
)
.
collect
(
Collectors
.
toSet
());
// 获取相关工序设备关系
List
<
RoutingDetailEquip
>
operationEquipments
=
operationEquipService
.
lambdaQuery
()
.
in
(
RoutingDetailEquip:
:
getRoutingDetailId
,
operationIds
)
.
list
();
if
(
operationEquipments
.
isEmpty
())
{
return
R
.
failed
(
"未找到工序设备关系信息"
);
}
// 提取设备ID用于后续查询
Set
<
Integer
>
equipmentIds
=
operationEquipments
.
stream
()
.
map
(
RoutingDetailEquip:
:
getEquipId
)
.
collect
(
Collectors
.
toSet
());
// 获取相关设备
List
<
Equipinfo
>
equipments
=
equipmentService
.
lambdaQuery
()
.
in
(
Equipinfo:
:
getId
,
equipmentIds
)
.
list
();
// 添加空值检查
if
(
orders
==
null
||
processes
==
null
||
operations
==
null
||
operationEquipments
==
null
||
equipments
==
null
)
{
return
R
.
failed
(
"获取调度数据失败,存在空数据"
);
}
List
<
ScheduledTask
>
result
=
schedulerService
.
scheduleOrders
(
orders
,
processes
,
operations
,
operationEquipments
,
equipments
);
// 转换设备信息为简要信息,并关联相关任务
List
<
SimpleEquipinfo1
>
simpleEquipinfos
=
equipments
.
stream
()
.
map
(
equip
->
{
// 查找与该设备关联的任务
List
<
ScheduledTask
>
equipTasks
=
result
.
stream
()
.
filter
(
task
->
task
.
getEquipId
()
!=
null
&&
task
.
getEquipId
().
equals
(
equip
.
getId
()))
.
collect
(
Collectors
.
toList
());
return
new
SimpleEquipinfo1
()
.
setId
(
equip
.
getId
())
.
setEquipId
(
equip
.
getEquipId
())
.
setEquipName
(
equip
.
getEquipName
())
.
setTasks
(
equipTasks
);
})
.
collect
(
Collectors
.
toList
());
// 设置甘特图VO的最早时间为2025年6月1日,最晚时间为2025年12月1日
PlanResourceTaskGanttVO1
ganttVO
=
new
PlanResourceTaskGanttVO1
()
.
setResources
(
simpleEquipinfos
)
.
setEarliestTaskStartTime
(
LocalDateTime
.
of
(
2025
,
6
,
1
,
0
,
0
,
0
))
.
setLastTaskAssignmentTime
(
LocalDateTime
.
of
(
2025
,
12
,
1
,
0
,
0
,
0
));
return
R
.
ok
(
ganttVO
);
}
catch
(
Exception
e
)
{
return
R
.
failed
(
"调度执行失败: "
+
e
.
getMessage
());
}
}
}
\ No newline at end of file
src/main/java/com/
example
/controller/codeGeneratorController/CodeGeneratorController.java
→
src/main/java/com/
aps
/controller/codeGeneratorController/CodeGeneratorController.java
View file @
1dd2520c
package
com
.
example
.
controller
.
codeGeneratorController
;
package
com
.
aps
.
controller
.
codeGeneratorController
;
import
com.
example
.entity.codeGeneratorEntity.DatabaseConfig
;
import
com.
aps
.entity.codeGeneratorEntity.DatabaseConfig
;
import
com.
example
.entity.codeGeneratorEntity.GenerateRequest
;
import
com.
aps
.entity.codeGeneratorEntity.GenerateRequest
;
import
com.
example
.service.codeGeneratorService.CodeGeneratorService
;
import
com.
aps
.service.codeGeneratorService.CodeGeneratorService
;
import
com.
example
.service.codeGeneratorService.DatabaseConfigService
;
import
com.
aps
.service.codeGeneratorService.DatabaseConfigService
;
import
io.swagger.
annotations.Api
;
import
io.swagger.
v3.oas.annotations.tags.Tag
;
import
io.swagger.
annotations.Api
Operation
;
import
io.swagger.
v3.oas.annotations.
Operation
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.web.bind.annotation.*
;
import
org.springframework.web.bind.annotation.*
;
...
@@ -15,7 +15,7 @@ import java.util.Map;
...
@@ -15,7 +15,7 @@ import java.util.Map;
@RestController
@RestController
@RequestMapping
(
"/api/code-generator"
)
@RequestMapping
(
"/api/code-generator"
)
@
Api
(
tags
=
"代码生成器
"
)
@
Tag
(
name
=
"代码生成器"
,
description
=
"代码生成相关接口
"
)
public
class
CodeGeneratorController
{
public
class
CodeGeneratorController
{
@Autowired
@Autowired
...
@@ -25,7 +25,7 @@ public class CodeGeneratorController {
...
@@ -25,7 +25,7 @@ public class CodeGeneratorController {
private
DatabaseConfigService
databaseConfigService
;
private
DatabaseConfigService
databaseConfigService
;
@GetMapping
(
"/config"
)
@GetMapping
(
"/config"
)
@
ApiOperation
(
"获取当前主数据源配置"
)
@
Operation
(
summary
=
"获取当前主数据源配置"
,
description
=
"获取当前主数据源配置"
)
public
DatabaseConfig
getDatabaseConfig
()
{
public
DatabaseConfig
getDatabaseConfig
()
{
DatabaseConfig
config
=
databaseConfigService
.
getPrimaryDatabaseConfig
();
DatabaseConfig
config
=
databaseConfigService
.
getPrimaryDatabaseConfig
();
if
(
config
==
null
)
{
if
(
config
==
null
)
{
...
@@ -35,7 +35,7 @@ public class CodeGeneratorController {
...
@@ -35,7 +35,7 @@ public class CodeGeneratorController {
}
}
@GetMapping
(
"/config/{dataSourceName}"
)
@GetMapping
(
"/config/{dataSourceName}"
)
@
ApiOperation
(
"获取指定数据源配置"
)
@
Operation
(
summary
=
"获取指定数据源配置"
,
description
=
"获取指定数据源配置"
)
public
DatabaseConfig
getDatabaseConfig
(
@PathVariable
String
dataSourceName
)
{
public
DatabaseConfig
getDatabaseConfig
(
@PathVariable
String
dataSourceName
)
{
DatabaseConfig
config
=
databaseConfigService
.
getDatabaseConfig
(
dataSourceName
);
DatabaseConfig
config
=
databaseConfigService
.
getDatabaseConfig
(
dataSourceName
);
if
(
config
==
null
)
{
if
(
config
==
null
)
{
...
@@ -45,7 +45,7 @@ public class CodeGeneratorController {
...
@@ -45,7 +45,7 @@ public class CodeGeneratorController {
}
}
@GetMapping
(
"/tables/{dataSourceName}"
)
@GetMapping
(
"/tables/{dataSourceName}"
)
@
ApiOperation
(
"获取指定数据源的表列表"
)
@
Operation
(
summary
=
"获取指定数据源的表列表"
,
description
=
"获取指定数据源的表列表"
)
public
List
<
String
>
getTables
(
@PathVariable
String
dataSourceName
)
{
public
List
<
String
>
getTables
(
@PathVariable
String
dataSourceName
)
{
DatabaseConfig
config
=
databaseConfigService
.
getDatabaseConfig
(
dataSourceName
);
DatabaseConfig
config
=
databaseConfigService
.
getDatabaseConfig
(
dataSourceName
);
if
(
config
==
null
||
config
.
getUrl
()
==
null
)
{
if
(
config
==
null
||
config
.
getUrl
()
==
null
)
{
...
@@ -55,7 +55,7 @@ public class CodeGeneratorController {
...
@@ -55,7 +55,7 @@ public class CodeGeneratorController {
}
}
@GetMapping
(
"/test-connection/{dataSourceName}"
)
@GetMapping
(
"/test-connection/{dataSourceName}"
)
@
ApiOperation
(
"测试指定数据源连接"
)
@
Operation
(
summary
=
"测试指定数据源连接"
,
description
=
"测试指定数据源连接"
)
public
String
testConnection
(
@PathVariable
String
dataSourceName
)
{
public
String
testConnection
(
@PathVariable
String
dataSourceName
)
{
DatabaseConfig
config
=
databaseConfigService
.
getDatabaseConfig
(
dataSourceName
);
DatabaseConfig
config
=
databaseConfigService
.
getDatabaseConfig
(
dataSourceName
);
if
(
config
==
null
)
{
if
(
config
==
null
)
{
...
@@ -67,7 +67,7 @@ public class CodeGeneratorController {
...
@@ -67,7 +67,7 @@ public class CodeGeneratorController {
}
}
@PostMapping
(
"/generate/{dataSourceName}"
)
@PostMapping
(
"/generate/{dataSourceName}"
)
@
ApiOperation
(
"使用指定数据源生成代码"
)
@
Operation
(
summary
=
"使用指定数据源生成代码"
,
description
=
"使用指定数据源生成代码"
)
public
String
generateCode
(
@PathVariable
String
dataSourceName
,
public
String
generateCode
(
@PathVariable
String
dataSourceName
,
@RequestBody
GenerateRequest
request
)
{
@RequestBody
GenerateRequest
request
)
{
try
{
try
{
...
...
src/main/java/com/aps/controller/plan/PlanSchedulerController.java
0 → 100644
View file @
1dd2520c
// MachineSchedulerController.java
package
com
.
aps
.
controller
.
plan
;
import
com.aps.common.util.R
;
import
com.aps.entity.Schedule.PlanResourceTaskGanttVO
;
import
com.aps.service.plan.PlanSchedulerService
;
import
io.swagger.v3.oas.annotations.tags.Tag
;
import
io.swagger.v3.oas.annotations.Operation
;
import
io.swagger.v3.oas.annotations.responses.ApiResponse
;
import
io.swagger.v3.oas.annotations.responses.ApiResponses
;
import
lombok.extern.slf4j.Slf4j
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.web.bind.annotation.GetMapping
;
import
org.springframework.web.bind.annotation.RequestMapping
;
import
org.springframework.web.bind.annotation.RestController
;
import
java.util.List
;
@Slf4j
@RestController
@RequestMapping
(
"/gantt"
)
@Tag
(
name
=
"机器调度管理"
,
description
=
"机器调度相关API"
)
public
class
PlanSchedulerController
{
@Autowired
private
PlanSchedulerService
schedulingService
;
@GetMapping
(
"/scheduleresource"
)
@Operation
(
summary
=
"执行机器调度"
,
description
=
"执行机器调度并返回甘特图数据"
)
@ApiResponses
({
@ApiResponse
(
responseCode
=
"200"
,
description
=
"成功返回调度结果"
)
})
public
R
<
List
<
PlanResourceTaskGanttVO
>>
runScheduling
()
{
List
<
PlanResourceTaskGanttVO
>
execute
=
schedulingService
.
execute
();
return
R
.
ok
(
execute
);
}
@GetMapping
(
"/health"
)
@Operation
(
summary
=
"健康检查"
,
description
=
"检查服务是否正常运行"
)
@ApiResponses
({
@ApiResponse
(
responseCode
=
"200"
,
description
=
"服务正常运行"
)
})
public
String
healthCheck
()
{
return
"Machine Scheduler Service is running!"
;
}
}
\ No newline at end of file
src/main/java/com/
example
/entity/Department.java
→
src/main/java/com/
aps
/entity/Department.java
View file @
1dd2520c
package
com
.
example
.
entity
;
package
com
.
aps
.
entity
;
import
com.baomidou.mybatisplus.annotation.IdType
;
import
com.baomidou.mybatisplus.annotation.IdType
;
import
com.baomidou.mybatisplus.annotation.TableId
;
import
com.baomidou.mybatisplus.annotation.TableId
;
...
...
src/main/java/com/aps/entity/Equipinfo.java
0 → 100644
View file @
1dd2520c
package
com
.
aps
.
entity
;
import
com.baomidou.mybatisplus.annotation.IdType
;
import
com.baomidou.mybatisplus.annotation.TableId
;
import
java.io.Serializable
;
import
java.math.BigDecimal
;
import
java.time.LocalDate
;
import
lombok.Getter
;
import
lombok.Setter
;
/**
* <p>
*
* </p>
*
* @author MyBatis-Plus
* @since 2025-10-09
*/
@Getter
@Setter
public
class
Equipinfo
implements
Serializable
{
private
static
final
long
serialVersionUID
=
1L
;
@TableId
(
value
=
"id"
,
type
=
IdType
.
AUTO
)
private
Integer
id
;
private
Integer
shopId
;
private
String
equipId
;
private
Integer
equipType
;
private
String
equipName
;
private
String
equipStatus
;
private
String
location
;
private
Integer
shaftQty
;
private
BigDecimal
capabilityValue
;
private
Integer
securityclassid
;
private
String
equipIp
;
private
String
equipmentSc
;
private
Integer
operatorId
;
private
String
equipVersion
;
private
String
equipSystem
;
private
String
equipPic
;
private
Integer
locationx
;
private
Integer
isimportant
;
private
String
filepath
;
private
LocalDate
equipStatusUpdatetime
;
private
Integer
hot
;
private
BigDecimal
capacity
;
private
BigDecimal
standard
;
private
String
usedepartment
;
private
String
installplace
;
private
String
mainnumber
;
private
String
manufacturer
;
private
String
enabledate
;
private
String
equipWinpwd
;
private
String
equipWinname
;
private
String
equipPort
;
private
Integer
status
;
private
String
property
;
private
LocalDate
creationtime
;
private
Long
creatoruserid
;
private
LocalDate
lastmodificationtime
;
private
Long
lastmodifieruserid
;
private
Boolean
isdeleted
;
private
Long
deleteruserid
;
private
LocalDate
deletiontime
;
private
Integer
head
;
private
Integer
runningstatus
;
private
String
systemInfo
;
private
Integer
ismdc
;
private
Integer
workPattern
;
private
String
workPatternName
;
private
String
measureUnitName
;
private
String
currencyTypeName
;
private
String
capacityTypeName
;
private
Integer
measureUnit
;
private
Integer
currencyType
;
private
Integer
capacityType
;
private
String
fequipid
;
private
BigDecimal
minTime
;
private
BigDecimal
minDurationTime
;
private
BigDecimal
maxDurationTime
;
private
BigDecimal
jpExpecationTime
;
}
src/main/java/com/aps/entity/EquipmentScheduleState.java
0 → 100644
View file @
1dd2520c
package
com
.
aps
.
entity
;
import
lombok.Data
;
import
java.time.LocalDateTime
;
import
java.util.LinkedList
;
import
java.util.Queue
;
@Data
public
class
EquipmentScheduleState
{
private
Integer
equipId
;
// 设备ID
private
String
equipName
;
// 设备名称
private
Queue
<
ScheduledTask
>
taskQueue
=
new
LinkedList
<>();
// 任务队列
private
LocalDateTime
nextAvailableTime
;
// 下次可用时间
// 从Equipinfo初始化
public
EquipmentScheduleState
(
Equipinfo
equipinfo
,
LocalDateTime
now
)
{
this
.
equipId
=
equipinfo
.
getId
();
this
.
equipName
=
equipinfo
.
getEquipName
();
// 添加设备名称
// 确保设备创建时间不为空
if
(
equipinfo
.
getCreationtime
()
!=
null
)
{
this
.
nextAvailableTime
=
equipinfo
.
getCreationtime
().
atStartOfDay
();
}
else
{
this
.
nextAvailableTime
=
now
!=
null
?
now
:
LocalDateTime
.
now
();
}
}
}
\ No newline at end of file
src/main/java/com/aps/entity/Gantt/PlanResourceTaskGanttVO.java
0 → 100644
View file @
1dd2520c
package
com
.
aps
.
entity
.
Gantt
;
import
com.aps.entity.Equipinfo
;
import
com.aps.entity.ScheduledTask
;
import
com.fasterxml.jackson.annotation.JsonFormat
;
import
io.swagger.v3.oas.annotations.media.Schema
;
import
lombok.Data
;
import
lombok.EqualsAndHashCode
;
import
lombok.experimental.Accessors
;
import
org.apache.ibatis.type.Alias
;
import
java.time.LocalDateTime
;
import
java.util.List
;
/**
* @author jvs
*/
@Data
@EqualsAndHashCode
(
callSuper
=
false
)
@Accessors
(
chain
=
true
)
@Schema
(
name
=
"排产结果可视化——资源任务甘特图"
,
description
=
"排产结果可视化——资源任务甘特图"
)
@Alias
(
"PlanResourceTaskGanttVO"
)
public
class
PlanResourceTaskGanttVO
{
@Schema
(
description
=
"任务计划最早开始时间"
)
@JsonFormat
(
timezone
=
"GMT+8"
,
pattern
=
"yyyy-MM-dd HH:mm:ss"
)
private
LocalDateTime
earliestTaskStartTime
;
@Schema
(
description
=
"最近任务派工截止时间"
)
@JsonFormat
(
timezone
=
"GMT+8"
,
pattern
=
"yyyy-MM-dd HH:mm:ss"
)
private
LocalDateTime
lastTaskAssignmentTime
;
@Schema
(
description
=
"资源集合"
)
private
List
<
SimpleEquipinfo
>
resources
;
@Schema
(
description
=
"任务集合"
)
private
List
<
ScheduledTask
>
tasks
;
}
\ No newline at end of file
src/main/java/com/aps/entity/Gantt/PlanResourceTaskGanttVO1.java
0 → 100644
View file @
1dd2520c
package
com
.
aps
.
entity
.
Gantt
;
import
com.aps.entity.ScheduledTask
;
import
com.fasterxml.jackson.annotation.JsonFormat
;
import
io.swagger.v3.oas.annotations.media.Schema
;
import
lombok.Data
;
import
lombok.EqualsAndHashCode
;
import
lombok.experimental.Accessors
;
import
org.apache.ibatis.type.Alias
;
import
java.time.LocalDateTime
;
import
java.util.List
;
/**
* @author jvs
*/
@Data
@EqualsAndHashCode
(
callSuper
=
false
)
@Accessors
(
chain
=
true
)
@Schema
(
name
=
"排产结果可视化——资源任务甘特图1"
,
description
=
"排产结果可视化——资源任务甘特图1"
)
@Alias
(
"PlanResourceTaskGanttVO1"
)
public
class
PlanResourceTaskGanttVO1
{
@Schema
(
description
=
"任务计划最早开始时间"
)
@JsonFormat
(
timezone
=
"GMT+8"
,
pattern
=
"yyyy-MM-dd HH:mm:ss"
)
private
LocalDateTime
earliestTaskStartTime
;
@Schema
(
description
=
"最近任务派工截止时间"
)
@JsonFormat
(
timezone
=
"GMT+8"
,
pattern
=
"yyyy-MM-dd HH:mm:ss"
)
private
LocalDateTime
lastTaskAssignmentTime
;
@Schema
(
description
=
"资源任务集合"
)
private
List
<
SimpleEquipinfo1
>
resources
;
}
\ No newline at end of file
src/main/java/com/aps/entity/Gantt/SimpleEquipinfo.java
0 → 100644
View file @
1dd2520c
package
com
.
aps
.
entity
.
Gantt
;
import
com.aps.entity.ScheduledTask
;
import
io.swagger.v3.oas.annotations.media.Schema
;
import
lombok.Data
;
import
lombok.experimental.Accessors
;
import
java.util.List
;
@Data
@Accessors
(
chain
=
true
)
@Schema
(
name
=
"设备简要信息"
,
description
=
"设备简要信息"
)
public
class
SimpleEquipinfo
{
@Schema
(
description
=
"设备内部ID"
)
private
Integer
id
;
@Schema
(
description
=
"设备编码"
)
private
String
equipId
;
@Schema
(
description
=
"设备名称"
)
private
String
equipName
;
@Schema
(
description
=
"关联的任务列表"
)
private
List
<
ScheduledTask
>
tasks
;
}
\ No newline at end of file
src/main/java/com/aps/entity/Gantt/SimpleEquipinfo1.java
0 → 100644
View file @
1dd2520c
package
com
.
aps
.
entity
.
Gantt
;
import
com.aps.entity.ScheduledTask
;
import
io.swagger.v3.oas.annotations.media.Schema
;
import
lombok.Data
;
import
lombok.experimental.Accessors
;
import
java.util.List
;
@Data
@Accessors
(
chain
=
true
)
@Schema
(
name
=
"设备简要信息"
,
description
=
"设备简要信息"
)
public
class
SimpleEquipinfo1
{
@Schema
(
description
=
"设备内部ID"
)
private
Integer
id
;
@Schema
(
description
=
"设备编码"
)
private
String
equipId
;
@Schema
(
description
=
"设备名称"
)
private
String
equipName
;
@Schema
(
description
=
"任务集合"
)
private
List
<
ScheduledTask
>
tasks
;
}
\ No newline at end of file
src/main/java/com/
example
/entity/MaterialInfo.java
→
src/main/java/com/
aps
/entity/MaterialInfo.java
View file @
1dd2520c
package
com
.
example
.
entity
;
package
com
.
aps
.
entity
;
import
com.baomidou.mybatisplus.annotation.TableField
;
import
com.baomidou.mybatisplus.annotation.TableField
;
import
com.baomidou.mybatisplus.annotation.TableId
;
import
com.baomidou.mybatisplus.annotation.TableId
;
...
@@ -175,13 +175,13 @@ public class MaterialInfo implements Serializable {
...
@@ -175,13 +175,13 @@ public class MaterialInfo implements Serializable {
private
Long
latest
;
private
Long
latest
;
/**
/**
* 是否创建原材料供应供应
* 是否创建原材料供应供应
?
*/
*/
@TableField
(
"iscreatesupplyrouting"
)
@TableField
(
"iscreatesupplyrouting"
)
private
Long
iscreatesupplyrouting
;
private
Long
iscreatesupplyrouting
;
/**
/**
* 是否创建原材料检验供应
* 是否创建原材料检验供应
?
*/
*/
@TableField
(
"iscreatecheckrouting"
)
@TableField
(
"iscreatecheckrouting"
)
private
Long
iscreatecheckrouting
;
private
Long
iscreatecheckrouting
;
...
@@ -250,13 +250,13 @@ public class MaterialInfo implements Serializable {
...
@@ -250,13 +250,13 @@ public class MaterialInfo implements Serializable {
private
String
ser
;
private
String
ser
;
/**
/**
* 是否共用
料
* 是否共用
?
*/
*/
@TableField
(
"iscommon"
)
@TableField
(
"iscommon"
)
private
Long
iscommon
;
private
Long
iscommon
;
/**
/**
* 是否创建汇总供应
* 是否创建汇总供应
?
*/
*/
@TableField
(
"iscreatepoolrouting"
)
@TableField
(
"iscreatepoolrouting"
)
private
Long
iscreatepoolrouting
;
private
Long
iscreatepoolrouting
;
...
@@ -358,7 +358,7 @@ public class MaterialInfo implements Serializable {
...
@@ -358,7 +358,7 @@ public class MaterialInfo implements Serializable {
private
Long
smallpro
;
private
Long
smallpro
;
/**
/**
* 周三后排
产
* 周三后排
?
*/
*/
@TableField
(
"isthree"
)
@TableField
(
"isthree"
)
private
Long
isthree
;
private
Long
isthree
;
...
@@ -403,13 +403,13 @@ public class MaterialInfo implements Serializable {
...
@@ -403,13 +403,13 @@ public class MaterialInfo implements Serializable {
private
String
fullName
;
private
String
fullName
;
/**
/**
* 是否包含库存,默认
1,1
是,0否
* 是否包含库存,默认是,0否
*/
*/
@TableField
(
"is_include_store"
)
@TableField
(
"is_include_store"
)
private
Long
isIncludeStore
;
private
Long
isIncludeStore
;
/**
/**
* 是否平分到未来四周,默认0
,0
否,1是
* 是否平分到未来四周,默认0否,1是
*/
*/
@TableField
(
"is_average_four_week"
)
@TableField
(
"is_average_four_week"
)
private
Long
isAverageFourWeek
;
private
Long
isAverageFourWeek
;
...
@@ -482,4 +482,4 @@ public class MaterialInfo implements Serializable {
...
@@ -482,4 +482,4 @@ public class MaterialInfo implements Serializable {
*/
*/
@TableField
(
"invisable"
)
@TableField
(
"invisable"
)
private
Long
invisable
;
private
Long
invisable
;
}
}
\ No newline at end of file
src/main/java/com/aps/entity/MesShiftWorkSched.java
0 → 100644
View file @
1dd2520c
package
com
.
aps
.
entity
;
import
com.baomidou.mybatisplus.annotation.IdType
;
import
com.baomidou.mybatisplus.annotation.TableId
;
import
com.baomidou.mybatisplus.annotation.TableName
;
import
java.io.Serializable
;
import
java.time.LocalDateTime
;
import
lombok.Getter
;
import
lombok.Setter
;
/**
* <p>
* 班次表
* </p>
*
* @author MyBatis-Plus
* @since 2025-10-10
*/
@Getter
@Setter
@TableName
(
"mes_shift_work_sched"
)
public
class
MesShiftWorkSched
implements
Serializable
{
private
static
final
long
serialVersionUID
=
1L
;
@TableId
(
value
=
"id"
,
type
=
IdType
.
AUTO
)
private
Integer
id
;
/**
* 编号
*/
private
String
shiftWorkSchedCode
;
/**
* 班次名称
*/
private
String
shiftName
;
/**
* 班次开始时间
*/
private
LocalDateTime
shiftStart
;
/**
* 班次结束时间
*/
private
LocalDateTime
shiftEnd
;
/**
* 状态
*/
private
Integer
status
;
/**
* 工作时长
*/
private
Integer
workingLong
;
/**
* 班次id
*/
private
Integer
shiftWorkSchedPk1
;
private
LocalDateTime
creationtime
;
private
Integer
creatoruserid
;
private
LocalDateTime
lastmodificationtime
;
private
Integer
lastmodifieruserid
;
private
Integer
isdeleted
;
private
LocalDateTime
deletiontime
;
private
Integer
deleteruserid
;
/**
* 开始周几值
*/
private
Integer
startWeekDay
;
/**
* 开始周几名称
*/
private
String
startWeekDayName
;
/**
* 班次模板id
*/
private
Integer
weekWorkSchedId
;
/**
* 结束周几值
*/
private
Integer
endWeekDay
;
/**
* 结束周几名称
*/
private
String
endWeekDayName
;
/**
* (字符duration)working_long
*/
private
String
strWorkingLong
;
}
\ No newline at end of file
src/main/java/com/aps/entity/Mpsplannedorder.java
0 → 100644
View file @
1dd2520c
package
com
.
aps
.
entity
;
import
lombok.Data
;
import
java.io.Serializable
;
import
java.time.LocalDateTime
;
@Data
public
class
Mpsplannedorder
{
private
String
routingid
;
private
Integer
quantity
;
private
LocalDateTime
startdate
;
private
LocalDateTime
end
;
private
LocalDateTime
duadate
;
private
Integer
orderid
;
private
String
mpplanid
;
private
String
id
;
private
Integer
priority
;
private
LocalDateTime
addtime
;
private
String
serie
;
private
String
bigorder
;
private
String
unitid
;
private
String
productid
;
}
src/main/java/com/aps/entity/PlanResource.java
0 → 100644
View file @
1dd2520c
package
com
.
aps
.
entity
;
import
lombok.Data
;
import
com.baomidou.mybatisplus.annotation.IdType
;
import
com.baomidou.mybatisplus.annotation.TableId
;
import
com.baomidou.mybatisplus.annotation.TableName
;
import
java.io.Serializable
;
import
java.math.BigDecimal
;
import
java.time.LocalDate
;
@Data
public
class
PlanResource
{
private
Integer
id
;
private
String
title
;
private
String
code
;
private
String
type1
;
private
Integer
referenceId
;
private
Integer
departId
;
private
String
departTitle
;
private
Integer
isimportant
;
private
BigDecimal
capabilityValue
;
private
LocalDate
creationtime
;
private
Long
creatoruserid
;
private
LocalDate
lastmodificationtime
;
private
Long
lastmodifieruserid
;
private
Boolean
isdeleted
;
private
LocalDate
deletiontime
;
private
Long
deleteruserid
;
private
String
calId
;
private
String
calName
;
private
String
holidayCalId
;
private
String
holidayCalName
;
private
String
referenceCode
;
private
Integer
equipTypeId
;
private
String
equipType
;
private
Integer
workSchedId
;
private
Long
nrofunitsopen
;
private
Integer
isstop
;
private
LocalDate
stoptime
;
private
LocalDate
stopendtime
;
}
src/main/java/com/aps/entity/RoutingDetail.java
0 → 100644
View file @
1dd2520c
package
com
.
aps
.
entity
;
import
lombok.Data
;
import
com.baomidou.mybatisplus.annotation.IdType
;
import
com.baomidou.mybatisplus.annotation.TableId
;
import
com.baomidou.mybatisplus.annotation.TableName
;
import
java.io.Serializable
;
import
java.math.BigDecimal
;
import
java.time.LocalDate
;
@Data
public
class
RoutingDetail
{
private
Integer
id
;
private
LocalDate
creationTime
;
private
Long
creatorUserId
;
private
LocalDate
lastModificationTime
;
private
Long
lastModifierUserId
;
private
Boolean
isDeleted
;
private
Long
deleterUserId
;
private
LocalDate
deletionTime
;
private
Integer
classId
;
private
Integer
routingHeaderId
;
private
String
name
;
private
BigDecimal
taskSeq
;
private
String
description
;
private
String
taskContent
;
private
Integer
resourceId
;
private
Short
resourceType
;
private
BigDecimal
runtime
;
private
BigDecimal
setupTime
;
private
BigDecimal
transportTime
;
private
BigDecimal
checkTime
;
private
Short
checkFlag
;
private
BigDecimal
efficiencyValue
;
private
BigDecimal
singleOut
;
private
Short
isOutside
;
private
Integer
departmentId
;
private
Short
isImportant
;
private
Integer
milestoneId
;
private
Integer
phaseId
;
private
Short
status
;
private
String
remark
;
private
String
extend
;
private
BigDecimal
outsideTime
;
private
BigDecimal
performanceHours
;
private
String
resourceCode
;
private
Integer
isImportantResources
;
private
BigDecimal
schedulingWorkingHours
;
private
BigDecimal
realWorkingHours
;
private
BigDecimal
realRuntime
;
private
BigDecimal
performanceWorkingHours
;
private
Integer
isParticipateIntime
;
private
String
equipType
;
private
Integer
equipTypeId
;
private
String
note
;
private
String
fileId
;
private
Integer
measureUnit
;
private
String
measureUnitName
;
private
BigDecimal
afterProcessTime
;
private
Integer
isGeneral
;
private
Integer
canInterrupt
;
private
Integer
canStartEarly
;
private
BigDecimal
previousStartTimeBegin
;
private
String
code
;
private
String
tool
;
private
BigDecimal
changeLineTime
;
private
Integer
preDetailId
;
private
Integer
connectType
;
private
Integer
connectProperty
;
private
String
connectTypeName
;
private
String
connectPropertyName
;
private
String
strSetupTime
;
private
Long
isync
;
private
BigDecimal
constTime
;
private
String
usable
;
private
BigDecimal
leadTime
;
}
src/main/java/com/aps/entity/RoutingDetailEquip.java
0 → 100644
View file @
1dd2520c
package
com
.
aps
.
entity
;
import
com.baomidou.mybatisplus.annotation.IdType
;
import
com.baomidou.mybatisplus.annotation.TableId
;
import
com.baomidou.mybatisplus.annotation.TableName
;
import
java.io.Serializable
;
import
java.math.BigDecimal
;
import
java.time.LocalDateTime
;
import
lombok.Getter
;
import
lombok.Setter
;
/**
* <p>
* 工序可用设备
* </p>
*
* @author MyBatis-Plus
* @since 2025-10-10
*/
@Getter
@Setter
@TableName
(
"routing_detail_equip"
)
public
class
RoutingDetailEquip
implements
Serializable
{
private
static
final
long
serialVersionUID
=
1L
;
@TableId
(
value
=
"id"
,
type
=
IdType
.
AUTO
)
private
Integer
id
;
/**
* 创建时间
*/
private
LocalDateTime
creationtime
;
/**
* 创建人
*/
private
Integer
creatoruserid
;
/**
* 更新时间
*/
private
LocalDateTime
lastmodificationtime
;
/**
* 更新人
*/
private
Integer
lastmodifieruserid
;
/**
* 删除人
*/
private
Integer
isdeleted
;
/**
* 删除时间
*/
private
LocalDateTime
deletiontime
;
/**
* 删除人
*/
private
Integer
deleteruserid
;
/**
* 设备类型
*/
private
Integer
type1
;
/**
* 设备类型名
*/
private
String
typeName
;
/**
* 设备名称
*/
private
String
name
;
/**
* 产出数量
*/
private
BigDecimal
outputQuantity
;
/**
* 计量单位
*/
private
Integer
measureUnit
;
/**
* 计量单位名称
*/
private
String
measureUnitName
;
/**
* 持续时间
*/
private
BigDecimal
duration
;
private
String
exp1
;
private
String
exp2
;
/**
* 设备的类型:1--设备 2--班组
*/
private
Integer
exp3
;
private
Integer
exp4
;
/**
* 工序id
*/
private
Integer
routingDetailId
;
/**
* 设备id
*/
private
Integer
equipId
;
/**
* 工艺id
*/
private
Integer
routingHeaderId
;
/**
* 单次批量产出
*/
private
BigDecimal
oneBatchQuantity
;
private
String
strId
;
}
\ No newline at end of file
src/main/java/com/aps/entity/RoutingHeader.java
0 → 100644
View file @
1dd2520c
package
com
.
aps
.
entity
;
import
com.baomidou.mybatisplus.annotation.IdType
;
import
com.baomidou.mybatisplus.annotation.TableId
;
import
com.baomidou.mybatisplus.annotation.TableName
;
import
java.io.Serializable
;
import
java.math.BigDecimal
;
import
java.time.LocalDate
;
import
lombok.Getter
;
import
lombok.Setter
;
/**
* <p>
*
* </p>
*
* @author MyBatis-Plus
* @since 2025-10-09
*/
@Getter
@Setter
@TableName
(
"routing_header"
)
public
class
RoutingHeader
implements
Serializable
{
private
static
final
long
serialVersionUID
=
1L
;
@TableId
(
value
=
"id"
,
type
=
IdType
.
AUTO
)
private
Integer
id
;
private
LocalDate
creationTime
;
private
Long
creatorUserId
;
private
LocalDate
lastModificationTime
;
private
Long
lastModifierUserId
;
private
Integer
deleterUserId
;
private
LocalDate
deletionTime
;
private
Integer
classId
;
private
String
unicode
;
private
String
name
;
private
String
code
;
private
Integer
productId
;
private
String
version
;
private
Integer
author
;
private
Integer
departmentId
;
private
Integer
isMain
;
private
Integer
upId
;
private
Integer
upDetailId
;
private
Integer
routingType
;
private
Short
status
;
private
Short
approvalStatus
;
private
String
remark
;
private
String
approvalStatusRemark
;
private
String
auditUserId1
;
private
String
auditUserId2
;
private
Boolean
isDeleted
;
private
Double
platesnum
;
private
String
isEffect
;
private
String
versionnotes
;
private
Integer
phase
;
private
Integer
versionid
;
private
Integer
isSendPpm
;
private
String
fileId
;
private
String
productName
;
private
String
departmentName
;
private
String
drawingNo
;
private
Integer
productBomId
;
private
String
routingChangeorderCode
;
private
Integer
routingChangeheaderId
;
private
String
auditUserId3
;
private
String
materialId
;
private
Double
outputQuantity
;
private
String
routingTypeName
;
private
Double
leadTime
;
private
Integer
quintiqOrtems
;
private
Integer
iscreatecheckrouting
;
private
Integer
iscreateoutbom
;
private
Integer
issupportingstore
;
private
Long
isync
;
private
Integer
routingUsetype
;
private
Integer
linkroutingid
;
private
LocalDate
effectEnd
;
private
Integer
year
;
private
LocalDate
effectBegin
;
private
Integer
cost
;
private
Integer
erptag
;
private
LocalDate
createoutbomtime
;
private
Integer
materialPlanType
;
private
BigDecimal
pcost
;
private
Integer
invisable
;
}
src/main/java/com/aps/entity/RoutingStep.java
0 → 100644
View file @
1dd2520c
package
com
.
aps
.
entity
;
import
com.baomidou.mybatisplus.annotation.IdType
;
import
com.baomidou.mybatisplus.annotation.TableId
;
import
com.baomidou.mybatisplus.annotation.TableName
;
import
java.io.Serializable
;
import
java.time.LocalDate
;
import
lombok.Getter
;
import
lombok.Setter
;
/**
* <p>
*
* </p>
*
* @author MyBatis-Plus
* @since 2025-10-10
*/
@Getter
@Setter
@TableName
(
"routing_step"
)
public
class
RoutingStep
implements
Serializable
{
private
static
final
long
serialVersionUID
=
1L
;
@TableId
(
value
=
"id"
,
type
=
IdType
.
AUTO
)
private
Integer
id
;
private
LocalDate
creationTime
;
private
Long
creatorUserId
;
private
LocalDate
lastModificationTime
;
private
Long
lastModifierUserId
;
private
Long
isDeleted
;
private
Long
deleterUserId
;
private
LocalDate
deletionTime
;
private
Integer
routingHeaderId
;
private
Integer
routingDetailId
;
private
Integer
classId
;
private
Integer
stepSeq
;
private
String
name
;
private
String
description
;
private
Short
status
;
private
String
remark
;
private
String
stepContent
;
private
String
extend
;
}
src/main/java/com/aps/entity/Schedule/GenVO.java
0 → 100644
View file @
1dd2520c
package
com
.
aps
.
entity
.
Schedule
;
import
com.fasterxml.jackson.annotation.JsonFormat
;
import
lombok.Data
;
import
java.math.BigDecimal
;
import
java.time.LocalDateTime
;
@Data
public
class
GenVO
{
private
String
orderId
;
// 工单ID
private
Integer
operationId
;
// 工序ID
private
Integer
equipId
;
// 设备ID
@JsonFormat
(
timezone
=
"GMT+8"
,
pattern
=
"yyyy-MM-dd HH:mm:ss"
)
private
LocalDateTime
startTime
;
// 实际开始时间
@JsonFormat
(
timezone
=
"GMT+8"
,
pattern
=
"yyyy-MM-dd HH:mm:ss"
)
private
LocalDateTime
endTime
;
// 实际结束时间
private
BigDecimal
quantity
;
// 加工数量
private
String
operationName
;
// 工序名称
private
String
equipName
;
// 设备名称
}
\ No newline at end of file
src/main/java/com/aps/entity/Schedule/HolidayDTO.java
0 → 100644
View file @
1dd2520c
package
com
.
aps
.
entity
.
Schedule
;
import
io.swagger.v3.oas.annotations.media.Schema
;
import
lombok.Data
;
import
java.time.LocalDateTime
;
@Data
@Schema
(
name
=
"节假日信息"
,
description
=
"节假日信息"
)
public
class
HolidayDTO
{
@Schema
(
description
=
"开始时间"
)
private
LocalDateTime
start
;
@Schema
(
description
=
"结束时间"
)
private
LocalDateTime
end
;
}
\ No newline at end of file
src/main/java/com/aps/entity/Schedule/MachineVO.java
0 → 100644
View file @
1dd2520c
package
com
.
aps
.
entity
.
Schedule
;
import
io.swagger.v3.oas.annotations.media.Schema
;
import
lombok.Data
;
import
java.util.List
;
@Data
public
class
MachineVO
{
@Schema
(
description
=
"设备内部ID"
)
private
Integer
id
;
@Schema
(
description
=
"设备编码"
)
private
String
equipId
;
@Schema
(
description
=
"设备名称"
)
private
String
equipName
;
@Schema
(
description
=
"任务集合"
)
private
List
<
GenVO
>
tasks
;
}
\ No newline at end of file
src/main/java/com/aps/entity/Schedule/PlanResourceTaskGanttVO.java
0 → 100644
View file @
1dd2520c
package
com
.
aps
.
entity
.
Schedule
;
import
com.fasterxml.jackson.annotation.JsonFormat
;
import
io.swagger.v3.oas.annotations.media.Schema
;
import
lombok.Data
;
import
lombok.EqualsAndHashCode
;
import
lombok.experimental.Accessors
;
import
org.apache.ibatis.type.Alias
;
import
java.time.LocalDateTime
;
import
java.util.List
;
/**
* @author jvs
*/
@Data
@EqualsAndHashCode
(
callSuper
=
false
)
@Accessors
(
chain
=
true
)
@Schema
(
name
=
"排产结果可视化——资源任务甘特图"
,
description
=
"排产结果可视化——资源任务甘特图"
)
@Alias
(
"SchedulePlanResourceTaskGanttVO"
)
public
class
PlanResourceTaskGanttVO
{
@Schema
(
description
=
"任务计划最早开始时间"
)
@JsonFormat
(
timezone
=
"GMT+8"
,
pattern
=
"yyyy-MM-dd HH:mm:ss"
)
private
LocalDateTime
earliestTaskStartTime
;
@Schema
(
description
=
"最近任务派工截止时间"
)
@JsonFormat
(
timezone
=
"GMT+8"
,
pattern
=
"yyyy-MM-dd HH:mm:ss"
)
private
LocalDateTime
lastTaskAssignmentTime
;
@Schema
(
description
=
"资源任务集合"
)
private
List
<
MachineVO
>
resources
;
@Schema
(
description
=
"场景id"
)
private
Long
sceneId
;
}
\ No newline at end of file
src/main/java/com/aps/entity/Schedule/ScheduleRequest.java
0 → 100644
View file @
1dd2520c
// ScheduleRequest.java
package
com
.
aps
.
entity
.
Schedule
;
import
io.swagger.v3.oas.annotations.media.Schema
;
import
lombok.Data
;
import
java.time.LocalDateTime
;
import
java.util.List
;
@Data
@Schema
(
name
=
"调度请求参数"
,
description
=
"调度请求参数"
)
public
class
ScheduleRequest
{
@Schema
(
description
=
"开始时间"
,
example
=
"2025-10-01T00:00:00"
)
private
LocalDateTime
startTime
;
@Schema
(
description
=
"节假日列表"
)
private
List
<
HolidayDTO
>
holidays
;
@Schema
(
description
=
"是否运行所有算法"
,
example
=
"true"
)
private
boolean
runAll
=
false
;
}
src/main/java/com/aps/entity/Schedule/ScheduleResponse.java
0 → 100644
View file @
1dd2520c
package
com
.
aps
.
entity
.
Schedule
;
import
io.swagger.v3.oas.annotations.media.Schema
;
import
lombok.Data
;
import
java.util.List
;
@Data
@Schema
(
name
=
"调度响应结果"
,
description
=
"调度响应结果"
)
public
class
ScheduleResponse
{
@Schema
(
description
=
"成功标志"
)
private
boolean
success
;
@Schema
(
description
=
"返回消息"
)
private
String
message
;
@Schema
(
description
=
"单个调度结果"
)
private
ScheduleResult
singleResult
;
@Schema
(
description
=
"所有调度结果"
)
private
List
<
ScheduleResultList
>
allResults
;
@Schema
(
description
=
"缓存大小"
)
private
Integer
cacheSize
;
}
\ No newline at end of file
src/main/java/com/aps/entity/Schedule/ScheduleResult.java
0 → 100644
View file @
1dd2520c
package
com
.
aps
.
entity
.
Schedule
;
import
io.swagger.v3.oas.annotations.media.Schema
;
import
lombok.Data
;
@Data
@Schema
(
name
=
"调度结果详情"
,
description
=
"调度结果详情"
)
public
class
ScheduleResult
{
@Schema
(
description
=
"适应度分数"
)
private
Double
fitness
;
@Schema
(
description
=
"调度摘要"
)
private
String
summary
;
@Schema
(
description
=
"算法运行ID"
)
private
String
runId
;
}
\ No newline at end of file
src/main/java/com/aps/entity/Schedule/ScheduleResultList.java
0 → 100644
View file @
1dd2520c
package
com
.
aps
.
entity
.
Schedule
;
import
com.aps.entity.basic.ScheduleChromosome
;
import
io.swagger.v3.oas.annotations.media.Schema
;
import
lombok.Data
;
@Data
@Schema
(
name
=
"调度结果"
,
description
=
"调度结果"
)
public
class
ScheduleResultList
{
@Schema
(
description
=
"计划详情"
)
private
ScheduleChromosome
chromosomeList
;
@Schema
(
description
=
"运算ID"
)
private
String
runId
;
}
\ No newline at end of file
src/main/java/com/aps/entity/ScheduledTask.java
0 → 100644
View file @
1dd2520c
package
com
.
aps
.
entity
;
import
com.fasterxml.jackson.annotation.JsonFormat
;
import
lombok.Data
;
import
java.math.BigDecimal
;
import
java.time.LocalDateTime
;
@Data
public
class
ScheduledTask
{
private
String
orderId
;
// 工单ID
private
Integer
operationId
;
// 工序ID
private
Integer
equipId
;
// 设备ID
@JsonFormat
(
timezone
=
"GMT+8"
,
pattern
=
"yyyy-MM-dd HH:mm:ss"
)
private
LocalDateTime
startTime
;
// 实际开始时间
@JsonFormat
(
timezone
=
"GMT+8"
,
pattern
=
"yyyy-MM-dd HH:mm:ss"
)
private
LocalDateTime
endTime
;
// 实际结束时间
private
BigDecimal
quantity
;
// 加工数量
private
BigDecimal
utilization
;
// 加工效率
private
String
routeId
;
// 工艺路线ID
private
String
operationName
;
// 工序名称
private
String
equipName
;
// 设备名称
}
\ No newline at end of file
src/main/java/com/aps/entity/basic/Gene.java
0 → 100644
View file @
1dd2520c
package
com
.
aps
.
entity
.
basic
;
import
lombok.Data
;
import
java.util.List
;
/**
* 基因表示
*/
@Data
public
class
Gene
{
private
int
orderId
;
private
int
productId
;
private
int
operationId
;
private
int
machineId
;
private
int
startTime
;
// 相对开始时间(分钟)
private
int
endTime
;
// 相对结束时间(分钟)
private
int
batchSize
;
// 批次大小(订单可拆分)
private
List
<
GeneDetail
>
geneDetails
;
// 时间详情
private
int
processingTime
;
// 绝对处理时间(分钟)
}
\ No newline at end of file
src/main/java/com/aps/entity/basic/GeneDetail.java
0 → 100644
View file @
1dd2520c
package
com
.
aps
.
entity
.
basic
;
import
lombok.Data
;
@Data
public
class
GeneDetail
{
private
String
key
;
private
int
startTime
;
// 相对开始时间(分钟)
private
int
endTime
;
// 相对结束时间(分钟)
}
\ No newline at end of file
src/main/java/com/aps/entity/basic/Holiday.java
0 → 100644
View file @
1dd2520c
package
com
.
aps
.
entity
.
basic
;
import
java.time.LocalDateTime
;
public
class
Holiday
{
private
LocalDateTime
start
;
private
LocalDateTime
end
;
public
Holiday
()
{}
public
Holiday
(
LocalDateTime
start
,
LocalDateTime
end
)
{
this
.
start
=
start
;
this
.
end
=
end
;
}
public
LocalDateTime
getStart
()
{
return
start
;
}
public
void
setStart
(
LocalDateTime
start
)
{
this
.
start
=
start
;
}
public
LocalDateTime
getEnd
()
{
return
end
;
}
public
void
setEnd
(
LocalDateTime
end
)
{
this
.
end
=
end
;
}
}
\ No newline at end of file
src/main/java/com/aps/entity/basic/Machine.java
0 → 100644
View file @
1dd2520c
package
com
.
aps
.
entity
.
basic
;
import
lombok.Data
;
import
java.util.ArrayList
;
import
java.util.List
;
import
java.util.Objects
;
import
java.util.function.Consumer
;
@Data
public
class
Machine
{
private
int
id
;
private
String
name
;
private
int
earliestTime
=
0
;
private
int
totalTaskTime
=
0
;
private
List
<
Shift
>
shifts
;
private
List
<
MaintenanceWindow
>
maintenanceWindows
;
private
List
<
TimeSegment
>
availability
;
// 事件回调
private
Consumer
<
Void
>
shiftsChanged
;
private
Consumer
<
Void
>
maintenanceWindowsChanged
;
public
Machine
()
{
this
.
shifts
=
new
ArrayList
<>();
this
.
maintenanceWindows
=
new
ArrayList
<>();
this
.
availability
=
new
ArrayList
<>();
}
public
Machine
(
int
id
,
String
name
)
{
this
();
this
.
id
=
id
;
this
.
name
=
name
;
}
// 添加维护窗口的方法
public
void
addMaintenanceWindow
(
MaintenanceWindow
window
)
{
maintenanceWindows
.
add
(
window
);
if
(
maintenanceWindowsChanged
!=
null
)
{
maintenanceWindowsChanged
.
accept
(
null
);
}
}
public
void
addShift
(
Shift
shift
)
{
shifts
.
add
(
shift
);
if
(
shiftsChanged
!=
null
)
{
shiftsChanged
.
accept
(
null
);
}
}
// 重写equals和hashCode方法,只基于id进行比较
@Override
public
boolean
equals
(
Object
o
)
{
if
(
this
==
o
)
return
true
;
if
(
o
==
null
||
getClass
()
!=
o
.
getClass
())
return
false
;
Machine
machine
=
(
Machine
)
o
;
return
id
==
machine
.
id
;
}
@Override
public
int
hashCode
()
{
return
Objects
.
hash
(
id
);
}
}
\ No newline at end of file
src/main/java/com/aps/entity/basic/MachineOption.java
0 → 100644
View file @
1dd2520c
package
com
.
aps
.
entity
.
basic
;
import
lombok.Data
;
/**
* 设备选项
*/
@Data
public
class
MachineOption
{
private
int
machineId
;
private
int
processingTime
;
// 加工时间
private
int
setupTime
;
// 换型时间(如果与前一个产品不同)
}
\ No newline at end of file
src/main/java/com/aps/entity/basic/MachineTimeline.java
0 → 100644
View file @
1dd2520c
package
com
.
aps
.
entity
.
basic
;
import
java.time.LocalDateTime
;
import
java.util.ArrayList
;
import
java.util.List
;
import
java.util.Objects
;
public
class
MachineTimeline
{
private
int
machineId
;
private
List
<
TimeSegment
>
segments
;
private
LocalDateTime
validFrom
;
private
LocalDateTime
validTo
;
private
LocalDateTime
lastUpdated
;
private
int
version
=
1
;
public
MachineTimeline
()
{
this
.
segments
=
new
ArrayList
<>();
}
// Getters and Setters
public
int
getMachineId
()
{
return
machineId
;
}
public
void
setMachineId
(
int
machineId
)
{
this
.
machineId
=
machineId
;
}
public
List
<
TimeSegment
>
getSegments
()
{
return
segments
;
}
public
void
setSegments
(
List
<
TimeSegment
>
segments
)
{
this
.
segments
=
segments
;
}
public
LocalDateTime
getValidFrom
()
{
return
validFrom
;
}
public
void
setValidFrom
(
LocalDateTime
validFrom
)
{
this
.
validFrom
=
validFrom
;
}
public
LocalDateTime
getValidTo
()
{
return
validTo
;
}
public
void
setValidTo
(
LocalDateTime
validTo
)
{
this
.
validTo
=
validTo
;
}
public
LocalDateTime
getLastUpdated
()
{
return
lastUpdated
;
}
public
void
setLastUpdated
(
LocalDateTime
lastUpdated
)
{
this
.
lastUpdated
=
lastUpdated
;
}
public
int
getVersion
()
{
return
version
;
}
public
void
setVersion
(
int
version
)
{
this
.
version
=
version
;
}
@Override
public
boolean
equals
(
Object
o
)
{
if
(
this
==
o
)
return
true
;
if
(
o
==
null
||
getClass
()
!=
o
.
getClass
())
return
false
;
MachineTimeline
that
=
(
MachineTimeline
)
o
;
return
machineId
==
that
.
machineId
;
}
@Override
public
int
hashCode
()
{
return
Objects
.
hash
(
machineId
);
}
}
\ No newline at end of file
src/main/java/com/aps/entity/basic/MaintenanceWindow.java
0 → 100644
View file @
1dd2520c
package
com
.
aps
.
entity
.
basic
;
import
java.time.LocalDateTime
;
import
java.util.Objects
;
public
class
MaintenanceWindow
{
private
LocalDateTime
startTime
;
private
LocalDateTime
endTime
;
private
String
reason
;
public
MaintenanceWindow
()
{}
public
MaintenanceWindow
(
LocalDateTime
startTime
,
LocalDateTime
endTime
,
String
reason
)
{
this
.
startTime
=
startTime
;
this
.
endTime
=
endTime
;
this
.
reason
=
reason
;
}
// Getters and Setters
public
LocalDateTime
getStartTime
()
{
return
startTime
;
}
public
void
setStartTime
(
LocalDateTime
startTime
)
{
this
.
startTime
=
startTime
;
}
public
LocalDateTime
getEndTime
()
{
return
endTime
;
}
public
void
setEndTime
(
LocalDateTime
endTime
)
{
this
.
endTime
=
endTime
;
}
public
String
getReason
()
{
return
reason
;
}
public
void
setReason
(
String
reason
)
{
this
.
reason
=
reason
;
}
@Override
public
boolean
equals
(
Object
o
)
{
if
(
this
==
o
)
return
true
;
if
(
o
==
null
||
getClass
()
!=
o
.
getClass
())
return
false
;
MaintenanceWindow
that
=
(
MaintenanceWindow
)
o
;
return
Objects
.
equals
(
startTime
,
that
.
startTime
)
&&
Objects
.
equals
(
endTime
,
that
.
endTime
);
}
@Override
public
int
hashCode
()
{
return
Objects
.
hash
(
startTime
,
endTime
);
}
}
\ No newline at end of file
src/main/java/com/aps/entity/basic/Operation.java
0 → 100644
View file @
1dd2520c
package
com
.
aps
.
entity
.
basic
;
import
com.fasterxml.jackson.annotation.JsonProperty
;
import
lombok.Data
;
import
java.util.List
;
/**
* 工序定义
*/
@Data
public
class
Operation
{
@JsonProperty
(
"id"
)
private
int
id
;
@JsonProperty
(
"productId"
)
private
int
productId
;
@JsonProperty
(
"sequence"
)
private
int
sequence
;
// 工序顺序
@JsonProperty
(
"machineOptions"
)
private
List
<
MachineOption
>
machineOptions
;
// 可选设备列表
@JsonProperty
(
"isInterrupt"
)
private
boolean
isInterrupt
=
false
;
// 是否可中断,间缝插针
}
\ No newline at end of file
src/main/java/com/aps/entity/basic/Order.java
0 → 100644
View file @
1dd2520c
package
com
.
aps
.
entity
.
basic
;
import
lombok.Data
;
import
java.time.LocalDateTime
;
import
java.time.OffsetDateTime
;
/**
* 订单定义
*/
@Data
public
class
Order
{
private
int
id
;
private
int
productId
;
private
int
quantity
=
100
;
// 100个
private
OffsetDateTime
dueDate
;
private
LocalDateTime
orderCompletion
;
private
double
tardiness
;
private
int
priority
;
private
boolean
canSplit
=
false
;
private
boolean
canInterrupt
=
false
;
}
\ No newline at end of file
src/main/java/com/aps/entity/basic/Product.java
0 → 100644
View file @
1dd2520c
package
com
.
aps
.
entity
.
basic
;
import
lombok.Data
;
import
java.util.List
;
/**
* 产品定义
*/
@Data
public
class
Product
{
private
int
id
;
private
String
name
;
private
List
<
Operation
>
operations
;
// 工序列表,顺序代表工序顺序约束
}
\ No newline at end of file
src/main/java/com/aps/entity/basic/ScheduleChromosome.java
0 → 100644
View file @
1dd2520c
package
com
.
aps
.
entity
.
basic
;
import
lombok.Data
;
import
java.time.LocalDateTime
;
import
java.util.*
;
import
java.util.stream.Collectors
;
@Data
public
class
ScheduleChromosome
{
private
List
<
Gene
>
genes
;
private
List
<
Order
>
orders
;
private
List
<
Machine
>
machines
;
private
double
fitness
;
private
double
tardiness
;
private
Map
<
Integer
,
Double
>
objectiveValues
;
private
LocalDateTime
baseTime
;
public
ScheduleChromosome
()
{
this
.
genes
=
new
ArrayList
<>();
this
.
objectiveValues
=
new
HashMap
<>();
}
public
ScheduleChromosome
(
LocalDateTime
baseTime
)
{
this
();
this
.
baseTime
=
baseTime
;
}
// 修改:放宽去重条件,包含更多关键信息
// public String getGenesStr() {
// return genes.stream()
// .sorted(Comparator.comparing(Gene::getOrderId)
// .thenComparing(Gene::getOperationId)
// .thenComparing(Gene::getStartTime))
// .map(p -> String.format("%d:%d:%d:%d:%d:%d",
// p.getOrderId(), p.getOperationId(), p.getMachineId(),
// p.getBatchSize(), p.getStartTime(), p.getEndTime()))
// .collect(Collectors.joining(";"));
// }
public
String
getGenesStr
()
{
return
getGenes
().
stream
()
.
sorted
(
Comparator
.
comparing
(
Gene:
:
getOrderId
)
.
thenComparing
(
Gene:
:
getOperationId
)
.
thenComparing
(
Gene:
:
getMachineId
))
.
map
(
g
->
String
.
format
(
"%d:%d:%d"
,
g
.
getOrderId
(),
g
.
getOperationId
(),
g
.
getMachineId
()))
.
collect
(
Collectors
.
joining
(
"; "
));
}
// 新增:生成更详细的键用于调试
public
String
getDetailedKey
()
{
return
genes
.
stream
()
.
sorted
(
Comparator
.
comparing
(
Gene:
:
getOrderId
)
.
thenComparing
(
Gene:
:
getOperationId
)
.
thenComparing
(
Gene:
:
getStartTime
))
.
map
(
g
->
String
.
format
(
"O%d-P%d-M%d-B%d-S%d-E%d"
,
g
.
getOrderId
(),
g
.
getOperationId
(),
g
.
getMachineId
(),
g
.
getBatchSize
(),
g
.
getStartTime
(),
g
.
getEndTime
()))
.
collect
(
Collectors
.
joining
(
"_"
));
}
public
List
<
Order
>
getOrders
()
{
return
calTardiness
();
}
// private List<Order> calTardiness() {
// tardiness = 0;
//
// for (Order order : orders) {
// final int orderId = order.getId();
// List<Gene> orderGroups = genes.stream()
// .filter(g -> g.getOrderId() == orderId)
// .collect(Collectors.toList());
//
// int orderCompletion = orderGroups.stream()
// .mapToInt(Gene::getEndTime)
// .max()
// .orElse(0);
//
// LocalDateTime orderCompletionTime = baseTime.plusMinutes(orderCompletion);
// order.setOrderCompletion(orderCompletionTime);
// order.setTardiness(0);
//
// if (orderCompletionTime.isAfter(order.getDueDate().toLocalDateTime())) {
// long diffHours = java.time.temporal.ChronoUnit.HOURS.between(order.getDueDate(), orderCompletionTime);
// double tardinessHours = diffHours + (double) java.time.temporal.ChronoUnit.MINUTES.between(order.getDueDate(), orderCompletionTime) % 60 / 60;
// order.setTardiness(tardinessHours);
// tardiness += tardinessHours;
// }
// }
// return orders;
// }
private
List
<
Order
>
calTardiness
()
{
tardiness
=
0
;
for
(
Order
order
:
orders
)
{
final
int
orderId
=
order
.
getId
();
List
<
Gene
>
orderGroups
=
genes
.
stream
()
.
filter
(
g
->
g
.
getOrderId
()
==
orderId
)
.
collect
(
Collectors
.
toList
());
int
orderCompletion
=
orderGroups
.
stream
()
.
mapToInt
(
Gene:
:
getEndTime
)
.
max
()
.
orElse
(
0
);
LocalDateTime
orderCompletionTime
=
baseTime
.
plusMinutes
(
orderCompletion
);
order
.
setOrderCompletion
(
orderCompletionTime
);
order
.
setTardiness
(
0
);
// 修复:统一时间类型
LocalDateTime
dueDateTime
=
order
.
getDueDate
().
toLocalDateTime
();
if
(
orderCompletionTime
.
isAfter
(
dueDateTime
))
{
// 方法1:使用分钟计算再转换为小时(推荐)
long
totalMinutes
=
java
.
time
.
temporal
.
ChronoUnit
.
MINUTES
.
between
(
dueDateTime
,
orderCompletionTime
);
double
tardinessHours
=
totalMinutes
/
60.0
;
// 方法2:或者保持原有逻辑但使用统一的时间类型
// long diffHours = java.time.temporal.ChronoUnit.HOURS.between(dueDateTime, orderCompletionTime);
// long remainingMinutes = java.time.temporal.ChronoUnit.MINUTES.between(dueDateTime, orderCompletionTime) % 60;
// double tardinessHours = diffHours + (double) remainingMinutes / 60;
order
.
setTardiness
(
tardinessHours
);
tardiness
+=
tardinessHours
;
}
}
return
orders
;
}
}
\ No newline at end of file
src/main/java/com/aps/entity/basic/SegmentType.java
0 → 100644
View file @
1dd2520c
package
com
.
aps
.
entity
.
basic
;
public
enum
SegmentType
{
REGULAR
,
// 常规班次
TEMP
,
// 临时班次(优先级高)
MAINTENANCE
// 维护窗口(不可用)
}
\ No newline at end of file
src/main/java/com/aps/entity/basic/Shift.java
0 → 100644
View file @
1dd2520c
package
com
.
aps
.
entity
.
basic
;
import
java.time.DayOfWeek
;
import
java.time.LocalDateTime
;
import
java.time.LocalTime
;
import
java.util.Set
;
public
class
Shift
{
private
LocalTime
startTime
;
private
LocalTime
endTime
;
private
Set
<
Integer
>
days
;
// 改为Integer类型,便于JSON反序列化
private
LocalDateTime
shiftDate
;
private
boolean
isTemporaryShift
;
private
int
priority
;
public
Shift
()
{}
public
LocalTime
getStartTime
()
{
return
startTime
;
}
public
void
setStartTime
(
LocalTime
startTime
)
{
this
.
startTime
=
startTime
;
}
public
LocalTime
getEndTime
()
{
return
endTime
;
}
public
void
setEndTime
(
LocalTime
endTime
)
{
this
.
endTime
=
endTime
;
}
public
Set
<
Integer
>
getDays
()
{
return
days
;
}
public
void
setDays
(
Set
<
Integer
>
days
)
{
this
.
days
=
days
;
}
// 辅助方法:将数字转换为DayOfWeek
public
Set
<
DayOfWeek
>
getDaysAsEnum
()
{
if
(
days
==
null
)
return
null
;
return
days
.
stream
()
.
map
(
day
->
DayOfWeek
.
of
(
day
==
0
?
7
:
day
))
// 处理周日(0)转换为7
.
collect
(
java
.
util
.
stream
.
Collectors
.
toSet
());
}
public
LocalDateTime
getShiftDate
()
{
return
shiftDate
;
}
public
void
setShiftDate
(
LocalDateTime
shiftDate
)
{
this
.
shiftDate
=
shiftDate
;
}
public
boolean
isTemporaryShift
()
{
return
isTemporaryShift
;
}
public
void
setTemporaryShift
(
boolean
temporaryShift
)
{
isTemporaryShift
=
temporaryShift
;
}
public
int
getPriority
()
{
return
priority
;
}
public
void
setPriority
(
int
priority
)
{
this
.
priority
=
priority
;
}
}
\ No newline at end of file
src/main/java/com/aps/entity/basic/TimeSegment.java
0 → 100644
View file @
1dd2520c
package
com
.
aps
.
entity
.
basic
;
import
lombok.Data
;
import
java.time.LocalDateTime
;
import
java.util.UUID
;
/**
* 时间段(设备的时间片段,标记可用/不可用状态)
*/
@Data
public
class
TimeSegment
{
private
String
key
=
UUID
.
randomUUID
().
toString
();
// 时间段唯一标识(如"Machine-1_20251008_1000")
private
LocalDateTime
start
;
// 时间段开始时间
private
LocalDateTime
end
;
// 时间段结束时间
private
int
earliestTime
;
// 该时段内最早可用时间(分钟)
private
int
totalTaskTime
;
// 该时段内已分配任务时间(分钟)
private
SegmentType
type
;
// 时间段类型(关联SegmentType枚举)
private
boolean
isHoliday
;
// 是否节假日(true=节假日)
private
boolean
isUsed
;
// 是否已被占用(true=已分配任务)
// 无参构造(Lombok默认生成)
public
TimeSegment
()
{}
// 全参构造(按需添加)
public
TimeSegment
(
LocalDateTime
start
,
LocalDateTime
end
,
SegmentType
type
,
boolean
isHoliday
)
{
this
.
start
=
start
;
this
.
end
=
end
;
this
.
type
=
type
;
this
.
isHoliday
=
isHoliday
;
}
public
TimeSegment
(
String
key
,
LocalDateTime
start
,
LocalDateTime
end
,
int
earliestTime
,
int
totalTaskTime
,
SegmentType
type
,
boolean
isHoliday
,
boolean
isUsed
)
{
this
.
key
=
key
;
this
.
start
=
start
;
this
.
end
=
end
;
this
.
earliestTime
=
earliestTime
;
this
.
totalTaskTime
=
totalTaskTime
;
this
.
type
=
type
;
this
.
isHoliday
=
isHoliday
;
this
.
isUsed
=
isUsed
;
}
}
\ No newline at end of file
src/main/java/com/
example
/entity/codeGeneratorEntity/DatabaseConfig.java
→
src/main/java/com/
aps
/entity/codeGeneratorEntity/DatabaseConfig.java
View file @
1dd2520c
package
com
.
example
.
entity
.
codeGeneratorEntity
;
package
com
.
aps
.
entity
.
codeGeneratorEntity
;
public
class
DatabaseConfig
{
public
class
DatabaseConfig
{
private
String
url
;
private
String
url
;
...
...
src/main/java/com/
example
/entity/codeGeneratorEntity/GenerateRequest.java
→
src/main/java/com/
aps
/entity/codeGeneratorEntity/GenerateRequest.java
View file @
1dd2520c
package
com
.
example
.
entity
.
codeGeneratorEntity
;
package
com
.
aps
.
entity
.
codeGeneratorEntity
;
import
java.util.List
;
import
java.util.List
;
...
@@ -22,4 +22,4 @@ public class GenerateRequest {
...
@@ -22,4 +22,4 @@ public class GenerateRequest {
public
void
setAuthor
(
String
author
)
{
this
.
author
=
author
;
}
public
void
setAuthor
(
String
author
)
{
this
.
author
=
author
;
}
public
boolean
isOverwrite
()
{
return
overwrite
;
}
public
boolean
isOverwrite
()
{
return
overwrite
;
}
public
void
setOverwrite
(
boolean
overwrite
)
{
this
.
overwrite
=
overwrite
;
}
public
void
setOverwrite
(
boolean
overwrite
)
{
this
.
overwrite
=
overwrite
;
}
}
}
\ No newline at end of file
src/main/java/com/
example
/generator/CodeGenerator.java
→
src/main/java/com/
aps
/generator/CodeGenerator.java
View file @
1dd2520c
package
com
.
example
.
generator
;
package
com
.
aps
.
generator
;
import
com.baomidou.mybatisplus.generator.FastAutoGenerator
;
import
com.baomidou.mybatisplus.generator.FastAutoGenerator
;
import
com.baomidou.mybatisplus.generator.config.OutputFile
;
import
com.baomidou.mybatisplus.generator.config.OutputFile
;
...
@@ -21,7 +21,7 @@ public class CodeGenerator {
...
@@ -21,7 +21,7 @@ public class CodeGenerator {
})
})
// 3. 包配置(指定代码存放的包路径)
// 3. 包配置(指定代码存放的包路径)
.
packageConfig
(
builder
->
{
.
packageConfig
(
builder
->
{
builder
.
parent
(
"com.
example
"
)
// 父包名
builder
.
parent
(
"com.
aps
"
)
// 父包名
.
entity
(
"entity"
)
// 实体类包
.
entity
(
"entity"
)
// 实体类包
.
mapper
(
"mapper"
)
// Mapper接口包
.
mapper
(
"mapper"
)
// Mapper接口包
.
service
(
"service"
)
// Service接口包
.
service
(
"service"
)
// Service接口包
...
@@ -56,4 +56,4 @@ public class CodeGenerator {
...
@@ -56,4 +56,4 @@ public class CodeGenerator {
// 执行生成
// 执行生成
.
execute
();
.
execute
();
}
}
}
}
\ No newline at end of file
src/main/java/com/
example
/generator/CodeGenerator1.java
→
src/main/java/com/
aps
/generator/CodeGenerator1.java
View file @
1dd2520c
package
com
.
example
.
generator
;
package
com
.
aps
.
generator
;
import
com.baomidou.mybatisplus.generator.FastAutoGenerator
;
import
com.baomidou.mybatisplus.generator.FastAutoGenerator
;
import
com.baomidou.mybatisplus.generator.config.OutputFile
;
import
com.baomidou.mybatisplus.generator.config.OutputFile
;
...
@@ -21,7 +21,7 @@ public class CodeGenerator1 {
...
@@ -21,7 +21,7 @@ public class CodeGenerator1 {
})
})
// 3. 包配置
// 3. 包配置
.
packageConfig
(
builder
->
{
.
packageConfig
(
builder
->
{
builder
.
parent
(
"com.
example
"
)
// 父包名
builder
.
parent
(
"com.
aps
"
)
// 父包名
.
entity
(
"entity"
)
// 实体类包
.
entity
(
"entity"
)
// 实体类包
.
mapper
(
"mapper"
)
// Mapper接口包
.
mapper
(
"mapper"
)
// Mapper接口包
.
service
(
"service"
)
// Service接口包
.
service
(
"service"
)
// Service接口包
...
@@ -29,7 +29,7 @@ public class CodeGenerator1 {
...
@@ -29,7 +29,7 @@ public class CodeGenerator1 {
.
controller
(
"controller"
)
// Controller包
.
controller
(
"controller"
)
// Controller包
// Mapper XML文件输出路径
// Mapper XML文件输出路径
.
pathInfo
(
Collections
.
singletonMap
(
.
pathInfo
(
Collections
.
singletonMap
(
OutputFile
.
xml
,
OutputFile
.
xml
,
System
.
getProperty
(
"user.dir"
)
+
"/src/main/resources/mapper"
System
.
getProperty
(
"user.dir"
)
+
"/src/main/resources/mapper"
));
));
})
})
...
@@ -55,7 +55,7 @@ public class CodeGenerator1 {
...
@@ -55,7 +55,7 @@ public class CodeGenerator1 {
.
templateEngine
(
new
VelocityTemplateEngine
())
.
templateEngine
(
new
VelocityTemplateEngine
())
// 执行生成
// 执行生成
.
execute
();
.
execute
();
System
.
out
.
println
(
"代码生成完成
!
"
);
System
.
out
.
println
(
"代码生成完成
!
"
);
}
}
}
}
\ No newline at end of file
src/main/java/com/
example
/mapper/DepartmentMapper.java
→
src/main/java/com/
aps
/mapper/DepartmentMapper.java
View file @
1dd2520c
package
com
.
example
.
mapper
;
package
com
.
aps
.
mapper
;
import
com.
example
.entity.Department
;
import
com.
aps
.entity.Department
;
import
com.baomidou.mybatisplus.core.mapper.BaseMapper
;
import
com.baomidou.mybatisplus.core.mapper.BaseMapper
;
/**
/**
...
...
src/main/java/com/aps/mapper/EquipinfoMapper.java
0 → 100644
View file @
1dd2520c
package
com
.
aps
.
mapper
;
import
com.aps.entity.Equipinfo
;
import
com.baomidou.mybatisplus.core.mapper.BaseMapper
;
/**
* <p>
* Mapper 接口
* </p>
*
* @author MyBatis-Plus
* @since 2025-10-09
*/
public
interface
EquipinfoMapper
extends
BaseMapper
<
Equipinfo
>
{
}
src/main/java/com/
example
/mapper/MaterialInfoMapper.java
→
src/main/java/com/
aps
/mapper/MaterialInfoMapper.java
View file @
1dd2520c
package
com
.
example
.
mapper
;
package
com
.
aps
.
mapper
;
import
com.
example
.entity.MaterialInfo
;
import
com.
aps
.entity.MaterialInfo
;
import
com.baomidou.mybatisplus.core.mapper.BaseMapper
;
import
com.baomidou.mybatisplus.core.mapper.BaseMapper
;
/**
/**
...
...
src/main/java/com/aps/mapper/MesShiftWorkSchedMapper.java
0 → 100644
View file @
1dd2520c
package
com
.
aps
.
mapper
;
import
com.aps.entity.MesShiftWorkSched
;
import
com.baomidou.mybatisplus.core.mapper.BaseMapper
;
/**
* <p>
* 班次表 Mapper 接口
* </p>
*
* @author MyBatis-Plus
* @since 2025-10-10
*/
public
interface
MesShiftWorkSchedMapper
extends
BaseMapper
<
MesShiftWorkSched
>
{
}
\ No newline at end of file
src/main/java/com/aps/mapper/MpsplannedorderMapper.java
0 → 100644
View file @
1dd2520c
package
com
.
aps
.
mapper
;
import
com.aps.entity.Mpsplannedorder
;
import
com.baomidou.mybatisplus.core.mapper.BaseMapper
;
/**
* <p>
* Mapper 接口
* </p>
*
* @author MyBatis-Plus
* @since 2025-10-14
*/
public
interface
MpsplannedorderMapper
extends
BaseMapper
<
Mpsplannedorder
>
{
}
src/main/java/com/aps/mapper/PlanResourceMapper.java
0 → 100644
View file @
1dd2520c
package
com
.
aps
.
mapper
;
import
com.aps.entity.PlanResource
;
import
com.baomidou.mybatisplus.core.mapper.BaseMapper
;
/**
* <p>
* Mapper 接口
* </p>
*
* @author MyBatis-Plus
* @since 2025-10-10
*/
public
interface
PlanResourceMapper
extends
BaseMapper
<
PlanResource
>
{
}
src/main/java/com/aps/mapper/RoutingDetailEquipMapper.java
0 → 100644
View file @
1dd2520c
package
com
.
aps
.
mapper
;
import
com.aps.entity.RoutingDetailEquip
;
import
com.baomidou.mybatisplus.core.mapper.BaseMapper
;
/**
* <p>
* 工序可用设备 Mapper 接口
* </p>
*
* @author MyBatis-Plus
* @since 2025-10-10
*/
public
interface
RoutingDetailEquipMapper
extends
BaseMapper
<
RoutingDetailEquip
>
{
}
src/main/java/com/aps/mapper/RoutingDetailMapper.java
0 → 100644
View file @
1dd2520c
package
com
.
aps
.
mapper
;
import
com.aps.entity.RoutingDetail
;
import
com.baomidou.mybatisplus.core.mapper.BaseMapper
;
/**
* <p>
* Mapper 接口
* </p>
*
* @author MyBatis-Plus
* @since 2025-10-14
*/
public
interface
RoutingDetailMapper
extends
BaseMapper
<
RoutingDetail
>
{
}
src/main/java/com/aps/mapper/RoutingHeaderMapper.java
0 → 100644
View file @
1dd2520c
package
com
.
aps
.
mapper
;
import
com.aps.entity.RoutingHeader
;
import
com.baomidou.mybatisplus.core.mapper.BaseMapper
;
/**
* <p>
* Mapper 接口
* </p>
*
* @author MyBatis-Plus
* @since 2025-10-09
*/
public
interface
RoutingHeaderMapper
extends
BaseMapper
<
RoutingHeader
>
{
}
src/main/java/com/aps/mapper/RoutingStepMapper.java
0 → 100644
View file @
1dd2520c
package
com
.
aps
.
mapper
;
import
com.aps.entity.RoutingStep
;
import
com.baomidou.mybatisplus.core.mapper.BaseMapper
;
/**
* <p>
* Mapper 接口
* </p>
*
* @author MyBatis-Plus
* @since 2025-10-10
*/
public
interface
RoutingStepMapper
extends
BaseMapper
<
RoutingStep
>
{
}
src/main/java/com/
example
/service/DepartmentService.java
→
src/main/java/com/
aps
/service/DepartmentService.java
View file @
1dd2520c
package
com
.
example
.
service
;
package
com
.
aps
.
service
;
import
com.
example
.entity.Department
;
import
com.
aps
.entity.Department
;
import
com.baomidou.mybatisplus.extension.service.IService
;
import
com.baomidou.mybatisplus.extension.service.IService
;
/**
/**
...
@@ -13,4 +13,4 @@ import com.baomidou.mybatisplus.extension.service.IService;
...
@@ -13,4 +13,4 @@ import com.baomidou.mybatisplus.extension.service.IService;
*/
*/
public
interface
DepartmentService
extends
IService
<
Department
>
{
public
interface
DepartmentService
extends
IService
<
Department
>
{
}
}
\ No newline at end of file
src/main/java/com/aps/service/EquipinfoService.java
0 → 100644
View file @
1dd2520c
package
com
.
aps
.
service
;
import
com.aps.entity.Equipinfo
;
import
com.baomidou.mybatisplus.extension.service.IService
;
/**
* <p>
* 服务类
* </p>
*
* @author MyBatis-Plus
* @since 2025-10-09
*/
public
interface
EquipinfoService
extends
IService
<
Equipinfo
>
{
}
\ No newline at end of file
src/main/java/com/
example
/service/MaterialInfoService.java
→
src/main/java/com/
aps
/service/MaterialInfoService.java
View file @
1dd2520c
package
com
.
example
.
service
;
package
com
.
aps
.
service
;
import
com.
example
.entity.MaterialInfo
;
import
com.
aps
.entity.MaterialInfo
;
import
com.baomidou.mybatisplus.extension.service.IService
;
import
com.baomidou.mybatisplus.extension.service.IService
;
/**
/**
...
@@ -13,4 +13,4 @@ import com.baomidou.mybatisplus.extension.service.IService;
...
@@ -13,4 +13,4 @@ import com.baomidou.mybatisplus.extension.service.IService;
*/
*/
public
interface
MaterialInfoService
extends
IService
<
MaterialInfo
>
{
public
interface
MaterialInfoService
extends
IService
<
MaterialInfo
>
{
}
}
\ No newline at end of file
src/main/java/com/aps/service/MesShiftWorkSchedService.java
0 → 100644
View file @
1dd2520c
package
com
.
aps
.
service
;
import
com.aps.entity.MesShiftWorkSched
;
import
com.baomidou.mybatisplus.extension.service.IService
;
/**
* <p>
* 班次表 服务类
* </p>
*
* @author MyBatis-Plus
* @since 2025-10-10
*/
public
interface
MesShiftWorkSchedService
extends
IService
<
MesShiftWorkSched
>
{
}
\ No newline at end of file
src/main/java/com/aps/service/MpsplannedorderService.java
0 → 100644
View file @
1dd2520c
package
com
.
aps
.
service
;
import
com.aps.entity.Mpsplannedorder
;
import
com.baomidou.mybatisplus.extension.service.IService
;
/**
* <p>
* 服务类
* </p>
*
* @author MyBatis-Plus
* @since 2025-10-14
*/
public
interface
MpsplannedorderService
extends
IService
<
Mpsplannedorder
>
{
}
\ No newline at end of file
src/main/java/com/aps/service/PlanResourceService.java
0 → 100644
View file @
1dd2520c
package
com
.
aps
.
service
;
import
com.aps.entity.PlanResource
;
import
com.baomidou.mybatisplus.extension.service.IService
;
/**
* <p>
* 服务类
* </p>
*
* @author MyBatis-Plus
* @since 2025-10-10
*/
public
interface
PlanResourceService
extends
IService
<
PlanResource
>
{
}
\ No newline at end of file
src/main/java/com/aps/service/RoutingDetailEquipService.java
0 → 100644
View file @
1dd2520c
package
com
.
aps
.
service
;
import
com.aps.entity.RoutingDetailEquip
;
import
com.baomidou.mybatisplus.extension.service.IService
;
/**
* <p>
* 工序可用设备 服务类
* </p>
*
* @author MyBatis-Plus
* @since 2025-10-10
*/
public
interface
RoutingDetailEquipService
extends
IService
<
RoutingDetailEquip
>
{
}
\ No newline at end of file
src/main/java/com/aps/service/RoutingDetailService.java
0 → 100644
View file @
1dd2520c
package
com
.
aps
.
service
;
import
com.aps.entity.RoutingDetail
;
import
com.baomidou.mybatisplus.extension.service.IService
;
/**
* <p>
* 服务类
* </p>
*
* @author MyBatis-Plus
* @since 2025-10-14
*/
public
interface
RoutingDetailService
extends
IService
<
RoutingDetail
>
{
}
\ No newline at end of file
src/main/java/com/aps/service/RoutingHeaderService.java
0 → 100644
View file @
1dd2520c
package
com
.
aps
.
service
;
import
com.aps.entity.RoutingHeader
;
import
com.baomidou.mybatisplus.extension.service.IService
;
/**
* <p>
* 服务类
* </p>
*
* @author MyBatis-Plus
* @since 2025-10-09
*/
public
interface
RoutingHeaderService
extends
IService
<
RoutingHeader
>
{
}
\ No newline at end of file
src/main/java/com/aps/service/RoutingStepService.java
0 → 100644
View file @
1dd2520c
package
com
.
aps
.
service
;
import
com.aps.entity.RoutingStep
;
import
com.baomidou.mybatisplus.extension.service.IService
;
/**
* <p>
* 服务类
* </p>
*
* @author MyBatis-Plus
* @since 2025-10-10
*/
public
interface
RoutingStepService
extends
IService
<
RoutingStep
>
{
}
\ No newline at end of file
src/main/java/com/aps/service/ScheduleService.java
0 → 100644
View file @
1dd2520c
package
com
.
aps
.
service
;
import
com.aps.entity.*
;
import
java.util.List
;
public
interface
ScheduleService
{
public
List
<
ScheduledTask
>
scheduleOrders
(
List
<
Mpsplannedorder
>
orders
,
List
<
RoutingHeader
>
processHeaders
,
List
<
RoutingDetail
>
operations
,
List
<
RoutingDetailEquip
>
operationEquipments
,
List
<
Equipinfo
>
equipments
);
}
src/main/java/com/
example
/service/codeGeneratorService/CodeGeneratorService.java
→
src/main/java/com/
aps
/service/codeGeneratorService/CodeGeneratorService.java
View file @
1dd2520c
package
com
.
example
.
service
.
codeGeneratorService
;
package
com
.
aps
.
service
.
codeGeneratorService
;
import
com.baomidou.mybatisplus.generator.FastAutoGenerator
;
import
com.baomidou.mybatisplus.generator.FastAutoGenerator
;
import
com.baomidou.mybatisplus.generator.config.OutputFile
;
import
com.baomidou.mybatisplus.generator.config.OutputFile
;
import
com.baomidou.mybatisplus.generator.config.rules.NamingStrategy
;
import
com.baomidou.mybatisplus.generator.config.rules.NamingStrategy
;
import
com.baomidou.mybatisplus.generator.engine.VelocityTemplateEngine
;
import
com.baomidou.mybatisplus.generator.engine.VelocityTemplateEngine
;
import
com.
example
.entity.codeGeneratorEntity.DatabaseConfig
;
import
com.
aps
.entity.codeGeneratorEntity.DatabaseConfig
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.stereotype.Service
;
import
org.springframework.stereotype.Service
;
import
java.util.Collections
;
import
java.util.Collections
;
import
java.util.List
;
import
java.util.List
;
@Service
@Service
public
class
CodeGeneratorService
{
public
class
CodeGeneratorService
{
...
@@ -65,6 +67,9 @@ public class CodeGeneratorService {
...
@@ -65,6 +67,9 @@ public class CodeGeneratorService {
.
enableBaseColumnList
();
.
enableBaseColumnList
();
})
})
.
templateEngine
(
new
VelocityTemplateEngine
())
.
templateEngine
(
new
VelocityTemplateEngine
())
// .templateConfig(builder -> {
// builder.entity("/templates/entity.java.vm"); // 指向自定义模板
// })
.
execute
();
.
execute
();
}
}
...
...
src/main/java/com/
example
/service/codeGeneratorService/DatabaseConfigService.java
→
src/main/java/com/
aps
/service/codeGeneratorService/DatabaseConfigService.java
View file @
1dd2520c
package
com
.
example
.
service
.
codeGeneratorService
;
package
com
.
aps
.
service
.
codeGeneratorService
;
import
com.
example
.entity.codeGeneratorEntity.DatabaseConfig
;
import
com.
aps
.entity.codeGeneratorEntity.DatabaseConfig
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.boot.context.properties.EnableConfigurationProperties
;
import
org.springframework.boot.context.properties.EnableConfigurationProperties
;
import
org.springframework.core.env.Environment
;
import
org.springframework.core.env.Environment
;
...
...
src/main/java/com/
example
/service/codeGeneratorService/DatabaseService.java
→
src/main/java/com/
aps
/service/codeGeneratorService/DatabaseService.java
View file @
1dd2520c
package
com
.
example
.
service
.
codeGeneratorService
;
package
com
.
aps
.
service
.
codeGeneratorService
;
import
com.
example
.entity.codeGeneratorEntity.DatabaseConfig
;
import
com.
aps
.entity.codeGeneratorEntity.DatabaseConfig
;
import
org.springframework.stereotype.Service
;
import
org.springframework.stereotype.Service
;
import
java.sql.Connection
;
import
java.sql.Connection
;
...
@@ -25,7 +25,41 @@ public class DatabaseService {
...
@@ -25,7 +25,41 @@ public class DatabaseService {
DatabaseMetaData
metaData
=
connection
.
getMetaData
();
DatabaseMetaData
metaData
=
connection
.
getMetaData
();
String
[]
types
=
{
"TABLE"
};
String
[]
types
=
{
"TABLE"
};
ResultSet
resultSet
=
metaData
.
getTables
(
null
,
null
,
"%"
,
types
);
// 根据不同数据库类型设置不同的schemaPattern参数
String
schemaPattern
=
null
;
String
catalog
=
null
;
if
(
"oracle"
.
equals
(
dbConfig
.
getDbType
()))
{
// Oracle数据库使用用户名作为schema
schemaPattern
=
dbConfig
.
getUsername
().
toUpperCase
();
}
else
if
(
"mysql"
.
equals
(
dbConfig
.
getDbType
()))
{
// MySQL从URL中提取数据库名作为catalog
String
url
=
dbConfig
.
getUrl
();
if
(
url
.
contains
(
"?"
))
{
url
=
url
.
substring
(
0
,
url
.
indexOf
(
"?"
));
}
if
(
url
.
contains
(
"/"
))
{
catalog
=
url
.
substring
(
url
.
lastIndexOf
(
"/"
)
+
1
);
}
}
else
if
(
"sqlserver"
.
equals
(
dbConfig
.
getDbType
()))
{
// SQL Server使用用户名作为schema,同时catalog设置为数据库名
schemaPattern
=
"dbo"
;
// SQL Server默认schema通常是dbo
// 从URL中提取数据库名作为catalog
String
url
=
dbConfig
.
getUrl
();
if
(
url
.
contains
(
";"
))
{
String
[]
parts
=
url
.
split
(
";"
);
for
(
String
part
:
parts
)
{
if
(
part
.
toLowerCase
().
startsWith
(
"databasename="
))
{
catalog
=
part
.
substring
(
part
.
indexOf
(
"="
)
+
1
);
break
;
}
}
}
}
ResultSet
resultSet
=
metaData
.
getTables
(
catalog
,
schemaPattern
,
"%"
,
types
);
while
(
resultSet
.
next
())
{
while
(
resultSet
.
next
())
{
String
tableName
=
resultSet
.
getString
(
"TABLE_NAME"
);
String
tableName
=
resultSet
.
getString
(
"TABLE_NAME"
);
...
...
src/main/java/com/
example
/service/impl/DepartmentServiceImpl.java
→
src/main/java/com/
aps
/service/impl/DepartmentServiceImpl.java
View file @
1dd2520c
package
com
.
example
.
service
.
impl
;
package
com
.
aps
.
service
.
impl
;
import
com.
example
.entity.Department
;
import
com.
aps
.entity.Department
;
import
com.
example
.mapper.DepartmentMapper
;
import
com.
aps
.mapper.DepartmentMapper
;
import
com.
example
.service.DepartmentService
;
import
com.
aps
.service.DepartmentService
;
import
com.baomidou.mybatisplus.extension.service.impl.ServiceImpl
;
import
com.baomidou.mybatisplus.extension.service.impl.ServiceImpl
;
import
org.springframework.stereotype.Service
;
import
org.springframework.stereotype.Service
;
...
@@ -17,4 +17,4 @@ import org.springframework.stereotype.Service;
...
@@ -17,4 +17,4 @@ import org.springframework.stereotype.Service;
@Service
@Service
public
class
DepartmentServiceImpl
extends
ServiceImpl
<
DepartmentMapper
,
Department
>
implements
DepartmentService
{
public
class
DepartmentServiceImpl
extends
ServiceImpl
<
DepartmentMapper
,
Department
>
implements
DepartmentService
{
}
}
\ No newline at end of file
src/main/java/com/aps/service/impl/EquipinfoServiceImpl.java
0 → 100644
View file @
1dd2520c
package
com
.
aps
.
service
.
impl
;
import
com.aps.entity.Equipinfo
;
import
com.aps.mapper.EquipinfoMapper
;
import
com.aps.service.EquipinfoService
;
import
com.baomidou.mybatisplus.extension.service.impl.ServiceImpl
;
import
org.springframework.stereotype.Service
;
/**
* <p>
* 服务实现类
* </p>
*
* @author MyBatis-Plus
* @since 2025-10-09
*/
@Service
public
class
EquipinfoServiceImpl
extends
ServiceImpl
<
EquipinfoMapper
,
Equipinfo
>
implements
EquipinfoService
{
}
\ No newline at end of file
src/main/java/com/
example
/service/impl/MaterialInfoServiceImpl.java
→
src/main/java/com/
aps
/service/impl/MaterialInfoServiceImpl.java
View file @
1dd2520c
package
com
.
example
.
service
.
impl
;
package
com
.
aps
.
service
.
impl
;
import
com.
example
.entity.MaterialInfo
;
import
com.
aps
.entity.MaterialInfo
;
import
com.
example
.mapper.MaterialInfoMapper
;
import
com.
aps
.mapper.MaterialInfoMapper
;
import
com.
example
.service.MaterialInfoService
;
import
com.
aps
.service.MaterialInfoService
;
import
com.baomidou.mybatisplus.extension.service.impl.ServiceImpl
;
import
com.baomidou.mybatisplus.extension.service.impl.ServiceImpl
;
import
org.springframework.stereotype.Service
;
import
org.springframework.stereotype.Service
;
...
@@ -17,4 +17,4 @@ import org.springframework.stereotype.Service;
...
@@ -17,4 +17,4 @@ import org.springframework.stereotype.Service;
@Service
@Service
public
class
MaterialInfoServiceImpl
extends
ServiceImpl
<
MaterialInfoMapper
,
MaterialInfo
>
implements
MaterialInfoService
{
public
class
MaterialInfoServiceImpl
extends
ServiceImpl
<
MaterialInfoMapper
,
MaterialInfo
>
implements
MaterialInfoService
{
}
}
\ No newline at end of file
src/main/java/com/aps/service/impl/MesShiftWorkSchedServiceImpl.java
0 → 100644
View file @
1dd2520c
package
com
.
aps
.
service
.
impl
;
import
com.aps.entity.MesShiftWorkSched
;
import
com.aps.mapper.MesShiftWorkSchedMapper
;
import
com.aps.service.MesShiftWorkSchedService
;
import
com.baomidou.mybatisplus.extension.service.impl.ServiceImpl
;
import
org.springframework.stereotype.Service
;
/**
* <p>
* 班次表 服务实现类
* </p>
*
* @author MyBatis-Plus
* @since 2025-10-10
*/
@Service
public
class
MesShiftWorkSchedServiceImpl
extends
ServiceImpl
<
MesShiftWorkSchedMapper
,
MesShiftWorkSched
>
implements
MesShiftWorkSchedService
{
}
\ No newline at end of file
src/main/java/com/aps/service/impl/MpsplannedorderServiceImpl.java
0 → 100644
View file @
1dd2520c
package
com
.
aps
.
service
.
impl
;
import
com.aps.entity.Mpsplannedorder
;
import
com.aps.mapper.MpsplannedorderMapper
;
import
com.aps.service.MpsplannedorderService
;
import
com.baomidou.mybatisplus.extension.service.impl.ServiceImpl
;
import
org.springframework.stereotype.Service
;
/**
* <p>
* 服务实现类
* </p>
*
* @author MyBatis-Plus
* @since 2025-10-14
*/
@Service
public
class
MpsplannedorderServiceImpl
extends
ServiceImpl
<
MpsplannedorderMapper
,
Mpsplannedorder
>
implements
MpsplannedorderService
{
}
\ No newline at end of file
src/main/java/com/aps/service/impl/PlanResourceServiceImpl.java
0 → 100644
View file @
1dd2520c
package
com
.
aps
.
service
.
impl
;
import
com.aps.entity.PlanResource
;
import
com.aps.mapper.PlanResourceMapper
;
import
com.aps.service.PlanResourceService
;
import
com.baomidou.mybatisplus.extension.service.impl.ServiceImpl
;
import
org.springframework.stereotype.Service
;
/**
* <p>
* 服务实现类
* </p>
*
* @author MyBatis-Plus
* @since 2025-10-10
*/
@Service
public
class
PlanResourceServiceImpl
extends
ServiceImpl
<
PlanResourceMapper
,
PlanResource
>
implements
PlanResourceService
{
}
\ No newline at end of file
src/main/java/com/aps/service/impl/RoutingDetailEquipServiceImpl.java
0 → 100644
View file @
1dd2520c
package
com
.
aps
.
service
.
impl
;
import
com.aps.entity.RoutingDetailEquip
;
import
com.aps.mapper.RoutingDetailEquipMapper
;
import
com.aps.service.RoutingDetailEquipService
;
import
com.baomidou.mybatisplus.extension.service.impl.ServiceImpl
;
import
org.springframework.stereotype.Service
;
/**
* <p>
* 工序可用设备 服务实现类
* </p>
*
* @author MyBatis-Plus
* @since 2025-10-10
*/
@Service
public
class
RoutingDetailEquipServiceImpl
extends
ServiceImpl
<
RoutingDetailEquipMapper
,
RoutingDetailEquip
>
implements
RoutingDetailEquipService
{
}
\ No newline at end of file
src/main/java/com/aps/service/impl/RoutingDetailServiceImpl.java
0 → 100644
View file @
1dd2520c
package
com
.
aps
.
service
.
impl
;
import
com.aps.entity.RoutingDetail
;
import
com.aps.mapper.RoutingDetailMapper
;
import
com.aps.service.RoutingDetailService
;
import
com.baomidou.mybatisplus.extension.service.impl.ServiceImpl
;
import
org.springframework.stereotype.Service
;
/**
* <p>
* 服务实现类
* </p>
*
* @author MyBatis-Plus
* @since 2025-10-14
*/
@Service
public
class
RoutingDetailServiceImpl
extends
ServiceImpl
<
RoutingDetailMapper
,
RoutingDetail
>
implements
RoutingDetailService
{
}
\ No newline at end of file
src/main/java/com/aps/service/impl/RoutingHeaderServiceImpl.java
0 → 100644
View file @
1dd2520c
package
com
.
aps
.
service
.
impl
;
import
com.aps.entity.RoutingHeader
;
import
com.aps.mapper.RoutingHeaderMapper
;
import
com.aps.service.RoutingHeaderService
;
import
com.baomidou.mybatisplus.extension.service.impl.ServiceImpl
;
import
org.springframework.stereotype.Service
;
/**
* <p>
* 服务实现类
* </p>
*
* @author MyBatis-Plus
* @since 2025-10-09
*/
@Service
public
class
RoutingHeaderServiceImpl
extends
ServiceImpl
<
RoutingHeaderMapper
,
RoutingHeader
>
implements
RoutingHeaderService
{
}
\ No newline at end of file
src/main/java/com/aps/service/impl/RoutingStepServiceImpl.java
0 → 100644
View file @
1dd2520c
package
com
.
aps
.
service
.
impl
;
import
com.aps.entity.RoutingStep
;
import
com.aps.mapper.RoutingStepMapper
;
import
com.aps.service.RoutingStepService
;
import
com.baomidou.mybatisplus.extension.service.impl.ServiceImpl
;
import
org.springframework.stereotype.Service
;
/**
* <p>
* 服务实现类
* </p>
*
* @author MyBatis-Plus
* @since 2025-10-10
*/
@Service
public
class
RoutingStepServiceImpl
extends
ServiceImpl
<
RoutingStepMapper
,
RoutingStep
>
implements
RoutingStepService
{
}
\ No newline at end of file
src/main/java/com/aps/service/impl/ScheduleServiceImpl.java
0 → 100644
View file @
1dd2520c
package
com
.
aps
.
service
.
impl
;
import
com.aps.entity.*
;
import
com.aps.service.ScheduleService
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
org.springframework.stereotype.Service
;
import
java.math.BigDecimal
;
import
java.math.RoundingMode
;
import
java.time.LocalDateTime
;
import
java.util.*
;
import
java.util.concurrent.ConcurrentHashMap
;
import
java.util.stream.Collectors
;
@Service
public
class
ScheduleServiceImpl
implements
ScheduleService
{
private
static
final
Logger
logger
=
LoggerFactory
.
getLogger
(
ScheduleServiceImpl
.
class
);
// 缓存设备速度计算结果
private
final
Map
<
RoutingDetailEquip
,
BigDecimal
>
equipmentSpeedCache
=
new
ConcurrentHashMap
<>();
@Override
public
List
<
ScheduledTask
>
scheduleOrders
(
List
<
Mpsplannedorder
>
orders
,
List
<
RoutingHeader
>
processes
,
List
<
RoutingDetail
>
operations
,
List
<
RoutingDetailEquip
>
operationEquipments
,
List
<
Equipinfo
>
equipments
)
{
long
startTime
=
System
.
currentTimeMillis
();
logger
.
info
(
"开始调度,订单数量: {}"
,
orders
.
size
());
// 1. 初始化设备状态(只使用可用设备)
Map
<
Integer
,
EquipmentScheduleState
>
equipmentStates
=
equipments
.
stream
()
.
filter
(
e
->
e
.
getStatus
()
!=
null
&&
e
.
getStatus
()
==
0
)
// 只使用状态为0(可用)的设备
.
collect
(
Collectors
.
toMap
(
Equipinfo:
:
getId
,
e
->
new
EquipmentScheduleState
(
e
,
LocalDateTime
.
now
()),
(
existing
,
replacement
)
->
existing
));
// 2. 构建工序-设备关系映射
Map
<
Integer
,
List
<
RoutingDetailEquip
>>
operationToEquipments
=
operationEquipments
.
stream
()
.
collect
(
Collectors
.
groupingBy
(
RoutingDetailEquip:
:
getRoutingDetailId
));
// 3. 按优先级和截止时间排序工单
orders
.
sort
(
Comparator
.
comparing
(
Mpsplannedorder:
:
getPriority
)
.
thenComparing
(
Mpsplannedorder:
:
getDuadate
));
List
<
ScheduledTask
>
scheduledTasks
=
new
ArrayList
<>();
// 4. 处理每个工单
for
(
Mpsplannedorder
order
:
orders
)
{
try
{
processOrder
(
order
,
processes
,
operations
,
operationToEquipments
,
equipmentStates
,
scheduledTasks
);
}
catch
(
Exception
e
)
{
logger
.
error
(
"工单 {} 调度失败: {}"
,
order
.
getOrderid
(),
e
.
getMessage
(),
e
);
throw
new
RuntimeException
(
"工单调度失败: "
+
order
.
getOrderid
(),
e
);
}
}
long
endTime
=
System
.
currentTimeMillis
();
logger
.
info
(
"调度完成,生成任务数量: {}, 耗时: {}ms"
,
scheduledTasks
.
size
(),
(
endTime
-
startTime
));
return
scheduledTasks
;
}
private
void
processOrder
(
Mpsplannedorder
order
,
List
<
RoutingHeader
>
processes
,
List
<
RoutingDetail
>
operations
,
Map
<
Integer
,
List
<
RoutingDetailEquip
>>
operationToEquipments
,
Map
<
Integer
,
EquipmentScheduleState
>
equipmentStates
,
List
<
ScheduledTask
>
scheduledTasks
)
{
// 1. 匹配工艺
RoutingHeader
process
=
findProcess
(
order
.
getRoutingid
(),
processes
);
// 2. 获取该工艺的所有工序(严格按taskSeq排序)
List
<
RoutingDetail
>
processOperations
=
operations
.
stream
()
.
filter
(
op
->
op
.
getRoutingHeaderId
()
!=
null
&&
op
.
getRoutingHeaderId
().
equals
(
process
.
getId
()))
.
sorted
(
Comparator
.
comparing
(
RoutingDetail:
:
getTaskSeq
))
.
collect
(
Collectors
.
toList
());
// 3. 记录上一道工序的结束时间(初始为工单计划开始时间)
LocalDateTime
lastOperationEndTime
=
order
.
getStartdate
();
// 4. 按顺序处理每道工序
for
(
RoutingDetail
operation
:
processOperations
)
{
ScheduledTask
task
=
scheduleOperation
(
order
,
operation
,
operationToEquipments
,
equipmentStates
,
lastOperationEndTime
);
scheduledTasks
.
add
(
task
);
lastOperationEndTime
=
task
.
getEndTime
();
// 更新上一道工序的结束时间
}
}
private
ScheduledTask
scheduleOperation
(
Mpsplannedorder
order
,
RoutingDetail
operation
,
Map
<
Integer
,
List
<
RoutingDetailEquip
>>
operationToEquipments
,
Map
<
Integer
,
EquipmentScheduleState
>
equipmentStates
,
LocalDateTime
lastOperationEndTime
)
{
// 1. 获取该工序可用的设备
List
<
RoutingDetailEquip
>
availableEquipments
=
operationToEquipments
.
getOrDefault
(
operation
.
getId
(),
Collections
.
emptyList
());
if
(
availableEquipments
.
isEmpty
())
{
throw
new
RuntimeException
(
"工序 "
+
operation
.
getId
()
+
" 没有配置可用设备"
);
}
// 2. 选择最优设备(按产出速度降序)
RoutingDetailEquip
selectedEquipment
=
selectFastestEquipment
(
availableEquipments
);
EquipmentScheduleState
equipmentState
=
equipmentStates
.
get
(
selectedEquipment
.
getEquipId
());
if
(
equipmentState
==
null
)
{
throw
new
RuntimeException
(
"设备 "
+
selectedEquipment
.
getEquipId
()
+
" 状态异常"
);
}
// 3. 计算时间范围(关键修改:考虑工序顺序约束)
LocalDateTime
startTime
=
calculateOperationStartTime
(
lastOperationEndTime
,
order
.
getStartdate
(),
equipmentState
.
getNextAvailableTime
()
);
LocalDateTime
endTime
=
calculateOperationEndTime
(
startTime
,
order
.
getQuantity
(),
selectedEquipment
,
operation
.
getSetupTime
()
);
// 4. 更新设备状态
equipmentState
.
getTaskQueue
().
add
(
new
ScheduledTask
());
// 只用于记录设备占用
equipmentState
.
setNextAvailableTime
(
endTime
);
// 4. 创建任务
ScheduledTask
task
=
new
ScheduledTask
();
task
.
setOrderId
(
order
.
getOrderid
()
!=
null
?
order
.
getOrderid
().
toString
()
:
""
);
task
.
setOperationId
(
operation
.
getId
());
task
.
setEquipId
(
selectedEquipment
.
getEquipId
());
task
.
setEquipName
(
equipmentState
.
getEquipName
());
// 设置设备名称
task
.
setStartTime
(
startTime
);
task
.
setEndTime
(
endTime
);
task
.
setQuantity
(
order
.
getQuantity
()
!=
null
?
BigDecimal
.
valueOf
(
order
.
getQuantity
())
:
BigDecimal
.
ZERO
);
task
.
setOperationName
(
operation
.
getName
());
task
.
setRouteId
(
order
.
getRoutingid
());
return
task
;
}
// 关键方法:计算工序的实际开始时间
private
LocalDateTime
calculateOperationStartTime
(
LocalDateTime
lastOperationEndTime
,
// 上一道工序的结束时间
LocalDateTime
orderPlannedStartTime
,
// 工单计划开始时间
LocalDateTime
equipmentAvailableTime
// 设备可用时间
)
{
// 取最晚的时间:上一道工序结束时间、工单计划开始时间、设备可用时间
return
Collections
.
max
(
Arrays
.
asList
(
lastOperationEndTime
,
orderPlannedStartTime
,
equipmentAvailableTime
));
}
// 计算工序结束时间
private
LocalDateTime
calculateOperationEndTime
(
LocalDateTime
startTime
,
Integer
quantity
,
RoutingDetailEquip
equipment
,
BigDecimal
setupTime
)
{
// 总时间= (数量 × 单件时间) + 准备时间
BigDecimal
totalHours
=
calculateTotalProcessingTime
(
quantity
,
equipment
,
setupTime
);
return
startTime
.
plusMinutes
(
totalHours
.
multiply
(
BigDecimal
.
valueOf
(
60
)).
longValue
());
}
private
BigDecimal
calculateTotalProcessingTime
(
Integer
quantity
,
RoutingDetailEquip
equipment
,
BigDecimal
setupTime
)
{
// 参数校验
if
(
equipment
.
getOutputQuantity
()
==
null
||
equipment
.
getOutputQuantity
().
compareTo
(
BigDecimal
.
ZERO
)
<=
0
)
{
throw
new
IllegalArgumentException
(
"设备产出数量必须大于0"
);
}
if
(
equipment
.
getDuration
()
==
null
||
equipment
.
getDuration
().
compareTo
(
BigDecimal
.
ZERO
)
<=
0
)
{
throw
new
IllegalArgumentException
(
"设备持续时间必须大于0"
);
}
if
(
quantity
==
null
||
quantity
<=
0
)
{
throw
new
IllegalArgumentException
(
"工单数量必须大于0"
);
}
// 单件时间(小时)= (持续时间(秒)/产出数量)/3600
BigDecimal
singleItemTimeHours
=
equipment
.
getDuration
()
.
divide
(
equipment
.
getOutputQuantity
(),
10
,
RoundingMode
.
HALF_UP
)
.
divide
(
BigDecimal
.
valueOf
(
3600
),
10
,
RoundingMode
.
HALF_UP
);
// 总加工时间= 数量 × 单件时间
BigDecimal
processingTime
=
BigDecimal
.
valueOf
(
quantity
)
.
multiply
(
singleItemTimeHours
);
// 加上准备时间(如果存在)
if
(
setupTime
!=
null
&&
setupTime
.
compareTo
(
BigDecimal
.
ZERO
)
>
0
)
{
return
processingTime
.
add
(
setupTime
);
}
return
processingTime
;
}
// 其他辅助方法保持不变
private
RoutingDetailEquip
selectFastestEquipment
(
List
<
RoutingDetailEquip
>
equipments
)
{
return
equipments
.
stream
()
.
max
(
Comparator
.
comparing
(
this
::
calculateEquipmentSpeed
))
.
orElseThrow
(()
->
new
RuntimeException
(
"没有可用的设备"
));
}
private
BigDecimal
calculateEquipmentSpeed
(
RoutingDetailEquip
equipment
)
{
return
equipmentSpeedCache
.
computeIfAbsent
(
equipment
,
eq
->
{
if
(
eq
.
getOutputQuantity
()
==
null
||
eq
.
getDuration
()
==
null
||
eq
.
getOutputQuantity
().
compareTo
(
BigDecimal
.
ZERO
)
<=
0
||
eq
.
getDuration
().
compareTo
(
BigDecimal
.
ZERO
)
<=
0
)
{
return
BigDecimal
.
ZERO
;
}
return
eq
.
getOutputQuantity
()
.
divide
(
eq
.
getDuration
(),
10
,
RoundingMode
.
HALF_UP
)
.
multiply
(
BigDecimal
.
valueOf
(
3600
));
});
}
private
RoutingHeader
findProcess
(
String
routingCode
,
List
<
RoutingHeader
>
processes
)
{
return
processes
.
stream
()
.
filter
(
p
->
p
.
getCode
()
!=
null
&&
p
.
getCode
().
equals
(
routingCode
))
.
min
(
Comparator
.
comparing
(
RoutingHeader:
:
getCreationTime
))
.
orElseThrow
(()
->
new
RuntimeException
(
"工艺不存在: "
+
routingCode
));
}
}
\ No newline at end of file
src/main/java/com/aps/service/plan/AlgorithmScheduler6.java
0 → 100644
View file @
1dd2520c
package
com
.
aps
.
service
.
plan
;
import
com.aps.common.util.FileHelper
;
import
com.aps.entity.basic.*
;
import
java.time.LocalDateTime
;
import
java.time.temporal.ChronoUnit
;
import
java.util.*
;
import
java.util.stream.Collectors
;
public
class
AlgorithmScheduler6
{
private
final
List
<
Product
>
_products
;
private
final
List
<
Machine
>
_machines
;
private
final
List
<
Order
>
_orders
;
private
final
Random
_random
;
private
final
MachineSchedulerService
_machineScheduler
;
private
int
_populationSize
=
100
;
private
double
_crossoverRate
=
0.8
;
private
double
_mutationRate
=
0.1
;
private
int
_maxGenerations
=
500
;
private
int
_elitismCount
=
5
;
private
final
LocalDateTime
baseTime
=
LocalDateTime
.
of
(
2025
,
10
,
1
,
0
,
0
,
0
);
public
AlgorithmScheduler6
(
List
<
Product
>
products
,
List
<
Machine
>
machines
,
List
<
Order
>
orders
,
MachineSchedulerService
machineScheduler
)
{
this
.
_products
=
deepCopyProductList
(
products
);
this
.
_machines
=
deepCopyMachineList
(
machines
);
this
.
_orders
=
deepCopyOrderList
(
orders
);
this
.
_machineScheduler
=
machineScheduler
;
this
.
_random
=
new
Random
();
}
public
ScheduleChromosome
Run
()
{
List
<
ScheduleChromosome
>
population
=
InitializePopulation
();
ScheduleChromosome
bestSolution
=
null
;
ScheduleChromosome
currentBest
=
null
;
double
bestFitness
=
Double
.
MIN_VALUE
;
currentBest
=
population
.
stream
()
.
max
(
Comparator
.
comparingDouble
(
ScheduleChromosome:
:
getFitness
))
.
orElse
(
null
);
if
(
currentBest
!=
null
)
{
bestFitness
=
currentBest
.
getFitness
();
bestSolution
=
deepCopyScheduleChromosome
(
currentBest
);
}
return
bestSolution
;
}
public
List
<
ScheduleChromosome
>
RunAll
()
{
return
InitializePopulation
();
}
private
List
<
ScheduleChromosome
>
InitializePopulation
()
{
List
<
ScheduleChromosome
>
population
=
new
ArrayList
<>();
System
.
out
.
println
(
"开始初始化种群,目标大小: "
+
_populationSize
);
for
(
int
i
=
0
;
i
<
_populationSize
;
i
++)
{
ScheduleChromosome
chromosome
=
new
ScheduleChromosome
(
baseTime
);
chromosome
.
setGenes
(
new
ArrayList
<>());
chromosome
.
setObjectiveValues
(
new
HashMap
<>());
chromosome
.
setOrders
(
deepCopyOrderList
(
_orders
));
chromosome
.
setMachines
(
deepCopyMachineList
(
_machines
));
// 为每个订单分配工序
for
(
Order
order
:
_orders
)
{
Product
product
=
_products
.
stream
()
.
filter
(
p
->
p
.
getId
()
==
order
.
getProductId
())
.
findFirst
()
.
orElseThrow
(()
->
new
NoSuchElementException
(
"Product not found: "
+
order
.
getProductId
()));
int
prevtime
=
0
;
int
remainingQuantity
=
order
.
getQuantity
();
// 订单拆分逻辑 - 增强随机性
while
(
remainingQuantity
>
0
)
{
int
batchSize
;
if
(
order
.
isCanSplit
()
&&
remainingQuantity
>
1
)
{
// 修改:增强批次拆分的随机性
int
maxSplit
=
Math
.
min
(
remainingQuantity
,
Math
.
max
(
1
,
remainingQuantity
/
2
));
batchSize
=
_random
.
nextInt
(
maxSplit
)
+
1
;
}
else
{
batchSize
=
remainingQuantity
;
}
if
(
batchSize
>
remainingQuantity
)
{
batchSize
=
remainingQuantity
;
}
remainingQuantity
-=
batchSize
;
// 按工序顺序处理
for
(
Operation
operation
:
product
.
getOperations
().
stream
()
.
sorted
(
Comparator
.
comparingInt
(
Operation:
:
getSequence
))
.
collect
(
Collectors
.
toList
()))
{
if
(
operation
.
getId
()
>
1
)
{
Gene
prevGene
=
chromosome
.
getGenes
().
stream
()
.
filter
(
t
->
t
.
getOrderId
()
==
order
.
getId
()
&&
t
.
getOperationId
()
==
operation
.
getId
()
-
1
)
.
findFirst
()
.
orElse
(
null
);
prevtime
=
prevGene
!=
null
?
prevGene
.
getEndTime
()
:
0
;
}
MachineOption
machineOption
;
Machine
machine
;
// 多设备选择逻辑 - 增强随机性
if
(
operation
.
getMachineOptions
().
size
()
>
1
)
{
Set
<
Integer
>
machineIds
=
operation
.
getMachineOptions
().
stream
()
.
map
(
MachineOption:
:
getMachineId
)
.
collect
(
Collectors
.
toSet
());
// 修改:增强设备选择的随机性
List
<
Machine
>
availableMachines
=
chromosome
.
getMachines
().
stream
()
.
filter
(
t
->
machineIds
.
contains
(
t
.
getId
()))
.
collect
(
Collectors
.
toList
());
if
(!
availableMachines
.
isEmpty
())
{
// 随机打乱后选择
Collections
.
shuffle
(
availableMachines
,
_random
);
machine
=
availableMachines
.
get
(
0
);
Machine
finalMachine
=
machine
;
machineOption
=
operation
.
getMachineOptions
().
stream
()
.
filter
(
t
->
t
.
getMachineId
()
==
finalMachine
.
getId
())
.
findFirst
()
.
orElseThrow
(()
->
new
NoSuchElementException
(
"MachineOption not found for machine: "
+
finalMachine
.
getId
()));
}
else
{
// 回退到原始逻辑
machine
=
chromosome
.
getMachines
().
stream
()
.
filter
(
t
->
machineIds
.
contains
(
t
.
getId
()))
.
sorted
(
Comparator
.
comparingInt
(
Machine:
:
getEarliestTime
)
.
thenComparingInt
(
Machine:
:
getTotalTaskTime
)
.
thenComparing
(
t
->
_random
.
nextDouble
()))
.
findFirst
()
.
orElseThrow
(()
->
new
NoSuchElementException
(
"No available machine for operation: "
+
operation
.
getId
()));
Machine
finalMachine
=
machine
;
machineOption
=
operation
.
getMachineOptions
().
stream
()
.
filter
(
t
->
t
.
getMachineId
()
==
finalMachine
.
getId
())
.
findFirst
()
.
orElseThrow
(()
->
new
NoSuchElementException
(
"MachineOption not found for machine: "
+
finalMachine
.
getId
()));
}
}
else
{
machineOption
=
operation
.
getMachineOptions
().
get
(
0
);
MachineOption
finalMachineOption
=
machineOption
;
machine
=
chromosome
.
getMachines
().
stream
()
.
filter
(
m
->
m
.
getId
()
==
finalMachineOption
.
getMachineId
())
.
findFirst
()
.
orElseThrow
(()
->
new
NoSuchElementException
(
"Machine not found: "
+
finalMachineOption
.
getMachineId
()));
}
int
processingTime
=
machineOption
.
getProcessingTime
()
*
batchSize
;
List
<
GeneDetail
>
geneDetails
=
GetNextAvailableTime
(
machine
,
prevtime
,
-
1
,
processingTime
,
chromosome
.
getGenes
(),
false
,
true
);
int
startTime
=
geneDetails
.
stream
().
mapToInt
(
GeneDetail:
:
getStartTime
).
min
().
orElse
(
0
);
int
endTime
=
geneDetails
.
stream
().
mapToInt
(
GeneDetail:
:
getEndTime
).
max
().
orElse
(
0
);
machine
.
setEarliestTime
(
endTime
);
machine
.
setTotalTaskTime
(
machine
.
getTotalTaskTime
()
+
processingTime
);
Gene
gene
=
new
Gene
();
gene
.
setOrderId
(
order
.
getId
());
gene
.
setProductId
(
order
.
getProductId
());
gene
.
setOperationId
(
operation
.
getId
());
gene
.
setMachineId
(
machineOption
.
getMachineId
());
gene
.
setBatchSize
(
batchSize
);
gene
.
setStartTime
(
startTime
);
gene
.
setEndTime
(
endTime
);
gene
.
setProcessingTime
(
processingTime
);
gene
.
setGeneDetails
(
deepCopyGeneDetailList
(
geneDetails
));
chromosome
.
getGenes
().
add
(
gene
);
}
}
}
population
.
add
(
chromosome
);
}
System
.
out
.
println
(
"生成种群大小: "
+
population
.
size
());
Map
<
String
,
List
<
ScheduleChromosome
>>
grouped
=
population
.
stream
()
.
collect
(
Collectors
.
groupingBy
(
ScheduleChromosome:
:
getGenesStr
));
population
=
grouped
.
values
().
stream
()
.
map
(
group
->
group
.
get
(
0
))
// 对应 C# 的 g.First()
.
collect
(
Collectors
.
toList
());
//
//
// // 修改:更宽松的去重策略,接近C#的行为
// if (population.size() > _populationSize) {
// Map<String, ScheduleChromosome> uniqueMap = new LinkedHashMap<>();
// for (ScheduleChromosome chrom : population) {
// // 使用更宽松的键:只基于设备分配和批次,忽略时间差异
// String relaxedKey = generateRelaxedKey(chrom);
// uniqueMap.putIfAbsent(relaxedKey, chrom);
// }
//
// // 如果去重后仍然过多,再使用严格键
// if (uniqueMap.size() < _populationSize * 0.8) {
// uniqueMap.clear();
// for (ScheduleChromosome chrom : population) {
// uniqueMap.putIfAbsent(chrom.getGenesStr(), chrom);
// }
// }
//
// population = new ArrayList<>(uniqueMap.values());
// System.out.println("去重后种群大小: " + population.size());
// }
// 调试输出染色体多样性
System
.
out
.
println
(
"染色体多样性分析:"
);
Map
<
String
,
Integer
>
keyCounts
=
new
HashMap
<>();
for
(
ScheduleChromosome
chrom
:
population
)
{
String
key
=
chrom
.
getGenesStr
();
keyCounts
.
put
(
key
,
keyCounts
.
getOrDefault
(
key
,
0
)
+
1
);
}
System
.
out
.
println
(
"唯一染色体数量: "
+
keyCounts
.
size
());
System
.
out
.
println
(
"染色体分布: "
+
keyCounts
);
// 并行计算适应度
population
.
parallelStream
().
forEach
(
this
::
CalculateFitness
);
// 打印摘要
population
.
forEach
(
this
::
WriteScheduleSummary
);
return
population
;
}
// 新增:生成宽松的键(只关注设备分配模式)
private
String
generateRelaxedKey
(
ScheduleChromosome
chrom
)
{
return
chrom
.
getGenes
().
stream
()
.
sorted
(
Comparator
.
comparing
(
Gene:
:
getOrderId
)
.
thenComparing
(
Gene:
:
getOperationId
))
.
map
(
g
->
String
.
format
(
"O%d-Op%d-M%d-B%d"
,
g
.
getOrderId
(),
g
.
getOperationId
(),
g
.
getMachineId
(),
g
.
getBatchSize
()))
.
collect
(
Collectors
.
joining
(
"|"
));
}
private
List
<
ScheduleChromosome
>
removeTrueDuplicates
(
List
<
ScheduleChromosome
>
population
)
{
Map
<
String
,
ScheduleChromosome
>
uniqueMap
=
new
LinkedHashMap
<>();
for
(
ScheduleChromosome
chrom
:
population
)
{
// 使用更宽松的键:包含批次大小、开始时间等关键信息
String
key
=
generateChromosomeKey
(
chrom
);
uniqueMap
.
putIfAbsent
(
key
,
chrom
);
}
return
new
ArrayList
<>(
uniqueMap
.
values
());
}
private
String
generateChromosomeKey
(
ScheduleChromosome
chrom
)
{
// 与C#一致的键生成逻辑:包含订单、工序、设备、批次、时间等关键信息
return
chrom
.
getGenes
().
stream
()
.
sorted
(
Comparator
.
comparing
(
Gene:
:
getOrderId
)
.
thenComparing
(
Gene:
:
getOperationId
)
.
thenComparing
(
Gene:
:
getStartTime
))
.
map
(
g
->
String
.
format
(
"%d-%d-%d-%d-%d-%d"
,
g
.
getOrderId
(),
g
.
getOperationId
(),
g
.
getMachineId
(),
g
.
getBatchSize
(),
g
.
getStartTime
(),
g
.
getEndTime
()))
.
collect
(
Collectors
.
joining
(
"|"
));
}
// ========================== CalculateFitness(参数与C#一致) ==========================
private
void
CalculateFitness
(
ScheduleChromosome
chromosome
)
{
// 1. 最大完工时间
double
makespan
=
chromosome
.
getGenes
().
stream
()
.
mapToInt
(
Gene:
:
getEndTime
)
.
max
()
.
orElse
(
0
);
// 2. 总延迟时间
double
tardiness
=
0.0
;
Map
<
Integer
,
List
<
Gene
>>
orderGroups
=
chromosome
.
getGenes
().
stream
()
.
collect
(
Collectors
.
groupingBy
(
Gene:
:
getOrderId
));
for
(
Map
.
Entry
<
Integer
,
List
<
Gene
>>
group
:
orderGroups
.
entrySet
())
{
int
orderCompletion
=
group
.
getValue
().
stream
()
.
mapToInt
(
Gene:
:
getEndTime
)
.
max
()
.
orElse
(
0
);
Order
order
=
_orders
.
stream
()
.
filter
(
o
->
o
.
getId
()
==
group
.
getKey
())
.
findFirst
()
.
orElse
(
null
);
if
(
order
!=
null
)
{
LocalDateTime
completionTime
=
chromosome
.
getBaseTime
().
plusMinutes
(
orderCompletion
);
// 修复:正确处理OffsetDateTime到LocalDateTime的转换
LocalDateTime
dueDateTime
=
order
.
getDueDate
().
toLocalDateTime
();
if
(
completionTime
.
isAfter
(
dueDateTime
))
{
// 计算延迟小时数(修复时间计算)
long
hours
=
ChronoUnit
.
HOURS
.
between
(
dueDateTime
,
completionTime
);
long
minutes
=
ChronoUnit
.
MINUTES
.
between
(
dueDateTime
,
completionTime
)
%
60
;
tardiness
+=
hours
+
(
double
)
minutes
/
60
;
}
}
}
// 3. 总换型时间
double
totalSetupTime
=
CalculateTotalSetupTime
(
chromosome
);
// 4. 总流程时间
double
totalFlowTime
=
CalculateTotalFlowTime
(
chromosome
);
// 5. 机器负载均衡
double
machineLoadBalance
=
CalculateMachineLoadBalance
(
chromosome
);
// 存储目标值(键与C#一致)
double
finalTardiness
=
tardiness
;
HashMap
<
Integer
,
Double
>
objMap
=
new
HashMap
<>();
objMap
.
put
(
0
,
makespan
);
objMap
.
put
(
1
,
finalTardiness
);
objMap
.
put
(
2
,
totalSetupTime
);
objMap
.
put
(
3
,
totalFlowTime
);
objMap
.
put
(
4
,
machineLoadBalance
);
chromosome
.
setObjectiveValues
(
objMap
);
// 计算适应度
chromosome
.
setFitness
(
0.4
*
(
1.0
/
(
1
+
makespan
))
+
0.3
*
(
1.0
/
(
1
+
tardiness
))
+
0.1
*
(
1.0
/
(
1
+
totalSetupTime
))
+
0.1
*
(
1.0
/
(
1
+
totalFlowTime
))
+
0.1
*
machineLoadBalance
);
}
// ========================== CalculateTotalFlowTime(参数与C#一致) ==========================
private
double
CalculateTotalFlowTime
(
ScheduleChromosome
chromosome
)
{
double
totalFlowTime
=
0.0
;
Map
<
Integer
,
List
<
Gene
>>
orderGroups
=
chromosome
.
getGenes
().
stream
()
.
collect
(
Collectors
.
groupingBy
(
Gene:
:
getOrderId
));
for
(
Map
.
Entry
<
Integer
,
List
<
Gene
>>
group
:
orderGroups
.
entrySet
())
{
int
minStartTime
=
group
.
getValue
().
stream
().
mapToInt
(
Gene:
:
getStartTime
).
min
().
orElse
(
0
);
int
maxEndTime
=
group
.
getValue
().
stream
().
mapToInt
(
Gene:
:
getEndTime
).
max
().
orElse
(
0
);
LocalDateTime
start
=
chromosome
.
getBaseTime
().
plusMinutes
(
minStartTime
);
LocalDateTime
end
=
chromosome
.
getBaseTime
().
plusMinutes
(
maxEndTime
);
// 修复:计算流程时间(小时)
long
hours
=
ChronoUnit
.
HOURS
.
between
(
start
,
end
);
long
minutes
=
ChronoUnit
.
MINUTES
.
between
(
start
,
end
)
%
60
;
totalFlowTime
+=
hours
+
(
double
)
minutes
/
60
;
}
return
totalFlowTime
;
}
// ========================== CalculateTotalSetupTime(参数与C#一致) ==========================
private
double
CalculateTotalSetupTime
(
ScheduleChromosome
chromosome
)
{
double
totalSetupTime
=
0.0
;
Map
<
Integer
,
List
<
Gene
>>
machineGroups
=
chromosome
.
getGenes
().
stream
()
.
collect
(
Collectors
.
groupingBy
(
Gene:
:
getMachineId
));
for
(
Map
.
Entry
<
Integer
,
List
<
Gene
>>
machineGroup
:
machineGroups
.
entrySet
())
{
List
<
Gene
>
sortedGenes
=
machineGroup
.
getValue
().
stream
()
.
sorted
(
Comparator
.
comparingInt
(
Gene:
:
getStartTime
))
.
collect
(
Collectors
.
toList
());
Integer
lastProductId
=
null
;
for
(
Gene
gene
:
sortedGenes
)
{
if
(
lastProductId
!=
null
&&
lastProductId
!=
gene
.
getProductId
())
{
// 查找对应工序和设备选项
Product
product
=
_products
.
stream
()
.
filter
(
p
->
p
.
getId
()
==
gene
.
getProductId
())
.
findFirst
()
.
orElse
(
null
);
if
(
product
==
null
)
continue
;
Operation
operation
=
product
.
getOperations
().
stream
()
.
filter
(
o
->
o
.
getId
()
==
gene
.
getOperationId
())
.
findFirst
()
.
orElse
(
null
);
if
(
operation
==
null
)
continue
;
MachineOption
machineOption
=
operation
.
getMachineOptions
().
stream
()
.
filter
(
m
->
m
.
getMachineId
()
==
gene
.
getMachineId
())
.
findFirst
()
.
orElse
(
null
);
if
(
machineOption
!=
null
)
{
totalSetupTime
+=
machineOption
.
getSetupTime
();
}
}
lastProductId
=
gene
.
getProductId
();
}
}
return
totalSetupTime
;
}
// ========================== CalculateMachineLoadBalance(参数与C#一致) ==========================
private
double
CalculateMachineLoadBalance
(
ScheduleChromosome
chromosome
)
{
Map
<
Integer
,
Double
>
machineUtilization
=
new
HashMap
<>();
int
maxEndTime
=
chromosome
.
getGenes
().
stream
()
.
mapToInt
(
Gene:
:
getEndTime
)
.
max
()
.
orElse
(
0
);
if
(
maxEndTime
==
0
)
return
0.0
;
// 计算设备忙碌时间
for
(
Machine
machine
:
_machines
)
{
double
busyTime
=
chromosome
.
getGenes
().
stream
()
.
filter
(
g
->
g
.
getMachineId
()
==
machine
.
getId
())
.
mapToInt
(
g
->
g
.
getEndTime
()
-
g
.
getStartTime
())
.
sum
();
machineUtilization
.
put
(
machine
.
getId
(),
busyTime
/
maxEndTime
);
}
// 计算方差
double
avgUtilization
=
machineUtilization
.
values
().
stream
().
mapToDouble
(
Double:
:
doubleValue
).
average
().
orElse
(
0.0
);
double
variance
=
machineUtilization
.
values
().
stream
()
.
mapToDouble
(
u
->
Math
.
pow
(
u
-
avgUtilization
,
2
))
.
average
()
.
orElse
(
0.0
);
// 负载均衡得分
return
1.0
/
(
1
+
variance
);
}
// ========================== RemoveMachineAvailable(参数与C#一致) ==========================
private
void
RemoveMachineAvailable
(
Machine
machine
,
GeneDetail
geneDetails
)
{
List
<
TimeSegment
>
timeSegments
=
new
ArrayList
<>();
// 查找对应时间段
int
index
=
machine
.
getAvailability
().
stream
()
.
filter
(
t
->
t
.
getKey
().
equals
(
geneDetails
.
getKey
()))
.
findFirst
()
.
map
(
machine
.
getAvailability
()::
indexOf
)
.
orElse
(-
1
);
if
(
index
>
-
1
)
{
TimeSegment
targetSegment
=
machine
.
getAvailability
().
get
(
index
);
LocalDateTime
geneEndTime
=
baseTime
.
plusMinutes
(
geneDetails
.
getEndTime
());
if
(
targetSegment
.
getEnd
().
isAfter
(
geneEndTime
))
{
// 拆分时间段
TimeSegment
usedSegment
=
new
TimeSegment
();
usedSegment
.
setStart
(
baseTime
.
plusMinutes
(
geneDetails
.
getStartTime
()));
usedSegment
.
setEnd
(
geneEndTime
);
usedSegment
.
setHoliday
(
false
);
usedSegment
.
setKey
(
UUID
.
randomUUID
().
toString
());
usedSegment
.
setType
(
SegmentType
.
REGULAR
);
usedSegment
.
setUsed
(
true
);
timeSegments
.
add
(
usedSegment
);
// 更新基因详情Key
geneDetails
.
setKey
(
usedSegment
.
getKey
());
// 更新原时间段开始时间
targetSegment
.
setStart
(
geneEndTime
);
}
else
{
targetSegment
.
setUsed
(
true
);
}
}
// 添加新段并排序
if
(!
timeSegments
.
isEmpty
())
{
machine
.
getAvailability
().
addAll
(
timeSegments
);
}
machine
.
getAvailability
().
sort
(
Comparator
.
comparing
(
TimeSegment:
:
getStart
));
}
// ========================== AddMachineAvailable(参数与C#一致) ==========================
private
void
AddMachineAvailable
(
Machine
machine
,
List
<
GeneDetail
>
geneDetails
)
{
if
(
geneDetails
==
null
||
geneDetails
.
isEmpty
())
return
;
// 标记时间段为未占用
for
(
GeneDetail
detail
:
geneDetails
)
{
machine
.
getAvailability
().
stream
()
.
filter
(
t
->
t
.
getKey
().
equals
(
detail
.
getKey
()))
.
findFirst
()
.
ifPresent
(
t
->
t
.
setUsed
(
false
));
}
// 合并时间段
machine
.
setAvailability
(
MergeSegments
(
machine
.
getAvailability
()));
}
// ========================== MergeSegments(参数与C#一致) ==========================
private
List
<
TimeSegment
>
MergeSegments
(
List
<
TimeSegment
>
segments
)
{
// 分离维护段、未占用段、已占用段
List
<
TimeSegment
>
maintenanceSegments
=
segments
.
stream
()
.
filter
(
t
->
t
.
getType
()
==
SegmentType
.
MAINTENANCE
)
.
collect
(
Collectors
.
toList
());
List
<
TimeSegment
>
unusedRegularSegments
=
segments
.
stream
()
.
filter
(
t
->
t
.
getType
()
!=
SegmentType
.
MAINTENANCE
&&
!
t
.
isUsed
())
.
collect
(
Collectors
.
toList
());
List
<
TimeSegment
>
usedRegularSegments
=
segments
.
stream
()
.
filter
(
t
->
t
.
getType
()
!=
SegmentType
.
MAINTENANCE
&&
t
.
isUsed
())
.
collect
(
Collectors
.
toList
());
// 排序未占用段
unusedRegularSegments
.
sort
(
Comparator
.
comparing
(
TimeSegment:
:
getStart
));
// 合并未占用段
Deque
<
TimeSegment
>
mergedUnused
=
new
ArrayDeque
<>();
for
(
TimeSegment
seg
:
unusedRegularSegments
)
{
if
(!
mergedUnused
.
isEmpty
()
&&
mergedUnused
.
peekLast
().
getEnd
().
isAfter
(
seg
.
getStart
()))
{
TimeSegment
last
=
mergedUnused
.
pollLast
();
last
.
setEnd
(
last
.
getEnd
().
isAfter
(
seg
.
getEnd
())
?
last
.
getEnd
()
:
seg
.
getEnd
());
mergedUnused
.
offerLast
(
last
);
}
else
{
mergedUnused
.
offerLast
(
seg
);
}
}
// 重组结果
List
<
TimeSegment
>
result
=
new
ArrayList
<>(
mergedUnused
);
result
.
addAll
(
usedRegularSegments
);
result
.
addAll
(
maintenanceSegments
);
result
.
sort
(
Comparator
.
comparing
(
TimeSegment:
:
getStart
));
return
result
;
}
// ========================== GetNextAvailableTime(参数与C#一致) ==========================
private
List
<
GeneDetail
>
GetNextAvailableTime
(
Machine
machine
,
int
proposedStartTime
,
int
prevtime
,
int
processingTime
,
List
<
Gene
>
existingTasks
,
boolean
IsInterrupt
,
boolean
istask
)
{
LocalDateTime
startTime
=
baseTime
.
plusMinutes
(
proposedStartTime
);
String
prevtimeStr
=
prevtime
>
-
1
?
baseTime
.
plusMinutes
(
prevtime
).
toString
()
:
""
;
// 查找最早可用班次
return
FindEarliestStart
(
machine
,
processingTime
,
startTime
,
prevtimeStr
,
existingTasks
,
istask
);
}
// ========================== FindEarliestStart(参数与C#一致) ==========================
private
List
<
GeneDetail
>
FindEarliestStart
(
Machine
machine
,
int
processingTime
,
LocalDateTime
currentTime
,
String
prevtime
,
List
<
Gene
>
existingTasks
,
boolean
checkprevtime
)
{
// 获取设备已有任务
List
<
Gene
>
machineTasks
=
existingTasks
.
stream
()
.
filter
(
t
->
t
.
getMachineId
()
==
machine
.
getId
())
.
sorted
(
Comparator
.
comparingInt
(
Gene:
:
getStartTime
))
.
collect
(
Collectors
.
toList
());
List
<
GeneDetail
>
times
=
new
ArrayList
<>();
// 获取当前或下一个班次
TimeSegment
slot
=
GetCurrentOrNextShift
(
machine
,
currentTime
,
prevtime
,
checkprevtime
);
if
(
slot
==
null
)
return
times
;
// 计算候选时间
LocalDateTime
prevTimeDateTime
=
StringUtils
.
isEmpty
(
prevtime
)
?
null
:
LocalDateTime
.
parse
(
prevtime
);
LocalDateTime
startCandidate
=
slot
.
getStart
().
isAfter
(
prevTimeDateTime
!=
null
?
prevTimeDateTime
:
currentTime
)
?
slot
.
getStart
()
:
(
prevTimeDateTime
!=
null
?
prevTimeDateTime
:
currentTime
);
LocalDateTime
endCandidate
=
startCandidate
.
plusMinutes
(
processingTime
);
// 检查是否容纳
if
(
endCandidate
.
isAfter
(
slot
.
getEnd
()))
{
return
CaldEarliestStart
(
machine
,
processingTime
,
currentTime
,
prevtime
,
machineTasks
,
checkprevtime
);
}
else
{
// 创建时间详情
GeneDetail
time
=
new
GeneDetail
();
time
.
setKey
(
slot
.
getKey
());
time
.
setStartTime
((
int
)
ChronoUnit
.
MINUTES
.
between
(
baseTime
,
startCandidate
));
time
.
setEndTime
((
int
)
ChronoUnit
.
MINUTES
.
between
(
baseTime
,
endCandidate
));
times
.
add
(
time
);
// 标记占用
RemoveMachineAvailable
(
machine
,
time
);
return
times
;
}
}
// ========================== CaldEarliestStart(参数与C#一致) ==========================
private
List
<
GeneDetail
>
CaldEarliestStart
(
Machine
machine
,
int
processingTime
,
LocalDateTime
currentTime
,
String
prevtime
,
List
<
Gene
>
machineTasks
,
boolean
checkprevtime
)
{
int
remainingTime
=
processingTime
;
LocalDateTime
st
=
StringUtils
.
isEmpty
(
prevtime
)
?
currentTime
:
LocalDateTime
.
parse
(
prevtime
);
LocalDateTime
prevEnd
=
LocalDateTime
.
of
(
2000
,
1
,
1
,
0
,
0
,
0
);
List
<
GeneDetail
>
times
=
new
ArrayList
<>();
List
<
GeneDetail
>
oldTimes
=
new
ArrayList
<>();
while
(
remainingTime
>
0
)
{
TimeSegment
shift
=
GetCurrentOrNextShift
(
machine
,
currentTime
,
prevtime
,
checkprevtime
);
if
(
shift
==
null
)
break
;
LocalDateTime
shiftStart
=
shift
.
getStart
();
LocalDateTime
shiftEnd
=
shift
.
getEnd
();
// 检查班次间冲突
if
(!
prevEnd
.
isEqual
(
LocalDateTime
.
of
(
2000
,
1
,
1
,
0
,
0
,
0
)))
{
if
(
prevEnd
.
isBefore
(
currentTime
))
{
// 检查班次间任务
LocalDateTime
finalPrevEnd
=
prevEnd
;
boolean
hasTask
=
machineTasks
.
stream
()
.
anyMatch
(
t
->
{
LocalDateTime
taskStart
=
baseTime
.
plusMinutes
(
t
.
getStartTime
());
return
taskStart
.
isAfter
(
finalPrevEnd
)
&&
taskStart
.
isBefore
(
shiftStart
);
});
if
(
hasTask
)
{
// 重置状态
currentTime
=
shiftStart
;
st
=
shiftStart
;
remainingTime
=
processingTime
;
prevEnd
=
LocalDateTime
.
of
(
2000
,
1
,
1
,
0
,
0
,
0
);
oldTimes
.
addAll
(
deepCopyGeneDetailList
(
times
));
times
.
clear
();
continue
;
}
// 检查班次间维修窗口
if
(
machine
.
getMaintenanceWindows
()
!=
null
)
{
LocalDateTime
finalPrevEnd1
=
prevEnd
;
boolean
hasMaintenance
=
machine
.
getMaintenanceWindows
().
stream
()
.
anyMatch
(
w
->
w
.
getStartTime
().
isAfter
(
finalPrevEnd1
)
&&
w
.
getStartTime
().
isBefore
(
shiftStart
));
if
(
hasMaintenance
)
{
currentTime
=
shiftStart
;
st
=
shiftStart
;
remainingTime
=
processingTime
;
prevEnd
=
LocalDateTime
.
of
(
2000
,
1
,
1
,
0
,
0
,
0
);
times
.
clear
();
continue
;
}
}
}
}
prevEnd
=
shiftEnd
;
// 计算有效时间
LocalDateTime
effectiveStart
=
st
.
isAfter
(
shiftStart
)
?
st
:
shiftStart
;
long
availableMinutes
=
ChronoUnit
.
MINUTES
.
between
(
effectiveStart
,
shiftEnd
);
// 处理当前班次
int
processable
=
Math
.
min
(
remainingTime
,
(
int
)
availableMinutes
);
remainingTime
-=
processable
;
currentTime
=
effectiveStart
.
plusMinutes
(
processable
);
// 添加时间详情
GeneDetail
time
=
new
GeneDetail
();
time
.
setKey
(
shift
.
getKey
());
time
.
setStartTime
((
int
)
ChronoUnit
.
MINUTES
.
between
(
baseTime
,
effectiveStart
));
time
.
setEndTime
((
int
)
ChronoUnit
.
MINUTES
.
between
(
baseTime
,
currentTime
));
times
.
add
(
time
);
RemoveMachineAvailable
(
machine
,
time
);
}
// 还原未使用的时间段
AddMachineAvailable
(
machine
,
oldTimes
);
return
times
;
}
// ========================== GetCurrentOrNextShift(参数与C#一致) ==========================
private
TimeSegment
GetCurrentOrNextShift
(
Machine
machine
,
LocalDateTime
time
,
String
prevtime
,
boolean
checkprevtime
)
{
TimeSegment
start
=
null
;
// 查找有效班次
start
=
machine
.
getAvailability
().
stream
()
.
filter
(
slot
->
!
slot
.
isUsed
()
&&
slot
.
getType
()
!=
SegmentType
.
MAINTENANCE
)
.
filter
(
slot
->
slot
.
getStart
().
isAfter
(
time
)
||
slot
.
getEnd
().
isAfter
(
time
))
.
findFirst
()
.
orElse
(
null
);
if
(
start
==
null
)
{
// 生成新时间段
List
<
TimeSegment
>
timeSegments
=
_machineScheduler
.
generateTimeSegment
(
machine
,
time
);
machine
.
getAvailability
().
addAll
(
timeSegments
);
// 更新设备时间线
Machine
originalMachine
=
_machines
.
stream
()
.
filter
(
t
->
t
.
getId
()
==
machine
.
getId
())
.
findFirst
()
.
orElse
(
null
);
if
(
originalMachine
!=
null
)
{
MachineTimeline
timeline
=
_machineScheduler
.
getOrCreateTimeline
(
originalMachine
);
}
// 递归查找
return
GetCurrentOrNextShift
(
machine
,
time
,
prevtime
,
checkprevtime
);
}
return
start
;
}
// ========================== PrintScheduleSummary(参数与C#一致) ==========================
public
void
PrintScheduleSummary
(
ScheduleChromosome
schedule
)
{
System
.
out
.
println
(
"\n=== Schedule Summary ==="
);
// 按订单分组打印
Map
<
Integer
,
List
<
Gene
>>
orderGroups
=
schedule
.
getGenes
().
stream
()
.
collect
(
Collectors
.
groupingBy
(
Gene:
:
getOrderId
));
for
(
Map
.
Entry
<
Integer
,
List
<
Gene
>>
group
:
orderGroups
.
entrySet
())
{
System
.
out
.
printf
(
"\nOrder %d Schedule:%n"
,
group
.
getKey
());
// 按工序排序
List
<
Gene
>
sortedJobs
=
group
.
getValue
().
stream
()
.
sorted
(
Comparator
.
comparingInt
(
Gene:
:
getOperationId
))
.
collect
(
Collectors
.
toList
());
for
(
Gene
job
:
sortedJobs
)
{
Product
product
=
_products
.
stream
()
.
filter
(
p
->
p
.
getId
()
==
job
.
getProductId
())
.
findFirst
()
.
orElse
(
null
);
Operation
operation
=
product
!=
null
?
product
.
getOperations
().
stream
()
.
filter
(
o
->
o
.
getId
()
==
job
.
getOperationId
())
.
findFirst
()
.
orElse
(
null
)
:
null
;
if
(
product
!=
null
&&
operation
!=
null
)
{
String
print
=
String
.
format
(
"[%s-%s] Order %d, Product %s, Machine %d, Operation %d, Batch %d, processingTime %d"
,
ConvertTime
(
job
.
getStartTime
()),
ConvertTime
(
job
.
getEndTime
()),
job
.
getOrderId
(),
product
.
getName
(),
job
.
getMachineId
(),
operation
.
getSequence
(),
job
.
getBatchSize
(),
job
.
getProcessingTime
()
);
System
.
out
.
println
(
print
);
}
}
}
}
// ========================== WriteScheduleSummary(参数与C#一致) ==========================
public
void
WriteScheduleSummary
(
ScheduleChromosome
schedule
)
{
// 写入日志
FileHelper
.
writeLogFile
(
String
.
format
(
"\n=== Schedule Summary === %f"
,
schedule
.
getFitness
()));
FileHelper
.
writeLogFile
(
String
.
format
(
"Makespan: %f minutes"
,
schedule
.
getObjectiveValues
().
get
(
0
)));
FileHelper
.
writeLogFile
(
String
.
format
(
"Total Tardiness: %f hours"
,
schedule
.
getObjectiveValues
().
get
(
1
)));
FileHelper
.
writeLogFile
(
String
.
format
(
"Setup Time: %f minutes"
,
schedule
.
getObjectiveValues
().
get
(
2
)));
FileHelper
.
writeLogFile
(
String
.
format
(
"Flow Time: %f minutes"
,
schedule
.
getObjectiveValues
().
get
(
3
)));
FileHelper
.
writeLogFile
(
String
.
format
(
"Machine Load Balance: %.2f%%"
,
schedule
.
getObjectiveValues
().
get
(
4
)
*
100
));
FileHelper
.
writeLogFile
(
"-------------------------"
);
// 按订单分组写入
Map
<
Integer
,
List
<
Gene
>>
orderGroups
=
schedule
.
getGenes
().
stream
()
.
collect
(
Collectors
.
groupingBy
(
Gene:
:
getOrderId
));
for
(
Map
.
Entry
<
Integer
,
List
<
Gene
>>
group
:
orderGroups
.
entrySet
())
{
List
<
Gene
>
sortedJobs
=
group
.
getValue
().
stream
()
.
sorted
(
Comparator
.
comparingInt
(
Gene:
:
getOperationId
))
.
collect
(
Collectors
.
toList
());
for
(
Gene
job
:
sortedJobs
)
{
Product
product
=
_products
.
stream
()
.
filter
(
p
->
p
.
getId
()
==
job
.
getProductId
())
.
findFirst
()
.
orElse
(
null
);
Operation
operation
=
product
!=
null
?
product
.
getOperations
().
stream
()
.
filter
(
o
->
o
.
getId
()
==
job
.
getOperationId
())
.
findFirst
()
.
orElse
(
null
)
:
null
;
if
(
product
!=
null
&&
operation
!=
null
)
{
StringBuilder
sb
=
new
StringBuilder
();
sb
.
append
(
String
.
format
(
"[%d-%d]:[%s-%s] Order %d, Product %s, Machine %d, Operation %d, Batch %d, processingTime %d"
,
job
.
getStartTime
(),
job
.
getEndTime
(),
ConvertTime
(
job
.
getStartTime
()),
ConvertTime
(
job
.
getEndTime
()),
job
.
getOrderId
(),
product
.
getName
(),
job
.
getMachineId
(),
operation
.
getSequence
(),
job
.
getBatchSize
(),
job
.
getProcessingTime
()
));
// 追加基因详情
for
(
GeneDetail
d
:
job
.
getGeneDetails
())
{
sb
.
append
(
String
.
format
(
"\n\t\t\t\t\t\t\t\t\t\t [%d-%d]:[%s-%s] %d"
,
d
.
getStartTime
(),
d
.
getEndTime
(),
ConvertTime
(
d
.
getStartTime
()),
ConvertTime
(
d
.
getEndTime
()),
d
.
getEndTime
()
-
d
.
getStartTime
()
));
}
FileHelper
.
writeLogFile
(
sb
.
toString
());
}
}
FileHelper
.
writeLogFile
(
""
);
}
}
// ========================== ConvertTime(参数与C#一致) ==========================
private
String
ConvertTime
(
int
minute
)
{
return
baseTime
.
plusMinutes
(
minute
).
format
(
java
.
time
.
format
.
DateTimeFormatter
.
ofPattern
(
"MM-dd HH:mm"
));
}
// ========================== 深拷贝工具方法(替换C# Mapster,方法名前缀统一为deepCopy) ==========================
private
List
<
Product
>
deepCopyProductList
(
List
<
Product
>
source
)
{
return
source
==
null
?
new
ArrayList
<>()
:
source
.
stream
().
map
(
this
::
deepCopyProduct
).
collect
(
Collectors
.
toList
());
}
private
Product
deepCopyProduct
(
Product
source
)
{
if
(
source
==
null
)
return
null
;
Product
copy
=
new
Product
();
copy
.
setId
(
source
.
getId
());
copy
.
setName
(
source
.
getName
());
copy
.
setOperations
(
deepCopyOperationList
(
source
.
getOperations
()));
return
copy
;
}
private
List
<
Operation
>
deepCopyOperationList
(
List
<
Operation
>
source
)
{
return
source
==
null
?
new
ArrayList
<>()
:
source
.
stream
().
map
(
this
::
deepCopyOperation
).
collect
(
Collectors
.
toList
());
}
private
Operation
deepCopyOperation
(
Operation
source
)
{
if
(
source
==
null
)
return
null
;
Operation
copy
=
new
Operation
();
copy
.
setId
(
source
.
getId
());
copy
.
setProductId
(
source
.
getProductId
());
copy
.
setSequence
(
source
.
getSequence
());
copy
.
setInterrupt
(
source
.
isInterrupt
());
copy
.
setMachineOptions
(
deepCopyMachineOptionList
(
source
.
getMachineOptions
()));
return
copy
;
}
private
List
<
MachineOption
>
deepCopyMachineOptionList
(
List
<
MachineOption
>
source
)
{
return
source
==
null
?
new
ArrayList
<>()
:
source
.
stream
().
map
(
this
::
deepCopyMachineOption
).
collect
(
Collectors
.
toList
());
}
private
MachineOption
deepCopyMachineOption
(
MachineOption
source
)
{
if
(
source
==
null
)
return
null
;
MachineOption
copy
=
new
MachineOption
();
copy
.
setMachineId
(
source
.
getMachineId
());
copy
.
setProcessingTime
(
source
.
getProcessingTime
());
copy
.
setSetupTime
(
source
.
getSetupTime
());
return
copy
;
}
private
List
<
Machine
>
deepCopyMachineList
(
List
<
Machine
>
source
)
{
return
source
==
null
?
new
ArrayList
<>()
:
source
.
stream
().
map
(
this
::
deepCopyMachine
).
collect
(
Collectors
.
toList
());
}
private
Machine
deepCopyMachine
(
Machine
source
)
{
if
(
source
==
null
)
return
null
;
Machine
copy
=
new
Machine
();
copy
.
setId
(
source
.
getId
());
copy
.
setName
(
source
.
getName
());
copy
.
setEarliestTime
(
source
.
getEarliestTime
());
copy
.
setTotalTaskTime
(
source
.
getTotalTaskTime
());
copy
.
setShifts
(
deepCopyShiftList
(
source
.
getShifts
()));
copy
.
setMaintenanceWindows
(
deepCopyMaintenanceWindowList
(
source
.
getMaintenanceWindows
()));
copy
.
setAvailability
(
deepCopyTimeSegmentList
(
source
.
getAvailability
()));
copy
.
setShiftsChanged
(
source
.
getShiftsChanged
());
copy
.
setMaintenanceWindowsChanged
(
source
.
getMaintenanceWindowsChanged
());
return
copy
;
}
private
List
<
Shift
>
deepCopyShiftList
(
List
<
Shift
>
source
)
{
return
source
==
null
?
new
ArrayList
<>()
:
source
.
stream
().
map
(
this
::
deepCopyShift
).
collect
(
Collectors
.
toList
());
}
private
Shift
deepCopyShift
(
Shift
source
)
{
if
(
source
==
null
)
return
null
;
Shift
copy
=
new
Shift
();
copy
.
setStartTime
(
source
.
getStartTime
());
copy
.
setEndTime
(
source
.
getEndTime
());
copy
.
setDays
(
source
.
getDays
()
!=
null
?
new
HashSet
<>(
source
.
getDays
())
:
null
);
copy
.
setShiftDate
(
source
.
getShiftDate
());
copy
.
setTemporaryShift
(
source
.
isTemporaryShift
());
copy
.
setPriority
(
source
.
getPriority
());
return
copy
;
}
private
List
<
MaintenanceWindow
>
deepCopyMaintenanceWindowList
(
List
<
MaintenanceWindow
>
source
)
{
return
source
==
null
?
new
ArrayList
<>()
:
source
.
stream
().
map
(
this
::
deepCopyMaintenanceWindow
).
collect
(
Collectors
.
toList
());
}
private
MaintenanceWindow
deepCopyMaintenanceWindow
(
MaintenanceWindow
source
)
{
if
(
source
==
null
)
return
null
;
MaintenanceWindow
copy
=
new
MaintenanceWindow
();
copy
.
setStartTime
(
source
.
getStartTime
());
copy
.
setEndTime
(
source
.
getEndTime
());
copy
.
setReason
(
source
.
getReason
());
return
copy
;
}
private
List
<
TimeSegment
>
deepCopyTimeSegmentList
(
List
<
TimeSegment
>
source
)
{
return
source
==
null
?
new
ArrayList
<>()
:
source
.
stream
().
map
(
this
::
deepCopyTimeSegment
).
collect
(
Collectors
.
toList
());
}
private
TimeSegment
deepCopyTimeSegment
(
TimeSegment
source
)
{
if
(
source
==
null
)
return
null
;
TimeSegment
copy
=
new
TimeSegment
();
copy
.
setKey
(
source
.
getKey
());
copy
.
setStart
(
source
.
getStart
());
copy
.
setEnd
(
source
.
getEnd
());
copy
.
setEarliestTime
(
source
.
getEarliestTime
());
copy
.
setTotalTaskTime
(
source
.
getTotalTaskTime
());
copy
.
setType
(
source
.
getType
());
copy
.
setHoliday
(
source
.
isHoliday
());
copy
.
setUsed
(
source
.
isUsed
());
return
copy
;
}
private
List
<
Order
>
deepCopyOrderList
(
List
<
Order
>
source
)
{
return
source
==
null
?
new
ArrayList
<>()
:
source
.
stream
().
map
(
this
::
deepCopyOrder
).
collect
(
Collectors
.
toList
());
}
private
Order
deepCopyOrder
(
Order
source
)
{
if
(
source
==
null
)
return
null
;
Order
copy
=
new
Order
();
copy
.
setId
(
source
.
getId
());
copy
.
setProductId
(
source
.
getProductId
());
copy
.
setQuantity
(
source
.
getQuantity
());
copy
.
setDueDate
(
source
.
getDueDate
());
copy
.
setOrderCompletion
(
source
.
getOrderCompletion
());
copy
.
setTardiness
(
source
.
getTardiness
());
copy
.
setPriority
(
source
.
getPriority
());
copy
.
setCanSplit
(
source
.
isCanSplit
());
copy
.
setCanInterrupt
(
source
.
isCanInterrupt
());
return
copy
;
}
private
List
<
Gene
>
deepCopyGeneList
(
List
<
Gene
>
source
)
{
return
source
==
null
?
new
ArrayList
<>()
:
source
.
stream
().
map
(
this
::
deepCopyGene
).
collect
(
Collectors
.
toList
());
}
private
Gene
deepCopyGene
(
Gene
source
)
{
if
(
source
==
null
)
return
null
;
Gene
copy
=
new
Gene
();
copy
.
setOrderId
(
source
.
getOrderId
());
copy
.
setProductId
(
source
.
getProductId
());
copy
.
setOperationId
(
source
.
getOperationId
());
copy
.
setMachineId
(
source
.
getMachineId
());
copy
.
setBatchSize
(
source
.
getBatchSize
());
copy
.
setStartTime
(
source
.
getStartTime
());
copy
.
setEndTime
(
source
.
getEndTime
());
copy
.
setProcessingTime
(
source
.
getProcessingTime
());
copy
.
setGeneDetails
(
deepCopyGeneDetailList
(
source
.
getGeneDetails
()));
return
copy
;
}
private
List
<
GeneDetail
>
deepCopyGeneDetailList
(
List
<
GeneDetail
>
source
)
{
return
source
==
null
?
new
ArrayList
<>()
:
source
.
stream
().
map
(
this
::
deepCopyGeneDetail
).
collect
(
Collectors
.
toList
());
}
private
GeneDetail
deepCopyGeneDetail
(
GeneDetail
source
)
{
if
(
source
==
null
)
return
null
;
GeneDetail
copy
=
new
GeneDetail
();
copy
.
setKey
(
source
.
getKey
());
copy
.
setStartTime
(
source
.
getStartTime
());
copy
.
setEndTime
(
source
.
getEndTime
());
return
copy
;
}
private
ScheduleChromosome
deepCopyScheduleChromosome
(
ScheduleChromosome
source
)
{
if
(
source
==
null
)
return
null
;
ScheduleChromosome
copy
=
new
ScheduleChromosome
(
source
.
getBaseTime
());
copy
.
setGenes
(
deepCopyGeneList
(
source
.
getGenes
()));
copy
.
setOrders
(
deepCopyOrderList
(
source
.
getOrders
()));
copy
.
setMachines
(
deepCopyMachineList
(
source
.
getMachines
()));
copy
.
setObjectiveValues
(
new
HashMap
<>(
source
.
getObjectiveValues
()));
copy
.
setFitness
(
source
.
getFitness
());
copy
.
setTardiness
(
source
.
getTardiness
());
return
copy
;
}
// ========================== 辅助类:StringUtils(对应C#字符串工具) ==========================
private
static
class
StringUtils
{
public
static
boolean
isEmpty
(
String
str
)
{
return
str
==
null
||
str
.
trim
().
isEmpty
();
}
}
}
\ No newline at end of file
src/main/java/com/aps/service/plan/MachineSchedulerService.java
0 → 100644
View file @
1dd2520c
package
com
.
aps
.
service
.
plan
;
import
com.aps.entity.basic.*
;
import
java.time.DayOfWeek
;
import
java.time.Duration
;
import
java.time.LocalDate
;
import
java.time.LocalDateTime
;
import
java.util.*
;
import
java.util.concurrent.ConcurrentHashMap
;
import
java.util.stream.Collectors
;
public
class
MachineSchedulerService
{
// 全局缓存(线程安全)
private
static
final
ConcurrentHashMap
<
Integer
,
MachineTimeline
>
timelineCache
=
new
ConcurrentHashMap
<>();
private
LocalDateTime
currentTime
;
private
List
<
Holiday
>
holidays
;
public
MachineSchedulerService
(
List
<
Holiday
>
holidays
,
LocalDateTime
currentTime
)
{
this
.
holidays
=
holidays
!=
null
?
holidays
:
new
ArrayList
<>();
this
.
currentTime
=
currentTime
;
}
public
MachineTimeline
getOrCreateTimeline
(
Machine
machine
)
{
int
machineId
=
machine
.
getId
();
// 尝试从缓存获取
MachineTimeline
timeline
=
timelineCache
.
get
(
machineId
);
if
(
timeline
!=
null
)
{
// 检查有效期(4小时刷新)
if
(
Duration
.
between
(
timeline
.
getLastUpdated
(),
LocalDateTime
.
now
()).
toHours
()
<
4
)
{
return
timeline
;
}
}
// 创建新时间线(60天范围)
MachineTimeline
newTimeline
=
generateTimeline
(
machine
);
timelineCache
.
put
(
machineId
,
newTimeline
);
return
newTimeline
;
}
private
MachineTimeline
generateTimeline
(
Machine
machine
)
{
MachineTimeline
timeline
=
new
MachineTimeline
();
timeline
.
setMachineId
(
machine
.
getId
());
timeline
.
setValidFrom
(
currentTime
);
timeline
.
setValidTo
(
currentTime
.
plusDays
(
60
));
timeline
.
setLastUpdated
(
LocalDateTime
.
now
());
LocalDate
currentDate
=
currentTime
.
toLocalDate
();
LocalDate
endDate
=
currentTime
.
plusDays
(
60
).
toLocalDate
();
List
<
TimeSegment
>
allSegments
=
new
ArrayList
<>();
while
(!
currentDate
.
isAfter
(
endDate
))
{
// 检查是否在假期内
boolean
isHolidayPeriod
=
isHoliday
(
currentDate
);
// 生成当日时间段
List
<
TimeSegment
>
daySegments
=
calculateDaySegments
(
machine
,
currentDate
,
isHolidayPeriod
);
allSegments
.
addAll
(
daySegments
);
// 跳到下一天
currentDate
=
currentDate
.
plusDays
(
1
);
}
// 合并连续时间段
timeline
.
setSegments
(
mergeSegments
(
allSegments
));
// 处理维护窗口
if
(
machine
.
getMaintenanceWindows
()
!=
null
&&
!
timeline
.
getSegments
().
isEmpty
())
{
LocalDateTime
maxEnd
=
timeline
.
getSegments
().
stream
()
.
map
(
TimeSegment:
:
getEnd
)
.
max
(
LocalDateTime:
:
compareTo
)
.
orElse
(
LocalDateTime
.
MIN
);
for
(
MaintenanceWindow
maintenanceWindow
:
machine
.
getMaintenanceWindows
())
{
if
(
maintenanceWindow
.
getStartTime
().
isAfter
(
maxEnd
))
{
continue
;
}
updateSegmentsForMaintenance
(
timeline
.
getSegments
(),
maintenanceWindow
.
getStartTime
(),
maintenanceWindow
.
getEndTime
());
}
}
return
timeline
;
}
public
List
<
TimeSegment
>
generateTimeSegment
(
Machine
machine
,
LocalDateTime
currentTime
)
{
int
machineId
=
machine
.
getId
();
MachineTimeline
timeline
=
timelineCache
.
get
(
machineId
);
if
(
timeline
==
null
)
{
timeline
=
new
MachineTimeline
();
timeline
.
setMachineId
(
machine
.
getId
());
timeline
.
setValidFrom
(
currentTime
);
timeline
.
setValidTo
(
currentTime
.
plusDays
(
60
));
timeline
.
setLastUpdated
(
LocalDateTime
.
now
());
timeline
.
setSegments
(
new
ArrayList
<>());
}
else
{
timeline
.
setValidTo
(
currentTime
.
plusDays
(
60
));
timeline
.
setLastUpdated
(
LocalDateTime
.
now
());
}
LocalDate
currentDate
=
currentTime
.
toLocalDate
();
LocalDate
endDate
=
currentTime
.
plusDays
(
60
).
toLocalDate
();
List
<
TimeSegment
>
segments
=
new
ArrayList
<>();
while
(!
currentDate
.
isAfter
(
endDate
))
{
// 检查是否在假期内
boolean
isHolidayPeriod
=
isHoliday
(
currentDate
);
// 生成当日时间段
List
<
TimeSegment
>
daySegments
=
calculateDaySegments
(
machine
,
currentDate
,
isHolidayPeriod
);
segments
.
addAll
(
daySegments
);
// 跳到下一天
currentDate
=
currentDate
.
plusDays
(
1
);
}
// 处理维护窗口
if
(
machine
.
getMaintenanceWindows
()
!=
null
&&
!
segments
.
isEmpty
())
{
LocalDateTime
maxEnd
=
segments
.
stream
()
.
map
(
TimeSegment:
:
getEnd
)
.
max
(
LocalDateTime:
:
compareTo
)
.
orElse
(
LocalDateTime
.
MIN
);
for
(
MaintenanceWindow
maintenanceWindow
:
machine
.
getMaintenanceWindows
())
{
if
(
maintenanceWindow
.
getStartTime
().
isAfter
(
maxEnd
)
||
maintenanceWindow
.
getStartTime
().
isBefore
(
currentTime
))
{
continue
;
}
updateSegmentsForMaintenance
(
segments
,
maintenanceWindow
.
getStartTime
(),
maintenanceWindow
.
getEndTime
());
}
}
// 添加新生成的段到时间线
timeline
.
getSegments
().
addAll
(
copyTimeSegments
(
segments
));
// 合并连续时间段
timeline
.
setSegments
(
mergeSegments
(
timeline
.
getSegments
()));
segments
=
mergeSegments
(
segments
);
return
segments
;
}
private
boolean
isHoliday
(
LocalDate
currentDate
)
{
for
(
Holiday
holiday
:
holidays
)
{
LocalDateTime
holidayStart
=
holiday
.
getStart
();
LocalDateTime
holidayEnd
=
holiday
.
getEnd
();
if
(
holidayStart
!=
null
&&
holidayEnd
!=
null
)
{
LocalDate
holidayStartDate
=
holidayStart
.
toLocalDate
();
LocalDate
holidayEndDate
=
holidayEnd
.
toLocalDate
();
if
((
currentDate
.
isEqual
(
holidayStartDate
)
||
currentDate
.
isAfter
(
holidayStartDate
))
&&
(
currentDate
.
isEqual
(
holidayEndDate
)
||
currentDate
.
isBefore
(
holidayEndDate
)))
{
return
true
;
}
}
}
return
false
;
}
private
List
<
TimeSegment
>
calculateDaySegments
(
Machine
machine
,
LocalDate
date
,
boolean
isHoliday
)
{
List
<
TimeSegment
>
segments
=
new
ArrayList
<>();
if
(
isHoliday
)
{
// 假期:只处理特定日期的班次
List
<
Shift
>
shifts
=
machine
.
getShifts
().
stream
()
.
filter
(
s
->
s
.
getDays
()
==
null
&&
s
.
getShiftDate
()
!=
null
&&
s
.
getShiftDate
().
toLocalDate
().
equals
(
date
))
.
collect
(
Collectors
.
toList
());
for
(
Shift
shift
:
shifts
)
{
LocalDateTime
shiftStart
=
date
.
atTime
(
shift
.
getStartTime
());
LocalDateTime
shiftEnd
=
shift
.
getEndTime
().
isBefore
(
shift
.
getStartTime
())
?
date
.
plusDays
(
1
).
atTime
(
shift
.
getEndTime
())
:
date
.
atTime
(
shift
.
getEndTime
());
segments
.
add
(
new
TimeSegment
(
shiftStart
,
shiftEnd
,
shift
.
isTemporaryShift
()
?
SegmentType
.
TEMP
:
SegmentType
.
REGULAR
,
false
));
}
}
else
{
// 非假期:处理常规班次
List
<
Shift
>
shifts
=
machine
.
getShifts
().
stream
()
.
filter
(
s
->
s
.
getDays
()
!=
null
&&
containsDay
(
s
.
getDays
(),
date
.
getDayOfWeek
()))
.
collect
(
Collectors
.
toList
());
for
(
Shift
shift
:
shifts
)
{
LocalDateTime
shiftStart
=
date
.
atTime
(
shift
.
getStartTime
());
LocalDateTime
shiftEnd
=
shift
.
getEndTime
().
isBefore
(
shift
.
getStartTime
())
?
date
.
plusDays
(
1
).
atTime
(
shift
.
getEndTime
())
:
date
.
atTime
(
shift
.
getEndTime
());
segments
.
add
(
new
TimeSegment
(
shiftStart
,
shiftEnd
,
shift
.
isTemporaryShift
()
?
SegmentType
.
TEMP
:
SegmentType
.
REGULAR
,
false
));
}
}
return
segments
;
}
/**
* 检查班次是否包含指定的星期几
* JSON中的Day映射:0=周日, 1=周一, 2=周二, ..., 6=周六
* Java DayOfWeek: MONDAY=1, TUESDAY=2, ..., SUNDAY=7
*/
private
boolean
containsDay
(
Set
<
Integer
>
shiftDays
,
DayOfWeek
targetDay
)
{
if
(
shiftDays
==
null
||
shiftDays
.
isEmpty
())
{
return
false
;
}
// 将Java的DayOfWeek转换为JSON格式的数字
int
targetDayValue
=
targetDay
.
getValue
();
// 特殊处理周日:JSON中0表示周日,Java中Sunday是7
if
(
targetDay
==
DayOfWeek
.
SUNDAY
)
{
return
shiftDays
.
contains
(
0
)
||
shiftDays
.
contains
(
7
);
}
return
shiftDays
.
contains
(
targetDayValue
);
}
private
List
<
TimeSegment
>
mergeSegments
(
List
<
TimeSegment
>
segments
)
{
List
<
TimeSegment
>
maintenanceSegments
=
segments
.
stream
()
.
filter
(
t
->
t
.
getType
()
==
SegmentType
.
MAINTENANCE
)
.
collect
(
Collectors
.
toList
());
List
<
TimeSegment
>
otherSegments
=
segments
.
stream
()
.
filter
(
t
->
t
.
getType
()
!=
SegmentType
.
MAINTENANCE
)
.
collect
(
Collectors
.
toList
());
// 按开始时间排序
otherSegments
.
sort
(
Comparator
.
comparing
(
TimeSegment:
:
getStart
));
Stack
<
TimeSegment
>
merged
=
new
Stack
<>();
for
(
TimeSegment
seg
:
otherSegments
)
{
if
(!
merged
.
isEmpty
()
&&
!
merged
.
peek
().
getEnd
().
isBefore
(
seg
.
getStart
()))
{
TimeSegment
top
=
merged
.
peek
();
if
(
top
.
getEnd
().
isBefore
(
seg
.
getEnd
()))
{
top
.
setEnd
(
seg
.
getEnd
());
}
}
else
{
seg
.
setKey
(
UUID
.
randomUUID
().
toString
());
merged
.
push
(
seg
);
}
}
List
<
TimeSegment
>
result
=
new
ArrayList
<>(
merged
);
result
.
addAll
(
maintenanceSegments
);
// 按开始时间排序
result
.
sort
(
Comparator
.
comparing
(
TimeSegment:
:
getStart
));
return
result
;
}
private
void
updateSegmentsForMaintenance
(
List
<
TimeSegment
>
segments
,
LocalDateTime
maintenanceStart
,
LocalDateTime
maintenanceEnd
)
{
if
(
segments
.
isEmpty
())
return
;
// 1. 二分查找
int
firstIndex
=
binarySearchSegment
(
segments
,
maintenanceStart
);
if
(
firstIndex
==
segments
.
size
())
return
;
// 2. 收集有交集的段
List
<
Integer
>
indicesToProcess
=
new
ArrayList
<>();
int
i
=
firstIndex
;
while
(
i
<
segments
.
size
()
&&
segments
.
get
(
i
).
getStart
().
isBefore
(
maintenanceEnd
))
{
if
(
segments
.
get
(
i
).
getEnd
().
isAfter
(
maintenanceStart
))
{
indicesToProcess
.
add
(
i
);
}
i
++;
}
// 3. 倒序处理
for
(
int
j
=
indicesToProcess
.
size
()
-
1
;
j
>=
0
;
j
--)
{
int
index
=
indicesToProcess
.
get
(
j
);
TimeSegment
seg
=
segments
.
get
(
index
);
LocalDateTime
segStart
=
seg
.
getStart
();
LocalDateTime
segEnd
=
seg
.
getEnd
();
// 完全覆盖
if
((
maintenanceStart
.
isBefore
(
segStart
)
||
maintenanceStart
.
equals
(
segStart
))
&&
(
maintenanceEnd
.
isAfter
(
segEnd
)
||
maintenanceEnd
.
equals
(
segEnd
)))
{
segments
.
remove
(
index
);
}
// 维护时间段在段内部
else
if
(
maintenanceStart
.
isAfter
(
segStart
)
&&
maintenanceEnd
.
isBefore
(
segEnd
))
{
// 分割:原段变成前半段 [segStart, maintenanceStart)
seg
.
setEnd
(
maintenanceStart
);
// 添加后半段 [maintenanceEnd, segEnd)
segments
.
add
(
index
+
1
,
new
TimeSegment
(
maintenanceEnd
,
segEnd
,
seg
.
getType
(),
seg
.
isHoliday
()
));
}
// 维护时间段覆盖开始部分
else
if
(
maintenanceStart
.
isBefore
(
segStart
)
||
maintenanceStart
.
equals
(
segStart
))
{
// 保留:维护时间段之后的部分 [maintenanceEnd, segEnd)
seg
.
setStart
(
maintenanceEnd
);
}
// 维护时间段覆盖结束部分
else
if
(
maintenanceEnd
.
isAfter
(
segEnd
)
||
maintenanceEnd
.
equals
(
segEnd
))
{
// 保留:维护时间段之前的部分 [segStart, maintenanceStart)
seg
.
setEnd
(
maintenanceStart
);
}
}
segments
.
add
(
new
TimeSegment
(
maintenanceStart
,
maintenanceEnd
,
SegmentType
.
MAINTENANCE
,
false
));
}
private
int
binarySearchSegment
(
List
<
TimeSegment
>
segments
,
LocalDateTime
maintenanceStart
)
{
int
left
=
0
;
int
right
=
segments
.
size
()
-
1
;
int
result
=
segments
.
size
();
while
(
left
<=
right
)
{
int
mid
=
left
+
(
right
-
left
)
/
2
;
TimeSegment
seg
=
segments
.
get
(
mid
);
if
((
seg
.
getStart
().
isBefore
(
maintenanceStart
)
||
seg
.
getStart
().
equals
(
maintenanceStart
))
&&
maintenanceStart
.
isBefore
(
seg
.
getEnd
()))
{
return
mid
;
}
if
(
seg
.
getEnd
().
isBefore
(
maintenanceStart
)
||
seg
.
getEnd
().
equals
(
maintenanceStart
))
{
left
=
mid
+
1
;
}
else
{
result
=
mid
;
right
=
mid
-
1
;
}
}
return
result
;
}
private
List
<
TimeSegment
>
copyTimeSegments
(
List
<
TimeSegment
>
originals
)
{
return
originals
.
stream
()
.
map
(
seg
->
{
TimeSegment
copy
=
new
TimeSegment
();
copy
.
setStart
(
seg
.
getStart
());
copy
.
setEnd
(
seg
.
getEnd
());
copy
.
setType
(
seg
.
getType
());
copy
.
setHoliday
(
seg
.
isHoliday
());
copy
.
setUsed
(
seg
.
isUsed
());
copy
.
setKey
(
seg
.
getKey
());
return
copy
;
})
.
collect
(
Collectors
.
toList
());
}
// 清理缓存的方法
public
static
void
clearCache
()
{
timelineCache
.
clear
();
}
public
static
int
getCacheSize
()
{
return
timelineCache
.
size
();
}
}
\ No newline at end of file
src/main/java/com/aps/service/plan/PlanSchedulerService.java
0 → 100644
View file @
1dd2520c
package
com
.
aps
.
service
.
plan
;
import
com.aps.common.util.JsonFileReader
;
import
com.aps.entity.Schedule.GenVO
;
import
com.aps.entity.Schedule.MachineVO
;
import
com.aps.entity.Schedule.PlanResourceTaskGanttVO
;
import
com.aps.entity.basic.*
;
import
org.springframework.stereotype.Service
;
import
java.math.BigDecimal
;
import
java.time.LocalDateTime
;
import
java.util.*
;
import
java.util.stream.Collectors
;
@Service
public
class
PlanSchedulerService
{
private
final
LocalDateTime
baseTime
=
LocalDateTime
.
of
(
2025
,
10
,
1
,
0
,
0
,
0
);
public
List
<
PlanResourceTaskGanttVO
>
execute
()
{
try
{
// 1. 读取数据
List
<
Machine
>
machines
=
JsonFileReader
.
readListFromResources
(
"machines.json"
,
Machine
.
class
);
List
<
Product
>
products
=
JsonFileReader
.
readListFromResources
(
"products.json"
,
Product
.
class
);
List
<
Order
>
orders
=
JsonFileReader
.
readListFromResources
(
"orders.json"
,
Order
.
class
);
// 2. 创建节假日
List
<
Holiday
>
holidays
=
Arrays
.
asList
(
new
Holiday
(
LocalDateTime
.
of
(
2025
,
10
,
1
,
0
,
0
),
LocalDateTime
.
of
(
2025
,
10
,
7
,
23
,
59
))
);
// 3. 创建调度服务
MachineSchedulerService
machineScheduler
=
new
MachineSchedulerService
(
holidays
,
LocalDateTime
.
of
(
2025
,
10
,
1
,
0
,
0
,
0
));
// 4. 初始化机器时间线
for
(
Machine
machine
:
machines
)
{
MachineTimeline
timeline
=
machineScheduler
.
getOrCreateTimeline
(
machine
);
machine
.
setAvailability
(
timeline
.
getSegments
());
}
// 5. 执行调度算法
AlgorithmScheduler6
scheduler
=
new
AlgorithmScheduler6
(
products
,
machines
,
orders
,
machineScheduler
);
List
<
ScheduleChromosome
>
scheduleChromosomes
=
scheduler
.
RunAll
();
List
<
PlanResourceTaskGanttVO
>
ganttlist
=
new
ArrayList
<>();
long
sceneId
=
1L
;
for
(
ScheduleChromosome
chromosome
:
scheduleChromosomes
)
{
// 转换基因列表和设备列表
List
<
GenVO
>
genVOS
=
convertGeneListToGenVO
(
chromosome
.
getGenes
(),
baseTime
);
List
<
MachineVO
>
machineVOS
=
machines
.
stream
()
.
map
(
this
::
convertToVO
)
.
collect
(
Collectors
.
toList
());
// 按设备ID分组任务
Map
<
Integer
,
List
<
GenVO
>>
taskMap
=
genVOS
.
stream
()
.
collect
(
Collectors
.
groupingBy
(
GenVO:
:
getEquipId
));
// 为每个设备设置任务
for
(
MachineVO
machine
:
machineVOS
)
{
Integer
equipId
=
Integer
.
valueOf
(
machine
.
getEquipId
());
List
<
GenVO
>
tasks
=
taskMap
.
get
(
equipId
);
if
(
tasks
!=
null
)
{
// 按开始时间排序
tasks
.
sort
(
Comparator
.
comparing
(
GenVO:
:
getStartTime
));
machine
.
setTasks
(
tasks
);
}
else
{
machine
.
setTasks
(
new
ArrayList
<>());
// 如果没有任务,设置为空列表
}
}
// 现在machineVOS中的每个MachineVO都包含了对应的任务列表
PlanResourceTaskGanttVO
ganttVO
=
new
PlanResourceTaskGanttVO
()
.
setResources
(
machineVOS
)
.
setEarliestTaskStartTime
(
LocalDateTime
.
of
(
2025
,
9
,
1
,
0
,
0
,
0
))
.
setLastTaskAssignmentTime
(
LocalDateTime
.
of
(
2025
,
12
,
1
,
0
,
0
,
0
))
.
setSceneId
(
sceneId
);
sceneId
++;
ganttlist
.
add
(
ganttVO
);
}
return
ganttlist
;
}
catch
(
Exception
e
)
{
throw
new
RuntimeException
(
"调度执行失败"
,
e
);
}
}
public
GenVO
convertGeneToGenVO
(
Gene
gene
,
LocalDateTime
baseTime
)
{
GenVO
genVO
=
new
GenVO
();
genVO
.
setOrderId
(
String
.
valueOf
(
gene
.
getOrderId
()));
genVO
.
setOperationId
(
gene
.
getOperationId
());
genVO
.
setEquipId
(
gene
.
getMachineId
());
genVO
.
setQuantity
(
BigDecimal
.
valueOf
(
gene
.
getBatchSize
()));
genVO
.
setStartTime
(
baseTime
.
plusMinutes
(
gene
.
getStartTime
()));
genVO
.
setEndTime
(
baseTime
.
plusMinutes
(
gene
.
getEndTime
()));
genVO
.
setOperationName
(
""
);
// 从其他数据源获取
genVO
.
setEquipName
(
""
);
// 从其他数据源获取
return
genVO
;
}
// 批量转换
public
List
<
GenVO
>
convertGeneListToGenVO
(
List
<
Gene
>
geneList
,
LocalDateTime
baseTime
)
{
return
geneList
.
stream
()
.
map
(
gene
->
convertGeneToGenVO
(
gene
,
baseTime
))
.
collect
(
Collectors
.
toList
());
}
private
MachineVO
convertToVO
(
Machine
machine
)
{
MachineVO
machineVO
=
new
MachineVO
();
machineVO
.
setId
(
machine
.
getId
());
machineVO
.
setEquipId
(
String
.
valueOf
(
machine
.
getId
()));
machineVO
.
setEquipName
(
machine
.
getName
());
return
machineVO
;
}
}
\ No newline at end of file
src/main/java/com/example/config/SwaggerConfig.java
deleted
100644 → 0
View file @
fee62722
package
com
.
example
.
config
;
import
org.springframework.context.annotation.Bean
;
import
org.springframework.context.annotation.Configuration
;
import
springfox.documentation.builders.ApiInfoBuilder
;
import
springfox.documentation.builders.PathSelectors
;
import
springfox.documentation.builders.RequestHandlerSelectors
;
import
springfox.documentation.service.ApiInfo
;
import
springfox.documentation.spi.DocumentationType
;
import
springfox.documentation.spring.web.plugins.Docket
;
import
springfox.documentation.swagger2.annotations.EnableSwagger2
;
@Configuration
@EnableSwagger2
public
class
SwaggerConfig
{
@Bean
public
Docket
createRestApi
()
{
return
new
Docket
(
DocumentationType
.
SWAGGER_2
)
.
apiInfo
(
apiInfo
())
.
select
()
.
apis
(
RequestHandlerSelectors
.
basePackage
(
"com.example.controller"
))
// 修改为您的包名
.
paths
(
PathSelectors
.
any
())
.
build
();
}
private
ApiInfo
apiInfo
()
{
return
new
ApiInfoBuilder
()
.
title
(
"Demo2 API 文档"
)
.
description
(
"多数据库项目接口文档"
)
.
version
(
"1.0.0"
)
.
build
();
}
}
\ No newline at end of file
src/main/java/com/example/controller/TestController.java
deleted
100644 → 0
View file @
fee62722
package
com
.
example
.
controller
;
import
io.swagger.annotations.Api
;
import
io.swagger.annotations.ApiOperation
;
import
org.springframework.web.bind.annotation.GetMapping
;
import
org.springframework.web.bind.annotation.RequestMapping
;
import
org.springframework.web.bind.annotation.RestController
;
@RestController
@RequestMapping
(
"/api/test"
)
@Api
(
tags
=
"测试接口"
)
public
class
TestController
{
@GetMapping
(
"/hello"
)
@ApiOperation
(
"Hello World 测试接口"
)
public
String
hello
()
{
return
"Hello, Swagger!"
;
}
@GetMapping
(
"/info"
)
@ApiOperation
(
"获取应用信息"
)
public
String
info
()
{
return
"Demo2 Application - Multi Database Project"
;
}
}
\ No newline at end of file
src/main/resources/application.yml
View file @
1dd2520c
server
:
port
:
8181
# 修改为你想要的端口号
spring
:
spring
:
mvc
:
mvc
:
pathmatch
:
pathmatch
:
matching-strategy
:
ant_path_matcher
# Spring Boot 2.6+ 需要这个配置
matching-strategy
:
ant_path_matcher
# Spring Boot 2.6+ 需要这个配置
# Swagger 配置
# Swagger 配置
swagger
:
doc
:
enabled
:
true
swagger-ui
:
path
:
/swagger-ui.html
api-docs
:
path
:
/v3/api-docs
datasource
:
datasource
:
dynamic
:
dynamic
:
primary
:
sqlserver
primary
:
oracle
# 默认数据源
# 默认数据源
strict
:
false
# 关闭严格模式
strict
:
false
# 关闭严格模式
datasource
:
datasource
:
...
@@ -34,10 +40,11 @@ spring:
...
@@ -34,10 +40,11 @@ spring:
# MyBatis-Plus配置
# MyBatis-Plus配置
mybatis-plus
:
mybatis-plus
:
mapper-locations
:
classpath:mapper/**/*.xml
# Mapper XML路径
mapper-locations
:
classpath:mapper/**/*.xml
# Mapper XML路径
type-aliases-package
:
com.
example
.entity
# 实体类包路径
type-aliases-package
:
com.
aps
.entity
# 实体类包路径
configuration
:
configuration
:
map-underscore-to-camel-case
:
true
# 下划线转驼峰
map-underscore-to-camel-case
:
true
# 下划线转驼峰
log-impl
:
org.apache.ibatis.logging.stdout.StdOutImpl
# 打印SQL日志(调试用)
log-impl
:
org.apache.ibatis.logging.nologging.NoLoggingImpl
# 打印SQL日志(调试用)
# log-impl: org.apache.ibatis.logging.stdout.StdOutImpl # 开启SQL打印
global-config
:
global-config
:
db-config
:
db-config
:
id-type
:
auto
# 主键自增策略
id-type
:
auto
# 主键自增策略
\ No newline at end of file
src/main/resources/machines.json
0 → 100644
View file @
1dd2520c
[{
"id"
:
1
,
"name"
:
"Machine-1"
,
"shifts"
:
[{
"startTime"
:
"08:00:00"
,
"endTime"
:
"18:00:00"
,
"days"
:
[
1
,
2
,
3
,
4
,
5
],
"shiftDate"
:
"0001-01-01T00:00:00"
,
"temporaryShift"
:
false
,
"priority"
:
0
},{
"startTime"
:
"18:00:00"
,
"endTime"
:
"20:00:00"
,
"days"
:
[
1
,
2
,
3
,
4
,
5
],
"shiftDate"
:
"0001-01-01T00:00:00"
,
"temporaryShift"
:
true
,
"priority"
:
0
},{
"startTime"
:
"08:00:00"
,
"endTime"
:
"18:00:00"
,
"days"
:
[
0
],
"shiftDate"
:
"0001-01-01T00:00:00"
,
"temporaryShift"
:
true
,
"priority"
:
0
},{
"startTime"
:
"08:00:00"
,
"endTime"
:
"18:00:00"
,
"days"
:
null
,
"shiftDate"
:
"2025-10-01T00:00:00"
,
"temporaryShift"
:
true
,
"priority"
:
0
}],
"maintenanceWindows"
:
[{
"startTime"
:
"2025-10-08T10:00:00"
,
"endTime"
:
"2025-10-10T12:00:00"
}]
},
{
"id"
:
2
,
"name"
:
"Machine-2"
,
"shifts"
:
[{
"startTime"
:
"08:00:00"
,
"endTime"
:
"18:00:00"
,
"days"
:
[
1
,
2
,
3
,
4
,
5
],
"shiftDate"
:
"0001-01-01T00:00:00"
,
"temporaryShift"
:
false
,
"priority"
:
0
}],
"maintenanceWindows"
:
null
},
{
"id"
:
3
,
"name"
:
"Machine-3"
,
"shifts"
:
[{
"startTime"
:
"08:00:00"
,
"endTime"
:
"18:00:00"
,
"days"
:
[
1
,
2
,
3
,
4
,
5
],
"shiftDate"
:
"0001-01-01T00:00:00"
,
"temporaryShift"
:
false
,
"priority"
:
0
}],
"maintenanceWindows"
:
null
},
{
"id"
:
4
,
"name"
:
"Machine-4"
,
"shifts"
:
[{
"startTime"
:
"08:00:00"
,
"endTime"
:
"18:00:00"
,
"days"
:
[
1
,
2
,
3
,
4
,
5
],
"shiftDate"
:
"0001-01-01T00:00:00"
,
"temporaryShift"
:
false
,
"priority"
:
0
}],
"maintenanceWindows"
:
null
},
{
"id"
:
5
,
"name"
:
"Machine-5"
,
"shifts"
:
[{
"startTime"
:
"08:00:00"
,
"endTime"
:
"18:00:00"
,
"days"
:
[
1
,
2
,
3
,
4
,
5
],
"shiftDate"
:
"0001-01-01T00:00:00"
,
"temporaryShift"
:
false
,
"priority"
:
0
}],
"maintenanceWindows"
:
null
}]
\ No newline at end of file
src/main/resources/mapper/DepartmentMapper.xml
View file @
1dd2520c
<?xml version="1.0" encoding="UTF-8"?>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper
namespace=
"com.
example
.mapper.DepartmentMapper"
>
<mapper
namespace=
"com.
aps
.mapper.DepartmentMapper"
>
<!-- 通用查询映射结果 -->
<!-- 通用查询映射结果 -->
<resultMap
id=
"BaseResultMap"
type=
"com.
example
.entity.Department"
>
<resultMap
id=
"BaseResultMap"
type=
"com.
aps
.entity.Department"
>
<id
column=
"id"
property=
"id"
/>
<id
column=
"id"
property=
"id"
/>
<result
column=
"name"
property=
"name"
/>
<result
column=
"name"
property=
"name"
/>
<result
column=
"organization_id"
property=
"organizationId"
/>
<result
column=
"organization_id"
property=
"organizationId"
/>
...
@@ -38,4 +38,4 @@
...
@@ -38,4 +38,4 @@
id, name, organization_id, parent_id, status, creatoruserid, creationtime, lastmodifieruserid, lastmodificationtime, deleteruserid, deletiontime, isdeleted, level_desc, is_production, code, location, property, note, sys_dept_id, measure_unit_name, currency_type_name, capacity_type_name, measure_unit, currency_type, capacity_type, product_type, belong_code
id, name, organization_id, parent_id, status, creatoruserid, creationtime, lastmodifieruserid, lastmodificationtime, deleteruserid, deletiontime, isdeleted, level_desc, is_production, code, location, property, note, sys_dept_id, measure_unit_name, currency_type_name, capacity_type_name, measure_unit, currency_type, capacity_type, product_type, belong_code
</sql>
</sql>
</mapper>
</mapper>
\ No newline at end of file
src/main/resources/mapper/EquipinfoMapper.xml
0 → 100644
View file @
1dd2520c
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper
namespace=
"com.aps.mapper.EquipinfoMapper"
>
<!-- 通用查询映射结果 -->
<resultMap
id=
"BaseResultMap"
type=
"com.aps.entity.Equipinfo"
>
<id
column=
"id"
property=
"id"
/>
<result
column=
"shop_id"
property=
"shopId"
/>
<result
column=
"equip_id"
property=
"equipId"
/>
<result
column=
"equip_type"
property=
"equipType"
/>
<result
column=
"equip_name"
property=
"equipName"
/>
<result
column=
"equip_status"
property=
"equipStatus"
/>
<result
column=
"location"
property=
"location"
/>
<result
column=
"shaft_qty"
property=
"shaftQty"
/>
<result
column=
"capability_value"
property=
"capabilityValue"
/>
<result
column=
"securityclassid"
property=
"securityclassid"
/>
<result
column=
"equip_ip"
property=
"equipIp"
/>
<result
column=
"equipment_sc"
property=
"equipmentSc"
/>
<result
column=
"operator_id"
property=
"operatorId"
/>
<result
column=
"equip_version"
property=
"equipVersion"
/>
<result
column=
"equip_system"
property=
"equipSystem"
/>
<result
column=
"equip_pic"
property=
"equipPic"
/>
<result
column=
"locationx"
property=
"locationx"
/>
<result
column=
"isimportant"
property=
"isimportant"
/>
<result
column=
"filepath"
property=
"filepath"
/>
<result
column=
"equip_status_updatetime"
property=
"equipStatusUpdatetime"
/>
<result
column=
"hot"
property=
"hot"
/>
<result
column=
"capacity"
property=
"capacity"
/>
<result
column=
"standard"
property=
"standard"
/>
<result
column=
"usedepartment"
property=
"usedepartment"
/>
<result
column=
"installplace"
property=
"installplace"
/>
<result
column=
"mainnumber"
property=
"mainnumber"
/>
<result
column=
"manufacturer"
property=
"manufacturer"
/>
<result
column=
"enabledate"
property=
"enabledate"
/>
<result
column=
"equip_winpwd"
property=
"equipWinpwd"
/>
<result
column=
"equip_winname"
property=
"equipWinname"
/>
<result
column=
"equip_port"
property=
"equipPort"
/>
<result
column=
"status"
property=
"status"
/>
<result
column=
"property"
property=
"property"
/>
<result
column=
"creationtime"
property=
"creationtime"
/>
<result
column=
"creatoruserid"
property=
"creatoruserid"
/>
<result
column=
"lastmodificationtime"
property=
"lastmodificationtime"
/>
<result
column=
"lastmodifieruserid"
property=
"lastmodifieruserid"
/>
<result
column=
"isdeleted"
property=
"isdeleted"
/>
<result
column=
"deleteruserid"
property=
"deleteruserid"
/>
<result
column=
"deletiontime"
property=
"deletiontime"
/>
<result
column=
"head"
property=
"head"
/>
<result
column=
"runningstatus"
property=
"runningstatus"
/>
<result
column=
"system_info"
property=
"systemInfo"
/>
<result
column=
"ismdc"
property=
"ismdc"
/>
<result
column=
"work_pattern"
property=
"workPattern"
/>
<result
column=
"work_pattern_name"
property=
"workPatternName"
/>
<result
column=
"measure_unit_name"
property=
"measureUnitName"
/>
<result
column=
"currency_type_name"
property=
"currencyTypeName"
/>
<result
column=
"capacity_type_name"
property=
"capacityTypeName"
/>
<result
column=
"measure_unit"
property=
"measureUnit"
/>
<result
column=
"currency_type"
property=
"currencyType"
/>
<result
column=
"capacity_type"
property=
"capacityType"
/>
<result
column=
"fequipid"
property=
"fequipid"
/>
<result
column=
"min_time"
property=
"minTime"
/>
<result
column=
"min_duration_time"
property=
"minDurationTime"
/>
<result
column=
"max_duration_time"
property=
"maxDurationTime"
/>
<result
column=
"jp_expecation_time"
property=
"jpExpecationTime"
/>
</resultMap>
<!-- 通用查询结果列 -->
<sql
id=
"Base_Column_List"
>
id, shop_id, equip_id, equip_type, equip_name, equip_status, location, shaft_qty, capability_value, securityclassid, equip_ip, equipment_sc, operator_id, equip_version, equip_system, equip_pic, locationx, isimportant, filepath, equip_status_updatetime, hot, capacity, standard, usedepartment, installplace, mainnumber, manufacturer, enabledate, equip_winpwd, equip_winname, equip_port, status, property, creationtime, creatoruserid, lastmodificationtime, lastmodifieruserid, isdeleted, deleteruserid, deletiontime, head, runningstatus, system_info, ismdc, work_pattern, work_pattern_name, measure_unit_name, currency_type_name, capacity_type_name, measure_unit, currency_type, capacity_type, fequipid, min_time, min_duration_time, max_duration_time, jp_expecation_time
</sql>
</mapper>
\ No newline at end of file
src/main/resources/mapper/MaterialInfoMapper.xml
View file @
1dd2520c
<?xml version="1.0" encoding="UTF-8"?>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper
namespace=
"com.
example
.mapper.MaterialInfoMapper"
>
<mapper
namespace=
"com.
aps
.mapper.MaterialInfoMapper"
>
<!-- 通用查询映射结果 -->
<!-- 通用查询映射结果 -->
<resultMap
id=
"BaseResultMap"
type=
"com.
example
.entity.MaterialInfo"
>
<resultMap
id=
"BaseResultMap"
type=
"com.
aps
.entity.MaterialInfo"
>
<id
column=
"id"
property=
"id"
/>
<id
column=
"id"
property=
"id"
/>
<result
column=
"creationtime"
property=
"creationtime"
/>
<result
column=
"creationtime"
property=
"creationtime"
/>
<result
column=
"creatoruserid"
property=
"creatoruserid"
/>
<result
column=
"creatoruserid"
property=
"creatoruserid"
/>
...
@@ -108,4 +108,4 @@
...
@@ -108,4 +108,4 @@
id, creationtime, creatoruserid, lastmodificationtime, lastmodifieruserid, isdeleted, deletiontime, deleteruserid, name, brand, specifications, batch, unit_price, min_num, tempcode, code, material_type_name, inspect_duration, purchase_duration, first_lot, tail_lot, standard_log, safe_stock_day, safe_stock_quantity, category_name, category_code, category_id, material_property, root_category_id, code_rule_id, code_rule_type, drawing, material_type, measure_unit, measure_unit_name, version, product_type, status, latest, iscreatesupplyrouting, iscreatecheckrouting, description, quintiq_ortems, isync, issend, measure_unit2, measure_unit_name2, linkmaterialid, measure_unit3, measure_unit_name3, zjltofjl1, supply_id, supply_name, supply_code, istrade, ser, iscommon, iscreatepoolrouting, variety, spec, category_id2, utility_material, special_product, bottle_type, bottle_type_str, max_inventory_day, max_inventory_quantity, min_inventory_day, min_inventory_quantity, minimum_supply, start_time, end_time, equip_id, bigpro, smallpro, isthree, is_minus, remark, match_bigpro_id, match_bigpro_code, match_smallpro_id, match_smallpro_code, full_name, is_include_store, is_average_four_week, stocksynctime, inventory_host_cost, beforeplanid, plannum, plancount, new_long_id, new_oldnumber, min_quantity, material_plan_type, min_production, max_production, invisable
id, creationtime, creatoruserid, lastmodificationtime, lastmodifieruserid, isdeleted, deletiontime, deleteruserid, name, brand, specifications, batch, unit_price, min_num, tempcode, code, material_type_name, inspect_duration, purchase_duration, first_lot, tail_lot, standard_log, safe_stock_day, safe_stock_quantity, category_name, category_code, category_id, material_property, root_category_id, code_rule_id, code_rule_type, drawing, material_type, measure_unit, measure_unit_name, version, product_type, status, latest, iscreatesupplyrouting, iscreatecheckrouting, description, quintiq_ortems, isync, issend, measure_unit2, measure_unit_name2, linkmaterialid, measure_unit3, measure_unit_name3, zjltofjl1, supply_id, supply_name, supply_code, istrade, ser, iscommon, iscreatepoolrouting, variety, spec, category_id2, utility_material, special_product, bottle_type, bottle_type_str, max_inventory_day, max_inventory_quantity, min_inventory_day, min_inventory_quantity, minimum_supply, start_time, end_time, equip_id, bigpro, smallpro, isthree, is_minus, remark, match_bigpro_id, match_bigpro_code, match_smallpro_id, match_smallpro_code, full_name, is_include_store, is_average_four_week, stocksynctime, inventory_host_cost, beforeplanid, plannum, plancount, new_long_id, new_oldnumber, min_quantity, material_plan_type, min_production, max_production, invisable
</sql>
</sql>
</mapper>
</mapper>
\ No newline at end of file
src/main/resources/mapper/MesShiftWorkSchedMapper.xml
0 → 100644
View file @
1dd2520c
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper
namespace=
"com.aps.mapper.MesShiftWorkSchedMapper"
>
<!-- 通用查询映射结果 -->
<resultMap
id=
"BaseResultMap"
type=
"com.aps.entity.MesShiftWorkSched"
>
<id
column=
"id"
property=
"id"
/>
<result
column=
"shift_work_sched_code"
property=
"shiftWorkSchedCode"
/>
<result
column=
"shift_name"
property=
"shiftName"
/>
<result
column=
"shift_start"
property=
"shiftStart"
/>
<result
column=
"shift_end"
property=
"shiftEnd"
/>
<result
column=
"status"
property=
"status"
/>
<result
column=
"working_long"
property=
"workingLong"
/>
<result
column=
"shift_work_sched_pk1"
property=
"shiftWorkSchedPk1"
/>
<result
column=
"creationtime"
property=
"creationtime"
/>
<result
column=
"creatoruserid"
property=
"creatoruserid"
/>
<result
column=
"lastmodificationtime"
property=
"lastmodificationtime"
/>
<result
column=
"lastmodifieruserid"
property=
"lastmodifieruserid"
/>
<result
column=
"isdeleted"
property=
"isdeleted"
/>
<result
column=
"deletiontime"
property=
"deletiontime"
/>
<result
column=
"deleteruserid"
property=
"deleteruserid"
/>
<result
column=
"start_week_day"
property=
"startWeekDay"
/>
<result
column=
"start_week_day_name"
property=
"startWeekDayName"
/>
<result
column=
"week_work_sched_id"
property=
"weekWorkSchedId"
/>
<result
column=
"end_week_day"
property=
"endWeekDay"
/>
<result
column=
"end_week_day_name"
property=
"endWeekDayName"
/>
<result
column=
"str_working_long"
property=
"strWorkingLong"
/>
</resultMap>
<!-- 通用查询结果列 -->
<sql
id=
"Base_Column_List"
>
id, shift_work_sched_code, shift_name, shift_start, shift_end, status, working_long, shift_work_sched_pk1, creationtime, creatoruserid, lastmodificationtime, lastmodifieruserid, isdeleted, deletiontime, deleteruserid, start_week_day, start_week_day_name, week_work_sched_id, end_week_day, end_week_day_name, str_working_long
</sql>
</mapper>
\ No newline at end of file
src/main/resources/mapper/MpsplannedorderMapper.xml
0 → 100644
View file @
1dd2520c
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper
namespace=
"com.aps.mapper.MpsplannedorderMapper"
>
<!-- 通用查询映射结果 -->
<resultMap
id=
"BaseResultMap"
type=
"com.aps.entity.Mpsplannedorder"
>
<id
column=
"ID"
property=
"id"
/>
<result
column=
"ROUTINGID"
property=
"routingid"
/>
<result
column=
"QUANTITY"
property=
"quantity"
/>
<result
column=
"STARTDATE"
property=
"startdate"
/>
<result
column=
"END"
property=
"end"
/>
<result
column=
"DUADATE"
property=
"duadate"
/>
<result
column=
"ORDERID"
property=
"orderid"
/>
<result
column=
"MPPLANID"
property=
"mpplanid"
/>
<result
column=
"PRIORITY"
property=
"priority"
/>
<result
column=
"ADDTIME"
property=
"addtime"
/>
<result
column=
"SERIE"
property=
"serie"
/>
<result
column=
"BIGORDER"
property=
"bigorder"
/>
<result
column=
"UNITID"
property=
"unitid"
/>
<result
column=
"PRODUCTID"
property=
"productid"
/>
</resultMap>
<!-- 通用查询结果列 -->
<sql
id=
"Base_Column_List"
>
ROUTINGID, QUANTITY, STARTDATE, END, DUADATE, ORDERID, MPPLANID, ID, PRIORITY, ADDTIME, SERIE, BIGORDER, UNITID, PRODUCTID
</sql>
</mapper>
\ No newline at end of file
src/main/resources/mapper/PlanResourceMapper.xml
0 → 100644
View file @
1dd2520c
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper
namespace=
"com.aps.mapper.PlanResourceMapper"
>
<!-- 通用查询映射结果 -->
<resultMap
id=
"BaseResultMap"
type=
"com.aps.entity.PlanResource"
>
<id
column=
"id"
property=
"id"
/>
<result
column=
"title"
property=
"title"
/>
<result
column=
"code"
property=
"code"
/>
<result
column=
"type1"
property=
"type1"
/>
<result
column=
"reference_id"
property=
"referenceId"
/>
<result
column=
"depart_id"
property=
"departId"
/>
<result
column=
"depart_title"
property=
"departTitle"
/>
<result
column=
"isimportant"
property=
"isimportant"
/>
<result
column=
"capability_value"
property=
"capabilityValue"
/>
<result
column=
"creationtime"
property=
"creationtime"
/>
<result
column=
"creatoruserid"
property=
"creatoruserid"
/>
<result
column=
"lastmodificationtime"
property=
"lastmodificationtime"
/>
<result
column=
"lastmodifieruserid"
property=
"lastmodifieruserid"
/>
<result
column=
"isdeleted"
property=
"isdeleted"
/>
<result
column=
"deletiontime"
property=
"deletiontime"
/>
<result
column=
"deleteruserid"
property=
"deleteruserid"
/>
<result
column=
"cal_id"
property=
"calId"
/>
<result
column=
"cal_name"
property=
"calName"
/>
<result
column=
"holiday_cal_id"
property=
"holidayCalId"
/>
<result
column=
"holiday_cal_name"
property=
"holidayCalName"
/>
<result
column=
"reference_code"
property=
"referenceCode"
/>
<result
column=
"equip_type_id"
property=
"equipTypeId"
/>
<result
column=
"equip_type"
property=
"equipType"
/>
<result
column=
"work_sched_id"
property=
"workSchedId"
/>
<result
column=
"nrofunitsopen"
property=
"nrofunitsopen"
/>
<result
column=
"isstop"
property=
"isstop"
/>
<result
column=
"stoptime"
property=
"stoptime"
/>
<result
column=
"stopendtime"
property=
"stopendtime"
/>
</resultMap>
<!-- 通用查询结果列 -->
<sql
id=
"Base_Column_List"
>
id, title, code, type1, reference_id, depart_id, depart_title, isimportant, capability_value, creationtime, creatoruserid, lastmodificationtime, lastmodifieruserid, isdeleted, deletiontime, deleteruserid, cal_id, cal_name, holiday_cal_id, holiday_cal_name, reference_code, equip_type_id, equip_type, work_sched_id, nrofunitsopen, isstop, stoptime, stopendtime
</sql>
</mapper>
\ No newline at end of file
src/main/resources/mapper/RoutingDetailEquipMapper.xml
0 → 100644
View file @
1dd2520c
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper
namespace=
"com.aps.mapper.RoutingDetailEquipMapper"
>
<!-- 通用查询映射结果 -->
<resultMap
id=
"BaseResultMap"
type=
"com.aps.entity.RoutingDetailEquip"
>
<id
column=
"id"
property=
"id"
/>
<result
column=
"creationtime"
property=
"creationtime"
/>
<result
column=
"creatoruserid"
property=
"creatoruserid"
/>
<result
column=
"lastmodificationtime"
property=
"lastmodificationtime"
/>
<result
column=
"lastmodifieruserid"
property=
"lastmodifieruserid"
/>
<result
column=
"isdeleted"
property=
"isdeleted"
/>
<result
column=
"deletiontime"
property=
"deletiontime"
/>
<result
column=
"deleteruserid"
property=
"deleteruserid"
/>
<result
column=
"type1"
property=
"type1"
/>
<result
column=
"type_name"
property=
"typeName"
/>
<result
column=
"name"
property=
"name"
/>
<result
column=
"output_quantity"
property=
"outputQuantity"
/>
<result
column=
"measure_unit"
property=
"measureUnit"
/>
<result
column=
"measure_unit_name"
property=
"measureUnitName"
/>
<result
column=
"duration"
property=
"duration"
/>
<result
column=
"exp1"
property=
"exp1"
/>
<result
column=
"exp2"
property=
"exp2"
/>
<result
column=
"exp3"
property=
"exp3"
/>
<result
column=
"exp4"
property=
"exp4"
/>
<result
column=
"routing_detail_id"
property=
"routingDetailId"
/>
<result
column=
"equip_id"
property=
"equipId"
/>
<result
column=
"routing_header_id"
property=
"routingHeaderId"
/>
<result
column=
"one_batch_quantity"
property=
"oneBatchQuantity"
/>
<result
column=
"str_id"
property=
"strId"
/>
</resultMap>
<!-- 通用查询结果列 -->
<sql
id=
"Base_Column_List"
>
id, creationtime, creatoruserid, lastmodificationtime, lastmodifieruserid, isdeleted, deletiontime, deleteruserid, type1, type_name, name, output_quantity, measure_unit, measure_unit_name, duration, exp1, exp2, exp3, exp4, routing_detail_id, equip_id, routing_header_id, one_batch_quantity, str_id
</sql>
</mapper>
\ No newline at end of file
src/main/resources/mapper/RoutingDetailMapper.xml
0 → 100644
View file @
1dd2520c
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper
namespace=
"com.aps.mapper.RoutingDetailMapper"
>
<!-- 通用查询映射结果 -->
<resultMap
id=
"BaseResultMap"
type=
"com.aps.entity.RoutingDetail"
>
<id
column=
"id"
property=
"id"
/>
<result
column=
"creation_time"
property=
"creationTime"
/>
<result
column=
"creator_user_id"
property=
"creatorUserId"
/>
<result
column=
"last_modification_time"
property=
"lastModificationTime"
/>
<result
column=
"last_modifier_user_id"
property=
"lastModifierUserId"
/>
<result
column=
"is_deleted"
property=
"isDeleted"
/>
<result
column=
"deleter_user_id"
property=
"deleterUserId"
/>
<result
column=
"deletion_time"
property=
"deletionTime"
/>
<result
column=
"class_id"
property=
"classId"
/>
<result
column=
"routing_header_id"
property=
"routingHeaderId"
/>
<result
column=
"name"
property=
"name"
/>
<result
column=
"task_seq"
property=
"taskSeq"
/>
<result
column=
"description"
property=
"description"
/>
<result
column=
"task_content"
property=
"taskContent"
/>
<result
column=
"resource_id"
property=
"resourceId"
/>
<result
column=
"resource_type"
property=
"resourceType"
/>
<result
column=
"runtime"
property=
"runtime"
/>
<result
column=
"setup_time"
property=
"setupTime"
/>
<result
column=
"transport_time"
property=
"transportTime"
/>
<result
column=
"check_time"
property=
"checkTime"
/>
<result
column=
"check_flag"
property=
"checkFlag"
/>
<result
column=
"efficiency_value"
property=
"efficiencyValue"
/>
<result
column=
"single_out"
property=
"singleOut"
/>
<result
column=
"is_outside"
property=
"isOutside"
/>
<result
column=
"department_id"
property=
"departmentId"
/>
<result
column=
"is_important"
property=
"isImportant"
/>
<result
column=
"milestone_id"
property=
"milestoneId"
/>
<result
column=
"phase_id"
property=
"phaseId"
/>
<result
column=
"status"
property=
"status"
/>
<result
column=
"remark"
property=
"remark"
/>
<result
column=
"extend"
property=
"extend"
/>
<result
column=
"outside_time"
property=
"outsideTime"
/>
<result
column=
"performance_hours"
property=
"performanceHours"
/>
<result
column=
"resource_code"
property=
"resourceCode"
/>
<result
column=
"is_important_resources"
property=
"isImportantResources"
/>
<result
column=
"scheduling_working_hours"
property=
"schedulingWorkingHours"
/>
<result
column=
"real_working_hours"
property=
"realWorkingHours"
/>
<result
column=
"real_runtime"
property=
"realRuntime"
/>
<result
column=
"performance_working_hours"
property=
"performanceWorkingHours"
/>
<result
column=
"is_participate_intime"
property=
"isParticipateIntime"
/>
<result
column=
"equip_type"
property=
"equipType"
/>
<result
column=
"equip_type_id"
property=
"equipTypeId"
/>
<result
column=
"note"
property=
"note"
/>
<result
column=
"file_id"
property=
"fileId"
/>
<result
column=
"measure_unit"
property=
"measureUnit"
/>
<result
column=
"measure_unit_name"
property=
"measureUnitName"
/>
<result
column=
"after_process_time"
property=
"afterProcessTime"
/>
<result
column=
"is_general"
property=
"isGeneral"
/>
<result
column=
"can_interrupt"
property=
"canInterrupt"
/>
<result
column=
"can_start_early"
property=
"canStartEarly"
/>
<result
column=
"previous_start_time_begin"
property=
"previousStartTimeBegin"
/>
<result
column=
"code"
property=
"code"
/>
<result
column=
"tool"
property=
"tool"
/>
<result
column=
"change_line_time"
property=
"changeLineTime"
/>
<result
column=
"pre_detail_id"
property=
"preDetailId"
/>
<result
column=
"connect_type"
property=
"connectType"
/>
<result
column=
"connect_property"
property=
"connectProperty"
/>
<result
column=
"connect_type_name"
property=
"connectTypeName"
/>
<result
column=
"connect_property_name"
property=
"connectPropertyName"
/>
<result
column=
"str_setup_time"
property=
"strSetupTime"
/>
<result
column=
"isync"
property=
"isync"
/>
<result
column=
"const_time"
property=
"constTime"
/>
<result
column=
"usable"
property=
"usable"
/>
<result
column=
"lead_time"
property=
"leadTime"
/>
</resultMap>
<!-- 通用查询结果列 -->
<sql
id=
"Base_Column_List"
>
id, creation_time, creator_user_id, last_modification_time, last_modifier_user_id, is_deleted, deleter_user_id, deletion_time, class_id, routing_header_id, name, task_seq, description, task_content, resource_id, resource_type, runtime, setup_time, transport_time, check_time, check_flag, efficiency_value, single_out, is_outside, department_id, is_important, milestone_id, phase_id, status, remark, extend, outside_time, performance_hours, resource_code, is_important_resources, scheduling_working_hours, real_working_hours, real_runtime, performance_working_hours, is_participate_intime, equip_type, equip_type_id, note, file_id, measure_unit, measure_unit_name, after_process_time, is_general, can_interrupt, can_start_early, previous_start_time_begin, code, tool, change_line_time, pre_detail_id, connect_type, connect_property, connect_type_name, connect_property_name, str_setup_time, isync, const_time, usable, lead_time
</sql>
</mapper>
\ No newline at end of file
src/main/resources/mapper/RoutingHeaderMapper.xml
0 → 100644
View file @
1dd2520c
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper
namespace=
"com.aps.mapper.RoutingHeaderMapper"
>
<!-- 通用查询映射结果 -->
<resultMap
id=
"BaseResultMap"
type=
"com.aps.entity.RoutingHeader"
>
<id
column=
"id"
property=
"id"
/>
<result
column=
"creation_time"
property=
"creationTime"
/>
<result
column=
"creator_user_id"
property=
"creatorUserId"
/>
<result
column=
"last_modification_time"
property=
"lastModificationTime"
/>
<result
column=
"last_modifier_user_id"
property=
"lastModifierUserId"
/>
<result
column=
"deleter_user_id"
property=
"deleterUserId"
/>
<result
column=
"deletion_time"
property=
"deletionTime"
/>
<result
column=
"class_id"
property=
"classId"
/>
<result
column=
"unicode"
property=
"unicode"
/>
<result
column=
"name"
property=
"name"
/>
<result
column=
"code"
property=
"code"
/>
<result
column=
"product_id"
property=
"productId"
/>
<result
column=
"version"
property=
"version"
/>
<result
column=
"author"
property=
"author"
/>
<result
column=
"department_id"
property=
"departmentId"
/>
<result
column=
"is_main"
property=
"isMain"
/>
<result
column=
"up_id"
property=
"upId"
/>
<result
column=
"up_detail_id"
property=
"upDetailId"
/>
<result
column=
"routing_type"
property=
"routingType"
/>
<result
column=
"status"
property=
"status"
/>
<result
column=
"approval_status"
property=
"approvalStatus"
/>
<result
column=
"remark"
property=
"remark"
/>
<result
column=
"approval_status_remark"
property=
"approvalStatusRemark"
/>
<result
column=
"audit_user_id1"
property=
"auditUserId1"
/>
<result
column=
"audit_user_id2"
property=
"auditUserId2"
/>
<result
column=
"is_deleted"
property=
"isDeleted"
/>
<result
column=
"platesnum"
property=
"platesnum"
/>
<result
column=
"is_effect"
property=
"isEffect"
/>
<result
column=
"versionnotes"
property=
"versionnotes"
/>
<result
column=
"phase"
property=
"phase"
/>
<result
column=
"versionid"
property=
"versionid"
/>
<result
column=
"is_send_ppm"
property=
"isSendPpm"
/>
<result
column=
"file_id"
property=
"fileId"
/>
<result
column=
"product_name"
property=
"productName"
/>
<result
column=
"department_name"
property=
"departmentName"
/>
<result
column=
"drawing_no"
property=
"drawingNo"
/>
<result
column=
"product_bom_id"
property=
"productBomId"
/>
<result
column=
"routing_changeorder_code"
property=
"routingChangeorderCode"
/>
<result
column=
"routing_changeheader_id"
property=
"routingChangeheaderId"
/>
<result
column=
"audit_user_id3"
property=
"auditUserId3"
/>
<result
column=
"material_id"
property=
"materialId"
/>
<result
column=
"output_quantity"
property=
"outputQuantity"
/>
<result
column=
"routing_type_name"
property=
"routingTypeName"
/>
<result
column=
"lead_time"
property=
"leadTime"
/>
<result
column=
"quintiq_ortems"
property=
"quintiqOrtems"
/>
<result
column=
"iscreatecheckrouting"
property=
"iscreatecheckrouting"
/>
<result
column=
"iscreateoutbom"
property=
"iscreateoutbom"
/>
<result
column=
"issupportingstore"
property=
"issupportingstore"
/>
<result
column=
"isync"
property=
"isync"
/>
<result
column=
"routing_usetype"
property=
"routingUsetype"
/>
<result
column=
"linkroutingid"
property=
"linkroutingid"
/>
<result
column=
"effect_end"
property=
"effectEnd"
/>
<result
column=
"year"
property=
"year"
/>
<result
column=
"effect_begin"
property=
"effectBegin"
/>
<result
column=
"cost"
property=
"cost"
/>
<result
column=
"erptag"
property=
"erptag"
/>
<result
column=
"createoutbomtime"
property=
"createoutbomtime"
/>
<result
column=
"material_plan_type"
property=
"materialPlanType"
/>
<result
column=
"pcost"
property=
"pcost"
/>
<result
column=
"invisable"
property=
"invisable"
/>
</resultMap>
<!-- 通用查询结果列 -->
<sql
id=
"Base_Column_List"
>
id, creation_time, creator_user_id, last_modification_time, last_modifier_user_id, deleter_user_id, deletion_time, class_id, unicode, name, code, product_id, version, author, department_id, is_main, up_id, up_detail_id, routing_type, status, approval_status, remark, approval_status_remark, audit_user_id1, audit_user_id2, is_deleted, platesnum, is_effect, versionnotes, phase, versionid, is_send_ppm, file_id, product_name, department_name, drawing_no, product_bom_id, routing_changeorder_code, routing_changeheader_id, audit_user_id3, material_id, output_quantity, routing_type_name, lead_time, quintiq_ortems, iscreatecheckrouting, iscreateoutbom, issupportingstore, isync, routing_usetype, linkroutingid, effect_end, year, effect_begin, cost, erptag, createoutbomtime, material_plan_type, pcost, invisable
</sql>
</mapper>
\ No newline at end of file
src/main/resources/mapper/RoutingStepMapper.xml
0 → 100644
View file @
1dd2520c
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper
namespace=
"com.aps.mapper.RoutingStepMapper"
>
<!-- 通用查询映射结果 -->
<resultMap
id=
"BaseResultMap"
type=
"com.aps.entity.RoutingStep"
>
<id
column=
"id"
property=
"id"
/>
<result
column=
"creation_time"
property=
"creationTime"
/>
<result
column=
"creator_user_id"
property=
"creatorUserId"
/>
<result
column=
"last_modification_time"
property=
"lastModificationTime"
/>
<result
column=
"last_modifier_user_id"
property=
"lastModifierUserId"
/>
<result
column=
"is_deleted"
property=
"isDeleted"
/>
<result
column=
"deleter_user_id"
property=
"deleterUserId"
/>
<result
column=
"deletion_time"
property=
"deletionTime"
/>
<result
column=
"routing_header_id"
property=
"routingHeaderId"
/>
<result
column=
"routing_detail_id"
property=
"routingDetailId"
/>
<result
column=
"class_id"
property=
"classId"
/>
<result
column=
"step_seq"
property=
"stepSeq"
/>
<result
column=
"name"
property=
"name"
/>
<result
column=
"description"
property=
"description"
/>
<result
column=
"status"
property=
"status"
/>
<result
column=
"remark"
property=
"remark"
/>
<result
column=
"step_content"
property=
"stepContent"
/>
<result
column=
"extend"
property=
"extend"
/>
</resultMap>
<!-- 通用查询结果列 -->
<sql
id=
"Base_Column_List"
>
id, creation_time, creator_user_id, last_modification_time, last_modifier_user_id, is_deleted, deleter_user_id, deletion_time, routing_header_id, routing_detail_id, class_id, step_seq, name, description, status, remark, step_content, extend
</sql>
</mapper>
\ No newline at end of file
src/main/resources/orders.json
0 → 100644
View file @
1dd2520c
[
{
"id"
:
1
,
"productId"
:
1
,
"quantity"
:
50
,
"dueDate"
:
"2025-10-27T16:21:31.0756427+08:00"
,
"priority"
:
1
,
"canSplit"
:
false
,
"canInterrupt"
:
false
},
{
"id"
:
2
,
"productId"
:
1
,
"quantity"
:
100
,
"dueDate"
:
"2025-10-18T16:21:31.0756427+08:00"
,
"priority"
:
2
,
"canSplit"
:
false
,
"canInterrupt"
:
false
},
{
"id"
:
3
,
"productId"
:
2
,
"quantity"
:
100
,
"dueDate"
:
"2025-10-31T16:21:31.0756427+08:00"
,
"priority"
:
2
,
"canSplit"
:
false
,
"canInterrupt"
:
false
}
]
\ No newline at end of file
src/main/resources/products.json
0 → 100644
View file @
1dd2520c
[
{
"id"
:
1
,
"name"
:
"Product-1"
,
"operations"
:
[
{
"id"
:
1
,
"productId"
:
1
,
"sequence"
:
1
,
"machineOptions"
:
[
{
"machineId"
:
2
,
"processingTime"
:
11
,
"setupTime"
:
59
}
],
"isInterrupt"
:
false
},
{
"id"
:
2
,
"productId"
:
1
,
"sequence"
:
2
,
"machineOptions"
:
[
{
"machineId"
:
3
,
"processingTime"
:
5
,
"setupTime"
:
45
},
{
"machineId"
:
5
,
"processingTime"
:
21
,
"setupTime"
:
11
}
],
"isInterrupt"
:
false
},
{
"id"
:
3
,
"productId"
:
1
,
"sequence"
:
3
,
"machineOptions"
:
[
{
"machineId"
:
5
,
"processingTime"
:
6
,
"setupTime"
:
40
}
],
"isInterrupt"
:
false
},
{
"id"
:
4
,
"productId"
:
1
,
"sequence"
:
4
,
"machineOptions"
:
[
{
"machineId"
:
1
,
"processingTime"
:
19
,
"setupTime"
:
48
},
{
"machineId"
:
4
,
"processingTime"
:
20
,
"setupTime"
:
51
}
],
"isInterrupt"
:
false
}
]
},
{
"id"
:
2
,
"name"
:
"Product-2"
,
"operations"
:
[
{
"id"
:
1
,
"productId"
:
2
,
"sequence"
:
1
,
"machineOptions"
:
[
{
"machineId"
:
1
,
"processingTime"
:
5
,
"setupTime"
:
30
}
],
"isInterrupt"
:
false
},
{
"id"
:
2
,
"productId"
:
2
,
"sequence"
:
2
,
"machineOptions"
:
[
{
"machineId"
:
2
,
"processingTime"
:
22
,
"setupTime"
:
47
}
],
"isInterrupt"
:
false
},
{
"id"
:
3
,
"productId"
:
2
,
"sequence"
:
3
,
"machineOptions"
:
[
{
"machineId"
:
1
,
"processingTime"
:
8
,
"setupTime"
:
35
},
{
"machineId"
:
5
,
"processingTime"
:
28
,
"setupTime"
:
31
}
],
"isInterrupt"
:
false
}
]
}
]
\ No newline at end of file
src/main/resources/static/code-generator.html
View file @
1dd2520c
...
@@ -348,7 +348,7 @@
...
@@ -348,7 +348,7 @@
<div
class=
"mb-3"
>
<div
class=
"mb-3"
>
<label
class=
"form-label fw-bold"
><i
class=
"fas fa-code me-2"
></i>
包名
</label>
<label
class=
"form-label fw-bold"
><i
class=
"fas fa-code me-2"
></i>
包名
</label>
<input
type=
"text"
class=
"form-control"
id=
"packageName"
value=
"com.
example
"
<input
type=
"text"
class=
"form-control"
id=
"packageName"
value=
"com.
aps
"
placeholder=
"例如: com.company.project"
>
placeholder=
"例如: com.company.project"
>
</div>
</div>
...
...
src/main/resources/templates/entity.java.vm
0 → 100644
View file @
1dd2520c
package
${
package
.
Entity
};
import
lombok
.
Data
;
#
foreach
($
pkg
in
${
table
.
importPackages
})
#
if
(
!$pkg.startsWith("java.lang."))
import
${
pkg
};
#
end
#
end
@
Data
public
class
${
entity
}
{
#
foreach
($
field
in
${
table
.
fields
})
private
${
field
.
propertyType
}
${
field
.
propertyName
};
#
end
}
\ No newline at end of file
src/test/java/com/
example
/demo/Demo1ApplicationTests.java
→
src/test/java/com/
aps
/demo/Demo1ApplicationTests.java
View file @
1dd2520c
package
com
.
example
.
demo
;
package
com
.
aps
.
demo
;
import
org.junit.jupiter.api.Test
;
import
org.junit.jupiter.api.Test
;
import
org.springframework.boot.test.context.SpringBootTest
;
import
org.springframework.boot.test.context.SpringBootTest
;
...
...
src/test/java/com/aps/demo/MachineSchedulerTest.java
0 → 100644
View file @
1dd2520c
package
com
.
aps
.
demo
;
import
com.aps.common.util.JsonFileReader
;
import
com.aps.entity.basic.*
;
import
com.aps.service.plan.AlgorithmScheduler6
;
import
com.aps.service.plan.MachineSchedulerService
;
import
java.time.LocalDateTime
;
import
java.util.Arrays
;
import
java.util.List
;
public
class
MachineSchedulerTest
{
public
static
void
main
(
String
[]
args
)
{
try
{
// // 1. 读取JSON文件
// String jsonContent = new String(Files.readAllBytes(Paths.get("src/main/resources/machines.json")));
// // 2. 配置ObjectMapper支持Java 8时间API
// ObjectMapper objectMapper = new ObjectMapper();
// objectMapper.registerModule(new JavaTimeModule());
// objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
List
<
Machine
>
machines
=
JsonFileReader
.
readListFromResources
(
"machines.json"
,
Machine
.
class
);
// 读取产品数据
List
<
Product
>
products
=
JsonFileReader
.
readListFromResources
(
"products.json"
,
Product
.
class
);
// 读取订单数据
List
<
Order
>
orders
=
JsonFileReader
.
readListFromResources
(
"orders.json"
,
Order
.
class
);
// 3. 反序列化JSON到Machine列表
// List<Machine> machines = objectMapper.readValue(jsonContent,
// objectMapper.getTypeFactory().constructCollectionType(List.class, Machine.class));
// 4. 创建节假日数据
List
<
Holiday
>
holidays
=
Arrays
.
asList
(
new
Holiday
(
LocalDateTime
.
of
(
2025
,
10
,
1
,
0
,
0
),
LocalDateTime
.
of
(
2025
,
10
,
7
,
23
,
59
))
);
// 5. 创建调度服务
MachineSchedulerService
machineScheduler
=
new
MachineSchedulerService
(
holidays
,
LocalDateTime
.
of
(
2025
,
10
,
1
,
0
,
0
,
0
));
// 6. 为每个设备生成时间线
for
(
Machine
machine
:
machines
)
{
System
.
out
.
println
(
"处理设备: "
+
machine
.
getName
());
MachineTimeline
machineTimeline
=
machineScheduler
.
getOrCreateTimeline
(
machine
);
machine
.
setAvailability
(
machineTimeline
.
getSegments
());
// 打印结果
System
.
out
.
println
(
"设备 "
+
machine
.
getName
()
+
" 的时间段数量: "
+
(
machine
.
getAvailability
()
!=
null
?
machine
.
getAvailability
().
size
()
:
0
));
if
(
machine
.
getAvailability
()
!=
null
&&
!
machine
.
getAvailability
().
isEmpty
())
{
System
.
out
.
println
(
"时间段:"
);
machine
.
getAvailability
().
stream
().
forEach
(
segment
->
{
System
.
out
.
printf
(
" %s - %s (%s)%n"
,
segment
.
getStart
(),
segment
.
getEnd
(),
segment
.
getType
());
});
}
System
.
out
.
println
(
"---"
);
}
// 7. 测试缓存功能
System
.
out
.
println
(
"缓存中的设备数量: "
+
MachineSchedulerService
.
getCacheSize
());
// 8. 测试特定设备的时间段生成
if
(!
machines
.
isEmpty
())
{
Machine
firstMachine
=
machines
.
get
(
0
);
List
<
TimeSegment
>
segments
=
machineScheduler
.
generateTimeSegment
(
firstMachine
,
LocalDateTime
.
of
(
2025
,
10
,
1
,
0
,
0
,
0
));
System
.
out
.
println
(
"直接生成的时间段数量: "
+
segments
.
size
());
}
AlgorithmScheduler6
scheduler
=
new
AlgorithmScheduler6
(
products
,
machines
,
orders
,
machineScheduler
);
List
<
ScheduleChromosome
>
scheduleChromosomes
=
scheduler
.
RunAll
();
for
(
ScheduleChromosome
run:
scheduleChromosomes
)
{
System
.
out
.
println
(
"------------------"
+
run
.
getFitness
()+
"------------------"
);
scheduler
.
PrintScheduleSummary
(
run
);
}
ScheduleChromosome
run
=
scheduler
.
Run
();
scheduler
.
PrintScheduleSummary
(
run
);
System
.
out
.
println
(
run
.
getFitness
());
System
.
out
.
println
(
"------------------"
+
scheduleChromosomes
.
size
()+
"------------------"
);
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
}
}
}
\ No newline at end of file
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