diff --git a/luoo_user/src/main/java/com/luoo/user/service/UserInfoService.java b/luoo_user/src/main/java/com/luoo/user/service/UserInfoService.java index 853aebd..127eff0 100644 --- a/luoo_user/src/main/java/com/luoo/user/service/UserInfoService.java +++ b/luoo_user/src/main/java/com/luoo/user/service/UserInfoService.java @@ -293,22 +293,6 @@ public class UserInfoService { userInfoDaoByInvitationCode.getId()); userPointLogService.addByTaskDailyAndUserId(TaskPointIdConstants.NEW_USER_INVITE, userInfo.getId()); - - List list = userPointLogDao.findUserPointLogsByUserIdAndTaskPointId( - userInfoDaoByInvitationCode.getId(), TaskPointIdConstants.NEW_USER_INVITE); - if (list.size() == 3) { - userPointLogService.addByTaskDailyAndUserId(TaskPointIdConstants.INVITE_USER_3, - userInfoDaoByInvitationCode.getId()); - } else if (list.size() == 6) { - userPointLogService.addByTaskDailyAndUserId(TaskPointIdConstants.INVITE_USER_6, - userInfoDaoByInvitationCode.getId()); - } else if (list.size() == 10) { - userPointLogService.addByTaskDailyAndUserId(TaskPointIdConstants.INVITE_USER_10, - userInfoDaoByInvitationCode.getId()); - } else if (list.size() == 20) { - userPointLogService.addByTaskDailyAndUserId(TaskPointIdConstants.INVITE_USER_20, - userInfoDaoByInvitationCode.getId()); - } } else { throw new BizException(ErrorConstants.INVITATION_CODE_IS_INCORRECT); } diff --git a/luoo_user/src/main/java/com/luoo/user/service/UserPointLogService.java b/luoo_user/src/main/java/com/luoo/user/service/UserPointLogService.java index b5016b4..ff50c19 100644 --- a/luoo_user/src/main/java/com/luoo/user/service/UserPointLogService.java +++ b/luoo_user/src/main/java/com/luoo/user/service/UserPointLogService.java @@ -50,398 +50,454 @@ import java.util.Objects; @Slf4j public class UserPointLogService { - public static final String LOTTERY_POINTS_TYPE = "积分抽奖"; - - private final UserPointLogDao userPointLogDao; - - private final IdWorker idWorker; - - private final JwtUtil jwtUtil; - - private final TaskPointDao taskPointDao; - - private final RabbitTemplate rabbitTemplate; - - private final UserInfoDao userInfoDao; - - private final JPAQueryFactory jpaQueryFactory; - - private final LotteryUserDao lotteryUserDao; - - public UserPointLogService(UserPointLogDao userPointLogDao, IdWorker idWorker, JwtUtil jwtUtil, - TaskPointDao taskPointDao, RabbitTemplate rabbitTemplate, UserInfoDao userInfoDao, JPAQueryFactory jpaQueryFactory, LotteryUserDao lotteryUserDao) { - this.userPointLogDao = userPointLogDao; - this.idWorker = idWorker; - this.jwtUtil = jwtUtil; - this.taskPointDao = taskPointDao; - this.rabbitTemplate = rabbitTemplate; - this.userInfoDao = userInfoDao; - this.jpaQueryFactory = jpaQueryFactory; - this.lotteryUserDao = lotteryUserDao; - } - - private TaskPointService taskPointService; - - @Autowired - private void setTaskPointService(TaskPointService taskPointService) { - this.taskPointService = taskPointService; - } - - /** - * 新手任务,只触发一次 - * - * @param taskPointId 任务点ID - * @param token 用户的token,用于验证用户身份并获取用户ID。 - */ - public Integer addByTaskNew(String taskPointId, String token) { - // todo 缓存优化 - UserLoginDto userLoginDto = jwtUtil.getUserLoginDto(token); - - // 新手任务,只触发一次 - if (!userPointLogDao.findUserPointLogByUserIdAndTaskPointId(userLoginDto.getUserId(), - taskPointId).isEmpty()) { - return 0; - } - - addByTask(taskPointId, userLoginDto); - TaskPoint taskPoint = taskPointDao.findById(taskPointId).get(); - return taskPoint.getScore(); - } - - /** - * 通过任务添加积分明细。 - *

- * 此方法用于处理用户完成特定任务后增加积分的逻辑。它首先根据任务点ID获取任务点信息, 然后根据用户token获取用户信息,最后创建一个积分日志对象并将其发送到RabbitMQ, - * 以异步方式记录用户的积分变动。 - * - * @param taskPointId 任务点ID,用于查找任务点信息。 - * @param token 用户的token,用于验证用户身份并获取用户ID。 - */ - public void addByTaskDaily(String taskPointId, String token) { - - UserLoginDto userLoginDto = jwtUtil.getUserLoginDto(token); - - if(null !=userLoginDto) { - addByTask(taskPointId, userLoginDto); - } - - } - - /** - * 通过任务添加积分明细,直接使用userId - */ - public void addByTaskDailyAndUserId(String taskPointId, String userId) { - UserPointLog userPointLog = UserPointLog.builder() - .id(String.valueOf(idWorker.nextId())) - .type(PointEnums.TASK_POINT_TYPE_ADD.getCode()) - .createUser(userId) - .taskPointId(taskPointId) - .userId(userId) - .build(); - - ObjectMapper objectMapper = new ObjectMapper(); - - try { - String json = objectMapper.writeValueAsString(userPointLog); - System.out.println(json); - - rabbitTemplate.convertAndSend("pointLog", json); - } catch (IOException e) { - e.printStackTrace(); - } - } - - private void addByTask(String taskPointId, UserLoginDto userLoginDto) { - - UserPointLog userPointLog = UserPointLog.builder() - .id(String.valueOf(idWorker.nextId())) - .type(PointEnums.TASK_POINT_TYPE_ADD.getCode()) - .createUser(userLoginDto.getUserId()) - .taskPointId(taskPointId) - .userId(userLoginDto.getUserId()) - .build(); - - ObjectMapper objectMapper = new ObjectMapper(); - - try { - String json = objectMapper.writeValueAsString(userPointLog); - System.out.println(json); - - rabbitTemplate.convertAndSend("pointLog", json); - } catch (IOException e) { - e.printStackTrace(); - } - } - - /** - * 添加用户积分记录。 - *

- * 通过@Transactional注解确保该方法操作的数据库事务一致性,任何异常都将导致事务回滚。 - * - * @param userPointLog 用户积分记录对象,包含积分任务ID、用户ID和积分得分。 - */ - @Transactional(rollbackFor = Exception.class) - public void add(UserPointLog userPointLog) { - // 根据积分任务ID获取积分任务详情 - // 保存积分记录 - String taskPointId = userPointLog.getTaskPointId(); - - if (taskPointId != null) { - TaskPoint taskPoint = taskPointService.getTaskPoint(taskPointId); - - // 如果不存在于数据库,就是后台控制的积分,如取消抽奖的返还的积分 - // 积分 - Integer score = taskPoint == null ? userPointLog.getScore() : taskPoint.getScore(); - // 获取积分任务类型 - Integer type = taskPoint == null ? userPointLog.getType() : taskPoint.getType(); - // 描述 - String description = taskPoint == null ? userPointLog.getDescription() : taskPoint.getDescription(); - - - // 对于新手任务,只允许完成一次,如果用户已经完成过,则直接返回,不重复添加积分 - if (Objects.equals(type, PointEnums.TASK_TYPE_NEW.getCode())) { - // 新手任务,只触发一次 - if (!userPointLogDao.findUserPointLogByUserIdAndTaskPointId(userPointLog.getUserId(), - userPointLog.getTaskPointId()).isEmpty()) { - return; - } - } - - // 对于日常任务,每天只允许完成一次,如果用户已经完成过,则直接返回,不重复添加积分 - if (Objects.equals(type, PointEnums.TASK_TYPE_DAILY.getCode())) { - if (!Objects.equals(taskPointId, TaskPointIdConstants.NEW_USER_INVITE)) { - // 日常任务,每天只触发一次(新用户邀请除外) - if (userPointLogDao.findTodayByUserIdAndTaskPointId(userPointLog.getUserId(), userPointLog.getTaskPointId()) != null) { - return; - } - } - } - - userPointLog.setScore(score); - userPointLog.setDescription(description); - - // 保存用户积分记录 - userPointLogDao.save(userPointLog); - log.info("用户 {} 添加积分记录 {} 成功", userPointLog.getUserId(), userPointLog.getId()); - } - - // 更新用户积分,获取用户信息并累加积分得分 - // 对用户进行积分计算 - UserInfo userInfo = userInfoDao.findById(userPointLog.getUserId()).get(); - Integer point = 0; - if (ObjectUtil.equals(PointEnums.TASK_POINT_TYPE_ADD.getCode(), userPointLog.getType())) { - point += userInfo.getPoint() == null ? 0 : userInfo.getPoint(); - } else { - point -= userInfo.getPoint() == null ? 0 : userInfo.getPoint(); - } - point += userPointLog.getScore(); - userInfo.setPoint(point); - // 更新用户积分信息 - userInfoDao.save(userInfo); - } - - @Transactional(rollbackFor = Exception.class) - public void executeDraw(DrawDTO drawDTO) { - - // 调整用户积分 - UserInfo userInfo = userInfoDao.findById(drawDTO.getUserId()).get(); - int point = userInfo.getPoint() == null ? 0 : userInfo.getPoint(); - if (point < drawDTO.getScore()) { - throw new BizException(ErrorConstants.POINT_NOT_ENOUGH); - } - userInfo.setPoint(point - drawDTO.getScore()); - userInfoDao.save(userInfo); - - UserPointLog userPointLog = UserPointLog.builder() - .id(String.valueOf(idWorker.nextId())) - .type(PointEnums.TASK_POINT_TYPE_REDUCE.getCode()) - .createUser(drawDTO.getUserId()) - .description(LOTTERY_POINTS_TYPE) - .userId(drawDTO.getUserId()) - .score(drawDTO.getScore()) - .taskPointId(drawDTO.getTaskPointId()) - .build(); - userPointLogDao.save(userPointLog); - - // 确保先扣除积分,再报名成功 - // 抽奖报名成功 - LotteryUser lotteryUser = LotteryUser.builder() - .id(String.valueOf(idWorker.nextId())) - .lotteryId(drawDTO.getLotteryId()) - .regionId(drawDTO.getRegionId()) - .userId(drawDTO.getUserId()) - .createUser(drawDTO.getUserId()) - .updateUser(drawDTO.getUserId()) - .popup(PointEnums.NOT_POPUP.getCode()) - .showTime(drawDTO.getShowTime()) - .build(); - - lotteryUserDao.save(lotteryUser); - } - - /** - * 每日签到 - * - * @param token 用户token - */ - public void dailySign(String token) { - UserLoginDto userLoginDto = jwtUtil.getUser(); - UserPointLog todayByUserIdAndTaskPointId = userPointLogDao.findTodayByUserIdAndTaskPointId(userLoginDto.getUserId(), TaskPointIdConstants.DAILY_SIGN); - - if (todayByUserIdAndTaskPointId == null) { - // 今天还没签到 - addByTaskDaily(TaskPointIdConstants.DAILY_SIGN, token); - - // 连续3天 - List daysByUserIdAndTaskPointId3 = userPointLogDao.findDaysByUserIdAndTaskPointId(userLoginDto.getUserId(), TaskPointIdConstants.DAILY_SIGN, 3 - 1); - if (daysByUserIdAndTaskPointId3.size() == 3) { - addByTaskDaily(TaskPointIdConstants.DAILY_SIGN_3, token); - } - - // 连续7天 - List daysByUserIdAndTaskPointId7 = userPointLogDao.findDaysByUserIdAndTaskPointId(userLoginDto.getUserId(), TaskPointIdConstants.DAILY_SIGN, 7 - 1); - if (daysByUserIdAndTaskPointId7.size() == 7) { - addByTaskDaily(TaskPointIdConstants.DAILY_SIGN_7, token); - } - - // 连续30天 - List daysByUserIdAndTaskPointId30 = userPointLogDao.findDaysByUserIdAndTaskPointId(userLoginDto.getUserId(), TaskPointIdConstants.DAILY_SIGN, 30 - 1); - if (daysByUserIdAndTaskPointId30.size() == 30) { - addByTaskDaily(TaskPointIdConstants.DAILY_SIGN_30, token); - } - } else { - throw new BizException(ErrorConstants.DAILY_SIGN_ALREADY); - } - } - - /** - * 分享期刊 - * - * @param token 用户token - */ - public void shareJournal(String token) { - if (token != null) { - addByTaskDaily(TaskPointIdConstants.SHARE_JOURNAL, token); - } - } - - public UserInvitationLogVO getUserInvitationLog(String token) { - UserLoginDto userLoginDto = jwtUtil.getUser(); - - String userId = userLoginDto.getUserId(); - - List taskPointIds = new ArrayList<>(); - taskPointIds.add(TaskPointIdConstants.NEW_USER_INVITE); - taskPointIds.add(TaskPointIdConstants.INVITE_USER_3); - taskPointIds.add(TaskPointIdConstants.INVITE_USER_6); - taskPointIds.add(TaskPointIdConstants.INVITE_USER_10); - taskPointIds.add(TaskPointIdConstants.INVITE_USER_20); - - List userPointLogByTaskPointIdInAndUserId = userPointLogDao.findUserPointLogByTaskPointIdInAndUserId(taskPointIds, userId); - UserInvitationLogVO userInvitationLogVO = new UserInvitationLogVO(); - userInvitationLogVO.setNum(userPointLogByTaskPointIdInAndUserId.isEmpty() ? 0 : userPointLogByTaskPointIdInAndUserId.size()); - userInvitationLogVO.setPoint(userPointLogByTaskPointIdInAndUserId.isEmpty() ? 0 : - userPointLogByTaskPointIdInAndUserId.stream().map(UserPointLog::getScore).reduce(0, Integer::sum) - ); - return userInvitationLogVO; - } - - /** - * 分页查询用户积分列表 - * - * @param token 用户token - * @param page 页码 - * @param size 每页数量 - * @return 用户积分列表 - */ - public PageResult getUserPointLogList(String token, - UserPointLogSearchDto userPointLogSearchDto, Integer page, - Integer size) { - - if (token != null) { - UserLoginDto userLoginDto = jwtUtil.getUserLoginDto(token); - userPointLogSearchDto.setUserId(userLoginDto.getUserId()); - } - BooleanBuilder booleanBuilder = new BooleanBuilder(); - QUserPointLog qUserPointLog = QUserPointLog.userPointLog; - checkCondition(booleanBuilder, qUserPointLog, userPointLogSearchDto); - StringExpression formattedCreateTime = Expressions.stringTemplate( - "DATE_FORMAT({0}, {1})", - qUserPointLog.createTime, - Expressions.constant("%Y年%m月") - ); - - // 创建分页对象 - Pageable pageable = PageRequest.of(page - 1, size); - - List userPointLogPage = jpaQueryFactory.select( - Projections.constructor(UserPointLogVO.class, - qUserPointLog.id, - qUserPointLog.score, - qUserPointLog.type, - qUserPointLog.userId, - qUserPointLog.taskPointId, - qUserPointLog.description, - qUserPointLog.createTime, - formattedCreateTime.as("createMonth") - )) - .from(qUserPointLog) - .where(booleanBuilder) - .orderBy(qUserPointLog.createTime.desc()) - .offset(pageable.getOffset()) - .limit(pageable.getPageSize()) - .fetch(); - long totalElements = jpaQueryFactory.select(qUserPointLog.id.count()).from(qUserPointLog) - .where(booleanBuilder) - .fetchCount(); - - return new PageResult<>(totalElements, userPointLogPage); - } - - public void checkCondition(BooleanBuilder booleanBuilder, QUserPointLog qUserPointLog, UserPointLogSearchDto userPointLogSearchDto) { - if (StringUtils.isNotBlank(userPointLogSearchDto.getUserId())) { - booleanBuilder.and(qUserPointLog.createUser.eq(userPointLogSearchDto.getUserId())); - } - if (userPointLogSearchDto.getType() != null) { - booleanBuilder.and(qUserPointLog.type.eq(userPointLogSearchDto.getType())); - } - if (StringUtils.isNotBlank(userPointLogSearchDto.getCreateMonth())) { - // 判断userPointLogSearchDto.getCreateMonth() 是否是当月时间 - LocalDate now = LocalDate.now(); - DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMM"); - String currentMonth = now.format(formatter); - - // 判断是否是当前月份 - boolean isCurrentMonth = userPointLogSearchDto.getCreateMonth().equals(currentMonth); - - if (!isCurrentMonth) { - // 不是当前月份,仅展示传入月份的记录 - - StringExpression formattedCreateTime = Expressions.stringTemplate( - "DATE_FORMAT({0}, {1})", - qUserPointLog.createTime, - Expressions.constant("%Y年%m月") - ); - - booleanBuilder.and(formattedCreateTime.eq(userPointLogSearchDto.getCreateMonth())); - } - } - } - - /** - * 查询是否已领取过积分-此方法仅供新手任务使用 - * - * @param userId 用户id - * @param taskPointId 任务id - * @return 空 || 已领取积分的记录 - */ - public UserPointLog getUserPointLog(String userId, String taskPointId) { - List userPointLogByUserIdAndTaskPointId = userPointLogDao.findUserPointLogByUserIdAndTaskPointId(userId, taskPointId); - if (userPointLogByUserIdAndTaskPointId.isEmpty()) { - return null; - } else { - return userPointLogByUserIdAndTaskPointId.get(0); - } - } + public static final String LOTTERY_POINTS_TYPE = "积分抽奖"; + + private final UserPointLogDao userPointLogDao; + + private final IdWorker idWorker; + + private final JwtUtil jwtUtil; + + private final TaskPointDao taskPointDao; + + private final RabbitTemplate rabbitTemplate; + + private final UserInfoDao userInfoDao; + + private final JPAQueryFactory jpaQueryFactory; + + private final LotteryUserDao lotteryUserDao; + + private final UserPointLogService userPointLogService; + + public UserPointLogService(UserPointLogDao userPointLogDao, IdWorker idWorker, JwtUtil jwtUtil, + TaskPointDao taskPointDao, RabbitTemplate rabbitTemplate, UserInfoDao userInfoDao, + JPAQueryFactory jpaQueryFactory, LotteryUserDao lotteryUserDao, + UserPointLogService userPointLogService) { + this.userPointLogDao = userPointLogDao; + this.idWorker = idWorker; + this.jwtUtil = jwtUtil; + this.taskPointDao = taskPointDao; + this.rabbitTemplate = rabbitTemplate; + this.userInfoDao = userInfoDao; + this.jpaQueryFactory = jpaQueryFactory; + this.lotteryUserDao = lotteryUserDao; + this.userPointLogService = userPointLogService; + } + + private TaskPointService taskPointService; + + @Autowired + private void setTaskPointService(TaskPointService taskPointService) { + this.taskPointService = taskPointService; + } + + /** + * 新手任务,只触发一次 + * + * @param taskPointId 任务点ID + * @param token 用户的token,用于验证用户身份并获取用户ID。 + */ + public Integer addByTaskNew(String taskPointId, String token) { + // todo 缓存优化 + UserLoginDto userLoginDto = jwtUtil.getUserLoginDto(token); + + // 新手任务,只触发一次 + if (!userPointLogDao.findUserPointLogByUserIdAndTaskPointId(userLoginDto.getUserId(), + taskPointId).isEmpty()) { + return 0; + } + + addByTask(taskPointId, userLoginDto); + TaskPoint taskPoint = taskPointDao.findById(taskPointId).get(); + return taskPoint.getScore(); + } + + /** + * 通过任务添加积分明细。 + *

+ * 此方法用于处理用户完成特定任务后增加积分的逻辑。它首先根据任务点ID获取任务点信息, 然后根据用户token获取用户信息,最后创建一个积分日志对象并将其发送到RabbitMQ, + * 以异步方式记录用户的积分变动。 + * + * @param taskPointId 任务点ID,用于查找任务点信息。 + * @param token 用户的token,用于验证用户身份并获取用户ID。 + */ + public void addByTaskDaily(String taskPointId, String token) { + + UserLoginDto userLoginDto = jwtUtil.getUserLoginDto(token); + + if (null != userLoginDto) { + addByTask(taskPointId, userLoginDto); + } + + } + + /** + * 通过任务添加积分明细,直接使用userId + */ + public void addByTaskDailyAndUserId(String taskPointId, String userId) { + UserPointLog userPointLog = UserPointLog.builder() + .id(String.valueOf(idWorker.nextId())) + .type(PointEnums.TASK_POINT_TYPE_ADD.getCode()) + .createUser(userId) + .taskPointId(taskPointId) + .userId(userId) + .build(); + + ObjectMapper objectMapper = new ObjectMapper(); + + try { + String json = objectMapper.writeValueAsString(userPointLog); + System.out.println(json); + + rabbitTemplate.convertAndSend("pointLog", json); + } catch (IOException e) { + e.printStackTrace(); + } + } + + private void addByTask(String taskPointId, UserLoginDto userLoginDto) { + + UserPointLog userPointLog = UserPointLog.builder() + .id(String.valueOf(idWorker.nextId())) + .type(PointEnums.TASK_POINT_TYPE_ADD.getCode()) + .createUser(userLoginDto.getUserId()) + .taskPointId(taskPointId) + .userId(userLoginDto.getUserId()) + .build(); + + ObjectMapper objectMapper = new ObjectMapper(); + + try { + String json = objectMapper.writeValueAsString(userPointLog); + System.out.println(json); + + rabbitTemplate.convertAndSend("pointLog", json); + } catch (IOException e) { + e.printStackTrace(); + } + } + + /** + * 添加用户积分记录。 + *

+ * 通过@Transactional注解确保该方法操作的数据库事务一致性,任何异常都将导致事务回滚。 + * + * @param userPointLog 用户积分记录对象,包含积分任务ID、用户ID和积分得分。 + */ + @Transactional(rollbackFor = Exception.class) + public void add(UserPointLog userPointLog) { + // 根据积分任务ID获取积分任务详情 + // 保存积分记录 + String taskPointId = userPointLog.getTaskPointId(); + + if (taskPointId != null) { + TaskPoint taskPoint = taskPointService.getTaskPoint(taskPointId); + + // 如果不存在于数据库,就是后台控制的积分,如取消抽奖的返还的积分 + // 积分 + Integer score = taskPoint == null ? userPointLog.getScore() : taskPoint.getScore(); + // 获取积分任务类型 + Integer type = taskPoint == null ? userPointLog.getType() : taskPoint.getType(); + // 描述 + String description = + taskPoint == null ? userPointLog.getDescription() : taskPoint.getDescription(); + + // 对于新手任务,只允许完成一次,如果用户已经完成过,则直接返回,不重复添加积分 + if (Objects.equals(type, PointEnums.TASK_TYPE_NEW.getCode())) { + // 新手任务,只触发一次 + if (!userPointLogDao.findUserPointLogByUserIdAndTaskPointId( + userPointLog.getUserId(), + userPointLog.getTaskPointId()).isEmpty()) { + return; + } + } + + // 对于日常任务,每天只允许完成一次,如果用户已经完成过,则直接返回,不重复添加积分 + if (Objects.equals(type, PointEnums.TASK_TYPE_DAILY.getCode())) { + if (!Objects.equals(taskPointId, TaskPointIdConstants.NEW_USER_INVITE)) { + // 日常任务,每天只触发一次(新用户邀请除外) + if (userPointLogDao.findTodayByUserIdAndTaskPointId(userPointLog.getUserId(), + userPointLog.getTaskPointId()) != null) { + return; + } + } else { + List list = userPointLogDao.findUserPointLogsByUserIdAndTaskPointId( + userPointLog.getUserId(), TaskPointIdConstants.NEW_USER_INVITE); + if (list.size() >= 3) { + // 邀请人数 >= 3人,并且没有获得对应的积分 + List userPointLogsByUserIdAndTaskPointId3 = userPointLogDao.findUserPointLogsByUserIdAndTaskPointId( + TaskPointIdConstants.INVITE_USER_3, userPointLog.getUserId()); + if (userPointLogsByUserIdAndTaskPointId3.isEmpty()) { + userPointLogService.addByTaskDailyAndUserId( + TaskPointIdConstants.INVITE_USER_3, userPointLog.getUserId()); + } + } + if (list.size() >= 6) { + // 邀请人数 >= 6人,并且没有获得对应的积分 + List userPointLogsByUserIdAndTaskPointId6 = userPointLogDao.findUserPointLogsByUserIdAndTaskPointId( + TaskPointIdConstants.INVITE_USER_6, userPointLog.getUserId()); + if (userPointLogsByUserIdAndTaskPointId6.isEmpty()) { + userPointLogService.addByTaskDailyAndUserId( + TaskPointIdConstants.INVITE_USER_6, userPointLog.getUserId()); + } + } + if (list.size() >= 10) { + // 邀请人数 >= 10人,并且没有获得对应的积分 + List userPointLogsByUserIdAndTaskPointId10 = userPointLogDao.findUserPointLogsByUserIdAndTaskPointId( + TaskPointIdConstants.INVITE_USER_10, userPointLog.getUserId()); + if (userPointLogsByUserIdAndTaskPointId10.isEmpty()) { + userPointLogService.addByTaskDailyAndUserId( + TaskPointIdConstants.INVITE_USER_10, userPointLog.getUserId()); + } + } + if (list.size() >= 20) { + // 邀请人数 >= 20人,并且没有获得对应的积分 + List userPointLogsByUserIdAndTaskPointId20 = userPointLogDao.findUserPointLogsByUserIdAndTaskPointId( + TaskPointIdConstants.INVITE_USER_20, userPointLog.getUserId()); + if (userPointLogsByUserIdAndTaskPointId20.isEmpty()) { + userPointLogService.addByTaskDailyAndUserId( + TaskPointIdConstants.INVITE_USER_20, userPointLog.getUserId()); + } + } + } + } + + userPointLog.setScore(score); + userPointLog.setDescription(description); + + // 保存用户积分记录 + userPointLogDao.save(userPointLog); + log.info("用户 {} 添加积分记录 {} 成功", userPointLog.getUserId(), + userPointLog.getId()); + } + + // 更新用户积分,获取用户信息并累加积分得分 + // 对用户进行积分计算 + UserInfo userInfo = userInfoDao.findById(userPointLog.getUserId()).get(); + Integer point = 0; + if (ObjectUtil.equals(PointEnums.TASK_POINT_TYPE_ADD.getCode(), userPointLog.getType())) { + point += userInfo.getPoint() == null ? 0 : userInfo.getPoint(); + } else { + point -= userInfo.getPoint() == null ? 0 : userInfo.getPoint(); + } + point += userPointLog.getScore(); + userInfo.setPoint(point); + // 更新用户积分信息 + userInfoDao.save(userInfo); + } + + @Transactional(rollbackFor = Exception.class) + public void executeDraw(DrawDTO drawDTO) { + + // 调整用户积分 + UserInfo userInfo = userInfoDao.findById(drawDTO.getUserId()).get(); + int point = userInfo.getPoint() == null ? 0 : userInfo.getPoint(); + if (point < drawDTO.getScore()) { + throw new BizException(ErrorConstants.POINT_NOT_ENOUGH); + } + userInfo.setPoint(point - drawDTO.getScore()); + userInfoDao.save(userInfo); + + UserPointLog userPointLog = UserPointLog.builder() + .id(String.valueOf(idWorker.nextId())) + .type(PointEnums.TASK_POINT_TYPE_REDUCE.getCode()) + .createUser(drawDTO.getUserId()) + .description(LOTTERY_POINTS_TYPE) + .userId(drawDTO.getUserId()) + .score(drawDTO.getScore()) + .taskPointId(drawDTO.getTaskPointId()) + .build(); + userPointLogDao.save(userPointLog); + + // 确保先扣除积分,再报名成功 + // 抽奖报名成功 + LotteryUser lotteryUser = LotteryUser.builder() + .id(String.valueOf(idWorker.nextId())) + .lotteryId(drawDTO.getLotteryId()) + .regionId(drawDTO.getRegionId()) + .userId(drawDTO.getUserId()) + .createUser(drawDTO.getUserId()) + .updateUser(drawDTO.getUserId()) + .popup(PointEnums.NOT_POPUP.getCode()) + .showTime(drawDTO.getShowTime()) + .build(); + + lotteryUserDao.save(lotteryUser); + } + + /** + * 每日签到 + * + * @param token 用户token + */ + public void dailySign(String token) { + UserLoginDto userLoginDto = jwtUtil.getUser(); + UserPointLog todayByUserIdAndTaskPointId = userPointLogDao.findTodayByUserIdAndTaskPointId( + userLoginDto.getUserId(), TaskPointIdConstants.DAILY_SIGN); + + if (todayByUserIdAndTaskPointId == null) { + // 今天还没签到 + addByTaskDaily(TaskPointIdConstants.DAILY_SIGN, token); + + // 连续3天 + List daysByUserIdAndTaskPointId3 = userPointLogDao.findDaysByUserIdAndTaskPointId( + userLoginDto.getUserId(), TaskPointIdConstants.DAILY_SIGN, 3 - 1); + if (daysByUserIdAndTaskPointId3.size() == 3) { + addByTaskDaily(TaskPointIdConstants.DAILY_SIGN_3, token); + } + + // 连续7天 + List daysByUserIdAndTaskPointId7 = userPointLogDao.findDaysByUserIdAndTaskPointId( + userLoginDto.getUserId(), TaskPointIdConstants.DAILY_SIGN, 7 - 1); + if (daysByUserIdAndTaskPointId7.size() == 7) { + addByTaskDaily(TaskPointIdConstants.DAILY_SIGN_7, token); + } + + // 连续30天 + List daysByUserIdAndTaskPointId30 = userPointLogDao.findDaysByUserIdAndTaskPointId( + userLoginDto.getUserId(), TaskPointIdConstants.DAILY_SIGN, 30 - 1); + if (daysByUserIdAndTaskPointId30.size() == 30) { + addByTaskDaily(TaskPointIdConstants.DAILY_SIGN_30, token); + } + } else { + throw new BizException(ErrorConstants.DAILY_SIGN_ALREADY); + } + } + + /** + * 分享期刊 + * + * @param token 用户token + */ + public void shareJournal(String token) { + if (token != null) { + addByTaskDaily(TaskPointIdConstants.SHARE_JOURNAL, token); + } + } + + public UserInvitationLogVO getUserInvitationLog(String token) { + UserLoginDto userLoginDto = jwtUtil.getUser(); + + String userId = userLoginDto.getUserId(); + + List taskPointIds = new ArrayList<>(); + taskPointIds.add(TaskPointIdConstants.NEW_USER_INVITE); + taskPointIds.add(TaskPointIdConstants.INVITE_USER_3); + taskPointIds.add(TaskPointIdConstants.INVITE_USER_6); + taskPointIds.add(TaskPointIdConstants.INVITE_USER_10); + taskPointIds.add(TaskPointIdConstants.INVITE_USER_20); + + List userPointLogByTaskPointIdInAndUserId = userPointLogDao.findUserPointLogByTaskPointIdInAndUserId( + taskPointIds, userId); + UserInvitationLogVO userInvitationLogVO = new UserInvitationLogVO(); + userInvitationLogVO.setNum(userPointLogByTaskPointIdInAndUserId.isEmpty() ? 0 + : userPointLogByTaskPointIdInAndUserId.size()); + userInvitationLogVO.setPoint(userPointLogByTaskPointIdInAndUserId.isEmpty() ? 0 : + userPointLogByTaskPointIdInAndUserId.stream().map(UserPointLog::getScore) + .reduce(0, Integer::sum) + ); + return userInvitationLogVO; + } + + /** + * 分页查询用户积分列表 + * + * @param token 用户token + * @param page 页码 + * @param size 每页数量 + * @return 用户积分列表 + */ + public PageResult getUserPointLogList(String token, + UserPointLogSearchDto userPointLogSearchDto, Integer page, + Integer size) { + + if (token != null) { + UserLoginDto userLoginDto = jwtUtil.getUserLoginDto(token); + userPointLogSearchDto.setUserId(userLoginDto.getUserId()); + } + BooleanBuilder booleanBuilder = new BooleanBuilder(); + QUserPointLog qUserPointLog = QUserPointLog.userPointLog; + checkCondition(booleanBuilder, qUserPointLog, userPointLogSearchDto); + StringExpression formattedCreateTime = Expressions.stringTemplate( + "DATE_FORMAT({0}, {1})", + qUserPointLog.createTime, + Expressions.constant("%Y年%m月") + ); + + // 创建分页对象 + Pageable pageable = PageRequest.of(page - 1, size); + + List userPointLogPage = jpaQueryFactory.select( + Projections.constructor(UserPointLogVO.class, + qUserPointLog.id, + qUserPointLog.score, + qUserPointLog.type, + qUserPointLog.userId, + qUserPointLog.taskPointId, + qUserPointLog.description, + qUserPointLog.createTime, + formattedCreateTime.as("createMonth") + )) + .from(qUserPointLog) + .where(booleanBuilder) + .orderBy(qUserPointLog.createTime.desc()) + .offset(pageable.getOffset()) + .limit(pageable.getPageSize()) + .fetch(); + long totalElements = jpaQueryFactory.select(qUserPointLog.id.count()).from(qUserPointLog) + .where(booleanBuilder) + .fetchCount(); + + return new PageResult<>(totalElements, userPointLogPage); + } + + public void checkCondition(BooleanBuilder booleanBuilder, QUserPointLog qUserPointLog, + UserPointLogSearchDto userPointLogSearchDto) { + if (StringUtils.isNotBlank(userPointLogSearchDto.getUserId())) { + booleanBuilder.and(qUserPointLog.createUser.eq(userPointLogSearchDto.getUserId())); + } + if (userPointLogSearchDto.getType() != null) { + booleanBuilder.and(qUserPointLog.type.eq(userPointLogSearchDto.getType())); + } + if (StringUtils.isNotBlank(userPointLogSearchDto.getCreateMonth())) { + // 判断userPointLogSearchDto.getCreateMonth() 是否是当月时间 + LocalDate now = LocalDate.now(); + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMM"); + String currentMonth = now.format(formatter); + + // 判断是否是当前月份 + boolean isCurrentMonth = userPointLogSearchDto.getCreateMonth().equals(currentMonth); + + if (!isCurrentMonth) { + // 不是当前月份,仅展示传入月份的记录 + + StringExpression formattedCreateTime = Expressions.stringTemplate( + "DATE_FORMAT({0}, {1})", + qUserPointLog.createTime, + Expressions.constant("%Y年%m月") + ); + + booleanBuilder.and(formattedCreateTime.eq(userPointLogSearchDto.getCreateMonth())); + } + } + } + + /** + * 查询是否已领取过积分-此方法仅供新手任务使用 + * + * @param userId 用户id + * @param taskPointId 任务id + * @return 空 || 已领取积分的记录 + */ + public UserPointLog getUserPointLog(String userId, String taskPointId) { + List userPointLogByUserIdAndTaskPointId = userPointLogDao.findUserPointLogByUserIdAndTaskPointId( + userId, taskPointId); + if (userPointLogByUserIdAndTaskPointId.isEmpty()) { + return null; + } else { + return userPointLogByUserIdAndTaskPointId.get(0); + } + } }