浏览代码

签到活动代码

zhangchen 3 月之前
父节点
当前提交
29b902c2d5

+ 3 - 0
alien-entity/src/main/java/shop/alien/entity/store/ActivitySignInConfig.java

@@ -33,6 +33,9 @@ public class ActivitySignInConfig {
     @ApiModelProperty(value = "活动规则")
     private String activityRule;
 
+    @ApiModelProperty(value = "基础奖励积分")
+    private Integer basePoints;
+
     @ApiModelProperty(value = "创建时间")
     @TableField(value = "created_time", fill = FieldFill.INSERT)
     @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")

+ 2 - 5
alien-entity/src/main/java/shop/alien/entity/store/ActivitySignInReward.java

@@ -30,11 +30,8 @@ public class ActivitySignInReward {
     @ApiModelProperty(value = "奖励类型1,积分,2.其他")
     private Integer rewardType;
 
-    @ApiModelProperty(value = "签到配置类型1,连续签到,2.基础签到")
-    private Integer signConfigType;
-
-    @ApiModelProperty(value = "方案配置类型1,默认方案,2.特殊方案")
-    private Integer planConfigType;
+//    @ApiModelProperty(value = "签到配置类型1,连续签到,2.基础签到")
+//    private Integer signConfigType;
 
     @ApiModelProperty(value = "创建时间")
     @TableField(value = "created_time", fill = FieldFill.INSERT)

+ 48 - 0
alien-entity/src/main/java/shop/alien/entity/store/SignInActivity.java

@@ -0,0 +1,48 @@
+package shop.alien.entity.store;
+import com.baomidou.mybatisplus.annotation.*;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.fasterxml.jackson.annotation.JsonInclude;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.util.Date;
+@Data
+@JsonInclude
+@TableName("sign_in_activity")
+@ApiModel(value = "SignInActivity", description = "用户签到记录活动表")
+public class SignInActivity {
+    @ApiModelProperty(value = "主键")
+    @TableId(value = "id", type = IdType.AUTO)
+    private Integer id;
+
+    @ApiModelProperty(value = "用户签到记录ID")
+    private Integer userSignInRecordId;
+
+    @ApiModelProperty(value = "活动ID")
+    private Integer activityId;
+
+    @ApiModelProperty(value = "创建时间")
+    @TableField(value = "created_time", fill = FieldFill.INSERT)
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private Date createdTime;
+
+    @ApiModelProperty(value = "创建人ID")
+    private Integer createdUserId;
+
+    @ApiModelProperty(value = "修改时间")
+    @TableField(value = "updated_time", fill = FieldFill.INSERT_UPDATE)
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private Date updatedTime;
+
+    @ApiModelProperty(value = "修改人ID")
+    private Integer updatedUserId;
+
+    @ApiModelProperty(value = "删除标记, 0:未删除, 1:已删除")
+    @TableField("delete_flag")
+    @TableLogic
+    private Integer deleteFlag;
+
+    @ApiModelProperty(value = "积分")
+    private Integer point;
+}

+ 60 - 0
alien-entity/src/main/java/shop/alien/entity/store/UserSignInRecord.java

@@ -0,0 +1,60 @@
+package shop.alien.entity.store;
+
+import com.baomidou.mybatisplus.annotation.*;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.fasterxml.jackson.annotation.JsonInclude;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.util.Date;
+@Data
+@JsonInclude
+@TableName("user_sign_in_record")
+@ApiModel(value = "UserSignInRecord", description = "用户签到记录表")
+public class UserSignInRecord {
+    @ApiModelProperty(value = "主键")
+    @TableId(value = "id", type = IdType.AUTO)
+    private Integer id;
+
+    @ApiModelProperty(value = "用户ID")
+    private Integer userId;
+
+    @ApiModelProperty(value = "当前连续签到天数")
+    private Integer continuousDays;
+
+    @ApiModelProperty(value = "本次获得积分")
+    private Integer pointsObtained;
+
+    @ApiModelProperty(value = "签到时间")
+    @TableField(value = "sign_in_date", fill = FieldFill.INSERT)
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private Date signInDate;
+
+    @ApiModelProperty(value = "创建时间")
+    @TableField(value = "created_time", fill = FieldFill.INSERT)
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private Date createdTime;
+
+    @ApiModelProperty(value = "创建人ID")
+    private Integer createdUserId;
+
+    @ApiModelProperty(value = "修改时间")
+    @TableField(value = "updated_time", fill = FieldFill.INSERT_UPDATE)
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private Date updatedTime;
+
+    @ApiModelProperty(value = "修改人ID")
+    private Integer updatedUserId;
+
+    @ApiModelProperty(value = "删除标记, 0:未删除, 1:已删除")
+    @TableField("delete_flag")
+    @TableLogic
+    private Integer deleteFlag;
+
+    @ApiModelProperty(value = "总计连续签到天数")
+    private Integer totalContinuousDays;
+
+    @ApiModelProperty(value = "特殊方案连续签到天数")
+    private Integer specialContinuousDays;
+}

+ 7 - 1
alien-entity/src/main/java/shop/alien/entity/store/vo/ActivityPeriodVo.java

@@ -6,7 +6,6 @@ import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
 import lombok.EqualsAndHashCode;
 import shop.alien.entity.store.ActivityPeriod;
-
 @EqualsAndHashCode(callSuper = true)
 @Data
 @JsonInclude
@@ -17,4 +16,11 @@ public class ActivityPeriodVo extends ActivityPeriod {
     @ApiModelProperty(value = "活动名称")
     @TableField("activity_name")
     private String activityName;
+
+    /**
+     * 方案类型配置类型
+     */
+    @ApiModelProperty(value = "方案配置类型")
+    @TableField("plan_config_type")
+    private Integer planConfigType;
 }

+ 22 - 0
alien-entity/src/main/java/shop/alien/entity/store/vo/ActivityPointInfoVo.java

@@ -0,0 +1,22 @@
+package shop.alien.entity.store.vo;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * @author zhangchen
+ * @version 1.0
+ * @date 2025/9/8 10:00
+ */
+@EqualsAndHashCode(callSuper = false)
+@Data
+@JsonInclude
+public class ActivityPointInfoVo {
+    @ApiModelProperty(value = "积分")
+    private Integer point;
+
+    @ApiModelProperty(value = "奖励名称")
+    private String pointInfo;
+}

+ 31 - 0
alien-entity/src/main/java/shop/alien/entity/store/vo/SignInVo.java

@@ -0,0 +1,31 @@
+package shop.alien.entity.store.vo;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import shop.alien.entity.store.UserSignInRecord;
+
+import java.util.List;
+
+/**
+ * @author zhangchen
+ * @version 1.0
+ * @date 2025/9/8 10:00
+ */
+@EqualsAndHashCode(callSuper = false)
+@Data
+@JsonInclude
+public class SignInVo {
+    @ApiModelProperty(value = "累计获得积分")
+    private Integer totalPoint;
+
+    @ApiModelProperty(value = "总计连续签到天数")
+    private Integer totalContinueDay;
+
+    @ApiModelProperty(value = "当前连续签到天数")
+    private Integer continuousDays;
+
+    @ApiModelProperty(value = "签到记录")
+    private List<UserSignInRecord> userSignInRecordList;
+}

+ 19 - 0
alien-entity/src/main/java/shop/alien/entity/store/vo/UserSignInRecordVo.java

@@ -0,0 +1,19 @@
+package shop.alien.entity.store.vo;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.fasterxml.jackson.annotation.JsonInclude;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import shop.alien.entity.store.UserSignInRecord;
+
+import java.util.List;
+
+@Data
+@JsonInclude
+@ApiModel(value = "UserSignInRecord", description = "用户签到记录VO")
+public class UserSignInRecordVo extends UserSignInRecord {
+
+    @ApiModelProperty(value = "奖励积分列表")
+    List<ActivityPointInfoVo> activityPointInfoVoList;
+}

+ 4 - 0
alien-entity/src/main/java/shop/alien/mapper/ActivityPeriodMapper.java

@@ -12,4 +12,8 @@ public interface ActivityPeriodMapper extends BaseMapper<ActivityPeriod> {
             "left join activity_sign_in_config asic on asic.id = ap.activity_id " +
             "where asic.delete_flag = 0 and ap.delete_flag = 0 and ap.start_time < #{endTime} and ap.end_time > #{startTime}")
     List<ActivityPeriodVo> getActivityPeriodList(@Param("startTime") String startTime, @Param("endTime") String endTime);
+    @Select("select ap.id,ap.activity_id,asic.activity_name,asic.plan_config_type from activity_period ap " +
+            "left join activity_sign_in_config asic on asic.id = ap.activity_id " +
+            "where ap.delete_flag = 0 and asic.delete_flag = 0 and asic.status = 1 and ap.start_time < CURDATE() and ap.end_time > CURDATE()")
+    List<ActivityPeriodVo> getCurrentActivityPeriodList();
 }

+ 13 - 1
alien-entity/src/main/java/shop/alien/mapper/ActivitySignRewardMapper.java

@@ -1,13 +1,25 @@
 package shop.alien.mapper;
-
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.core.toolkit.Constants;
 import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+import org.apache.ibatis.annotations.Select;
 import shop.alien.entity.store.ActivitySignInConfig;
 import shop.alien.entity.store.ActivitySignInReward;
+import shop.alien.entity.store.vo.ActivityPeriodVo;
+import shop.alien.entity.store.vo.LifeFansVo;
 
+import java.util.List;
 /**
  * 签到奖励配置mapper
  */
 @Mapper
 public interface ActivitySignRewardMapper extends BaseMapper<ActivitySignInReward> {
+    @Select("select * from activity_sign_in_reward asir " +
+            "where asir.delete_flag = 0 and asir.day_of_sequence % #{continueDay} = 0 ${ew.customSqlSegment}")
+    List<ActivitySignInReward> getActivitySignRewardList(@Param("continueDay") int continueDay, @Param(Constants.WRAPPER) QueryWrapper<ActivitySignInReward> dynamicsWrapper);
+
+    @Select("select * from activity_sign_in_reward asir where asir.delete_flag = 0 and asir.day_of_sequence % #{continueDay} = 0 and activity_id = #{activityId} order by asir.day_of_sequence desc limit 1")
+    ActivitySignInReward getActivitySignReward(@Param("continueDay") int continueDay, @Param("activityId") int activityId);
 }

+ 13 - 0
alien-entity/src/main/java/shop/alien/mapper/UserSignInRecordMapper.java

@@ -0,0 +1,13 @@
+package shop.alien.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Mapper;
+import shop.alien.entity.store.ActivitySignInConfig;
+import shop.alien.entity.store.UserSignInRecord;
+
+/**
+ * 签到记录mapper
+ */
+@Mapper
+public interface UserSignInRecordMapper extends BaseMapper<UserSignInRecord> {
+}

+ 15 - 0
alien-entity/src/main/java/shop/alien/mapper/system/SignInActivityMapper.java

@@ -0,0 +1,15 @@
+package shop.alien.mapper.system;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+import org.apache.ibatis.annotations.Select;
+import shop.alien.entity.store.ActivityPeriod;
+import shop.alien.entity.store.SignInActivity;
+import shop.alien.entity.store.vo.ActivityPeriodVo;
+
+import java.util.List;
+
+@Mapper
+public interface SignInActivityMapper extends BaseMapper<SignInActivity> {
+}

+ 73 - 0
alien-store/src/main/java/shop/alien/store/controller/SignInController.java

@@ -0,0 +1,73 @@
+package shop.alien.store.controller;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import io.swagger.annotations.*;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.web.bind.annotation.*;
+import shop.alien.entity.result.R;
+import shop.alien.entity.store.ActivitySignInConfig;
+import shop.alien.entity.store.UserSignInRecord;
+import shop.alien.entity.store.vo.SignInVo;
+import shop.alien.entity.store.vo.UserSignInRecordVo;
+import shop.alien.store.service.SignInService;
+
+@Api(tags = {"二期-用户签到"})
+@Slf4j
+@CrossOrigin
+@RestController
+@RequestMapping("/userSign")
+@RequiredArgsConstructor
+public class SignInController {
+    private final SignInService signInService;
+
+    /**
+     * 用户签到
+     */
+    @ApiOperation("用户签到")
+    @ApiOperationSupport(order = 1)
+    @GetMapping("/signIn")
+    public R<UserSignInRecordVo> signIn(@RequestParam("userId") Integer userId) {
+        log.info("SignInController.signIn, userid = {}", userId);
+        UserSignInRecordVo userSignInRecordVo = signInService.signIn(userId);
+        return R.data(userSignInRecordVo);
+    }
+
+    @ApiOperation("获取活动配置信息")
+    @ApiOperationSupport(order = 2)
+    @GetMapping("/getActivitySignInConfigInfo")
+    public R<ActivitySignInConfig> getActivitySignInConfigInfo() {
+        log.info("SignInController.getActivitySignInConfigInfo");
+        ActivitySignInConfig activitySignInConfig = signInService.getActivitySignInConfigInfo();
+        return R.data(activitySignInConfig);
+    }
+
+    @ApiOperation("获取是否签到")
+    @ApiOperationSupport(order = 3)
+    @GetMapping("/checkSignInStatus")
+    public R<Boolean> checkSignInStatus(@RequestParam("userId") Integer userId) {
+        log.info("SignInController.checkSignInStatus, {}", userId);
+        boolean result = signInService.checkSignInStatus(userId);
+        return R.data(result);
+    }
+
+    @ApiOperation("获取签到相关信息")
+    @ApiOperationSupport(order = 4)
+    @GetMapping("/getUserSignInInfo")
+    public R<SignInVo> getUserSignInInfo(@RequestParam("userId") Integer userId, @RequestParam("num") Integer num) {
+        log.info("SignInController.getUserSignInInfo");
+        SignInVo signInVo = signInService.getUserSignInInfo(userId, num);
+        return R.data(signInVo);
+    }
+
+    @ApiOperation("获取签到记录列表(分页)")
+    @ApiOperationSupport(order = 5)
+    @GetMapping("/getUserSignInRecordList")
+    public R<IPage<UserSignInRecord>> getUserSignInRecordList(@RequestParam(defaultValue = "1") int pageNum,
+                                            @RequestParam(defaultValue = "10") int pageSize,
+                                            @RequestParam(required = true) int userId){
+        log.info("SignInController.getUserSignInRecordList");
+        IPage<UserSignInRecord> userSignInRecordList = signInService.getUserSignInRecordList(pageNum, pageSize,userId);
+        return R.data(userSignInRecordList);
+    }
+}

+ 21 - 0
alien-store/src/main/java/shop/alien/store/service/SignInService.java

@@ -0,0 +1,21 @@
+package shop.alien.store.service;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.service.IService;
+import shop.alien.entity.store.ActivitySignInConfig;
+import shop.alien.entity.store.UserSignInRecord;
+import shop.alien.entity.store.vo.SignInVo;
+import shop.alien.entity.store.vo.UserSignInRecordVo;
+
+public interface SignInService extends IService<UserSignInRecord> {
+
+    UserSignInRecordVo signIn(int userId);
+
+    ActivitySignInConfig getActivitySignInConfigInfo();
+
+    boolean checkSignInStatus(int userId);
+
+    SignInVo getUserSignInInfo(int userId, int num);
+
+    IPage<UserSignInRecord> getUserSignInRecordList(int pageNum, int pageSize, int userId);
+}

+ 6 - 10
alien-store/src/main/java/shop/alien/store/service/impl/ActivityConfigServiceImpl.java

@@ -22,7 +22,6 @@ import shop.alien.mapper.ActivitySignInConfigMapper;
 
 import java.util.ArrayList;
 import java.util.Comparator;
-import java.util.Date;
 import java.util.List;
 
 /**
@@ -50,11 +49,6 @@ public class ActivityConfigServiceImpl extends ServiceImpl<ActivitySignInConfigM
             return configVO;
         }
         List<ActivitySignInReward> activitySignInRewardList = configVO.getRewards();
-        if(CollectionUtils.isEmpty(activitySignInRewardList)) {
-            log.error("创建活动奖励配置为空。");
-            configVO.setErrorMessage("活动奖励配置为空");
-            return configVO;
-        }
 
         // 校验是否存在重复时间段的方案
         List<ActivityPeriod> activityPeriodList = configVO.getActivityPeriodList();
@@ -101,10 +95,12 @@ public class ActivityConfigServiceImpl extends ServiceImpl<ActivitySignInConfigM
             }
 
             // 创建活动奖励记录
-            activitySignInRewardList.forEach(item -> {
-                item.setActivityId(activitySignInConfig.getId());
-                activitySignRewardMapper.insert(item);
-            });
+            if(!CollectionUtils.isEmpty(activitySignInRewardList)){
+                activitySignInRewardList.forEach(item -> {
+                    item.setActivityId(activitySignInConfig.getId());
+                    activitySignRewardMapper.insert(item);
+                });
+            }
         } else {
             //更新操作
             BeanUtils.copyProperties(configVO, activitySignInConfig);

+ 369 - 0
alien-store/src/main/java/shop/alien/store/service/impl/SignInServiceImpl.java

@@ -0,0 +1,369 @@
+package shop.alien.store.service.impl;
+
+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 lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.BeanUtils;
+import org.springframework.stereotype.Service;
+import org.springframework.util.CollectionUtils;
+import shop.alien.entity.store.*;
+import shop.alien.entity.store.vo.ActivityPeriodVo;
+import shop.alien.entity.store.vo.ActivityPointInfoVo;
+import shop.alien.entity.store.vo.SignInVo;
+import shop.alien.entity.store.vo.UserSignInRecordVo;
+import shop.alien.mapper.ActivityPeriodMapper;
+import shop.alien.mapper.ActivitySignInConfigMapper;
+import shop.alien.mapper.UserSignInRecordMapper;
+import shop.alien.mapper.ActivitySignRewardMapper;
+import shop.alien.mapper.system.SignInActivityMapper;
+import shop.alien.store.service.SignInService;
+
+import java.text.SimpleDateFormat;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.LocalTime;
+import java.time.ZoneId;
+import java.time.format.DateTimeFormatter;
+import java.util.*;
+import java.util.stream.Collectors;
+
+/**
+ *
+ * 签到类型活动服务
+ * @author zhangchen
+ * @since 2025-9-8
+ */
+@Slf4j
+@Service
+@RequiredArgsConstructor
+public class SignInServiceImpl extends ServiceImpl<UserSignInRecordMapper, UserSignInRecord> implements SignInService {
+
+    private final ActivitySignInConfigMapper activitySignInConfigMapper;
+    private final ActivitySignRewardMapper activitySignRewardMapper;
+    private final ActivityPeriodMapper activityPeriodMapper;
+    private final UserSignInRecordMapper userSignInRecordMapper;
+    private final SignInActivityMapper signInActivityMapper;
+
+    @Override
+    public UserSignInRecordVo signIn(int userId) {
+
+        UserSignInRecordVo userSignInRecordVo = new UserSignInRecordVo();
+
+        // 查询特殊方案活动
+        List<ActivityPeriodVo> activityPeriodVoList = activityPeriodMapper.getCurrentActivityPeriodList();
+
+        // 查询默认方案活动
+        LambdaQueryWrapper<ActivitySignInConfig> connomActivitySignInConfigLambdaQueryWrapper = new LambdaQueryWrapper<>();
+        connomActivitySignInConfigLambdaQueryWrapper.eq(ActivitySignInConfig::getDeleteFlag, 0);
+        connomActivitySignInConfigLambdaQueryWrapper.eq(ActivitySignInConfig::getPlanConfigType, 1);
+        ActivitySignInConfig commonActivitySignInConfig = activitySignInConfigMapper.selectOne(connomActivitySignInConfigLambdaQueryWrapper);
+        if(commonActivitySignInConfig == null){
+            // 默认方案为空
+            return null;
+        }
+
+
+        // 检查是否已经签到
+        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
+        String currentDate = simpleDateFormat.format(new Date());
+
+        LambdaQueryWrapper<UserSignInRecord> userSignInRecordLambdaQueryWrapper = new LambdaQueryWrapper<>();
+        userSignInRecordLambdaQueryWrapper.between(UserSignInRecord::getSignInDate, currentDate + " 00:00:00", currentDate + " 23:59:59");
+        userSignInRecordLambdaQueryWrapper.eq(UserSignInRecord::getDeleteFlag, 0);
+        userSignInRecordLambdaQueryWrapper.eq(UserSignInRecord::getUserId, userId);
+        UserSignInRecord userSignInRecord =  userSignInRecordMapper.selectOne(userSignInRecordLambdaQueryWrapper);
+        if(userSignInRecord != null){
+            BeanUtils.copyProperties(userSignInRecord, userSignInRecordVo);
+            return userSignInRecordVo;
+        }
+
+        // 计算连续签到天数
+        int continueDay = calculateContinuousDays(userId, 1);
+        // 计算总计连续签到天数
+        int totalContinueDay = totalContinuousDays(userId, 1);
+        totalContinueDay++;
+
+        // 方案奖励
+        Map<Integer, Integer> activityPoint = new HashMap<>();
+        // 获取默认方案奖励
+        int basePoints = commonActivitySignInConfig.getBasePoints();
+        List<ActivityPointInfoVo> activityPointInfoVoList = new ArrayList<>();
+        ActivityPointInfoVo activityPointInfoVo = new ActivityPointInfoVo();
+        activityPointInfoVo.setPoint(basePoints);
+        activityPointInfoVo.setPointInfo("今日签到奖励"+basePoints+"积分");
+        activityPointInfoVoList.add(activityPointInfoVo);
+
+        LambdaQueryWrapper<ActivitySignInReward> activitySignInRewardLambdaQueryWrapper = new LambdaQueryWrapper<>();
+        activitySignInRewardLambdaQueryWrapper.eq(ActivitySignInReward::getDeleteFlag,0);
+        activitySignInRewardLambdaQueryWrapper.eq(ActivitySignInReward::getActivityId, commonActivitySignInConfig.getId());
+        List<ActivitySignInReward> activitySignInRewardList = activitySignRewardMapper.selectList(activitySignInRewardLambdaQueryWrapper);
+        if(!CollectionUtils.isEmpty(activitySignInRewardList)){
+            int maxNum = activitySignInRewardList.stream()
+                    .map(ActivitySignInReward::getDayOfSequence)
+                    .max(Comparator.naturalOrder())
+                    .orElse(0);
+            if(continueDay >= maxNum){
+                continueDay = 1;
+            } else {
+                continueDay++;
+            }
+            Map<Integer, List<ActivitySignInReward>> groupActivitySignInReward = activitySignInRewardList.stream()
+                    .collect(Collectors.groupingBy(ActivitySignInReward::getDayOfSequence));
+            if(groupActivitySignInReward.containsKey(continueDay)){
+                List<ActivitySignInReward> activitySignInRewards =  groupActivitySignInReward.get(continueDay);
+                if(!CollectionUtils.isEmpty(activitySignInRewards)){
+                    ActivitySignInReward activitySignInReward = activitySignInRewards.get(0);
+                    basePoints = basePoints + activitySignInReward.getPoints();
+                    ActivityPointInfoVo groupActivityPointInfoVo = new ActivityPointInfoVo();
+                    groupActivityPointInfoVo.setPoint(activitySignInReward.getPoints());
+                    groupActivityPointInfoVo.setPointInfo("已连续签到"+continueDay+"天奖励积分"+activitySignInReward.getPoints());
+                    activityPointInfoVoList.add(groupActivityPointInfoVo);
+                }
+            }
+        }
+        activityPoint.put(commonActivitySignInConfig.getId(), basePoints);
+
+        // 获取特殊方案奖励
+        int specialPoints = 0;
+        int specialContinueDay = 0;
+        if(!CollectionUtils.isEmpty(activityPeriodVoList)){
+            ActivityPeriod activityPeriod = activityPeriodVoList.get(0);
+            int activityId =  activityPeriod.getActivityId();
+            LambdaQueryWrapper<ActivitySignInReward> specialActivitySignInRewardLambdaQueryWrapper = new LambdaQueryWrapper<>();
+            specialActivitySignInRewardLambdaQueryWrapper.eq(ActivitySignInReward::getDeleteFlag, 0);
+            specialActivitySignInRewardLambdaQueryWrapper.eq(ActivitySignInReward::getActivityId, activityId);
+            List<ActivitySignInReward> specialActivitySignInRewardList = activitySignRewardMapper.selectList(specialActivitySignInRewardLambdaQueryWrapper);
+
+            // 计算特殊方案连续签到天数
+            specialContinueDay = specialContinuousDays(userId, 1);
+            if(!CollectionUtils.isEmpty(specialActivitySignInRewardList)){
+                int maxNum = specialActivitySignInRewardList.stream()
+                        .map(ActivitySignInReward::getDayOfSequence)
+                        .max(Comparator.naturalOrder())
+                        .orElse(0);
+                if(specialContinueDay >= maxNum){
+                    specialContinueDay = 1;
+                } else {
+                    specialContinueDay++;
+                }
+
+                Map<Integer, List<ActivitySignInReward>> groupSpecialActivitySignInReward = specialActivitySignInRewardList.stream()
+                        .collect(Collectors.groupingBy(ActivitySignInReward::getDayOfSequence));
+                if(groupSpecialActivitySignInReward.containsKey(continueDay)){
+                    List<ActivitySignInReward> specialActivitySignInRewards =  groupSpecialActivitySignInReward.get(specialContinueDay);
+                    if(!CollectionUtils.isEmpty(specialActivitySignInRewards)){
+                        ActivitySignInReward specialActivitySignInReward = specialActivitySignInRewards.get(0);
+                        specialPoints = specialPoints + specialActivitySignInReward.getPoints();
+                        ActivityPointInfoVo specialActivityPointInfoVo = new ActivityPointInfoVo();
+                        specialActivityPointInfoVo.setPoint(specialActivitySignInReward.getPoints());
+                        specialActivityPointInfoVo.setPointInfo("福利日签到奖励积分"+specialActivitySignInReward.getPoints());
+                        activityPointInfoVoList.add(specialActivityPointInfoVo);
+                    }
+                }
+            }
+            activityPoint.put(activityId, specialPoints);
+        }
+
+        LocalDateTime now = LocalDateTime.now();
+        Date date = Date.from(now.atZone(ZoneId.systemDefault()).toInstant());
+
+        // 保存签到记录
+        UserSignInRecord record = new UserSignInRecord();
+        record.setSignInDate(date);
+        record.setContinuousDays(continueDay);
+        record.setTotalContinuousDays(totalContinueDay);
+        record.setSpecialContinuousDays(specialContinueDay);
+        record.setPointsObtained(basePoints + specialPoints);
+        record.setUserId(userId);
+        record.setDeleteFlag(0);
+        userSignInRecordMapper.insert(record);
+
+        if(!CollectionUtils.isEmpty(activityPoint)){
+            activityPoint.forEach((key, value) -> {
+                if(value == 0 ){
+                    return;
+                }
+                SignInActivity signInActivity = new SignInActivity();
+                signInActivity.setActivityId(key);
+                signInActivity.setPoint(value);
+                signInActivity.setUserSignInRecordId(record.getId());
+                signInActivityMapper.insert(signInActivity);
+            });
+        }
+
+        BeanUtils.copyProperties(record, userSignInRecordVo);
+        userSignInRecordVo.setActivityPointInfoVoList(activityPointInfoVoList);
+        return userSignInRecordVo;
+    }
+
+    @Override
+    public ActivitySignInConfig getActivitySignInConfigInfo() {
+        // 查询默认方案信息
+        LambdaQueryWrapper<ActivitySignInConfig> activitySignInConfigLambdaQueryWrapper = new LambdaQueryWrapper<>();
+        activitySignInConfigLambdaQueryWrapper.eq(ActivitySignInConfig::getDeleteFlag, 0);
+        activitySignInConfigLambdaQueryWrapper.eq(ActivitySignInConfig::getPlanConfigType, 1);
+        activitySignInConfigLambdaQueryWrapper.eq(ActivitySignInConfig::getStatus, 1);
+        return activitySignInConfigMapper.selectOne(activitySignInConfigLambdaQueryWrapper);
+    }
+
+    @Override
+    public boolean checkSignInStatus(int userId) {
+        // 获取当天时间段
+        LocalDateTime todayStart = LocalDateTime.of(LocalDate.now(), LocalTime.MIN);
+        LocalDateTime todayEnd = LocalDateTime.of(LocalDate.now(), LocalTime.MAX);
+
+        LambdaQueryWrapper<UserSignInRecord> userSignInRecordLambdaQueryWrapper = new LambdaQueryWrapper<>();
+        userSignInRecordLambdaQueryWrapper.between(UserSignInRecord::getSignInDate, todayStart, todayEnd);
+        userSignInRecordLambdaQueryWrapper.eq(UserSignInRecord::getDeleteFlag, 0);
+        userSignInRecordLambdaQueryWrapper.eq(UserSignInRecord::getUserId, userId);
+        UserSignInRecord userSignInRecord =  userSignInRecordMapper.selectOne(userSignInRecordLambdaQueryWrapper);
+        return userSignInRecord != null;
+    }
+
+    @Override
+    public SignInVo getUserSignInInfo(int userId, int num) {
+        SignInVo signInVo = new SignInVo();
+        // 获取累计获得积分
+        int totalPoint = 0;
+        LambdaQueryWrapper<UserSignInRecord> userSignInRecordLambdaQueryWrapper = new LambdaQueryWrapper<>();
+        userSignInRecordLambdaQueryWrapper.eq(UserSignInRecord::getUserId, userId);
+        userSignInRecordLambdaQueryWrapper.eq(UserSignInRecord::getDeleteFlag, 0);
+        userSignInRecordLambdaQueryWrapper.orderByDesc(UserSignInRecord::getSignInDate);
+        List<UserSignInRecord> userSignInRecordList =  userSignInRecordMapper.selectList(userSignInRecordLambdaQueryWrapper);
+        UserSignInRecord lastUserSignInRecord = null;
+        if(!CollectionUtils.isEmpty(userSignInRecordList)){
+            totalPoint = userSignInRecordList.stream()
+                    .mapToInt(UserSignInRecord::getPointsObtained)
+                    .sum();
+            lastUserSignInRecord = userSignInRecordList.get(0);
+        }
+        signInVo.setTotalPoint(totalPoint);
+
+        // 获取连续签到天数
+        int continueDay = totalContinuousDays(userId,0);
+        signInVo.setTotalContinueDay(continueDay);
+
+        // 计算连续签到天数
+        int countDay = 1;
+        if(lastUserSignInRecord != null && lastUserSignInRecord.getSignInDate() != null){
+            boolean isToday = isSameDay(lastUserSignInRecord.getSignInDate(),0);
+            if(isToday){
+                countDay = lastUserSignInRecord.getContinuousDays();
+            } else{
+                boolean isYestDay = isSameDay(lastUserSignInRecord.getSignInDate(),1);
+                if(isYestDay){
+                    countDay = lastUserSignInRecord.getContinuousDays() + 1;
+                }
+            }
+        }
+        signInVo.setContinuousDays(countDay);
+
+        // 获取签到记录
+//        LambdaQueryWrapper<UserSignInRecord> wrapper = new LambdaQueryWrapper<>();
+//        wrapper.eq(UserSignInRecord::getUserId, userId);
+//        wrapper.eq(UserSignInRecord::getDeleteFlag, 0);
+//        wrapper.orderByDesc(UserSignInRecord::getSignInDate);
+//        wrapper.last("Limit " + num);
+//        List<UserSignInRecord> userSignInRecords = userSignInRecordMapper.selectList(wrapper);
+//        signInVo.setUserSignInRecordList(userSignInRecords);
+        return signInVo;
+    }
+
+    @Override
+    public IPage<UserSignInRecord> getUserSignInRecordList(int pageNum, int pageSize, int userId) {
+        IPage<UserSignInRecord> iPage = new Page<>(pageNum, pageSize);
+        // 获取签到记录
+        LambdaQueryWrapper<UserSignInRecord> wrapper = new LambdaQueryWrapper<>();
+        wrapper.eq(UserSignInRecord::getUserId, userId);
+        wrapper.eq(UserSignInRecord::getDeleteFlag, 0);
+        wrapper.orderByDesc(UserSignInRecord::getSignInDate);
+        return userSignInRecordMapper.selectPage(iPage, wrapper);
+    }
+
+    /**
+     * 计算连续签到天数
+     */
+    private int calculateContinuousDays(int userId, int dayCount) {
+        LambdaQueryWrapper<UserSignInRecord> userSignInRecordLambdaQueryWrapper = new LambdaQueryWrapper<>();
+        userSignInRecordLambdaQueryWrapper.eq(UserSignInRecord::getDeleteFlag, 0);
+        userSignInRecordLambdaQueryWrapper.eq(UserSignInRecord::getUserId, userId);
+        userSignInRecordLambdaQueryWrapper.orderByDesc(UserSignInRecord::getSignInDate);
+        userSignInRecordLambdaQueryWrapper.last("Limit 1");
+        List<UserSignInRecord> userSignInRecordList =  userSignInRecordMapper.selectList(userSignInRecordLambdaQueryWrapper);
+        if(CollectionUtils.isEmpty(userSignInRecordList)){
+            return 0;
+        }
+        UserSignInRecord userSignInRecord = userSignInRecordList.get(0);
+        Date signInDate = userSignInRecord.getSignInDate();
+        boolean result = isSameDay(signInDate, dayCount);
+        if(result){
+            return userSignInRecord.getContinuousDays();
+        } else{
+            return 0;
+        }
+    }
+
+    /**
+     * 计算总计连续签到天数
+     */
+    private int totalContinuousDays(int userId, int dayCount) {
+        LambdaQueryWrapper<UserSignInRecord> userSignInRecordLambdaQueryWrapper = new LambdaQueryWrapper<>();
+        userSignInRecordLambdaQueryWrapper.eq(UserSignInRecord::getDeleteFlag, 0);
+        userSignInRecordLambdaQueryWrapper.eq(UserSignInRecord::getUserId, userId);
+        userSignInRecordLambdaQueryWrapper.orderByDesc(UserSignInRecord::getSignInDate);
+        userSignInRecordLambdaQueryWrapper.last("Limit 1");
+        List<UserSignInRecord> userSignInRecordList =  userSignInRecordMapper.selectList(userSignInRecordLambdaQueryWrapper);
+        if(CollectionUtils.isEmpty(userSignInRecordList)){
+            return 0;
+        }
+        UserSignInRecord userSignInRecord = userSignInRecordList.get(0);
+        Date signInDate = userSignInRecord.getSignInDate();
+        boolean result = isSameDay(signInDate, dayCount);
+        if(result){
+            return userSignInRecord.getTotalContinuousDays();
+        } else{
+            return 0;
+        }
+    }
+
+    /**
+     * 计算特殊方案连续签到天数
+     */
+    private int specialContinuousDays(int userId, int dayCount) {
+        LambdaQueryWrapper<UserSignInRecord> userSignInRecordLambdaQueryWrapper = new LambdaQueryWrapper<>();
+        userSignInRecordLambdaQueryWrapper.eq(UserSignInRecord::getDeleteFlag, 0);
+        userSignInRecordLambdaQueryWrapper.eq(UserSignInRecord::getUserId, userId);
+        userSignInRecordLambdaQueryWrapper.orderByDesc(UserSignInRecord::getSignInDate);
+        userSignInRecordLambdaQueryWrapper.last("Limit 1");
+        List<UserSignInRecord> userSignInRecordList =  userSignInRecordMapper.selectList(userSignInRecordLambdaQueryWrapper);
+        if(CollectionUtils.isEmpty(userSignInRecordList)){
+            return 0;
+        }
+        UserSignInRecord userSignInRecord = userSignInRecordList.get(0);
+        Date signInDate = userSignInRecord.getSignInDate();
+        boolean result = isSameDay(signInDate, dayCount);
+        if(result){
+            return userSignInRecord.getSpecialContinuousDays();
+        } else{
+            return 0;
+        }
+    }
+
+    /**
+     * 判断两个Date对象是否是同一天(Java 8+ 推荐)
+     */
+    public static boolean isSameDay(Date date, int dayCount) {
+        if (date == null) {
+            return false;
+        }
+        LocalDate localDate1 = date.toInstant()
+                .atZone(java.time.ZoneId.systemDefault())
+                .toLocalDate();
+        LocalDate today = LocalDate.now();
+        LocalDate localDate2 = today.minusDays(dayCount);
+        return localDate1.isEqual(localDate2);
+    }
+}