Forráskód Böngészése

feat: "完善course课程相关逻辑"

Leonezhurui 2 éve
szülő
commit
0aded98cce
24 módosított fájl, 415 hozzáadás és 108 törlés
  1. 3 3
      .drone.yml
  2. 2 3
      src/main/java/com/njuzr/eaibackend/controller/AdminController.java
  3. 1 7
      src/main/java/com/njuzr/eaibackend/controller/AuthenticationController.java
  4. 120 42
      src/main/java/com/njuzr/eaibackend/controller/CourseController.java
  5. 2 4
      src/main/java/com/njuzr/eaibackend/controller/UserController.java
  6. 1 1
      src/main/java/com/njuzr/eaibackend/dto/course/CourseDTO.java
  7. 18 0
      src/main/java/com/njuzr/eaibackend/dto/course/CourseQueryDTO.java
  8. 35 0
      src/main/java/com/njuzr/eaibackend/dto/course/CourseUpdateDTO.java
  9. 4 1
      src/main/java/com/njuzr/eaibackend/dto/course/EnrollDTO.java
  10. 1 1
      src/main/java/com/njuzr/eaibackend/dto/user/AdminRegisterDTO.java
  11. 1 1
      src/main/java/com/njuzr/eaibackend/dto/user/UserDTO.java
  12. 1 1
      src/main/java/com/njuzr/eaibackend/dto/user/UserLoginDTO.java
  13. 1 1
      src/main/java/com/njuzr/eaibackend/dto/user/UserRegisterDTO.java
  14. 1 1
      src/main/java/com/njuzr/eaibackend/dto/user/UserUpdateDTO.java
  15. 5 0
      src/main/java/com/njuzr/eaibackend/exception/MyException.java
  16. 15 0
      src/main/java/com/njuzr/eaibackend/mapper/CourseStudentMapper.java
  17. 3 0
      src/main/java/com/njuzr/eaibackend/po/Course.java
  18. 5 2
      src/main/java/com/njuzr/eaibackend/po/Enrollment.java
  19. 16 2
      src/main/java/com/njuzr/eaibackend/service/CourseService.java
  20. 4 4
      src/main/java/com/njuzr/eaibackend/service/UserService.java
  21. 171 12
      src/main/java/com/njuzr/eaibackend/service/impl/CourseServiceImpl.java
  22. 4 11
      src/main/java/com/njuzr/eaibackend/service/impl/UserServiceImpl.java
  23. 0 10
      src/main/java/com/njuzr/eaibackend/utils/ModelMapperUtil.java
  24. 1 1
      src/main/java/com/njuzr/eaibackend/vo/CourseVO.java

+ 3 - 3
.drone.yml

@@ -7,7 +7,7 @@ steps:
   - name: build-with-maven
     image: maven:3.8.5-openjdk-17-slim
     volumes:
-      - name: cache
+      - name: maven-cache
         path: /root/.m2
     commands:
       - mvn clean package -DskipTests
@@ -25,7 +25,7 @@ steps:
       tags: latest
       dockerfile: Dockerfile
 
-  # 步骤 3: 调用脚本进行部署
+  # 步骤 3: 通过ssh进行部署
   - name: deploy-with-ssh
     image: appleboy/drone-ssh
     environment:
@@ -52,7 +52,7 @@ steps:
         - docker run -d -p 8081:8080 --name eai-backend -v $(pwd)/logs:/app/logs registry.cn-hangzhou.aliyuncs.com/english-ai/eai-backend
 
 volumes:
-  - name: cache
+  - name: maven-cache
     host:
       path: /tmp/cache/.m2
 

+ 2 - 3
src/main/java/com/njuzr/eaibackend/controller/AdminController.java

@@ -1,8 +1,7 @@
 package com.njuzr.eaibackend.controller;
 
-import com.njuzr.eaibackend.dto.AdminRegisterDTO;
-import com.njuzr.eaibackend.dto.UserDTO;
-import com.njuzr.eaibackend.dto.UserRegisterDTO;
+import com.njuzr.eaibackend.dto.user.AdminRegisterDTO;
+import com.njuzr.eaibackend.dto.user.UserDTO;
 import com.njuzr.eaibackend.service.UserService;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;

+ 1 - 7
src/main/java/com/njuzr/eaibackend/controller/AuthenticationController.java

@@ -1,26 +1,20 @@
 package com.njuzr.eaibackend.controller;
 
-import com.njuzr.eaibackend.dto.UserLoginDTO;
-import com.njuzr.eaibackend.dto.UserRegisterDTO;
-import com.njuzr.eaibackend.exception.MyException;
+import com.njuzr.eaibackend.dto.user.UserLoginDTO;
 import com.njuzr.eaibackend.po.MyUserDetails;
 import com.njuzr.eaibackend.service.UserService;
 import com.njuzr.eaibackend.utils.JWTTokenUtil;
 import com.njuzr.eaibackend.utils.ModelMapperUtil;
 import com.njuzr.eaibackend.vo.UserLoginVO;
