抽奖新增连抽功能

This commit is contained in:
tianfeng 2025-10-20 11:01:42 +08:00
parent 8976ce27df
commit 5b42ea8840
10 changed files with 620 additions and 3 deletions

View File

@ -157,6 +157,11 @@ public enum LotteryErrorCode implements IResponseErrorCode {
*/
USER_DRAW_COUNT_UPDATE_FAILED(9729, "Failed to update user draw count"),
/**
* 活动未启用连抽功能.
*/
MULTI_DRAW_NOT_ENABLED(9730, "Multi-draw feature is not enabled for this activity"),
;
private final Integer code;

View File

@ -6,9 +6,11 @@ import com.red.circle.framework.web.controller.BaseController;
import com.red.circle.other.app.dto.clientobject.activity.LotteryActivityCO;
import com.red.circle.other.app.dto.clientobject.activity.LotteryActivityDetailCO;
import com.red.circle.other.app.dto.clientobject.activity.LotteryDrawResultCO;
import com.red.circle.other.app.dto.clientobject.activity.LotteryMultiDrawResultCO;
import com.red.circle.other.app.dto.clientobject.activity.LotteryRecordCO;
import com.red.circle.other.app.dto.clientobject.activity.LotteryTicketCO;
import com.red.circle.other.app.dto.cmd.activity.LotteryDrawCmd;
import com.red.circle.other.app.dto.cmd.activity.LotteryMultiDrawCmd;
import com.red.circle.other.app.dto.cmd.activity.LotteryRecordQryCmd;
import com.red.circle.other.app.service.activity.LotteryActivityRestService;
@ -82,6 +84,19 @@ public class LotteryActivityRestController extends BaseController {
return lotteryActivityRestService.draw(cmd);
}
/**
* 执行连抽.
*
* @eo.name 执行连抽.
* @eo.url /multi-draw
* @eo.method post
* @eo.request-type json
*/
@PostMapping("/multi-draw")
public LotteryMultiDrawResultCO multiDraw(@RequestBody @Validated LotteryMultiDrawCmd cmd) {
return lotteryActivityRestService.multiDraw(cmd);
}
/**
* 查询我的中奖记录.
*

View File

@ -0,0 +1,426 @@
package com.red.circle.other.app.command.activity;
import com.red.circle.framework.core.asserts.ResponseAssert;
import com.red.circle.other.app.dto.clientobject.activity.LotteryDrawResultCO;
import com.red.circle.other.app.dto.clientobject.activity.LotteryMultiDrawResultCO;
import com.red.circle.other.app.dto.clientobject.activity.LotteryPrizeCO;
import com.red.circle.other.app.dto.cmd.activity.LotteryMultiDrawCmd;
import com.red.circle.other.infra.database.rds.entity.activity.LotteryActivity;
import com.red.circle.other.infra.database.rds.entity.activity.LotteryPrize;
import com.red.circle.other.infra.database.rds.entity.activity.LotteryRecord;
import com.red.circle.other.infra.database.rds.entity.activity.LotteryTicket;
import com.red.circle.other.infra.database.rds.entity.activity.LotteryTicketRecord;
import com.red.circle.other.infra.database.rds.entity.activity.LotteryUserCount;
import com.red.circle.other.infra.database.rds.service.activity.LotteryActivityService;
import com.red.circle.other.infra.database.rds.service.activity.LotteryPrizeService;
import com.red.circle.other.infra.database.rds.service.activity.LotteryRecordService;
import com.red.circle.other.infra.database.rds.service.activity.LotteryTicketRecordService;
import com.red.circle.other.infra.database.rds.service.activity.LotteryTicketService;
import com.red.circle.other.infra.database.rds.service.activity.LotteryUserCountService;
import com.red.circle.other.inner.asserts.lottery.LotteryErrorCode;
import com.red.circle.tool.core.date.TimestampUtils;
import java.math.BigDecimal;
import java.sql.Timestamp;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ThreadLocalRandom;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
/**
* 执行连抽.
*
* @author system
* @since 2025-10-20
*/
@Slf4j
@Component
@RequiredArgsConstructor
public class LotteryMultiDrawExe {
private final LotteryActivityService lotteryActivityService;
private final LotteryPrizeService lotteryPrizeService;
private final LotteryRecordService lotteryRecordService;
private final LotteryTicketService lotteryTicketService;
private final LotteryTicketRecordService lotteryTicketRecordService;
private final LotteryUserCountService lotteryUserCountService;
@Transactional(rollbackFor = Exception.class)
public LotteryMultiDrawResultCO execute(LotteryMultiDrawCmd cmd) {
Long userId = cmd.requiredReqUserId();
Long activityId = cmd.getActivityId();
Integer drawCount = cmd.getDrawCount();
Timestamp now = TimestampUtils.now();
// 1. 校验活动
LotteryActivity activity = validateActivity(activityId, now);
// 2. 校验是否启用连抽
ResponseAssert.isTrue(LotteryErrorCode.MULTI_DRAW_NOT_ENABLED,
activity.getEnableMultiDraw() != null && activity.getEnableMultiDraw() == 1);
// 3. 校验抽奖次数限制需要剩余足够次数
validateDrawCount(userId, activityId, activity, drawCount);
// 4. 校验并扣除抽奖券连抽消耗更少
Integer ticketCost = activity.getMultiDrawTicketCost() != null
? activity.getMultiDrawTicketCost()
: drawCount * activity.getTicketCost();
if (activity.getNeedTicket() == 1) {
deductTicket(userId, ticketCost);
}
// 5. 生成批次号
String batchNo = generateBatchNo();
// 6. 执行连抽
List<LotteryDrawResultCO> results = new ArrayList<>();
boolean guaranteeTriggered = false;
// 前N-1次正常抽奖使用连抽概率
for (int i = 0; i < drawCount - 1; i++) {
LotteryPrize prize = drawPrizeWithMultiProbability(activityId);
// 扣减库存
if (prize != null) {
deductPrizeStock(prize.getId());
}
// 保存记录
LotteryRecord record = saveDrawRecord(userId, activityId, prize, now, batchNo, 2);
results.add(convertToResultCO(record, prize));
}
// 最后一次检查是否需要保底
BigDecimal totalAmount = calculateTotalAmount(results);
BigDecimal guaranteeMinAmount = activity.getMultiDrawGuaranteeMinAmount() != null
? activity.getMultiDrawGuaranteeMinAmount()
: BigDecimal.ZERO;
LotteryPrize lastPrize;
if (totalAmount.compareTo(guaranteeMinAmount) < 0) {
// 触发保底
guaranteeTriggered = true;
lastPrize = getGuaranteePrize(activityId, activity.getMultiDrawGuaranteePrizeId());
log.info("Multi-draw guarantee triggered, userId: {}, activityId: {}", userId, activityId);
} else {
// 正常抽奖
lastPrize = drawPrizeWithMultiProbability(activityId);
}
// 扣减库存
if (lastPrize != null) {
deductPrizeStock(lastPrize.getId());
}
// 保存最后一次记录
LotteryRecord lastRecord = saveDrawRecord(userId, activityId, lastPrize, now, batchNo, 2);
results.add(convertToResultCO(lastRecord, lastPrize));
// 7. 更新用户抽奖次数+drawCount次
updateUserDrawCount(userId, activityId, drawCount);
// 8. 组装返回结果
return buildMultiDrawResult(batchNo, results, guaranteeTriggered);
}
/**
* 校验活动状态和时间.
*/
private LotteryActivity validateActivity(Long activityId, Timestamp now) {
LotteryActivity activity = lotteryActivityService.getById(activityId);
ResponseAssert.isTrue(LotteryErrorCode.ACTIVITY_NOT_FOUND, activity != null);
ResponseAssert.isTrue(LotteryErrorCode.ACTIVITY_CLOSED, activity.getStatus() == 1);
ResponseAssert.isTrue(LotteryErrorCode.NOT_IN_ACTIVITY_TIME,
now.after(activity.getStartTime()) && now.before(activity.getEndTime()));
return activity;
}
/**
* 校验抽奖次数限制.
*/
private void validateDrawCount(Long userId, Long activityId, LotteryActivity activity, Integer drawCount) {
if (activity.getDrawCountLimit() == null || activity.getDrawCountLimit() <= 0) {
return; // 无限制
}
LotteryUserCount userCount = lotteryUserCountService.query()
.eq(LotteryUserCount::getUserId, userId)
.eq(LotteryUserCount::getActivityId, activityId)
.eq(LotteryUserCount::getDrawDate, LocalDate.now())
.getOne();
int currentDrawCount = userCount != null ? userCount.getDrawCount() : 0;
ResponseAssert.isTrue(LotteryErrorCode.DRAW_COUNT_EXHAUSTED,
currentDrawCount + drawCount <= activity.getDrawCountLimit());
}
/**
* 扣除抽奖券.
*/
private void deductTicket(Long userId, Integer ticketCost) {
List<LotteryTicket> tickets = lotteryTicketService.query()
.eq(LotteryTicket::getUserId, userId)
.eq(LotteryTicket::getStatus, 1)
.gt(LotteryTicket::getRemainingCount, 0)
.orderByAsc(LotteryTicket::getExpireTime)
.list();
int totalRemaining = tickets.stream()
.mapToInt(LotteryTicket::getRemainingCount)
.sum();
ResponseAssert.isTrue(LotteryErrorCode.INSUFFICIENT_TICKETS, totalRemaining >= ticketCost);
List<LotteryTicketRecord> records = new ArrayList<>();
int remaining = ticketCost;
for (LotteryTicket ticket : tickets) {
if (remaining <= 0) {
break;
}
int deduct = Math.min(remaining, ticket.getRemainingCount());
boolean updateSuccess = lotteryTicketService.update()
.eq(LotteryTicket::getId, ticket.getId())
.eq(LotteryTicket::getRemainingCount, ticket.getRemainingCount())
.setSql("used_count = used_count + " + deduct)
.setSql("remaining_count = remaining_count - " + deduct)
.execute();
ResponseAssert.isTrue(LotteryErrorCode.INSUFFICIENT_TICKETS, updateSuccess);
LotteryTicketRecord ticketRecord = new LotteryTicketRecord();
ticketRecord.setUserId(userId);
ticketRecord.setTicketId(ticket.getId());
ticketRecord.setChangeCount(-deduct);
ticketRecord.setChangeType(2);
ticketRecord.setRemark("连抽消耗");
records.add(ticketRecord);
remaining -= deduct;
}
if (!records.isEmpty()) {
lotteryTicketRecordService.saveBatch(records);
}
}
/**
* 使用连抽概率抽奖.
*/
private LotteryPrize drawPrizeWithMultiProbability(Long activityId) {
List<LotteryPrize> prizes = lotteryPrizeService.query()
.eq(LotteryPrize::getActivityId, activityId)
.gt(LotteryPrize::getRemainingStock, 0)
.orderByAsc(LotteryPrize::getSortOrder)
.list();
if (prizes.isEmpty()) {
return null;
}
// 使用连抽概率如果配置了
BigDecimal totalProbability = prizes.stream()
.map(prize -> prize.getMultiDrawProbability() != null
? prize.getMultiDrawProbability()
: prize.getProbability())
.reduce(BigDecimal.ZERO, BigDecimal::add);
double randomValue = ThreadLocalRandom.current().nextDouble() * totalProbability.doubleValue();
double cumulative = 0.0;
for (LotteryPrize prize : prizes) {
BigDecimal probability = prize.getMultiDrawProbability() != null
? prize.getMultiDrawProbability()
: prize.getProbability();
cumulative += probability.doubleValue();
if (randomValue <= cumulative) {
return prize;
}
}
return prizes.get(prizes.size() - 1);
}
/**
* 获取保底奖品.
*/
private LotteryPrize getGuaranteePrize(Long activityId, Long guaranteePrizeId) {
if (guaranteePrizeId != null) {
LotteryPrize prize = lotteryPrizeService.getById(guaranteePrizeId);
if (prize != null && prize.getRemainingStock() > 0) {
return prize;
}
}
// 如果没有配置保底奖品ID查找可作为保底的奖品
return lotteryPrizeService.query()
.eq(LotteryPrize::getActivityId, activityId)
.eq(LotteryPrize::getIsGuaranteePrize, 1)
.gt(LotteryPrize::getRemainingStock, 0)
.orderByAsc(LotteryPrize::getPrizeValue)
.last("LIMIT 1")
.getOne();
}
/**
* 扣减奖品库存.
*/
private boolean deductPrizeStock(Long prizeId) {
return lotteryPrizeService.update()
.eq(LotteryPrize::getId, prizeId)
.gt(LotteryPrize::getRemainingStock, 0)
.setSql("remaining_stock = remaining_stock - 1")
.execute();
}
/**
* 保存抽奖记录.
*/
private LotteryRecord saveDrawRecord(Long userId, Long activityId, LotteryPrize prize,
Timestamp now, String batchNo, Integer drawType) {
String recordNo = generateRecordNo();
LotteryRecord record = new LotteryRecord();
record.setRecordNo(recordNo);
record.setUserId(userId);
record.setActivityId(activityId);
record.setDrawTime(now);
record.setDrawBatchNo(batchNo);
record.setDrawType(drawType);
if (prize != null) {
record.setPrizeId(prize.getId());
record.setPrizeName(prize.getPrizeName());
record.setPrizeType(prize.getPrizeType());
record.setIsWin(1);
record.setPrizeStatus(0);
} else {
record.setIsWin(0);
}
lotteryRecordService.save(record);
return record;
}
/**
* 更新用户抽奖次数.
*/
private void updateUserDrawCount(Long userId, Long activityId, Integer drawCount) {
LocalDate today = LocalDate.now();
boolean updated = lotteryUserCountService.update()
.eq(LotteryUserCount::getUserId, userId)
.eq(LotteryUserCount::getActivityId, activityId)
.eq(LotteryUserCount::getDrawDate, today)
.setSql("draw_count = draw_count + " + drawCount)
.execute();
if (!updated) {
try {
LotteryUserCount userCount = new LotteryUserCount();
userCount.setUserId(userId);
userCount.setActivityId(activityId);
userCount.setDrawDate(today);
userCount.setDrawCount(drawCount);
lotteryUserCountService.save(userCount);
} catch (Exception e) {
lotteryUserCountService.update()
.eq(LotteryUserCount::getUserId, userId)
.eq(LotteryUserCount::getActivityId, activityId)
.eq(LotteryUserCount::getDrawDate, today)
.setSql("draw_count = draw_count + " + drawCount)
.execute();
}
}
}
/**
* 计算前N次的总金额.
*/
private BigDecimal calculateTotalAmount(List<LotteryDrawResultCO> results) {
return results.stream()
.filter(LotteryDrawResultCO::getIsWin)
.map(r -> r.getPrize() != null ? r.getPrize().getPrizeValue() : BigDecimal.ZERO)
.reduce(BigDecimal.ZERO, BigDecimal::add);
}
/**
* 转换为结果CO.
*/
private LotteryDrawResultCO convertToResultCO(LotteryRecord record, LotteryPrize prize) {
LotteryDrawResultCO result = new LotteryDrawResultCO();
result.setRecordNo(record.getRecordNo());
result.setIsWin(record.getIsWin() == 1);
result.setDrawTime(record.getDrawTime());
if (prize != null) {
LotteryPrizeCO prizeCO = new LotteryPrizeCO();
BeanUtils.copyProperties(prize, prizeCO);
result.setPrize(prizeCO);
}
return result;
}
/**
* 构建连抽结果.
*/
private LotteryMultiDrawResultCO buildMultiDrawResult(String batchNo,
List<LotteryDrawResultCO> results,
boolean guaranteeTriggered) {
LotteryMultiDrawResultCO multiResult = new LotteryMultiDrawResultCO();
multiResult.setBatchNo(batchNo);
multiResult.setDrawType(2);
multiResult.setResults(results);
// 汇总信息
LotteryMultiDrawResultCO.MultiDrawSummary summary = new LotteryMultiDrawResultCO.MultiDrawSummary();
BigDecimal totalAmount = results.stream()
.filter(LotteryDrawResultCO::getIsWin)
.map(r -> r.getPrize() != null ? r.getPrize().getPrizeValue() : BigDecimal.ZERO)
.reduce(BigDecimal.ZERO, BigDecimal::add);
summary.setTotalAmount(totalAmount);
summary.setGuaranteeTriggered(guaranteeTriggered);
long winCount = results.stream()
.filter(LotteryDrawResultCO::getIsWin)
.count();
summary.setWinCount((int) winCount);
long bigPrizeCount = results.stream()
.filter(LotteryDrawResultCO::getIsWin)
.filter(r -> r.getPrize() != null && r.getPrize().getPrizeValue().compareTo(new BigDecimal("0.5")) >= 0)
.count();
summary.setBigPrizeCount((int) bigPrizeCount);
multiResult.setSummary(summary);
return multiResult;
}
/**
* 生成批次号.
*/
private String generateBatchNo() {
return "BATCH" + System.currentTimeMillis() +
String.format("%06d", ThreadLocalRandom.current().nextInt(1000000));
}
/**
* 生成记录编号.
*/
private String generateRecordNo() {
return "LT" + System.currentTimeMillis() +
String.format("%06d", ThreadLocalRandom.current().nextInt(1000000));
}
}

View File

@ -5,15 +5,18 @@ import com.red.circle.framework.dto.PageResult;
import com.red.circle.other.app.command.activity.LotteryActivityDetailQryExe;
import com.red.circle.other.app.command.activity.LotteryActivityListQryExe;
import com.red.circle.other.app.command.activity.LotteryDrawExe;
import com.red.circle.other.app.command.activity.LotteryMultiDrawExe;
import com.red.circle.other.app.command.activity.LotteryRecordQryExe;
import com.red.circle.other.app.command.activity.LotteryTicketCountQryExe;
import com.red.circle.other.app.command.activity.LotteryTicketQryExe;
import com.red.circle.other.app.dto.clientobject.activity.LotteryActivityCO;
import com.red.circle.other.app.dto.clientobject.activity.LotteryActivityDetailCO;
import com.red.circle.other.app.dto.clientobject.activity.LotteryDrawResultCO;
import com.red.circle.other.app.dto.clientobject.activity.LotteryMultiDrawResultCO;
import com.red.circle.other.app.dto.clientobject.activity.LotteryRecordCO;
import com.red.circle.other.app.dto.clientobject.activity.LotteryTicketCO;
import com.red.circle.other.app.dto.cmd.activity.LotteryDrawCmd;
import com.red.circle.other.app.dto.cmd.activity.LotteryMultiDrawCmd;
import com.red.circle.other.app.dto.cmd.activity.LotteryRecordQryCmd;
import java.util.List;
import lombok.RequiredArgsConstructor;
@ -32,6 +35,7 @@ public class LotteryActivityRestServiceImpl implements LotteryActivityRestServic
private final LotteryActivityListQryExe lotteryActivityListQryExe;
private final LotteryActivityDetailQryExe lotteryActivityDetailQryExe;
private final LotteryDrawExe lotteryDrawExe;
private final LotteryMultiDrawExe lotteryMultiDrawExe;
private final LotteryRecordQryExe lotteryRecordQryExe;
private final LotteryTicketQryExe lotteryTicketQryExe;
private final LotteryTicketCountQryExe lotteryTicketCountQryExe;
@ -51,6 +55,11 @@ public class LotteryActivityRestServiceImpl implements LotteryActivityRestServic
return lotteryDrawExe.execute(cmd);
}
@Override
public LotteryMultiDrawResultCO multiDraw(LotteryMultiDrawCmd cmd) {
return lotteryMultiDrawExe.execute(cmd);
}
@Override
public PageResult<LotteryRecordCO> listMyRecords(LotteryRecordQryCmd cmd) {
return lotteryRecordQryExe.execute(cmd);

View File

@ -0,0 +1,65 @@
package com.red.circle.other.app.dto.clientobject.activity;
import com.red.circle.framework.dto.ClientObject;
import java.math.BigDecimal;
import java.util.List;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
/**
* 连抽结果CO.
*
* @author system
* @since 2025-10-20
*/
@Data
@Accessors(chain = true)
@EqualsAndHashCode(callSuper = true)
public class LotteryMultiDrawResultCO extends ClientObject {
/**
* 批次号.
*/
private String batchNo;
/**
* 抽奖类型1-单抽2-十连抽.
*/
private Integer drawType;
/**
* 抽奖结果列表.
*/
private List<LotteryDrawResultCO> results;
/**
* 汇总信息.
*/
private MultiDrawSummary summary;
@Data
@Accessors(chain = true)
public static class MultiDrawSummary {
/**
* 本次总获得金额.
*/
private BigDecimal totalAmount;
/**
* 是否触发保底.
*/
private Boolean guaranteeTriggered;
/**
* 大奖数量0.5美元.
*/
private Integer bigPrizeCount;
/**
* 中奖次数.
*/
private Integer winCount;
}
}

View File

@ -0,0 +1,38 @@
package com.red.circle.other.app.dto.cmd.activity;
import com.red.circle.common.business.dto.cmd.AppExtCommand;
import jakarta.validation.constraints.Max;
import jakarta.validation.constraints.Min;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* 执行连抽Cmd.
*
* @author system
* @since 2025-10-20
*/
@Data
@EqualsAndHashCode(callSuper = false)
public class LotteryMultiDrawCmd extends AppExtCommand {
/**
* 活动ID.
*
* @eo.required
*/
@NotNull(message = "activityId required.")
private Long activityId;
/**
* 连抽次数.
*
* @eo.required
*/
@NotNull(message = "drawCount required.")
@Min(value = 1, message = "drawCount must >= 1")
@Max(value = 10, message = "drawCount must <= 10")
private Integer drawCount;
}

View File

@ -5,9 +5,11 @@ import com.red.circle.framework.dto.PageResult;
import com.red.circle.other.app.dto.clientobject.activity.LotteryActivityCO;
import com.red.circle.other.app.dto.clientobject.activity.LotteryActivityDetailCO;
import com.red.circle.other.app.dto.clientobject.activity.LotteryDrawResultCO;
import com.red.circle.other.app.dto.clientobject.activity.LotteryMultiDrawResultCO;
import com.red.circle.other.app.dto.clientobject.activity.LotteryRecordCO;
import com.red.circle.other.app.dto.clientobject.activity.LotteryTicketCO;
import com.red.circle.other.app.dto.cmd.activity.LotteryDrawCmd;
import com.red.circle.other.app.dto.cmd.activity.LotteryMultiDrawCmd;
import com.red.circle.other.app.dto.cmd.activity.LotteryRecordQryCmd;
import java.util.List;
@ -34,6 +36,11 @@ public interface LotteryActivityRestService {
*/
LotteryDrawResultCO draw(LotteryDrawCmd cmd);
/**
* 执行连抽.
*/
LotteryMultiDrawResultCO multiDraw(LotteryMultiDrawCmd cmd);
/**
* 查询我的中奖记录.
*/

View File

@ -3,12 +3,11 @@ package com.red.circle.other.infra.database.rds.entity.activity;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.red.circle.framework.mybatis.entity.TimestampBaseEntity;
import java.io.Serial;
import java.io.Serializable;
import java.math.BigDecimal;
import java.sql.Timestamp;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
/**
@ -115,4 +114,34 @@ public class LotteryActivity implements Serializable {
private Timestamp updateTime;
/**
* 是否启用连抽0-1-.
*/
@TableField("enable_multi_draw")
private Integer enableMultiDraw;
/**
* 连抽次数.
*/
@TableField("multi_draw_count")
private Integer multiDrawCount;
/**
* 连抽消耗券数优惠.
*/
@TableField("multi_draw_ticket_cost")
private Integer multiDrawTicketCost;
/**
* 连抽保底奖品ID.
*/
@TableField("multi_draw_guarantee_prize_id")
private Long multiDrawGuaranteePrizeId;
/**
* 连抽保底最低金额.
*/
@TableField("multi_draw_guarantee_min_amount")
private BigDecimal multiDrawGuaranteeMinAmount;
}

View File

@ -9,7 +9,6 @@ import java.math.BigDecimal;
import java.sql.Timestamp;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
/**
@ -100,6 +99,18 @@ public class LotteryPrize implements Serializable {
@TableField("probability")
private BigDecimal probability;
/**
* 连抽时的概率可以比单抽高.
*/
@TableField("multi_draw_probability")
private BigDecimal multiDrawProbability;
/**
* 是否可作为保底奖品0-1-.
*/
@TableField("is_guarantee_prize")
private Integer isGuaranteePrize;
/**
* 排序九宫格位置.
*/

View File

@ -91,6 +91,18 @@ public class LotteryRecord implements Serializable {
@TableField("deliver_time")
private Timestamp deliverTime;
/**
* 抽奖批次号连抽时相同.
*/
@TableField("draw_batch_no")
private String drawBatchNo;
/**
* 抽奖类型1-单抽2-十连抽.
*/
@TableField("draw_type")
private Integer drawType;
/**
* 备注.
*/