Browse Source

完善抽奖逻辑,修改其他接口的细节。

feature/0725lihuilin
willy 4 weeks ago
parent
commit
2b372ff080
  1. 2
      lottery-system/lottery-pojo/src/main/java/com/lottery/dto/FixUserDto.java
  2. 2
      lottery-system/lottery-pojo/src/main/java/com/lottery/dto/PrizeDto.java
  3. 10
      lottery-system/lottery-pojo/src/main/java/com/lottery/dto/StartLotteryDto.java
  4. 4
      lottery-system/lottery-pojo/src/main/java/com/lottery/dto/UserQueryDto.java
  5. 31
      lottery-system/lottery-pojo/src/main/java/com/lottery/dto/WinUserExportDto.java
  6. 10
      lottery-system/lottery-pojo/src/main/java/com/lottery/dto/WinUserQueryDto.java
  7. 7
      lottery-system/lottery-pojo/src/main/java/com/lottery/entity/Grade.java
  8. 2
      lottery-system/lottery-pojo/src/main/java/com/lottery/entity/WinnerRecord.java
  9. 18
      lottery-system/lottery-pojo/src/main/java/com/lottery/vo/GradeSimpleVo.java
  10. 2
      lottery-system/lottery-pojo/src/main/java/com/lottery/vo/GradeVo.java
  11. 21
      lottery-system/lottery-pojo/src/main/java/com/lottery/vo/LotteryVo.java
  12. 12
      lottery-system/lottery-pojo/src/main/java/com/lottery/vo/PrizeAndGradeVo.java
  13. 2
      lottery-system/lottery-pojo/src/main/java/com/lottery/vo/PrizeVo.java
  14. 1
      lottery-system/lottery-pojo/src/main/java/com/lottery/vo/UserVo.java
  15. 5
      lottery-system/lottery-pojo/src/main/java/com/lottery/vo/WinUserVo.java
  16. 6
      lottery-system/lottery-service/pom.xml
  17. 22
      lottery-system/lottery-service/src/main/java/com/lottery/admin/controller/AdminGradeController.java
  18. 5
      lottery-system/lottery-service/src/main/java/com/lottery/admin/controller/AdminPrizeController.java
  19. 27
      lottery-system/lottery-service/src/main/java/com/lottery/admin/controller/AdminUserController.java
  20. 14
      lottery-system/lottery-service/src/main/java/com/lottery/admin/controller/AdminWInController.java
  21. 5
      lottery-system/lottery-service/src/main/java/com/lottery/admin/mapper/AdminGradeMapper.java
  22. 7
      lottery-system/lottery-service/src/main/java/com/lottery/admin/service/AdminGradeService.java
  23. 2
      lottery-system/lottery-service/src/main/java/com/lottery/admin/service/AdminUserDetailService.java
  24. 3
      lottery-system/lottery-service/src/main/java/com/lottery/admin/service/AdminWinService.java
  25. 19
      lottery-system/lottery-service/src/main/java/com/lottery/admin/service/Impl/AdminGradeServiceImpl.java
  26. 17
      lottery-system/lottery-service/src/main/java/com/lottery/admin/service/Impl/AdminPrizeServiceImpl.java
  27. 100
      lottery-system/lottery-service/src/main/java/com/lottery/admin/service/Impl/AdminUserDetailServiceImpl.java
  28. 96
      lottery-system/lottery-service/src/main/java/com/lottery/admin/service/Impl/AdminWinServiceImpl.java
  29. 13
      lottery-system/lottery-service/src/main/java/com/lottery/api/controller/LotteryController.java
  30. 2
      lottery-system/lottery-service/src/main/java/com/lottery/api/controller/UserController.java
  31. 6
      lottery-system/lottery-service/src/main/java/com/lottery/api/service/IUserDetailService.java
  32. 56
      lottery-system/lottery-service/src/main/java/com/lottery/api/service/Impl/PrizeServiceImpl.java
  33. 124
      lottery-system/lottery-service/src/main/java/com/lottery/api/service/Impl/UserDetailServiceImpl.java
  34. 32
      lottery-system/lottery-service/src/main/java/com/lottery/api/service/Impl/UserServiceImpl.java
  35. 75
      lottery-system/lottery-service/src/main/java/com/lottery/config/RedisConfig.java
  36. 28
      lottery-system/lottery-service/src/main/resources/application.yml
  37. 2
      lottery-system/lottery-service/src/main/resources/mapper/api/prizeMapper.xml

2
lottery-system/lottery-pojo/src/main/java/com/lottery/dto/FixUserDto.java

@ -17,5 +17,5 @@ public class FixUserDto {
private String jwcode;
private String GradeName;
private Long GradeId;
}

2
lottery-system/lottery-pojo/src/main/java/com/lottery/dto/PrizeDto.java

@ -21,7 +21,7 @@ public class PrizeDto {
private String prizeName;
private String gradeName;
private Long gradeId;
private String imageUrl;
}

10
lottery-system/lottery-pojo/src/main/java/com/lottery/dto/StartLotteryDto.java

@ -14,7 +14,13 @@ import lombok.Data;
public class StartLotteryDto {
private int perWin;
private String gradeName;
private Long gradeId;
private String PrizeName;
private Long PrizeId;
private int remainNum;
// private String gradeName;
// private String prizeName;
}

4
lottery-system/lottery-pojo/src/main/java/com/lottery/dto/UserQueryDto.java

@ -16,4 +16,8 @@ public class UserQueryDto {
private String username;
private String jwcode;
private Integer pageNum;
private Integer pageSize;
}

31
lottery-system/lottery-pojo/src/main/java/com/lottery/dto/WinUserExportDto.java

@ -0,0 +1,31 @@
package com.lottery.dto;
import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.annotation.format.DateTimeFormat;
import lombok.Data;
import java.util.Date;
@Data
public class WinUserExportDto {
@ExcelProperty("序号")
private int index;
@ExcelProperty("姓名")
private String username;
@ExcelProperty("精网号")
private String jwcode;
@ExcelProperty("中奖等级")
private String GradeName;
@ExcelProperty("所中礼品")
private String prizeName;
@ExcelProperty("中奖时间")
@DateTimeFormat("yyyy-MM-dd HH:mm:ss")
private Date winTime;
}

10
lottery-system/lottery-pojo/src/main/java/com/lottery/dto/WinUserQueryDto.java

