Bladeren bron

feat: "阶段性上传"

Leonezhurui 2 jaren geleden
bovenliggende
commit
49136e80cd

+ 13 - 0
src/main/java/com/njuzr/eaibackend/controller/AIController.java

@@ -47,6 +47,19 @@ public class AIController {
         return MyResponse.success(dialogues);
     }
 
+    /**
+     * 获得AI智能评价的内容(取最后一个即可)
+     * @return
+     */
+    @GetMapping("/rewrite/result")
+    public MyResponse getRewriteResult(
+            @RequestParam Long assignmentId,
+            @RequestParam Long userId
+    ) {
+
+        return MyResponse.success(aiDialogueService.getRewriteResult(assignmentId, userId));
+    }
+
     /**
      * 学生进入写作界面触发,创建AI会话
      * @param assignmentId

+ 22 - 0
src/main/java/com/njuzr/eaibackend/controller/AssignmentController.java

@@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.njuzr.eaibackend.dto.AssignmentDTO;
 import com.njuzr.eaibackend.dto.AssignmentQueryDTO;
 import com.njuzr.eaibackend.dto.AssignmentUpdateDTO;
+import com.njuzr.eaibackend.dto.CorrectDTO;
 import com.njuzr.eaibackend.enums.AssignmentCompletionStatus;
 import com.njuzr.eaibackend.po.Assignment;
 import com.njuzr.eaibackend.po.MyUserDetails;
@@ -131,6 +132,14 @@ public class AssignmentController {
         return MyResponse.success(assignmentService.getEngagement(studentId, assignmentId));
     }
 
+    @GetMapping("/engage/detail")
+    public MyResponse getDetailEngagement(
+            @RequestParam Long studentId,
+            @RequestParam Long assignmentId
+    ) {
+        return MyResponse.success(assignmentService.getDetailEngagement(studentId, assignmentId));
+    }
+
     @PutMapping("/engage/submit")
     public MyResponse engagementSubmit(
             @RequestParam Long studentId,
@@ -151,6 +160,19 @@ public class AssignmentController {
         return MyResponse.success("作业暂存成功");
     }
 
+    @PreAuthorize("hasRole('TEACHER')")
+    @PutMapping("/engage/correct")
+    public MyResponse engagementCorrect(
+            @AuthenticationPrincipal(expression = "id") Long teacherId,
+            @RequestParam Long studentId,
+            @RequestParam Long assignmentId,
+            @RequestBody CorrectDTO correctDTO
+    ) {
+        assignmentService.engagementCorrect(teacherId, studentId, assignmentId, correctDTO);
+        return MyResponse.success("批改成功");
+    }
+
+
     /**
      * 更新状态(需要多种情况讨论)
      * @param assignmentId

+ 0 - 3
src/main/java/com/njuzr/eaibackend/controller/OnlyOfficeController.java

@@ -1,10 +1,8 @@
 package com.njuzr.eaibackend.controller;
 
 import com.alibaba.fastjson2.JSONObject;
-import com.njuzr.eaibackend.exception.MyException;
 import com.njuzr.eaibackend.utils.FileUtil;
 import com.njuzr.eaibackend.utils.OssUtil;
-import com.njuzr.eaibackend.utils.WebClientUtil;
 import jakarta.servlet.http.HttpServletRequest;
 import jakarta.servlet.http.HttpServletResponse;
 import lombok.AllArgsConstructor;
@@ -12,7 +10,6 @@ import lombok.Data;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.core.io.Resource;
-import org.springframework.http.HttpStatus;
 import org.springframework.web.bind.annotation.*;
 
 import java.io.IOException;

+ 9 - 0
src/main/java/com/njuzr/eaibackend/controller/TranslateController.java

@@ -29,4 +29,13 @@ public class TranslateController {
         return MyResponse.success(translateService.translate(assignmentId, studentId, translationDTO));
     }
 
+
+    @GetMapping
+    public MyResponse getTranslation(
+            @RequestParam Long studentId,
+            @RequestParam Long assignmentId
+    ) {
+        return MyResponse.success(translateService.getTranslations(assignmentId, studentId));
+    }
+
 }

+ 15 - 0
src/main/java/com/njuzr/eaibackend/dto/CorrectDTO.java

@@ -0,0 +1,15 @@
+package com.njuzr.eaibackend.dto;
+
+import lombok.Data;
+
+/**
+ * @author: Leonezhurui
+ * @Date: 2024/3/23 - 23:57
+ * @Package: EAI-Backend
+ */
+
+@Data
+public class CorrectDTO {
+    private Double score;
+    private String remark;
+}

