feature: [课程] 课程中心界面

This commit is contained in:
ovo 2025-05-12 20:30:55 +08:00
parent 16eb04344b
commit 7dc80cd187
12 changed files with 130 additions and 118 deletions

View File

@ -0,0 +1,28 @@
问题 本质原因
访问 POST 接口用 GET路径又模糊匹配 Spring 把你写的 testMethod 误当成其他接口的参数,比如 {id},尝试类型转换失败
预期 405 报错却看到类型转换失败 是路径匹配到了别的接口,没走到你定义的方法
解决办法 用正确的请求方式 / 添加明确前缀 / 避免通配路径冲突
现在有这个一个方法
```java
@GetMapping("{id}")
public Result<Course> queryById(@PathVariable("id") Integer id) {
return Result.success(courseService.getById(id));
}
```
我又写了一个方法
```java
@PostMapping("/testMethod")
public void testMethod(@RequestParam(name = "page") Long pageNum){
}
```
然后我请求
```java
GET http://localhost:8084/bs/courses/testMethod?page=1
```
请求其实走到了上面
Spring 的路径匹配是优先按 URL 结构匹配方法类型GET/POST其次。

View File

@ -1,6 +1,5 @@
package com.guwan.backend; package com.guwan.backend;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import java.lang.reflect.Method; import java.lang.reflect.Method;

View File

@ -1,52 +0,0 @@
package com.guwan.backend;
import org.apache.tika.metadata.Metadata;
import org.apache.tika.parser.AutoDetectParser;
import org.apache.tika.parser.ParseContext;
import org.apache.tika.parser.Parser;
import org.apache.tika.sax.BodyContentHandler;
import java.io.FileInputStream;
import java.io.InputStream;
import java.net.URL;
public class VideoDuration {
// public static void main(String[] args) {
// /* String preSignedUrl = "http://localhost:9000/videos/ffffad37-9804-4765-ae18-3f8dcda9bea8.mp4"; // Minio 预签名 URL
//
// try (InputStream stream = new URL(preSignedUrl).openStream()) {
// Metadata metadata = new Metadata();
// Parser parser = new AutoDetectParser();
// parser.parse(stream, new BodyContentHandler(), metadata, new ParseContext());
//
// String duration = metadata.get("duration");
// System.out.println("视频时长(毫秒): " + duration);
// } catch (Exception e) {
// e.printStackTrace();
// }*/
// int i = 0;
// while (i< 5){
// if (i ==3){
// i++;
// continue;
// }
// System.out.println(i);
// i++;
// }
//
// }
static boolean foo(char x) {
System.out.print(x);
return true;
}
public static void main(String[] args) {
int i = 0;
for (foo('A'); foo('B') && (i < 2); foo('C')) {
i++;
foo('D');
}
}
}

View File

@ -23,6 +23,11 @@ public class SecurityConstants {
"/captcha/verify", //验证码认证接口 "/captcha/verify", //验证码认证接口
"/bs/courses/testMethod",
"/bs/courses/testMethodOne",
"/challenge", "/challenge",
"/ws/**", "/ws/**",
"/faceTest", "/compareFaces", "/faceTest", "/compareFaces",

View File

@ -14,6 +14,7 @@ import dev.langchain4j.community.model.dashscope.QwenStreamingChatModel;
import dev.langchain4j.model.chat.response.ChatResponse; import dev.langchain4j.model.chat.response.ChatResponse;
import dev.langchain4j.model.chat.response.StreamingChatResponseHandler; import dev.langchain4j.model.chat.response.StreamingChatResponseHandler;
import io.minio.MinioClient; import io.minio.MinioClient;
import jakarta.transaction.Transactional;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import okhttp3.OkHttpClient; import okhttp3.OkHttpClient;
@ -74,6 +75,22 @@ public class CommonController {
(bucketName, minioUtil.uploadFile(bucketName, file)))); (bucketName, minioUtil.uploadFile(bucketName, file))));
} }
@PostMapping("/test111111")
public Result<String> test111111(@RequestParam Integer id){
return null;
}
@GetMapping("/test222222")
public Result<String> test222222(){
return null;
}
@PostMapping("/test333333")
public Result<String> test333333(@RequestParam(name = "page") Long id){
return null;
}
// @PostMapping("/addBookComment") // @PostMapping("/addBookComment")
// public Result<String> addBookComment(String url) { // public Result<String> addBookComment(String url) {
// log.debug(url); // log.debug(url);

View File

