321
This commit is contained in:
parent
32c21d5a73
commit
b4859f7151
|
|
@ -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]: '优惠券'
|
||||
}
|
||||
|
||||
// ==================== 权益等级类型定义 ====================
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user