@ -2,6 +2,8 @@ package com.lottery.dto;
import lombok.Data;
import javax.persistence.criteria.CriteriaBuilder;
/**
* @program: lottery
* @ClassName WinUserQuertDto
@ -14,7 +16,11 @@ import lombok.Data;
public class WinUserQueryDto {
private String username;
private String jwcode;
private String jwcode;
private Long gradeId;
private Integer pageNum;
private String gradeName;
private Integer pageSize;
}

7
lottery-system/lottery-pojo/src/main/java/com/lottery/entity/Grade.java

@ -27,14 +27,17 @@ public class Grade {
@TableId(type = IdType.AUTO) // 主键自增策略
private Long id;
private String GradeName; // 等级名称
private String gradeName; // 等级名称
private int amount; //等级数量
private int sort;
@TableField("per_win")
private int perWin;
private int perWin; //每轮抽取人数
@TableField("remain_num")
private int remainNum;
@TableField(value = "create_time", fill = FieldFill.INSERT) // 自动填充创建时间
private Date createTime;

2
lottery-system/lottery-pojo/src/main/java/com/lottery/entity/WinnerRecord.java

@ -11,6 +11,7 @@ package com.lottery.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
@ -32,6 +33,7 @@ public class WinnerRecord {
private Long prizeId; // 奖品ID
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date winTime; // 中奖时间
}

18
lottery-system/lottery-pojo/src/main/java/com/lottery/vo/GradeSimpleVo.java

@ -0,0 +1,18 @@
package com.lottery.vo;
import lombok.Data;
/**
* @program: lottery
* @ClassName GradeSimpleVo
* @description:
* @author: wwl
* @create: 2025-07-19 11:50
* @Version 1.0
**/
@Data
public class GradeSimpleVo {
private String gradeName;
private int id;
}

2
lottery-system/lottery-pojo/src/main/java/com/lottery/vo/GradeVo.java