-import com.njuzr.eaibackend.vo.UserVO;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.http.HttpStatus;
-import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.security.authentication.AuthenticationManager;
 import org.springframework.security.authentication.BadCredentialsException;
 import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
 import org.springframework.security.core.Authentication;
-import org.springframework.security.core.AuthenticationException;
 import org.springframework.security.core.context.SecurityContextHolder;
 import org.springframework.security.core.userdetails.UsernameNotFoundException;
-import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.PostMapping;
 import org.springframework.web.bind.annotation.RequestBody;
 import org.springframework.web.bind.annotation.RequestMapping;

+ 120 - 42
src/main/java/com/njuzr/eaibackend/controller/CourseController.java

@@ -1,14 +1,18 @@
 package com.njuzr.eaibackend.controller;
 
+import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
-import com.njuzr.eaibackend.dto.CourseDTO;
-import com.njuzr.eaibackend.dto.EnrollDTO;
+import com.njuzr.eaibackend.dto.course.CourseDTO;
+import com.njuzr.eaibackend.dto.course.CourseQueryDTO;
+import com.njuzr.eaibackend.dto.course.CourseUpdateDTO;
+import com.njuzr.eaibackend.dto.course.EnrollDTO;
 import com.njuzr.eaibackend.po.Course;
-import com.njuzr.eaibackend.po.User;
+import com.njuzr.eaibackend.po.MyUserDetails;
 import com.njuzr.eaibackend.service.CourseService;
 import com.njuzr.eaibackend.vo.CourseVO;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.security.core.annotation.AuthenticationPrincipal;
 import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.*;
 
