Просмотр исходного кода

Merge remote-tracking branch 'origin/seec' into seec

yhd12345 3 лет назад
Родитель
Сommit
356b3d174d
26 измененных файлов с 934 добавлено и 70 удалено
  1. 2 1
      seecoder-portal-common/src/main/java/cn/seecoder/seecoderportalcommon/vo/ActionType.java
  2. 122 0
      seecoder-portal-common/src/main/java/cn/seecoder/seecoderportalcommon/vo/CourseWareVO.java
  3. 2 1
      seecoder-portal-common/src/main/java/cn/seecoder/seecoderportalcommon/vo/ObjectType.java
  4. 17 0
      seecoder-portal-common/src/main/java/cn/seecoder/seecoderportalcommon/vo/UseMethod.java
  5. 25 0
      seecoder-portal-common/src/main/java/cn/seecoder/seecoderportalcommon/vo/UseTime.java
  6. 33 0
      seecoder-portal-common/src/main/java/cn/seecoder/seecoderportalcommon/vo/dto/CourseWareDTO.java
  7. 153 0
      seecoder-portal-server/src/main/java/cn/seecoder/seecoderportalserver/domain/CourseWare.java
  8. 12 0
      seecoder-portal-server/src/main/java/cn/seecoder/seecoderportalserver/mapper/CourseWareMapper.java
  9. 26 0
      seecoder-portal-server/src/main/java/cn/seecoder/seecoderportalserver/repository/CourseWareRepository.java
  10. 3 0
      seecoder-portal-server/src/main/java/cn/seecoder/seecoderportalserver/repository/MessageRepository.java
  11. 4 0
      seecoder-portal-server/src/main/java/cn/seecoder/seecoderportalserver/service/CourseService.java
  12. 35 0
      seecoder-portal-server/src/main/java/cn/seecoder/seecoderportalserver/service/CourseWareService.java
  13. 10 0
      seecoder-portal-server/src/main/java/cn/seecoder/seecoderportalserver/service/GroupService.java
  14. 2 0
      seecoder-portal-server/src/main/java/cn/seecoder/seecoderportalserver/service/MessageService.java
  15. 13 2
      seecoder-portal-server/src/main/java/cn/seecoder/seecoderportalserver/service/UserService.java
  16. 61 9
      seecoder-portal-server/src/main/java/cn/seecoder/seecoderportalserver/serviceImpl/CourseServiceImpl.java
  17. 152 0
      seecoder-portal-server/src/main/java/cn/seecoder/seecoderportalserver/serviceImpl/CourseWareServiceImpl.java
  18. 53 1
      seecoder-portal-server/src/main/java/cn/seecoder/seecoderportalserver/serviceImpl/GroupServiceImpl.java
  19. 34 1
      seecoder-portal-server/src/main/java/cn/seecoder/seecoderportalserver/serviceImpl/MessageServiceImpl.java
  20. 49 49
      seecoder-portal-server/src/main/java/cn/seecoder/seecoderportalserver/serviceImpl/subsystem/HelperService.java
  21. 6 3
      seecoder-portal-server/src/main/java/cn/seecoder/seecoderportalserver/web/rest/AdminController.java
  22. 11 2
      seecoder-portal-server/src/main/java/cn/seecoder/seecoderportalserver/web/rest/CourseController.java
  23. 77 0
      seecoder-portal-server/src/main/java/cn/seecoder/seecoderportalserver/web/rest/CourseWareController.java
  24. 5 0
      seecoder-portal-server/src/main/java/cn/seecoder/seecoderportalserver/web/rest/GroupController.java
  25. 5 0
      seecoder-portal-server/src/main/java/cn/seecoder/seecoderportalserver/web/rest/MessageController.java
  26. 22 1
      seecoder-portal-server/src/main/resources/portal.sql

+ 2 - 1
seecoder-portal-common/src/main/java/cn/seecoder/seecoderportalcommon/vo/ActionType.java

