Explorar o código

提交代码,签到面板接口

wangzhijun hai 5 horas
pai
achega
4736ee8e97

+ 74 - 46
nightFragrance-massage/src/main/java/com/ylx/point/service/impl/PointActivityServiceImpl.java

@@ -1,6 +1,7 @@
 package com.ylx.point.service.impl;
 
 import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.collection.CollUtil;
 import cn.hutool.core.collection.CollectionUtil;
 import cn.hutool.core.date.DateUtil;
 import cn.hutool.core.util.ObjectUtil;
@@ -334,88 +335,115 @@ public class PointActivityServiceImpl extends ServiceImpl<PointActivityMapper, P
 
     @Override
     public List<SignDayVo> getSignInfo(SignDTO dto) {
-
-        // 当前登录用户信息
+        // 1. 获取当前登录用户
         WxLoginUser wxLoginUser = getCurrentWxLoginUser();
         String openId = wxLoginUser.getCOpenid();
 
+        // 2. 获取当前城市签到任务
         PointSignTask task = getEnabledTask(dto.getCityCode());
-        if (task == null) throw new ServiceException("当前城市暂无签到活动");
+        if (ObjectUtil.isNull(task)) {
+            throw new ServiceException("当前城市暂无签到活动");
+        }
         Long taskId = task.getId();
         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<>();
-        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);
 
-        // 2. 获取状态
+        // 4. 查询用户签到状态 & 当前连续天数
         boolean signedToday = pointUserSignLogService.countTodaySign(openId, taskId) > 0;
         PointUserSignStatus status = pointUserSignStatusService.selectByOpenIdAndActivityIdForUpdate(openId, activityId);
-        int continuousDays = (status == null) ? 0 : status.getCurrentContinuousDays();
+        int currentContinuousDays = (status == null) ? 0 : status.getCurrentContinuousDays();
 
-        // --- 核心修改:计算本周日期 & 状态判断 ---
+        // ==================== 计算本周日期 ====================
         LocalDate today = LocalDate.now();
-
-        // 计算本周周日
         DayOfWeek dayOfWeek = today.getDayOfWeek();
         int daysSinceSunday = (dayOfWeek.getValue() == 7) ? 0 : dayOfWeek.getValue();
         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<>();
+        // 核心:未来连续天数
+        int futureContinues =  1;
 
         for (int i = 0; i < 7; i++) {
             LocalDate date = thisWeekSunday.plusDays(i);
-            int dayIndex = i + 1;
+            boolean isToday = date.equals(today);
+            boolean signed = signedDateSet.contains(date);
 
             SignDayVo vo = new SignDayVo();
             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)) {
-                vo.setStatus(0); // 0: 未来日期 = 没到时间没签
+                vo.setStatus(0);
             } else {
-                // 没签到的情况 (且不是今天)
-                // 计算该日期距离今天的天数
                 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);
         }