Bläddra i källkod

feat(course):优化批量添加课程小节逻辑,支持按courseSort排序- 在FsUserCoursePeriodDaysServiceImpl中获取视频详情时增加排序逻辑- 根据courseSort对要添加的视频进行排序(从小到大)- 调整课次计算逻辑,确保按排序后的顺序递增
-修正日期计算方式,基于课次正确设置日期
- 完善日志记录,记录排序后的视频顺序和添加的课程小节信息- 批量保存前再次按课次排序,确保数据库中顺序正确
- 添加详细调试日志,便于追踪添加过程
- 在FsUserCoursePeriodController中增加批量添加课程小节的日志记录

xw 2 veckor sedan
förälder
incheckning
3ada963601

+ 2 - 0
fs-admin/src/main/java/com/fs/course/controller/FsUserCoursePeriodController.java

@@ -157,6 +157,8 @@ public class FsUserCoursePeriodController extends BaseController {
     @ApiOperation("一键批量添加课程小节")
     public R batchAddCourseSections(@Validated @RequestBody BatchAddCourseSectionParam param) {
         try {
+            logger.info("开始批量添加课程小节,营期ID:{},课程ID:{},视频数量:{},视频ID列表:{}", 
+                param.getPeriodId(), param.getCourseId(), param.getVideoIds().size(), param.getVideoIds());
             return fsUserCoursePeriodDaysService.batchAddCourseSections(param);
         } catch (Exception e) {
             logger.error("批量添加课程小节失败,营期ID:{},错误信息:{}", param.getPeriodId(), e.getMessage(), e);

+ 69 - 26
fs-service/src/main/java/com/fs/course/service/impl/FsUserCoursePeriodDaysServiceImpl.java

@@ -263,7 +263,7 @@ public class FsUserCoursePeriodDaysServiceImpl extends ServiceImpl<FsUserCourseP
                 }
             }
 
-            // 7. 获取视频详情
+            // 7. 获取视频详情并按courseSort排序
             FsUserCourseVideo queryVideo = new FsUserCourseVideo();
             queryVideo.setCourseId(param.getCourseId());
             List<FsUserCourseVideo> videoList = fsUserCourseVideoService.selectFsUserCourseVideoListByCourseId(queryVideo);
@@ -276,43 +276,66 @@ public class FsUserCoursePeriodDaysServiceImpl extends ServiceImpl<FsUserCourseP
                 }
             }
 
-            // 9. 准备添加的小节数据
+            // 9. 根据courseSort对要添加的视频进行排序(从小到大)
+            List<FsUserCourseVideo> sortedVideos = param.getVideoIds().stream()
+                    .map(videoMap::get)
+                    .sorted((v1, v2) -> {
+                        Long sort1 = v1.getCourseSort() != null ? v1.getCourseSort() : Long.MAX_VALUE;
+                        Long sort2 = v2.getCourseSort() != null ? v2.getCourseSort() : Long.MAX_VALUE;
+                        return sort1.compareTo(sort2);
+                    })
+                    .collect(Collectors.toList());
+            
+            log.info("按courseSort排序后的视频顺序:");
+            for (int i = 0; i < sortedVideos.size(); i++) {
+                FsUserCourseVideo video = sortedVideos.get(i);
+                log.info("  序号: {}, 视频ID: {}, 标题: {}, courseSort: {}", 
+                    i + 1, video.getVideoId(), video.getTitle(), video.getCourseSort());
+            }
+
+            // 10. 准备添加的小节数据,使用按courseSort排序后的视频列表
             List<FsUserCoursePeriodDays> newDays = new ArrayList<>();
-            AtomicInteger lessonCounter = new AtomicInteger(existingDays.size());
             
-            // 确定开始课次
-            int startLesson = param.getStartLesson() != null ? param.getStartLesson() : existingDays.size();
+            // 确定开始课次 - 从现有最大课次+1开始,确保连续性
+            int startLesson;
+            if (param.getStartLesson() != null) {
+                startLesson = param.getStartLesson();
+            } else {
+                // 获取现有最大课次,如果没有则从1开始
+                startLesson = existingDays.stream()
+                        .mapToInt(FsUserCoursePeriodDays::getLesson)
+                        .max()
+                        .orElse(0) + 1;
+            }
             
