Commit 9d78ba94 by Jony.L

算力资源重构-算力资源SKU管理修改1.0

parent e3a046d6
......@@ -111,6 +111,7 @@ export enum DICT_TYPE {
USER_TYPE = 'user_type',
COMMON_STATUS = 'common_status',
COMMON_ENABLE_DISABLE = 'common_enable_disable',
COMMON_LIST_STATUS = 'common_list_status',
TERMINAL = 'terminal', // 终端
DATE_INTERVAL = 'date_interval', // 数据间隔
......@@ -177,6 +178,7 @@ export enum DICT_TYPE {
// ==========Compute 算力资源模块========
COMPUTE_RESOURCE_SPU_STATUS = 'compute_resource_spu_status',
COMPUTE_RESOURCE_CONFIG_CATEGORY = 'compute_resource_config_category',
COMPUTE_RESOURCE_DURATION = 'compute_resource_duration',
// ========== MALL - 商品模块 ==========
PRODUCT_SPU_STATUS = 'product_spu_status', //商品状态
......
......@@ -7,21 +7,66 @@
label-width="100px"
v-loading="formLoading"
>
<el-form-item label="关联的SPU ID" prop="spuId">
<el-input v-model="formData.spuId" placeholder="请输入关联的SPU ID" />
<el-form-item label="关联的SPU" prop="spuId">
<el-input
v-model="selectedSpuName"
placeholder="请选择SPU"
clearable
readonly
@click="openSpuSelector"
class="!w-240px cursor-pointer"
>
<template #suffix>
<Icon icon="ep:search" class="cursor-pointer" />
</template>
</el-input>
</el-form-item>
<el-form-item label="租赁天数(30/90/365等)" prop="durationDays">
<el-input v-model="formData.durationDays" placeholder="请输入租赁天数(30/90/365等)" />
<el-form-item label="租赁时长" prop="durationDays">
<el-select
v-model="formData.durationDays"
placeholder="请选择租赁时长"
clearable
class="!w-240px"
>
<el-option
v-for="dict in durationOptions"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
<el-form-item label="支付价格(单位:分)" prop="paymentPrice">
<el-input v-model="formData.paymentPrice" placeholder="请输入支付价格(单位:分)" />
<el-form-item label="支付价格" prop="paymentPrice">
<el-input-number
v-model="paymentPriceYuan"
placeholder="请输入支付价格"
:min="0"
:precision="2"
:step="0.1"
class="!w-240px"
controls-position="right"
/>
</el-form-item>
<el-form-item label="市场价格(单位:分)" prop="marketPrice">
<el-input v-model="formData.marketPrice" placeholder="请输入市场价格(单位:分)" />
<el-form-item label="市场价格" prop="marketPrice">
<el-input-number
v-model="marketPriceYuan"
placeholder="请输入市场价格"
:min="0"
:precision="2"
:step="0.1"
class="!w-240px"
controls-position="right"
/>
</el-form-item>
<el-form-item label="状态(0-下架,1-上架)" prop="status">
<el-form-item label="状态" prop="status">
<el-radio-group v-model="formData.status">
<el-radio value="1">请选择字典生成</el-radio>
<el-radio
v-for="dict in getIntDictOptions(DICT_TYPE.COMMON_LIST_STATUS)"
:key="dict.value"
:value="dict.value"
>
{{ dict.label }}
</el-radio>
</el-radio-group>
</el-form-item>
</el-form>
......@@ -30,9 +75,20 @@
<el-button @click="dialogVisible = false">取 消</el-button>
</template>
</Dialog>
<!-- SPU选择弹窗 -->
<ResourceSpuSelectDialog
v-model="spuSelectorVisible"
:multiple="false"
title="选择算力资源SPU"
@confirm="handleSpuSelect"
/>
</template>
<script setup lang="ts">
import { ResourceSkuApi, ResourceSku } from '@/api/compute/resourcesku'
import ResourceSpuSelectDialog from '../resourcespu/ResourceSpuSelectDialog.vue'
import { DICT_TYPE, getIntDictOptions, getStrDictOptions } from "@/utils/dict"
import { fenToYuan, yuanToFen } from '@/utils'
/** 算力资源SKU表(价格和租赁信息) 表单 */
defineOptions({ name: 'ResourceSkuForm' })
......@@ -44,6 +100,8 @@ const dialogVisible = ref(false) // 弹窗的是否展示
const dialogTitle = ref('') // 弹窗的标题
const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
const formType = ref('') // 表单的类型:create - 新增;update - 修改
const spuSelectorVisible = ref(false) // SPU选择弹窗显示状态
const selectedSpu = ref<any>(null) // 选中的SPU
const formData = ref({
id: undefined,
spuId: undefined,
......@@ -52,10 +110,31 @@ const formData = ref({
marketPrice: undefined,
status: undefined
})
const selectedSpuName = ref('') // 选中的SPU名称显示
// 租赁时长选项
const durationOptions = getStrDictOptions(DICT_TYPE.COMPUTE_RESOURCE_DURATION)
// 价格的计算属性(元单位)
const paymentPriceYuan = computed({
get: () => fenToYuan(formData.value.paymentPrice || 0),
set: (value) => {
formData.value.paymentPrice = yuanToFen(value || 0)
}
})
const marketPriceYuan = computed({
get: () => fenToYuan(formData.value.marketPrice || 0),
set: (value) => {
formData.value.marketPrice = yuanToFen(value || 0)
}
})
const formRules = reactive({
spuId: [{ required: true, message: '关联的SPU ID不能为空', trigger: 'blur' }],
durationDays: [{ required: true, message: '租赁天数(30/90/365等)不能为空', trigger: 'blur' }],
paymentPrice: [{ required: true, message: '支付价格(单位:分)不能为空', trigger: 'blur' }],
spuId: [{ required: true, message: '关联的SPU不能为空', trigger: 'change' }],
durationDays: [{ required: true, message: '租赁时长不能为空', trigger: 'change' }],
paymentPrice: [{ required: true, message: '支付价格不能为空', trigger: 'blur' }],
marketPrice: [{ required: true, message: '市场价格不能为空', trigger: 'blur' }],
status: [{ required: true, message: '状态(0-下架,1-上架)不能为空', trigger: 'blur' }]
})
const formRef = ref() // 表单 Ref
......@@ -102,8 +181,26 @@ const submitForm = async () => {
}
}
/** 打开SPU选择器 */
const openSpuSelector = () => {
spuSelectorVisible.value = true
}
/** 处理SPU选择确认 */
const handleSpuSelect = (selections: any[]) => {
if (selections.length > 0) {
const spu = selections[0]
selectedSpu.value = spu
selectedSpuName.value = spu.name
formData.value.spuId = spu.id
}
spuSelectorVisible.value = false
}
/** 重置表单 */
const resetForm = () => {
selectedSpu.value = null
selectedSpuName.value = ''
formData.value = {
id: undefined,
spuId: undefined,
......
......@@ -8,50 +8,60 @@
:inline="true"
label-width="68px"
>
<el-form-item label="关联的SPU ID" prop="spuId">
<el-form-item label="SPU名称" prop="spuId">
<el-input
v-model="queryParams.spuId"
placeholder="请输入关联的SPU ID"
v-model="selectedSpuName"
placeholder="请选择SPU"
clearable
@keyup.enter="handleQuery"
class="!w-240px"
/>
</el-form-item>
<el-form-item label="租赁天数(30/90/365等)" prop="durationDays">
<el-input
v-model="queryParams.durationDays"
placeholder="请输入租赁天数(30/90/365等)"
clearable
@keyup.enter="handleQuery"
class="!w-240px"
/>
</el-form-item>
<el-form-item label="支付价格(单位:分)" prop="paymentPrice">
<el-input
v-model="queryParams.paymentPrice"
placeholder="请输入支付价格(单位:分)"
clearable
@keyup.enter="handleQuery"
class="!w-240px"
/>
</el-form-item>
<el-form-item label="市场价格(单位:分)" prop="marketPrice">
<el-input
v-model="queryParams.marketPrice"
placeholder="请输入市场价格(单位:分)"
clearable
@keyup.enter="handleQuery"
class="!w-240px"
/>
readonly
@click="openSpuSelector"
class="!w-240px cursor-pointer"
>
<template #suffix>
<Icon icon="ep:search" class="cursor-pointer" />
</template>
</el-input>
</el-form-item>
<el-form-item label="状态(0-下架,1-上架)" prop="status">
<!-- <el-form-item label="租赁天数(30/90/365等)" prop="durationDays">-->
<!-- <el-input-->
<!-- v-model="queryParams.durationDays"-->
<!-- placeholder="请输入租赁天数(30/90/365等)"-->
<!-- clearable-->
<!-- @keyup.enter="handleQuery"-->
<!-- class="!w-240px"-->
<!-- />-->
<!-- </el-form-item>-->
<!-- <el-form-item label="支付价格" prop="paymentPrice">-->
<!-- <el-input-->
<!-- v-model="queryParams.paymentPrice"-->
<!-- placeholder="请输入支付价格(单位:分)"-->
<!-- clearable-->
<!-- @keyup.enter="handleQuery"-->
<!-- class="!w-240px"-->
<!-- />-->
<!-- </el-form-item>-->
<!-- <el-form-item label="市场价格" prop="marketPrice">-->
<!-- <el-input-->
<!-- v-model="queryParams.marketPrice"-->
<!-- placeholder="请输入市场价格(单位:分)"-->
<!-- clearable-->
<!-- @keyup.enter="handleQuery"-->
<!-- class="!w-240px"-->
<!-- />-->
<!-- </el-form-item>-->
<el-form-item label="状态" prop="status">
<el-select
v-model="queryParams.status"
placeholder="请选择状态(0-下架,1-上架)"
placeholder="请选择状态"
clearable
class="!w-240px"
>
<el-option label="请选择字典生成" value="" />
<el-option
v-for="dict in getIntDictOptions(DICT_TYPE.COMMON_LIST_STATUS)"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
<el-form-item label="创建时间" prop="createTime">
......@@ -109,12 +119,25 @@
@selection-change="handleRowCheckboxChange"
>
<el-table-column type="selection" width="55" />
<el-table-column label="主键ID" align="center" prop="id" />
<el-table-column label="关联的SPU ID" align="center" prop="spuId" />
<el-table-column label="租赁天数(30/90/365等)" align="center" prop="durationDays" />
<el-table-column label="支付价格(单位:分)" align="center" prop="paymentPrice" />
<el-table-column label="市场价格(单位:分)" align="center" prop="marketPrice" />
<el-table-column label="状态(0-下架,1-上架)" align="center" prop="status" />
<!-- <el-table-column label="主键ID" align="center" prop="id" />-->
<!-- <el-table-column label="关联的SPU ID" align="center" prop="spuId" />-->
<el-table-column label="关联的SPU" align="center" prop="spuName"/>
<el-table-column label="租赁天数" align="center" prop="durationDays" />
<el-table-column label="支付价格" align="center" prop="paymentPrice">
<template #default="{ row }">
¥{{ fenToYuan(row.paymentPrice) }}
</template>
</el-table-column>
<el-table-column label="市场价格" align="center" prop="marketPrice">
<template #default="{ row }">
¥{{ fenToYuan(row.marketPrice) }}
</template>
</el-table-column>
<el-table-column label="状态" align="center" prop="status">
<template #default="scope">
<dict-tag :type="DICT_TYPE.COMMON_LIST_STATUS" :value="scope.row.status" />
</template>
</el-table-column>
<el-table-column
label="创建时间"
align="center"
......@@ -154,6 +177,14 @@
<!-- 表单弹窗:添加/修改 -->
<ResourceSkuForm ref="formRef" @success="getList" />
<!-- SPU选择弹窗 -->
<ResourceSpuSelectDialog
v-model="spuSelectorVisible"
:multiple="false"
title="选择算力资源SPU"
@confirm="handleSpuSelect"
/>
</template>
<script setup lang="ts">
......@@ -162,6 +193,9 @@ import { dateFormatter } from '@/utils/formatTime'
import download from '@/utils/download'
import { ResourceSkuApi, ResourceSku } from '@/api/compute/resourcesku'
import ResourceSkuForm from './ResourceSkuForm.vue'
import ResourceSpuSelectDialog from '../resourcespu/ResourceSpuSelectDialog.vue'
import {DICT_TYPE, getIntDictOptions} from "@/utils/dict"
import { fenToYuan } from '@/utils'
/** 算力资源SKU表(价格和租赁信息) 列表 */
defineOptions({ name: 'ResourceSku' })
......@@ -176,6 +210,7 @@ const queryParams = reactive({
pageNo: 1,
pageSize: 10,
spuId: undefined,
spuName: undefined,
durationDays: undefined,
paymentPrice: undefined,
marketPrice: undefined,
......@@ -184,6 +219,9 @@ const queryParams = reactive({
})
const queryFormRef = ref() // 搜索的表单
const exportLoading = ref(false) // 导出的加载中
const spuSelectorVisible = ref(false) // SPU选择弹窗显示状态
const selectedSpu = ref<any>(null) // 选中的SPU
const selectedSpuName = ref('') // 选中的SPU名称
/** 查询列表 */
const getList = async () => {
......@@ -259,6 +297,26 @@ const handleExport = async () => {
}
}
/** 打开SPU选择器 */
const openSpuSelector = () => {
// 清除之前的选择状态
selectedSpu.value = null
selectedSpuName.value = ''
spuSelectorVisible.value = true
}
/** 处理SPU选择确认 */
const handleSpuSelect = (selections: any[]) => {
if (selections.length > 0) {
const spu = selections[0]
selectedSpu.value = spu
selectedSpuName.value = spu.name
queryParams.spuId = spu.id
queryParams.spuName = spu.name
}
spuSelectorVisible.value = false
}
/** 初始化 **/
onMounted(() => {
getList()
......
......@@ -78,9 +78,21 @@
</div>
<!-- 5. 服务器信息 -->
<el-form-item label="服务器IP" prop="ip">
<el-input v-model="formData.ip" placeholder="请输入服务器IP" style="width: 300px;" :disabled="isDetailMode" />
<div style="display: flex; margin-bottom: 24px;">
<el-form-item label="服务器所在地" prop="location" style="margin-right: 20px; margin-bottom: 0;">
<el-select v-model="formData.location" placeholder="请选择服务器所在地" clearable style="width: 180px;" :disabled="isDetailMode">
<el-option
v-for="option in resourceConfigStore.getOptionsByType('location')"
:key="option.id"
:label="option.configOption"
:value="option.configOption"
/>
</el-select>
</el-form-item>
<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-form-item>
</div>
<div style="display: flex; margin-bottom: 24px;">
<el-form-item label="初始用户名" prop="initUsername" style="margin-right: 20px; margin-bottom: 0;">
......@@ -101,6 +113,7 @@
</el-form-item>
</div>
<!-- 7. 商品简介 -->
<el-form-item label="商品简介" prop="intro">
<el-input
......@@ -154,7 +167,7 @@
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
import { UploadImg } from '@/components/UploadFile'
import { useTagsViewStore } from '@/store/modules/tagsView'
import { useHardwareConfigStore } from '@/store/modules/compute/hardwareConfig'
import { useResourceConfigStore } from '@/store/modules/compute/hardwareConfig'
import { ResourceSpu, ResourceSpuApi } from '@/api/compute/resourcespu'
defineOptions({ name: 'ResourceSpuAdd' })
......@@ -173,17 +186,17 @@ const isDetailMode = computed(() => currentMode.value === 'detail')
const isEditMode = computed(() => currentMode.value === 'edit')
const isAddMode = computed(() => currentMode.value === 'add')
const { delView } = useTagsViewStore() // 视图操作
const hardwareConfigStore = useHardwareConfigStore() // 硬件配置store
const resourceConfigStore = useResourceConfigStore() // 资源配置store
const formLoading = ref(false) // 表单的加载中
const formRef = ref() // 表单 Ref
const categoryList = ref<any[]>([])
// 从store获取硬件配置选项
const cpuOptions = computed(() => hardwareConfigStore.getOptionsByType('cpu'))
const gpuOptions = computed(() => hardwareConfigStore.getOptionsByType('gpu'))
const ramOptions = computed(() => hardwareConfigStore.getOptionsByType('ram'))
const storageOptions = computed(() => hardwareConfigStore.getOptionsByType('storage'))
const cpuOptions = computed(() => resourceConfigStore.getOptionsByType('cpu'))
const gpuOptions = computed(() => resourceConfigStore.getOptionsByType('gpu'))
const ramOptions = computed(() => resourceConfigStore.getOptionsByType('ram'))
const storageOptions = computed(() => resourceConfigStore.getOptionsByType('storage'))
const formData = ref<ResourceSpu>({
id: undefined,
......@@ -201,6 +214,7 @@ const formData = ref<ResourceSpu>({
sliderPicUrls: undefined,
stock: undefined,
sales: undefined,
location: undefined,
status: undefined
})
......@@ -257,7 +271,7 @@ onMounted(async () => {
// 并行加载分类列表和硬件配置选项
const [categoryResponse] = await Promise.all([
ResourceSpuApi.listSimpleCategory(),
hardwareConfigStore.loadConfigOptions()
resourceConfigStore.loadConfigOptions()
])
categoryList.value = categoryResponse
......
......@@ -25,7 +25,7 @@
class="!w-240px"
>
<el-option
v-for="option in hardwareConfigStore.getOptionsByType('cpu')"
v-for="option in resourceConfigStore.getOptionsByType('cpu')"
:key="option.id"
:label="option.configOption"
:value="option.configOption"
......@@ -40,7 +40,7 @@
class="!w-240px"
>
<el-option
v-for="option in hardwareConfigStore.getOptionsByType('gpu')"
v-for="option in resourceConfigStore.getOptionsByType('gpu')"
:key="option.id"
:label="option.configOption"
:value="option.configOption"
......@@ -55,7 +55,7 @@
class="!w-240px"
>
<el-option
v-for="option in hardwareConfigStore.getOptionsByType('ram')"
v-for="option in resourceConfigStore.getOptionsByType('ram')"
:key="option.id"
:label="option.configOption"
:value="option.configOption"
......@@ -70,7 +70,7 @@
class="!w-240px"
>
<el-option
v-for="option in hardwareConfigStore.getOptionsByType('storage')"
v-for="option in resourceConfigStore.getOptionsByType('storage')"
:key="option.id"
:label="option.configOption"
:value="option.configOption"
......@@ -128,6 +128,21 @@
/>
</el-select>
</el-form-item>
<el-form-item label="服务器所在地" prop="location">
<el-select
v-model="queryParams.location"
placeholder="请选择服务器所在地"
clearable
class="!w-240px"
>
<el-option
v-for="option in resourceConfigStore.getOptionsByType('location')"
:key="option.id"
:label="option.configOption"
:value="option.configOption"
/>
</el-select>
</el-form-item>
<!-- <el-form-item label="商品封面图" prop="picUrl">-->
<!-- <el-input-->
<!-- v-model="queryParams.picUrl"-->
......@@ -253,9 +268,10 @@
</template>
</el-table-column>
<!-- 硬件配置字段已隐藏 -->
<el-table-column label="商品简介" align="center" prop="intro" min-width="200" />
<!-- <el-table-column label="算力资源分类编号" align="center" prop="categoryId" />-->
<el-table-column label="算力资源分类" align="center" prop="categoryName" min-width="150" />
<el-table-column label="服务器所在地" align="center" prop="location" min-width="120" />
<el-table-column label="商品简介" align="center" prop="intro" min-width="200" />
<!-- 轮播图地址已隐藏 -->
<el-table-column label="总库存数量" align="center" prop="stock" />
......@@ -312,17 +328,17 @@
</template>
<script setup lang="ts">
import { ref, reactive, computed, onMounted, onActivated } from 'vue'
import { ref, reactive, onMounted, onActivated } from 'vue'
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 {DICT_TYPE, getIntDictOptions} from "@/utils/dict";
import { useHardwareConfigStore } from '@/store/modules/compute/hardwareConfig'
import { useResourceConfigStore } from '@/store/modules/compute/hardwareConfig'
const { push } = useRouter()
const hardwareConfigStore = useHardwareConfigStore()
const resourceConfigStore = useResourceConfigStore()
/** 算力资源SPU表(基础配置信息) 列表 */
defineOptions({ name: 'ResourceSpu' })
......@@ -347,6 +363,7 @@ const queryParams = reactive({
initPassword: undefined,
intro: undefined,
categoryId: undefined,
location: undefined,
picUrl: undefined,
sliderPicUrls: undefined,
stock: undefined,
......@@ -456,7 +473,7 @@ onMounted(async () => {
// 并行加载数据
const [categoryResponse] = await Promise.all([
ResourceSpuApi.listSimpleCategory(),
hardwareConfigStore.loadConfigOptions()
resourceConfigStore.loadConfigOptions()
])
categoryList.value = categoryResponse
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment