|
|
@@ -269,6 +269,125 @@ public class LiveCompletionPointsRecordServiceImpl implements ILiveCompletionPoi
|
|
|
return recordMapper.selectByUserAndDate(liveId, userId, date);
|
|
|
}
|
|
|
|
|
|
+ @Override
|
|
|
+ public LiveCompletionPointsRecord createCompletionRecord(Long liveId, Long userId) {
|
|
|
+ try {
|
|
|
+ // 1. 获取直播信息和配置
|
|
|
+ Live live = liveService.selectLiveByLiveId(liveId);
|
|
|
+ if (live == null) {
|
|
|
+
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 2. 从数据库获取完课积分配置
|
|
|
+ CompletionPointsConfig config = getCompletionPointsConfig(live);
|
|
|
+
|
|
|
+ // 检查是否开启完课积分功能
|
|
|
+ if (!config.isEnabled()) {
|
|
|
+
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 检查配置完整性
|
|
|
+ Integer completionRate = config.getCompletionRate();
|
|
|
+ int[] pointsConfig = config.getPointsConfig();
|
|
|
+
|
|
|
+ if (completionRate == null || pointsConfig == null || pointsConfig.length == 0) {
|
|
|
+
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 3. 获取观看时长(如果为null,则从数据库累计直播+回放时长)
|
|
|
+
|
|
|
+ Long actualWatchDuration = liveWatchUserService.getTotalWatchDuration(liveId, userId);
|
|
|
+
|
|
|
+ if (actualWatchDuration == null || actualWatchDuration <= 0) {
|
|
|
+
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 4. 获取视频总时长(秒)
|
|
|
+ Long videoDuration = live.getDuration();
|
|
|
+ if (videoDuration == null || videoDuration <= 0) {
|
|
|
+
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 5. 计算完课比例
|
|
|
+ BigDecimal watchRate = BigDecimal.valueOf(actualWatchDuration)
|
|
|
+ .multiply(BigDecimal.valueOf(100))
|
|
|
+ .divide(BigDecimal.valueOf(videoDuration), 2, RoundingMode.HALF_UP);
|
|
|
+
|
|
|
+ // 限制完课比例最大值为100.00%(防止数据库字段溢出)
|
|
|
+ if (watchRate.compareTo(BigDecimal.valueOf(100)) > 0) {
|
|
|
+ watchRate = BigDecimal.valueOf(100);
|
|
|
+ }
|
|
|
+
|
|
|
+// // 6. 判断是否达到完课标准
|
|
|
+// if (watchRate.compareTo(BigDecimal.valueOf(completionRate)) < 0) {
|
|
|
+//
|
|
|
+// return null;
|
|
|
+// }
|
|
|
+
|
|
|
+ // 7. 检查今天是否已有完课记录
|
|
|
+ LocalDate today = LocalDate.now();
|
|
|
+ Date currentDate = Date.from(today.atStartOfDay(ZoneId.systemDefault()).toInstant());
|
|
|
+
|
|
|
+ LiveCompletionPointsRecord todayRecord = recordMapper.selectByUserAndDate(liveId, userId, currentDate);
|
|
|
+ if (todayRecord != null) {
|
|
|
+
|
|
|
+ return todayRecord;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 7. 查询最近一次完课记录(不限直播间),计算连续天数
|
|
|
+ LiveCompletionPointsRecord latestRecord = recordMapper.selectLatestByUser(userId);
|
|
|
+ int continuousDays = 1;
|
|
|
+
|
|
|
+ if (latestRecord != null) {
|
|
|
+ LocalDate lastDate = latestRecord.getCurrentCompletionDate()
|
|
|
+ .toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
|
|
|
+
|
|
|
+ long daysBetween = ChronoUnit.DAYS.between(lastDate, today);
|
|
|
+
|
|
|
+ if (daysBetween == 0) {
|
|
|
+ continuousDays = latestRecord.getContinuousDays();
|
|
|
+
|
|
|
+ } else if (daysBetween == 1) {
|
|
|
+ // 昨天完课了,连续天数+1
|
|
|
+ continuousDays = latestRecord.getContinuousDays() + 1;
|
|
|
+ } else {
|
|
|
+ // 中断了,重新开始
|
|
|
+ continuousDays = 1;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 8. 计算积分
|
|
|
+ int points = calculatePoints(continuousDays, pointsConfig);
|
|
|
+
|
|
|
+ // 9. 创建完课记录
|
|
|
+ LiveCompletionPointsRecord record = new LiveCompletionPointsRecord();
|
|
|
+ record.setLiveId(liveId);
|
|
|
+ record.setUserId(userId);
|
|
|
+ record.setWatchDuration(actualWatchDuration);
|
|
|
+ record.setVideoDuration(videoDuration);
|
|
|
+ record.setCompletionRate(watchRate);
|
|
|
+ record.setContinuousDays(continuousDays);
|
|
|
+ record.setPointsAwarded(points);
|
|
|
+ record.setCurrentCompletionDate(currentDate);
|
|
|
+ record.setReceiveStatus(0); // 未领取
|
|
|
+
|
|
|
+ if (latestRecord != null) {
|
|
|
+ record.setLastCompletionDate(latestRecord.getCurrentCompletionDate());
|
|
|
+ }
|
|
|
+
|
|
|
+ recordMapper.insertRecord(record);
|
|
|
+ return record;
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("检查并创建完课记录失败, liveId={}, userId={}", liveId, userId, e);
|
|
|
+ throw e;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
/**
|
|
|
* 从直播配置中获取完课积分配置
|
|
|
*/
|