@@ -1,7 +1,8 @@
 package cn.seecoder.seecoderportalcommon.vo;
 
 public enum ActionType {
-    COMMENT("COMMENT");
+    COMMENT("COMMENT"),
+    INVITATION("INVITATION");
 
     private final String type;
 

+ 122 - 0
seecoder-portal-common/src/main/java/cn/seecoder/seecoderportalcommon/vo/CourseWareVO.java

@@ -0,0 +1,122 @@
+package cn.seecoder.seecoderportalcommon.vo;
+
+import java.time.OffsetDateTime;
+
+public class CourseWareVO {
+    private Long id;
+
+    private String name;
+
+    private Double size;
+
+    private Long senderId;
+
+    private Long courseId;
+
+    private OffsetDateTime createdTime;
+
+    private UseTime useTime;
+
+    private UseMethod useMethod;
+
+    private String fileUrl;
+
+    private ObjectState state;
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public Double getSize() {
+        return size;
+    }
+
+    public void setSize(Double size) {
+        this.size = size;
+    }
+
+    public Long getSenderId() {
+        return senderId;
+    }
+
+    public void setSenderId(Long senderId) {
+        this.senderId = senderId;
+    }
+
+    public Long getCourseId() {
+        return courseId;
+    }
+
+    public void setCourseId(Long courseId) {
+        this.courseId = courseId;
+    }
+
+    public OffsetDateTime getCreatedTime() {
+        return createdTime;
+    }
+
+    public void setCreatedTime(OffsetDateTime createdTime) {
+        this.createdTime = createdTime;
+    }
+
+    public UseTime getUseTime() {
+        return useTime;
+    }
+
+    public void setUseTime(UseTime useTime) {
+        this.useTime = useTime;
+    }
+
+    public UseMethod getUseMethod() {
+        return useMethod;
+    }
+
+    public void setUseMethod(UseMethod useMethod) {
+        this.useMethod = useMethod;
+    }
+
+    public String getFileUrl() {
+        return fileUrl;
+    }
+
+    public void setFileUrl(String fileUrl) {
+        this.fileUrl = fileUrl;
+    }
+
+    public ObjectState getState() {
+        return state;
+    }
+
+    public void setState(ObjectState state) {
+        this.state = state;
+    }
+
+    @Override
+    public String toString() {
+        return "CourseWareVO{" +
+                "id=" + id +
+                ", name='" + name + '\'' +
+                ", size=" + size +
+                ", senderId=" + senderId +
+                ", courseId='" + courseId +
+                ", createdTime=" + createdTime +
+                ", useTime=" + useTime +
+                ", useMethod=" + useMethod +
+                ", fileUrl=" + fileUrl +
+                ", state=" + state +
+                '}';
+    }
+
+}

+ 2 - 1
seecoder-portal-common/src/main/java/cn/seecoder/seecoderportalcommon/vo/ObjectType.java

@@ -5,7 +5,8 @@ public enum ObjectType {
     ANNOUNCEMENT("ANNOUNCEMENT"),
     HOMEWORK("HOMEWORK"),
     EXAM("EXAM"),
-    COMMENT("COMMENT");
+    COMMENT("COMMENT"),
+    INVITATION("INVITATION");
 
     private final String type;
 

+ 17 - 0
seecoder-portal-common/src/main/java/cn/seecoder/seecoderportalcommon/vo/UseMethod.java

@@ -0,0 +1,17 @@
+package cn.seecoder.seecoderportalcommon.vo;
+
+public enum UseMethod {
+    // 浏览
+    SCAN("SCAN"),
+
+    // 附件
+    ATTACHMENT("ATTACHMENT");
+
+    private final String useMethod;
+
+    UseMethod(String useMethod) {this.useMethod = useMethod;}
+
+    public String getUseMethod() {
+        return useMethod;
+    }
+}

+ 25 - 0
seecoder-portal-common/src/main/java/cn/seecoder/seecoderportalcommon/vo/UseTime.java

@@ -0,0 +1,25 @@
+package cn.seecoder.seecoderportalcommon.vo;
+
+public enum UseTime {
+    // 课前
+    BEFORE_CLASS("BEFORE_CLASS"),
+
+    // 课中
+    IN_CLASS("IN_CLASS"),
+
+    // 课后
+    AFTER_CLASS("AFTER_CLASS"),
+
+    // 期末
+    FINISH_CLASS("FINISH_CLASS");
+
+    private final String useTime;
+
+    UseTime(String useTime) {
+        this.useTime = useTime;
+    }
+
+    public String getUseTime() {
+        return useTime;
+    }
+}

+ 33 - 0
seecoder-portal-common/src/main/java/cn/seecoder/seecoderportalcommon/vo/dto/CourseWareDTO.java

@@ -0,0 +1,33 @@
+package cn.seecoder.seecoderportalcommon.vo.dto;
+
+import cn.seecoder.seecoderportalcommon.vo.CourseWareVO;
+
+import java.util.List;
+
+public class CourseWareDTO {
+    private CourseWareVO courseWareVO;
+
+//    private List<CourseWareVO> courseWares;
+
+    public CourseWareVO getCourseWareVO() {
+        return courseWareVO;
+    }
+
+    public void setCourseWareVO(CourseWareVO courseWareVO) {
+        this.courseWareVO = courseWareVO;
+    }
+
+//    public List<CourseWareVO> getCourseWares() {
+//        return courseWares;
+//    }
+//
+//    public void setCourseWares(List<CourseWareVO> courseWares) {
+//        this.courseWares = courseWares;
+//    }
+
+    public CourseWareDTO(CourseWareVO courseWareVO) {this.courseWareVO = courseWareVO;}
+
+//    public void addCourseWare(CourseWareVO courseWareVO){
+//        this.courseWares.add(courseWareVO);
+//    }
+}

+ 153 - 0
seecoder-portal-server/src/main/java/cn/seecoder/seecoderportalserver/domain/CourseWare.java

@@ -0,0 +1,153 @@
+package cn.seecoder.seecoderportalserver.domain;
+
+import cn.seecoder.seecoderportalcommon.vo.ObjectState;
+import cn.seecoder.seecoderportalcommon.vo.UseMethod;
+import cn.seecoder.seecoderportalcommon.vo.UseTime;
+
+import javax.persistence.*;
+import javax.validation.constraints.NotNull;
+import java.time.OffsetDateTime;
+
+@Entity
+@Table(name = "courseWare")
+public class CourseWare {
+    @Id
+    @GeneratedValue(strategy = GenerationType.AUTO)
+    private Long id;
+
+    @Column
+    @NotNull
+    private String name;
+
+    @Column
+    @NotNull
+    private Double size;
+
+    @Column
+    @NotNull
+    private Long senderId;
+
+    @Column
+    @NotNull
+    private Long courseId;
+
+    @Column
+    @NotNull
+    private OffsetDateTime createdTime;
+
+    @Column
+    @NotNull
+    @Enumerated(EnumType.STRING)
+    private UseTime useTime;
+
+    @Column
+    @NotNull
+    @Enumerated(EnumType.STRING)
+    private UseMethod useMethod;
+
+    @Column
+    @NotNull
+    private String fileUrl;
+
+    @Column
+    @Enumerated(EnumType.STRING)
+    @NotNull
+    private ObjectState state;
+
+    public String getFileUrl() {
+        return fileUrl;
+    }
+
+    public void setFileUrl(String fileUrl) {
+        this.fileUrl = fileUrl;
+    }
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public Double getSize() {
+        return size;
+    }
+
+    public void setSize(Double size) {
+        this.size = size;
+    }
+
+    public Long getSenderId() {
+        return senderId;
+    }
+
+    public void setSenderId(Long senderId) {
+        this.senderId = senderId;
+    }
+
+    public Long getCourseId() {
+        return courseId;
+    }
+
+    public void setCourseId(Long courseId) {
+        this.courseId = courseId;
+    }
+
+    public OffsetDateTime getCreatedTime() {
+        return createdTime;
+    }
+
+    public void setCreatedTime(OffsetDateTime createdTime) {
+        this.createdTime = createdTime;
+    }
+
+    public UseTime getUseTime() {
+        return useTime;
+    }
+
+    public void setUseTime(UseTime useTime) {
+        this.useTime = useTime;
+    }
+
+    public UseMethod getUseMethod() {
+        return useMethod;
+    }
+
+    public void setUseMethod(UseMethod useMethod) {
+        this.useMethod = useMethod;
+    }
+
+    public ObjectState getState() {
+        return state;
+    }
+
+    public void setState(ObjectState state) {
+        this.state = state;
+    }
+
+    @Override
+    public String toString() {
+        return "CourseWare{" +
+                "id=" + id +
+                ", name='" + name + '\'' +
+                ", size=" + size +
+                ", senderId=" + senderId +
+                ", courseId='" + courseId +
+                ", createdTime=" + createdTime +
+                ", useTime=" + useTime +
+                ", useMethod=" + useMethod +
+                ", fileUrl=" + fileUrl +
+                ", state=" + state +
+                '}';
+    }
+
+}

+ 12 - 0
seecoder-portal-server/src/main/java/cn/seecoder/seecoderportalserver/mapper/CourseWareMapper.java

@@ -0,0 +1,12 @@
+package cn.seecoder.seecoderportalserver.mapper;
+
+import cn.seecoder.seecoderportalcommon.vo.CourseWareVO;
+import cn.seecoder.seecoderportalserver.domain.CourseWare;
+import org.mapstruct.Mapper;
+
+@Mapper(componentModel = "spring")
+public interface CourseWareMapper {
+    CourseWare toCourseWare(CourseWareVO courseWareVO);
+
+    CourseWareVO toCourseWareVO(CourseWare courseWare);
+}

+ 26 - 0
seecoder-portal-server/src/main/java/cn/seecoder/seecoderportalserver/repository/CourseWareRepository.java

@@ -0,0 +1,26 @@
+package cn.seecoder.seecoderportalserver.repository;
+
+import cn.seecoder.seecoderportalcommon.vo.ObjectState;
+import cn.seecoder.seecoderportalserver.domain.Course;
+import cn.seecoder.seecoderportalserver.domain.CourseWare;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Select;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.stereotype.Repository;
+
+import java.util.List;
+import java.util.Optional;
+
+public interface CourseWareRepository extends JpaRepository<CourseWare, Long> {
+    //@Select("select * from ${name}")
+    List<CourseWare> findCourseWaresByCourseIdAndStateNot(Long courseId, ObjectState state);
+
+    //@Select("select * from ${name} where id=${id}")
+    CourseWare findCourseWareById(Long id);
+
+    Optional<Course> findCourseByName(String name);
+
+    CourseWare findCourseWareByName(String name);
+
+    CourseWare findCourseWareByCourseIdAndName(Long courseId, String name);
+}

+ 3 - 0
seecoder-portal-server/src/main/java/cn/seecoder/seecoderportalserver/repository/MessageRepository.java

@@ -22,4 +22,7 @@ public interface MessageRepository extends JpaRepository<Message, Long> {
     List<Message> findMessagesByTargetIdAndCreatedAtIsBetweenAndStateNot(@NotNull Long targetId, @NotNull OffsetDateTime createdAt, @NotNull OffsetDateTime createdAt2, @NotNull ObjectState state);
 
     Optional<Message> findFirstMessageByTargetIdOrderByCreatedAt(@NotNull Long targetId);
+
+    List<Message> findMessagesByActionTypeAndMntId(@NotNull ActionType actionType, @NotNull Long mntId);
+
 }

+ 4 - 0
seecoder-portal-server/src/main/java/cn/seecoder/seecoderportalserver/service/CourseService.java

@@ -55,4 +55,8 @@ public interface CourseService {
      * @return Boolean
      */
     Boolean isCourseAccessible(Long id);
+
+    Boolean uploadCarouselChart(List<String> courses);
+
+    List<CourseVO> queryCarouselChart();
 }

+ 35 - 0
seecoder-portal-server/src/main/java/cn/seecoder/seecoderportalserver/service/CourseWareService.java

@@ -0,0 +1,35 @@
+package cn.seecoder.seecoderportalserver.service;
+
+import cn.seecoder.seecoderportalcommon.vo.CourseWareVO;
+import cn.seecoder.seecoderportalcommon.vo.dto.CourseWareDTO;
+import org.springframework.core.io.ByteArrayResource;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.multipart.MultipartFile;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.util.List;
+
+public interface CourseWareService {
+
+    CourseWareVO createCourseWare(CourseWareVO courseWareVO);
+
+    String uploadCourseWareFile(String name, MultipartFile file);
+
+    Boolean checkCourseWareNameUnique(Long courseId, String name);
+
+    String deleteCourseWare(Long id);
+
+    List<CourseWareDTO> getCourseWaresByCourseId(Long courseId);
+
+    CourseWareVO getCourseWareById(Long id);
+
+    String downloadCourseWare(HttpServletRequest req, HttpServletResponse res, Long id) throws IOException;
+
+    String getSlideUrl(Long slideId);
+
+    CourseWareVO getOneSlide(Long slideId);
+
+}

+ 10 - 0
seecoder-portal-server/src/main/java/cn/seecoder/seecoderportalserver/service/GroupService.java

@@ -45,6 +45,14 @@ public interface GroupService {
      */
     GroupDTO addGroupMember(GroupMemberVO groupMemberVO);
 
+    /**
+     * 发送组队邀请
+     *
+     * @param groupMemberVO
+     * @return
+     */
+    GroupDTO sendInvitation(GroupMemberVO groupMemberVO);
+
 
     /**
      * 查找某个课程小组
@@ -62,4 +70,6 @@ public interface GroupService {
      * @return List
      */
     List<GroupDTO> findAllGroupsByCourse(Long courseId);
+
+
 }

+ 2 - 0
seecoder-portal-server/src/main/java/cn/seecoder/seecoderportalserver/service/MessageService.java

@@ -22,4 +22,6 @@ public interface MessageService {
     JSONObject findViewByMessage(Long id);
 
     String readMessage(Long id, Long userId);
+
+    List<MessageVO> findUnreadInvitationsByUser(Long id);
 }

+ 13 - 2
seecoder-portal-server/src/main/java/cn/seecoder/seecoderportalserver/service/UserService.java

@@ -6,6 +6,7 @@ import cn.seecoder.seecoderportalserver.domain.User;
 import cn.seecoder.seecoderportalserver.mapper.UserMapper;
 import cn.seecoder.seecoderportalserver.repository.UserRepository;
 import cn.seecoder.seecoderportalserver.web.rest.errors.CustomErrorException;
+import com.nju.edu.gitlab.SeecoderGitlabApi;
 import com.nju.edu.gitlab.SeecoderGitlabException;
 import com.nju.edu.gitlab.vo.GitlabUserVO;
 import org.slf4j.Logger;
@@ -32,15 +33,17 @@ public class UserService {
     private final UserMapper userMapper;
     private final AliService aliService;
     private final GitlabService gitlabService;
+    private final SeecoderGitlabApi gitlabApi;
 
     public UserService(
             UserRepository userRepository, PasswordEncoder passwordEncoder,
-            UserMapper userMapper, AliService aliService, GitlabService gitlabService) {
+            UserMapper userMapper, AliService aliService, GitlabService gitlabService, SeecoderGitlabApi gitlabApi) {
         this.userRepository = userRepository;
         this.passwordEncoder = passwordEncoder;
         this.userMapper = userMapper;
         this.aliService = aliService;
         this.gitlabService = gitlabService;
+        this.gitlabApi = gitlabApi;
     }
 
     public List<User> findAllUsers() {
@@ -211,10 +214,18 @@ public class UserService {
         user.setPassword(encodedPassword);
         User savedUser = userRepository.save(user);
         try {
-            GitlabUserVO gitlabUserVO = generateGitlabUser(savedUser);
+            user.setPassword(userVO.getUsername());
+            GitlabUserVO gitlabUserVO = generateGitlabUser(user);
+            gitlabApi.changePassword(gitlabUserVO.getUserId(), "12345678" + userVO.getUsername());
         } catch (CustomErrorException customErrorException) {
+            log.error("Yuantu register create gitlab user error");
+            log.error(customErrorException.getMessage());
             userRepository.delete(savedUser);
             throw customErrorException;
+        } catch (SeecoderGitlabException e) {
+            log.error("Yuantu register change password error");
+            log.error(e.getMessage());
+            throw new RuntimeException(e);
         }
         log.debug("Created Information for Platform Yuantu User: {}", savedUser);
         return userMapper.userToUserVO(savedUser);

+ 61 - 9
seecoder-portal-server/src/main/java/cn/seecoder/seecoderportalserver/serviceImpl/CourseServiceImpl.java

@@ -1,11 +1,11 @@
 package cn.seecoder.seecoderportalserver.serviceImpl;
 
-import cn.seecoder.seecoderportalserver.domain.key.CourseSelectionKey;
 import cn.seecoder.seecoderportalcommon.vo.CourseVO;
 import cn.seecoder.seecoderportalcommon.vo.ObjectState;
 import cn.seecoder.seecoderportalcommon.vo.UserVO;
 import cn.seecoder.seecoderportalserver.domain.Course;
 import cn.seecoder.seecoderportalserver.domain.CourseSelection;
+import cn.seecoder.seecoderportalserver.domain.key.CourseSelectionKey;
 import cn.seecoder.seecoderportalserver.mapper.CourseMapper;
 import cn.seecoder.seecoderportalserver.repository.CourseRepository;
 import cn.seecoder.seecoderportalserver.repository.CourseSelectionRepository;
@@ -15,17 +15,22 @@ import cn.seecoder.seecoderportalserver.service.CourseService;
 import cn.seecoder.seecoderportalserver.service.UserService;
 import cn.seecoder.seecoderportalserver.serviceImpl.subsystem.CoderService;
 import cn.seecoder.seecoderportalserver.serviceImpl.subsystem.EvalService;
-import cn.seecoder.seecoderportalserver.serviceImpl.subsystem.HelperService;
 import cn.seecoder.seecoderportalserver.utility.OssUtil;
 import cn.seecoder.seecoderportalserver.web.rest.errors.CustomErrorException;
 import com.alibaba.fastjson.JSONObject;
+import com.google.common.io.Files;
 import org.springframework.stereotype.Service;
 import org.springframework.web.multipart.MultipartFile;
 
+import java.io.File;
+import java.io.FileWriter;
 import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
 import java.util.List;
 import java.util.stream.Collectors;
 
+
 @Service
 public class CourseServiceImpl implements CourseService {
     private final CourseRepository courseRepository;
@@ -33,23 +38,25 @@ public class CourseServiceImpl implements CourseService {
     private final CourseSelectionRepository courseSelectionRepository;
     private final UserService userService;
     private final CoderService coderService;
-    private final HelperService helperService;
+    //private final HelperService helperService;
     private final EvalService evalService;
     private final OssUtil ossUtil;
 
-    public CourseServiceImpl(CourseRepository courseRepository, CourseMapper courseMapper, CourseSelectionRepository courseSelectionRepository, CoderService coderService, HelperService helperService, EvalService evalService, UserService userService, OssUtil ossUtil) {
+    public CourseServiceImpl(CourseRepository courseRepository, CourseMapper courseMapper, CourseSelectionRepository courseSelectionRepository, CoderService coderService, /*HelperService helperService,*/ EvalService evalService, UserService userService, OssUtil ossUtil) {
         this.courseRepository = courseRepository;
         this.courseMapper = courseMapper;
         this.courseSelectionRepository = courseSelectionRepository;
         this.userService = userService;
         this.coderService = coderService;
-        this.helperService = helperService;
+        //this.helperService = helperService;
         this.evalService = evalService;
         this.ossUtil = ossUtil;
     }
 
     @Override
     public CourseVO createCourse(CourseVO courseVO, Long userId) {
+        System.out.println(courseVO);
+
         // 确认授课教师
         UserVO teacher = userService.findUserById(userId);
         if (!courseVO.getTeacher().getId().equals(userId) || !userService.isTeacher(teacher.getRole())) {
@@ -85,6 +92,9 @@ public class CourseServiceImpl implements CourseService {
         Course course = courseMapper.courseVOToCourse(courseVO);
         course.setState(ObjectState.NORMAL);
         Course result = courseRepository.save(course);
+        System.out.println(5);
+        System.out.println(course);
+        System.out.println(result);
         return courseMapper.courseToCourseVO(result);
     }
 
@@ -191,10 +201,10 @@ public class CourseServiceImpl implements CourseService {
         if (course.getEvalId() != null) {
             JSONObject evalRes = evalService.chooseCourse(course.getInvitationCode());
         }
-        // 门户系统选课
-        if (course.getHelperId() != null) {
-            JSONObject jsonObject = helperService.chooseCourse(course.getInvitationCode());
-        }
+//        // 门户系统选课
+//        if (course.getHelperId() != null) {
+//            JSONObject jsonObject = helperService.chooseCourse(course.getInvitationCode());
+//        }
         CourseSelection courseSelection = new CourseSelection(courseSelectionKey);
         courseSelection.setState(true);
         courseSelectionRepository.save(courseSelection);
@@ -267,4 +277,46 @@ public class CourseServiceImpl implements CourseService {
         }
         return checkSelection(user.getId(), id);
     }
+
+    @Override
+    public Boolean uploadCarouselChart(List<String> courses) {
+        try {
+            File file=new File("p.txt");
+            file.delete();
+            file.createNewFile();
+            String content="";
+            for (int i=0;i<3;i++){
+                String className=courses.get(i);
+                if (className!=null && className.length()!=0){
+                    if (!isCourseNameExisted(className)){
+                        throw CustomErrorException.courseNotFound();
+                    }else {
+                        content=content.concat(className).concat("\n");
+                    }
+                }
+            }
+            FileWriter fileWriter = new FileWriter(file.getPath(),true);
+            fileWriter.write(content);
+            fileWriter.close();
+            return true;
+        }catch (IOException e) {
+            return false;
+        }
+
+    }
+
+    @Override
+    public List<CourseVO> queryCarouselChart() {
+        try{
+            File file=new File("p.txt");
+            List<String> names= Files.readLines(file, StandardCharsets.UTF_8);
+            List<CourseVO> ans=new ArrayList<>();
+            for (String name : names) {
+                ans.add(courseMapper.courseToCourseVO(courseRepository.findCourseByName(name).get()));
+            }
+            return ans;
+        }catch (IOException e){
+            return null;
+        }
+    }
 }

+ 152 - 0
seecoder-portal-server/src/main/java/cn/seecoder/seecoderportalserver/serviceImpl/CourseWareServiceImpl.java

@@ -0,0 +1,152 @@
+package cn.seecoder.seecoderportalserver.serviceImpl;
+
+import cn.seecoder.seecoderportalcommon.vo.*;
+import cn.seecoder.seecoderportalcommon.vo.dto.CourseWareDTO;
+import cn.seecoder.seecoderportalserver.domain.CourseWare;
+import cn.seecoder.seecoderportalserver.mapper.CourseWareMapper;
+import cn.seecoder.seecoderportalserver.repository.CourseWareRepository;
+import cn.seecoder.seecoderportalserver.service.CourseWareService;
+import cn.seecoder.seecoderportalserver.utility.OssUtil;
+import org.springframework.core.io.ByteArrayResource;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.MediaType;
+import org.springframework.http.ResponseEntity;
+import org.springframework.stereotype.Service;
+import org.springframework.web.multipart.MultipartFile;
+
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.*;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.List;
+import java.util.Objects;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+@Service
+public class CourseWareServiceImpl implements CourseWareService {
+    private final CourseWareRepository courseWareRepository;
+    private final CourseWareMapper courseWareMapper;
+    private final OssUtil ossUtil;
+
+    public CourseWareServiceImpl(CourseWareRepository courseWareRepository, CourseWareMapper courseWareMapper, OssUtil ossUtil) {
+        this.courseWareRepository = courseWareRepository;
+        this.courseWareMapper = courseWareMapper;
+        this.ossUtil = ossUtil;
+    }
+
+    @Override
+    public CourseWareVO createCourseWare(CourseWareVO courseWareVO) {
+        System.out.println("create");
+        CourseWare courseWare = courseWareMapper.toCourseWare(courseWareVO);
+        courseWare.setState(ObjectState.NORMAL);
+        CourseWare result = courseWareRepository.save(courseWare);
+        System.out.println(result);
+        return courseWareMapper.toCourseWareVO(result);
+    }
+
+    @Override
+    public Boolean checkCourseWareNameUnique(Long courseId, String name) {
+        System.out.println("checkname");
+        List<CourseWare> courseWares = courseWareRepository.findCourseWaresByCourseIdAndStateNot(courseId, ObjectState.DELETED);
+        for (CourseWare courseWare: courseWares) {
+            if (courseWare.getName().equals(name)) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    @Override
+    public String deleteCourseWare(Long id) {
+        System.out.println("delete");
+        CourseWare courseWare = courseWareRepository.findCourseWareById(id);
+        courseWare.setState(ObjectState.DELETED);
+        courseWareRepository.save(courseWare);
+        return "delete success";
+    }
+
+    @Override
+    public List<CourseWareDTO> getCourseWaresByCourseId(Long courseId) {
+        System.out.println("get");
+        List<CourseWareDTO> result = courseWareRepository.findCourseWaresByCourseIdAndStateNot(courseId, ObjectState.DELETED).stream()
+                .map(courseWare -> new CourseWareDTO(courseWareMapper.toCourseWareVO(courseWare)))
+                .collect(Collectors.toList());
+        return result;
+    }
+
+    @Override
+    public CourseWareVO getCourseWareById(Long id) {
+        CourseWare courseWare = courseWareRepository.findCourseWareById(id);
+        return courseWareMapper.toCourseWareVO(courseWare);
+    }
+
+    @Override
+    public String uploadCourseWareFile(String name, MultipartFile file) {
+        try {
+            System.out.println("upload");
+            String courseWareUrl = ossUtil.upload(name, file.getInputStream());
+            System.out.println(courseWareUrl);
+            return courseWareUrl;
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    @Override
+    public String downloadCourseWare(HttpServletRequest req, HttpServletResponse res, Long id) throws IOException {
+        System.out.println("download");
+        CourseWare courseWare = courseWareRepository.findCourseWareById(id);
+        String fileName = courseWare.getName();
+        String filePath = courseWare.getFileUrl();
+
+        OutputStream os = null;
+        InputStream is = null;
+        try{
+            res.reset();
+            res.setCharacterEncoding("utf-8");
+            res.setContentType("application/octet-stream");
+            res.setHeader("Content-Disposition", "attachment;" + new String(fileName.getBytes("gb2312"), "ISO8859-1"));
+            File f = new File(filePath);
+            is = new FileInputStream(f);
+            ServletOutputStream sout = res.getOutputStream();
+            BufferedInputStream bis = null;
+            BufferedOutputStream bos = null;
+            bis = new BufferedInputStream(is);
+            bos = new BufferedOutputStream(sout);
+            byte[] buff = new byte[2048];
+            int bytesRead;
+            while (-1 != (bytesRead = bis.read(buff, 0, buff.length))) {
+                bos.write(buff, 0, bytesRead);
+            }
+            bos.flush();
+            bos.close();
+            bis.close();
+            is.close();
+            os.close();
+        }catch (Exception e){
+
+        }
+
+        return fileName;
+    }
+
+    @Override
+    public String getSlideUrl(Long slideId) {
+        System.out.println("geturl");
+        CourseWare courseWare = courseWareRepository.findCourseWareById(slideId);
+        return courseWare.getFileUrl();
+    }
+
+    @Override
+    public CourseWareVO getOneSlide(Long slideId) {
+        System.out.println("getinfo");
+        CourseWare courseWare = courseWareRepository.findCourseWareById(slideId);
+        return courseWareMapper.toCourseWareVO(courseWare);
+    }
+
+}

+ 53 - 1
seecoder-portal-server/src/main/java/cn/seecoder/seecoderportalserver/serviceImpl/GroupServiceImpl.java

@@ -1,5 +1,6 @@
 package cn.seecoder.seecoderportalserver.serviceImpl;
 
+import cn.seecoder.seecoderportalcommon.vo.*;
 import cn.seecoder.seecoderportalcommon.vo.dto.GroupDTO;
 import cn.seecoder.seecoderportalcommon.vo.group.GroupMemberVO;
 import cn.seecoder.seecoderportalcommon.vo.group.GroupRuleVO;
@@ -17,6 +18,7 @@ import cn.seecoder.seecoderportalserver.security.DomainUserDetails;
 import cn.seecoder.seecoderportalserver.security.SecurityUtils;
 import cn.seecoder.seecoderportalserver.service.CourseService;
 import cn.seecoder.seecoderportalserver.service.GroupService;
+import cn.seecoder.seecoderportalserver.service.MessageService;
 import cn.seecoder.seecoderportalserver.service.UserService;
 import cn.seecoder.seecoderportalserver.web.rest.errors.CustomErrorException;
 import org.postgresql.util.PSQLException;
@@ -25,6 +27,7 @@ import org.slf4j.LoggerFactory;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
+import java.time.OffsetDateTime;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.stream.Collectors;
@@ -43,8 +46,9 @@ public class GroupServiceImpl implements GroupService {
     private final GroupMemberMapper groupMemberMapper;
     private final CourseService courseService;
     private final UserService userService;
+    private final MessageService messageService;
 
-    public GroupServiceImpl(GroupRepository groupRepository, GroupMapper groupMapper, GroupRuleRepository groupRuleRepository, GroupRuleMapper groupRuleMapper, GroupMemberRepository groupMemberRepository, GroupMemberMapper groupMemberMapper, CourseService courseService, UserService userService) {
+    public GroupServiceImpl(GroupRepository groupRepository, GroupMapper groupMapper, GroupRuleRepository groupRuleRepository, GroupRuleMapper groupRuleMapper, GroupMemberRepository groupMemberRepository, GroupMemberMapper groupMemberMapper, CourseService courseService, UserService userService, MessageService messageService) {
         this.groupRepository = groupRepository;
         this.groupMapper = groupMapper;
         this.groupRuleRepository = groupRuleRepository;
@@ -53,6 +57,7 @@ public class GroupServiceImpl implements GroupService {
         this.groupMemberMapper = groupMemberMapper;
         this.courseService = courseService;
         this.userService = userService;
+        this.messageService = messageService;
     }
 
     @Override
@@ -90,6 +95,12 @@ public class GroupServiceImpl implements GroupService {
         Long courseId = groupMemberVO.getCourseId();
         Long userId = groupMemberVO.getUserId();
         String tableName = getGroupMemberTableName(courseId);
+        //对应前端,这里传入的组号并非真的是组号,而是发起者的id
+        try {
+            groupMemberVO.setGroupId(groupMemberRepository.findByUserId(tableName,groupMemberVO.getGroupId()).getGroupId());
+        }catch (Exception e){
+            throw new RuntimeException();
+        }
         // 验证选课
         if (!courseService.checkSelection(userId, courseId)) {
             throw CustomErrorException.courseSelectionNotFound();
@@ -117,6 +128,47 @@ public class GroupServiceImpl implements GroupService {
         return generateGroupDTO(courseId, group);
     }
 
+    @Override
+    @Transactional(rollbackFor = RuntimeException.class)
+    public GroupDTO sendInvitation(GroupMemberVO groupMemberVO) {
+        Long courseId = groupMemberVO.getCourseId();
+        Long userId = groupMemberVO.getUserId();
+        String tableName = getGroupMemberTableName(courseId);
+        // 验证选课
+        if (!courseService.checkSelection(userId, courseId)) {
+            throw CustomErrorException.courseSelectionNotFound();
+        }
+        // 验证尚未加入小组
+        try {
+            if (groupMemberRepository.findByUserId(tableName, userId) != null) {
+                throw CustomErrorException.groupMemberAlreadyExists();
+            }
+        } catch (PSQLException e) {
+            throw new RuntimeException(e);
+        }
+        // 验证小组未满员
+        GroupRule groupRule = groupRuleRepository.findByCourse_Id(courseId)
+                .orElseThrow(CustomErrorException::groupRuleNotFound);
+        int currentSize = groupMemberRepository.findByGroupId(tableName, groupMemberVO.getGroupId()).size();
+        if (currentSize == groupRule.getMaxSize()) {
+            throw CustomErrorException.groupAlreadyMaxSize();
+        }
+        //发送邀请
+        MessageVO messageVO=new MessageVO();
+        DomainUserDetails user = SecurityUtils.getCurrentUser();
+        messageVO.setContent(user.getName()+"邀请您加入他的小组。");
+        messageVO.setCreatedAt(OffsetDateTime.now());
+        messageVO.setState(ObjectState.NORMAL);
+        messageVO.setActionType(ActionType.INVITATION);
+        messageVO.setMntId(groupMemberVO.getUserId());
+        messageVO.setSender(new UserVOSimplified());
+        messageVO.setTargetType(ObjectType.INVITATION);
+        messageVO.setTargetId(groupMemberVO.getCourseId());
+        messageService.create(messageVO,user.getId());
+        Group group = groupRepository.findGroupById(getGroupTableName(courseId), groupMemberVO.getGroupId());
+        return generateGroupDTO(courseId, group);
+    }
+
     @Override
     public GroupDTO findGroup(Long courseId) throws CustomErrorException {
         DomainUserDetails user = SecurityUtils.getCurrentUser();

+ 34 - 1
seecoder-portal-server/src/main/java/cn/seecoder/seecoderportalserver/serviceImpl/MessageServiceImpl.java

@@ -125,7 +125,7 @@ public class MessageServiceImpl implements MessageService {
                         .map(messageMapper::toMessageVO)
                         .collect(Collectors.toList());
                 for (MessageVO messageVO : list) {
-                    if (!messageVO.getSender().getId().equals(userId)){
+                    if (!messageVO.getSender().getId().equals(userId) && messageVO.getActionType()!=ActionType.INVITATION){
                         result.add(messageVO);
                     }
                 }
@@ -176,6 +176,7 @@ public class MessageServiceImpl implements MessageService {
                 .stream()
                 .map(message -> new CourseMessageDTO(messageMapper.toMessageVO(message)))
                 .collect(Collectors.toList());
+        System.out.println(2);
         for (CourseMessageDTO courseMessageDTO : result) {
             for (MessageVO messageVO : messageRepository
                     .findMessagesByMntIdAndActionTypeIsAndTargetTypeIsAndStateNot(
@@ -207,6 +208,7 @@ public class MessageServiceImpl implements MessageService {
             case ANNOUNCEMENT:
             case EXAM:
             case HOMEWORK:
+            case INVITATION:
             default:
                 break;
         }
@@ -220,4 +222,35 @@ public class MessageServiceImpl implements MessageService {
         messageRecordRepository.save(record);
         return "消息阅读完成";
     }
+
+    @Override
+    public List<MessageVO> findUnreadInvitationsByUser(Long id) {
+        List<MessageVO> result = new ArrayList<>();
+        if (userService.isStudent(userService.findUserById(id).getRole())){
+            for (Message message : messageRepository
+                    .findMessagesByActionTypeAndMntId(ActionType.INVITATION,id)) {
+                result.add(messageMapper.toMessageVO(message));
+            }
+        }
+        result = result.stream()
+                .filter(messageVO -> {
+                    MessageRecord record = messageRecordRepository
+                            .findById(new MessageRecordKey(
+                                    messageVO.getId(),
+                                    id)).orElse(null);
+                    if (record == null) {
+                        messageRecordRepository.save(
+                                new MessageRecord(messageVO.getId(),
+                                        id,
+                                        OffsetDateTime.now(),
+                                        false,
+                                        null));
+                        return true;
+                    } else {
+                        return !record.getState();
+                    }
+                })
+                .collect(Collectors.toList());
+        return result;
+    }
 }

+ 49 - 49
seecoder-portal-server/src/main/java/cn/seecoder/seecoderportalserver/serviceImpl/subsystem/HelperService.java

@@ -1,49 +1,49 @@
-package cn.seecoder.seecoderportalserver.serviceImpl.subsystem;
-
-import cn.seecoder.seecoderportalcommon.vo.CourseVO;
-import cn.seecoder.seecoderportalserver.service.subsystem.SubsystemService;
-import com.alibaba.fastjson.JSONObject;
-import org.springframework.stereotype.Service;
-
-@Service
-public class HelperService implements SubsystemService {
-    @Override
-    public JSONObject createCourse(CourseVO courseVO) {
-        return null;
-    }
-
-    @Override
-    public void deleteCourse(CourseVO courseVO) {
-    }
-
-    @Override
-    public JSONObject chooseCourse(String code) {
-        return null;
-    }
-
-    @Override
-    public JSONObject findRecommendExamsByCourseId(int courseId) {
-        return null;
-    }
-
-    @Override
-    public JSONObject findTeacherExamsByCourseId(int courseId) {
-        return null;
-    }
-
-    @Override
-    public JSONObject findStudentExamsByCourseId(int courseId) {
-        return null;
-    }
-
-    @Override
-    public JSONObject findTeacherExams(int page, int limit, int state) {
-        return null;
-    }
-
-    @Override
-    public JSONObject findStudentExams(int page, int limit, int state) {
-        return null;
-    }
-
-}
+//package cn.seecoder.seecoderportalserver.serviceImpl.subsystem;
+//
+//import cn.seecoder.seecoderportalcommon.vo.CourseVO;
+//import cn.seecoder.seecoderportalserver.service.subsystem.SubsystemService;
+//import com.alibaba.fastjson.JSONObject;
+//import org.springframework.stereotype.Service;
+//
+//@Service
+//public class HelperService implements SubsystemService {
+//    @Override
+//    public JSONObject createCourse(CourseVO courseVO) {
+//        return null;
+//    }
+//
+//    @Override
+//    public void deleteCourse(CourseVO courseVO) {
+//    }
+//
+//    @Override
+//    public JSONObject chooseCourse(String code) {
+//        return null;
+//    }
+//
+//    @Override
+//    public JSONObject findRecommendExamsByCourseId(int courseId) {
+//        return null;
+//    }
+//
+//    @Override
+//    public JSONObject findTeacherExamsByCourseId(int courseId) {
+//        return null;
+//    }
+//
+//    @Override
+//    public JSONObject findStudentExamsByCourseId(int courseId) {
+//        return null;
+//    }
+//
+//    @Override
+//    public JSONObject findTeacherExams(int page, int limit, int state) {
+//        return null;
+//    }
+//
+//    @Override
+//    public JSONObject findStudentExams(int page, int limit, int state) {
+//        return null;
+//    }
+//
+//}

+ 6 - 3
seecoder-portal-server/src/main/java/cn/seecoder/seecoderportalserver/web/rest/AdminController.java

@@ -4,13 +4,14 @@ import cn.seecoder.seecoderportalcommon.vo.SuperState;
 import cn.seecoder.seecoderportalcommon.vo.SuperVO;
 import cn.seecoder.seecoderportalcommon.vo.UserRole;
 import cn.seecoder.seecoderportalcommon.vo.UserVO;
+import cn.seecoder.seecoderportalcommon.vo.dto.UpdateUserByIdDTO;
 import cn.seecoder.seecoderportalcommon.vo.dto.UpdateUserRoleDTO;
+import cn.seecoder.seecoderportalcommon.vo.dto.UpdateUserValidDTO;
 import cn.seecoder.seecoderportalserver.mapper.UserMapper;
 import cn.seecoder.seecoderportalserver.service.SuperService;
 import cn.seecoder.seecoderportalserver.service.UserService;
 import cn.seecoder.seecoderportalserver.utility.OkResponse;
-import cn.seecoder.seecoderportalcommon.vo.dto.UpdateUserByIdDTO;
-import cn.seecoder.seecoderportalcommon.vo.dto.UpdateUserValidDTO;
+import cn.seecoder.seecoderportalserver.utility.OssUtil;
 import org.springframework.web.bind.annotation.*;
 
 import java.util.List;
@@ -26,11 +27,13 @@ public class AdminController {
     private final SuperService superService;
     private final UserService userService;
     private final UserMapper userMapper;
+    private final OssUtil ossUtil;
 
-    public AdminController(SuperService superService, UserService userService, UserMapper userMapper) {
+    public AdminController(SuperService superService, UserService userService, UserMapper userMapper, OssUtil ossUtil) {
         this.superService = superService;
         this.userService = userService;
         this.userMapper = userMapper;
+        this.ossUtil = ossUtil;
     }
 
     /**

+ 11 - 2
seecoder-portal-server/src/main/java/cn/seecoder/seecoderportalserver/web/rest/CourseController.java

@@ -1,11 +1,10 @@
 package cn.seecoder.seecoderportalserver.web.rest;
 
-import cn.seecoder.seecoderportalserver.domain.key.CourseSelectionKey;
 import cn.seecoder.seecoderportalcommon.vo.CourseVO;
+import cn.seecoder.seecoderportalserver.domain.key.CourseSelectionKey;
 import cn.seecoder.seecoderportalserver.security.SecurityUtils;
 import cn.seecoder.seecoderportalserver.service.CourseService;
 import cn.seecoder.seecoderportalserver.utility.OkResponse;
-import com.alibaba.fastjson.JSONObject;
 import com.nju.edu.paasMonitorClient.MonitorClient;
 import com.nju.edu.paasMonitorClient.entity.Call;
 import com.nju.edu.paasMonitorCommon.enums.SeecSystem;
@@ -109,4 +108,14 @@ public class CourseController {
                                                 @RequestPart("file") MultipartFile file) {
         return OkResponse.of(courseService.uploadCourseImage(name, file));
     }
+
+    @PostMapping("/uploadCarouseChart")
+    public OkResponse<Boolean> uploadCarouselChart(@RequestBody List<String> courses) {
+        return OkResponse.of(courseService.uploadCarouselChart(courses));
+    }
+
+    @GetMapping("/queryCarouselChart")
+    public OkResponse<List<CourseVO>> queryCarouselChart(){
+        return OkResponse.of(courseService.queryCarouselChart());
+    }
 }

+ 77 - 0
seecoder-portal-server/src/main/java/cn/seecoder/seecoderportalserver/web/rest/CourseWareController.java

@@ -0,0 +1,77 @@
+package cn.seecoder.seecoderportalserver.web.rest;
+
+import cn.seecoder.seecoderportalcommon.vo.CourseWareVO;
+import cn.seecoder.seecoderportalcommon.vo.dto.CourseWareDTO;
+import cn.seecoder.seecoderportalserver.domain.CourseWare;
+import cn.seecoder.seecoderportalserver.service.CourseWareService;
+import cn.seecoder.seecoderportalserver.utility.OkResponse;
+import org.springframework.core.io.ByteArrayResource;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.util.List;
+
+@RestController
+@RequestMapping("/api/courseWare")
+public class CourseWareController {
+    private final CourseWareService courseWareService;
+
+    public CourseWareController(CourseWareService courseWareService) {
+        this.courseWareService = courseWareService;
+    }
+
+    @PostMapping("/create")
+    public OkResponse<CourseWareVO> createCourseWare(@RequestBody CourseWareVO courseWareVO) {
+        return OkResponse.of(courseWareService.createCourseWare(courseWareVO));
+    }
+
+    @PostMapping("/uploadCourseWareFile")
+    public OkResponse<String> uploadCourseWareFile(
+            @RequestPart("name") String name,
+            @RequestPart("file") MultipartFile file) {
+        return OkResponse.of(courseWareService.uploadCourseWareFile(name, file));
+    }
+
+    @GetMapping("/checkName")
+    public OkResponse<Boolean> checkCourseWareNameUnique(@RequestParam Long courseId, @RequestParam String name) {
+        return OkResponse.of(courseWareService.checkCourseWareNameUnique(courseId, name));
+    }
+
+    @DeleteMapping("/delete")
+    public OkResponse<String> deleteCourseWare(@RequestParam Long id) {
+        return OkResponse.of(courseWareService.deleteCourseWare(id));
+    }
+
+    @GetMapping("/getCourseWaresByCourseId")
+    public OkResponse<List<CourseWareDTO>> getCourseWaresByCourseId(@RequestParam Long courseId) {
+        return OkResponse.of(courseWareService.getCourseWaresByCourseId(courseId));
+    }
+
+    @GetMapping("/getById")
+    public OkResponse<CourseWareVO> getCourseWareById(@RequestParam Long id) {
+        return OkResponse.of(courseWareService.getCourseWareById(id));
+    }
+
+    @GetMapping("/download")
+    public OkResponse<String> downloadCourseWare(HttpServletRequest req, HttpServletResponse res, @RequestParam Long id) throws IOException {
+        return OkResponse.of(courseWareService.downloadCourseWare(req, res, id));
+    }
+
+    @GetMapping("/{slideId}/url")
+    public OkResponse<String> getSlideUrl(@PathVariable Long slideId) {
+        return OkResponse.of(courseWareService.getSlideUrl(slideId));
+    }
+
+    @GetMapping("/{slideId}")
+    public OkResponse<CourseWareVO> getOneSlide(@PathVariable Long slideId) {
+        return OkResponse.of(courseWareService.getOneSlide(slideId));
+    }
+
+
+
+
+}

+ 5 - 0
seecoder-portal-server/src/main/java/cn/seecoder/seecoderportalserver/web/rest/GroupController.java

@@ -42,6 +42,11 @@ public class GroupController {
         return OkResponse.of(groupService.addGroupMember(groupMemberVO));
     }
 
+    @PostMapping("/invite")
+    public OkResponse<GroupDTO> sendInvitation(@RequestBody GroupMemberVO groupMemberVO){
+        return OkResponse.of(groupService.sendInvitation(groupMemberVO));
+    }
+
     @GetMapping
     public OkResponse<GroupDTO> findGroup(@RequestParam Long courseId){
         return OkResponse.of(groupService.findGroup(courseId));

+ 5 - 0
seecoder-portal-server/src/main/java/cn/seecoder/seecoderportalserver/web/rest/MessageController.java

@@ -58,4 +58,9 @@ public class MessageController {
     public OkResponse<String> readMessage(@RequestBody MessageVO messageVO) {
         return OkResponse.of(messageService.readMessage(messageVO.getId(), SecurityUtils.getCurrentUser().getId()));
     }
+
+    @PutMapping("/getInvitations")
+    public OkResponse<List<MessageVO>> findUnreadInvitationsByUser(){
+        return OkResponse.of(messageService.findUnreadInvitationsByUser(SecurityUtils.getCurrentUser().getId()));
+    }
 }

+ 22 - 1
seecoder-portal-server/src/main/resources/portal.sql

@@ -231,6 +231,27 @@ CREATE TABLE IF NOT EXISTS public.user_generation (
 
 ALTER TABLE public.user_generation OWNER TO postgres;
 
+--
+-- Name: course_ware; Type: TABLE; Schema: public; Owner: postgres
+--
+
+DROP TABLE IF EXISTS public.course_ware;
+
+CREATE TABLE IF NOT EXISTS public.course_ware (
+    id bigint NOT NULL,
+    name character varying(255) NOT NULL,
+    size bigint NOT NULL,
+    sender_id bigint NOT NULL,
+    course_id bigint NOT NULL,
+    created_time timestamp without time zone NOT NULL,
+    use_time character varying(255) NOT NULL,
+    use_method character varying(255) NOT NULL,
+    file_url character varying(255) NOT NULL
+);
+
+
+ALTER TABLE public.course_ware OWNER TO postgres;
+
 --
 -- Name: announcement announcement_pkey; Type: CONSTRAINT; Schema: public; Owner: postgres
 --
@@ -450,7 +471,7 @@ ALTER TABLE ONLY public.announcement_record
 --
 
 ALTER TABLE ONLY public.announcement_record
-    ADD CONSTRAINT announcement_record_portal_user_id_fk FOREIGN KEY (announcement_id) REFERENCES public.portal_user(id) ON DELETE CASCADE;
+    ADD CONSTRAINT announcement_record_portal_user_id_fk FOREIGN KEY (recipient_id) REFERENCES public.portal_user(id) ON DELETE CASCADE;
 
 
 --