|
|
@@ -4,7 +4,8 @@ import cn.hutool.core.bean.BeanUtil;
|
|
|
import cn.hutool.core.collection.CollectionUtil;
|
|
|
import cn.hutool.core.date.DateUtil;
|
|
|
import cn.hutool.core.util.ObjectUtil;
|
|
|
-import cn.hutool.core.util.StrUtil;
|
|
|
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
|
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
|
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
|
|
import com.ylx.common.core.domain.model.WxLoginUser;
|
|
|
import com.ylx.common.exception.base.BaseException;
|
|
|
@@ -20,7 +21,6 @@ import com.ylx.point.enums.PointActivityTypeEnum;
|
|
|
import com.ylx.point.mapper.PointActivityMapper;
|
|
|
import com.ylx.point.service.*;
|
|
|
import lombok.extern.slf4j.Slf4j;
|
|
|
-import org.springframework.beans.factory.annotation.Autowired;
|
|
|
import org.springframework.stereotype.Service;
|
|
|
import org.springframework.transaction.annotation.Transactional;
|
|
|
|
|
|
@@ -29,6 +29,7 @@ import java.time.DateTimeException;
|
|
|
import java.time.LocalDate;
|
|
|
import java.time.LocalDateTime;
|
|
|
import java.time.ZoneId;
|
|
|
+import java.time.format.DateTimeFormatter;
|
|
|
import java.util.*;
|
|
|
import java.util.stream.Collectors;
|
|
|
|
|
|
@@ -44,18 +45,22 @@ import java.util.stream.Collectors;
|
|
|
public class PointActivityServiceImpl extends ServiceImpl<PointActivityMapper, PointActivity> implements IPointActivityService {
|
|
|
@Resource
|
|
|
private PointActivityMapper pointActivityMapper;
|
|
|
- @Autowired
|
|
|
+ @Resource
|
|
|
private IPointActivityTaskService pointActivityTaskService;
|
|
|
- @Autowired
|
|
|
+ @Resource
|
|
|
private IPointSignTaskService pointSignTaskService;
|
|
|
- @Autowired
|
|
|
+ @Resource
|
|
|
private IPointSignRewardService pointSignRewardService;
|
|
|
- @Autowired
|
|
|
+ @Resource
|
|
|
private IPointUserActivityTaskCompletionService pointUserActivityTaskCompletionService;
|
|
|
- @Autowired
|
|
|
+ @Resource
|
|
|
private IPointActivityExpirePolicyService pointActivityExpirePolicyService;
|
|
|
@Resource
|
|
|
private TWxUserService wxUserService;
|
|
|
+ @Resource
|
|
|
+ private IPointUserSignLogService pointUserSignLogService;
|
|
|
+ @Resource
|
|
|
+ private IPointUserSignStatusService pointUserSignStatusService;
|
|
|
|
|
|
private static final int BATCH_SIZE = 1000;
|
|
|
|
|
|
@@ -239,6 +244,7 @@ public class PointActivityServiceImpl extends ServiceImpl<PointActivityMapper, P
|
|
|
|
|
|
String userId = user.getId();
|
|
|
dto.setUserId(userId);
|
|
|
+ // TODO 根据cityName换cityCode
|
|
|
return pointActivityMapper.selectTaskWithProgress(dto);
|
|
|
}
|
|
|
|
|
|
@@ -291,6 +297,134 @@ public class PointActivityServiceImpl extends ServiceImpl<PointActivityMapper, P
|
|
|
|
|
|
}
|
|
|
|
|
|
+ @Override
|
|
|
+ public List<SignDayVo> getSignInfo(String cityName) {
|
|
|
+
|
|
|
+ WxLoginUser wxLoginUser = SecurityUtils.getWxLoginUser();
|
|
|
+ TWxUser user = wxUserService.getByOpenId(wxLoginUser.getCOpenid());
|
|
|
+ if (user == null) {
|
|
|
+ throw new RuntimeException("用户不存在");
|
|
|
+ }
|
|
|
+
|
|
|
+ String userId = user.getId();
|
|
|
+ // TODO 根据cityName换cityCode
|
|
|
+ String cityCode = "110000";
|
|
|
+ // 动态获取启用任务
|
|
|
+ PointSignTask task = getEnabledTask(cityCode);
|
|
|
+ Long taskId = task.getId();
|
|
|
+
|
|
|
+ List<SignDayVo> voList = new ArrayList<>();
|
|
|
+ LocalDate today = LocalDate.now();
|
|
|
+
|
|
|
+ // 奖励配置
|
|
|
+ LambdaQueryWrapper<PointSignReward> queryWrapper = new LambdaQueryWrapper<>();
|
|
|
+ queryWrapper.eq(PointSignReward::getSignTaskId, taskId);
|
|
|
+ queryWrapper.orderByAsc(PointSignReward::getContinueDays);
|
|
|
+ queryWrapper.last("LIMIT 7");
|
|
|
+ List<PointSignReward> rewardList = this.pointSignRewardService.list(queryWrapper);
|
|
|
+
|
|
|
+ // 今日是否已签
|
|
|
+ boolean signedToday = pointUserSignLogService.countTodaySign(userId, taskId) > 0;
|
|
|
+
|
|
|
+ // 用户签到状态
|
|
|
+ LambdaQueryWrapper<PointUserSignStatus> statusQueryWrapper = new LambdaQueryWrapper<>();
|
|
|
+ statusQueryWrapper.eq(PointUserSignStatus::getUserId, userId);
|
|
|
+ statusQueryWrapper.eq(PointUserSignStatus::getActivityId, taskId);
|
|
|
+ PointUserSignStatus status = pointUserSignStatusService.getOne(statusQueryWrapper);
|
|
|
+ int continuousDays = ObjectUtil.isNull(status) ? 0 : status.getCurrentContinuousDays();
|
|
|
+
|
|
|
+ // 组装7天展示
|
|
|
+ DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MM-dd");
|
|
|
+ for (int i = 0; i < 7; i++) {
|
|
|
+ LocalDate date = today.minusDays(i);
|
|
|
+ SignDayVo vo = new SignDayVo();
|
|
|
+ vo.setDate(date);
|
|
|
+
|
|
|
+ // 奖励匹配
|
|
|
+// PointSignReward reward = rewardList.stream()
|
|
|
+// .filter(r -> r.getContinueDays() == (i + 1))
|
|
|
+// .findFirst()
|
|
|
+// .orElse(null);
|
|
|
+// vo.setPoints(reward == null ? 0 : reward.getRewardPoints());
|
|
|
+
|
|
|
+ // 状态 0未签 1已签 2今日可签
|
|
|
+ if (i == 0) {
|
|
|
+ vo.setStatus(signedToday ? 1 : 2);
|
|
|
+ } else {
|
|
|
+ vo.setStatus((i + 1) <= continuousDays ? 1 : 0);
|
|
|
+ }
|
|
|
+ voList.add(vo);
|
|
|
+ }
|
|
|
+ return voList;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ @Transactional(rollbackFor = Exception.class)
|
|
|
+ public void sign() {
|
|
|
+// // 1. 检查今天是否已签
|
|
|
+// int count = pointUserSignLogService.countTodaySign(userId, DEFAULT_TASK_ID);
|
|
|
+// if (count > 0) {
|
|
|
+// throw new RuntimeException("今天已经签到过了");
|
|
|
+// }
|
|
|
+//
|
|
|
+// // 2. 锁定用户签到状态行 (悲观锁,防止并发重复签到)
|
|
|
+// PointUserSignStatus status = statusMapper.selectByUserAndTaskForUpdate(userId, DEFAULT_TASK_ID);
|
|
|
+//
|
|
|
+// int newContinuousDays = 1; // 默认第一天
|
|
|
+//
|
|
|
+// if (status != null) {
|
|
|
+// // 3. 判断是否断签
|
|
|
+// // 逻辑:如果上次签到时间不是昨天,且断签规则是"重置",则重置天数
|
|
|
+// boolean isBreak = !status.getLastSignTime().toLocalDate().equals(LocalDate.now().minusDays(1));
|
|
|
+//
|
|
|
+// PointSignTask task = taskMapper.selectById(DEFAULT_TASK_ID);
|
|
|
+// if (isBreak && task.getBreakRule() == 0) {
|
|
|
+// newContinuousDays = 1;
|
|
|
+// } else {
|
|
|
+// newContinuousDays = status.getCurrentContinuousDays() + 1;
|
|
|
+// }
|
|
|
+//
|
|
|
+// // 更新状态表
|
|
|
+// status.setCurrentContinuousDays(newContinuousDays);
|
|
|
+// status.setLastSignTime(LocalDateTime.now());
|
|
|
+// statusMapper.updateById(status);
|
|
|
+// } else {
|
|
|
+// // 第一次签到,插入状态
|
|
|
+// PointUserSignStatus newStatus = new PointUserSignStatus();
|
|
|
+// newStatus.setUserId(userId);
|
|
|
+// newStatus.setTaskId(DEFAULT_TASK_ID);
|
|
|
+// newStatus.setCurrentContinuousDays(1);
|
|
|
+// newStatus.setLastSignTime(LocalDateTime.now());
|
|
|
+// statusMapper.insert(newStatus);
|
|
|
+// }
|
|
|
+//
|
|
|
+// // 4. 计算奖励
|
|
|
+// PointSignReward reward = rewardMapper.selectOne(
|
|
|
+// new QueryWrapper<PointSignReward>()
|
|
|
+// .eq("task_id", DEFAULT_TASK_ID)
|
|
|
+// .eq("day", newContinuousDays)
|
|
|
+// );
|
|
|
+//
|
|
|
+// // 如果当前天数没有配置具体奖励,取最近的一个配置或者默认值
|
|
|
+// if (reward == null) {
|
|
|
+// // 这里可以写兜底逻辑,比如取最大天数的奖励
|
|
|
+// reward = rewardMapper.selectOne(new QueryWrapper<PointSignReward>().eq("task_id", DEFAULT_TASK_ID).orderByDesc("day").last("limit 1"));
|
|
|
+// }
|
|
|
+//
|
|
|
+// int points = (reward == null) ? 1 : reward.getPoints();
|
|
|
+//
|
|
|
+// // 5. 写入日志
|
|
|
+// PointUserSignLog log = new PointUserSignLog();
|
|
|
+// log.setUserId(userId);
|
|
|
+// log.setTaskId(DEFAULT_TASK_ID);
|
|
|
+// log.setPoints(points);
|
|
|
+// log.setCreateTime(LocalDateTime.now());
|
|
|
+// logMapper.insert(log);
|
|
|
+//
|
|
|
+// // 6. 增加用户总积分 (调用账户服务)
|
|
|
+// pointAccountService.addPoints(userId, points);
|
|
|
+ }
|
|
|
+
|
|
|
/**
|
|
|
* 判断任务是否未完成
|
|
|
*/
|
|
|
@@ -364,7 +498,7 @@ public class PointActivityServiceImpl extends ServiceImpl<PointActivityMapper, P
|
|
|
PointActivityDTO.ActivityTimeConfig timeConfig = dto.getTimeConfig();
|
|
|
entity.setStartTime(DateUtil.beginOfDay(timeConfig.getStartTime()));
|
|
|
entity.setEndTime(processEndTime(timeConfig.getEndTime()));
|
|
|
- entity.setIsPermanent(timeConfig.getIsPermanent()? 1 : 0);
|
|
|
+ entity.setIsPermanent(timeConfig.getIsPermanent() ? 1 : 0);
|
|
|
|
|
|
// 处理状态
|
|
|
if (PointActivityStatusEnum.PUBLISHED.getCode().equals(dto.getStatus())) {
|
|
|
@@ -482,7 +616,7 @@ public class PointActivityServiceImpl extends ServiceImpl<PointActivityMapper, P
|
|
|
if (timeConfig != null) {
|
|
|
entity.setStartTime(DateUtil.beginOfDay(timeConfig.getStartTime()));
|
|
|
entity.setEndTime(processEndTime(timeConfig.getEndTime()));
|
|
|
- entity.setIsPermanent(timeConfig.getIsPermanent()? 1 : 0);
|
|
|
+ entity.setIsPermanent(timeConfig.getIsPermanent() ? 1 : 0);
|
|
|
}
|
|
|
|
|
|
// 处理状态
|
|
|
@@ -730,5 +864,29 @@ public class PointActivityServiceImpl extends ServiceImpl<PointActivityMapper, P
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ private PointSignTask getEnabledTask(String cityCode) {
|
|
|
+ // 1. 根据城市查询当前生效的活动
|
|
|
+ PointActivity activity = pointActivityMapper.selectOne(
|
|
|
+ new QueryWrapper<PointActivity>()
|
|
|
+ .eq("cityCode", cityCode)
|
|
|
+ .eq("status", 1) // 活动启用
|
|
|
+ .last("LIMIT 1")
|
|
|
+ );
|
|
|
+ if (ObjectUtil.isNull(activity)) {
|
|
|
+ throw new RuntimeException("当前城市未配置签到活动");
|
|
|
+ }
|
|
|
+
|
|
|
+ // 2. 根据活动绑定的 taskId 查询签到任务
|
|
|
+ LambdaQueryWrapper<PointSignTask> queryWrapper = new LambdaQueryWrapper<>();
|
|
|
+ queryWrapper.eq(PointSignTask::getActivityId, activity.getId());
|
|
|
+ queryWrapper.eq(PointSignTask::getIsDeleted, 1);
|
|
|
+ List<PointSignTask> list = pointSignTaskService.list(queryWrapper);
|
|
|
+ PointSignTask task = new PointSignTask();
|
|
|
+ ;
|
|
|
+ if (CollectionUtil.isNotEmpty(list)) {
|
|
|
+ task = CollectionUtil.getLast(list);
|
|
|
+ }
|
|
|
+ return task;
|
|
|
+ }
|
|
|
|
|
|
}
|