wangliang 4 anni fa
parent
commit
8c1bd409ce
100 ha cambiato i file con 1243 aggiunte e 1209 eliminazioni
  1. 1 1
      README.md
  2. 8 8
      pom.xml
  3. 0 0
      themis-admin/Dockerfile
  4. 1 1
      themis-admin/README.md
  5. 2 2
      themis-admin/pom.xml
  6. 4 4
      themis-admin/src/main/java/com/qmth/themis/admin/ThemisAdminApplication.java
  7. 13 34
      themis-admin/src/main/java/com/qmth/themis/admin/api/SysController.java
  8. 48 0
      themis-admin/src/main/java/com/qmth/themis/admin/api/TBAppVersionController.java
  9. 100 0
      themis-admin/src/main/java/com/qmth/themis/admin/api/TBClientVersionController.java
  10. 40 32
      themis-admin/src/main/java/com/qmth/themis/admin/api/TBExamInvigilateUserController.java
  11. 15 19
      themis-admin/src/main/java/com/qmth/themis/admin/api/TBOrgController.java
  12. 1 1
      themis-admin/src/main/java/com/qmth/themis/admin/api/TBTaskHistoryController.java
  13. 105 91
      themis-admin/src/main/java/com/qmth/themis/admin/api/TBUserController.java
  14. 71 0
      themis-admin/src/main/java/com/qmth/themis/admin/api/TEExamActivityController.java
  15. 141 124
      themis-admin/src/main/java/com/qmth/themis/admin/api/TEExamController.java
  16. 2 2
      themis-admin/src/main/java/com/qmth/themis/admin/api/TEExamCourseController.java
  17. 21 15
      themis-admin/src/main/java/com/qmth/themis/admin/api/TEExamPaperController.java
  18. 8 5
      themis-admin/src/main/java/com/qmth/themis/admin/api/TEExamReexamController.java
  19. 83 77
      themis-admin/src/main/java/com/qmth/themis/admin/api/TEExamStudentController.java
  20. 13 14
      themis-admin/src/main/java/com/qmth/themis/admin/api/TEOpenController.java
  21. 8 16
      themis-admin/src/main/java/com/qmth/themis/admin/api/TEStudentController.java
  22. 37 31
      themis-admin/src/main/java/com/qmth/themis/admin/api/TIeInvigilateCallMobileController.java
  23. 102 73
      themis-admin/src/main/java/com/qmth/themis/admin/api/TIeInvigilateController.java
  24. 14 13
      themis-admin/src/main/java/com/qmth/themis/admin/api/TIeInvigilateWarnInfoController.java
  25. 2 5
      themis-admin/src/main/java/com/qmth/themis/admin/api/TIeReportController.java
  26. 11 12
      themis-admin/src/main/java/com/qmth/themis/admin/aspect/ApiControllerAspect.java
  27. 23 1
      themis-admin/src/main/java/com/qmth/themis/admin/config/DictionaryConfig.java
  28. 1 1
      themis-admin/src/main/java/com/qmth/themis/admin/config/DruidConfig.java
  29. 1 1
      themis-admin/src/main/java/com/qmth/themis/admin/config/ScheduleTaskConfig.java
  30. 3 3
      themis-admin/src/main/java/com/qmth/themis/admin/config/SwaggerConfig.java
  31. 3 4
      themis-admin/src/main/java/com/qmth/themis/admin/config/WebMvcConfig.java
  32. 1 1
      themis-admin/src/main/java/com/qmth/themis/admin/config/WebSocketConfig.java
  33. 1 1
      themis-admin/src/main/java/com/qmth/themis/admin/elasticsearch/entity/ETEStudentEntity.java
  34. 2 2
      themis-admin/src/main/java/com/qmth/themis/admin/elasticsearch/repository/ETEStudentRepo.java
  35. 2 2
      themis-admin/src/main/java/com/qmth/themis/admin/elasticsearch/service/ETEStudentService.java
  36. 4 4
      themis-admin/src/main/java/com/qmth/themis/admin/elasticsearch/service/impl/ETEStudentServiceImpl.java
  37. 61 0
      themis-admin/src/main/java/com/qmth/themis/admin/interceptor/AuthInterceptor.java
  38. 2 17
      themis-admin/src/main/java/com/qmth/themis/admin/interceptor/AuthThirdInterceptor.java
  39. 1 1
      themis-admin/src/main/java/com/qmth/themis/admin/listener/service/MqAdminLogicService.java
  40. 2 2
      themis-admin/src/main/java/com/qmth/themis/admin/listener/service/impl/MqAdminLogicServiceImpl.java
  41. 1 1
      themis-admin/src/main/java/com/qmth/themis/admin/mongodb/entity/MTEExamActivityEntity.java
  42. 1 1
      themis-admin/src/main/java/com/qmth/themis/admin/mongodb/entity/MTEExamCourseEntity.java
  43. 1 1
      themis-admin/src/main/java/com/qmth/themis/admin/mongodb/entity/MTEExamEntity.java
  44. 1 1
      themis-admin/src/main/java/com/qmth/themis/admin/mongodb/entity/MTEExamPaperEntity.java
  45. 1 1
      themis-admin/src/main/java/com/qmth/themis/admin/mongodb/entity/MTEExamStudentEntity.java
  46. 1 1
      themis-admin/src/main/java/com/qmth/themis/admin/mongodb/entity/MTEStudentEntity.java
  47. 2 2
      themis-admin/src/main/java/com/qmth/themis/admin/mongodb/repository/MTEExamActivityRepo.java
  48. 2 2
      themis-admin/src/main/java/com/qmth/themis/admin/mongodb/repository/MTEExamCourseRepo.java
  49. 3 3
      themis-admin/src/main/java/com/qmth/themis/admin/mongodb/repository/MTEExamPaperRepo.java
  50. 2 2
      themis-admin/src/main/java/com/qmth/themis/admin/mongodb/repository/MTEExamRepo.java
  51. 3 3
      themis-admin/src/main/java/com/qmth/themis/admin/mongodb/repository/MTEExamStudentRepo.java
  52. 2 2
      themis-admin/src/main/java/com/qmth/themis/admin/mongodb/repository/MTEStudentRepo.java
  53. 1 1
      themis-admin/src/main/java/com/qmth/themis/admin/mongodb/service/MTEExamActivityService.java
  54. 1 1
      themis-admin/src/main/java/com/qmth/themis/admin/mongodb/service/MTEExamCourseService.java
  55. 1 1
      themis-admin/src/main/java/com/qmth/themis/admin/mongodb/service/MTEExamPaperService.java
  56. 1 1
      themis-admin/src/main/java/com/qmth/themis/admin/mongodb/service/MTEExamService.java
  57. 1 1
      themis-admin/src/main/java/com/qmth/themis/admin/mongodb/service/MTEExamStudentService.java
  58. 1 1
      themis-admin/src/main/java/com/qmth/themis/admin/mongodb/service/MTEStudentService.java
  59. 3 3
      themis-admin/src/main/java/com/qmth/themis/admin/mongodb/service/impl/MTEExamActivityServiceImpl.java
  60. 3 3
      themis-admin/src/main/java/com/qmth/themis/admin/mongodb/service/impl/MTEExamCourseServiceImpl.java
  61. 3 3
      themis-admin/src/main/java/com/qmth/themis/admin/mongodb/service/impl/MTEExamPaperServiceImpl.java
  62. 3 3
      themis-admin/src/main/java/com/qmth/themis/admin/mongodb/service/impl/MTEExamServiceImpl.java
  63. 5 5
      themis-admin/src/main/java/com/qmth/themis/admin/mongodb/service/impl/MTEExamStudentServiceImpl.java
  64. 3 3
      themis-admin/src/main/java/com/qmth/themis/admin/mongodb/service/impl/MTEStudentServiceImpl.java
  65. 32 0
      themis-admin/src/main/java/com/qmth/themis/admin/start/StartRunning.java
  66. 49 81
      themis-admin/src/main/java/com/qmth/themis/admin/websocket/WebSocketAdminServer.java
  67. 7 10
      themis-admin/src/main/java/com/qmth/themis/admin/websocketTemplete/WebSocketAdminMessageTemplete.java
  68. 33 10
      themis-admin/src/main/resources/application.properties
  69. 13 15
      themis-admin/src/main/resources/logback-spring.xml
  70. 2 2
      themis-admin/src/test/java/com/qmth/themis/admin/ThemisAdminApplicationTests.java
  71. 0 140
      themis-backend/src/main/java/com/qmth/themis/backend/api/TEExamActivityController.java
  72. 0 145
      themis-backend/src/main/java/com/qmth/themis/backend/interceptor/AuthInterceptor.java
  73. 0 88
      themis-backend/src/main/java/com/qmth/themis/backend/start/StartRunning.java
  74. 4 4
      themis-business/pom.xml
  75. 0 17
      themis-business/src/main/java/com/qmth/themis/business/annotation/ExcelNotNull.java
  76. 1 1
      themis-business/src/main/java/com/qmth/themis/business/bean/admin/ExamBreachDetailListBean.java
  77. 1 1
      themis-business/src/main/java/com/qmth/themis/business/bean/admin/ExamBreachListBean.java
  78. 1 1
      themis-business/src/main/java/com/qmth/themis/business/bean/admin/ExamDeficiencyListBean.java
  79. 1 1
      themis-business/src/main/java/com/qmth/themis/business/bean/admin/ExamExceptionDetailListBean.java
  80. 1 1
      themis-business/src/main/java/com/qmth/themis/business/bean/admin/ExamExceptionListBean.java
  81. 1 1
      themis-business/src/main/java/com/qmth/themis/business/bean/admin/ExamReexamListBean.java
  82. 1 1
      themis-business/src/main/java/com/qmth/themis/business/bean/admin/ExamStudentLogDetailListBean.java
  83. 1 1
      themis-business/src/main/java/com/qmth/themis/business/bean/admin/ExamStudentLogListBean.java
  84. 1 1
      themis-business/src/main/java/com/qmth/themis/business/bean/admin/ExamViewCountListBean.java
  85. 1 1
      themis-business/src/main/java/com/qmth/themis/business/bean/admin/ExaminationMonitorCountBean.java
  86. 1 1
      themis-business/src/main/java/com/qmth/themis/business/bean/admin/ExaminationMonitorHourWarnCountBean.java
  87. 1 1
      themis-business/src/main/java/com/qmth/themis/business/bean/admin/ExaminationMonitorWarnDistributionBean.java
  88. 1 1
      themis-business/src/main/java/com/qmth/themis/business/bean/admin/ExaminationMonitorWarnMsgBean.java
  89. 1 3
      themis-business/src/main/java/com/qmth/themis/business/bean/admin/InvigilateListBean.java
  90. 1 1
      themis-business/src/main/java/com/qmth/themis/business/bean/admin/InvigilateListDetailBean.java
  91. 1 2
      themis-business/src/main/java/com/qmth/themis/business/bean/admin/InvigilateListHistoryBean.java
  92. 1 2
      themis-business/src/main/java/com/qmth/themis/business/bean/admin/InvigilateListPatrolBean.java
  93. 1 3
      themis-business/src/main/java/com/qmth/themis/business/bean/admin/InvigilateListPatrolReportBean.java
  94. 1 1
      themis-business/src/main/java/com/qmth/themis/business/bean/admin/InvigilateListProgressBean.java
  95. 1 1
      themis-business/src/main/java/com/qmth/themis/business/bean/admin/InvigilateListProgressExcelBean.java
  96. 12 1
      themis-business/src/main/java/com/qmth/themis/business/bean/admin/InvigilateListVideoBean.java
  97. 1 2
      themis-business/src/main/java/com/qmth/themis/business/bean/admin/InvigilateListWarningBean.java
  98. 1 1
      themis-business/src/main/java/com/qmth/themis/business/bean/admin/OpenExamBean.java
  99. 1 1
      themis-business/src/main/java/com/qmth/themis/business/bean/admin/OpenExamCourseBean.java
  100. 64 0
      themis-business/src/main/java/com/qmth/themis/business/bean/admin/OpenRecordAnswerBean.java

+ 1 - 1
README.md

@@ -1,7 +1,7 @@
 在线考试平台
 
 项目模块:
-1.backend
+1.admin
 2.business
 3.exam
 4.common

+ 8 - 8
pom.xml

@@ -9,7 +9,7 @@
 
     <modules>
         <module>themis-common</module>
-        <module>themis-backend</module>
+        <module>themis-admin</module>
         <module>themis-business</module>
         <module>themis-exam</module>
         <module>themis-mq</module>
@@ -44,8 +44,8 @@
         <commons.version>3.10</commons.version>
         <commons.codec.version>1.15</commons.codec.version>
         <jackson.version>2.11.0</jackson.version>
-        <!--        <ehcache.version>2.10.6</ehcache.version>-->
-<!--        <swagger2-bootstrap.version>1.9.6</swagger2-bootstrap.version>-->
+<!--        <ehcache.version>2.10.6</ehcache.version>-->
+        <swagger2-bootstrap.version>1.9.6</swagger2-bootstrap.version>
         <jetbrains.version>13.0</jetbrains.version>
         <tencentyun.version>1.1</tencentyun.version>
     </properties>
@@ -99,11 +99,11 @@
                 <artifactId>springfox-swagger2</artifactId>
                 <version>${swagger2.version}</version>
             </dependency>
-<!--            <dependency>-->
-<!--                <groupId>com.github.xiaoymin</groupId>-->
-<!--                <artifactId>swagger-bootstrap-ui</artifactId>-->
-<!--                <version>${swagger2-bootstrap.version}</version>-->
-<!--            </dependency>-->
+            <dependency>
+                <groupId>com.github.xiaoymin</groupId>
+                <artifactId>swagger-bootstrap-ui</artifactId>
+                <version>${swagger2-bootstrap.version}</version>
+            </dependency>
             <dependency>
                 <groupId>com.alibaba</groupId>
                 <artifactId>druid</artifactId>

+ 0 - 0
themis-backend/Dockerfile → themis-admin/Dockerfile


+ 1 - 1
themis-backend/README.md → themis-admin/README.md

@@ -1,7 +1,7 @@
 在线考试平台-后台管理
 
 项目模块:
-backend
+admin
 
 项目框架:
 java8,spring boot2.3.0,rocketmq

+ 2 - 2
themis-backend/pom.xml → themis-admin/pom.xml

@@ -2,8 +2,8 @@
 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
     <modelVersion>4.0.0</modelVersion>
-    <groupId>com.qmth.themis.backend</groupId>
-    <artifactId>themis-backend</artifactId>
+    <groupId>com.qmth.themis.admin</groupId>
+    <artifactId>themis-admin</artifactId>
     <version>1.0.0</version>
     <packaging>jar</packaging>
 

+ 4 - 4
themis-backend/src/main/java/com/qmth/themis/backend/ThemisBackendApplication.java → themis-admin/src/main/java/com/qmth/themis/admin/ThemisAdminApplication.java

@@ -1,4 +1,4 @@
-package com.qmth.themis.backend;
+package com.qmth.themis.admin;
 
 import org.mybatis.spring.annotation.MapperScan;
 import org.springframework.boot.SpringApplication;
@@ -21,10 +21,10 @@ import org.springframework.transaction.annotation.EnableTransactionManagement;
 @EnableAsync // 开启异步任务
 @EnableCaching // 开启缓存注解
 @EnableScheduling//开启定时任务