@ -4,15 +4,15 @@ 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.core.conditions.update.LambdaUpdateWrapper; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.conditions.update.LambdaUpdateChainWrapper;
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.common.SearchResult;
import com.guwan.backend.mybatis.query.LambdaQueryWrapperX; import com.guwan.backend.mybatis.query.LambdaQueryWrapperX;
import com.guwan.backend.pojo.dto.BSCategory; import com.guwan.backend.pojo.entity.BSCategory;
import com.guwan.backend.pojo.dto.course.InsertCourseDTO; import com.guwan.backend.pojo.dto.course.InsertCourseDTO;
import com.guwan.backend.pojo.entity.*; import com.guwan.backend.pojo.entity.*;
import com.guwan.backend.pojo.response.CourseByAdminVO; import com.guwan.backend.pojo.response.CourseByAdminVO;
import com.guwan.backend.pojo.response.CourseCenterVO;
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;
import com.guwan.backend.pojo.response.courseDetail.CourseDetailVO; import com.guwan.backend.pojo.response.courseDetail.CourseDetailVO;
@ -350,5 +350,55 @@ public class CourseController {
return Result.success(); return Result.success();
} }
@GetMapping("/getCourseCenterList")
public SearchResult getCourseCenterList(@RequestParam(name = "page") Long pageNum,
@RequestParam Long size,
@RequestParam(required = false) String categoryId,
@RequestParam(required = false) String levelId,
@RequestParam(required = false) String typeId,
@RequestParam(required = false) String sortBy,
@RequestParam(required = false) String search) {
Page<Course> page = new Page<>(pageNum, size);
long count = courseService.count();
List<Course> courseList = courseService.list(page, new
LambdaQueryWrapperX<Course>().eqIfPresent(Course::getCategoryId, categoryId)
.eqIfPresent(Course::getLevelId, levelId).eqIfPresent(Course::getTypeId, typeId)
.likeIfPresent(Course::getTitle, search));
List<CourseCenterVO> courseCenterVOList = courseList.stream().map(
course -> {
CourseCenterVO courseCenterVO = new CourseCenterVO();
BeanUtils.copyProperties(course, courseCenterVO);
courseCenterVO.setTeacher(teacherService.getById(course.getTeacherId()).getName());
return courseCenterVO;
}
).toList();
if (sortBy != null && !sortBy.isEmpty()) {
if (sortBy.equals("newest")) {
}
if (sortBy.equals("popular")) {
}
if (sortBy.equals("rating")) {
}
}
return SearchResult.success(courseCenterVOList, count);
}
@PostMapping("/testMethod")
public void testMethod(@RequestParam(name = "page") Long pageNum){
}
} }

View File

@ -1,6 +1,6 @@
package com.guwan.backend.mapper; package com.guwan.backend.mapper;
import com.guwan.backend.pojo.dto.BSCategory; import com.guwan.backend.pojo.entity.BSCategory;
import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Mapper;
@ -8,7 +8,7 @@ import org.apache.ibatis.annotations.Mapper;
* @author 12455 * @author 12455
* @description 针对表category的数据库操作Mapper * @description 针对表category的数据库操作Mapper
* @createDate 2025-03-13 23:00:51 * @createDate 2025-03-13 23:00:51
* @Entity com.guwan.backend.pojo.dto.BSCategory * @Entity com.guwan.backend.pojo.entity.BSCategory
*/ */
@Mapper @Mapper
public interface BSCategoryMapper extends BaseMapper<BSCategory> { public interface BSCategoryMapper extends BaseMapper<BSCategory> {

View File

@ -1,57 +0,0 @@
package com.guwan.backend.pojo.dto.video;
import lombok.Data;
import java.time.LocalDateTime;
import io.swagger.v3.oas.annotations.media.Schema;
@Schema(description = "视频信息DTO")
@Data
public class VideoDTO {
@Schema(description = "视频ID")
private Long id;
@Schema(description = "视频标题")
private String title;
@Schema(description = "视频描述")
private String description;
@Schema(description = "视频URL")
private String url;
@Schema(description = "封面URL")
private String coverUrl;
@Schema(description = "视频时长(秒)")
private Long duration;
@Schema(description = "文件大小(字节)")
private Long size;
@Schema(description = "状态DRAFT-草稿PUBLISHED-已发布DELETED-已删除")
private String status;
@Schema(description = "上传用户ID")
private Long userId;
@Schema(description = "上传用户名")
private String username;
@Schema(description = "创建时间")
private LocalDateTime createdTime;
@Schema(description = "更新时间")
private LocalDateTime updatedTime;
@Schema(description = "观看次数")
private Integer viewCount;
@Schema(description = "点赞次数")
private Integer likeCount;
@Schema(description = "标签,多个用逗号分隔")
private String tags;
@Schema(description = "当前用户是否已点赞")
private Boolean hasLiked;
}

View File

@ -1,6 +1,5 @@
package com.guwan.backend.pojo.dto; package com.guwan.backend.pojo.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName; import com.baomidou.mybatisplus.annotation.TableName;

View File

@ -0,0 +1,23 @@
package com.guwan.backend.pojo.response;
import lombok.Data;
import java.math.BigDecimal;
@Data
public class CourseCenterVO {
private String id;
private String title;
private String description;
private String levelId;
private String typeId;
private String categoryId;
private String coverImg;
private BigDecimal rating;
private Integer ratingCount;
private BigDecimal price;
private Integer studentCount;
private String teacher;
}

View File

@ -1,6 +1,6 @@
package com.guwan.backend.service; package com.guwan.backend.service;
import com.guwan.backend.pojo.dto.BSCategory; import com.guwan.backend.pojo.entity.BSCategory;
import com.baomidou.mybatisplus.extension.service.IService; import com.baomidou.mybatisplus.extension.service.IService;
/** /**

View File

@ -1,7 +1,7 @@
package com.guwan.backend.service.impl; package com.guwan.backend.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.guwan.backend.pojo.dto.BSCategory; import com.guwan.backend.pojo.entity.BSCategory;
import com.guwan.backend.service.BSCategoryService; import com.guwan.backend.service.BSCategoryService;
import com.guwan.backend.mapper.BSCategoryMapper; import com.guwan.backend.mapper.BSCategoryMapper;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;