|
|
@@ -19,6 +19,7 @@ import com.fs.live.vo.LiveCompletionCouponInfoVO;
|
|
|
import com.fs.live.vo.LiveCompletionCouponNotifyResult;
|
|
|
import com.fs.live.vo.LiveCompletionCouponStatusVO;
|
|
|
import com.fs.live.vo.LiveCompletionQuestionVO;
|
|
|
+import com.fs.live.vo.LiveRewardCouponItem;
|
|
|
import lombok.extern.slf4j.Slf4j;
|
|
|
import org.springframework.beans.BeanUtils;
|
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
|
@@ -86,6 +87,7 @@ public class LiveCompletionCouponServiceImpl implements ILiveCompletionCouponSer
|
|
|
vo.setCompletionRate(config.getCompletionRate());
|
|
|
vo.setCouponId(config.getCouponId());
|
|
|
vo.setCouponCount(config.getCouponCount());
|
|
|
+ vo.setCouponItems(config.resolveCouponItems());
|
|
|
vo.setFinishQuestionIds(config.getFinishQuestionIds());
|
|
|
if (config.isEnabled() && live != null && live.getDuration() != null && live.getDuration() > 0) {
|
|
|
vo.setRequiredDurationSeconds(calculateRequiredDuration(live.getDuration(), config.getCompletionRate()));
|
|
|
@@ -114,7 +116,10 @@ public class LiveCompletionCouponServiceImpl implements ILiveCompletionCouponSer
|
|
|
return result;
|
|
|
}
|
|
|
|
|
|
- result.setCoupon(loadCouponInfo(config.getCouponId()));
|
|
|
+ List<LiveRewardCouponItem> couponItems = config.resolveCouponItems();
|
|
|
+ List<LiveCompletionCouponInfoVO> couponInfos = loadCouponInfos(couponItems);
|
|
|
+ result.setCoupons(couponInfos);
|
|
|
+ result.setCoupon(couponInfos.isEmpty() ? null : couponInfos.get(0));
|
|
|
|
|
|
if (!isWatchRateEligible(liveId, userId, watchDuration, config)) {
|
|
|
log.info("[完课优惠券] 观看比例未达标(已在上层方法记录详情), liveId={}, userId={}", liveId, userId);
|
|
|
@@ -122,7 +127,7 @@ public class LiveCompletionCouponServiceImpl implements ILiveCompletionCouponSer
|
|
|
}
|
|
|
result.setEligible(true);
|
|
|
|
|
|
- if (hasIssuedToday(liveId, userId, config.getCouponId())) {
|
|
|
+ if (hasIssuedToday(liveId, userId)) {
|
|
|
log.info("[完课优惠券] 今日已发券, 跳过, liveId={}, userId={}", liveId, userId);
|
|
|
return result;
|
|
|
}
|
|
|
@@ -182,7 +187,7 @@ public class LiveCompletionCouponServiceImpl implements ILiveCompletionCouponSer
|
|
|
status.setHasQuestions(!questions.isEmpty());
|
|
|
status.setQuestions(questions);
|
|
|
status.setEligible(isWatchRateEligible(liveId, userId, watchDuration, config));
|
|
|
- status.setReceivedToday(hasIssuedToday(liveId, userId, config.getCouponId()));
|
|
|
+ status.setReceivedToday(hasIssuedToday(liveId, userId));
|
|
|
|
|
|
LiveCompletionAnswerRecord dbAnswer = liveCompletionAnswerRecordService.selectTodayLatest(liveId, userId);
|
|
|
if (dbAnswer != null) {
|
|
|
@@ -217,13 +222,13 @@ public class LiveCompletionCouponServiceImpl implements ILiveCompletionCouponSer
|
|
|
|
|
|
Long liveId = param.getLiveId();
|
|
|
CompletionCouponConfig config = resolveConfig(liveId);
|
|
|
- if (!config.isEnabled() || config.getCouponId() == null) {
|
|
|
+ if (!config.isEnabled() || config.resolveCouponItems().isEmpty()) {
|
|
|
throw new BaseException("完课优惠券未开启");
|
|
|
}
|
|
|
if (!isWatchRateEligible(liveId, userId, null, config)) {
|
|
|
throw new BaseException("未达到完课要求");
|
|
|
}
|
|
|
- if (hasIssuedToday(liveId, userId, config.getCouponId())) {
|
|
|
+ if (hasIssuedToday(liveId, userId)) {
|
|
|
throw new BaseException("今日福利券已领取");
|
|
|
}
|
|
|
|
|
|
@@ -252,13 +257,13 @@ public class LiveCompletionCouponServiceImpl implements ILiveCompletionCouponSer
|
|
|
}
|
|
|
Long liveId = param.getLiveId();
|
|
|
CompletionCouponConfig config = resolveConfig(liveId);
|
|
|
- if (!config.isEnabled() || config.getCouponId() == null) {
|
|
|
+ if (!config.isEnabled() || config.resolveCouponItems().isEmpty()) {
|
|
|
throw new BaseException("完课优惠券未开启");
|
|
|
}
|
|
|
if (!isWatchRateEligible(liveId, userId, null, config)) {
|
|
|
throw new BaseException("未达到完课要求");
|
|
|
}
|
|
|
- if (hasIssuedToday(liveId, userId, config.getCouponId())) {
|
|
|
+ if (hasIssuedToday(liveId, userId)) {
|
|
|
throw new BaseException("今日福利券已领取");
|
|
|
}
|
|
|
|
|
|
@@ -272,16 +277,23 @@ public class LiveCompletionCouponServiceImpl implements ILiveCompletionCouponSer
|
|
|
if (live == null) {
|
|
|
throw new BaseException("直播不存在");
|
|
|
}
|
|
|
- List<LiveCouponUser> couponUsers = issueCoupon(live, userId, config.getCouponId(), config.getCouponCount());
|
|
|
- if (couponUsers.isEmpty()) {
|
|
|
+ List<LiveCouponUser> allCouponUsers = new ArrayList<>();
|
|
|
+ for (LiveRewardCouponItem item : config.resolveCouponItems()) {
|
|
|
+ if (item == null || item.getCouponId() == null) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ List<LiveCouponUser> issued = issueCoupon(live, userId, item.getCouponId(), item.resolveCount());
|
|
|
+ allCouponUsers.addAll(issued);
|
|
|
+ }
|
|
|
+ if (allCouponUsers.isEmpty()) {
|
|
|
throw new BaseException("优惠券发放失败");
|
|
|
}
|
|
|
List<LiveConsoleOpLogUser> relations = new ArrayList<>();
|
|
|
- for (LiveCouponUser couponUser : couponUsers) {
|
|
|
+ for (LiveCouponUser couponUser : allCouponUsers) {
|
|
|
relations.add(new LiveConsoleOpLogUser(null, userId, liveId, couponUser.getId()));
|
|
|
}
|
|
|
liveConsoleOpLogService.bindOpLogUsers(opLog.getId(), liveId, relations);
|
|
|
- return couponUsers.get(0);
|
|
|
+ return allCouponUsers.get(0);
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
@@ -631,9 +643,8 @@ public class LiveCompletionCouponServiceImpl implements ILiveCompletionCouponSer
|
|
|
return couponUsers;
|
|
|
}
|
|
|
|
|
|
- private boolean hasIssuedToday(Long liveId, Long userId, Long couponId) {
|
|
|
+ private boolean hasIssuedToday(Long liveId, Long userId) {
|
|
|
LiveCouponUser query = new LiveCouponUser();
|
|
|
- query.setCouponId(couponId);
|
|
|
query.setUserId(userId.intValue());
|
|
|
query.setType(COMPLETION_COUPON_TYPE + "-" + liveId);
|
|
|
List<LiveCouponUser> existingList = liveCouponUserService.selectLiveCouponUserList(query);
|
|
|
@@ -646,6 +657,24 @@ public class LiveCompletionCouponServiceImpl implements ILiveCompletionCouponSer
|
|
|
&& item.getCreateTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDate().equals(today));
|
|
|
}
|
|
|
|
|
|
+ private List<LiveCompletionCouponInfoVO> loadCouponInfos(List<LiveRewardCouponItem> items) {
|
|
|
+ if (items == null || items.isEmpty()) {
|
|
|
+ return Collections.emptyList();
|
|
|
+ }
|
|
|
+ List<LiveCompletionCouponInfoVO> list = new ArrayList<>();
|
|
|
+ for (LiveRewardCouponItem item : items) {
|
|
|
+ if (item == null || item.getCouponId() == null) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ LiveCompletionCouponInfoVO vo = loadCouponInfo(item.getCouponId());
|
|
|
+ if (vo != null) {
|
|
|
+ vo.setCount(item.resolveCount());
|
|
|
+ list.add(vo);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return list;
|
|
|
+ }
|
|
|
+
|
|
|
private LiveCompletionCouponInfoVO loadCouponInfo(Long couponId) {
|
|
|
if (couponId == null) {
|
|
|
return null;
|
|
|
@@ -727,20 +756,20 @@ public class LiveCompletionCouponServiceImpl implements ILiveCompletionCouponSer
|
|
|
return config;
|
|
|
}
|
|
|
|
|
|
- String finishCouponId = jsonConfig.getString("finishCouponId");
|
|
|
- if (StringUtils.isEmpty(finishCouponId)) {
|
|
|
+ List<LiveRewardCouponItem> couponItems = LiveCompletionConfigUtils.resolveFinishCoupons(jsonConfig);
|
|
|
+ if (couponItems == null || couponItems.isEmpty()) {
|
|
|
return config;
|
|
|
}
|
|
|
|
|
|
config.setEnabled(true);
|
|
|
- config.setCouponId(Long.parseLong(finishCouponId));
|
|
|
+ config.setCouponItems(couponItems);
|
|
|
+ // 兼容旧字段:首张券
|
|
|
+ config.setCouponId(couponItems.get(0).getCouponId());
|
|
|
+ config.setCouponCount(couponItems.get(0).resolveCount());
|
|
|
config.setFinishQuestionIds(jsonConfig.getString("finishQuestionIds"));
|
|
|
|
|
|
Integer completionRate = jsonConfig.getInteger("completionRate");
|
|
|
config.setCompletionRate(completionRate != null && completionRate > 0 && completionRate <= 100 ? completionRate : 90);
|
|
|
-
|
|
|
- Integer finishCouponCount = jsonConfig.getInteger("finishCouponCount");
|
|
|
- config.setCouponCount(finishCouponCount != null && finishCouponCount > 0 ? finishCouponCount : 1);
|
|
|
} catch (Exception e) {
|
|
|
log.warn("解析完课优惠券配置失败, liveId={}", live.getLiveId(), e);
|
|
|
return disabledConfig();
|
|
|
@@ -753,6 +782,7 @@ public class LiveCompletionCouponServiceImpl implements ILiveCompletionCouponSer
|
|
|
config.setEnabled(false);
|
|
|
config.setCompletionRate(90);
|
|
|
config.setCouponCount(1);
|
|
|
+ config.setCouponItems(Collections.emptyList());
|
|
|
return config;
|
|
|
}
|
|
|
|
|
|
@@ -801,6 +831,7 @@ public class LiveCompletionCouponServiceImpl implements ILiveCompletionCouponSer
|
|
|
private Integer completionRate;
|
|
|
private Long couponId;
|
|
|
private Integer couponCount;
|
|
|
+ private List<LiveRewardCouponItem> couponItems;
|
|
|
private String finishQuestionIds;
|
|
|
|
|
|
public boolean isEnabled() {
|
|
|
@@ -835,6 +866,14 @@ public class LiveCompletionCouponServiceImpl implements ILiveCompletionCouponSer
|
|
|
this.couponCount = couponCount;
|
|
|
}
|
|
|
|
|
|
+ public List<LiveRewardCouponItem> getCouponItems() {
|
|
|
+ return couponItems;
|
|
|
+ }
|
|
|
+
|
|
|
+ public void setCouponItems(List<LiveRewardCouponItem> couponItems) {
|
|
|
+ this.couponItems = couponItems;
|
|
|
+ }
|
|
|
+
|
|
|
public String getFinishQuestionIds() {
|
|
|
return finishQuestionIds;
|
|
|
}
|
|
|
@@ -842,6 +881,16 @@ public class LiveCompletionCouponServiceImpl implements ILiveCompletionCouponSer
|
|
|
public void setFinishQuestionIds(String finishQuestionIds) {
|
|
|
this.finishQuestionIds = finishQuestionIds;
|
|
|
}
|
|
|
+
|
|
|
+ public List<LiveRewardCouponItem> resolveCouponItems() {
|
|
|
+ if (couponItems != null && !couponItems.isEmpty()) {
|
|
|
+ return couponItems;
|
|
|
+ }
|
|
|
+ if (couponId != null) {
|
|
|
+ return Collections.singletonList(new LiveRewardCouponItem(couponId, couponCount));
|
|
|
+ }
|
|
|
+ return Collections.emptyList();
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
private static class AnswerRecord {
|