|
|
@@ -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);
|