Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
T
thermal-control-system
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
luwei
thermal-control-system
Commits
478c4876
Commit
478c4876
authored
Apr 27, 2026
by
luwei
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
修改
parent
36e2cc19
Changes
10
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
20 additions
and
16 deletions
+20
-16
eval_service.py
backend/app/services/eval_service.py
+8
-1
train_service.py
backend/app/services/train_service.py
+10
-3
DataCurve--Vg_Op5b.js
frontend/dist/assets/DataCurve--Vg_Op5b.js
+0
-4
DataCurve-DL-fCLWu.css
frontend/dist/assets/DataCurve-DL-fCLWu.css
+0
-1
DataManagement-CA4nqNQp.js
frontend/dist/assets/DataManagement-CA4nqNQp.js
+0
-1
ModelTraining-D7HksGk_.css
frontend/dist/assets/ModelTraining-D7HksGk_.css
+0
-1
ModelTraining-DPxp6Y6Z.js
frontend/dist/assets/ModelTraining-DPxp6Y6Z.js
+0
-1
PackageManagement-DHmLXqM4.css
frontend/dist/assets/PackageManagement-DHmLXqM4.css
+0
-1
PackageManagement-DRdx9gQd.js
frontend/dist/assets/PackageManagement-DRdx9gQd.js
+0
-1
index.html
frontend/dist/index.html
+2
-2
No files found.
backend/app/services/eval_service.py
View file @
478c4876
...
@@ -14,6 +14,13 @@ from app.services.data_management_service import DataManagementService
...
@@ -14,6 +14,13 @@ from app.services.data_management_service import DataManagementService
class
EvalService
:
class
EvalService
:
def
__init__
(
self
)
->
None
:
def
__init__
(
self
)
->
None
:
self
.
_dm
=
DataManagementService
()
self
.
_dm
=
DataManagementService
()
self
.
_base_dir
=
Path
(
__file__
)
.
resolve
()
.
parents
[
2
]
def
_resolve_model_path
(
self
,
file_path
:
str
)
->
Path
:
p
=
Path
(
file_path
)
if
p
.
is_absolute
():
return
p
return
self
.
_base_dir
/
p
# ── dropdown data ─────────────────────────────────────────────────────────
# ── dropdown data ─────────────────────────────────────────────────────────
...
@@ -39,7 +46,7 @@ class EvalService:
...
@@ -39,7 +46,7 @@ class EvalService:
if
not
pkg
:
if
not
pkg
:
raise
ValueError
(
'数据包不存在'
)
raise
ValueError
(
'数据包不存在'
)
model_path
=
P
ath
(
model
.
file_path
)
model_path
=
self
.
_resolve_model_p
ath
(
model
.
file_path
)
model_name
=
model
.
model_name
model_name
=
model
.
model_name
package_name
=
pkg
.
name
package_name
=
pkg
.
name
...
...
backend/app/services/train_service.py
View file @
478c4876
...
@@ -23,7 +23,8 @@ _registry_lock = threading.Lock()
...
@@ -23,7 +23,8 @@ _registry_lock = threading.Lock()
class
TrainService
:
class
TrainService
:
def
__init__
(
self
)
->
None
:
def
__init__
(
self
)
->
None
:
self
.
_dm
=
DataManagementService
()
self
.
_dm
=
DataManagementService
()
self
.
_models_dir
=
Path
(
__file__
)
.
resolve
()
.
parents
[
2
]
/
'saved_models'
self
.
_base_dir
=
Path
(
__file__
)
.
resolve
()
.
parents
[
2
]
self
.
_models_dir
=
self
.
_base_dir
/
'saved_models'
self
.
_models_dir
.
mkdir
(
parents
=
True
,
exist_ok
=
True
)
self
.
_models_dir
.
mkdir
(
parents
=
True
,
exist_ok
=
True
)
# ── packages (for dropdown) ──────────────────────────────────────────────
# ── packages (for dropdown) ──────────────────────────────────────────────
...
@@ -147,7 +148,7 @@ class TrainService:
...
@@ -147,7 +148,7 @@ class TrainService:
package_id
=
task
.
package_id
,
package_id
=
task
.
package_id
,
package_name
=
task
.
package_name
,
package_name
=
task
.
package_name
,
params
=
task
.
params
,
params
=
task
.
params
,
file_path
=
str
(
model_path
),
file_path
=
model_path
.
relative_to
(
self
.
_base_dir
)
.
as_posix
(
),
train_loss
=
task
.
train_loss
,
train_loss
=
task
.
train_loss
,
val_loss
=
task
.
val_loss
,
val_loss
=
task
.
val_loss
,
test_loss
=
task
.
test_loss
,
test_loss
=
task
.
test_loss
,
...
@@ -177,7 +178,7 @@ class TrainService:
...
@@ -177,7 +178,7 @@ class TrainService:
task
.
is_saved
=
0
task
.
is_saved
=
0
# Delete the .pt file only if nothing else references it
# Delete the .pt file only if nothing else references it
model_path
=
P
ath
(
model
.
file_path
)
model_path
=
self
.
_resolve_model_p
ath
(
model
.
file_path
)
if
model_path
.
exists
():
if
model_path
.
exists
():
model_path
.
unlink
(
missing_ok
=
True
)
model_path
.
unlink
(
missing_ok
=
True
)
...
@@ -186,6 +187,12 @@ class TrainService:
...
@@ -186,6 +187,12 @@ class TrainService:
# ── private helpers ───────────────────────────────────────────────────────
# ── private helpers ───────────────────────────────────────────────────────
def
_resolve_model_path
(
self
,
file_path
:
str
)
->
Path
:
"""Return absolute Path whether file_path is relative or absolute."""
p
=
Path
(
file_path
)
if
p
.
is_absolute
():
return
p
return
self
.
_base_dir
/
p
def
_launch_thread
(
self
,
task_id
:
int
,
package_id
:
int
,
params
:
dict
)
->
None
:
def
_launch_thread
(
self
,
task_id
:
int
,
package_id
:
int
,
params
:
dict
)
->
None
:
cancel_event
=
threading
.
Event
()
cancel_event
=
threading
.
Event
()
with
_registry_lock
:
with
_registry_lock
:
...
...
frontend/dist/assets/DataCurve--Vg_Op5b.js
deleted
100644 → 0
View file @
36e2cc19
import
{
A
as
e
,
D
as
t
,
Ht
as
n
,
I
as
r
,
N
as
i
,
X
as
a
,
d
as
o
,
m
as
s
,
st
as
c
,
t
as
l
,
u
}
from
"./_plugin-vue_export-helper-D1RKUtCV.js"
;
import
{
t
as
d
}
from
"./echarts-B4btcaVd.js"
;
var
f
=
{
class
:
`curve-box`
},
p
=
{
class
:
`stats-row`
},
m
=
{
class
:
`stat-card`
},
h
=
{
class
:
`stat-value`
},
g
=
{
class
:
`stat-card`
},
_
=
{
class
:
`stat-value`
},
v
=
{
class
:
`stat-card`
},
y
=
{
class
:
`stat-value`
},
b
=
l
({
__name
:
`DataCurve`
,
props
:{
records
:{
type
:
Array
,
default
:()
=>
[]}},
setup
(
l
){
let
b
=
l
,
x
=
c
(
null
),
S
=
null
,
C
=
u
(()
=>
(
Array
.
isArray
(
b
.
records
)?
b
.
records
:[]).
map
((
e
,
t
)
=>
({
idx
:
t
,
time
:
e
.
time
||
`第
${
t
+
1
}
条`
,
current
:
Number
(
e
.
current
),
voltage
:
Number
(
e
.
voltage
),
actual_temperature
:
Number
(
e
.
actual_temperature
)})).
filter
(
e
=>
Number
.
isFinite
(
e
.
current
)
||
Number
.
isFinite
(
e
.
voltage
)
||
Number
.
isFinite
(
e
.
actual_temperature
))),
w
=
u
(()
=>
{
let
e
=
C
.
value
.
map
(
e
=>
e
.
actual_temperature
).
filter
(
e
=>
Number
.
isFinite
(
e
));
return
{
count
:
C
.
value
.
length
,
max
:
e
.
length
?
Math
.
max
(...
e
):
0
,
min
:
e
.
length
?
Math
.
min
(...
e
):
0
}}),
T
=
e
=>
Number
.
isFinite
(
e
)?
Number
(
e
).
toFixed
(
2
):
`--`
,
E
=
e
=>
C
.
value
.
map
(
t
=>
Number
.
isFinite
(
t
[
e
])?
t
[
e
]:
null
),
D
=
()
=>
{
if
(
!
x
.
value
)
return
;
S
||=
d
(
x
.
value
);
let
e
=
C
.
value
.
length
>
0
;
S
.
setOption
({
animation
:
!
0
,
color
:[
`#409EFF`
,
`#67C23A`
,
`#FF6B6B`
],
tooltip
:{
trigger
:
`axis`
,
backgroundColor
:
`rgba(255,255,255,0.96)`
,
borderColor
:
`#e2e8f0`
,
borderWidth
:
1
,
textStyle
:{
color
:
`#334155`
},
extraCssText
:
`box-shadow: 0 10px 30px rgba(15,23,42,0.16); border-radius: 12px;`
,
formatter
(
e
){
if
(
!
e
?.
length
)
return
``
;
let
t
=
[
`<div style="margin-bottom:6px;font-weight:600;">
${
e
[
0
].
axisValue
}
</div>`
];
return
e
.
forEach
(
e
=>
{
t
.
push
(
`<div style="display:flex;align-items:center;gap:6px;min-width:160px;justify-content:space-between;">
<span>
${
e
.
marker
}${
e
.
seriesName
}
</span>
<strong>
${
T
(
e
.
data
)}
</strong>
</div>`
)}),
t
.
join
(
``
)}},
legend
:{
bottom
:
0
,
itemWidth
:
18
,
itemHeight
:
10
,
textStyle
:{
color
:
`#475569`
},
data
:[
`电流(A)`
,
`电压(V)`
,
`温度(℃)`
]},
grid
:{
top
:
24
,
left
:
24
,
right
:
24
,
bottom
:
56
,
containLabel
:
!
0
},
xAxis
:{
type
:
`category`
,
boundaryGap
:
!
1
,
data
:
C
.
value
.
map
(
e
=>
e
.
time
),
axisLabel
:{
color
:
`#64748b`
,
rotate
:
35
},
axisLine
:{
lineStyle
:{
color
:
`#94a3b8`
}}},
yAxis
:{
type
:
`value`
,
axisLabel
:{
color
:
`#64748b`
},
splitLine
:{
lineStyle
:{
type
:
`dashed`
,
color
:
`rgba(148, 163, 184, 0.45)`
}}},
series
:[{
name
:
`电流(A)`
,
type
:
`line`
,
smooth
:
!
0
,
symbol
:
`circle`
,
symbolSize
:
7
,
data
:
E
(
`current`
)},{
name
:
`电压(V)`
,
type
:
`line`
,
smooth
:
!
0
,
symbol
:
`circle`
,
symbolSize
:
7
,
data
:
E
(
`voltage`
)},{
name
:
`温度(℃)`
,
type
:
`line`
,
smooth
:
!
0
,
symbol
:
`circle`
,
symbolSize
:
7
,
data
:
E
(
`actual_temperature`
)}],
graphic
:
e
?[]:[{
type
:
`text`
,
left
:
`center`
,
top
:
`middle`
,
style
:{
text
:
`暂无足够数据生成曲线`
,
fill
:
`#64748b`
,
fontSize
:
14
}}]},
!
0
)},
O
=
()
=>
{
S
?.
resize
()};
return
i
(
async
()
=>
{
await
t
(),
D
(),
window
.
addEventListener
(
`resize`
,
O
)}),
a
(()
=>
b
.
records
,
async
()
=>
{
await
t
(),
D
()},{
deep
:
!
0
}),
e
(()
=>
{
window
.
removeEventListener
(
`resize`
,
O
),
S
?.
dispose
(),
S
=
null
}),(
e
,
t
)
=>
(
r
(),
s
(
`div`
,
f
,[
o
(
`div`
,
p
,[
o
(
`div`
,
m
,[
t
[
0
]
||=
o
(
`div`
,{
class
:
`stat-label`
},
`总条数`
,
-
1
),
o
(
`div`
,
h
,
n
(
w
.
value
.
count
),
1
)]),
o
(
`div`
,
g
,[
t
[
1
]
||=
o
(
`div`
,{
class
:
`stat-label`
},
`最高温度`
,
-
1
),
o
(
`div`
,
_
,
n
(
T
(
w
.
value
.
max
))
+
` °C`
,
1
)]),
o
(
`div`
,
v
,[
t
[
2
]
||=
o
(
`div`
,{
class
:
`stat-label`
},
`最低温度`
,
-
1
),
o
(
`div`
,
y
,
n
(
T
(
w
.
value
.
min
))
+
` °C`
,
1
)])]),
o
(
`div`
,{
ref_key
:
`chartRef`
,
ref
:
x
,
class
:
`echarts-box`
},
null
,
512
)]))}},[[
`__scopeId`
,
`data-v-7c9af9ab`
]]);
export
{
b
as
t
};
\ No newline at end of file
frontend/dist/assets/DataCurve-DL-fCLWu.css
deleted
100644 → 0
View file @
36e2cc19
.curve-box
[
data-v-7c9af9ab
]
{
flex-direction
:
column
;
gap
:
14px
;
height
:
100%
;
display
:
flex
}
.stats-row
[
data-v-7c9af9ab
]
{
grid-template-columns
:
repeat
(
3
,
minmax
(
0
,
1
fr
));
gap
:
12px
;
display
:
grid
}
.stat-card
[
data-v-7c9af9ab
]
{
background
:
#f3f6fb
;
border-radius
:
14px
;
padding
:
14px
16px
}
.stat-label
[
data-v-7c9af9ab
]
{
color
:
#64748b
;
margin-bottom
:
8px
;
font-size
:
13px
}
.stat-value
[
data-v-7c9af9ab
]
{
color
:
#0f172a
;
font-size
:
18px
;
font-weight
:
700
}
.echarts-box
[
data-v-7c9af9ab
]
{
background
:
linear-gradient
(
#fff
,
#f8fafc
);
border
:
1px
solid
#0f172a1
a
;
border-radius
:
14px
;
flex
:
1
;
min-height
:
360px
}
frontend/dist/assets/DataManagement-CA4nqNQp.js
deleted
100644 → 0
View file @
36e2cc19
This diff is collapsed.
Click to expand it.
frontend/dist/assets/ModelTraining-D7HksGk_.css
deleted
100644 → 0
View file @
36e2cc19
.train-page
[
data-v-fea158ef
]
{
background
:
var
(
--bg-page
);
flex-direction
:
column
;
gap
:
12px
;
height
:
100%
;
display
:
flex
;
overflow-y
:
auto
}
.config-card
[
data-v-fea158ef
],
.tasks-card
[
data-v-fea158ef
]
{
border
:
1px
solid
var
(
--border-color
);
border-radius
:
4px
;
flex-shrink
:
0
;
box-shadow
:
var
(
--shadow-card
)
!important
}
.config-card
[
data-v-fea158ef
]
.el-card__header
,
.tasks-card
[
data-v-fea158ef
]
.el-card__header
{
border-bottom
:
1px
solid
var
(
--border-color
);
background
:
#f7f8fa
;
align-items
:
center
;
height
:
44px
;
padding
:
0
20px
;
display
:
flex
}
.config-card
[
data-v-fea158ef
]
.el-card__body
,
.tasks-card
[
data-v-fea158ef
]
.el-card__body
{
padding
:
16px
20px
}
.tasks-card
[
data-v-fea158ef
]
{
flex
:
1
;
min-height
:
0
;
overflow
:
hidden
}
.card-title
[
data-v-fea158ef
]
{
color
:
var
(
--text-primary
);
font-size
:
14px
;
font-weight
:
600
}
.card-header-row
[
data-v-fea158ef
]
{
justify-content
:
space-between
;
align-items
:
center
;
width
:
100%
;
display
:
flex
}
.train-form
.form-row
[
data-v-fea158ef
]
{
flex-wrap
:
wrap
;
gap
:
24px
;
margin-bottom
:
4px
;
display
:
flex
}
.train-form
.form-item-wide
[
data-v-fea158ef
]
{
flex
:
1
;
min-width
:
220px
}
.train-form
.form-item-wide
[
data-v-fea158ef
]
.el-form-item__content
{
display
:
block
}
.params-section
[
data-v-fea158ef
]
{
border-top
:
1px
solid
var
(
--border-color
);
margin-bottom
:
8px
;
padding-top
:
12px
}
.params-label
[
data-v-fea158ef
]
{
color
:
var
(
--text-secondary
);
margin-bottom
:
12px
;
font-size
:
13px
;
font-weight
:
600
;
display
:
block
}
.params-grid
[
data-v-fea158ef
]
{
grid-template-columns
:
repeat
(
auto-fill
,
minmax
(
160px
,
1
fr
));
gap
:
12px
24px
;
display
:
grid
}
.params-grid
[
data-v-fea158ef
]
.el-form-item
{
margin-bottom
:
0
}
.form-action
[
data-v-fea158ef
]
{
border-top
:
1px
solid
var
(
--border-color
);
text-align
:
right
;
padding-top
:
16px
}
.params-cell
[
data-v-fea158ef
]
{
color
:
var
(
--text-secondary
);
white-space
:
nowrap
;
text-overflow
:
ellipsis
;
font-size
:
12px
;
display
:
block
;
overflow
:
hidden
}
.muted
[
data-v-fea158ef
]
{
color
:
var
(
--text-tertiary
)}
.err-text
[
data-v-fea158ef
]
{
color
:
#f53f3f
;
white-space
:
nowrap
;
text-overflow
:
ellipsis
;
font-size
:
12px
;
display
:
block
;
overflow
:
hidden
}
frontend/dist/assets/ModelTraining-DPxp6Y6Z.js
deleted
100644 → 0
View file @
36e2cc19
import
{
n
as
e
,
r
as
t
,
u
as
n
}
from
"./es-DCOtnflc.js"
;
import
{
$
as
ee
,
A
as
r
,
B
as
i
,
Ht
as
a
,
I
as
o
,
N
as
s
,
Q
as
c
,
R
as
l
,
V
as
u
,
_
as
d
,
a
as
f
,
at
as
p
,
d
as
m
,
f
as
h
,
ht
as
g
,
m
as
_
,
st
as
v
,
t
as
y
,
u
as
b
,
v
as
x
}
from
"./_plugin-vue_export-helper-D1RKUtCV.js"
;
import
{
c
as
S
,
i
as
C
,
l
as
w
,
n
as
T
,
o
as
E
,
s
as
D
,
t
as
O
}
from
"./trainManagement-TFX-G3Jl.js"
;
var
k
=
{
class
:
`train-page`
},
A
=
{
class
:
`form-row`
},
j
=
{
class
:
`params-section`
},
M
=
{
class
:
`params-grid`
},
N
=
{
class
:
`form-action`
},
P
=
{
class
:
`card-header-row`
},
F
=
{
class
:
`params-cell`
},
I
=
{
key
:
2
,
class
:
`muted`
},
L
=
{
key
:
0
,
class
:
`err-text`
},
R
=
{
key
:
1
},
z
=
`calc(100vh - 520px)`
,
B
=
y
(
Object
.
assign
({},{
__name
:
`index`
,
setup
(
y
){
let
B
=
p
({
model_name
:
``
,
package_id
:
``
,
params
:{
seq_len
:
20
,
hidden_size
:
64
,
num_layers
:
2
,
epochs
:
50
,
batch_size
:
32
,
learning_rate
:.
001
,
train_ratio
:.
8
}}),
V
=
v
([]),
H
=
v
(
!
1
),
U
=
v
([]),
W
=
v
(
!
1
),
G
=
null
,
K
=
b
(()
=>
U
.
value
.
some
(
e
=>
e
.
status
===
`pending`
||
e
.
status
===
`running`
)),
q
=
()
=>
{
G
||=
setInterval
(
Y
,
3
e3
)},
J
=
()
=>
{
G
&&=
(
clearInterval
(
G
),
null
)},
Y
=
async
()
=>
{
try
{
U
.
value
=
await
D
(),
K
.
value
?
q
():
J
()}
catch
{}},
te
=
async
()
=>
{
if
(
!
B
.
model_name
.
trim
()){
t
.
warning
(
`请输入模型名称`
);
return
}
if
(
!
B
.
package_id
){
t
.
warning
(
`请选择数据包`
);
return
}
H
.
value
=!
0
;
try
{
await
T
({
model_name
:
B
.
model_name
.
trim
(),
package_id
:
B
.
package_id
,
params
:{...
B
.
params
}}),
t
.
success
(
`训练任务已提交`
),
B
.
model_name
=
``
,
await
Y
()}
finally
{
H
.
value
=!
1
}},
ne
=
async
e
=>
{
try
{
await
O
(
e
.
id
),
t
.
success
(
`已发送取消请求`
),
await
Y
()}
catch
(
e
){
t
.
error
(
e
?.
message
||
`取消失败`
)}},
X
=
async
e
=>
{
try
{
await
S
(
e
.
id
),
t
.
success
(
`重新训练已启动`
),
await
Y
()}
catch
(
e
){
t
.
error
(
e
?.
message
||
`重启失败`
)}},
re
=
async
e
=>
{
try
{
await
w
(
e
.
id
),
t
.
success
(
`模型已保存,可在模型列表中查看`
),
await
Y
()}
catch
(
e
){
t
.
error
(
e
?.
message
||
`保存失败`
)}},
Z
=
async
n
=>
{
try
{
await
e
.
confirm
(
`确定删除训练任务"
${
n
.
model_name
}
"吗?`
,
`提示`
,{
type
:
`warning`
}),
await
C
(
n
.
id
),
t
.
success
(
`已删除`
),
await
Y
()}
catch
{}},
ie
=
{
pending
:{
type
:
`info`
,
text
:
`等待中`
},
running
:{
type
:
`warning`
,
text
:
`训练中`
},
completed
:{
type
:
`success`
,
text
:
`已完成`
},
failed
:{
type
:
`danger`
,
text
:
`失败`
},
cancelled
:{
type
:
``
,
text
:
`已取消`
}},
Q
=
e
=>
ie
[
e
]
||
{
type
:
`info`
,
text
:
e
},
$
=
e
=>
e
?[
`序列长度
${
e
.
seq_len
}
`
,
`隐藏层
${
e
.
hidden_size
}
`
,
`层数
${
e
.
num_layers
}
`
,
`轮数
${
e
.
epochs
}
`
,
`批次
${
e
.
batch_size
}
`
,
`学习率
${
e
.
learning_rate
}
`
,
`训练比
${
e
.
train_ratio
}
`
].
join
(
` / `
):
`-`
,
ae
=
e
=>
e
.
train_loss
==
null
?
`-`
:
`训练:
${
Number
(
e
.
train_loss
).
toFixed
(
5
)}
`
+
(
e
.
val_loss
==
null
?
``
:
` / 验证:
${
Number
(
e
.
val_loss
).
toFixed
(
5
)}
`
);
return
s
(
async
()
=>
{
W
.
value
=!
0
;
try
{
await
Promise
.
all
([
E
().
then
(
e
=>
V
.
value
=
e
),
Y
()])}
finally
{
W
.
value
=!
1
}}),
r
(
J
),(
e
,
t
)
=>
{
let
r
=
i
(
`el-option`
),
s
=
i
(
`el-select`
),
p
=
i
(
`el-form-item`
),
v
=
i
(
`el-input`
),
y
=
i
(
`el-input-number`
),
b
=
i
(
`el-button`
),
S
=
i
(
`el-form`
),
C
=
i
(
`el-card`
),
w
=
i
(
`el-table-column`
),
T
=
i
(
`el-tooltip`
),
E
=
i
(
`el-tag`
),
D
=
i
(
`el-progress`
),
O
=
i
(
`el-table`
),
G
=
u
(
`loading`
);
return
o
(),
_
(
`div`
,
k
,[
x
(
C
,{
class
:
`config-card`
,
shadow
:
`hover`
},{
header
:
c
(()
=>
[...
t
[
9
]
||=
[
m
(
`span`
,{
class
:
`card-title`
},
`训练配置`
,
-
1
)]]),
default
:
c
(()
=>
[
x
(
S
,{
model
:
B
,
"label-position"
:
`top`
,
class
:
`train-form`
},{
default
:
c
(()
=>
[
m
(
`div`
,
A
,[
x
(
p
,{
label
:
`选择数据包`
,
required
:
``
,
class
:
`form-item-wide`
},{
default
:
c
(()
=>
[
x
(
s
,{
modelValue
:
B
.
package_id
,
"onUpdate:modelValue"
:
t
[
0
]
||=
e
=>
B
.
package_id
=
e
,
placeholder
:
`请选择数据包`
,
filterable
:
``
,
style
:{
width
:
`100%`
}},{
default
:
c
(()
=>
[(
o
(
!
0
),
_
(
f
,
null
,
l
(
V
.
value
,
e
=>
(
o
(),
h
(
r
,{
key
:
e
.
id
,
label
:
`
${
e
.
name
}
(
${
e
.
data_count
}
条)`
,
value
:
e
.
id
},
null
,
8
,[
`label`
,
`value`
]))),
128
))]),
_
:
1
},
8
,[
`modelValue`
])]),
_
:
1
}),
x
(
p
,{
label
:
`模型名称`
,
required
:
``
,
class
:
`form-item-wide`
},{
default
:
c
(()
=>
[
x
(
v
,{
modelValue
:
B
.
model_name
,
"onUpdate:modelValue"
:
t
[
1
]
||=
e
=>
B
.
model_name
=
e
,
placeholder
:
`请输入模型名称`
,
maxlength
:
`100`
,
"show-word-limit"
:
``
},
null
,
8
,[
`modelValue`
])]),
_
:
1
})]),
m
(
`div`
,
j
,[
t
[
10
]
||=
m
(
`span`
,{
class
:
`params-label`
},
`LSTM 超参数`
,
-
1
),
m
(
`div`
,
M
,[
x
(
p
,{
label
:
`序列长度`
},{
default
:
c
(()
=>
[
x
(
y
,{
modelValue
:
B
.
params
.
seq_len
,
"onUpdate:modelValue"
:
t
[
2
]
||=
e
=>
B
.
params
.
seq_len
=
e
,
min
:
5
,
max
:
500
,
step
:
5
,
"controls-position"
:
`right`
,
style
:{
width
:
`100%`
}},
null
,
8
,[
`modelValue`
])]),
_
:
1
}),
x
(
p
,{
label
:
`隐藏层大小`
},{
default
:
c
(()
=>
[
x
(
y
,{
modelValue
:
B
.
params
.
hidden_size
,
"onUpdate:modelValue"
:
t
[
3
]
||=
e
=>
B
.
params
.
hidden_size
=
e
,
min
:
8
,
max
:
1024
,
step
:
8
,
"controls-position"
:
`right`
,
style
:{
width
:
`100%`
}},
null
,
8
,[
`modelValue`
])]),
_
:
1
}),
x
(
p
,{
label
:
`LSTM 层数`
},{
default
:
c
(()
=>
[
x
(
y
,{
modelValue
:
B
.
params
.
num_layers
,
"onUpdate:modelValue"
:
t
[
4
]
||=
e
=>
B
.
params
.
num_layers
=
e
,
min
:
1
,
max
:
8
,
"controls-position"
:
`right`
,
style
:{
width
:
`100%`
}},
null
,
8
,[
`modelValue`
])]),
_
:
1
}),
x
(
p
,{
label
:
`训练轮数 (Epochs)`
},{
default
:
c
(()
=>
[
x
(
y
,{
modelValue
:
B
.
params
.
epochs
,
"onUpdate:modelValue"
:
t
[
5
]
||=
e
=>
B
.
params
.
epochs
=
e
,
min
:
1
,
max
:
2
e3
,
step
:
10
,
"controls-position"
:
`right`
,
style
:{
width
:
`100%`
}},
null
,
8
,[
`modelValue`
])]),
_
:
1
}),
x
(
p
,{
label
:
`批次大小 (Batch)`
},{
default
:
c
(()
=>
[
x
(
y
,{
modelValue
:
B
.
params
.
batch_size
,
"onUpdate:modelValue"
:
t
[
6
]
||=
e
=>
B
.
params
.
batch_size
=
e
,
min
:
1
,
max
:
512
,
step
:
8
,
"controls-position"
:
`right`
,
style
:{
width
:
`100%`
}},
null
,
8
,[
`modelValue`
])]),
_
:
1
}),
x
(
p
,{
label
:
`学习率`
},{
default
:
c
(()
=>
[
x
(
y
,{
modelValue
:
B
.
params
.
learning_rate
,
"onUpdate:modelValue"
:
t
[
7
]
||=
e
=>
B
.
params
.
learning_rate
=
e
,
min
:
1
e
-
5
,
max
:
1
,
step
:
1
e
-
4
,
precision
:
5
,
"controls-position"
:
`right`
,
style
:{
width
:
`100%`
}},
null
,
8
,[
`modelValue`
])]),
_
:
1
}),
x
(
p
,{
label
:
`训练集比例`
},{
default
:
c
(()
=>
[
x
(
y
,{
modelValue
:
B
.
params
.
train_ratio
,
"onUpdate:modelValue"
:
t
[
8
]
||=
e
=>
B
.
params
.
train_ratio
=
e
,
min
:.
5
,
max
:.
99
,
step
:.
05
,
precision
:
2
,
"controls-position"
:
`right`
,
style
:{
width
:
`100%`
}},
null
,
8
,[
`modelValue`
])]),
_
:
1
})])]),
m
(
`div`
,
N
,[
x
(
b
,{
type
:
`primary`
,
size
:
`large`
,
loading
:
H
.
value
,
onClick
:
te
},{
default
:
c
(()
=>
[...
t
[
11
]
||=
[
d
(
` 开始训练 `
,
-
1
)]]),
_
:
1
},
8
,[
`loading`
])])]),
_
:
1
},
8
,[
`model`
])]),
_
:
1
}),
x
(
C
,{
class
:
`tasks-card`
,
shadow
:
`hover`
},{
header
:
c
(()
=>
[
m
(
`div`
,
P
,[
t
[
13
]
||=
m
(
`span`
,{
class
:
`card-title`
},
`训练记录`
,
-
1
),
x
(
b
,{
icon
:
g
(
n
),
size
:
`small`
,
plain
:
``
,
loading
:
W
.
value
,
onClick
:
Y
},{
default
:
c
(()
=>
[...
t
[
12
]
||=
[
d
(
` 刷新 `
,
-
1
)]]),
_
:
1
},
8
,[
`icon`
,
`loading`
])])]),
default
:
c
(()
=>
[
ee
((
o
(),
h
(
O
,{
data
:
U
.
value
,
border
:
``
,
stripe
:
``
,
height
:
z
},{
default
:
c
(()
=>
[
x
(
w
,{
prop
:
`model_name`
,
label
:
`模型名称`
,
"min-width"
:
`140`
,
"show-overflow-tooltip"
:
``
}),
x
(
w
,{
prop
:
`package_name`
,
label
:
`数据包`
,
"min-width"
:
`130`
,
"show-overflow-tooltip"
:
``
}),
x
(
w
,{
label
:
`参数`
,
"min-width"
:
`180`
,
"show-overflow-tooltip"
:
``
},{
default
:
c
(({
row
:
e
})
=>
[
x
(
T
,{
content
:
$
(
e
.
params
),
placement
:
`top`
},{
default
:
c
(()
=>
[
m
(
`span`
,
F
,
a
(
$
(
e
.
params
)),
1
)]),
_
:
2
},
1032
,[
`content`
])]),
_
:
1
}),
x
(
w
,{
label
:
`状态`
,
width
:
`100`
,
align
:
`center`
},{
default
:
c
(({
row
:
e
})
=>
[
x
(
E
,{
type
:
Q
(
e
.
status
).
type
,
size
:
`small`
},{
default
:
c
(()
=>
[
d
(
a
(
Q
(
e
.
status
).
text
),
1
)]),
_
:
2
},
1032
,[
`type`
])]),
_
:
1
}),
x
(
w
,{
label
:
`进度`
,
width
:
`150`
,
align
:
`center`
},{
default
:
c
(({
row
:
e
})
=>
[
e
.
status
===
`running`
?(
o
(),
h
(
D
,{
key
:
0
,
percentage
:
e
.
progress
,
"stroke-width"
:
6
,
"show-text"
:
!
0
,
style
:{
width
:
`120px`
}},
null
,
8
,[
`percentage`
])):
e
.
status
===
`completed`
?(
o
(),
h
(
D
,{
key
:
1
,
percentage
:
100
,
status
:
`success`
,
"stroke-width"
:
6
,
style
:{
width
:
`120px`
}})):(
o
(),
_
(
`span`
,
I
,
`—`
))]),
_
:
1
}),
x
(
w
,{
label
:
`损失`
,
"min-width"
:
`200`
,
"show-overflow-tooltip"
:
``
},{
default
:
c
(({
row
:
e
})
=>
[
e
.
status
===
`failed`
?(
o
(),
_
(
`span`
,
L
,
a
(
e
.
error_msg
||
`未知错误`
),
1
)):(
o
(),
_
(
`span`
,
R
,
a
(
ae
(
e
)),
1
))]),
_
:
1
}),
x
(
w
,{
prop
:
`created_at`
,
label
:
`创建时间`
,
width
:
`160`
}),
x
(
w
,{
label
:
`操作`
,
width
:
`210`
,
fixed
:
`right`
},{
default
:
c
(({
row
:
e
})
=>
[
e
.
status
===
`running`
||
e
.
status
===
`pending`
?(
o
(),
h
(
b
,{
key
:
0
,
link
:
``
,
type
:
`warning`
,
onClick
:
t
=>
ne
(
e
)},{
default
:
c
(()
=>
[...
t
[
14
]
||=
[
d
(
`取消`
,
-
1
)]]),
_
:
1
},
8
,[
`onClick`
])):
e
.
status
===
`completed`
?(
o
(),
_
(
f
,{
key
:
1
},[
e
.
is_saved
?(
o
(),
h
(
E
,{
key
:
1
,
type
:
`success`
,
size
:
`small`
,
style
:{
"margin-right"
:
`6px`
}},{
default
:
c
(()
=>
[...
t
[
16
]
||=
[
d
(
`已保存`
,
-
1
)]]),
_
:
1
})):(
o
(),
h
(
b
,{
key
:
0
,
link
:
``
,
type
:
`primary`
,
onClick
:
t
=>
re
(
e
)},{
default
:
c
(()
=>
[...
t
[
15
]
||=
[
d
(
` 保存模型 `
,
-
1
)]]),
_
:
1
},
8
,[
`onClick`
])),
x
(
b
,{
link
:
``
,
type
:
`info`
,
onClick
:
t
=>
X
(
e
)},{
default
:
c
(()
=>
[...
t
[
17
]
||=
[
d
(
`重新训练`
,
-
1
)]]),
_
:
1
},
8
,[
`onClick`
]),
x
(
b
,{
link
:
``
,
type
:
`danger`
,
onClick
:
t
=>
Z
(
e
)},{
default
:
c
(()
=>
[...
t
[
18
]
||=
[
d
(
`删除`
,
-
1
)]]),
_
:
1
},
8
,[
`onClick`
])],
64
)):(
o
(),
_
(
f
,{
key
:
2
},[
x
(
b
,{
link
:
``
,
type
:
`info`
,
onClick
:
t
=>
X
(
e
)},{
default
:
c
(()
=>
[...
t
[
19
]
||=
[
d
(
`重新训练`
,
-
1
)]]),
_
:
1
},
8
,[
`onClick`
]),
x
(
b
,{
link
:
``
,
type
:
`danger`
,
onClick
:
t
=>
Z
(
e
)},{
default
:
c
(()
=>
[...
t
[
20
]
||=
[
d
(
`删除`
,
-
1
)]]),
_
:
1
},
8
,[
`onClick`
])],
64
))]),
_
:
1
})]),
_
:
1
},
8
,[
`data`
])),[[
G
,
W
.
value
]])]),
_
:
1
})])}}}),[[
`__scopeId`
,
`data-v-fea158ef`
]]);
export
{
B
as
default
};
\ No newline at end of file
frontend/dist/assets/PackageManagement-DHmLXqM4.css
deleted
100644 → 0
View file @
36e2cc19
.pane-card
[
data-v-bbcd2093
]
{
border
:
none
;
border-right
:
1px
solid
var
(
--border-color
);
background
:
var
(
--bg-white
);
border-radius
:
0
;
flex-direction
:
column
;
height
:
100%
;
display
:
flex
;
overflow
:
hidden
;
box-shadow
:
none
!important
}
.pane-card
[
data-v-bbcd2093
]
.el-card__header
{
border-bottom
:
1px
solid
var
(
--border-color
);
background
:
#f7f8fa
;
align-items
:
center
;
height
:
44px
;
padding
:
0
16px
;
display
:
flex
}
.pane-card
[
data-v-bbcd2093
]
.el-card__body
{
flex
:
1
;
padding
:
8px
0
;
overflow-y
:
auto
}
.pane-header
[
data-v-bbcd2093
]
{
width
:
100%
;
color
:
var
(
--text-primary
);
justify-content
:
space-between
;
align-items
:
center
;
font-size
:
14px
;
font-weight
:
600
;
display
:
flex
}
.tree-node
[
data-v-bbcd2093
]
{
justify-content
:
space-between
;
align-items
:
center
;
width
:
100%
;
min-width
:
0
;
padding-right
:
4px
;
display
:
flex
}
.tree-main
[
data-v-bbcd2093
]
{
align-items
:
center
;
gap
:
6px
;
min-width
:
0
;
display
:
flex
}
.tree-icon
[
data-v-bbcd2093
]
{
color
:
var
(
--primary
);
flex-shrink
:
0
;
font-size
:
14px
}
.tree-name
[
data-v-bbcd2093
]
{
text-overflow
:
ellipsis
;
white-space
:
nowrap
;
color
:
var
(
--text-primary
);
font-size
:
13px
;
overflow
:
hidden
}
.tree-actions
[
data-v-bbcd2093
]
{
flex-shrink
:
0
;
gap
:
0
;
display
:
none
}
.tree-actions
.el-button
[
data-v-bbcd2093
]
{
color
:
var
(
--text-tertiary
);
padding
:
0
3px
;
font-size
:
13px
}
.tree-actions
.el-button
[
data-v-bbcd2093
]
:hover
{
color
:
var
(
--primary
)}
.tree-node
:hover
.tree-actions
[
data-v-bbcd2093
]
{
display
:
inline-flex
}
.pane-card
[
data-v-8f5781ed
]
{
border
:
none
;
border-right
:
1px
solid
var
(
--border-color
);
background
:
var
(
--bg-white
);
border-radius
:
0
;
flex-direction
:
column
;
height
:
100%
;
display
:
flex
;
overflow
:
hidden
;
box-shadow
:
none
!important
}
.pane-card
[
data-v-8f5781ed
]
.el-card__header
{
border-bottom
:
1px
solid
var
(
--border-color
);
background
:
#f7f8fa
;
align-items
:
center
;
height
:
44px
;
padding
:
0
16px
;
display
:
flex
}
.pane-card
[
data-v-8f5781ed
]
.el-card__body
{
flex
:
1
;
padding
:
12px
16px
;
overflow
:
hidden
}
.pane-header
[
data-v-8f5781ed
]
{
width
:
100%
;
color
:
var
(
--text-primary
);
justify-content
:
space-between
;
align-items
:
center
;
font-size
:
14px
;
font-weight
:
600
;
display
:
flex
}
.search-bar
[
data-v-8f5781ed
]
{
gap
:
8px
;
margin-bottom
:
12px
;
display
:
flex
}
.search-bar
.el-input
[
data-v-8f5781ed
]
{
flex
:
1
}
[
data-v-8f5781ed
]
.el-table
.current-row
>
td
{
background
:
var
(
--primary-light
)
!important
}
[
data-v-8f5781ed
]
.el-table
.el-button.is-link
{
height
:
auto
;
padding
:
0
4px
;
font-size
:
13px
;
line-height
:
1
}
.pane-card
[
data-v-6b2fedfc
]
{
background
:
var
(
--bg-white
);
border
:
none
;
border-radius
:
0
;
flex-direction
:
column
;
height
:
100%
;
display
:
flex
;
overflow
:
hidden
;
box-shadow
:
none
!important
}
.pane-card
[
data-v-6b2fedfc
]
.el-card__header
{
border-bottom
:
1px
solid
var
(
--border-color
);
background
:
#f7f8fa
;
align-items
:
center
;
height
:
44px
;
padding
:
0
16px
;
display
:
flex
}
.pane-card
[
data-v-6b2fedfc
]
.el-card__body
{
flex
:
1
;
padding
:
0
;
overflow
:
hidden
}
.pane-header
[
data-v-6b2fedfc
]
{
width
:
100%
;
color
:
var
(
--text-primary
);
justify-content
:
space-between
;
align-items
:
center
;
font-size
:
14px
;
font-weight
:
600
;
display
:
flex
}
.pkg-title
[
data-v-6b2fedfc
]
{
color
:
var
(
--text-secondary
);
margin-left
:
4px
;
font-size
:
13px
;
font-weight
:
400
}
.content-wrap
[
data-v-6b2fedfc
]
{
height
:
100%
;
padding
:
0
16px
12px
}
[
data-v-6b2fedfc
]
.el-radio-group
.el-radio-button__inner
{
color
:
var
(
--text-secondary
);
border-color
:
var
(
--border-color
);
background
:
0
0
;
padding
:
4px
12px
;
font-size
:
13px
}
[
data-v-6b2fedfc
]
.el-radio-group
.el-radio-button__original-radio
:checked
+
.el-radio-button__inner
{
color
:
#fff
;
background
:
var
(
--primary
)
!important
;
border-color
:
var
(
--primary
)
!important
;
box-shadow
:
none
!important
}
.add-pkg-page
[
data-v-03a732e5
]
{
flex-direction
:
column
;
gap
:
0
;
height
:
100%
;
display
:
flex
;
overflow
:
hidden
}
.add-pkg-header
[
data-v-03a732e5
]
{
background
:
#ffffff
e6
;
border-bottom
:
1px
solid
#e8edf3
;
flex-shrink
:
0
;
align-items
:
center
;
gap
:
16px
;
padding
:
12px
20px
;
display
:
flex
}
.add-pkg-title
[
data-v-03a732e5
]
{
color
:
#0f172a
;
font-size
:
16px
;
font-weight
:
600
}
.section-card
[
data-v-03a732e5
]
{
background
:
#fff
;
border
:
1px
solid
#e8edf3
;
border-radius
:
8px
;
padding
:
16px
;
overflow
:
hidden
}
.section-title
[
data-v-03a732e5
]
{
color
:
#0f172a
;
align-items
:
center
;
gap
:
8px
;
margin-bottom
:
12px
;
font-size
:
14px
;
font-weight
:
600
;
display
:
flex
}
.section-hint
[
data-v-03a732e5
]
{
color
:
#64748b
;
font-size
:
12px
;
font-weight
:
400
}
.file-search-bar
[
data-v-03a732e5
]
{
margin-bottom
:
10px
}
.file-section
[
data-v-03a732e5
]
{
flex-shrink
:
0
;
margin
:
12px
12px
0
}
.section-bottom
[
data-v-03a732e5
]
{
flex
:
1
;
gap
:
12px
;
min-height
:
0
;
padding
:
12px
;
display
:
flex
;
overflow
:
hidden
}
.form-section
[
data-v-03a732e5
]
{
flex-shrink
:
0
;
width
:
320px
;
overflow-y
:
auto
}
.preview-section
[
data-v-03a732e5
]
{
flex-direction
:
column
;
flex
:
1
;
min-width
:
0
;
display
:
flex
;
overflow
:
hidden
}
.preview-section
.section-title
[
data-v-03a732e5
]
{
flex-shrink
:
0
}
.preview-content
[
data-v-03a732e5
]
{
flex
:
1
;
min-height
:
0
;
overflow
:
hidden
}
.pkg-form
[
data-v-03a732e5
]
.el-form-item
{
margin-bottom
:
16px
}
.pkg-page
[
data-v-bc327363
]
{
background
:
var
(
--bg-page
);
height
:
100%
}
.pkg-page.dragging
[
data-v-bc327363
]
{
-webkit-user-select
:
none
;
user-select
:
none
;
cursor
:
col-resize
}
.pkg-layout
[
data-v-bc327363
]
{
background
:
var
(
--bg-white
);
border
:
1px
solid
var
(
--border-color
);
height
:
100%
;
box-shadow
:
var
(
--shadow-card
);
align-items
:
stretch
;
gap
:
0
;
display
:
flex
}
.pane-divider
[
data-v-bc327363
]
{
background
:
var
(
--border-color
);
cursor
:
col-resize
;
flex-shrink
:
0
;
width
:
4px
;
transition
:
background
.15s
;
position
:
relative
}
.pane-divider
[
data-v-bc327363
]
:after
{
content
:
""
;
position
:
absolute
;
inset
:
0
-2px
}
.pane-divider
[
data-v-bc327363
]
:hover
,
.dragging
.pane-divider
[
data-v-bc327363
]
{
background
:
var
(
--primary-border
)}
frontend/dist/assets/PackageManagement-DRdx9gQd.js
deleted
100644 → 0
View file @
36e2cc19
This diff is collapsed.
Click to expand it.
frontend/dist/index.html
View file @
478c4876
...
@@ -5,10 +5,10 @@
...
@@ -5,10 +5,10 @@
<link
rel=
"icon"
href=
"/favicon.ico"
>
<link
rel=
"icon"
href=
"/favicon.ico"
>
<meta
name=
"viewport"
content=
"width=device-width, initial-scale=1.0"
>
<meta
name=
"viewport"
content=
"width=device-width, initial-scale=1.0"
>
<title>
热实验温度控制系统
</title>
<title>
热实验温度控制系统
</title>
<script
type=
"module"
crossorigin
src=
"/assets/index-
D5S_ELZm
.js"
></script>
<script
type=
"module"
crossorigin
src=
"/assets/index-
CvdqK_rU
.js"
></script>
<link
rel=
"modulepreload"
crossorigin
href=
"/assets/_plugin-vue_export-helper-D1RKUtCV.js"
>
<link
rel=
"modulepreload"
crossorigin
href=
"/assets/_plugin-vue_export-helper-D1RKUtCV.js"
>
<link
rel=
"modulepreload"
crossorigin
href=
"/assets/es-DCOtnflc.js"
>
<link
rel=
"modulepreload"
crossorigin
href=
"/assets/es-DCOtnflc.js"
>
<link
rel=
"stylesheet"
crossorigin
href=
"/assets/index-
BrwBxauG
.css"
>
<link
rel=
"stylesheet"
crossorigin
href=
"/assets/index-
pfQxyObg
.css"
>
</head>
</head>
<body>
<body>
<div
id=
"app"
></div>
<div
id=
"app"
></div>
...
...
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