21
This commit is contained in:
parent
8a36e8c2ac
commit
af6d00316b
|
|
@ -257,8 +257,10 @@ export interface PrizeItem {
|
|||
rewardId: string | null
|
||||
doubling: number
|
||||
isLingzhu: number
|
||||
goodsListId: number // 父奖品ID,0表示父奖品,>0表示子奖品
|
||||
createdAt: string | null
|
||||
updatedAt: string
|
||||
children?: PrizeItem[] // 子奖品列表(前端构建树形结构用)
|
||||
}
|
||||
|
||||
/** 创建奖品请求 */
|
||||
|
|
@ -283,6 +285,7 @@ export interface PrizeCreateRequest {
|
|||
rewardId?: string
|
||||
doubling: number
|
||||
isLingzhu: number
|
||||
goodsListId?: number // 父奖品ID,添加宝箱子奖品时使用
|
||||
}
|
||||
|
||||
/** 更新奖品请求 */
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
<template>
|
||||
<el-dialog
|
||||
v-model="dialogVisible"
|
||||
title="新增奖品"
|
||||
:title="dialogTitle"
|
||||
width="800px"
|
||||
:close-on-click-modal="false"
|
||||
@close="handleClose"
|
||||
|
|
@ -260,9 +260,14 @@ interface Props {
|
|||
modelValue: boolean
|
||||
goodsId: number
|
||||
goodsType: number
|
||||
parentPrizeId?: number // 父奖品ID(添加宝箱子奖品时使用)
|
||||
parentPrizeTitle?: string // 父奖品标题
|
||||
}
|
||||
|
||||
const props = defineProps<Props>()
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
parentPrizeId: 0,
|
||||
parentPrizeTitle: ''
|
||||
})
|
||||
|
||||
const emit = defineEmits<{
|
||||
(e: 'update:modelValue', value: boolean): void
|
||||
|
|
@ -274,6 +279,16 @@ const dialogVisible = computed({
|
|||
set: (val) => emit('update:modelValue', val)
|
||||
})
|
||||
|
||||
// 是否是添加子奖品模式
|
||||
const isChildPrizeMode = computed(() => props.parentPrizeId > 0)
|
||||
|
||||
// 弹窗标题
|
||||
const dialogTitle = computed(() => {
|
||||
return isChildPrizeMode.value
|
||||
? `新增子奖品 - ${props.parentPrizeTitle}`
|
||||
: '新增奖品'
|
||||
})
|
||||
|
||||
const formRef = ref<FormInstance>()
|
||||
const submitting = ref(false)
|
||||
const prizeLevelOptions = ref<PrizeLevelOptionResponse[]>([])
|
||||
|
|
@ -425,6 +440,7 @@ const handleSubmit = async () => {
|
|||
rewardId: formData.rewardId || undefined,
|
||||
doubling: formData.doubling,
|
||||
isLingzhu: formData.isLingzhu,
|
||||
goodsListId: props.parentPrizeId, // 父奖品ID
|
||||
}
|
||||
|
||||
await addPrize(props.goodsId, requestData)
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@
|
|||
<el-button type="warning" @click="handleDesignatedPrize">
|
||||
<el-icon><Star /></el-icon>奖品配置
|
||||
</el-button>
|
||||
<el-button type="primary" @click="handleAdd">
|
||||
<el-button type="primary" @click="handleAdd()">
|
||||
<el-icon><Plus /></el-icon>新增奖品
|
||||
</el-button>
|
||||
<!-- 概率统计(无限赏等类型显示) -->
|
||||
|
|
@ -49,6 +49,7 @@
|
|||
row-key="id"
|
||||
:tree-props="{ children: 'children', hasChildren: 'hasChildren' }"
|
||||
max-height="500px"
|
||||
default-expand-all
|
||||
>
|
||||
<!-- ID -->
|
||||
<el-table-column prop="id" label="ID" width="70" align="center" />
|
||||
|
|
@ -75,7 +76,10 @@
|
|||
<!-- 奖品名称 -->
|
||||
<el-table-column prop="title" label="奖品名称" min-width="150">
|
||||
<template #default="{ row }">
|
||||
<div class="prize-title">{{ row.title }}</div>
|
||||
<div class="prize-title">
|
||||
<el-tag v-if="row.goodsListId > 0" type="info" size="small" style="margin-right: 4px;">子</el-tag>
|
||||
{{ row.title }}
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
|
|
@ -164,8 +168,17 @@
|
|||
</el-table-column>
|
||||
|
||||
<!-- 操作 -->
|
||||
<el-table-column label="操作" width="150" fixed="right" align="center">
|
||||
<el-table-column label="操作" width="200" fixed="right" align="center">
|
||||
<template #default="{ row }">
|
||||
<!-- 宝箱类型奖品显示"子奖品"按钮 -->
|
||||
<el-button
|
||||
v-if="row.goodsType === PrizeCategory.BaoXiang && row.goodsListId === 0"
|
||||
type="success"
|
||||
link
|
||||
@click="handleAddChildPrize(row)"
|
||||
>
|
||||
<el-icon><FolderAdd /></el-icon>子奖品
|
||||
</el-button>
|
||||
<el-button type="primary" link @click="handleEdit(row)">
|
||||
<el-icon><Edit /></el-icon>编辑
|
||||
</el-button>
|
||||
|
|
@ -185,6 +198,8 @@
|
|||
v-model="addDialogVisible"
|
||||
:goods-id="goodsId"
|
||||
:goods-type="goodsType"
|
||||
:parent-prize-id="currentParentPrizeId"
|
||||
:parent-prize-title="currentParentPrizeTitle"
|
||||
@success="handleRefresh"
|
||||
/>
|
||||
|
||||
|
|
@ -209,7 +224,7 @@
|
|||
<script setup lang="ts">
|
||||
import { ref, computed, watch } from 'vue'
|
||||
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||
import { Search, Plus, Picture, Edit, Delete, Star } from '@element-plus/icons-vue'
|
||||
import { Search, Plus, Picture, Edit, Delete, Star, FolderAdd } from '@element-plus/icons-vue'
|
||||
import {
|
||||
getGoodsPrizes,
|
||||
updatePrize,
|
||||
|
|
@ -250,6 +265,8 @@ const editDialogVisible = ref(false)
|
|||
const designatedPrizeDialogVisible = ref(false)
|
||||
const currentPrizeId = ref(0)
|
||||
const currentPrizeData = ref<PrizeItem | undefined>(undefined)
|
||||
const currentParentPrizeId = ref(0) // 当前父奖品ID(添加子奖品时使用)
|
||||
const currentParentPrizeTitle = ref('') // 当前父奖品标题
|
||||
|
||||
// 根据盒子类型判断显示哪些列(使用统一配置)
|
||||
const prizeColumnConfig = computed(() => getPrizeColumnConfig(props.goodsType))
|
||||
|
|
@ -259,18 +276,56 @@ const showProbability = computed(() => prizeColumnConfig.value.showProbability)
|
|||
const showDoubling = computed(() => prizeColumnConfig.value.showGiftMultiple)
|
||||
const showLingzhu = computed(() => prizeColumnConfig.value.showIsLingzhu)
|
||||
|
||||
// 概率总和
|
||||
// 概率总和(只计算父奖品)
|
||||
const probabilityTotal = computed(() => {
|
||||
return prizeList.value.reduce((sum, item) => sum + (item.realPro || 0), 0)
|
||||
return prizeList.value
|
||||
.filter(item => (item.goodsListId ?? 0) === 0)
|
||||
.reduce((sum, item) => sum + (item.realPro || 0), 0)
|
||||
})
|
||||
|
||||
// 过滤后的奖品列表
|
||||
// 构建树形结构的奖品列表
|
||||
const buildTreePrizeList = (prizes: PrizeItem[]): PrizeItem[] => {
|
||||
// 分离父奖品和子奖品
|
||||
const parentPrizes = prizes.filter(p => (p.goodsListId ?? 0) === 0)
|
||||
const childPrizes = prizes.filter(p => (p.goodsListId ?? 0) > 0)
|
||||
|
||||
// 为每个父奖品添加子奖品
|
||||
return parentPrizes.map(parent => {
|
||||
const children = childPrizes.filter(child => child.goodsListId === parent.id)
|
||||
return {
|
||||
...parent,
|
||||
children: children.length > 0 ? children : undefined
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 过滤后的奖品列表(树形结构)
|
||||
const filteredPrizeList = computed(() => {
|
||||
if (!searchTitle.value) return prizeList.value
|
||||
const treeList = buildTreePrizeList(prizeList.value)
|
||||
|
||||
if (!searchTitle.value) return treeList
|
||||
|
||||
const keyword = searchTitle.value.toLowerCase()
|
||||
return prizeList.value.filter(item =>
|
||||
|
||||
// 搜索时展平显示,包括匹配的子奖品
|
||||
return treeList.filter(item => {
|
||||
const parentMatch = item.title.toLowerCase().includes(keyword)
|
||||
const childMatch = item.children?.some(child =>
|
||||
child.title.toLowerCase().includes(keyword)
|
||||
)
|
||||
return parentMatch || childMatch
|
||||
}).map(item => {
|
||||
if (item.children) {
|
||||
return {
|
||||
...item,
|
||||
children: item.children.filter(child =>
|
||||
child.title.toLowerCase().includes(keyword) ||
|
||||
item.title.toLowerCase().includes(keyword)
|
||||
)
|
||||
}
|
||||
}
|
||||
return item
|
||||
})
|
||||
})
|
||||
|
||||
// 获取奖品列表
|
||||
|
|
@ -298,11 +353,18 @@ const handleReset = () => {
|
|||
searchTitle.value = ''
|
||||
}
|
||||
|
||||
// 新增奖品
|
||||
const handleAdd = () => {
|
||||
// 新增奖品(可选父奖品ID)
|
||||
const handleAdd = (parentPrizeId: number = 0, parentPrizeTitle: string = '') => {
|
||||
currentParentPrizeId.value = parentPrizeId
|
||||
currentParentPrizeTitle.value = parentPrizeTitle
|
||||
addDialogVisible.value = true
|
||||
}
|
||||
|
||||
// 添加宝箱子奖品
|
||||
const handleAddChildPrize = (parentPrize: PrizeItem) => {
|
||||
handleAdd(parentPrize.id, parentPrize.title)
|
||||
}
|
||||
|
||||
// 指定中奖配置
|
||||
const handleDesignatedPrize = () => {
|
||||
designatedPrizeDialogVisible.value = true
|
||||
|
|
@ -317,12 +379,13 @@ const handleEdit = (row: PrizeItem) => {
|
|||
|
||||
// 删除奖品
|
||||
const handleDelete = async (row: PrizeItem) => {
|
||||
const hasChildren = row.children && row.children.length > 0
|
||||
const confirmMsg = hasChildren
|
||||
? `确定要删除宝箱奖品 "${row.title}" 及其所有子奖品吗?删除后不可恢复!`
|
||||
: `确定要删除奖品 "${row.title}" 吗?删除后不可恢复!`
|
||||
|
||||
try {
|
||||
await ElMessageBox.confirm(
|
||||
`确定要删除奖品 "${row.title}" 吗?删除后不可恢复!`,
|
||||
'删除确认',
|
||||
{ type: 'warning' }
|
||||
)
|
||||
await ElMessageBox.confirm(confirmMsg, '删除确认', { type: 'warning' })
|
||||
await deletePrize(row.id)
|
||||
ElMessage.success('删除成功')
|
||||
fetchPrizes()
|
||||
|
|
@ -423,6 +486,8 @@ const handleOpen = () => {
|
|||
const handleClose = () => {
|
||||
searchTitle.value = ''
|
||||
prizeList.value = []
|
||||
currentParentPrizeId.value = 0
|
||||
currentParentPrizeTitle.value = ''
|
||||
emit('update:modelValue', false)
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user