-            for (int i = 0; i < param.getVideoIds().size(); i++) {
-                Long videoId = param.getVideoIds().get(i);
-                FsUserCourseVideo video = videoMap.get(videoId);
+            // 使用排序后的视频列表进行处理,确保按courseSort顺序添加
+            for (int i = 0; i < sortedVideos.size(); i++) {
+                FsUserCourseVideo video = sortedVideos.get(i);
+                Long videoId = video.getVideoId();
                 
                 FsUserCoursePeriodDays newDay = new FsUserCoursePeriodDays();
                 newDay.setPeriodId(param.getPeriodId());
                 newDay.setCourseId(param.getCourseId());
                 newDay.setVideoId(videoId);
                 
-                // 设置课次
-                if (param.getAutoSort() != null && param.getAutoSort()) {
-                    newDay.setLesson(startLesson + i);
-                } else {
-                    newDay.setLesson(lessonCounter.getAndIncrement());
-                }
+                // 设置课次 - 严格按排序后的顺序递增,确保有序
+                newDay.setLesson(startLesson + i);
                 
-                // 计算日期
-                newDay.setDayDate(period.getPeriodStartingTime().plusDays(newDay.getLesson()));
+                // 计算日期 - 基于课次计算正确日期(课次从1开始,所以偏移量是课次-1)
+                LocalDate courseDate = period.getPeriodStartingTime().plusDays(newDay.getLesson() - 1);
+                newDay.setDayDate(courseDate);
                 
                 // 设置时间 - 优先使用参数中的时间,其次使用视频默认时间
                 if (param.getStartTime() != null) {
-                    newDay.setStartDateTime(LocalDateTime.of(newDay.getDayDate(), param.getStartTime()));
+                    newDay.setStartDateTime(LocalDateTime.of(courseDate, param.getStartTime()));
                 } else if (video.getViewStartTime() != null) {
-                    newDay.setStartDateTime(LocalDateTime.of(newDay.getDayDate(), video.getViewStartTime()));
+                    newDay.setStartDateTime(LocalDateTime.of(courseDate, video.getViewStartTime()));
                 }
                 
                 if (param.getEndDateTime() != null) {
-                    newDay.setEndDateTime(LocalDateTime.of(newDay.getDayDate(), param.getEndDateTime()));
+                    newDay.setEndDateTime(LocalDateTime.of(courseDate, param.getEndDateTime()));
                 } else if (video.getViewEndTime() != null) {
-                    newDay.setEndDateTime(LocalDateTime.of(newDay.getDayDate(), video.getViewEndTime()));
+                    newDay.setEndDateTime(LocalDateTime.of(courseDate, video.getViewEndTime()));
                 }
                 
                 // 设置加入时间 
@@ -322,15 +345,15 @@ public class FsUserCoursePeriodDaysServiceImpl extends ServiceImpl<FsUserCourseP
                     newDay.setLastJoinTime(newDay.getEndDateTime());
                 } else {
                     if (param.getJoinTime() != null) {
-                        newDay.setLastJoinTime(LocalDateTime.of(newDay.getDayDate(), param.getJoinTime()));
+                        newDay.setLastJoinTime(LocalDateTime.of(courseDate, param.getJoinTime()));
                     } else if (video.getLastJoinTime() != null) {
-                        newDay.setLastJoinTime(LocalDateTime.of(newDay.getDayDate(), video.getLastJoinTime()));
+                        newDay.setLastJoinTime(LocalDateTime.of(courseDate, video.getLastJoinTime()));
                     }
                 }
                 
                 // 设置状态 - 默认开启今天及以后的两天
                 LocalDate compareDay = LocalDate.now().plusDays(1);
-                if (newDay.getDayDate().isBefore(compareDay)) {
+                if (courseDate.isBefore(compareDay)) {
                     newDay.setStatus(1); // 已开始
                 } else {
                     newDay.setStatus(0); // 未开始
@@ -338,13 +361,33 @@ public class FsUserCoursePeriodDaysServiceImpl extends ServiceImpl<FsUserCourseP
                 
                 newDay.setCreateTime(new Date());
                 newDays.add(newDay);
+                
+                log.debug("准备添加课程:课次={}, 日期={}, 视频ID={}, 标题={}, courseSort={}", 
+                    newDay.getLesson(), newDay.getDayDate(), videoId, video.getTitle(), video.getCourseSort());
             }
             
-            // 10. 批量保存
+            // 11. 批量保存,确保按courseSort排序的结果保存
             if (!newDays.isEmpty()) {
+                // 再次按课次排序,确保数据库中的顺序正确(按照批量操作排序保障规范)
+                newDays.sort(Comparator.comparing(FsUserCoursePeriodDays::getLesson));
+                
+                log.info("即将批量添加课程小节(按courseSort排序):");
+                for (int i = 0; i < newDays.size(); i++) {
+                    FsUserCoursePeriodDays day = newDays.get(i);
+                    FsUserCourseVideo video = videoMap.get(day.getVideoId());
+                    log.info("  序号: {}, 课次: {}, 日期: {}, 视频ID: {}, 标题: {}, courseSort: {}", 
+                        i + 1, day.getLesson(), day.getDayDate(), day.getVideoId(), 
+                        video != null ? video.getTitle() : "Unknown", 
+                        video != null ? video.getCourseSort() : "null");
+                }
+                
                 super.saveBatch(newDays);
-                log.info("批量添加课程小节成功,营期ID:{},添加数量:{}", param.getPeriodId(), newDays.size());
-                return R.ok("成功添加 " + newDays.size() + " 个课程小节");
+                log.info("批量添加课程小节成功(按courseSort排序),营期ID:{},添加数量:{},课次范围:{}-{}", 
+                    param.getPeriodId(), newDays.size(), 
+                    newDays.get(0).getLesson(), 
+                    newDays.get(newDays.size() - 1).getLesson());
+                return R.ok("成功按courseSort排序添加 " + newDays.size() + " 个课程小节,课次范围:" + 
+                          newDays.get(0).getLesson() + "-" + newDays.get(newDays.size() - 1).getLesson());
             } else {
                 return R.ok("没有需要添加的课程小节");
             }