21
This commit is contained in:
parent
284b0c20f0
commit
4e4849eac1
|
|
@ -113,6 +113,28 @@ public class PrizeCreateRequest
|
|||
/// 系统会自动为所有箱号中的同一父奖品创建对应的子奖品
|
||||
/// </summary>
|
||||
public int GoodsListId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 奖励配置列表
|
||||
/// 用于配置抽中该奖品时发放的货币奖励
|
||||
/// </summary>
|
||||
public List<PrizeRewardItem>? Rewards { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 奖品奖励配置项
|
||||
/// </summary>
|
||||
public class PrizeRewardItem
|
||||
{
|
||||
/// <summary>
|
||||
/// 奖励类型:1=钻石(HH币) 2=UU币(积分) 3=哈尼券
|
||||
/// </summary>
|
||||
public int Type { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 奖励数量
|
||||
/// </summary>
|
||||
public int Amount { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -272,6 +294,11 @@ public class PrizeDto
|
|||
/// </summary>
|
||||
public int GoodsListId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 奖励配置列表
|
||||
/// </summary>
|
||||
public List<PrizeRewardItem>? Rewards { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 创建时间
|
||||
/// </summary>
|
||||
|
|
|
|||
|
|
@ -307,6 +307,51 @@ public class GoodsService : IGoodsService
|
|||
|
||||
#region 奖品管理
|
||||
|
||||
/// <summary>
|
||||
/// 创建奖品奖励配置
|
||||
/// 在 rewards 表中创建对应的奖励记录
|
||||
/// </summary>
|
||||
/// <param name="prizeCode">奖品编码,用作 reward_id</param>
|
||||
/// <param name="rewards">奖励配置列表</param>
|
||||
/// <param name="now">当前时间</param>
|
||||
/// <returns>生成的 reward_id</returns>
|
||||
private async Task<string> CreatePrizeRewardsAsync(string prizeCode, List<PrizeRewardItem> rewards, DateTime now)
|
||||
{
|
||||
// 使用 prize_code 作为 reward_id,确保唯一性
|
||||
var rewardId = $"PRIZE_{prizeCode}";
|
||||
|
||||
// 删除已存在的同 reward_id 的记录(如果有)
|
||||
var existingRewards = await _dbContext.Rewards
|
||||
.Where(r => r.RewardId == rewardId)
|
||||
.ToListAsync();
|
||||
if (existingRewards.Any())
|
||||
{
|
||||
_dbContext.Rewards.RemoveRange(existingRewards);
|
||||
}
|
||||
|
||||
// 创建新的奖励记录
|
||||
foreach (var item in rewards.Where(r => r.Amount > 0))
|
||||
{
|
||||
var reward = new HoneyBox.Model.Entities.Reward
|
||||
{
|
||||
RewardId = rewardId,
|
||||
RewardType = item.Type,
|
||||
RewardValue = item.Amount,
|
||||
RewardExtend = null,
|
||||
CreatedAt = now,
|
||||
UpdatedAt = now
|
||||
};
|
||||
_dbContext.Rewards.Add(reward);
|
||||
}
|
||||
|
||||
await _dbContext.SaveChangesAsync();
|
||||
|
||||
_logger.LogInformation("创建奖品奖励配置: RewardId={RewardId}, Count={Count}",
|
||||
rewardId, rewards.Count(r => r.Amount > 0));
|
||||
|
||||
return rewardId;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task<List<PrizeDto>> GetPrizesAsync(int goodsId)
|
||||
{
|
||||
|
|
@ -337,7 +382,31 @@ public class GoodsService : IGoodsService
|
|||
.Where(pl => shangIds.Contains(pl.Id))
|
||||
.ToDictionaryAsync(pl => pl.Id, pl => new PrizeLevelInfo { Title = pl.Title, Color = pl.Color });
|
||||
|
||||
return prizes.Select(p => MapToPrizeDto(p, prizeLevels)).ToList();
|
||||
// 获取所有奖励ID
|
||||
var rewardIds = prizes
|
||||
.Where(p => !string.IsNullOrEmpty(p.RewardId))
|
||||
.Select(p => p.RewardId!)
|
||||
.Distinct()
|
||||
.ToList();
|
||||
|
||||
// 批量查询奖励配置
|
||||
var rewardsDict = new Dictionary<string, List<PrizeRewardItem>>();
|
||||
if (rewardIds.Any())
|
||||
{
|
||||
var rewards = await _dbContext.Rewards
|
||||
.AsNoTracking()
|
||||
.Where(r => rewardIds.Contains(r.RewardId))
|
||||
.ToListAsync();
|
||||
|
||||
rewardsDict = rewards
|
||||
.GroupBy(r => r.RewardId)
|
||||
.ToDictionary(
|
||||
g => g.Key,
|
||||
g => g.Select(r => new PrizeRewardItem { Type = r.RewardType, Amount = (int)r.RewardValue }).ToList()
|
||||
);
|
||||
}
|
||||
|
||||
return prizes.Select(p => MapToPrizeDto(p, prizeLevels, rewardsDict)).ToList();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -362,6 +431,13 @@ public class GoodsService : IGoodsService
|
|||
var now = DateTime.Now;
|
||||
var prizeCode = GeneratePrizeCode();
|
||||
|
||||
// 处理奖励配置:如果有 rewards 配置,创建 rewards 表记录
|
||||
var rewardId = request.RewardId;
|
||||
if (request.Rewards != null && request.Rewards.Count > 0)
|
||||
{
|
||||
rewardId = await CreatePrizeRewardsAsync(prizeCode, request.Rewards, now);
|
||||
}
|
||||
|
||||
// 根据商品类型决定添加逻辑
|
||||
// 无限赏(2)、盲盒(8)、扭蛋(9)、福利屋(15)、连抽赏(16)、大乱斗(17):num = 0(模板奖品,只添加一条)
|
||||
// 一番赏(1)、擂台赏(3)、福袋(5)、幸运赏(6)、积分商城(10)、转转赏(11):为每个箱子都添加一条奖品
|
||||
|
|
@ -370,7 +446,7 @@ public class GoodsService : IGoodsService
|
|||
// 处理宝箱子奖品的情况
|
||||
if (request.GoodsListId > 0)
|
||||
{
|
||||
return await AddChildPrizeAsync(goodsId, request, now);
|
||||
return await AddChildPrizeAsync(goodsId, request, now, rewardId);
|
||||
}
|
||||
|
||||
if (templateTypes.Contains(goods.Type))
|
||||
|
|
@ -399,7 +475,7 @@ public class GoodsService : IGoodsService
|
|||
PrizeCode = prizeCode,
|
||||
Type = (byte)request.Type,
|
||||
LianJiType = (byte)request.LianJiType,
|
||||
RewardId = request.RewardId,
|
||||
RewardId = rewardId,
|
||||
Doubling = request.Doubling,
|
||||
IsLingzhu = (byte)request.IsLingzhu,
|
||||
PrizeNum = 1,
|
||||
|
|
@ -456,7 +532,7 @@ public class GoodsService : IGoodsService
|
|||
PrizeCode = prizeCode, // 同一个 prize_code,表示是同一个奖品配置
|
||||
Type = (byte)request.Type,
|
||||
LianJiType = (byte)request.LianJiType,
|
||||
RewardId = request.RewardId,
|
||||
RewardId = rewardId,
|
||||
Doubling = request.Doubling,
|
||||
IsLingzhu = (byte)request.IsLingzhu,
|
||||
PrizeNum = 1,
|
||||
|
|
@ -486,7 +562,7 @@ public class GoodsService : IGoodsService
|
|||
/// 添加宝箱子奖品
|
||||
/// 当父奖品存在于多个箱号中时,会为每个箱号的父奖品都创建对应的子奖品
|
||||
/// </summary>
|
||||
private async Task<int> AddChildPrizeAsync(int goodsId, PrizeCreateRequest request, DateTime now)
|
||||
private async Task<int> AddChildPrizeAsync(int goodsId, PrizeCreateRequest request, DateTime now, string? rewardId = null)
|
||||
{
|
||||
// 获取父奖品信息
|
||||
var parentPrize = await _dbContext.GoodsItems
|
||||
|
|
@ -506,6 +582,12 @@ public class GoodsService : IGoodsService
|
|||
|
||||
// 子奖品生成自己的 prize_code
|
||||
var childPrizeCode = GeneratePrizeCode();
|
||||
|
||||
// 如果有 rewards 配置但没有传入 rewardId,创建 rewards 表记录
|
||||
if (string.IsNullOrEmpty(rewardId) && request.Rewards != null && request.Rewards.Count > 0)
|
||||
{
|
||||
rewardId = await CreatePrizeRewardsAsync(childPrizeCode, request.Rewards, now);
|
||||
}
|
||||
|
||||
// 查找所有箱号中具有相同 prize_code 的父奖品(同一个宝箱配置在不同箱号中的记录)
|
||||
var sameParentPrizes = await _dbContext.GoodsItems
|
||||
|
|
@ -542,7 +624,7 @@ public class GoodsService : IGoodsService
|
|||
PrizeCode = childPrizeCode, // 子奖品使用自己的 prize_code
|
||||
Type = (byte)request.Type,
|
||||
LianJiType = (byte)request.LianJiType,
|
||||
RewardId = request.RewardId,
|
||||
RewardId = rewardId,
|
||||
Doubling = request.Doubling,
|
||||
IsLingzhu = (byte)request.IsLingzhu,
|
||||
PrizeNum = 1,
|
||||
|
|
@ -572,6 +654,17 @@ public class GoodsService : IGoodsService
|
|||
throw new BusinessException(BusinessErrorCodes.NotFound, "奖品不存在");
|
||||
}
|
||||
|
||||
var now = DateTime.Now;
|
||||
|
||||
// 处理奖励配置:如果有 rewards 配置,创建/更新 rewards 表记录
|
||||
var rewardId = request.RewardId;
|
||||
if (request.Rewards != null && request.Rewards.Count > 0)
|
||||
{
|
||||
// 使用现有的 prize_code 或生成新的
|
||||
var prizeCode = prize.PrizeCode ?? GeneratePrizeCode();
|
||||
rewardId = await CreatePrizeRewardsAsync(prizeCode, request.Rewards, now);
|
||||
}
|
||||
|
||||
prize.Title = request.Title;
|
||||
prize.ImgUrl = request.ImgUrl;
|
||||
prize.ImgUrlDetail = request.ImgUrlDetail;
|
||||
|
|
@ -590,10 +683,10 @@ public class GoodsService : IGoodsService
|
|||
prize.CardNo = request.CardNo;
|
||||
prize.Type = (byte)request.Type;
|
||||
prize.LianJiType = (byte)request.LianJiType;
|
||||
prize.RewardId = request.RewardId;
|
||||
prize.RewardId = rewardId;
|
||||
prize.Doubling = request.Doubling;
|
||||
prize.IsLingzhu = (byte)request.IsLingzhu;
|
||||
prize.UpdatedAt = DateTime.Now;
|
||||
prize.UpdatedAt = now;
|
||||
|
||||
var result = await _dbContext.SaveChangesAsync() > 0;
|
||||
|
||||
|
|
@ -944,7 +1037,7 @@ public class GoodsService : IGoodsService
|
|||
/// <summary>
|
||||
/// 映射奖品到DTO
|
||||
/// </summary>
|
||||
private PrizeDto MapToPrizeDto(GoodsItem prize, Dictionary<int, PrizeLevelInfo>? prizeLevels = null)
|
||||
private PrizeDto MapToPrizeDto(GoodsItem prize, Dictionary<int, PrizeLevelInfo>? prizeLevels = null, Dictionary<string, List<PrizeRewardItem>>? rewardsDict = null)
|
||||
{
|
||||
string? shangTitle = null;
|
||||
string? shangColor = null;
|
||||
|
|
@ -955,6 +1048,13 @@ public class GoodsService : IGoodsService
|
|||
shangColor = level.Color;
|
||||
}
|
||||
|
||||
// 获取奖励配置
|
||||
List<PrizeRewardItem>? rewards = null;
|
||||
if (!string.IsNullOrEmpty(prize.RewardId) && rewardsDict != null && rewardsDict.TryGetValue(prize.RewardId, out var rewardList))
|
||||
{
|
||||
rewards = rewardList;
|
||||
}
|
||||
|
||||
return new PrizeDto
|
||||
{
|
||||
Id = prize.Id,
|
||||
|
|
@ -985,6 +1085,7 @@ public class GoodsService : IGoodsService
|
|||
Doubling = prize.Doubling,
|
||||
IsLingzhu = prize.IsLingzhu,
|
||||
GoodsListId = prize.GoodsListId,
|
||||
Rewards = rewards,
|
||||
CreatedAt = prize.CreatedAt,
|
||||
UpdatedAt = prize.UpdatedAt
|
||||
};
|
||||
|
|
|
|||
|
|
@ -245,11 +245,18 @@ export interface PrizeItem {
|
|||
doubling: number
|
||||
isLingzhu: number
|
||||
goodsListId: number // 父奖品ID,0表示父奖品,>0表示子奖品
|
||||
rewards?: PrizeRewardItem[] // 奖励配置
|
||||
createdAt: string | null
|
||||
updatedAt: string
|
||||
children?: PrizeItem[] // 子奖品列表(前端构建树形结构用)
|
||||
}
|
||||
|
||||
/** 奖品奖励配置项 */
|
||||
export interface PrizeRewardItem {
|
||||
type: number // 奖励类型:1=钻石 2=UU币 3=哈尼券
|
||||
amount: number // 数量
|
||||
}
|
||||
|
||||
/** 创建奖品请求 */
|
||||
export interface PrizeCreateRequest {
|
||||
title: string
|
||||
|
|
@ -273,6 +280,7 @@ export interface PrizeCreateRequest {
|
|||
doubling: number
|
||||
isLingzhu: number
|
||||
goodsListId?: number // 父奖品ID,添加宝箱子奖品时使用
|
||||
rewards?: PrizeRewardItem[] // 奖励配置
|
||||
}
|
||||
|
||||
/** 更新奖品请求 */
|
||||
|
|
|
|||
|
|
@ -168,36 +168,9 @@
|
|||
<!-- 赠送货币配置 -->
|
||||
<el-divider content-position="left">赠送配置</el-divider>
|
||||
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="8">
|
||||
<el-form-item label="赠送余额">
|
||||
<el-input-number
|
||||
v-model="formData.giveMoney"
|
||||
:min="0"
|
||||
style="width: 100%"
|
||||
placeholder="赠送余额"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="赠送积分">
|
||||
<el-input-number
|
||||
v-model="formData.rewardNum"
|
||||
:min="0"
|
||||
style="width: 100%"
|
||||
placeholder="赠送积分"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="奖励ID">
|
||||
<el-input
|
||||
v-model="formData.rewardId"
|
||||
placeholder="奖励配置ID"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-form-item label="赠送奖励">
|
||||
<PrizeRewardConfig v-model="formData.rewards" />
|
||||
</el-form-item>
|
||||
|
||||
<!-- 连击赏配置 -->
|
||||
<el-row :gutter="20" v-if="showLianji">
|
||||
|
|
@ -255,6 +228,12 @@ import {
|
|||
} from '@/api/business/goods'
|
||||
import { getPrizeLevelOptionsByType, type PrizeLevelOptionResponse } from '@/api/business/prizelevel'
|
||||
import ImageUpload from '@/components/ImageUpload/index.vue'
|
||||
import PrizeRewardConfig from './PrizeRewardConfig.vue'
|
||||
|
||||
interface RewardItem {
|
||||
type: number
|
||||
amount: number
|
||||
}
|
||||
|
||||
interface Props {
|
||||
modelValue: boolean
|
||||
|
|
@ -346,6 +325,7 @@ const formData = reactive({
|
|||
cardNo: '',
|
||||
lianJiType: 0,
|
||||
rewardId: '',
|
||||
rewards: [] as RewardItem[],
|
||||
})
|
||||
|
||||
// 表单验证规则
|
||||
|
|
@ -382,6 +362,7 @@ const resetForm = () => {
|
|||
formData.cardNo = ''
|
||||
formData.lianJiType = 0
|
||||
formData.rewardId = ''
|
||||
formData.rewards = []
|
||||
formRef.value?.resetFields()
|
||||
}
|
||||
|
||||
|
|
@ -435,6 +416,7 @@ const handleSubmit = async () => {
|
|||
doubling: formData.doubling,
|
||||
isLingzhu: formData.isLingzhu,
|
||||
goodsListId: props.parentPrizeId, // 父奖品ID
|
||||
rewards: formData.rewards.length > 0 ? formData.rewards : undefined,
|
||||
}
|
||||
|
||||
await addPrize(props.goodsId, requestData)
|
||||
|
|
|
|||
|
|
@ -169,36 +169,9 @@
|
|||
<!-- 赠送货币配置 -->
|
||||
<el-divider content-position="left">赠送配置</el-divider>
|
||||
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="8">
|
||||
<el-form-item label="赠送余额">
|
||||
<el-input-number
|
||||
v-model="formData.giveMoney"
|
||||
:min="0"
|
||||
style="width: 100%"
|
||||
placeholder="赠送余额"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="赠送积分">
|
||||
<el-input-number
|
||||
v-model="formData.rewardNum"
|
||||
:min="0"
|
||||
style="width: 100%"
|
||||
placeholder="赠送积分"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="奖励ID">
|
||||
<el-input
|
||||
v-model="formData.rewardId"
|
||||
placeholder="奖励配置ID"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-form-item label="赠送奖励">
|
||||
<PrizeRewardConfig v-model="formData.rewards" />
|
||||
</el-form-item>
|
||||
|
||||
<!-- 连击赏配置 -->
|
||||
<el-row :gutter="20" v-if="showLianji">
|
||||
|
|
@ -263,6 +236,12 @@ import {
|
|||
} from '@/api/business/goods'
|
||||
import { getPrizeLevelOptionsByType, type PrizeLevelOptionResponse } from '@/api/business/prizelevel'
|
||||
import ImageUpload from '@/components/ImageUpload/index.vue'
|
||||
import PrizeRewardConfig from './PrizeRewardConfig.vue'
|
||||
|
||||
interface RewardItem {
|
||||
type: number
|
||||
amount: number
|
||||
}
|
||||
|
||||
interface Props {
|
||||
modelValue: boolean
|
||||
|
|
@ -342,6 +321,7 @@ const formData = reactive({
|
|||
cardNo: '',
|
||||
lianJiType: 0,
|
||||
rewardId: '',
|
||||
rewards: [] as RewardItem[],
|
||||
})
|
||||
|
||||
// 表单验证规则
|
||||
|
|
@ -377,6 +357,12 @@ const fillFormData = (data: PrizeItem) => {
|
|||
formData.cardNo = data.cardNo || ''
|
||||
formData.lianJiType = data.lianJiType
|
||||
formData.rewardId = data.rewardId || ''
|
||||
// 加载奖励配置
|
||||
if (data.rewards && data.rewards.length > 0) {
|
||||
formData.rewards = data.rewards.map(r => ({ type: r.type, amount: r.amount }))
|
||||
} else {
|
||||
formData.rewards = []
|
||||
}
|
||||
}
|
||||
|
||||
// 重置表单
|
||||
|
|
@ -402,6 +388,7 @@ const resetForm = () => {
|
|||
formData.cardNo = ''
|
||||
formData.lianJiType = 0
|
||||
formData.rewardId = ''
|
||||
formData.rewards = []
|
||||
formRef.value?.resetFields()
|
||||
}
|
||||
|
||||
|
|
@ -458,6 +445,7 @@ const handleSubmit = async () => {
|
|||
rewardId: formData.rewardId || undefined,
|
||||
doubling: formData.doubling,
|
||||
isLingzhu: formData.isLingzhu,
|
||||
rewards: formData.rewards.length > 0 ? formData.rewards : undefined,
|
||||
}
|
||||
|
||||
await updatePrize(props.prizeId, requestData)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,119 @@
|
|||
<template>
|
||||
<div class="prize-reward-config">
|
||||
<div v-for="(item, index) in rewardList" :key="index" class="reward-item">
|
||||
<el-select
|
||||
v-model="item.type"
|
||||
placeholder="奖励类型"
|
||||
style="width: 120px"
|
||||
@change="handleChange"
|
||||
>
|
||||
<el-option
|
||||
v-for="opt in rewardTypeOptions"
|
||||
:key="opt.value"
|
||||
:label="opt.label"
|
||||
:value="opt.value"
|
||||
/>
|
||||
</el-select>
|
||||
<el-input-number
|
||||
v-model="item.amount"
|
||||
:min="0"
|
||||
:max="999999999"
|
||||
placeholder="数量"
|
||||
style="width: 150px; margin-left: 8px"
|
||||
@change="handleChange"
|
||||
/>
|
||||
<el-button
|
||||
type="danger"
|
||||
:icon="Delete"
|
||||
circle
|
||||
size="small"
|
||||
style="margin-left: 8px"
|
||||
@click="removeItem(index)"
|
||||
/>
|
||||
</div>
|
||||
<el-button type="primary" link @click="addItem" style="margin-top: 8px">
|
||||
<el-icon><Plus /></el-icon>添加奖励
|
||||
</el-button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, watch, onMounted } from 'vue'
|
||||
import { Plus, Delete } from '@element-plus/icons-vue'
|
||||
|
||||
interface RewardItem {
|
||||
type: number
|
||||
amount: number
|
||||
}
|
||||
|
||||
interface Props {
|
||||
modelValue: RewardItem[]
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
modelValue: () => []
|
||||
})
|
||||
|
||||
const emit = defineEmits<{
|
||||
(e: 'update:modelValue', value: RewardItem[]): void
|
||||
}>()
|
||||
|
||||
// 奖励类型选项
|
||||
const rewardTypeOptions = [
|
||||
{ label: '钻石', value: 1 },
|
||||
{ label: 'HH币', value: 2 },
|
||||
{ label: '哈尼券', value: 3 }
|
||||
]
|
||||
|
||||
// 内部数据
|
||||
const rewardList = ref<RewardItem[]>([])
|
||||
|
||||
// 监听外部值变化
|
||||
watch(() => props.modelValue, (newVal) => {
|
||||
if (Array.isArray(newVal) && newVal.length > 0) {
|
||||
rewardList.value = newVal.map(item => ({ ...item }))
|
||||
} else {
|
||||
rewardList.value = []
|
||||
}
|
||||
}, { immediate: true, deep: true })
|
||||
|
||||
// 处理变化
|
||||
const handleChange = () => {
|
||||
// 过滤掉数量为0的项
|
||||
const validList = rewardList.value.filter(item => item.amount > 0)
|
||||
emit('update:modelValue', validList)
|
||||
}
|
||||
|
||||
// 添加奖励配置
|
||||
const addItem = () => {
|
||||
rewardList.value.push({ type: 1, amount: 0 })
|
||||
}
|
||||
|
||||
// 移除奖励配置
|
||||
const removeItem = (index: number) => {
|
||||
rewardList.value.splice(index, 1)
|
||||
handleChange()
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
if (Array.isArray(props.modelValue) && props.modelValue.length > 0) {
|
||||
rewardList.value = props.modelValue.map(item => ({ ...item }))
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.prize-reward-config {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.reward-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.reward-item:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -120,8 +120,8 @@ export const defaultFieldConfig: GoodsTypeFieldConfig = {
|
|||
showLianji: false,
|
||||
showTimeConfig: false,
|
||||
showAutoXiajia: false,
|
||||
showCoupon: true,
|
||||
showIntegral: true,
|
||||
showCoupon: false,
|
||||
showIntegral: false,
|
||||
showDescription: false,
|
||||
showQuanjuXiangou: false,
|
||||
showShowIs: true,
|
||||
|
|
@ -148,7 +148,7 @@ export const GoodsTypeFieldConfigs: Record<number, GoodsTypeFieldConfig> = {
|
|||
showStock: true, showLock: true, showDailyLimit: true,
|
||||
showRage: false, showItemCard: false, showLingzhu: false,
|
||||
showLianji: false, showTimeConfig: false, showAutoXiajia: false,
|
||||
showCoupon: true, showIntegral: true, showDescription: false,
|
||||
showCoupon: false, showIntegral: false, showDescription: false,
|
||||
showQuanjuXiangou: false, showShowIs: true, showUnlockAmount: true,
|
||||
showCoverImage: true, showDetailImage: true,
|
||||
showPrice: true, showShouZhe: true,
|
||||
|
|
@ -158,7 +158,7 @@ export const GoodsTypeFieldConfigs: Record<number, GoodsTypeFieldConfig> = {
|
|||
showStock: false, showLock: false, showDailyLimit: false,
|
||||
showRage: false, showItemCard: false, showLingzhu: false,
|
||||
showLianji: false, showTimeConfig: false, showAutoXiajia: false,
|
||||
showCoupon: true, showIntegral: true, showDescription: false,
|
||||
showCoupon: false, showIntegral: false, showDescription: false,
|
||||
showQuanjuXiangou: false, showShowIs: false, showUnlockAmount: true,
|
||||
showCoverImage: true, showDetailImage: true,
|
||||
showPrice: true, showShouZhe: true,
|
||||
|
|
|
|||
|
|
@ -89,6 +89,14 @@ public class WelfareLotteryService : BackgroundService
|
|||
.Where(gi => gi.GoodsId == goods.Id && gi.Num == 0)
|
||||
.ToListAsync(stoppingToken);
|
||||
|
||||
// 添加调试日志:输出所有奖品信息
|
||||
_logger.LogInformation("福利屋奖品列表: GoodsId={GoodsId}, 奖品数量={Count}", goods.Id, prizeList.Count);
|
||||
foreach (var p in prizeList)
|
||||
{
|
||||
_logger.LogInformation(" 奖品: Id={Id}, Title={Title}, GoodsType={GoodsType}, RewardId={RewardId}, Stock={Stock}, SurplusStock={SurplusStock}, ScMoney={ScMoney}",
|
||||
p.Id, p.Title, p.GoodsType, p.RewardId ?? "(空)", p.Stock, p.SurplusStock, p.ScMoney);
|
||||
}
|
||||
|
||||
// 展开奖品列表(根据库存数量)
|
||||
var expandedPrizes = new List<GoodsItem>();
|
||||
foreach (var prize in prizeList)
|
||||
|
|
@ -176,9 +184,14 @@ public class WelfareLotteryService : BackgroundService
|
|||
}
|
||||
|
||||
// 发放奖励
|
||||
// 添加调试日志
|
||||
_logger.LogInformation("准备发放奖励: PrizeId={PrizeId}, Title={Title}, GoodsType={GoodsType}, RewardId={RewardId}, ScMoney={ScMoney}, UserId={UserId}",
|
||||
prize.Id, prize.Title, prize.GoodsType, prize.RewardId ?? "(空)", prize.ScMoney, participant.UserId);
|
||||
|
||||
// 1. 如果有reward_id(字符串类型奖励码),通过奖励配置发放
|
||||
if (!string.IsNullOrEmpty(prize.RewardId))
|
||||
{
|
||||
_logger.LogInformation("尝试通过RewardId发放奖励: RewardId={RewardId}", prize.RewardId);
|
||||
var rewardSent = await SendRewardByCodeAsync(dbContext, participant.UserId, prize.RewardId,
|
||||
$"{goods.Title}开奖-{prize.Title}", stoppingToken);
|
||||
if (rewardSent)
|
||||
|
|
@ -188,13 +201,14 @@ public class WelfareLotteryService : BackgroundService
|
|||
}
|
||||
else
|
||||
{
|
||||
_logger.LogWarning("奖励配置不存在: GoodsId={GoodsId}, UserId={UserId}, Prize={Prize}, RewardCode={RewardCode}",
|
||||
_logger.LogWarning("奖励配置不存在或发放失败: GoodsId={GoodsId}, UserId={UserId}, Prize={Prize}, RewardCode={RewardCode}",
|
||||
goods.Id, participant.UserId, prize.Title, prize.RewardId);
|
||||
}
|
||||
}
|
||||
// 2. 如果是货币类型奖品(GoodsType=3)且没有reward_id,直接发放ScMoney金额
|
||||
else if (prize.GoodsType == 3 && prize.ScMoney > 0)
|
||||
{
|
||||
_logger.LogInformation("尝试通过GoodsType=3发放货币奖品: ScMoney={ScMoney}", prize.ScMoney);
|
||||
await SendCurrencyPrizeAsync(dbContext, participant.UserId, prize.ScMoney,
|
||||
$"{goods.Title}开奖-{prize.Title}", stoppingToken);
|
||||
_logger.LogInformation("发放货币奖品成功: GoodsId={GoodsId}, UserId={UserId}, Prize={Prize}, Amount={Amount}",
|
||||
|
|
@ -202,8 +216,8 @@ public class WelfareLotteryService : BackgroundService
|
|||
}
|
||||
else
|
||||
{
|
||||
_logger.LogInformation("发放奖品成功: GoodsId={GoodsId}, UserId={UserId}, Prize={Prize}",
|
||||
goods.Id, participant.UserId, prize.Title);
|
||||
_logger.LogInformation("实物奖品,无需发放货币: GoodsId={GoodsId}, UserId={UserId}, Prize={Prize}, GoodsType={GoodsType}",
|
||||
goods.Id, participant.UserId, prize.Title, prize.GoodsType);
|
||||
}
|
||||
|
||||
prizeIndex++;
|
||||
|
|
@ -240,6 +254,7 @@ public class WelfareLotteryService : BackgroundService
|
|||
|
||||
/// <summary>
|
||||
/// 通过奖励码发放奖励
|
||||
/// 支持同一个 reward_id 对应多条奖励记录(如同时赠送钻石和积分)
|
||||
/// </summary>
|
||||
/// <param name="dbContext">数据库上下文</param>
|
||||
/// <param name="userId">用户ID</param>
|
||||
|
|
@ -254,17 +269,28 @@ public class WelfareLotteryService : BackgroundService
|
|||
string remark,
|
||||
CancellationToken stoppingToken)
|
||||
{
|
||||
// 通过奖励码查询奖励配置
|
||||
var reward = await dbContext.Rewards
|
||||
_logger.LogInformation("SendRewardByCodeAsync开始: UserId={UserId}, RewardCode={RewardCode}", userId, rewardCode);
|
||||
|
||||
// 通过奖励码查询所有奖励配置(同一个 reward_id 可能有多条记录)
|
||||
var rewards = await dbContext.Rewards
|
||||
.Where(r => r.RewardId == rewardCode)
|
||||
.FirstOrDefaultAsync(stoppingToken);
|
||||
.ToListAsync(stoppingToken);
|
||||
|
||||
if (reward == null)
|
||||
_logger.LogInformation("查询rewards表结果: RewardCode={RewardCode}, 找到记录数={Count}", rewardCode, rewards?.Count ?? 0);
|
||||
|
||||
if (rewards == null || rewards.Count == 0)
|
||||
{
|
||||
_logger.LogWarning("奖励配置不存在: RewardCode={RewardCode}", rewardCode);
|
||||
return false;
|
||||
}
|
||||
|
||||
// 输出每条奖励记录的详情
|
||||
foreach (var r in rewards)
|
||||
{
|
||||
_logger.LogInformation(" 奖励记录: Id={Id}, RewardId={RewardId}, RewardType={RewardType}, RewardValue={RewardValue}",
|
||||
r.Id, r.RewardId, r.RewardType, r.RewardValue);
|
||||
}
|
||||
|
||||
var user = await dbContext.Users
|
||||
.Where(u => u.Id == userId)
|
||||
.FirstOrDefaultAsync(stoppingToken);
|
||||
|
|
@ -275,74 +301,86 @@ public class WelfareLotteryService : BackgroundService
|
|||
return false;
|
||||
}
|
||||
|
||||
var rewardTypeName = "";
|
||||
_logger.LogInformation("用户当前余额: UserId={UserId}, Money={Money}, Integral={Integral}, Money2={Money2}",
|
||||
userId, user.Money, user.Integral, user.Money2);
|
||||
|
||||
// 根据奖励类型发放
|
||||
switch (reward.RewardType)
|
||||
var rewardDetails = new List<string>();
|
||||
|
||||
// 遍历所有奖励记录,根据类型发放
|
||||
foreach (var reward in rewards)
|
||||
{
|
||||
case 1: // 钻石/余额 (HH币)
|
||||
user.Money += reward.RewardValue;
|
||||
// 记录流水
|
||||
dbContext.ProfitMoneys.Add(new ProfitMoney
|
||||
{
|
||||
UserId = userId,
|
||||
ChangeMoney = reward.RewardValue,
|
||||
Money = user.Money,
|
||||
Type = 6, // 签到赠送/福利奖励
|
||||
Content = remark,
|
||||
ShareUid = 0,
|
||||
CreatedAt = DateTime.Now
|
||||
});
|
||||
rewardTypeName = "钻石/HH币";
|
||||
_logger.LogInformation("发放钻石: UserId={UserId}, Amount={Amount}, After={After}, Remark={Remark}",
|
||||
userId, reward.RewardValue, user.Money, remark);
|
||||
break;
|
||||
switch (reward.RewardType)
|
||||
{
|
||||
case 1: // 钻石
|
||||
user.Money += reward.RewardValue;
|
||||
// 记录流水
|
||||
dbContext.ProfitMoneys.Add(new ProfitMoney
|
||||
{
|
||||
UserId = userId,
|
||||
ChangeMoney = reward.RewardValue,
|
||||
Money = user.Money,
|
||||
Type = 6, // 签到赠送/福利奖励
|
||||
Content = remark,
|
||||
ShareUid = 0,
|
||||
CreatedAt = DateTime.Now
|
||||
});
|
||||
rewardDetails.Add($"钻石{reward.RewardValue}");
|
||||
_logger.LogInformation("发放钻石: UserId={UserId}, Amount={Amount}, After={After}, Remark={Remark}",
|
||||
userId, reward.RewardValue, user.Money, remark);
|
||||
break;
|
||||
|
||||
case 2: // 积分/UU币
|
||||
user.Integral += reward.RewardValue;
|
||||
// 记录流水
|
||||
dbContext.ProfitIntegrals.Add(new ProfitIntegral
|
||||
{
|
||||
UserId = userId,
|
||||
ChangeMoney = reward.RewardValue,
|
||||
Money = user.Integral,
|
||||
Type = 4, // 抽赏奖励
|
||||
Content = remark,
|
||||
ShareUid = 0,
|
||||
CreatedAt = DateTime.Now
|
||||
});
|
||||
rewardTypeName = "积分/UU币";
|
||||
_logger.LogInformation("发放积分: UserId={UserId}, Amount={Amount}, After={After}, Remark={Remark}",
|
||||
userId, reward.RewardValue, user.Integral, remark);
|
||||
break;
|
||||
case 2: // HH币
|
||||
user.Integral += reward.RewardValue;
|
||||
// 记录流水
|
||||
dbContext.ProfitIntegrals.Add(new ProfitIntegral
|
||||
{
|
||||
UserId = userId,
|
||||
ChangeMoney = reward.RewardValue,
|
||||
Money = user.Integral,
|
||||
Type = 4, // 抽赏奖励
|
||||
Content = remark,
|
||||
ShareUid = 0,
|
||||
CreatedAt = DateTime.Now
|
||||
});
|
||||
rewardDetails.Add($"HH币{reward.RewardValue}");
|
||||
_logger.LogInformation("发放HH币: UserId={UserId}, Amount={Amount}, After={After}, Remark={Remark}",
|
||||
userId, reward.RewardValue, user.Integral, remark);
|
||||
break;
|
||||
|
||||
case 3: // 哈尼券/达达卷
|
||||
user.Money2 = (user.Money2 ?? 0) + reward.RewardValue;
|
||||
// 记录流水
|
||||
dbContext.ProfitMoney2s.Add(new ProfitMoney2
|
||||
{
|
||||
UserId = userId,
|
||||
ChangeMoney = reward.RewardValue,
|
||||
Money = user.Money2 ?? 0,
|
||||
Type = 5, // 推荐奖励/福利奖励
|
||||
Content = remark,
|
||||
ShareUid = 0,
|
||||
CreatedAt = DateTime.Now
|
||||
});
|
||||
rewardTypeName = "哈尼券";
|
||||
_logger.LogInformation("发放哈尼券: UserId={UserId}, Amount={Amount}, After={After}, Remark={Remark}",
|
||||
userId, reward.RewardValue, user.Money2, remark);
|
||||
break;
|
||||
case 3: // 哈尼券
|
||||
user.Money2 = (user.Money2 ?? 0) + reward.RewardValue;
|
||||
// 记录流水
|
||||
dbContext.ProfitMoney2s.Add(new ProfitMoney2
|
||||
{
|
||||
UserId = userId,
|
||||
ChangeMoney = reward.RewardValue,
|
||||
Money = user.Money2 ?? 0,
|
||||
Type = 5, // 推荐奖励/福利奖励
|
||||
Content = remark,
|
||||
ShareUid = 0,
|
||||
CreatedAt = DateTime.Now
|
||||
});
|
||||
rewardDetails.Add($"哈尼券{reward.RewardValue}");
|
||||
_logger.LogInformation("发放哈尼券: UserId={UserId}, Amount={Amount}, After={After}, Remark={Remark}",
|
||||
userId, reward.RewardValue, user.Money2, remark);
|
||||
break;
|
||||
|
||||
default:
|
||||
_logger.LogWarning("未知奖励类型: Type={Type}, RewardCode={RewardCode}", reward.RewardType, rewardCode);
|
||||
return false;
|
||||
default:
|
||||
_logger.LogWarning("未知奖励类型: Type={Type}, RewardCode={RewardCode}", reward.RewardType, rewardCode);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (rewardDetails.Count == 0)
|
||||
{
|
||||
_logger.LogWarning("没有有效的奖励类型: RewardCode={RewardCode}", rewardCode);
|
||||
return false;
|
||||
}
|
||||
|
||||
await dbContext.SaveChangesAsync(stoppingToken);
|
||||
|
||||
_logger.LogInformation("福利屋奖励发放成功: UserId={UserId}, RewardCode={RewardCode}, Type={Type}, Value={Value}, Remark={Remark}",
|
||||
userId, rewardCode, rewardTypeName, reward.RewardValue, remark);
|
||||
_logger.LogInformation("福利屋奖励发放成功: UserId={UserId}, RewardCode={RewardCode}, Rewards={Rewards}, Remark={Remark}",
|
||||
userId, rewardCode, string.Join("+", rewardDetails), remark);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -123,16 +123,16 @@ public class RewardService : IRewardService
|
|||
detail.Message = $"获得钻石*{rewardValue}";
|
||||
break;
|
||||
|
||||
case 2: // UU币 (Integral)
|
||||
case 2: // HH币 (Integral)
|
||||
await AddIntegralAsync(userId, user, rewardValue, source);
|
||||
detail.Success = true;
|
||||
detail.Message = $"获得UU币*{rewardValue}";
|
||||
detail.Message = $"获得HH币*{rewardValue}";
|
||||
break;
|
||||
|
||||
case 3: // 达达券 (Money2)
|
||||
case 3: // 哈尼券 (Money2)
|
||||
await AddMoney2Async(userId, user, rewardValue, source);
|
||||
detail.Success = true;
|
||||
detail.Message = $"获得达达券*{rewardValue}";
|
||||
detail.Message = $"获得哈尼券*{rewardValue}";
|
||||
break;
|
||||
|
||||
case 4: // 优惠券
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user