release: 新增实物抽奖逻辑

release-2024-08-08
huangyw 4 months ago
parent 8f674eec70
commit 61c9b1eb92

@ -52,5 +52,7 @@ public class ErrorConstants {
public static final String NOT_ARTIST = "非音乐人不能参与"; public static final String NOT_ARTIST = "非音乐人不能参与";
public static final String ALREADY_PARTICIPATED = "已参与抽奖"; public static final String ALREADY_PARTICIPATED = "已参与抽奖";
public static final String NOT_END_OF_SIGN_UP = "报名未结束,不允许抽奖"; public static final String NOT_END_OF_SIGN_UP = "报名未结束,不允许抽奖";
public static final String TICKET_CITY_IS_REQUIRED = "门票抽奖城市必填";
public static final String REAL_NUMBER_IS_REQUIRED = "实物抽奖数量必填";
} }

@ -14,6 +14,9 @@ public enum PointEnums {
TASK_POINT_TYPE_ADD(1, "增加"), TASK_POINT_TYPE_ADD(1, "增加"),
TASK_POINT_TYPE_REDUCE(2, "减少"), TASK_POINT_TYPE_REDUCE(2, "减少"),
LOTTERY_TICKET(1, "门票抽奖"),
LOTTERY_REAL(2, "实物抽奖"),
LOTTERY_ALL(1, "全部"), LOTTERY_ALL(1, "全部"),
LOTTERY_ALL_MEMBER(2, "全部会员"), LOTTERY_ALL_MEMBER(2, "全部会员"),
LOTTERY_LIFE_MEMBER(3, "永久会员"), LOTTERY_LIFE_MEMBER(3, "永久会员"),

@ -3,6 +3,7 @@ package com.luoo.user.controller;
import annotation.GlobalInterceptor; import annotation.GlobalInterceptor;
import api.PageResult; import api.PageResult;
import api.Result; import api.Result;
import com.luoo.user.dto.point.LotteryDto;
import com.luoo.user.dto.point.LotterySearchDto; import com.luoo.user.dto.point.LotterySearchDto;
import com.luoo.user.dto.point.TaskPointDto; import com.luoo.user.dto.point.TaskPointDto;
import com.luoo.user.dto.point.UserPointLogSearchDto; import com.luoo.user.dto.point.UserPointLogSearchDto;
@ -242,7 +243,9 @@ public class PointController {
@ApiImplicitParam(name = "lottery", value = "抽奖信息", required = true, dataType = "Lottery", paramType = "body") @ApiImplicitParam(name = "lottery", value = "抽奖信息", required = true, dataType = "Lottery", paramType = "body")
}) })
public Result<Void> editLottery(@RequestHeader("Authorization") String token, public Result<Void> editLottery(@RequestHeader("Authorization") String token,
@RequestBody Lottery lottery) { @RequestBody LotteryDto lotteryDto) {
Lottery lottery = new Lottery();
BeanUtils.copyProperties(lotteryDto, lottery);
lotteryService.edit(lottery, token); lotteryService.edit(lottery, token);
return Result.success(); return Result.success();
} }

