|
|
@@ -79,6 +79,83 @@ public class LiveCompletionPointsController extends AppBaseController {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * 获取直播间信息并验证(公共方法)
|
|
|
+ * @param liveId 直播间ID
|
|
|
+ * @return Live对象,如果不存在或未开启奖励则返回null
|
|
|
+ */
|
|
|
+ private Live getLiveAndValidate(Long liveId) {
|
|
|
+ Live live = liveService.selectLiveByLiveId(liveId);
|
|
|
+ if (live == null) {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ if (!checkWatchRewardEnabled(live)) {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ return live;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 解析直播间配置并获取看课时长(公共方法)
|
|
|
+ * @param live 直播间信息
|
|
|
+ * @return 看课时长(秒),如果未配置则返回null
|
|
|
+ */
|
|
|
+ private Long parseRequiredWatchDuration(Live live) {
|
|
|
+ if (live == null) {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ String configJson = live.getConfigJson();
|
|
|
+ if (configJson == null || configJson.isEmpty()) {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ try {
|
|
|
+ LiveWatchConfig config = JSON.parseObject(configJson, LiveWatchConfig.class);
|
|
|
+ if (config != null && config.getWatchDuration() != null) {
|
|
|
+ // watchDuration是分钟,转换为秒
|
|
|
+ return config.getWatchDuration() * 60;
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ logger.warn("解析直播间配置失败: {}", e.getMessage());
|
|
|
+ }
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取或创建完课记录(公共方法)
|
|
|
+ * @param liveId 直播间ID
|
|
|
+ * @param userId 用户ID
|
|
|
+ * @return 完课记录
|
|
|
+ */
|
|
|
+ private LiveCompletionPointsRecord getOrCreateRecord(Long liveId, Long userId) {
|
|
|
+ LiveCompletionPointsRecord record = completionPointsRecordMapper.selectLatestByUserAndLiveId(liveId, userId);
|
|
|
+ if (record == null) {
|
|
|
+ record = completionPointsRecordService.createCompletionRecord(liveId, userId);
|
|
|
+ }
|
|
|
+ return record;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 计算完课比例(公共方法)
|
|
|
+ * @param watchDuration 观看时长(秒)
|
|
|
+ * @param targetDuration 目标时长(秒)
|
|
|
+ * @return 完课比例(0-100)
|
|
|
+ */
|
|
|
+ private BigDecimal calculateCompletionRate(Long watchDuration, Long targetDuration) {
|
|
|
+ if (targetDuration == null || targetDuration <= 0) {
|
|
|
+ return BigDecimal.ZERO;
|
|
|
+ }
|
|
|
+ BigDecimal rate = BigDecimal.valueOf(watchDuration != null ? watchDuration : 0L)
|
|
|
+ .multiply(BigDecimal.valueOf(100))
|
|
|
+ .divide(BigDecimal.valueOf(targetDuration), 2, java.math.RoundingMode.HALF_UP);
|
|
|
+ if (rate.compareTo(BigDecimal.valueOf(100)) > 0) {
|
|
|
+ rate = BigDecimal.valueOf(100);
|
|
|
+ }
|
|
|
+ if (rate.compareTo(BigDecimal.ZERO) < 0) {
|
|
|
+ rate = BigDecimal.ZERO;
|
|
|
+ }
|
|
|
+ return rate;
|
|
|
+ }
|
|
|
+
|
|
|
/**
|
|
|
* 领取完课积分
|
|
|
*/
|
|
|
@@ -170,40 +247,19 @@ public class LiveCompletionPointsController extends AppBaseController {
|
|
|
Long userId = Long.parseLong(getUserId());
|
|
|
|
|
|
try {
|
|
|
- // 1. 获取直播间信息
|
|
|
- Live live = liveService.selectLiveByLiveId(liveId);
|
|
|
+ // 1. 获取直播间信息并验证(复用公共方法)
|
|
|
+ Live live = getLiveAndValidate(liveId);
|
|
|
if (live == null) {
|
|
|
- return R.error("直播间不存在");
|
|
|
- }
|
|
|
- // 2. 检查直播间是否开启观看积分奖励
|
|
|
- if (!checkWatchRewardEnabled(live)) {
|
|
|
- return R.error(406, "直播间未开启直播观看奖励");
|
|
|
+ return R.error(406, "直播间不存在或未开启直播观看奖励");
|
|
|
}
|
|
|
|
|
|
- // 2. 查询当前用户和当前直播间的最近一次完课记录(不限制日期)
|
|
|
- LiveCompletionPointsRecord record = completionPointsRecordMapper.selectLatestByUserAndLiveId(liveId, userId);
|
|
|
+ // 2. 获取或创建完课记录(复用公共方法)
|
|
|
+ LiveCompletionPointsRecord record = getOrCreateRecord(liveId, userId);
|
|
|
|
|
|
- // 3. 如果没有记录,查询直播间配置并生成记录
|
|
|
- if (record == null) {
|
|
|
- record = completionPointsRecordService.createCompletionRecord(liveId, userId);
|
|
|
- }
|
|
|
+ // 3. 获取看课时长配置(复用公共方法)
|
|
|
+ Long requiredWatchDuration = parseRequiredWatchDuration(live);
|
|
|
|
|
|
- // 4. 获取看课时长配置(从直播间配置1中获取)
|
|
|
- Long requiredWatchDuration = null;
|
|
|
- String configJson = live.getConfigJson();
|
|
|
- if (configJson != null && !configJson.isEmpty()) {
|
|
|
- try {
|
|
|
- LiveWatchConfig config = JSON.parseObject(configJson, LiveWatchConfig.class);
|
|
|
- if (config != null && config.getWatchDuration() != null) {
|
|
|
- // watchDuration是分钟,转换为秒
|
|
|
- requiredWatchDuration = config.getWatchDuration() * 60;
|
|
|
- }
|
|
|
- } catch (Exception e) {
|
|
|
- logger.warn("解析直播间配置失败: {}", e.getMessage());
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- // 5. 计算剩余时长
|
|
|
+ // 4. 计算剩余时长
|
|
|
RemainingTimeVO vo = new RemainingTimeVO();
|
|
|
Long videoDuration = live.getDuration() != null ? live.getDuration() : 0L;
|
|
|
Long watchDuration = record != null && record.getWatchDuration() != null
|
|
|
@@ -216,19 +272,11 @@ public class LiveCompletionPointsController extends AppBaseController {
|
|
|
Long targetDuration = requiredWatchDuration != null ? requiredWatchDuration : videoDuration;
|
|
|
vo.setRemainingTime(Math.max(0, targetDuration - watchDuration));
|
|
|
|
|
|
- // 使用RemainingTime和videoDuration计算完课比例
|
|
|
- // 先计算基于videoDuration的剩余时长
|
|
|
- if (videoDuration > 0) {
|
|
|
- BigDecimal completionRate = BigDecimal.valueOf(targetDuration)
|
|
|
- .multiply(BigDecimal.valueOf(100))
|
|
|
- .divide(BigDecimal.valueOf(videoDuration), 2, java.math.RoundingMode.HALF_UP);
|
|
|
- if (completionRate.compareTo(BigDecimal.valueOf(100)) > 0) {
|
|
|
- completionRate = BigDecimal.valueOf(100);
|
|
|
- }
|
|
|
- if (completionRate.compareTo(BigDecimal.ZERO) < 0) {
|
|
|
- completionRate = BigDecimal.ZERO;
|
|
|
- }
|
|
|
- vo.setCompletionRate(completionRate);
|
|
|
+ // 计算完课比例(复用公共方法)
|
|
|
+ if (videoDuration > 0 && watchDuration > 0) {
|
|
|
+ vo.setCompletionRate(calculateCompletionRate(watchDuration, targetDuration));
|
|
|
+ } else {
|
|
|
+ vo.setCompletionRate(BigDecimal.ZERO);
|
|
|
}
|
|
|
vo.setHasReceived(record != null && record.getReceiveStatus() != null && record.getReceiveStatus() == 1);
|
|
|
|
|
|
@@ -249,18 +297,13 @@ public class LiveCompletionPointsController extends AppBaseController {
|
|
|
Long userId = Long.parseLong(getUserId());
|
|
|
|
|
|
try {
|
|
|
- // 1. 获取直播间信息
|
|
|
- Live live = liveService.selectLiveByLiveId(liveId);
|
|
|
+ // 1. 获取直播间信息并验证(复用公共方法)
|
|
|
+ Live live = getLiveAndValidate(liveId);
|
|
|
if (live == null) {
|
|
|
- return R.error("直播间不存在");
|
|
|
- }
|
|
|
-
|
|
|
- // 2. 检查直播间是否开启观看积分奖励
|
|
|
- if (!checkWatchRewardEnabled(live)) {
|
|
|
- return R.error(406, "直播间未开启直播观看奖励");
|
|
|
+ return R.error(406, "直播间不存在或未开启直播观看奖励");
|
|
|
}
|
|
|
|
|
|
- // 3. 判断当前时间是否在直播期间(状态为2,直播中)
|
|
|
+ // 2. 判断当前时间是否在直播期间(状态为2,直播中)
|
|
|
boolean isLiveInProgress = false;
|
|
|
LocalDateTime now = LocalDateTime.now();
|
|
|
|
|
|
@@ -277,10 +320,10 @@ public class LiveCompletionPointsController extends AppBaseController {
|
|
|
return R.error("当前不在直播期间,无法更新看课时长");
|
|
|
}
|
|
|
|
|
|
- // 4. 查询当前直播间的完课记录(不限制日期)
|
|
|
+ // 3. 查询当前直播间的完课记录(不限制日期)
|
|
|
LiveCompletionPointsRecord record = completionPointsRecordMapper.selectLatestByUserAndLiveId(liveId, userId);
|
|
|
|
|
|
- // 5. 计算看课时长
|
|
|
+ // 4. 计算看课时长
|
|
|
Date updateTime = null;
|
|
|
if (record != null && record.getUpdateTime() != null) {
|
|
|
updateTime = record.getUpdateTime();
|
|
|
@@ -306,7 +349,7 @@ public class LiveCompletionPointsController extends AppBaseController {
|
|
|
timeDiff = (currentTime.getTime() - startTime.getTime()) / 1000; // 转换为秒
|
|
|
}
|
|
|
|
|
|
- // 6. 如果请求传入的时间大于这个时间差,就使用计算出的看课时长,否则使用请求传入的时长
|
|
|
+ // 5. 如果请求传入的时间大于这个时间差,就使用计算出的看课时长,否则使用请求传入的时长
|
|
|
Long finalWatchDuration;
|
|
|
if (watchDuration > timeDiff) {
|
|
|
// 请求传入的时间大于时间差,使用计算出的看课时长
|
|
|
@@ -316,55 +359,53 @@ public class LiveCompletionPointsController extends AppBaseController {
|
|
|
finalWatchDuration = watchDuration;
|
|
|
}
|
|
|
|
|
|
- // 7. 更新完课记录中的看课时长
|
|
|
+ // 6. 更新完课记录中的看课时长(只更新变化的字段)
|
|
|
if (record == null) {
|
|
|
// 如果没有记录,先创建记录
|
|
|
record = completionPointsRecordService.createCompletionRecord(liveId, userId);
|
|
|
if (record == null) {
|
|
|
return R.error(406, "直播间未开启直播观看奖励");
|
|
|
}
|
|
|
+ // 只更新 watchDuration 字段
|
|
|
+ LiveCompletionPointsRecord updateRecord = new LiveCompletionPointsRecord();
|
|
|
+ updateRecord.setId(record.getId());
|
|
|
+ updateRecord.setWatchDuration(finalWatchDuration);
|
|
|
+ completionPointsRecordMapper.updateRecord(updateRecord);
|
|
|
record.setWatchDuration(finalWatchDuration);
|
|
|
- completionPointsRecordMapper.updateRecord(record);
|
|
|
} else {
|
|
|
- // 更新现有记录的看课时长
|
|
|
+ // 更新现有记录的看课时长(只更新变化的字段)
|
|
|
Long currentWatchDuration = record.getWatchDuration() != null
|
|
|
? record.getWatchDuration() : 0L;
|
|
|
- record.setWatchDuration(currentWatchDuration + finalWatchDuration);
|
|
|
+ Long newWatchDuration = currentWatchDuration + finalWatchDuration;
|
|
|
|
|
|
- // 重新计算完课比例(基于看课时长配置)
|
|
|
+ // 获取看课时长配置(复用公共方法)
|
|
|
+ Long requiredWatchDuration = parseRequiredWatchDuration(live);
|
|
|
Long videoDuration = live.getDuration();
|
|
|
- String configJson = live.getConfigJson();
|
|
|
- Long requiredWatchDuration = null;
|
|
|
-
|
|
|
- // 从直播间配置获取看课时长
|
|
|
- if (configJson != null && !configJson.isEmpty()) {
|
|
|
- try {
|
|
|
- LiveWatchConfig config = JSON.parseObject(configJson, LiveWatchConfig.class);
|
|
|
- if (config != null && config.getWatchDuration() != null) {
|
|
|
- // watchDuration是分钟,转换为秒
|
|
|
- requiredWatchDuration = config.getWatchDuration() * 60;
|
|
|
- }
|
|
|
- } catch (Exception e) {
|
|
|
- logger.warn("解析直播间配置失败: {}", e.getMessage());
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- // 如果配置了看课时长,使用看课时长计算比例;否则使用视频总时长
|
|
|
Long targetDuration = requiredWatchDuration != null ? requiredWatchDuration : videoDuration;
|
|
|
+
|
|
|
+ // 计算完课比例(复用公共方法)
|
|
|
+ BigDecimal completionRate = null;
|
|
|
if (targetDuration != null && targetDuration > 0) {
|
|
|
- BigDecimal completionRate = BigDecimal.valueOf(record.getWatchDuration())
|
|
|
- .multiply(BigDecimal.valueOf(100))
|
|
|
- .divide(BigDecimal.valueOf(targetDuration), 2, java.math.RoundingMode.HALF_UP);
|
|
|
- if (completionRate.compareTo(BigDecimal.valueOf(100)) > 0) {
|
|
|
- completionRate = BigDecimal.valueOf(100);
|
|
|
- }
|
|
|
- record.setCompletionRate(completionRate);
|
|
|
+ completionRate = calculateCompletionRate(newWatchDuration, targetDuration);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 只更新变化的字段:watchDuration 和 completionRate
|
|
|
+ LiveCompletionPointsRecord updateRecord = new LiveCompletionPointsRecord();
|
|
|
+ updateRecord.setId(record.getId());
|
|
|
+ updateRecord.setWatchDuration(newWatchDuration);
|
|
|
+ if (completionRate != null) {
|
|
|
+ updateRecord.setCompletionRate(completionRate);
|
|
|
}
|
|
|
|
|
|
- int updateResult = completionPointsRecordMapper.updateRecord(record);
|
|
|
+ int updateResult = completionPointsRecordMapper.updateRecord(updateRecord);
|
|
|
if (updateResult <= 0) {
|
|
|
return R.error("更新看课时间失败");
|
|
|
}
|
|
|
+ // 更新本地对象用于返回
|
|
|
+ record.setWatchDuration(newWatchDuration);
|
|
|
+ if (completionRate != null) {
|
|
|
+ record.setCompletionRate(completionRate);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
UpdateWatchDurationVO vo = new UpdateWatchDurationVO();
|
|
|
@@ -402,46 +443,29 @@ public class LiveCompletionPointsController extends AppBaseController {
|
|
|
}
|
|
|
|
|
|
try {
|
|
|
- // 1. 获取直播间信息和配置
|
|
|
- Live live = liveService.selectLiveByLiveId(liveId);
|
|
|
+ // 1. 获取直播间信息并验证(复用公共方法)
|
|
|
+ Live live = getLiveAndValidate(liveId);
|
|
|
if (live == null) {
|
|
|
- return R.error("直播间不存在");
|
|
|
+ return R.error(406, "直播间不存在或未开启直播观看奖励");
|
|
|
}
|
|
|
|
|
|
- // 2. 检查直播间是否开启观看积分奖励
|
|
|
- if (!checkWatchRewardEnabled(live)) {
|
|
|
- return R.error(406, "直播间未开启直播观看奖励");
|
|
|
- }
|
|
|
-
|
|
|
- // 3. 查询当前用户和当前直播间的最近一次完课记录(不限制日期)
|
|
|
+ // 2. 查询当前用户和当前直播间的最近一次完课记录(不限制日期)
|
|
|
LiveCompletionPointsRecord record = completionPointsRecordMapper.selectLatestByUserAndLiveId(liveId, userId);
|
|
|
|
|
|
if (record == null) {
|
|
|
return R.error("您还没有看课记录,无法领取积分");
|
|
|
}
|
|
|
|
|
|
- // 4. 检查看课记录里面的时长是否达到完课标准
|
|
|
+ // 3. 检查看课记录里面的时长是否达到完课标准
|
|
|
Long watchDuration = record.getWatchDuration();
|
|
|
if (watchDuration == null || watchDuration <= 0) {
|
|
|
return R.error("您的看课时长不足,无法领取积分");
|
|
|
}
|
|
|
|
|
|
- // 5. 从直播间配置获取看课时长(配置1中的watchDuration)
|
|
|
- String configJson = live.getConfigJson();
|
|
|
- Long requiredWatchDuration = null;
|
|
|
- if (configJson != null && !configJson.isEmpty()) {
|
|
|
- try {
|
|
|
- LiveWatchConfig config = JSON.parseObject(configJson, LiveWatchConfig.class);
|
|
|
- if (config != null && config.getWatchDuration() != null) {
|
|
|
- // watchDuration是分钟,转换为秒
|
|
|
- requiredWatchDuration = config.getWatchDuration() * 60;
|
|
|
- }
|
|
|
- } catch (Exception e) {
|
|
|
- logger.warn("解析直播间配置失败: {}", e.getMessage());
|
|
|
- }
|
|
|
- }
|
|
|
+ // 4. 获取看课时长配置(复用公共方法)
|
|
|
+ Long requiredWatchDuration = parseRequiredWatchDuration(live);
|
|
|
|
|
|
- // 6. 判断是否达到完课标准(使用看课时长而不是完课比例)
|
|
|
+ // 5. 判断是否达到完课标准(使用看课时长而不是完课比例)
|
|
|
if (requiredWatchDuration != null && watchDuration < requiredWatchDuration) {
|
|
|
// 转换为分钟显示
|
|
|
long requiredMinutes = requiredWatchDuration / 60;
|
|
|
@@ -449,12 +473,13 @@ public class LiveCompletionPointsController extends AppBaseController {
|
|
|
return R.error("您的看课时长未达到标准(" + requiredMinutes + "分钟),当前看课时长:" + currentMinutes + "分钟");
|
|
|
}
|
|
|
|
|
|
- // 7. 检查是否已领取
|
|
|
+ // 6. 检查是否已领取
|
|
|
if (record.getReceiveStatus() != null && record.getReceiveStatus() == 1) {
|
|
|
return R.error("该完课积分已领取");
|
|
|
}
|
|
|
|
|
|
- // 8. 领取积分(更新看课记录的领取状态,给用户加积分)
|
|
|
+ // 7. 领取积分(更新看课记录的领取状态,给用户加积分)
|
|
|
+ // Service层已经实现了只更新 receiveStatus 和 receiveTime 的部分更新
|
|
|
LiveCompletionPointsRecord receivedRecord = completionPointsRecordService.receiveCompletionPoints(record.getId(), userId);
|
|
|
|
|
|
ReceivePointsVO vo = new ReceivePointsVO();
|