|
|
@@ -4,7 +4,6 @@ import cn.hutool.core.collection.CollectionUtil;
|
|
|
import cn.hutool.core.date.DateUtil;
|
|
|
import cn.hutool.core.util.ObjectUtil;
|
|
|
import cn.hutool.core.util.StrUtil;
|
|
|
-import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
|
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
|
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
|
|
import com.ylx.common.core.domain.model.WxLoginUser;
|
|
|
@@ -17,7 +16,7 @@ import com.ylx.point.domain.PointActivity;
|
|
|
import com.ylx.point.domain.PointActivityTask;
|
|
|
import com.ylx.point.domain.PointUserActivityTaskCompletion;
|
|
|
import com.ylx.point.domain.vo.PointActivityOverviewVO;
|
|
|
-import com.ylx.point.enums.TaskNameEnum;
|
|
|
+import com.ylx.point.enums.ActivityNameEnum;
|
|
|
import com.ylx.point.enums.PointActivityStatusEnum;
|
|
|
import com.ylx.point.enums.PointActivityTaskTypeEnum;
|
|
|
import com.ylx.point.enums.PointActivityTypeEnum;
|
|
|
@@ -32,13 +31,13 @@ import org.springframework.transaction.annotation.Transactional;
|
|
|
|
|
|
import javax.annotation.Resource;
|
|
|
import java.time.LocalDate;
|
|
|
-import java.util.Arrays;
|
|
|
-import java.util.Date;
|
|
|
-import java.util.List;
|
|
|
+import java.util.*;
|
|
|
+import java.util.function.Function;
|
|
|
import java.util.stream.Collectors;
|
|
|
|
|
|
/**
|
|
|
* 用户活动任务完成Service业务层处理
|
|
|
+ * JDK8 兼容版
|
|
|
*
|
|
|
* @author wzj
|
|
|
* @date 2026-03-25
|
|
|
@@ -60,6 +59,15 @@ public class PointUserActivityTaskCompletionServiceImpl extends ServiceImpl<Poin
|
|
|
@Resource
|
|
|
private IPointAccountService pointAccountService;
|
|
|
|
|
|
+ /**
|
|
|
+ * 活动类型优先级:新手活动 > 每日活动 > 每月活动
|
|
|
+ */
|
|
|
+ private static final List<Integer> ACTIVITY_TYPE_PRIORITY = Arrays.asList(
|
|
|
+ PointActivityTypeEnum.NEW_USER_ACTIVITY.getCode(),
|
|
|
+ PointActivityTypeEnum.DAILY_ACTIVITY.getCode(),
|
|
|
+ PointActivityTypeEnum.MONTHLY_ACTIVITY.getCode()
|
|
|
+ );
|
|
|
+
|
|
|
@Override
|
|
|
public PointActivityOverviewVO getPointActivityOverviewByActivityId(Long activityId) {
|
|
|
return pointUserActivityTaskCompletionMapper.getPointActivityOverviewByActivityId(activityId);
|
|
|
@@ -72,6 +80,9 @@ public class PointUserActivityTaskCompletionServiceImpl extends ServiceImpl<Poin
|
|
|
|
|
|
@Override
|
|
|
public List<PointUserActivityTaskCompletion> selectCompletionsByOpenIdAndTaskIds(String openId, List<Long> taskIds) {
|
|
|
+ if (CollectionUtil.isEmpty(taskIds)) {
|
|
|
+ return Collections.emptyList();
|
|
|
+ }
|
|
|
return pointUserActivityTaskCompletionMapper.selectCompletionsByOpenIdAndTaskIds(openId, taskIds);
|
|
|
}
|
|
|
|
|
|
@@ -85,20 +96,19 @@ public class PointUserActivityTaskCompletionServiceImpl extends ServiceImpl<Poin
|
|
|
.eq(PointUserActivityTaskCompletion::getActivityId, activityId)
|
|
|
.eq(PointUserActivityTaskCompletion::getTaskId, taskId)
|
|
|
.eq(PointUserActivityTaskCompletion::getTaskType, taskType)
|
|
|
- .eq(PointUserActivityTaskCompletion::getCompletedDate, LocalDate.now()) // 生成列,超快
|
|
|
+ .eq(PointUserActivityTaskCompletion::getCompletedDate, LocalDate.now())
|
|
|
);
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
@Transactional(rollbackFor = Exception.class)
|
|
|
public void completeTask(String openId, Long activityId, Long taskId, Integer taskType) {
|
|
|
- // 1. 先查询是否存在记录
|
|
|
- PointUserActivityTaskCompletion completion = pointUserActivityTaskCompletionMapper.selectOne(
|
|
|
- Wrappers.lambdaQuery(PointUserActivityTaskCompletion.class)
|
|
|
- .eq(PointUserActivityTaskCompletion::getOpenId, openId)
|
|
|
- .eq(PointUserActivityTaskCompletion::getActivityId, activityId)
|
|
|
- .eq(PointUserActivityTaskCompletion::getTaskId, taskId)
|
|
|
- .eq(PointUserActivityTaskCompletion::getTaskType, taskType)
|
|
|
+ // 1. 查询是否存在记录
|
|
|
+ PointUserActivityTaskCompletion completion = this.getOne(Wrappers.lambdaQuery(PointUserActivityTaskCompletion.class)
|
|
|
+ .eq(PointUserActivityTaskCompletion::getOpenId, openId)
|
|
|
+ .eq(PointUserActivityTaskCompletion::getActivityId, activityId)
|
|
|
+ .eq(PointUserActivityTaskCompletion::getTaskId, taskId)
|
|
|
+ .eq(PointUserActivityTaskCompletion::getTaskType, taskType)
|
|
|
);
|
|
|
|
|
|
if (ObjectUtil.isNull(completion)) {
|
|
|
@@ -110,26 +120,25 @@ public class PointUserActivityTaskCompletionServiceImpl extends ServiceImpl<Poin
|
|
|
insert.setTaskType(taskType);
|
|
|
insert.setCompletedCount(1);
|
|
|
insert.setLastCompletedTime(DateUtils.getNowDate());
|
|
|
- pointUserActivityTaskCompletionMapper.insert(insert);
|
|
|
+ insert.setCompletedDate(DateUtils.getNowDate());
|
|
|
+ this.save(insert);
|
|
|
} else {
|
|
|
- // 非首次:次数+1(原子更新)
|
|
|
- pointUserActivityTaskCompletionMapper.update(null,
|
|
|
- Wrappers.lambdaUpdate(PointUserActivityTaskCompletion.class)
|
|
|
- .eq(PointUserActivityTaskCompletion::getId, completion.getId())
|
|
|
- .setSql("completed_count = completed_count + 1")
|
|
|
- .set(PointUserActivityTaskCompletion::getLastCompletedTime, DateUtils.getNowDate())
|
|
|
+ // 非首次:原子更新次数+1
|
|
|
+ this.update(Wrappers.lambdaUpdate(PointUserActivityTaskCompletion.class)
|
|
|
+ .eq(PointUserActivityTaskCompletion::getId, completion.getId())
|
|
|
+ .setSql("completed_count = completed_count + 1")
|
|
|
+ .set(PointUserActivityTaskCompletion::getLastCompletedTime, DateUtils.getNowDate())
|
|
|
);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
public int getUserTaskTotalCount(String openId, Long activityId, Long taskId, Integer taskType) {
|
|
|
- PointUserActivityTaskCompletion completion = pointUserActivityTaskCompletionMapper.selectOne(
|
|
|
- Wrappers.lambdaQuery(PointUserActivityTaskCompletion.class)
|
|
|
- .eq(PointUserActivityTaskCompletion::getOpenId, openId)
|
|
|
- .eq(PointUserActivityTaskCompletion::getActivityId, activityId)
|
|
|
- .eq(PointUserActivityTaskCompletion::getTaskId, taskId)
|
|
|
- .eq(PointUserActivityTaskCompletion::getTaskType, taskType)
|
|
|
+ PointUserActivityTaskCompletion completion = this.getOne(Wrappers.lambdaQuery(PointUserActivityTaskCompletion.class)
|
|
|
+ .eq(PointUserActivityTaskCompletion::getOpenId, openId)
|
|
|
+ .eq(PointUserActivityTaskCompletion::getActivityId, activityId)
|
|
|
+ .eq(PointUserActivityTaskCompletion::getTaskId, taskId)
|
|
|
+ .eq(PointUserActivityTaskCompletion::getTaskType, taskType)
|
|
|
);
|
|
|
return completion == null ? 0 : completion.getCompletedCount();
|
|
|
}
|
|
|
@@ -137,168 +146,128 @@ public class PointUserActivityTaskCompletionServiceImpl extends ServiceImpl<Poin
|
|
|
@Override
|
|
|
@Transactional(rollbackFor = Exception.class)
|
|
|
public void executeTask(Long taskId) {
|
|
|
-
|
|
|
- String taskName;
|
|
|
-
|
|
|
- // 1. 获取当前登录用户
|
|
|
+ // 1. 获取登录用户
|
|
|
WxLoginUser loginUser = getCurrentWxLoginUser();
|
|
|
String openId = loginUser.getCOpenid();
|
|
|
|
|
|
- // 2. 获取任务信息
|
|
|
- PointActivityTask task = this.pointActivityTaskService.getById(taskId);
|
|
|
+ // 2. 校验任务
|
|
|
+ PointActivityTask task = pointActivityTaskService.getById(taskId);
|
|
|
if (ObjectUtil.isNull(task)) {
|
|
|
throw new ServiceException("任务不存在");
|
|
|
}
|
|
|
|
|
|
- // 3. 获取活动信息
|
|
|
- PointActivity activity = this.pointActivityService.getById(task.getActivityId());
|
|
|
- if (ObjectUtil.isNull(activity) || !ObjectUtil.equals(activity.getStatus(), PointActivityStatusEnum.IN_PROGRESS.getCode())) {
|
|
|
+ // 3. 校验活动
|
|
|
+ PointActivity activity = pointActivityService.getById(task.getActivityId());
|
|
|
+ if (ObjectUtil.isNull(activity) || !PointActivityStatusEnum.IN_PROGRESS.getCode().equals(activity.getStatus())) {
|
|
|
throw new ServiceException("活动不存在或已结束");
|
|
|
}
|
|
|
|
|
|
Long activityId = activity.getId();
|
|
|
- Integer activityType = activity.getActivityType();
|
|
|
- String isPermanent = activity.getIsPermanent();
|
|
|
- Date activityStartTime = activity.getStartTime();
|
|
|
- String activityName = activity.getName();
|
|
|
-
|
|
|
- PointActivityTypeEnum pointActivityType = PointActivityTypeEnum.valueOf(activityType);
|
|
|
- PointActivityTaskTypeEnum taskType = PointActivityTaskTypeEnum.getByInfo(task.getTaskName());
|
|
|
-
|
|
|
- // 目标次数
|
|
|
+ PointActivityTypeEnum activityTypeEnum = PointActivityTypeEnum.valueOf(activity.getActivityType());
|
|
|
+ PointActivityTaskTypeEnum taskTypeEnum = PointActivityTaskTypeEnum.getByInfo(task.getTaskName());
|
|
|
int targetCount = Integer.parseInt(task.getTriggerValue());
|
|
|
+ boolean isVerified;
|
|
|
+ String taskName;
|
|
|
|
|
|
- boolean isVerified = false;
|
|
|
-
|
|
|
- // --- 逻辑分支开始 ---
|
|
|
-
|
|
|
- // 场景 A: 每日任务/签到 -> 只需要检查今天是否做过
|
|
|
- if (pointActivityType == PointActivityTypeEnum.SIGN_TASK) {
|
|
|
- taskName = TaskNameEnum.USER_SIGN_IN.getInfo();
|
|
|
- boolean completed = this.isTodayCompleted(openId, activityId, taskId, taskType.getCode());
|
|
|
- if (completed) {
|
|
|
- throw new ServiceException("今日任务已完成,请勿重复领取");
|
|
|
+ // 4. 任务校验逻辑
|
|
|
+ if (activityTypeEnum == PointActivityTypeEnum.SIGN_TASK) {
|
|
|
+ // 签到任务:今日未完成才可领取
|
|
|
+ taskName = ActivityNameEnum.USER_SIGN_IN.getInfo();
|
|
|
+ if (isTodayCompleted(openId, activityId, taskId, taskTypeEnum.getCode())) {
|
|
|
+ throw new ServiceException("今日已签到,请勿重复操作");
|
|
|
}
|
|
|
- // 每日任务通常点一下就算完成,或者根据具体业务逻辑判断
|
|
|
isVerified = true;
|
|
|
- } else if (pointActivityType == PointActivityTypeEnum.DAILY_ACTIVITY) {
|
|
|
- // 1. 检查今日是否已完成 (保留核心业务校验)
|
|
|
- boolean completed = this.isTodayCompleted(openId, activityId, taskId, taskType.getCode());
|
|
|
- if (completed) {
|
|
|
+ } else if (activityTypeEnum == PointActivityTypeEnum.DAILY_ACTIVITY) {
|
|
|
+ // 每日任务:今日未完成
|
|
|
+ taskName = getTaskNameByType(taskTypeEnum);
|
|
|
+ if (isTodayCompleted(openId, activityId, taskId, taskTypeEnum.getCode())) {
|
|
|
throw new ServiceException("今日任务已完成,请勿重复领取");
|
|
|
}
|
|
|
-
|
|
|
- // 2. 仅根据任务类型获取名称 (移除所有业务计数逻辑)
|
|
|
- switch (taskType) {
|
|
|
- case COMPLETE_ORDER:
|
|
|
- taskName = TaskNameEnum.COMPLETE_ORDER.getInfo();
|
|
|
- break;
|
|
|
- case RECHARGE_TASK:
|
|
|
- taskName = TaskNameEnum.RECHARGE_TASK.getInfo();
|
|
|
- break;
|
|
|
- case SHARE_SERVICE:
|
|
|
- taskName = TaskNameEnum.SHARE_ACCOUNT.getInfo();
|
|
|
- break;
|
|
|
- case BROWLE_NEWS:
|
|
|
- taskName = TaskNameEnum.BROWSE_DYNAMIC.getInfo();
|
|
|
- break;
|
|
|
- case BROWLE_MERCHANT:
|
|
|
- taskName = TaskNameEnum.BROWSE_MERCHANT.getInfo();
|
|
|
- break;
|
|
|
- default:
|
|
|
- throw new ServiceException("不支持的任务类型: " + taskType);
|
|
|
- }
|
|
|
-
|
|
|
- // 标记为已验证,允许后续流程继续(如果需要)
|
|
|
isVerified = true;
|
|
|
- }
|
|
|
- // 场景 B: 新手任务 或 每月任务 -> 需要核实业务数据(订单/充值)
|
|
|
- else if (pointActivityType == PointActivityTypeEnum.NEW_USER_ACTIVITY || pointActivityType == PointActivityTypeEnum.MONTHLY_ACTIVITY) {
|
|
|
-
|
|
|
- // 计算查询业务数据的时间起点
|
|
|
- Date queryTime = getQueryStartTime(isPermanent, activityStartTime, activityType);
|
|
|
-
|
|
|
- switch (taskType) {
|
|
|
- case COMPLETE_ORDER: // 完成订单
|
|
|
- int orderCount = orderService.countCompletedOrders(openId, queryTime);
|
|
|
- isVerified = orderCount >= targetCount;
|
|
|
- taskName = TaskNameEnum.COMPLETE_ORDER.getInfo();
|
|
|
- break;
|
|
|
- case RECHARGE_TASK: // 充值任务
|
|
|
- int rechargeCount = rechargeService.countSuccessRecharges(openId, queryTime);
|
|
|
- isVerified = rechargeCount >= targetCount;
|
|
|
- taskName = TaskNameEnum.RECHARGE_TASK.getInfo();
|
|
|
- break;
|
|
|
- case SHARE_SERVICE: // 分享服务号
|
|
|
- taskName = TaskNameEnum.SHARE_ACCOUNT.getInfo();
|
|
|
- isVerified = true;
|
|
|
- break;
|
|
|
- case BROWLE_NEWS: // 浏览动态
|
|
|
- taskName = TaskNameEnum.BROWSE_DYNAMIC.getInfo();
|
|
|
- isVerified = true;
|
|
|
- break;
|
|
|
- case BROWLE_MERCHANT:// 浏览商户
|
|
|
- taskName = TaskNameEnum.BROWSE_MERCHANT.getInfo();
|
|
|
- isVerified = true;
|
|
|
- break;
|
|
|
- default:
|
|
|
- throw new ServiceException("不支持的任务类型: " + taskType);
|
|
|
- }
|
|
|
+ } else if (activityTypeEnum == PointActivityTypeEnum.NEW_USER_ACTIVITY || activityTypeEnum == PointActivityTypeEnum.MONTHLY_ACTIVITY) {
|
|
|
+ // 新手/月度任务:校验业务数据
|
|
|
+ taskName = getTaskNameByType(taskTypeEnum);
|
|
|
+ Date queryTime = getQueryStartTime(activity.getIsPermanent(), activity.getStartTime(), activity.getActivityType());
|
|
|
+ isVerified = checkBusinessData(openId, taskTypeEnum, queryTime, targetCount);
|
|
|
} else {
|
|
|
throw new ServiceException("不支持的活动类型");
|
|
|
}
|
|
|
|
|
|
- // --- 执行发奖逻辑 ---
|
|
|
-
|
|
|
- // 4. 如果核实通过,执行本地记录和发分
|
|
|
+ // 5. 校验通过 → 发放奖励
|
|
|
if (isVerified) {
|
|
|
- // 4.1 【关键修复】先查询本地记录,判断是否已经达标
|
|
|
- PointUserActivityTaskCompletion existingRecord = this.getOne(
|
|
|
- new LambdaQueryWrapper<PointUserActivityTaskCompletion>()
|
|
|
- .eq(PointUserActivityTaskCompletion::getOpenId, openId)
|
|
|
- .eq(PointUserActivityTaskCompletion::getTaskId, taskId)
|
|
|
- .eq(PointUserActivityTaskCompletion::getActivityId, activityId)
|
|
|
- .eq(PointUserActivityTaskCompletion::getTaskType, taskType.getCode())
|
|
|
- );
|
|
|
-
|
|
|
- // 防刷:如果已经达标,不再重复发分
|
|
|
- if (existingRecord != null && existingRecord.getCompletedCount() >= targetCount) {
|
|
|
+ // 防重复发奖:已达标则直接返回
|
|
|
+ PointUserActivityTaskCompletion record = this.getTaskRecord(openId, activityId, taskId, taskTypeEnum.getCode());
|
|
|
+ if (record != null && record.getCompletedCount() >= targetCount) {
|
|
|
throw new ServiceException("任务奖励已领取");
|
|
|
}
|
|
|
|
|
|
- // 4.2 更新任务进度表 (插入或更新)
|
|
|
- // 注意:这里我使用了你之前的 completeTask 逻辑,而不是直接 set 目标值
|
|
|
- // 因为如果是“累计充值1000元”,用户充了500+500,直接set成1会丢失进度
|
|
|
- // 但如果是“完成1笔订单”,直接调用 completeTask 即可
|
|
|
- this.completeTask(openId, activityId, taskId, taskType.getCode());
|
|
|
+ // 更新任务进度
|
|
|
+ this.completeTask(openId, activityId, taskId, taskTypeEnum.getCode());
|
|
|
+ // 发放积分
|
|
|
+ pointAccountService.addPoints(openId, task.getRewardPoints().intValue(),
|
|
|
+ activity.getName(), null, activityId, taskId, taskTypeEnum.getCode(), taskName);
|
|
|
+ } else {
|
|
|
+ throw new ServiceException("任务未完成,无法领取奖励");
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
- // 4.3 发放积分
|
|
|
- // 注意:这里需要确保只发一次。如果 completeTask 只是增加次数,这里需要判断是否刚好达标才发分
|
|
|
- // 为了简单,假设这里调用 addPoints 是安全的(或者你在 addPoints 内部做幂等)
|
|
|
- pointAccountService.addPoints(openId, task.getRewardPoints().intValue(), activityName, null, activityId, taskId, taskType.getCode(), taskName);
|
|
|
+ /**
|
|
|
+ * 根据任务类型获取任务名称 JDK8 兼容
|
|
|
+ */
|
|
|
+ private String getTaskNameByType(PointActivityTaskTypeEnum taskType) {
|
|
|
+ if (taskType == PointActivityTaskTypeEnum.COMPLETE_ORDER) {
|
|
|
+ return ActivityNameEnum.COMPLETE_ORDER.getInfo();
|
|
|
+ } else if (taskType == PointActivityTaskTypeEnum.RECHARGE_TASK) {
|
|
|
+ return ActivityNameEnum.RECHARGE_TASK.getInfo();
|
|
|
+ } else if (taskType == PointActivityTaskTypeEnum.SHARE_SERVICE) {
|
|
|
+ return ActivityNameEnum.SHARE_ACCOUNT.getInfo();
|
|
|
+ } else if (taskType == PointActivityTaskTypeEnum.BROWLE_NEWS) {
|
|
|
+ return ActivityNameEnum.BROWSE_DYNAMIC.getInfo();
|
|
|
+ } else if (taskType == PointActivityTaskTypeEnum.BROWLE_MERCHANT) {
|
|
|
+ return ActivityNameEnum.BROWSE_MERCHANT.getInfo();
|
|
|
+ } else {
|
|
|
+ throw new ServiceException("不支持的任务类型: " + taskType);
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
+ /**
|
|
|
+ * 校验业务数据(订单/充值) JDK8 兼容
|
|
|
+ */
|
|
|
+ private boolean checkBusinessData(String openId, PointActivityTaskTypeEnum taskType, Date queryTime, int targetCount) {
|
|
|
+ if (taskType == PointActivityTaskTypeEnum.COMPLETE_ORDER) {
|
|
|
+ return orderService.countCompletedOrders(openId, queryTime) >= targetCount;
|
|
|
+ } else if (taskType == PointActivityTaskTypeEnum.RECHARGE_TASK) {
|
|
|
+ return rechargeService.countSuccessRecharges(openId, queryTime) >= targetCount;
|
|
|
+ } else if (taskType == PointActivityTaskTypeEnum.SHARE_SERVICE
|
|
|
+ || taskType == PointActivityTaskTypeEnum.BROWLE_NEWS
|
|
|
+ || taskType == PointActivityTaskTypeEnum.BROWLE_MERCHANT) {
|
|
|
+ return true;
|
|
|
+ } else {
|
|
|
+ return false;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * 获取查询开始时间 JDK8 兼容
|
|
|
+ */
|
|
|
private Date getQueryStartTime(String isPermanent, Date startTime, Integer activityType) {
|
|
|
- // 1. 永久任务(永久有效 = 查询所有历史数据,直接返回任务开始时间)
|
|
|
- if (StrUtil.equals(isPermanent, "1")) { // 假设 1=永久,0=非永久
|
|
|
+ // 永久任务:查询全部历史
|
|
|
+ if (StrUtil.equals(isPermanent, "1")) {
|
|
|
return null;
|
|
|
}
|
|
|
-
|
|
|
- // 2. 非永久任务 → 根据活动类型判断
|
|
|
- if (ObjectUtil.equals(PointActivityTypeEnum.DAILY_ACTIVITY.getCode(), activityType)) {
|
|
|
- // 每日任务 → 今天 0 点
|
|
|
+ PointActivityTypeEnum typeEnum = PointActivityTypeEnum.valueOf(activityType);
|
|
|
+ if (typeEnum == PointActivityTypeEnum.DAILY_ACTIVITY) {
|
|
|
return DateUtil.beginOfDay(new Date());
|
|
|
- } else if (ObjectUtil.equals(PointActivityTypeEnum.MONTHLY_ACTIVITY.getCode(), activityType)) {
|
|
|
- // 每月任务 → 本月 1 号 0 点
|
|
|
+ } else if (typeEnum == PointActivityTypeEnum.MONTHLY_ACTIVITY) {
|
|
|
return DateUtil.beginOfMonth(new Date());
|
|
|
} else {
|
|
|
- // 新手任务 / 其他 → 任务开始时间(查全部历史)
|
|
|
return startTime;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * 获取当前微信登录用户
|
|
|
+ */
|
|
|
private WxLoginUser getCurrentWxLoginUser() {
|
|
|
WxLoginUser loginUser = SecurityUtils.getWxLoginUser();
|
|
|
if (ObjectUtil.isNull(loginUser)) {
|
|
|
@@ -308,114 +277,84 @@ public class PointUserActivityTaskCompletionServiceImpl extends ServiceImpl<Poin
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * 通用任务完成方法(内部使用)
|
|
|
- *
|
|
|
- * @param openId 用户openId
|
|
|
- * @param taskTypeEnum 任务类型枚举
|
|
|
- * @param taskNameEnum 活动名称枚举
|
|
|
- * @param countSupplier 查询已完成次数的函数
|
|
|
+ * 获取任务完成记录
|
|
|
*/
|
|
|
- private void completeTaskByPriorityInternal(String openId,
|
|
|
- PointActivityTaskTypeEnum taskTypeEnum,
|
|
|
- TaskNameEnum taskNameEnum,
|
|
|
- java.util.function.Function<Date, Integer> countSupplier) {
|
|
|
- // 活动类型优先级:新手活动、每日活动、每月活动
|
|
|
- List<Integer> priorityTypes = Arrays.asList(
|
|
|
- PointActivityTypeEnum.NEW_USER_ACTIVITY.getCode(),
|
|
|
- PointActivityTypeEnum.DAILY_ACTIVITY.getCode(),
|
|
|
- PointActivityTypeEnum.MONTHLY_ACTIVITY.getCode()
|
|
|
+ private PointUserActivityTaskCompletion getTaskRecord(String openId, Long activityId, Long taskId, Integer taskType) {
|
|
|
+ return this.getOne(Wrappers.lambdaQuery(PointUserActivityTaskCompletion.class)
|
|
|
+ .eq(PointUserActivityTaskCompletion::getOpenId, openId)
|
|
|
+ .eq(PointUserActivityTaskCompletion::getActivityId, activityId)
|
|
|
+ .eq(PointUserActivityTaskCompletion::getTaskId, taskId)
|
|
|
+ .eq(PointUserActivityTaskCompletion::getTaskType, taskType)
|
|
|
);
|
|
|
+ }
|
|
|
|
|
|
- // 按优先级遍历活动类型
|
|
|
- for (Integer activityType : priorityTypes) {
|
|
|
- try {
|
|
|
- // 查询该活动类型下所有进行中的任务
|
|
|
- List<PointActivityTask> taskList = pointActivityTaskService.list(
|
|
|
- Wrappers.lambdaQuery(PointActivityTask.class)
|
|
|
- .eq(PointActivityTask::getTaskName, taskNameEnum.getInfo())
|
|
|
- .eq(PointActivityTask::getStatus, 0)
|
|
|
- .eq(PointActivityTask::getIsDeleted, 0)
|
|
|
- );
|
|
|
-
|
|
|
- // 过滤出属于该活动类型的任务
|
|
|
- taskList = taskList.stream()
|
|
|
- .filter(task -> {
|
|
|
- PointActivity activity = pointActivityService.getById(task.getActivityId());
|
|
|
- return activity != null
|
|
|
- && activity.getActivityType().equals(activityType)
|
|
|
- && activity.getStatus().equals(PointActivityStatusEnum.IN_PROGRESS.getCode());
|
|
|
- })
|
|
|
- .collect(Collectors.toList());
|
|
|
-
|
|
|
- if (CollectionUtil.isEmpty(taskList)) {
|
|
|
- continue;
|
|
|
- }
|
|
|
+ /**
|
|
|
+ * 通用优先级任务完成方法
|
|
|
+ */
|
|
|
+ private void completeTaskByPriority(String openId, ActivityNameEnum activityNameEnum,
|
|
|
+ PointActivityTaskTypeEnum taskTypeEnum,
|
|
|
+ Function<Date, Integer> countFunction) {
|
|
|
+ // 批量查询所有有效任务
|
|
|
+ List<PointActivityTask> allTasks = pointActivityTaskService.list(Wrappers.lambdaQuery(PointActivityTask.class)
|
|
|
+ .eq(PointActivityTask::getTaskName, activityNameEnum.getInfo())
|
|
|
+ .eq(PointActivityTask::getStatus, 0)
|
|
|
+ .eq(PointActivityTask::getIsDeleted, 0)
|
|
|
+ );
|
|
|
+ if (CollectionUtil.isEmpty(allTasks)) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 批量查询关联活动,解决N+1查询
|
|
|
+ Set<Long> activityIds = allTasks.stream().map(PointActivityTask::getActivityId).collect(Collectors.toSet());
|
|
|
+ List<PointActivity> activityList = pointActivityService.listByIds(activityIds);
|
|
|
+ Map<Long, PointActivity> activityMap = activityList.stream().collect(Collectors.toMap(PointActivity::getId, a -> a));
|
|
|
+
|
|
|
+ // 按优先级处理活动类型
|
|
|
+ for (Integer typeCode : ACTIVITY_TYPE_PRIORITY) {
|
|
|
+ // 过滤当前类型的有效任务
|
|
|
+ List<PointActivityTask> taskList = allTasks.stream()
|
|
|
+ .filter(task -> {
|
|
|
+ PointActivity activity = activityMap.get(task.getActivityId());
|
|
|
+ return activity != null
|
|
|
+ && Objects.equals(activity.getActivityType(), typeCode)
|
|
|
+ && Objects.equals(activity.getStatus(), PointActivityStatusEnum.IN_PROGRESS.getCode());
|
|
|
+ })
|
|
|
+ .collect(Collectors.toList());
|
|
|
+
|
|
|
+ if (CollectionUtil.isEmpty(taskList)) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 执行任务
|
|
|
+ for (PointActivityTask task : taskList) {
|
|
|
+ try {
|
|
|
+ PointActivity activity = activityMap.get(task.getActivityId());
|
|
|
+ int targetCount = Integer.parseInt(task.getTriggerValue());
|
|
|
+ Date queryTime = getQueryStartTime(activity.getIsPermanent(), activity.getStartTime(), typeCode);
|
|
|
+ int completed = countFunction.apply(queryTime);
|
|
|
|
|
|
- // 对每个任务按优先级顺序执行
|
|
|
- for (PointActivityTask task : taskList) {
|
|
|
- try {
|
|
|
- // 获取任务信息
|
|
|
- PointActivity activity = pointActivityService.getById(task.getActivityId());
|
|
|
-
|
|
|
- // 获取触发阈值(目标次数)
|
|
|
- int targetCount = Integer.parseInt(task.getTriggerValue());
|
|
|
-
|
|
|
- // 获取限制类型值(每日/每月/一次性)
|
|
|
- String frequencyLimitValue = task.getFrequencyLimitValue();
|
|
|
-
|
|
|
- // 计算查询业务数据的时间起点
|
|
|
- Date queryTime = getQueryStartTime(activity.getIsPermanent(), activity.getStartTime(), activity.getActivityType());
|
|
|
-
|
|
|
- // 查询用户已完成次数
|
|
|
- int completedCount = countSupplier.apply(queryTime);
|
|
|
-
|
|
|
- // 判断是否达到目标次数
|
|
|
- if (completedCount >= targetCount) {
|
|
|
- // 查询是否已经完成过该任务
|
|
|
- PointUserActivityTaskCompletion existingRecord = this.getOne(
|
|
|
- new LambdaQueryWrapper<PointUserActivityTaskCompletion>()
|
|
|
- .eq(PointUserActivityTaskCompletion::getOpenId, openId)
|
|
|
- .eq(PointUserActivityTaskCompletion::getTaskId, task.getId())
|
|
|
- .eq(PointUserActivityTaskCompletion::getActivityId, activity.getId())
|
|
|
- .eq(PointUserActivityTaskCompletion::getTaskType, taskTypeEnum.getCode())
|
|
|
- );
|
|
|
-
|
|
|
- // 检查是否已经达到目标次数(防刷)
|
|
|
- if (existingRecord != null && existingRecord.getCompletedCount() >= targetCount) {
|
|
|
- // 已经完成过,继续尝试下一个任务
|
|
|
- continue;
|
|
|
- }
|
|
|
-
|
|
|
- // 更新任务完成记录
|
|
|
- completeTask(openId, activity.getId(), task.getId(), taskTypeEnum.getCode());
|
|
|
-
|
|
|
- // 发放积分
|
|
|
- pointAccountService.addPoints(
|
|
|
- openId,
|
|
|
- task.getRewardPoints().intValue(),
|
|
|
- activity.getName(),
|
|
|
- null,
|
|
|
- activity.getId(),
|
|
|
- task.getId(),
|
|
|
- taskTypeEnum.getCode(),
|
|
|
- taskNameEnum.getInfo()
|
|
|
- );
|
|
|
-
|
|
|
- // 成功完成一个任务后,跳出循环(只完成优先级最高的一个任务)
|
|
|
- return;
|
|
|
- }
|
|
|
- } catch (ServiceException e) {
|
|
|
- // 如果任务已完成或不符合条件,继续尝试下一个任务
|
|
|
- if (!e.getMessage().contains("今日任务已完成")
|
|
|
- && !e.getMessage().contains("任务奖励已领取")) {
|
|
|
- // 其他异常则抛出
|
|
|
- throw e;
|
|
|
- }
|
|
|
+ if (completed < targetCount) {
|
|
|
+ continue;
|
|
|
}
|
|
|
+
|
|
|
+ // 防重复领取
|
|
|
+ PointUserActivityTaskCompletion record = getTaskRecord(openId, activity.getId(), task.getId(), taskTypeEnum.getCode());
|
|
|
+ if (record != null && record.getCompletedCount() >= targetCount) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 完成任务+发奖
|
|
|
+ completeTask(openId, activity.getId(), task.getId(), taskTypeEnum.getCode());
|
|
|
+ pointAccountService.addPoints(openId, task.getRewardPoints().intValue(),
|
|
|
+ activity.getName(), null, activity.getId(), task.getId(),
|
|
|
+ taskTypeEnum.getCode(), activityNameEnum.getInfo());
|
|
|
+ return;
|
|
|
+ } catch (ServiceException e) {
|
|
|
+ if (!e.getMessage().contains("已完成") && !e.getMessage().contains("已领取")) {
|
|
|
+ throw e;
|
|
|
+ }
|
|
|
+ log.warn("任务处理异常:{}", e.getMessage());
|
|
|
}
|
|
|
- } catch (Exception e) {
|
|
|
- log.error("完成{}任务失败 - 活动类型:{}, 错误信息:{}", taskNameEnum.getInfo(), activityType, e.getMessage(), e);
|
|
|
- // 继续尝试下一个优先级的活动类型
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
@@ -423,209 +362,26 @@ public class PointUserActivityTaskCompletionServiceImpl extends ServiceImpl<Poin
|
|
|
@Override
|
|
|
@Transactional(rollbackFor = Exception.class)
|
|
|
public void completeOrderTaskByPriority(String openId) {
|
|
|
- // 活动类型优先级:新手活动、每日活动、每月活动
|
|
|
- List<Integer> priorityTypes = Arrays.asList(
|
|
|
- PointActivityTypeEnum.NEW_USER_ACTIVITY.getCode(),
|
|
|
- PointActivityTypeEnum.DAILY_ACTIVITY.getCode(),
|
|
|
- PointActivityTypeEnum.MONTHLY_ACTIVITY.getCode()
|
|
|
- );
|
|
|
-
|
|
|
- // 按优先级遍历活动类型
|
|
|
- for (Integer activityType : priorityTypes) {
|
|
|
- try {
|
|
|
- // 查询该活动类型下所有进行中的"完成订单"任务
|
|
|
- List<PointActivityTask> taskList = pointActivityTaskService.list(
|
|
|
- Wrappers.lambdaQuery(PointActivityTask.class)
|
|
|
- .eq(PointActivityTask::getTaskName, TaskNameEnum.COMPLETE_ORDER.getInfo())
|
|
|
- .eq(PointActivityTask::getStatus, 0)
|
|
|
- .eq(PointActivityTask::getIsDeleted, 0)
|
|
|
- );
|
|
|
-
|
|
|
- // 过滤出属于该活动类型的任务
|
|
|
- taskList = taskList.stream()
|
|
|
- .filter(task -> {
|
|
|
- PointActivity activity = pointActivityService.getById(task.getActivityId());
|
|
|
- return activity != null
|
|
|
- && activity.getActivityType().equals(activityType)
|
|
|
- && activity.getStatus().equals(PointActivityStatusEnum.IN_PROGRESS.getCode());
|
|
|
- })
|
|
|
- .collect(Collectors.toList());
|
|
|
-
|
|
|
- if (CollectionUtil.isEmpty(taskList)) {
|
|
|
- continue;
|
|
|
- }
|
|
|
-
|
|
|
- // 对每个任务按优先级顺序执行
|
|
|
- for (PointActivityTask task : taskList) {
|
|
|
- try {
|
|
|
- // 获取任务信息
|
|
|
- PointActivity activity = pointActivityService.getById(task.getActivityId());
|
|
|
-
|
|
|
- // 获取触发阈值(目标次数)
|
|
|
- int targetCount = Integer.parseInt(task.getTriggerValue());
|
|
|
-
|
|
|
- // 获取限制类型值(每日/每月/一次性)
|
|
|
- String frequencyLimitValue = task.getFrequencyLimitValue();
|
|
|
-
|
|
|
- // 计算查询业务数据的时间起点
|
|
|
- Date queryTime = getQueryStartTime(activity.getIsPermanent(), activity.getStartTime(), activity.getActivityType());
|
|
|
-
|
|
|
- // 查询用户已完成订单数
|
|
|
- int orderCount = orderService.countCompletedOrders(openId, queryTime);
|
|
|
-
|
|
|
- // 判断是否达到目标次数
|
|
|
- if (orderCount >= targetCount) {
|
|
|
- // 查询是否已经完成过该任务
|
|
|
- PointUserActivityTaskCompletion existingRecord = this.getOne(
|
|
|
- new LambdaQueryWrapper<PointUserActivityTaskCompletion>()
|
|
|
- .eq(PointUserActivityTaskCompletion::getOpenId, openId)
|
|
|
- .eq(PointUserActivityTaskCompletion::getTaskId, task.getId())
|
|
|
- .eq(PointUserActivityTaskCompletion::getActivityId, activity.getId())
|
|
|
- .eq(PointUserActivityTaskCompletion::getTaskType, PointActivityTaskTypeEnum.COMPLETE_ORDER.getCode())
|
|
|
- );
|
|
|
-
|
|
|
- // 检查是否已经达到目标次数(防刷)
|
|
|
- if (existingRecord != null && existingRecord.getCompletedCount() >= targetCount) {
|
|
|
- // 已经完成过,继续尝试下一个任务
|
|
|
- continue;
|
|
|
- }
|
|
|
-
|
|
|
- // 更新任务完成记录
|
|
|
- completeTask(openId, activity.getId(), task.getId(), PointActivityTaskTypeEnum.COMPLETE_ORDER.getCode());
|
|
|
-
|
|
|
- // 发放积分
|
|
|
- pointAccountService.addPoints(
|
|
|
- openId,
|
|
|
- task.getRewardPoints().intValue(),
|
|
|
- activity.getName(),
|
|
|
- null,
|
|
|
- activity.getId(),
|
|
|
- task.getId(),
|
|
|
- PointActivityTaskTypeEnum.COMPLETE_ORDER.getCode(),
|
|
|
- TaskNameEnum.COMPLETE_ORDER.getInfo()
|
|
|
- );
|
|
|
-
|
|
|
- // 成功完成一个任务后,跳出循环(只完成优先级最高的一个任务)
|
|
|
- return;
|
|
|
- }
|
|
|
- } catch (ServiceException e) {
|
|
|
- // 如果任务已完成或不符合条件,继续尝试下一个任务
|
|
|
- if (!e.getMessage().contains("今日任务已完成")
|
|
|
- && !e.getMessage().contains("任务奖励已领取")) {
|
|
|
- // 其他异常则抛出
|
|
|
- throw e;
|
|
|
- }
|
|
|
+ completeTaskByPriority(openId, ActivityNameEnum.COMPLETE_ORDER,
|
|
|
+ PointActivityTaskTypeEnum.COMPLETE_ORDER,
|
|
|
+ new Function<Date, Integer>() {
|
|
|
+ @Override
|
|
|
+ public Integer apply(Date queryTime) {
|
|
|
+ return orderService.countCompletedOrders(openId, queryTime);
|
|
|
}
|
|
|
- }
|
|
|
- } catch (Exception e) {
|
|
|
- log.error("完成订单任务失败 - 活动类型:{}, 错误信息:{}", activityType, e.getMessage(), e);
|
|
|
- // 继续尝试下一个优先级的活动类型
|
|
|
- }
|
|
|
- }
|
|
|
+ });
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
@Transactional(rollbackFor = Exception.class)
|
|
|
public void completeRechargeTaskByPriority(String openId) {
|
|
|
- // 活动类型优先级:新手活动、每日活动、每月活动
|
|
|
- List<Integer> priorityTypes = Arrays.asList(
|
|
|
- PointActivityTypeEnum.NEW_USER_ACTIVITY.getCode(),
|
|
|
- PointActivityTypeEnum.DAILY_ACTIVITY.getCode(),
|
|
|
- PointActivityTypeEnum.MONTHLY_ACTIVITY.getCode()
|
|
|
- );
|
|
|
-
|
|
|
- // 按优先级遍历活动类型
|
|
|
- for (Integer activityType : priorityTypes) {
|
|
|
- try {
|
|
|
- // 查询该活动类型下所有进行中的"充值任务"
|
|
|
- List<PointActivityTask> taskList = pointActivityTaskService.list(
|
|
|
- Wrappers.lambdaQuery(PointActivityTask.class)
|
|
|
- .eq(PointActivityTask::getTaskName, TaskNameEnum.RECHARGE_TASK.getInfo())
|
|
|
- .eq(PointActivityTask::getStatus, 0)
|
|
|
- .eq(PointActivityTask::getIsDeleted, 0)
|
|
|
- );
|
|
|
-
|
|
|
- // 过滤出属于该活动类型的任务
|
|
|
- taskList = taskList.stream()
|
|
|
- .filter(task -> {
|
|
|
- PointActivity activity = pointActivityService.getById(task.getActivityId());
|
|
|
- return activity != null
|
|
|
- && activity.getActivityType().equals(activityType)
|
|
|
- && activity.getStatus().equals(PointActivityStatusEnum.IN_PROGRESS.getCode());
|
|
|
- })
|
|
|
- .collect(Collectors.toList());
|
|
|
-
|
|
|
- if (CollectionUtil.isEmpty(taskList)) {
|
|
|
- continue;
|
|
|
- }
|
|
|
-
|
|
|
- // 对每个任务按优先级顺序执行
|
|
|
- for (PointActivityTask task : taskList) {
|
|
|
- try {
|
|
|
- // 获取任务信息
|
|
|
- PointActivity activity = pointActivityService.getById(task.getActivityId());
|
|
|
-
|
|
|
- // 获取触发阈值(目标次数)
|
|
|
- int targetCount = Integer.parseInt(task.getTriggerValue());
|
|
|
-
|
|
|
- // 获取限制类型值(每日/每月/一次性)
|
|
|
- String frequencyLimitValue = task.getFrequencyLimitValue();
|
|
|
-
|
|
|
- // 计算查询业务数据的时间起点
|
|
|
- Date queryTime = getQueryStartTime(activity.getIsPermanent(), activity.getStartTime(), activity.getActivityType());
|
|
|
-
|
|
|
- // 查询用户已完成充值数
|
|
|
- int rechargeCount = rechargeService.countSuccessRecharges(openId, queryTime);
|
|
|
-
|
|
|
- // 判断是否达到目标次数
|
|
|
- if (rechargeCount >= targetCount) {
|
|
|
- // 查询是否已经完成过该任务
|
|
|
- PointUserActivityTaskCompletion existingRecord = this.getOne(
|
|
|
- new LambdaQueryWrapper<PointUserActivityTaskCompletion>()
|
|
|
- .eq(PointUserActivityTaskCompletion::getOpenId, openId)
|
|
|
- .eq(PointUserActivityTaskCompletion::getTaskId, task.getId())
|
|
|
- .eq(PointUserActivityTaskCompletion::getActivityId, activity.getId())
|
|
|
- .eq(PointUserActivityTaskCompletion::getTaskType, PointActivityTaskTypeEnum.RECHARGE_TASK.getCode())
|
|
|
- );
|
|
|
-
|
|
|
- // 检查是否已经达到目标次数(防刷)
|
|
|
- if (existingRecord != null && existingRecord.getCompletedCount() >= targetCount) {
|
|
|
- // 已经完成过,继续尝试下一个任务
|
|
|
- continue;
|
|
|
- }
|
|
|
-
|
|
|
- // 更新任务完成记录
|
|
|
- completeTask(openId, activity.getId(), task.getId(), PointActivityTaskTypeEnum.RECHARGE_TASK.getCode());
|
|
|
-
|
|
|
- // 发放积分
|
|
|
- pointAccountService.addPoints(
|
|
|
- openId,
|
|
|
- task.getRewardPoints().intValue(),
|
|
|
- activity.getName(),
|
|
|
- null,
|
|
|
- activity.getId(),
|
|
|
- task.getId(),
|
|
|
- PointActivityTaskTypeEnum.RECHARGE_TASK.getCode(),
|
|
|
- TaskNameEnum.RECHARGE_TASK.getInfo()
|
|
|
- );
|
|
|
-
|
|
|
- // 成功完成一个任务后,跳出循环(只完成优先级最高的一个任务)
|
|
|
- return;
|
|
|
- }
|
|
|
- } catch (ServiceException e) {
|
|
|
- // 如果任务已完成或不符合条件,继续尝试下一个任务
|
|
|
- if (!e.getMessage().contains("今日任务已完成")
|
|
|
- && !e.getMessage().contains("任务奖励已领取")) {
|
|
|
- // 其他异常则抛出
|
|
|
- throw e;
|
|
|
- }
|
|
|
+ completeTaskByPriority(openId, ActivityNameEnum.RECHARGE_TASK,
|
|
|
+ PointActivityTaskTypeEnum.RECHARGE_TASK,
|
|
|
+ new Function<Date, Integer>() {
|
|
|
+ @Override
|
|
|
+ public Integer apply(Date queryTime) {
|
|
|
+ return rechargeService.countSuccessRecharges(openId, queryTime);
|
|
|
}
|
|
|
- }
|
|
|
- } catch (Exception e) {
|
|
|
- log.error("完成充值任务失败 - 活动类型:{}, 错误信息:{}", activityType, e.getMessage(), e);
|
|
|
- // 继续尝试下一个优先级的活动类型
|
|
|
- }
|
|
|
- }
|
|
|
+ });
|
|
|
}
|
|
|
-
|
|
|
-}
|
|
|
+}
|