Ver Fonte

Merge branch 'feature-coding-visualize' into 'Develop'

Feature coding visualize



See merge request !1195

menduo há 5 anos atrás
pai
commit
1eaad1a9b0

+ 2 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/configure/ShiroConfiguration.java

@@ -126,6 +126,8 @@ public class ShiroConfiguration {
 
         filterChainDefinitionManager.put("/api/onlinejudge/**","anon");
 
+        filterChainDefinitionManager.put("/api/codeVisualize/**", "authc");
+
         filterChainDefinitionManager.put("/api/onlinejudge/u/**","authc");
         filterChainDefinitionManager.put("/api/sendGetHelpEmail", "anon");
         filterChainDefinitionManager.put("/**", "authc");

+ 17 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/dao/CodeCovDao.java

@@ -0,0 +1,17 @@
+package cn.iselab.mooctest.site.dao;
+
+import cn.iselab.mooctest.site.models.CodeCov;
+import org.springframework.data.jpa.repository.JpaRepository;
+
+import java.util.List;
+
+/**
+ * @author yyy
+ * @date 2020/3/14 14:29
+ */
+public interface CodeCovDao extends JpaRepository<CodeCov, Long> {
+
+    List<CodeCov> findByExamIdAndCaseIdAndWorkerIdOrderByRunTimeAsc(long examId, long caseId, long workerId);
+
+    List<CodeCov> findByExamIdAndWorkerIdOrderByRunTimeAsc(long examId, long workerId);
+}

+ 34 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/models/CodeCov.java

@@ -0,0 +1,34 @@
+package cn.iselab.mooctest.site.models;
+
+import lombok.Data;
+
+import javax.persistence.*;
+
+/**
+ * @author yyy
+ * @date 2020/3/14 14:24
+ */
+@Data
+@Entity
+@Table(name = "code_cov")
+public class CodeCov {
+
+    @Id
+    @GeneratedValue(strategy = GenerationType.IDENTITY)
+    private long id;
+
+    @Column(name="exam_id")
+    private long examId;
+
+    @Column(name="case_id")
+    private long caseId;
+
+    @Column(name="worker_id")
+    private long workerId;
+
+    @Column(name="cov_matrix")
+    private String covMatrix;
+
+    @Column(name="run_time")
+    private long runTime;
+}

+ 18 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/service/CodeCovService.java

@@ -0,0 +1,18 @@
+package cn.iselab.mooctest.site.service;
+
+import cn.iselab.mooctest.site.models.CodeCov;
+
+import java.util.List;
+
+/**
+ * @author yyy
+ * @date 2020/3/14 14:32
+ */
+public interface CodeCovService {
+
+    List<Integer[]> getCodeCov(long examId, long caseId, long workerId);
+
+    void saveCodeCov(long examId, long caseId, long workerId, int[] covMatrix);
+
+    int[] getRunCounts(long examId, long workerId, long startTime, long endTime, int stepMinutes);
+}

+ 95 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/service/impl/CodeCovServiceImpl.java

@@ -0,0 +1,95 @@
+package cn.iselab.mooctest.site.service.impl;
+
+import cn.iselab.mooctest.site.dao.CodeCovDao;
+import cn.iselab.mooctest.site.models.CodeCov;
+import cn.iselab.mooctest.site.service.CodeCovService;
+import com.google.gson.Gson;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+/**
+ * @author yyy
+ * @date 2020/3/14 14:33
+ */
+@Service
+public class CodeCovServiceImpl implements CodeCovService {
+
+    @Resource
+    CodeCovDao codeCovDao;
+
+    @Override
+    public List<Integer[]> getCodeCov(long examId, long caseId, long workerId) {
+        List<CodeCov> ccList = codeCovDao.findByExamIdAndCaseIdAndWorkerIdOrderByRunTimeAsc(examId, caseId, workerId);
+        Gson gson = new Gson();
+        List<Integer[]> covMatrix = new ArrayList<>();
+        ccList.forEach(cc -> {
+            String m = cc.getCovMatrix();
+            if(m!=null && !m.isEmpty()){ //兼容无covMatrix的情况
+                covMatrix.add(gson.fromJson(m, Integer[].class));
+            }
+        });
+        return covMatrix;
+    }
+
+    @Override
+    public void saveCodeCov(long examId, long caseId, long workerId, int[] covMatrix) {
+        CodeCov cc = new CodeCov();
+        cc.setRunTime(System.currentTimeMillis());
+        cc.setExamId(examId);
+        cc.setCaseId(caseId);
+        cc.setWorkerId(workerId);
+        if(covMatrix != null){
+            cc.setCovMatrix(new Gson().toJson(covMatrix));
+        }
+        codeCovDao.save(cc);
+    }
+
+    @Override
+    public int[] getRunCounts(long examId, long workerId, long startTime, long endTime, int stepMinutes) {
+
+        long stepMillis = stepMinutes*60*1000;
+        int blockNums = (int)Math.ceil((endTime-startTime)*1.0/stepMillis);
+        int[] blockCounts = new int[blockNums];
+        List<CodeCov> ccList = codeCovDao.findByExamIdAndWorkerIdOrderByRunTimeAsc(examId, workerId);
+
+        int blockIndex = 0;
+        long blockEndTime = startTime+stepMillis;
+        for(int i=0; i<ccList.size(); i++){
+
+            long runTime = ccList.get(i).getRunTime();
+
+            // 运行记录时间大于结束时间,遍历直接结束
+            if(runTime >= endTime){
+                break;
+            }
+
+            // 运行记录时间小于开始时间,直接下一个
+            if(runTime < startTime){
+                continue;
+            }
+
+            // 运行记录时间大于等于开始时间,但小于第一个方格结束时间
+            if(runTime < blockEndTime){
+                blockCounts[blockIndex] = blockCounts[blockIndex]+1;
+            }else{ // 运行记录时间大于等于当前方格结束时间且当前方格结束时间小于endTime,则上一阶段计数结束
+                while(runTime >= blockEndTime ){
+                    blockIndex++;
+                    startTime = blockEndTime;
+                    blockEndTime+=stepMillis;
+                }
+                blockCounts[blockIndex] = blockCounts[blockIndex]+1;
+            }
+        }
+
+
+        return blockCounts;
+    }
+
+
+}

+ 87 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/ctrl/CodingVisualizeController.java

@@ -0,0 +1,87 @@
+package cn.iselab.mooctest.site.web.ctrl;
+
+import cn.iselab.mooctest.site.common.constant.UrlConstants;
+import cn.iselab.mooctest.site.models.CodeCov;
+import cn.iselab.mooctest.site.service.CodeCovService;
+import cn.iselab.mooctest.site.web.data.json.CodeCovJson;
+import cn.iselab.mooctest.site.web.data.response.ResponseVO;
+import cn.iselab.mooctest.site.web.logic.CodeVisualizeLogic;
+import org.apache.shiro.SecurityUtils;
+import org.apache.shiro.authz.annotation.RequiresRoles;
+import org.bson.types.Code;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+/**
+ * @author yyy
+ * @date 2020/3/14 14:12
+ */
+@RestController
+public class CodingVisualizeController {
+
+    @Autowired
+    CodeVisualizeLogic codeVisualizeLogic;
+
+    @Autowired
+    CodeCovService codeCovService;
+
+    @PostMapping(UrlConstants.API +"/codeVisualize/saveCodeCov")
+    public ResponseVO getCovMatrix(@RequestBody CodeCovJson cc){
+        try{
+            return codeVisualizeLogic.saveCodeCov(cc.getExamId(), cc.getCaseId(), cc.getWorkerId(), cc.getCovMatrix());
+        }catch (Exception e){
+            e.printStackTrace();
+            return new ResponseVO<>(50000, e.getMessage(), null);
+        }
+    }
+
+    @GetMapping(UrlConstants.API +"/codeVisualize/getCodeCov")
+    public ResponseVO getCovMatrix(@RequestParam long examId,
+                                   @RequestParam long caseId,
+                                   @RequestParam long workerId){
+        try{
+            return codeVisualizeLogic.getCodeCov(examId, caseId, workerId);
+        }catch (Exception e){
+            e.printStackTrace();
+            return new ResponseVO<>(50000, e.getMessage(), null);
+        }
+    }
+
+    @PostMapping(UrlConstants.API + "/codeVisualize/getWorkingBlock")
+    public ResponseVO getWorkingBlock(@RequestParam long examId,
+                                      @RequestParam long workerId,
+                                      @RequestParam long startTime,
+                                      @RequestParam long endTime,
+                                      @RequestParam int stepMinutes){
+
+        return codeVisualizeLogic.getWorkingBlock(examId,workerId,startTime,endTime,stepMinutes);
+    }
+
+    @RequiresRoles(value = "manager")
+    @GetMapping(UrlConstants.API +"/codeVisualize/classCodeCov")
+    public ResponseVO getClassCovMatrix(@RequestParam long examId,
+                                        @RequestParam long caseId,
+                                        @RequestParam long groupId){
+        try{
+            return codeVisualizeLogic.getClassCodeCov(examId, caseId, groupId);
+        }catch (Exception e){
+            e.printStackTrace();
+            return new ResponseVO<>(50000, e.getMessage(), null);
+        }
+    }
+
+    @RequiresRoles(value = "manager")
+    @PostMapping(UrlConstants.API +"/codeVisualize/classWorkBlock")
+    public ResponseVO getClassWorkBlock(@RequestParam long examId,
+                                        @RequestParam long groupId,
+                                        @RequestParam long startTime,
+                                        @RequestParam long endTime,
+                                        @RequestParam int stepMinutes){
+        try{
+            return codeVisualizeLogic.getClassWorkingBlock(examId, groupId, startTime, endTime, stepMinutes);
+        }catch (Exception e){
+            e.printStackTrace();
+            return new ResponseVO<>(50000, e.getMessage(), null);
+        }
+    }
+}

+ 17 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/data/StudentCodeCovVO.java

@@ -0,0 +1,17 @@
+package cn.iselab.mooctest.site.web.data;
+
+import cn.iselab.mooctest.site.models.User;
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * @author yyy
+ * @date 2020/3/14 22:36
+ */
+@Data
+public class StudentCodeCovVO {
+
+    private User worker;
+    private List<Integer[]> covMatrix;
+}

+ 14 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/data/StudentWorkBlockVO.java

@@ -0,0 +1,14 @@
+package cn.iselab.mooctest.site.web.data;
+
+import cn.iselab.mooctest.site.models.User;
+import lombok.Data;
+
+/**
+ * @author yyy
+ * @date 2020/3/14 23:03
+ */
+@Data
+public class StudentWorkBlockVO {
+    private User user;
+    private int[] workBlockCounts;
+}

+ 15 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/data/json/CodeCovJson.java

@@ -0,0 +1,15 @@
+package cn.iselab.mooctest.site.web.data.json;
+
+import lombok.Data;
+
+/**
+ * @author yyy
+ * @date 2020/3/14 22:57
+ */
+@Data
+public class CodeCovJson {
+    private long examId;
+    private long caseId;
+    private long workerId;
+    private int[] covMatrix;
+}

+ 27 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/logic/CodeVisualizeLogic.java

@@ -0,0 +1,27 @@
+package cn.iselab.mooctest.site.web.logic;
+
+import cn.iselab.mooctest.site.models.CodeCov;
+import cn.iselab.mooctest.site.web.data.StudentCodeCovVO;
+import cn.iselab.mooctest.site.web.data.StudentWorkBlockVO;
+import cn.iselab.mooctest.site.web.data.response.ResponseVO;
+
+import java.util.List;
+
+/**
+ * @author yyy
+ * @date 2020/3/14 14:45
+ */
+public interface CodeVisualizeLogic {
+
+    //预留接口,供可能的需求使用
+    ResponseVO<Void> saveCodeCov(long examId, long caseId, long workerId, int[] covMatrix);
+
+    ResponseVO<List<Integer[]>> getCodeCov(long examId, long caseId, long workerId);
+
+    ResponseVO<int[]> getWorkingBlock(long examId, long workerId,
+                                      long startTime, long endTime, int stepMinutes);
+
+    ResponseVO<List<StudentCodeCovVO>> getClassCodeCov(long examId, long caseId, long groupId);
+
+    ResponseVO<List<StudentWorkBlockVO>> getClassWorkingBlock(long examId, long groupId, long startTime, long endTime, int stepMinutes);
+}

+ 79 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/logic/impl/CodeVisualizeLogicImpl.java

@@ -0,0 +1,79 @@
+package cn.iselab.mooctest.site.web.logic.impl;
+
+import cn.iselab.mooctest.site.models.CodeCov;
+import cn.iselab.mooctest.site.models.Group;
+import cn.iselab.mooctest.site.models.User;
+import cn.iselab.mooctest.site.service.CodeCovService;
+import cn.iselab.mooctest.site.service.GroupService;
+import cn.iselab.mooctest.site.web.data.StudentCodeCovVO;
+import cn.iselab.mooctest.site.web.data.StudentWorkBlockVO;
+import cn.iselab.mooctest.site.web.data.response.ResponseVO;
+import cn.iselab.mooctest.site.web.data.response.ServerCode;
+import cn.iselab.mooctest.site.web.logic.CodeVisualizeLogic;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+/**
+ * @author yyy
+ * @date 2020/3/14 14:47
+ */
+@Service
+public class CodeVisualizeLogicImpl implements CodeVisualizeLogic {
+
+    @Autowired
+    CodeCovService codeCovService;
+
+    @Autowired
+    GroupService groupService;
+
+    @Override
+    public ResponseVO<Void> saveCodeCov(long examId, long caseId, long workerId, int[] covMatrix) {
+        codeCovService.saveCodeCov(examId, caseId, workerId, covMatrix);
+        return new ResponseVO<>(ServerCode.SUCCESS);
+    }
+
+    @Override
+    public ResponseVO<List<Integer[]>> getCodeCov(long examId, long caseId, long workerId) {
+        List<Integer[]> matrix = codeCovService.getCodeCov(examId, caseId, workerId);
+        return new ResponseVO<>(ServerCode.SUCCESS, matrix);
+    }
+
+    @Override
+    public ResponseVO<int[]> getWorkingBlock(long examId, long workerId,
+                                                     long startTime, long endTime, int stepMinutes) {
+        int[] runCounts = codeCovService.getRunCounts(examId, workerId, startTime, endTime, stepMinutes);
+        return new ResponseVO<>(ServerCode.SUCCESS, runCounts);
+    }
+
+    @Override
+    public ResponseVO<List<StudentCodeCovVO>> getClassCodeCov(long examId, long caseId, long groupId) {
+        List<User> userList = groupService.getUserByGroupId(groupId);
+        List<StudentCodeCovVO> resultList = new ArrayList<>();
+        userList.forEach(user -> {
+            StudentCodeCovVO vo = new StudentCodeCovVO();
+            vo.setWorker(user);
+            vo.setCovMatrix(codeCovService.getCodeCov(examId, caseId, user.getId()));
+            resultList.add(vo);
+        });
+        return new ResponseVO<>(ServerCode.SUCCESS, resultList);
+    }
+
+    @Override
+    public ResponseVO<List<StudentWorkBlockVO>> getClassWorkingBlock(long examId, long groupId, long startTime, long endTime, int stepMinutes) {
+        List<User> userList = groupService.getUserByGroupId(groupId);
+        List<StudentWorkBlockVO> resultList = new ArrayList<>();
+        userList.forEach(user -> {
+            StudentWorkBlockVO vo = new StudentWorkBlockVO();
+            vo.setUser(user);
+            vo.setWorkBlockCounts(codeCovService.getRunCounts(examId, user.getId(),startTime, endTime, stepMinutes));
+            resultList.add(vo);
+        });
+        return new ResponseVO<>(ServerCode.SUCCESS, resultList);
+    }
+}