Selaa lähdekoodia

Merge branch 'dev'
1

wangliang 4 vuotta sitten
vanhempi
commit
875b9ca0c5
17 muutettua tiedostoa jossa 245 lisäystä ja 208 poistoa
  1. 12 4
      themis-backend/src/main/java/com/qmth/themis/backend/api/SysController.java
  2. 1 1
      themis-backend/src/main/java/com/qmth/themis/backend/api/TEExamStudentController.java
  3. 1 1
      themis-backend/src/main/java/com/qmth/themis/backend/api/TEStudentController.java
  4. 3 9
      themis-backend/src/main/java/com/qmth/themis/backend/api/TIeInvigilateCallMobileController.java
  5. 1 1
      themis-backend/src/main/java/com/qmth/themis/backend/api/TIeInvigilateController.java
  6. 15 6
      themis-backend/src/main/resources/application.properties
  7. 11 4
      themis-business/src/main/java/com/qmth/themis/business/config/SystemConfig.java
  8. 90 30
      themis-business/src/main/java/com/qmth/themis/business/domain/AliYunOssDomain.java
  9. 71 131
      themis-business/src/main/java/com/qmth/themis/business/service/impl/TEExamServiceImpl.java
  10. 2 2
      themis-business/src/main/java/com/qmth/themis/business/service/impl/TEOpenServiceImpl.java
  11. 1 1
      themis-business/src/main/java/com/qmth/themis/business/service/impl/TEStudentServiceImpl.java
  12. 2 2
      themis-business/src/main/java/com/qmth/themis/business/templete/impl/TaskExamPaperImportTemplete.java
  13. 0 1
      themis-business/src/main/resources/mapper/TEExamMapper.xml
  14. 4 2
      themis-exam/src/main/java/com/qmth/themis/exam/api/SysController.java
  15. 1 1
      themis-exam/src/main/java/com/qmth/themis/exam/api/TEStudentController.java
  16. 15 6
      themis-exam/src/main/resources/application.properties
  17. 15 6
      themis-task/src/main/resources/application.properties

+ 12 - 4
themis-backend/src/main/java/com/qmth/themis/backend/api/SysController.java