+ 3 - 0
src/main/java/com/njuzr/eaibackend/mapper/TranslationMapper.java

@@ -4,6 +4,8 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import com.njuzr.eaibackend.po.Translation;
 import org.apache.ibatis.annotations.Mapper;
 
+import java.util.List;
+
 /**
  * @author: Leonezhurui
  * @Date: 2024/3/21 - 01:50
@@ -12,4 +14,5 @@ import org.apache.ibatis.annotations.Mapper;
 
 @Mapper
 public interface TranslationMapper extends BaseMapper<Translation> {
+    List<Translation> findTranslationsByUserIdAndAssignmentId(Long assignmentId, Long userId);
 }

+ 2 - 0
src/main/java/com/njuzr/eaibackend/po/Engagement.java

@@ -6,6 +6,8 @@ import com.baomidou.mybatisplus.annotation.TableName;
 import com.njuzr.eaibackend.enums.AssignmentCompletionStatus;
 import lombok.Data;
 
+import java.util.Date;
+
 /**
  * @author: Leonezhurui
  * @Date: 2024/3/4 - 23:21

+ 22 - 5
src/main/java/com/njuzr/eaibackend/service/AIDialogueService.java

@@ -140,6 +140,22 @@ public class AIDialogueService {
         return aiDialogueVO;
     }
 
+
+    public List<AIRewriteRecord.RecordEntry> getRewriteResult(Long assignmentId, Long userId) {
+        AIRewriteRecord targetRecord = mongoTemplate.findOne(
+                Query.query(Criteria.where("assignmentId").is(assignmentId).and("userId").is(userId)), AIRewriteRecord.class
+        );
+
+        if (targetRecord == null) {
+            throw new MyException(HttpStatus.BAD_REQUEST.value(), HttpStatus.BAD_REQUEST.getReasonPhrase()+":"+"找不到AI智能批改记录");
+        }
+        return targetRecord.getRecords();
+
+    }
+
+
+
+
     public AIEntry requestAI(String dialogueId, AIDTO aidto) {
         // 1 使用WebClient请求数据
         String modelType = aidto.getModel();
@@ -148,6 +164,10 @@ public class AIDialogueService {
             // TODO 限制上下文数量
         }
 
+        // 优先构造userEntry(用于timestamp的构建)
+        AIEntry lastEntry = aidto.getMessages().get(aidto.getMessages().size()-1);
+        AIDialogue.DialogueEntry userEntry = new AIDialogue.DialogueEntry(lastEntry.getRole(), lastEntry.getContent(), System.currentTimeMillis() / 1000);
+
         AIRequestService.AIResponse res;
         if (Objects.equals(modelType, "ChatGLM3")) {
             res = aiRequestService.requestChatGLM(aidto.getMessages());
@@ -159,10 +179,6 @@ public class AIDialogueService {
             throw new MyException(HttpStatus.BAD_REQUEST.value(), HttpStatus.BAD_REQUEST.getReasonPhrase()+":"+"模型不支持");
         }
 
-        // 2 更新数据库
-        AIEntry lastEntry = aidto.getMessages().get(aidto.getMessages().size()-1);
-        AIDialogue.DialogueEntry userEntry = new AIDialogue.DialogueEntry(lastEntry.getRole(), lastEntry.getContent(), System.currentTimeMillis() / 1000);
-
         String retContent;
         String role;
         Long timestamp;
@@ -175,6 +191,7 @@ public class AIDialogueService {
             throw new MyException(HttpStatus.INTERNAL_SERVER_ERROR.value(), HttpStatus.INTERNAL_SERVER_ERROR.getReasonPhrase()+":"+"请求失败");
         }
 
+        // 2 更新数据库
         AIDialogue.DialogueEntry aiEntry = new AIDialogue.DialogueEntry(role, retContent, timestamp);
 
         addDialogueEntry(dialogueId, userEntry, aiEntry);
@@ -281,7 +298,7 @@ public class AIDialogueService {
     private void addRecordEntry(String recordId, AIRewriteRecord.RecordEntry userEntry, AIRewriteRecord.RecordEntry aiEntry) {
         try {
             Query query =  new Query(Criteria.where("id").is(recordId));
-            Update update = new Update().push("dialogues").each(userEntry, aiEntry);
+            Update update = new Update().push("records").each(userEntry, aiEntry);
             mongoTemplate.updateFirst(query, update, AIRewriteRecord.class);
         } catch (Exception e) {
             log.error("MongoDB数据库更新出错");

+ 6 - 0
src/main/java/com/njuzr/eaibackend/service/AssignmentService.java

@@ -5,10 +5,12 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.njuzr.eaibackend.dto.AssignmentDTO;
 import com.njuzr.eaibackend.dto.AssignmentQueryDTO;
 import com.njuzr.eaibackend.dto.AssignmentUpdateDTO;
+import com.njuzr.eaibackend.dto.CorrectDTO;
 import com.njuzr.eaibackend.po.Assignment;
 import com.njuzr.eaibackend.po.Engagement;
 import com.njuzr.eaibackend.po.MyUserDetails;
 import com.njuzr.eaibackend.vo.AssignmentVO;
+import com.njuzr.eaibackend.vo.EngagementDetailVO;
 import com.njuzr.eaibackend.vo.EngagementVO;
 
 /**
@@ -33,8 +35,12 @@ public interface AssignmentService {
 
     EngagementVO getEngagement(Long studentId, Long assignmentId);
 
+    EngagementDetailVO getDetailEngagement(Long studentId, Long assignmentId);
+
     void engagementSubmit(Long studentId, Long assignmentId);
 
     void engagementStage(Long studentId, Long assignmentId);
+
+    void engagementCorrect(Long teacherId, Long studentId, Long assignmentId, CorrectDTO correctDTO);
     
 }

+ 12 - 1
src/main/java/com/njuzr/eaibackend/service/TranslateService.java

@@ -4,7 +4,9 @@ import com.njuzr.eaibackend.dto.TranslationDTO;
 import com.njuzr.eaibackend.exception.MyException;
 import com.njuzr.eaibackend.mapper.TranslationMapper;
 import com.njuzr.eaibackend.po.Translation;
+import com.njuzr.eaibackend.utils.ModelMapperUtil;
 import com.njuzr.eaibackend.utils.WebClientUtil;
+import com.njuzr.eaibackend.vo.TranslationVO;
 import lombok.AllArgsConstructor;
 import lombok.Data;
 import lombok.extern.slf4j.Slf4j;
@@ -15,7 +17,9 @@ import org.springframework.stereotype.Service;
 import java.security.MessageDigest;
 import java.security.NoSuchAlgorithmException;
 import java.util.Date;
+import java.util.List;
 import java.util.Objects;
+import java.util.stream.Collectors;
 
 /**
  * @author: Leonezhurui
@@ -36,7 +40,7 @@ public class TranslateService {
     }
 
     public String translate(Long assignmentId, Long userId, TranslationDTO translationDTO) {
-        MyResponseObject response = webClientUtil.post("http://47.111.23.171:5000/api/translate", translationDTO, MyResponseObject.class);
+        MyResponseObject response = webClientUtil.post("http://localhost:5000/api/translate", translationDTO, MyResponseObject.class);
 
         if (Objects.equals(response.getCode(), 200)) {
             Translation translation = new Translation();
@@ -76,4 +80,11 @@ public class TranslateService {
         private String data;
         private String msg;
     }
+
+
+    public List<TranslationVO> getTranslations(Long assignmentId, Long userId) {
+        List<Translation> translations = translationMapper.findTranslationsByUserIdAndAssignmentId(assignmentId, userId);
+        return translations.stream().map(translation -> ModelMapperUtil.map(translation, TranslationVO.class)).toList();
+    }
+
 }

+ 65 - 6
src/main/java/com/njuzr/eaibackend/service/impl/AssignmentServiceImpl.java

@@ -6,6 +6,7 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.njuzr.eaibackend.dto.AssignmentDTO;
 import com.njuzr.eaibackend.dto.AssignmentQueryDTO;
 import com.njuzr.eaibackend.dto.AssignmentUpdateDTO;
+import com.njuzr.eaibackend.dto.CorrectDTO;
 import com.njuzr.eaibackend.enums.AssignmentCompletionStatus;
 import com.njuzr.eaibackend.enums.AssignmentStatus;
 import com.njuzr.eaibackend.enums.Role;
@@ -13,20 +14,19 @@ import com.njuzr.eaibackend.exception.MyException;
 import com.njuzr.eaibackend.mapper.AssignmentMapper;
 import com.njuzr.eaibackend.mapper.CourseMapper;
 import com.njuzr.eaibackend.mapper.StudentAssignmentMapper;
-import com.njuzr.eaibackend.po.Assignment;
-import com.njuzr.eaibackend.po.Course;
-import com.njuzr.eaibackend.po.Engagement;
-import com.njuzr.eaibackend.po.MyUserDetails;
+import com.njuzr.eaibackend.mapper.UserMapper;
+import com.njuzr.eaibackend.po.*;
 import com.njuzr.eaibackend.service.AssignmentService;
 import com.njuzr.eaibackend.utils.*;
 import com.njuzr.eaibackend.vo.AssignmentVO;
+import com.njuzr.eaibackend.vo.EngagementDetailVO;
 import com.njuzr.eaibackend.vo.EngagementVO;
+import com.njuzr.eaibackend.vo.UserVO;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.BeanUtils;
 import org.springframework.http.HttpStatus;
 import org.springframework.stereotype.Service;
 
-import java.io.ByteArrayInputStream;
 import java.io.InputStream;
 import java.time.LocalDateTime;
 import java.util.Date;
@@ -47,14 +47,17 @@ public class AssignmentServiceImpl implements AssignmentService {
 
     private final StudentAssignmentMapper studentAssignmentMapper;
 
+    private final UserMapper userMapper;
+
     private final OssUtil ossUtil;
 
     private final FileUtil fileUtil = new FileUtil();
 
-    public AssignmentServiceImpl(AssignmentMapper assignmentMapper, CourseMapper courseMapper, StudentAssignmentMapper studentAssignmentMapper, OssUtil ossUtil) {
+    public AssignmentServiceImpl(AssignmentMapper assignmentMapper, CourseMapper courseMapper, StudentAssignmentMapper studentAssignmentMapper, UserMapper userMapper, OssUtil ossUtil) {
         this.assignmentMapper = assignmentMapper;
         this.courseMapper = courseMapper;
         this.studentAssignmentMapper = studentAssignmentMapper;
+        this.userMapper = userMapper;
         this.ossUtil = ossUtil;
     }
 
@@ -214,6 +217,34 @@ public class AssignmentServiceImpl implements AssignmentService {
     }
 
 
+    @Override
+    public EngagementDetailVO getDetailEngagement(Long studentId, Long assignmentId) {
+        // 1 获取用户详细信息
+        User student = userMapper.selectById(studentId);
+        if (student == null)
+            throw MyException.create(HttpStatus.BAD_REQUEST, "学生不存在");
+
+        // 2 获取作业详细信息
+        Assignment assignment = assignmentMapper.selectById(assignmentId);
+        if (assignment == null)
+            throw MyException.create(HttpStatus.BAD_REQUEST, "作业不存在");
+
+        // 3 获取作业参与详细信息
+        Engagement engagement = studentAssignmentMapper.findEngagementByStudentIdAndAssignmentId(studentId, assignmentId);
+        if (engagement == null)
+            throw MyException.create(HttpStatus.BAD_REQUEST, "参与作业情况不存在");
+
+
+        EngagementDetailVO detailVO = ModelMapperUtil.map(engagement, EngagementDetailVO.class);
+        detailVO.setUserVO(ModelMapperUtil.map(student, UserVO.class));
+        detailVO.setAssignmentVO(convertToVO(assignment));
+        detailVO.setFileKey(assignmentId+"_"+studentId+"_"+engagement.getVersion());
+
+        log.info("请求到详细信息:"+detailVO.toString());
+
+        return detailVO;
+    }
+
     /**
      * 作业提交,更新文件版本和作业状态
      * @param studentId
@@ -260,6 +291,34 @@ public class AssignmentServiceImpl implements AssignmentService {
         }
     }
 
+    @Override
+    public void engagementCorrect(Long teacherId, Long studentId, Long assignmentId, CorrectDTO correctDTO) {
+        Engagement engagement = studentAssignmentMapper.findEngagementByStudentIdAndAssignmentId(studentId, assignmentId);
+        if (engagement == null)
+            throw MyException.create(HttpStatus.BAD_REQUEST, "参与作业情况不存在");
+
+        Assignment assignment = assignmentMapper.selectById(assignmentId);
+        if (assignment == null)
+            throw MyException.create(HttpStatus.BAD_REQUEST, "作业不存在");
+
+        if (!Objects.equals(assignment.getTeacherId(), teacherId))
+            throw MyException.create(HttpStatus.BAD_REQUEST, "无权限批改");
+
+        engagement.setStatus(AssignmentCompletionStatus.CORRECTED); // 第一步,修改状态,改为已批改
+        engagement.setScore(correctDTO.getScore());
+        engagement.setRemark(correctDTO.getRemark());
+
+        try {
+            int code = studentAssignmentMapper.updateById(engagement);
+            if (code == 0)
+                throw MyException.create(HttpStatus.INTERNAL_SERVER_ERROR, "批改作业失败");
+        } catch (Exception e) {
+            log.error(e.getMessage());
+            throw MyException.create(HttpStatus.INTERNAL_SERVER_ERROR, "批改作业失败");
+        }
+
+    }
+
     private Assignment convertToPO(AssignmentDTO assignmentDTO) {
         Assignment assignment = new Assignment();
         BeanUtils.copyProperties(assignmentDTO, assignment);

+ 23 - 0
src/main/java/com/njuzr/eaibackend/vo/EngagementDetailVO.java

@@ -0,0 +1,23 @@
+package com.njuzr.eaibackend.vo;
+
+import com.njuzr.eaibackend.enums.AssignmentCompletionStatus;
+import lombok.Data;
+
+/**
+ * @author: Leonezhurui
+ * @Date: 2024/3/23 - 11:37
+ * @Package: EAI-Backend
+ */
+
+@Data
+public class EngagementDetailVO {
+    private Long id;
+    private AssignmentVO assignmentVO;
+    private UserVO userVO;
+    private Double score;
+    private String remark;
+    private String fileUrl; // 学生作业的oss链接
+    private int version; // 文件版本,用于onlyoffice key的构建(解决文件不同步问题)
+    private AssignmentCompletionStatus status; // 学生作业状态
+    private String fileKey;
+}

+ 22 - 0
src/main/java/com/njuzr/eaibackend/vo/TranslationVO.java

@@ -0,0 +1,22 @@
+package com.njuzr.eaibackend.vo;
+
+import lombok.Data;
+
+import java.util.Date;
+
+/**
+ * @author: Leonezhurui
+ * @Date: 2024/3/23 - 20:25
+ * @Package: EAI-Backend
+ */
+
+@Data
+public class TranslationVO {
+    private String queryText;
+
+    private String queryResult;
+
+    private String targetLanguage; // 目标语言类型
+
+    private Date queryTime;
+}

+ 12 - 0
src/main/resources/mapper/TranslationMapper.xml

@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.njuzr.eaibackend.mapper.TranslationMapper">
+
+    <select id="findTranslationsByUserIdAndAssignmentId" resultType="Translation">
+        SELECT *
+        FROM translations
+        WHERE user_id = #{userId}
+          AND assignment_id = #{assignmentId}
+    </select>
+
+</mapper>