fix: [课程管理]

This commit is contained in:
ovo 2025-05-11 16:22:58 +08:00
parent 38ce56d5f9
commit c07b0cac0d
26 changed files with 414 additions and 45 deletions

View File

@ -17,7 +17,6 @@ public class SecurityConstants {
"/bs/user/register", "/bs/user/register",
"/bs/user/getEmailCode", "/bs/user/getEmailCode",
"/bs/user/getPhoneCode", "/bs/user/getPhoneCode",
"/bs/user/verifyFace", "/bs/user/verifyFace",
"/challenge", "/challenge",

View File

@ -0,0 +1,30 @@
package com.guwan.backend.controller;
import com.guwan.backend.common.Result;
import com.guwan.backend.service.BSCategoryService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@Slf4j
@RestController
@RequestMapping("/category")
@RequiredArgsConstructor
public class CategotyController {
private final BSCategoryService categoryService;
@GetMapping("/getAll")
public Result getAllCategory() {
try {
return Result.success(categoryService.list());
} catch (Exception e) {
log.error("Failed to get categories", e);
return Result.error("Failed to get categories");
}
}
}

View File

@ -55,26 +55,17 @@ import java.util.regex.Pattern;
public class CommonController { public class CommonController {
private final MinioUtil minioUtil; private final MinioUtil minioUtil;
private final VoiceServiceClient voiceServiceClient; private final VoiceServiceClient voiceServiceClient;
private final SimpleTTSClient simpleTTSClient; private final SimpleTTSClient simpleTTSClient;
private final MinioClient minioClient; private final MinioClient minioClient;
//private final BookContentService bookContentService; //private final BookContentService bookContentService;
private final MongodbUserService mongodbUserService; private final MongodbUserService mongodbUserService;
private final EveryReadDetailOfMongodbService everyReadDetailOfMongodbService; private final EveryReadDetailOfMongodbService everyReadDetailOfMongodbService;
private final QwenChatModel qwenChatModel; private final QwenChatModel qwenChatModel;
private final QwenStreamingChatModel qwenStreamingChatModel; private final QwenStreamingChatModel qwenStreamingChatModel;
private final TestDateRepository testDateRepository; private final TestDateRepository testDateRepository;
private final TestDateDao testDateDao; private final TestDateDao testDateDao;
@PostMapping("/uploadFile") @PostMapping("/uploadFile")
public Result<String> uploadFile(String bucketName, MultipartFile file){ public Result<String> uploadFile(String bucketName, MultipartFile file){
return Result.success(minioUtil.getUrl(minioUtil.getFileUrl return Result.success(minioUtil.getUrl(minioUtil.getFileUrl

View File

@ -5,16 +5,22 @@ package com.guwan.backend.controller;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.guwan.backend.common.Result; import com.guwan.backend.common.Result;
import com.guwan.backend.common.SearchResult;
import com.guwan.backend.pojo.dto.BSCategory; import com.guwan.backend.pojo.dto.BSCategory;
import com.guwan.backend.pojo.entity.Course; import com.guwan.backend.pojo.entity.Course;
import com.guwan.backend.pojo.entity.Teacher;
import com.guwan.backend.pojo.response.CourseByAdminVO;
import com.guwan.backend.pojo.response.courseDetail.CourseDetailVO; import com.guwan.backend.pojo.response.courseDetail.CourseDetailVO;
import com.guwan.backend.service.BSCategoryService; import com.guwan.backend.service.BSCategoryService;
import com.guwan.backend.service.CourseService; import com.guwan.backend.service.CourseService;
import com.guwan.backend.service.TeacherService;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import java.util.List;
import java.util.stream.Collectors; import java.util.stream.Collectors;
/** /**
@ -36,12 +42,10 @@ public class CourseController {
private final BSCategoryService categoryService; private final BSCategoryService categoryService;
private final TeacherService teacherService;
/** /**
* 分页查询 * 分页查询
*
* @param courses 筛选条件
* @param pageRequest 分页对象
* @return 查询结果
*/ */
@GetMapping("/queryByPage") @GetMapping("/queryByPage")
public Result queryByPage(@RequestParam("page") Integer pageNumber, public Result queryByPage(@RequestParam("page") Integer pageNumber,
@ -57,7 +61,7 @@ public class CourseController {
.peek(course -> { .peek(course -> {
course.setCategoryName(categoryService.list() course.setCategoryName(categoryService.list()
.stream() .stream()
.collect(Collectors.toMap(BSCategory::getId, BSCategory::getName)) .collect(Collectors.toMap(BSCategory::getId, BSCategory::getChineseName))
.get(course.getCategoryId())); // 赋值类别名称 .get(course.getCategoryId())); // 赋值类别名称
}) })
.toList()); .toList());
@ -120,5 +124,40 @@ public class CourseController {
return Result.success(this.courseService.removeById(id)); return Result.success(this.courseService.removeById(id));
} }
@GetMapping("/listByAdmin")
public SearchResult listByAdmin(@RequestParam("page") Integer pageNumber,
@RequestParam("size") Integer size,
@RequestParam(required = false) String courseName) {
Page<Course> page = new Page<>(pageNumber, size);
LambdaQueryWrapper<Course> lambdaQueryWrapper = new LambdaQueryWrapper<>();
Page<Course> resultPage = this.courseService.page(page, lambdaQueryWrapper);
List<CourseByAdminVO> courseByAdminVOS = resultPage.getRecords().stream().map(
course -> {
CourseByAdminVO courseByAdminVO = new CourseByAdminVO();
course.setCategoryName(categoryService.list()
.stream()
.collect(Collectors.toMap(BSCategory::getId, BSCategory::getChineseName))
.get(course.getCategoryId())); // 赋值类别名称
BeanUtils.copyProperties(course, courseByAdminVO);
courseByAdminVO.setTeacherName(teacherService.list()
.stream()
.collect(Collectors.toMap(Teacher::getId, Teacher::getName))
.get(course.getTeacherId()));//赋值教师名称
return courseByAdminVO;
}
).toList();
return SearchResult.success(courseByAdminVOS, resultPage.getTotal());
}
} }

View File

@ -0,0 +1,29 @@
package com.guwan.backend.controller;
import com.guwan.backend.common.Result;
import com.guwan.backend.pojo.entity.CourseLevel;
import com.guwan.backend.service.CourseLevelService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@Slf4j
@RestController
@RequestMapping("/course/level")
@RequiredArgsConstructor
public class CourseLevelController {
/**
* 服务对象
*/
private final CourseLevelService courseLevelService;
@GetMapping("/getAll")
public Result getAll() {
List<CourseLevel> courseLevelslist = courseLevelService.list();
return Result.success(courseLevelslist);
}
}

View File

@ -0,0 +1,41 @@
package com.guwan.backend.controller;
import com.guwan.backend.common.Result;
import com.guwan.backend.pojo.entity.CourseLevel;
import com.guwan.backend.pojo.entity.CourseType;
import com.guwan.backend.service.CourseLevelService;
import com.guwan.backend.service.CourseTypeService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
/**
* 课程表(Courses)表控制层
*
* @author Guwan
* @since 2025-03-13 22:47:31
*/
@Slf4j
@RestController
@RequestMapping("/course/type")
@RequiredArgsConstructor
public class CourseTypeController {
/**
* 服务对象
*/
private final CourseTypeService courseTypeService;
@GetMapping("/getAll")
public Result getAll() {
List<CourseType> courseLevelslist = courseTypeService.list();
return Result.success(courseLevelslist);
}
}

View File

@ -0,0 +1,30 @@
package com.guwan.backend.controller;
import com.guwan.backend.common.Result;
import com.guwan.backend.pojo.entity.Teacher;
import com.guwan.backend.service.TeacherService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
@Slf4j
@RestController
@RequestMapping("/teacher")
@RequiredArgsConstructor
public class TeacherController {
private final TeacherService teacherService;
@GetMapping("/getAll")
public Result getAll() {
List<Teacher> courseLevelslist = teacherService.list();
return Result.success(courseLevelslist);
}
}

View File

@ -1,13 +0,0 @@
package com.guwan.backend.controller;
// 测试用例类
class TestCase {
String input; // 输入数据
String expectedOutput; // 预期输出
int timeoutSeconds = 2;// 超时时间
public TestCase(String input, String expectedOutput) {
this.input = input;
this.expectedOutput = expectedOutput;
}
}

View File

@ -5,6 +5,7 @@ import com.guwan.backend.mapper.SlideMapper;
import com.guwan.backend.pojo.entity.Section; import com.guwan.backend.pojo.entity.Section;
import com.guwan.backend.pojo.entity.Slide; import com.guwan.backend.pojo.entity.Slide;
import com.guwan.backend.pojo.response.courseDetail.*; import com.guwan.backend.pojo.response.courseDetail.*;
import com.guwan.backend.util.KKviewUrlUtil;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.springframework.beans.BeanUtils; import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
@ -52,6 +53,8 @@ public class SectionVOFactory {
.collect(Collectors.toList()); .collect(Collectors.toList());
ppt.setSlides(slideVOS); ppt.setSlides(slideVOS);
ppt.setDownUrl(section.getUrl());
ppt.setPreViewUrl(KKviewUrlUtil.toKKViewUrl(section.getUrl()));
return ppt; return ppt;
default: default:
throw new IllegalArgumentException("Unsupported type: " + section.getType()); throw new IllegalArgumentException("Unsupported type: " + section.getType());

View File

@ -0,0 +1,18 @@
package com.guwan.backend.mapper;
import com.guwan.backend.pojo.entity.CourseLevel;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
* @author 12455
* @description 针对表course_level的数据库操作Mapper
* @createDate 2025-05-11 13:56:43
* @Entity com.guwan.backend.pojo.entity.CourseLevel
*/
public interface CourseLevelMapper extends BaseMapper<CourseLevel> {
}

View File

@ -0,0 +1,18 @@
package com.guwan.backend.mapper;
import com.guwan.backend.pojo.entity.CourseType;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
* @author 12455
* @description 针对表course_type的数据库操作Mapper
* @createDate 2025-05-11 14:43:17
* @Entity com.guwan.backend.pojo.entity.CourseType
*/
public interface CourseTypeMapper extends BaseMapper<CourseType> {
}

View File

@ -23,7 +23,9 @@ public class BSCategory implements Serializable {
/** /**
* 种类名称 * 种类名称
*/ */
private String name; private String chineseName;
private String englishName;
@TableField(exist = false) @TableField(exist = false)
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;

View File

@ -37,6 +37,10 @@ public class Course implements Serializable {
*/ */
private String categoryId; private String categoryId;
private String levelId;
private String typeId;
/** /**
* 分类名称 * 分类名称
*/ */

View File

@ -0,0 +1,27 @@
package com.guwan.backend.pojo.entity;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
/**
*
* @TableName course_level
*/
@TableName(value ="course_level")
@Data
public class CourseLevel {
/**
* 课程级别id
*/
private String id;
/**
* 难度中文名
*/
private String chineseName;
/**
* 难度英文名
*/
private String englishName;
}

View File

@ -0,0 +1,29 @@
package com.guwan.backend.pojo.entity;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
/**
*
* @TableName course_type
*/
@TableName(value ="course_type")
@Data
public class CourseType {
/**
* 课程类别:全部入门等
*/
@TableId
private String id;
/**
*
*/
private String chineseName;
/**
*
*/
private String englishName;
}

View File

@ -0,0 +1,21 @@
package com.guwan.backend.pojo.response;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.math.BigDecimal;
import java.util.Date;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class CourseByAdminVO {
private String id;
private String title;
private String categoryName;
private BigDecimal price;
private String teacherName;
private BigDecimal rating;
private Date createdAt;
}

View File

@ -24,6 +24,10 @@ public class CourseDetailVO {
private String teacherAvatar; private String teacherAvatar;
private String levelName;
private String typeName;
private Double price; private Double price;
private Double rating; private Double rating;

View File

@ -10,6 +10,8 @@ import java.util.List;
@ToString(callSuper = true) @ToString(callSuper = true)
@EqualsAndHashCode(callSuper = true) @EqualsAndHashCode(callSuper = true)
public class PptSectionVO extends BaseSectionVO { public class PptSectionVO extends BaseSectionVO {
private String downUrl;
private String preViewUrl;
private List<SlideVO> slides; private List<SlideVO> slides;
} }

View File

@ -0,0 +1,13 @@
package com.guwan.backend.service;
import com.guwan.backend.pojo.entity.CourseLevel;
import com.baomidou.mybatisplus.extension.service.IService;
/**
* @author 12455
* @description 针对表course_level的数据库操作Service
* @createDate 2025-05-11 13:56:43
*/
public interface CourseLevelService extends IService<CourseLevel> {
}

View File

@ -0,0 +1,13 @@
package com.guwan.backend.service;
import com.guwan.backend.pojo.entity.CourseType;
import com.baomidou.mybatisplus.extension.service.IService;
/**
* @author 12455
* @description 针对表course_type的数据库操作Service
* @createDate 2025-05-11 14:43:17
*/
public interface CourseTypeService extends IService<CourseType> {
}

View File

@ -0,0 +1,22 @@
package com.guwan.backend.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.guwan.backend.mapper.CourseLevelMapper;
import com.guwan.backend.pojo.entity.CourseLevel;
import com.guwan.backend.service.CourseLevelService;
import org.springframework.stereotype.Service;
/**
* @author 12455
* @description 针对表course_level的数据库操作Service实现
* @createDate 2025-05-11 13:56:43
*/
@Service
public class CourseLevelServiceImpl extends ServiceImpl<CourseLevelMapper, CourseLevel>
implements CourseLevelService {
}

View File

@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.guwan.backend.factory.SectionVOFactory; import com.guwan.backend.factory.SectionVOFactory;
import com.guwan.backend.mapper.*; import com.guwan.backend.mapper.*;
import com.guwan.backend.mapper.CourseTypeMapper;
import com.guwan.backend.pojo.entity.*; import com.guwan.backend.pojo.entity.*;
import com.guwan.backend.pojo.response.courseDetail.BaseSectionVO; import com.guwan.backend.pojo.response.courseDetail.BaseSectionVO;
import com.guwan.backend.pojo.response.courseDetail.ChapterVO; import com.guwan.backend.pojo.response.courseDetail.ChapterVO;
@ -44,6 +45,10 @@ public class CourseServiceImpl extends ServiceImpl<CourseMapper, Course>
private final UserMapper userMapper; private final UserMapper userMapper;
private final CourseLevelMapper courseLevelMapper;
private final CourseTypeMapper courseTypeMapper;
private static final Map<String, Integer> courseStudentCounts = new ConcurrentHashMap<>(); private static final Map<String, Integer> courseStudentCounts = new ConcurrentHashMap<>();
@Override @Override
@ -61,6 +66,8 @@ public class CourseServiceImpl extends ServiceImpl<CourseMapper, Course>
CourseDetailVO courseDetailVO = new CourseDetailVO(); CourseDetailVO courseDetailVO = new CourseDetailVO();
courseDetailVO.setTitle(course.getTitle()); courseDetailVO.setTitle(course.getTitle());
courseDetailVO.setDescription(course.getDescription()); courseDetailVO.setDescription(course.getDescription());
courseDetailVO.setLevelName(courseLevelMapper.selectById(course.getLevelId()).getChineseName());
courseDetailVO.setTypeName(courseTypeMapper.selectById(course.getTypeId()).getChineseName());
// Course(id=1, title=黑马程序员匠心之作|C++教程从0到1入门编程, description=null, categoryId=2, categoryName=null, teacherId=1, coverImg=http://localhost:9000/photo/cover/c315f738-71aa-4329-8c7c-9092284c33c3.png, price=0.00, coursrTeacherId=null, rating=0.0, ratingCount=null, studentCount=0, videoCount=null, documentCount=null, totalDuration=null, createdAt=null, updatedAt=null) // Course(id=1, title=黑马程序员匠心之作|C++教程从0到1入门编程, description=null, categoryId=2, categoryName=null, teacherId=1, coverImg=http://localhost:9000/photo/cover/c315f738-71aa-4329-8c7c-9092284c33c3.png, price=0.00, coursrTeacherId=null, rating=0.0, ratingCount=null, studentCount=0, videoCount=null, documentCount=null, totalDuration=null, createdAt=null, updatedAt=null)
var teacherId = course.getTeacherId(); var teacherId = course.getTeacherId();

View File

@ -0,0 +1,23 @@
package com.guwan.backend.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.guwan.backend.mapper.CourseTypeMapper;
import com.guwan.backend.pojo.entity.CourseType;
import com.guwan.backend.service.CourseTypeService;
import org.springframework.stereotype.Service;
/**
* @author 12455
* @description 针对表course_type的数据库操作Service实现
* @createDate 2025-05-11 14:43:17
*/
@Service
public class CourseTypeServiceImpl extends ServiceImpl<CourseTypeMapper, CourseType>
implements CourseTypeService {
}

View File

@ -1,15 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.guwan.backend.mapper.BSCategoryMapper">
<resultMap id="BaseResultMap" type="com.guwan.backend.pojo.dto.BSCategory">
<id property="id" column="id" jdbcType="VARCHAR"/>
<result property="name" column="name" jdbcType="VARCHAR"/>
</resultMap>
<sql id="Base_Column_List">
id,name
</sql>
</mapper>

View File

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.guwan.backend.mapper.CourseLevelMapper">
<resultMap id="BaseResultMap" type="com.guwan.backend.pojo.entity.CourseLevel">
<result property="id" column="id" jdbcType="VARCHAR"/>
<result property="chineseName" column="chinese_name" jdbcType="VARCHAR"/>
<result property="englishName" column="english_name" jdbcType="VARCHAR"/>
</resultMap>
<sql id="Base_Column_List">
id,chinese_name,english_name
</sql>
</mapper>

View File

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.guwan.backend.mapper.CourseTypeMapper">
<resultMap id="BaseResultMap" type="com.guwan.backend.pojo.entity.CourseType">
<id property="id" column="id" jdbcType="VARCHAR"/>
<result property="chineseName" column="chinese_name" jdbcType="VARCHAR"/>
<result property="englishName" column="english_name" jdbcType="VARCHAR"/>
</resultMap>
<sql id="Base_Column_List">
id,chinese_name,english_name
</sql>
</mapper>