@@ -30,26 +34,38 @@ public class CourseController {
 
 
     /**
-     * 分页返回所有的课程信息
+     * 创建课程
+     * @param courseDTO
+     * @return
+     */
+    @PreAuthorize("hasRole('TEACHER') or hasRole('ADMIN')")
+    @PostMapping
+    public MyResponse createCourse(@Validated @RequestBody CourseDTO courseDTO) {
+        CourseVO courseVO = courseService.createCourse(courseDTO);
+        return MyResponse.success(courseVO);
+    }
+
+
+    /**
+     * 管理查询课程,内容查询
+     * @param currentPage
+     * @param pageSize
+     * @param courseQueryDTO
      * @return
      */
-    @GetMapping("/findAll")
-    public MyResponse findAllCourses(
+    @PreAuthorize("hasRole('ADMIN')")
+    @GetMapping
+    public MyResponse findCoursePage(
             @RequestParam(value = "page", defaultValue = "1") int currentPage,
-            @RequestParam(value = "size", defaultValue = "10") int pageSize
-    ) {
+            @RequestParam(value = "size", defaultValue = "10") int pageSize,
+            @RequestBody CourseQueryDTO courseQueryDTO
+            ) {
+        Page<Course> page = new Page<>(currentPage, pageSize);
+        IPage<CourseVO> courses =  courseService.findCoursesPage(page, courseQueryDTO);
 
-        return MyResponse.success("");
+        return MyResponse.success(courses);
     }
 
-//    @GetMapping()
-//    public MyResponse searchCourses(
-//            @RequestParam String courseName,
-//            @RequestParam String
-//    ) {
-//
-//    }
-
 
     /**
      * 根据学生Id获取其所选的所有课程的信息
@@ -57,12 +73,17 @@ public class CourseController {
      * @return
      */
     @GetMapping("/byStudent/{studentId}")
-    public MyResponse findByStudentId(
+    public MyResponse findCourseByStudentId(
             @PathVariable Long studentId,
-            @RequestParam(defaultValue = "0") int page,
-            @RequestParam(defaultValue = "10") int size
+            @RequestParam(value = "page", defaultValue = "1") int currentPage,
+            @RequestParam(value = "size", defaultValue = "10") int pageSize
     ) {
-        return MyResponse.success("");
+        Page<Course> page = new Page<>(currentPage, pageSize);
+
+        CourseQueryDTO courseQueryDTO = new CourseQueryDTO();
+        courseQueryDTO.setStudentId(studentId);
+
+        return MyResponse.success(courseService.findCoursesPage(page, courseQueryDTO));
     }
 
     /**
@@ -74,10 +95,15 @@ public class CourseController {
     @GetMapping("/byTeacher/{teacherId}")
     public MyResponse findByTeacherId(
             @PathVariable Long teacherId,
-            @RequestParam(defaultValue = "0") int page,
-            @RequestParam(defaultValue = "10") int size
+            @RequestParam(value = "page", defaultValue = "1") int currentPage,
+            @RequestParam(value = "size", defaultValue = "10") int pageSize
     ) {
-        return MyResponse.success("");
+        Page<Course> page = new Page<>(currentPage, pageSize);
+
+        CourseQueryDTO courseQueryDTO = new CourseQueryDTO();
+        courseQueryDTO.setTeacherId(teacherId);
+
+        return MyResponse.success(courseService.findCoursesPage(page, courseQueryDTO));
     }
 
     /**
@@ -95,44 +121,96 @@ public class CourseController {
     ) {
         Page<Course> page = new Page<>(currentPage, pageSize);
 
-        return MyResponse.success("");
+        CourseQueryDTO courseQueryDTO = new CourseQueryDTO();
+        courseQueryDTO.setCourseId(courseId);
+
+        return MyResponse.success(courseService.findCoursesPage(page, courseQueryDTO));
+    }
+
+    @GetMapping("/byName")
+    public MyResponse findByCourseName(
+            @RequestParam String courseName,
+            @RequestParam(value = "page", defaultValue = "1") int currentPage,
+            @RequestParam(value = "size", defaultValue = "10") int pageSize
+    ) {
+        Page<Course> page = new Page<>(currentPage, pageSize);
+
+        CourseQueryDTO courseQueryDTO =  new CourseQueryDTO();
+        courseQueryDTO.setCourseName(courseName);
+
+        return MyResponse.success(courseService.findCoursesPage(page, courseQueryDTO));
+    }
+
+
+    @GetMapping("/byTime")
+    public MyResponse findByCourseTime(
+            @RequestParam String courseTime,
+            @RequestParam(value = "page", defaultValue = "1") int currentPage,
+            @RequestParam(value = "size", defaultValue = "10") int pageSize
+    ) {
+        Page<Course> page = new Page<>(currentPage, pageSize);
+
+        CourseQueryDTO courseQueryDTO =  new CourseQueryDTO();
+        courseQueryDTO.setSemester(courseTime);
+
+        return MyResponse.success(courseService.findCoursesPage(page, courseQueryDTO));
     }
 
     /**
-     * 创建课程
-     * @param courseDTO
+     * 只有课程老师或管理员可以修改当前课程的信息
+     * @param userId
+     * @param courseId
+     * @param updateDTO
      * @return
      */
     @PreAuthorize("hasRole('TEACHER') or hasRole('ADMIN')")
-    @PostMapping
-    public MyResponse createCourse(@Validated @RequestBody CourseDTO courseDTO) {
-        CourseVO courseVO = courseService.createCourse(courseDTO);
-        return MyResponse.success(courseVO);
-    }
-
     @PutMapping
-    public MyResponse updateCourse(@RequestBody CourseDTO courseDTO) {
-        return MyResponse.success("");
+    public MyResponse updateCourse(
+            @AuthenticationPrincipal(expression = "id") Long userId,
+            @RequestParam Long courseId,
+            @RequestBody CourseUpdateDTO updateDTO
+    ) {
+        return MyResponse.success(courseService.updateCourse(userId, courseId, updateDTO));
     }
 
+
+    @PreAuthorize("hasRole('TEACHER') or hasRole('ADMIN')")
     @PutMapping("/enrollCode")
-    public MyResponse updateEnrollCode(@RequestParam String enrollCode) {
-        return MyResponse.success("");
+    public MyResponse updateEnrollCode(
+            @AuthenticationPrincipal(expression = "id") Long userId,
+            @RequestParam Long courseId,
+            @RequestParam String enrollCode
+    ) {
+        CourseUpdateDTO updateDTO = new CourseUpdateDTO();
+        updateDTO.setEnrollCode(enrollCode);
+        return MyResponse.success(courseService.updateCourse(userId, courseId, updateDTO));
     }
 
+    @PreAuthorize("hasRole('TEACHER') or hasRole('ADMIN')")
     @DeleteMapping
-    public MyResponse deleteCourse(@RequestParam Long courseId) {
-        return MyResponse.success("");
+    public MyResponse deleteCourse(
+            @AuthenticationPrincipal MyUserDetails user,
+            @RequestParam Long courseId
+    ) {
+        courseService.deleteById(user, courseId);
+        return MyResponse.success("删除课程成功");
     }
 
     /**
-     * 选课,通过studentId和courseId,完成选课
+     * 选课,通过studentId和courseId,完成选课。其中studentId从Token中获取。
+     * @param studentId
      * @param enrollDTO
      * @return
      */
+    @PreAuthorize("hasRole('STUDENT')")
     @PostMapping("/enroll")
-    public MyResponse enroll(@RequestBody EnrollDTO enrollDTO) {
-        return MyResponse.success("");
+    public MyResponse enroll(
+            @AuthenticationPrincipal(expression = "id") Long studentId,
+            @RequestBody EnrollDTO enrollDTO
+    ) {
+        enrollDTO.setStudentId(studentId);
+        courseService.enroll(enrollDTO);
+        return MyResponse.success("选课成功");
     }
 
 

+ 2 - 4
src/main/java/com/njuzr/eaibackend/controller/UserController.java

@@ -2,8 +2,8 @@ package com.njuzr.eaibackend.controller;
 
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
-import com.njuzr.eaibackend.dto.UserRegisterDTO;
-import com.njuzr.eaibackend.dto.UserUpdateDTO;
+import com.njuzr.eaibackend.dto.user.UserRegisterDTO;
+import com.njuzr.eaibackend.dto.user.UserUpdateDTO;
 import com.njuzr.eaibackend.enums.Role;
 import com.njuzr.eaibackend.exception.MyException;
 import com.njuzr.eaibackend.po.User;
@@ -11,10 +11,8 @@ import com.njuzr.eaibackend.service.UserService;
 import com.njuzr.eaibackend.vo.UserVO;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.http.HttpStatus;
 import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.security.core.annotation.AuthenticationPrincipal;
-import org.springframework.security.core.userdetails.UserDetails;
 import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.*;
 

+ 1 - 1
src/main/java/com/njuzr/eaibackend/dto/CourseDTO.java → src/main/java/com/njuzr/eaibackend/dto/course/CourseDTO.java

@@ -1,4 +1,4 @@
-package com.njuzr.eaibackend.dto;
+package com.njuzr.eaibackend.dto.course;
 
 import com.fasterxml.jackson.annotation.JsonFormat;
 import jakarta.validation.constraints.NotNull;

+ 18 - 0
src/main/java/com/njuzr/eaibackend/dto/course/CourseQueryDTO.java

@@ -0,0 +1,18 @@
+package com.njuzr.eaibackend.dto.course;
+
+import lombok.Data;
+
+/**
+ * @author: Leonezhurui
+ * @Date: 2024/3/12 - 09:14
+ * @Package: EAI-Backend
+ */
+
+@Data
+public class CourseQueryDTO {
+    private Long courseId;
+    private Long teacherId;
+    private Long studentId;
+    private String courseName;
+    private String semester;
+}

+ 35 - 0
src/main/java/com/njuzr/eaibackend/dto/course/CourseUpdateDTO.java

@@ -0,0 +1,35 @@
+package com.njuzr.eaibackend.dto.course;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import jakarta.validation.constraints.NotNull;
+import lombok.Data;
+
+import java.util.Date;
+import java.util.List;
+
+/**
+ * @author: Leonezhurui
+ * @Date: 2024/3/12 - 11:12
+ * @Package: EAI-Backend
+ */
+
+@Data
+public class CourseUpdateDTO {
+    private String courseName;
+
+    private List<Long> teacherIds;
+
+    private List<String> courseImages;
+
+    private String targetGrade;
+
+    @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss")
+    private Date startTime;
+
+    @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss")
+    private Date endTime;
+
+    private String description;
+
+    private String enrollCode; // 选课码
+}

+ 4 - 1
src/main/java/com/njuzr/eaibackend/dto/EnrollDTO.java → src/main/java/com/njuzr/eaibackend/dto/course/EnrollDTO.java

@@ -1,5 +1,6 @@
-package com.njuzr.eaibackend.dto;
+package com.njuzr.eaibackend.dto.course;
 
+import lombok.AllArgsConstructor;
 import lombok.Data;
 
 /**
@@ -8,8 +9,10 @@ import lombok.Data;
  * @Package: EAI-Backend
  */
 
+@AllArgsConstructor
 @Data
 public class EnrollDTO {
     private Long studentId;
     private Long courseId;
+    private String enrollCode;
 }

+ 1 - 1
src/main/java/com/njuzr/eaibackend/dto/AdminRegisterDTO.java → src/main/java/com/njuzr/eaibackend/dto/user/AdminRegisterDTO.java

@@ -1,4 +1,4 @@
-package com.njuzr.eaibackend.dto;
+package com.njuzr.eaibackend.dto.user;
 
 import com.njuzr.eaibackend.enums.Role;
 import jakarta.validation.constraints.NotNull;

+ 1 - 1
src/main/java/com/njuzr/eaibackend/dto/UserDTO.java → src/main/java/com/njuzr/eaibackend/dto/user/UserDTO.java

@@ -1,4 +1,4 @@
-package com.njuzr.eaibackend.dto;
+package com.njuzr.eaibackend.dto.user;
 
 import com.njuzr.eaibackend.po.base.BaseUser;
 import lombok.Data;

+ 1 - 1
src/main/java/com/njuzr/eaibackend/dto/UserLoginDTO.java → src/main/java/com/njuzr/eaibackend/dto/user/UserLoginDTO.java

@@ -1,4 +1,4 @@
-package com.njuzr.eaibackend.dto;
+package com.njuzr.eaibackend.dto.user;
 
 import lombok.Data;
 

+ 1 - 1
src/main/java/com/njuzr/eaibackend/dto/UserRegisterDTO.java → src/main/java/com/njuzr/eaibackend/dto/user/UserRegisterDTO.java

@@ -1,4 +1,4 @@
-package com.njuzr.eaibackend.dto;
+package com.njuzr.eaibackend.dto.user;
 
 import com.njuzr.eaibackend.enums.Role;
 import com.njuzr.eaibackend.po.base.BaseUser;

+ 1 - 1
src/main/java/com/njuzr/eaibackend/dto/UserUpdateDTO.java → src/main/java/com/njuzr/eaibackend/dto/user/UserUpdateDTO.java

@@ -1,4 +1,4 @@
-package com.njuzr.eaibackend.dto;
+package com.njuzr.eaibackend.dto.user;
 
 import com.njuzr.eaibackend.enums.Gender;
 import lombok.Data;

+ 5 - 0
src/main/java/com/njuzr/eaibackend/exception/MyException.java

@@ -1,6 +1,7 @@
 package com.njuzr.eaibackend.exception;
 
 import lombok.Getter;
+import org.springframework.http.HttpStatus;
 
 /**
  * @author: Leonezhurui
@@ -16,4 +17,8 @@ public class MyException extends RuntimeException{
         super(errMsg);
         this.errCode = errCode;
     }
+
+    public static MyException create(HttpStatus status, String msg) {
+        return new MyException(status.value(), status.getReasonPhrase()+":"+msg);
+    }
 }

+ 15 - 0
src/main/java/com/njuzr/eaibackend/mapper/CourseStudentMapper.java

@@ -0,0 +1,15 @@
+package com.njuzr.eaibackend.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.njuzr.eaibackend.po.Enrollment;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * @author: Leonezhurui
+ * @Date: 2024/3/11 - 21:09
+ * @Package: EAI-Backend
+ */
+
+@Mapper
+public interface CourseStudentMapper extends BaseMapper<Enrollment> {
+}

+ 3 - 0
src/main/java/com/njuzr/eaibackend/po/Course.java

@@ -26,6 +26,9 @@ public class Course {
     @TableField("teacher_ids")
     private String teacherIds; // 序列化好的字符串
 
+    @TableField("enroll_code")
+    private String enrollCode; //选课码
+
     @TableField("course_imgs")
     private String courseImages; // 序列化好的字符串
 

+ 5 - 2
src/main/java/com/njuzr/eaibackend/po/Enrollment.java

@@ -1,6 +1,7 @@
 package com.njuzr.eaibackend.po;
 
 import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
 import com.baomidou.mybatisplus.annotation.TableId;
 import com.baomidou.mybatisplus.annotation.TableName;
 import lombok.Data;
@@ -17,9 +18,11 @@ import org.springframework.data.annotation.Id;
 @TableName("course_student")
 public class Enrollment {
     @TableId(type = IdType.AUTO)
-    private Long id;
+    private Long enrollmentId;
 
+    @TableField(value = "course_id")
     private Long courseId;
 
-    private Long userId;
+    @TableField(value = "student_id")
+    private Long studentId;
 }

+ 16 - 2
src/main/java/com/njuzr/eaibackend/service/CourseService.java

@@ -1,6 +1,14 @@
 package com.njuzr.eaibackend.service;
 
-import com.njuzr.eaibackend.dto.CourseDTO;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.njuzr.eaibackend.dto.course.CourseDTO;
+import com.njuzr.eaibackend.dto.course.CourseQueryDTO;
+import com.njuzr.eaibackend.dto.course.CourseUpdateDTO;
+import com.njuzr.eaibackend.dto.course.EnrollDTO;
+import com.njuzr.eaibackend.enums.Role;
+import com.njuzr.eaibackend.po.Course;
+import com.njuzr.eaibackend.po.MyUserDetails;
 import com.njuzr.eaibackend.vo.CourseVO;
 
 /**
@@ -12,6 +20,12 @@ import com.njuzr.eaibackend.vo.CourseVO;
 public interface CourseService {
     CourseVO createCourse(CourseDTO courseDTO);
 
-    CourseVO findByCourseId(Long courseId);
+    IPage<CourseVO> findCoursesPage(Page<Course> page, CourseQueryDTO courseQueryDTO);
+
+    CourseVO updateCourse(Long userId, Long courseId, CourseUpdateDTO courseUpdateDTO);
+
+    void deleteById(MyUserDetails role, Long courseId);
+
+    void enroll(EnrollDTO enrollDTO);
 
 }

+ 4 - 4
src/main/java/com/njuzr/eaibackend/service/UserService.java

@@ -2,10 +2,10 @@ package com.njuzr.eaibackend.service;
 
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
-import com.njuzr.eaibackend.dto.AdminRegisterDTO;
-import com.njuzr.eaibackend.dto.UserDTO;
-import com.njuzr.eaibackend.dto.UserRegisterDTO;
-import com.njuzr.eaibackend.dto.UserUpdateDTO;
+import com.njuzr.eaibackend.dto.user.AdminRegisterDTO;
+import com.njuzr.eaibackend.dto.user.UserDTO;
+import com.njuzr.eaibackend.dto.user.UserRegisterDTO;
+import com.njuzr.eaibackend.dto.user.UserUpdateDTO;
 import com.njuzr.eaibackend.enums.Role;
 import com.njuzr.eaibackend.po.User;
 import com.njuzr.eaibackend.vo.UserVO;

+ 171 - 12
src/main/java/com/njuzr/eaibackend/service/impl/CourseServiceImpl.java

@@ -1,25 +1,36 @@
 package com.njuzr.eaibackend.service.impl;
 
-import com.baomidou.mybatisplus.core.toolkit.StringUtils;
-import com.njuzr.eaibackend.dto.CourseDTO;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.njuzr.eaibackend.controller.MyResponse;
+import com.njuzr.eaibackend.dto.course.CourseDTO;
+import com.njuzr.eaibackend.dto.course.CourseQueryDTO;
+import com.njuzr.eaibackend.dto.course.CourseUpdateDTO;
+import com.njuzr.eaibackend.dto.course.EnrollDTO;
+import com.njuzr.eaibackend.enums.Role;
 import com.njuzr.eaibackend.exception.MyException;
 import com.njuzr.eaibackend.mapper.CourseMapper;
+import com.njuzr.eaibackend.mapper.CourseStudentMapper;
+import com.njuzr.eaibackend.mapper.UserMapper;
 import com.njuzr.eaibackend.po.Course;
+import com.njuzr.eaibackend.po.Enrollment;
+import com.njuzr.eaibackend.po.MyUserDetails;
+import com.njuzr.eaibackend.po.User;
 import com.njuzr.eaibackend.service.CourseService;
 import com.njuzr.eaibackend.utils.ConvertUtil;
 import com.njuzr.eaibackend.utils.ModelMapperUtil;
+import com.njuzr.eaibackend.utils.PageMapperUtil;
 import com.njuzr.eaibackend.vo.CourseVO;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.context.annotation.Bean;
 import org.springframework.http.HttpStatus;
 import org.springframework.stereotype.Service;
 
-import java.util.Arrays;
+import java.time.LocalDate;
+import java.time.format.DateTimeFormatter;
 import java.util.Date;
-import java.util.List;
-import java.util.stream.Collectors;
 
 /**
  * @author: Leonezhurui
@@ -33,15 +44,20 @@ public class CourseServiceImpl implements CourseService {
 
     private final CourseMapper courseMapper;
 
+    private final UserMapper userMapper;
+
+    private final CourseStudentMapper courseStudentMapper;
+
     @Autowired
-    public CourseServiceImpl(CourseMapper courseMapper) {
+    public CourseServiceImpl(CourseMapper courseMapper, UserMapper userMapper, CourseStudentMapper courseStudentMapper) {
         this.courseMapper = courseMapper;
+        this.userMapper = userMapper;
+        this.courseStudentMapper = courseStudentMapper;
     }
 
 
     @Override
     public CourseVO createCourse(CourseDTO courseDTO) {
-        log.info("解析CourseDTO:"+courseDTO.toString());
         // 类型转换
         Course targetCourse = convertToPO(courseDTO);
         targetCourse.setCreateTime(new Date());
@@ -60,11 +76,145 @@ public class CourseServiceImpl implements CourseService {
 
 
     @Override
-    public CourseVO findByCourseId(Long courseId) {
-        Course res = courseMapper.selectById(courseId);
-        return convertToVO(res);
+    public IPage<CourseVO> findCoursesPage(Page<Course> page, CourseQueryDTO courseQueryDTO) {
+        QueryWrapper<Course> wrapper = getCourseQueryWrapper(courseQueryDTO);
+
+        IPage<Course> courses = courseMapper.selectPage(page, wrapper);
+
+        return PageMapperUtil.convert(courses, this::convertToVO);
     }
 
+    /**
+     * 设置查询条件
+     * @param courseQueryDTO
+     * @return
+     */
+    private static QueryWrapper<Course> getCourseQueryWrapper(CourseQueryDTO courseQueryDTO) {
+        QueryWrapper<Course> wrapper = new QueryWrapper<>();
+
+        if (courseQueryDTO.getCourseId() != null) { // courseId直接判断是否相等
+            wrapper.eq("course_id", courseQueryDTO.getCourseId());
+        }
+        if (courseQueryDTO.getTeacherId() != null) { // 模糊匹配teacherIds中是否包含这个字段
+            wrapper.like("teacher_ids", "%" + courseQueryDTO.getTeacherId() + "%"); // 模糊匹配
+        }
+        if (courseQueryDTO.getCourseName() != null) { // 模糊匹配课程名字
+            wrapper.like("course_name", courseQueryDTO.getCourseName());
+        }
+
+        if (courseQueryDTO.getStudentId() != null) { // 联表查询学生所选课程
+            wrapper.inSql("course_id", "SELECT course_id FROM course_student WHERE student_id = " + courseQueryDTO.getStudentId());
+        }
+
+        if (courseQueryDTO.getSemester() != null) { // 课程时间过滤,转换成具体日期
+            String semester = courseQueryDTO.getSemester();
+
+            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
+
+            LocalDate startDate, endDate;
+            // 解析输入字符串获取学年和学期
+            try {
+                String[] parts = semester.split("学年第");
+                String[] years = parts[0].split("-");
+                int yearStart = Integer.parseInt(years[0]);
+                int semesterType = parts[1].startsWith("一") ? 1 : 2;
+
+                // 根据学期计算开始和结束日期
+                if (semesterType == 1) {
+                    startDate = LocalDate.of(yearStart, 9, 1);
+                    endDate = LocalDate.of(yearStart + 1, 3, 1);
+                } else {
+                    startDate = LocalDate.of(yearStart + 1, 3, 1);
+                    endDate = LocalDate.of(yearStart + 1, 9, 1);
+                }
+            } catch (Exception e) {
+                log.error(e.getMessage());
+                throw MyException.create(HttpStatus.BAD_REQUEST, "学期字符串解析错误");
+            }
+
+            wrapper.ge("start_time", startDate.format(formatter))
+                    .le("end_time", endDate.format(formatter));
+        }
+
+        return wrapper;
+    }
+
+    /**
+     * 更新课程信息
+     * @param courseUpdateDTO
+     */
+    @Override
+    public CourseVO updateCourse(Long userId, Long courseId, CourseUpdateDTO courseUpdateDTO) {
+        User targetUser = userMapper.selectById(userId);
+        Course targetCourse = courseMapper.selectById(courseId);
+
+        if (targetCourse == null)
+            throw MyException.create(HttpStatus.BAD_REQUEST, "课程不存在");
+
+        if (targetUser.getRole() != Role.ADMIN && !targetCourse.getTeacherIds().contains(String.valueOf(userId)))
+            throw MyException.create(HttpStatus.BAD_REQUEST, "无权限更新");
+
+        Course opeCourse = convertToPO(courseUpdateDTO);
+        opeCourse.setCourseId(courseId);
+
+        try {
+            int code = courseMapper.updateById(opeCourse);
+            if (code == 0) {
+                throw MyException.create(HttpStatus.INTERNAL_SERVER_ERROR, "更新课程失败");
+            }
+        } catch (Exception e) {
+            log.error(e.getMessage());
+            throw MyException.create(HttpStatus.INTERNAL_SERVER_ERROR, "更新课程失败");
+        }
+
+        return convertToVO(courseMapper.selectById(courseId));
+    }
+
+
+    /**
+     * 删除课程
+     * @param user
+     * @param courseId
+     */
+    @Override
+    public void deleteById(MyUserDetails user, Long courseId) {
+        Course course = courseMapper.selectById(courseId);
+        if (course == null)
+            throw MyException.create(HttpStatus.BAD_REQUEST, "课程不存在");
+
+        if (user.getRole() != Role.ADMIN && !course.getTeacherIds().contains(String.valueOf(user.getId())))
+            throw MyException.create(HttpStatus.BAD_REQUEST, "无权限删除");
+
+        try {
+            int code = courseMapper.deleteById(courseId);
+            if (code == 0)
+                throw MyException.create(HttpStatus.INTERNAL_SERVER_ERROR, "删除课程失败");
+        } catch (Exception e) {
+            log.error(e.getMessage());
+            throw MyException.create(HttpStatus.INTERNAL_SERVER_ERROR, "删除课程失败");
+        }
+    }
+
+    /**
+     * 学生选课。给course_student表添加记录。
+     * @param enrollDTO
+     */
+    @Override
+    public void enroll(EnrollDTO enrollDTO) {
+        Course target = courseMapper.selectById(enrollDTO.getCourseId());
+
+        if (target == null)
+            throw MyException.create(HttpStatus.BAD_REQUEST, "课程不存在");
+        if (!target.getEnrollCode().equals(enrollDTO.getEnrollCode()))
+            throw MyException.create(HttpStatus.BAD_REQUEST, "选课码错误");
+
+        Enrollment enrollment = ModelMapperUtil.map(enrollDTO, Enrollment.class);
+        courseStudentMapper.insert(enrollment);
+    }
+
+
+
+
     /**
      * 将DTO转换成PO
      * @param courseDTO
@@ -79,6 +229,16 @@ public class CourseServiceImpl implements CourseService {
         return course;
     }
 
+    private Course convertToPO(CourseUpdateDTO updateDTO) {
+        Course course = new Course();
+        BeanUtils.copyProperties(updateDTO, course);
+        if (updateDTO.getTeacherIds() != null)
+            course.setTeacherIds(ConvertUtil.listToString(updateDTO.getTeacherIds()));
+        if (updateDTO.getCourseImages() != null)
+            course.setCourseImages(ConvertUtil.listToString(updateDTO.getCourseImages()));
+        return course;
+    }
+
     /**
      * 将PO转换成VO
      * @param course
@@ -94,5 +254,4 @@ public class CourseServiceImpl implements CourseService {
         return res;
     }
 
-
 }

+ 4 - 11
src/main/java/com/njuzr/eaibackend/service/impl/UserServiceImpl.java

@@ -3,12 +3,11 @@ package com.njuzr.eaibackend.service.impl;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.core.toolkit.StringUtils;
-import com.baomidou.mybatisplus.extension.activerecord.Model;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
-import com.njuzr.eaibackend.dto.AdminRegisterDTO;
-import com.njuzr.eaibackend.dto.UserDTO;
-import com.njuzr.eaibackend.dto.UserRegisterDTO;
-import com.njuzr.eaibackend.dto.UserUpdateDTO;
+import com.njuzr.eaibackend.dto.user.AdminRegisterDTO;
+import com.njuzr.eaibackend.dto.user.UserDTO;
+import com.njuzr.eaibackend.dto.user.UserRegisterDTO;
+import com.njuzr.eaibackend.dto.user.UserUpdateDTO;
 import com.njuzr.eaibackend.enums.Role;
 import com.njuzr.eaibackend.exception.MyException;
 import com.njuzr.eaibackend.mapper.UserMapper;
@@ -19,13 +18,9 @@ import com.njuzr.eaibackend.utils.ModelMapperUtil;
 import com.njuzr.eaibackend.utils.PageMapperUtil;
 import com.njuzr.eaibackend.vo.UserVO;
 import com.opencsv.CSVReader;
-import com.opencsv.exceptions.CsvValidationException;
-import jakarta.mail.MessagingException;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.poi.ss.usermodel.*;
 import org.apache.poi.xssf.usermodel.XSSFWorkbook;
-import org.springframework.beans.BeanUtils;
-import org.springframework.beans.BeansException;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.data.redis.core.RedisTemplate;
 import org.springframework.data.redis.core.ValueOperations;
@@ -35,11 +30,9 @@ import org.springframework.security.crypto.password.PasswordEncoder;
 import org.springframework.stereotype.Service;
 import org.springframework.web.multipart.MultipartFile;
 
-import java.io.IOException;
 import java.io.InputStreamReader;
 import java.util.*;
 import java.util.concurrent.TimeUnit;
-import java.util.stream.Collectors;
 
 /**
  * @author: Leonezhurui

+ 0 - 10
src/main/java/com/njuzr/eaibackend/utils/ModelMapperUtil.java

@@ -1,19 +1,9 @@
 package com.njuzr.eaibackend.utils;
 
-import com.njuzr.eaibackend.dto.CourseDTO;
 import com.njuzr.eaibackend.exception.MyException;
-import com.njuzr.eaibackend.po.Course;
-import com.njuzr.eaibackend.vo.CourseVO;
 import lombok.extern.slf4j.Slf4j;
-import org.modelmapper.Conditions;
-import org.modelmapper.Converter;
 import org.modelmapper.ModelMapper;
 import org.modelmapper.convention.MatchingStrategies;
-import org.modelmapper.spi.MappingContext;
-
-import java.util.Arrays;
-import java.util.List;
-import java.util.stream.Collectors;
 
 /**
  * @author: Leonezhurui

+ 1 - 1
src/main/java/com/njuzr/eaibackend/vo/CourseVO.java

@@ -18,7 +18,7 @@ import java.util.List;
  */
 
 @Data
-public class CourseVO {
+public class CourseVO { // 不需要把选课码放出来
     private Long courseId;
 
     private String courseName;