@ -17,7 +17,7 @@ import java.util.Date;
@Data
public class GradeVo {
// private Long id;
private Long id;
private String GradeName; // 等级名称

21
lottery-system/lottery-pojo/src/main/java/com/lottery/vo/LotteryVo.java

@ -0,0 +1,21 @@
package com.lottery.vo;
import lombok.Data;
import java.util.List;
/**
* @program: lottery
* @ClassName lotteryVo
* @description:
* @author: wwl
* @create: 2025-07-19 10:45
* @Version 1.0
**/
@Data
public class LotteryVo {
private List<UserVo> data; // 只包含jwcode和username
private Boolean round; // 整体是否还有下一轮
}

12
lottery-system/lottery-pojo/src/main/java/com/lottery/vo/PrizeAndGradeVo.java

@ -23,4 +23,16 @@ public class PrizeAndGradeVo {
private int perWin;
private int remainNum;
private int gradeId;
private int prizeId;
// private Integer isRound;
//
// private Integer currentRound;
// 总轮次
}

2
lottery-system/lottery-pojo/src/main/java/com/lottery/vo/PrizeVo.java

@ -16,7 +16,7 @@ import java.util.Date;
@Data
public class PrizeVo {
// private Long id;
private Long id;
private String PrizeName;

1
lottery-system/lottery-pojo/src/main/java/com/lottery/vo/UserVo.java

@ -13,6 +13,7 @@ import lombok.Data;
@Data
public class UserVo {
private Long id;
private String jwcode;
private String username;
}

5
lottery-system/lottery-pojo/src/main/java/com/lottery/vo/WinUserVo.java

@ -1,5 +1,6 @@
package com.lottery.vo;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import java.util.Date;
@ -16,6 +17,8 @@ import java.util.Date;
@Data
public class WinUserVo {
private Long id;
private String username;
private String jwcode;
@ -24,5 +27,7 @@ public class WinUserVo {
private String prizeName;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date winTime; // 中奖时间;
}

6
lottery-system/lottery-service/pom.xml

@ -30,6 +30,12 @@
<artifactId>lottery-common</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>

22
lottery-system/lottery-service/src/main/java/com/lottery/admin/controller/AdminGradeController.java

@ -8,6 +8,7 @@ import com.lottery.exception.SomeException;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.lottery.result.Result;
import com.lottery.utils.ConvertBeanUtil;
import com.lottery.vo.GradeSimpleVo;
import com.lottery.vo.GradeVo;
import com.lottery.vo.PageInfo;
import org.slf4j.Logger;
@ -57,12 +58,11 @@ public class AdminGradeController {
}
@PostMapping("/allGradeName")
public Result<List<String>> selectAllGrade(){
//TODo 按照grade的sort返回
public Result<List<GradeSimpleVo>> selectAllGrade(){
LOGGER.info("查询所有等级,仅反等级名和id,为了下拉框");
return Result.success(adminGradeService.selectAllGrade());
}
@PostMapping("/add")
public Result add(@RequestBody GradeDto gradeDto){
@ -78,17 +78,11 @@ public class AdminGradeController {
return Result.failure("等级已存在,新增失败");
}
Grade grade = ConvertBeanUtil.convert(gradeDto, Grade.class);
grade.setCreateTime(new Date());
grade.setUpdateTime(new Date());
if (!adminGradeService.save(grade)) return Result.failure("新增失败");
if (!adminGradeService.saveGrade(gradeDto)) return Result.failure("新增失败");
return Result.success();
}
@PostMapping("/update")
public Result update(@RequestBody GradeDto gradeDto){
@ -102,6 +96,12 @@ public class AdminGradeController {
return Result.failure("修改的id不存在");
}
LambdaQueryWrapper<Grade> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(Grade::getGradeName, gradeDto.getGradeName());
if (adminGradeService.count(queryWrapper) > 0) {
return Result.failure("等级已存在,修改失败");
}
Grade grade = ConvertBeanUtil.convert(gradeDto, Grade.class);
grade.setUpdateTime(new Date());
@ -109,7 +109,6 @@ public class AdminGradeController {
return Result.success();
}
@PostMapping("/delete")
public Result delete(@RequestParam Long id){
LOGGER.info("删除id为:{} 的等级" ,id);
@ -118,5 +117,4 @@ public class AdminGradeController {
}
return Result.success();
}
}

5
lottery-system/lottery-service/src/main/java/com/lottery/admin/controller/AdminPrizeController.java

@ -47,7 +47,7 @@ public class AdminPrizeController {
public Result addPrize(@RequestBody PrizeDto prizeDto) {
LOGGER.info("新增奖品:{}", prizeDto);
if (prizeDto.getPrizeName() == null || prizeDto.getImageUrl() == null||
prizeDto.getGradeName() == null) {
prizeDto.getGradeId() == null) {
return Result.failure("所有字段都必须填写");
}
if(!adminPrizeService.add(prizeDto)){
@ -61,7 +61,7 @@ public class AdminPrizeController {
public Result updatePrize(@RequestBody PrizeDto prizeDto) {
LOGGER.info("修改奖品信息:{}",prizeDto);
if (prizeDto.getPrizeName() == null || prizeDto.getImageUrl() == null||
prizeDto.getGradeName() == null) {
prizeDto.getGradeId() == null) {
return Result.failure("所有字段都必须填写");
}
@ -86,6 +86,7 @@ public class AdminPrizeController {
return Result.success();
}
//新增内定
@PostMapping("/addFixUser")
public Result addWinUser(@RequestBody FixUserDto fixUserDto) {

27
lottery-system/lottery-service/src/main/java/com/lottery/admin/controller/AdminUserController.java

@ -57,11 +57,15 @@ public class AdminUserController {
}
@PostMapping("/list")
public Result<PageInfo<UserVo>> getAllUser(@RequestParam(defaultValue = "1") int pageNum, @RequestParam(defaultValue = "10") int pageSize,
@RequestBody UserQueryDto userQueryDto ){
public Result<PageInfo<UserVo>> getAllUser(@RequestBody UserQueryDto userQueryDto ){
LOGGER.info("分页查询所有用户");
return Result.success(adminUserService.listUser(pageNum,pageSize,userQueryDto));
if (userQueryDto.getPageNum() == null) {
userQueryDto.setPageNum(1);
}
if (userQueryDto.getPageSize() == null) {
userQueryDto.setPageSize(10);
}
return Result.success(adminUserService.listUser(userQueryDto.getPageNum(), userQueryDto.getPageSize(), userQueryDto));
}
@ -108,10 +112,15 @@ public class AdminUserController {
@PostMapping("/list/fix")
public Result<PageInfo<UserVo>> getAllFixUser(@RequestParam(defaultValue = "1") int pageNum, @RequestParam(defaultValue = "10") int pageSize,
@RequestBody UserQueryDto userQueryDto ){
public Result<PageInfo<UserVo>> getAllFixUser(@RequestBody UserQueryDto userQueryDto){
LOGGER.info("分页查询所有内定用户");
return Result.success(adminUserDetailService.listFixUser(pageNum,pageSize,userQueryDto));
if (userQueryDto.getPageNum() == null) {
userQueryDto.setPageNum(1);
}
if (userQueryDto.getPageSize() == null) {
userQueryDto.setPageSize(10);
}
return Result.success(adminUserDetailService.listFixUser(userQueryDto.getPageNum(),userQueryDto.getPageSize(),userQueryDto));
}
@ -134,7 +143,7 @@ public class AdminUserController {
//TODO 导入有点问题
@PostMapping("/import/fix")
public Result importFixUsers(@RequestParam("file") MultipartFile file, @RequestParam String gradeName) {
public Result importFixUsers(@RequestParam("file") MultipartFile file, @RequestParam Long gradeId) {
LOGGER.info("开始导入内定用户Excel文件: {}", file.getOriginalFilename());
// 1. 基本文件校验
@ -146,7 +155,7 @@ public class AdminUserController {
if (!fileName.endsWith(".xlsx") && !fileName.endsWith(".xls")) {
return Result.failure("仅支持Excel文件(.xlsx, .xls)");
}
return adminUserDetailService.importUsers(file,gradeName);
return adminUserDetailService.importFixUsers(file,gradeId);
}
}

14
lottery-system/lottery-service/src/main/java/com/lottery/admin/controller/AdminWInController.java

@ -36,10 +36,16 @@ public class AdminWInController {
@PostMapping("/list")
public Result<PageInfo<WinUserVo>> WInController(@RequestParam(defaultValue = "1") int pageNum, @RequestParam(defaultValue = "10") int pageSize,
@RequestBody WinUserQueryDto winUserQueryDto) {
public Result<PageInfo<WinUserVo>> WInController(@RequestBody WinUserQueryDto winUserQueryDto) {
LOGGER.info("分页查询所有中奖用户");
return Result.success(adminWinService.listWinUser(pageNum, pageSize, winUserQueryDto));
if (winUserQueryDto.getPageNum() == null) {
winUserQueryDto.setPageNum(1);
}
if (winUserQueryDto.getPageSize() == null) {
winUserQueryDto.setPageSize(10);
}
return Result.success(adminWinService.listWinUser(winUserQueryDto.getPageNum(), winUserQueryDto.getPageSize(), winUserQueryDto));
}
@ -48,6 +54,4 @@ public class AdminWInController {
log.info("导出中奖用户数据");
adminWinService.exportWinUser(winUserQueryDto, response);
}
}

5
lottery-system/lottery-service/src/main/java/com/lottery/admin/mapper/AdminGradeMapper.java

@ -2,6 +2,7 @@ package com.lottery.admin.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.lottery.entity.Grade;
import com.lottery.vo.GradeSimpleVo;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
@ -22,6 +23,6 @@ public interface AdminGradeMapper extends BaseMapper<Grade> {
@Select("select * from grade where grade_name = #{gradeName}")
Grade selectByName(String gradeName);
@Select("select grade_name from grade order by sort desc ")
List<String> selectAllGrade();
@Select("select grade_name, id from grade order by sort desc ")
List<GradeSimpleVo> selectAllGrade();
}

7
lottery-system/lottery-service/src/main/java/com/lottery/admin/service/AdminGradeService.java

@ -7,6 +7,7 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.lottery.dto.GradeDto;
import com.lottery.entity.Grade;
import com.lottery.vo.GradeSimpleVo;
import com.lottery.vo.GradeVo;
import com.lottery.vo.PageInfo;
import org.springframework.stereotype.Service;
@ -27,7 +28,11 @@ import java.util.List;
public interface AdminGradeService extends IService<Grade> {
PageInfo<GradeVo> pageSelectGrade(Integer pageNum, Integer pageSize);
List<String > selectAllGrade();
List<GradeSimpleVo> selectAllGrade();
boolean saveGrade(GradeDto gradeDto);
// boolean updateGradeById(GradeDto GradeDto);
// boolean updateGrade(GradeDto gradeDto);

2
lottery-system/lottery-service/src/main/java/com/lottery/admin/service/AdminUserDetailService.java

@ -21,5 +21,5 @@ import org.springframework.web.multipart.MultipartFile;
public interface AdminUserDetailService extends IService<UserDetail> {
PageInfo<UserVo> listFixUser(int pageNum, int pageSize, UserQueryDto userQueryDto);
Result importUsers(MultipartFile file, String gradeName);
Result importFixUsers(MultipartFile file, Long gradeId);
}

3
lottery-system/lottery-service/src/main/java/com/lottery/admin/service/AdminWinService.java

@ -7,6 +7,7 @@ import com.lottery.vo.PageInfo;
import com.lottery.vo.WinUserVo;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.List;
import java.util.Map;
@ -24,5 +25,5 @@ public interface AdminWinService extends IService<WinnerRecord> {
PageInfo<WinUserVo> listWinUser(int pageNum, int pageSize, WinUserQueryDto winUserQueryDto);
void exportWinUser(WinUserQueryDto winUserQueryDto, HttpServletResponse response) throws UnsupportedEncodingException;
void exportWinUser(WinUserQueryDto winUserQueryDto, HttpServletResponse response) throws IOException;
}

19
lottery-system/lottery-service/src/main/java/com/lottery/admin/service/Impl/AdminGradeServiceImpl.java

@ -11,6 +11,7 @@ import com.lottery.entity.Grade;
import com.lottery.exception.SomeException;
import com.lottery.result.Result;
import com.lottery.utils.ConvertBeanUtil;
import com.lottery.vo.GradeSimpleVo;
import com.lottery.vo.GradeVo;
import com.lottery.vo.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
@ -59,9 +60,23 @@ public class AdminGradeServiceImpl extends ServiceImpl<AdminGradeMapper, Grade>
}
@Override
public List<String> selectAllGrade() {
public List<GradeSimpleVo> selectAllGrade() {
// List<String> GradeNameList = new ArrayList<>();
return adminGradeMapper.selectAllGrade();
List<GradeSimpleVo> gradeSimpleVos = adminGradeMapper.selectAllGrade();
return gradeSimpleVos;
}
@Override
public boolean saveGrade(GradeDto gradeDto) {
Grade grade = ConvertBeanUtil.convert(gradeDto, Grade.class);
grade.setRemainNum(gradeDto.getAmount());
grade.setCreateTime(new Date());
grade.setUpdateTime(new Date());
if (this.save(grade)){
return true;
};
return false;
}
// @Autowired

17
lottery-system/lottery-service/src/main/java/com/lottery/admin/service/Impl/AdminPrizeServiceImpl.java

@ -60,8 +60,8 @@ public class AdminPrizeServiceImpl extends ServiceImpl<AdminPrizeMapper, Prize>
@Override
public boolean add(PrizeDto prizeDto) {
String gradeName = prizeDto.getGradeName();
Grade grade = adminGradeMapper.selectByName(gradeName);
Long gradeId = prizeDto.getGradeId();
Grade grade = adminGradeMapper.selectById(gradeId);
// if (grade == null) {
//// return Result.failure("等级不存在");
// throw new SomeException("heheh");
@ -85,15 +85,13 @@ public class AdminPrizeServiceImpl extends ServiceImpl<AdminPrizeMapper, Prize>
.build();
return this.save(prize);
}
@Override
public boolean updatePrize(PrizeDto prizeDto) {
String gradeName = prizeDto.getGradeName();
Grade grade = adminGradeMapper.selectByName(gradeName);
Long gradeId = prizeDto.getGradeId();
Grade grade = adminGradeMapper.selectById(gradeId);
//TODO 修改自己的等奖会失败
// 2. 检查是否是修改现有奖品需要传入prizeId
// 1. 查询原奖品信息
Prize originalPrize = adminPrizeMapper.selectById(prizeDto.getId());
@ -102,7 +100,7 @@ public class AdminPrizeServiceImpl extends ServiceImpl<AdminPrizeMapper, Prize>
}
// 2. 查询目标等级信息
Grade targetGrade = adminGradeMapper.selectByName(prizeDto.getGradeName());
Grade targetGrade = adminGradeMapper.selectById(gradeId);
if (targetGrade == null) {
return false; // 目标等级不存在
}
@ -124,7 +122,6 @@ public class AdminPrizeServiceImpl extends ServiceImpl<AdminPrizeMapper, Prize>
return false; // 奖品名称已存在
}
// LambdaQueryWrapper<Prize> wrapper = new LambdaQueryWrapper<>();
// wrapper.eq(Prize::getGradeId, grade.getId());
// if (this.count(wrapper) > 0) {
@ -167,8 +164,8 @@ public class AdminPrizeServiceImpl extends ServiceImpl<AdminPrizeMapper, Prize>
adminUserMapper.insert(user); //不存在插入总表
}
Grade grade = adminGradeMapper.selectByName(fixUserDto.getGradeName());
Long gradeId = grade.getId();
// Grade grade = adminGradeMapper.selectByName(fixUserDto.getGradeName());
Long gradeId = fixUserDto.getGradeId();
Long userIdd = adminUserMapper.selectByJwcode(fixUserDto.getJwcode());

100
lottery-system/lottery-service/src/main/java/com/lottery/admin/service/Impl/AdminUserDetailServiceImpl.java

@ -84,7 +84,7 @@ public class AdminUserDetailServiceImpl extends ServiceImpl<IUserDetailMapper, U
@Override
@Transactional(rollbackFor = Exception.class)
public Result importUsers(MultipartFile file, String gradeName) {
public Result importFixUsers(MultipartFile file, Long gradeId) {
try {
// 1. 解析Excel
List<UserImportDto> userDtos = EasyExcel.read(file.getInputStream())
@ -92,29 +92,33 @@ public class AdminUserDetailServiceImpl extends ServiceImpl<IUserDetailMapper, U
.sheet()
.doReadSync();
// 2. 数据校验和去重
Set<String> existingCodes = adminUserMapper.selectAllUserCodes();
List<User> users = new ArrayList<>();
// 2. 准备数据集合
List<User> newUsers = new ArrayList<>(); // 新用户(需要插入user表)
List<User> existingUsers = new ArrayList<>(); // 已存在用户(从数据库查询)
List<UserDetail> userDetails = new ArrayList<>();
Set<String> processedCodes = new HashSet<>();
int successCount = 0;
int skipCount = 0;
// 3. 查询所有已存在的jwcode
Set<String> existingCodes = adminUserMapper.selectAllUserCodes();
for (int i = 0; i < userDtos.size(); i++) {
UserImportDto dto = userDtos.get(i);
try {
validateUser(dto, i + 2, existingCodes, processedCodes);
// 转换User实体
User user = convertToEntity(dto);
users.add(user);
// 生成UserDetail
UserDetail detail = new UserDetail();
detail.setUserId(user.getId()); // 会在保存后自动填充
detail.setGradeId(adminGradeMapper.selectByName(gradeName).getId()); // 默认等级
detail.setIsFixed(1); // 默认未固定
userDetails.add(detail);
validateUser(dto, i + 2, processedCodes); // 移除了existingCodes检查
// 检查用户是否已存在
if (existingCodes.contains(dto.getJwcode())) {
// 用户已存在查询用户信息
// User existingUser = adminUserMapper.selectByJwcode(dto.getJwcode());
Long userId = adminUserMapper.selectByJwcode(dto.getJwcode());
existingUsers.add(adminUserMapper.selectById(userId));
} else {
// 用户不存在创建新用户
User newUser = convertToEntity(dto);
newUsers.add(newUser);
}
processedCodes.add(dto.getJwcode());
successCount++;
@ -124,24 +128,30 @@ public class AdminUserDetailServiceImpl extends ServiceImpl<IUserDetailMapper, U
}
}
// 3. 批量保存
if (!users.isEmpty()) {
// 批量保存用户
boolean userSaved = adminUserService.saveBatch(users);
// 设置userDetail的userId
for (int i = 0; i < users.size(); i++) {
userDetails.get(i).setUserId(users.get(i).getId());
}
// 4. 批量保存新用户
if (!newUsers.isEmpty()) {
adminUserService.saveBatch(newUsers);
}
// 批量保存用户详情
boolean detailSaved = this.saveBatch(userDetails);
// 5. 准备userDetail数据 (包括新用户和已存在用户)
List<User> allUsers = new ArrayList<>();
allUsers.addAll(newUsers);
allUsers.addAll(existingUsers);
for (User user : allUsers) {
UserDetail detail = new UserDetail();
detail.setUserId(user.getId());
detail.setGradeId(gradeId);
detail.setIsFixed(1); // 标记为内定用户
userDetails.add(detail);
}
if (userSaved && detailSaved) {
return Result.success(String.format("导入成功%d条,跳过%d条", successCount, skipCount));
}
return Result.failure("部分数据导入失败");
// 6. 批量保存userDetail
if (!userDetails.isEmpty()) {
this.saveBatch(userDetails);
return Result.success(String.format("导入成功%d条,跳过%d条", successCount, skipCount));
}
return Result.failure("没有有效数据可导入");
} catch (Exception e) {
LOGGER.error("导入用户失败", e);
@ -149,18 +159,7 @@ public class AdminUserDetailServiceImpl extends ServiceImpl<IUserDetailMapper, U
}
}
private User convertToEntity(UserImportDto dto) {
User user = new User();
user.setJwcode(dto.getJwcode());
user.setUsername(dto.getUsername());
user.setCreateTime(new Date());
user.setUpdateTime(new Date());
// 密码加密
user.setPassword("123456");
return user;
}
private void validateUser(UserImportDto dto, int rowNum, Set<String> existingCodes, Set<String> processedCodes) {
private void validateUser(UserImportDto dto, int rowNum, Set<String> processedCodes) {
if (StringUtils.isBlank(dto.getJwcode())) {
throw new IllegalArgumentException("第" + rowNum + "行: 精网号不能为空");
}
@ -169,12 +168,19 @@ public class AdminUserDetailServiceImpl extends ServiceImpl<IUserDetailMapper, U
throw new IllegalArgumentException("第" + rowNum + "行: 姓名不能为空");
}
if (existingCodes.contains(dto.getJwcode())) {
throw new IllegalArgumentException("第" + rowNum + "行: 精网号已存在");
}
if (processedCodes.contains(dto.getJwcode())) {
throw new IllegalArgumentException("第" + rowNum + "行: 精网号在当前文件中重复");
}
}
private User convertToEntity(UserImportDto dto) {
User user = new User();
user.setJwcode(dto.getJwcode());
user.setUsername(dto.getUsername());
user.setCreateTime(new Date());
user.setUpdateTime(new Date());
// 密码加密
user.setPassword("123456");
return user;
}
}

96
lottery-system/lottery-service/src/main/java/com/lottery/admin/service/Impl/AdminWinServiceImpl.java

@ -14,7 +14,9 @@ import com.lottery.admin.service.AdminGradeService;
import com.lottery.admin.service.AdminPrizeService;
import com.lottery.admin.service.AdminUserService;
import com.lottery.admin.service.AdminWinService;
import com.lottery.dto.UserImportDto;
import com.lottery.dto.UserQueryDto;
import com.lottery.dto.WinUserExportDto;
import com.lottery.dto.WinUserQueryDto;
import com.lottery.entity.*;
import com.lottery.utils.ConvertBeanUtil;
@ -25,12 +27,10 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.*;
import java.util.stream.Collectors;
/**
@ -80,6 +80,14 @@ public class AdminWinServiceImpl extends ServiceImpl<AdminWinMapper, WinnerRecor
);
}
if (!(winUserQueryDto.getGradeId() == null)) {
recordWrapper.exists(
"SELECT 1 FROM prize p WHERE p.id = winning_record.prize_id AND p.grade_id = {0}",
winUserQueryDto.getGradeId()
).or(); // 添加 OR 条件避免无结果时报错
//.isNull("grade_id"); // 同时允许 grade_id 为空的记录;
}
// 3. 执行分页查询WinnerRecord表
Page<WinnerRecord> recordPage = adminWinMapper.selectPage(page, recordWrapper);
@ -92,18 +100,19 @@ public class AdminWinServiceImpl extends ServiceImpl<AdminWinMapper, WinnerRecor
.distinct()
.collect(Collectors.toList());
// 4.1 查询用户基本信息
Map<Long, User> userMap = adminUserService.listByIds(userIds).stream()
// 4.1 查询用户基本信息 //如果ids为空返回空列表
Map<Long, User> userMap = userIds.isEmpty() ? new HashMap<>() : adminUserService.listByIds(userIds).stream()
.collect(Collectors.toMap(User::getId, u -> u));
// 4.2 查询奖品及对应等级信息
Map<Long, Prize> prizeMap = adminPrizeService.listByIds(prizeIds).stream()
Map<Long, Prize> prizeMap = prizeIds.isEmpty() ? new HashMap<>(): adminPrizeService.listByIds(prizeIds).stream()
.collect(Collectors.toMap(Prize::getId, p -> p));
List<Long> gradeIds = prizeMap.values().stream()
.map(Prize::getGradeId)
.collect(Collectors.toList());
Map<Long, Grade> gradeMap = adminGradeService.listByIds(gradeIds).stream()
Map<Long, Grade> gradeMap =gradeIds.isEmpty() ? new HashMap<>():adminGradeService.listByIds(gradeIds).stream()
.collect(Collectors.toMap(Grade::getId, g -> g));
// 5. 转换为VO
@ -131,7 +140,7 @@ public class AdminWinServiceImpl extends ServiceImpl<AdminWinMapper, WinnerRecor
// 设置中奖时间
vo.setWinTime(record.getWinTime());
vo.setId(record.getId());
return vo;
})
.collect(Collectors.toList());
@ -146,33 +155,50 @@ public class AdminWinServiceImpl extends ServiceImpl<AdminWinMapper, WinnerRecor
//导出数据
@Override
public void exportWinUser(WinUserQueryDto winUserQueryDto, HttpServletResponse response) throws UnsupportedEncodingException {
// response.setContentType("application/json.openxmlfomats-officedocument.spreadsheetml.sheet;charset=utf-8");
// response.setCharacterEncoding("utf-8");
//
// // 根据姓名获取user_id列表
//
//
// // 根据user_id查询用户信息
//
//
public void exportWinUser(WinUserQueryDto winUserQueryDto, HttpServletResponse response) throws IOException {
//
// // 3. 处理中文文件名URL 编码
// String fileName = "获奖记录" + ".xlsx";
// String encodedFileName = URLEncoder.encode(fileName, "UTF-8").replaceAll("\\+", "%20");
//
// // 4. 设置 Content-Disposition 响应头指定下载文件名
// response.setHeader("Content-Disposition", "attachment; filename*=UTF-8''" + encodedFileName);
//
//
// // 查询数据列表
// List<FundingExport> list = listWinUser(1,10,winUserQueryDto);
//
// EasyExcel.write(response.getOutputStream(), FundingExport.class)
// .excelType(ExcelTypeEnum.XLSX)
// .sheet("获奖记录")
// .doWrite(list);
// 1. 设置响应内容类型和编码
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
response.setCharacterEncoding("UTF-8");
// 2. 设置文件名处理中文乱码
String fileName = "中奖名单_" + System.currentTimeMillis() + ".xlsx";
String encodedFileName = URLEncoder.encode(fileName, "UTF-8").replaceAll("\\+", "%20");
response.setHeader("Content-Disposition", "attachment; filename*=UTF-8''" + encodedFileName);
// 3. 查询中奖用户数据
// List<WinUserExportDto> winUsers = listWinUser(1, 1000, winUserQueryDto);
//全部放进一页里面直接取
PageInfo<WinUserVo> winUserVoPageInfo = listWinUser(1, Integer.MAX_VALUE, winUserQueryDto);
// 4. 使用EasyExcel导出
EasyExcel.write(response.getOutputStream(), WinUserExportDto.class)
.excelType(ExcelTypeEnum.XLSX)
.sheet("中奖名单")
.doWrite(convertToExportDto(winUserVoPageInfo.getList()));
}
// Vo ExportDto 的转换方法
private List<WinUserExportDto> convertToExportDto(List<WinUserVo> voList) {
List<WinUserExportDto> result = new ArrayList<>();
for (int i = 0; i < voList.size(); i++) {
WinUserVo vo = voList.get(i);
WinUserExportDto dto = new WinUserExportDto();
// 设置序号
dto.setIndex(i + 1);
// 复制其他字段
dto.setJwcode(vo.getJwcode());
dto.setUsername(vo.getUsername());
dto.setPrizeName(vo.getPrizeName());
dto.setWinTime(vo.getWinTime());
dto.setGradeName(vo.getGradeName());
result.add(dto);
}
return result;
}
}

13
lottery-system/lottery-service/src/main/java/com/lottery/api/controller/LotteryController.java

@ -1,18 +1,14 @@
package com.lottery.api.controller;
import com.lottery.api.service.IUserDetailService;
import com.lottery.api.service.Impl.UserDetailServiceImpl;
import com.lottery.dto.StartLotteryDto;
import com.lottery.entity.User;
import com.lottery.result.Result;
import com.lottery.vo.UserVo;
import com.lottery.vo.LotteryVo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* @program: lottery
* @ClassName LotteryController
@ -31,11 +27,12 @@ public class LotteryController {
@Autowired
private IUserDetailService userDetailService;
//TODO 一个用户内定多个等奖会出现bug
@PostMapping("/start")
public Result<List<UserVo>> StartLottery(@RequestBody StartLotteryDto startLotteryDto){
public Result<LotteryVo> StartLottery(@RequestBody StartLotteryDto startLotteryDto){
LOGGER.info("开始抽奖: 等级是:{},奖品是:{},抽取人数:{}",startLotteryDto.getGradeName(),startLotteryDto.getPrizeName(),startLotteryDto.getPerWin());
List<UserVo> userVos = userDetailService.StartLottery(startLotteryDto);
LOGGER.info("开始抽奖: 等级是:{},奖品是:{},抽取人数:{}",startLotteryDto.getGradeId(),startLotteryDto.getPrizeId(),startLotteryDto.getPerWin());
LotteryVo userVos = userDetailService.StartLottery(startLotteryDto);
return Result.success(userVos);
}
}

2
lottery-system/lottery-service/src/main/java/com/lottery/api/controller/UserController.java

@ -68,6 +68,8 @@ public class UserController {
}
@PostMapping("/list")
//TODO 返回数据给前端最大140条数据库不够140条凑够140条
public Result<List<UserVo>> getAllUser(){
LOGGER.info("查询所有用户");

6
lottery-system/lottery-service/src/main/java/com/lottery/api/service/IUserDetailService.java

@ -3,9 +3,7 @@ package com.lottery.api.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.lottery.dto.StartLotteryDto;
import com.lottery.entity.UserDetail;
import com.lottery.vo.UserVo;
import java.util.List;
import com.lottery.vo.LotteryVo;
/**
* @program: lottery
@ -16,5 +14,5 @@ import java.util.List;
* @Version 1.0
**/
public interface IUserDetailService extends IService<UserDetail> {
List<UserVo> StartLottery(StartLotteryDto startLotteryDto);
LotteryVo StartLottery(StartLotteryDto startLotteryDto);
}

56
lottery-system/lottery-service/src/main/java/com/lottery/api/service/Impl/PrizeServiceImpl.java

@ -1,5 +1,6 @@
package com.lottery.api.service.Impl;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lottery.api.mapper.IGradeMapper;
import com.lottery.api.mapper.IPrizeMapper;
@ -8,11 +9,15 @@ import com.lottery.api.service.IPrizeService;
import com.lottery.entity.Prize;
import com.lottery.vo.PrizeAndGradeVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.persistence.criteria.CriteriaBuilder;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Map;
/**
* @program: lottery-system
@ -32,10 +37,59 @@ public class PrizeServiceImpl extends ServiceImpl<IPrizeMapper, Prize> implement
@Autowired
private IGradeMapper gradeMapper;
// @Autowired
// private RedisTemplate<String, Integer> redisTemplate; // 使用Integer类型的RedisTemplate
//
// private static final String REDIS_KEY_PREFIX = "grade:";
@Override
public List<PrizeAndGradeVo> getAllPrizeAndGrade() {
return prizeMapper.selectPrizeAndGrade();
List<PrizeAndGradeVo> prizeAndGradeVos = prizeMapper.selectPrizeAndGrade();
// for (PrizeAndGradeVo vo : prizeAndGradeVos) {
// String redisKey = REDIS_KEY_PREFIX + vo.getGradeId();
//
// // 从Redis获取已抽取数量如果没有则返回0
// Integer drawedCount = redisTemplate.opsForValue().get(redisKey);
// if (drawedCount == null) {
// drawedCount = 0;
// }
//
// // 计算剩余数量 = 总数 - 已抽取数 - 每轮抽取数
// int remainNum = vo.getAmount() - drawedCount - vo.getPerWin();
// vo.setRemainNum(remainNum);
//
// // 计算是否还有下一轮剩余数量 >= 0 也放在抽奖之后
// Integer isRound = 0;
// if ((vo.getAmount() - drawedCount) - vo.getPerWin() >= 0){
// isRound = 1;
// }
// vo.setIsRound(isRound);
//
// // 计算当前轮次
// int currentRound = (drawedCount / vo.getPerWin()) + 1;
// vo.setCurrentRound(currentRound);
// }
// return prizeAndGradeVos;
// }
//
//
// @Transactional
// public List<PrizeAndGradeVo> drawWinners(Long gradeId, int winnerCount) {
// String redisKey = REDIS_KEY_PREFIX + gradeId;
//
// // 原子性增加已抽取数量
// redisTemplate.opsForValue().increment(redisKey, winnerCount);
//
// // 返回更新后的奖品信息
// return getAllPrizeAndGrade();
// }
//
// public void resetDrawCount(Long gradeId) {
// String redisKey = REDIS_KEY_PREFIX + gradeId;
// redisTemplate.delete(redisKey);
// }
return prizeAndGradeVos;
}
}

124
lottery-system/lottery-service/src/main/java/com/lottery/api/service/Impl/UserDetailServiceImpl.java

@ -1,8 +1,8 @@
package com.lottery.api.service.Impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
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;
@ -15,18 +15,14 @@ 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 com.lottery.vo.LotteryVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.*;
import java.util.stream.Collectors;
/**
* @program: lottery
@ -138,24 +134,27 @@ public class UserDetailServiceImpl extends ServiceImpl<IUserDetailMapper, UserDe
@Override
@Transactional(rollbackFor = Exception.class)
public List<UserVo> StartLottery(StartLotteryDto startLotteryDto) {
// 1. 获取年级ID
Long gradeId = gradeMapper.selectByName(startLotteryDto.getGradeName());
if (gradeId == null) {
throw new SomeException("未找到指定等级:" + startLotteryDto.getGradeName());
public LotteryVo StartLottery(StartLotteryDto startLotteryDto) {
// 校验
Grade grade = gradeMapper.selectById(startLotteryDto.getGradeId());
if (grade == null) {
throw new SomeException("未找到指定等级:" + startLotteryDto.getGradeId());
}
// 2. 查询该年级下所有内定人员
// 该等奖下所有内定人员集合
LambdaQueryWrapper<UserDetail> userDetailWrapper = new LambdaQueryWrapper<>();
userDetailWrapper.eq(UserDetail::getGradeId, gradeId)
userDetailWrapper.eq(UserDetail::getGradeId, startLotteryDto.getGradeId())
.eq(UserDetail::getIsFixed, 1);
List<UserDetail> fixedUsers = userDetailMapper.selectList(userDetailWrapper);
// 3. 准备中奖用户结果集
// 该等奖下该轮中奖用户结果即winners.size() = perwin 但是也有特殊情况per_win > 剩余人数,只抽剩余人数就行
List<UserVo> winners = new ArrayList<>();
int requiredWinners = startLotteryDto.getPerWin();
if (requiredWinners > startLotteryDto.getRemainNum()) {
requiredWinners = startLotteryDto.getRemainNum();
}
// 4. 先处理内定用户过滤掉已中奖的
// 先处理内定用户过滤掉已中奖的
List<User> availableFixedUsers = getAvailableFixedUsers(fixedUsers);
int fixedWinnersCount = Math.min(availableFixedUsers.size(), requiredWinners);
@ -165,15 +164,30 @@ public class UserDetailServiceImpl extends ServiceImpl<IUserDetailMapper, UserDe
markUsersAsWinners(fixedWinners, startLotteryDto); // 标记为已中奖,并加入到中奖记录表里面
}
// 5. 如果人数不足从全体用户补充同样过滤掉已中奖的
// 5. 如果人数不足从全体用户补充同样过滤掉已中奖的和别的等级下内定的也要过滤
if (winners.size() < requiredWinners) {
int remaining = requiredWinners - winners.size();
List<User> allAvailableUsers = getAllAvailableUsers();
// List<User> allAvailableUsers = getAllAvailableUsers();
// List<User> supplementWinners = randomSelectUsers(allAvailableUsers, Math.min(remaining, allAvailableUsers.size()));
// winners.addAll(convertToUserVoList(supplementWinners));
// markUsersAsWinners(supplementWinners, startLotteryDto); // 标记为已中奖,并加入到中奖记录表里面
List<User> allAvailableUsers = getAllAvailableUsers(startLotteryDto.getGradeId()); //过滤别的等级下内定的用户和已中奖的用户
List<User> supplementWinners = randomSelectUsers(allAvailableUsers, Math.min(remaining, allAvailableUsers.size()));
winners.addAll(convertToUserVoList(supplementWinners));
markUsersAsWinners(supplementWinners, startLotteryDto); // 标记为已中奖,并加入到中奖记录表里面
markUsersAsWinners(supplementWinners, startLotteryDto);
}
return winners;
//剩余人数
int lastNum = startLotteryDto.getRemainNum() - winners.size();
updateRemainNum(grade, lastNum);
boolean hasNextRound = lastNum > 0;
LotteryVo lotteryVo = new LotteryVo();
lotteryVo.setData(winners);
lotteryVo.setRound(hasNextRound);
return lotteryVo;
}
// 获取可用的内定用户未中奖的
@ -188,11 +202,37 @@ public class UserDetailServiceImpl extends ServiceImpl<IUserDetailMapper, UserDe
return availableUsers;
}
// 获取全体可用用户未中奖的
private List<User> getAllAvailableUsers() {
// 获取所有其他等奖的内定用户排除当前等级
private List<User> getOtherGradeFixedUsers(Long excludeGradeId) {
LambdaQueryWrapper<UserDetail> wrapper = new LambdaQueryWrapper<>();
wrapper.ne(UserDetail::getGradeId, excludeGradeId) // 排除当前等级
.eq(UserDetail::getIsFixed, 1);
List<UserDetail> otherFixedUsers = userDetailMapper.selectList(wrapper);
return otherFixedUsers.stream()
.map(userDetail -> userMapper.selectById(userDetail.getUserId()))
.filter(Objects::nonNull)
.collect(Collectors.toList());
}
//获取全体可用用户未中奖且非其他等奖内定用户
private List<User> getAllAvailableUsers(Long currentGradeId) {
// 获取所有其他等奖的内定用户
List<User> otherFixedUsers = getOtherGradeFixedUsers(currentGradeId);
Set<Long> otherFixedUserIds = otherFixedUsers.stream()
.map(User::getId)
.collect(Collectors.toSet());
// 查询所有未中奖用户
LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(User::getIsWin, 0); // 只查询未中奖的
return userMapper.selectList(wrapper);
wrapper.eq(User::getIsWin, 0);
List<User> allUsers = userMapper.selectList(wrapper);
// 过滤掉其他等奖的内定用户
return allUsers.stream()
.filter(user -> !otherFixedUserIds.contains(user.getId()))
.collect(Collectors.toList());
}
// 随机选择用户
@ -206,14 +246,15 @@ public class UserDetailServiceImpl extends ServiceImpl<IUserDetailMapper, UserDe
// 转换为UserVo列表
private List<UserVo> convertToUserVoList(List<User> users) {
List<UserVo> result = new ArrayList<>();
for (User user : users) {
UserVo vo = new UserVo();
vo.setUsername(user.getUsername());
vo.setJwcode(user.getJwcode());
result.add(vo);
}
return result;
return users.stream()
.map(user -> {
UserVo vo = new UserVo();
vo.setUsername(user.getUsername());
vo.setJwcode(user.getJwcode());
vo.setId((long) user.getId());
return vo;
})
.collect(Collectors.toList());
}
// 标记用户为中奖状态
@ -228,12 +269,27 @@ public class UserDetailServiceImpl extends ServiceImpl<IUserDetailMapper, UserDe
WinnerRecord winnerRecord = WinnerRecord.builder()
.userId(user.getId())
.winTime(new Date())
.prizeId(adminPrizeMapper.selectByName(startLotteryDto.getPrizeName())).build();
.prizeId(startLotteryDto.getPrizeId()).build();
adminWinMapper.insert(winnerRecord);
userMapper.updateById(user);
}
}
//抽奖之后更新grade表的remainNum
private void updateRemainNum(Grade grade, int drawnCount) {
// Grade grade = new Grade();
// grade.setId(gradeId);
// grade.setRemainNum(grade.getRemainNum() - drawnCount);
// grade.setUpdateTime(new Date());
// gradeMapper.updateById(grade);
LambdaUpdateWrapper<Grade> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
lambdaUpdateWrapper.eq(Grade::getId, grade.getId())
.set(Grade::getRemainNum, drawnCount)
.set(Grade::getUpdateTime, new Date());
gradeMapper.update(null, lambdaUpdateWrapper);
}
// // 随机选择指定数量的用户(内定名单中)
// private List<UserDetail> randomSelectFixUser(List<UserDetail> users, int count) {
// List<UserDetail> shuffled = new ArrayList<>(users); // 避免修改原集合

32
lottery-system/lottery-service/src/main/java/com/lottery/api/service/Impl/UserServiceImpl.java

@ -1,6 +1,9 @@
package com.lottery.api.service.Impl;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lottery.constant.RedisCacheConstant;
import com.lottery.dto.UserLoginDto;
@ -14,6 +17,7 @@ import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Random;
/**
* @program: lottery-system
@ -49,8 +53,30 @@ public class UserServiceImpl extends ServiceImpl<IUserMapper, User> implements I
@Override
public List<User> listAllUser() {
List<User> list = this.list();
//redisTemplate.opsForValue().set(RedisCacheConstant.ALL_USER_CACHE, JSON.toJSONString(list));
return list;
// 1. 查询前140条用户,直接分页逻辑查就行,
Page<User> page = new Page<>(1, 140);
IPage<User> userPage = this.page(page);
List<User> users = userPage.getRecords();
// 2. 如果不足140条随机补充
if (users.size() < 140) {
int needed = 140 - users.size();
Random random = new Random();
for (int i = 0; i < needed; i++) {
User randomUser = users.get(random.nextInt(users.size()));
users.add(cloneUser(randomUser));
}
}
return users;
}
private User cloneUser(User original) {
User clone = new User();
clone.setId(original.getId());
clone.setUsername(original.getUsername());
clone.setJwcode(original.getJwcode());
return clone;
}
}

75
lottery-system/lottery-service/src/main/java/com/lottery/config/RedisConfig.java

@ -0,0 +1,75 @@
package com.lottery.config;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import com.fasterxml.jackson.databind.ObjectMapper;
@Configuration
public class RedisConfig {
// @Bean
// public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
// RedisTemplate<String, Object> template = new RedisTemplate<>();
// template.setConnectionFactory(redisConnectionFactory);
//
// // 设置 key 的序列化器
// template.setKeySerializer(new StringRedisSerializer());
//
// // 使用 Jackson2JsonRedisSerializer 来序列化/反序列化 Object 类型的 value
// Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class);
// ObjectMapper objectMapper = new ObjectMapper();
// jackson2JsonRedisSerializer.setObjectMapper(objectMapper);
//
// // 设置 value 的序列化器
// template.setValueSerializer(jackson2JsonRedisSerializer);
//
// return template;
// }
// @Bean
// public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
// RedisTemplate<String, Object> template = new RedisTemplate<>();
// template.setConnectionFactory(redisConnectionFactory);
// template.setKeySerializer(new StringRedisSerializer());
//
// // 创建支持 Java 8 时间的序列化器
// Jackson2JsonRedisSerializer<Object> serializer = new Jackson2JsonRedisSerializer<>(Object.class);
//
// // 配置 ObjectMapper
// ObjectMapper objectMapper = new ObjectMapper();
// // 注册 Java 8 时间支持模块
// objectMapper.registerModule(new JavaTimeModule());
// // 禁用时间戳格式避免日期被序列化成数字
// objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
//
// serializer.setObjectMapper(objectMapper);
// template.setValueSerializer(serializer);
//
// return template;
// }
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory connectionFactory) {
RedisTemplate<String, Object> template = new RedisTemplate<>();
template.setConnectionFactory(connectionFactory);
// 使用StringRedisSerializer来序列化和反序列化redis的key值
template.setKeySerializer(new StringRedisSerializer());
template.setHashKeySerializer(new StringRedisSerializer());
// 使用GenericJackson2JsonRedisSerializer来序列化和反序列化redis的value值
template.setValueSerializer(new GenericJackson2JsonRedisSerializer());
template.setHashValueSerializer(new GenericJackson2JsonRedisSerializer());
template.afterPropertiesSet();
return template;
}
}

28
lottery-system/lottery-service/src/main/resources/application.yml

@ -19,20 +19,20 @@ spring:
idle-timeout: 600000 # 空闲连接超时时间(默认 10 分钟)
max-lifetime: 1800000 # 连接最大生命周期(默认 30 分钟)
leak-detection-threshold: 5000 # 连接泄漏检测(毫秒,建议 5s)
# ========== Redis 配置 ==========
# redis:
# host: 127.0.0.1
# port: 6379
# password: # 若无密码则留空
# database: 0 # 默认DB索引
# jedis:
# pool:
# max-active: 8 # 最大连接数
# max-wait: 5000ms # 最大等待时间
# max-idle: 4 # 最大空闲连接
# min-idle: 1 # 最小空闲连接
# timeout: 3000ms # 连接超时时间
#
# ========== Redis 配置 ==========
redis:
host: 39.98.127.73
port: 7001
password: 2TOVfFeJ0pyi9Wtj
database: 0 # 默认DB索引
jedis:
pool:
max-active: 8 # 最大连接数
max-wait: 5000ms # 最大等待时间
max-idle: 4 # 最大空闲连接
min-idle: 1 # 最小空闲连接
timeout: 3000ms # 连接超时时间
# ========== MyBatis 配置(如果使用MyBatis代替JPA) ==========

2
lottery-system/lottery-service/src/main/resources/mapper/api/prizeMapper.xml

@ -3,7 +3,7 @@
<mapper namespace="com.lottery.api.mapper.IPrizeMapper">
<select id="selectPrizeAndGrade" resultType="com.lottery.vo.PrizeAndGradeVo">
select p.prize_name, p.image_url, g.grade_name, g.amount, g.per_win
select p.prize_name, p.image_url, p.id as prizeId, g.grade_name, g.amount, g.per_win, p.grade_id, g.remain_num
from prize p
left join grade g on p.grade_id = g.id
order by g.sort desc

Loading…
Cancel
Save