|
@@ -1,6 +1,7 @@
|
|
|
package com.ylx.point.service.impl;
|
|
package com.ylx.point.service.impl;
|
|
|
|
|
|
|
|
import cn.hutool.core.bean.BeanUtil;
|
|
import cn.hutool.core.bean.BeanUtil;
|
|
|
|
|
+import cn.hutool.core.collection.CollUtil;
|
|
|
import cn.hutool.core.collection.CollectionUtil;
|
|
import cn.hutool.core.collection.CollectionUtil;
|
|
|
import cn.hutool.core.date.DateUtil;
|
|
import cn.hutool.core.date.DateUtil;
|
|
|
import cn.hutool.core.util.ObjectUtil;
|
|
import cn.hutool.core.util.ObjectUtil;
|
|
@@ -334,88 +335,115 @@ public class PointActivityServiceImpl extends ServiceImpl<PointActivityMapper, P
|
|
|
|
|
|
|
|
@Override
|
|
@Override
|
|
|
public List<SignDayVo> getSignInfo(SignDTO dto) {
|
|
public List<SignDayVo> getSignInfo(SignDTO dto) {
|
|
|
-
|
|
|
|
|
- // 当前登录用户信息
|
|
|
|
|
|
|
+ // 1. 获取当前登录用户
|
|
|
WxLoginUser wxLoginUser = getCurrentWxLoginUser();
|
|
WxLoginUser wxLoginUser = getCurrentWxLoginUser();
|
|
|
String openId = wxLoginUser.getCOpenid();
|
|
String openId = wxLoginUser.getCOpenid();
|
|
|
|
|
|
|
|
|
|
+ // 2. 获取当前城市签到任务
|
|
|
PointSignTask task = getEnabledTask(dto.getCityCode());
|
|
PointSignTask task = getEnabledTask(dto.getCityCode());
|
|
|
- if (task == null) throw new ServiceException("当前城市暂无签到活动");
|
|
|
|
|
|
|
+ if (ObjectUtil.isNull(task)) {
|
|
|
|
|
+ throw new ServiceException("当前城市暂无签到活动");
|
|
|
|
|
+ }
|
|
|
Long taskId = task.getId();
|
|
Long taskId = task.getId();
|
|
|
Long activityId = task.getActivityId();
|
|
Long activityId = task.getActivityId();
|
|
|
|
|
|
|
|
|
|
+ PointActivity entity = this.pointActivityMapper.selectPointActivityById(activityId);
|
|
|
|
|
+ if (ObjectUtil.isNull(entity)) {
|
|
|
|
|
+ throw new IllegalArgumentException("参数有误,活动不存在");
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ Date activityStartTime = entity.getStartTime();
|
|
|
|
|
+ int basePoints = task.getBasePoints() == null ? 0 : task.getBasePoints();
|
|
|
|
|
+
|
|
|
|
|
+ // 3. 查询连续签到奖励配置(按continue_days升序,保证累加顺序)
|
|
|
LambdaQueryWrapper<PointSignReward> rewardQuery = new LambdaQueryWrapper<>();
|
|
LambdaQueryWrapper<PointSignReward> rewardQuery = new LambdaQueryWrapper<>();
|
|
|
- rewardQuery.eq(PointSignReward::getSignTaskId, taskId);
|
|
|
|
|
- rewardQuery.orderByAsc(PointSignReward::getContinueDays);
|
|
|
|
|
- rewardQuery.last("LIMIT 7");
|
|
|
|
|
|
|
+ rewardQuery.eq(PointSignReward::getSignTaskId, taskId)
|
|
|
|
|
+ .eq(PointSignReward::getIsDeleted, 0)
|
|
|
|
|
+ .orderByAsc(PointSignReward::getContinueDays);
|
|
|
List<PointSignReward> rewardList = pointSignRewardService.list(rewardQuery);
|
|
List<PointSignReward> rewardList = pointSignRewardService.list(rewardQuery);
|
|
|
|
|
|
|
|
- // 2. 获取状态
|
|
|
|
|
|
|
+ // 4. 查询用户签到状态 & 当前连续天数
|
|
|
boolean signedToday = pointUserSignLogService.countTodaySign(openId, taskId) > 0;
|
|
boolean signedToday = pointUserSignLogService.countTodaySign(openId, taskId) > 0;
|
|
|
PointUserSignStatus status = pointUserSignStatusService.selectByOpenIdAndActivityIdForUpdate(openId, activityId);
|
|
PointUserSignStatus status = pointUserSignStatusService.selectByOpenIdAndActivityIdForUpdate(openId, activityId);
|
|
|
- int continuousDays = (status == null) ? 0 : status.getCurrentContinuousDays();
|
|
|
|
|
|
|
+ int currentContinuousDays = (status == null) ? 0 : status.getCurrentContinuousDays();
|
|
|
|
|
|
|
|
- // --- 核心修改:计算本周日期 & 状态判断 ---
|
|
|
|
|
|
|
+ // ==================== 计算本周日期 ====================
|
|
|
LocalDate today = LocalDate.now();
|
|
LocalDate today = LocalDate.now();
|
|
|
-
|
|
|
|
|
- // 计算本周周日
|
|
|
|
|
DayOfWeek dayOfWeek = today.getDayOfWeek();
|
|
DayOfWeek dayOfWeek = today.getDayOfWeek();
|
|
|
int daysSinceSunday = (dayOfWeek.getValue() == 7) ? 0 : dayOfWeek.getValue();
|
|
int daysSinceSunday = (dayOfWeek.getValue() == 7) ? 0 : dayOfWeek.getValue();
|
|
|
LocalDate thisWeekSunday = today.minusDays(daysSinceSunday);
|
|
LocalDate thisWeekSunday = today.minusDays(daysSinceSunday);
|
|
|
|
|
|
|
|
- // 定义“过期”判定阈值:例如,超过 7 天未签视为过期
|
|
|
|
|
- // 注意:这里的逻辑是,如果是“本周”的视图,通常只有“断签”和“未签”。
|
|
|
|
|
- // 如果漏签日期距离今天超过 2 天,标记为 4。
|
|
|
|
|
- int expireThresholdDays = 1;
|
|
|
|
|
|
|
+ // ==================== 查询本周签到记录 ====================
|
|
|
|
|
+ ZoneId zoneId = ZoneId.of("Asia/Shanghai");
|
|
|
|
|
+ Set<LocalDate> signedDateSet = new HashSet<>();
|
|
|
|
|
+ List<PointUserSignLog> signLogList = pointUserSignLogService.list(
|
|
|
|
|
+ new LambdaQueryWrapper<PointUserSignLog>()
|
|
|
|
|
+ .eq(PointUserSignLog::getOpenId, openId)
|
|
|
|
|
+ .eq(PointUserSignLog::getTaskId, taskId)
|
|
|
|
|
+ );
|
|
|
|
|
+ if (CollUtil.isNotEmpty(signLogList)) {
|
|
|
|
|
+ signedDateSet = signLogList.stream()
|
|
|
|
|
+ .map(log -> log.getSignDate().toInstant().atZone(zoneId).toLocalDate())
|
|
|
|
|
+ .collect(Collectors.toSet());
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
|
|
+ // ==================== 生成7天签到数据 ====================
|
|
|
List<SignDayVo> voList = new ArrayList<>();
|
|
List<SignDayVo> voList = new ArrayList<>();
|
|
|
|
|
+ // 核心:未来连续天数
|
|
|
|
|
+ int futureContinues = 1;
|
|
|
|
|
|
|
|
for (int i = 0; i < 7; i++) {
|
|
for (int i = 0; i < 7; i++) {
|
|
|
LocalDate date = thisWeekSunday.plusDays(i);
|
|
LocalDate date = thisWeekSunday.plusDays(i);
|
|
|
- int dayIndex = i + 1;
|
|
|
|
|
|
|
+ boolean isToday = date.equals(today);
|
|
|
|
|
+ boolean signed = signedDateSet.contains(date);
|
|
|
|
|
|
|
|
SignDayVo vo = new SignDayVo();
|
|
SignDayVo vo = new SignDayVo();
|
|
|
vo.setDate(date);
|
|
vo.setDate(date);
|
|
|
|
|
|
|
|
- boolean isToday = date.equals(today);
|
|
|
|
|
-
|
|
|
|
|
- // 查询该天是否已签 (建议优化为批量查询)
|
|
|
|
|
- boolean actuallySigned = false;
|
|
|
|
|
- if (isToday) {
|
|
|
|
|
- actuallySigned = signedToday;
|
|
|
|
|
- } else {
|
|
|
|
|
- // 模拟查询
|
|
|
|
|
- actuallySigned = pointUserSignLogService.count(new LambdaQueryWrapper<PointUserSignLog>()
|
|
|
|
|
- .eq(PointUserSignLog::getOpenId, openId)
|
|
|
|
|
- .eq(PointUserSignLog::getTaskId, taskId)
|
|
|
|
|
- .eq(PointUserSignLog::getSignDate, date)) > 0;
|
|
|
|
|
|
|
+ // 活动未开始
|
|
|
|
|
+ if (activityStartTime != null) {
|
|
|
|
|
+ LocalDate activityStartDate = activityStartTime.toInstant().atZone(zoneId).toLocalDate();
|
|
|
|
|
+ if (date.isBefore(activityStartDate)) {
|
|
|
|
|
+ vo.setStatus(4);
|
|
|
|
|
+ vo.setPoints(basePoints);
|
|
|
|
|
+ voList.add(vo);
|
|
|
|
|
+ continue;
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- // --- 状态赋值逻辑 ---
|
|
|
|
|
- if (isToday && !actuallySigned) {
|
|
|
|
|
- vo.setStatus(2); // 2: 今天未签到
|
|
|
|
|
- } else if (actuallySigned) {
|
|
|
|
|
- vo.setStatus(1); // 1: 已签
|
|
|
|
|
|
|
+ // 状态判断
|
|
|
|
|
+ if (isToday && !signed) {
|
|
|
|
|
+ vo.setStatus(2);
|
|
|
|
|
+ } else if (signed) {
|
|
|
|
|
+ vo.setStatus(1);
|
|
|
} else if (date.isAfter(today)) {
|
|
} else if (date.isAfter(today)) {
|
|
|
- vo.setStatus(0); // 0: 未来日期 = 没到时间没签
|
|
|
|
|
|
|
+ vo.setStatus(0);
|
|
|
} else {
|
|
} else {
|
|
|
- // 没签到的情况 (且不是今天)
|
|
|
|
|
- // 计算该日期距离今天的天数
|
|
|
|
|
long daysDiff = ChronoUnit.DAYS.between(date, today);
|
|
long daysDiff = ChronoUnit.DAYS.between(date, today);
|
|
|
|
|
+ vo.setStatus(daysDiff > 1 ? 4 : 3);
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- if (daysDiff > expireThresholdDays) {
|
|
|
|
|
- vo.setStatus(4); // 4: 已过期 (漏签太久,无法补签)
|
|
|
|
|
- } else {
|
|
|
|
|
- vo.setStatus(3); // 3: 断签 (漏签在可接受范围内)
|
|
|
|
|
|
|
+ // ==================== 积分核心:完全动态累加 ====================
|
|
|
|
|
+ int points = basePoints;
|
|
|
|
|
+ if (vo.getStatus() == 4) {
|
|
|
|
|
+ points = basePoints;
|
|
|
|
|
+ } else if (isToday) {
|
|
|
|
|
+ points = basePoints;
|
|
|
|
|
+ } else if (date.isAfter(today)) {
|
|
|
|
|
+ int totalReward = 0;
|
|
|
|
|
+ // 累加所有满足「连续天数 ≥ 配置天数」的奖励
|
|
|
|
|
+ for (PointSignReward reward : rewardList) {
|
|
|
|
|
+ if (futureContinues >= reward.getContinueDays()) {
|
|
|
|
|
+ totalReward += reward.getRewardPoints();
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
|
|
+ points = basePoints + totalReward;
|
|
|
|
|
+ futureContinues++;
|
|
|
|
|
+ } else {
|
|
|
|
|
+ points = signed ? basePoints : 0;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- // --- 奖励匹配 ---
|
|
|
|
|
- PointSignReward reward = rewardList.stream()
|
|
|
|
|
- .filter(r -> r.getContinueDays() == dayIndex)
|
|
|
|
|
- .findFirst()
|
|
|
|
|
- .orElse(null);
|
|
|
|
|
- vo.setPoints(reward != null ? reward.getRewardPoints() : 0);
|
|
|
|
|
|
|
+ vo.setPoints(points);
|
|
|
voList.add(vo);
|
|
voList.add(vo);
|
|
|
}
|
|
}
|
|
|
|
|
|