|
|
@@ -11,13 +11,11 @@ import com.fs.live.domain.LiveConsoleOpLogUser;
|
|
|
import com.fs.live.domain.LiveCoupon;
|
|
|
import com.fs.live.domain.LiveCouponIssue;
|
|
|
import com.fs.live.domain.LiveCouponIssueRelation;
|
|
|
-import com.fs.live.domain.LiveCouponIssueUser;
|
|
|
import com.fs.live.domain.LiveCouponUser;
|
|
|
import com.fs.live.domain.LiveLotteryConf;
|
|
|
import com.fs.live.domain.LiveRedConf;
|
|
|
import com.fs.live.mapper.LiveConsoleOpLogMapper;
|
|
|
import com.fs.live.mapper.LiveConsoleOpLogUserMapper;
|
|
|
-import com.fs.live.mapper.LiveCouponIssueUserMapper;
|
|
|
import com.fs.live.mapper.LiveCouponMapper;
|
|
|
import com.fs.live.mapper.LiveMapper;
|
|
|
import com.fs.live.service.ILiveConsoleOpLogService;
|
|
|
@@ -77,12 +75,11 @@ public class LiveConsoleOpLogServiceImpl implements ILiveConsoleOpLogService {
|
|
|
@Autowired
|
|
|
private LiveCouponMapper liveCouponMapper;
|
|
|
|
|
|
+ /** 中控台发券 live_coupon_user.type 前缀(按直播间隔离:live-{liveId}) */
|
|
|
+ private static final String LIVE_COUPON_USER_TYPE_PREFIX = "live-";
|
|
|
/** 完课优惠券 live_coupon_user.type 前缀 */
|
|
|
private static final String COMPLETION_COUPON_USER_TYPE_PREFIX = "4-";
|
|
|
|
|
|
- @Autowired
|
|
|
- private LiveCouponIssueUserMapper liveCouponIssueUserMapper;
|
|
|
-
|
|
|
@Autowired
|
|
|
private ILiveCouponUserService liveCouponUserService;
|
|
|
|
|
|
@@ -265,8 +262,10 @@ public class LiveConsoleOpLogServiceImpl implements ILiveConsoleOpLogService {
|
|
|
.filter(Objects::nonNull)
|
|
|
.collect(Collectors.toSet());
|
|
|
}
|
|
|
- Set<Long> claimedCouponIssueIds = loadUserClaimedCouponIssueIds(userId);
|
|
|
+ // 中控台发券以 live_coupon_user(type=live-{liveId}) 为准,避免跨直播间共用 issue 误判已领取
|
|
|
+ Set<Long> claimedLiveCouponIds = loadUserClaimedLiveCouponIds(liveId, userId);
|
|
|
Set<Long> claimedCompletionCouponIds = loadUserClaimedCompletionCouponIds(liveId, userId);
|
|
|
+ Map<Long, Long> issueCouponIdMap = resolveIssueCouponIdMap(opLogs);
|
|
|
|
|
|
Date now = DateUtils.getNowDate();
|
|
|
Live live = liveMapper.selectLiveByLiveId(liveId);
|
|
|
@@ -281,7 +280,8 @@ public class LiveConsoleOpLogServiceImpl implements ILiveConsoleOpLogService {
|
|
|
&& opLog.getOpType() == LiveConsoleOpLog.OP_COMPLETION_POINTS) {
|
|
|
continue;
|
|
|
}
|
|
|
- boolean claimed = isUserClaimedOpLog(opLog, claimedOpLogIds, claimedCouponIssueIds, claimedCompletionCouponIds);
|
|
|
+ boolean claimed = isUserClaimedOpLog(opLog, claimedOpLogIds, claimedLiveCouponIds,
|
|
|
+ claimedCompletionCouponIds, issueCouponIdMap);
|
|
|
int status = resolveOpLogStatus(opLog, claimed, now, live);
|
|
|
LiveConsoleOpLogRecordVo recordVo = LiveConsoleOpLogRecordVo.from(opLog, status);
|
|
|
fillCouponType(recordVo, opLog, couponTypeMap);
|
|
|
@@ -350,30 +350,26 @@ public class LiveConsoleOpLogServiceImpl implements ILiveConsoleOpLogService {
|
|
|
recordVo.setCouponType(couponTypeMap.get(opLog.getBizId()));
|
|
|
}
|
|
|
|
|
|
- private Set<Long> loadUserClaimedCouponIssueIds(Long userId) {
|
|
|
- if (userId == null) {
|
|
|
- return Collections.emptySet();
|
|
|
- }
|
|
|
- LiveCouponIssueUser query = new LiveCouponIssueUser();
|
|
|
- query.setUserId(userId);
|
|
|
- query.setIsDel(0);
|
|
|
- List<LiveCouponIssueUser> issueUsers = liveCouponIssueUserMapper.selectLiveCouponIssueUserList(query);
|
|
|
- if (issueUsers == null || issueUsers.isEmpty()) {
|
|
|
- return Collections.emptySet();
|
|
|
- }
|
|
|
- return issueUsers.stream()
|
|
|
- .map(LiveCouponIssueUser::getIssueId)
|
|
|
- .filter(Objects::nonNull)
|
|
|
- .collect(Collectors.toSet());
|
|
|
+ /**
|
|
|
+ * 当前直播间中控台发券已领取的优惠券 ID(live_coupon_user.type = live-{liveId})。
|
|
|
+ * 按直播间隔离,避免同一 issue 绑定到多个直播间时跨场误判。
|
|
|
+ */
|
|
|
+ private Set<Long> loadUserClaimedLiveCouponIds(Long liveId, Long userId) {
|
|
|
+ return loadUserClaimedCouponIdsByType(userId, LIVE_COUPON_USER_TYPE_PREFIX + liveId);
|
|
|
}
|
|
|
|
|
|
private Set<Long> loadUserClaimedCompletionCouponIds(Long liveId, Long userId) {
|
|
|
- if (liveId == null || userId == null) {
|
|
|
+ return loadUserClaimedCouponIdsByType(userId, COMPLETION_COUPON_USER_TYPE_PREFIX + liveId);
|
|
|
+ }
|
|
|
+
|
|
|
+ private Set<Long> loadUserClaimedCouponIdsByType(Long userId, String type) {
|
|
|
+ if (userId == null || StringUtils.isEmpty(type)) {
|
|
|
return Collections.emptySet();
|
|
|
}
|
|
|
LiveCouponUser query = new LiveCouponUser();
|
|
|
query.setUserId(userId.intValue());
|
|
|
- query.setType(COMPLETION_COUPON_USER_TYPE_PREFIX + liveId);
|
|
|
+ query.setType(type);
|
|
|
+ query.setIsDel(0);
|
|
|
List<LiveCouponUser> couponUsers = liveCouponUserService.selectLiveCouponUserList(query);
|
|
|
if (couponUsers == null || couponUsers.isEmpty()) {
|
|
|
return Collections.emptySet();
|
|
|
@@ -384,12 +380,35 @@ public class LiveConsoleOpLogServiceImpl implements ILiveConsoleOpLogService {
|
|
|
.collect(Collectors.toSet());
|
|
|
}
|
|
|
|
|
|
+ /** 优惠券展示留存 bizId=issueId → couponId,用于对齐 live_coupon_user.coupon_id */
|
|
|
+ private Map<Long, Long> resolveIssueCouponIdMap(List<LiveConsoleOpLog> opLogs) {
|
|
|
+ Map<Long, Long> issueCouponIdMap = new HashMap<>();
|
|
|
+ if (opLogs == null || opLogs.isEmpty()) {
|
|
|
+ return issueCouponIdMap;
|
|
|
+ }
|
|
|
+ List<Long> issueIds = opLogs.stream()
|
|
|
+ .filter(log -> log.getOpType() != null && log.getBizId() != null
|
|
|
+ && (log.getOpType() == LiveConsoleOpLog.OP_COUPON_SHOW
|
|
|
+ || log.getOpType() == LiveConsoleOpLog.OP_VERIFY_COUPON_SHOW))
|
|
|
+ .map(LiveConsoleOpLog::getBizId)
|
|
|
+ .distinct()
|
|
|
+ .collect(Collectors.toList());
|
|
|
+ for (Long issueId : issueIds) {
|
|
|
+ LiveCouponIssue issue = liveCouponIssueService.selectLiveCouponIssueById(issueId);
|
|
|
+ if (issue != null && issue.getCouponId() != null) {
|
|
|
+ issueCouponIdMap.put(issueId, issue.getCouponId());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return issueCouponIdMap;
|
|
|
+ }
|
|
|
+
|
|
|
/**
|
|
|
* 判断用户是否已领取/参与该条留存。
|
|
|
- * 普通优惠券 additionally 以 live_coupon_issue_user 为准,避免领券时未绑定 opLog 被误判为已结束。
|
|
|
+ * 普通优惠券以当前直播间 live_coupon_user 为准,避免领券未绑定 opLog 或跨直播间共用 issue 误判。
|
|
|
*/
|
|
|
private boolean isUserClaimedOpLog(LiveConsoleOpLog opLog, Set<Long> claimedOpLogIds,
|
|
|
- Set<Long> claimedCouponIssueIds, Set<Long> claimedCompletionCouponIds) {
|
|
|
+ Set<Long> claimedLiveCouponIds, Set<Long> claimedCompletionCouponIds,
|
|
|
+ Map<Long, Long> issueCouponIdMap) {
|
|
|
if (opLog == null) {
|
|
|
return false;
|
|
|
}
|
|
|
@@ -401,10 +420,11 @@ public class LiveConsoleOpLogServiceImpl implements ILiveConsoleOpLogService {
|
|
|
}
|
|
|
int opType = opLog.getOpType();
|
|
|
if (opType == LiveConsoleOpLog.OP_COUPON_SHOW || opType == LiveConsoleOpLog.OP_VERIFY_COUPON_SHOW) {
|
|
|
- return claimedCouponIssueIds.contains(opLog.getBizId());
|
|
|
+ Long couponId = issueCouponIdMap != null ? issueCouponIdMap.get(opLog.getBizId()) : null;
|
|
|
+ return couponId != null && claimedLiveCouponIds != null && claimedLiveCouponIds.contains(couponId);
|
|
|
}
|
|
|
if (opType == LiveConsoleOpLog.OP_COMPLETION_COUPON) {
|
|
|
- return claimedCompletionCouponIds.contains(opLog.getBizId());
|
|
|
+ return claimedCompletionCouponIds != null && claimedCompletionCouponIds.contains(opLog.getBizId());
|
|
|
}
|
|
|
return false;
|
|
|
}
|