@@ -130,10 +130,18 @@ public class SysController {
         JSONObject jsonObject = JSONObject.parseObject(tbAttachment.getRemark());
         String attachmentType = String.valueOf(jsonObject.get("type"));
         String url = null;
+        String filePath = (String) jsonObject.get("path");
         if (Objects.equals(attachmentType, SystemConstant.LOCAL)) {
-            url = "http://" + dictionaryConfig.sysDomain().getFileHost() + File.separator + jsonObject.get("path");
+            url = "http://" + dictionaryConfig.sysDomain().getFileHost() + File.separator + filePath;
         } else {
-            url = dictionaryConfig.aliYunOssDomain().getUrl() + File.separator + jsonObject.get("path");
+            if (Objects.nonNull(mapParameter.get(SystemConstant.UPLOAD_TYPE))) {
+                Integer fileId = UploadFileEnum.convertToId((String) mapParameter.get(SystemConstant.UPLOAD_TYPE));
+                if (fileId == 3) {
+                    url = dictionaryConfig.aliYunOssDomain().getPrivateUrl() + File.separator + filePath;
+                } else {
+                    url = dictionaryConfig.aliYunOssDomain().getPublicUrl() + File.separator + filePath;
+                }
+            }
         }
         Map map = new HashMap();
         map.put(SystemConstant.ID, tbAttachment.getId());
@@ -176,7 +184,7 @@ public class SysController {
         if (Objects.isNull(jsonObject) || Objects.isNull(jsonObject.get("path"))) {
             throw new BusinessException("下载文件地址不存在");
         }
-        String filePath = String.valueOf(jsonObject.get("path"));
+        String filePath = (String) jsonObject.get("path");
         String url = null;
         if (oss) {
             if (Objects.nonNull(filePath)) {
@@ -185,7 +193,7 @@ public class SysController {
                 if (fileId == 3) {
                     url = OssUtil.getUrlForPrivateBucket(systemConfig.getOssEnv(3), filePath);
                 } else {
-                    url = dictionaryConfig.aliYunOssDomain().getUrl() + File.separator + filePath;
+                    url = dictionaryConfig.aliYunOssDomain().getPublicUrl() + File.separator + filePath;
                 }
             }
         } else {

+ 1 - 1
themis-backend/src/main/java/com/qmth/themis/backend/api/TEExamStudentController.java

@@ -143,7 +143,7 @@ public class TEExamStudentController {
         if (teExamStudentIPage.getRecords() != null && teExamStudentIPage.getRecords().size() > 0) {
             for (TEExamStudentDto dto : teExamStudentIPage.getRecords()) {
                 if (StringUtils.isNotBlank(dto.getBasePhotoUrl())) {
-                    dto.setBasePhotoUrl(systemConfig.getProperty("aliyun.oss.url") + "/" + dto.getBasePhotoUrl());
+                    dto.setBasePhotoUrl(systemConfig.getProperty("aliyun.oss.publicUrl") + "/" + dto.getBasePhotoUrl());
                 }
             }
         }

+ 1 - 1
themis-backend/src/main/java/com/qmth/themis/backend/api/TEStudentController.java

@@ -60,7 +60,7 @@ public class TEStudentController {
         if (teExamStudentIPage.getRecords() != null && teExamStudentIPage.getRecords().size() > 0) {
             for (TEStudentDto dto : teExamStudentIPage.getRecords()) {
                 if (StringUtils.isNotBlank(dto.getBasePhotoPath())) {
-                    dto.setBasePhotoPath(systemConfig.getProperty("aliyun.oss.url") + "/" + dto.getBasePhotoPath());
+                    dto.setBasePhotoPath(systemConfig.getProperty("aliyun.oss.publicUrl") + "/" + dto.getBasePhotoPath());
                 }
             }
         }

+ 3 - 9
themis-backend/src/main/java/com/qmth/themis/backend/api/TIeInvigilateCallMobileController.java

@@ -100,7 +100,7 @@ public class TIeInvigilateCallMobileController {
         }
         IPage<TIeExamInvigilateCallDto> tIeExamInvigilateCallIPage = tIeExamInvigilateCallService.examInvigilateCallQuery(new Page<>(pageNumber, pageSize), examId, userId, tbUser.getOrgId(), MonitorStatusSourceEnum.START.name(), callStatus);
         tIeExamInvigilateCallIPage.getRecords().forEach(s -> {
-            s.setBasePhotoPath(systemConfig.getProperty("aliyun.oss.url") + File.separator + s.getBasePhotoPath());
+            s.setBasePhotoPath(systemConfig.getProperty("aliyun.oss.publicUrl") + File.separator + s.getBasePhotoPath());
             try {
                 s.setSourceUserId(this.getSourceUserId(s.getExamRecordId()));
             } catch (NoSuchAlgorithmException e) {
@@ -251,14 +251,8 @@ public class TIeInvigilateCallMobileController {
         }
         ExamCacheBean ec = teExamService.getExamCacheBean(examId);//考试缓存
         ExamStudentCacheBean examStudentCacheBean = teExamStudentService.getExamStudentCacheBean(examStudentId);
-        ec.getMonitorVideoSource();
-        List<String> monitorVideoSourceList = null;
-        if (Objects.nonNull(ec.getMonitorVideoSource()) && !Objects.equals(ec.getMonitorVideoSource().toString().trim().replaceAll(" ", ""), "")) {
-            monitorVideoSourceList = Arrays.asList(ec.getMonitorVideoSource().trim().toUpperCase().replaceAll(" ", "").split(","));
-        }
-        //加入monitorAudioEnable逻辑
-        if (Objects.nonNull(monitorVideoSourceList)) {
-            if (monitorVideoSourceList.size() == 4 || (ec.getMonitorVideoSource().toUpperCase().contains(MonitorVideoSourceEnum.CLIENT_SCREEN.name()) || ec.getMonitorVideoSource().toUpperCase().contains(MonitorVideoSourceEnum.CLIENT_CAMERA.name()))) {
+        if (Objects.nonNull(ec.getMonitorAudioEnable())) {
+            if (ec.getMonitorAudioEnable()) {
                 for (Source s : Source.values()) {
                     String sessionId = SessionUtil.digest(examStudentCacheBean.getIdentity(), Math.abs(Sets.newHashSet(RoleEnum.STUDENT.name()).toString().hashCode()), s.name());
                     TBSession tbSessionClient = (TBSession) redisUtil.getUserSession(sessionId);

+ 1 - 1
themis-backend/src/main/java/com/qmth/themis/backend/api/TIeInvigilateController.java

@@ -264,7 +264,7 @@ public class TIeInvigilateController {
         }
         ExamStudentCacheBean examStudentCacheBean = teExamStudentService.getExamStudentCacheBean(examStudentId);
         TEStudent teStudent = teStudentService.getById(examStudentCacheBean.getStudentId());
-        String basePhotoPath = systemConfig.getProperty("aliyun.oss.url") + File.separator + teStudent.getBasePhotoPath();
+        String basePhotoPath = systemConfig.getProperty("aliyun.oss.publicUrl") + File.separator + teStudent.getBasePhotoPath();
         String identity = examStudentCacheBean.getIdentity();
         String examStudentName = examStudentCacheBean.getName();
         String courseNameCode = examStudentCacheBean.getCourseName() + "(" + examStudentCacheBean.getCourseCode() + ")";

+ 15 - 6
themis-backend/src/main/resources/application.properties

@@ -108,14 +108,23 @@ spring.jackson.date-format=yyyy-MM-dd HH:mm:ss
 spring.jackson.time-zone=GMT+8
 
 #\u963F\u91CC\u4E91OSS\u914D\u7F6E
-aliyun.oss.name=oss-cn-shenzhen.aliyuncs.com
+aliyun.oss.publicName=oss-cn-shenzhen.aliyuncs.com
 #aliyun.oss.endpoint=http://${aliyun.oss.name}
-aliyun.oss.endpoint=http://oss-cn-shenzhen.aliyuncs.com
-aliyun.oss.accessKeyId=LTAI4FnJ2pgV6aGceYcCkeEi
-aliyun.oss.accessKeySecret=ktrMEVE7PfoxRPeJUPDFeygOIH4aU7
-aliyun.oss.bucket=qmth-test
+aliyun.oss.publicEndpoint=http://oss-cn-shenzhen.aliyuncs.com
+aliyun.oss.publicAccessKeyId=LTAI4FnJ2pgV6aGceYcCkeEi
+aliyun.oss.publicAccessKeySecret=ktrMEVE7PfoxRPeJUPDFeygOIH4aU7
+aliyun.oss.publicBucket=qmth-test
 #aliyun.oss.url=http://${aliyun.oss.bucket}.${aliyun.oss.name}
-aliyun.oss.url=http://qmth-test.oss-cn-shenzhen.aliyuncs.com
+aliyun.oss.publicUrl=http://qmth-test.oss-cn-shenzhen.aliyuncs.com
+
+aliyun.oss.privateName=oss-cn-shenzhen.aliyuncs.com
+#aliyun.oss.endpoint=http://${aliyun.oss.name}
+aliyun.oss.privateEndpoint=http://oss-cn-shenzhen.aliyuncs.com
+aliyun.oss.privateAccessKeyId=LTAI4FnJ2pgV6aGceYcCkeEi
+aliyun.oss.privateAccessKeySecret=ktrMEVE7PfoxRPeJUPDFeygOIH4aU7
+aliyun.oss.privateBucket=qmth-test
+#aliyun.oss.url=http://${aliyun.oss.bucket}.${aliyun.oss.name}
+aliyun.oss.privateUrl=http://qmth-test.oss-cn-shenzhen.aliyuncs.com
 
 #\u817E\u8BAF\u4E91\u914D\u7F6E
 tencentyun.sdk.appId=1400411036

+ 11 - 4
themis-business/src/main/java/com/qmth/themis/business/config/SystemConfig.java

@@ -71,10 +71,17 @@ public class SystemConfig {
      */
     public Map<String, Object> getOssEnv(Integer type) {
         Map<String, Object> mapParameter = new HashMap<>();
-        mapParameter.put(SystemConstant.END_POINT, props.getProperty("aliyun.oss.endpoint", "aliyun.oss.name"));
-        mapParameter.put(SystemConstant.ACCESS_KEY_ID, props.getProperty("aliyun.oss.accessKeyId"));
-        mapParameter.put(SystemConstant.ACCESS_KEY_SECRET, props.getProperty("aliyun.oss.accessKeySecret"));
-        mapParameter.put(SystemConstant.BUCKET, props.getProperty("aliyun.oss.bucket"));
+        if (Objects.nonNull(type) && type == 3) {
+            mapParameter.put(SystemConstant.END_POINT, props.getProperty("aliyun.oss.privateEndpoint", "aliyun.oss.privateName"));
+            mapParameter.put(SystemConstant.ACCESS_KEY_ID, props.getProperty("aliyun.oss.privateAccessKeyId"));
+            mapParameter.put(SystemConstant.ACCESS_KEY_SECRET, props.getProperty("aliyun.oss.privateAccessKeySecret"));
+            mapParameter.put(SystemConstant.BUCKET, props.getProperty("aliyun.oss.privateBucket"));
+        } else {
+            mapParameter.put(SystemConstant.END_POINT, props.getProperty("aliyun.oss.publicEndpoint", "aliyun.oss.publicName"));
+            mapParameter.put(SystemConstant.ACCESS_KEY_ID, props.getProperty("aliyun.oss.publicAccessKeyId"));
+            mapParameter.put(SystemConstant.ACCESS_KEY_SECRET, props.getProperty("aliyun.oss.publicAccessKeySecret"));
+            mapParameter.put(SystemConstant.BUCKET, props.getProperty("aliyun.oss.publicBucket"));
+        }
         mapParameter.put(SystemConstant.OSS, Boolean.valueOf(props.getProperty("sys.config.oss")));
         mapParameter.put(SystemConstant.ATTACHMENT_TYPE, Arrays.asList(props.getProperty("sys.config.attachmentType").split(",")));
         String uploadType = UploadFileEnum.convertToName(type);

+ 90 - 30
themis-business/src/main/java/com/qmth/themis/business/domain/AliYunOssDomain.java

@@ -11,63 +11,123 @@ import java.io.Serializable;
  */
 public class AliYunOssDomain implements Serializable {
 
-    private String endpoint;
+    private String publicEndpoint;
 
-    private String name;
+    private String publicName;
 
-    private String accessKeyId;
+    private String publicAccessKeyId;
 
-    private String accessKeySecret;
+    private String publicAccessKeySecret;
 
-    private String bucket;
+    private String publicBucket;
 
-    private String url;
+    private String publicUrl;
 
-    public String getEndpoint() {
-        return endpoint;
+    private String privateEndpoint;
+
+    private String privateName;
+
+    private String privateAccessKeyId;
+
+    private String privateAccessKeySecret;
+
+    private String privateBucket;
+
+    private String privateUrl;
+
+    public String getPrivateEndpoint() {
+        return privateEndpoint;
+    }
+
+    public void setPrivateEndpoint(String privateEndpoint) {
+        this.privateEndpoint = privateEndpoint;
+    }
+
+    public String getPrivateName() {
+        return privateName;
+    }
+
+    public void setPrivateName(String privateName) {
+        this.privateName = privateName;
+    }
+
+    public String getPrivateAccessKeyId() {
+        return privateAccessKeyId;
+    }
+
+    public void setPrivateAccessKeyId(String privateAccessKeyId) {
+        this.privateAccessKeyId = privateAccessKeyId;
+    }
+
+    public String getPrivateAccessKeySecret() {
+        return privateAccessKeySecret;
+    }
+
+    public void setPrivateAccessKeySecret(String privateAccessKeySecret) {
+        this.privateAccessKeySecret = privateAccessKeySecret;
+    }
+
+    public String getPrivateBucket() {
+        return privateBucket;
+    }
+
+    public void setPrivateBucket(String privateBucket) {
+        this.privateBucket = privateBucket;
+    }
+
+    public String getPrivateUrl() {
+        return privateUrl;
+    }
+
+    public void setPrivateUrl(String privateUrl) {
+        this.privateUrl = privateUrl;
+    }
+
+    public String getPublicEndpoint() {
+        return publicEndpoint;
     }
 
-    public void setEndpoint(String endpoint) {
-        this.endpoint = endpoint;
+    public void setPublicEndpoint(String publicEndpoint) {
+        this.publicEndpoint = publicEndpoint;
     }
 
-    public String getName() {
-        return name;
+    public String getPublicName() {
+        return publicName;
     }
 
-    public void setName(String name) {
-        this.name = name;
+    public void setPublicName(String publicName) {
+        this.publicName = publicName;
     }
 
-    public String getAccessKeyId() {
-        return accessKeyId;
+    public String getPublicAccessKeyId() {
+        return publicAccessKeyId;
     }
 
-    public void setAccessKeyId(String accessKeyId) {
-        this.accessKeyId = accessKeyId;
+    public void setPublicAccessKeyId(String publicAccessKeyId) {
+        this.publicAccessKeyId = publicAccessKeyId;
     }
 
-    public String getAccessKeySecret() {
-        return accessKeySecret;
+    public String getPublicAccessKeySecret() {
+        return publicAccessKeySecret;
     }
 
-    public void setAccessKeySecret(String accessKeySecret) {
-        this.accessKeySecret = accessKeySecret;
+    public void setPublicAccessKeySecret(String publicAccessKeySecret) {
+        this.publicAccessKeySecret = publicAccessKeySecret;
     }
 
-    public String getBucket() {
-        return bucket;
+    public String getPublicBucket() {
+        return publicBucket;
     }
 
-    public void setBucket(String bucket) {
-        this.bucket = bucket;
+    public void setPublicBucket(String publicBucket) {
+        this.publicBucket = publicBucket;
     }
 
-    public String getUrl() {
-        return url;
+    public String getPublicUrl() {
+        return publicUrl;
     }
 
-    public void setUrl(String url) {
-        this.url = url;
+    public void setPublicUrl(String publicUrl) {
+        this.publicUrl = publicUrl;
     }
 }

+ 71 - 131
themis-business/src/main/java/com/qmth/themis/business/service/impl/TEExamServiceImpl.java

@@ -1,67 +1,16 @@
 package com.qmth.themis.business.service.impl;
 
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.math.BigDecimal;
-import java.text.SimpleDateFormat;
-import java.time.LocalDateTime;
-import java.time.ZoneOffset;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Calendar;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
-import java.util.Set;
-import java.util.UUID;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-import java.util.stream.Collectors;
-
-import javax.annotation.Resource;
-
-import org.apache.commons.codec.digest.DigestUtils;
-import org.springframework.beans.BeanUtils;
-import org.springframework.cache.annotation.CacheEvict;
-import org.springframework.cache.annotation.CachePut;
-import org.springframework.cache.annotation.Cacheable;
-import org.springframework.stereotype.Service;
-import org.springframework.transaction.annotation.Transactional;
-import org.springframework.web.multipart.MultipartFile;
-
 import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.qmth.themis.business.bean.backend.OpenExamBean;
-import com.qmth.themis.business.bean.exam.AnswerSubmitBean;
-import com.qmth.themis.business.bean.exam.AudioLeftPlayCountSubmitBean;
-import com.qmth.themis.business.bean.exam.ExamFileUploadBean;
-import com.qmth.themis.business.bean.exam.ExamFinishBean;
-import com.qmth.themis.business.bean.exam.ExamPrepareBean;
-import com.qmth.themis.business.bean.exam.ExamResultBean;
-import com.qmth.themis.business.bean.exam.ExamResumeBean;
-import com.qmth.themis.business.bean.exam.ExamStartBean;
-import com.qmth.themis.business.bean.exam.StudentPaperStructBean;
+import com.qmth.themis.business.bean.exam.*;
 import com.qmth.themis.business.cache.ExamActivityRecordCacheUtil;
 import com.qmth.themis.business.cache.ExamRecordCacheUtil;
 import com.qmth.themis.business.cache.ExamingDataCacheUtil;
 import com.qmth.themis.business.cache.RedisKeyHelper;
-import com.qmth.themis.business.cache.bean.ExamActivityCacheBean;
-import com.qmth.themis.business.cache.bean.ExamActivityRecordCacheBean;
-import com.qmth.themis.business.cache.bean.ExamCacheBean;
-import com.qmth.themis.business.cache.bean.ExamCourseCacheBean;
-import com.qmth.themis.business.cache.bean.ExamPaperCacheBean;
-import com.qmth.themis.business.cache.bean.ExamStudentAnswerCacheBean;
-import com.qmth.themis.business.cache.bean.ExamStudentCacheBean;
-import com.qmth.themis.business.cache.bean.ExamStudentPaperStructCacheBean;
-import com.qmth.themis.business.cache.bean.ObjectiveAnswerCacheBean;
+import com.qmth.themis.business.cache.bean.*;
 import com.qmth.themis.business.config.SystemConfig;
 import com.qmth.themis.business.constant.SpringContextHolder;
 import com.qmth.themis.business.constant.SystemConstant;
@@ -75,40 +24,33 @@ import com.qmth.themis.business.entity.TBSession;
 import com.qmth.themis.business.entity.TBTaskHistory;
 import com.qmth.themis.business.entity.TEExam;
 import com.qmth.themis.business.entity.TOeExamRecord;
-import com.qmth.themis.business.enums.EntryAuthenticationPolicyEnum;
-import com.qmth.themis.business.enums.ExamModeEnum;
-import com.qmth.themis.business.enums.ExamRecordFieldEnum;
-import com.qmth.themis.business.enums.ExamRecordStatusEnum;
-import com.qmth.themis.business.enums.FinishExamResultEnum;
-import com.qmth.themis.business.enums.FinishTypeEnum;
-import com.qmth.themis.business.enums.HardwareTestEnum;
-import com.qmth.themis.business.enums.InvigilateMonitorStatusEnum;
-import com.qmth.themis.business.enums.InvigilateVerifyEnum;
-import com.qmth.themis.business.enums.MonitorStatusSourceEnum;
-import com.qmth.themis.business.enums.MonitorVideoSourceEnum;
-import com.qmth.themis.business.enums.MqTagEnum;
-import com.qmth.themis.business.enums.MqTopicEnum;
-import com.qmth.themis.business.enums.ReviewResultEnum;
-import com.qmth.themis.business.enums.ScoreStatusEnum;
-import com.qmth.themis.business.enums.SystemOperationEnum;
-import com.qmth.themis.business.enums.TaskStatusEnum;
-import com.qmth.themis.business.enums.WebsocketStatusEnum;
-import com.qmth.themis.business.service.MqDtoService;
-import com.qmth.themis.business.service.TBTaskHistoryService;
-import com.qmth.themis.business.service.TEExamActivityService;
-import com.qmth.themis.business.service.TEExamCourseService;
-import com.qmth.themis.business.service.TEExamPaperService;
-import com.qmth.themis.business.service.TEExamService;
-import com.qmth.themis.business.service.TEExamStudentService;
-import com.qmth.themis.business.service.TOeExamRecordService;
-import com.qmth.themis.business.util.JacksonUtil;
-import com.qmth.themis.business.util.OssUtil;
-import com.qmth.themis.business.util.RedisUtil;
-import com.qmth.themis.business.util.ServletUtil;
-import com.qmth.themis.business.util.TencentYunUtil;
+import com.qmth.themis.business.enums.*;
+import com.qmth.themis.business.service.*;
+import com.qmth.themis.business.util.*;
 import com.qmth.themis.common.enums.ExceptionResultEnum;
 import com.qmth.themis.common.exception.BusinessException;
 import com.qmth.themis.common.util.IpUtil;
+import org.apache.commons.codec.digest.DigestUtils;
+import org.springframework.beans.BeanUtils;
+import org.springframework.cache.annotation.CacheEvict;
+import org.springframework.cache.annotation.CachePut;
+import org.springframework.cache.annotation.Cacheable;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.web.multipart.MultipartFile;
+
+import javax.annotation.Resource;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.math.BigDecimal;
+import java.text.SimpleDateFormat;
+import java.time.LocalDateTime;
+import java.time.ZoneOffset;
+import java.util.*;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import java.util.stream.Collectors;
 
 /**
  * @Description: 考试批次 服务实现类
@@ -217,10 +159,7 @@ public class TEExamServiceImpl extends ServiceImpl<TEExamMapper, TEExam> impleme
                 }
                 if (Objects.nonNull(v.getMonitorVideoSourceStr()) && !Objects.equals(v.getMonitorVideoSourceStr().toString().trim().replaceAll(" ", ""), "")) {
                     v.setMonitorVideoSource(Arrays.asList(v.getMonitorVideoSourceStr().trim().toUpperCase().replaceAll(" ", "").split(",")));
-                    //加入monitorAudioEnable逻辑
-                    if (v.getMonitorVideoSource().size() == 4 || (v.getMonitorVideoSourceStr().toUpperCase().contains(MonitorVideoSourceEnum.CLIENT_SCREEN.name()) || v.getMonitorVideoSourceStr().toUpperCase().contains(MonitorVideoSourceEnum.CLIENT_CAMERA.name()))) {
-                        v.setMonitorAudioEnable(true);
-                    }
+                    v.setMonitorAudioEnable(examCache.getMonitorAudioEnable());
                     //加入hardwareTest逻辑
                     if (v.getMonitorVideoSourceStr().toUpperCase().contains(MonitorVideoSourceEnum.CLIENT_CAMERA.name()) || (Objects.nonNull(v.getEntryAuthenticationPolicy()) && (Objects.equals(v.getEntryAuthenticationPolicy(), EntryAuthenticationPolicyEnum.LIVENESS_VERIFY.name()) || Objects.equals(v.getEntryAuthenticationPolicy(), EntryAuthenticationPolicyEnum.FACE_VERIFY_FORCE.name()))) || (Objects.nonNull(v.getCameraPhotoUpload()) && v.getCameraPhotoUpload() == 1)) {
                         List<String> hardwareTest = v.getHardwareTest();
@@ -365,7 +304,7 @@ public class TEExamServiceImpl extends ServiceImpl<TEExamMapper, TEExam> impleme
 //        }
 
         Long recordId = toeExamRecordService.saveByPrepare(es.getExamId(), es.getExamActivityId(), examStudentId,
-                paperId, es.getAlreadyExamCount()+1);
+                paperId, es.getAlreadyExamCount() + 1);
 
         es.setCurrentRecordId(recordId);
 
@@ -490,7 +429,6 @@ public class TEExamServiceImpl extends ServiceImpl<TEExamMapper, TEExam> impleme
             }
         }
 
-
         Long paperId = ExamRecordCacheUtil.getPaperId(recordId);
         ExamPaperCacheBean ep = teExamPaperService.getExamPaperCacheBean(paperId);
         if (ep == null) {
@@ -501,21 +439,24 @@ public class TEExamServiceImpl extends ServiceImpl<TEExamMapper, TEExam> impleme
         if (Objects.nonNull(websocketStatusEnum) && Objects.equals(WebsocketStatusEnum.OFF_LINE, websocketStatusEnum)) {
             throw new BusinessException(ExceptionResultEnum.CLIENT_NET_OFFLINE);
         }
-        MonitorStatusSourceEnum clientCameraStatus = ExamRecordCacheUtil.getMonitorStatus(recordId, MonitorVideoSourceEnum.CLIENT_CAMERA);
-        if (Objects.nonNull(clientCameraStatus) && Objects.equals(MonitorStatusSourceEnum.STOP, clientCameraStatus)) {
-            throw new BusinessException(ExceptionResultEnum.CLIENT_CAMERA_OFFLINE);
-        }
-        MonitorStatusSourceEnum clientScreenStatus = ExamRecordCacheUtil.getMonitorStatus(recordId, MonitorVideoSourceEnum.CLIENT_SCREEN);
-        if (Objects.nonNull(clientScreenStatus) && Objects.equals(MonitorStatusSourceEnum.STOP, clientScreenStatus)) {
-            throw new BusinessException(ExceptionResultEnum.CLIENT_SCREEN_OFFLINE);
-        }
-        MonitorStatusSourceEnum mobileFirstStatus = ExamRecordCacheUtil.getMonitorStatus(recordId, MonitorVideoSourceEnum.MOBILE_FIRST);
-        if (Objects.nonNull(mobileFirstStatus) && Objects.equals(MonitorStatusSourceEnum.STOP, mobileFirstStatus)) {
-            throw new BusinessException(ExceptionResultEnum.MOBILE_FIRST_OFFLINE);
-        }
-        MonitorStatusSourceEnum mobileSecondStatus = ExamRecordCacheUtil.getMonitorStatus(recordId, MonitorVideoSourceEnum.MOBILE_SECOND);
-        if (Objects.nonNull(mobileSecondStatus) && Objects.equals(MonitorStatusSourceEnum.STOP, mobileSecondStatus)) {
-            throw new BusinessException(ExceptionResultEnum.MOBILE_SECOND_OFFLINE);
+
+        if (Objects.nonNull(exam.getMonitorVideoSource())) {
+            String[] strs = exam.getMonitorVideoSource().split(",");
+            for (int i = 0; i < strs.length; i++) {
+                MonitorStatusSourceEnum clientCameraStatus = ExamRecordCacheUtil.getMonitorStatus(recordId, MonitorVideoSourceEnum.valueOf(strs[i]));
+                if (Objects.isNull(clientCameraStatus) || Objects.equals(MonitorStatusSourceEnum.STOP, clientCameraStatus)) {
+                    switch (strs[i]) {
+                        case "CLIENT_CAMERA":
+                            throw new BusinessException(ExceptionResultEnum.CLIENT_CAMERA_OFFLINE);
+                        case "CLIENT_SCREEN":
+                            throw new BusinessException(ExceptionResultEnum.CLIENT_SCREEN_OFFLINE);
+                        case "MOBILE_FIRST":
+                            throw new BusinessException(ExceptionResultEnum.MOBILE_FIRST_OFFLINE);
+                        default:
+                            throw new BusinessException(ExceptionResultEnum.MOBILE_SECOND_OFFLINE);
+                    }
+                }
+            }
         }
 
         ExamStudentCacheBean examStudentCacheBean = teExamStudentService.getExamStudentCacheBean(examStudentId);
@@ -541,11 +482,11 @@ public class TEExamServiceImpl extends ServiceImpl<TEExamMapper, TEExam> impleme
         ret.setPaperDecryptVector(ep.getDecryptVector());
 
         if (!ExamRecordStatusEnum.RESUME_PREPARE.equals(sta)) {//非断点进入的
-	        // 写入次数
-	        es.setAlreadyExamCount(es.getAlreadyExamCount()+1);
-	        // 更新考生缓存
-	        redisUtil.set(RedisKeyHelper.examStudentCacheKey(examStudentId), es);
-	        updateExamStudent(examStudentId, es.getAlreadyExamCount(), recordId);
+            // 写入次数
+            es.setAlreadyExamCount(es.getAlreadyExamCount() + 1);
+            // 更新考生缓存
+            redisUtil.set(RedisKeyHelper.examStudentCacheKey(examStudentId), es);
+            updateExamStudent(examStudentId, es.getAlreadyExamCount(), recordId);
         }
         // 更新考试记录缓存
         Long firstStartTime = System.currentTimeMillis();
@@ -558,7 +499,7 @@ public class TEExamServiceImpl extends ServiceImpl<TEExamMapper, TEExam> impleme
         toeExamRecordService.dataUpdatesMq(recordId, columns, values);
         //更新场次-考试记录缓存
         ExamActivityRecordCacheUtil.setExamRecordStatus(activityId, recordId, new ExamActivityRecordCacheBean(ExamRecordCacheUtil.getExamStudentId(recordId), ExamRecordCacheUtil.getStatus(recordId)));
-        
+
         //非强制交卷,换算最终交卷时间并生成一次性延时任务
         if (Objects.nonNull(exam.getForceFinish()) && exam.getForceFinish().intValue() == 0) {
             Long date = ExamRecordCacheUtil.getExamFinalFinishTime(recordId);
@@ -750,7 +691,6 @@ public class TEExamServiceImpl extends ServiceImpl<TEExamMapper, TEExam> impleme
     @Override
     public ExamFileUploadBean fileUpload(Long studentId, Long recordId, MultipartFile file, String suffix, String
             md5) {
-
         // 校验当前登录用户和参数一致性
         if (ExamRecordCacheUtil.getId(recordId) == null) {
             throw new BusinessException(ExceptionResultEnum.NOT_FOUND_EXAM_RECORD);
@@ -778,7 +718,7 @@ public class TEExamServiceImpl extends ServiceImpl<TEExamMapper, TEExam> impleme
             }
             in = file.getInputStream();
             OssUtil.ossUploadStream(systemConfig.getOssEnv(3), filePath, in);
-            String url = systemConfig.getProperty("aliyun.oss.url") + File.separator + filePath;
+            String url = systemConfig.getProperty("aliyun.oss.privateUrl") + File.separator + filePath;
             ExamFileUploadBean ret = new ExamFileUploadBean();
             ret.setUrl(url);
             ret.setUploadTime(System.currentTimeMillis());
@@ -1252,24 +1192,24 @@ public class TEExamServiceImpl extends ServiceImpl<TEExamMapper, TEExam> impleme
         int timeOutSecond = 60 * 60 * 5;
         String lockKey = SystemConstant.REDIS_LOCK_CALCULATE_SCORE_PREFIX + examId;
         String multLockKey = SystemConstant.REDIS_LOCK_CALCULATE_SCORE_PAPER_IMPORT_PREFIX + examId;
-        
+
         TBTaskHistory task = null;
         Long recordId = null;
         try {
-        	Boolean lock = redisUtil.lock(lockKey, timeOutSecond);
+            Boolean lock = redisUtil.lock(lockKey, timeOutSecond);
             if (!lock) {
-            	throw new BusinessException("该考试批次有正在进行的重新算分");
+                throw new BusinessException("该考试批次有正在进行的重新算分");
             }
-            
+
             //重新算分和试卷导入互斥锁
-	        Boolean multLock = redisUtil.lock(multLockKey, timeOutSecond);
-	        if (!multLock) {
-	        	throw new BusinessException("该考试批次有正在进行的试卷导入");
-	        }
-	        
-        	TEExamService examService = SpringContextHolder.getBean(TEExamService.class);
-        	teExamMapper.updateScoreStatus(ScoreStatusEnum.CALCULATING, examId);
-        	examService.updateExamCacheBean(examId);
+            Boolean multLock = redisUtil.lock(multLockKey, timeOutSecond);
+            if (!multLock) {
+                throw new BusinessException("该考试批次有正在进行的试卷导入");
+            }
+
+            TEExamService examService = SpringContextHolder.getBean(TEExamService.class);
+            teExamMapper.updateScoreStatus(ScoreStatusEnum.CALCULATING, examId);
+            examService.updateExamCacheBean(examId);
             task = tbTaskHistoryService.getById(taskId);
             task.setStatus(TaskStatusEnum.RUNNING);
             tbTaskHistoryService.saveOrUpdate(task);
@@ -1306,7 +1246,7 @@ public class TEExamServiceImpl extends ServiceImpl<TEExamMapper, TEExam> impleme
             task.setStatus(TaskStatusEnum.FINISH);
             task.setFinishTime(System.currentTimeMillis());
             JSONObject json = new JSONObject();
-            String reportFilePath="file/"+sdf.format(new Date()) + "/" + uuid() + SystemConstant.TXT_PREFIX;
+            String reportFilePath = "file/" + sdf.format(new Date()) + "/" + uuid() + SystemConstant.TXT_PREFIX;
             json.put("path", reportFilePath);
             json.put("type", SystemConstant.OSS);
             OssUtil.ossUploadContent(systemConfig.getOssEnv(3), reportFilePath, e.getMessage());
@@ -1340,15 +1280,15 @@ public class TEExamServiceImpl extends ServiceImpl<TEExamMapper, TEExam> impleme
     public void updateInvigilateMonitorStatus(InvigilateMonitorStatusEnum monitorStatus, Long examId) {
         teExamMapper.updateInvigilateMonitorStatus(monitorStatus, examId);
     }
-    
+
     @Transactional
     @Override
     public void updateScoreStatus(ScoreStatusEnum scoreStatus, Long examId) {
         teExamMapper.updateScoreStatus(scoreStatus, examId);
     }
 
-	@Override
-	public IPage<OpenExamBean> examQueryForOpen(Page<OpenExamBean> ipage, Long examId, String examCode) {
-		return teExamMapper.examQueryForOpen(ipage, examId, examCode);
-	}
+    @Override
+    public IPage<OpenExamBean> examQueryForOpen(Page<OpenExamBean> ipage, Long examId, String examCode) {
+        return teExamMapper.examQueryForOpen(ipage, examId, examCode);
+    }
 }

+ 2 - 2
themis-business/src/main/java/com/qmth/themis/business/service/impl/TEOpenServiceImpl.java

@@ -102,8 +102,8 @@ public class TEOpenServiceImpl implements TEOpenService {
 			SystemConfig systemConfig = SpringContextHolder.getBean(SystemConfig.class);
 			File paperFile = new File(dir + uuid() + ".json");
 			File anwserFile = new File(dir + uuid() + ".json");
-			FileUtil.saveUrlAsFile(systemConfig.getProperty("aliyun.oss.url") + "/"+paperPath, paperFile);
-			FileUtil.saveUrlAsFile(systemConfig.getProperty("aliyun.oss.url") + "/"+anwserPath, anwserFile);
+			FileUtil.saveUrlAsFile(systemConfig.getProperty("aliyun.oss.privateUrl") + "/"+paperPath, paperFile);
+			FileUtil.saveUrlAsFile(systemConfig.getProperty("aliyun.oss.privateUrl") + "/"+anwserPath, anwserFile);
 			JSONObject answerJson = JSONObject.parseObject(FileUtil.readFileContent(anwserFile));
 			JSONArray answerdetails = answerJson.getJSONArray("details");
 			JSONObject structJson = JSONObject.parseObject(FileUtil.readFileContent(paperFile));

+ 1 - 1
themis-business/src/main/java/com/qmth/themis/business/service/impl/TEStudentServiceImpl.java

@@ -100,7 +100,7 @@ public class TEStudentServiceImpl extends ServiceImpl<TEStudentMapper, TEStudent
             redisUtil.setStudent(student.getId(), teStudentCacheDto);
             in = file.getInputStream();
             OssUtil.ossUploadStream(systemConfig.getOssEnv(3), filePath, in);
-            String url = systemConfig.getProperty("aliyun.oss.url") + File.separator + filePath;
+            String url = systemConfig.getProperty("aliyun.oss.publicUrl") + File.separator + filePath;
             StudentPhotoUploadResponseBean ret = new StudentPhotoUploadResponseBean();
             ret.setPhotoUrl(url);
             return ret;

+ 2 - 2
themis-business/src/main/java/com/qmth/themis/business/templete/impl/TaskExamPaperImportTemplete.java

@@ -552,14 +552,14 @@ public class TaskExamPaperImportTemplete implements TaskImportTemplete {
                 String filePath = "upload/paper_file/"+paperId+"/" + uuid() +"."+ suff;
                 SystemConfig systemConfig = SpringContextHolder.getBean(SystemConfig.class);
 				OssUtil.ossUpload(systemConfig.getOssEnv(3), filePath, iamgeFile);
-				blockInfo.put("value", systemConfig.getProperty("aliyun.oss.url") + "/" +filePath);
+				blockInfo.put("value", systemConfig.getProperty("aliyun.oss.privateUrl") + "/" +filePath);
 			}else{
 				String suff=value.substring(value.indexOf("."));
 				String filePath = "upload/paper_file/"+paperId+"/" + uuid() + suff;
 				File audioFile=new File(attachmentDir.getAbsolutePath()+"/"+value);
 				SystemConfig systemConfig = SpringContextHolder.getBean(SystemConfig.class);
 				OssUtil.ossUpload(systemConfig.getOssEnv(3), filePath, audioFile);
-				blockInfo.put("value", systemConfig.getProperty("aliyun.oss.url") + "/" +filePath);
+				blockInfo.put("value", systemConfig.getProperty("aliyun.oss.privateUrl") + "/" +filePath);
 			}
 		}
 	}

+ 0 - 1
themis-business/src/main/resources/mapper/TEExamMapper.xml

@@ -78,7 +78,6 @@
             <!--and t.monitor_status <![CDATA[ <> ]]> 'FINISHED'-->
             <if test="userId != null and userId != ''">
                 and t.start_time <![CDATA[ <= ]]> unix_timestamp(current_timestamp()) * 1000
-                and t.end_time <![CDATA[ >= ]]> unix_timestamp(current_timestamp()) * 1000
                 and t.enable = 1
                 and EXISTS(
                 select

+ 4 - 2
themis-exam/src/main/java/com/qmth/themis/exam/api/SysController.java

@@ -6,6 +6,7 @@ import com.qmth.themis.business.bean.exam.EnvBean;
 import com.qmth.themis.business.bean.exam.OrgInfoBean;
 import com.qmth.themis.business.bean.exam.VersionBean;
 import com.qmth.themis.business.entity.TBOrg;
+import com.qmth.themis.business.enums.UploadFileEnum;
 import com.qmth.themis.business.service.TBOrgService;
 import com.qmth.themis.business.util.RedisUtil;
 import com.qmth.themis.common.util.Result;
@@ -18,6 +19,7 @@ import org.springframework.web.bind.annotation.RequestMethod;
 import org.springframework.web.bind.annotation.RestController;
 
 import javax.annotation.Resource;
+import java.io.File;
 import java.util.Map;
 import java.util.Objects;
 
@@ -65,9 +67,9 @@ public class SysController {
         boolean oss = dictionaryConfig.sysDomain().isOss();
         String url = null;
         if (oss) {
-            url = dictionaryConfig.aliYunOssDomain().getUrl() + "/client/denyList.json";
+            url = dictionaryConfig.aliYunOssDomain().getPublicUrl() + File.separator + UploadFileEnum.client.name() + "/denyList.json";
         } else {
-            url = "http://" + dictionaryConfig.sysDomain().getFileHost() + "/client/denyList.json";
+            url = "http://" + dictionaryConfig.sysDomain().getFileHost() + File.separator + UploadFileEnum.client.name() + "/denyList.json";
         }
         env.setDenyList(url);
         return ResultUtil.ok(env);

+ 1 - 1
themis-exam/src/main/java/com/qmth/themis/exam/api/TEStudentController.java

@@ -151,7 +151,7 @@ public class TEStudentController {
             throw new BusinessException(ExceptionResultEnum.STUDENT_NO);
         }
         if (StringUtils.isNotBlank(user.getBasePhotoPath())) {
-            user.setBasePhotoPath(systemConfig.getProperty("aliyun.oss.url") + File.separator + user.getBasePhotoPath());
+            user.setBasePhotoPath(systemConfig.getProperty("aliyun.oss.publicUrl") + File.separator + user.getBasePhotoPath());
         }
         String loginPassword = AesUtil.decryptCs7(password, Constants.AES_RULE);
         //密码错误

+ 15 - 6
themis-exam/src/main/resources/application.properties

@@ -120,14 +120,23 @@ rocketmq.producer.enable-msg-trace=true
 rocketmq.producer.customized-trace-topic=my-trace-topic
 
 #\u963F\u91CC\u4E91OSS\u914D\u7F6E
-aliyun.oss.name=oss-cn-shenzhen.aliyuncs.com
+aliyun.oss.publicName=oss-cn-shenzhen.aliyuncs.com
 #aliyun.oss.endpoint=http://${aliyun.oss.name}
-aliyun.oss.endpoint=http://oss-cn-shenzhen.aliyuncs.com
-aliyun.oss.accessKeyId=LTAI4FnJ2pgV6aGceYcCkeEi
-aliyun.oss.accessKeySecret=ktrMEVE7PfoxRPeJUPDFeygOIH4aU7
-aliyun.oss.bucket=qmth-test
+aliyun.oss.publicEndpoint=http://oss-cn-shenzhen.aliyuncs.com
+aliyun.oss.publicAccessKeyId=LTAI4FnJ2pgV6aGceYcCkeEi
+aliyun.oss.publicAccessKeySecret=ktrMEVE7PfoxRPeJUPDFeygOIH4aU7
+aliyun.oss.publicBucket=qmth-test
 #aliyun.oss.url=http://${aliyun.oss.bucket}.${aliyun.oss.name}
-aliyun.oss.url=http://qmth-test.oss-cn-shenzhen.aliyuncs.com
+aliyun.oss.publicUrl=http://qmth-test.oss-cn-shenzhen.aliyuncs.com
+
+aliyun.oss.privateName=oss-cn-shenzhen.aliyuncs.com
+#aliyun.oss.endpoint=http://${aliyun.oss.name}
+aliyun.oss.privateEndpoint=http://oss-cn-shenzhen.aliyuncs.com
+aliyun.oss.privateAccessKeyId=LTAI4FnJ2pgV6aGceYcCkeEi
+aliyun.oss.privateAccessKeySecret=ktrMEVE7PfoxRPeJUPDFeygOIH4aU7
+aliyun.oss.privateBucket=qmth-test
+#aliyun.oss.url=http://${aliyun.oss.bucket}.${aliyun.oss.name}
+aliyun.oss.privateUrl=http://qmth-test.oss-cn-shenzhen.aliyuncs.com
 
 #\u817E\u8BAF\u4E91\u914D\u7F6E
 tencentyun.sdk.appId=1400411036

+ 15 - 6
themis-task/src/main/resources/application.properties

@@ -100,14 +100,23 @@ sys.config.serverUpload=/Users/king/git/themis-files/
 spring.resources.static-locations=file:${sys.config.serverUpload},classpath:/META-INF/resources/,classpath:/resources/
 
 #\u963F\u91CC\u4E91OSS\u914D\u7F6E
-aliyun.oss.name=oss-cn-shenzhen.aliyuncs.com
+aliyun.oss.publicName=oss-cn-shenzhen.aliyuncs.com
 #aliyun.oss.endpoint=http://${aliyun.oss.name}
-aliyun.oss.endpoint=http://oss-cn-shenzhen.aliyuncs.com
-aliyun.oss.accessKeyId=LTAI4FnJ2pgV6aGceYcCkeEi
-aliyun.oss.accessKeySecret=ktrMEVE7PfoxRPeJUPDFeygOIH4aU7
-aliyun.oss.bucket=qmth-test
+aliyun.oss.publicEndpoint=http://oss-cn-shenzhen.aliyuncs.com
+aliyun.oss.publicAccessKeyId=LTAI4FnJ2pgV6aGceYcCkeEi
+aliyun.oss.publicAccessKeySecret=ktrMEVE7PfoxRPeJUPDFeygOIH4aU7
+aliyun.oss.publicBucket=qmth-test
 #aliyun.oss.url=http://${aliyun.oss.bucket}.${aliyun.oss.name}
-aliyun.oss.url=http://qmth-test.oss-cn-shenzhen.aliyuncs.com
+aliyun.oss.publicUrl=http://qmth-test.oss-cn-shenzhen.aliyuncs.com
+
+aliyun.oss.privateName=oss-cn-shenzhen.aliyuncs.com
+#aliyun.oss.endpoint=http://${aliyun.oss.name}
+aliyun.oss.privateEndpoint=http://oss-cn-shenzhen.aliyuncs.com
+aliyun.oss.privateAccessKeyId=LTAI4FnJ2pgV6aGceYcCkeEi
+aliyun.oss.privateAccessKeySecret=ktrMEVE7PfoxRPeJUPDFeygOIH4aU7
+aliyun.oss.privateBucket=qmth-test
+#aliyun.oss.url=http://${aliyun.oss.bucket}.${aliyun.oss.name}
+aliyun.oss.privateUrl=http://qmth-test.oss-cn-shenzhen.aliyuncs.com
 #============================================================================
 # \u914D\u7F6EJobStore
 #============================================================================