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
074de057
Commit
074de057
authored
Apr 29, 2026
by
DESKTOP-VKRD9QF\Administration
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
索引版本返回
parent
87592467
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
336 additions
and
3 deletions
+336
-3
ResourceGanttController.java
...ava/com/aps/controller/gantt/ResourceGanttController.java
+18
-1
Machine.java
src/main/java/com/aps/entity/basic/Machine.java
+4
-1
PlanResultService.java
src/main/java/com/aps/service/plan/PlanResultService.java
+312
-0
SceneService.java
src/main/java/com/aps/service/plan/SceneService.java
+2
-1
No files found.
src/main/java/com/aps/controller/gantt/ResourceGanttController.java
View file @
074de057
...
...
@@ -973,6 +973,23 @@ public class ResourceGanttController {
return
R
.
ok
(
versionData
);
}
@PostMapping
(
"/getSceneVersionWithIndexPreview"
)
@Operation
(
summary
=
"获取版本号、当前索引和甘特概览"
,
description
=
"返回版本信息,并按资源甘特数据统计场景时间、工单、订单、设备和预览图"
)
public
R
<
Map
<
String
,
Object
>>
getSceneVersionWithIndexPreview
(
@io
.
swagger
.
v3
.
oas
.
annotations
.
parameters
.
RequestBody
(
description
=
"previewWidth、previewHeight 为可选字段,用于控制返回 preview 图片尺寸。"
,
content
=
@io
.
swagger
.
v3
.
oas
.
annotations
.
media
.
Content
(
mediaType
=
"application/json"
,
examples
=
@io
.
swagger
.
v3
.
oas
.
annotations
.
media
.
ExampleObject
(
name
=
"获取版本和缩略图示例"
,
value
=
"{\n \"sceneId\": \"F397427A76754E33A5655C41A7D0BC4A\",\n \"previewWidth\": 896,\n \"previewHeight\": 20\n}"
)
)
)
@RequestBody
Map
<
String
,
Object
>
params
)
{
String
sceneId
=
ParamValidator
.
getString
(
params
,
"sceneId"
,
"场景ID"
);
return
R
.
ok
(
planResultService
.
getSceneVersionWithIndexPreview
(
sceneId
,
params
));
}
@PostMapping
(
"/revertVersion"
)
@Operation
(
summary
=
"撤销操作"
,
description
=
"撤销操作"
,
...
...
@@ -1092,4 +1109,4 @@ public class ResourceGanttController {
}
}
\ No newline at end of file
}
src/main/java/com/aps/entity/basic/Machine.java
View file @
074de057
...
...
@@ -57,7 +57,10 @@ public class Machine {
* 设备编码
*/
private
String
code
;
/**
* 设备类型
*
*/
private
String
capacityTypeName
;
/**
...
...
src/main/java/com/aps/service/plan/PlanResultService.java
View file @
074de057
...
...
@@ -24,6 +24,12 @@ import lombok.extern.slf4j.Slf4j;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.stereotype.Service
;
import
javax.imageio.ImageIO
;
import
java.awt.Color
;
import
java.awt.Graphics2D
;
import
java.awt.RenderingHints
;
import
java.awt.image.BufferedImage
;
import
java.io.ByteArrayOutputStream
;
import
java.io.File
;
import
java.io.IOException
;
import
java.math.BigDecimal
;
...
...
@@ -3714,5 +3720,311 @@ public class PlanResultService {
public
Map
<
String
,
Object
>
getSceneVersionWithIndexPreview
(
String
sceneId
,
Map
<
String
,
Object
>
params
)
{
Map
<
String
,
Object
>
versionData
=
getSceneVersion
(
sceneId
);
Chromosome
schedule
=
_sceneService
.
loadChromosomeFromFile
(
sceneId
);
if
(
schedule
==
null
)
{
throw
new
RuntimeException
(
"未找到对应的场景文件"
);
}
SceneVersionPreviewData
previewData
=
collectSceneVersionPreviewData
(
schedule
);
int
previewWidth
=
getPositiveIntegerParam
(
params
,
"previewWidth"
,
100
);
int
previewHeight
=
getPositiveIntegerParam
(
params
,
"previewHeight"
,
calculateDefaultPreviewHeight
(
previewData
.
equipCount
));
return
buildSceneVersionPreview
(
versionData
,
previewData
,
previewWidth
,
previewHeight
);
}
private
Map
<
String
,
Object
>
buildSceneVersionPreview
(
Map
<
String
,
Object
>
versionData
,
SceneVersionPreviewData
previewData
,
int
previewWidth
,
int
previewHeight
)
{
Map
<
String
,
Object
>
result
=
new
LinkedHashMap
<>();
result
.
put
(
"index"
,
versionData
==
null
?
-
1
:
versionData
.
get
(
"index"
));
result
.
put
(
"start"
,
previewData
.
minStart
==
null
?
null
:
previewData
.
minStart
.
toLocalDate
().
toString
());
result
.
put
(
"end"
,
previewData
.
maxEnd
==
null
?
null
:
previewData
.
maxEnd
.
toLocalDate
().
toString
());
result
.
put
(
"taskCount"
,
previewData
.
taskCount
);
result
.
put
(
"planCount"
,
previewData
.
planCount
);
result
.
put
(
"equipCount"
,
previewData
.
equipCount
);
result
.
put
(
"taskMinTime"
,
previewData
.
taskMinTime
);
result
.
put
(
"taskMaxTime"
,
previewData
.
taskMaxTime
);
result
.
put
(
"taskAverageTime"
,
previewData
.
taskAverageTime
);
result
.
put
(
"previewWidth"
,
previewWidth
);
result
.
put
(
"previewHeight"
,
previewHeight
);
result
.
put
(
"preview"
,
buildGanttPreviewPng
(
previewData
,
previewWidth
,
previewHeight
));
result
.
put
(
"list"
,
versionData
==
null
?
new
ArrayList
<>()
:
versionData
.
get
(
"list"
));
return
result
;
}
private
SceneVersionPreviewData
collectSceneVersionPreviewData
(
Chromosome
schedule
)
{
SceneVersionPreviewData
previewData
=
new
SceneVersionPreviewData
();
if
(
schedule
==
null
||
schedule
.
getResult
()
==
null
||
schedule
.
getResult
().
isEmpty
())
{
return
previewData
;
}
List
<
GAScheduleResult
>
genes
=
schedule
.
getResult
();
Set
<
Long
>
resultMachineIds
=
new
HashSet
<>();
for
(
GAScheduleResult
gene
:
genes
)
{
if
(
gene
!=
null
)
{
resultMachineIds
.
add
(
gene
.
getMachineId
());
}
}
List
<
Machine
>
machines
=
schedule
.
getInitMachines
();
if
(
machines
==
null
||
machines
.
isEmpty
())
{
return
previewData
;
}
for
(
Machine
machine
:
machines
)
{
if
(
machine
==
null
||
!
resultMachineIds
.
contains
(
machine
.
getId
()))
{
continue
;
}
previewData
.
machineIds
.
add
(
machine
.
getId
());
previewData
.
genesByMachine
.
put
(
machine
.
getId
(),
new
ArrayList
<>());
}
previewData
.
equipCount
=
previewData
.
machineIds
.
size
();
if
(
previewData
.
equipCount
==
0
)
{
return
previewData
;
}
Long
minStartOffset
=
null
;
Long
maxEndOffset
=
null
;
long
durationSum
=
0L
;
int
durationCount
=
0
;
Set
<
String
>
planIds
=
new
HashSet
<>();
for
(
GAScheduleResult
gene
:
genes
)
{
if
(
gene
==
null
||
!
previewData
.
genesByMachine
.
containsKey
(
gene
.
getMachineId
()))
{
continue
;
}
previewData
.
genesByMachine
.
get
(
gene
.
getMachineId
()).
add
(
gene
);
previewData
.
taskCount
++;
planIds
.
add
(
getSchedulePlanKey
(
gene
));
long
startOffset
=
gene
.
getStartTime
();
long
endOffset
=
gene
.
getEndTime
();
minStartOffset
=
minStartOffset
==
null
?
startOffset
:
Math
.
min
(
minStartOffset
,
startOffset
);
maxEndOffset
=
maxEndOffset
==
null
?
endOffset
:
Math
.
max
(
maxEndOffset
,
endOffset
);
long
duration
=
endOffset
-
startOffset
;
if
(
duration
>=
0L
)
{
previewData
.
taskMinTime
=
durationCount
==
0
?
duration
:
Math
.
min
(
previewData
.
taskMinTime
,
duration
);
previewData
.
taskMaxTime
=
durationCount
==
0
?
duration
:
Math
.
max
(
previewData
.
taskMaxTime
,
duration
);
durationSum
+=
duration
;
durationCount
++;
}
}
for
(
List
<
GAScheduleResult
>
machineGenes
:
previewData
.
genesByMachine
.
values
())
{
machineGenes
.
sort
(
Comparator
.
comparingInt
(
GAScheduleResult:
:
getStartTime
));
}
previewData
.
planCount
=
planIds
.
size
();
previewData
.
taskAverageTime
=
durationCount
==
0
?
0L
:
Math
.
round
(
durationSum
/
(
double
)
durationCount
);
previewData
.
minStartOffset
=
minStartOffset
;
previewData
.
maxEndOffset
=
maxEndOffset
;
if
(
schedule
.
getBaseTime
()
!=
null
&&
minStartOffset
!=
null
&&
maxEndOffset
!=
null
)
{
previewData
.
minStart
=
schedule
.
getBaseTime
().
plusSeconds
(
minStartOffset
);
previewData
.
maxEnd
=
schedule
.
getBaseTime
().
plusSeconds
(
maxEndOffset
);
}
return
previewData
;
}
private
int
getPositiveIntegerParam
(
Map
<
String
,
Object
>
params
,
String
key
,
int
defaultValue
)
{
if
(
params
==
null
||
params
.
get
(
key
)
==
null
)
{
return
defaultValue
;
}
try
{
int
value
=
Integer
.
parseInt
(
String
.
valueOf
(
params
.
get
(
key
)));
return
value
>
0
?
value
:
defaultValue
;
}
catch
(
NumberFormatException
ex
)
{
return
defaultValue
;
}
}
private
int
calculateDefaultPreviewHeight
(
int
equipCount
)
{
return
Math
.
max
(
160
,
Math
.
min
(
1200
,
equipCount
*
6
));
}
private
String
buildGanttPreviewPng
(
SceneVersionPreviewData
previewData
,
int
imageWidth
,
int
imageHeight
)
{
if
(
previewData
==
null
||
previewData
.
machineIds
.
isEmpty
()
||
previewData
.
minStartOffset
==
null
||
previewData
.
maxEndOffset
==
null
||
previewData
.
maxEndOffset
<=
previewData
.
minStartOffset
)
{
return
""
;
}
long
totalSeconds
=
Math
.
max
(
1L
,
previewData
.
maxEndOffset
-
previewData
.
minStartOffset
);
int
equipCount
=
previewData
.
machineIds
.
size
();
BufferedImage
image
=
new
BufferedImage
(
imageWidth
,
imageHeight
,
BufferedImage
.
TYPE_INT_ARGB
);
Graphics2D
graphics
=
image
.
createGraphics
();
Map
<
String
,
Color
>
colorCache
=
new
HashMap
<>();
try
{
graphics
.
setRenderingHint
(
RenderingHints
.
KEY_ANTIALIASING
,
RenderingHints
.
VALUE_ANTIALIAS_OFF
);
graphics
.
setColor
(
new
Color
(
0xf6f8fb
));
graphics
.
fillRect
(
0
,
0
,
imageWidth
,
imageHeight
);
for
(
int
i
=
0
;
i
<
previewData
.
machineIds
.
size
();
i
++)
{
List
<
GAScheduleResult
>
machineGenes
=
previewData
.
genesByMachine
.
get
(
previewData
.
machineIds
.
get
(
i
));
if
(
machineGenes
==
null
||
machineGenes
.
isEmpty
())
{
continue
;
}
double
y
=
getPreviewRowY
(
i
,
equipCount
,
imageHeight
);
double
rowHeight
=
getPreviewRowHeight
(
i
,
equipCount
,
imageHeight
,
y
);
for
(
GAScheduleResult
gene
:
machineGenes
)
{
long
duration
=
gene
.
getEndTime
()
-
gene
.
getStartTime
();
if
(
duration
<
0L
)
{
continue
;
}
long
offset
=
Math
.
max
(
0L
,
gene
.
getStartTime
()
-
previewData
.
minStartOffset
);
double
x
=
offset
*
(
double
)
imageWidth
/
totalSeconds
;
double
width
=
Math
.
max
(
1
D
,
Math
.
max
(
1L
,
duration
)
*
(
double
)
imageWidth
/
totalSeconds
);
if
(
x
>=
imageWidth
||
x
+
width
<=
0
)
{
continue
;
}
if
(
x
<
0
)
{
width
+=
x
;
x
=
0
;
}
width
=
Math
.
min
(
width
,
imageWidth
-
x
);
if
(
width
<=
0
||
rowHeight
<=
0
)
{
continue
;
}
fillPreviewRect
(
graphics
,
x
,
y
,
width
,
rowHeight
,
getScheduleTaskColor
(
gene
,
colorCache
),
imageWidth
,
imageHeight
);
}
}
}
finally
{
graphics
.
dispose
();
}
try
(
ByteArrayOutputStream
output
=
new
ByteArrayOutputStream
())
{
ImageIO
.
write
(
image
,
"png"
,
output
);
return
"data:image/png;base64,"
+
Base64
.
getEncoder
().
encodeToString
(
output
.
toByteArray
());
}
catch
(
IOException
ex
)
{
log
.
warn
(
"Failed to build Gantt preview PNG."
,
ex
);
return
""
;
}
}
private
void
fillPreviewRect
(
Graphics2D
graphics
,
double
x
,
double
y
,
double
width
,
double
height
,
Color
color
,
int
imageWidth
,
int
imageHeight
)
{
int
left
=
Math
.
max
(
0
,
(
int
)
Math
.
floor
(
x
));
int
top
=
Math
.
max
(
0
,
(
int
)
Math
.
floor
(
y
));
int
right
=
Math
.
min
(
imageWidth
,
Math
.
max
(
left
+
1
,
(
int
)
Math
.
ceil
(
x
+
width
)));
int
bottom
=
Math
.
min
(
imageHeight
,
Math
.
max
(
top
+
1
,
(
int
)
Math
.
ceil
(
y
+
height
)));
if
(
left
>=
imageWidth
||
top
>=
imageHeight
||
right
<=
left
||
bottom
<=
top
)
{
return
;
}
graphics
.
setColor
(
color
);
graphics
.
fillRect
(
left
,
top
,
right
-
left
,
bottom
-
top
);
}
private
double
getPreviewRowY
(
int
index
,
int
equipCount
,
int
imageHeight
)
{
if
(
equipCount
<=
0
||
imageHeight
<=
0
)
{
return
0
D
;
}
if
(
imageHeight
<
equipCount
)
{
return
Math
.
min
(
imageHeight
-
1
D
,
Math
.
floor
(
index
*
(
double
)
imageHeight
/
equipCount
));
}
return
index
*
(
double
)
imageHeight
/
equipCount
;
}
private
double
getPreviewRowHeight
(
int
index
,
int
equipCount
,
int
imageHeight
,
double
y
)
{
if
(
equipCount
<=
0
||
imageHeight
<=
0
||
y
>=
imageHeight
)
{
return
0
D
;
}
if
(
imageHeight
<
equipCount
)
{
double
nextY
=
Math
.
floor
((
index
+
1
D
)
*
imageHeight
/
equipCount
);
return
Math
.
min
(
imageHeight
-
y
,
Math
.
max
(
1
D
,
nextY
-
y
));
}
double
rowHeight
=
imageHeight
/
(
double
)
equipCount
;
return
Math
.
min
(
rowHeight
,
Math
.
max
(
1
D
,
rowHeight
*
0.85
D
));
}
private
Color
getScheduleTaskColor
(
GAScheduleResult
gene
,
Map
<
String
,
Color
>
colorCache
)
{
String
key
=
getSchedulePlanKey
(
gene
);
Color
color
=
colorCache
.
get
(
key
);
if
(
color
!=
null
)
{
return
color
;
}
int
hue
=
key
==
null
?
210
:
(
key
.
hashCode
()
&
0x7fffffff
)
%
360
;
Color
rgb
=
hslToRgb
(
hue
,
0.70
D
,
0.55
D
);
color
=
new
Color
(
rgb
.
getRed
(),
rgb
.
getGreen
(),
rgb
.
getBlue
(),
199
);
colorCache
.
put
(
key
,
color
);
return
color
;
}
private
String
getSchedulePlanKey
(
GAScheduleResult
gene
)
{
if
(
gene
==
null
)
{
return
null
;
}
if
(
gene
.
getOrderId
()
!=
null
&&
!
gene
.
getOrderId
().
trim
().
isEmpty
())
{
return
gene
.
getOrderId
();
}
if
(
gene
.
getOrderCode
()
!=
null
&&
!
gene
.
getOrderCode
().
trim
().
isEmpty
())
{
return
gene
.
getOrderCode
();
}
return
String
.
valueOf
(
gene
.
getOperationId
());
}
private
Color
hslToRgb
(
int
hue
,
double
saturation
,
double
lightness
)
{
double
c
=
(
1
D
-
Math
.
abs
(
2
D
*
lightness
-
1
D
))
*
saturation
;
double
h
=
hue
/
60
D
;
double
x
=
c
*
(
1
D
-
Math
.
abs
(
h
%
2
D
-
1
D
));
double
r
=
0
D
;
double
g
=
0
D
;
double
b
=
0
D
;
if
(
h
<
1
D
)
{
r
=
c
;
g
=
x
;
}
else
if
(
h
<
2
D
)
{
r
=
x
;
g
=
c
;
}
else
if
(
h
<
3
D
)
{
g
=
c
;
b
=
x
;
}
else
if
(
h
<
4
D
)
{
g
=
x
;
b
=
c
;
}
else
if
(
h
<
5
D
)
{
r
=
x
;
b
=
c
;
}
else
{
r
=
c
;
b
=
x
;
}
double
m
=
lightness
-
c
/
2
D
;
return
new
Color
(
toRgbChannel
(
r
+
m
),
toRgbChannel
(
g
+
m
),
toRgbChannel
(
b
+
m
));
}
private
int
toRgbChannel
(
double
value
)
{
return
Math
.
max
(
0
,
Math
.
min
(
255
,
(
int
)
Math
.
round
(
value
*
255
D
)));
}
private
static
class
SceneVersionPreviewData
{
private
final
List
<
Long
>
machineIds
=
new
ArrayList
<>();
private
final
Map
<
Long
,
List
<
GAScheduleResult
>>
genesByMachine
=
new
LinkedHashMap
<>();
private
LocalDateTime
minStart
;
private
LocalDateTime
maxEnd
;
private
Long
minStartOffset
;
private
Long
maxEndOffset
;
private
int
taskCount
;
private
int
planCount
;
private
int
equipCount
;
private
long
taskMinTime
;
private
long
taskMaxTime
;
private
long
taskAverageTime
;
}
}
src/main/java/com/aps/service/plan/SceneService.java
View file @
074de057
...
...
@@ -28,6 +28,8 @@ public class SceneService {
@Autowired
private
RedisUtils
redisUtils
;
private
final
ObjectMapper
objectMapper
=
createObjectMapper
();
private
ObjectMapper
createObjectMapper
()
{
ObjectMapper
objectMapper
=
new
ObjectMapper
();
objectMapper
.
registerModule
(
new
JavaTimeModule
());
...
...
@@ -72,7 +74,6 @@ public class SceneService {
try
{
long
totalStart
=
System
.
nanoTime
();
ObjectMapper
objectMapper
=
createObjectMapper
();
SceneChromsome
sceneChromsome
=
(
SceneChromsome
)
redisUtils
.
get
(
"SceneId."
+
sceneId
);
File
file
;
if
(
sceneChromsome
==
null
)
{
...
...
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