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
e924edf5
authored
Oct 01, 2025
by
Jony.L
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
算力资源重构-算力资源SPU管理、资源配置管理修改
parent
c6d675ba
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
846 additions
and
124 deletions
+846
-124
src/api/compute/resourcecategory/index.ts
+1
-3
src/api/compute/resourceconfig/index.ts
+56
-0
src/api/compute/resourcespu/index.ts
+5
-4
src/utils/dict.ts
+5
-0
src/views/compute/resourcecategory/ResourceCategoryForm.vue
+2
-2
src/views/compute/resourcecategory/index.vue
+4
-4
src/views/compute/resourceconfig/ResourceConfigForm.vue
+137
-0
src/views/compute/resourceconfig/index.vue
+273
-0
src/views/compute/resourcespu/ResourceSpuForm.vue
+290
-69
src/views/compute/resourcespu/index.vue
+73
-42
No files found.
src/api/compute/resourcecategory/index.ts
View file @
e924edf5
import
request
from
'@/config/axios'
import
type
{
Dayjs
}
from
'dayjs'
;
/** 算力资源分类表(仅用于算力服务器分类)信息 */
export
interface
ResourceCategory
{
...
...
@@ -46,4 +45,4 @@ export const ResourceCategoryApi = {
exportResourceCategory
:
async
(
params
)
=>
{
return
await
request
.
download
({
url
:
`/compute/resource-category/export-excel`
,
params
})
}
}
\ No newline at end of file
}
src/api/compute/resourceconfig/index.ts
0 → 100644
View file @
e924edf5
import
request
from
'@/config/axios'
import
type
{
Dayjs
}
from
'dayjs'
;
/** 算力资源配置信息 */
export
interface
ResourceConfig
{
id
:
number
;
// 主键ID
configCategory
?:
string
;
// 配置类别
configOption
?:
string
;
// 配置选项
sort
:
number
;
// 排序
status
?:
number
;
// 状态:0=启用,1=禁用
detailRemark
:
string
;
// 详情备注(如:i7-13700K 16核24线程)
}
// 算力资源配置 API
export
const
ResourceConfigApi
=
{
// 查询算力资源配置分页
getResourceConfigPage
:
async
(
params
:
any
)
=>
{
return
await
request
.
get
({
url
:
`/compute/resource-config/page`
,
params
})
},
// 查询算力资源配置详情
getResourceConfig
:
async
(
id
:
number
)
=>
{
return
await
request
.
get
({
url
:
`/compute/resource-config/get?id=`
+
id
})
},
// 新增算力资源配置
createResourceConfig
:
async
(
data
:
ResourceConfig
)
=>
{
return
await
request
.
post
({
url
:
`/compute/resource-config/create`
,
data
})
},
// 修改算力资源配置
updateResourceConfig
:
async
(
data
:
ResourceConfig
)
=>
{
return
await
request
.
put
({
url
:
`/compute/resource-config/update`
,
data
})
},
// 删除算力资源配置
deleteResourceConfig
:
async
(
id
:
number
)
=>
{
return
await
request
.
delete
({
url
:
`/compute/resource-config/delete?id=`
+
id
})
},
/** 批量删除算力资源配置 */
deleteResourceConfigList
:
async
(
ids
:
number
[])
=>
{
return
await
request
.
delete
({
url
:
`/compute/resource-config/delete-list?ids=
${
ids
.
join
(
','
)}
`
})
},
// 导出算力资源配置 Excel
exportResourceConfig
:
async
(
params
)
=>
{
return
await
request
.
download
({
url
:
`/compute/resource-config/export-excel`
,
params
})
},
// 根据类别获取精简配置选项列表
listSimpleConfigByCategory
:
async
(
category
:
string
)
=>
{
return
await
request
.
get
({
url
:
`/compute/resource-config/list-simple-config-by-category?category=
${
category
}
`
})
}
}
\ No newline at end of file
src/api/compute/resourcespu/index.ts
View file @
e924edf5
import
request
from
'@/config/axios'
import
type
{
Dayjs
}
from
'dayjs'
;
/** 算力资源SPU表(基础配置信息)信息 */
export
interface
ResourceSpu
{
...
...
@@ -27,7 +26,10 @@ export const ResourceSpuApi = {
getResourceSpuPage
:
async
(
params
:
any
)
=>
{
return
await
request
.
get
({
url
:
`/compute/resource-spu/page`
,
params
})
},
//查询精简算力资源分类列表
listSimpleCategory
:
async
()
=>
{
return
await
request
.
get
({
url
:
`/compute/resource-category/list-simple`
})
},
// 查询算力资源SPU表(基础配置信息)详情
getResourceSpu
:
async
(
id
:
number
)
=>
{
return
await
request
.
get
({
url
:
`/compute/resource-spu/get?id=`
+
id
})
...
...
@@ -57,4 +59,4 @@ export const ResourceSpuApi = {
exportResourceSpu
:
async
(
params
)
=>
{
return
await
request
.
download
({
url
:
`/compute/resource-spu/export-excel`
,
params
})
}
}
\ No newline at end of file
}
src/utils/dict.ts
View file @
e924edf5
...
...
@@ -110,6 +110,7 @@ export const getDictLabel = (dictType: string, value: any): string => {
export
enum
DICT_TYPE
{
USER_TYPE
=
'user_type'
,
COMMON_STATUS
=
'common_status'
,
COMMON_ENABLE_DISABLE
=
'common_enable_disable'
,
TERMINAL
=
'terminal'
,
// 终端
DATE_INTERVAL
=
'date_interval'
,
// 数据间隔
...
...
@@ -173,6 +174,10 @@ export enum DICT_TYPE {
MEMBER_EXPERIENCE_BIZ_TYPE
=
'member_experience_biz_type'
,
// 会员经验业务类型
CHECK_STATUS
=
'check_status'
,
// 客户企业管理审核
// ==========Compute 算力资源模块========
COMPUTE_RESOURCE_SPU_STATUS
=
'compute_resource_spu_status'
,
COMPUTE_RESOURCE_CONFIG_CATEGORY
=
'compute_resource_config_category'
,
// ========== MALL - 商品模块 ==========
PRODUCT_SPU_STATUS
=
'product_spu_status'
,
//商品状态
...
...
src/views/compute/resourcecategory/ResourceCategoryForm.vue
View file @
e924edf5
...
...
@@ -15,12 +15,12 @@
<div
style=
"font-size: 10px"
class=
"pl-10px"
>
推荐 180x180 图片分辨率
</div>
</el-form-item>
<el-form-item
label=
"分类排序"
prop=
"sort"
>
<el-input
v-model=
"formData.sort"
placeholder=
"请输入分类排序
"
/>
<el-input
-number
v-model=
"formData.sort"
controls-position=
"right"
:min=
"0
"
/>
</el-form-item>
<el-form-item
label=
"开启状态"
prop=
"status"
>
<el-radio-group
v-model=
"formData.status"
>
<el-radio
v-for=
"dict in getIntDictOptions(DICT_TYPE.COMMON_
STATUS
)"
v-for=
"dict in getIntDictOptions(DICT_TYPE.COMMON_
ENABLE_DISABLE
)"
:key=
"dict.value"
:value=
"dict.value"
>
...
...
src/views/compute/resourcecategory/index.vue
View file @
e924edf5
...
...
@@ -115,7 +115,7 @@
<el-table-column
label=
"分类排序"
align=
"center"
prop=
"sort"
/>
<el-table-column
label=
"状态"
align=
"center"
min-width=
"150"
prop=
"status"
>
<
template
#
default=
"scope"
>
<dict-tag
:type=
"DICT_TYPE.COMMON_
STATUS
"
:value=
"scope.row.status"
/>
<dict-tag
:type=
"DICT_TYPE.COMMON_
ENABLE_DISABLE
"
:value=
"scope.row.status"
/>
</
template
>
</el-table-column>
<el-table-column
...
...
@@ -165,7 +165,7 @@ import { dateFormatter } from '@/utils/formatTime'
import
download
from
'@/utils/download'
import
{
ResourceCategoryApi
,
ResourceCategory
}
from
'@/api/compute/resourcecategory'
import
ResourceCategoryForm
from
'./ResourceCategoryForm.vue'
import
{
DICT_TYPE
,
getIntDictOptions
}
from
"@/utils/dict"
;
import
{
DICT_TYPE
,
getIntDictOptions
,
getStrDictOptions
}
from
"@/utils/dict"
;
/** 算力资源分类表(仅用于算力服务器分类) 列表 */
defineOptions
({
name
:
'ResourceCategory'
})
...
...
@@ -188,8 +188,8 @@ const queryParams = reactive({
const
queryFormRef
=
ref
()
// 搜索的表单
const
exportLoading
=
ref
(
false
)
// 导出的加载中
//
3. 调用方法获取数字字典(替换 'sys_status' 为你的实际字典类型)
const
statusOptions
=
get
IntDictOptions
(
DICT_TYPE
.
COMMON_STATUS
);
//
调用方法获取数字字典
const
statusOptions
=
get
StrDictOptions
(
DICT_TYPE
.
COMMON_ENABLE_DISABLE
);
/** 查询列表 */
const
getList
=
async
()
=>
{
...
...
src/views/compute/resourceconfig/ResourceConfigForm.vue
0 → 100644
View file @
e924edf5
<
template
>
<Dialog
:title=
"dialogTitle"
v-model=
"dialogVisible"
>
<el-form
ref=
"formRef"
:model=
"formData"
:rules=
"formRules"
label-width=
"100px"
v-loading=
"formLoading"
>
<el-form-item
label=
"配置类别"
prop=
"configCategory"
>
<!--
<el-input
v-model=
"formData.configCategory"
placeholder=
"请输入配置类别"
/>
-->
<el-select
v-model=
"formData.configCategory"
placeholder=
"请选择状态"
clearable
class=
"!w-240px"
>
<el-option
v-for=
"dict in categoryOptions"
:key=
"dict.value"
:label=
"dict.label"
:value=
"dict.value"
/>
</el-select>
</el-form-item>
<el-form-item
label=
"配置选项"
prop=
"configOption"
>
<el-input
v-model=
"formData.configOption"
placeholder=
"请输入配置选项"
/>
</el-form-item>
<el-form-item
label=
"排序"
prop=
"sort"
>
<el-input-number
v-model=
"formData.sort"
controls-position=
"right"
:min=
"0"
/>
</el-form-item>
<el-form-item
label=
"状态"
prop=
"status"
>
<el-radio
v-model=
"formData.status"
v-for=
"dict in getIntDictOptions(DICT_TYPE.COMMON_STATUS)"
:key=
"dict.value"
:value=
"dict.value"
>
{{
dict
.
label
}}
</el-radio>
</el-form-item>
<el-form-item
label=
"详情备注"
prop=
"detailRemark"
>
<el-input
v-model=
"formData.detailRemark"
placeholder=
"请输入详情备注"
/>
</el-form-item>
</el-form>
<template
#
footer
>
<el-button
@
click=
"submitForm"
type=
"primary"
:disabled=
"formLoading"
>
确 定
</el-button>
<el-button
@
click=
"dialogVisible = false"
>
取 消
</el-button>
</
template
>
</Dialog>
</template>
<
script
setup
lang=
"ts"
>
import
{
ResourceConfig
,
ResourceConfigApi
}
from
'@/api/compute/resourceconfig'
import
{
DICT_TYPE
,
getIntDictOptions
,
getStrDictOptions
}
from
"@/utils/dict"
;
/** 算力资源配置 表单 */
defineOptions
({
name
:
'ResourceConfigForm'
})
const
{
t
}
=
useI18n
()
// 国际化
const
message
=
useMessage
()
// 消息弹窗
const
categoryOptions
=
getStrDictOptions
(
DICT_TYPE
.
COMPUTE_RESOURCE_CONFIG_CATEGORY
);
const
dialogVisible
=
ref
(
false
)
// 弹窗的是否展示
const
dialogTitle
=
ref
(
''
)
// 弹窗的标题
const
formLoading
=
ref
(
false
)
// 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
const
formType
=
ref
(
''
)
// 表单的类型:create - 新增;update - 修改
const
formData
=
ref
({
id
:
undefined
,
configCategory
:
undefined
,
configOption
:
undefined
,
sort
:
undefined
,
status
:
undefined
,
detailRemark
:
undefined
})
const
formRules
=
reactive
({
configCategory
:
[{
required
:
true
,
message
:
'配置类别不能为空'
,
trigger
:
'blur'
}],
configOption
:
[{
required
:
true
,
message
:
'配置选项不能为空'
,
trigger
:
'blur'
}],
status
:
[{
required
:
true
,
message
:
'状态:0=启用,1=禁用不能为空'
,
trigger
:
'blur'
}]
})
const
formRef
=
ref
()
// 表单 Ref
/** 打开弹窗 */
const
open
=
async
(
type
:
string
,
id
?:
number
)
=>
{
dialogVisible
.
value
=
true
dialogTitle
.
value
=
t
(
'action.'
+
type
)
formType
.
value
=
type
resetForm
()
// 修改时,设置数据
if
(
id
)
{
formLoading
.
value
=
true
try
{
formData
.
value
=
await
ResourceConfigApi
.
getResourceConfig
(
id
)
}
finally
{
formLoading
.
value
=
false
}
}
}
defineExpose
({
open
})
// 提供 open 方法,用于打开弹窗
/** 提交表单 */
const
emit
=
defineEmits
([
'success'
])
// 定义 success 事件,用于操作成功后的回调
const
submitForm
=
async
()
=>
{
// 校验表单
await
formRef
.
value
.
validate
()
// 提交请求
formLoading
.
value
=
true
try
{
const
data
=
formData
.
value
as
unknown
as
ResourceConfig
if
(
formType
.
value
===
'create'
)
{
await
ResourceConfigApi
.
createResourceConfig
(
data
)
message
.
success
(
t
(
'common.createSuccess'
))
}
else
{
await
ResourceConfigApi
.
updateResourceConfig
(
data
)
message
.
success
(
t
(
'common.updateSuccess'
))
}
dialogVisible
.
value
=
false
// 发送操作成功的事件
emit
(
'success'
)
}
finally
{
formLoading
.
value
=
false
}
}
/** 重置表单 */
const
resetForm
=
()
=>
{
formData
.
value
=
{
id
:
undefined
,
configCategory
:
undefined
,
configOption
:
undefined
,
sort
:
undefined
,
status
:
undefined
,
detailRemark
:
undefined
}
formRef
.
value
?.
resetFields
()
}
</
script
>
src/views/compute/resourceconfig/index.vue
0 → 100644
View file @
e924edf5
<
template
>
<ContentWrap>
<!-- 搜索工作栏 -->
<el-form
class=
"-mb-15px"
:model=
"queryParams"
ref=
"queryFormRef"
:inline=
"true"
label-width=
"68px"
>
<el-form-item
label=
"配置类别"
prop=
"configCategory"
>
<el-input
v-model=
"queryParams.configCategory"
placeholder=
"请输入配置类别"
clearable
@
keyup
.
enter=
"handleQuery"
class=
"!w-240px"
/>
</el-form-item>
<el-form-item
label=
"配置选项"
prop=
"configOption"
>
<el-input
v-model=
"queryParams.configOption"
placeholder=
"请输入配置选项"
clearable
@
keyup
.
enter=
"handleQuery"
class=
"!w-240px"
/>
</el-form-item>
<el-form-item
label=
"排序"
prop=
"sort"
>
<el-input
v-model=
"queryParams.sort"
placeholder=
"请输入排序"
clearable
@
keyup
.
enter=
"handleQuery"
class=
"!w-240px"
/>
</el-form-item>
<el-form-item
label=
"状态"
prop=
"status"
>
<el-select
v-model=
"queryParams.status"
placeholder=
"请选择状态"
clearable
class=
"!w-240px"
>
<el-option
v-for=
"dict in statusOptions"
:key=
"dict.value"
:label=
"dict.label"
:value=
"dict.value"
/>
</el-select>
</el-form-item>
<el-form-item
label=
"详情备注"
prop=
"detailRemark"
>
<el-input
v-model=
"queryParams.detailRemark"
placeholder=
"请输入详情备注"
clearable
@
keyup
.
enter=
"handleQuery"
class=
"!w-240px"
/>
</el-form-item>
<el-form-item
label=
"创建时间"
prop=
"createTime"
>
<el-date-picker
v-model=
"queryParams.createTime"
value-format=
"YYYY-MM-DD HH:mm:ss"
type=
"daterange"
start-placeholder=
"开始日期"
end-placeholder=
"结束日期"
:default-time=
"[new Date('1 00:00:00'), new Date('1 23:59:59')]"
class=
"!w-220px"
/>
</el-form-item>
<el-form-item>
<el-button
@
click=
"handleQuery"
><Icon
icon=
"ep:search"
class=
"mr-5px"
/>
搜索
</el-button>
<el-button
@
click=
"resetQuery"
><Icon
icon=
"ep:refresh"
class=
"mr-5px"
/>
重置
</el-button>
<el-button
type=
"primary"
plain
@
click=
"openForm('create')"
v-hasPermi=
"['compute:resource-config:create']"
>
<Icon
icon=
"ep:plus"
class=
"mr-5px"
/>
新增
</el-button>
<el-button
type=
"success"
plain
@
click=
"handleExport"
:loading=
"exportLoading"
v-hasPermi=
"['compute:resource-config:export']"
>
<Icon
icon=
"ep:download"
class=
"mr-5px"
/>
导出
</el-button>
<el-button
type=
"danger"
plain
:disabled=
"isEmpty(checkedIds)"
@
click=
"handleDeleteBatch"
v-hasPermi=
"['compute:resource-config:delete']"
>
<Icon
icon=
"ep:delete"
class=
"mr-5px"
/>
批量删除
</el-button>
</el-form-item>
</el-form>
</ContentWrap>
<!-- 列表 -->
<ContentWrap>
<el-table
row-key=
"id"
v-loading=
"loading"
:data=
"list"
:stripe=
"true"
:show-overflow-tooltip=
"true"
@
selection-change=
"handleRowCheckboxChange"
>
<el-table-column
type=
"selection"
width=
"55"
/>
<el-table-column
label=
"主键ID"
align=
"center"
prop=
"id"
/>
<el-table-column
label=
"配置类别"
align=
"center"
prop=
"configCategory"
/>
<el-table-column
label=
"配置选项"
align=
"center"
prop=
"configOption"
/>
<el-table-column
label=
"排序"
align=
"center"
prop=
"sort"
/>
<el-table-column
label=
"状态"
align=
"center"
prop=
"status"
/>
<el-table-column
label=
"详情备注"
align=
"center"
prop=
"detailRemark"
/>
<el-table-column
label=
"创建时间"
align=
"center"
prop=
"createTime"
:formatter=
"dateFormatter"
width=
"180px"
/>
<el-table-column
label=
"操作"
align=
"center"
min-width=
"120px"
>
<template
#
default=
"scope"
>
<el-button
link
type=
"primary"
@
click=
"openForm('update', scope.row.id)"
v-hasPermi=
"['compute:resource-config:update']"
>
编辑
</el-button>
<el-button
link
type=
"danger"
@
click=
"handleDelete(scope.row.id)"
v-hasPermi=
"['compute:resource-config:delete']"
>
删除
</el-button>
</
template
>
</el-table-column>
</el-table>
<!-- 分页 -->
<Pagination
:total=
"total"
v-model:page=
"queryParams.pageNo"
v-model:limit=
"queryParams.pageSize"
@
pagination=
"getList"
/>
</ContentWrap>
<!-- 表单弹窗:添加/修改 -->
<ResourceConfigForm
ref=
"formRef"
@
success=
"getList"
/>
</template>
<
script
setup
lang=
"ts"
>
import
{
isEmpty
}
from
'@/utils/is'
import
{
dateFormatter
}
from
'@/utils/formatTime'
import
download
from
'@/utils/download'
import
{
ResourceConfigApi
,
ResourceConfig
}
from
'@/api/compute/resourceconfig'
import
ResourceConfigForm
from
'./ResourceConfigForm.vue'
import
{
DICT_TYPE
,
getIntDictOptions
}
from
"@/utils/dict"
;
/** 算力资源配置 列表 */
defineOptions
({
name
:
'ResourceConfig'
})
const
statusOptions
=
getIntDictOptions
(
DICT_TYPE
.
COMMON_ENABLE_DISABLE
)
const
message
=
useMessage
()
// 消息弹窗
const
{
t
}
=
useI18n
()
// 国际化
const
loading
=
ref
(
true
)
// 列表的加载中
const
list
=
ref
<
ResourceConfig
[]
>
([])
// 列表的数据
const
total
=
ref
(
0
)
// 列表的总页数
const
queryParams
=
reactive
({
pageNo
:
1
,
pageSize
:
10
,
configCategory
:
undefined
,
configOption
:
undefined
,
sort
:
undefined
,
status
:
undefined
,
detailRemark
:
undefined
,
createTime
:
[]
})
const
queryFormRef
=
ref
()
// 搜索的表单
const
exportLoading
=
ref
(
false
)
// 导出的加载中
/** 查询列表 */
const
getList
=
async
()
=>
{
loading
.
value
=
true
try
{
const
data
=
await
ResourceConfigApi
.
getResourceConfigPage
(
queryParams
)
list
.
value
=
data
.
list
total
.
value
=
data
.
total
}
finally
{
loading
.
value
=
false
}
}
/** 搜索按钮操作 */
const
handleQuery
=
()
=>
{
queryParams
.
pageNo
=
1
getList
()
}
/** 重置按钮操作 */
const
resetQuery
=
()
=>
{
queryFormRef
.
value
.
resetFields
()
handleQuery
()
}
/** 添加/修改操作 */
const
formRef
=
ref
()
const
openForm
=
(
type
:
string
,
id
?:
number
)
=>
{
formRef
.
value
.
open
(
type
,
id
)
}
/** 删除按钮操作 */
const
handleDelete
=
async
(
id
:
number
)
=>
{
try
{
// 删除的二次确认
await
message
.
delConfirm
()
// 发起删除
await
ResourceConfigApi
.
deleteResourceConfig
(
id
)
message
.
success
(
t
(
'common.delSuccess'
))
// 刷新列表
await
getList
()
}
catch
{}
}
/** 批量删除算力资源配置 */
const
handleDeleteBatch
=
async
()
=>
{
try
{
// 删除的二次确认
await
message
.
delConfirm
()
await
ResourceConfigApi
.
deleteResourceConfigList
(
checkedIds
.
value
);
message
.
success
(
t
(
'common.delSuccess'
))
await
getList
();
}
catch
{}
}
const
checkedIds
=
ref
<
number
[]
>
([])
const
handleRowCheckboxChange
=
(
records
:
ResourceConfig
[])
=>
{
checkedIds
.
value
=
records
.
map
((
item
)
=>
item
.
id
);
}
/** 导出按钮操作 */
const
handleExport
=
async
()
=>
{
try
{
// 导出的二次确认
await
message
.
exportConfirm
()
// 发起导出
exportLoading
.
value
=
true
const
data
=
await
ResourceConfigApi
.
exportResourceConfig
(
queryParams
)
download
.
excel
(
data
,
'算力资源配置.xls'
)
}
catch
{
}
finally
{
exportLoading
.
value
=
false
}
}
/** 初始化 **/
onMounted
(()
=>
{
getList
()
})
</
script
>
src/views/compute/resourcespu/ResourceSpuForm.vue
View file @
e924edf5
vue
<
template
>
<Dialog
:title=
"dialogTitle"
v-model=
"dialogVisible"
>
<Dialog
:title=
"dialogTitle"
v-model=
"dialogVisible"
:width=
"800"
>
<el-form
ref=
"formRef"
:model=
"formData"
:rules=
"formRules"
label-width=
"1
0
0px"
label-width=
"1
2
0px"
v-loading=
"formLoading"
size=
"default"
>
<el-form-item
label=
"算力资源名称"
prop=
"name"
>
<el-input
v-model=
"formData.name"
placeholder=
"请输入算力资源名称"
/>
</el-form-item>
<el-form-item
label=
"CPU配置"
prop=
"cpu"
>
<el-input
v-model=
"formData.cpu"
placeholder=
"请输入CPU配置"
/>
</el-form-item>
<el-form-item
label=
"GPU配置"
prop=
"gpu"
>
<el-input
v-model=
"formData.gpu"
placeholder=
"请输入GPU配置"
/>
</el-form-item>
<el-form-item
label=
"内存配置"
prop=
"ram"
>
<el-input
v-model=
"formData.ram"
placeholder=
"请输入内存配置"
/>
</el-form-item>
<el-form-item
label=
"存储配置"
prop=
"storage"
>
<el-input
v-model=
"formData.storage"
placeholder=
"请输入存储配置"
/>
</el-form-item>
<el-form-item
label=
"服务器ip"
prop=
"ip"
>
<el-input
v-model=
"formData.ip"
placeholder=
"请输入服务器ip"
/>
</el-form-item>
<el-form-item
label=
"初始用户名"
prop=
"initUsername"
>
<el-input
v-model=
"formData.initUsername"
placeholder=
"请输入初始用户名"
/>
</el-form-item>
<el-form-item
label=
"初始密码"
prop=
"initPassword"
>
<el-input
v-model=
"formData.initPassword"
placeholder=
"请输入初始密码"
/>
</el-form-item>
<el-form-item
label=
"商品简介"
prop=
"intro"
>
<el-input
v-model=
"formData.intro"
placeholder=
"请输入商品简介"
/>
</el-form-item>
<el-form-item
label=
"算力资源分类编号"
prop=
"categoryId"
>
<el-input
v-model=
"formData.categoryId"
placeholder=
"请输入算力资源分类编号"
/>
</el-form-item>
<el-form-item
label=
"商品封面图"
prop=
"picUrl"
>
<el-input
v-model=
"formData.picUrl"
placeholder=
"请输入商品封面图"
/>
</el-form-item>
<el-form-item
label=
"商品轮播图地址,以逗号分隔,最多15张"
prop=
"sliderPicUrls"
>
<el-input
v-model=
"formData.sliderPicUrls"
placeholder=
"请输入商品轮播图地址,以逗号分隔,最多15张"
/>
</el-form-item>
<el-form-item
label=
"总库存数量"
prop=
"stock"
>
<el-input
v-model=
"formData.stock"
placeholder=
"请输入总库存数量"
/>
</el-form-item>
<el-form-item
label=
"商品销量"
prop=
"sales"
>
<el-input
v-model=
"formData.sales"
placeholder=
"请输入商品销量"
/>
</el-form-item>
<el-form-item
label=
"状态(0 下架,1 上架,2 回收)"
prop=
"status"
>
<el-radio-group
v-model=
"formData.status"
>
<el-radio
value=
"1"
>
请选择字典生成
</el-radio>
</el-radio-group>
</el-form-item>
</el-form>
<!-- 第一行:基础信息 -->
<el-row
:gutter=
"20"
class=
"mb-4"
>
<el-col
:span=
"12"
>
<el-form-item
label=
"算力资源名称"
prop=
"name"
>
<el-input
v-model=
"formData.name"
placeholder=
"请输入算力资源名称"
/>
</el-form-item>
</el-col>
<el-col
:span=
"12"
>
<el-form-item
label=
"算力资源分类"
prop=
"categoryId"
>
<el-select
v-model=
"formData.categoryId"
placeholder=
"请选择算力资源分类"
clearable
class=
"w-full"
>
<el-option
v-for=
"category in categoryList"
:key=
"category.id"
:label=
"category.name"
:value=
"category.id"
/>
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row
:gutter=
"10"
class=
"mb-2"
>
<!-- 仅减小列间距和行底间距,不缩输入框 -->
<el-col
:span=
"6"
>
<el-form-item
label=
"CPU"
prop=
"cpu"
label-width=
"60px"
class=
"compact-item"
>
<el-select
v-model=
"formData.cpu"
placeholder=
"请选择CPU配置"
clearable
class=
"w-full"
>
<el-option
v-for=
"option in cpuOptions"
:key=
"option.id"
:label=
"option.configOption"
:value=
"option.configOption"
/>
</el-select>
</el-form-item>
</el-col>
<el-col
:span=
"6"
>
<el-form-item
label=
"GPU"
prop=
"gpu"
label-width=
"60px"
class=
"compact-item"
>
<el-select
v-model=
"formData.gpu"
placeholder=
"请选择GPU配置"
clearable
class=
"w-full"
>
<el-option
v-for=
"option in gpuOptions"
:key=
"option.id"
:label=
"option.configOption"
:value=
"option.configOption"
/>
</el-select>
</el-form-item>
</el-col>
<el-col
:span=
"6"
>
<el-form-item
label=
"内存"
prop=
"ram"
label-width=
"60px"
class=
"compact-item"
>
<el-select
v-model=
"formData.ram"
placeholder=
"请选择内存配置"
clearable
class=
"w-full"
>
<el-option
v-for=
"option in ramOptions"
:key=
"option.id"
:label=
"option.configOption"
:value=
"option.configOption"
/>
</el-select>
</el-form-item>
</el-col>
<el-col
:span=
"6"
>
<el-form-item
label=
"存储"
prop=
"storage"
label-width=
"60px"
class=
"compact-item"
>
<el-select
v-model=
"formData.storage"
placeholder=
"请选择存储配置"
clearable
class=
"w-full"
>
<el-option
v-for=
"option in storageOptions"
:key=
"option.id"
:label=
"option.configOption"
:value=
"option.configOption"
/>
</el-select>
</el-form-item>
</el-col>
</el-row>
<!-- 第三行:服务器IP -->
<el-row
:gutter=
"20"
class=
"mb-4"
>
<el-col
:span=
"12"
>
<el-form-item
label=
"服务器ip"
prop=
"ip"
>
<el-input
v-model=
"formData.ip"
placeholder=
"请输入服务器ip"
class=
"w-full"
/>
</el-form-item>
</el-col>
<el-col
:span=
"12"
>
<!-- 可以在这里添加其他字段 -->
</el-col>
</el-row>
<!-- 第四行:登录信息 -->
<el-row
:gutter=
"20"
class=
"mb-4"
>
<el-col
:span=
"12"
>
<el-form-item
label=
"初始用户名"
prop=
"initUsername"
>
<el-input
v-model=
"formData.initUsername"
placeholder=
"请输入初始用户名"
class=
"w-full"
/>
</el-form-item>
</el-col>
<el-col
:span=
"12"
>
<el-form-item
label=
"初始密码"
prop=
"initPassword"
>
<el-input
v-model=
"formData.initPassword"
placeholder=
"请输入初始密码"
class=
"w-full"
/>
</el-form-item>
</el-col>
</el-row>
<!-- 第五行:商品简介(textarea 完整闭合) -->
<el-row
class=
"mb-4"
>
<el-col
:span=
"24"
>
<el-form-item
label=
"商品简介"
prop=
"intro"
>
<el-input
v-model=
"formData.intro"
placeholder=
"请输入商品简介"
class=
"w-full"
type=
"textarea"
rows=
"2"
/>
</el-form-item>
</el-col>
</el-row>
<!-- 第六行:商品图片 -->
<el-row
:gutter=
"20"
class=
"mb-4"
>
<el-col
:span=
"12"
>
<el-form-item
label=
"商品封面图"
prop=
"picUrl"
>
<UploadImg
v-model=
"formData.picUrl"
height=
"80px"
/>
</el-form-item>
</el-col>
<el-col
:span=
"12"
>
<el-form-item
label=
"商品轮播图地址"
prop=
"sliderPicUrls"
>
<el-input
v-model=
"formData.sliderPicUrls"
placeholder=
"以逗号分隔,最多15张"
class=
"w-full"
/>
</el-form-item>
</el-col>
</el-row>
<!-- 第七行:库存销量 -->
<el-row
:gutter=
"20"
class=
"mb-4"
>
<el-col
:span=
"12"
>
<el-form-item
label=
"总库存数量"
prop=
"stock"
>
<el-input
v-model=
"formData.stock"
placeholder=
"请输入库存数量"
class=
"w-full"
/>
</el-form-item>
</el-col>
<el-col
:span=
"12"
>
<el-form-item
label=
"商品销量"
prop=
"sales"
>
<el-input
v-model=
"formData.sales"
placeholder=
"请输入商品销量"
class=
"w-full"
/>
</el-form-item>
</el-col>
</el-row>
<!-- 第八行:状态 -->
<el-row
class=
"mb-4"
>
<el-col
:span=
"24"
>
<el-form-item
label=
"状态"
prop=
"status"
>
<el-radio-group
v-model=
"formData.status"
class=
"flex gap-6"
>
<el-radio
v-for=
"dict in getIntDictOptions(DICT_TYPE.COMPUTE_RESOURCE_SPU_STATUS)"
:key=
"dict.value"
:value=
"dict.value"
>
{{
dict
.
label
}}
</el-radio>
</el-radio-group>
</el-form-item>
</el-col>
</el-row>
</el-form>
<!-- 现在这个
</el-form>
会正常解析,不会爆红 -->
<template
#
footer
>
<el-button
@
click=
"submitForm"
type=
"primary"
:disabled=
"formLoading"
>
确 定
</el-button>
<el-button
@
click=
"dialogVisible = false"
>
取 消
</el-button>
<el-button
@
click=
"dialogVisible = false"
style=
"margin-left: 8px;"
>
取 消
</el-button>
</
template
>
</Dialog>
</template>
<
script
setup
lang=
"ts"
>
import
{
ResourceSpuApi
,
ResourceSpu
}
from
'@/api/compute/resourcespu'
import
{
ResourceSpu
,
ResourceSpuApi
}
from
'@/api/compute/resourcespu'
import
{
ResourceConfigApi
}
from
'@/api/compute/resourceconfig'
import
{
DICT_TYPE
,
getIntDictOptions
}
from
"@/utils/dict"
;
import
{
UploadImg
}
from
"@/components/UploadFile"
;
/** 算力资源SPU表(基础配置信息) 表单 */
defineOptions
({
name
:
'ResourceSpuForm'
})
defineOptions
({
name
:
'ResourceSpuForm'
})
const
{
t
}
=
useI18n
()
// 国际化
const
{
t
}
=
useI18n
()
// 国际化
const
message
=
useMessage
()
// 消息弹窗
const
dialogVisible
=
ref
(
false
)
// 弹窗的是否展示
...
...
@@ -93,23 +258,56 @@ const formData = ref({
status
:
undefined
})
const
formRules
=
reactive
({
name
:
[{
required
:
true
,
message
:
'算力资源名称不能为空'
,
trigger
:
'blur'
}],
cpu
:
[{
required
:
true
,
message
:
'CPU配置不能为空'
,
trigger
:
'blur'
}],
ram
:
[{
required
:
true
,
message
:
'内存配置不能为空'
,
trigger
:
'blur'
}],
storage
:
[{
required
:
true
,
message
:
'存储配置不能为空'
,
trigger
:
'blur'
}],
ip
:
[{
required
:
true
,
message
:
'服务器ip不能为空'
,
trigger
:
'blur'
}],
initUsername
:
[{
required
:
true
,
message
:
'初始用户名不能为空'
,
trigger
:
'blur'
}],
initPassword
:
[{
required
:
true
,
message
:
'初始密码不能为空'
,
trigger
:
'blur'
}],
categoryId
:
[{
required
:
true
,
message
:
'算力资源分类编号不能为空'
,
trigger
:
'blur'
}],
picUrl
:
[{
required
:
true
,
message
:
'商品封面图不能为空'
,
trigger
:
'blur'
}],
stock
:
[{
required
:
true
,
message
:
'总库存数量不能为空'
,
trigger
:
'blur'
}],
sales
:
[{
required
:
true
,
message
:
'商品销量不能为空'
,
trigger
:
'blur'
}],
status
:
[{
required
:
true
,
message
:
'状态(0 下架,1 上架,2 回收)不能为空'
,
trigger
:
'blur'
}]
name
:
[{
required
:
true
,
message
:
'算力资源名称不能为空'
,
trigger
:
'blur'
}],
cpu
:
[{
required
:
true
,
message
:
'CPU配置不能为空'
,
trigger
:
'blur'
}],
gpu
:
[{
required
:
true
,
message
:
'GPU配置不能为空'
,
trigger
:
'blur'
}],
ram
:
[{
required
:
true
,
message
:
'内存配置不能为空'
,
trigger
:
'blur'
}],
storage
:
[{
required
:
true
,
message
:
'存储配置不能为空'
,
trigger
:
'blur'
}],
ip
:
[{
required
:
true
,
message
:
'服务器ip不能为空'
,
trigger
:
'blur'
}],
initUsername
:
[{
required
:
true
,
message
:
'初始用户名不能为空'
,
trigger
:
'blur'
}],
initPassword
:
[{
required
:
true
,
message
:
'初始密码不能为空'
,
trigger
:
'blur'
}],
categoryId
:
[{
required
:
true
,
message
:
'算力资源分类编号不能为空'
,
trigger
:
'blur'
}],
picUrl
:
[{
required
:
true
,
message
:
'商品封面图不能为空'
,
trigger
:
'blur'
}],
stock
:
[{
required
:
true
,
message
:
'总库存数量不能为空'
,
trigger
:
'blur'
}],
sales
:
[{
required
:
true
,
message
:
'商品销量不能为空'
,
trigger
:
'blur'
}],
status
:
[{
required
:
true
,
message
:
'状态(0 下架,1 上架,2 回收)不能为空'
,
trigger
:
'blur'
}]
})
const
formRef
=
ref
()
// 表单 Ref
const
categoryList
=
ref
<
CategoryItem
[]
>
([]);
// 配置选项列表
const
cpuOptions
=
ref
<
any
[]
>
([])
const
gpuOptions
=
ref
<
any
[]
>
([])
const
ramOptions
=
ref
<
any
[]
>
([])
const
storageOptions
=
ref
<
any
[]
>
([])
interface
CategoryItem
{
id
:
number
;
name
:
string
;
}
/** 加载配置选项 */
const
loadConfigOptions
=
async
()
=>
{
const
[
cpuRes
,
gpuRes
,
ramRes
,
storageRes
]
=
await
Promise
.
all
([
ResourceConfigApi
.
listSimpleConfigByCategory
(
'cpu'
),
ResourceConfigApi
.
listSimpleConfigByCategory
(
'gpu'
),
ResourceConfigApi
.
listSimpleConfigByCategory
(
'ram'
),
ResourceConfigApi
.
listSimpleConfigByCategory
(
'storage'
)
])
cpuOptions
.
value
=
cpuRes
gpuOptions
.
value
=
gpuRes
ramOptions
.
value
=
ramRes
storageOptions
.
value
=
storageRes
}
/** 打开弹窗 */
const
open
=
async
(
type
:
string
,
id
?:
number
)
=>
{
const
categoryResponse
=
await
ResourceSpuApi
.
listSimpleCategory
();
categoryList
.
value
=
categoryResponse
;
// 加载配置选项
await
loadConfigOptions
()
dialogVisible
.
value
=
true
dialogTitle
.
value
=
t
(
'action.'
+
type
)
formType
.
value
=
type
...
...
@@ -124,7 +322,7 @@ const open = async (type: string, id?: number) => {
}
}
}
defineExpose
({
open
})
// 提供 open 方法,用于打开弹窗
defineExpose
({
open
})
// 提供 open 方法,用于打开弹窗
/** 提交表单 */
const
emit
=
defineEmits
([
'success'
])
// 定义 success 事件,用于操作成功后的回调
...
...
@@ -172,4 +370,28 @@ const resetForm = () => {
}
formRef
.
value
?.
resetFields
()
}
</
script
>
\ No newline at end of file
</
script
>
<
style
scoped
>
/* 硬件配置紧凑布局样式 */
.compact-hardware
{
margin-bottom
:
16px
!important
;
}
.compact-hardware
.el-form-item__label
{
width
:
80px
!important
;
padding-right
:
4px
!important
;
box-sizing
:
border-box
!important
;
text-align
:
right
!important
;
}
.compact-hardware
.el-form-item__content
{
margin-left
:
80px
!important
;
}
/* 移除列之间的间距 */
.el-row
[
gutter
=
"0"
]
.el-col
{
padding-left
:
0
!important
;
padding-right
:
0
!important
;
}
</
style
>
src/views/compute/resourcespu/index.vue
View file @
e924edf5
...
...
@@ -62,24 +62,24 @@
class=
"!w-240px"
/>
</el-form-item>
<el-form-item
label=
"初始用户名"
prop=
"initUsername"
>
<el-input
v-model=
"queryParams.initUsername"
placeholder=
"请输入初始用户名"
clearable
@
keyup
.
enter=
"handleQuery"
class=
"!w-240px"
/
>
</el-form-item
>
<el-form-item
label=
"初始密码"
prop=
"initPassword"
>
<el-input
v-model=
"queryParams.initPassword"
placeholder=
"请输入初始密码"
clearable
@
keyup
.
enter=
"handleQuery"
class=
"!w-240px"
/
>
</el-form-item
>
<!--
<el-form-item
label=
"初始用户名"
prop=
"initUsername"
>
--
>
<!--
<el-input-->
<!-- v-model="queryParams.initUsername"-->
<!-- placeholder="请输入初始用户名"-->
<!-- clearable-->
<!-- @keyup.enter="handleQuery"-->
<!-- class="!w-240px"-->
<!-- />--
>
<!--
</el-form-item>
--
>
<!--
<el-form-item
label=
"初始密码"
prop=
"initPassword"
>
--
>
<!--
<el-input-->
<!-- v-model="queryParams.initPassword"-->
<!-- placeholder="请输入初始密码"-->
<!-- clearable-->
<!-- @keyup.enter="handleQuery"-->
<!-- class="!w-240px"-->
<!-- />--
>
<!--
</el-form-item>
--
>
<el-form-item
label=
"商品简介"
prop=
"intro"
>
<el-input
v-model=
"queryParams.intro"
...
...
@@ -107,15 +107,15 @@
class=
"!w-240px"
/>
</el-form-item>
<el-form-item
label=
"商品轮播图地址,以逗号分隔,最多15张"
prop=
"sliderPicUrls"
>
<el-input
v-model=
"queryParams.sliderPicUrls"
placeholder=
"请输入商品轮播图地址,以逗号分隔,最多15张"
clearable
@
keyup
.
enter=
"handleQuery"
class=
"!w-240px"
/
>
</el-form-item
>
<!--
<el-form-item
label=
"商品轮播图地址"
prop=
"sliderPicUrls"
>
--
>
<!--
<el-input-->
<!-- v-model="queryParams.sliderPicUrls"-->
<!-- placeholder="请输入商品轮播图地址"-->
<!-- clearable-->
<!-- @keyup.enter="handleQuery"-->
<!-- class="!w-240px"-->
<!-- />--
>
<!--
</el-form-item>
--
>
<el-form-item
label=
"总库存数量"
prop=
"stock"
>
<el-input
v-model=
"queryParams.stock"
...
...
@@ -134,14 +134,19 @@
class=
"!w-240px"
/>
</el-form-item>
<el-form-item
label=
"状态
(0 下架,1 上架,2 回收)
"
prop=
"status"
>
<el-form-item
label=
"状态"
prop=
"status"
>
<el-select
v-model=
"queryParams.status"
placeholder=
"请选择状态
(0 下架,1 上架,2 回收)
"
placeholder=
"请选择状态"
clearable
class=
"!w-240px"
>
<el-option
label=
"请选择字典生成"
value=
""
/>
<el-option
v-for=
"dict in statusOptions"
:key=
"dict.value"
:label=
"dict.label"
:value=
"dict.value"
/>
</el-select>
</el-form-item>
<el-form-item
label=
"创建时间"
prop=
"createTime"
>
...
...
@@ -199,22 +204,38 @@
@
selection-change=
"handleRowCheckboxChange"
>
<el-table-column
type=
"selection"
width=
"55"
/>
<el-table-column
label=
"主键ID"
align=
"center"
prop=
"id"
/>
<el-table-column
label=
"算力资源名称"
align=
"center"
prop=
"name"
/>
<!--
<el-table-column
label=
"主键ID"
align=
"center"
prop=
"id"
/>
-->
<el-table-column
label=
"算力资源名称"
min-width=
"200"
>
<template
#
default=
"
{ row }">
<div
class=
"flex"
>
<el-image
fit=
"cover"
:src=
"row.picUrl"
class=
"flex-none w-50px h-50px"
@
click=
"imagePreview(row.picUrl)"
/>
<div
class=
"ml-4 overflow-hidden"
>
<el-tooltip
effect=
"dark"
:content=
"row.name"
placement=
"top"
>
<div>
{{
row
.
name
}}
</div>
</el-tooltip>
</div>
</div>
</
template
>
</el-table-column>
<el-table-column
label=
"CPU配置"
align=
"center"
prop=
"cpu"
/>
<el-table-column
label=
"GPU配置"
align=
"center"
prop=
"gpu"
/>
<el-table-column
label=
"内存配置"
align=
"center"
prop=
"ram"
/>
<el-table-column
label=
"存储配置"
align=
"center"
prop=
"storage"
/>
<el-table-column
label=
"服务器ip"
align=
"center"
prop=
"ip"
/>
<el-table-column
label=
"初始用户名"
align=
"center"
prop=
"initUsername"
/>
<el-table-column
label=
"初始密码"
align=
"center"
prop=
"initPassword"
/>
<el-table-column
label=
"内存"
align=
"center"
prop=
"ram"
/>
<el-table-column
label=
"存储"
align=
"center"
prop=
"storage"
/>
<el-table-column
label=
"商品简介"
align=
"center"
prop=
"intro"
/>
<el-table-column
label=
"算力资源分类编号"
align=
"center"
prop=
"categoryId"
/>
<el-table-column
label=
"商品封面图"
align=
"center"
prop=
"picUrl"
/>
<el-table-column
label=
"商品轮播图地址,以逗号分隔,最多15张"
align=
"center"
prop=
"sliderPicUrls"
/>
<el-table-column
label=
"商品轮播图地址"
align=
"center"
prop=
"sliderPicUrls"
/>
<el-table-column
label=
"总库存数量"
align=
"center"
prop=
"stock"
/>
<el-table-column
label=
"商品销量"
align=
"center"
prop=
"sales"
/>
<el-table-column
label=
"状态(0 下架,1 上架,2 回收)"
align=
"center"
prop=
"status"
/>
<el-table-column
label=
"状态"
align=
"center"
min-width=
"150"
prop=
"status"
>
<
template
#
default=
"scope"
>
<dict-tag
:type=
"DICT_TYPE.COMPUTE_RESOURCE_SPU_STATUS"
:value=
"scope.row.status"
/>
</
template
>
</el-table-column>
<el-table-column
label=
"创建时间"
align=
"center"
...
...
@@ -260,8 +281,10 @@
import
{
isEmpty
}
from
'@/utils/is'
import
{
dateFormatter
}
from
'@/utils/formatTime'
import
download
from
'@/utils/download'
import
{
createImageViewer
}
from
'@/components/ImageViewer'
import
{
ResourceSpuApi
,
ResourceSpu
}
from
'@/api/compute/resourcespu'
import
ResourceSpuForm
from
'./ResourceSpuForm.vue'
import
{
DICT_TYPE
,
getIntDictOptions
}
from
"@/utils/dict"
;
/** 算力资源SPU表(基础配置信息) 列表 */
defineOptions
({
name
:
'ResourceSpu'
})
...
...
@@ -295,6 +318,8 @@ const queryParams = reactive({
const
queryFormRef
=
ref
()
// 搜索的表单
const
exportLoading
=
ref
(
false
)
// 导出的加载中
const
statusOptions
=
getIntDictOptions
(
DICT_TYPE
.
COMPUTE_RESOURCE_SPU_STATUS
)
/** 查询列表 */
const
getList
=
async
()
=>
{
loading
.
value
=
true
...
...
@@ -354,6 +379,13 @@ const handleRowCheckboxChange = (records: ResourceSpu[]) => {
checkedIds
.
value
=
records
.
map
((
item
)
=>
item
.
id
);
}
/** 商品图预览 */
const
imagePreview
=
(
imgUrl
:
string
)
=>
{
createImageViewer
({
urlList
:
[
imgUrl
]
})
}
/** 导出按钮操作 */
const
handleExport
=
async
()
=>
{
try
{
...
...
@@ -373,4 +405,4 @@ const handleExport = async () => {
onMounted
(()
=>
{
getList
()
})
</
script
>
\ No newline at end of file
</
script
>
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