-//@EnableMongoRepositories("com.qmth.themis.backend.mongodb.repository")
-public class ThemisBackendApplication {
+//@EnableMongoRepositories("com.qmth.themis.admin.mongodb.repository")
+public class ThemisAdminApplication {
 
     public static void main(String[] args) {
-        SpringApplication.run(ThemisBackendApplication.class, args);
+        SpringApplication.run(ThemisAdminApplication.class, args);
     }
 }

+ 13 - 34
themis-backend/src/main/java/com/qmth/themis/backend/api/SysController.java → themis-admin/src/main/java/com/qmth/themis/admin/api/SysController.java

@@ -1,10 +1,10 @@
-package com.qmth.themis.backend.api;
+package com.qmth.themis.admin.api;
 
 import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.google.common.reflect.TypeToken;
 import com.google.gson.Gson;
-import com.qmth.themis.backend.config.DictionaryConfig;
+import com.qmth.themis.admin.config.DictionaryConfig;
 import com.qmth.themis.business.constant.SystemConstant;
 import com.qmth.themis.business.dto.AuthDto;
 import com.qmth.themis.business.dto.response.RoomCodeQueryDto;
@@ -16,13 +16,13 @@ import com.qmth.themis.business.enums.RoleEnum;
 import com.qmth.themis.business.enums.UploadFileEnum;
 import com.qmth.themis.business.service.*;
 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.common.enums.ExceptionResultEnum;
 import com.qmth.themis.common.exception.BusinessException;
 import com.qmth.themis.common.util.Result;
 import com.qmth.themis.common.util.ResultUtil;
 import io.swagger.annotations.*;
+import org.springframework.cache.annotation.Cacheable;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RequestMethod;
@@ -83,7 +83,7 @@ public class SysController {
     TEExamStudentService teExamStudentService;
 
     @Resource
-    RedisUtil redisUtil;
+    CacheService cacheService;
 
     @ApiOperation(value = "菜单查询接口")
     @RequestMapping(value = "/getMenu", method = RequestMethod.POST)
@@ -103,11 +103,7 @@ public class SysController {
         if (Objects.isNull(orgId) || Objects.equals(orgId, "")) {
             throw new BusinessException(ExceptionResultEnum.ORG_ID_IS_NULL);
         }
-        //        SchoolDto schoolDto = (SchoolDto) redisTemplate.opsForValue().get(SystemConstant.SCHOOL_CACHE + orgId);
-        //        Map map = new HashMap();
-        //        map.put(SystemConstant.ENV_FILEHOST, schoolDto.getFileHost());
-        //        return ResultUtil.ok(map);
-        return ResultUtil.ok(Collections.singletonMap(SystemConstant.SUCCESS, true));
+        return ResultUtil.ok(true);
     }
 
     @ApiOperation(value = "上传文件接口")
@@ -144,7 +140,7 @@ public class SysController {
         } else {
             if (Objects.nonNull(mapParameter.get(SystemConstant.UPLOAD_TYPE))) {
                 Integer fileId = UploadFileEnum.convertToId((String) mapParameter.get(SystemConstant.UPLOAD_TYPE));
-                if (fileId == 3) {
+                if (fileId.intValue() == 3) {
                     url = dictionaryConfig.aliYunOssDomain().getPrivateUrl() + File.separator + filePath;
                 } else {
                     url = dictionaryConfig.aliYunOssDomain().getPublicUrl() + File.separator + filePath;
@@ -216,15 +212,7 @@ public class SysController {
             throw new BusinessException(ExceptionResultEnum.ORG_CODE_IS_NULL);
         }
         if (!Objects.equals(code.toUpperCase(), SystemConstant.ADMIN)) {
-            TBOrg tbOrg = (TBOrg) redisUtil.getOrgCode(code);
-            if (Objects.isNull(tbOrg)) {
-                QueryWrapper<TBOrg> tbOrgQueryWrapper = new QueryWrapper<>();
-                tbOrgQueryWrapper.lambda().eq(TBOrg::getCode, code);
-                tbOrg = tbOrgService.getOne(tbOrgQueryWrapper);
-                if (Objects.nonNull(tbOrg)) {
-                    redisUtil.setOrgCode(code, tbOrg);
-                }
-            }
+            TBOrg tbOrg = cacheService.addOrgCodeCache(code);
             if (Objects.isNull(tbOrg)) {
                 throw new BusinessException(ExceptionResultEnum.ORG_NO);
             }
@@ -260,20 +248,11 @@ public class SysController {
     @ApiOperation(value = "角色查询接口")
     @RequestMapping(value = "/role/query", method = RequestMethod.POST)
     @ApiResponses({@ApiResponse(code = 200, message = "角色信息", response = TBRole.class)})
+    @Cacheable(value = SystemConstant.roleCache, key = "methodName")
     public Result roleList() {
-        List<TBRole> tbRoleList = (List<TBRole>) redisUtil.getRole();
-        if (Objects.nonNull(tbRoleList) && tbRoleList.size() > 0) {
-            tbRoleList = (List<TBRole>) tbRoleList.get(0);
-        } else {
-            QueryWrapper<TBRole> tbRoleQueryWrapper = new QueryWrapper<>();
-            tbRoleQueryWrapper.lambda()
-                    .notIn(TBRole::getRoleCode, RoleEnum.SUPER_ADMIN.name(), RoleEnum.STUDENT.name());
-            tbRoleList = tbRoleService.list(tbRoleQueryWrapper);
-            if (Objects.nonNull(tbRoleList)) {
-                redisUtil.setRole(tbRoleList);
-            }
-        }
-        return ResultUtil.ok(tbRoleList);
+        QueryWrapper<TBRole> tbRoleQueryWrapper = new QueryWrapper<>();
+        tbRoleQueryWrapper.lambda().notIn(TBRole::getRoleCode, RoleEnum.SUPER_ADMIN.name(), RoleEnum.STUDENT.name());
+        return ResultUtil.ok(tbRoleService.list(tbRoleQueryWrapper));
     }
 
     @ApiOperation(value = "考试场次查询接口")
@@ -290,7 +269,7 @@ public class SysController {
                             @ApiParam(value = "批次名称", required = false) @RequestParam(required = false) String name,
                             @ApiParam(value = "类型(区分实时监考台和考务)", required = false) @RequestParam(required = false) String type) {
         TBUser tbUser = (TBUser) ServletUtil.getRequestAccount();
-        AuthDto authDto = (AuthDto) redisUtil.get(SystemConstant.userOauth + "::" + tbUser.getId());
+        AuthDto authDto = cacheService.addAccountAuthCache(tbUser.getId());
         List<TEExam> teExamList = null;
         if (authDto.getRoleCodes().toString().contains(RoleEnum.ADMIN.name()) || authDto.getRoleCodes().toString()
                 .contains(RoleEnum.SUPER_ADMIN.name())) {//管理员
@@ -350,7 +329,7 @@ public class SysController {
         }
         //首先查询当前用户所要监控的roomCode
         QueryWrapper<TBExamInvigilateUser> examInvigilateUserQueryWrapper = new QueryWrapper<>();
-        AuthDto authDto = (AuthDto) redisUtil.get(SystemConstant.userOauth + "::" + tbUser.getId());
+        AuthDto authDto = cacheService.addAccountAuthCache(tbUser.getId());
         examInvigilateUserQueryWrapper.lambda().eq(TBExamInvigilateUser::getOrgId, tbUser.getOrgId())
                 .eq(TBExamInvigilateUser::getExamId, examId);
         if (authDto.getRoleCodes().toString().contains(RoleEnum.INVIGILATE.name())) {

+ 48 - 0
themis-admin/src/main/java/com/qmth/themis/admin/api/TBAppVersionController.java

@@ -0,0 +1,48 @@
+package com.qmth.themis.admin.api;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.qmth.themis.business.constant.SystemConstant;
+import com.qmth.themis.business.entity.TBAppVersion;
+import com.qmth.themis.business.service.TBAppVersionService;
+import com.qmth.themis.common.util.Result;
+import com.qmth.themis.common.util.ResultUtil;
+import io.swagger.annotations.*;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.web.bind.annotation.*;
+
+import javax.annotation.Resource;
+import java.util.Collections;
+
+/**
+ * @Description: 移动端 前端控制器
+ * @Param:
+ * @return:
+ * @Author: wangliang
+ * @Date: 2020/11/20
+ */
+@Api(tags = "移动端Controller")
+@RestController
+@RequestMapping("/${prefix.url.admin}/app")
+public class TBAppVersionController {
+    private final static Logger log = LoggerFactory.getLogger(TBAppVersionController.class);
+
+    @Resource
+    TBAppVersionService tbAppVersionService;
+
+    @ApiOperation(value = "移动端版本新增/编辑接口")
+    @RequestMapping(value = "/save", method = RequestMethod.POST)
+    @ApiResponses({@ApiResponse(code = 200, message = "{\"success\":true}", response = Result.class)})
+    public Result save(@ApiParam(value = "移动端版本信息", required = true) @RequestBody TBAppVersion tbAppVersion) {
+        tbAppVersionService.saveOrUpdate(tbAppVersion);
+        return ResultUtil.ok( true);
+    }
+
+    @ApiOperation(value = "移动端版本查询接口")
+    @RequestMapping(value = "/query", method = RequestMethod.POST)
+    @ApiResponses({@ApiResponse(code = 200, message = "移动端信息", response = TBAppVersion.class)})
+    public Result query(@ApiParam(value = "分页页码", required = true) @RequestParam int pageNumber,
+                        @ApiParam(value = "分页数", required = true) @RequestParam int pageSize) {
+        return ResultUtil.ok(tbAppVersionService.appVersionQuery(new Page<>(pageNumber, pageSize)));
+    }
+}

+ 100 - 0
themis-admin/src/main/java/com/qmth/themis/admin/api/TBClientVersionController.java

@@ -0,0 +1,100 @@
+package com.qmth.themis.admin.api;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.qmth.themis.business.constant.SystemConstant;
+import com.qmth.themis.business.entity.TBAttachment;
+import com.qmth.themis.business.entity.TBClientVersion;
+import com.qmth.themis.business.entity.TBUser;
+import com.qmth.themis.business.enums.UploadFileEnum;
+import com.qmth.themis.business.service.TBAttachmentService;
+import com.qmth.themis.business.service.TBClientVersionService;
+import com.qmth.themis.business.util.OssUtil;
+import com.qmth.themis.business.util.ServletUtil;
+import com.qmth.themis.common.enums.ExceptionResultEnum;
+import com.qmth.themis.common.exception.BusinessException;
+import com.qmth.themis.common.util.Result;
+import com.qmth.themis.common.util.ResultUtil;
+import io.swagger.annotations.*;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
+
+import javax.annotation.Resource;
+import java.util.Collections;
+import java.util.Map;
+import java.util.Objects;
+
+/**
+ * @Description: 客户端 前端控制器
+ * @Param:
+ * @return:
+ * @Author: wangliang
+ * @Date: 2020/11/20
+ */
+@Api(tags = "客户端Controller")
+@RestController
+@RequestMapping("/${prefix.url.admin}/client")
+public class TBClientVersionController {
+    private final static Logger log = LoggerFactory.getLogger(TBClientVersionController.class);
+
+    @Resource
+    TBClientVersionService tbClientVersionService;
+
+    @Resource
+    OssUtil ossUtil;
+
+    @Resource
+    TBAttachmentService tbAttachmentService;
+
+    @ApiOperation(value = "客户端上传附件接口")
+    @RequestMapping(value = "/upload", method = RequestMethod.POST)
+    @ApiResponses({@ApiResponse(code = 200, message = "{\"success\":true}", response = Result.class)})
+    @Transactional
+    public Result upload(@ApiParam(value = "上传文件", required = true) @RequestParam MultipartFile file,
+                         @ApiParam(value = "版本号", required = true) @RequestParam String version) {
+        if (Objects.isNull(file) || Objects.equals(file, "")) {
+            throw new BusinessException(ExceptionResultEnum.ATTACHMENT_IS_NULL);
+        }
+        if (Objects.isNull(version) || Objects.equals(version, "")) {
+            throw new BusinessException(ExceptionResultEnum.VERSION_IS_NULL);
+        }
+        Map<String, Object> mapParameter = ossUtil.getAliYunOssPublicDomain().getMap();
+        TBAttachment tbAttachment = null;
+        try {
+            TBUser tbUser = (TBUser) ServletUtil.getRequestAccount();
+            mapParameter.put(SystemConstant.VERSION, version);
+            tbAttachment = tbAttachmentService
+                    .saveAttachment(file, ServletUtil.getRequestMd5(), ServletUtil.getRequestPath(), mapParameter,
+                            UploadFileEnum.client, tbUser.getOrgId(), tbUser.getId());
+        } catch (Exception e) {
+            log.error("请求出错", e);
+            if (Objects.nonNull(tbAttachment)) {
+                tbAttachmentService.deleteAttachment(mapParameter, UploadFileEnum.client, tbAttachment);
+            }
+            if (e instanceof BusinessException) {
+                throw new BusinessException(e.getMessage());
+            } else {
+                throw new RuntimeException(e);
+            }
+        }
+        return ResultUtil.ok(true);
+    }
+
+    @ApiOperation(value = "客户端版本新增/编辑接口")
+    @RequestMapping(value = "/save", method = RequestMethod.POST)
+    @ApiResponses({@ApiResponse(code = 200, message = "{\"success\":true}", response = Result.class)})
+    public Result save(@ApiParam(value = "客户端版本信息", required = true) @RequestBody TBClientVersion tbClientVersion) {
+        tbClientVersionService.saveOrUpdate(tbClientVersion);
+        return ResultUtil.ok(true);
+    }
+
+    @ApiOperation(value = "客户端版本查询接口")
+    @RequestMapping(value = "/query", method = RequestMethod.POST)
+    @ApiResponses({@ApiResponse(code = 200, message = "客户端信息", response = TBClientVersion.class)})
+    public Result query(@ApiParam(value = "分页页码", required = true) @RequestParam int pageNumber,
+                        @ApiParam(value = "分页数", required = true) @RequestParam int pageSize) {
+        return ResultUtil.ok(tbClientVersionService.clientVersionQuery(new Page<>(pageNumber, pageSize)));
+    }
+}

+ 40 - 32
themis-backend/src/main/java/com/qmth/themis/backend/api/TBExamInvigilateUserController.java → themis-admin/src/main/java/com/qmth/themis/admin/api/TBExamInvigilateUserController.java

@@ -1,4 +1,4 @@
-package com.qmth.themis.backend.api;
+package com.qmth.themis.admin.api;
 
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
@@ -13,6 +13,7 @@ import com.qmth.themis.business.service.MqDtoService;
 import com.qmth.themis.business.service.TBAttachmentService;
 import com.qmth.themis.business.service.TBExamInvigilateUserService;
 import com.qmth.themis.business.service.TBTaskHistoryService;
+import com.qmth.themis.business.util.MqUtil;
 import com.qmth.themis.business.util.OssUtil;
 import com.qmth.themis.business.util.ServletUtil;
 import com.qmth.themis.common.enums.ExceptionResultEnum;
@@ -60,14 +61,17 @@ public class TBExamInvigilateUserController {
     @Resource
     OssUtil ossUtil;
 
+    @Resource
+    MqUtil mqUtil;
+
     @ApiOperation(value = "监考员查询接口")
     @RequestMapping(value = "/query", method = RequestMethod.POST)
-    @ApiResponses({ @ApiResponse(code = 200, message = "监考员信息", response = TBExamInvigilateUserDto.class) })
+    @ApiResponses({@ApiResponse(code = 200, message = "监考员信息", response = TBExamInvigilateUserDto.class)})
     public Result query(@ApiParam(value = "考试批次id", required = true) @RequestParam(required = false) Long examId,
-            @ApiParam(value = "考场代码", required = false) @RequestParam(required = false) String roomCode,
-            @ApiParam(value = "用户id", required = false) @RequestParam(required = false) Long userId,
-            @ApiParam(value = "分页页码", required = true) @RequestParam int pageNumber,
-            @ApiParam(value = "分页数", required = true) @RequestParam int pageSize) {
+                        @ApiParam(value = "考场代码", required = false) @RequestParam(required = false) String roomCode,
+                        @ApiParam(value = "用户id", required = false) @RequestParam(required = false) Long userId,
+                        @ApiParam(value = "分页页码", required = true) @RequestParam int pageNumber,
+                        @ApiParam(value = "分页数", required = true) @RequestParam int pageSize) {
         TBUser tbUser = (TBUser) ServletUtil.getRequestAccount();
         return ResultUtil.ok(tbExamInvigilateUserService
                 .examInvigilateUserQuery(new Page<>(pageNumber, pageSize), examId, roomCode, userId,
@@ -77,11 +81,11 @@ public class TBExamInvigilateUserController {
     @ApiOperation(value = "监考员修改接口")
     @RequestMapping(value = "/save", method = RequestMethod.POST)
     @Transactional
-    @ApiResponses({ @ApiResponse(code = 200, message = "{\"success\":true}", response = Result.class) })
+    @ApiResponses({@ApiResponse(code = 200, message = "{\"success\":true}", response = Result.class)})
     public Result save(@ApiJsonObject(name = "saveInvigilateUser", value = {
             @ApiJsonProperty(key = "examId", type = "long", example = "1", description = "考试批次id", required = true),
             @ApiJsonProperty(key = "roomCode", description = "考场代码"),
-            @ApiJsonProperty(key = "userIds", description = "用户id") }) @ApiParam(value = "监考员信息", required = true) @RequestBody Map<String, Object> mapParameter) {
+            @ApiJsonProperty(key = "userIds", description = "用户id")}) @ApiParam(value = "监考员信息", required = true) @RequestBody Map<String, Object> mapParameter) {
         String roomCode = null;
         try {
             if (Objects.isNull(mapParameter.get("examId")) || Objects.equals(mapParameter.get("examId"), "")) {
@@ -100,28 +104,32 @@ public class TBExamInvigilateUserController {
                 throw new BusinessException(ExceptionResultEnum.ERROR.getStatusCode(),
                         ExceptionResultEnum.ERROR.getCode(), "一个考场最多设置3名监考员");
             }
+            TBOrg tbOrg = (TBOrg) ServletUtil.getRequestOrg();
+            QueryWrapper<TBExamInvigilateUser> tbExamInvigilateUserQueryWrapper = new QueryWrapper<>();
+            tbExamInvigilateUserQueryWrapper.lambda().eq(TBExamInvigilateUser::getRoomCode, roomCode)
+                    .eq(TBExamInvigilateUser::getExamId, examId);
+            if (Objects.nonNull(tbOrg) && Objects.isNull(tbOrg.getId())) {
+                throw new BusinessException("监考员机构id不允许为空");
+            }
+            List<TBExamInvigilateUser> tbExamInvigilateUserList = tbExamInvigilateUserService
+                    .list(tbExamInvigilateUserQueryWrapper);
+            List<String> roomNameList = tbExamInvigilateUserList.stream().map(s -> s.getRoomName())
+                    .collect(Collectors.toList());
+            Long orgId = tbOrg.getId();
+            tbExamInvigilateUserService.remove(tbExamInvigilateUserQueryWrapper);
+            tbExamInvigilateUserList = new ArrayList<>();
             if (userIds.size() > 0) {
-                TBOrg tbOrg = (TBOrg) ServletUtil.getRequestOrg();
-                QueryWrapper<TBExamInvigilateUser> tbExamInvigilateUserQueryWrapper = new QueryWrapper<>();
-                tbExamInvigilateUserQueryWrapper.lambda().eq(TBExamInvigilateUser::getRoomCode, roomCode)
-                        .eq(TBExamInvigilateUser::getExamId, examId);
-                if (Objects.nonNull(tbOrg) && Objects.isNull(tbOrg.getId())) {
-                    throw new BusinessException("监考员机构id不允许为空");
-                }
-                List<TBExamInvigilateUser> tbExamInvigilateUserList = tbExamInvigilateUserService
-                        .list(tbExamInvigilateUserQueryWrapper);
-                Long orgId = tbOrg.getId();
-                List<String> roomNameList = tbExamInvigilateUserList.stream().map(s -> s.getRoomName())
-                        .collect(Collectors.toList());
-                tbExamInvigilateUserService.remove(tbExamInvigilateUserQueryWrapper);
-                tbExamInvigilateUserList = new ArrayList<>();
                 for (int i = 0; i < userIds.size(); i++) {
                     TBExamInvigilateUser tbExamInvigilateUser = new TBExamInvigilateUser(examId, orgId,
                             Long.parseLong(userIds.get(i)), roomCode, roomNameList.get(0));
                     tbExamInvigilateUserList.add(tbExamInvigilateUser);
                 }
-                tbExamInvigilateUserService.saveBatch(tbExamInvigilateUserList);
+            } else {
+                TBExamInvigilateUser tbExamInvigilateUser = new TBExamInvigilateUser(examId, orgId,
+                        null, roomCode, roomNameList.get(0));
+                tbExamInvigilateUserList.add(tbExamInvigilateUser);
             }
+            tbExamInvigilateUserService.saveBatch(tbExamInvigilateUserList);
         } catch (Exception e) {
             log.error("请求出错", e);
             if (e instanceof DuplicateKeyException) {
@@ -136,15 +144,15 @@ public class TBExamInvigilateUserController {
                 throw new RuntimeException(e);
             }
         }
-        return ResultUtil.ok(Collections.singletonMap(SystemConstant.SUCCESS, true));
+        return ResultUtil.ok(true);
     }
 
     @ApiOperation(value = "监考员导入接口")
     @RequestMapping(value = "/import", method = RequestMethod.POST)
     @Transactional
-    @ApiResponses({ @ApiResponse(code = 200, message = "{\"taskId\":0}", response = Result.class) })
+    @ApiResponses({@ApiResponse(code = 200, message = "{\"taskId\":0}", response = Result.class)})
     public Result importData(@ApiParam(value = "上传文件", required = true) @RequestParam MultipartFile file,
-            @ApiParam(value = "考试批次id", required = true) @RequestParam Long examId) {
+                             @ApiParam(value = "考试批次id", required = true) @RequestParam Long examId) {
         if (Objects.isNull(file) || Objects.equals(file, "")) {
             throw new BusinessException(ExceptionResultEnum.ATTACHMENT_IS_NULL);
         }
@@ -176,7 +184,7 @@ public class TBExamInvigilateUserController {
             transMap.put("orgId", tbUser.getOrgId());
             transMap.put("remark", tbAttachment.getRemark());
             //mq发送消息start
-            MqDto mqDto = new MqDto(MqTopicEnum.THEMIS_TOPIC.getCode(), MqTagEnum.ROOM_CODE_IMPORT.name(), transMap,
+            MqDto mqDto = new MqDto(mqUtil.getMqGroupDomain().getTopic(), MqTagEnum.ROOM_CODE_IMPORT.name(), transMap,
                     MqTagEnum.ROOM_CODE_IMPORT, String.valueOf(tbTaskHistory.getId()), tbUser.getName());
             mqDtoService.assembleSendOneWayMsg(mqDto);
             //mq发送消息end
@@ -197,10 +205,10 @@ public class TBExamInvigilateUserController {
     @ApiOperation(value = "监考员导出接口")
     @RequestMapping(value = "/export", method = RequestMethod.POST)
     @Transactional
-    @ApiResponses({ @ApiResponse(code = 200, message = "{\"taskId\":0}", response = Result.class) })
+    @ApiResponses({@ApiResponse(code = 200, message = "{\"taskId\":0}", response = Result.class)})
     public Result export(@ApiParam(value = "考试批次id", required = true) @RequestParam(required = false) Long examId,
-            @ApiParam(value = "考场代码", required = false) @RequestParam(required = false) String roomCode,
-            @ApiParam(value = "用户id", required = false) @RequestParam(required = false) Long userId) {
+                         @ApiParam(value = "考场代码", required = false) @RequestParam(required = false) String roomCode,
+                         @ApiParam(value = "用户id", required = false) @RequestParam(required = false) Long userId) {
         TBTaskHistory tbTaskHistory = null;
         try {
             int count = tbExamInvigilateUserService.count();
@@ -219,12 +227,12 @@ public class TBExamInvigilateUserController {
                 transMap.put("roomCode", roomCode);
                 transMap.put("userId", userId);
                 //mq发送消息start
-                MqDto mqDto = new MqDto(MqTopicEnum.THEMIS_TOPIC.getCode(), MqTagEnum.ROOM_CODE_EXPORT.name(), transMap,
+                MqDto mqDto = new MqDto(mqUtil.getMqGroupDomain().getTopic(), MqTagEnum.ROOM_CODE_EXPORT.name(), transMap,
                         MqTagEnum.ROOM_CODE_EXPORT, String.valueOf(tbTaskHistory.getId()), tbUser.getName());
                 mqDtoService.assembleSendOneWayMsg(mqDto);
                 //mq发送消息end
             } else {
-                return ResultUtil.ok(Collections.singletonMap(SystemConstant.SUCCESS, true));
+                return ResultUtil.ok(true);
             }
         } catch (Exception e) {
             log.error("请求出错", e);

+ 15 - 19
themis-backend/src/main/java/com/qmth/themis/backend/api/TBOrgController.java → themis-admin/src/main/java/com/qmth/themis/admin/api/TBOrgController.java

@@ -1,4 +1,4 @@
-package com.qmth.themis.backend.api;
+package com.qmth.themis.admin.api;
 
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.qmth.themis.business.annotation.ApiJsonObject;
@@ -8,8 +8,8 @@ import com.qmth.themis.business.dto.response.TBOrgDto;
 import com.qmth.themis.business.entity.TBOrg;
 import com.qmth.themis.business.entity.TBUser;
 import com.qmth.themis.business.enums.FieldUniqueEnum;
+import com.qmth.themis.business.service.CacheService;
 import com.qmth.themis.business.service.TBOrgService;
-import com.qmth.themis.business.util.RedisUtil;
 import com.qmth.themis.business.util.ServletUtil;
 import com.qmth.themis.business.util.UidUtil;
 import com.qmth.themis.common.enums.ExceptionResultEnum;
@@ -24,7 +24,6 @@ import org.springframework.transaction.annotation.Transactional;
 import org.springframework.web.bind.annotation.*;
 
 import javax.annotation.Resource;
-import java.util.Collections;
 import java.util.Map;
 import java.util.Objects;
 
@@ -46,13 +45,11 @@ public class TBOrgController {
     TBOrgService tbOrgService;
 
     @Resource
-    RedisUtil redisUtil;
+    UidUtil uidUtil;
 
     @Resource
-    UidUtil uidUtil;
+    CacheService cacheService;
 
-    //    @CachePut(value = "org_cache", key = "'orgCacheQuery'")
-    //    @Cacheable(value = "org_cache", key = "#p0")
     @ApiOperation(value = "机构查询分页接口")
     @RequestMapping(value = "/query", method = RequestMethod.POST)
     @ApiResponses({@ApiResponse(code = 200, message = "机构信息", response = TBOrgDto.class)})
@@ -64,7 +61,6 @@ public class TBOrgController {
         return ResultUtil.ok(tbOrgService.queryByPage(new Page<>(pageNumber, pageSize), code, name, enable));
     }
 
-    //    @CacheEvict(value = "org_cache", key = "'orgCacheQuery'")
     @ApiOperation(value = "机构新增/编辑接口")
     @RequestMapping(value = "/save", method = RequestMethod.POST)
     @Transactional
@@ -76,6 +72,9 @@ public class TBOrgController {
         if (Objects.isNull(tbOrg.getCode()) || Objects.equals(tbOrg.getCode(), "")) {
             throw new BusinessException(ExceptionResultEnum.ORG_CODE_IS_NULL);
         }
+        if (Objects.isNull(tbOrg.getName()) || Objects.equals(tbOrg.getName(), "")) {
+            throw new BusinessException(ExceptionResultEnum.ORG_NAME_IS_NULL);
+        }
         if (Objects.nonNull(tbOrg.getCode()) && Objects.equals(tbOrg.getCode().toUpperCase(), SystemConstant.ADMIN)) {
             throw new BusinessException("admin为超级管理员专属编码,请重新输入");
         }
@@ -88,8 +87,8 @@ public class TBOrgController {
                 tbOrg.setUpdateId(tbUser.getId());
             }
             tbOrgService.saveOrUpdate(tbOrg);
-            redisUtil.setOrg(tbOrg.getId(), tbOrg);
-            redisUtil.setOrgCode(tbOrg.getCode(), tbOrg);
+            cacheService.addOrgCache(tbOrg.getId());
+            cacheService.addOrgCodeCache(tbOrg.getCode());
         } catch (Exception e) {
             log.error("请求出错", e);
             if (e instanceof DuplicateKeyException) {
@@ -103,7 +102,7 @@ public class TBOrgController {
                 throw new RuntimeException(e);
             }
         }
-        return ResultUtil.ok(Collections.singletonMap(SystemConstant.SUCCESS, true));
+        return ResultUtil.ok(true);
     }
 
     @ApiOperation(value = "机构停用/启用接口")
@@ -121,18 +120,15 @@ public class TBOrgController {
             throw new BusinessException(ExceptionResultEnum.ENABLE_IS_NULL);
         }
         Integer enable = Integer.parseInt(String.valueOf(user.get("enable")));
-        TBOrg tbOrg = (TBOrg) redisUtil.getOrg(orgId);
-        if (Objects.isNull(tbOrg)) {
-            tbOrg = tbOrgService.getById(orgId);
-        }
+        TBOrg tbOrg = cacheService.addOrgCache(orgId);
         if (Objects.isNull(tbOrg)) {
-            throw new BusinessException(ExceptionResultEnum.USER_NO);
+            throw new BusinessException(ExceptionResultEnum.ORG_NO);
         }
         //保存机构
         tbOrg.setEnable(enable);
         tbOrgService.updateById(tbOrg);
-        redisUtil.setOrg(orgId, tbOrg);
-        redisUtil.setOrgCode(tbOrg.getCode(), tbOrg);
-        return ResultUtil.ok(Collections.singletonMap(SystemConstant.SUCCESS, true));
+        cacheService.updateOrgCache(orgId);
+        cacheService.updateOrgCodeCache(tbOrg.getCode());
+        return ResultUtil.ok(true);
     }
 }

+ 1 - 1
themis-backend/src/main/java/com/qmth/themis/backend/api/TBTaskHistoryController.java → themis-admin/src/main/java/com/qmth/themis/admin/api/TBTaskHistoryController.java

@@ -1,4 +1,4 @@
-package com.qmth.themis.backend.api;
+package com.qmth.themis.admin.api;
 
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.qmth.themis.business.dto.response.TBTaskDto;

+ 105 - 91
themis-backend/src/main/java/com/qmth/themis/backend/api/TBUserController.java → themis-admin/src/main/java/com/qmth/themis/admin/api/TBUserController.java

@@ -1,4 +1,4 @@
-package com.qmth.themis.backend.api;
+package com.qmth.themis.admin.api;
 
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
@@ -17,23 +17,19 @@ import com.qmth.themis.business.entity.TBUser;
 import com.qmth.themis.business.entity.TBUserRole;
 import com.qmth.themis.business.enums.FieldUniqueEnum;
 import com.qmth.themis.business.enums.MqTagEnum;
-import com.qmth.themis.business.enums.MqTopicEnum;
 import com.qmth.themis.business.enums.SystemOperationEnum;
-import com.qmth.themis.business.service.*;
-import com.qmth.themis.business.util.RedisUtil;
-import com.qmth.themis.business.util.ServletUtil;
-import com.qmth.themis.business.util.SessionUtil;
-import com.qmth.themis.business.util.UidUtil;
-import com.qmth.themis.common.contanst.Constants;
+import com.qmth.themis.business.service.CacheService;
+import com.qmth.themis.business.service.MqDtoService;
+import com.qmth.themis.business.service.TBUserRoleService;
+import com.qmth.themis.business.service.TBUserService;
+import com.qmth.themis.business.util.*;
 import com.qmth.themis.common.enums.ExceptionResultEnum;
 import com.qmth.themis.common.enums.Platform;
 import com.qmth.themis.common.enums.Source;
 import com.qmth.themis.common.exception.BusinessException;
-import com.qmth.themis.common.util.AesUtil;
 import com.qmth.themis.common.util.Result;
 import com.qmth.themis.common.util.ResultUtil;
 import io.swagger.annotations.*;
-import org.apache.commons.lang3.RandomStringUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.dao.DuplicateKeyException;
@@ -41,6 +37,7 @@ import org.springframework.transaction.annotation.Transactional;
 import org.springframework.web.bind.annotation.*;
 
 import javax.annotation.Resource;
+import java.io.UnsupportedEncodingException;
 import java.security.NoSuchAlgorithmException;
 import java.util.*;
 
@@ -74,19 +71,19 @@ public class TBUserController {
     TBUserRoleService tbUserRoleService;
 
     @Resource
-    TBOrgService tbOrgService;
+    UidUtil uidUtil;
 
     @Resource
-    UidUtil uidUtil;
+    MqUtil mqUtil;
 
     @ApiOperation(value = "用户登录接口")
     @RequestMapping(value = "/login/account", method = RequestMethod.POST)
-    @ApiResponses({ @ApiResponse(code = 200, message = "用户信息", response = TBUser.class) })
+    @ApiResponses({@ApiResponse(code = 200, message = "用户信息", response = TBUser.class)})
     public Result login(
-            @ApiJsonObject(name = "loginAccount", value = { @ApiJsonProperty(key = "loginName", description = "登录名"),
+            @ApiJsonObject(name = "loginAccount", value = {@ApiJsonProperty(key = "loginName", description = "登录名"),
                     @ApiJsonProperty(key = "password", description = "密码"),
-                    @ApiJsonProperty(key = "code", description = "机构代码") }) @ApiParam(value = "用户信息", required = true) @RequestBody Map<String, Object> mapParameter)
-            throws NoSuchAlgorithmException {
+                    @ApiJsonProperty(key = "code", description = "机构代码")}) @ApiParam(value = "用户信息", required = true) @RequestBody Map<String, Object> mapParameter)
+            throws NoSuchAlgorithmException, UnsupportedEncodingException {
         if (Objects.isNull(mapParameter)) {
             throw new BusinessException(ExceptionResultEnum.USER_INFO_IS_NULL);
         }
@@ -104,15 +101,7 @@ public class TBUserController {
         String orgCode = String.valueOf(mapParameter.get("code"));
         TBOrg tbOrg = null;
         if (!Objects.equals(orgCode.toUpperCase(), SystemConstant.ADMIN)) {
-            tbOrg = (TBOrg) redisUtil.getOrgCode(orgCode);
-            if (Objects.isNull(tbOrg)) {
-                QueryWrapper<TBOrg> tbOrgQueryWrapper = new QueryWrapper<>();
-                tbOrgQueryWrapper.lambda().eq(TBOrg::getCode, orgCode);
-                tbOrg = tbOrgService.getOne(tbOrgQueryWrapper);
-                if (Objects.nonNull(tbOrg)) {
-                    redisUtil.setOrgCode(orgCode, tbOrg);
-                }
-            }
+            tbOrg = cacheService.addOrgCodeCache(orgCode);
             if (Objects.isNull(tbOrg)) {
                 throw new BusinessException(ExceptionResultEnum.ORG_NO);
             }
@@ -144,10 +133,10 @@ public class TBUserController {
         if (Objects.nonNull(user.getOrgId()) && user.getOrgId().longValue() != tbOrg.getId().longValue()) {
             throw new BusinessException("用户机构不匹配");
         }
-        String loginPassword = AesUtil.decryptCs7(password, Constants.AES_RULE);
-        //密码错误
-        String aesPassword = AesUtil.decryptCs7(user.getPassword(), Constants.AES_RULE);
-        if (!Objects.equals(loginPassword, aesPassword)) {
+//        String loginPassword = new String(Base64Util.decode(password), Constants.CHARSET_NAME);
+//        密码错误
+//        String base64Password = new String(Base64Util.decode(user.getPassword()), Constants.CHARSET_NAME);
+        if (!Objects.equals(password, user.getPassword())) {
             throw new BusinessException(ExceptionResultEnum.PASSWORD_ERROR);
         }
         return userLoginCommon(user);
@@ -155,7 +144,7 @@ public class TBUserController {
 
     @ApiOperation(value = "短信验证码登陆接口")
     @RequestMapping(value = "/login/verifyCode", method = RequestMethod.POST)
-    @ApiResponses({ @ApiResponse(code = 200, message = "用户信息", response = TBUser.class) })
+    @ApiResponses({@ApiResponse(code = 200, message = "用户信息", response = TBUser.class)})
     public Result verifyCode(@ApiParam(value = "用户信息", required = true) @RequestBody Map<String, Object> mapParameter)
             throws NoSuchAlgorithmException {
         if (Objects.isNull(mapParameter.get("loginName")) || Objects.equals(mapParameter.get("loginName"), "")) {
@@ -193,11 +182,10 @@ public class TBUserController {
         Platform platform = ServletUtil.getRequestPlatform();
         String deviceId = ServletUtil.getRequestDeviceId();
         //添加用户鉴权缓存
-        AuthDto authDto = cacheService.addAccountCache(user.getId());
+        AuthDto authDto = cacheService.addAccountAuthCache(user.getId());
         //生成token
-        String token = RandomStringUtils.randomAlphanumeric(32);
-        //添加用户缓存
-        redisUtil.setUser(user.getId(), user);
+        String token = String.valueOf(UUID.randomUUID()).replaceAll("-", "");
+        cacheService.addAccountCache(user.getId());
         Source source = null;
         if (Platform.WIN == platform || Platform.MAC == platform) {
             source = Source.ADMIN_CLIENT;
@@ -216,18 +204,17 @@ public class TBUserController {
                 expireTime.getDate().getTime());
         redisUtil.setUserSession(sessionId, tbSession, expireTime.getExpireSeconds());
         //mq发送消息start
-        MqDto mqDto = new MqDto(MqTopicEnum.THEMIS_TOPIC.getCode(), platform.name(), tbSession,
-                MqTagEnum.valueOf(platform.name()), tbSession.getId(), user.getLoginName());
+        MqDto mqDto = new MqDto(mqUtil.getMqGroupDomain().getTopic(), platform.name(), SystemOperationEnum.SESSION, sessionId);
         mqDtoService.assembleSendOneWayMsg(mqDto);
-        MqDto mqDtoLog = new MqDto(MqTopicEnum.THEMIS_TOPIC.getCode(), MqTagEnum.USER.name(), SystemOperationEnum.LOGIN,
+        MqDto mqDtoLog = new MqDto(mqUtil.getMqGroupDomain().getTopic(), MqTagEnum.USER.name(), SystemOperationEnum.LOGIN,
                 MqTagEnum.USER, String.valueOf(user.getId()), user.getLoginName());
         mqDtoService.assembleSendOneWayMsg(mqDtoLog);
         //mq发送消息end
         //测试
-        //        String test = SignatureInfo.build(SignatureType.TOKEN, sessionId, token);
+//        String test = SignatureInfo.build(SignatureType.TOKEN, sessionId, token);
         Map<String, Object> map = new HashMap<>();
         map.put(SystemConstant.ACCESS_TOKEN, token);
-        //        map.put(SystemConstant.ACCESS_TOKEN, test);
+//        map.put(SystemConstant.ACCESS_TOKEN, test);
         map.put(SystemConstant.ACCOUNT, user);
         map.put(SystemConstant.SESSION_ID, sessionId);
         map.put("roleCodes", authDto.getRoleCodes());
@@ -237,7 +224,7 @@ public class TBUserController {
             orgMap.put("logo", authDto.getTbOrg().getLogo());
             orgMap.put("enableMonitorRecord", authDto.getTbOrg().getEnableMonitorRecord());
             map.put(SystemConstant.ORG_INFO, orgMap);
-            redisUtil.setOrg(authDto.getTbOrg().getId(), authDto.getTbOrg());
+            cacheService.addOrgCache(authDto.getTbOrg().getId());
         }
         return ResultUtil.ok(map);
     }
@@ -538,11 +525,11 @@ public class TBUserController {
 
     @ApiOperation(value = "登出接口")
     @RequestMapping(value = "/logout", method = RequestMethod.POST)
-    @ApiResponses({ @ApiResponse(code = 200, message = "{\"success\":true}", response = Result.class) })
+    @ApiResponses({@ApiResponse(code = 200, message = "{\"success\":true}", response = Result.class)})
     public Result logout() throws NoSuchAlgorithmException {
         TBUser tbUser = (TBUser) ServletUtil.getRequestAccount();
         TBSession tbSession = (TBSession) ServletUtil.getRequestSession();
-        AuthDto authDto = (AuthDto) redisUtil.get(SystemConstant.userOauth + "::" + tbUser.getId());
+        AuthDto authDto = cacheService.addAccountAuthCache(tbUser.getId());
         if (Objects.isNull(tbSession)) {
             throw new BusinessException(ExceptionResultEnum.LOGIN_NO);
         }
@@ -558,28 +545,28 @@ public class TBUserController {
             }
         }
         if (delete) {
-            redisUtil.deleteUser(tbUser.getId());
             cacheService.removeAccountCache(tbUser.getId());
+            cacheService.removeAccountAuthCache(tbUser.getId());
         }
         //mq发送消息start
-        MqDto mqDto = new MqDto(MqTopicEnum.THEMIS_TOPIC.getCode(), MqTagEnum.USER.name(), SystemOperationEnum.LOGOUT,
+        MqDto mqDto = new MqDto(mqUtil.getMqGroupDomain().getTopic(), MqTagEnum.USER.name(), SystemOperationEnum.LOGOUT,
                 MqTagEnum.USER, String.valueOf(tbUser.getId()), tbUser.getLoginName());
         mqDtoService.assembleSendOneWayMsg(mqDto);
         //mq发送消息end
-        return ResultUtil.ok(Collections.singletonMap(SystemConstant.SUCCESS, true));
+        return ResultUtil.ok(true);
     }
 
     //    @CachePut(value = "user_cache", key = "'userCacheQuery'")
     @ApiOperation(value = "用户查询接口")
     @RequestMapping(value = "/query", method = RequestMethod.POST)
-    @ApiResponses({ @ApiResponse(code = 200, message = "用户信息", response = TBUserDto.class) })
+    @ApiResponses({@ApiResponse(code = 200, message = "用户信息", response = TBUserDto.class)})
     public Result query(@ApiParam(value = "用户id", required = false) @RequestParam(required = false) Long id,
-            @ApiParam(value = "登录名", required = false) @RequestParam(required = false) String loginName,
-            @ApiParam(value = "姓名", required = false) @RequestParam(required = false) String name,
-            @ApiParam(value = "角色", required = false) @RequestParam(required = false) String roleCode,
-            @ApiParam(value = "是否启用", required = false) @RequestParam(required = false) Integer enable,
-            @ApiParam(value = "分页页码", required = true) @RequestParam int pageNumber,
-            @ApiParam(value = "分页数", required = true) @RequestParam int pageSize) {
+                        @ApiParam(value = "登录名", required = false) @RequestParam(required = false) String loginName,
+                        @ApiParam(value = "姓名", required = false) @RequestParam(required = false) String name,
+                        @ApiParam(value = "角色", required = false) @RequestParam(required = false) String roleCode,
+                        @ApiParam(value = "是否启用", required = false) @RequestParam(required = false) Integer enable,
+                        @ApiParam(value = "分页页码", required = true) @RequestParam int pageNumber,
+                        @ApiParam(value = "分页数", required = true) @RequestParam int pageSize) {
         TBUser tbUser = (TBUser) ServletUtil.getRequestAccount();
         IPage<TBUserDto> tbUserIPage = tbUserService
                 .userQuery(new Page<>(pageNumber, pageSize), id, loginName, name, roleCode, enable, tbUser.getOrgId());
@@ -597,7 +584,7 @@ public class TBUserController {
     //    @CacheEvict(value = "user_cache", key = "'userCacheQuery'")
     @ApiOperation(value = "用户新增/编辑接口")
     @RequestMapping(value = "/save", method = RequestMethod.POST)
-    @ApiResponses({ @ApiResponse(code = 200, message = "{\"success\":true}", response = Result.class) })
+    @ApiResponses({@ApiResponse(code = 200, message = "{\"success\":true}", response = Result.class)})
     @Transactional
     public Result save(@ApiJsonObject(name = "userSave", value = {
             @ApiJsonProperty(key = "id", type = "long", example = "1", description = "新增不需要主键"),
@@ -607,26 +594,40 @@ public class TBUserController {
             @ApiJsonProperty(key = "password", description = "密码,新增必须"),
             @ApiJsonProperty(key = "enable", type = "int", example = "1", description = "是否启用"),
             @ApiJsonProperty(key = "mobileNumber", description = "手机号"),
-            @ApiJsonProperty(key = "roleCode", description = "角色") }) @ApiParam(value = "用户信息", required = true) @RequestBody Map<String, Object> mapParameter) {
+            @ApiJsonProperty(key = "roleCode", description = "角色")}) @ApiParam(value = "用户信息", required = true) @RequestBody Map<String, Object> mapParameter) {
         if (Objects.isNull(mapParameter)) {
             throw new BusinessException(ExceptionResultEnum.USER_INFO_IS_NULL);
         }
         if (Objects.isNull(mapParameter.get("orgId"))) {
             throw new BusinessException(ExceptionResultEnum.ORG_ID_IS_NULL);
         }
+        boolean cacheClean = false;
         TBUser loginUser = (TBUser) ServletUtil.getRequestAccount();
+        TBUser dbUser = null;
+        AuthDto authDto = null;
+        if (Objects.nonNull(mapParameter.get("id"))) {
+            dbUser = cacheService.addAccountCache(Long.parseLong(String.valueOf(mapParameter.get("id"))));
+            authDto = cacheService.addAccountAuthCache(dbUser.getId());
+        }
+        Gson gson = new Gson();
+        TBUser tbUser = gson.fromJson(gson.toJson(mapParameter), TBUser.class);
+        if ((Objects.isNull(tbUser.getPassword()) || Objects.equals(tbUser.getPassword(), "")) && Objects.nonNull(dbUser)) {
+            tbUser.setPassword(dbUser.getPassword());
+        }
+        List<String> roleList = (List<String>) mapParameter.get("roleCode");
+        if (Objects.isNull(roleList) || roleList.size() == 0) {
+            throw new BusinessException("请选择角色");
+        }
+        Set<String> roleSet = new HashSet<>(roleList);
+        if (roleSet.size() > 1) {
+            throw new BusinessException("暂不支持多个角色");
+        }
+        if ((Objects.nonNull(tbUser) && Objects.nonNull(dbUser) && !tbUser.equals(dbUser))
+                || (Objects.nonNull(authDto) && !roleSet.equals(authDto.getRoleCodes()))) {
+            cacheClean = true;
+        }
         Long orgId = Long.parseLong(String.valueOf(mapParameter.get("orgId")));
         try {
-            Gson gson = new Gson();
-            TBUser tbUser = gson.fromJson(gson.toJson(mapParameter), TBUser.class);
-            List<String> roleList = (List<String>) mapParameter.get("roleCode");
-            if (Objects.isNull(roleList) || roleList.size() == 0) {
-                throw new BusinessException("请选择角色");
-            }
-            Set<String> roleSet = new HashSet<>(roleList);
-            if (roleSet.size() > 1) {
-                throw new BusinessException("暂不支持多个角色");
-            }
             if (Objects.isNull(tbUser.getId())) {
                 tbUser.setId(uidUtil.getId());
                 tbUser.setOrgId(orgId);
@@ -653,18 +654,17 @@ public class TBUserController {
             }
             tbUserService.saveOrUpdate(tbUser);
             //清除用户缓存
-            if (Objects.nonNull(roleSet) && roleSet.size() > 0) {
-                AuthDto authDto = (AuthDto) redisUtil.get(SystemConstant.userOauth + "::" + tbUser.getId());
-                if (Objects.nonNull(authDto)) {
-                    for (Source s : Source.values()) {
-                        String sessionId = SessionUtil
-                                .digest(tbUser.getId(), Math.abs(authDto.getRoleCodes().toString().hashCode()),
-                                        s.name());
-                        redisUtil.deleteUserSession(sessionId);
-                    }
+            if (cacheClean && Objects.nonNull(authDto)) {
+                for (Source s : Source.values()) {
+                    String sessionId = SessionUtil
+                            .digest(tbUser.getId(), Math.abs(authDto.getRoleCodes().toString().hashCode()),
+                                    s.name());
+                    redisUtil.deleteUserSession(sessionId);
                 }
-                redisUtil.deleteUser(tbUser.getId());
                 cacheService.removeAccountCache(tbUser.getId());
+                cacheService.removeAccountAuthCache(tbUser.getId());
+            } else {
+                cacheService.updateAccountCache(tbUser.getId());
             }
         } catch (Exception e) {
             log.error("请求出错", e);
@@ -680,43 +680,43 @@ public class TBUserController {
                 throw new RuntimeException(e);
             }
         }
-        return ResultUtil.ok(Collections.singletonMap(SystemConstant.SUCCESS, true));
+        return ResultUtil.ok(true);
     }
 
     @ApiOperation(value = "获取短信验证码接口")
     @RequestMapping(value = "/getVerifyCode", method = RequestMethod.POST)
-    @ApiResponses({ @ApiResponse(code = 200, message = "{\"verifyCode\":123456}", response = Result.class) })
+    @ApiResponses({@ApiResponse(code = 200, message = "{\"verifyCode\":123456}", response = Result.class)})
     public Result getVerifyCode(@ApiParam(value = "登录名", required = true) @RequestParam String loginName) {
         if (Objects.isNull(loginName) || Objects.equals(loginName, "")) {
             throw new BusinessException(ExceptionResultEnum.LOGIN_NAME_IS_NULL);
         }
-        return ResultUtil.ok(Collections.singletonMap(SystemConstant.SUCCESS, true));
+        return ResultUtil.ok(true);
     }
 
     @ApiOperation(value = "获取短信验证码接口")
     @RequestMapping(value = "/validate/verifyCode", method = RequestMethod.POST)
-    @ApiResponses({ @ApiResponse(code = 200, message = "{\"success\":true}", response = Result.class) })
+    @ApiResponses({@ApiResponse(code = 200, message = "{\"success\":true}", response = Result.class)})
     public Result validateVerifyCode(@ApiParam(value = "验证码", required = true) @RequestParam String verifyCode) {
         if (Objects.isNull(verifyCode) || Objects.equals(verifyCode, "")) {
             throw new BusinessException(ExceptionResultEnum.VERIFYCODE_IS_NULL);
         }
-        return ResultUtil.ok(Collections.singletonMap(SystemConstant.SUCCESS, true));
+        return ResultUtil.ok(true);
     }
 
     @ApiOperation(value = "二次验证获取短信验证码接口")
     @RequestMapping(value = "/validate/getVerifyCode", method = RequestMethod.POST)
-    @ApiResponses({ @ApiResponse(code = 200, message = "{\"success\":true}", response = Result.class) })
+    @ApiResponses({@ApiResponse(code = 200, message = "{\"success\":true}", response = Result.class)})
     public Result validateGetVerifyCode() {
-        return ResultUtil.ok(Collections.singletonMap(SystemConstant.SUCCESS, true));
+        return ResultUtil.ok(true);
     }
 
     @ApiOperation(value = "用户停用/启用接口")
     @RequestMapping(value = "/enable", method = RequestMethod.POST)
     @Transactional
-    @ApiResponses({ @ApiResponse(code = 200, message = "{\"success\":true}", response = Result.class) })
+    @ApiResponses({@ApiResponse(code = 200, message = "{\"success\":true}", response = Result.class)})
     public Result enableUser(@ApiJsonObject(name = "enableUser", value = {
             @ApiJsonProperty(key = "id", type = "long", example = "1", description = "用户id"),
-            @ApiJsonProperty(key = "enable", type = "int", example = "1", description = "停用/启用") }) @ApiParam(value = "用户信息", required = true) @RequestBody Map<String, Object> user) {
+            @ApiJsonProperty(key = "enable", type = "int", example = "1", description = "停用/启用")}) @ApiParam(value = "用户信息", required = true) @RequestBody Map<String, Object> user) throws NoSuchAlgorithmException {
         if (Objects.isNull(user.get("id")) || Objects.equals(user.get("id"), "")) {
             throw new BusinessException(ExceptionResultEnum.USER_ID_IS_NULL);
         }
@@ -725,24 +725,38 @@ public class TBUserController {
             throw new BusinessException(ExceptionResultEnum.ENABLE_IS_NULL);
         }
         Integer enable = Integer.parseInt(String.valueOf(user.get("enable")));
-        TBUser tbUser = tbUserService.getById(userId);
+        TBUser tbUser = cacheService.addAccountCache(userId);
         if (Objects.isNull(tbUser)) {
             throw new BusinessException(ExceptionResultEnum.USER_NO);
         }
         //保存用户
         tbUser.setEnable(enable);
         tbUserService.updateById(tbUser);
-        redisUtil.setUser(tbUser.getId(), tbUser);
-        return ResultUtil.ok(Collections.singletonMap(SystemConstant.SUCCESS, true));
+        if (enable == 0) {
+            AuthDto authDto = cacheService.addAccountAuthCache(tbUser.getId());
+            if (Objects.nonNull(authDto)) {
+                for (Source s : Source.values()) {
+                    String sessionId = SessionUtil
+                            .digest(tbUser.getId(), Math.abs(authDto.getRoleCodes().toString().hashCode()),
+                                    s.name());
+                    redisUtil.deleteUserSession(sessionId);
+                }
+            }
+            cacheService.removeAccountCache(tbUser.getId());
+            cacheService.removeAccountAuthCache(tbUser.getId());
+        } else {
+            cacheService.updateAccountCache(tbUser.getId());
+        }
+        return ResultUtil.ok(true);
     }
 
     @ApiOperation(value = "用户修改密码接口")
     @RequestMapping(value = "/updatePwd", method = RequestMethod.POST)
-    @ApiResponses({ @ApiResponse(code = 200, message = "{\"success\":true}", response = Result.class) })
+    @ApiResponses({@ApiResponse(code = 200, message = "{\"success\":true}", response = Result.class)})
     @Transactional
     public Result userUpdatePwd(@ApiJsonObject(name = "userUpdatePwd", value = {
             @ApiJsonProperty(key = "id", type = "long", example = "1", description = "用户ID"),
-            @ApiJsonProperty(key = "password", description = "新密码") }) @ApiParam(value = "用户信息", required = true) @RequestBody Map<String, Object> mapParameter) {
+            @ApiJsonProperty(key = "password", description = "新密码")}) @ApiParam(value = "用户信息", required = true) @RequestBody Map<String, Object> mapParameter) {
         if (Objects.isNull(mapParameter.get("id")) || Objects.equals(mapParameter.get("id"), "")) {
             throw new BusinessException(ExceptionResultEnum.USER_ID_IS_NULL);
         }
@@ -751,7 +765,7 @@ public class TBUserController {
             throw new BusinessException(ExceptionResultEnum.PASSWORD_IS_NULL);
         }
         String password = String.valueOf(mapParameter.get("password"));
-        TBUser tbUser = tbUserService.getById(id);
+        TBUser tbUser = cacheService.addAccountCache(id);
         if (Objects.isNull(tbUser)) {
             throw new BusinessException(ExceptionResultEnum.USER_NO);
         }
@@ -759,7 +773,7 @@ public class TBUserController {
         tbUser.setPassword(password);
         tbUser.setUpdateId(currentUser.getId());
         tbUserService.updateById(tbUser);
-        redisUtil.deleteUser(tbUser.getId());
-        return ResultUtil.ok(Collections.singletonMap(SystemConstant.SUCCESS, true));
+        cacheService.removeAccountCache(tbUser.getId());
+        return ResultUtil.ok(true);
     }
 }

+ 71 - 0
themis-admin/src/main/java/com/qmth/themis/admin/api/TEExamActivityController.java

@@ -0,0 +1,71 @@
+package com.qmth.themis.admin.api;
+
+import java.util.Collections;
+import java.util.List;
+
+import javax.annotation.Resource;
+
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.qmth.themis.business.constant.SystemConstant;
+import com.qmth.themis.business.entity.TEExamActivity;
+import com.qmth.themis.business.service.TEExamActivityService;
+import com.qmth.themis.business.service.TEExamPaperService;
+import com.qmth.themis.common.util.Result;
+import com.qmth.themis.common.util.ResultUtil;
+
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
+import io.swagger.annotations.ApiResponse;
+import io.swagger.annotations.ApiResponses;
+
+/**
+ * @Description: 考试场次 前端控制器
+ * @Param:
+ * @return:
+ * @Author: wangliang
+ * @Date: 2020/6/25
+ */
+@Api(tags = "考试场次Controller")
+@RestController
+@RequestMapping("/${prefix.url.admin}/activity")
+public class TEExamActivityController {
+
+    @Resource
+    private TEExamActivityService teExamActivityService;
+    
+    @Resource
+    private  TEExamPaperService examPaperService;
+
+    @ApiOperation(value = "考试场次修改/新增接口")
+    @RequestMapping(value = "/save", method = RequestMethod.POST)
+    @Transactional
+    @ApiResponses({@ApiResponse(code = 200, message = "{\"success\":true}", response = Result.class)})
+    public Result save(
+            @ApiParam(value = "考试场次信息", required = true) @RequestBody List<TEExamActivity> teExamActivityList) {
+    	teExamActivityService.saveExamActivity(teExamActivityList);
+    	examPaperService.disposeObjectiveAnswer(teExamActivityList.get(0).getExamId());
+        return ResultUtil.ok(true);
+    }
+
+    @ApiOperation(value = "考试场次查询接口")
+    @RequestMapping(value = "/query", method = RequestMethod.POST)
+    @ApiResponses({@ApiResponse(code = 200, message = "考试场次信息", response = TEExamActivity.class)})
+    public Result query(@ApiParam(value = "主键", required = false) @RequestParam(required = false) Long id,
+                        @ApiParam(value = "考试批次id", required = false) @RequestParam(required = false) Long examId,
+                        @ApiParam(value = "考试场次编码", required = false) @RequestParam(required = false) String code,
+                        @ApiParam(value = "开始日期", required = false) @RequestParam(required = false) Long startDate,
+                        @ApiParam(value = "结束日期", required = false) @RequestParam(required = false) Long finishDate,
+                        @ApiParam(value = "分页页码", required = true) @RequestParam int pageNumber,
+                        @ApiParam(value = "分页数", required = true) @RequestParam int pageSize) {
+        return ResultUtil.ok(teExamActivityService
+                .examActivityQuery(new Page<>(pageNumber, pageSize), id, examId, code, startDate, finishDate));
+    }
+}

+ 141 - 124
themis-backend/src/main/java/com/qmth/themis/backend/api/TEExamController.java → themis-admin/src/main/java/com/qmth/themis/admin/api/TEExamController.java

@@ -1,13 +1,10 @@
-package com.qmth.themis.backend.api;
+package com.qmth.themis.admin.api;
 
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.qmth.themis.business.annotation.ApiJsonObject;
 import com.qmth.themis.business.annotation.ApiJsonProperty;
-import com.qmth.themis.business.cache.ExamRecordCacheUtil;
-import com.qmth.themis.business.cache.RedisKeyHelper;
-import com.qmth.themis.business.cache.bean.ExamActivityRecordCacheBean;
-import com.qmth.themis.business.cache.bean.ExamStudentCacheBean;
+import com.qmth.themis.business.cache.bean.ExamCacheBean;
 import com.qmth.themis.business.constant.SystemConstant;
 import com.qmth.themis.business.dto.AuthDto;
 import com.qmth.themis.business.dto.ExamPropCountDto;
@@ -16,10 +13,7 @@ import com.qmth.themis.business.dto.request.TEExamDto;
 import com.qmth.themis.business.entity.*;
 import com.qmth.themis.business.enums.*;
 import com.qmth.themis.business.service.*;
-import com.qmth.themis.business.util.JacksonUtil;
-import com.qmth.themis.business.util.RedisUtil;
-import com.qmth.themis.business.util.ServletUtil;
-import com.qmth.themis.business.util.UidUtil;
+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.Result;
@@ -72,13 +66,25 @@ public class TEExamController {
     @Resource
     UidUtil uidUtil;
 
+    @Resource
+    MqUtil mqUtil;
+
     @Resource
     TBTaskHistoryService taskHistoryService;
 
+    @Resource
+    TOeExamRecordService tOeExamRecordService;
+
+    @Resource
+    private TEExamPaperService examPaperService;
+
+    @Resource
+    CacheService cacheService;
+
     @ApiOperation(value = "考试批次修改/新增接口")
     @RequestMapping(value = "/save", method = RequestMethod.POST)
     @Transactional
-    @ApiResponses({ @ApiResponse(code = 200, message = "{\"success\":true}", response = Result.class) })
+    @ApiResponses({@ApiResponse(code = 200, message = "{\"success\":true}", response = Result.class)})
     public Result save(@ApiParam(value = "考试批次信息", required = true) @RequestBody TEExamDto teExamDto) {
         if (Objects.isNull(teExamDto) || Objects.equals(teExamDto, "")) {
             throw new BusinessException(ExceptionResultEnum.EXAM_INFO_IS_NULL);
@@ -98,31 +104,44 @@ public class TEExamController {
         try {
             TBUser tbUser = (TBUser) ServletUtil.getRequestAccount();
             TBOrg tbOrg = (TBOrg) ServletUtil.getRequestOrg();
-            if (Objects.nonNull(tbOrg)) {
-                if (Objects.isNull(tbOrg.getId())) {
-                    throw new BusinessException("考试的机构id不允许为空");
-                }
-                teExamDto.setOrgId(tbOrg.getId());
+            if (Objects.nonNull(tbOrg) && Objects.isNull(tbOrg.getId())) {
+                throw new BusinessException("考试的机构id不允许为空");
             }
+            teExamDto.setOrgId(tbOrg.getId());
             oldId = teExamDto.getId();
             TEExam oldTeExam = null;
             if (Objects.nonNull(oldId)) {
                 teExamDto.setUpdateId(tbUser.getId());
-                oldTeExam = teExamService.getById(oldId);
+                ExamCacheBean examCacheBean = teExamService.getExamCacheBean(oldId);
+                oldTeExam = teExamService.cacheConvert(examCacheBean);
+                if (Objects.equals(oldTeExam.getMonitorStatus(), InvigilateMonitorStatusEnum.FINISHED)) {
+                    throw new BusinessException("监考结束的考试批次不可以修改");
+                }
+                boolean recordUpdate = true;
+                if ((Objects.nonNull(oldTeExam.getRecordSelectStrategy()) && Objects.nonNull(teExamDto.getRecordSelectStrategy()) && !Objects.equals(oldTeExam.getRecordSelectStrategy(), teExamDto.getRecordSelectStrategy()))) {
+                    recordUpdate = false;
+                }
+                boolean objectiveUpdate = true;
+                if ((Objects.nonNull(oldTeExam.getObjectiveScorePolicy()) && Objects.nonNull(teExamDto.getObjectiveScorePolicy()) && !Objects.equals(oldTeExam.getObjectiveScorePolicy(), teExamDto.getObjectiveScorePolicy()))) {
+                    objectiveUpdate = false;
+                }
+                QueryWrapper<TOeExamRecord> tOeExamRecordQueryWrapper = new QueryWrapper<>();
+                tOeExamRecordQueryWrapper.lambda().eq(TOeExamRecord::getExamId, oldId);
+                int count = tOeExamRecordService.count(tOeExamRecordQueryWrapper);
+                if (count > 0) {
+                    if (!recordUpdate) {
+                        throw new BusinessException("已有考试记录,取分策略不允许修改");
+                    }
+                    if (!objectiveUpdate) {
+                        throw new BusinessException("已有考试记录,客观题判分策略不允许修改");
+                    }
+                }
             } else {
                 teExamDto.setId(uidUtil.getId());
                 teExamDto.setCreateId(tbUser.getId());
             }
+            teExamDto.setMonitorStatus(Objects.nonNull(oldTeExam) ? oldTeExam.getMonitorStatus() : InvigilateMonitorStatusEnum.NOT_START);
             teExam = new TEExam(teExamDto);
-            if (oldTeExam != null) {
-                teExam.setMonitorStatus(oldTeExam.getMonitorStatus());
-            } else {
-                teExam.setMonitorStatus(InvigilateMonitorStatusEnum.NOT_START);
-            }
-            if (Objects.nonNull(teExam.getMonitorStatus()) && Objects
-                    .equals(teExam.getMonitorStatus(), InvigilateMonitorStatusEnum.FINISHED)) {
-                throw new BusinessException("监考结束的考试批次不可以修改");
-            }
             teExamService.saveOrUpdate(teExam);
             if (Objects.nonNull(oldTeExam) && !Objects
                     .equals(oldTeExam.getMode().name(), teExamDto.getMode().name())) {//如果模式改变,则删除之前模式的全部quartz
@@ -134,10 +153,10 @@ public class TEExamController {
                     Map<String, Object> prop = new HashMap<>();
                     prop.put("oper", "delete");
                     if (Objects.nonNull(teExamActivityList.get(0)) && teExamActivityList.get(0).getEnable() == 1) {
-                        MqDto mqDto = new MqDto(MqTopicEnum.THEMIS_TOPIC.getCode(), MqTagEnum.EXAM_ACTIVITY.name(),
+                        MqDto mqDto = new MqDto(mqUtil.getMqGroupDomain().getTopic(), MqTagEnum.EXAM_ACTIVITY.name(),
                                 JacksonUtil.parseJson(teExamActivityList), MqTagEnum.EXAM_ACTIVITY,
                                 String.valueOf(teExam.getId()), prop, tbUser.getName());
-                        mqDtoService.assembleSendOneWayMsg(mqDto);
+                        mqDtoService.assembleSendOneOrderMsg(mqDto);
                     }
                     //删除quartz任务,发送mq消息end
                     //删除数据
@@ -169,10 +188,10 @@ public class TEExamController {
                         Map<String, Object> prop = new HashMap<>();
                         prop.put("oper", "insert");
                         prop.put("exam", teExam);
-                        MqDto mqDto = new MqDto(MqTopicEnum.THEMIS_TOPIC.getCode(), MqTagEnum.EXAM_ACTIVITY.name(),
+                        MqDto mqDto = new MqDto(mqUtil.getMqGroupDomain().getTopic(), MqTagEnum.EXAM_ACTIVITY.name(),
                                 JacksonUtil.parseJson(teExamActivityList), MqTagEnum.EXAM_ACTIVITY,
                                 String.valueOf(teExam.getId()), prop, tbUser.getName());
-                        mqDtoService.assembleSendOneWayMsg(mqDto);
+                        mqDtoService.assembleSendOneOrderMsg(mqDto);
                         //新增quartz任务,发送mq消息end
                     }
                 } else {
@@ -191,10 +210,10 @@ public class TEExamController {
                         Map<String, Object> prop = new HashMap<>();
                         prop.put("oper", "insert");
                         prop.put("exam", teExam);
-                        MqDto mqDto = new MqDto(MqTopicEnum.THEMIS_TOPIC.getCode(), MqTagEnum.EXAM_ACTIVITY.name(),
+                        MqDto mqDto = new MqDto(mqUtil.getMqGroupDomain().getTopic(), MqTagEnum.EXAM_ACTIVITY.name(),
                                 JacksonUtil.parseJson(Arrays.asList(teExamActivity)), MqTagEnum.EXAM_ACTIVITY,
                                 String.valueOf(teExam.getId()), prop, tbUser.getName());
-                        mqDtoService.assembleSendOneWayMsg(mqDto);
+                        mqDtoService.assembleSendOneOrderMsg(mqDto);
                     }
                 }
             }
@@ -216,15 +235,16 @@ public class TEExamController {
             }
         }
         teExamService.updateExamCacheBean(teExam.getId());
-        return ResultUtil.ok(Collections.singletonMap(SystemConstant.SUCCESS, true));
+        examPaperService.disposeObjectiveAnswer(teExam.getId());
+        return ResultUtil.ok(true);
     }
 
     @ApiOperation(value = "考试批次统计接口")
     @RequestMapping(value = "/count", method = RequestMethod.POST)
-    @ApiResponses({ @ApiResponse(code = 200, message = "{\"count\":1}", response = Result.class) })
+    @ApiResponses({@ApiResponse(code = 200, message = "{\"count\":1}", response = Result.class)})
     public Result count(@ApiParam(value = "考试批次编码", required = false) @RequestParam(required = false) String code,
-            @ApiParam(value = "考试批次名称", required = false) @RequestParam(required = false) String name,
-            @ApiParam(value = "考试批次模式", required = false) @RequestParam(required = false) Integer mode) {
+                        @ApiParam(value = "考试批次名称", required = false) @RequestParam(required = false) String name,
+                        @ApiParam(value = "考试批次模式", required = false) @RequestParam(required = false) Integer mode) {
         QueryWrapper<TEExam> teExamQueryWrapper = new QueryWrapper<>();
         if (Objects.nonNull(code)) {
             teExamQueryWrapper.lambda().eq(TEExam::getCode, code);
@@ -241,18 +261,18 @@ public class TEExamController {
 
     @ApiOperation(value = "考试批次查询接口")
     @RequestMapping(value = "/query", method = RequestMethod.POST)
-    @ApiResponses({ @ApiResponse(code = 200, message = "考试批次信息", response = TEExam.class) })
+    @ApiResponses({@ApiResponse(code = 200, message = "考试批次信息", response = TEExam.class)})
     public Result query(@ApiParam(value = "用户id", required = false) @RequestParam(required = false) Long userId,
-            @ApiParam(value = "考试批次id", required = false) @RequestParam(required = false) Long id,
-            @ApiParam(value = "考试批次编码", required = false) @RequestParam(required = false) String code,
-            @ApiParam(value = "考试批次名称", required = false) @RequestParam(required = false) String name,
-            @ApiParam(value = "考试批次模式", required = false) @RequestParam(required = false) String mode,
-            @ApiParam(value = "是否启用", required = false) @RequestParam(required = false) Integer enable,
-            @ApiParam(value = "类型(区分实时监考台和考务)", required = false) @RequestParam(required = false) String type,
-            @ApiParam(value = "分页页码", required = true) @RequestParam int pageNumber,
-            @ApiParam(value = "分页数", required = true) @RequestParam int pageSize) {
+                        @ApiParam(value = "考试批次id", required = false) @RequestParam(required = false) Long id,
+                        @ApiParam(value = "考试批次编码", required = false) @RequestParam(required = false) String code,
+                        @ApiParam(value = "考试批次名称", required = false) @RequestParam(required = false) String name,
+                        @ApiParam(value = "考试批次模式", required = false) @RequestParam(required = false) String mode,
+                        @ApiParam(value = "是否启用", required = false) @RequestParam(required = false) Integer enable,
+                        @ApiParam(value = "类型(区分实时监考台和考务)", required = false) @RequestParam(required = false) String type,
+                        @ApiParam(value = "分页页码", required = true) @RequestParam int pageNumber,
+                        @ApiParam(value = "分页数", required = true) @RequestParam int pageSize) {
         TBUser tbUser = (TBUser) ServletUtil.getRequestAccount();
-        AuthDto authDto = (AuthDto) redisUtil.get(SystemConstant.userOauth + "::" + tbUser.getId());
+        AuthDto authDto = cacheService.addAccountAuthCache(tbUser.getId());
         if (authDto.getRoleCodes().toString().contains(RoleEnum.INSPECTION.name())) {
             userId = null;
         }
@@ -263,11 +283,11 @@ public class TEExamController {
 
     @ApiOperation(value = "考试批次停用/启用接口")
     @RequestMapping(value = "/toggle", method = RequestMethod.POST)
-    @ApiResponses({ @ApiResponse(code = 200, message = "{\"success\":true}", response = Result.class) })
+    @ApiResponses({@ApiResponse(code = 200, message = "{\"success\":true}", response = Result.class)})
     @Transactional
     public Result examToggle(@ApiJsonObject(name = "examToggle", value = {
             @ApiJsonProperty(key = "id", type = "long", example = "1", description = "考试批次ID"),
-            @ApiJsonProperty(key = "enable", type = "int", example = "1", description = "是否启用") }) @ApiParam(value = "考试批次信息", required = true) @RequestBody Map<String, Object> mapParameter) {
+            @ApiJsonProperty(key = "enable", type = "int", example = "1", description = "是否启用")}) @ApiParam(value = "考试批次信息", required = true) @RequestBody Map<String, Object> mapParameter) {
         if (Objects.isNull(mapParameter.get("id")) || Objects.equals(mapParameter.get("id"), "")) {
             throw new BusinessException(ExceptionResultEnum.EXAM_ID_IS_NULL);
         }
@@ -276,40 +296,41 @@ public class TEExamController {
             throw new BusinessException(ExceptionResultEnum.ENABLE_IS_NULL);
         }
         Integer enable = Integer.parseInt(String.valueOf(mapParameter.get("enable")));
-        TEExam teExam = teExamService.getById(examId);
-        if (Objects.isNull(teExam)) {
+        ExamCacheBean examCacheBean = teExamService.getExamCacheBean(examId);
+        if (Objects.isNull(examCacheBean)) {
             throw new BusinessException(ExceptionResultEnum.EXAM_NO);
         }
+        TEExam teExam = teExamService.cacheConvert(examCacheBean);
         TBUser tbUser = (TBUser) ServletUtil.getRequestAccount();
         teExam.setEnable(enable);
         teExam.setUpdateId(tbUser.getId());
         teExamService.updateById(teExam);
         teExamService.updateExamCacheBean(teExam.getId());
-        return ResultUtil.ok(Collections.singletonMap(SystemConstant.SUCCESS, true));
+        return ResultUtil.ok(true);
     }
 
     @ApiOperation(value = "考试批次详情接口")
     @RequestMapping(value = "/detail", method = RequestMethod.POST)
-    @ApiResponses({ @ApiResponse(code = 200, message = "考试批次信息", response = TEExam.class) })
+    @ApiResponses({@ApiResponse(code = 200, message = "考试批次信息", response = TEExam.class)})
     public Result detail(@ApiParam(value = "考试批次id", required = true) @RequestParam Long id) {
         if (Objects.isNull(id) || Objects.equals(id, "")) {
             throw new BusinessException(ExceptionResultEnum.EXAM_ID_IS_NULL);
         }
-        TEExam teExam = teExamService.getById(id);
-        if (Objects.isNull(teExam)) {
+        ExamCacheBean examCacheBean = teExamService.getExamCacheBean(id);
+        if (Objects.isNull(examCacheBean)) {
             throw new BusinessException(ExceptionResultEnum.EXAM_NO);
         }
-        return ResultUtil.ok(new TEExamDto(teExam));
+        return ResultUtil.ok(new TEExamDto(teExamService.cacheConvert(examCacheBean)));
     }
 
     @ApiOperation(value = "考试批次复制接口")
     @RequestMapping(value = "/copy", method = RequestMethod.POST)
-    @ApiResponses({ @ApiResponse(code = 200, message = "{\"success\":true}", response = Result.class) })
+    @ApiResponses({@ApiResponse(code = 200, message = "{\"success\":true}", response = Result.class)})
     @Transactional
     public Result copy(@ApiJsonObject(name = "examCopy", value = {
             @ApiJsonProperty(key = "sourceId", type = "long", example = "1", description = "来源批次ID"),
             @ApiJsonProperty(key = "code", description = "代码"),
-            @ApiJsonProperty(key = "name", description = "名称") }) @ApiParam(value = "考试批次信息", required = true) @RequestBody Map<String, Object> mapParameter) {
+            @ApiJsonProperty(key = "name", description = "名称")}) @ApiParam(value = "考试批次信息", required = true) @RequestBody Map<String, Object> mapParameter) {
         if (Objects.isNull(mapParameter.get("sourceId")) || Objects.equals(mapParameter.get("sourceId"), "")) {
             throw new BusinessException(ExceptionResultEnum.EXAM_ID_IS_NULL);
         }
@@ -322,10 +343,11 @@ public class TEExamController {
             throw new BusinessException(ExceptionResultEnum.EXAM_NAME_IS_NULL);
         }
         String name = String.valueOf(mapParameter.get("name"));
-        TEExam teExam = teExamService.getById(examId);
-        if (Objects.isNull(teExam)) {
+        ExamCacheBean examCacheBean = teExamService.getExamCacheBean(examId);
+        if (Objects.isNull(examCacheBean)) {
             throw new BusinessException(ExceptionResultEnum.EXAM_NO);
         }
+        TEExam teExam = teExamService.cacheConvert(examCacheBean);
         List<TEExamActivity> teExamActivityList = null;
         try {
             teExam.setId(null);
@@ -374,12 +396,12 @@ public class TEExamController {
                 throw new RuntimeException(e);
             }
         }
-        return ResultUtil.ok(Collections.singletonMap(SystemConstant.SUCCESS, true));
+        return ResultUtil.ok(true);
     }
 
     @ApiOperation(value = "监考端获取考试批次提醒接口")
     @RequestMapping(value = "/list/count", method = RequestMethod.POST)
-    @ApiResponses({ @ApiResponse(code = 200, message = "考试批次信息", response = Result.class) })
+    @ApiResponses({@ApiResponse(code = 200, message = "考试批次信息", response = Result.class)})
     public Result listCount(@ApiParam(value = "用户id", required = false) @RequestParam(required = false) Long userId) {
         TBUser tbUser = (TBUser) ServletUtil.getRequestAccount();
         return ResultUtil.ok(teExamService.examList(userId, tbUser.getOrgId()));
@@ -387,7 +409,7 @@ public class TEExamController {
 
     @ApiOperation(value = "考试属性统计接口")
     @RequestMapping(value = "/prop/count", method = RequestMethod.POST)
-    @ApiResponses({ @ApiResponse(code = 200, message = "考试属性信息", response = ExamPropCountDto.class) })
+    @ApiResponses({@ApiResponse(code = 200, message = "考试属性信息", response = ExamPropCountDto.class)})
     public Result propCount(@ApiParam(value = "考试id", required = true) @RequestParam Long examId) {
         if (Objects.isNull(examId) || Objects.equals(examId, "")) {
             throw new BusinessException(ExceptionResultEnum.EXAM_ID_IS_NULL);
@@ -399,7 +421,7 @@ public class TEExamController {
         }
         //首先查询当前用户所要监控的roomCode
         QueryWrapper<TBExamInvigilateUser> examInvigilateUserQueryWrapper = new QueryWrapper<>();
-        AuthDto authDto = (AuthDto) redisUtil.get(SystemConstant.userOauth + "::" + tbUser.getId());
+        AuthDto authDto = cacheService.addAccountAuthCache(tbUser.getId());
         //如果有监考员角色,只能查看自己所监考的考场,巡考员和管理员则可以查看全部考场
         examInvigilateUserQueryWrapper.lambda().eq(TBExamInvigilateUser::getOrgId, tbUser.getOrgId())
                 .eq(TBExamInvigilateUser::getExamId, examId);
@@ -448,66 +470,60 @@ public class TEExamController {
                 alreadyComplete = new HashSet<>();
                 //获取已待考、考试中、已完成学生
                 Set<Long> finalAlreadyComplete = alreadyComplete;
-                examActivityIdSet.forEach(s -> {
-                    Map<String, Object> objectMap = redisUtil
-                            .getHashEntries(RedisKeyHelper.examActivityRecordCacheKey(s));
-                    if (Objects.nonNull(objectMap) && objectMap.size() > 0) {
-                        objectMap.forEach((k, v) -> {
-                            Long recordId = Long.parseLong(k);
-                            ExamActivityRecordCacheBean examActivityRecordCacheBean = (ExamActivityRecordCacheBean) v;
-                            ExamRecordStatusEnum examRecordStatusEnum = examActivityRecordCacheBean.getStatus();
-                            ExamStudentCacheBean examStudentCacheBean = teExamStudentService
-                                    .getExamStudentCacheBean(examActivityRecordCacheBean.getExamStudentId());
-                            if (Objects.nonNull(examStudentCacheBean)
-                                    && examStudentCacheBean.getEnable().intValue() == 1 && Objects
-                                    .nonNull(examRecordStatusEnum) && !Objects
-                                    .equals(examRecordStatusEnum, ExamRecordStatusEnum.PERSISTED) && !Objects
-                                    .equals(examRecordStatusEnum, ExamRecordStatusEnum.FINISHED)) {
-                                //客户端通讯状态
-                                WebsocketStatusEnum clientStatus = Objects
-                                        .isNull(ExamRecordCacheUtil.getClientWebsocketStatus(recordId)) ?
-                                        null :
-                                        ExamRecordCacheUtil.getClientWebsocketStatus(recordId);
-                                if (Objects.nonNull(clientStatus) && Objects
-                                        .equals(clientStatus, WebsocketStatusEnum.OFF_LINE)) {
-                                    clientWebsocketStatusCount.getAndSet(clientWebsocketStatusCount.get() + 1);
-                                }
-                                //监控端通讯状态
-                                MonitorVideoSourceEnum source = null;
-                                if (Objects.nonNull(ExamRecordCacheUtil.getMonitorLiveUrlClientCamera(recordId))) {
-                                    source = MonitorVideoSourceEnum.CLIENT_CAMERA;
-                                } else if (Objects
-                                        .nonNull(ExamRecordCacheUtil.getMonitorLiveUrlClientScreen(recordId))) {
-                                    source = MonitorVideoSourceEnum.CLIENT_SCREEN;
-                                } else if (Objects
-                                        .nonNull(ExamRecordCacheUtil.getMonitorLiveUrlMobileFirst(recordId))) {
-                                    source = MonitorVideoSourceEnum.MOBILE_FIRST;
-                                } else if (Objects
-                                        .nonNull(ExamRecordCacheUtil.getMonitorLiveUrlMobileSecond(recordId))) {
-                                    source = MonitorVideoSourceEnum.MOBILE_SECOND;
-                                }
-                                MonitorStatusSourceEnum status = Objects.isNull(source) ?
-                                        null :
-                                        ExamRecordCacheUtil.getMonitorStatus(recordId, source);
-                                if (Objects.nonNull(status) && Objects.equals(status, MonitorStatusSourceEnum.STOP)) {
-                                    monitorStatusSourceCount.getAndSet(monitorStatusSourceCount.get() + 1);
-                                }
-                            }
-                            //已待考
-                            if (Objects.equals(examRecordStatusEnum, ExamRecordStatusEnum.FIRST_PREPARE)) {
-                                prepareCount.getAndSet(prepareCount.get() + 1);
-                            }
-                            //考试中
-                            else if (Objects.equals(examRecordStatusEnum, ExamRecordStatusEnum.ANSWERING)) {
-                                examCount.getAndSet(examCount.get() + 1);
-                            }
-                            //已完成
-                            else if (Objects.equals(examRecordStatusEnum, ExamRecordStatusEnum.FINISHED) || Objects
-                                    .equals(examRecordStatusEnum, ExamRecordStatusEnum.PERSISTED)) {
-                                finalAlreadyComplete.add(examActivityRecordCacheBean.getExamStudentId());
-                            }
-                        });
+                QueryWrapper<TOeExamRecord> tOeExamRecordQueryWrapper = new QueryWrapper<>();
+                tOeExamRecordQueryWrapper.lambda().in(TOeExamRecord::getExamActivityId, examActivityIdSet);
+                List<TOeExamRecord> examRecordList = tOeExamRecordService.list(tOeExamRecordQueryWrapper);
+                examRecordList.forEach(s -> {
+//                    Map<String, Object> objectMap = redisUtil
+//                            .getHashEntries(RedisKeyHelper.examActivityRecordCacheKey(s));
+//                    if (Objects.nonNull(objectMap) && objectMap.size() > 0) {
+//                        objectMap.forEach((k, v) -> {
+//                            Long recordId = Long.parseLong(k);
+//                            ExamActivityRecordCacheBean examActivityRecordCacheBean = (ExamActivityRecordCacheBean) v;
+                    ExamRecordStatusEnum examRecordStatusEnum = s.getStatus();
+//                            ExamStudentCacheBean examStudentCacheBean = teExamStudentService
+//                                    .getExamStudentCacheBean(examActivityRecordCacheBean.getExamStudentId());
+//                            if (Objects.nonNull(examStudentCacheBean)
+//                                    && examStudentCacheBean.getEnable().intValue() == 1) {
+                    //客户端通讯状态
+                    WebsocketStatusEnum clientStatus = Objects.isNull(s.getClientWebsocketStatus()) ? null : s.getClientWebsocketStatus();
+                    if (Objects
+                            .nonNull(examRecordStatusEnum) && !Objects
+                            .equals(examRecordStatusEnum, ExamRecordStatusEnum.PERSISTED) && !Objects
+                            .equals(examRecordStatusEnum, ExamRecordStatusEnum.FINISHED)) {
+                        if (Objects.nonNull(clientStatus) && Objects
+                                .equals(clientStatus, WebsocketStatusEnum.OFF_LINE)) {
+                            clientWebsocketStatusCount.getAndSet(clientWebsocketStatusCount.get() + 1);
+                        }
+                        //监控端通讯状态
+                        if (Objects.nonNull(s.getCameraMonitorStatus()) && Objects.equals(s.getCameraMonitorStatus(), MonitorStatusSourceEnum.STOP)) {
+                            monitorStatusSourceCount.getAndSet(monitorStatusSourceCount.get() + 1);
+                        } else if (Objects.nonNull(s.getScreenMonitorStatus()) && Objects.equals(s.getScreenMonitorStatus(), MonitorStatusSourceEnum.STOP)) {
+                            monitorStatusSourceCount.getAndSet(monitorStatusSourceCount.get() + 1);
+                        } else if (Objects.nonNull(s.getMobileFirstMonitorStatus()) && Objects.equals(s.getMobileFirstMonitorStatus(), MonitorStatusSourceEnum.STOP)) {
+                            monitorStatusSourceCount.getAndSet(monitorStatusSourceCount.get() + 1);
+                        } else if (Objects.nonNull(s.getMobileSecondMonitorStatus()) && Objects.equals(s.getMobileSecondMonitorStatus(), MonitorStatusSourceEnum.STOP)) {
+                            monitorStatusSourceCount.getAndSet(monitorStatusSourceCount.get() + 1);
+                        }
+                    }
+                    //已待考
+                    if (Objects.equals(examRecordStatusEnum, ExamRecordStatusEnum.FIRST_PREPARE) && Objects.nonNull(clientStatus) && Objects
+                            .equals(clientStatus, WebsocketStatusEnum.ON_LINE)) {
+                        prepareCount.getAndSet(prepareCount.get() + 1);
+                    }
+                    //考试中
+                    else if (Objects.equals(examRecordStatusEnum, ExamRecordStatusEnum.ANSWERING) && Objects.nonNull(clientStatus) && Objects
+                            .equals(clientStatus, WebsocketStatusEnum.ON_LINE)) {
+                        examCount.getAndSet(examCount.get() + 1);
+                    }
+                    //已完成
+                    else if (Objects.equals(examRecordStatusEnum, ExamRecordStatusEnum.FINISHED) || Objects
+                            .equals(examRecordStatusEnum, ExamRecordStatusEnum.PERSISTED)) {
+                        finalAlreadyComplete.add(s.getExamStudentId());
                     }
+//                            }
+//                        });
+//                    }
                 });
             }
             notComplete = allCount - alreadyComplete.size();
@@ -526,10 +542,11 @@ public class TEExamController {
     @ApiOperation(value = "考试重新算分")
     @RequestMapping(value = "/score/calculate", method = RequestMethod.POST)
     @Transactional
-    @ApiResponses({ @ApiResponse(code = 200, message = "{\"taskId\":0}", response = Result.class) })
+    @ApiResponses({@ApiResponse(code = 200, message = "{\"taskId\":0}", response = Result.class)})
     public Result scoreCalculate(@ApiParam(value = "批次ID", required = true) @RequestParam Long id) {
         //先查询考试相关信息
-        TEExam teExam = teExamService.getById(id);
+        ExamCacheBean examCacheBean = teExamService.getExamCacheBean(id);
+        TEExam teExam = teExamService.cacheConvert(examCacheBean);
         if (Objects.isNull(teExam)) {
             throw new BusinessException(ExceptionResultEnum.EXAM_NO);
         }
@@ -547,7 +564,7 @@ public class TEExamController {
             transMap.put("orgId", tbUser.getOrgId());
             transMap.put(SystemConstant.TASK_ID, tbTaskHistory.getId());
             //mq发送消息start
-            MqDto mqDto = new MqDto(MqTopicEnum.THEMIS_TOPIC.getCode(), MqTagEnum.EXAM_SCORE_CALCULATE.name(), transMap,
+            MqDto mqDto = new MqDto(mqUtil.getMqGroupDomain().getTopic(), MqTagEnum.EXAM_SCORE_CALCULATE.name(), transMap,
                     MqTagEnum.EXAM_SCORE_CALCULATE, String.valueOf(tbTaskHistory.getId()), tbUser.getName());
             mqDtoService.assembleSendOneWayMsg(mqDto);
             //mq发送消息end

+ 2 - 2
themis-backend/src/main/java/com/qmth/themis/backend/api/TEExamCourseController.java → themis-admin/src/main/java/com/qmth/themis/admin/api/TEExamCourseController.java

@@ -1,4 +1,4 @@
-package com.qmth.themis.backend.api;
+package com.qmth.themis.admin.api;
 
 import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
@@ -68,7 +68,7 @@ public class TEExamCourseController {
             }
         }
         teExamCourseService.updateExamCourseCacheBean(teExamCourse.getExamId(), teExamCourse.getCourseCode());
-        return ResultUtil.ok(Collections.singletonMap(SystemConstant.SUCCESS, true));
+        return ResultUtil.ok(true);
     }
 
     @ApiOperation(value = "考试科目查询接口")

+ 21 - 15
themis-backend/src/main/java/com/qmth/themis/backend/api/TEExamPaperController.java → themis-admin/src/main/java/com/qmth/themis/admin/api/TEExamPaperController.java

@@ -1,12 +1,14 @@
-package com.qmth.themis.backend.api;
+package com.qmth.themis.admin.api;
 
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.qmth.themis.business.cache.bean.ExamCacheBean;
 import com.qmth.themis.business.cache.bean.ExamPaperCacheBean;
 import com.qmth.themis.business.constant.SystemConstant;
 import com.qmth.themis.business.dto.MqDto;
 import com.qmth.themis.business.entity.*;
 import com.qmth.themis.business.enums.*;
 import com.qmth.themis.business.service.*;
+import com.qmth.themis.business.util.MqUtil;
 import com.qmth.themis.business.util.OssUtil;
 import com.qmth.themis.business.util.ServletUtil;
 import com.qmth.themis.common.enums.ExceptionResultEnum;
@@ -56,14 +58,17 @@ public class TEExamPaperController {
     @Resource
     OssUtil ossUtil;
 
+    @Resource
+    MqUtil mqUtil;
+
     @Resource
     TEExamCourseService examCourseService;
 
     @ApiOperation(value = "考试试卷查询接口")
     @RequestMapping(value = "/query", method = RequestMethod.POST)
-    @ApiResponses({ @ApiResponse(code = 200, message = "考试科目信息", response = TEExamPaper.class) })
+    @ApiResponses({@ApiResponse(code = 200, message = "考试科目信息", response = TEExamPaper.class)})
     public Result query(@ApiParam(value = "考试批次id", required = true) @RequestParam Long examId,
-            @ApiParam(value = "科目编码", required = true) @RequestParam String courseCode) {
+                        @ApiParam(value = "科目编码", required = true) @RequestParam String courseCode) {
         if (Objects.isNull(examId) || Objects.equals(examId, "")) {
             throw new BusinessException(ExceptionResultEnum.EXAM_ID_IS_NULL);
         }
@@ -78,7 +83,7 @@ public class TEExamPaperController {
     @ApiOperation(value = "考试试卷参数修改接口")
     @RequestMapping(value = "/save", method = RequestMethod.POST)
     @Transactional
-    @ApiResponses({ @ApiResponse(code = 200, message = "{\"success\":true}", response = Result.class) })
+    @ApiResponses({@ApiResponse(code = 200, message = "{\"success\":true}", response = Result.class)})
     public Result save(@ApiParam(value = "考试试卷信息", required = true) @RequestBody List<TEExamPaper> teExamPaperList) {
         if (Objects.isNull(teExamPaperList) || teExamPaperList.size() == 0) {
             throw new BusinessException(ExceptionResultEnum.PAPER_INFO_IS_NULL);
@@ -109,20 +114,20 @@ public class TEExamPaperController {
             ExamPaperCacheBean paper = teExamPaperService.getExamPaperCacheBean(s.getId());
             examCourseService.deleteExamCourseCacheBean(paper.getExamId(), paper.getCourseCode());
         });
-        return ResultUtil.ok(Collections.singletonMap(SystemConstant.SUCCESS, true));
+        return ResultUtil.ok(true);
     }
 
     @ApiOperation(value = "考试试卷数据包上传接口")
     @RequestMapping(value = "/import", method = RequestMethod.POST)
     @Transactional
-    @ApiResponses({ @ApiResponse(code = 200, message = "{\"taskId\":0}", response = Result.class) })
+    @ApiResponses({@ApiResponse(code = 200, message = "{\"taskId\":0}", response = Result.class)})
     public Result importData(@ApiParam(value = "上传文件", required = true) @RequestParam MultipartFile file,
-            @ApiParam(value = "批次ID", required = true) @RequestParam Long examId,
-            @ApiParam(value = "客观题乱序", required = false) @RequestParam Boolean objectiveShuffle,
-            @ApiParam(value = "选项乱序", required = false) @RequestParam Boolean optionShuffle,
-            @ApiParam(value = "音频播放次数", required = false) @RequestParam Integer audioPlayCount,
-            @ApiParam(value = "解析试卷", required = true) @RequestParam Boolean processPaper,
-            @ApiParam(value = "解析标答", required = true) @RequestParam Boolean processAnswer) {
+                             @ApiParam(value = "批次ID", required = true) @RequestParam Long examId,
+                             @ApiParam(value = "客观题乱序", required = false) @RequestParam Boolean objectiveShuffle,
+                             @ApiParam(value = "选项乱序", required = false) @RequestParam Boolean optionShuffle,
+                             @ApiParam(value = "音频播放次数", required = false) @RequestParam Integer audioPlayCount,
+                             @ApiParam(value = "解析试卷", required = true) @RequestParam Boolean processPaper,
+                             @ApiParam(value = "解析标答", required = true) @RequestParam Boolean processAnswer) {
         if (file == null) {
             throw new BusinessException(ExceptionResultEnum.ATTACHMENT_IS_NULL);
         }
@@ -153,10 +158,11 @@ public class TEExamPaperController {
             transMap.put("createId", tbUser.getId());
             transMap.put("orgId", tbUser.getOrgId());
             //先查询考试相关信息
-            TEExam teExam = teExamService.getById(examId);
-            if (Objects.isNull(teExam)) {
+            ExamCacheBean examCacheBean = teExamService.getExamCacheBean(examId);
+            if (Objects.isNull(examCacheBean)) {
                 throw new BusinessException(ExceptionResultEnum.EXAM_NO);
             }
+            TEExam teExam = teExamService.cacheConvert(examCacheBean);
             transMap.put("objectiveShuffle", objectiveShuffle);
             transMap.put("optionShuffle", optionShuffle);
             transMap.put("audioPlayCount", audioPlayCount);
@@ -164,7 +170,7 @@ public class TEExamPaperController {
             transMap.put("processAnswer", processAnswer);
             transMap.put("remark", tbAttachment.getRemark());
             //mq发送消息start
-            MqDto mqDto = new MqDto(MqTopicEnum.THEMIS_TOPIC.getCode(), MqTagEnum.EXAM_PAPER_IMPORT.name(), transMap,
+            MqDto mqDto = new MqDto(mqUtil.getMqGroupDomain().getTopic(), MqTagEnum.EXAM_PAPER_IMPORT.name(), transMap,
                     MqTagEnum.EXAM_PAPER_IMPORT, String.valueOf(tbTaskHistory.getId()), tbUser.getName());
             mqDtoService.assembleSendOneWayMsg(mqDto);
             //mq发送消息end

+ 8 - 5
themis-backend/src/main/java/com/qmth/themis/backend/api/TEExamReexamController.java → themis-admin/src/main/java/com/qmth/themis/admin/api/TEExamReexamController.java

@@ -1,10 +1,10 @@
-package com.qmth.themis.backend.api;
+package com.qmth.themis.admin.api;
 
 import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.qmth.themis.business.annotation.ApiJsonObject;
 import com.qmth.themis.business.annotation.ApiJsonProperty;
-import com.qmth.themis.business.bean.backend.ReexamListRequestBean;
+import com.qmth.themis.business.bean.admin.ReexamListRequestBean;
 import com.qmth.themis.business.cache.bean.ExamCacheBean;
 import com.qmth.themis.business.cache.bean.ExamStudentCacheBean;
 import com.qmth.themis.business.constant.SystemConstant;
@@ -62,6 +62,9 @@ public class TEExamReexamController {
     @Resource
     TEExamStudentService teExamStudentService;
 
+    @Resource
+    CacheService cacheService;
+
     @ApiOperation(value = "重考申请接口")
     @RequestMapping(value = "/apply", method = RequestMethod.POST)
     @ApiResponses({@ApiResponse(code = 200, message = "{\"success\":true}", response = Result.class)})
@@ -151,7 +154,7 @@ public class TEExamReexamController {
                 });
             }
         }
-        return ResultUtil.ok(Collections.singletonMap(SystemConstant.SUCCESS, true));
+        return ResultUtil.ok(true);
     }
 
     @ApiOperation(value = "重考审核接口")
@@ -227,7 +230,7 @@ public class TEExamReexamController {
                 throw new RuntimeException(e);
             }
         }
-        return ResultUtil.ok(Collections.singletonMap(SystemConstant.SUCCESS, true));
+        return ResultUtil.ok(true);
     }
 
     @ApiOperation(value = "重考审核明细接口")
@@ -252,7 +255,7 @@ public class TEExamReexamController {
                        @ApiParam(value = "分页页码", required = true) @RequestParam int pageNumber,
                        @ApiParam(value = "分页数", required = true) @RequestParam int pageSize) {
         TBUser tbUser = (TBUser) ServletUtil.getRequestAccount();
-        AuthDto authDto = (AuthDto) redisUtil.get(SystemConstant.userOauth + "::" + tbUser.getId());
+        AuthDto authDto = cacheService.addAccountAuthCache(tbUser.getId());
         //如果有监考员角色,只能查看自己所监考的考场,巡考员和管理员则可以查看全部考场
         Long userId = null;
         if (authDto.getRoleCodes().toString().contains(RoleEnum.INVIGILATE.name())) {

+ 83 - 77
themis-backend/src/main/java/com/qmth/themis/backend/api/TEExamStudentController.java → themis-admin/src/main/java/com/qmth/themis/admin/api/TEExamStudentController.java

@@ -1,4 +1,4 @@
-package com.qmth.themis.backend.api;
+package com.qmth.themis.admin.api;
 
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
@@ -16,6 +16,7 @@ import com.qmth.themis.business.dto.response.TEExamStudentDto;
 import com.qmth.themis.business.entity.*;
 import com.qmth.themis.business.enums.*;
 import com.qmth.themis.business.service.*;
+import com.qmth.themis.business.util.MqUtil;
 import com.qmth.themis.business.util.OssUtil;
 import com.qmth.themis.business.util.ServletUtil;
 import com.qmth.themis.common.enums.ExceptionResultEnum;
@@ -83,18 +84,21 @@ public class TEExamStudentController {
     @Resource
     TOeExamRecordService tOeExamRecordService;
 
+    @Resource
+    MqUtil mqUtil;
+
     @ApiOperation(value = "考生导出")
     @RequestMapping(value = "/export", method = RequestMethod.POST)
     public Result export(@ApiParam(value = "考试批次id", required = true) @RequestParam Long examId,
-            @ApiParam(value = "考试场次id", required = false) @RequestParam(required = false) Long activityId,
-            @ApiParam(value = "证件号", required = false) @RequestParam(required = false) String identity,
-            @ApiParam(value = "姓名", required = false) @RequestParam(required = false) String name,
-            @ApiParam(value = "考场代码", required = false) @RequestParam(required = false) String roomCode,
-            @ApiParam(value = "科目代码", required = false) @RequestParam(required = false) String courseCode,
-            @ApiParam(value = "年级", required = false) @RequestParam(required = false) String grade,
-            @ApiParam(value = "是否启用", required = false) @RequestParam(required = false) Integer enable,
-            @ApiParam(value = "教学班级", required = false) @RequestParam(required = false) String classNo,
-            @ApiParam(value = "底照是否上传", required = false) @RequestParam(required = false) Integer hasPhoto)
+                         @ApiParam(value = "考试场次id", required = false) @RequestParam(required = false) Long activityId,
+                         @ApiParam(value = "证件号", required = false) @RequestParam(required = false) String identity,
+                         @ApiParam(value = "姓名", required = false) @RequestParam(required = false) String name,
+                         @ApiParam(value = "考场代码", required = false) @RequestParam(required = false) String roomCode,
+                         @ApiParam(value = "科目代码", required = false) @RequestParam(required = false) String courseCode,
+                         @ApiParam(value = "年级", required = false) @RequestParam(required = false) String grade,
+                         @ApiParam(value = "是否启用", required = false) @RequestParam(required = false) Integer enable,
+                         @ApiParam(value = "教学班级", required = false) @RequestParam(required = false) String classNo,
+                         @ApiParam(value = "底照是否上传", required = false) @RequestParam(required = false) Integer hasPhoto)
             throws Exception {
         TBTaskHistory tbTaskHistory = null;
         Map<String, Object> transMap = new HashMap<String, Object>();
@@ -119,7 +123,7 @@ public class TEExamStudentController {
         transMap.put("createId", tbUser.getId());
 
         //mq发送消息start
-        MqDto mqDto = new MqDto(MqTopicEnum.THEMIS_TOPIC.getCode(), MqTagEnum.EXAM_STUDENT_EXPORT.name(), transMap,
+        MqDto mqDto = new MqDto(mqUtil.getMqGroupDomain().getTopic(), MqTagEnum.EXAM_STUDENT_EXPORT.name(), transMap,
                 MqTagEnum.EXAM_STUDENT_EXPORT, String.valueOf(tbTaskHistory.getId()), tbUser.getName());
 
         mqDtoService.assembleSendOneWayMsg(mqDto);
@@ -129,19 +133,19 @@ public class TEExamStudentController {
 
     @ApiOperation(value = "考生查询接口")
     @RequestMapping(value = "/query", method = RequestMethod.POST)
-    @ApiResponses({ @ApiResponse(code = 200, message = "考生信息", response = TEExamStudentDto.class) })
+    @ApiResponses({@ApiResponse(code = 200, message = "考生信息", response = TEExamStudentDto.class)})
     public Result query(@ApiParam(value = "考试批次id", required = true) @RequestParam Long examId,
-            @ApiParam(value = "考试场次id", required = false) @RequestParam(required = false) Long activityId,
-            @ApiParam(value = "证件号", required = false) @RequestParam(required = false) String identity,
-            @ApiParam(value = "姓名", required = false) @RequestParam(required = false) String name,
-            @ApiParam(value = "考场代码", required = false) @RequestParam(required = false) String roomCode,
-            @ApiParam(value = "科目代码", required = false) @RequestParam(required = false) String courseCode,
-            @ApiParam(value = "年级", required = false) @RequestParam(required = false) String grade,
-            @ApiParam(value = "是否启用", required = false) @RequestParam(required = false) Integer enable,
-            @ApiParam(value = "教学班级", required = false) @RequestParam(required = false) String classNo,
-            @ApiParam(value = "底照是否上传", required = false) @RequestParam(required = false) Integer hasPhoto,
-            @ApiParam(value = "分页页码", required = true) @RequestParam int pageNumber,
-            @ApiParam(value = "分页数", required = true) @RequestParam int pageSize) {
+                        @ApiParam(value = "考试场次id", required = false) @RequestParam(required = false) Long activityId,
+                        @ApiParam(value = "证件号", required = false) @RequestParam(required = false) String identity,
+                        @ApiParam(value = "姓名", required = false) @RequestParam(required = false) String name,
+                        @ApiParam(value = "考场代码", required = false) @RequestParam(required = false) String roomCode,
+                        @ApiParam(value = "科目代码", required = false) @RequestParam(required = false) String courseCode,
+                        @ApiParam(value = "年级", required = false) @RequestParam(required = false) String grade,
+                        @ApiParam(value = "是否启用", required = false) @RequestParam(required = false) Integer enable,
+                        @ApiParam(value = "教学班级", required = false) @RequestParam(required = false) String classNo,
+                        @ApiParam(value = "底照是否上传", required = false) @RequestParam(required = false) Integer hasPhoto,
+                        @ApiParam(value = "分页页码", required = true) @RequestParam int pageNumber,
+                        @ApiParam(value = "分页数", required = true) @RequestParam int pageSize) {
         if (Objects.isNull(examId) || Objects.equals(examId, "")) {
             throw new BusinessException(ExceptionResultEnum.EXAM_ID_IS_NULL);
         }
@@ -161,11 +165,11 @@ public class TEExamStudentController {
 
     @ApiOperation(value = "考生停用/启用接口")
     @RequestMapping(value = "/toggle", method = RequestMethod.POST)
-    @ApiResponses({ @ApiResponse(code = 200, message = "{\"success\":true}", response = Result.class) })
+    @ApiResponses({@ApiResponse(code = 200, message = "{\"success\":true}", response = Result.class)})
     @Transactional
     public Result examStudentToggle(@ApiJsonObject(name = "examStudentToggle", value = {
             @ApiJsonProperty(key = "id", type = "long", example = "1", description = "考生ID"),
-            @ApiJsonProperty(key = "enable", type = "int", example = "1", description = "是否启用") }) @ApiParam(value = "考生信息", required = true) @RequestBody List<Map<String, Object>> mapParameter) {
+            @ApiJsonProperty(key = "enable", type = "int", example = "1", description = "是否启用")}) @ApiParam(value = "考生信息", required = true) @RequestBody List<Map<String, Object>> mapParameter) {
         if (Objects.isNull(mapParameter) || mapParameter.size() == 0) {
             throw new BusinessException(ExceptionResultEnum.EXAM_STUDENT_INFO_IS_NULL);
         }
@@ -185,12 +189,12 @@ public class TEExamStudentController {
         teExamStudentList.forEach(s -> {
             teExamStudentService.updateExamStudentCacheBean(s.getId());
         });
-        return ResultUtil.ok(Collections.singletonMap(SystemConstant.SUCCESS, true));
+        return ResultUtil.ok(true);
     }
 
     @ApiOperation(value = "考生修改接口")
     @RequestMapping(value = "/save", method = RequestMethod.POST)
-    @ApiResponses({ @ApiResponse(code = 200, message = "{\"success\":true}", response = Result.class) })
+    @ApiResponses({@ApiResponse(code = 200, message = "{\"success\":true}", response = Result.class)})
     @Transactional
     public Result save(@ApiParam(value = "考生信息", required = true) @RequestBody List<TEExamStudent> teExamStudentList) {
         if (Objects.isNull(teExamStudentList) || teExamStudentList.size() == 0) {
@@ -199,29 +203,30 @@ public class TEExamStudentController {
         TBUser tbUser = (TBUser) ServletUtil.getRequestAccount();
         TBOrg tbOrg = (TBOrg) ServletUtil.getRequestOrg();
         teExamStudentList.forEach(s -> {
-            if (Objects.isNull(s.getId())) {
-                QueryWrapper<TEStudent> teExamStudentQueryWrapper = new QueryWrapper<>();
-                teExamStudentQueryWrapper.lambda().eq(TEStudent::getName, s.getName())
-                        .eq(TEStudent::getIdentity, s.getIdentity()).eq(TEStudent::getOrgId, tbOrg.getId());
-                TEStudent student = teStudentService.getOne(teExamStudentQueryWrapper);
-                if (student == null) {
-                    TEStudent teStudent = new TEStudent(tbOrg.getId(), s.getIdentity(), s.getName(), tbUser.getId());
+            QueryWrapper<TEExamStudent> teExamStudentQueryWrapper = new QueryWrapper<>();
+            teExamStudentQueryWrapper.lambda().eq(TEExamStudent::getIdentity, s.getIdentity())
+                    .eq(TEExamStudent::getCourseCode, s.getCourseCode())
+                    .eq(TEExamStudent::getExamId, s.getExamId())
+                    .eq(TEExamStudent::getExamActivityId, s.getExamActivityId());
+            TEExamStudent teExamStudent = teExamStudentService.getOne(teExamStudentQueryWrapper);
+
+            QueryWrapper<TEStudent> teStudentQueryWrapper = new QueryWrapper<>();
+            teStudentQueryWrapper.lambda().eq(TEStudent::getIdentity, s.getIdentity()).eq(TEStudent::getOrgId, tbOrg.getId());
+            TEStudent teStudent = teStudentService.getOne(teStudentQueryWrapper);
+
+            if (Objects.isNull(teExamStudent)) {
+                if (Objects.isNull(teStudent)) {//如果学生数据为空则插入学生数据
+                    //先插入学生档案数据
+                    teStudent = new TEStudent(tbOrg.getId(), s.getIdentity(), s.getName(), tbUser.getId());
                     teStudentService.save(teStudent);
                     s.setStudentId(teStudent.getId());
                     s.setCreateId(tbUser.getId());
-                } else {
-                    s.setStudentId(student.getId());
-                    s.setCreateId(tbUser.getId());
                 }
             } else {
-                UpdateWrapper<TEExamStudent> teExamStudentUpdateWrapper = new UpdateWrapper<>();
-                teExamStudentUpdateWrapper.lambda().set(TEExamStudent::getName, s.getName())
-                        .eq(TEExamStudent::getIdentity, s.getIdentity());
-                teExamStudentService.update(teExamStudentUpdateWrapper);
-
                 UpdateWrapper<TEStudent> teStudentUpdateWrapper = new UpdateWrapper<>();
                 teStudentUpdateWrapper.lambda().set(TEStudent::getName, s.getName())
-                        .eq(TEStudent::getIdentity, s.getIdentity());
+                        .eq(TEStudent::getIdentity, s.getIdentity())
+                        .eq(TEStudent::getOrgId, tbOrg.getId());
                 teStudentService.update(teStudentUpdateWrapper);
                 s.setUpdateId(tbUser.getId());
             }
@@ -235,26 +240,26 @@ public class TEExamStudentController {
             if (Objects.nonNull(roomCodeQueryDtoList)) {
                 Map<String, RoomCodeQueryDto> roomCodeQueryDtoMap = roomCodeQueryDtoList.stream().collect(
                         Collectors.toMap(RoomCodeQueryDto::getRoomCode, Function.identity(), (dto1, dto2) -> dto1));
-                String roomName = roomCodeQueryDtoMap.get(s.getRoomCode()).getRoomName();
-                if (Objects.isNull(roomName)) {
-                    throw new BusinessException("考场不存在");
+                if (Objects.nonNull(s.getRoomCode())) {
+                    String roomName = roomCodeQueryDtoMap.get(s.getRoomCode()).getRoomName();
+                    if (Objects.isNull(roomName)) {
+                        throw new BusinessException("考场不存在");
+                    }
+                    s.setRoomName(roomCodeQueryDtoMap.get(s.getRoomCode()).getRoomName());
                 }
-                s.setRoomName(roomCodeQueryDtoMap.get(s.getRoomCode()).getRoomName());
-            }
-            if (s.getAlreadyExamCount() == null) {
-                s.setAlreadyExamCount(0);
             }
+            s.setAlreadyExamCount(Objects.isNull(s.getAlreadyExamCount()) ? 0 : s.getAlreadyExamCount());
             teExamStudentService.saveOrUpdate(s);
         });
         for (TEExamStudent es : teExamStudentList) {
             teExamStudentService.updateExamStudentCacheBean(es.getId());
         }
-        return ResultUtil.ok(Collections.singletonMap(SystemConstant.SUCCESS, true));
+        return ResultUtil.ok(true);
     }
 
     @ApiOperation(value = "考生删除接口")
     @RequestMapping(value = "/delete", method = RequestMethod.POST)
-    @ApiResponses({ @ApiResponse(code = 200, message = "{\"success\":true}", response = Result.class) })
+    @ApiResponses({@ApiResponse(code = 200, message = "{\"success\":true}", response = Result.class)})
     @Transactional
     public Result delete(@ApiParam(value = "考生id", required = true) @RequestBody List<Long> ids) {
         if (Objects.isNull(ids) || ids.size() == 0) {
@@ -264,15 +269,15 @@ public class TEExamStudentController {
         ids.forEach(s -> {
             teExamStudentService.deleteExamStudentCacheBean(s);
         });
-        return ResultUtil.ok(Collections.singletonMap(SystemConstant.SUCCESS, true));
+        return ResultUtil.ok(true);
     }
 
     @ApiOperation(value = "考生导入接口")
     @RequestMapping(value = "/import", method = RequestMethod.POST)
     @Transactional
-    @ApiResponses({ @ApiResponse(code = 200, message = "{\"taskId\":0}", response = Result.class) })
+    @ApiResponses({@ApiResponse(code = 200, message = "{\"taskId\":0}", response = Result.class)})
     public Result importData(@ApiParam(value = "上传文件", required = true) @RequestParam MultipartFile file,
-            @ApiParam(value = "考试批次id", required = true) @RequestParam Long examId) throws IOException {
+                             @ApiParam(value = "考试批次id", required = true) @RequestParam Long examId) throws IOException {
         if (Objects.isNull(file) || Objects.equals(file, "")) {
             throw new BusinessException(ExceptionResultEnum.ATTACHMENT_IS_NULL);
         }
@@ -303,10 +308,11 @@ public class TEExamStudentController {
             transMap.put("createId", tbUser.getId());
 
             // 先查询考试相关信息
-            TEExam teExam = teExamService.getById(examId);
-            if (Objects.isNull(teExam)) {
+            ExamCacheBean examCacheBean = teExamService.getExamCacheBean(examId);
+            if (Objects.isNull(examCacheBean)) {
                 throw new BusinessException(ExceptionResultEnum.EXAM_NO);
             }
+            TEExam teExam = teExamService.cacheConvert(examCacheBean);
             transMap.put("mode", teExam.getMode());
             transMap.put("orgId", teExam.getOrgId());
             transMap.put("examCount", teExam.getExamCount());
@@ -335,7 +341,7 @@ public class TEExamStudentController {
             }
             transMap.put("remark", tbAttachment.getRemark());
             // mq发送消息start
-            MqDto mqDto = new MqDto(MqTopicEnum.THEMIS_TOPIC.getCode(), MqTagEnum.EXAM_STUDENT_IMPORT.name(), transMap,
+            MqDto mqDto = new MqDto(mqUtil.getMqGroupDomain().getTopic(), MqTagEnum.EXAM_STUDENT_IMPORT.name(), transMap,
                     MqTagEnum.EXAM_STUDENT_IMPORT, String.valueOf(tbTaskHistory.getId()), tbUser.getName());
             mqDtoService.assembleSendOneWayMsg(mqDto);
             // mq发送消息end
@@ -355,14 +361,14 @@ public class TEExamStudentController {
 
     @ApiOperation(value = "成绩查询接口")
     @RequestMapping(value = "/mark/result", method = RequestMethod.POST)
-    @ApiResponses({ @ApiResponse(code = 200, message = "考试批次信息", response = MarkResultDto.class) })
+    @ApiResponses({@ApiResponse(code = 200, message = "考试批次信息", response = MarkResultDto.class)})
     public Result markResult(@ApiParam(value = "考试批次id", required = true) @RequestParam Long examId,
-            @ApiParam(value = "考试场次id", required = false) @RequestParam(required = false) Long activityId,
-            @ApiParam(value = "证件号", required = false) @RequestParam(required = false) String identity,
-            @ApiParam(value = "姓名", required = false) @RequestParam(required = false) String name,
-            @ApiParam(value = "科目代码", required = false) @RequestParam(required = false) String courseCode,
-            @ApiParam(value = "分页页码", required = true) @RequestParam int pageNumber,
-            @ApiParam(value = "分页数", required = true) @RequestParam int pageSize) {
+                             @ApiParam(value = "考试场次id", required = false) @RequestParam(required = false) Long activityId,
+                             @ApiParam(value = "证件号", required = false) @RequestParam(required = false) String identity,
+                             @ApiParam(value = "姓名", required = false) @RequestParam(required = false) String name,
+                             @ApiParam(value = "科目代码", required = false) @RequestParam(required = false) String courseCode,
+                             @ApiParam(value = "分页页码", required = true) @RequestParam int pageNumber,
+                             @ApiParam(value = "分页数", required = true) @RequestParam int pageSize) {
         if (Objects.isNull(examId) || Objects.equals(examId, "")) {
             throw new BusinessException(ExceptionResultEnum.EXAM_ID_IS_NULL);
         }
@@ -395,12 +401,12 @@ public class TEExamStudentController {
     @ApiOperation(value = "成绩查询简版导出接口")
     @RequestMapping(value = "/mark/result/simple/export", method = RequestMethod.POST)
     @Transactional
-    @ApiResponses({ @ApiResponse(code = 200, message = "{\"taskId\":0}", response = Result.class) })
+    @ApiResponses({@ApiResponse(code = 200, message = "{\"taskId\":0}", response = Result.class)})
     public Result markResultSimpleExport(@ApiParam(value = "考试批次id", required = true) @RequestParam Long examId,
-            @ApiParam(value = "考试场次id", required = false) @RequestParam(required = false) Long activityId,
-            @ApiParam(value = "证件号", required = false) @RequestParam(required = false) String identity,
-            @ApiParam(value = "姓名", required = false) @RequestParam(required = false) String name,
-            @ApiParam(value = "科目代码", required = false) @RequestParam(required = false) String courseCode) {
+                                         @ApiParam(value = "考试场次id", required = false) @RequestParam(required = false) Long activityId,
+                                         @ApiParam(value = "证件号", required = false) @RequestParam(required = false) String identity,
+                                         @ApiParam(value = "姓名", required = false) @RequestParam(required = false) String name,
+                                         @ApiParam(value = "科目代码", required = false) @RequestParam(required = false) String courseCode) {
         if (Objects.isNull(examId) || Objects.equals(examId, "")) {
             throw new BusinessException(ExceptionResultEnum.EXAM_ID_IS_NULL);
         }
@@ -423,7 +429,7 @@ public class TEExamStudentController {
             transMap.put("name", name);
             transMap.put("courseCode", courseCode);
             //mq发送消息start
-            MqDto mqDto = new MqDto(MqTopicEnum.THEMIS_TOPIC.getCode(), MqTagEnum.MARK_RESULT_SIMPLE_EXPORT.name(),
+            MqDto mqDto = new MqDto(mqUtil.getMqGroupDomain().getTopic(), MqTagEnum.MARK_RESULT_SIMPLE_EXPORT.name(),
                     transMap, MqTagEnum.MARK_RESULT_SIMPLE_EXPORT, String.valueOf(tbTaskHistory.getId()),
                     tbUser.getName());
             mqDtoService.assembleSendOneWayMsg(mqDto);
@@ -442,12 +448,12 @@ public class TEExamStudentController {
     @ApiOperation(value = "成绩查询标准版导出接口")
     @RequestMapping(value = "/mark/result/standard/export", method = RequestMethod.POST)
     @Transactional
-    @ApiResponses({ @ApiResponse(code = 200, message = "{\"taskId\":0}", response = Result.class) })
+    @ApiResponses({@ApiResponse(code = 200, message = "{\"taskId\":0}", response = Result.class)})
     public Result markResultStandardExport(@ApiParam(value = "考试批次id", required = true) @RequestParam Long examId,
-            @ApiParam(value = "考试场次id", required = false) @RequestParam(required = false) Long activityId,
-            @ApiParam(value = "证件号", required = false) @RequestParam(required = false) String identity,
-            @ApiParam(value = "姓名", required = false) @RequestParam(required = false) String name,
-            @ApiParam(value = "科目代码", required = false) @RequestParam(required = false) String courseCode) {
+                                           @ApiParam(value = "考试场次id", required = false) @RequestParam(required = false) Long activityId,
+                                           @ApiParam(value = "证件号", required = false) @RequestParam(required = false) String identity,
+                                           @ApiParam(value = "姓名", required = false) @RequestParam(required = false) String name,
+                                           @ApiParam(value = "科目代码", required = false) @RequestParam(required = false) String courseCode) {
         if (Objects.isNull(examId) || Objects.equals(examId, "")) {
             throw new BusinessException(ExceptionResultEnum.EXAM_ID_IS_NULL);
         }
@@ -470,7 +476,7 @@ public class TEExamStudentController {
             transMap.put("name", name);
             transMap.put("courseCode", courseCode);
             //mq发送消息start
-            MqDto mqDto = new MqDto(MqTopicEnum.THEMIS_TOPIC.getCode(), MqTagEnum.MARK_RESULT_STANDARD_EXPORT.name(),
+            MqDto mqDto = new MqDto(mqUtil.getMqGroupDomain().getTopic(), MqTagEnum.MARK_RESULT_STANDARD_EXPORT.name(),
                     transMap, MqTagEnum.MARK_RESULT_STANDARD_EXPORT, String.valueOf(tbTaskHistory.getId()),
                     tbUser.getName());
             mqDtoService.assembleSendOneWayMsg(mqDto);

+ 13 - 14
themis-backend/src/main/java/com/qmth/themis/backend/api/TEOpenController.java → themis-admin/src/main/java/com/qmth/themis/admin/api/TEOpenController.java

@@ -1,4 +1,4 @@
-package com.qmth.themis.backend.api;
+package com.qmth.themis.admin.api;
 
 import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
@@ -33,9 +33,9 @@ public class TEOpenController {
     @RequestMapping(value = "/exam/query", method = RequestMethod.POST)
     @ApiResponses({ @ApiResponse(code = 200, message = "结果信息") })
     public Object examQueryPage(@ApiParam(value = "考试id", required = false) @RequestParam(required = false) Long id,
-            @ApiParam(value = "考试code", required = false) @RequestParam(required = false) String code,
-            @ApiParam(value = "分页页码", required = false) @RequestParam(required = false) Integer pageNumber,
-            @ApiParam(value = "分页数", required = false) @RequestParam(required = false) Integer pageSize) {
+                                @ApiParam(value = "考试code", required = false) @RequestParam(required = false) String code,
+                                @ApiParam(value = "分页页码", required = false) @RequestParam(required = false) Integer pageNumber,
+                                @ApiParam(value = "分页数", required = false) @RequestParam(required = false) Integer pageSize) {
         if (pageNumber == null || pageNumber < 1) {
             pageNumber = 1;
         }
@@ -49,10 +49,10 @@ public class TEOpenController {
     @RequestMapping(value = "/exam/course/query", method = RequestMethod.POST)
     @ApiResponses({ @ApiResponse(code = 200, message = "结果信息") })
     public Object examCourseQueryPage(@ApiParam(value = "考试id", required = true) @RequestParam Long examId,
-            @ApiParam(value = "课程code", required = false) @RequestParam(required = false) String courseCode,
-            @ApiParam(value = "是否有试卷", required = false) @RequestParam(required = false) Boolean hasPaper,
-            @ApiParam(value = "分页页码", required = false) @RequestParam(required = false) Integer pageNumber,
-            @ApiParam(value = "分页数", required = false) @RequestParam(required = false) Integer pageSize) {
+                                      @ApiParam(value = "课程code", required = false) @RequestParam(required = false) String courseCode,
+                                      @ApiParam(value = "是否有试卷", required = false) @RequestParam(required = false) Boolean hasPaper,
+                                      @ApiParam(value = "分页页码", required = false) @RequestParam(required = false) Integer pageNumber,
+                                      @ApiParam(value = "分页数", required = false) @RequestParam(required = false) Integer pageSize) {
         if (pageNumber == null || pageNumber < 1) {
             pageNumber = 1;
         }
@@ -70,7 +70,7 @@ public class TEOpenController {
     @RequestMapping(value = "/exam/paper/detail", method = RequestMethod.POST)
     @ApiResponses({ @ApiResponse(code = 200, message = "结果信息") })
     public JSONObject examPaperDetail(@ApiParam(value = "试卷id", required = true) @RequestParam Long id,
-            @ApiParam(value = "内容过滤", required = false) @RequestParam(required = false) String filter)
+                                      @ApiParam(value = "内容过滤", required = false) @RequestParam(required = false) String filter)
             throws IOException {
         filter = StringUtils.trimToNull(filter);
         if (filter != null && !"objective".equals(filter) && !"subjective".equals(filter)) {
@@ -83,9 +83,9 @@ public class TEOpenController {
     @RequestMapping(value = "/exam/record/need_mark", method = RequestMethod.POST)
     @ApiResponses({ @ApiResponse(code = 200, message = "结果信息") })
     public JSONArray examRecordNeedMark(@ApiParam(value = "考试id", required = true) @RequestParam Long examId,
-            @ApiParam(value = "课程代码", required = false) @RequestParam(required = false) String courseCode,
-            @ApiParam(value = "考生ID大于此参数", required = false) @RequestParam(required = false) Long examStudentIdGt,
-            @ApiParam(value = "数量(最大20)", required = false) @RequestParam(required = false) Integer count) {
+                                        @ApiParam(value = "课程代码", required = false) @RequestParam(required = false) String courseCode,
+                                        @ApiParam(value = "考生ID大于此参数", required = false) @RequestParam(required = false) Long examStudentIdGt,
+                                        @ApiParam(value = "数量(最大20)", required = false) @RequestParam(required = false) Integer count) {
         if (examStudentIdGt == null || examStudentIdGt < 0) {
             examStudentIdGt = 0L;
         }
@@ -94,5 +94,4 @@ public class TEOpenController {
         }
         return openService.examRecordNeedMark(examId, StringUtils.trimToNull(courseCode), examStudentIdGt, count);
     }
-
-}
+}

+ 8 - 16
themis-backend/src/main/java/com/qmth/themis/backend/api/TEStudentController.java → themis-admin/src/main/java/com/qmth/themis/admin/api/TEStudentController.java

@@ -1,19 +1,16 @@
-package com.qmth.themis.backend.api;
+package com.qmth.themis.admin.api;
 
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
-import com.google.gson.Gson;
 import com.qmth.themis.business.annotation.ApiJsonObject;
 import com.qmth.themis.business.annotation.ApiJsonProperty;
-import com.qmth.themis.business.constant.SystemConstant;
-import com.qmth.themis.business.dto.cache.TEStudentCacheDto;
 import com.qmth.themis.business.dto.response.TEStudentDto;
 import com.qmth.themis.business.entity.TBUser;
 import com.qmth.themis.business.entity.TEStudent;
 import com.qmth.themis.business.entity.TOeExamRecord;
+import com.qmth.themis.business.service.CacheService;
 import com.qmth.themis.business.service.TEStudentService;
 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.common.enums.ExceptionResultEnum;
 import com.qmth.themis.common.exception.BusinessException;
@@ -26,7 +23,6 @@ import org.springframework.web.bind.annotation.*;
 import org.springframework.web.multipart.MultipartFile;
 
 import javax.annotation.Resource;
-import java.util.Collections;
 import java.util.Map;
 import java.util.Objects;
 
@@ -46,10 +42,10 @@ public class TEStudentController {
     TEStudentService teStudentService;
 
     @Resource
-    RedisUtil redisUtil;
+    OssUtil ossUtil;
 
     @Resource
-    OssUtil ossUtil;
+    CacheService cacheService;
 
     @ApiOperation(value = "学生查询接口")
     @RequestMapping(value = "/query", method = RequestMethod.POST)
@@ -91,10 +87,8 @@ public class TEStudentController {
         teStudent.setEnable(enable);
         teStudent.setUpdateId(tbUser.getId());
         teStudentService.updateById(teStudent);
-        Gson gson = new Gson();
-        TEStudentCacheDto teStudentCacheDto = gson.fromJson(gson.toJson(teStudent), TEStudentCacheDto.class);
-        redisUtil.setStudent(teStudent.getId(), teStudentCacheDto);
-        return ResultUtil.ok(Collections.singletonMap(SystemConstant.SUCCESS, true));
+        cacheService.updateStudentAccountCache(teStudent.getId());
+        return ResultUtil.ok(true);
     }
 
     @ApiOperation(value = "学生修改密码接口")
@@ -121,10 +115,8 @@ public class TEStudentController {
         teStudent.setPassword(password);
         teStudent.setUpdateId(tbUser.getId());
         teStudentService.updateById(teStudent);
-        Gson gson = new Gson();
-        TEStudentCacheDto teStudentCacheDto = gson.fromJson(gson.toJson(teStudent), TEStudentCacheDto.class);
-        redisUtil.setStudent(teStudent.getId(), teStudentCacheDto);
-        return ResultUtil.ok(Collections.singletonMap(SystemConstant.SUCCESS, true));
+        cacheService.updateStudentAccountCache(teStudent.getId());
+        return ResultUtil.ok(true);
     }
 
     @ApiOperation(value = "学生考试记录查询接口")

+ 37 - 31
themis-backend/src/main/java/com/qmth/themis/backend/api/TIeInvigilateCallMobileController.java → themis-admin/src/main/java/com/qmth/themis/admin/api/TIeInvigilateCallMobileController.java

@@ -1,10 +1,10 @@
-package com.qmth.themis.backend.api;
+package com.qmth.themis.admin.api;
 
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.google.common.collect.Sets;
-import com.qmth.themis.backend.config.DictionaryConfig;
+import com.qmth.themis.admin.config.DictionaryConfig;
 import com.qmth.themis.business.annotation.ApiJsonObject;
 import com.qmth.themis.business.annotation.ApiJsonProperty;
 import com.qmth.themis.business.bean.mobile.MobileAuthorizationMonitorBean;
@@ -45,7 +45,6 @@ import java.util.*;
 @RestController
 @RequestMapping("/${prefix.url.admin}/monitor")
 public class TIeInvigilateCallMobileController {
-
     private final static Logger log = LoggerFactory.getLogger(TIeInvigilateCallMobileController.class);
 
     @Resource
@@ -66,22 +65,25 @@ public class TIeInvigilateCallMobileController {
     @Resource
     DictionaryConfig dictionaryConfig;
 
-    @Resource
-    TEExamService teExamService;
-
     @Resource
     TOeExamRecordService tOeExamRecordService;
 
     @Resource
     TEExamStudentService teExamStudentService;
 
+    @Resource
+    MqUtil mqUtil;
+
+    @Resource
+    CacheService cacheService;
+
     @ApiOperation(value = "监考监控通话查询接口")
     @RequestMapping(value = "/call/list", method = RequestMethod.POST)
-    @ApiResponses({ @ApiResponse(code = 200, message = "监考监控信息", response = TIeExamInvigilateCallDto.class) })
+    @ApiResponses({@ApiResponse(code = 200, message = "监考监控信息", response = TIeExamInvigilateCallDto.class)})
     public Result callList(@ApiParam(value = "考试批次id", required = true) @RequestParam(required = true) Long examId,
-            @ApiParam(value = "通话状态", required = false) @RequestParam(required = false) String callStatus,
-            @ApiParam(value = "分页页码", required = true) @RequestParam int pageNumber,
-            @ApiParam(value = "分页数", required = true) @RequestParam int pageSize) {
+                           @ApiParam(value = "通话状态", required = false) @RequestParam(required = false) String callStatus,
+                           @ApiParam(value = "分页页码", required = true) @RequestParam int pageNumber,
+                           @ApiParam(value = "分页数", required = true) @RequestParam int pageSize) {
         if (Objects.isNull(examId) || Objects.equals(examId, "")) {
             throw new BusinessException(ExceptionResultEnum.EXAM_ID_IS_NULL);
         }
@@ -90,7 +92,7 @@ public class TIeInvigilateCallMobileController {
             callStatus = callStatusEnum.name();
         }
         TBUser tbUser = (TBUser) ServletUtil.getRequestAccount();
-        AuthDto authDto = (AuthDto) redisUtil.get(SystemConstant.userOauth + "::" + tbUser.getId());
+        AuthDto authDto = cacheService.addAccountAuthCache(tbUser.getId());
         //如果有监考员角色,只能查看自己所监考的考场,巡考员和管理员则可以查看全部考场
         Long userId = null;
         if (authDto.getRoleCodes().toString().contains(RoleEnum.INVIGILATE.name())) {
@@ -113,9 +115,9 @@ public class TIeInvigilateCallMobileController {
 
     @ApiOperation(value = "监考监控通话提醒接口")
     @RequestMapping(value = "/call/count", method = RequestMethod.POST)
-    @ApiResponses({ @ApiResponse(code = 200, message = "监考监控信息", response = Integer.class) })
+    @ApiResponses({@ApiResponse(code = 200, message = "监考监控信息", response = Integer.class)})
     public Result callCount(@ApiParam(value = "考试批次id", required = true) @RequestParam Long examId,
-            @ApiParam(value = "通话状态", required = false) @RequestParam(required = false) String callStatus) {
+                            @ApiParam(value = "通话状态", required = false) @RequestParam(required = false) String callStatus) {
         if (Objects.isNull(examId) || Objects.equals(examId, "")) {
             throw new BusinessException(ExceptionResultEnum.EXAM_ID_IS_NULL);
         }
@@ -124,7 +126,7 @@ public class TIeInvigilateCallMobileController {
             callStatus = callStatusEnum.name();
         }
         TBUser tbUser = (TBUser) ServletUtil.getRequestAccount();
-        AuthDto authDto = (AuthDto) redisUtil.get(SystemConstant.userOauth + "::" + tbUser.getId());
+        AuthDto authDto = cacheService.addAccountAuthCache(tbUser.getId());
         //如果有监考员角色,只能查看自己所监考的考场,巡考员和管理员则可以查看全部考场
         Long userId = null;
         if (authDto.getRoleCodes().toString().contains(RoleEnum.INVIGILATE.name())) {
@@ -138,7 +140,7 @@ public class TIeInvigilateCallMobileController {
 
     @ApiOperation(value = "监考监控通话查询来源接口")
     @RequestMapping(value = "/call/query", method = RequestMethod.POST)
-    @ApiResponses({ @ApiResponse(code = 200, message = "监考监控信息", response = TIeExamInvigilateCall.class) })
+    @ApiResponses({@ApiResponse(code = 200, message = "监考监控信息", response = TIeExamInvigilateCall.class)})
     public Result callQuery(@ApiParam(value = "考试记录id", required = true) @RequestParam(required = true) Long recordId) {
         QueryWrapper<TIeExamInvigilateCall> tIeExamInvigilateCallQueryWrapper = new QueryWrapper<>();
         tIeExamInvigilateCallQueryWrapper.lambda().eq(TIeExamInvigilateCall::getExamRecordId, recordId);
@@ -147,11 +149,11 @@ public class TIeInvigilateCallMobileController {
 
     @ApiOperation(value = "通话中接口")
     @RequestMapping(value = "/call/calling", method = RequestMethod.POST)
-    @ApiResponses({ @ApiResponse(code = 200, message = "{\"success\":true}", response = Result.class) })
+    @ApiResponses({@ApiResponse(code = 200, message = "{\"success\":true}", response = Result.class)})
     @Transactional
-    public Result callCalling(@ApiJsonObject(name = "callCallingBackendMobile", value = {
+    public Result callCalling(@ApiJsonObject(name = "callCallingAdminMobile", value = {
             @ApiJsonProperty(key = "recordId", type = "long", example = "1", description = "考试记录id", required = true),
-            @ApiJsonProperty(key = "source", description = "监考视频源", required = true) }) @ApiParam(value = "监控信息", required = true) @RequestBody Map<String, Object> mapParameter) {
+            @ApiJsonProperty(key = "source", description = "监考视频源", required = true)}) @ApiParam(value = "监控信息", required = true) @RequestBody Map<String, Object> mapParameter) {
         if (Objects.isNull(mapParameter.get("recordId")) || Objects.equals(mapParameter.get("recordId"), "")) {
             throw new BusinessException(ExceptionResultEnum.RECORD_ID_IS_NULL);
         }
@@ -161,31 +163,33 @@ public class TIeInvigilateCallMobileController {
         }
         MonitorVideoSourceEnum source = MonitorVideoSourceEnum.valueOf(String.valueOf(mapParameter.get("source")));
         //获取考试记录缓存
-        String liveUrl = null;
+        String liveUrl = SystemConstant.setStreamId(dictionaryConfig.monitorDomain().getPrefix(), recordId, source);
         if (Objects.isNull(ExamRecordCacheUtil.getMonitorStatus(recordId, source))) {
             throw new BusinessException("推流状态为空");
         }
-        ExamRecordCacheUtil.setMonitorCallStatus(recordId, source, MonitorCallStatusSourceEnum.CALLING);
+        Long timestamp = System.currentTimeMillis();
+        ExamRecordCacheUtil.setMonitorCallStatus(recordId, source, MonitorCallStatusSourceEnum.CALLING, timestamp);
+        tOeExamRecordService.sendExamRecordDataSaveMq(recordId, timestamp);
         String monitorKey = ExamRecordCacheUtil.getMonitorKey(recordId);
         MonitorStatusSourceEnum status = ExamRecordCacheUtil.getMonitorStatus(recordId, source);
         TIeExamInvigilateCallLog tIeExamInvigilateCallLog = new TIeExamInvigilateCallLog(recordId, source, liveUrl,
                 status, monitorKey, MonitorCallStatusSourceEnum.CALLING);
         //监考监控通话信息 发送mq start
-        MqDto mqDto = new MqDto(MqTopicEnum.THEMIS_TOPIC.getCode(), MqTagEnum.MONITOR_LOG.name(),
+        MqDto mqDto = new MqDto(mqUtil.getMqGroupDomain().getTopic(), MqTagEnum.MONITOR_LOG.name(),
                 tIeExamInvigilateCallLog, MqTagEnum.MONITOR_LOG, String.valueOf(tIeExamInvigilateCallLog.getId()),
                 source.name());
         mqDtoService.assembleSendOneWayMsg(mqDto);
         //监考监控通话信息 发送mq end
-        return ResultUtil.ok(Collections.singletonMap(SystemConstant.SUCCESS, true));
+        return ResultUtil.ok(true);
     }
 
     @ApiOperation(value = "撤销通话申请接口")
     @RequestMapping(value = "/call/cancel", method = RequestMethod.POST)
-    @ApiResponses({ @ApiResponse(code = 200, message = "{\"success\":true}", response = Result.class) })
+    @ApiResponses({@ApiResponse(code = 200, message = "{\"success\":true}", response = Result.class)})
     @Transactional
-    public Result callCancel(@ApiJsonObject(name = "callCancelBackendMobile", value = {
+    public Result callCancel(@ApiJsonObject(name = "callCancelAdminMobile", value = {
             @ApiJsonProperty(key = "recordId", type = "long", example = "1", description = "考试记录id", required = true),
-            @ApiJsonProperty(key = "source", description = "监考视频源", required = true) }) @ApiParam(value = "监控信息", required = true) @RequestBody Map<String, Object> mapParameter) {
+            @ApiJsonProperty(key = "source", description = "监考视频源", required = true)}) @ApiParam(value = "监控信息", required = true) @RequestBody Map<String, Object> mapParameter) {
         if (Objects.isNull(mapParameter.get("recordId")) || Objects.equals(mapParameter.get("recordId"), "")) {
             throw new BusinessException(ExceptionResultEnum.RECORD_ID_IS_NULL);
         }
@@ -195,33 +199,35 @@ public class TIeInvigilateCallMobileController {
         }
         MonitorVideoSourceEnum source = MonitorVideoSourceEnum.valueOf(String.valueOf(mapParameter.get("source")));
         //获取考试记录缓存
-        String liveUrl = null;
+        String liveUrl = SystemConstant.setStreamId(dictionaryConfig.monitorDomain().getPrefix(), recordId, source);
         ExamRecordStatusEnum statusEnum = ExamRecordCacheUtil.getStatus(recordId);
         if (Objects.isNull(statusEnum) || Objects.equals(statusEnum, ExamRecordStatusEnum.FINISHED) || Objects
                 .equals(statusEnum, ExamRecordStatusEnum.PERSISTED)) {
-            return ResultUtil.ok(Collections.singletonMap(SystemConstant.SUCCESS, true));
+            return ResultUtil.ok(true);
         } else if (Objects.isNull(ExamRecordCacheUtil.getMonitorStatus(recordId, source))) {
             throw new BusinessException("推流状态为空");
         }
-        ExamRecordCacheUtil.setMonitorCallStatus(recordId, source, MonitorCallStatusSourceEnum.STOP);
+        Long timestamp = System.currentTimeMillis();
+        ExamRecordCacheUtil.setMonitorCallStatus(recordId, source, MonitorCallStatusSourceEnum.STOP, timestamp);
+        tOeExamRecordService.sendExamRecordDataSaveMq(recordId, timestamp);
         String monitorKey = ExamRecordCacheUtil.getMonitorKey(recordId);
         MonitorStatusSourceEnum status = ExamRecordCacheUtil.getMonitorStatus(recordId, source);
         TIeExamInvigilateCallLog tIeExamInvigilateCallLog = new TIeExamInvigilateCallLog(recordId, source, liveUrl,
                 status, monitorKey, MonitorCallStatusSourceEnum.STOP);
         tIeExamInvigilateCallLog.setEndTime(System.currentTimeMillis());
         //监考监控通话信息 发送mq start
-        MqDto mqDto = new MqDto(MqTopicEnum.THEMIS_TOPIC.getCode(), MqTagEnum.MONITOR_LOG.name(),
+        MqDto mqDto = new MqDto(mqUtil.getMqGroupDomain().getTopic(), MqTagEnum.MONITOR_LOG.name(),
                 tIeExamInvigilateCallLog, MqTagEnum.MONITOR_LOG, String.valueOf(tIeExamInvigilateCallLog.getId()),
                 source.name());
         mqDtoService.assembleSendOneWayMsg(mqDto);
         //监考监控通话信息 发送mq end
-        return ResultUtil.ok(Collections.singletonMap(SystemConstant.SUCCESS, true));
+        return ResultUtil.ok(true);
     }
 
     @ApiOperation(value = "监考获取monitorKey接口")
     @RequestMapping(value = "/getMonitorKey", method = RequestMethod.POST)
     @ApiResponses({
-            @ApiResponse(code = 200, message = "获取监考monitorKey", response = MobileAuthorizationMonitorBean.class) })
+            @ApiResponse(code = 200, message = "获取监考monitorKey", response = MobileAuthorizationMonitorBean.class)})
     public Result getMonitorKey(@ApiParam(value = "考试记录id", required = true) @RequestParam Long recordId)
             throws NoSuchAlgorithmException {
         TBSession tbSession = (TBSession) ServletUtil.getRequestSession();

+ 102 - 73
themis-backend/src/main/java/com/qmth/themis/backend/api/TIeInvigilateController.java → themis-admin/src/main/java/com/qmth/themis/admin/api/TIeInvigilateController.java

@@ -1,29 +1,29 @@
-package com.qmth.themis.backend.api;
+package com.qmth.themis.admin.api;
 
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.qmth.themis.admin.config.DictionaryConfig;
 import com.qmth.themis.business.annotation.ApiJsonObject;
 import com.qmth.themis.business.annotation.ApiJsonProperty;
-import com.qmth.themis.business.bean.backend.*;
+import com.qmth.themis.business.bean.admin.*;
 import com.qmth.themis.business.cache.ExamRecordCacheUtil;
-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.ExamStudentCacheBean;
 import com.qmth.themis.business.constant.SystemConstant;
 import com.qmth.themis.business.dto.AuthDto;
 import com.qmth.themis.business.dto.ExamPropCountDto;
 import com.qmth.themis.business.dto.MqDto;
+import com.qmth.themis.business.dto.cache.TEStudentCacheDto;
 import com.qmth.themis.business.entity.*;
 import com.qmth.themis.business.enums.*;
 import com.qmth.themis.business.excel.ExportUtils;
 import com.qmth.themis.business.service.*;
 import com.qmth.themis.business.util.JacksonUtil;
+import com.qmth.themis.business.util.MqUtil;
 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.common.enums.ExceptionResultEnum;
 import com.qmth.themis.common.exception.BusinessException;
@@ -60,9 +60,6 @@ public class TIeInvigilateController {
     @Resource
     TEExamBreachLogService teExamBreachLogService;
 
-    @Resource
-    RedisUtil redisUtil;
-
     @Resource
     TOeExamRecordService tOeExamRecordService;
 
@@ -91,10 +88,16 @@ public class TIeInvigilateController {
     TEExamService teExamService;
 
     @Resource
-    TEStudentService teStudentService;
+    OssUtil ossUtil;
+
+    @Resource
+    MqUtil mqUtil;
 
     @Resource
-    OssUtil ossUtil;
+    DictionaryConfig dictionaryConfig;
+
+    @Resource
+    CacheService cacheService;
 
     @ApiOperation(value = "实时监控台视频列表接口")
     @RequestMapping(value = "/list/video", method = RequestMethod.POST)
@@ -110,32 +113,35 @@ public class TIeInvigilateController {
                             @ApiParam(value = "预警量max", required = false) @RequestParam(required = false) Integer maxWarningCount,
                             @ApiParam(value = "客户端网络通信状态", required = false) @RequestParam(required = false) String clientWebsocketStatus,
                             @ApiParam(value = "监控设备来源", required = false) @RequestParam(required = false) String monitorVideoSource,
+                            @ApiParam(value = "摄像头监控设备推流状态('START'or'STOP')", required = false) @RequestParam(required = false) String cameraMonitorStatus,
+                            @ApiParam(value = "屏幕监控设备推流状态('START'or'STOP')", required = false) @RequestParam(required = false) String screenMonitorStatus,
+                            @ApiParam(value = "手机端主机位监控设备推流状态('START'or'STOP')", required = false) @RequestParam(required = false) String mobileFirstMonitorStatus,
+                            @ApiParam(value = "手机端辅机位监控设备推流状态('START'or'STOP')", required = false) @RequestParam(required = false) String mobileSecondMonitorStatus,
                             @ApiParam(value = "分页页码", required = true) @RequestParam int pageNumber,
                             @ApiParam(value = "分页数", required = true) @RequestParam int pageSize) {
         TBUser tbUser = (TBUser) ServletUtil.getRequestAccount();
-        AuthDto authDto = (AuthDto) redisUtil.get(SystemConstant.userOauth + "::" + tbUser.getId());
+        AuthDto authDto = cacheService.addAccountAuthCache(tbUser.getId());
         //如果有监考员角色,只能查看自己所监考的考场,巡考员和管理员则可以查看全部考场
         Long userId = null;
         if (authDto.getRoleCodes().toString().contains(RoleEnum.INVIGILATE.name())) {
             userId = tbUser.getId();
         }
-        IPage<InvigilateListVideoBean> invigilateListVideoBeanIPage = tOeExamRecordService.invigilatePageListVideo(new Page<>(pageNumber, pageSize), examId, examActivityId, roomCode, paperDownload, status, name, identity, minWarningCount, maxWarningCount, clientWebsocketStatus, userId, tbUser.getOrgId());
+        IPage<InvigilateListVideoBean> invigilateListVideoBeanIPage = tOeExamRecordService.invigilatePageListVideo(new Page<>(pageNumber, pageSize), examId, examActivityId, roomCode, paperDownload, status, name, identity, minWarningCount, maxWarningCount, clientWebsocketStatus, cameraMonitorStatus, screenMonitorStatus, mobileFirstMonitorStatus, mobileSecondMonitorStatus, userId, tbUser.getOrgId());
         if (Objects.nonNull(invigilateListVideoBeanIPage)) {
             List<InvigilateListVideoBean> invigilateListVideoBeanList = invigilateListVideoBeanIPage.getRecords();
             ExamCacheBean examCacheBean = null;
             if (Objects.nonNull(examId)) {
                 examCacheBean = teExamService.getExamCacheBean(examId);
             }
-            List<String> monitorVideoSourceList = null;
-            if (Objects.nonNull(examCacheBean) && Objects.nonNull(examCacheBean.getMonitorVideoSource()) && !Objects.equals(examCacheBean.getMonitorVideoSource().toString().trim().replaceAll(" ", ""), "")) {
-                monitorVideoSourceList = Arrays.asList(examCacheBean.getMonitorVideoSource().trim().toUpperCase().replaceAll(" ", "").split(","));
-            }
             if (Objects.nonNull(invigilateListVideoBeanList) && invigilateListVideoBeanList.size() > 0) {
-                List<String> finalMonitorVideoSourceList = monitorVideoSourceList;
                 ExamCacheBean finalExamCacheBean = examCacheBean;
                 invigilateListVideoBeanList.forEach(s -> {
-                    if (Objects.nonNull(finalMonitorVideoSourceList) && finalMonitorVideoSourceList.size() > 0) {
-                        finalMonitorVideoSourceList.forEach(l -> {
+                    List<String> monitorVideoSourceList = null;
+                    if (Objects.nonNull(s.getMonitorVideoSource()) && !Objects.equals(s.getMonitorVideoSource().trim().replaceAll(" ", ""), "")) {
+                        monitorVideoSourceList = Arrays.asList(s.getMonitorVideoSource().trim().toUpperCase().replaceAll(" ", "").split(","));
+                    }
+                    if (Objects.nonNull(monitorVideoSourceList) && monitorVideoSourceList.size() > 0) {
+                        monitorVideoSourceList.forEach(l -> {
                             MonitorVideoSourceEnum source = MonitorVideoSourceEnum.valueOf(l);
                             switch (source.name()) {
                                 case "CLIENT_SCREEN":
@@ -153,13 +159,10 @@ public class TIeInvigilateController {
                             }
                         });
                     }
-                    MonitorVideoSourceEnum source = MonitorVideoSourceEnum.CLIENT_CAMERA;
                     if (Objects.nonNull(monitorVideoSource)) {
-                        source = MonitorVideoSourceEnum.valueOf(monitorVideoSource);
-                    }
-                    String monitorLiveUrl = ExamRecordCacheUtil.getMonitorLiveUrl(s.getExamRecordId(), source);
-                    if (Objects.nonNull(monitorLiveUrl)) {
-                        s.setMonitorLiveUrl(monitorLiveUrl);
+                        s.setMonitorLiveUrl(SystemConstant.setStreamId(dictionaryConfig.monitorDomain().getPrefix(), s.getExamRecordId(), MonitorVideoSourceEnum.valueOf(monitorVideoSource)));
+                    } else if (Objects.nonNull(monitorVideoSourceList) && monitorVideoSourceList.contains(MonitorVideoSourceEnum.CLIENT_CAMERA.name())) {
+                        s.setMonitorLiveUrl(SystemConstant.setStreamId(dictionaryConfig.monitorDomain().getPrefix(), s.getExamRecordId(), MonitorVideoSourceEnum.CLIENT_CAMERA));
                     }
                     WebsocketStatusEnum websocketStatusEnum = ExamRecordCacheUtil.getClientWebsocketStatus(s.getExamRecordId());
                     if (Objects.nonNull(websocketStatusEnum)) {
@@ -187,7 +190,7 @@ public class TIeInvigilateController {
             throw new BusinessException("随机数不能为空");
         }
         TBUser tbUser = (TBUser) ServletUtil.getRequestAccount();
-        AuthDto authDto = (AuthDto) redisUtil.get(SystemConstant.userOauth + "::" + tbUser.getId());
+        AuthDto authDto = cacheService.addAccountAuthCache(tbUser.getId());
         //如果有监考员角色,只能查看自己所监考的考场,巡考员和管理员则可以查看全部考场
         Long userId = null;
         if (authDto.getRoleCodes().toString().contains(RoleEnum.INVIGILATE.name())) {
@@ -195,15 +198,14 @@ public class TIeInvigilateController {
         }
         List<InvigilateListVideoBean> invigilateListVideoBeanList = tOeExamRecordService.invigilatePageListVideoRandom(examId, userId, randomNum, tbUser.getOrgId());
         if (Objects.nonNull(invigilateListVideoBeanList) && invigilateListVideoBeanList.size() > 0) {
-            ExamCacheBean examCacheBean = null;
-            if (Objects.nonNull(examId)) {
-                examCacheBean = teExamService.getExamCacheBean(examId);
-            }
-            ExamCacheBean finalExamCacheBean = examCacheBean;
             invigilateListVideoBeanList.forEach(s -> {
-                String monitorLiveUrl = ExamRecordCacheUtil.getMonitorLiveUrl(s.getExamRecordId(), MonitorVideoSourceEnum.CLIENT_CAMERA);
-                if (Objects.nonNull(monitorLiveUrl)) {
-                    s.setMonitorLiveUrl(monitorLiveUrl);
+                ExamCacheBean examCacheBean = teExamService.getExamCacheBean(s.getExamId());
+                List<String> monitorVideoSourceList = null;
+                if (Objects.nonNull(s.getMonitorVideoSource()) && !Objects.equals(s.getMonitorVideoSource().trim().replaceAll(" ", ""), "")) {
+                    monitorVideoSourceList = Arrays.asList(s.getMonitorVideoSource().trim().toUpperCase().replaceAll(" ", "").split(","));
+                }
+                if (Objects.nonNull(monitorVideoSourceList) && monitorVideoSourceList.contains(MonitorVideoSourceEnum.CLIENT_CAMERA.name())) {
+                    s.setMonitorLiveUrl(SystemConstant.setStreamId(dictionaryConfig.monitorDomain().getPrefix(), s.getExamRecordId(), MonitorVideoSourceEnum.CLIENT_CAMERA));
                 }
                 WebsocketStatusEnum websocketStatusEnum = ExamRecordCacheUtil.getClientWebsocketStatus(s.getExamRecordId());
                 if (Objects.nonNull(websocketStatusEnum)) {
@@ -214,8 +216,8 @@ public class TIeInvigilateController {
                     s.setPaperDownload(paperDownLoad);
                 }
                 //剩余时间计算
-                if (Objects.nonNull(finalExamCacheBean)) {
-                    s.setRemainTime(this.getRemainTime(finalExamCacheBean.getMode(), s.getExamRecordId()));
+                if (Objects.nonNull(examCacheBean)) {
+                    s.setRemainTime(this.getRemainTime(examCacheBean.getMode(), s.getExamRecordId()));
                 }
             });
         }
@@ -243,7 +245,7 @@ public class TIeInvigilateController {
                               @ApiParam(value = "分页页码", required = true) @RequestParam int pageNumber,
                               @ApiParam(value = "分页数", required = true) @RequestParam int pageSize) {
         TBUser tbUser = (TBUser) ServletUtil.getRequestAccount();
-        AuthDto authDto = (AuthDto) redisUtil.get(SystemConstant.userOauth + "::" + tbUser.getId());
+        AuthDto authDto = cacheService.addAccountAuthCache(tbUser.getId());
         //如果有监考员角色,只能查看自己所监考的考场,巡考员和管理员则可以查看全部考场
         Long userId = null;
         if (authDto.getRoleCodes().toString().contains(RoleEnum.INVIGILATE.name())) {
@@ -280,7 +282,7 @@ public class TIeInvigilateController {
             breachStatus = Objects.isNull(ExamRecordCacheUtil.getBreachStatus(examRecordId)) ? 1 : ExamRecordCacheUtil.getBreachStatus(examRecordId);
         }
         ExamStudentCacheBean examStudentCacheBean = teExamStudentService.getExamStudentCacheBean(examStudentId);
-        TEStudent teStudent = teStudentService.getById(examStudentCacheBean.getStudentId());
+        TEStudentCacheDto teStudent = cacheService.addStudentAccountCache(examStudentCacheBean.getStudentId());
         String basePhotoPath = ossUtil.getAliYunOssPublicDomain().getPublicUrl() + File.separator + teStudent.getBasePhotoPath();
         String identity = examStudentCacheBean.getIdentity();
         String examStudentName = examStudentCacheBean.getName();
@@ -324,7 +326,7 @@ public class TIeInvigilateController {
 
         //2020/11/24新增管理员不清除预警状态
         TBUser tbUser = (TBUser) ServletUtil.getRequestAccount();
-        AuthDto authDto = (AuthDto) redisUtil.get(SystemConstant.userOauth + "::" + tbUser.getId());
+        AuthDto authDto = cacheService.addAccountAuthCache(tbUser.getId());
         if (!authDto.getRoleCodes().toString().contains(RoleEnum.ADMIN.name())) {
             //清除预警未阅状态
             UpdateWrapper<TIeInvigilateWarnInfo> tIeExamInvigilateNoticeUpdateWrapper = new UpdateWrapper<>();
@@ -368,11 +370,11 @@ public class TIeInvigilateController {
             } else {
                 mqTagEnum = MqTagEnum.OE_HARD_FINISH;
             }
-            MqDto mqDto = new MqDto(MqTopicEnum.THEMIS_TOPIC.getCode(), mqTagEnum.name(), JacksonUtil.parseJson(recordIdList), mqTagEnum, String.valueOf(tbUser.getId()), mapParameter, tbUser.getName());
-            mqDtoService.assembleSendOneWayMsg(mqDto);
+            MqDto mqDto = new MqDto(mqUtil.getMqGroupDomain().getTopic(), mqTagEnum.name(), JacksonUtil.parseJson(recordIdList), mqTagEnum, String.valueOf(tbUser.getId()), mapParameter, tbUser.getName());
+            mqDtoService.assembleSendOneOrderMsg(mqDto);
             //发送mq给客户端强制收卷end
         }
-        return ResultUtil.ok(Collections.singletonMap(SystemConstant.SUCCESS, true));
+        return ResultUtil.ok(true);
     }
 
     @ApiOperation(value = "在线巡考列表接口")
@@ -394,7 +396,7 @@ public class TIeInvigilateController {
                              @ApiParam(value = "分页页码", required = true) @RequestParam int pageNumber,
                              @ApiParam(value = "分页数", required = true) @RequestParam int pageSize) {
         TBUser tbUser = (TBUser) ServletUtil.getRequestAccount();
-        AuthDto authDto = (AuthDto) redisUtil.get(SystemConstant.userOauth + "::" + tbUser.getId());
+        AuthDto authDto = cacheService.addAccountAuthCache(tbUser.getId());
         //如果有监考员角色,只能查看自己所监考的考场,巡考员和管理员则可以查看全部考场
         Long userId = null;
         if (authDto.getRoleCodes().toString().contains(RoleEnum.INVIGILATE.name())) {
@@ -436,7 +438,7 @@ public class TIeInvigilateController {
                                @ApiParam(value = "分页页码", required = true) @RequestParam int pageNumber,
                                @ApiParam(value = "分页数", required = true) @RequestParam int pageSize) {
         TBUser tbUser = (TBUser) ServletUtil.getRequestAccount();
-        AuthDto authDto = (AuthDto) redisUtil.get(SystemConstant.userOauth + "::" + tbUser.getId());
+        AuthDto authDto = cacheService.addAccountAuthCache(tbUser.getId());
         //如果有监考员角色,只能查看自己所监考的考场,巡考员和管理员则可以查看全部考场
         Long userId = null;
         if (authDto.getRoleCodes().toString().contains(RoleEnum.INVIGILATE.name())) {
@@ -455,7 +457,7 @@ public class TIeInvigilateController {
                                    @ApiParam(value = "姓名", required = false) @RequestParam(required = false) String name,
                                    @ApiParam(value = "证件号", required = false) @RequestParam(required = false) String identity) throws Exception {
         TBUser tbUser = (TBUser) ServletUtil.getRequestAccount();
-        AuthDto authDto = (AuthDto) redisUtil.get(SystemConstant.userOauth + "::" + tbUser.getId());
+        AuthDto authDto = cacheService.addAccountAuthCache(tbUser.getId());
         //如果有监考员角色,只能查看自己所监考的考场,巡考员和管理员则可以查看全部考场
         Long userId = null;
         if (authDto.getRoleCodes().toString().contains(RoleEnum.INVIGILATE.name())) {
@@ -489,6 +491,7 @@ public class TIeInvigilateController {
         if (Objects.isNull(mapParameter.get("status")) || Objects.equals(mapParameter.get("status"), "")) {
             throw new BusinessException(ExceptionResultEnum.BREACH_STATUS_IS_NULL);
         }
+        List<TOeExamRecord> tOeExamRecordList = new ArrayList<>();
         if (recordIdList.size() > 0) {
             Integer status = Integer.parseInt(String.valueOf(mapParameter.get("status")));
             TBUser tbUser = (TBUser) ServletUtil.getRequestAccount();
@@ -501,8 +504,9 @@ public class TIeInvigilateController {
                     Long examId = ExamRecordCacheUtil.getExamId(l);
                     Long examStudentId = null;
                     Long examActivityId = null;
+                    TOeExamRecord tOeExamRecord = null;
                     if (Objects.isNull(examId)) {
-                        TOeExamRecord tOeExamRecord = tOeExamRecordService.getById(l);
+                        tOeExamRecord = tOeExamRecordService.getById(l);
                         examId = tOeExamRecord.getExamId();
                         examStudentId = tOeExamRecord.getExamStudentId();
                         examActivityId = tOeExamRecord.getExamActivityId();
@@ -514,7 +518,13 @@ public class TIeInvigilateController {
                     TEExamBreachLog teExamBreachLog = new TEExamBreachLog(examId, examActivityId, l, examStudentId, type.name(), description, status);
                     teExamBreachLog.setCreateId(tbUser.getId());
                     finalTeExamBreachLogList.add(teExamBreachLog);
-                    ExamRecordCacheUtil.setBreachStatus(l, 0, true);
+                    if (Objects.nonNull(ExamRecordCacheUtil.getId(l)) && Objects.nonNull(tOeExamRecord)) {
+                        ExamRecordCacheUtil.setBreachStatus(l, status);
+                        tOeExamRecordService.sendExamRecordDataSaveMq(l, System.currentTimeMillis());
+                    } else {
+                        tOeExamRecord.setBreachStatus(status);
+                        tOeExamRecordList.add(tOeExamRecord);
+                    }
                 }
             } else {//撤销违纪
                 BreachCancelTypeEnum type = BreachCancelTypeEnum.valueOf(String.valueOf(mapParameter.get("type")));
@@ -523,13 +533,24 @@ public class TIeInvigilateController {
                         .eq(TEExamBreachLog::getStatus, 0);
                 teExamBreachLogList = teExamBreachLogService.list(teExamBreachLogQueryWrapper);
                 teExamBreachLogList.forEach(s -> {
+                    TOeExamRecord tOeExamRecord = null;
                     s.setType(type.name());
                     s.setDescription(description);
                     s.setStatus(status);
                     s.setUpdateId(tbUser.getId());
-                    ExamRecordCacheUtil.setBreachStatus(s.getExamRecordId(), 1, true);
+                    if (Objects.isNull(ExamRecordCacheUtil.getId(s.getExamRecordId()))) {
+                        tOeExamRecord = tOeExamRecordService.getById(s.getExamRecordId());
+                        tOeExamRecord.setBreachStatus(status);
+                        tOeExamRecordList.add(tOeExamRecord);
+                    } else {
+                        ExamRecordCacheUtil.setBreachStatus(s.getExamRecordId(), status);
+                        tOeExamRecordService.sendExamRecordDataSaveMq(s.getExamRecordId(), System.currentTimeMillis());
+                    }
                 });
             }
+            if (Objects.nonNull(tOeExamRecordList) && tOeExamRecordList.size() > 0) {
+                tOeExamRecordService.saveOrUpdateBatch(tOeExamRecordList);
+            }
             for (TEExamBreachLog eb : teExamBreachLogList) {
                 Map<String, Object> properties = new HashMap<>();
                 properties.put("type", eb.getDescription());
@@ -537,12 +558,12 @@ public class TIeInvigilateController {
                 properties.put("examStudentId", eb.getExamStudentId());
                 properties.put("examRecordId", eb.getExamRecordId());
                 ExamStudentCacheBean examStudentCacheBean = teExamStudentService.getExamStudentCacheBean(eb.getExamStudentId());
-                MqDto mqDto = new MqDto(MqTopicEnum.THEMIS_TOPIC.getCode(), MqTagEnum.STUDENT.name(), eb.getStatus() == 0 ? SystemOperationEnum.BREACH_HANDLE : SystemOperationEnum.BREACH_REVOKE, MqTagEnum.STUDENT, String.valueOf(examStudentCacheBean.getStudentId()), properties, examStudentCacheBean.getIdentity());
+                MqDto mqDto = new MqDto(mqUtil.getMqGroupDomain().getTopic(), MqTagEnum.STUDENT.name(), eb.getStatus() == 0 ? SystemOperationEnum.BREACH_HANDLE : SystemOperationEnum.BREACH_REVOKE, MqTagEnum.STUDENT, String.valueOf(examStudentCacheBean.getStudentId()), properties, examStudentCacheBean.getIdentity());
                 mqDtoService.assembleSendOneWayMsg(mqDto);
-                teExamBreachLogService.saveOrUpdate(eb);
             }
+            teExamBreachLogService.saveOrUpdateBatch(teExamBreachLogList);
         }
-        return ResultUtil.ok(Collections.singletonMap(SystemConstant.SUCCESS, true));
+        return ResultUtil.ok(true);
     }
 
     @ApiOperation(value = "监考消息通知接口")
@@ -562,15 +583,16 @@ public class TIeInvigilateController {
         }
         TBUser tbUser = (TBUser) ServletUtil.getRequestAccount();
         //发送mq给客户端监考消息start
-        MqDto mqDto = new MqDto(MqTopicEnum.THEMIS_TOPIC.getCode(), MqTagEnum.OE_IM_CLUSTERING.name(), recordId, MqTagEnum.OE_IM_CLUSTERING, String.valueOf(tbUser.getId()), mapParameter, tbUser.getName());
-        mqDtoService.assembleSendOneWayMsg(mqDto);
+        mapParameter.put("formUserId", tbUser.getId());
+        MqDto mqDto = new MqDto(mqUtil.getMqGroupDomain().getTopic(), MqTagEnum.OE_IM_CLUSTERING.name(), recordId, MqTagEnum.OE_IM_CLUSTERING, String.valueOf(recordId), mapParameter, tbUser.getName());
+        mqDtoService.assembleSendOneOrderMsg(mqDto);
         //发送mq给客户端监考消息end
 
 //        //发送mq给客户端监考强制活体验证start
-//        mqDto = new MqDto(MqTopicEnum.THEMIS_TOPIC.getCode(), MqTagEnum.OE_LIVENESS_VERIFY.name(), recordId, MqTagEnum.OE_LIVENESS_VERIFY, String.valueOf(tbUser.getId()), mapParameter, tbUser.getName());
-//        mqDtoService.assembleSendOneWayMsg(mqDto);
+//        mqDto = new MqDto(MqTopicEnum.THEMIS_TOPIC.getCode(), MqTagEnum.OE_LIVENESS_VERIFY.name(), recordId, MqTagEnum.OE_LIVENESS_VERIFY, String.valueOf(recordId), mapParameter, tbUser.getName());
+//        mqDtoService.assembleSendOneOrderMsg(mqDto);
 //        //发送mq给客户端监考强制活体验证end
-        return ResultUtil.ok(Collections.singletonMap(SystemConstant.SUCCESS, true));
+        return ResultUtil.ok(true);
     }
 
     @ApiOperation(value = "结束监考接口")
@@ -640,9 +662,12 @@ public class TIeInvigilateController {
             examPropCountDto.setReexamCount(reexamCount);
         }
         if (Objects.nonNull(examActivityIdSet)) {
+            QueryWrapper<TOeExamRecord> tOeExamRecordQueryWrapper = new QueryWrapper<>();
+            tOeExamRecordQueryWrapper.lambda().in(TOeExamRecord::getExamActivityId, examActivityIdSet);
+            List<TOeExamRecord> examRecordList = tOeExamRecordService.list(tOeExamRecordQueryWrapper);
             //获取已待考、考试中学生
-            examActivityIdSet.forEach(s -> {
-                ExamActivityCacheBean examActivityCacheBean = teExamActivityService.getExamActivityCacheBean(s);
+            examRecordList.forEach(s -> {
+                ExamActivityCacheBean examActivityCacheBean = teExamActivityService.getExamActivityCacheBean(s.getExamActivityId());
                 Long startTime = examActivityCacheBean.getStartTime();
                 Long finishTime = examActivityCacheBean.getFinishTime();
                 Integer activityMaxDurationSeconds = Objects.nonNull(examActivityCacheBean.getMaxDurationSeconds()) ? examActivityCacheBean.getMaxDurationSeconds() : null;
@@ -659,21 +684,25 @@ public class TIeInvigilateController {
                 if (Objects.nonNull(examCacheBean.getForceFinish()) && examCacheBean.getForceFinish() == 1) {
                     examPropCountDto.setFinishTime(finishTime);
                 }
-                Map<String, Object> objectMap = redisUtil.getHashEntries(RedisKeyHelper.examActivityRecordCacheKey(s));
-                if (Objects.nonNull(objectMap) && objectMap.size() > 0) {
-                    objectMap.forEach((k, v) -> {
-                        ExamActivityRecordCacheBean examActivityRecordCache = (ExamActivityRecordCacheBean) v;
-                        ExamRecordStatusEnum examRecordStatusEnum = examActivityRecordCache.getStatus();
-                        //已待考
-                        if (Objects.equals(examRecordStatusEnum, ExamRecordStatusEnum.FIRST_PREPARE)) {
-                            prepareCount.getAndSet(prepareCount.get() + 1);
-                        }
-                        //考试中
-                        else if (Objects.equals(examRecordStatusEnum, ExamRecordStatusEnum.ANSWERING)) {
-                            examCount.getAndSet(examCount.get() + 1);
-                        }
-                    });
+//                Map<String, Object> objectMap = redisUtil.getHashEntries(RedisKeyHelper.examActivityRecordCacheKey(s));
+//                if (Objects.nonNull(objectMap) && objectMap.size() > 0) {
+//                    objectMap.forEach((k, v) -> {
+//                        ExamActivityRecordCacheBean examActivityRecordCache = (ExamActivityRecordCacheBean) v;
+//                        ExamRecordStatusEnum examRecordStatusEnum = examActivityRecordCache.getStatus();
+                ExamRecordStatusEnum examRecordStatusEnum = s.getStatus();
+                WebsocketStatusEnum clientStatus = Objects.isNull(s.getClientWebsocketStatus()) ? null : s.getClientWebsocketStatus();
+                //已待考
+                if (Objects.equals(examRecordStatusEnum, ExamRecordStatusEnum.FIRST_PREPARE) && Objects.nonNull(clientStatus) && Objects
+                        .equals(clientStatus, WebsocketStatusEnum.ON_LINE)) {
+                    prepareCount.getAndSet(prepareCount.get() + 1);
                 }
+                //考试中
+                else if (Objects.equals(examRecordStatusEnum, ExamRecordStatusEnum.ANSWERING) && Objects.nonNull(clientStatus) && Objects
+                        .equals(clientStatus, WebsocketStatusEnum.ON_LINE)) {
+                    examCount.getAndSet(examCount.get() + 1);
+                }
+//                    });
+//                }
 //                }
             });
         }
@@ -709,4 +738,4 @@ public class TIeInvigilateController {
         }
         return remainTime;
     }
-}
+}

+ 14 - 13
themis-backend/src/main/java/com/qmth/themis/backend/api/TIeInvigilateWarnInfoController.java → themis-admin/src/main/java/com/qmth/themis/admin/api/TIeInvigilateWarnInfoController.java

@@ -1,16 +1,17 @@
-package com.qmth.themis.backend.api;
+package com.qmth.themis.admin.api;
 
 import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.qmth.themis.business.annotation.ApiJsonObject;
 import com.qmth.themis.business.annotation.ApiJsonProperty;
-import com.qmth.themis.business.bean.backend.InvigilateListWarningBean;
+import com.qmth.themis.business.bean.admin.InvigilateListWarningBean;
 import com.qmth.themis.business.constant.SystemConstant;
 import com.qmth.themis.business.dto.AuthDto;
 import com.qmth.themis.business.dto.response.TIeWarningNotifyDto;
 import com.qmth.themis.business.entity.TBUser;
 import com.qmth.themis.business.entity.TIeInvigilateWarnInfo;
 import com.qmth.themis.business.enums.RoleEnum;
+import com.qmth.themis.business.service.CacheService;
 import com.qmth.themis.business.service.TIeInvigilateWarnInfoService;
 import com.qmth.themis.business.service.TOeExamRecordService;
 import com.qmth.themis.business.util.RedisUtil;
@@ -37,15 +38,15 @@ import java.util.*;
 @RequestMapping("/${prefix.url.admin}/invigilate/warn")
 public class TIeInvigilateWarnInfoController {
 
-    @Resource
-    RedisUtil redisUtil;
-
     @Resource
     TIeInvigilateWarnInfoService tIeInvigilateWarnInfoService;
 
     @Resource
     TOeExamRecordService tOeExamRecordService;
 
+    @Resource
+    CacheService cacheService;
+
     @ApiOperation(value = "预警提醒接口")
     @RequestMapping(value = "/notify", method = RequestMethod.POST)
     @ApiResponses({@ApiResponse(code = 200, message = "{\"count\":1}", response = Result.class)})
@@ -53,7 +54,7 @@ public class TIeInvigilateWarnInfoController {
                          @ApiParam(value = "考试场次id", required = false) @RequestParam(required = false) Long examActivityId,
                          @ApiParam(value = "虚拟考场代码", required = false) @RequestParam(required = false) String roomCode) {
         TBUser tbUser = (TBUser) ServletUtil.getRequestAccount();
-        AuthDto authDto = (AuthDto) redisUtil.get(SystemConstant.userOauth + "::" + tbUser.getId());
+        AuthDto authDto = cacheService.addAccountAuthCache(tbUser.getId());
         //如果有监考员角色,只能查看自己所监考的考场,巡考员和管理员则可以查看全部考场
         Long userId = null;
         if (authDto.getRoleCodes().toString().contains(RoleEnum.INVIGILATE.name())) {
@@ -81,7 +82,7 @@ public class TIeInvigilateWarnInfoController {
                        @ApiParam(value = "分页页码", required = true) @RequestParam int pageNumber,
                        @ApiParam(value = "分页数", required = true) @RequestParam int pageSize) {
         TBUser tbUser = (TBUser) ServletUtil.getRequestAccount();
-        AuthDto authDto = (AuthDto) redisUtil.get(SystemConstant.userOauth + "::" + tbUser.getId());
+        AuthDto authDto = cacheService.addAccountAuthCache(tbUser.getId());
         //如果有监考员角色,只能查看自己所监考的考场,巡考员和管理员则可以查看全部考场
         Long userId = null;
         if (authDto.getRoleCodes().toString().contains(RoleEnum.INVIGILATE.name())) {
@@ -95,7 +96,7 @@ public class TIeInvigilateWarnInfoController {
     @ApiResponses({@ApiResponse(code = 200, message = "预警通知信息", response = TIeWarningNotifyDto.class)})
     public Result warningMessage(@ApiParam(value = "考试批次id", required = false) @RequestParam(required = false) Long examId) {
         TBUser tbUser = (TBUser) ServletUtil.getRequestAccount();
-        AuthDto authDto = (AuthDto) redisUtil.get(SystemConstant.userOauth + "::" + tbUser.getId());
+        AuthDto authDto = cacheService.addAccountAuthCache(tbUser.getId());
         //如果有监考员角色,只能查看自己所监考的考场,巡考员和管理员则可以查看全部考场
         Long userId = null;
         if (authDto.getRoleCodes().toString().contains(RoleEnum.INVIGILATE.name())) {
@@ -117,7 +118,7 @@ public class TIeInvigilateWarnInfoController {
         }
         //2020/11/24新增管理员不清除预警状态
         TBUser tbUser = (TBUser) ServletUtil.getRequestAccount();
-        AuthDto authDto = (AuthDto) redisUtil.get(SystemConstant.userOauth + "::" + tbUser.getId());
+        AuthDto authDto = cacheService.addAccountAuthCache(tbUser.getId());
         if (!authDto.getRoleCodes().toString().contains(RoleEnum.ADMIN.name())) {
             List<String> warningIds = (List<String>) mapParameter.get("warningIds");
             if (warningIds.size() > 0) {
@@ -135,7 +136,7 @@ public class TIeInvigilateWarnInfoController {
                 tIeInvigilateWarnInfoService.update(tIeInvigilateWarnInfoUpdateWrapper);
             }
         }
-        return ResultUtil.ok(Collections.singletonMap(SystemConstant.SUCCESS, true));
+        return ResultUtil.ok(true);
     }
 
     @ApiOperation(value = "预警提醒清除未阅列表接口")
@@ -154,7 +155,7 @@ public class TIeInvigilateWarnInfoController {
                                           @ApiParam(value = "预警量min", required = false) @RequestParam(required = false) Integer minWarningCount,
                                           @ApiParam(value = "预警量max", required = false) @RequestParam(required = false) Integer maxWarningCount) {
         TBUser tbUser = (TBUser) ServletUtil.getRequestAccount();
-        AuthDto authDto = (AuthDto) redisUtil.get(SystemConstant.userOauth + "::" + tbUser.getId());
+        AuthDto authDto = cacheService.addAccountAuthCache(tbUser.getId());
         //如果有监考员角色,只能查看自己所监考的考场,巡考员和管理员则可以查看全部考场
         Long userId = null;
         if (authDto.getRoleCodes().toString().contains(RoleEnum.INVIGILATE.name())) {
@@ -164,6 +165,6 @@ public class TIeInvigilateWarnInfoController {
         if (!authDto.getRoleCodes().toString().contains(RoleEnum.ADMIN.name())) {
             tOeExamRecordService.approveStatusListUpdate(examId, examActivityId, roomCode, approveStatus, name, identity, minMultipleFaceCount, maxMultipleFaceCount, minExceptionCount, maxExceptionCount, minWarningCount, maxWarningCount, userId, tbUser.getOrgId());
         }
-        return ResultUtil.ok(Collections.singletonMap(SystemConstant.SUCCESS, true));
+        return ResultUtil.ok(true);
     }
-}
+}

+ 2 - 5
themis-backend/src/main/java/com/qmth/themis/backend/api/TIeReportController.java → themis-admin/src/main/java/com/qmth/themis/admin/api/TIeReportController.java

@@ -1,6 +1,6 @@
-package com.qmth.themis.backend.api;
+package com.qmth.themis.admin.api;
 
-import com.qmth.themis.business.bean.backend.InvigilateListPatrolReportBean;
+import com.qmth.themis.business.bean.admin.InvigilateListPatrolReportBean;
 import com.qmth.themis.business.entity.TBUser;
 import com.qmth.themis.business.service.TIeReportService;
 import com.qmth.themis.business.util.RedisUtil;
@@ -34,9 +34,6 @@ public class TIeReportController {
     @Resource
     private TIeReportService reportService;
 
-    @Resource
-    RedisUtil redisUtil;
-
     @ApiOperation(value = "考试概览")
     @RequestMapping(value = "/exam_view", method = RequestMethod.POST)
     @ApiResponses({@ApiResponse(code = 200, message = "结果信息")})

+ 11 - 12
themis-backend/src/main/java/com/qmth/themis/backend/aspect/ApiControllerAspect.java → themis-admin/src/main/java/com/qmth/themis/admin/aspect/ApiControllerAspect.java

@@ -1,4 +1,4 @@
-package com.qmth.themis.backend.aspect;
+package com.qmth.themis.admin.aspect;
 
 import com.qmth.themis.business.util.JacksonUtil;
 import com.qmth.themis.business.util.ServletUtil;
@@ -12,6 +12,7 @@ import org.aspectj.lang.reflect.MethodSignature;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.stereotype.Component;
+import org.springframework.web.multipart.MultipartFile;
 import org.springframework.web.multipart.commons.CommonsMultipartFile;
 
 import javax.servlet.http.HttpServletRequest;
@@ -27,13 +28,12 @@ import java.util.Objects;
 @Aspect
 @Component
 public class ApiControllerAspect {
-
     private final static Logger log = LoggerFactory.getLogger(ApiControllerAspect.class);
 
     /**
      * api切入点
      */
-    @Pointcut("execution(public * com.qmth.themis.backend.api.*.*(..))")
+    @Pointcut("execution(public * com.qmth.themis.admin.api.*.*(..))")
     public void apiAspect() {
     }
 
@@ -54,30 +54,29 @@ public class ApiControllerAspect {
             Object[] args = joinPoint.getArgs();
             String[] paramsName = msig.getParameterNames();
             HttpServletRequest request = ServletUtil.getRequest();
-            log.info("============请求地址========:{}", request.getRequestURL());
+            log.info("============请求地址========:{}", request.getServletPath());
             log.info("============类=============:{}", className);
             log.info("============方法===========:{}", methodName);
             if (Objects.nonNull(args) && args.length > 0) {
                 boolean jsonOut = true;
                 for (Object o : args) {
-                    if (o instanceof CommonsMultipartFile) {
+                    if (o instanceof CommonsMultipartFile || o instanceof MultipartFile) {
                         jsonOut = false;
                         break;
                     }
                 }
                 if (jsonOut) {
-                    log.info("============参数key:{},参数value===========:{}", JacksonUtil.parseJson(paramsName),
-                            JacksonUtil.parseJson(args));
+                    log.info("============参数key:{},参数value===========:{}", JacksonUtil.parseJson(paramsName), JacksonUtil.parseJson(args));
                 } else {
                     for (int i = 0; i < args.length; i++) {
                         log.info("============参数key:{},参数value===========:{}", paramsName[i], args[i]);
                     }
                 }
             }
-            //log.info("============platform===========:{}", ServletUtil.getRequestPlatform());
-            //log.info("============deviceId===========:{}", ServletUtil.getRequestDeviceId());
-            //log.info("============Authorization===========:{}", ServletUtil.getRequestAuthorizationForAspect());
-            //log.info("============time===========:{}", ServletUtil.getRequestTimeForTime());
+//            log.info("============platform===========:{}", ServletUtil.getRequestPlatform());
+//            log.info("============deviceId===========:{}", ServletUtil.getRequestDeviceId());
+//            log.info("============Authorization===========:{}", ServletUtil.getRequestAuthorizationForAspect());
+//            log.info("============time===========:{}", ServletUtil.getRequestTimeForTime());
             Object proceed = joinPoint.proceed();
             long end = System.currentTimeMillis();
             log.info("============耗时============:{}秒", (end - start) / 1000);
@@ -91,4 +90,4 @@ public class ApiControllerAspect {
             }
         }
     }
-}
+}

+ 23 - 1
themis-backend/src/main/java/com/qmth/themis/backend/config/DictionaryConfig.java → themis-admin/src/main/java/com/qmth/themis/admin/config/DictionaryConfig.java

@@ -1,4 +1,4 @@
-package com.qmth.themis.backend.config;
+package com.qmth.themis.admin.config;
 
 import com.qmth.themis.business.domain.*;
 import org.springframework.boot.context.properties.ConfigurationProperties;
@@ -91,4 +91,26 @@ public class DictionaryConfig {
     public WxappDomain wxappDomain() {
         return new WxappDomain();
     }
+
+    /**
+     * mq配置
+     *
+     * @return
+     */
+    @Bean
+    @ConfigurationProperties(prefix = "mq.config", ignoreUnknownFields = false)
+    public MqConfigDomain mqConfigDomain() {
+        return new MqConfigDomain();
+    }
+
+    /**
+     * 监控配置
+     *
+     * @return
+     */
+    @Bean
+    @ConfigurationProperties(prefix = "monitor.config", ignoreUnknownFields = false)
+    public MonitorDomain monitorDomain() {
+        return new MonitorDomain();
+    }
 }

+ 1 - 1
themis-backend/src/main/java/com/qmth/themis/backend/config/DruidConfig.java → themis-admin/src/main/java/com/qmth/themis/admin/config/DruidConfig.java

@@ -1,4 +1,4 @@
-package com.qmth.themis.backend.config;
+package com.qmth.themis.admin.config;
 
 import com.alibaba.druid.pool.DruidDataSource;
 import com.alibaba.druid.support.http.StatViewServlet;

+ 1 - 1
themis-backend/src/main/java/com/qmth/themis/backend/config/ScheduleTaskConfig.java → themis-admin/src/main/java/com/qmth/themis/admin/config/ScheduleTaskConfig.java

@@ -1,4 +1,4 @@
-package com.qmth.themis.backend.config;
+package com.qmth.themis.admin.config;
 
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;

+ 3 - 3
themis-backend/src/main/java/com/qmth/themis/backend/config/SwaggerConfig.java → themis-admin/src/main/java/com/qmth/themis/admin/config/SwaggerConfig.java

@@ -1,4 +1,4 @@
-package com.qmth.themis.backend.config;
+package com.qmth.themis.admin.config;
 
 import com.google.common.base.Predicates;
 import com.qmth.themis.business.constant.SystemConstant;
@@ -46,9 +46,9 @@ public class SwaggerConfig {
         pars.add(tokenPar3.build());
 
         return new Docket(DocumentationType.SWAGGER_2)
-                .groupName("themis-backend")
+                .groupName("themis-admin")
                 .select()
-                .apis(RequestHandlerSelectors.basePackage("com.qmth.themis.backend"))
+                .apis(RequestHandlerSelectors.basePackage("com.qmth.themis.admin"))
 //                .apis(RequestHandlerSelectors.any())
                 .paths(PathSelectors.any())
                 // 不显示错误的接口地址

+ 3 - 4
themis-backend/src/main/java/com/qmth/themis/backend/config/WebMvcConfig.java → themis-admin/src/main/java/com/qmth/themis/admin/config/WebMvcConfig.java

@@ -1,7 +1,7 @@
-package com.qmth.themis.backend.config;
+package com.qmth.themis.admin.config;
 
-import com.qmth.themis.backend.interceptor.AuthInterceptor;
-import com.qmth.themis.backend.interceptor.AuthThirdInterceptor;
+import com.qmth.themis.admin.interceptor.AuthInterceptor;
+import com.qmth.themis.admin.interceptor.AuthThirdInterceptor;
 import com.qmth.themis.business.constant.SystemConstant;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
@@ -39,7 +39,6 @@ public class WebMvcConfig implements WebMvcConfigurer {
                 .excludePathPatterns(dictionaryConfig.authNoUrlDomain().getUrls());
         registry.addInterceptor(AuthThirdInterceptor()).addPathPatterns(SystemConstant.THIRD_ALL_PATH)
                 .excludePathPatterns(dictionaryConfig.authNoUrlDomain().getUrls());
-        ;
     }
 
     //    @Override

+ 1 - 1
themis-backend/src/main/java/com/qmth/themis/backend/config/WebSocketConfig.java → themis-admin/src/main/java/com/qmth/themis/admin/config/WebSocketConfig.java

@@ -1,4 +1,4 @@
-package com.qmth.themis.backend.config;//package com.qmth.themis.backend.config;
+package com.qmth.themis.admin.config;
 
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;

+ 1 - 1
themis-backend/src/main/java/com/qmth/themis/backend/elasticsearch/entity/ETEStudentEntity.java → themis-admin/src/main/java/com/qmth/themis/admin/elasticsearch/entity/ETEStudentEntity.java

@@ -1,4 +1,4 @@
-//package com.qmth.themis.backend.elasticsearch.entity;
+//package com.qmth.themis.admin.elasticsearch.entity;
 //
 //import com.baomidou.mybatisplus.annotation.TableField;
 //import com.baomidou.mybatisplus.annotation.TableId;

+ 2 - 2
themis-backend/src/main/java/com/qmth/themis/backend/elasticsearch/repository/ETEStudentRepo.java → themis-admin/src/main/java/com/qmth/themis/admin/elasticsearch/repository/ETEStudentRepo.java

@@ -1,6 +1,6 @@
-//package com.qmth.themis.backend.elasticsearch.repository;
+//package com.qmth.themis.admin.elasticsearch.repository;
 //
-//import com.qmth.themis.backend.elasticsearch.entity.ETEStudentEntity;
+//import com.qmth.themis.admin.elasticsearch.entity.ETEStudentEntity;
 //import org.springframework.data.domain.Page;
 //import org.springframework.data.domain.Pageable;
 //import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;

+ 2 - 2
themis-backend/src/main/java/com/qmth/themis/backend/elasticsearch/service/ETEStudentService.java → themis-admin/src/main/java/com/qmth/themis/admin/elasticsearch/service/ETEStudentService.java

@@ -1,6 +1,6 @@
-//package com.qmth.themis.backend.elasticsearch.service;
+//package com.qmth.themis.admin.elasticsearch.service;
 //
-//import com.qmth.themis.backend.elasticsearch.entity.ETEStudentEntity;
+//import com.qmth.themis.admin.elasticsearch.entity.ETEStudentEntity;
 //import org.springframework.data.domain.Page;
 //import org.springframework.data.domain.Pageable;
 //import org.springframework.data.elasticsearch.annotations.Query;

+ 4 - 4
themis-backend/src/main/java/com/qmth/themis/backend/elasticsearch/service/impl/ETEStudentServiceImpl.java → themis-admin/src/main/java/com/qmth/themis/admin/elasticsearch/service/impl/ETEStudentServiceImpl.java

@@ -1,8 +1,8 @@
-//package com.qmth.themis.backend.elasticsearch.service.impl;
+//package com.qmth.themis.admin.elasticsearch.service.impl;
 //
-//import com.qmth.themis.backend.elasticsearch.entity.ETEStudentEntity;
-//import com.qmth.themis.backend.elasticsearch.repository.ETEStudentRepo;
-//import com.qmth.themis.backend.elasticsearch.service.ETEStudentService;
+//import com.qmth.themis.admin.elasticsearch.entity.ETEStudentEntity;
+//import com.qmth.themis.admin.elasticsearch.repository.ETEStudentRepo;
+//import com.qmth.themis.admin.elasticsearch.service.ETEStudentService;
 //import org.springframework.data.domain.Page;
 //import org.springframework.data.domain.PageRequest;
 //import org.springframework.data.domain.Pageable;

+ 61 - 0
themis-admin/src/main/java/com/qmth/themis/admin/interceptor/AuthInterceptor.java

@@ -0,0 +1,61 @@
+package com.qmth.themis.admin.interceptor;
+
+import com.qmth.themis.admin.config.DictionaryConfig;
+import com.qmth.themis.business.constant.SystemConstant;
+import com.qmth.themis.business.util.AuthUtil;
+import com.qmth.themis.business.util.ServletUtil;
+import com.qmth.themis.common.enums.ExceptionResultEnum;
+import com.qmth.themis.common.enums.Platform;
+import com.qmth.themis.common.exception.BusinessException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.web.servlet.HandlerInterceptor;
+import org.springframework.web.servlet.ModelAndView;
+
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+/**
+ * @Description: 鉴权拦截器
+ * @Param:
+ * @return:
+ * @Author: wangliang
+ * @Date: 2020/6/27
+ */
+public class AuthInterceptor implements HandlerInterceptor {
+    private final static Logger log = LoggerFactory.getLogger(AuthInterceptor.class);
+
+    @Resource
+    DictionaryConfig dictionaryConfig;
+
+    @Override
+    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object object) {
+        log.info("admin HandlerInterceptor preHandle is come in");
+        String url = request.getServletPath();
+        String method = request.getMethod();
+        if (url.equalsIgnoreCase(SystemConstant.ERROR)) {
+            throw new BusinessException(ExceptionResultEnum.NOT_FOUND);
+        }
+        Platform platform = ServletUtil.getRequestPlatform();
+        String deviceId = ServletUtil.getRequestDeviceId();
+        String authorization = ServletUtil.getRequestAuthorization();
+        Long time = ServletUtil.getRequestTime();
+        log.info("Start authorization: url:{}, method:{}, platform:{}, deviceId:{}, authorization:{}, time:{}", url,
+                method, platform, deviceId, authorization, time);
+        return AuthUtil.adminAuthInterceptor(platform, deviceId, authorization, time, dictionaryConfig.systemUrlDomain().getUrls(), request, response);
+    }
+
+    @Override
+    public void postHandle(HttpServletRequest request,
+                           HttpServletResponse response,
+                           Object o, ModelAndView modelAndView) throws Exception {
+
+    }
+
+    @Override
+    public void afterCompletion(HttpServletRequest request,
+                                HttpServletResponse response,
+                                Object o, Exception e) throws Exception {
+    }
+}

+ 2 - 17
themis-backend/src/main/java/com/qmth/themis/backend/interceptor/AuthThirdInterceptor.java → themis-admin/src/main/java/com/qmth/themis/admin/interceptor/AuthThirdInterceptor.java

@@ -1,30 +1,15 @@
-package com.qmth.themis.backend.interceptor;
+package com.qmth.themis.admin.interceptor;
 
-import com.qmth.themis.backend.config.DictionaryConfig;
 import com.qmth.themis.business.constant.SystemConstant;
-import com.qmth.themis.business.dto.AuthDto;
-import com.qmth.themis.business.entity.TBSession;
-import com.qmth.themis.business.entity.TBUser;
-import com.qmth.themis.business.service.CacheService;
-import com.qmth.themis.business.service.TBUserService;
-import com.qmth.themis.business.util.RedisUtil;
-import com.qmth.themis.business.util.ServletUtil;
 import com.qmth.themis.common.enums.ExceptionResultEnum;
-import com.qmth.themis.common.enums.Platform;
 import com.qmth.themis.common.exception.BusinessException;
-import com.qmth.themis.common.signature.SignatureInfo;
-import com.qmth.themis.common.signature.SignatureType;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.web.servlet.HandlerInterceptor;
 import org.springframework.web.servlet.ModelAndView;
 
-import javax.annotation.Resource;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
-import java.util.List;
-import java.util.Objects;
-import java.util.Set;
 
 /**
  * @Description: 第三方接口鉴权拦截器
@@ -38,7 +23,7 @@ public class AuthThirdInterceptor implements HandlerInterceptor {
 
     @Override
     public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object object) throws Exception {
-        log.info("backend authThirdInterceptor preHandle is come in");
+        log.info("admin authThirdInterceptor preHandle is come in");
         String url = request.getServletPath();
         String method = request.getMethod();
         if (url.equalsIgnoreCase(SystemConstant.ERROR)) {

+ 1 - 1
themis-backend/src/main/java/com/qmth/themis/backend/listener/service/MqAdminLogicService.java → themis-admin/src/main/java/com/qmth/themis/admin/listener/service/MqAdminLogicService.java

@@ -1,4 +1,4 @@
-package com.qmth.themis.backend.listener.service;
+package com.qmth.themis.admin.listener.service;
 
 import com.qmth.themis.business.dto.MqDto;
 

+ 2 - 2
themis-backend/src/main/java/com/qmth/themis/backend/listener/service/impl/MqAdminLogicServiceImpl.java → themis-admin/src/main/java/com/qmth/themis/admin/listener/service/impl/MqAdminLogicServiceImpl.java

@@ -1,7 +1,7 @@
-package com.qmth.themis.backend.listener.service.impl;
+package com.qmth.themis.admin.listener.service.impl;
 
 import com.google.gson.Gson;
-import com.qmth.themis.backend.listener.service.MqAdminLogicService;
+import com.qmth.themis.admin.listener.service.MqAdminLogicService;
 import com.qmth.themis.business.constant.SystemConstant;
 import com.qmth.themis.business.entity.TMRocketMessage;
 import com.qmth.themis.business.service.TMRocketMessageService;

+ 1 - 1
themis-backend/src/main/java/com/qmth/themis/backend/mongodb/entity/MTEExamActivityEntity.java → themis-admin/src/main/java/com/qmth/themis/admin/mongodb/entity/MTEExamActivityEntity.java

@@ -1,4 +1,4 @@
-//package com.qmth.themis.backend.mongodb.entity;
+//package com.qmth.themis.admin.mongodb.entity;
 //
 //import com.qmth.themis.business.entity.common.ExamActivity;
 //import io.swagger.annotations.ApiModel;

+ 1 - 1
themis-backend/src/main/java/com/qmth/themis/backend/mongodb/entity/MTEExamCourseEntity.java → themis-admin/src/main/java/com/qmth/themis/admin/mongodb/entity/MTEExamCourseEntity.java

@@ -1,4 +1,4 @@
-//package com.qmth.themis.backend.mongodb.entity;
+//package com.qmth.themis.admin.mongodb.entity;
 //
 //import com.qmth.themis.business.entity.common.ExamCourse;
 //import io.swagger.annotations.ApiModel;

+ 1 - 1
themis-backend/src/main/java/com/qmth/themis/backend/mongodb/entity/MTEExamEntity.java → themis-admin/src/main/java/com/qmth/themis/admin/mongodb/entity/MTEExamEntity.java

@@ -1,4 +1,4 @@
-//package com.qmth.themis.backend.mongodb.entity;
+//package com.qmth.themis.admin.mongodb.entity;
 //
 //import com.qmth.themis.business.entity.common.Exam;
 //import io.swagger.annotations.ApiModel;

+ 1 - 1
themis-backend/src/main/java/com/qmth/themis/backend/mongodb/entity/MTEExamPaperEntity.java → themis-admin/src/main/java/com/qmth/themis/admin/mongodb/entity/MTEExamPaperEntity.java

@@ -1,4 +1,4 @@
-//package com.qmth.themis.backend.mongodb.entity;
+//package com.qmth.themis.admin.mongodb.entity;
 //
 //import com.qmth.themis.business.entity.common.ExamPaper;
 //import io.swagger.annotations.ApiModel;

+ 1 - 1
themis-backend/src/main/java/com/qmth/themis/backend/mongodb/entity/MTEExamStudentEntity.java → themis-admin/src/main/java/com/qmth/themis/admin/mongodb/entity/MTEExamStudentEntity.java

@@ -1,4 +1,4 @@
-//package com.qmth.themis.backend.mongodb.entity;
+//package com.qmth.themis.admin.mongodb.entity;
 //
 //import com.qmth.themis.business.entity.common.ExamStudent;
 //import io.swagger.annotations.ApiModel;

+ 1 - 1
themis-backend/src/main/java/com/qmth/themis/backend/mongodb/entity/MTEStudentEntity.java → themis-admin/src/main/java/com/qmth/themis/admin/mongodb/entity/MTEStudentEntity.java

@@ -1,4 +1,4 @@
-//package com.qmth.themis.backend.mongodb.entity;
+//package com.qmth.themis.admin.mongodb.entity;
 //
 //import com.qmth.themis.business.entity.common.Student;
 //import io.swagger.annotations.ApiModel;

+ 2 - 2
themis-backend/src/main/java/com/qmth/themis/backend/mongodb/repository/MTEExamActivityRepo.java → themis-admin/src/main/java/com/qmth/themis/admin/mongodb/repository/MTEExamActivityRepo.java

@@ -1,6 +1,6 @@
-//package com.qmth.themis.backend.mongodb.repository;
+//package com.qmth.themis.admin.mongodb.repository;
 //
-//import com.qmth.themis.backend.mongodb.entity.MTEExamActivityEntity;
+//import com.qmth.themis.admin.mongodb.entity.MTEExamActivityEntity;
 //import org.springframework.data.mongodb.repository.MongoRepository;
 //import org.springframework.data.repository.query.QueryByExampleExecutor;
 //import org.springframework.stereotype.Repository;

+ 2 - 2
themis-backend/src/main/java/com/qmth/themis/backend/mongodb/repository/MTEExamCourseRepo.java → themis-admin/src/main/java/com/qmth/themis/admin/mongodb/repository/MTEExamCourseRepo.java

@@ -1,6 +1,6 @@
-//package com.qmth.themis.backend.mongodb.repository;
+//package com.qmth.themis.admin.mongodb.repository;
 //
-//import com.qmth.themis.backend.mongodb.entity.MTEExamCourseEntity;
+//import com.qmth.themis.admin.mongodb.entity.MTEExamCourseEntity;
 //import org.springframework.data.mongodb.repository.MongoRepository;
 //import org.springframework.data.repository.query.QueryByExampleExecutor;
 //import org.springframework.stereotype.Repository;

+ 3 - 3
themis-backend/src/main/java/com/qmth/themis/backend/mongodb/repository/MTEExamPaperRepo.java → themis-admin/src/main/java/com/qmth/themis/admin/mongodb/repository/MTEExamPaperRepo.java

@@ -1,7 +1,7 @@
-//package com.qmth.themis.backend.mongodb.repository;
+//package com.qmth.themis.admin.mongodb.repository;
 //
-//import com.qmth.themis.backend.mongodb.entity.MTEExamEntity;
-//import com.qmth.themis.backend.mongodb.entity.MTEExamPaperEntity;
+//import com.qmth.themis.admin.mongodb.entity.MTEExamEntity;
+//import com.qmth.themis.admin.mongodb.entity.MTEExamPaperEntity;
 //import org.springframework.data.mongodb.repository.MongoRepository;
 //import org.springframework.data.repository.query.QueryByExampleExecutor;
 //import org.springframework.stereotype.Repository;

+ 2 - 2
themis-backend/src/main/java/com/qmth/themis/backend/mongodb/repository/MTEExamRepo.java → themis-admin/src/main/java/com/qmth/themis/admin/mongodb/repository/MTEExamRepo.java

@@ -1,6 +1,6 @@
-//package com.qmth.themis.backend.mongodb.repository;
+//package com.qmth.themis.admin.mongodb.repository;
 //
-//import com.qmth.themis.backend.mongodb.entity.MTEExamEntity;
+//import com.qmth.themis.admin.mongodb.entity.MTEExamEntity;
 //import org.springframework.data.mongodb.repository.MongoRepository;
 //import org.springframework.data.repository.query.QueryByExampleExecutor;
 //import org.springframework.stereotype.Repository;

+ 3 - 3
themis-backend/src/main/java/com/qmth/themis/backend/mongodb/repository/MTEExamStudentRepo.java → themis-admin/src/main/java/com/qmth/themis/admin/mongodb/repository/MTEExamStudentRepo.java

@@ -1,7 +1,7 @@
-//package com.qmth.themis.backend.mongodb.repository;
+//package com.qmth.themis.admin.mongodb.repository;
 //
-//import com.qmth.themis.backend.mongodb.entity.MTEExamEntity;
-//import com.qmth.themis.backend.mongodb.entity.MTEExamStudentEntity;
+//import com.qmth.themis.admin.mongodb.entity.MTEExamEntity;
+//import com.qmth.themis.admin.mongodb.entity.MTEExamStudentEntity;
 //import org.springframework.data.mongodb.repository.MongoRepository;
 //import org.springframework.data.repository.query.QueryByExampleExecutor;
 //import org.springframework.stereotype.Repository;

+ 2 - 2
themis-backend/src/main/java/com/qmth/themis/backend/mongodb/repository/MTEStudentRepo.java → themis-admin/src/main/java/com/qmth/themis/admin/mongodb/repository/MTEStudentRepo.java

@@ -1,6 +1,6 @@
-//package com.qmth.themis.backend.mongodb.repository;
+//package com.qmth.themis.admin.mongodb.repository;
 //
-//import com.qmth.themis.backend.mongodb.entity.MTEStudentEntity;
+//import com.qmth.themis.admin.mongodb.entity.MTEStudentEntity;
 //import org.springframework.data.mongodb.repository.MongoRepository;
 //import org.springframework.data.repository.query.QueryByExampleExecutor;
 //import org.springframework.stereotype.Repository;

+ 1 - 1
themis-backend/src/main/java/com/qmth/themis/backend/mongodb/service/MTEExamActivityService.java → themis-admin/src/main/java/com/qmth/themis/admin/mongodb/service/MTEExamActivityService.java

@@ -1,4 +1,4 @@
-//package com.qmth.themis.backend.mongodb.service;
+//package com.qmth.themis.admin.mongodb.service;
 //
 ///**
 // * @Description: mongodb 考试场次 服务类

+ 1 - 1
themis-backend/src/main/java/com/qmth/themis/backend/mongodb/service/MTEExamCourseService.java → themis-admin/src/main/java/com/qmth/themis/admin/mongodb/service/MTEExamCourseService.java

@@ -1,4 +1,4 @@
-//package com.qmth.themis.backend.mongodb.service;
+//package com.qmth.themis.admin.mongodb.service;
 //
 ///**
 //* @Description: mongodb 考试科目 服务类

+ 1 - 1
themis-backend/src/main/java/com/qmth/themis/backend/mongodb/service/MTEExamPaperService.java → themis-admin/src/main/java/com/qmth/themis/admin/mongodb/service/MTEExamPaperService.java

@@ -1,4 +1,4 @@
-//package com.qmth.themis.backend.mongodb.service;
+//package com.qmth.themis.admin.mongodb.service;
 //
 ///**
 //* @Description: mongodb 考试试卷 服务类

+ 1 - 1
themis-backend/src/main/java/com/qmth/themis/backend/mongodb/service/MTEExamService.java → themis-admin/src/main/java/com/qmth/themis/admin/mongodb/service/MTEExamService.java

@@ -1,4 +1,4 @@
-//package com.qmth.themis.backend.mongodb.service;
+//package com.qmth.themis.admin.mongodb.service;
 //
 ///**
 //* @Description: mongodb 考试批次 服务类

+ 1 - 1
themis-backend/src/main/java/com/qmth/themis/backend/mongodb/service/MTEExamStudentService.java → themis-admin/src/main/java/com/qmth/themis/admin/mongodb/service/MTEExamStudentService.java

@@ -1,4 +1,4 @@
-//package com.qmth.themis.backend.mongodb.service;
+//package com.qmth.themis.admin.mongodb.service;
 //
 ///**
 //* @Description: mongodb 考生 服务类

+ 1 - 1
themis-backend/src/main/java/com/qmth/themis/backend/mongodb/service/MTEStudentService.java → themis-admin/src/main/java/com/qmth/themis/admin/mongodb/service/MTEStudentService.java

@@ -1,4 +1,4 @@
-//package com.qmth.themis.backend.mongodb.service;
+//package com.qmth.themis.admin.mongodb.service;
 //
 ///**
 //* @Description: mongodb 学生档案 服务类

+ 3 - 3
themis-backend/src/main/java/com/qmth/themis/backend/mongodb/service/impl/MTEExamActivityServiceImpl.java → themis-admin/src/main/java/com/qmth/themis/admin/mongodb/service/impl/MTEExamActivityServiceImpl.java

@@ -1,7 +1,7 @@
-//package com.qmth.themis.backend.mongodb.service.impl;
+//package com.qmth.themis.admin.mongodb.service.impl;
 //
-//import com.qmth.themis.backend.mongodb.repository.MTEExamActivityRepo;
-//import com.qmth.themis.backend.mongodb.service.MTEExamActivityService;
+//import com.qmth.themis.admin.mongodb.repository.MTEExamActivityRepo;
+//import com.qmth.themis.admin.mongodb.service.MTEExamActivityService;
 //import org.springframework.stereotype.Service;
 //
 //import javax.annotation.Resource;

+ 3 - 3
themis-backend/src/main/java/com/qmth/themis/backend/mongodb/service/impl/MTEExamCourseServiceImpl.java → themis-admin/src/main/java/com/qmth/themis/admin/mongodb/service/impl/MTEExamCourseServiceImpl.java

@@ -1,7 +1,7 @@
-//package com.qmth.themis.backend.mongodb.service.impl;
+//package com.qmth.themis.admin.mongodb.service.impl;
 //
-//import com.qmth.themis.backend.mongodb.repository.MTEExamCourseRepo;
-//import com.qmth.themis.backend.mongodb.service.MTEExamCourseService;
+//import com.qmth.themis.admin.mongodb.repository.MTEExamCourseRepo;
+//import com.qmth.themis.admin.mongodb.service.MTEExamCourseService;
 //import org.springframework.stereotype.Service;
 //
 //import javax.annotation.Resource;

+ 3 - 3
themis-backend/src/main/java/com/qmth/themis/backend/mongodb/service/impl/MTEExamPaperServiceImpl.java → themis-admin/src/main/java/com/qmth/themis/admin/mongodb/service/impl/MTEExamPaperServiceImpl.java

@@ -1,7 +1,7 @@
-//package com.qmth.themis.backend.mongodb.service.impl;
+//package com.qmth.themis.admin.mongodb.service.impl;
 //
-//import com.qmth.themis.backend.mongodb.repository.MTEExamPaperRepo;
-//import com.qmth.themis.backend.mongodb.service.MTEExamPaperService;
+//import com.qmth.themis.admin.mongodb.repository.MTEExamPaperRepo;
+//import com.qmth.themis.admin.mongodb.service.MTEExamPaperService;
 //import org.springframework.stereotype.Service;
 //
 //import javax.annotation.Resource;

+ 3 - 3
themis-backend/src/main/java/com/qmth/themis/backend/mongodb/service/impl/MTEExamServiceImpl.java → themis-admin/src/main/java/com/qmth/themis/admin/mongodb/service/impl/MTEExamServiceImpl.java

@@ -1,7 +1,7 @@
-//package com.qmth.themis.backend.mongodb.service.impl;
+//package com.qmth.themis.admin.mongodb.service.impl;
 //
-//import com.qmth.themis.backend.mongodb.repository.MTEExamRepo;
-//import com.qmth.themis.backend.mongodb.service.MTEExamService;
+//import com.qmth.themis.admin.mongodb.repository.MTEExamRepo;
+//import com.qmth.themis.admin.mongodb.service.MTEExamService;
 //import org.springframework.stereotype.Service;
 //
 //import javax.annotation.Resource;

+ 5 - 5
themis-backend/src/main/java/com/qmth/themis/backend/mongodb/service/impl/MTEExamStudentServiceImpl.java → themis-admin/src/main/java/com/qmth/themis/admin/mongodb/service/impl/MTEExamStudentServiceImpl.java

@@ -1,9 +1,9 @@
-//package com.qmth.themis.backend.mongodb.service.impl;
+//package com.qmth.themis.admin.mongodb.service.impl;
 //
-//import com.qmth.themis.backend.mongodb.repository.MTEExamRepo;
-//import com.qmth.themis.backend.mongodb.repository.MTEExamStudentRepo;
-//import com.qmth.themis.backend.mongodb.service.MTEExamService;
-//import com.qmth.themis.backend.mongodb.service.MTEExamStudentService;
+//import com.qmth.themis.admin.mongodb.repository.MTEExamRepo;
+//import com.qmth.themis.admin.mongodb.repository.MTEExamStudentRepo;
+//import com.qmth.themis.admin.mongodb.service.MTEExamService;
+//import com.qmth.themis.admin.mongodb.service.MTEExamStudentService;
 //import org.springframework.stereotype.Service;
 //
 //import javax.annotation.Resource;

+ 3 - 3
themis-backend/src/main/java/com/qmth/themis/backend/mongodb/service/impl/MTEStudentServiceImpl.java → themis-admin/src/main/java/com/qmth/themis/admin/mongodb/service/impl/MTEStudentServiceImpl.java

@@ -1,7 +1,7 @@
-//package com.qmth.themis.backend.mongodb.service.impl;
+//package com.qmth.themis.admin.mongodb.service.impl;
 //
-//import com.qmth.themis.backend.mongodb.repository.MTEStudentRepo;
-//import com.qmth.themis.backend.mongodb.service.MTEStudentService;
+//import com.qmth.themis.admin.mongodb.repository.MTEStudentRepo;
+//import com.qmth.themis.admin.mongodb.service.MTEStudentService;
 //import org.springframework.stereotype.Service;
 //
 //import javax.annotation.Resource;

+ 32 - 0
themis-admin/src/main/java/com/qmth/themis/admin/start/StartRunning.java

@@ -0,0 +1,32 @@
+package com.qmth.themis.admin.start;
+
+import com.qmth.themis.business.constant.SystemConstant;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.boot.CommandLineRunner;
+import org.springframework.stereotype.Component;
+
+/**
+ * @Description: 服务启动时初始化运行,哪个微服务模块需要则拿此模版去用
+ * @Param:
+ * @return:
+ * @Author: wangliang
+ * @Date: 2020/7/3
+ */
+@Component
+public class StartRunning implements CommandLineRunner {
+    private final static Logger log = LoggerFactory.getLogger(StartRunning.class);
+
+//    @Resource
+//    RocketMessageConsumer rocketMessageConsumer;
+
+//    @Value("${rocketmq.name-server}")
+//    String nameServer;
+
+    @Override
+    public void run(String... args) throws Exception {
+        log.info("服务器启动时执行 start");
+        SystemConstant.initTempFiles();
+        log.info("服务器启动时执行 end");
+    }
+}

+ 49 - 81
themis-backend/src/main/java/com/qmth/themis/backend/websocket/WebSocketAdminServer.java → themis-admin/src/main/java/com/qmth/themis/admin/websocket/WebSocketAdminServer.java

@@ -1,20 +1,18 @@
-package com.qmth.themis.backend.websocket;
+package com.qmth.themis.admin.websocket;
 
 import com.alibaba.fastjson.JSONObject;
 import com.google.gson.Gson;
-import com.qmth.themis.backend.websocketTemplete.WebSocketAdminMessageTemplete;
+import com.qmth.themis.admin.websocketTemplete.WebSocketAdminMessageTemplete;
 import com.qmth.themis.business.constant.SpringContextHolder;
 import com.qmth.themis.business.constant.SystemConstant;
 import com.qmth.themis.business.dto.WebsocketDto;
 import com.qmth.themis.business.entity.TBSession;
 import com.qmth.themis.business.enums.WebsocketTypeEnum;
-import com.qmth.themis.business.util.JacksonUtil;
-import com.qmth.themis.business.util.RedisUtil;
-import com.qmth.themis.business.util.WebsocketUtil;
+import com.qmth.themis.business.util.*;
+import com.qmth.themis.common.contanst.Constants;
 import com.qmth.themis.common.enums.ExceptionResultEnum;
+import com.qmth.themis.common.enums.Platform;
 import com.qmth.themis.common.exception.BusinessException;
-import com.qmth.themis.common.signature.SignatureInfo;
-import com.qmth.themis.common.signature.SignatureType;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.stereotype.Component;
@@ -24,7 +22,6 @@ import javax.websocket.server.ServerEndpoint;
 import java.io.IOException;
 import java.lang.reflect.Method;
 import java.net.InetSocketAddress;
-import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Objects;
@@ -40,7 +37,7 @@ import java.util.concurrent.ConcurrentHashMap;
 @ServerEndpoint("/ws/admin")
 @Component
 public class WebSocketAdminServer
-//        implements Concurrently
+//        implements Orderly
 {
     private final static Logger log = LoggerFactory.getLogger(WebSocketAdminServer.class);
     public volatile static ConcurrentHashMap<Long, WebSocketAdminServer> webSocketMap = new ConcurrentHashMap<>();
@@ -48,14 +45,11 @@ public class WebSocketAdminServer
      * 与某个客户端的连接会话,需要通过它来给客户端发送数据
      */
     private Session session = null;
-    private String sessionId = null, ip = null;
-    private Long userId = null;
-    private String platform = null, deviceId = null, Authorization = null;
-    private Long time = null;
+    private Platform platform = null;
+    private String sessionId = null, ip = null, deviceId = null, authorization = null, url = "/ws/admin", websocketSessionId = null;
+    private Long time = null, userId = null, updateTime = null;
     private RedisUtil redisUtil;
-    private Long updateTime = null;
     private Map<String, Object> tranMap = null;
-    private String url = "/ws/admin";
 
     /**
      * 连接建立成功调用的方法
@@ -68,63 +62,37 @@ public class WebSocketAdminServer
         }
         log.info("mapParameter:{}", JacksonUtil.parseJson(mapParameter));
         log.info("uri:{}", session.getRequestURI());
-        if (Objects.isNull(mapParameter.get("platform")) || mapParameter.get("platform").size() == 0) {
+        if (Objects.isNull(mapParameter.get(Constants.HEADER_PLATFORM)) || mapParameter.get(Constants.HEADER_PLATFORM).size() == 0) {
             throw new BusinessException(ExceptionResultEnum.PLATFORM_INVALID);
         }
-        this.platform = String.valueOf(mapParameter.get("platform").get(0));
-        if (Objects.isNull(mapParameter.get("deviceId")) || mapParameter.get("deviceId").size() == 0) {
+        this.platform = Platform.valueOf(mapParameter.get(Constants.HEADER_PLATFORM).get(0));
+        if (Objects.isNull(mapParameter.get(Constants.HEADER_DEVICE_ID)) || mapParameter.get(Constants.HEADER_DEVICE_ID).size() == 0) {
             throw new BusinessException(ExceptionResultEnum.DEVICE_ID_INVALID);
         }
-        this.deviceId = String.valueOf(mapParameter.get("deviceId").get(0));
-        this.Authorization = String.valueOf(mapParameter.get("Authorization").get(0));
-        this.time = Long.parseLong(String.valueOf(mapParameter.get("time").get(0)));
-        this.userId = Long.parseLong(String.valueOf(mapParameter.get("userId").get(0)));
-//        final SignatureInfo info = SignatureInfo
-//                .parse(Authorization);
-        if (!SystemConstant.expire(this.time.longValue())) {
-            final SignatureInfo info = SignatureInfo
-                    .parse(SystemConstant.GET, url, this.time, this.Authorization);
-            if (Objects.nonNull(info) && info.getType() == SignatureType.TOKEN) {
-                String sessionId = info.getInvoker();
-                redisUtil = SpringContextHolder.getBean(RedisUtil.class);
-                TBSession tbSession = (TBSession) redisUtil.getUserSession(sessionId);
-                if (Objects.isNull(tbSession)) {
-                    throw new BusinessException(ExceptionResultEnum.LOGIN_NO);
-                } else {
-                    if (info.validate(tbSession.getAccessToken()) && info.getTimestamp() < tbSession.getExpireTime()
-                            && platform.equalsIgnoreCase(tbSession.getPlatform()) && Objects.equals(deviceId, tbSession.getDeviceId())) {
-                        this.session = session;
-                        session.setMaxIdleTimeout(SystemConstant.WEBSOCKET_MAX_TIME_OUT);
-                        this.sessionId = tbSession.getId();
-                        if (webSocketMap.containsKey(this.userId)) {
-                            webSocketMap.remove(this.userId);
-                            webSocketMap.put(this.userId, this);
-                        } else {
-                            webSocketMap.put(this.userId, this);
-                            addOnlineCount();
-                        }
-                        //发送恢复网络mq消息
-                        log.info("用户连接:{},当前在线人数为:{}", this.sessionId, getOnlineCount());
-                        InetSocketAddress addr = (InetSocketAddress) WebsocketUtil.getFieldInstance(this.session.getAsyncRemote(), "base#socketWrapper#socket#sc#remoteAddress");
-                        this.ip = addr.toString().replace("/", "").split(":")[0];
-//                    this.sendMessage("ip[" + this.ip + "]连接成功");
-                        log.info("ip[:{}]连接成功", this.ip);
-                        tranMap = new HashMap<>();
-                        tranMap.put("userId", this.userId);
-                        tranMap.put("deviceId", this.deviceId);
-                        tranMap.put("ip", this.ip);
-                        this.updateTime = System.currentTimeMillis();
-                        tranMap.put("updateTime", this.updateTime);
-                    } else {
-                        throw new BusinessException(ExceptionResultEnum.AUTHORIZATION_ERROR);
-                    }
-                }
-            } else {
-                throw new BusinessException(ExceptionResultEnum.AUTHORIZATION_ERROR);
-            }
+        this.deviceId = mapParameter.get(Constants.HEADER_DEVICE_ID).get(0);
+        this.authorization = mapParameter.get(Constants.HEADER_AUTHORIZATION).get(0);
+        this.time = Long.parseLong(mapParameter.get(Constants.HEADER_TIME).get(0));
+        this.userId = Long.parseLong(mapParameter.get(Constants.HEADER_USER_ID).get(0));
+
+        redisUtil = SpringContextHolder.getBean(RedisUtil.class);
+        TBSession tbSession = AuthUtil.websocketAuthInterceptor(this.platform, this.deviceId, this.authorization, this.time, SystemConstant.GET, this.url);
+        this.session = session;
+        session.setMaxIdleTimeout(SystemConstant.WEBSOCKET_MAX_TIME_OUT);
+        this.sessionId = tbSession.getId();
+        websocketSessionId = String.valueOf(UidUtil.nextId());
+        if (webSocketMap.containsKey(this.userId)) {
+            webSocketMap.remove(this.userId);
+            webSocketMap.put(this.userId, this);
         } else {
-            throw new BusinessException(ExceptionResultEnum.AUTHORIZATION_ERROR);
+            webSocketMap.put(this.userId, this);
+            addOnlineCount();
         }
+        log.info("用户连接:{},当前在线人数为:{}", this.websocketSessionId, getOnlineCount());
+        InetSocketAddress addr = (InetSocketAddress) WebsocketUtil.getFieldInstance(this.session.getAsyncRemote(), "base#socketWrapper#socket#sc#remoteAddress");
+        this.ip = addr.toString().replace("/", "").split(":")[0];
+        log.info("ip[:{}]连接成功", this.ip);
+        this.updateTime = System.currentTimeMillis();
+        tranMap = WebsocketUtil.initWebsocket(null, userId, deviceId, ip, updateTime);
     }
 
     /**
@@ -139,7 +107,7 @@ public class WebSocketAdminServer
             subOnlineCount();
             //管理端无需发送延时mq消息
         }
-        log.info("用户退出:{},当前在线人数为:{},updateTime:{}", this.sessionId, getOnlineCount(), this.updateTime);
+        log.info("用户退出:{},当前在线人数为:{},updateTime:{}", this.websocketSessionId, getOnlineCount(), this.updateTime);
     }
 
     /**
@@ -161,8 +129,8 @@ public class WebSocketAdminServer
                     WebSocketAdminMessageTemplete webSocketAdminMessageTemplete = SpringContextHolder.getBean(WebSocketAdminMessageTemplete.class);
                     Gson gson = new Gson();
                     WebsocketDto websocketDto = gson.fromJson(gson.toJson(jsonObject), WebsocketDto.class);
-                    Method method = webSocketAdminMessageTemplete.getClass().getDeclaredMethod(WebsocketTypeEnum.valueOf(websocketDto.getType()).getDesc(), String.class);
-                    WebsocketDto result = (WebsocketDto) method.invoke(webSocketAdminMessageTemplete, String.valueOf(websocketDto.getBody()));
+                    Method method = webSocketAdminMessageTemplete.getClass().getDeclaredMethod(WebsocketTypeEnum.valueOf(websocketDto.getType()).getDesc(), String.class, Long.class);
+                    WebsocketDto result = (WebsocketDto) method.invoke(webSocketAdminMessageTemplete, String.valueOf(websocketDto.getBody()), websocketDto.getTime());
                     this.sendMessage(result);
                 }
             } catch (Exception e) {
@@ -179,7 +147,7 @@ public class WebSocketAdminServer
      */
     @OnError
     public void onError(Session session, Throwable error) {
-        log.error("用户错误:{},原因:{}", this.sessionId, error);
+        log.error("用户错误:{},原因:{}", this.websocketSessionId, error);
         throw new BusinessException(error.getMessage());
     }
 
@@ -209,7 +177,7 @@ public class WebSocketAdminServer
      * 在线人数加一
      */
     public synchronized void addOnlineCount() {
-        if (redisUtil.lock(SystemConstant.REDIS_LOCK_WEBSOCKET_PREFIX + this.sessionId, SystemConstant.REDIS_LOCK_WEBSOCKET_TIME_OUT)) {
+        if (redisUtil.lock(SystemConstant.REDIS_LOCK_WEBSOCKET_PREFIX + this.websocketSessionId, SystemConstant.REDIS_LOCK_WEBSOCKET_TIME_OUT)) {
             try {
                 Object o = redisUtil.get(SystemConstant.WEBSOCKET_ADMIN_ONLINE_COUNT);
                 int count = 0;
@@ -219,8 +187,8 @@ public class WebSocketAdminServer
                 count++;
                 redisUtil.set(SystemConstant.WEBSOCKET_ADMIN_ONLINE_COUNT, count);
             } finally {
-                if (Objects.nonNull(this.sessionId)) {
-                    redisUtil.releaseLock(SystemConstant.REDIS_LOCK_WEBSOCKET_PREFIX + this.sessionId);
+                if (Objects.nonNull(this.websocketSessionId)) {
+                    redisUtil.releaseLock(SystemConstant.REDIS_LOCK_WEBSOCKET_PREFIX + this.websocketSessionId);
                 }
             }
         }
@@ -230,7 +198,7 @@ public class WebSocketAdminServer
      * 在线人数减一
      */
     public synchronized void subOnlineCount() {
-        if (redisUtil.lock(SystemConstant.REDIS_LOCK_WEBSOCKET_PREFIX + this.sessionId, SystemConstant.REDIS_LOCK_WEBSOCKET_TIME_OUT)) {
+        if (redisUtil.lock(SystemConstant.REDIS_LOCK_WEBSOCKET_PREFIX + this.websocketSessionId, SystemConstant.REDIS_LOCK_WEBSOCKET_TIME_OUT)) {
             try {
                 Object o = redisUtil.get(SystemConstant.WEBSOCKET_ADMIN_ONLINE_COUNT);
                 int count = 0;
@@ -240,15 +208,15 @@ public class WebSocketAdminServer
                 count--;
                 redisUtil.set(SystemConstant.WEBSOCKET_ADMIN_ONLINE_COUNT, count < 0 ? 0 : count);
             } finally {
-                if (Objects.nonNull(this.sessionId)) {
-                    redisUtil.releaseLock(SystemConstant.REDIS_LOCK_WEBSOCKET_PREFIX + this.sessionId);
+                if (Objects.nonNull(this.websocketSessionId)) {
+                    redisUtil.releaseLock(SystemConstant.REDIS_LOCK_WEBSOCKET_PREFIX + this.websocketSessionId);
                 }
             }
         }
     }
 
 //    @Override
-//    public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> msgs, ConsumeConcurrentlyContext consumeConcurrentlyContext) {
+//    public ConsumeOrderlyStatus consumeMessage(List<MessageExt> msgs, ConsumeOrderlyContext consumeOrderlyContext) {
 //        RedisUtil redisUtil = SpringContextHolder.getBean(RedisUtil.class);
 //        MqAdminLogicService mqAdminLogicService = SpringContextHolder.getBean(MqAdminLogicService.class);
 //        MqDto mqDto = null;
@@ -265,23 +233,23 @@ public class WebSocketAdminServer
 //                } else {
 //                    if (Objects.nonNull(mqDto.getAck()) && mqDto.getAck().intValue() != SystemConstant.STANDARD_ACK_TYPE && Objects.nonNull(redisUtil.get(SystemConstant.MQ_TOPIC_BUFFER_LIST, mqDto.getId())) && redisUtil.lock(SystemConstant.REDIS_LOCK_MQ_PREFIX + mqDto.getId(), SystemConstant.REDIS_LOCK_MQ_TIME_OUT)) {
 //                        mqAdminLogicService.execMqAdminLogic(mqDto, SystemConstant.MQ_TOPIC_BUFFER_LIST);
-//                        return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
+//                        return ConsumeOrderlyStatus.SUCCESS;
 //                    } else {
 //                        log.info(":{}-:{} 消息ack未确认,重发", threadId, threadName);
-//                        return ConsumeConcurrentlyStatus.RECONSUME_LATER;//重试
+//                        return ConsumeConcurrentlyStatus.SUSPEND_CURRENT_QUEUE_A_MOMENT;//重试
 //                    }
 //                }
 //            }
 //        } catch (Exception e) {
 //            log.error("mq websocket admin,消息消费出错", e);
 //            e.printStackTrace();
-//            return ConsumeConcurrentlyStatus.RECONSUME_LATER;//重试
+//            return ConsumeOrderlyStatus.RECONSUME_LATER;//重试
 //        } finally {
 //            if (Objects.nonNull(mqDto)) {
 //                redisUtil.releaseLock(SystemConstant.REDIS_LOCK_MQ_PREFIX + mqDto.getId());
 //            }
 //        }
-//        return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;//成功
+//        return ConsumeOrderlyStatus.SUCCESS;//成功
 //    }
 
     public static ConcurrentHashMap<Long, WebSocketAdminServer> getWebSocketMap() {

+ 7 - 10
themis-backend/src/main/java/com/qmth/themis/backend/websocketTemplete/WebSocketAdminMessageTemplete.java → themis-admin/src/main/java/com/qmth/themis/admin/websocketTemplete/WebSocketAdminMessageTemplete.java

@@ -1,18 +1,14 @@
-package com.qmth.themis.backend.websocketTemplete;
+package com.qmth.themis.admin.websocketTemplete;
 
 import com.alibaba.fastjson.JSONObject;
 import com.qmth.themis.business.constant.SystemConstant;
 import com.qmth.themis.business.dto.WebsocketDto;
-import com.qmth.themis.common.util.Result;
-import com.qmth.themis.common.util.ResultUtil;
+import com.qmth.themis.business.enums.WebsocketTypeEnum;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.stereotype.Component;
-import org.springframework.transaction.annotation.Transactional;
 
 import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
 
 /**
  * @Description: 管理端websocket模版
@@ -29,12 +25,13 @@ public class WebSocketAdminMessageTemplete {
      * 状态同步
      *
      * @param body
+     * @param time
      * @return
      */
-    public WebsocketDto syncStatus(String body) {
+    public WebsocketDto syncStatus(String body, Long time) {
         JSONObject jsonObject = JSONObject.parseObject(body);
         log.info("syncStatus jsonObject:{}", jsonObject.toJSONString());
-        return this.syncAck();
+        return this.syncAck(body, time);
     }
 
     /**
@@ -42,7 +39,7 @@ public class WebSocketAdminMessageTemplete {
      *
      * @return
      */
-    public WebsocketDto syncAck() {
-        return new WebsocketDto(this.getClass().getEnclosingMethod().getName(), Collections.singletonMap(SystemConstant.ACK_MESSAGE, System.currentTimeMillis()));
+    public WebsocketDto syncAck(String body, Long time) {
+        return new WebsocketDto(WebsocketTypeEnum.convertToName(Thread.currentThread().getStackTrace()[1].getMethodName()), Collections.singletonMap(SystemConstant.ACK_MESSAGE, time));
     }
 }

+ 33 - 10
themis-backend/src/main/resources/application.properties → themis-admin/src/main/resources/application.properties

@@ -11,18 +11,18 @@ server.tomcat.uri-encoding=UTF-8
 spring.application.name=themis-admin
 
 #\u6570\u636E\u6E90\u914D\u7F6E
-db.host=localhost
+db.host=192.168.10.36
 db.port=3306
-db.name=themis
+db.name=themis_test_v1.1
 db.username=root
-db.password=123456789
+db.password=Qmth87863577!
 #redis\u6570\u636E\u6E90\u914D\u7F6E
-redis.host=${db.host}
-redis.database=15
+redis.host=192.168.10.36
+redis.database=13
 redis.port=6379
-redis.password=
+redis.password=123456
 #mongodb\u6570\u636E\u6E90\u914D\u7F6E
-#mongodb.database=themis-backend
+#mongodb.database=themis-admin
 #mongodb.host=${db.host}
 #mongodb.port=27017
 spring.datasource.url=jdbc:mysql://${db.host}:${db.port}/${db.name}?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=UTF-8
@@ -130,7 +130,7 @@ tencentyun.sdk.urls=https://live1.qmth.com.cn,https://live2.qmth.com.cn,https://
 #\u7CFB\u7EDF\u914D\u7F6E
 sys.config.datacenterId=1
 sys.config.oss=true
-sys.config.attachmentType=.xlsx,.xls,.doc,.docx,.pdf,.jpg,.jpeg,.png,.html,.zip,.mp3,.wav
+sys.config.attachmentType=.xlsx,.xls,.doc,.docx,.pdf,.jpg,.jpeg,.png,.html,.zip,.mp3,.wav,.dll,.exe
 sys.config.serverUpload=/Users/king/git/themis-files/
 #\u7F51\u5173accessKey\u548Csecret,\u6D4B\u8BD5\u7528
 #sys.config.gatewayAccessKey=LTAI4FhEmrrhh27vzPGh25xe
@@ -167,10 +167,33 @@ rocketmq.producer.enable-msg-trace=true
 #\u81EA\u5B9A\u4E49\u7684\u6D88\u606F\u8F68\u8FF9\u4E3B\u9898
 #rocketmq.producer.customized-trace-topic=my-trace-topic
 
+#mq topic\u548Cgroup\u914D\u7F6E
+mq.config.topic=themis-topic-exam
+mq.config.map.SESSION_GROUP=themis-group-exam-session
+mq.config.map.USER_LOG_GROUP=themis-group-exam-userLog
+mq.config.map.LOG_GROUP=themis-group-exam-log
+mq.config.map.TASK_GROUP=themis-group-exam-task
+mq.config.map.WEBSOCKET_DELAY_GROUP=themis-group-exam-websocketDelay
+mq.config.map.QUARTZ_GROUP=themis-group-exam-quartz
+mq.config.map.CALCULATE_OBJECTIVE_SCORE_GROUP=themis-group-exam-calculateObjectiveScore
+mq.config.map.FACE_VERIFY_SAVE_GROUP=themis-group-exam-faceVerifySave
+mq.config.map.LIVENESS_VERIFY_SAVE_GROUP=themis-group-exam-livenessVerifySave
+mq.config.map.EXAM_RECORD_PERSISTED_GROUP=themis-group-exam-examRecordPersisted
+mq.config.map.EXAM_RECORD_UPDATE_GROUP=themis-group-exam-examRecordUpdate
+mq.config.map.EXAM_BREAK_RECORD_PERSISTED_GROUP=themis-group-exam-examBreakHistoryPersisted
+mq.config.map.SCORE_CALCULATE_GROUP=themis-group-exam-scoreCalculate
+mq.config.map.EXAM_STUDENT_UPDATE_GROUP=themis-group-exam-examStudentUpdate
+mq.config.map.EXAM_BREAK_GROUP=themis-group-exam-examBreak
+mq.config.map.EXAM_BREAK_DELAY_GROUP=themis-group-exam-examBreakDelay
+mq.config.map.WEBSOCKET_OE_GROUP=themis-group-exam-websocketOe
+mq.config.map.WEBSOCKET_OE_MOBILE_GROUP=themis-group-exam-websocketOeMobile
+
 #api\u524D\u7F00
 prefix.url.admin=api/admin
 prefix.url.open=api/open
 
+monitor.config.prefix=oe_test
+
 #\u65E0\u9700\u9274\u6743\u7684url
-no.auth.urls=/webjars/**,/druid/**,/swagger-ui.html,/doc.html,/swagger-resources/**,/v2/api-docs,/webjars/springfox-swagger-ui/**,/api/admin/user/login/account,/api/admin/sys/org/queryByOrgCode,/file/**,/upload/**,/client/**,/base_photo/**,/frontend/**
-common.system.urls=/api/admin/sys/getMenu,/api/admin/user/logout,/api/admin/sys/env,/api/admin/sys/file/upload,/api/admin/sys/file/download,/api/admin/sys/org/query,/api/admin/sys/role/query,/api/admin/sys/examActivity/query,/api/admin/sys/exam/query,/api/admin/sys/examRoom/query,/api/admin/sys/exam/privilegeQuery,/api/admin/student/photo/upload,/api/admin/sys/getPlayUrls
+no.auth.urls=/webjars/**,/druid/**,/swagger-ui.html,/doc.html,/swagger-resources/**,/v2/api-docs,/webjars/springfox-swagger-ui/**,/api/admin/user/login/account,/api/admin/sys/org/queryByOrgCode,/file/**,/upload/**,/client/**,/base_photo/**,/frontend/**,/api/admin/client/save,/api/admin/client/upload,/api/admin/client/query,/api/admin/app/save,/api/admin/app/query
+common.system.urls=/api/admin/sys/getMenu,/api/admin/user/logout,/api/admin/sys/env,/api/admin/sys/file/upload,/api/admin/sys/file/download,/api/admin/sys/org/query,/api/admin/sys/role/query,/api/admin/sys/examActivity/query,/api/admin/sys/exam/query,/api/admin/sys/examRoom/query,/api/admin/sys/exam/privilegeQuery,/api/admin/student/photo/upload,/api/admin/sys/getPlayUrls

+ 13 - 15
themis-backend/src/main/resources/logback-spring.xml → themis-admin/src/main/resources/logback-spring.xml

@@ -1,44 +1,42 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <configuration debug="true" scan="true" scanPeriod="30 seconds">
 
-    <springProperty scope="context" name="logLevel" source="logging.level.root"/>
+    <springProperty scope="context" name="logLevel" source="logging.level.root" />
 
     <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
         <encoder>
-            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS}| %thread | %level | %X{TRACE_ID} - %X{KEY} | %m | [%class:%line]%n
-            </pattern>
+            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS}| %thread | %level | %X{TRACE_ID} - %X{KEY} | %m | [%class:%line]%n</pattern>
             <charset>UTF-8</charset>
         </encoder>
     </appender>
 
     <!-- debug 日志 -->
     <appender name="DEBUG_APPENDER" class="ch.qos.logback.core.rolling.RollingFileAppender">
-        <file>logs/themis-backend.log</file>
+        <file>logs/themis-admin.log</file>
         <encoder>
-            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS}| %thread | %level | %X{TRACE_ID} - %X{KEY} | %m | [%class:%line]%n
-            </pattern>
+            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS}| %thread | %level | %X{TRACE_ID} - %X{KEY} | %m | [%class:%line]%n</pattern>
             <charset>UTF-8</charset>
         </encoder>
         <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
-            <fileNamePattern>logs/themis-backend.%d{yyyy-MM-dd}.%i.log</fileNamePattern>
-            <maxHistory>7</maxHistory>
+            <fileNamePattern>logs/themis-admin.%d{yyyy-MM-dd}.%i.log</fileNamePattern>
+            <maxHistory>100</maxHistory>
             <maxFileSize>100MB</maxFileSize>
         </rollingPolicy>
     </appender>
 
     <logger name="org.springframework" level="${logLevel}" additivity="false">
         <appender-ref ref="DEBUG_APPENDER"/>
-        <appender-ref ref="STDOUT"/>
+        <appender-ref ref="STDOUT" />
     </logger>
 
-    <logger name="com.qmth.themis.backend" level="${logLevel}" additivity="false">
-        <appender-ref ref="DEBUG_APPENDER"/>
-        <appender-ref ref="STDOUT"/>
+    <logger name="com.qmth.themis.admin" level="${logLevel}" additivity="false">
+        <appender-ref ref="DEBUG_APPENDER" />
+        <appender-ref ref="STDOUT" />
     </logger>
 
     <root level="INFO">
-        <appender-ref ref="DEBUG_APPENDER"/>
-        <appender-ref ref="STDOUT"/>
+        <appender-ref ref="DEBUG_APPENDER" />
+        <appender-ref ref="STDOUT" />
     </root>
 
-</configuration>
+</configuration>

+ 2 - 2
themis-backend/src/test/java/com/qmth/themis/backend/ThemisBackendApplicationTests.java → themis-admin/src/test/java/com/qmth/themis/admin/ThemisAdminApplicationTests.java

@@ -1,10 +1,10 @@
-package com.qmth.themis.backend;
+package com.qmth.themis.admin;
 
 import org.junit.jupiter.api.Test;
 import org.springframework.boot.test.context.SpringBootTest;
 
 @SpringBootTest
-class ThemisBackendApplicationTests {
+class ThemisAdminApplicationTests {
 
     @Test
     void contextLoads() {

+ 0 - 140
themis-backend/src/main/java/com/qmth/themis/backend/api/TEExamActivityController.java

@@ -1,140 +0,0 @@
-package com.qmth.themis.backend.api;
-
-import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
-import com.qmth.themis.business.constant.SystemConstant;
-import com.qmth.themis.business.dto.MqDto;
-import com.qmth.themis.business.entity.TBUser;
-import com.qmth.themis.business.entity.TEExam;
-import com.qmth.themis.business.entity.TEExamActivity;
-import com.qmth.themis.business.enums.FieldUniqueEnum;
-import com.qmth.themis.business.enums.InvigilateMonitorStatusEnum;
-import com.qmth.themis.business.enums.MqTagEnum;
-import com.qmth.themis.business.enums.MqTopicEnum;
-import com.qmth.themis.business.service.MqDtoService;
-import com.qmth.themis.business.service.TEExamActivityService;
-import com.qmth.themis.business.service.TEExamService;
-import com.qmth.themis.business.util.JacksonUtil;
-import com.qmth.themis.business.util.RedisUtil;
-import com.qmth.themis.business.util.ServletUtil;
-import com.qmth.themis.business.util.UidUtil;
-import com.qmth.themis.common.enums.ExceptionResultEnum;
-import com.qmth.themis.common.exception.BusinessException;
-import com.qmth.themis.common.util.Result;
-import com.qmth.themis.common.util.ResultUtil;
-import io.swagger.annotations.*;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.dao.DuplicateKeyException;
-import org.springframework.transaction.annotation.Transactional;
-import org.springframework.web.bind.annotation.*;
-
-import javax.annotation.Resource;
-import java.util.*;
-
-/**
- * @Description: 考试场次 前端控制器
- * @Param:
- * @return:
- * @Author: wangliang
- * @Date: 2020/6/25
- */
-@Api(tags = "考试场次Controller")
-@RestController
-@RequestMapping("/${prefix.url.admin}/activity")
-public class TEExamActivityController {
-
-    private final static Logger log = LoggerFactory.getLogger(TEExamActivityController.class);
-
-    @Resource
-    TEExamActivityService teExamActivityService;
-
-    @Resource
-    MqDtoService mqDtoService;
-
-    @Resource
-    TEExamService teExamService;
-
-    @Resource
-    RedisUtil redisUtil;
-
-    @Resource
-    UidUtil uidUtil;
-
-    @ApiOperation(value = "考试场次修改/新增接口")
-    @RequestMapping(value = "/save", method = RequestMethod.POST)
-    @Transactional
-    @ApiResponses({ @ApiResponse(code = 200, message = "{\"success\":true}", response = Result.class) })
-    public Result save(
-            @ApiParam(value = "考试场次信息", required = true) @RequestBody List<TEExamActivity> teExamActivityList) {
-        if (Objects.isNull(teExamActivityList) || teExamActivityList.size() == 0) {
-            throw new BusinessException(ExceptionResultEnum.EXAM_INFO_IS_NULL);
-        }
-        Long examId = null;
-        try {
-            TBUser tbUser = (TBUser) ServletUtil.getRequestAccount();
-            teExamActivityList.forEach(s -> {
-                if (Objects.nonNull(s.getId())) {
-                    s.setUpdateId(tbUser.getId());
-                } else {
-                    s.setId(uidUtil.getId());
-                    s.setCreateId(tbUser.getId());
-                    s.setCode(String.valueOf(redisUtil.getRedisActivityCodeSequence(s.getExamId())));
-                }
-                teExamActivityService.saveOrUpdate(s);
-            });
-            examId = teExamActivityList.get(0).getExamId();
-            TEExam teExam = teExamService.getById(teExamActivityList.get(0).getExamId());
-            if (Objects.nonNull(teExam.getMonitorStatus()) && Objects
-                    .equals(teExam.getMonitorStatus(), InvigilateMonitorStatusEnum.FINISHED)) {
-                throw new BusinessException("监考结束的考试场次不可以修改");
-            }
-            for (TEExamActivity ac : teExamActivityList) {
-                teExamActivityService.updateExamActivityCacheBean(ac.getId());
-            }
-            if (Objects.nonNull(teExam.getForceFinish()) && teExam.getForceFinish().intValue() == 1) {
-                //新增quartz任务,发送mq消息start
-                Map<String, Object> prop = new HashMap<>();
-                prop.put("oper", "insert");
-                prop.put("exam", teExam);
-                MqDto mqDto = new MqDto(MqTopicEnum.THEMIS_TOPIC.getCode(), MqTagEnum.EXAM_ACTIVITY.name(),
-                        JacksonUtil.parseJson(teExamActivityList), MqTagEnum.EXAM_ACTIVITY,
-                        String.valueOf(teExam.getId()), prop, tbUser.getName());
-                mqDtoService.assembleSendOneWayMsg(mqDto);
-                //新增quartz任务,发送mq消息end
-            }
-        } catch (Exception e) {
-            log.error("请求出错", e);
-            if (Objects.nonNull(examId) && Objects.nonNull(teExamActivityList) && (Objects.nonNull(teExamActivityList)
-                    && teExamActivityList.size() > 0 && Objects.nonNull(teExamActivityList.get(0)))) {
-                redisUtil.setRedisActivityCodeSequence(examId,
-                        Integer.parseInt(teExamActivityList.get(0).getCode()) - 1);
-            }
-            if (e instanceof DuplicateKeyException) {
-                String errorColumn = e.getCause().toString();
-                String columnStr = errorColumn.substring(errorColumn.lastIndexOf("key") + 3, errorColumn.length())
-                        .replaceAll("'", "");
-                throw new BusinessException("机构id[" + teExamActivityList.get(0).getExamId() + "]下的" + FieldUniqueEnum
-                        .convertToCode(columnStr) + "数据不允许重复插入");
-            } else if (e instanceof BusinessException) {
-                throw new BusinessException(e.getMessage());
-            } else {
-                throw new RuntimeException(e);
-            }
-        }
-        return ResultUtil.ok(Collections.singletonMap(SystemConstant.SUCCESS, true));
-    }
-
-    @ApiOperation(value = "考试场次查询接口")
-    @RequestMapping(value = "/query", method = RequestMethod.POST)
-    @ApiResponses({ @ApiResponse(code = 200, message = "考试场次信息", response = TEExamActivity.class) })
-    public Result query(@ApiParam(value = "主键", required = false) @RequestParam(required = false) Long id,
-            @ApiParam(value = "考试批次id", required = false) @RequestParam(required = false) Long examId,
-            @ApiParam(value = "考试场次编码", required = false) @RequestParam(required = false) String code,
-            @ApiParam(value = "开始日期", required = false) @RequestParam(required = false) Long startDate,
-            @ApiParam(value = "结束日期", required = false) @RequestParam(required = false) Long finishDate,
-            @ApiParam(value = "分页页码", required = true) @RequestParam int pageNumber,
-            @ApiParam(value = "分页数", required = true) @RequestParam int pageSize) {
-        return ResultUtil.ok(teExamActivityService
-                .examActivityQuery(new Page<>(pageNumber, pageSize), id, examId, code, startDate, finishDate));
-    }
-}

+ 0 - 145
themis-backend/src/main/java/com/qmth/themis/backend/interceptor/AuthInterceptor.java

@@ -1,145 +0,0 @@
-package com.qmth.themis.backend.interceptor;
-
-import com.qmth.themis.backend.config.DictionaryConfig;
-import com.qmth.themis.business.constant.SystemConstant;
-import com.qmth.themis.business.dto.AuthDto;
-import com.qmth.themis.business.entity.TBSession;
-import com.qmth.themis.business.entity.TBUser;
-import com.qmth.themis.business.service.CacheService;
-import com.qmth.themis.business.service.TBUserService;
-import com.qmth.themis.business.util.RedisUtil;
-import com.qmth.themis.business.util.ServletUtil;
-import com.qmth.themis.common.enums.ExceptionResultEnum;
-import com.qmth.themis.common.enums.Platform;
-import com.qmth.themis.common.exception.BusinessException;
-import com.qmth.themis.common.signature.SignatureInfo;
-import com.qmth.themis.common.signature.SignatureType;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.web.servlet.HandlerInterceptor;
-import org.springframework.web.servlet.ModelAndView;
-
-import javax.annotation.Resource;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import java.util.List;
-import java.util.Objects;
-import java.util.Set;
-
-/**
- * @Description: 鉴权拦截器
- * @Param:
- * @return:
- * @Author: wangliang
- * @Date: 2020/6/27
- */
-public class AuthInterceptor implements HandlerInterceptor {
-
-    private final static Logger log = LoggerFactory.getLogger(AuthInterceptor.class);
-
-    @Resource
-    CacheService cacheService;
-
-    @Resource
-    DictionaryConfig dictionaryConfig;
-
-    @Resource
-    TBUserService tbUserService;
-
-    @Resource
-    RedisUtil redisUtil;
-
-    @Override
-    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object object) throws Exception {
-        log.info("backend HandlerInterceptor preHandle is come in");
-        String url = request.getServletPath();
-        String method = request.getMethod();
-        if (url.equalsIgnoreCase(SystemConstant.ERROR)) {
-            throw new BusinessException(ExceptionResultEnum.NOT_FOUND);
-        }
-        Platform platform = ServletUtil.getRequestPlatform();
-        String deviceId = ServletUtil.getRequestDeviceId();
-        String authorization = ServletUtil.getRequestAuthorization();
-        long time = ServletUtil.getRequestTime();
-        log.info("platform:{},deviceId:{},authorization:{},method:{},time:{}", platform, deviceId, authorization,
-                method, time);
-        Long userId = null;
-        if (!SystemConstant.expire(time)) {
-            final SignatureInfo info = SignatureInfo.parse(method.toLowerCase(), url, time, authorization);
-            //测试
-            //        final SignatureInfo info = SignatureInfo
-            //                .parse(authorization);
-            if (Objects.nonNull(info) && info.getType() == SignatureType.TOKEN) {
-                String sessionId = info.getInvoker();
-                TBSession tbSession = (TBSession) redisUtil.getUserSession(sessionId);
-                if (Objects.isNull(tbSession)) {
-                    throw new BusinessException(ExceptionResultEnum.LOGIN_NO);
-                } else {
-                    if (info.validate(tbSession.getAccessToken()) && info.getTimestamp() < tbSession.getExpireTime()
-                            && platform.name().equalsIgnoreCase(tbSession.getPlatform()) && Objects
-                            .equals(deviceId, tbSession.getDeviceId())) {
-                        userId = Long.parseLong(tbSession.getIdentity());
-                        Long expireTime = tbSession.getExpireTime();
-                        //手机端的token时长为一个月,所以会出现缓存没有的情况
-                        if (expireTime <= System.currentTimeMillis()) {//先判断时间是否过期
-                            throw new BusinessException(ExceptionResultEnum.LOGIN_NO);
-                        }
-                        TBUser tbUser = (TBUser) redisUtil.getUser(userId);
-                        if (Objects.isNull(tbUser)) {
-                            tbUser = tbUserService.getById(userId);
-                            redisUtil.setUser(tbUser.getId(), tbUser);
-                        }
-
-                        request.setAttribute(SystemConstant.SESSION, tbSession);
-                        request.setAttribute(SystemConstant.ACCOUNT, tbUser);
-
-                        AuthDto authDto = (AuthDto) redisUtil.get(SystemConstant.userOauth + "::" + userId);
-                        //验证权限
-                        if (Objects.isNull(authDto)) {
-                            authDto = cacheService.addAccountCache(userId);
-                        }
-                        request.setAttribute(SystemConstant.ORG, authDto.getTbOrg());
-                        //系统管理员拥有所有权限
-                        //                    if (authDto.getRoleCodes().contains(RoleEnum.SUPER_ADMIN.name())) {
-                        //                        return true;
-                        //                    }
-                        //系统公用接口不拦截
-                        List<String> sysUrls = dictionaryConfig.systemUrlDomain().getUrls();
-                        int sysCount = (int) sysUrls.stream().filter(s -> {
-                            return s.equalsIgnoreCase(url);
-                        }).count();
-                        if (sysCount > 0) {
-                            return true;
-                        }
-                        Set<String> urls = authDto.getUrls();
-                        int count = (int) urls.stream().filter(s -> {
-                            return s.equalsIgnoreCase(url);
-                        }).count();
-                        if (count == 0) {
-                            throw new BusinessException(ExceptionResultEnum.UN_AUTHORIZATION);
-                        }
-                    } else {
-                        throw new BusinessException(ExceptionResultEnum.AUTHORIZATION_ERROR);
-                    }
-                }
-            } else {
-                throw new BusinessException(ExceptionResultEnum.AUTHORIZATION_ERROR);
-            }
-        } else {
-            throw new BusinessException(ExceptionResultEnum.AUTHORIZATION_ERROR);
-        }
-        response.setStatus(ExceptionResultEnum.SUCCESS.getCode());
-        return true;
-    }
-
-    @Override
-    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object o,
-            ModelAndView modelAndView) throws Exception {
-
-    }
-
-    @Override
-    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object o, Exception e)
-            throws Exception {
-    }
-}

+ 0 - 88
themis-backend/src/main/java/com/qmth/themis/backend/start/StartRunning.java

@@ -1,88 +0,0 @@
-package com.qmth.themis.backend.start;
-
-import com.qmth.themis.business.constant.SpringContextHolder;
-import com.qmth.themis.business.constant.SystemConstant;
-import com.qmth.themis.business.enums.MqGroupEnum;
-import com.qmth.themis.business.enums.MqTagEnum;
-import com.qmth.themis.business.enums.MqTopicEnum;
-import com.qmth.themis.mq.listener.RocketMessageConsumer;
-import com.qmth.themis.mq.templete.impl.*;
-import org.apache.rocketmq.common.protocol.heartbeat.MessageModel;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Value;
-import org.springframework.boot.CommandLineRunner;
-import org.springframework.stereotype.Component;
-
-import javax.annotation.Resource;
-
-/**
- * @Description: 服务启动时初始化运行,哪个微服务模块需要则拿此模版去用
- * @Param:
- * @return:
- * @Author: wangliang
- * @Date: 2020/7/3
- */
-@Component
-public class StartRunning implements CommandLineRunner {
-    private final static Logger log = LoggerFactory.getLogger(StartRunning.class);
-
-    @Resource
-    RocketMessageConsumer rocketMessageConsumer;
-
-    @Value("${rocketmq.name-server}")
-    String nameServer;
-
-    @Override
-    public void run(String... args) throws Exception {
-        log.info("服务器启动时执行 start");
-        /**
-         * session
-         */
-        rocketMessageConsumer.setRocketMQConsumer(nameServer, MqGroupEnum.SESSION_GROUP.getCode(), MqTopicEnum.THEMIS_TOPIC.getCode(), MqTagEnum.WEB.name() + "||" + MqTagEnum.WIN.name() + "||" + MqTagEnum.MAC.name() + "||" + MqTagEnum.WXAPP.name() + "||" + MqTagEnum.IOS.name() + "||" + MqTagEnum.ANDROID.name(), MessageModel.CLUSTERING, SpringContextHolder.getBean(SessionConcurrentlyImpl.class));
-        /**
-         * userLog
-         */
-        rocketMessageConsumer.setRocketMQConsumer(nameServer, MqGroupEnum.USER_LOG_GROUP.getCode(), MqTopicEnum.THEMIS_TOPIC.getCode(), MqTagEnum.USER.name() + "||" + MqTagEnum.STUDENT.name(), MessageModel.CLUSTERING, SpringContextHolder.getBean(UserLogConcurrentlyImpl.class));
-        /**
-         * task
-         */
-        rocketMessageConsumer.setRocketMQConsumer(nameServer, MqGroupEnum.TASK_GROUP.getCode(), MqTopicEnum.THEMIS_TOPIC.getCode(), MqTagEnum.EXAM_STUDENT_IMPORT.name() + "||" + MqTagEnum.ROOM_CODE_IMPORT.name() + "||" + MqTagEnum.ROOM_CODE_EXPORT.name() + "||" + MqTagEnum.EXAM_PAPER_IMPORT.name() + "||" + MqTagEnum.EXAM_STUDENT_EXPORT.name() + "||" + MqTagEnum.MARK_RESULT_SIMPLE_EXPORT.name() + "||" + MqTagEnum.MARK_RESULT_STANDARD_EXPORT.name(), MessageModel.CLUSTERING, SpringContextHolder.getBean(TaskConcurrentlyImpl.class));
-        /**
-         * log
-         */
-        rocketMessageConsumer.setRocketMQConsumer(nameServer, MqGroupEnum.LOG_GROUP.getCode(), MqTopicEnum.THEMIS_TOPIC.getCode(), MqTagEnum.EXCEPTION_LOG.name() + "||" + MqTagEnum.WARNING_LOG.name() + "||" + MqTagEnum.MONITOR_LOG.name(), MessageModel.CLUSTERING, SpringContextHolder.getBean(LogConcurrentlyImpl.class));
-        /**
-         * websocket mq start
-         */
-        rocketMessageConsumer.setRocketMQConsumer(nameServer, MqGroupEnum.WEBSOCKET_DELAY_GROUP.getCode(), MqTopicEnum.THEMIS_TOPIC.getCode(), MqTagEnum.OE_UN_NORMAL.name(), MessageModel.CLUSTERING, SpringContextHolder.getBean(WebsocketUnNormalConcurrentlyImpl.class));
-        /**
-         * websocket mq end
-         */
-        //计算客观分
-        rocketMessageConsumer.setRocketMQConsumer(nameServer, MqGroupEnum.CALCULATE_OBJECTIVE_SCORE_GROUP.getCode(), MqTopicEnum.THEMIS_TOPIC.getCode(), MqTagEnum.CALCULATE_OBJECTIVE_SCORE.name(), MessageModel.CLUSTERING, SpringContextHolder.getBean(CalculateObjectiveScoreConcurrentlyImpl.class));
-        //人脸验证保存
-        rocketMessageConsumer.setRocketMQConsumer(nameServer, MqGroupEnum.FACE_VERIFY_SAVE_GROUP.getCode(), MqTopicEnum.THEMIS_TOPIC.getCode(), MqTagEnum.FACE_VERIFY_SAVE.name(), MessageModel.CLUSTERING, SpringContextHolder.getBean(FaceVerifyConcurrentlyImpl.class));
-        //活体验证保存
-        rocketMessageConsumer.setRocketMQConsumer(nameServer, MqGroupEnum.LIVENESS_VERIFY_SAVE_GROUP.getCode(), MqTopicEnum.THEMIS_TOPIC.getCode(), MqTagEnum.LIVENESS_VERIFY_SAVE.name(), MessageModel.CLUSTERING, SpringContextHolder.getBean(LivenessVerifyConcurrentlyImpl.class));
-        //考试记录数据持久化
-        rocketMessageConsumer.setRocketMQConsumer(nameServer, MqGroupEnum.EXAM_RECORD_PERSISTED_GROUP.getCode(), MqTopicEnum.THEMIS_TOPIC.getCode(), MqTagEnum.EXAM_RECORD_PERSISTED.name(), MessageModel.CLUSTERING, SpringContextHolder.getBean(ExamRecordPersistedConcurrentlyImpl.class));
-        //考试记录数据更新
-        rocketMessageConsumer.setRocketMQConsumer(nameServer, MqGroupEnum.EXAM_RECORD_UPDATE_GROUP.getCode(), MqTopicEnum.THEMIS_TOPIC.getCode(), MqTagEnum.EXAM_RECORD_UPDATE.name() + "||" + MqTagEnum.EXAM_RECORD_UPDATE_COLUMNS.name() + "||" + MqTagEnum.EXAM_BREAK_HISTORY_UPDATE.name() + "||" + MqTagEnum.EXAM_BREAK_HISTORY_UPDATE_COLUMNS.name(), MessageModel.CLUSTERING, SpringContextHolder.getBean(ExamRecordUpdateConcurrentlyImpl.class));
-        //考试记录数据初始化
-        rocketMessageConsumer.setRocketMQConsumer(nameServer, MqGroupEnum.EXAM_RECORD_INIT_GROUP.getCode(), MqTopicEnum.THEMIS_TOPIC.getCode(), MqTagEnum.EXAM_RECORD_INIT.name(), MessageModel.CLUSTERING, SpringContextHolder.getBean(ExamRecordInitConcurrentlyImpl.class));
-
-        //考试重新算分
-        rocketMessageConsumer.setRocketMQConsumer(nameServer, MqGroupEnum.SCORE_CALCULATE_GROUP.getCode(), MqTopicEnum.THEMIS_TOPIC.getCode(), MqTagEnum.EXAM_SCORE_CALCULATE.name(), MessageModel.CLUSTERING, SpringContextHolder.getBean(CalculateScoreConcurrentlyImpl.class));
-
-        //考生数据更新
-        rocketMessageConsumer.setRocketMQConsumer(nameServer, MqGroupEnum.EXAM_STUDENT_UPDATE_GROUP.getCode(), MqTopicEnum.THEMIS_TOPIC.getCode(), MqTagEnum.EXAM_STUDNET_UPDATE.name(), MessageModel.CLUSTERING, SpringContextHolder.getBean(ExamStudentUpdateConcurrentlyImpl.class));
-
-        //考试断点
-        rocketMessageConsumer.setRocketMQConsumer(nameServer, MqGroupEnum.EXAM_BREAK_GROUP.getCode(), MqTopicEnum.THEMIS_TOPIC.getCode(), MqTagEnum.EXAM_BREAK.name(), MessageModel.CLUSTERING, SpringContextHolder.getBean(ExamBreakConcurrentlyImpl.class));
-        rocketMessageConsumer.setRocketMQConsumer(nameServer, MqGroupEnum.EXAM_BREAK_DELAY_GROUP.getCode(), MqTopicEnum.THEMIS_TOPIC.getCode(), MqTagEnum.EXAM_BREAK_DELAY.name(), MessageModel.CLUSTERING, SpringContextHolder.getBean(ExamBreakDelayConcurrentlyImpl.class));
-
-        SystemConstant.initTempFiles();
-        log.info("服务器启动时执行 end");
-    }
-}

+ 4 - 4
themis-business/pom.xml

@@ -76,10 +76,10 @@
 			<groupId>io.springfox</groupId>
 			<artifactId>springfox-swagger2</artifactId>
 		</dependency>
-<!--		<dependency>-->
-<!--			<groupId>com.github.xiaoymin</groupId>-->
-<!--			<artifactId>swagger-bootstrap-ui</artifactId>-->
-<!--		</dependency>-->
+		<dependency>
+			<groupId>com.github.xiaoymin</groupId>
+			<artifactId>swagger-bootstrap-ui</artifactId>
+		</dependency>
 		<dependency>
 			<groupId>com.alibaba</groupId>
 			<artifactId>druid</artifactId>

+ 0 - 17
themis-business/src/main/java/com/qmth/themis/business/annotation/ExcelNotNull.java

@@ -1,17 +0,0 @@
-package com.qmth.themis.business.annotation;
-
-import java.lang.annotation.*;
-
-/**
- * @Description: excel字段不为空注解
- * @Param:
- * @return:
- * @Author: wangliang
- * @Date: 2020/7/19
- */
-@Documented
-@Target(ElementType.FIELD)
-@Retention(RetentionPolicy.RUNTIME)
-public @interface ExcelNotNull {
-
-}

+ 1 - 1
themis-business/src/main/java/com/qmth/themis/business/bean/backend/ExamBreachDetailListBean.java → themis-business/src/main/java/com/qmth/themis/business/bean/admin/ExamBreachDetailListBean.java

@@ -1,4 +1,4 @@
-package com.qmth.themis.business.bean.backend;
+package com.qmth.themis.business.bean.admin;
 
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;

+ 1 - 1
themis-business/src/main/java/com/qmth/themis/business/bean/backend/ExamBreachListBean.java → themis-business/src/main/java/com/qmth/themis/business/bean/admin/ExamBreachListBean.java

@@ -1,4 +1,4 @@
-package com.qmth.themis.business.bean.backend;
+package com.qmth.themis.business.bean.admin;
 
 import com.fasterxml.jackson.databind.annotation.JsonSerialize;
 import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;

+ 1 - 1
themis-business/src/main/java/com/qmth/themis/business/bean/backend/ExamDeficiencyListBean.java → themis-business/src/main/java/com/qmth/themis/business/bean/admin/ExamDeficiencyListBean.java

@@ -1,4 +1,4 @@
-package com.qmth.themis.business.bean.backend;
+package com.qmth.themis.business.bean.admin;
 
 import java.io.Serializable;
 

+ 1 - 1
themis-business/src/main/java/com/qmth/themis/business/bean/backend/ExamExceptionDetailListBean.java → themis-business/src/main/java/com/qmth/themis/business/bean/admin/ExamExceptionDetailListBean.java

@@ -1,4 +1,4 @@
-package com.qmth.themis.business.bean.backend;
+package com.qmth.themis.business.bean.admin;
 
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;

+ 1 - 1
themis-business/src/main/java/com/qmth/themis/business/bean/backend/ExamExceptionListBean.java → themis-business/src/main/java/com/qmth/themis/business/bean/admin/ExamExceptionListBean.java

@@ -1,4 +1,4 @@
-package com.qmth.themis.business.bean.backend;
+package com.qmth.themis.business.bean.admin;
 
 import java.io.Serializable;
 

+ 1 - 1
themis-business/src/main/java/com/qmth/themis/business/bean/backend/ExamReexamListBean.java → themis-business/src/main/java/com/qmth/themis/business/bean/admin/ExamReexamListBean.java

@@ -1,4 +1,4 @@
-package com.qmth.themis.business.bean.backend;
+package com.qmth.themis.business.bean.admin;
 
 import com.fasterxml.jackson.databind.annotation.JsonSerialize;
 import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;

+ 1 - 1
themis-business/src/main/java/com/qmth/themis/business/bean/backend/ExamStudentLogDetailListBean.java → themis-business/src/main/java/com/qmth/themis/business/bean/admin/ExamStudentLogDetailListBean.java

@@ -1,4 +1,4 @@
-package com.qmth.themis.business.bean.backend;
+package com.qmth.themis.business.bean.admin;
 
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;

+ 1 - 1
themis-business/src/main/java/com/qmth/themis/business/bean/backend/ExamStudentLogListBean.java → themis-business/src/main/java/com/qmth/themis/business/bean/admin/ExamStudentLogListBean.java

@@ -1,4 +1,4 @@
-package com.qmth.themis.business.bean.backend;
+package com.qmth.themis.business.bean.admin;
 
 import com.fasterxml.jackson.databind.annotation.JsonSerialize;
 import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;

+ 1 - 1
themis-business/src/main/java/com/qmth/themis/business/bean/backend/ExamViewCountListBean.java → themis-business/src/main/java/com/qmth/themis/business/bean/admin/ExamViewCountListBean.java

@@ -1,4 +1,4 @@
-package com.qmth.themis.business.bean.backend;
+package com.qmth.themis.business.bean.admin;
 
 import java.io.Serializable;
 

+ 1 - 1
themis-business/src/main/java/com/qmth/themis/business/bean/backend/ExaminationMonitorCountBean.java → themis-business/src/main/java/com/qmth/themis/business/bean/admin/ExaminationMonitorCountBean.java

@@ -1,4 +1,4 @@
-package com.qmth.themis.business.bean.backend;
+package com.qmth.themis.business.bean.admin;
 
 import java.util.List;
 import java.util.Map;

+ 1 - 1
themis-business/src/main/java/com/qmth/themis/business/bean/backend/ExaminationMonitorHourWarnCountBean.java → themis-business/src/main/java/com/qmth/themis/business/bean/admin/ExaminationMonitorHourWarnCountBean.java

@@ -1,4 +1,4 @@
-package com.qmth.themis.business.bean.backend;
+package com.qmth.themis.business.bean.admin;
 
 import io.swagger.annotations.ApiModelProperty;
 

+ 1 - 1
themis-business/src/main/java/com/qmth/themis/business/bean/backend/ExaminationMonitorWarnDistributionBean.java → themis-business/src/main/java/com/qmth/themis/business/bean/admin/ExaminationMonitorWarnDistributionBean.java

@@ -1,4 +1,4 @@
-package com.qmth.themis.business.bean.backend;
+package com.qmth.themis.business.bean.admin;
 
 import java.util.List;
 import java.util.Map;

+ 1 - 1
themis-business/src/main/java/com/qmth/themis/business/bean/backend/ExaminationMonitorWarnMsgBean.java → themis-business/src/main/java/com/qmth/themis/business/bean/admin/ExaminationMonitorWarnMsgBean.java

@@ -1,4 +1,4 @@
-package com.qmth.themis.business.bean.backend;
+package com.qmth.themis.business.bean.admin;
 
 import io.swagger.annotations.ApiModelProperty;
 

+ 1 - 3
themis-business/src/main/java/com/qmth/themis/business/bean/backend/InvigilateListBean.java → themis-business/src/main/java/com/qmth/themis/business/bean/admin/InvigilateListBean.java

@@ -1,16 +1,14 @@
-package com.qmth.themis.business.bean.backend;
+package com.qmth.themis.business.bean.admin;
 
 import com.fasterxml.jackson.databind.annotation.JsonSerialize;
 import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
 import com.qmth.themis.business.enums.ExamRecordStatusEnum;
 import com.qmth.themis.business.enums.MonitorStatusSourceEnum;
-import com.qmth.themis.business.enums.MonitorVideoSourceEnum;
 import com.qmth.themis.business.enums.WebsocketStatusEnum;
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
 
 import java.io.Serializable;
-import java.util.Date;
 
 @ApiModel("实时监控台返回对象")
 public class InvigilateListBean implements Serializable {

+ 1 - 1
themis-business/src/main/java/com/qmth/themis/business/bean/backend/InvigilateListDetailBean.java → themis-business/src/main/java/com/qmth/themis/business/bean/admin/InvigilateListDetailBean.java

@@ -1,4 +1,4 @@
-package com.qmth.themis.business.bean.backend;
+package com.qmth.themis.business.bean.admin;
 
 import com.fasterxml.jackson.databind.annotation.JsonSerialize;
 import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;

+ 1 - 2
themis-business/src/main/java/com/qmth/themis/business/bean/backend/InvigilateListHistoryBean.java → themis-business/src/main/java/com/qmth/themis/business/bean/admin/InvigilateListHistoryBean.java

@@ -1,4 +1,4 @@
-package com.qmth.themis.business.bean.backend;
+package com.qmth.themis.business.bean.admin;
 
 import com.fasterxml.jackson.databind.annotation.JsonSerialize;
 import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
@@ -8,7 +8,6 @@ import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
 
 import java.io.Serializable;
-import java.util.Date;
 
 /**
  * @Description: 实时监控台视频返回对象

+ 1 - 2
themis-business/src/main/java/com/qmth/themis/business/bean/backend/InvigilateListPatrolBean.java → themis-business/src/main/java/com/qmth/themis/business/bean/admin/InvigilateListPatrolBean.java

@@ -1,4 +1,4 @@
-package com.qmth.themis.business.bean.backend;
+package com.qmth.themis.business.bean.admin;
 
 import com.fasterxml.jackson.databind.annotation.JsonSerialize;
 import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
@@ -8,7 +8,6 @@ import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
 
 import java.io.Serializable;
-import java.util.Date;
 
 /**
  * @Description: 在线巡考返回对象

+ 1 - 3
themis-business/src/main/java/com/qmth/themis/business/bean/backend/InvigilateListPatrolReportBean.java → themis-business/src/main/java/com/qmth/themis/business/bean/admin/InvigilateListPatrolReportBean.java

@@ -1,11 +1,9 @@
-package com.qmth.themis.business.bean.backend;
+package com.qmth.themis.business.bean.admin;
 
-import com.qmth.themis.business.enums.ExamRecordStatusEnum;
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
 
 import java.io.Serializable;
-import java.util.Date;
 
 /**
  * @Description: 在线巡考报表返回对象

+ 1 - 1
themis-business/src/main/java/com/qmth/themis/business/bean/backend/InvigilateListProgressBean.java → themis-business/src/main/java/com/qmth/themis/business/bean/admin/InvigilateListProgressBean.java

@@ -1,4 +1,4 @@
-package com.qmth.themis.business.bean.backend;
+package com.qmth.themis.business.bean.admin;
 
 import com.fasterxml.jackson.databind.annotation.JsonSerialize;
 import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;

+ 1 - 1
themis-business/src/main/java/com/qmth/themis/business/bean/backend/InvigilateListProgressExcelBean.java → themis-business/src/main/java/com/qmth/themis/business/bean/admin/InvigilateListProgressExcelBean.java

@@ -1,4 +1,4 @@
-package com.qmth.themis.business.bean.backend;
+package com.qmth.themis.business.bean.admin;
 
 import com.qmth.themis.business.excel.ExcelProperty;
 import io.swagger.annotations.ApiModel;

+ 12 - 1
themis-business/src/main/java/com/qmth/themis/business/bean/backend/InvigilateListVideoBean.java → themis-business/src/main/java/com/qmth/themis/business/bean/admin/InvigilateListVideoBean.java

@@ -1,4 +1,4 @@
-package com.qmth.themis.business.bean.backend;
+package com.qmth.themis.business.bean.admin;
 
 import com.fasterxml.jackson.databind.annotation.JsonSerialize;
 import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
@@ -112,6 +112,17 @@ public class InvigilateListVideoBean implements Serializable {
     @ApiModelProperty(name = "新增预警")
     private Integer warningNew;
 
+    @ApiModelProperty(name = "开启监控的视频源")
+    private String monitorVideoSource;
+
+    public String getMonitorVideoSource() {
+        return monitorVideoSource;
+    }
+
+    public void setMonitorVideoSource(String monitorVideoSource) {
+        this.monitorVideoSource = monitorVideoSource;
+    }
+
     public String getCourseCode() {
         return courseCode;
     }

+ 1 - 2
themis-business/src/main/java/com/qmth/themis/business/bean/backend/InvigilateListWarningBean.java → themis-business/src/main/java/com/qmth/themis/business/bean/admin/InvigilateListWarningBean.java

@@ -1,4 +1,4 @@
-package com.qmth.themis.business.bean.backend;
+package com.qmth.themis.business.bean.admin;
 
 import com.fasterxml.jackson.databind.annotation.JsonSerialize;
 import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
@@ -7,7 +7,6 @@ import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
 
 import java.io.Serializable;
-import java.util.Date;
 
 /**
  * @Description: 预警提醒返回对象

+ 1 - 1
themis-business/src/main/java/com/qmth/themis/business/bean/backend/OpenExamBean.java → themis-business/src/main/java/com/qmth/themis/business/bean/admin/OpenExamBean.java

@@ -1,4 +1,4 @@
-package com.qmth.themis.business.bean.backend;
+package com.qmth.themis.business.bean.admin;
 
 import com.qmth.themis.business.enums.ExamModeEnum;
 

+ 1 - 1
themis-business/src/main/java/com/qmth/themis/business/bean/backend/OpenExamCourseBean.java → themis-business/src/main/java/com/qmth/themis/business/bean/admin/OpenExamCourseBean.java

@@ -1,4 +1,4 @@
-package com.qmth.themis.business.bean.backend;
+package com.qmth.themis.business.bean.admin;
 
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;

+ 64 - 0
themis-business/src/main/java/com/qmth/themis/business/bean/admin/OpenRecordAnswerBean.java

@@ -0,0 +1,64 @@
+package com.qmth.themis.business.bean.admin;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+
+import java.util.List;
+
+@ApiModel("开放接口-待评卷考试记录答案")
+public class OpenRecordAnswerBean {
+
+    @ApiModelProperty("大题号")
+    private Integer mainNumber;
+
+    @ApiModelProperty("小题号")
+    private Integer subNumber;
+
+    @ApiModelProperty("套题子题序号")
+    private Integer subIndex;
+
+    @ApiModelProperty("作答")
+    private List<OpenRecordAnswerStructBean> answer;
+
+    public OpenRecordAnswerBean() {
+
+    }
+
+    public OpenRecordAnswerBean(Integer mainNumber, Integer subNumber, Integer subIndex) {
+        this.mainNumber = mainNumber;
+        this.subNumber = subNumber;
+        this.subIndex = subIndex;
+    }
+
+    public Integer getMainNumber() {
+        return mainNumber;
+    }
+
+    public void setMainNumber(Integer mainNumber) {
+        this.mainNumber = mainNumber;
+    }
+
+    public Integer getSubNumber() {
+        return subNumber;
+    }
+
+    public void setSubNumber(Integer subNumber) {
+        this.subNumber = subNumber;
+    }
+
+    public Integer getSubIndex() {
+        return subIndex;
+    }
+
+    public void setSubIndex(Integer subIndex) {
+        this.subIndex = subIndex;
+    }
+
+    public List<OpenRecordAnswerStructBean> getAnswer() {
+        return answer;
+    }
+
+    public void setAnswer(List<OpenRecordAnswerStructBean> answer) {
+        this.answer = answer;
+    }
+}

Some files were not shown because too many files changed in this diff