Sfoglia il codice sorgente

用户积分查询接口

wangzhijun 1 giorno fa
parent
commit
167d1530f2
27 ha cambiato i file con 588 aggiunte e 32 eliminazioni
  1. 1 1
      nightFragrance-admin/src/main/java/com/ylx/web/controller/point/PointActivityController.java
  2. 70 0
      nightFragrance-admin/src/main/java/com/ylx/web/controller/point/UserPointController.java
  3. 2 2
      nightFragrance-massage/src/main/java/com/ylx/point/domain/PointUserActivityTaskCompletion.java
  4. 4 3
      nightFragrance-massage/src/main/java/com/ylx/point/domain/PointUserLog.java
  5. 1 1
      nightFragrance-massage/src/main/java/com/ylx/point/domain/PointUserSignLog.java
  6. 1 1
      nightFragrance-massage/src/main/java/com/ylx/point/domain/PointUserSignStatus.java
  7. 23 0
      nightFragrance-massage/src/main/java/com/ylx/point/domain/dto/UserPointActivityPageDTO.java
  8. 21 0
      nightFragrance-massage/src/main/java/com/ylx/point/domain/dto/UserPointPageDTO.java
  9. 26 0
      nightFragrance-massage/src/main/java/com/ylx/point/domain/vo/UserPointActivityVo.java
  10. 28 0
      nightFragrance-massage/src/main/java/com/ylx/point/domain/vo/UserPointInfoVO.java
  11. 28 0
      nightFragrance-massage/src/main/java/com/ylx/point/domain/vo/UserPointLogVO.java
  12. 8 0
      nightFragrance-massage/src/main/java/com/ylx/point/mapper/PointActivityMapper.java
  13. 3 1
      nightFragrance-massage/src/main/java/com/ylx/point/mapper/PointActivityTaskMapper.java
  14. 6 0
      nightFragrance-massage/src/main/java/com/ylx/point/mapper/PointUserActivityTaskCompletionMapper.java
  15. 21 10
      nightFragrance-massage/src/main/java/com/ylx/point/mapper/PointUserLogMapper.java
  16. 8 4
      nightFragrance-massage/src/main/java/com/ylx/point/service/IPointActivityService.java
  17. 2 0
      nightFragrance-massage/src/main/java/com/ylx/point/service/IPointActivityTaskService.java
  18. 5 0
      nightFragrance-massage/src/main/java/com/ylx/point/service/IPointUserActivityTaskCompletionService.java
  19. 8 0
      nightFragrance-massage/src/main/java/com/ylx/point/service/IPointUserLogService.java
  20. 128 4
      nightFragrance-massage/src/main/java/com/ylx/point/service/impl/PointActivityServiceImpl.java
  21. 8 2
      nightFragrance-massage/src/main/java/com/ylx/point/service/impl/PointActivityTaskServiceImpl.java
  22. 16 1
      nightFragrance-massage/src/main/java/com/ylx/point/service/impl/PointUserActivityTaskCompletionServiceImpl.java
  23. 94 2
      nightFragrance-massage/src/main/java/com/ylx/point/service/impl/PointUserLogServiceImpl.java
  24. 29 0
      nightFragrance-massage/src/main/resources/mapper/point/PointActivityMapper.xml
  25. 10 0
      nightFragrance-massage/src/main/resources/mapper/point/PointActivityTaskMapper.xml
  26. 20 0
      nightFragrance-massage/src/main/resources/mapper/point/PointUserActivityTaskCompletionMapper.xml
  27. 17 0
      nightFragrance-massage/src/main/resources/mapper/point/PointUserLogMapper.xml

+ 1 - 1
nightFragrance-admin/src/main/java/com/ylx/web/controller/point/PointActivityController.java

