feat: 添加 CoursePackageServiceImpl 实现 CoursePackageService 接口修复启动失败

Made-with: Cursor
This commit is contained in:
zhonghua 2026-03-18 18:38:45 +08:00
parent 41d2cc4030
commit 640fbc94f9

View File

@ -0,0 +1,395 @@
package com.reading.platform.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.reading.platform.common.enums.CourseStatus;
import com.reading.platform.common.enums.TenantPackageStatus;
import com.reading.platform.common.exception.BusinessException;
import com.reading.platform.dto.request.CourseCreateRequest;
import com.reading.platform.dto.request.CourseUpdateRequest;
import com.reading.platform.dto.response.CourseLessonResponse;
import com.reading.platform.dto.response.CourseResponse;
import com.reading.platform.dto.response.LessonStepResponse;
import com.reading.platform.entity.CourseCollectionPackage;
import com.reading.platform.entity.CourseLesson;
import com.reading.platform.entity.CoursePackage;
import com.reading.platform.entity.LessonStep;
import com.reading.platform.entity.TenantPackage;
import com.reading.platform.mapper.CourseCollectionPackageMapper;
import com.reading.platform.mapper.CoursePackageMapper;
import com.reading.platform.mapper.TenantPackageMapper;
import com.reading.platform.service.CourseLessonService;
import com.reading.platform.service.CoursePackageService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
/**
* 课程包服务实现类
*/
@Slf4j
@Service
@RequiredArgsConstructor
public class CoursePackageServiceImpl extends ServiceImpl<CoursePackageMapper, CoursePackage>
implements CoursePackageService {
private final CoursePackageMapper coursePackageMapper;
private final CourseLessonService courseLessonService;
private final com.reading.platform.common.mapper.CoursePackageMapper coursePackageVoMapper;
private final CourseCollectionPackageMapper collectionPackageMapper;
private final TenantPackageMapper tenantPackageMapper;
@Override
@Transactional(rollbackFor = Exception.class)
public CoursePackage createCourse(Long tenantId, CourseCreateRequest request) {
log.info("创建租户课程tenantId={}, name={}", tenantId, request.getName());
CoursePackage entity = buildEntityFromRequest(request);
entity.setTenantId(tenantId);
entity.setIsSystem(0);
entity.setStatus(CourseStatus.DRAFT.getCode());
entity.setUsageCount(0);
coursePackageMapper.insert(entity);
log.info("课程创建成功id={}", entity.getId());
return entity;
}
@Override
@Transactional(rollbackFor = Exception.class)
public CoursePackage createSystemCourse(CourseCreateRequest request) {
log.info("创建系统课程name={}", request.getName());
CoursePackage entity = buildEntityFromRequest(request);
entity.setTenantId(null);
entity.setIsSystem(1);
entity.setStatus(CourseStatus.DRAFT.getCode());
entity.setUsageCount(0);
coursePackageMapper.insert(entity);
log.info("系统课程创建成功id={}", entity.getId());
return entity;
}
@Override
@Transactional(rollbackFor = Exception.class)
public CoursePackage updateCourse(Long id, CourseUpdateRequest request) {
log.info("更新课程id={}", id);
CoursePackage entity = getCourseById(id);
applyUpdateRequest(entity, request);
coursePackageMapper.updateById(entity);
log.info("课程更新成功id={}", id);
return entity;
}
@Override
public CoursePackage getCourseById(Long id) {
CoursePackage entity = coursePackageMapper.selectById(id);
if (entity == null) {
throw new BusinessException("课程不存在id=" + id);
}
return entity;
}
@Override
public CoursePackage getCourseByIdWithTenantCheck(Long id, Long tenantId) {
CoursePackage entity = getCourseById(id);
if (entity.getTenantId() != null && !entity.getTenantId().equals(tenantId)) {
throw new BusinessException("无权访问该课程");
}
return entity;
}
@Override
public CourseResponse getCourseByIdWithLessons(Long id) {
CoursePackage entity = getCourseById(id);
CourseResponse response = coursePackageVoMapper.toVO(entity);
List<CourseLesson> lessons = courseLessonService.findByCourseId(id);
List<CourseLessonResponse> lessonResponses = lessons.stream()
.map(this::toLessonResponse)
.collect(Collectors.toList());
response.setCourseLessons(lessonResponses);
return response;
}
@Override
public Page<CoursePackage> getCoursePage(Long tenantId, Integer pageNum, Integer pageSize,
String keyword, String category, String status) {
int current = pageNum != null && pageNum > 0 ? pageNum : 1;
int size = pageSize != null && pageSize > 0 ? pageSize : 10;
Page<CoursePackage> page = new Page<>(current, size);
LambdaQueryWrapper<CoursePackage> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(CoursePackage::getTenantId, tenantId);
if (StringUtils.hasText(keyword)) {
wrapper.and(w -> w
.like(CoursePackage::getName, keyword)
.or().like(CoursePackage::getPictureBookName, keyword)
.or().like(CoursePackage::getCode, keyword));
}
if (StringUtils.hasText(category)) {
wrapper.eq(CoursePackage::getCategory, category);
}
if (StringUtils.hasText(status)) {
wrapper.eq(CoursePackage::getStatus, status);
}
wrapper.orderByDesc(CoursePackage::getUpdatedAt);
return coursePackageMapper.selectPage(page, wrapper);
}
@Override
public Page<CoursePackage> getSystemCoursePage(Integer pageNum, Integer pageSize,
String keyword, String category, String status,
boolean reviewOnly) {
int current = pageNum != null && pageNum > 0 ? pageNum : 1;
int size = pageSize != null && pageSize > 0 ? pageSize : 10;
Page<CoursePackage> page = new Page<>(current, size);
LambdaQueryWrapper<CoursePackage> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(CoursePackage::getIsSystem, 1);
if (StringUtils.hasText(keyword)) {
wrapper.and(w -> w
.like(CoursePackage::getName, keyword)
.or().like(CoursePackage::getPictureBookName, keyword)
.or().like(CoursePackage::getCode, keyword));
}
if (StringUtils.hasText(category)) {
wrapper.eq(CoursePackage::getCategory, category);
}
if (StringUtils.hasText(status)) {
wrapper.eq(CoursePackage::getStatus, status);
}
if (reviewOnly) {
wrapper.eq(CoursePackage::getStatus, CourseStatus.PENDING.getCode());
}
wrapper.orderByDesc(CoursePackage::getUpdatedAt);
return coursePackageMapper.selectPage(page, wrapper);
}
@Override
@Transactional(rollbackFor = Exception.class)
public void deleteCourse(Long id) {
getCourseById(id);
coursePackageMapper.deleteById(id);
log.info("课程删除成功id={}", id);
}
@Override
@Transactional(rollbackFor = Exception.class)
public void publishCourse(Long id) {
CoursePackage entity = getCourseById(id);
entity.setStatus(CourseStatus.PUBLISHED.getCode());
entity.setPublishedAt(LocalDateTime.now());
coursePackageMapper.updateById(entity);
log.info("课程发布成功id={}", id);
}
@Override
@Transactional(rollbackFor = Exception.class)
public void archiveCourse(Long id) {
CoursePackage entity = getCourseById(id);
entity.setStatus(CourseStatus.ARCHIVED.getCode());
coursePackageMapper.updateById(entity);
log.info("课程归档成功id={}", id);
}
@Override
@Transactional(rollbackFor = Exception.class)
public void rejectCourse(Long id, String comment) {
CoursePackage entity = getCourseById(id);
entity.setStatus(CourseStatus.REJECTED.getCode());
entity.setReviewComment(comment);
entity.setReviewedAt(LocalDateTime.now());
coursePackageMapper.updateById(entity);
log.info("课程驳回成功id={}", id);
}
@Override
public List<CoursePackage> getCoursesByTenantId(Long tenantId) {
return coursePackageMapper.selectList(
new LambdaQueryWrapper<CoursePackage>()
.eq(CoursePackage::getTenantId, tenantId)
.eq(CoursePackage::getStatus, CourseStatus.PUBLISHED.getCode())
.orderByDesc(CoursePackage::getUsageCount));
}
@Override
public List<CoursePackage> getTenantPackageCourses(Long tenantId, String keyword, String grade) {
List<Long> collectionIds = tenantPackageMapper.selectList(
new LambdaQueryWrapper<TenantPackage>()
.eq(TenantPackage::getTenantId, tenantId)
.eq(TenantPackage::getStatus, TenantPackageStatus.ACTIVE.getCode())
.isNotNull(TenantPackage::getCollectionId))
.stream()
.map(TenantPackage::getCollectionId)
.distinct()
.collect(Collectors.toList());
if (collectionIds.isEmpty()) {
return new ArrayList<>();
}
List<Long> packageIds = collectionPackageMapper.selectList(
new LambdaQueryWrapper<CourseCollectionPackage>()
.in(CourseCollectionPackage::getCollectionId, collectionIds))
.stream()
.map(CourseCollectionPackage::getPackageId)
.distinct()
.collect(Collectors.toList());
if (packageIds.isEmpty()) {
return new ArrayList<>();
}
LambdaQueryWrapper<CoursePackage> wrapper = new LambdaQueryWrapper<>();
wrapper.in(CoursePackage::getId, packageIds)
.eq(CoursePackage::getStatus, CourseStatus.PUBLISHED.getCode());
if (StringUtils.hasText(keyword)) {
wrapper.and(w -> w
.like(CoursePackage::getName, keyword)
.or().like(CoursePackage::getPictureBookName, keyword)
.or().like(CoursePackage::getCode, keyword));
}
if (StringUtils.hasText(grade)) {
String gradeLower = grade.toLowerCase();
wrapper.and(w -> w
.like(CoursePackage::getGradeTags, grade)
.or().like(CoursePackage::getGradeTags, gradeLower)
.or().like(CoursePackage::getGradeTags, "\"" + grade + "\"")
.or().like(CoursePackage::getGradeTags, "\"" + gradeLower + "\""));
}
wrapper.orderByDesc(CoursePackage::getUsageCount);
return coursePackageMapper.selectList(wrapper);
}
private CoursePackage buildEntityFromRequest(CourseCreateRequest request) {
CoursePackage entity = new CoursePackage();
entity.setName(request.getName());
entity.setCode(request.getCode());
entity.setDescription(request.getDescription());
entity.setCoverUrl(request.getCoverUrl());
entity.setCoverImagePath(request.getCoverImagePath());
entity.setCategory(request.getCategory());
entity.setAgeRange(request.getAgeRange());
entity.setDifficultyLevel(request.getDifficultyLevel());
entity.setDurationMinutes(request.getDurationMinutes());
entity.setObjectives(request.getObjectives());
entity.setCoreContent(request.getCoreContent());
entity.setIntroSummary(request.getIntroSummary());
entity.setIntroHighlights(request.getIntroHighlights());
entity.setIntroGoals(request.getIntroGoals());
entity.setIntroSchedule(request.getIntroSchedule());
entity.setIntroKeyPoints(request.getIntroKeyPoints());
entity.setIntroMethods(request.getIntroMethods());
entity.setIntroEvaluation(request.getIntroEvaluation());
entity.setIntroNotes(request.getIntroNotes());
entity.setScheduleRefData(request.getScheduleRefData());
entity.setEnvironmentConstruction(request.getEnvironmentConstruction());
entity.setThemeId(request.getThemeId());
entity.setPictureBookName(request.getPictureBookName());
entity.setEbookPaths(request.getEbookPaths());
entity.setAudioPaths(request.getAudioPaths());
entity.setVideoPaths(request.getVideoPaths());
entity.setOtherResources(request.getOtherResources());
entity.setPptPath(request.getPptPath());
entity.setPptName(request.getPptName());
entity.setPosterPaths(request.getPosterPaths());
entity.setTools(request.getTools());
entity.setStudentMaterials(request.getStudentMaterials());
entity.setLessonPlanData(request.getLessonPlanData());
entity.setActivitiesData(request.getActivitiesData());
entity.setAssessmentData(request.getAssessmentData());
entity.setGradeTags(request.getGradeTags());
entity.setDomainTags(request.getDomainTags());
entity.setHasCollectiveLesson(request.getHasCollectiveLesson() != null && request.getHasCollectiveLesson() ? 1 : 0);
return entity;
}
private void applyUpdateRequest(CoursePackage entity, CourseUpdateRequest request) {
if (StringUtils.hasText(request.getName())) entity.setName(request.getName());
if (request.getCode() != null) entity.setCode(request.getCode());
if (request.getDescription() != null) entity.setDescription(request.getDescription());
if (request.getCoverUrl() != null) entity.setCoverUrl(request.getCoverUrl());
if (request.getCoverImagePath() != null) entity.setCoverImagePath(request.getCoverImagePath());
if (request.getCategory() != null) entity.setCategory(request.getCategory());
if (request.getAgeRange() != null) entity.setAgeRange(request.getAgeRange());
if (request.getDifficultyLevel() != null) entity.setDifficultyLevel(request.getDifficultyLevel());
if (request.getDurationMinutes() != null) entity.setDurationMinutes(request.getDurationMinutes());
if (request.getObjectives() != null) entity.setObjectives(request.getObjectives());
if (StringUtils.hasText(request.getStatus())) entity.setStatus(request.getStatus());
if (request.getCoreContent() != null) entity.setCoreContent(request.getCoreContent());
if (request.getIntroSummary() != null) entity.setIntroSummary(request.getIntroSummary());
if (request.getIntroHighlights() != null) entity.setIntroHighlights(request.getIntroHighlights());
if (request.getIntroGoals() != null) entity.setIntroGoals(request.getIntroGoals());
if (request.getIntroSchedule() != null) entity.setIntroSchedule(request.getIntroSchedule());
if (request.getIntroKeyPoints() != null) entity.setIntroKeyPoints(request.getIntroKeyPoints());
if (request.getIntroMethods() != null) entity.setIntroMethods(request.getIntroMethods());
if (request.getIntroEvaluation() != null) entity.setIntroEvaluation(request.getIntroEvaluation());
if (request.getIntroNotes() != null) entity.setIntroNotes(request.getIntroNotes());
if (request.getScheduleRefData() != null) entity.setScheduleRefData(request.getScheduleRefData());
if (request.getEnvironmentConstruction() != null) entity.setEnvironmentConstruction(request.getEnvironmentConstruction());
if (request.getThemeId() != null) entity.setThemeId(request.getThemeId());
if (request.getPictureBookName() != null) entity.setPictureBookName(request.getPictureBookName());
if (request.getEbookPaths() != null) entity.setEbookPaths(request.getEbookPaths());
if (request.getAudioPaths() != null) entity.setAudioPaths(request.getAudioPaths());
if (request.getVideoPaths() != null) entity.setVideoPaths(request.getVideoPaths());
if (request.getOtherResources() != null) entity.setOtherResources(request.getOtherResources());
if (request.getPptPath() != null) entity.setPptPath(request.getPptPath());
if (request.getPptName() != null) entity.setPptName(request.getPptName());
if (request.getPosterPaths() != null) entity.setPosterPaths(request.getPosterPaths());
if (request.getTools() != null) entity.setTools(request.getTools());
if (request.getStudentMaterials() != null) entity.setStudentMaterials(request.getStudentMaterials());
if (request.getLessonPlanData() != null) entity.setLessonPlanData(request.getLessonPlanData());
if (request.getActivitiesData() != null) entity.setActivitiesData(request.getActivitiesData());
if (request.getAssessmentData() != null) entity.setAssessmentData(request.getAssessmentData());
if (request.getGradeTags() != null) entity.setGradeTags(request.getGradeTags());
if (request.getDomainTags() != null) entity.setDomainTags(request.getDomainTags());
if (request.getHasCollectiveLesson() != null) entity.setHasCollectiveLesson(request.getHasCollectiveLesson() ? 1 : 0);
}
private CourseLessonResponse toLessonResponse(CourseLesson lesson) {
List<LessonStep> steps = courseLessonService.findSteps(lesson.getId());
List<LessonStepResponse> stepResponses = steps.stream()
.map(s -> LessonStepResponse.builder()
.id(s.getId())
.lessonId(s.getLessonId())
.name(s.getName())
.content(s.getContent())
.duration(s.getDuration())
.objective(s.getObjective())
.resourceIds(s.getResourceIds())
.sortOrder(s.getSortOrder())
.createdAt(s.getCreatedAt())
.updatedAt(s.getUpdatedAt())
.build())
.collect(Collectors.toList());
return CourseLessonResponse.builder()
.id(lesson.getId())
.courseId(lesson.getCourseId())
.lessonType(lesson.getLessonType())
.name(lesson.getName())
.description(lesson.getDescription())
.duration(lesson.getDuration())
.videoPath(lesson.getVideoPath())
.videoName(lesson.getVideoName())
.pptPath(lesson.getPptPath())
.pptName(lesson.getPptName())
.pdfPath(lesson.getPdfPath())
.pdfName(lesson.getPdfName())
.objectives(lesson.getObjectives())
.preparation(lesson.getPreparation())
.extension(lesson.getExtension())
.reflection(lesson.getReflection())
.assessmentData(lesson.getAssessmentData())
.useTemplate(lesson.getUseTemplate())
.sortOrder(lesson.getSortOrder())
.steps(stepResponses)
.createdAt(lesson.getCreatedAt())
.updatedAt(lesson.getUpdatedAt())
.build();
}
}