Kaynağa Gözat

fix:多版本可视化

wuzilong 4 ay önce
ebeveyn
işleme
0c3aa1dc75

+ 4 - 1
src/main/java/com/njuzr/eaibackend/config/SecurityConfig.java

@@ -61,7 +61,10 @@ public class SecurityConfig {
                                 "/doc/**",
                                 "/api/export/**",
                                 "/api/test",
-                                "api/auth/loginByPortal").permitAll() // 允许公开访问的路径
+                                "api/auth/loginByPortal",
+                                "/swagger-ui/**",
+                                "/swagger-ui.html",
+                                "/v3/api-docs/**").permitAll() // 允许公开访问的路径
                         .anyRequest().authenticated() // 其他所有请求需要认证
                 )
                 .exceptionHandling(exception -> exception

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

@@ -5,6 +5,7 @@ import com.njuzr.eaibackend.service.BehaviorOverviewService;
 import com.njuzr.eaibackend.vo.BehaviorOverviewVO;
 import com.njuzr.eaibackend.vo.TextAnalysisVO;
 import com.njuzr.eaibackend.vo.PauseStatisticsVO;
+import com.njuzr.eaibackend.vo.BehaviorRecordVersionsVO;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.security.core.annotation.AuthenticationPrincipal;
@@ -44,6 +45,14 @@ public class BehaviorRecordController {
         return MyResponse.success(behaviorRecordService.findALL(assignmentId, studentId));
     }
 
+    @GetMapping("/versions")
+    public MyResponse getBehaviorRecordVersions(
+            @RequestParam Long studentId,
+            @RequestParam Long assignmentId) {
+        BehaviorRecordVersionsVO vo = behaviorRecordService.findVersions(assignmentId, studentId);
+        return MyResponse.success(vo);
+    }
+
     @GetMapping("/textAnalysis")
     public MyResponse getTextAnalysis(
             @RequestParam Long studentId,

+ 3 - 0
src/main/java/com/njuzr/eaibackend/service/BehaviorRecordService.java

@@ -3,6 +3,7 @@ package com.njuzr.eaibackend.service;
 import com.njuzr.eaibackend.po.BehaviorRecord;
 import com.njuzr.eaibackend.vo.BehaviorRecordItemVO;
 import com.njuzr.eaibackend.vo.BehaviorRecordVO;
+import com.njuzr.eaibackend.vo.BehaviorRecordVersionsVO;
 import com.njuzr.eaibackend.vo.TextAnalysisVO;
 import org.springframework.web.multipart.MultipartFile;
 
@@ -18,6 +19,8 @@ public interface BehaviorRecordService {
 
     BehaviorRecordVO findALL(Long assignmentId, Long studentId);
 
+    BehaviorRecordVersionsVO findVersions(Long assignmentId, Long studentId);
+
     /**
      * 查询MongoDB中textAnalyses分析结果
      */

+ 123 - 0
src/main/java/com/njuzr/eaibackend/service/impl/BehaviorRecordServiceImpl.java

@@ -8,6 +8,7 @@ import com.njuzr.eaibackend.service.BehaviorOverviewService;
 import com.njuzr.eaibackend.utils.OssUtil;
 import com.njuzr.eaibackend.vo.BehaviorRecordItemVO;
 import com.njuzr.eaibackend.vo.BehaviorRecordVO;
+import com.njuzr.eaibackend.vo.BehaviorRecordVersionsVO;
 import com.njuzr.eaibackend.po.TextAnalysis;
 import com.njuzr.eaibackend.vo.TextAnalysisVO;
 import lombok.extern.slf4j.Slf4j;
@@ -106,6 +107,128 @@ public class BehaviorRecordServiceImpl implements BehaviorRecordService {
         return vo;
     }
 
+    @Override
+    public BehaviorRecordVersionsVO findVersions(Long assignmentId, Long studentId) {
+        Sort sort = Sort.by(Sort.Direction.ASC, "created_at");
+        List<BehaviorRecord> records = behaviorRecordMapper.findByAssignmentIdAndStudentId(assignmentId, studentId, sort);
+        
+        BehaviorRecordVersionsVO vo = new BehaviorRecordVersionsVO();
+        vo.setStudentId(studentId);
+        vo.setAssignmentId(assignmentId);
+        
+        List<BehaviorRecordVersionsVO.VersionEvents> versions = new java.util.ArrayList<>();
+        List<BehaviorRecord.BehaviorEvent> accumulatedEvents = new java.util.ArrayList<>();
+        int accumulatedInsertCount = 0;
+        int accumulatedDeleteCount = 0;
+        int accumulatedCopyCount = 0;
+        int accumulatedCopyCharacterCount = 0;
+        int accumulatedLongPauseCount = 0;
+        Long lastEndStamp = 0L;
+        
+        for (int i = 0; i < records.size(); i++) {
+            BehaviorRecord record = records.get(i);
+            BehaviorRecordVersionsVO.VersionEvents version = new BehaviorRecordVersionsVO.VersionEvents();
+            version.setVersion(i + 1);
+            version.setCreatedAt(record.getCreatedAt());
+            
+            List<BehaviorRecord.BehaviorEvent> events = record.getEvents();
+            if (events == null) {
+                events = new java.util.ArrayList<>();
+            }
+            
+            Long offset = calculateTimestampOffset(lastEndStamp, events);
+            
+            List<BehaviorRecord.BehaviorEvent> offsetEvents = new java.util.ArrayList<>();
+            int insertCount = 0;
+            int deleteCount = 0;
+            int copyCount = 0;
+            int copyCharacterCount = 0;
+            int longPauseCount = 0;
+            
+            for (BehaviorRecord.BehaviorEvent event : events) {
+                BehaviorRecord.BehaviorEvent offsetEvent = new BehaviorRecord.BehaviorEvent();
+                offsetEvent.setType(event.getType());
+                offsetEvent.setRetain(event.getRetain());
+                offsetEvent.setInsert(event.getInsert());
+                
+                Long startStamp = event.getStartStamp();
+                Long endStamp = event.getEndStamp();
+                if (startStamp != null) {
+                    offsetEvent.setStartStamp(startStamp + offset);
+                }
+                if (endStamp != null) {
+                    offsetEvent.setEndStamp(endStamp + offset);
+                }
+                offsetEvent.setPauseTime(event.getPauseTime());
+                offsetEvent.setDocLength(event.getDocLength());
+                
+                offsetEvents.add(offsetEvent);
+                
+                if (event.getType() != null) {
+                    switch (event.getType()) {
+                        case "insert":
+                            insertCount++;
+                            break;
+                        case "delete":
+                            deleteCount++;
+                            break;
+                        case "copy":
+                            copyCount++;
+                            if (event.getInsert() != null) {
+                                copyCharacterCount += event.getInsert().length();
+                            }
+                            break;
+                        case "pause":
+                            if (event.getPauseTime() != null && event.getPauseTime() > 2000) {
+                                longPauseCount++;
+                            }
+                            break;
+                    }
+                }
+                
+                if (event.getEndStamp() != null && event.getEndStamp() + offset > lastEndStamp) {
+                    lastEndStamp = event.getEndStamp() + offset;
+                }
+            }
+            
+            accumulatedEvents.addAll(offsetEvents);
+            accumulatedInsertCount += insertCount;
+            accumulatedDeleteCount += deleteCount;
+            accumulatedCopyCount += copyCount;
+            accumulatedCopyCharacterCount += copyCharacterCount;
+            accumulatedLongPauseCount += longPauseCount;
+            
+            version.setEvents(new java.util.ArrayList<>(accumulatedEvents));
+            version.setInsertCount(accumulatedInsertCount);
+            version.setDeleteCount(accumulatedDeleteCount);
+            version.setCopyCount(accumulatedCopyCount);
+            version.setCopyCharacterCount(accumulatedCopyCharacterCount);
+            version.setLongPauseCount(accumulatedLongPauseCount);
+            
+            versions.add(version);
+        }
+        
+        vo.setVersions(versions);
+        return vo;
+    }
+    
+    private Long calculateTimestampOffset(Long lastEndStamp, List<BehaviorRecord.BehaviorEvent> events) {
+        if (events == null || events.isEmpty()) {
+            return 0L;
+        }
+        
+        Long firstStartStamp = events.get(0).getStartStamp();
+        if (firstStartStamp == null) {
+            return 0L;
+        }
+        
+        if (firstStartStamp < 5000 && lastEndStamp > 5000) {
+            return lastEndStamp;
+        }
+        
+        return 0L;
+    }
+
     /**
      * 将Map转换为SimplifiedEvent
      */

+ 27 - 0
src/main/java/com/njuzr/eaibackend/vo/BehaviorRecordVersionsVO.java

@@ -0,0 +1,27 @@
+package com.njuzr.eaibackend.vo;
+
+import com.njuzr.eaibackend.po.BehaviorRecord;
+import lombok.Data;
+
+import java.util.Date;
+import java.util.List;
+
+@Data
+public class BehaviorRecordVersionsVO {
+    
+    private Long studentId;
+    private Long assignmentId;
+    private List<VersionEvents> versions;
+    
+    @Data
+    public static class VersionEvents {
+        private Integer version;
+        private Date createdAt;
+        private List<BehaviorRecord.BehaviorEvent> events;
+        private Integer insertCount;
+        private Integer deleteCount;
+        private Integer copyCount;
+        private Integer copyCharacterCount;
+        private Integer longPauseCount;
+    }
+}