@@ -43,7 +43,7 @@ public class PointActivityController extends BaseController {
     @PreAuthorize("@ss.hasPermi('point:activity:list')")
     @ApiOperation("根据条件分页查询积分活动")
     @GetMapping("/page")
-    public TableDataInfo page(PointActivityPageDTO dto) {
+    public TableDataInfo page(@Validated @RequestBody PointActivityPageDTO dto) {
         startPage();
         List<PointActivityPageVo> list = this.pointActivityService.list(dto);
         return getDataTable(list);

+ 70 - 0
nightFragrance-admin/src/main/java/com/ylx/web/controller/point/UserPointController.java

@@ -0,0 +1,70 @@
+package com.ylx.web.controller.point;
+
+import com.ylx.common.core.controller.BaseController;
+import com.ylx.common.core.domain.R;
+import com.ylx.common.core.page.TableDataInfo;
+import com.ylx.point.domain.dto.UserPointActivityPageDTO;
+import com.ylx.point.domain.dto.UserPointPageDTO;
+import com.ylx.point.domain.vo.PointActivityPageVo;
+import com.ylx.point.domain.vo.UserPointActivityVo;
+import com.ylx.point.domain.vo.UserPointInfoVO;
+import com.ylx.point.domain.vo.UserPointLogVO;
+import com.ylx.point.service.IPointActivityService;
+import com.ylx.point.service.IPointUserLogService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import javax.annotation.Resource;
+import java.util.ArrayList;
+import java.util.List;
+
+@RestController
+@RequestMapping("/user/point")
+@Api(tags = {"用户积分"})
+public class UserPointController extends BaseController {
+
+    @Resource
+    private IPointUserLogService pointUserLogService;
+    @Resource
+    private IPointActivityService pointActivityService;
+
+    @PreAuthorize("@ss.hasPermi('user:point:query')")
+    @ApiOperation("获取当前用户的积分信息")
+    @GetMapping
+    public R<UserPointInfoVO> getUserPointInfo() {
+        UserPointInfoVO vo = this.pointUserLogService.getUserPointInfo();
+        return R.ok(vo);
+    }
+
+    @PreAuthorize("@ss.hasPermi('user:point:query')")
+    @ApiOperation("获取当前用户的积分信息分页数据")
+    @GetMapping("/page")
+    public TableDataInfo page(@Validated @RequestBody UserPointPageDTO dto) {
+        startPage();
+        List<UserPointLogVO> list = pointUserLogService.getUserPointLogList(dto);
+        return getDataTable(list);
+    }
+
+    @PreAuthorize("@ss.hasPermi('user:point:query')")
+    @ApiOperation("获取当前用户活动任务分页数据")
+    @GetMapping("/activity/page")
+    public TableDataInfo activityPage(@Validated @RequestBody UserPointActivityPageDTO dto) {
+        startPage();
+        List<UserPointActivityVo> list = pointActivityService.getUserPointActivityList(dto);
+        return getDataTable(list);
+    }
+
+    @PreAuthorize("@ss.hasPermi('user:point:query')")
+    @ApiOperation("获取当前用户做任务赚积分集合")
+    @GetMapping("/activity/list")
+    public R<List<UserPointActivityVo>> activityList() {
+        List<UserPointActivityVo> list = pointActivityService.activityList();
+        return R.ok(list);
+    }
+
+
+}

+ 2 - 2
nightFragrance-massage/src/main/java/com/ylx/point/domain/PointUserActivityTaskCompletion.java

@@ -48,13 +48,13 @@ public class PointUserActivityTaskCompletion extends BaseEntity {
      * 用户ID
      */
     @Excel(name = "用户ID")
-    private Long userId;
+    private String userId;
 
     /**
      * 该任务已完成次数
      */
     @Excel(name = "该任务已完成次数")
-    private Long completedCount;
+    private Integer completedCount;
 
     /**
      * 最后完成时间

+ 4 - 3
nightFragrance-massage/src/main/java/com/ylx/point/domain/PointUserLog.java

@@ -1,5 +1,6 @@
 package com.ylx.point.domain;
 
+import java.math.BigDecimal;
 import java.util.Date;
 
 import com.fasterxml.jackson.annotation.JsonFormat;
@@ -30,7 +31,7 @@ public class PointUserLog extends BaseEntity {
      * 用户ID
      */
     @Excel(name = "用户ID")
-    private Long userId;
+    private String userId;
 
     /**
      * 活动ID
@@ -60,13 +61,13 @@ public class PointUserLog extends BaseEntity {
      * 变动值 (+获得, -消费, -过期)
      */
     @Excel(name = "变动值 (+获得, -消费, -过期)")
-    private Long points;
+    private BigDecimal points;
 
     /**
      * 变动后总余额 (快照)
      */
     @Excel(name = "变动后总余额 (快照)")
-    private Long balanceAfter;
+    private BigDecimal balanceAfter;
 
     /**
      * 关联ID: 消耗/过期记录指向被扣减的"获得记录ID"

+ 1 - 1
nightFragrance-massage/src/main/java/com/ylx/point/domain/PointUserSignLog.java

@@ -30,7 +30,7 @@ public class PointUserSignLog extends BaseEntity {
      * 用户ID
      */
     @Excel(name = "用户ID")
-    private Long userId;
+    private String userId;
 
     /**
      * 签到活动ID(对应point_activity.id)

+ 1 - 1
nightFragrance-massage/src/main/java/com/ylx/point/domain/PointUserSignStatus.java

@@ -28,7 +28,7 @@ public class PointUserSignStatus extends BaseEntity {
      * $column.columnComment
      */
     @Excel(name = "${comment}", readConverterExp = "$column.readConverterExp()")
-    private Long userId;
+    private String userId;
 
     /**
      * $column.columnComment

+ 23 - 0
nightFragrance-massage/src/main/java/com/ylx/point/domain/dto/UserPointActivityPageDTO.java

@@ -0,0 +1,23 @@
+package com.ylx.point.domain.dto;
+
+import com.ylx.common.core.domain.BaseEntity;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import javax.validation.constraints.NotNull;
+
+@Data
+@ApiModel("当前用户的积分活动分页查询DTO")
+public class UserPointActivityPageDTO extends BaseEntity {
+
+    @ApiModelProperty("活动类型:1-新手活动 2-每日活动 3-每月活动")
+    @NotNull(message = "活动类型不能为空")
+    private Integer type;
+
+
+    @ApiModelProperty(name = "用户ID", hidden = true)
+    private String userId;
+
+}
+

+ 21 - 0
nightFragrance-massage/src/main/java/com/ylx/point/domain/dto/UserPointPageDTO.java

@@ -0,0 +1,21 @@
+package com.ylx.point.domain.dto;
+
+import com.ylx.common.core.domain.BaseEntity;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import javax.validation.constraints.NotNull;
+
+@Data
+@ApiModel("当前用户的积分信息分页查询DTO")
+public class UserPointPageDTO extends BaseEntity {
+
+    @ApiModelProperty("操作类型:1-收入 2-支出 3-过期 ")
+    @NotNull(message = "操作类型不能为空")
+    private Integer opType;
+
+
+    @ApiModelProperty(name = "用户ID", hidden = true)
+    private String userId;
+}

+ 26 - 0
nightFragrance-massage/src/main/java/com/ylx/point/domain/vo/UserPointActivityVo.java

@@ -0,0 +1,26 @@
+package com.ylx.point.domain.vo;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+@Data
+@ApiModel("用户活动任务信息")
+public class UserPointActivityVo {
+
+    @ApiModelProperty("关联活动ID")
+    private Long activityId;
+
+    @ApiModelProperty("任务名称")
+    private String taskName;
+
+    @ApiModelProperty("奖励积分数")
+    private Long rewardPoints;
+
+    @ApiModelProperty("用户完成次数")
+    private String completedCount;
+
+    @ApiModelProperty("任务触发条件")
+    private String triggerValue;
+
+}

+ 28 - 0
nightFragrance-massage/src/main/java/com/ylx/point/domain/vo/UserPointInfoVO.java

@@ -0,0 +1,28 @@
+package com.ylx.point.domain.vo;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.math.BigDecimal;
+
+@Data
+@ApiModel("用户积分信息")
+public class UserPointInfoVO {
+
+    @ApiModelProperty("总积分")
+    private BigDecimal totalPoints;
+
+    @ApiModelProperty("本月即将到期积分")
+    private BigDecimal expirePoints;
+
+    @ApiModelProperty("本月新获取积分")
+    private BigDecimal earnedPoints;
+
+    @ApiModelProperty("已完成的任务")
+    private Integer completedTask;
+
+    @ApiModelProperty("待完成任务")
+    private Integer pendingTasks;
+
+}

+ 28 - 0
nightFragrance-massage/src/main/java/com/ylx/point/domain/vo/UserPointLogVO.java

@@ -0,0 +1,28 @@
+package com.ylx.point.domain.vo;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.math.BigDecimal;
+import java.util.Date;
+
+@Data
+@ApiModel("用户积分列表信息")
+public class UserPointLogVO {
+
+    @ApiModelProperty("活动名称")
+    private String activityName;
+
+    @ApiModelProperty("变动值")
+    private BigDecimal points;
+
+    @ApiModelProperty("1-收入 2-支出 3-过期")
+    private Integer opType;
+
+    @ApiModelProperty("变动时间")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private Date createTime;
+
+}

+ 8 - 0
nightFragrance-massage/src/main/java/com/ylx/point/mapper/PointActivityMapper.java

@@ -3,8 +3,11 @@ package com.ylx.point.mapper;
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import com.ylx.point.domain.PointActivity;
 import com.ylx.point.domain.dto.PointActivityPageDTO;
+import com.ylx.point.domain.dto.UserPointActivityPageDTO;
 import com.ylx.point.domain.vo.PointActivityPageVo;
 import com.ylx.point.domain.vo.PointActivityTaskDetailVO;
+import com.ylx.point.domain.vo.UserPointActivityVo;
+import org.apache.ibatis.annotations.Param;
 
 import java.util.List;
 
@@ -31,4 +34,9 @@ public interface PointActivityMapper extends BaseMapper<PointActivity> {
     List<PointActivityPageVo> list(PointActivityPageDTO dto);
 
     List<PointActivityTaskDetailVO> getTaskDetailListById(Long id);
+
+    Integer selectTotalActiveTasks(String cityCode);
+
+    List<UserPointActivityVo> selectTaskWithProgress(UserPointActivityPageDTO dto);
+
 }

+ 3 - 1
nightFragrance-massage/src/main/java/com/ylx/point/mapper/PointActivityTaskMapper.java

@@ -19,8 +19,10 @@ public interface PointActivityTaskMapper extends BaseMapper<PointActivityTask> {
     void insertPointActivityTask(PointActivityTask pointActivityTask);
 
     void batchInsertPointActivityTask(@Param("list") List<PointActivityTask> activityTasks);
-    
+
     List<PointActivityTask> selectPointActivityTaskByActivityId(@Param("activityId") Long activityId);
 
     int deletePointActivityTaskByActivityId(Long activityId);
+
+    List<PointActivityTask> selectTasksByActivityType(@Param("activityId") Integer activityType);
 }

+ 6 - 0
nightFragrance-massage/src/main/java/com/ylx/point/mapper/PointUserActivityTaskCompletionMapper.java

@@ -3,6 +3,7 @@ package com.ylx.point.mapper;
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import com.ylx.point.domain.PointUserActivityTaskCompletion;
 import com.ylx.point.domain.vo.PointActivityOverviewVO;
+import org.apache.ibatis.annotations.Param;
 
 import java.util.List;
 
@@ -15,4 +16,9 @@ import java.util.List;
 public interface PointUserActivityTaskCompletionMapper extends BaseMapper<PointUserActivityTaskCompletion> {
 
     PointActivityOverviewVO getPointActivityOverviewByActivityId(Long activityId);
+
+    Integer selectCompletedTaskCount(String userId);
+
+    List<PointUserActivityTaskCompletion> selectCompletionsByUserAndTaskIds(@Param("userId") String userId, @Param("taskIds") List<Long> taskIds);
+
 }

+ 21 - 10
nightFragrance-massage/src/main/java/com/ylx/point/mapper/PointUserLogMapper.java

@@ -2,8 +2,13 @@ package com.ylx.point.mapper;
 
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import com.ylx.point.domain.PointUserLog;
+import com.ylx.point.domain.dto.UserPointPageDTO;
+import com.ylx.point.domain.vo.UserPointLogVO;
+import org.apache.ibatis.annotations.Param;
+import org.apache.ibatis.annotations.Select;
 
 import java.util.List;
+import java.util.Map;
 
 /**
  * 用户积分流水Mapper接口
@@ -13,15 +18,21 @@ import java.util.List;
  */
 public interface PointUserLogMapper extends BaseMapper<PointUserLog> {
 
-    public PointUserLog selectPointUserLogById(String id);
+    @Select("<script>" +
+            "SELECT " +
+            "   COALESCE(SUM(CASE WHEN op_type = 1 THEN points ELSE 0 END) - " +
+            "            SUM(CASE WHEN op_type IN (2, 3) THEN points ELSE 0 END), 0) AS totalPoints, " +
+            "   COALESCE(SUM(CASE WHEN month = #{currentMonth} AND op_type = 1 THEN points ELSE 0 END), 0) AS earnedPoints, " +
+            "   COALESCE(SUM(CASE WHEN is_expired = 0 AND expire_time &gt;= #{startOfThisMonth} AND expire_time &lt;= #{endOfThisMonth} THEN points ELSE 0 END), 0) AS expirePoints " +
+            "FROM point_user_log " +
+            "WHERE user_id = #{userId} " +
+            "</script>")
+    Map<String, Object> selectPointStatistics(
+            @Param("userId") String userId,
+            @Param("currentMonth") String currentMonth,
+            @Param("startOfThisMonth") String startOfThisMonth,
+            @Param("endOfThisMonth") String endOfThisMonth);
+
+    List<UserPointLogVO> getUserPointLogList(UserPointPageDTO dto);
 
-    public List<PointUserLog> selectPointUserLogList(PointUserLog pointUserLog);
-
-    public int insertPointUserLog(PointUserLog pointUserLog);
-
-    public int updatePointUserLog(PointUserLog pointUserLog);
-
-    public int deletePointUserLogById(String id);
-
-    public int deletePointUserLogByIds(String[] ids);
 }

+ 8 - 4
nightFragrance-massage/src/main/java/com/ylx/point/service/IPointActivityService.java

@@ -5,10 +5,8 @@ import com.ylx.point.domain.PointActivity;
 import com.ylx.point.domain.dto.PointActivityDTO;
 import com.ylx.point.domain.dto.PointActivityPageDTO;
 import com.ylx.point.domain.dto.PointActivityValidityDTO;
-import com.ylx.point.domain.vo.PointActivityDetailsVo;
-import com.ylx.point.domain.vo.PointActivityPageVo;
-import com.ylx.point.domain.vo.PointActivityStatVo;
-import com.ylx.point.domain.vo.PointActivityValidityVo;
+import com.ylx.point.domain.dto.UserPointActivityPageDTO;
+import com.ylx.point.domain.vo.*;
 
 import java.util.List;
 
@@ -33,4 +31,10 @@ public interface IPointActivityService extends IService<PointActivity> {
     void editValidity(PointActivityValidityDTO dto);
 
     List<PointActivityValidityVo> validityDetails();
+
+    Integer selectTotalActiveTasks(String cityCode);
+
+    List<UserPointActivityVo> getUserPointActivityList(UserPointActivityPageDTO dto);
+
+    List<UserPointActivityVo> activityList();
 }

+ 2 - 0
nightFragrance-massage/src/main/java/com/ylx/point/service/IPointActivityTaskService.java

@@ -19,4 +19,6 @@ public interface IPointActivityTaskService extends IService<PointActivityTask> {
     void batchInsertPointActivityTask(List<PointActivityTask> activityTasks);
 
     void deletePointActivityTaskByActivityId(Long activityId);
+
+    List<PointActivityTask> selectTasksByActivityType(Integer activityType);
 }

+ 5 - 0
nightFragrance-massage/src/main/java/com/ylx/point/service/IPointUserActivityTaskCompletionService.java

@@ -4,6 +4,8 @@ import com.baomidou.mybatisplus.extension.service.IService;
 import com.ylx.point.domain.PointUserActivityTaskCompletion;
 import com.ylx.point.domain.vo.PointActivityOverviewVO;
 
+import java.util.List;
+
 /**
  * 用户活动任务完成Service接口
  *
@@ -14,4 +16,7 @@ public interface IPointUserActivityTaskCompletionService extends IService<PointU
 
     PointActivityOverviewVO getPointActivityOverviewByActivityId(Long activityId);
 
+    Integer selectCompletedTaskCount(String userId);
+
+    List<PointUserActivityTaskCompletion> selectCompletionsByUserAndTaskIds(String userId, List<Long> taskIds);
 }

+ 8 - 0
nightFragrance-massage/src/main/java/com/ylx/point/service/IPointUserLogService.java

@@ -2,6 +2,11 @@ package com.ylx.point.service;
 
 import com.baomidou.mybatisplus.extension.service.IService;
 import com.ylx.point.domain.PointUserLog;
+import com.ylx.point.domain.dto.UserPointPageDTO;
+import com.ylx.point.domain.vo.UserPointInfoVO;
+import com.ylx.point.domain.vo.UserPointLogVO;
+
+import java.util.List;
 
 /**
  * 用户积分流水Service接口
@@ -11,4 +16,7 @@ import com.ylx.point.domain.PointUserLog;
  */
 public interface IPointUserLogService extends IService<PointUserLog> {
 
+    UserPointInfoVO getUserPointInfo();
+
+    List<UserPointLogVO> getUserPointLogList(UserPointPageDTO dto);
 }

+ 128 - 4
nightFragrance-massage/src/main/java/com/ylx/point/service/impl/PointActivityServiceImpl.java

@@ -6,9 +6,12 @@ import cn.hutool.core.date.DateUtil;
 import cn.hutool.core.util.ObjectUtil;
 import cn.hutool.core.util.StrUtil;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.ylx.common.core.domain.model.WxLoginUser;
 import com.ylx.common.exception.base.BaseException;
 import com.ylx.common.utils.DateUtils;
 import com.ylx.common.utils.SecurityUtils;
+import com.ylx.massage.domain.TWxUser;
+import com.ylx.massage.service.TWxUserService;
 import com.ylx.point.domain.*;
 import com.ylx.point.domain.dto.*;
 import com.ylx.point.domain.vo.*;
@@ -23,11 +26,10 @@ import org.springframework.transaction.annotation.Transactional;
 
 import javax.annotation.Resource;
 import java.time.DateTimeException;
+import java.time.LocalDate;
 import java.time.LocalDateTime;
 import java.time.ZoneId;
-import java.util.Collections;
-import java.util.Date;
-import java.util.List;
+import java.util.*;
 import java.util.stream.Collectors;
 
 
@@ -52,15 +54,24 @@ public class PointActivityServiceImpl extends ServiceImpl<PointActivityMapper, P
     private IPointUserActivityTaskCompletionService pointUserActivityTaskCompletionService;
     @Autowired
     private IPointActivityExpirePolicyService pointActivityExpirePolicyService;
+    @Resource
+    private TWxUserService wxUserService;
 
     private static final int BATCH_SIZE = 1000;
 
-    private static final String INVALID_ARGUMENT_MESSAGE = "参数不能为空";
+    private static final int TARGET_COUNT = 2;
+
     private static final String INVALID_EXPIRE_POLICY_TYPE_MESSAGE = "无效的过期策略类型";
     private static final String EXPIRE_DAYS_REQUIRED_MESSAGE = "过期天数不能为空";
     private static final String EXPIRE_YEAR_REQUIRED_MESSAGE = "过期年数不能为空";
     private static final String UPDATE_FAILED_MESSAGE = "更新积分活动过期策略失败";
 
+    // 优先级顺序
+    private static final List<Integer> PRIORITY_TYPES = Arrays.asList(
+            PointActivityTypeEnum.NEW_USER_ACTIVITY.getCode(),
+            PointActivityTypeEnum.DAILY_ACTIVITY.getCode(),
+            PointActivityTypeEnum.MONTHLY_ACTIVITY.getCode()); // 新手, 每日, 每月
+
 
     @Override
     public List<PointActivityPageVo> list(PointActivityPageDTO dto) {
@@ -211,6 +222,119 @@ public class PointActivityServiceImpl extends ServiceImpl<PointActivityMapper, P
         }
     }
 
+    @Override
+    public Integer selectTotalActiveTasks(String cityCode) {
+        return pointActivityMapper.selectTotalActiveTasks(cityCode);
+    }
+
+    @Override
+    public List<UserPointActivityVo> getUserPointActivityList(UserPointActivityPageDTO dto) {
+
+        // 当前登录用户信息
+        WxLoginUser wxLoginUser = SecurityUtils.getWxLoginUser();
+        TWxUser user = wxUserService.getByOpenId(wxLoginUser.getCOpenid());
+        if (user == null) {
+            throw new RuntimeException("用户不存在");
+        }
+
+        String userId = user.getId();
+        dto.setUserId(userId);
+        return pointActivityMapper.selectTaskWithProgress(dto);
+    }
+
+    @Override
+    public List<UserPointActivityVo> activityList() {
+
+        // 当前登录用户信息
+        WxLoginUser wxLoginUser = SecurityUtils.getWxLoginUser();
+        TWxUser user = wxUserService.getByOpenId(wxLoginUser.getCOpenid());
+        if (user == null) {
+            throw new RuntimeException("用户不存在");
+        }
+
+        String userId = user.getId();
+
+        List<UserPointActivityVo> resultList = new ArrayList<>();
+
+        // 2. 按优先级遍历活动类型
+        for (Integer activityType : PRIORITY_TYPES) {
+            if (resultList.size() >= TARGET_COUNT) {
+                break;
+            }
+
+            // 3. 查询该类型下 进行中 的任务
+            List<PointActivityTask> taskList = pointActivityTaskService.selectTasksByActivityType(activityType);
+            if (CollectionUtil.isEmpty(taskList)) {
+                continue;
+            }
+
+            // 4. 批量查询用户完成记录
+            List<Long> taskIds = taskList.stream().map(PointActivityTask::getId).collect(Collectors.toList());
+            List<PointUserActivityTaskCompletion> completionList =
+                    pointUserActivityTaskCompletionService.selectCompletionsByUserAndTaskIds(userId, taskIds);
+
+            Map<Long, PointUserActivityTaskCompletion> completionMap = completionList.stream()
+                    .collect(Collectors.toMap(PointUserActivityTaskCompletion::getTaskId, c -> c));
+
+            // 5. 筛选【未完成】的任务
+            for (PointActivityTask task : taskList) {
+                if (resultList.size() >= TARGET_COUNT) break;
+
+                PointUserActivityTaskCompletion completion = completionMap.get(task.getId());
+                if (isTaskIncomplete(task, completion)) {
+                    resultList.add(convertToVo(task, completion));
+                }
+            }
+        }
+
+        return resultList.stream().limit(2).collect(Collectors.toList());
+
+    }
+
+    /**
+     * 判断任务是否未完成
+     */
+    private boolean isTaskIncomplete(PointActivityTask task, PointUserActivityTaskCompletion completion) {
+
+        // 1. 获取规则要求的次数
+        int requiredCount = 0;
+        try {
+            requiredCount = Integer.parseInt(task.getTriggerValue());
+        } catch (NumberFormatException e) {
+            // 如果配置错误,为了安全起见,默认视为未完成(或根据业务抛出异常)
+            return true;
+        }
+
+        // 2. 获取用户实际完成的次数
+        int actualCount = 0;
+        if (ObjectUtil.isNotNull(completion) && ObjectUtil.isNotNull(completion.getCompletedCount())) {
+            actualCount = completion.getCompletedCount();
+        }
+
+        // 3. 核心判断逻辑
+        // 如果 实际次数 < 要求次数,则任务“未完成” (返回 true)
+        return actualCount < requiredCount;
+    }
+
+    /**
+     * 组装 VO 对象
+     */
+    private UserPointActivityVo convertToVo(PointActivityTask task, PointUserActivityTaskCompletion completion) {
+        UserPointActivityVo vo = new UserPointActivityVo();
+
+        vo.setActivityId(task.getActivityId());
+        vo.setTaskName(task.getTaskName()); // 或者是从字典表查出的中文名称
+        vo.setRewardPoints(task.getRewardPoints());
+
+        // 完成次数:如果没有记录则为 "0"
+        vo.setCompletedCount(completion != null ? String.valueOf(completion.getCompletedCount()) : "0");
+
+        // 触发条件:直接从任务配置中获取,或者根据 taskCode 查字典
+        vo.setTriggerValue(task.getTriggerValue());
+
+        return vo;
+    }
+
     private PointActivityValidityVo convertToVo(PointActivityExpirePolicy policy) {
         PointActivityValidityVo vo = new PointActivityValidityVo();
         BeanUtil.copyProperties(policy, vo);

+ 8 - 2
nightFragrance-massage/src/main/java/com/ylx/point/service/impl/PointActivityTaskServiceImpl.java

@@ -7,10 +7,11 @@ import com.ylx.point.domain.PointActivityTask;
 import com.ylx.point.domain.dto.PointActivityTaskDTO;
 import com.ylx.point.mapper.PointActivityTaskMapper;
 import com.ylx.point.service.IPointActivityTaskService;
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
+import javax.annotation.Resource;
+import java.util.Collections;
 import java.util.List;
 
 
@@ -22,7 +23,7 @@ import java.util.List;
  */
 @Service
 public class PointActivityTaskServiceImpl extends ServiceImpl<PointActivityTaskMapper,PointActivityTask> implements IPointActivityTaskService {
-    @Autowired
+    @Resource
     private PointActivityTaskMapper pointActivityTaskMapper;
 
     @Override
@@ -59,4 +60,9 @@ public class PointActivityTaskServiceImpl extends ServiceImpl<PointActivityTaskM
         pointActivityTaskMapper.deletePointActivityTaskByActivityId(activityId);
     }
 
+    @Override
+    public List<PointActivityTask> selectTasksByActivityType(Integer activityType) {
+        return pointActivityTaskMapper.selectTasksByActivityType(activityType);
+    }
+
 }

+ 16 - 1
nightFragrance-massage/src/main/java/com/ylx/point/service/impl/PointUserActivityTaskCompletionServiceImpl.java

@@ -8,6 +8,10 @@ import com.ylx.point.service.IPointUserActivityTaskCompletionService;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
+import javax.annotation.Resource;
+import java.util.Collections;
+import java.util.List;
+
 /**
  * 用户活动任务完成Service业务层处理
  *
@@ -16,11 +20,22 @@ import org.springframework.stereotype.Service;
  */
 @Service
 public class PointUserActivityTaskCompletionServiceImpl extends ServiceImpl<PointUserActivityTaskCompletionMapper, PointUserActivityTaskCompletion> implements IPointUserActivityTaskCompletionService {
-    @Autowired
+
+    @Resource
     private PointUserActivityTaskCompletionMapper pointUserActivityTaskCompletionMapper;
 
     @Override
     public PointActivityOverviewVO getPointActivityOverviewByActivityId(Long activityId) {
         return pointUserActivityTaskCompletionMapper.getPointActivityOverviewByActivityId(activityId);
     }
+
+    @Override
+    public Integer selectCompletedTaskCount(String userId) {
+        return pointUserActivityTaskCompletionMapper.selectCompletedTaskCount(userId);
+    }
+
+    @Override
+    public List<PointUserActivityTaskCompletion> selectCompletionsByUserAndTaskIds(String userId, List<Long> taskIds) {
+        return pointUserActivityTaskCompletionMapper.selectCompletionsByUserAndTaskIds(userId, taskIds);
+    }
 }

+ 94 - 2
nightFragrance-massage/src/main/java/com/ylx/point/service/impl/PointUserLogServiceImpl.java

@@ -1,12 +1,27 @@
 package com.ylx.point.service.impl;
 
+import cn.hutool.core.date.DateUtil;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.ylx.common.core.domain.model.WxLoginUser;
+import com.ylx.common.utils.SecurityUtils;
+import com.ylx.massage.domain.TWxUser;
+import com.ylx.massage.service.TWxUserService;
 import com.ylx.point.domain.PointUserLog;
+import com.ylx.point.domain.dto.UserPointPageDTO;
+import com.ylx.point.domain.vo.UserPointInfoVO;
+import com.ylx.point.domain.vo.UserPointLogVO;
 import com.ylx.point.mapper.PointUserLogMapper;
+import com.ylx.point.service.IPointActivityService;
+import com.ylx.point.service.IPointUserActivityTaskCompletionService;
 import com.ylx.point.service.IPointUserLogService;
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
+import javax.annotation.Resource;
+import java.math.BigDecimal;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
 /**
  * 用户积分流水Service业务层处理
  *
@@ -15,7 +30,84 @@ import org.springframework.stereotype.Service;
  */
 @Service
 public class PointUserLogServiceImpl extends ServiceImpl<PointUserLogMapper, PointUserLog> implements IPointUserLogService {
-    @Autowired
+
+    @Resource
     private PointUserLogMapper pointUserLogMapper;
+    @Resource
+    private TWxUserService wxUserService;
+    @Resource
+    private IPointUserActivityTaskCompletionService pointUserActivityTaskCompletionService;
+    @Resource
+    private IPointActivityService pointActivityService;
+
+    @Override
+    public UserPointInfoVO getUserPointInfo() {
+
+        // 当前登录用户信息
+        WxLoginUser wxLoginUser = SecurityUtils.getWxLoginUser();
+        TWxUser user = wxUserService.getByOpenId(wxLoginUser.getCOpenid());
+        if (user == null) {
+            throw new RuntimeException("用户不存在");
+        }
+
+        String userId = user.getId();
+
+        // TODO 用户当前所在地区code
+        String cityCode = "140400";
+
+        UserPointInfoVO vo = new UserPointInfoVO();
+
+        // 1. 准备时间参数
+        String currentMonth = DateUtil.format(DateUtil.date(), "yyyyMM");
+        // 本月第一天 00:00:00
+        String startOfThisMonth = DateUtil.beginOfMonth(DateUtil.date()).toString();
+        // 本月最后一天 23:59:59
+        String endOfThisMonth = DateUtil.endOfMonth(DateUtil.date()).toString();
+        // 2. 查询积分相关数据 (Total, Earned, Expire)
+
+        // A. 查询积分统计 (Total, Earned, Expire)
+        Map<String, Object> pointStats = pointUserLogMapper.selectPointStatistics(userId, currentMonth, startOfThisMonth, endOfThisMonth);
+
+        // B. 查询已完成任务数
+        Integer completedCount = pointUserActivityTaskCompletionService.selectCompletedTaskCount(userId);
+
+        // C. 查询系统总任务数
+        Integer totalTasks = pointActivityService.selectTotalActiveTasks(cityCode);
+
+        if (pointStats != null) {
+            // 数据库返回的是 BigInteger 或 Long,需要转为 BigDecimal
+            vo.setTotalPoints(new BigDecimal(pointStats.get("totalPoints").toString()));
+            vo.setEarnedPoints(new BigDecimal(pointStats.get("earnedPoints").toString()));
+            vo.setExpirePoints(new BigDecimal(pointStats.get("expirePoints").toString()));
+        } else {
+            vo.setTotalPoints(BigDecimal.ZERO);
+            vo.setEarnedPoints(BigDecimal.ZERO);
+            vo.setExpirePoints(BigDecimal.ZERO);
+        }
+
+        // 任务数据
+        int completed = (completedCount != null) ? completedCount : 0;
+        vo.setCompletedTask(completed);
+
+        int pending = (totalTasks != null ? totalTasks : 0) - completed;
+        vo.setPendingTasks(Math.max(pending, 0)); // 防止出现负数
+
+        return vo;
+    }
+
+    @Override
+    public List<UserPointLogVO> getUserPointLogList(UserPointPageDTO dto) {
+
+        // 当前登录用户信息
+        WxLoginUser wxLoginUser = SecurityUtils.getWxLoginUser();
+        TWxUser user = wxUserService.getByOpenId(wxLoginUser.getCOpenid());
+        if (user == null) {
+            throw new RuntimeException("用户不存在");
+        }
+
+        String userId = user.getId();
+        dto.setUserId(userId);
+        return pointUserLogMapper.getUserPointLogList(dto);
+    }
 
 }

+ 29 - 0
nightFragrance-massage/src/main/resources/mapper/point/PointActivityMapper.xml

@@ -84,6 +84,35 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         ORDER BY pat.sort_order
     </select>
 
+    <select id="selectTotalActiveTasks" resultType="java.lang.Integer">
+        SELECT
+            COUNT(*)
+        FROM
+            point_activity
+        WHERE
+            STATUS IN ( 1, 4 )
+        AND ( city_code = '0' OR city_code = #{cityCode} )
+        AND (start_time IS NULL OR start_time &lt;= NOW()) AND ( end_time IS NULL OR end_time &gt;= NOW())
+    </select>
+
+    <select id="selectTaskWithProgress" parameterType="UserPointActivityPageDTO" resultType="com.ylx.point.domain.vo.UserPointActivityVo">
+        SELECT
+            t.id activityId,
+            t.task_name,
+            t.reward_points,
+            t.trigger_value,
+            COALESCE(c.completed_count, 0) AS completed_count
+        FROM point_activity_task t
+        LEFT JOIN point_user_activity_task_completion c ON t.id = c.task_id AND c.user_id = #{userId}
+        JOIN point_activity a ON t.activity_id = a.id
+        WHERE t.is_deleted = 0 AND t.status = 0
+          AND a.activity_type = #{type}
+          AND a.status = 1
+        ORDER BY t.sort_order ASC
+        <!-- 数据范围过滤 -->
+        ${params.dataScope}
+    </select>
+
     <insert id="insertPointActivity" parameterType="PointActivity" useGeneratedKeys="true" keyProperty="id">
         insert into point_activity
         <trim prefix="(" suffix=")" suffixOverrides=",">

+ 10 - 0
nightFragrance-massage/src/main/resources/mapper/point/PointActivityTaskMapper.xml

@@ -121,4 +121,14 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         order by sort_order
     </select>
 
+    <select id="selectTasksByActivityType" resultType="com.ylx.point.domain.PointActivityTask">
+        <include refid="selectPointActivityTaskVo"/>
+        WHERE
+            activity_id = #{activityType}
+        AND status = 1
+        ORDER BY
+            sort_order ASC,         -- 按排序字段正序排列
+            id ASC                  -- 二级排序,保证顺序稳定
+    </select>
+
 </mapper>

+ 20 - 0
nightFragrance-massage/src/main/resources/mapper/point/PointUserActivityTaskCompletionMapper.xml

@@ -16,6 +16,11 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         <result property="updateTime"    column="update_time"    />
         <result property="completedDate"    column="completed_date"    />
     </resultMap>
+
+    <sql id="selectPointUserActivityTaskCompletionVo">
+        select id, activity_id, task_id, task_type, user_id, completed_count, last_completed_time, create_time, update_time, completed_date from point_user_activity_task_completion
+    </sql>
+
     <select id="getPointActivityOverviewByActivityId"
             resultType="com.ylx.point.domain.vo.PointActivityOverviewVO">
         SELECT
@@ -28,4 +33,19 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         WHERE utc.activity_id = #{activityId}
     </select>
 
+    <select id="selectCompletedTaskCount" resultType="java.lang.Integer">
+        SELECT COUNT(*) FROM point_user_activity_task_completion WHERE user_id = #{userId} AND completed_count > 0
+    </select>
+
+    <select id="selectCompletionsByUserAndTaskIds"
+            resultType="com.ylx.point.domain.PointUserActivityTaskCompletion">
+        <include refid="selectPointUserActivityTaskCompletionVo"/>
+        WHERE
+            user_id = #{userId}
+        AND task_id IN
+        <foreach collection="taskIds" item="taskId" open="(" separator="," close=")">
+            #{taskId}
+        </foreach>
+    </select>
+
 </mapper>

+ 17 - 0
nightFragrance-massage/src/main/resources/mapper/point/PointUserLogMapper.xml

@@ -22,4 +22,21 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         <result property="month"    column="month"    />
     </resultMap>
 
+    <select id="getUserPointLogList" parameterType="UserPointPageDTO" resultType="com.ylx.point.domain.vo.UserPointLogVO">
+        SELECT
+            pul.activity_name AS activityName,
+            pul.points AS points,
+            pul.op_type AS opType,
+            pul.create_time AS createTime
+        FROM
+            point_user_log pul
+        WHERE
+            pul.user_id = #{userId}
+        AND pul.op_type = #{opType}
+        ORDER BY
+            pul.create_time DESC
+        <!-- 数据范围过滤 -->
+        ${params.dataScope}
+    </select>
+
 </mapper>