|
|
@ -3,6 +3,8 @@ package com.lottery.api.service.Impl; |
|
|
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
|
|
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; |
|
|
|
import com.lottery.LotteryApplication; |
|
|
|
import com.lottery.admin.mapper.AdminPrizeMapper; |
|
|
|
import com.lottery.admin.mapper.AdminWinMapper; |
|
|
|
import com.lottery.api.mapper.IGradeMapper; |
|
|
|
import com.lottery.api.mapper.IUserDetailMapper; |
|
|
|
import com.lottery.api.mapper.IUserMapper; |
|
|
@ -11,14 +13,18 @@ import com.lottery.dto.StartLotteryDto; |
|
|
|
import com.lottery.entity.Grade; |
|
|
|
import com.lottery.entity.User; |
|
|
|
import com.lottery.entity.UserDetail; |
|
|
|
import com.lottery.entity.WinnerRecord; |
|
|
|
import com.lottery.exception.SomeException; |
|
|
|
import com.lottery.utils.ConvertBeanUtil; |
|
|
|
import com.lottery.vo.UserVo; |
|
|
|
import com.lottery.vo.WinUserVo; |
|
|
|
import org.springframework.beans.factory.annotation.Autowired; |
|
|
|
import org.springframework.http.converter.StringHttpMessageConverter; |
|
|
|
import org.springframework.stereotype.Service; |
|
|
|
|
|
|
|
import java.util.ArrayList; |
|
|
|
import java.util.Collections; |
|
|
|
import java.util.Date; |
|
|
|
import java.util.List; |
|
|
|
|
|
|
|
/** |
|
|
@ -38,92 +44,205 @@ public class UserDetailServiceImpl extends ServiceImpl<IUserDetailMapper, UserDe |
|
|
|
private IGradeMapper gradeMapper; |
|
|
|
|
|
|
|
@Autowired |
|
|
|
private AdminPrizeMapper adminPrizeMapper; |
|
|
|
|
|
|
|
@Autowired |
|
|
|
private IUserDetailMapper userDetailMapper; |
|
|
|
|
|
|
|
@Autowired |
|
|
|
private AdminWinMapper adminWinMapper; |
|
|
|
|
|
|
|
|
|
|
|
// public List<UserVo> StartLottery(StartLotteryDto startLotteryDto) { |
|
|
|
// |
|
|
|
// Long gradeId = gradeMapper.selectByName(startLotteryDto.getGradeName()); |
|
|
|
// if (gradeId == null) { |
|
|
|
// throw new SomeException("未找到指定等级:" + startLotteryDto.getGradeName()); |
|
|
|
// } |
|
|
|
// |
|
|
|
// LambdaQueryWrapper<UserDetail> userDetailLambdaQueryWrapper = new LambdaQueryWrapper<>(); |
|
|
|
// userDetailLambdaQueryWrapper |
|
|
|
// .eq(UserDetail::getGradeId, gradeId) |
|
|
|
// .eq(UserDetail::getIsFixed, 1); |
|
|
|
// |
|
|
|
// //该等级下的所有内定人员 |
|
|
|
// List<UserDetail> userDetails = userDetailMapper.selectList(userDetailLambdaQueryWrapper); |
|
|
|
// |
|
|
|
// if (userDetails.isEmpty()) { |
|
|
|
// System.out.println("无内定"); |
|
|
|
// |
|
|
|
// //从user表中随机抽取startLotteryDto.getPerWin()人 |
|
|
|
// LambdaQueryWrapper<User> UserQueryWrapper = new LambdaQueryWrapper<>(); |
|
|
|
// List<User> users = randomSelectFromAllUser(userMapper.selectList(UserQueryWrapper), startLotteryDto.getPerWin()); |
|
|
|
// |
|
|
|
// List<UserVo> userVos = ConvertBeanUtil.convertList(users, UserVo.class); |
|
|
|
// return userVos; |
|
|
|
// } |
|
|
|
// |
|
|
|
// if (startLotteryDto.getPerWin() > userDetails.size()) { |
|
|
|
// //抽取人数大于内定人数,所有内定人员均中奖,剩余的从总的user表抽取 |
|
|
|
// List<UserVo> userVoList = new ArrayList<>(); |
|
|
|
// |
|
|
|
// //内定中奖的 |
|
|
|
// for (UserDetail userDetail : userDetails) { |
|
|
|
// User user = userMapper.selectById(userDetail.getUserId()); |
|
|
|
// if (user == null) { |
|
|
|
// throw new SomeException("未找到用户ID:" + userDetail.getUserId()); |
|
|
|
// } |
|
|
|
// |
|
|
|
// UserVo userVo = new UserVo(); |
|
|
|
// userVo.setUsername(user.getUsername()); |
|
|
|
// userVo.setJwcode(user.getJwcode()); |
|
|
|
// userVoList.add(userVo); |
|
|
|
// } |
|
|
|
// |
|
|
|
// //总中奖人数 - 内定人数 = 剩余从总用户表中抽取 |
|
|
|
// int lastNum = startLotteryDto.getPerWin() - userVoList.size(); |
|
|
|
// LambdaQueryWrapper<User> UserQueryWrapper = new LambdaQueryWrapper<>(); |
|
|
|
// List<User> users = randomSelectFromAllUser(userMapper.selectList(UserQueryWrapper), lastNum); |
|
|
|
// for (User user : users) { |
|
|
|
// UserVo userVo = new UserVo(); |
|
|
|
// userVo.setUsername(user.getUsername()); |
|
|
|
// userVo.setJwcode(user.getJwcode()); |
|
|
|
// userVoList.add(userVo); |
|
|
|
// } |
|
|
|
// return userVoList; |
|
|
|
// } |
|
|
|
// |
|
|
|
// if (startLotteryDto.getPerWin() <= userDetails.size()) { |
|
|
|
// //抽取人数小于等于内定人数,从内定人数中随机抽取 |
|
|
|
// List<UserDetail> winners = randomSelectFixUser(userDetails, startLotteryDto.getPerWin()); |
|
|
|
// |
|
|
|
// List<UserVo> userVoList = new ArrayList<>(); |
|
|
|
// // 遍历所有中奖用户 |
|
|
|
// for (UserDetail userDetail : winners) { |
|
|
|
// // 关联查询user表获取详细信息 |
|
|
|
// User user = userMapper.selectById(userDetail.getUserId()); |
|
|
|
// |
|
|
|
// // 检查用户是否存在 |
|
|
|
// if (user == null) { |
|
|
|
// throw new SomeException("未找到用户ID:" + userDetail.getUserId()); |
|
|
|
// } |
|
|
|
// |
|
|
|
// // 创建UserVo对象并添加到结果列表 |
|
|
|
// UserVo userVo = new UserVo(); |
|
|
|
// userVo.setUsername(user.getUsername()); |
|
|
|
// userVo.setJwcode(user.getJwcode()); |
|
|
|
// userVoList.add(userVo); |
|
|
|
// } |
|
|
|
// return userVoList; |
|
|
|
// } |
|
|
|
// return new ArrayList<>(); |
|
|
|
// } |
|
|
|
|
|
|
|
@Override |
|
|
|
public void StartLottery(StartLotteryDto startLotteryDto) { |
|
|
|
|
|
|
|
public List<UserVo> StartLottery(StartLotteryDto startLotteryDto) { |
|
|
|
// 1. 获取年级ID |
|
|
|
Long gradeId = gradeMapper.selectByName(startLotteryDto.getGradeName()); |
|
|
|
if (gradeId == null) { |
|
|
|
throw new SomeException("未找到指定等级:" + startLotteryDto.getGradeName()); |
|
|
|
} |
|
|
|
|
|
|
|
LambdaQueryWrapper<UserDetail> userDetailLambdaQueryWrapper = new LambdaQueryWrapper<>(); |
|
|
|
userDetailLambdaQueryWrapper |
|
|
|
.eq(UserDetail::getGradeId, gradeId) |
|
|
|
// 2. 查询该年级下所有内定人员 |
|
|
|
LambdaQueryWrapper<UserDetail> userDetailWrapper = new LambdaQueryWrapper<>(); |
|
|
|
userDetailWrapper.eq(UserDetail::getGradeId, gradeId) |
|
|
|
.eq(UserDetail::getIsFixed, 1); |
|
|
|
List<UserDetail> fixedUsers = userDetailMapper.selectList(userDetailWrapper); |
|
|
|
|
|
|
|
// 3. 准备中奖用户结果集 |
|
|
|
List<UserVo> winners = new ArrayList<>(); |
|
|
|
int requiredWinners = startLotteryDto.getPerWin(); |
|
|
|
|
|
|
|
//该等级下的内定人员 |
|
|
|
List<UserDetail> userDetails = userDetailMapper.selectList(userDetailLambdaQueryWrapper); |
|
|
|
// 4. 先处理内定用户(过滤掉已中奖的) |
|
|
|
List<User> availableFixedUsers = getAvailableFixedUsers(fixedUsers); |
|
|
|
int fixedWinnersCount = Math.min(availableFixedUsers.size(), requiredWinners); |
|
|
|
|
|
|
|
if (userDetails.isEmpty()) { |
|
|
|
System.out.println("无内定"); |
|
|
|
//从user表中抽取 |
|
|
|
if (fixedWinnersCount > 0) { //证明该等级下的内定用户还有没中奖的,先从内定用户抽取 |
|
|
|
List<User> fixedWinners = randomSelectUsers(availableFixedUsers, fixedWinnersCount); |
|
|
|
winners.addAll(convertToUserVoList(fixedWinners)); |
|
|
|
markUsersAsWinners(fixedWinners, startLotteryDto); // 标记为已中奖,并加入到中奖记录表里面 |
|
|
|
} |
|
|
|
if (startLotteryDto.getPerWin() > userDetails.size()) { |
|
|
|
//抽取人数大于内定人数,所有内定人员均中奖,剩余的从总的user表抽取 |
|
|
|
|
|
|
|
List<UserVo> userVoList = new ArrayList<>(); |
|
|
|
// 5. 如果人数不足,从全体用户补充(同样过滤掉已中奖的) |
|
|
|
if (winners.size() < requiredWinners) { |
|
|
|
int remaining = requiredWinners - winners.size(); |
|
|
|
List<User> allAvailableUsers = getAllAvailableUsers(); |
|
|
|
List<User> supplementWinners = randomSelectUsers(allAvailableUsers, Math.min(remaining, allAvailableUsers.size())); |
|
|
|
winners.addAll(convertToUserVoList(supplementWinners)); |
|
|
|
markUsersAsWinners(supplementWinners, startLotteryDto); // 标记为已中奖,并加入到中奖记录表里面 |
|
|
|
} |
|
|
|
return winners; |
|
|
|
} |
|
|
|
|
|
|
|
//内定中奖的 |
|
|
|
for (UserDetail userDetail : userDetails) { |
|
|
|
// 获取可用的内定用户(未中奖的) |
|
|
|
private List<User> getAvailableFixedUsers(List<UserDetail> fixedUsers) { |
|
|
|
List<User> availableUsers = new ArrayList<>(); |
|
|
|
for (UserDetail userDetail : fixedUsers) { |
|
|
|
User user = userMapper.selectById(userDetail.getUserId()); |
|
|
|
if (user == null) { |
|
|
|
throw new SomeException("未找到用户ID:" + userDetail.getUserId()); |
|
|
|
if (user != null && user.getIsWin() == 0) { // 0表示未中奖 |
|
|
|
availableUsers.add(user); |
|
|
|
} |
|
|
|
} |
|
|
|
return availableUsers; |
|
|
|
} |
|
|
|
|
|
|
|
UserVo userVo = new UserVo(); |
|
|
|
userVo.setUsername(user.getUsername()); |
|
|
|
userVo.setJwcode(user.getJwcode()); |
|
|
|
userVoList.add(userVo); |
|
|
|
// 获取全体可用用户(未中奖的) |
|
|
|
private List<User> getAllAvailableUsers() { |
|
|
|
LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>(); |
|
|
|
wrapper.eq(User::getIsWin, 0); // 只查询未中奖的 |
|
|
|
return userMapper.selectList(wrapper); |
|
|
|
} |
|
|
|
|
|
|
|
//总中奖人数 - 内定人数 = 剩余从总用户表中抽取 |
|
|
|
int lastNum = startLotteryDto.getPerWin() - userVoList.size(); |
|
|
|
LambdaQueryWrapper<User> UserQueryWrapper = new LambdaQueryWrapper<>(); |
|
|
|
List<User> users = randomSelectFromAll(userMapper.selectList(UserQueryWrapper), lastNum); |
|
|
|
// 随机选择用户 |
|
|
|
private List<User> randomSelectUsers(List<User> users, int count) { |
|
|
|
if (users.size() <= count) { |
|
|
|
return new ArrayList<>(users); |
|
|
|
} |
|
|
|
Collections.shuffle(users); |
|
|
|
return users.subList(0, count); |
|
|
|
} |
|
|
|
|
|
|
|
// 转换为UserVo列表 |
|
|
|
private List<UserVo> convertToUserVoList(List<User> users) { |
|
|
|
List<UserVo> result = new ArrayList<>(); |
|
|
|
for (User user : users) { |
|
|
|
UserVo userVo = new UserVo(); |
|
|
|
userVo.setUsername(user.getUsername()); |
|
|
|
userVo.setJwcode(user.getJwcode()); |
|
|
|
UserVo vo = new UserVo(); |
|
|
|
vo.setUsername(user.getUsername()); |
|
|
|
vo.setJwcode(user.getJwcode()); |
|
|
|
result.add(vo); |
|
|
|
} |
|
|
|
return result; |
|
|
|
} |
|
|
|
|
|
|
|
if (startLotteryDto.getPerWin() <= userDetails.size()) { |
|
|
|
//抽取人数小于等于内定人数,从内定人数中随机抽取 |
|
|
|
List<UserDetail> winners = randomSelect(userDetails, startLotteryDto.getPerWin()); |
|
|
|
// 标记用户为中奖状态 |
|
|
|
private void markUsersAsWinners(List<User> winners, StartLotteryDto startLotteryDto) { |
|
|
|
for (User user : winners) { |
|
|
|
user.setIsWin(1); // 1表示已中奖 |
|
|
|
|
|
|
|
List<UserVo> userVoList = new ArrayList<>(); |
|
|
|
// 遍历所有中奖用户 |
|
|
|
for (UserDetail userDetail : winners) { |
|
|
|
// 关联查询user表获取详细信息 |
|
|
|
User user = userMapper.selectById(userDetail.getUserId()); |
|
|
|
//把中奖的用户添加到中奖表里面 |
|
|
|
// WinnerRecord winnerRecord = new WinnerRecord(); |
|
|
|
// winnerRecord.setUserId(user.getId()); |
|
|
|
|
|
|
|
// 检查用户是否存在 |
|
|
|
if (user == null) { |
|
|
|
throw new SomeException("未找到用户ID:" + userDetail.getUserId()); |
|
|
|
} |
|
|
|
WinnerRecord winnerRecord = WinnerRecord.builder() |
|
|
|
.userId(user.getId()) |
|
|
|
.winTime(new Date()) |
|
|
|
.prizeId(adminPrizeMapper.selectByName(startLotteryDto.getPrizeName())).build(); |
|
|
|
|
|
|
|
// 创建UserVo对象并添加到结果列表 |
|
|
|
UserVo userVo = new UserVo(); |
|
|
|
userVo.setUsername(user.getUsername()); |
|
|
|
userVo.setJwcode(user.getJwcode()); |
|
|
|
userVoList.add(userVo); |
|
|
|
adminWinMapper.insert(winnerRecord); |
|
|
|
userMapper.updateById(user); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
// 随机选择指定数量的用户(内定名单中) |
|
|
|
private List<UserDetail> randomSelect(List<UserDetail> users, int count) { |
|
|
|
List<UserDetail> shuffled = new ArrayList<>(users); // 避免修改原集合 |
|
|
|
Collections.shuffle(shuffled); // 随机打乱顺序 |
|
|
|
return shuffled.subList(0, count); // 取前N个 |
|
|
|
} |
|
|
|
|
|
|
|
// 随机选择指定数量的用户(总名单中) |
|
|
|
private List<User> randomSelectFromAll(List<User> user, int count) { |
|
|
|
List<User> shuffled = new ArrayList<>(user); // 避免修改原集合 |
|
|
|
Collections.shuffle(shuffled); // 随机打乱顺序 |
|
|
|
return shuffled.subList(0, count); // 取前N个 |
|
|
|
} |
|
|
|
// // 随机选择指定数量的用户(内定名单中) |
|
|
|
// private List<UserDetail> randomSelectFixUser(List<UserDetail> users, int count) { |
|
|
|
// List<UserDetail> shuffled = new ArrayList<>(users); // 避免修改原集合 |
|
|
|
// Collections.shuffle(shuffled); // 随机打乱顺序 |
|
|
|
// return shuffled.subList(0, count); // 取前N个 |
|
|
|
// } |
|
|
|
// |
|
|
|
// // 随机选择指定数量的用户(总名单中) |
|
|
|
// private List<User> randomSelectFromAllUser(List<User> user, int count) { |
|
|
|
// List<User> shuffled = new ArrayList<>(user); // 避免修改原集合 |
|
|
|
// Collections.shuffle(shuffled); // 随机打乱顺序 |
|
|
|
// return shuffled.subList(0, count); // 取前N个 |
|
|
|
// } |
|
|
|
} |