@ -0,0 +1,72 @@
package com.luoo.user.dto.point;
import com.luoo.user.pojo.LotteryRegion;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import javax.persistence.Transient;
import java.io.Serializable;
import java.time.LocalDateTime;
import java.util.List;
/**
* DTO for {@link com.luoo.user.pojo.Lottery}
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class LotteryDto implements Serializable {
@ApiModelProperty(value = "主键")
private String id;
@ApiModelProperty(value = "抽奖编码")
private String code;
@ApiModelProperty(value = "标题")
private String title;
@ApiModelProperty(value = "抽奖类型 1-门票抽奖 2-实物抽奖")
private Integer type;
@ApiModelProperty(value = "奖品总数量")
private Integer num;
@ApiModelProperty(value = "可参加人员 1-全部 2-全部会员 3-永久会员 4-贡献者")
private Integer participant;
@ApiModelProperty(value = "积分")
private Integer point;
@ApiModelProperty(value = "地区编码")
private String regionCode;
@ApiModelProperty(value = "地区名称")
private String regionName;
@ApiModelProperty(value = "报名开始时间")
private LocalDateTime applyStartTime;
@ApiModelProperty(value = "报名结束时间")
private LocalDateTime applyEndTime;
@ApiModelProperty(value = "抽奖方式 1-自动抽奖 2-手动抽奖")
private Integer way;
@ApiModelProperty(value = "抽奖封面url")
private String image;
@ApiModelProperty(value = "抽奖描述")
private String description;
@ApiModelProperty(value = "抽奖状态 0-编辑中 1-报名中 2-已抽奖 3-已停止")
private Integer status;
@ApiModelProperty(value = "停止原因")
private String stopReason;
@Transient
@ApiModelProperty(value = "抽奖地区列表")
private List<LotteryRegion> lotteryRegionList;
}

@ -53,6 +53,14 @@ public class Lottery {
@ApiModelProperty(value = "标题") @ApiModelProperty(value = "标题")
private String title; private String title;
@Column(name = "type")
@ApiModelProperty(value = "抽奖类型 1-门票抽奖 2-实物抽奖")
private Integer type;
@Column(name = "num")
@ApiModelProperty(value = "奖品总数量")
private Integer num;
@Column(name = "participant") @Column(name = "participant")
@ApiModelProperty(value = "可参加人员 1-全部 2-全部会员 3-永久会员 4-贡献者") @ApiModelProperty(value = "可参加人员 1-全部 2-全部会员 3-永久会员 4-贡献者")
private Integer participant; private Integer participant;

@ -12,12 +12,16 @@ import com.luoo.user.pojo.LotteryUser;
import com.luoo.user.pojo.Region; import com.luoo.user.pojo.Region;
import com.luoo.user.pojo.UserInfo; import com.luoo.user.pojo.UserInfo;
import com.luoo.user.pojo.UserPointLog; import com.luoo.user.pojo.UserPointLog;
import constants.Constants;
import constants.ErrorConstants; import constants.ErrorConstants;
import dto.UserLoginDto; import dto.UserLoginDto;
import dto.UserMessageDto;
import enums.MessageTypeEnum;
import enums.PointEnums; import enums.PointEnums;
import enums.UserTypeEnum; import enums.UserTypeEnum;
import enums.UserVipStatusEnum; import enums.UserVipStatusEnum;
import exception.BizException; import exception.BizException;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
@ -28,6 +32,7 @@ import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery; import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate; import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root; import javax.persistence.criteria.Root;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.StringUtils;
import org.springframework.amqp.rabbit.core.RabbitTemplate; import org.springframework.amqp.rabbit.core.RabbitTemplate;
@ -75,9 +80,11 @@ public class LotteryService {
private final LotteryUserDao lotteryUserDao; private final LotteryUserDao lotteryUserDao;
private final UserMessageService userMessageService;
public LotteryService(LotteryDao lotteryDao, IdWorker idWorker, JwtUtil jwtUtil, public LotteryService(LotteryDao lotteryDao, IdWorker idWorker, JwtUtil jwtUtil,
RedisLockUtil redisLockUtil, RegionService regionService, LotteryRegionDao lotteryRegionDao, RedisLockUtil redisLockUtil, RegionService regionService, LotteryRegionDao lotteryRegionDao,
UserInfoDao userInfoDao, RabbitTemplate rabbitTemplate, LotteryUserDao lotteryUserDao) { UserInfoDao userInfoDao, RabbitTemplate rabbitTemplate, LotteryUserDao lotteryUserDao, UserMessageService userMessageService) {
this.lotteryDao = lotteryDao; this.lotteryDao = lotteryDao;
this.idWorker = idWorker; this.idWorker = idWorker;
this.jwtUtil = jwtUtil; this.jwtUtil = jwtUtil;
@ -87,6 +94,7 @@ public class LotteryService {
this.userInfoDao = userInfoDao; this.userInfoDao = userInfoDao;
this.rabbitTemplate = rabbitTemplate; this.rabbitTemplate = rabbitTemplate;
this.lotteryUserDao = lotteryUserDao; this.lotteryUserDao = lotteryUserDao;
this.userMessageService = userMessageService;
} }
/** /**
@ -103,34 +111,50 @@ public class LotteryService {
StringBuilder regionCode = new StringBuilder(); StringBuilder regionCode = new StringBuilder();
StringBuilder regionName = new StringBuilder(); StringBuilder regionName = new StringBuilder();
String id = String.valueOf(idWorker.nextId());
if (Objects.equals(lottery.getType(), PointEnums.LOTTERY_TICKET.getCode())) {
// 门票抽奖,城市必填
List<LotteryRegion> lotteryRegionList = lottery.getLotteryRegionList(); List<LotteryRegion> lotteryRegionList = lottery.getLotteryRegionList();
if (lotteryRegionList.isEmpty()) {
throw new BizException(ErrorConstants.TICKET_CITY_IS_REQUIRED);
}
Integer num = 0;
for (LotteryRegion lotteryRegion : lotteryRegionList) { for (LotteryRegion lotteryRegion : lotteryRegionList) {
Region regionById = regionService.getRegionById(lotteryRegion.getRegionId()); Region regionById = regionService.getRegionById(lotteryRegion.getRegionId());
regionCode.append(regionById.getCode()).append(","); regionCode.append(regionById.getCode()).append(",");
regionName.append(regionById.getName()).append(","); regionName.append(regionById.getName()).append(",");
num += lotteryRegion.getNum();
lotteryRegion.setId(id);
lotteryRegion.setLotteryId(lottery.getId());
lotteryRegion.setCreateUser(userLoginDto.getUserId());
lotteryRegion.setUpdateUser(userLoginDto.getUserId());
lotteryRegionDao.save(lotteryRegion);
} }
lottery.setRegionCode(regionCode.toString());
lottery.setRegionName(regionName.toString());
lottery.setNum(num);
lottery.setId(String.valueOf(idWorker.nextId())); } else {
// 实物抽奖,数量必填
if (lottery.getNum() == null) {
throw new BizException(ErrorConstants.REAL_NUMBER_IS_REQUIRED);
}
}
lottery.setId(id);
lottery.setCreateUser(userLoginDto.getUserId()); lottery.setCreateUser(userLoginDto.getUserId());
lottery.setUpdateUser(userLoginDto.getUserId()); lottery.setUpdateUser(userLoginDto.getUserId());
lottery.setCreateUserName(userLoginDto.getNickName()); lottery.setCreateUserName(userLoginDto.getNickName());
lottery.setUpdateUserName(userLoginDto.getNickName()); lottery.setUpdateUserName(userLoginDto.getNickName());
lottery.setCode(redisLockUtil.lotteryGenerateSerialNumber()); lottery.setCode(redisLockUtil.lotteryGenerateSerialNumber());
lottery.setStatus(PointEnums.LOTTERY_STATUS_EDITING.getCode()); lottery.setStatus(PointEnums.LOTTERY_STATUS_EDITING.getCode());
lottery.setRegionCode(regionCode.toString());
lottery.setRegionName(regionName.toString());
lotteryDao.save(lottery); lotteryDao.save(lottery);
lotteryRegionList.forEach(lotteryRegion -> {
lotteryRegion.setId(String.valueOf(idWorker.nextId()));
lotteryRegion.setLotteryId(lottery.getId());
lotteryRegion.setCreateUser(userLoginDto.getUserId());
lotteryRegion.setUpdateUser(userLoginDto.getUserId());
lotteryRegionDao.save(lotteryRegion);
});
} }
/** /**
@ -144,40 +168,61 @@ public class LotteryService {
UserLoginDto userLoginDto = jwtUtil.getUserLoginDto(token); UserLoginDto userLoginDto = jwtUtil.getUserLoginDto(token);
String id = lottery.getId();
StringBuilder regionCode = new StringBuilder(); StringBuilder regionCode = new StringBuilder();
StringBuilder regionName = new StringBuilder(); StringBuilder regionName = new StringBuilder();
if (Objects.equals(lottery.getType(), PointEnums.LOTTERY_TICKET.getCode())) {
// 门票抽奖,城市必填
List<LotteryRegion> lotteryRegionList = lottery.getLotteryRegionList(); List<LotteryRegion> lotteryRegionList = lottery.getLotteryRegionList();
if (lotteryRegionList.isEmpty()) {
throw new BizException(ErrorConstants.TICKET_CITY_IS_REQUIRED);
}
Integer num = 0;
lotteryRegionDao.deleteByLotteryId(id);
for (LotteryRegion lotteryRegion : lotteryRegionList) { for (LotteryRegion lotteryRegion : lotteryRegionList) {
Region regionById = regionService.getRegionById(lotteryRegion.getRegionId()); Region regionById = regionService.getRegionById(lotteryRegion.getRegionId());
regionCode.append(regionById.getCode()).append(","); regionCode.append(regionById.getCode()).append(",");
regionName.append(regionById.getName()).append(","); regionName.append(regionById.getName()).append(",");
num += lotteryRegion.getNum();
lotteryRegion.setId(String.valueOf(idWorker.nextId()));
lotteryRegion.setLotteryId(id);
lotteryRegion.setCreateUser(userLoginDto.getUserId());
lotteryRegion.setUpdateUser(userLoginDto.getUserId());
lotteryRegionDao.save(lotteryRegion);
} }
lottery.setRegionCode(regionCode.toString());
lottery.setRegionName(regionName.toString());
lottery.setNum(num);
String id = lottery.getId(); } else {
Lottery lottery1 = lotteryDao.findById(id).orElse(null); // 实物抽奖,数量必填
if (!Objects.equals(PointEnums.LOTTERY_STATUS_EDITING.getCode(), lottery1.getStatus())) { if (lottery.getNum() == null) {
throw new BizException(ErrorConstants.REAL_NUMBER_IS_REQUIRED);
}
}
Lottery oldLottery = lotteryDao.getOne(id);
if (!Objects.equals(PointEnums.LOTTERY_STATUS_EDITING.getCode(), oldLottery.getStatus())) {
// 不是编辑中,不允许修改 // 不是编辑中,不允许修改
throw new BizException(ErrorConstants.CAN_NOT_EDIT); throw new BizException(ErrorConstants.CAN_NOT_EDIT);
} }
lottery.setRegionCode(regionCode.toString()); lottery.setCreateTime(oldLottery.getCreateTime());
lottery.setRegionName(regionName.toString()); lottery.setCreateUser(oldLottery.getCreateUser());
lottery.setCreateUserName(oldLottery.getCreateUserName());
lottery.setUpdateUser(userLoginDto.getUserId()); lottery.setUpdateUser(userLoginDto.getUserId());
lottery.setUpdateUserName(userLoginDto.getNickName()); lottery.setUpdateUserName(userLoginDto.getNickName());
lotteryDao.save(lottery); lotteryDao.save(lottery);
lotteryRegionDao.deleteByLotteryId(id);
lotteryRegionList.forEach(lotteryRegion -> {
lotteryRegion.setId(String.valueOf(idWorker.nextId()));
lotteryRegion.setLotteryId(id);
lotteryRegion.setCreateUser(userLoginDto.getUserId());
lotteryRegion.setUpdateUser(userLoginDto.getUserId());
lotteryRegionDao.save(lotteryRegion);
});
} }
/** /**
@ -286,7 +331,7 @@ public class LotteryService {
List<LotteryUser> checkUserList = lotteryUserDao.findByLotteryIdAndUserIdAndRegionId( List<LotteryUser> checkUserList = lotteryUserDao.findByLotteryIdAndUserIdAndRegionId(
id, userLoginDto.getUserId(), regionId); id, userLoginDto.getUserId(), regionId);
if(!checkUserList.isEmpty()) { if (!checkUserList.isEmpty()) {
throw new BizException(ErrorConstants.ALREADY_PARTICIPATED); throw new BizException(ErrorConstants.ALREADY_PARTICIPATED);
} }
@ -332,6 +377,8 @@ public class LotteryService {
if (Objects.equals(lottery.getStatus(), PointEnums.LOTTERY_STATUS_SIGN.getCode())) { if (Objects.equals(lottery.getStatus(), PointEnums.LOTTERY_STATUS_SIGN.getCode())) {
if (Objects.equals(lottery.getType(), PointEnums.LOTTERY_TICKET.getCode())) {
// 门票抽奖业务
List<LotteryRegion> lotteryRegionList = lotteryRegionDao.findByLotteryId(id); List<LotteryRegion> lotteryRegionList = lotteryRegionDao.findByLotteryId(id);
lotteryRegionList.forEach(lotteryRegion -> { lotteryRegionList.forEach(lotteryRegion -> {
@ -340,11 +387,37 @@ public class LotteryService {
List<LotteryUser> lotteryUserList = lotteryUserDao.findByLotteryIdAndRegionId(id, List<LotteryUser> lotteryUserList = lotteryUserDao.findByLotteryIdAndRegionId(id,
lotteryRegion.getRegionId()); lotteryRegion.getRegionId());
lotteryFunc(token, lotteryUserList, num);
}
});
} else if (Objects.equals(lottery.getType(), PointEnums.LOTTERY_REAL.getCode())) {
// 实物抽奖业务
List<LotteryUser> byLotteryId = lotteryUserDao.findByLotteryId(id);
lotteryFunc(token, byLotteryId, lottery.getNum());
}
// 抽奖状态为报名中,自动抽奖
lottery.setStatus(PointEnums.LOTTERY_STATUS_LOTTERY.getCode());
lotteryDao.save(lottery);
}
}
/**
*
*
* @param token
* @param lotteryUserList
* @param num
*/
private void lotteryFunc(String token, List<LotteryUser> lotteryUserList, Integer num) {
List<LotteryUser> winnerList = new ArrayList<>(); List<LotteryUser> winnerList = new ArrayList<>();
if (lotteryUserList.size() > num) { if (lotteryUserList.size() > num) {
// 抽奖人数大于设定人数 // 抽奖人数大于设定人数
// 随机设定人数的数量中奖 // 随机设定人数的数量中奖
winnerList = drawWinners(lotteryUserList, lotteryRegion.getNum()); winnerList = drawWinners(lotteryUserList, num);
} else { } else {
// 抽奖人数小于设定人数 // 抽奖人数小于设定人数
// 全部中奖 // 全部中奖
@ -353,30 +426,34 @@ public class LotteryService {
winnerList.forEach(lotteryUser -> { winnerList.forEach(lotteryUser -> {
lotteryUser.setResult(PointEnums.LOTTERY_RESULT_WIN.getCode()); lotteryUser.setResult(PointEnums.LOTTERY_RESULT_WIN.getCode());
if(StringUtils.isNotBlank(token)) { if (StringUtils.isNotBlank(token)) {
UserLoginDto userLoginDto = jwtUtil.getUserLoginDto(token); UserLoginDto userLoginDto = jwtUtil.getUserLoginDto(token);
lotteryUser.setUpdateUser(userLoginDto.getUserId()); lotteryUser.setUpdateUser(userLoginDto.getUserId());
} }
lotteryUserDao.save(lotteryUser); lotteryUserDao.save(lotteryUser);
});
} // 发送恭喜中奖站内信
UserMessageDto userMessageDto = new UserMessageDto();
userMessageDto.setType(MessageTypeEnum.PRIVATE_MESSAGE.getType());
userMessageDto.setSendUserId(StringUtils.isNotBlank(token) ? jwtUtil.getUserLoginDto(token).getUserId() : null);
userMessageDto.setTitle("恭喜中奖!");
userMessageDto.setContent("恭喜中奖请加微信XXXXXX");
userMessageDto.setUserId(lotteryUser.getUserId());
userMessageDto.setSendUserAvatar(Constants.RESOURCE_PREFIX + (StringUtils.isNotBlank(token) ? jwtUtil.getUserLoginDto(token).getAvatar() : null));
userMessageDto.setSendUserNickName(StringUtils.isNotBlank(token) ? jwtUtil.getUserLoginDto(token).getNickName() : null);
userMessageService.sendUserMessage(userMessageDto);
}); });
// 抽奖状态为报名中,自动抽奖
lottery.setStatus(PointEnums.LOTTERY_STATUS_LOTTERY.getCode());
lotteryDao.save(lottery);
}
} }
/** /**
* *
* *
* @param participants * @param list
* @param winnersCount * @param winnersCount
* @return * @return
*/ */
private List<LotteryUser> drawWinners(List<LotteryUser> participants, int winnersCount) { private List<LotteryUser> drawWinners(List<LotteryUser> list, int winnersCount) {
List<LotteryUser> winners = new ArrayList<>(participants); List<LotteryUser> winners = new ArrayList<>();
Collections.shuffle(winners, new Random()); Collections.shuffle(winners, new Random());
return winners.subList(0, Math.min(winnersCount, winners.size())); return winners.subList(0, Math.min(winnersCount, winners.size()));
} }

@ -3,6 +3,8 @@ create table tb_lottery
id varchar(20) not null comment 'id' id varchar(20) not null comment 'id'
primary key, primary key,
code varchar(50) null comment '抽奖码', code varchar(50) null comment '抽奖码',
type tinyint null comment '抽奖类型 1-门票抽奖 2-实物抽奖',
num int null comment '奖品总数量',
title varchar(255) null comment '抽奖标题', title varchar(255) null comment '抽奖标题',
participant int null comment '可参加人员 1-全部 2-全部会员 3-永久会员 4-贡献者 5-音乐人', participant int null comment '可参加人员 1-全部 2-全部会员 3-永久会员 4-贡献者 5-音乐人',
point int null comment '消耗积分', point int null comment '消耗积分',

Loading…
Cancel
Save