Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
phsl
/
admin
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Pipelines
Wiki
Snippets
Members
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Commit
1fe9a380
authored
Mar 05, 2026
by
Jony.L
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
大屏数据:大地图 真实数据 管理端调整
parent
4ffe89c8
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
509 additions
and
110 deletions
+509
-110
src/api/compute/resourcespu/index.ts
+1
-0
src/views/Home/Home.vue
+12
-9
src/views/biz/home/index.vue
+433
-89
src/views/compute/resourcespu/form/index.vue
+63
-12
No files found.
src/api/compute/resourcespu/index.ts
View file @
1fe9a380
...
@@ -16,6 +16,7 @@ export interface ResourceSpu {
...
@@ -16,6 +16,7 @@ export interface ResourceSpu {
nic
?:
string
;
// 网卡配置
nic
?:
string
;
// 网卡配置
ip
?:
string
;
// 服务器ip
ip
?:
string
;
// 服务器ip
location
?:
string
;
// 位置
location
?:
string
;
// 位置
areaId
?:
number
;
// 地区ID
initUsername
?:
string
;
// 初始用户名
initUsername
?:
string
;
// 初始用户名
initPassword
?:
string
;
// 初始密码
initPassword
?:
string
;
// 初始密码
intro
?:
string
;
// 商品简介
intro
?:
string
;
// 商品简介
...
...
src/views/Home/Home.vue
View file @
1fe9a380
...
@@ -34,20 +34,18 @@
...
@@ -34,20 +34,18 @@
<div
class=
"statistical-item"
>
<div
class=
"statistical-item"
>
<i></i>
<i></i>
<div>
<div>
<div
class=
"label"
>
算力利用率
</div>
<div
class=
"label"
>
闲置算力
</div>
<div
class=
"value"
>
{{
dashboardData
.
overallSituation
.
computeUtilizationRate
}}
%
</div>
<div
class=
"value"
>
<!-- 42.37%-->
{{
dashboardData
.
overallSituation
.
idleCompute
}}
TOPS
</div>
</div>
</div>
</div>
</div>
<div
class=
"statistical-item"
>
<div
class=
"statistical-item"
>
<i></i>
<i></i>
<div>
<div>
<div
class=
"label"
>
运行中任务数
</div>
<div
class=
"label"
>
算力利用率
</div>
<div
class=
"value"
>
<div
class=
"value"
>
{{
dashboardData
.
overallSituation
.
computeUtilizationRate
}}
%
</div>
{{
dashboardData
.
overallSituation
.
runningTaskCount
}}
<!-- 42.37%-->
<!-- 29
<animation-count
:end-val=
"0.83"
decimals
:range-min=
"40"
:range-max=
"42"
/>
-->
</div>
</div>
</div>
</div>
</div>
</div>
</div>
...
@@ -268,6 +266,11 @@ const fetchRealData = async () => {
...
@@ -268,6 +266,11 @@ const fetchRealData = async () => {
if
(
res
.
carouselItems
)
{
if
(
res
.
carouselItems
)
{
dashboardData
.
value
.
carouselItems
=
res
.
carouselItems
dashboardData
.
value
.
carouselItems
=
res
.
carouselItems
}
}
// 地图数据
if
(
res
.
mapData
)
{
dashboardData
.
value
.
mapData
=
res
.
mapData
}
}
}
}
catch
(
error
)
{
}
catch
(
error
)
{
console
.
error
(
'获取真实数据失败:'
,
error
)
console
.
error
(
'获取真实数据失败:'
,
error
)
...
...
src/views/biz/home/index.vue
View file @
1fe9a380
...
@@ -21,9 +21,6 @@
...
@@ -21,9 +21,6 @@
</div>
</div>
</el-card>
</el-card>
<!-- 第一行:平台总体态势 + API请求趋势 -->
<el-row
:gutter=
"20"
>
<el-col
:span=
"12"
>
<!-- 平台总体态势 -->
<!-- 平台总体态势 -->
<el-card
class=
"config-card"
shadow=
"never"
>
<el-card
class=
"config-card"
shadow=
"never"
>
<
template
#
header
>
<
template
#
header
>
...
@@ -33,35 +30,34 @@
...
@@ -33,35 +30,34 @@
<el-button
type=
"primary"
size=
"small"
@
click=
"saveOverallSituation"
>
保存
</el-button>
<el-button
type=
"primary"
size=
"small"
@
click=
"saveOverallSituation"
>
保存
</el-button>
</div>
</div>
</
template
>
</
template
>
<el-form
:model=
"overallSituation"
label-width=
"1
4
0px"
class=
"config-form"
>
<el-form
:model=
"overallSituation"
label-width=
"1
3
0px"
class=
"config-form"
>
<el-row
:gutter=
"
2
0"
>
<el-row
:gutter=
"0"
>
<el-col
:span=
"12"
>
<el-col
:span=
"12"
>
<el-form-item
label=
"算力总规模(
P
)"
>
<el-form-item
label=
"算力总规模(
TOPS
)"
>
<el-input-number
v-model=
"overallSituation.allCompute"
:precision=
"2"
:min=
"0"
/>
<el-input-number
v-model=
"overallSituation.allCompute"
:precision=
"2"
:min=
"0"
:controls=
"false"
/>
</el-form-item>
</el-form-item>
</el-col>
</el-col>
<el-col
:span=
"12"
>
<el-col
:span=
"12"
>
<el-form-item
label=
"已租赁算力(
P
)"
>
<el-form-item
label=
"已租赁算力(
TOPS
)"
>
<el-input-number
v-model=
"overallSituation.leaseCompute"
:precision=
"2"
:min=
"0"
/>
<el-input-number
v-model=
"overallSituation.leaseCompute"
:precision=
"2"
:min=
"0"
:controls=
"false"
/>
</el-form-item>
</el-form-item>
</el-col>
</el-col>
</el-row>
<el-row
:gutter=
"20"
>
<el-col
:span=
"12"
>
<el-col
:span=
"12"
>
<el-form-item
label=
"
算力利用率(%
)"
>
<el-form-item
label=
"
闲置算力(TOPS
)"
>
<el-input-number
v-model=
"overallSituation.
computeUtilizationRate"
:precision=
"2"
:min=
"0"
:max=
"100
"
/>
<el-input-number
v-model=
"overallSituation.
idleCompute"
:precision=
"2"
:min=
"0"
:controls=
"false
"
/>
</el-form-item>
</el-form-item>
</el-col>
</el-col>
<el-col
:span=
"12"
>
<el-col
:span=
"12"
>
<el-form-item
label=
"
运行中任务数
"
>
<el-form-item
label=
"
算力利用率(%)
"
>
<el-input-number
v-model=
"overallSituation.
runningTaskCount"
:min=
"0
"
/>
<el-input-number
v-model=
"overallSituation.
computeUtilizationRate"
:precision=
"2"
:min=
"0"
:max=
"100"
:controls=
"false
"
/>
</el-form-item>
</el-form-item>
</el-col>
</el-col>
</el-row>
</el-row>
</el-form>
</el-form>
</el-card>
</el-card>
</el-col>
<!-- 第二行:API请求趋势 + 算力资源分布 -->
<el-row
:gutter=
"20"
>
<el-col
:span=
"12"
>
<el-col
:span=
"12"
>
<!-- API请求趋势 -->
<!-- API请求趋势 -->
<el-card
class=
"config-card"
shadow=
"never"
>
<el-card
class=
"config-card"
shadow=
"never"
>
...
@@ -72,11 +68,14 @@
...
@@ -72,11 +68,14 @@
<el-button
type=
"primary"
size=
"small"
@
click=
"saveApiCalls"
>
保存
</el-button>
<el-button
type=
"primary"
size=
"small"
@
click=
"saveApiCalls"
>
保存
</el-button>
</div>
</div>
</
template
>
</
template
>
<el-tabs
v-model=
"apiCallsTab"
type=
"border-card"
>
<!-- 日维度 -->
<el-tab-pane
label=
"日"
name=
"d"
>
<div
class=
"table-section"
>
<div
class=
"table-section"
>
<el-button
type=
"primary"
size=
"small"
@
click=
"addApiCallItem
"
style=
"margin-bottom: 10px;"
>
<el-button
type=
"primary"
size=
"small"
@
click=
"addApiCallItem('d')
"
style=
"margin-bottom: 10px;"
>
<Icon
icon=
"ep:plus"
class=
"mr-5px"
/>
添加数据项
<Icon
icon=
"ep:plus"
class=
"mr-5px"
/>
添加数据项
</el-button>
</el-button>
<table
class=
"data-table"
v-if=
"apiCallsList
.length > 0"
>
<table
class=
"data-table"
v-if=
"apiCallsData.d && apiCallsData.d
.length > 0"
>
<thead>
<thead>
<tr>
<tr>
<th>
日期
</th>
<th>
日期
</th>
...
@@ -85,7 +84,7 @@
...
@@ -85,7 +84,7 @@
</tr>
</tr>
</thead>
</thead>
<tbody>
<tbody>
<tr
v-for=
"(item, index) in apiCallsList
"
:key=
"index"
>
<tr
v-for=
"(item, index) in apiCallsData.d
"
:key=
"index"
>
<td>
<td>
<el-date-picker
<el-date-picker
v-model=
"item.countDate"
v-model=
"item.countDate"
...
@@ -97,10 +96,201 @@
...
@@ -97,10 +96,201 @@
/>
/>
</td>
</td>
<td>
<td>
<el-input-number
v-model=
"item.callsCount"
:min=
"0"
size=
"small"
/>
<el-input-number
v-model=
"item.callsCount"
:min=
"0"
:controls=
"false"
size=
"small"
/>
</td>
<td>
<el-button
type=
"danger"
size=
"small"
@
click=
"removeApiCallItem('d', index)"
>
删除
</el-button>
</td>
</tr>
</tbody>
</table>
<el-empty
v-else
description=
"暂无数据,请添加"
:image-size=
"80"
/>
</div>
</el-tab-pane>
<!-- 月维度 -->
<el-tab-pane
label=
"月"
name=
"m"
>
<div
class=
"table-section"
>
<el-button
type=
"primary"
size=
"small"
@
click=
"addApiCallItem('m')"
style=
"margin-bottom: 10px;"
>
<Icon
icon=
"ep:plus"
class=
"mr-5px"
/>
添加数据项
</el-button>
<table
class=
"data-table"
v-if=
"apiCallsData.m && apiCallsData.m.length > 0"
>
<thead>
<tr>
<th>
日期
</th>
<th>
调用次数
</th>
<th
style=
"width: 80px"
>
操作
</th>
</tr>
</thead>
<tbody>
<tr
v-for=
"(item, index) in apiCallsData.m"
:key=
"index"
>
<td>
<el-date-picker
v-model=
"item.countDate"
type=
"month"
placeholder=
"选择月份"
format=
"YYYY-MM"
value-format=
"YYYY-MM"
size=
"small"
/>
</td>
<td>
<el-input-number
v-model=
"item.callsCount"
:min=
"0"
:controls=
"false"
size=
"small"
/>
</td>
<td>
<el-button
type=
"danger"
size=
"small"
@
click=
"removeApiCallItem('m', index)"
>
删除
</el-button>
</td>
</tr>
</tbody>
</table>
<el-empty
v-else
description=
"暂无数据,请添加"
:image-size=
"80"
/>
</div>
</el-tab-pane>
<!-- 年维度 -->
<el-tab-pane
label=
"年"
name=
"y"
>
<div
class=
"table-section"
>
<el-button
type=
"primary"
size=
"small"
@
click=
"addApiCallItem('y')"
style=
"margin-bottom: 10px;"
>
<Icon
icon=
"ep:plus"
class=
"mr-5px"
/>
添加数据项
</el-button>
<table
class=
"data-table"
v-if=
"apiCallsData.y && apiCallsData.y.length > 0"
>
<thead>
<tr>
<th>
年份
</th>
<th>
调用次数
</th>
<th
style=
"width: 80px"
>
操作
</th>
</tr>
</thead>
<tbody>
<tr
v-for=
"(item, index) in apiCallsData.y"
:key=
"index"
>
<td>
<el-input
v-model=
"item.countDate"
placeholder=
"如:2025"
size=
"small"
/>
</td>
<td>
<el-input-number
v-model=
"item.callsCount"
:min=
"0"
:controls=
"false"
size=
"small"
/>
</td>
<td>
<el-button
type=
"danger"
size=
"small"
@
click=
"removeApiCallItem('y', index)"
>
删除
</el-button>
</td>
</tr>
</tbody>
</table>
<el-empty
v-else
description=
"暂无数据,请添加"
:image-size=
"80"
/>
</div>
</el-tab-pane>
</el-tabs>
</el-card>
</el-col>
<el-col
:span=
"12"
>
<!-- 算力资源分布 -->
<el-card
class=
"config-card"
shadow=
"never"
>
<
template
#
header
>
<div
class=
"card-header"
>
<Icon
icon=
"ep:pie-chart"
:size=
"20"
/>
<span
class=
"title"
>
算力资源分布
</span>
<el-button
type=
"primary"
size=
"small"
@
click=
"saveComputeDistribution"
>
保存
</el-button>
</div>
</
template
>
<el-tabs
v-model=
"activeTab"
type=
"border-card"
>
<!-- GPU型号 -->
<el-tab-pane
label=
"GPU型号"
name=
"gpu"
>
<div
class=
"table-section"
>
<el-button
type=
"primary"
size=
"small"
@
click=
"addComputeItem('gpu')"
style=
"margin-bottom: 10px;"
>
<Icon
icon=
"ep:plus"
class=
"mr-5px"
/>
添加GPU型号
</el-button>
<table
class=
"data-table"
v-if=
"computeDistribution.gpu && computeDistribution.gpu.length > 0"
>
<thead>
<tr>
<th>
型号名称
</th>
<th>
占比
</th>
<th
style=
"width: 80px"
>
操作
</th>
</tr>
</thead>
<tbody>
<tr
v-for=
"(item, index) in computeDistribution.gpu"
:key=
"index"
>
<td>
<el-input
v-model=
"item.name"
placeholder=
"如:4090"
size=
"small"
/>
</td>
<td>
<el-input-number
v-model=
"item.value"
:precision=
"2"
:min=
"0"
:controls=
"false"
size=
"small"
/>
</td>
<td>
<el-button
type=
"danger"
size=
"small"
@
click=
"removeComputeItem('gpu', index)"
>
删除
</el-button>
</td>
</tr>
</tbody>
</table>
<el-empty
v-else
description=
"暂无数据,请添加"
:image-size=
"80"
/>
</div>
</el-tab-pane>
<!-- 算力来源 -->
<el-tab-pane
label=
"算力来源"
name=
"source"
>
<div
class=
"table-section"
>
<el-button
type=
"primary"
size=
"small"
@
click=
"addComputeItem('source')"
style=
"margin-bottom: 10px;"
>
<Icon
icon=
"ep:plus"
class=
"mr-5px"
/>
添加来源
</el-button>
<table
class=
"data-table"
v-if=
"computeDistribution.source && computeDistribution.source.length > 0"
>
<thead>
<tr>
<th>
来源名称
</th>
<th>
占比
</th>
<th
style=
"width: 80px"
>
操作
</th>
</tr>
</thead>
<tbody>
<tr
v-for=
"(item, index) in computeDistribution.source"
:key=
"index"
>
<td>
<el-input
v-model=
"item.name"
placeholder=
"如:自有"
size=
"small"
/>
</td>
<td>
<el-input-number
v-model=
"item.value"
:precision=
"2"
:min=
"0"
:controls=
"false"
size=
"small"
/>
</td>
<td>
<el-button
type=
"danger"
size=
"small"
@
click=
"removeComputeItem('source', index)"
>
删除
</el-button>
</td>
</tr>
</tbody>
</table>
<el-empty
v-else
description=
"暂无数据,请添加"
:image-size=
"80"
/>
</div>
</el-tab-pane>
<!-- 计算资源 -->
<el-tab-pane
label=
"计算资源"
name=
"resource"
>
<div
class=
"table-section"
>
<el-button
type=
"primary"
size=
"small"
@
click=
"addComputeItem('resource')"
style=
"margin-bottom: 10px;"
>
<Icon
icon=
"ep:plus"
class=
"mr-5px"
/>
添加资源类型
</el-button>
<table
class=
"data-table"
v-if=
"computeDistribution.resource && computeDistribution.resource.length > 0"
>
<thead>
<tr>
<th>
资源名称
</th>
<th>
占比
</th>
<th
style=
"width: 80px"
>
操作
</th>
</tr>
</thead>
<tbody>
<tr
v-for=
"(item, index) in computeDistribution.resource"
:key=
"index"
>
<td>
<el-input
v-model=
"item.name"
placeholder=
"如:裸金属"
size=
"small"
/>
</td>
<td>
<el-input-number
v-model=
"item.value"
:precision=
"2"
:min=
"0"
:controls=
"false"
size=
"small"
/>
</td>
</td>
<td>
<td>
<el-button
type=
"danger"
size=
"small"
@
click=
"removeApiCallItem(
index)"
>
<el-button
type=
"danger"
size=
"small"
@
click=
"removeComputeItem('resource',
index)"
>
删除
删除
</el-button>
</el-button>
</td>
</td>
...
@@ -109,13 +299,16 @@
...
@@ -109,13 +299,16 @@
</table>
</table>
<el-empty
v-else
description=
"暂无数据,请添加"
:image-size=
"80"
/>
<el-empty
v-else
description=
"暂无数据,请添加"
:image-size=
"80"
/>
</div>
</div>
</el-tab-pane>
</el-tabs>
</el-card>
</el-card>
</el-col>
</el-col>
</el-row>
</el-row>
<!-- 第
二行:算力资源分布 + 用户管理
-->
<!-- 第
三行:用户管理 + 服务能力
-->
<el-row
:gutter=
"20"
>
<el-row
:gutter=
"20"
>
<el-col
:span=
"12"
>
<el-col
:span=
"12"
>
<!-- 用户管理 -->
<!-- 算力资源分布 -->
<!-- 算力资源分布 -->
<el-card
class=
"config-card"
shadow=
"never"
>
<el-card
class=
"config-card"
shadow=
"never"
>
<
template
#
header
>
<
template
#
header
>
...
@@ -146,7 +339,7 @@
...
@@ -146,7 +339,7 @@
<el-input
v-model=
"item.name"
placeholder=
"如:4090"
size=
"small"
/>
<el-input
v-model=
"item.name"
placeholder=
"如:4090"
size=
"small"
/>
</td>
</td>
<td>
<td>
<el-input-number
v-model=
"item.value"
:precision=
"2"
:min=
"0"
size=
"small"
/>
<el-input-number
v-model=
"item.value"
:precision=
"2"
:min=
"0"
:controls=
"false"
size=
"small"
/>
</td>
</td>
<td>
<td>
<el-button
type=
"danger"
size=
"small"
@
click=
"removeComputeItem('gpu', index)"
>
<el-button
type=
"danger"
size=
"small"
@
click=
"removeComputeItem('gpu', index)"
>
...
@@ -180,7 +373,7 @@
...
@@ -180,7 +373,7 @@
<el-input
v-model=
"item.name"
placeholder=
"如:自有"
size=
"small"
/>
<el-input
v-model=
"item.name"
placeholder=
"如:自有"
size=
"small"
/>
</td>
</td>
<td>
<td>
<el-input-number
v-model=
"item.value"
:precision=
"2"
:min=
"0"
size=
"small"
/>
<el-input-number
v-model=
"item.value"
:precision=
"2"
:min=
"0"
:controls=
"false"
size=
"small"
/>
</td>
</td>
<td>
<td>
<el-button
type=
"danger"
size=
"small"
@
click=
"removeComputeItem('source', index)"
>
<el-button
type=
"danger"
size=
"small"
@
click=
"removeComputeItem('source', index)"
>
...
@@ -214,7 +407,7 @@
...
@@ -214,7 +407,7 @@
<el-input
v-model=
"item.name"
placeholder=
"如:裸金属"
size=
"small"
/>
<el-input
v-model=
"item.name"
placeholder=
"如:裸金属"
size=
"small"
/>
</td>
</td>
<td>
<td>
<el-input-number
v-model=
"item.value"
:precision=
"2"
:min=
"0"
size=
"small"
/>
<el-input-number
v-model=
"item.value"
:precision=
"2"
:min=
"0"
:controls=
"false"
size=
"small"
/>
</td>
</td>
<td>
<td>
<el-button
type=
"danger"
size=
"small"
@
click=
"removeComputeItem('resource', index)"
>
<el-button
type=
"danger"
size=
"small"
@
click=
"removeComputeItem('resource', index)"
>
...
@@ -241,11 +434,14 @@
...
@@ -241,11 +434,14 @@
<el-button
type=
"primary"
size=
"small"
@
click=
"saveUsers"
>
保存
</el-button>
<el-button
type=
"primary"
size=
"small"
@
click=
"saveUsers"
>
保存
</el-button>
</div>
</div>
</
template
>
</
template
>
<el-tabs
v-model=
"usersTab"
type=
"border-card"
>
<!-- 日维度 -->
<el-tab-pane
label=
"日"
name=
"d"
>
<div
class=
"table-section"
>
<div
class=
"table-section"
>
<el-button
type=
"primary"
size=
"small"
@
click=
"addUserItem
"
style=
"margin-bottom: 10px;"
>
<el-button
type=
"primary"
size=
"small"
@
click=
"addUserItem('d')
"
style=
"margin-bottom: 10px;"
>
<Icon
icon=
"ep:plus"
class=
"mr-5px"
/>
添加数据项
<Icon
icon=
"ep:plus"
class=
"mr-5px"
/>
添加数据项
</el-button>
</el-button>
<table
class=
"data-table"
v-if=
"usersList
.length > 0"
>
<table
class=
"data-table"
v-if=
"usersData.d && usersData.d
.length > 0"
>
<thead>
<thead>
<tr>
<tr>
<th>
日期
</th>
<th>
日期
</th>
...
@@ -256,7 +452,7 @@
...
@@ -256,7 +452,7 @@
</tr>
</tr>
</thead>
</thead>
<tbody>
<tbody>
<tr
v-for=
"(item, index) in usersList
"
:key=
"index"
>
<tr
v-for=
"(item, index) in usersData.d
"
:key=
"index"
>
<td>
<td>
<el-date-picker
<el-date-picker
v-model=
"item.countDate"
v-model=
"item.countDate"
...
@@ -268,16 +464,16 @@
...
@@ -268,16 +464,16 @@
/>
/>
</td>
</td>
<td>
<td>
<el-input-number
v-model=
"item.usersCount"
:min=
"0
"
size=
"small"
/>
<el-input-number
v-model=
"item.usersCount"
:min=
"0"
:controls=
"false
"
size=
"small"
/>
</td>
</td>
<td>
<td>
<el-input-number
v-model=
"item.growthUsersCount"
:min=
"0
"
size=
"small"
/>
<el-input-number
v-model=
"item.growthUsersCount"
:min=
"0"
:controls=
"false
"
size=
"small"
/>
</td>
</td>
<td>
<td>
<el-input-number
v-model=
"item.activeUsersCount"
:min=
"0
"
size=
"small"
/>
<el-input-number
v-model=
"item.activeUsersCount"
:min=
"0"
:controls=
"false
"
size=
"small"
/>
</td>
</td>
<td>
<td>
<el-button
type=
"danger"
size=
"small"
@
click=
"removeUserItem(
index)"
>
<el-button
type=
"danger"
size=
"small"
@
click=
"removeUserItem('d',
index)"
>
删除
删除
</el-button>
</el-button>
</td>
</td>
...
@@ -286,6 +482,99 @@
...
@@ -286,6 +482,99 @@
</table>
</table>
<el-empty
v-else
description=
"暂无数据,请添加"
:image-size=
"80"
/>
<el-empty
v-else
description=
"暂无数据,请添加"
:image-size=
"80"
/>
</div>
</div>
</el-tab-pane>
<!-- 月维度 -->
<el-tab-pane
label=
"月"
name=
"m"
>
<div
class=
"table-section"
>
<el-button
type=
"primary"
size=
"small"
@
click=
"addUserItem('m')"
style=
"margin-bottom: 10px;"
>
<Icon
icon=
"ep:plus"
class=
"mr-5px"
/>
添加数据项
</el-button>
<table
class=
"data-table"
v-if=
"usersData.m && usersData.m.length > 0"
>
<thead>
<tr>
<th>
日期
</th>
<th>
用户总数
</th>
<th>
增长用户数
</th>
<th>
活跃用户数
</th>
<th
style=
"width: 80px"
>
操作
</th>
</tr>
</thead>
<tbody>
<tr
v-for=
"(item, index) in usersData.m"
:key=
"index"
>
<td>
<el-date-picker
v-model=
"item.countDate"
type=
"month"
placeholder=
"选择月份"
format=
"YYYY-MM"
value-format=
"YYYY-MM"
size=
"small"
/>
</td>
<td>
<el-input-number
v-model=
"item.usersCount"
:min=
"0"
:controls=
"false"
size=
"small"
/>
</td>
<td>
<el-input-number
v-model=
"item.growthUsersCount"
:min=
"0"
:controls=
"false"
size=
"small"
/>
</td>
<td>
<el-input-number
v-model=
"item.activeUsersCount"
:min=
"0"
:controls=
"false"
size=
"small"
/>
</td>
<td>
<el-button
type=
"danger"
size=
"small"
@
click=
"removeUserItem('m', index)"
>
删除
</el-button>
</td>
</tr>
</tbody>
</table>
<el-empty
v-else
description=
"暂无数据,请添加"
:image-size=
"80"
/>
</div>
</el-tab-pane>
<!-- 年维度 -->
<el-tab-pane
label=
"年"
name=
"y"
>
<div
class=
"table-section"
>
<el-button
type=
"primary"
size=
"small"
@
click=
"addUserItem('y')"
style=
"margin-bottom: 10px;"
>
<Icon
icon=
"ep:plus"
class=
"mr-5px"
/>
添加数据项
</el-button>
<table
class=
"data-table"
v-if=
"usersData.y && usersData.y.length > 0"
>
<thead>
<tr>
<th>
年份
</th>
<th>
用户总数
</th>
<th>
增长用户数
</th>
<th>
活跃用户数
</th>
<th
style=
"width: 80px"
>
操作
</th>
</tr>
</thead>
<tbody>
<tr
v-for=
"(item, index) in usersData.y"
:key=
"index"
>
<td>
<el-input
v-model=
"item.countDate"
placeholder=
"如:2025"
size=
"small"
/>
</td>
<td>
<el-input-number
v-model=
"item.usersCount"
:min=
"0"
:controls=
"false"
size=
"small"
/>
</td>
<td>
<el-input-number
v-model=
"item.growthUsersCount"
:min=
"0"
:controls=
"false"
size=
"small"
/>
</td>
<td>
<el-input-number
v-model=
"item.activeUsersCount"
:min=
"0"
:controls=
"false"
size=
"small"
/>
</td>
<td>
<el-button
type=
"danger"
size=
"small"
@
click=
"removeUserItem('y', index)"
>
删除
</el-button>
</td>
</tr>
</tbody>
</table>
<el-empty
v-else
description=
"暂无数据,请添加"
:image-size=
"80"
/>
</div>
</el-tab-pane>
</el-tabs>
</el-card>
</el-card>
</el-col>
</el-col>
</el-row>
</el-row>
...
@@ -302,17 +591,40 @@
...
@@ -302,17 +591,40 @@
<el-button
type=
"primary"
size=
"small"
@
click=
"saveServiceCapability"
>
保存
</el-button>
<el-button
type=
"primary"
size=
"small"
@
click=
"saveServiceCapability"
>
保存
</el-button>
</div>
</div>
</
template
>
</
template
>
<el-form
:model=
"serviceCapability"
label-width=
"120px"
class=
"config-form"
>
<div
class=
"table-section"
>
<el-form-item
label=
"年份"
>
<el-button
type=
"primary"
size=
"small"
@
click=
"addServiceCapabilityItem"
style=
"margin-bottom: 10px;"
>
<el-input
v-model=
"serviceCapability.yearsStr"
placeholder=
"如:2018,2019,2020"
/>
<Icon
icon=
"ep:plus"
class=
"mr-5px"
/>
添加数据项
</el-form-item>
</el-button>
<el-form-item
label=
"上线应用"
>
<table
class=
"data-table"
v-if=
"serviceCapabilityList.length > 0"
>
<el-input
v-model=
"serviceCapability.appOnlineStr"
placeholder=
"如:10,20,30,40,50(逗号分隔)"
/>
<thead>
</el-form-item>
<tr>
<el-form-item
label=
"上线API"
>
<th>
年份
</th>
<el-input
v-model=
"serviceCapability.apiOnlineStr"
placeholder=
"如:100,200,300,400,500(逗号分隔)"
/>
<th>
上线应用数
</th>
</el-form-item>
<th>
上线API数
</th>
</el-form>
<th
style=
"width: 80px"
>
操作
</th>
</tr>
</thead>
<tbody>
<tr
v-for=
"(item, index) in serviceCapabilityList"
:key=
"index"
>
<td>
<el-input
v-model=
"item.year"
placeholder=
"如:2018"
size=
"small"
/>
</td>
<td>
<el-input-number
v-model=
"item.appOnline"
:min=
"0"
:controls=
"false"
size=
"small"
/>
</td>
<td>
<el-input-number
v-model=
"item.apiOnline"
:min=
"0"
:controls=
"false"
size=
"small"
/>
</td>
<td>
<el-button
type=
"danger"
size=
"small"
@
click=
"removeServiceCapabilityItem(index)"
>
删除
</el-button>
</td>
</tr>
</tbody>
</table>
<el-empty
v-else
description=
"暂无数据,请添加"
:image-size=
"80"
/>
</div>
</el-card>
</el-card>
</el-col>
</el-col>
...
@@ -357,16 +669,16 @@
...
@@ -357,16 +669,16 @@
/>
/>
</td>
</td>
<td>
<td>
<el-input-number
v-model=
"item.computeOrdersCount"
:min=
"0"
size=
"small"
/>
<el-input-number
v-model=
"item.computeOrdersCount"
:min=
"0"
:controls=
"false"
size=
"small"
/>
</td>
</td>
<td>
<td>
<el-input-number
v-model=
"item.apiOrdersCount"
:min=
"0"
size=
"small"
/>
<el-input-number
v-model=
"item.apiOrdersCount"
:min=
"0"
:controls=
"false"
size=
"small"
/>
</td>
</td>
<td>
<td>
<el-input-number
v-model=
"item.computeOrdersAmount"
:min=
"0"
size=
"small"
/>
<el-input-number
v-model=
"item.computeOrdersAmount"
:min=
"0"
:controls=
"false"
size=
"small"
/>
</td>
</td>
<td>
<td>
<el-input-number
v-model=
"item.apiOrdersAmount"
:min=
"0"
size=
"small"
/>
<el-input-number
v-model=
"item.apiOrdersAmount"
:min=
"0"
:controls=
"false"
size=
"small"
/>
</td>
</td>
<td>
<td>
<el-button
type=
"danger"
size=
"small"
@
click=
"removeOrderItem('d', index)"
>
<el-button
type=
"danger"
size=
"small"
@
click=
"removeOrderItem('d', index)"
>
...
@@ -410,16 +722,16 @@
...
@@ -410,16 +722,16 @@
/>
/>
</td>
</td>
<td>
<td>
<el-input-number
v-model=
"item.computeOrdersCount"
:min=
"0"
size=
"small"
/>
<el-input-number
v-model=
"item.computeOrdersCount"
:min=
"0"
:controls=
"false"
size=
"small"
/>
</td>
</td>
<td>
<td>
<el-input-number
v-model=
"item.apiOrdersCount"
:min=
"0"
size=
"small"
/>
<el-input-number
v-model=
"item.apiOrdersCount"
:min=
"0"
:controls=
"false"
size=
"small"
/>
</td>
</td>
<td>
<td>
<el-input-number
v-model=
"item.computeOrdersAmount"
:min=
"0"
size=
"small"
/>
<el-input-number
v-model=
"item.computeOrdersAmount"
:min=
"0"
:controls=
"false"
size=
"small"
/>
</td>
</td>
<td>
<td>
<el-input-number
v-model=
"item.apiOrdersAmount"
:min=
"0"
size=
"small"
/>
<el-input-number
v-model=
"item.apiOrdersAmount"
:min=
"0"
:controls=
"false"
size=
"small"
/>
</td>
</td>
<td>
<td>
<el-button
type=
"danger"
size=
"small"
@
click=
"removeOrderItem('m', index)"
>
<el-button
type=
"danger"
size=
"small"
@
click=
"removeOrderItem('m', index)"
>
...
@@ -456,16 +768,16 @@
...
@@ -456,16 +768,16 @@
<el-input
v-model=
"item.countDate"
placeholder=
"如:2025"
size=
"small"
/>
<el-input
v-model=
"item.countDate"
placeholder=
"如:2025"
size=
"small"
/>
</td>
</td>
<td>
<td>
<el-input-number
v-model=
"item.computeOrdersCount"
:min=
"0"
size=
"small"
/>
<el-input-number
v-model=
"item.computeOrdersCount"
:min=
"0"
:controls=
"false"
size=
"small"
/>
</td>
</td>
<td>
<td>
<el-input-number
v-model=
"item.apiOrdersCount"
:min=
"0"
size=
"small"
/>
<el-input-number
v-model=
"item.apiOrdersCount"
:min=
"0"
:controls=
"false"
size=
"small"
/>
</td>
</td>
<td>
<td>
<el-input-number
v-model=
"item.computeOrdersAmount"
:min=
"0"
size=
"small"
/>
<el-input-number
v-model=
"item.computeOrdersAmount"
:min=
"0"
:controls=
"false"
size=
"small"
/>
</td>
</td>
<td>
<td>
<el-input-number
v-model=
"item.apiOrdersAmount"
:min=
"0"
size=
"small"
/>
<el-input-number
v-model=
"item.apiOrdersAmount"
:min=
"0"
:controls=
"false"
size=
"small"
/>
</td>
</td>
<td>
<td>
<el-button
type=
"danger"
size=
"small"
@
click=
"removeOrderItem('y', index)"
>
<el-button
type=
"danger"
size=
"small"
@
click=
"removeOrderItem('y', index)"
>
...
@@ -485,7 +797,7 @@
...
@@ -485,7 +797,7 @@
<!-- 地图数据 -->
<!-- 地图数据 -->
<el-row
:gutter=
"20"
>
<el-row
:gutter=
"20"
>
<el-col
:span=
"
24
"
>
<el-col
:span=
"
12
"
>
<el-card
class=
"config-card"
shadow=
"never"
>
<el-card
class=
"config-card"
shadow=
"never"
>
<
template
#
header
>
<
template
#
header
>
<div
class=
"card-header"
>
<div
class=
"card-header"
>
...
@@ -514,7 +826,7 @@
...
@@ -514,7 +826,7 @@
</el-select>
</el-select>
</td>
</td>
<td>
<td>
<el-input-number
v-model=
"item.value"
:precision=
"4"
:min=
"0"
size=
"small"
/>
<el-input-number
v-model=
"item.value"
:precision=
"4"
:min=
"0"
:controls=
"false"
size=
"small"
/>
</td>
</td>
<td>
<td>
<el-button
type=
"danger"
size=
"small"
@
click=
"removeMapDataItem(index)"
>
<el-button
type=
"danger"
size=
"small"
@
click=
"removeMapDataItem(index)"
>
...
@@ -551,21 +863,27 @@ const overallSituation = ref({
...
@@ -551,21 +863,27 @@ const overallSituation = ref({
allCompute
:
432.58
,
allCompute
:
432.58
,
leaseCompute
:
139.94
,
leaseCompute
:
139.94
,
computeUtilizationRate
:
42.37
,
computeUtilizationRate
:
42.37
,
runningTaskCount
:
29
idleCompute
:
292.64
})
})
// API请求趋势
// API请求趋势
const
apiCallsList
=
ref
([])
const
apiCallsTab
=
ref
(
'd'
)
const
apiCallsData
=
ref
({
d
:
[],
m
:
[],
y
:
[]
})
// 用户管理
// 用户管理
const
usersList
=
ref
([])
const
usersTab
=
ref
(
'd'
)
const
usersData
=
ref
({
d
:
[],
m
:
[],
y
:
[]
})
// 服务能力
// 服务能力
const
serviceCapability
=
ref
({
const
serviceCapabilityList
=
ref
([])
yearsStr
:
''
,
appOnlineStr
:
''
,
apiOnlineStr
:
''
})
// 算力资源分布
// 算力资源分布
const
activeTab
=
ref
(
'gpu'
)
const
activeTab
=
ref
(
'gpu'
)
...
@@ -611,7 +929,9 @@ const loadAllMockData = async () => {
...
@@ -611,7 +929,9 @@ const loadAllMockData = async () => {
}
}
}
else
if
(
item
.
configKey
===
'mock_api_calls'
)
{
}
else
if
(
item
.
configKey
===
'mock_api_calls'
)
{
try
{
try
{
apiCallsList
.
value
=
JSON
.
parse
(
item
.
configValue
)
const
data
=
JSON
.
parse
(
item
.
configValue
)
// API请求趋势数据是对象格式,包含 d/m/y 三个维度
apiCallsData
.
value
=
data
}
catch
(
e
)
{
}
catch
(
e
)
{
console
.
error
(
'解析API请求趋势失败'
,
e
)
console
.
error
(
'解析API请求趋势失败'
,
e
)
}
}
...
@@ -623,18 +943,21 @@ const loadAllMockData = async () => {
...
@@ -623,18 +943,21 @@ const loadAllMockData = async () => {
}
}
}
else
if
(
item
.
configKey
===
'mock_users'
)
{
}
else
if
(
item
.
configKey
===
'mock_users'
)
{
try
{
try
{
usersList
.
value
=
JSON
.
parse
(
item
.
configValue
)
const
data
=
JSON
.
parse
(
item
.
configValue
)
// 用户管理数据是对象格式,包含 d/m/y 三个维度
usersData
.
value
=
data
}
catch
(
e
)
{
}
catch
(
e
)
{
console
.
error
(
'解析用户管理失败'
,
e
)
console
.
error
(
'解析用户管理失败'
,
e
)
}
}
}
else
if
(
item
.
configKey
===
'mock_service_capability'
)
{
}
else
if
(
item
.
configKey
===
'mock_service_capability'
)
{
try
{
try
{
const
data
=
JSON
.
parse
(
item
.
configValue
)
const
data
=
JSON
.
parse
(
item
.
configValue
)
serviceCapability
.
value
=
{
// 将原来分开的数组合并成表格行
yearsStr
:
data
.
years
?
data
.
years
.
join
(
','
)
:
''
,
serviceCapabilityList
.
value
=
(
data
.
years
||
[]).
map
((
year
,
index
)
=>
({
appOnlineStr
:
data
.
appOnline
?
data
.
appOnline
.
join
(
','
)
:
''
,
year
:
year
,
apiOnlineStr
:
data
.
apiOnline
?
data
.
apiOnline
.
join
(
','
)
:
''
appOnline
:
data
.
appOnline
?
data
.
appOnline
[
index
]
||
0
:
0
,
}
apiOnline
:
data
.
apiOnline
?
data
.
apiOnline
[
index
]
||
0
:
0
}))
}
catch
(
e
)
{
}
catch
(
e
)
{
console
.
error
(
'解析服务能力失败'
,
e
)
console
.
error
(
'解析服务能力失败'
,
e
)
}
}
...
@@ -701,7 +1024,7 @@ const saveApiCalls = async () => {
...
@@ -701,7 +1024,7 @@ const saveApiCalls = async () => {
if
(
res
&&
res
.
list
)
{
if
(
res
&&
res
.
list
)
{
const
config
=
res
.
list
.
find
(
item
=>
item
.
configKey
===
'mock_api_calls'
)
const
config
=
res
.
list
.
find
(
item
=>
item
.
configKey
===
'mock_api_calls'
)
if
(
config
)
{
if
(
config
)
{
const
updateData
=
{
...
config
,
configValue
:
JSON
.
stringify
(
apiCalls
List
.
value
)
}
const
updateData
=
{
...
config
,
configValue
:
JSON
.
stringify
(
apiCalls
Data
.
value
)
}
await
HomeDashboardMockApi
.
updateHomeDashboardMock
(
updateData
)
await
HomeDashboardMockApi
.
updateHomeDashboardMock
(
updateData
)
message
.
success
(
'保存成功'
)
message
.
success
(
'保存成功'
)
}
}
...
@@ -712,17 +1035,20 @@ const saveApiCalls = async () => {
...
@@ -712,17 +1035,20 @@ const saveApiCalls = async () => {
}
}
}
}
// 添加API请求数据项
// API请求趋势 - 添加数据项
const
addApiCallItem
=
()
=>
{
const
addApiCallItem
=
(
type
:
'd'
|
'm'
|
'y'
)
=>
{
apiCallsList
.
value
.
push
({
if
(
!
apiCallsData
.
value
[
type
])
{
apiCallsData
.
value
[
type
]
=
[]
}
apiCallsData
.
value
[
type
].
push
({
countDate
:
''
,
countDate
:
''
,
callsCount
:
0
callsCount
:
0
})
})
}
}
//
删除API请求
数据项
//
API请求趋势 - 删除
数据项
const
removeApiCallItem
=
(
index
:
number
)
=>
{
const
removeApiCallItem
=
(
type
:
'd'
|
'm'
|
'y'
,
index
:
number
)
=>
{
apiCalls
List
.
value
.
splice
(
index
,
1
)
apiCalls
Data
.
value
[
type
]
.
splice
(
index
,
1
)
}
}
// 保存算力资源分布
// 保存算力资源分布
...
@@ -766,7 +1092,7 @@ const saveUsers = async () => {
...
@@ -766,7 +1092,7 @@ const saveUsers = async () => {
if
(
res
&&
res
.
list
)
{
if
(
res
&&
res
.
list
)
{
const
config
=
res
.
list
.
find
(
item
=>
item
.
configKey
===
'mock_users'
)
const
config
=
res
.
list
.
find
(
item
=>
item
.
configKey
===
'mock_users'
)
if
(
config
)
{
if
(
config
)
{
const
updateData
=
{
...
config
,
configValue
:
JSON
.
stringify
(
users
List
.
value
)
}
const
updateData
=
{
...
config
,
configValue
:
JSON
.
stringify
(
users
Data
.
value
)
}
await
HomeDashboardMockApi
.
updateHomeDashboardMock
(
updateData
)
await
HomeDashboardMockApi
.
updateHomeDashboardMock
(
updateData
)
message
.
success
(
'保存成功'
)
message
.
success
(
'保存成功'
)
}
}
...
@@ -777,9 +1103,12 @@ const saveUsers = async () => {
...
@@ -777,9 +1103,12 @@ const saveUsers = async () => {
}
}
}
}
// 添加用户数据项
// 用户管理 - 添加数据项
const
addUserItem
=
()
=>
{
const
addUserItem
=
(
type
:
'd'
|
'm'
|
'y'
)
=>
{
usersList
.
value
.
push
({
if
(
!
usersData
.
value
[
type
])
{
usersData
.
value
[
type
]
=
[]
}
usersData
.
value
[
type
].
push
({
countDate
:
''
,
countDate
:
''
,
usersCount
:
0
,
usersCount
:
0
,
growthUsersCount
:
0
,
growthUsersCount
:
0
,
...
@@ -787,9 +1116,9 @@ const addUserItem = () => {
...
@@ -787,9 +1116,9 @@ const addUserItem = () => {
})
})
}
}
//
删除用户
数据项
//
用户管理 - 删除
数据项
const
removeUserItem
=
(
index
:
number
)
=>
{
const
removeUserItem
=
(
type
:
'd'
|
'm'
|
'y'
,
index
:
number
)
=>
{
users
List
.
value
.
splice
(
index
,
1
)
users
Data
.
value
[
type
]
.
splice
(
index
,
1
)
}
}
// 保存服务能力
// 保存服务能力
...
@@ -798,10 +1127,11 @@ const saveServiceCapability = async () => {
...
@@ -798,10 +1127,11 @@ const saveServiceCapability = async () => {
const
res
=
await
HomeDashboardMockApi
.
getHomeDashboardMockPage
({
pageNo
:
1
,
pageSize
:
100
})
const
res
=
await
HomeDashboardMockApi
.
getHomeDashboardMockPage
({
pageNo
:
1
,
pageSize
:
100
})
if
(
res
&&
res
.
list
)
{
if
(
res
&&
res
.
list
)
{
const
config
=
res
.
list
.
find
(
item
=>
item
.
configKey
===
'mock_service_capability'
)
const
config
=
res
.
list
.
find
(
item
=>
item
.
configKey
===
'mock_service_capability'
)
// 将表格数据转换成原来的格式(分开的数组)
const
data
=
{
const
data
=
{
years
:
serviceCapability
.
value
.
yearsStr
.
split
(
','
).
map
(
s
=>
s
.
trim
()
),
years
:
serviceCapability
List
.
value
.
map
(
item
=>
item
.
year
),
appOnline
:
serviceCapability
.
value
.
appOnlineStr
.
split
(
','
).
map
(
s
=>
parseFloat
(
s
.
trim
())
||
0
),
appOnline
:
serviceCapability
List
.
value
.
map
(
item
=>
item
.
appOnline
),
apiOnline
:
serviceCapability
.
value
.
apiOnlineStr
.
split
(
','
).
map
(
s
=>
parseFloat
(
s
.
trim
())
||
0
)
apiOnline
:
serviceCapability
List
.
value
.
map
(
item
=>
item
.
apiOnline
)
}
}
if
(
config
)
{
if
(
config
)
{
const
updateData
=
{
...
config
,
configValue
:
JSON
.
stringify
(
data
)
}
const
updateData
=
{
...
config
,
configValue
:
JSON
.
stringify
(
data
)
}
...
@@ -823,6 +1153,20 @@ const saveServiceCapability = async () => {
...
@@ -823,6 +1153,20 @@ const saveServiceCapability = async () => {
}
}
}
}
// 服务能力 - 添加数据项
const
addServiceCapabilityItem
=
()
=>
{
serviceCapabilityList
.
value
.
push
({
year
:
''
,
appOnline
:
0
,
apiOnline
:
0
})
}
// 服务能力 - 删除数据项
const
removeServiceCapabilityItem
=
(
index
:
number
)
=>
{
serviceCapabilityList
.
value
.
splice
(
index
,
1
)
}
// 订单管理 - 保存
// 订单管理 - 保存
const
saveOrders
=
async
()
=>
{
const
saveOrders
=
async
()
=>
{
try
{
try
{
...
...
src/views/compute/resourcespu/form/index.vue
View file @
1fe9a380
...
@@ -130,15 +130,30 @@
...
@@ -130,15 +130,30 @@
<!-- 5. 服务器信息 -->
<!-- 5. 服务器信息 -->
<div
style=
"display: flex; margin-bottom: 24px;"
>
<div
style=
"display: flex; margin-bottom: 24px;"
>
<el-form-item
label=
"服务器所在地"
prop=
"location"
style=
"margin-right: 20px; margin-bottom: 0;"
>
<el-form-item
label=
"选择地区"
prop=
"areaId"
style=
"margin-bottom: 0;"
>
<el-select
v-model=
"formData.location"
placeholder=
"请选择服务器所在地"
clearable
style=
"width: 180px;"
:disabled=
"isDetailMode"
>
<el-cascader
<el-option
v-if=
"areaList.length > 0"
v-for=
"option in resourceConfigStore.getOptionsByType('location')"
v-model=
"formData.areaId"
:key=
"option.id"
:options=
"areaList"
:label=
"option.configOption"
:props=
"
{
:value=
"option.configOption"
value: 'id',
label: 'name',
children: 'children',
expandTrigger: 'click'
}"
placeholder="请选择省市区"
clearable
filterable
style="width: 300px;"
:disabled="isDetailMode"
@change="handleAreaChange"
/>
/>
</el-select>
<el-text
v-else
type=
"info"
>
加载中...
</el-text>
</el-form-item>
</div>
<div
style=
"display: flex; margin-bottom: 24px;"
>
<el-form-item
label=
"服务器所在地"
prop=
"location"
style=
"margin-right: 20px; margin-bottom: 0;"
>
<el-input
v-model=
"formData.location"
placeholder=
"选择地区后自动显示"
style=
"width: 180px;"
disabled
/>
</el-form-item>
</el-form-item>
<el-form-item
label=
"服务器IP"
prop=
"ip"
style=
"margin-bottom: 0;"
>
<el-form-item
label=
"服务器IP"
prop=
"ip"
style=
"margin-bottom: 0;"
>
<el-input
v-model=
"formData.ip"
placeholder=
"请输入服务器IP"
style=
"width: 180px;"
:disabled=
"isDetailMode"
/>
<el-input
v-model=
"formData.ip"
placeholder=
"请输入服务器IP"
style=
"width: 180px;"
:disabled=
"isDetailMode"
/>
...
@@ -217,6 +232,7 @@ import { UploadImg } from '@/components/UploadFile'
...
@@ -217,6 +232,7 @@ import { UploadImg } from '@/components/UploadFile'
import
{
useTagsViewStore
}
from
'@/store/modules/tagsView'
import
{
useTagsViewStore
}
from
'@/store/modules/tagsView'
import
{
useResourceConfigStore
}
from
'@/store/modules/compute/hardwareConfig'
import
{
useResourceConfigStore
}
from
'@/store/modules/compute/hardwareConfig'
import
{
ResourceSpu
,
ResourceSpuApi
}
from
'@/api/compute/resourcespu'
import
{
ResourceSpu
,
ResourceSpuApi
}
from
'@/api/compute/resourcespu'
import
*
as
AreaApi
from
'@/api/system/area'
defineOptions
({
name
:
'ResourceSpuAdd'
})
defineOptions
({
name
:
'ResourceSpuAdd'
})
...
@@ -239,6 +255,7 @@ const resourceConfigStore = useResourceConfigStore() // 资源配置store
...
@@ -239,6 +255,7 @@ const resourceConfigStore = useResourceConfigStore() // 资源配置store
const
formLoading
=
ref
(
false
)
// 表单的加载中
const
formLoading
=
ref
(
false
)
// 表单的加载中
const
formRef
=
ref
()
// 表单 Ref
const
formRef
=
ref
()
// 表单 Ref
const
categoryList
=
ref
<
any
[]
>
([])
const
categoryList
=
ref
<
any
[]
>
([])
const
areaList
=
ref
<
any
[]
>
([])
// 地区树数据
// 从store获取硬件配置选项
// 从store获取硬件配置选项
const
cpuOptions
=
computed
(()
=>
resourceConfigStore
.
getOptionsByType
(
'cpu'
))
const
cpuOptions
=
computed
(()
=>
resourceConfigStore
.
getOptionsByType
(
'cpu'
))
...
@@ -271,6 +288,7 @@ const formData = ref<ResourceSpu>({
...
@@ -271,6 +288,7 @@ const formData = ref<ResourceSpu>({
memoryCapacity
:
undefined
,
memoryCapacity
:
undefined
,
sales
:
undefined
,
sales
:
undefined
,
location
:
undefined
,
location
:
undefined
,
areaId
:
undefined
,
status
:
undefined
status
:
undefined
})
})
...
@@ -292,10 +310,41 @@ const formRules = reactive({
...
@@ -292,10 +310,41 @@ const formRules = reactive({
categoryId
:
[{
required
:
true
,
message
:
'算力资源分类编号不能为空'
,
trigger
:
'blur'
}],
categoryId
:
[{
required
:
true
,
message
:
'算力资源分类编号不能为空'
,
trigger
:
'blur'
}],
picUrl
:
[{
required
:
true
,
message
:
'商品封面图不能为空'
,
trigger
:
'blur'
}],
picUrl
:
[{
required
:
true
,
message
:
'商品封面图不能为空'
,
trigger
:
'blur'
}],
sales
:
[{
required
:
true
,
message
:
'商品销量不能为空'
,
trigger
:
'blur'
}],
sales
:
[{
required
:
true
,
message
:
'商品销量不能为空'
,
trigger
:
'blur'
}],
location
:
[{
required
:
true
,
message
:
'服务器所在地不能为空'
,
trigger
:
'blur'
}],
areaId
:
[{
required
:
true
,
message
:
'服务器所在地不能为空'
,
trigger
:
'blur'
}],
status
:
[{
required
:
true
,
message
:
'状态不能为空'
,
trigger
:
'blur'
}]
status
:
[{
required
:
true
,
message
:
'状态不能为空'
,
trigger
:
'blur'
}]
})
})
/** 地区选择变化时,自动设置 location 为市级名称(第二级) */
const
handleAreaChange
=
(
value
:
number
[])
=>
{
if
(
!
value
||
value
.
length
===
0
)
{
formData
.
value
.
location
=
undefined
formData
.
value
.
areaId
=
undefined
return
}
// el-cascader 返回的是数组 [省级id, 市级id, 区县级id]
// 取区县级id(最后一个元素)作为 areaId 的值
const
districtId
=
value
[
value
.
length
-
1
]
formData
.
value
.
areaId
=
districtId
// 获取市级id(第二个元素)
const
cityId
=
value
[
1
]
// 查找市级名称
const
findCityName
=
(
list
:
any
[],
cityId
:
number
):
string
|
null
=>
{
for
(
const
item
of
list
)
{
if
(
item
.
children
)
{
for
(
const
city
of
item
.
children
)
{
if
(
city
.
id
===
cityId
)
{
return
city
.
name
}
}
}
}
return
null
}
formData
.
value
.
location
=
findCityName
(
areaList
.
value
,
cityId
)
||
undefined
}
/** 提交表单 */
/** 提交表单 */
const
emit
=
defineEmits
([
'success'
])
// 定义 success 事件,用于操作成功后的回调
const
emit
=
defineEmits
([
'success'
])
// 定义 success 事件,用于操作成功后的回调
...
@@ -330,12 +379,14 @@ const close = () => {
...
@@ -330,12 +379,14 @@ const close = () => {
/** 初始化 */
/** 初始化 */
onMounted
(
async
()
=>
{
onMounted
(
async
()
=>
{
try
{
try
{
// 并行加载分类列表
和硬件配置选项
// 并行加载分类列表
、硬件配置选项和地区树
const
[
categoryResponse
]
=
await
Promise
.
all
([
const
[
categoryResponse
,
_
,
areaResponse
]
=
await
Promise
.
all
([
ResourceSpuApi
.
listSimpleCategory
(),
ResourceSpuApi
.
listSimpleCategory
(),
resourceConfigStore
.
loadConfigOptions
()
resourceConfigStore
.
loadConfigOptions
(),
AreaApi
.
getAreaTree
()
])
])
categoryList
.
value
=
categoryResponse
categoryList
.
value
=
categoryResponse
areaList
.
value
=
areaResponse
// 编辑模式或详情模式需要获取数据
// 编辑模式或详情模式需要获取数据
if
(
isEditMode
.
value
||
isDetailMode
.
value
)
{
if
(
isEditMode
.
value
||
isDetailMode
.
value
)
{
...
...
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