Browse Source

Merge remote-tracking branch 'origin/dev' into dev

wangliang 4 năm trước cách đây
mục cha
commit
e9877f9d09

+ 14 - 3
themis-business/src/main/java/com/qmth/themis/business/bean/mobile/MobileAuthorizationBean.java

@@ -16,10 +16,13 @@ public class MobileAuthorizationBean {
 	private Long time;
 	
 	@ApiModelProperty("sessionId")
-	private Long sessionId;
+	private String sessionId;
 	
 	@ApiModelProperty("考试记录id")
 	private Long recordId;
+	
+	//TODO
+	private String accessToken;
 
 	public MobileModeEnum getMode() {
 		return mode;
@@ -37,11 +40,11 @@ public class MobileAuthorizationBean {
 		this.time = time;
 	}
 
-	public Long getSessionId() {
+	public String getSessionId() {
 		return sessionId;
 	}
 
-	public void setSessionId(Long sessionId) {
+	public void setSessionId(String sessionId) {
 		this.sessionId = sessionId;
 	}
 
@@ -53,5 +56,13 @@ public class MobileAuthorizationBean {
 		this.recordId = recordId;
 	}
 
+	public String getAccessToken() {
+		return accessToken;
+	}
+
+	public void setAccessToken(String accessToken) {
+		this.accessToken = accessToken;
+	}
+
 	
 }

+ 3 - 5
themis-business/src/main/java/com/qmth/themis/business/bean/mobile/MobileAuthorizationParamBean.java

@@ -1,7 +1,5 @@
 package com.qmth.themis.business.bean.mobile;
 
-import com.qmth.themis.business.enums.MobileModeEnum;
-
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
 
@@ -10,16 +8,16 @@ public class MobileAuthorizationParamBean {
 
 	
 	@ApiModelProperty("功能模式")
-	private MobileModeEnum mode;
+	private String mode;
 	
 	@ApiModelProperty("临时授权码")
 	private String code;
 
-	public MobileModeEnum getMode() {
+	public String getMode() {
 		return mode;
 	}
 
-	public void setMode(MobileModeEnum mode) {
+	public void setMode(String mode) {
 		this.mode = mode;
 	}
 

+ 1 - 1
themis-business/src/main/java/com/qmth/themis/business/cache/ExamRecordCacheUtil.java

@@ -26,7 +26,7 @@ public class ExamRecordCacheUtil {
 	}
 
 	public static Long getExamStudentId(Long recordId) {
-		return Long.parseLong(String.valueOf(redisUtil.get(RedisKeyHelper.examRecordCacheKey(recordId), "examStudentId")));
+		return (Long)redisUtil.get(RedisKeyHelper.examRecordCacheKey(recordId), "examStudentId");
 	}
 
 	public static Long getPaperId(Long recordId) {

+ 1 - 1
themis-business/src/main/java/com/qmth/themis/business/cache/RedisKeyHelper.java

@@ -54,7 +54,7 @@ public class RedisKeyHelper {
 	/**
 	 * 移动端临时认证
 	 */
-	private static String mobileAuthKeyPrefix = "mobile_auth_";
+	private static String mobileAuthKeyPrefix = "mobile_auth::";
 	/**
 	 * 场次
 	 * 

+ 3 - 1
themis-business/src/main/java/com/qmth/themis/business/service/TEMobileService.java

@@ -1,10 +1,12 @@
 package com.qmth.themis.business.service;
 
+import java.security.NoSuchAlgorithmException;
+
 import com.qmth.themis.business.bean.mobile.MobileAuthorizationBean;
 import com.qmth.themis.business.bean.mobile.MobileAuthorizationParamBean;
 
 public interface TEMobileService {
 
-	public MobileAuthorizationBean authorization(MobileAuthorizationParamBean param);
+	public MobileAuthorizationBean authorization(MobileAuthorizationParamBean param) throws NoSuchAlgorithmException;
 
 }

+ 29 - 5
themis-business/src/main/java/com/qmth/themis/business/service/impl/TEExamServiceImpl.java

@@ -331,7 +331,7 @@ public class TEExamServiceImpl extends ServiceImpl<TEExamMapper, TEExam> impleme
     }
 
     /**
-     * 开始候考
+     * 开始答题
      */
     @Override
     public ExamStartBean start(Long studentId, Long recordId) {
@@ -365,7 +365,10 @@ public class TEExamServiceImpl extends ServiceImpl<TEExamMapper, TEExam> impleme
         if (now.getTime() > end) {
             throw new BusinessException("允许开考的时间已结束");
         }
-
+        ExamRecordStatusEnum sta=ExamRecordCacheUtil.getStatus(recordId);
+        if(ExamRecordStatusEnum.FINISHED.equals(sta)||ExamRecordStatusEnum.PERSISTED.equals(sta)) {
+			throw new BusinessException("该考试已结束");
+		}
         Long paperId = ExamRecordCacheUtil.getPaperId(recordId);
         ExamPaperCacheBean ep = teExamPaperService.getExamPaperCacheBean(paperId);
         if (ep == null) {
@@ -403,7 +406,10 @@ public class TEExamServiceImpl extends ServiceImpl<TEExamMapper, TEExam> impleme
         if (!studentId.equals(es.getStudentId())) {
             throw new BusinessException("考试记录的学生Id和当前登录用户不一致");
         }
-
+        ExamRecordStatusEnum sta=ExamRecordCacheUtil.getStatus(recordId);
+        if(ExamRecordStatusEnum.FINISHED.equals(sta)||ExamRecordStatusEnum.PERSISTED.equals(sta)) {
+			throw new BusinessException("该考试已结束");
+		}
         ExamStudentPaperStructCacheBean struct = new ExamStudentPaperStructCacheBean();
         struct.setContent(content);
         struct.setTime(System.currentTimeMillis());
@@ -434,7 +440,10 @@ public class TEExamServiceImpl extends ServiceImpl<TEExamMapper, TEExam> impleme
         if (!studentId.equals(es.getStudentId())) {
             throw new BusinessException("考试记录的学生Id和当前登录用户不一致");
         }
-
+        ExamRecordStatusEnum sta=ExamRecordCacheUtil.getStatus(recordId);
+        if(ExamRecordStatusEnum.FINISHED.equals(sta)||ExamRecordStatusEnum.PERSISTED.equals(sta)) {
+			throw new BusinessException("该考试已结束");
+		}
         ExamStudentAnswerCacheBean answerCache = (ExamStudentAnswerCacheBean) redisUtil.get(
                 RedisKeyHelper.examAnswerKey(recordId),
                 RedisKeyHelper.examAnswerHashKey(mainNumber, subNumber, subIndex));
@@ -497,7 +506,10 @@ public class TEExamServiceImpl extends ServiceImpl<TEExamMapper, TEExam> impleme
         if (!studentId.equals(es.getStudentId())) {
             throw new BusinessException("考试记录的学生Id和当前登录用户不一致");
         }
-
+        ExamRecordStatusEnum sta=ExamRecordCacheUtil.getStatus(recordId);
+        if(ExamRecordStatusEnum.FINISHED.equals(sta)||ExamRecordStatusEnum.PERSISTED.equals(sta)) {
+			throw new BusinessException("该考试已结束");
+		}
         // 音频剩余播放次数缓存
         redisUtil.set(RedisKeyHelper.audioLeftPlayCountKey(recordId), key, count);
         AudioLeftPlayCountSubmitBean ret = new AudioLeftPlayCountSubmitBean();
@@ -524,6 +536,10 @@ public class TEExamServiceImpl extends ServiceImpl<TEExamMapper, TEExam> impleme
         if (!studentId.equals(es.getStudentId())) {
             throw new BusinessException("考试记录的学生Id和当前登录用户不一致");
         }
+        ExamRecordStatusEnum sta=ExamRecordCacheUtil.getStatus(recordId);
+        if(ExamRecordStatusEnum.FINISHED.equals(sta)||ExamRecordStatusEnum.PERSISTED.equals(sta)) {
+			throw new BusinessException("该考试已结束");
+		}
 
         String filePath = "upload/" + sdf.format(new Date()) + "/" + uuid() + "." + suffix;
         InputStream in = null;
@@ -581,6 +597,10 @@ public class TEExamServiceImpl extends ServiceImpl<TEExamMapper, TEExam> impleme
         if (ep == null) {
             throw new BusinessException("未找到试卷");
         }
+        ExamRecordStatusEnum sta=ExamRecordCacheUtil.getStatus(recordId);
+        if(ExamRecordStatusEnum.FINISHED.equals(sta)||ExamRecordStatusEnum.PERSISTED.equals(sta)) {
+			throw new BusinessException("该考试已结束");
+		}
 
         ExamResumeBean ret = new ExamResumeBean();
         ret.setDurationSeconds(ExamRecordCacheUtil.getDurationSeconds(recordId));
@@ -669,6 +689,10 @@ public class TEExamServiceImpl extends ServiceImpl<TEExamMapper, TEExam> impleme
         if (!studentId.equals(es.getStudentId())) {
             throw new BusinessException("考试记录的学生Id和当前登录用户不一致");
         }
+        ExamRecordStatusEnum sta=ExamRecordCacheUtil.getStatus(recordId);
+        if(ExamRecordStatusEnum.FINISHED.equals(sta)||ExamRecordStatusEnum.PERSISTED.equals(sta)) {
+			throw new BusinessException("该考试已结束");
+		}
 
         Date now = new Date();
         ExamFinishBean ret = new ExamFinishBean();

+ 96 - 26
themis-business/src/main/java/com/qmth/themis/business/service/impl/TEMobileServiceImpl.java

@@ -1,63 +1,133 @@
 package com.qmth.themis.business.service.impl;
 
+import java.security.NoSuchAlgorithmException;
+import java.util.Date;
+import java.util.Map;
+import java.util.Objects;
+
 import javax.annotation.Resource;
 
+import org.apache.commons.lang3.RandomStringUtils;
 import org.springframework.stereotype.Service;
 
 import com.qmth.themis.business.bean.mobile.MobileAuthorizationBean;
 import com.qmth.themis.business.bean.mobile.MobileAuthorizationMonitorBean;
 import com.qmth.themis.business.bean.mobile.MobileAuthorizationParamBean;
 import com.qmth.themis.business.bean.mobile.MobileAuthorizationUploadBean;
+import com.qmth.themis.business.cache.ExamRecordCacheUtil;
 import com.qmth.themis.business.cache.MobileAuthCacheUtil;
+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.cache.TEStudentCacheDto;
+import com.qmth.themis.business.entity.TBSession;
+import com.qmth.themis.business.enums.ExamRecordStatusEnum;
 import com.qmth.themis.business.enums.MobileModeEnum;
+import com.qmth.themis.business.service.TEExamStudentService;
 import com.qmth.themis.business.service.TEMobileService;
 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.common.enums.Platform;
 import com.qmth.themis.common.enums.Source;
 import com.qmth.themis.common.exception.BusinessException;
+import com.qmth.themis.common.signature.SignatureInfo;
+import com.qmth.themis.common.signature.SignatureType;
 
 @Service
 public class TEMobileServiceImpl implements TEMobileService {
 
-    @Resource
-    RedisUtil redisUtil;
-	
+	@Resource
+	RedisUtil redisUtil;
+
+	@Resource
+	TEExamStudentService examStudentService;
+
 	@Override
-	public MobileAuthorizationBean authorization(MobileAuthorizationParamBean param) {
-		MobileModeEnum mode=param.getMode();
-		String code=param.getCode();
-		MobileAuthorizationBean ret=null;
-		if(MobileModeEnum.MOBILE_MONITOR.equals(mode)) {
-			ret=monitorAuthorization(mode, code);
-		}else if(MobileModeEnum.PHOTO_UPLOAD.equals(mode)||MobileModeEnum.AUDIO_UPLOAD.equals(mode)) {
-			ret=answerUploadAuthorization(mode, code);
+	public MobileAuthorizationBean authorization(MobileAuthorizationParamBean param) throws NoSuchAlgorithmException {
+		MobileModeEnum mode = MobileModeEnum.valueOf(param.getMode().toUpperCase());
+		String code = param.getCode();
+		MobileAuthorizationBean ret = null;
+		if (MobileModeEnum.MOBILE_MONITOR.equals(mode)) {
+			ret = monitorAuthorization(mode, code);
+		} else if (MobileModeEnum.PHOTO_UPLOAD.equals(mode) || MobileModeEnum.AUDIO_UPLOAD.equals(mode)) {
+			ret = answerUploadAuthorization(mode, code);
+		}
+		if(ExamRecordCacheUtil.getId(ret.getRecordId())==null) {
+			throw new BusinessException("考试记录不存在");
+		}
+		ExamStudentCacheBean es = examStudentService
+				.getExamStudentCacheBean(ExamRecordCacheUtil.getExamStudentId(ret.getRecordId()));
+		if(es==null) {
+			throw new BusinessException("未找到考生");
 		}
+		ExamRecordStatusEnum sta=ExamRecordCacheUtil.getStatus(ret.getRecordId());
+		if(ExamRecordStatusEnum.FIRST_PREPARE.equals(sta)) {
+			throw new BusinessException("该考试未开始答题");
+		}
+		if(ExamRecordStatusEnum.FINISHED.equals(sta)||ExamRecordStatusEnum.PERSISTED.equals(sta)) {
+			throw new BusinessException("该考试已结束");
+		}
+		Platform platform = Platform.valueOf(ServletUtil.getRequestPlatform());
+		String deviceId = ServletUtil.getRequestDeviceId();
+		AuthDto authDto = (AuthDto) redisUtil.get(SystemConstant.studentOauth + "::" + es.getStudentId());
+		// 生成token
+		String token = RandomStringUtils.randomAlphanumeric(32);
+		TEStudentCacheDto teStudentCacheDto = (TEStudentCacheDto) redisUtil.getStudent(es.getStudentId());
+		String source = null;
+		if (Objects.equals(platform.name(), Platform.win.name())
+				|| Objects.equals(platform.name(), Platform.mac.name())) {
+			source = platform.getSource().split(",")[1];
+		} else if (Objects.equals(platform.name(), Platform.wxapp.name())
+				|| Objects.equals(platform.name(), Platform.web.name())) {
+			source = platform.getSource();
+		} else if (Objects.equals(platform.name(), Platform.ios.name())
+				|| Objects.equals(platform.name(), Platform.android.name())) {
+			source = platform.getSource().split(",")[2];
+		}
+		String sessionId = SessionUtil.digest(teStudentCacheDto.getIdentity(),
+				Math.abs(authDto.getRoleCodes().toString().hashCode()), source);
+		Map<String, Object> expireMap = SystemConstant.getExpireTime(platform);
+		Date expire = (Date) expireMap.get("date");
+		Long redisExpire = Long.parseLong(String.valueOf(expireMap.get("redisExpire")));
+		TBSession tbSession = new TBSession(sessionId, String.valueOf(es.getStudentId()),
+				authDto.getRoleCodes().toString(), source, platform.name(), deviceId,
+				ServletUtil.getRequest().getLocalAddr(), token, expire);
+		redisUtil.setUserSession(sessionId, tbSession, redisExpire);
+		ret.setSessionId(sessionId);
+		ret.setTime(new Date().getTime());
+		ret.setMode(mode);
+		//测试
+        String test = SignatureInfo.build(SignatureType.TOKEN, sessionId, token);
+        ret.setAccessToken(test);
 		return ret;
 	}
-	
-	private MobileAuthorizationBean monitorAuthorization(MobileModeEnum mode,String code) {
-		Long recordId=MobileAuthCacheUtil.getRecordId(mode, code);
-		String monitorKey=MobileAuthCacheUtil.getMonitorKey(mode, code);
-		Source monitorVideoSource=MobileAuthCacheUtil.getMonitorVideoSource(mode, code);
-		Boolean monitorAudioEnable=MobileAuthCacheUtil.getMonitorAudioEnable(mode, code);
-		if(MobileAuthCacheUtil.getMode(mode, code)==null) {
+
+	private MobileAuthorizationBean monitorAuthorization(MobileModeEnum mode, String code) {
+		Long recordId = MobileAuthCacheUtil.getRecordId(mode, code);
+		String monitorKey = MobileAuthCacheUtil.getMonitorKey(mode, code);
+		Source monitorVideoSource = MobileAuthCacheUtil.getMonitorVideoSource(mode, code);
+		Boolean monitorAudioEnable = MobileAuthCacheUtil.getMonitorAudioEnable(mode, code);
+		if (MobileAuthCacheUtil.getMode(mode, code) == null) {
 			throw new BusinessException("二维码已过期");
 		}
-		MobileAuthorizationMonitorBean ret=new MobileAuthorizationMonitorBean();
+		MobileAuthorizationMonitorBean ret = new MobileAuthorizationMonitorBean();
 		ret.setRecordId(recordId);
 		ret.setMonitorKey(monitorKey);
 		ret.setMonitorVideoSource(monitorVideoSource);
 		ret.setMonitorAudioEnable(monitorAudioEnable);
 		return ret;
 	}
-	private MobileAuthorizationBean answerUploadAuthorization(MobileModeEnum mode,String code) {
-		Long recordId=MobileAuthCacheUtil.getRecordId(mode, code);
-		Integer mainNumber=MobileAuthCacheUtil.getMainNumber(mode, code);
-		Integer subNumber=MobileAuthCacheUtil.getSubNumber(mode, code);
-		Integer subIndex=MobileAuthCacheUtil.getSubIndex(mode, code);
-		if(MobileAuthCacheUtil.getMode(mode, code)==null) {
+
+	private MobileAuthorizationBean answerUploadAuthorization(MobileModeEnum mode, String code) {
+		Long recordId = MobileAuthCacheUtil.getRecordId(mode, code);
+		Integer mainNumber = MobileAuthCacheUtil.getMainNumber(mode, code);
+		Integer subNumber = MobileAuthCacheUtil.getSubNumber(mode, code);
+		Integer subIndex = MobileAuthCacheUtil.getSubIndex(mode, code);
+		if (MobileAuthCacheUtil.getMode(mode, code) == null) {
 			throw new BusinessException("二维码已过期");
 		}
-		MobileAuthorizationUploadBean ret=new MobileAuthorizationUploadBean();
+		MobileAuthorizationUploadBean ret = new MobileAuthorizationUploadBean();
 		ret.setRecordId(recordId);
 		ret.setMainNumber(mainNumber);
 		ret.setSubNumber(subNumber);

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

@@ -1,5 +1,7 @@
 package com.qmth.themis.exam.api;
 
+import java.security.NoSuchAlgorithmException;
+
 import javax.annotation.Resource;
 
 import org.springframework.web.bind.annotation.RequestBody;
@@ -30,7 +32,7 @@ public class TEMobileController {
 
 	@ApiOperation(value = "获取登录详细信息")
 	@RequestMapping(value = "/authorization", method = RequestMethod.POST)
-	public Result authorization(@RequestBody MobileAuthorizationParamBean param) {
+	public Result authorization(@RequestBody MobileAuthorizationParamBean param) throws NoSuchAlgorithmException {
 		if (param.getMode() == null) {
 			throw new BusinessException("mode不能为空");
 		}

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

@@ -49,7 +49,7 @@ public class TEQrcodeController {
 		return ResultUtil.ok(qrcodeService.mobileMonitor(param));
 	}
 
-	@ApiOperation(value = "获取移动端监考二维码")
+	@ApiOperation(value = "获取移动端拍照/录音上传二维码")
 	@RequestMapping(value = "/{uploadType}", method = RequestMethod.POST)
 	public Result mobileMonitor(@PathVariable String uploadType,@RequestBody QrUploadParamBean param) {
 		if (param.getRecordId() == null) {

+ 2 - 2
themis-exam/src/main/resources/application.properties

@@ -149,5 +149,5 @@ prefix.url.mobile=api/mobile
 wxapp.upload.url=http://wxapp2.qmth.com.cn
 
 #\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/oe/student/login,/api/oe/sys/env,/file/**,/upload/**,/client/**,/base_photo/**,/frontend/**,/api/oe/exam/short_code,/api/oe/monitor/live_url,/api/oe/monitor/call/apply,/api/oe/monitor/call/cancel,/api/oe/monitor/call/list,/api/oe/monitor/call/query
-common.system.urls=/api/oe/student/logout,/api/oe/exam/file/upload
+no.auth.urls=/webjars/**,/druid/**,/swagger-ui.html,/doc.html,/swagger-resources/**,/v2/api-docs,/webjars/springfox-swagger-ui/**,/api/oe/student/login,/api/oe/sys/env,/file/**,/upload/**,/client/**,/base_photo/**,/frontend/**,/api/oe/exam/short_code,/api/oe/monitor/live_url,/api/oe/monitor/call/apply,/api/oe/monitor/call/cancel,/api/oe/monitor/call/list,/api/oe/monitor/call/query,/api/mobile/authorization
+common.system.urls=/api/oe/student/logout,/api/oe/exam/file/upload,/api/oe/qrcode/mobile_monitor,/api/oe/qrcode/photo_upload,/api/oe/qrcode/audio_upload