This commit is contained in:
gpu 2026-02-04 21:03:17 +08:00
parent 32c21d5a73
commit b4859f7151
3 changed files with 44 additions and 309 deletions

View File

@ -6,15 +6,12 @@ import type { CouponInfo } from './reward'
/** 权益等级奖品类型枚举 */
export enum QyLevelPrizeType {
/** 优惠券 */
Coupon = 1,
/** 实物奖品 */
Physical = 2
Coupon = 1
}
/** 权益等级奖品类型标签映射 */
export const QyLevelPrizeTypeLabels: Record<number, string> = {
[QyLevelPrizeType.Coupon]: '优惠券',
[QyLevelPrizeType.Physical]: '实物奖品'
[QyLevelPrizeType.Coupon]: '优惠券'
}
// ==================== 权益等级类型定义 ====================

View File

@ -8,22 +8,6 @@
>
<!-- 搜索和操作区域 -->
<div class="toolbar">
<div class="filter-area">
<el-select
v-model="queryParams.type"
placeholder="奖品类型"
clearable
style="width: 150px"
@change="handleSearch"
>
<el-option
v-for="(label, value) in QyLevelPrizeTypeLabels"
:key="value"
:label="label"
:value="Number(value)"
/>
</el-select>
</div>
<el-button type="primary" @click="handleAdd">
<el-icon><Plus /></el-icon>
</el-button>
@ -33,55 +17,15 @@
<el-table :data="prizeList" v-loading="loading" border stripe max-height="400">
<el-table-column prop="id" label="ID" width="60" align="center" />
<el-table-column label="奖品类型" width="100" align="center">
<el-table-column label="优惠券名称" min-width="150">
<template #default="{ row }">
<el-tag :type="row.type === QyLevelPrizeType.Coupon ? 'warning' : 'success'" size="small">
{{ row.typeName || QyLevelPrizeTypeLabels[row.type] || '未知' }}
</el-tag>
{{ row.coupon?.title || row.title || '-' }}
</template>
</el-table-column>
<el-table-column label="奖品名称" min-width="150">
<el-table-column label="数量" width="80" align="center">
<template #default="{ row }">
<template v-if="row.type === QyLevelPrizeType.Coupon">
{{ row.coupon?.title || row.title || '-' }}
</template>
<template v-else>
{{ row.title || '-' }}
</template>
</template>
</el-table-column>
<el-table-column label="图片" width="80" align="center">
<template #default="{ row }">
<el-image
v-if="row.image"
:src="row.image"
:preview-src-list="[row.image]"
fit="cover"
style="width: 40px; height: 40px"
/>
<span v-else>-</span>
</template>
</el-table-column>
<el-table-column label="数量/价值" width="100" align="center">
<template #default="{ row }">
<template v-if="row.type === QyLevelPrizeType.Coupon">
{{ row.quantity ?? 1 }}
</template>
<template v-else>
¥{{ row.value ?? 0 }}
</template>
</template>
</el-table-column>
<el-table-column label="兑换价" width="90" align="center">
<template #default="{ row }">
<span v-if="row.type === QyLevelPrizeType.Physical">
¥{{ row.exchangePrice ?? 0 }}
</span>
<span v-else>-</span>
{{ row.quantity ?? 1 }}
</template>
</el-table-column>
@ -91,12 +35,6 @@
</template>
</el-table-column>
<el-table-column label="排序" width="70" align="center">
<template #default="{ row }">
{{ row.sort ?? 0 }}
</template>
</el-table-column>
<el-table-column label="操作" width="130" align="center" fixed="right">
<template #default="{ row }">
<el-button type="primary" link size="small" @click="handleEdit(row)">
@ -144,8 +82,6 @@ import QyLevelPrizeFormDialog from './QyLevelPrizeFormDialog.vue'
import {
getQyLevelPrizes,
deleteQyLevelPrize,
QyLevelPrizeType,
QyLevelPrizeTypeLabels,
type QyLevelResponse,
type QyLevelPrizeResponse,
type QyLevelPrizeListRequest
@ -209,12 +145,6 @@ watch(() => props.modelValue, (visible) => {
}
})
//
const handleSearch = () => {
queryParams.page = 1
fetchPrizes()
}
//
const handlePageChange = (page: number) => {
queryParams.page = page
@ -266,16 +196,11 @@ const handleClose = () => {
<style scoped>
.toolbar {
display: flex;
justify-content: space-between;
justify-content: flex-end;
align-items: center;
margin-bottom: 16px;
}
.filter-area {
display: flex;
gap: 12px;
}
.probability-value {
color: #409eff;
font-weight: 500;

View File

@ -12,108 +12,33 @@
:rules="formRules"
label-width="100px"
>
<el-form-item label="奖品类型" prop="type">
<!-- 优惠券类型字段 -->
<el-form-item label="选择优惠券" prop="couponId">
<el-select
v-model="formData.type"
placeholder="请选择奖品类型"
v-model="formData.couponId"
placeholder="请选择优惠券"
style="width: 100%"
:disabled="isEdit"
@change="handleTypeChange"
filterable
:loading="couponLoading"
>
<el-option
v-for="(label, value) in QyLevelPrizeTypeLabels"
:key="value"
:label="label"
:value="Number(value)"
v-for="coupon in couponList"
:key="coupon.id"
:label="`${coupon.title} (满${coupon.minPrice}减${coupon.discountPrice})`"
:value="coupon.id"
/>
</el-select>
</el-form-item>
<!-- 优惠券类型字段 -->
<template v-if="formData.type === QyLevelPrizeType.Coupon">
<el-form-item label="选择优惠券" prop="couponId">
<el-select
v-model="formData.couponId"
placeholder="请选择优惠券"
style="width: 100%"
filterable
:loading="couponLoading"
>
<el-option
v-for="coupon in couponList"
:key="coupon.id"
:label="`${coupon.title} (满${coupon.minPrice}减${coupon.discountPrice})`"
:value="coupon.id"
/>
</el-select>
</el-form-item>
<el-form-item label="数量" prop="quantity">
<el-input-number
v-model="formData.quantity"
:min="1"
:precision="0"
placeholder="请输入优惠券数量"
style="width: 100%"
/>
</el-form-item>
</template>
<!-- 实物奖品类型字段 -->
<template v-if="formData.type === QyLevelPrizeType.Physical">
<el-form-item label="奖品名称" prop="title">
<el-input
v-model="formData.title"
placeholder="请输入奖品名称"
maxlength="100"
show-word-limit
/>
</el-form-item>
<el-form-item label="奖品价值" prop="value">
<el-input-number
v-model="formData.value"
:min="0"
:precision="2"
placeholder="请输入奖品价值"
style="width: 100%"
/>
</el-form-item>
<el-form-item label="兑换价格" prop="exchangePrice">
<el-input-number
v-model="formData.exchangePrice"
:min="0"
:precision="2"
placeholder="请输入兑换价格"
style="width: 100%"
/>
</el-form-item>
<el-form-item label="参考价格" prop="referencePrice">
<el-input-number
v-model="formData.referencePrice"
:min="0"
:precision="2"
placeholder="请输入市场参考价格"
style="width: 100%"
/>
</el-form-item>
<el-form-item label="奖品图片" prop="image">
<el-input
v-model="formData.image"
placeholder="请输入奖品图片URL"
/>
<div v-if="formData.image" class="image-preview">
<el-image
:src="formData.image"
fit="cover"
style="width: 100px; height: 100px; margin-top: 8px"
/>
</div>
</el-form-item>
</template>
<el-form-item label="数量" prop="quantity">
<el-input-number
v-model="formData.quantity"
:min="1"
:precision="0"
placeholder="请输入优惠券数量"
style="width: 100%"
/>
</el-form-item>
<!-- 通用字段 -->
<el-form-item label="中奖概率" prop="probability">
@ -128,16 +53,6 @@
/>
<div class="form-tip">概率范围0-100最多2位小数</div>
</el-form-item>
<el-form-item label="排序" prop="sort">
<el-input-number
v-model="formData.sort"
:min="0"
:precision="0"
placeholder="请输入排序值"
style="width: 100%"
/>
</el-form-item>
</el-form>
<template #footer>
@ -156,7 +71,6 @@ import {
createQyLevelPrize,
updateQyLevelPrize,
QyLevelPrizeType,
QyLevelPrizeTypeLabels,
type QyLevelPrizeResponse,
type QyLevelPrizeCreateRequest,
type QyLevelPrizeUpdateRequest
@ -191,29 +105,15 @@ const couponLoading = ref(false)
//
interface FormDataType {
type: number | undefined
title: string
couponId: number | undefined
quantity: number
value: number
exchangePrice: number
referencePrice: number
probability: number
image: string
sort: number
}
const formData = reactive<FormDataType>({
type: undefined,
title: '',
couponId: undefined,
quantity: 1,
value: 0,
exchangePrice: 0,
referencePrice: 0,
probability: 0,
image: '',
sort: 0
probability: 0
})
//
@ -237,50 +137,13 @@ const probabilityValidator = (_rule: any, value: any, callback: any) => {
//
const formRules = computed<FormRules>(() => ({
type: [
{ required: true, message: '请选择奖品类型', trigger: 'change' }
couponId: [{ required: true, message: '请选择优惠券', trigger: 'change' }],
quantity: [
{ required: true, message: '请输入数量', trigger: 'blur' },
{ type: 'number', min: 1, message: '数量必须大于0', trigger: 'blur' }
],
couponId: formData.type === QyLevelPrizeType.Coupon
? [{ required: true, message: '请选择优惠券', trigger: 'change' }]
: [],
quantity: formData.type === QyLevelPrizeType.Coupon
? [
{ required: true, message: '请输入数量', trigger: 'blur' },
{ type: 'number', min: 1, message: '数量必须大于0', trigger: 'blur' }
]
: [],
title: formData.type === QyLevelPrizeType.Physical
? [
{ required: true, message: '请输入奖品名称', trigger: 'blur' },
{ min: 1, max: 100, message: '名称长度在1-100个字符之间', trigger: 'blur' }
]
: [],
value: formData.type === QyLevelPrizeType.Physical
? [
{ required: true, message: '请输入奖品价值', trigger: 'blur' },
{ type: 'number', min: 0, message: '价值不能为负数', trigger: 'blur' }
]
: [],
exchangePrice: formData.type === QyLevelPrizeType.Physical
? [
{ required: true, message: '请输入兑换价格', trigger: 'blur' },
{ type: 'number', min: 0, message: '兑换价格不能为负数', trigger: 'blur' }
]
: [],
referencePrice: formData.type === QyLevelPrizeType.Physical
? [
{ required: true, message: '请输入参考价格', trigger: 'blur' },
{ type: 'number', min: 0, message: '参考价格不能为负数', trigger: 'blur' }
]
: [],
image: formData.type === QyLevelPrizeType.Physical
? [{ required: true, message: '请输入奖品图片URL', trigger: 'blur' }]
: [],
probability: [
{ required: true, validator: probabilityValidator, trigger: 'blur' }
],
sort: [
{ type: 'number', min: 0, message: '排序值不能为负数', trigger: 'blur' }
]
}))
@ -306,16 +169,9 @@ watch(() => props.modelValue, (visible) => {
if (props.isEdit && props.prize) {
//
Object.assign(formData, {
type: props.prize.type,
title: props.prize.title || '',
couponId: props.prize.couponId,
quantity: props.prize.quantity || 1,
value: props.prize.value || 0,
exchangePrice: props.prize.exchangePrice || 0,
referencePrice: props.prize.referencePrice || 0,
probability: props.prize.probability || 0,
image: props.prize.image || '',
sort: props.prize.sort || 0
probability: props.prize.probability || 0
})
} else {
//
@ -324,35 +180,12 @@ watch(() => props.modelValue, (visible) => {
}
})
//
const handleTypeChange = () => {
if (formData.type === QyLevelPrizeType.Coupon) {
//
formData.title = ''
formData.value = 0
formData.exchangePrice = 0
formData.referencePrice = 0
formData.image = ''
} else {
//
formData.couponId = undefined
formData.quantity = 1
}
}
//
const resetForm = () => {
Object.assign(formData, {
type: undefined,
title: '',
couponId: undefined,
quantity: 1,
value: 0,
exchangePrice: 0,
referencePrice: 0,
probability: 0,
image: '',
sort: 0
probability: 0
})
formRef.value?.resetFields()
}
@ -386,43 +219,23 @@ const handleSubmit = async () => {
return
}
//
if (formData.type === QyLevelPrizeType.Coupon) {
if (!formData.couponId) {
ElMessage.error('请选择优惠券')
return
}
if (formData.quantity <= 0) {
ElMessage.error('数量必须大于0')
return
}
//
if (!formData.couponId) {
ElMessage.error('请选择优惠券')
return
}
//
if (formData.type === QyLevelPrizeType.Physical) {
if (!formData.title) {
ElMessage.error('请输入奖品名称')
return
}
if (!formData.image) {
ElMessage.error('请输入奖品图片URL')
return
}
if (formData.quantity <= 0) {
ElMessage.error('数量必须大于0')
return
}
submitLoading.value = true
try {
const submitData: QyLevelPrizeCreateRequest | QyLevelPrizeUpdateRequest = {
type: formData.type!,
title: formData.type === QyLevelPrizeType.Physical ? formData.title : undefined,
couponId: formData.type === QyLevelPrizeType.Coupon ? formData.couponId : undefined,
quantity: formData.type === QyLevelPrizeType.Coupon ? formData.quantity : undefined,
value: formData.type === QyLevelPrizeType.Physical ? formData.value : undefined,
exchangePrice: formData.type === QyLevelPrizeType.Physical ? formData.exchangePrice : undefined,
referencePrice: formData.type === QyLevelPrizeType.Physical ? formData.referencePrice : undefined,
probability: formData.probability,
image: formData.type === QyLevelPrizeType.Physical ? formData.image : undefined,
sort: formData.sort
type: QyLevelPrizeType.Coupon,
couponId: formData.couponId,
quantity: formData.quantity,
probability: formData.probability
}
if (props.isEdit && props.prize) {