|
|
@@ -52,6 +52,13 @@ public class Task {
|
|
|
private static final Logger log = LoggerFactory.getLogger(Task.class);
|
|
|
private static final String LOG_PREFIX = "[LiveScheduled]";
|
|
|
|
|
|
+ /** 观看奖励参与条件:达到指定观看时长(完课奖励走 LiveCompletionPointsTask,勿混用) */
|
|
|
+ private static final long WATCH_REWARD_CONDITION_DURATION = 1L;
|
|
|
+ /** 观看奖励实施动作:积分 */
|
|
|
+ private static final long WATCH_REWARD_ACTION_POINTS = 2L;
|
|
|
+ /** 观看奖励实施动作:优惠券 */
|
|
|
+ private static final long WATCH_REWARD_ACTION_COUPON = 3L;
|
|
|
+
|
|
|
|
|
|
private void logTaskFinish(String taskName, String summary) {
|
|
|
log.info("{} {} 完成, {}", LOG_PREFIX, taskName, summary);
|
|
|
@@ -502,16 +509,22 @@ public class Task {
|
|
|
}
|
|
|
String configJson = live.getConfigJson();
|
|
|
LiveWatchConfig config = JSON.parseObject(configJson, LiveWatchConfig.class);
|
|
|
- if (!config.getEnabled() || config.getParticipateCondition() == null || config.getAction() == null) {
|
|
|
+ if (config == null || !Boolean.TRUE.equals(config.getEnabled())
|
|
|
+ || config.getParticipateCondition() == null) {
|
|
|
log.info("{} autoUpdateWatchReward 配置未启用或缺失: liveId={}", LOG_PREFIX, live.getLiveId());
|
|
|
continue;
|
|
|
}
|
|
|
- // 只处理 "达到指定观看时长" 的参与条件
|
|
|
- if (1 != config.getParticipateCondition()) {
|
|
|
+ // 只处理「达到指定观看时长」;完课积分/优惠券由 LiveCompletionPointsTask 负责
|
|
|
+ if (WATCH_REWARD_CONDITION_DURATION != config.getParticipateCondition()) {
|
|
|
log.info("{} autoUpdateWatchReward 参与条件非观看时长: liveId={}, condition={}",
|
|
|
LOG_PREFIX, live.getLiveId(), config.getParticipateCondition());
|
|
|
continue;
|
|
|
}
|
|
|
+ List<Long> actions = config.resolveActions();
|
|
|
+ if (actions.isEmpty()) {
|
|
|
+ log.info("{} autoUpdateWatchReward 未配置实施动作: liveId={}", LOG_PREFIX, live.getLiveId());
|
|
|
+ continue;
|
|
|
+ }
|
|
|
if (live.getStartTime() != null && live.getStartTime().isAfter(LocalDateTime.now())) {
|
|
|
log.info("{} autoUpdateWatchReward 直播未开始,跳过: liveId={}, startTime={}",
|
|
|
LOG_PREFIX, live.getLiveId(), live.getStartTime());
|
|
|
@@ -542,8 +555,8 @@ public class Task {
|
|
|
continue;
|
|
|
}
|
|
|
|
|
|
- log.info("{} autoUpdateWatchReward 准备发放: liveId={}, action={}, 用户数={}, required={}s",
|
|
|
- LOG_PREFIX, live.getLiveId(), config.getAction(), userIds.size(), requiredWatchSeconds);
|
|
|
+ log.info("{} autoUpdateWatchReward 准备发放: liveId={}, actions={}, 用户数={}, required={}s",
|
|
|
+ LOG_PREFIX, live.getLiveId(), actions, userIds.size(), requiredWatchSeconds);
|
|
|
|
|
|
int granted = grantWatchRewardToUsers(live, config, userIds);
|
|
|
if (granted > 0) {
|
|
|
@@ -576,8 +589,11 @@ public class Task {
|
|
|
return;
|
|
|
}
|
|
|
LiveWatchConfig config = JSON.parseObject(live.getConfigJson(), LiveWatchConfig.class);
|
|
|
- if (!config.getEnabled() || config.getParticipateCondition() == null || config.getParticipateCondition() != 1
|
|
|
- || config.getAction() == null || config.getWatchDuration() == null || config.getWatchDuration() <= 0) {
|
|
|
+ if (config == null || !Boolean.TRUE.equals(config.getEnabled())
|
|
|
+ || config.getParticipateCondition() == null
|
|
|
+ || WATCH_REWARD_CONDITION_DURATION != config.getParticipateCondition()
|
|
|
+ || config.resolveActions().isEmpty()
|
|
|
+ || config.getWatchDuration() == null || config.getWatchDuration() <= 0) {
|
|
|
return;
|
|
|
}
|
|
|
if (live.getStartTime() != null && live.getStartTime().isAfter(LocalDateTime.now())) {
|
|
|
@@ -602,85 +618,115 @@ public class Task {
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * 向达标用户发放观看奖励(积分 / 优惠券)
|
|
|
+ * 向达标用户发放观看奖励(支持积分 / 优惠券多选同时发放)
|
|
|
*
|
|
|
- * @return 成功发放的用户数
|
|
|
+ * @return 成功发放的用户数(任一奖励发放成功即计入)
|
|
|
*/
|
|
|
private int grantWatchRewardToUsers(Live live, LiveWatchConfig config, List<Long> userIds) {
|
|
|
if (live == null || config == null || userIds == null || userIds.isEmpty()) {
|
|
|
return 0;
|
|
|
}
|
|
|
- Long action = config.getAction();
|
|
|
- if (action == null) {
|
|
|
+ List<Long> actions = config.resolveActions();
|
|
|
+ if (actions.isEmpty()) {
|
|
|
return 0;
|
|
|
}
|
|
|
Long liveId = live.getLiveId();
|
|
|
- switch (action.intValue()) {
|
|
|
- case 2:
|
|
|
- saveUserRewardRecord(live, userIds, BigDecimal.valueOf(config.getScoreAmount()), 2);
|
|
|
- LiveConsoleOpLog watchPointsOpLog = liveConsoleOpLogService.saveLog(
|
|
|
- liveId,
|
|
|
- LiveConsoleOpLog.OP_WATCH_REWARD_POINTS,
|
|
|
- LiveConsoleOpLog.HANDLE_AUTO,
|
|
|
- liveId,
|
|
|
- resolveWatchRewardPointsBizName(config, userIds.size())
|
|
|
- );
|
|
|
- int pointsSuccessCount = 0;
|
|
|
- for (Long uid : userIds) {
|
|
|
- if (grantWatchRewardIntegral(liveId, uid, config.getScoreAmount())) {
|
|
|
- liveConsoleOpLogService.bindOpLogUser(watchPointsOpLog.getId(), liveId, uid);
|
|
|
- webSocketServer.sendIntegralMessage(liveId, uid, config.getScoreAmount(), watchPointsOpLog);
|
|
|
- pointsSuccessCount++;
|
|
|
- }
|
|
|
- }
|
|
|
- if (pointsSuccessCount > 0) {
|
|
|
- log.info("{} 观看奖励积分发放完成: liveId={}, 成功用户数={}/{}",
|
|
|
- LOG_PREFIX, liveId, pointsSuccessCount, userIds.size());
|
|
|
- } else {
|
|
|
- log.warn("{} 观看奖励积分发放全部失败: liveId={}, 用户数={}",
|
|
|
- LOG_PREFIX, liveId, userIds.size());
|
|
|
- }
|
|
|
- return pointsSuccessCount;
|
|
|
+ Set<Long> grantedUserIds = new HashSet<>();
|
|
|
|
|
|
- case 3:
|
|
|
- String actionCouponIdStr = config.getActionCouponId();
|
|
|
- if (StringUtils.isBlank(actionCouponIdStr)) {
|
|
|
- log.warn("直播间观看奖励配置为优惠券,但未配置优惠券ID,liveId={}", liveId);
|
|
|
- return 0;
|
|
|
- }
|
|
|
- Long actionCouponId = Long.parseLong(actionCouponIdStr);
|
|
|
- int actionCouponCount = resolveActionCouponCount(config);
|
|
|
- LiveCoupon watchRewardCoupon = liveCouponService.selectLiveCouponById(actionCouponId);
|
|
|
- List<LiveConsoleOpLogUser> couponRelations = bindCouponToUsers(live, userIds, actionCouponId, false, actionCouponCount);
|
|
|
- if (!couponRelations.isEmpty()) {
|
|
|
- LiveConsoleOpLog watchCouponOpLog = liveConsoleOpLogService.saveLog(
|
|
|
- liveId,
|
|
|
- LiveConsoleOpLog.OP_WATCH_REWARD_COUPON,
|
|
|
- LiveConsoleOpLog.HANDLE_AUTO,
|
|
|
- actionCouponId,
|
|
|
- resolveWatchRewardCouponBizName(watchRewardCoupon, actionCouponId, couponRelations.size())
|
|
|
- );
|
|
|
- liveConsoleOpLogService.bindOpLogUsers(watchCouponOpLog.getId(), liveId, couponRelations);
|
|
|
- Set<Long> notifiedUserIds = new HashSet<>();
|
|
|
- couponRelations.forEach(relation -> {
|
|
|
- if (relation.getUserId() != null && notifiedUserIds.add(relation.getUserId())) {
|
|
|
- sendCouponRewardMessage(liveId, relation.getUserId(), watchRewardCoupon, watchCouponOpLog);
|
|
|
- }
|
|
|
- });
|
|
|
- log.info("{} 观看奖励优惠券发放完成: liveId={}, 用户数={}, 每人张数={}",
|
|
|
- LOG_PREFIX, liveId, notifiedUserIds.size(), actionCouponCount);
|
|
|
- return notifiedUserIds.size();
|
|
|
+ if (config.hasAction(WATCH_REWARD_ACTION_POINTS)) {
|
|
|
+ grantedUserIds.addAll(grantWatchRewardPoints(live, config, userIds));
|
|
|
+ }
|
|
|
+
|
|
|
+ if (config.hasAction(WATCH_REWARD_ACTION_COUPON)) {
|
|
|
+ grantedUserIds.addAll(grantWatchRewardCoupons(live, config, userIds));
|
|
|
+ }
|
|
|
+
|
|
|
+ boolean hasUnhandled = actions.stream().anyMatch(a ->
|
|
|
+ a != WATCH_REWARD_ACTION_POINTS && a != WATCH_REWARD_ACTION_COUPON);
|
|
|
+ if (hasUnhandled) {
|
|
|
+ log.info("{} 观看奖励含暂不处理的动作类型: actions={}, liveId={}",
|
|
|
+ LOG_PREFIX, actions, liveId);
|
|
|
+ }
|
|
|
+
|
|
|
+ return grantedUserIds.size();
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 发放观看奖励积分
|
|
|
+ *
|
|
|
+ * @return 成功发放的用户ID集合
|
|
|
+ */
|
|
|
+ private Set<Long> grantWatchRewardPoints(Live live, LiveWatchConfig config, List<Long> userIds) {
|
|
|
+ Set<Long> successUserIds = new HashSet<>();
|
|
|
+ if (config.getScoreAmount() == null || config.getScoreAmount() <= 0) {
|
|
|
+ log.warn("{} 观看奖励积分配额无效: liveId={}, scoreAmount={}",
|
|
|
+ LOG_PREFIX, live.getLiveId(), config.getScoreAmount());
|
|
|
+ return successUserIds;
|
|
|
+ }
|
|
|
+ Long liveId = live.getLiveId();
|
|
|
+ saveUserRewardRecord(live, userIds, BigDecimal.valueOf(config.getScoreAmount()), 2);
|
|
|
+ LiveConsoleOpLog watchPointsOpLog = liveConsoleOpLogService.saveLog(
|
|
|
+ liveId,
|
|
|
+ LiveConsoleOpLog.OP_WATCH_REWARD_POINTS,
|
|
|
+ LiveConsoleOpLog.HANDLE_AUTO,
|
|
|
+ liveId,
|
|
|
+ resolveWatchRewardPointsBizName(config, userIds.size())
|
|
|
+ );
|
|
|
+ for (Long uid : userIds) {
|
|
|
+ if (grantWatchRewardIntegral(liveId, uid, config.getScoreAmount())) {
|
|
|
+ liveConsoleOpLogService.bindOpLogUser(watchPointsOpLog.getId(), liveId, uid);
|
|
|
+ webSocketServer.sendIntegralMessage(liveId, uid, config.getScoreAmount(), watchPointsOpLog);
|
|
|
+ successUserIds.add(uid);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (!successUserIds.isEmpty()) {
|
|
|
+ log.info("{} 观看奖励积分发放完成: liveId={}, 成功用户数={}/{}",
|
|
|
+ LOG_PREFIX, liveId, successUserIds.size(), userIds.size());
|
|
|
+ } else {
|
|
|
+ log.warn("{} 观看奖励积分发放全部失败: liveId={}, 用户数={}",
|
|
|
+ LOG_PREFIX, liveId, userIds.size());
|
|
|
+ }
|
|
|
+ return successUserIds;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 发放观看奖励优惠券
|
|
|
+ *
|
|
|
+ * @return 成功发放的用户ID集合
|
|
|
+ */
|
|
|
+ private Set<Long> grantWatchRewardCoupons(Live live, LiveWatchConfig config, List<Long> userIds) {
|
|
|
+ Set<Long> notifiedUserIds = new HashSet<>();
|
|
|
+ Long liveId = live.getLiveId();
|
|
|
+ String actionCouponIdStr = config.getActionCouponId();
|
|
|
+ if (StringUtils.isBlank(actionCouponIdStr)) {
|
|
|
+ log.warn("直播间观看奖励配置为优惠券,但未配置优惠券ID,liveId={}", liveId);
|
|
|
+ return notifiedUserIds;
|
|
|
+ }
|
|
|
+ Long actionCouponId = Long.parseLong(actionCouponIdStr);
|
|
|
+ int actionCouponCount = resolveActionCouponCount(config);
|
|
|
+ LiveCoupon watchRewardCoupon = liveCouponService.selectLiveCouponById(actionCouponId);
|
|
|
+ List<LiveConsoleOpLogUser> couponRelations = bindCouponToUsers(live, userIds, actionCouponId, false, actionCouponCount);
|
|
|
+ if (!couponRelations.isEmpty()) {
|
|
|
+ LiveConsoleOpLog watchCouponOpLog = liveConsoleOpLogService.saveLog(
|
|
|
+ liveId,
|
|
|
+ LiveConsoleOpLog.OP_WATCH_REWARD_COUPON,
|
|
|
+ LiveConsoleOpLog.HANDLE_AUTO,
|
|
|
+ actionCouponId,
|
|
|
+ resolveWatchRewardCouponBizName(watchRewardCoupon, actionCouponId, couponRelations.size())
|
|
|
+ );
|
|
|
+ liveConsoleOpLogService.bindOpLogUsers(watchCouponOpLog.getId(), liveId, couponRelations);
|
|
|
+ couponRelations.forEach(relation -> {
|
|
|
+ if (relation.getUserId() != null && notifiedUserIds.add(relation.getUserId())) {
|
|
|
+ sendCouponRewardMessage(liveId, relation.getUserId(), watchRewardCoupon, watchCouponOpLog);
|
|
|
}
|
|
|
- log.warn("{} 观看奖励优惠券发放无成功用户: liveId={}, couponId={}",
|
|
|
- LOG_PREFIX, liveId, actionCouponId);
|
|
|
- return 0;
|
|
|
-
|
|
|
- case 1:
|
|
|
- default:
|
|
|
- log.info("{} 观看奖励类型暂不处理: action={}, liveId={}",
|
|
|
- LOG_PREFIX, action, liveId);
|
|
|
- return 0;
|
|
|
+ });
|
|
|
+ log.info("{} 观看奖励优惠券发放完成: liveId={}, 用户数={}, 每人张数={}",
|
|
|
+ LOG_PREFIX, liveId, notifiedUserIds.size(), actionCouponCount);
|
|
|
+ return notifiedUserIds;
|
|
|
}
|
|
|
+ log.warn("{} 观看奖励优惠券发放无成功用户: liveId={}, couponId={}",
|
|
|
+ LOG_PREFIX, liveId, actionCouponId);
|
|
|
+ return notifiedUserIds;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
@@ -814,7 +860,7 @@ public class Task {
|
|
|
if (!Boolean.TRUE.equals(config.getEnabled())) {
|
|
|
return R.error("观看奖励未开启");
|
|
|
}
|
|
|
- if (config.getAction() == null || config.getAction().intValue() != 3) {
|
|
|
+ if (!config.hasAction(WATCH_REWARD_ACTION_COUPON)) {
|
|
|
return R.error("观看奖励类型不是优惠券,请传入 couponId");
|
|
|
}
|
|
|
String actionCouponIdStr = config.getActionCouponId();
|