wangwei преди 6 години
родител
ревизия
bee9d9d9e1
променени са 37 файла, в които са добавени 1503 реда и са изтрити 1091 реда
  1. 29 20
      examcloud-exchange-outer-api-provider/src/main/java/cn/com/qmth/examcloud/exchange/outer/api/controller/FaceController.java
  2. 21 16
      examcloud-exchange-outer-api-provider/src/main/java/cn/com/qmth/examcloud/exchange/outer/api/controller/swufe/ExamVerifyPhotoController.java
  3. 11 7
      examcloud-exchange-outer-api-provider/src/main/java/cn/com/qmth/examcloud/exchange/outer/api/controller/swufe/StudentInfoController.java
  4. 6 6
      examcloud-exchange-outer-api-provider/src/main/java/cn/com/qmth/examcloud/exchange/outer/api/controller/sydx/StudentExamInfoController.java
  5. 7 2
      examcloud-exchange-outer-api-provider/src/main/java/cn/com/qmth/examcloud/exchange/outer/api/provider/ExamStudentOuterServiceProvider.java
  6. 176 0
      examcloud-exchange-outer-api-provider/src/main/java/cn/com/qmth/examcloud/exchange/outer/api/provider/FaceOuterServiceProvider.java
  7. 44 25
      examcloud-exchange-outer-api-provider/src/main/java/cn/com/qmth/examcloud/exchange/outer/api/provider/StudentOuterServiceProvider.java
  8. 167 0
      examcloud-exchange-outer-api-provider/src/main/java/cn/com/qmth/examcloud/exchange/outer/api/provider/cug/CugOuterServiceProvider.java
  9. 26 0
      examcloud-exchange-outer-api/src/main/java/cn/com/qmth/examcloud/exchange/outer/api/CugOuterService.java
  10. 0 15
      examcloud-exchange-outer-api/src/main/java/cn/com/qmth/examcloud/exchange/outer/api/DemoOuterService.java
  11. 27 0
      examcloud-exchange-outer-api/src/main/java/cn/com/qmth/examcloud/exchange/outer/api/FaceOuterService.java
  12. 0 33
      examcloud-exchange-outer-api/src/main/java/cn/com/qmth/examcloud/exchange/outer/api/request/GetXxxReq.java
  13. 139 139
      examcloud-exchange-outer-api/src/main/java/cn/com/qmth/examcloud/exchange/outer/api/request/SaveExamStudentReq.java
  14. 68 0
      examcloud-exchange-outer-api/src/main/java/cn/com/qmth/examcloud/exchange/outer/api/request/SaveStudentPhotoReq.java
  15. 18 5
      examcloud-exchange-outer-api/src/main/java/cn/com/qmth/examcloud/exchange/outer/api/request/SaveStudentReq.java
  16. 182 0
      examcloud-exchange-outer-api/src/main/java/cn/com/qmth/examcloud/exchange/outer/api/request/cug/SaveCugStudentAndExamStudentReq.java
  17. 0 23
      examcloud-exchange-outer-api/src/main/java/cn/com/qmth/examcloud/exchange/outer/api/response/GetXxxResp.java
  18. 20 20
      examcloud-exchange-outer-api/src/main/java/cn/com/qmth/examcloud/exchange/outer/api/response/SaveExamStudentResp.java
  19. 16 0
      examcloud-exchange-outer-api/src/main/java/cn/com/qmth/examcloud/exchange/outer/api/response/SaveStudentPhotoResp.java
  20. 61 0
      examcloud-exchange-outer-api/src/main/java/cn/com/qmth/examcloud/exchange/outer/api/response/cug/SaveCugStudentAndExamStudentResp.java
  21. 19 0
      examcloud-exchange-outer-service/src/main/java/cn/com/qmth/examcloud/exchange/outer/service/CourseGroupService.java
  22. 0 17
      examcloud-exchange-outer-service/src/main/java/cn/com/qmth/examcloud/exchange/outer/service/ExamService.java
  23. 25 0
      examcloud-exchange-outer-service/src/main/java/cn/com/qmth/examcloud/exchange/outer/service/FaceService.java
  24. 0 218
      examcloud-exchange-outer-service/src/main/java/cn/com/qmth/examcloud/exchange/outer/service/FaceppService.java
  25. 1 23
      examcloud-exchange-outer-service/src/main/java/cn/com/qmth/examcloud/exchange/outer/service/UpyunService.java
  26. 46 0
      examcloud-exchange-outer-service/src/main/java/cn/com/qmth/examcloud/exchange/outer/service/bean/Course.java
  27. 38 0
      examcloud-exchange-outer-service/src/main/java/cn/com/qmth/examcloud/exchange/outer/service/bean/CourseGroup.java
  28. 0 25
      examcloud-exchange-outer-service/src/main/java/cn/com/qmth/examcloud/exchange/outer/service/client/CourseClient.java
  29. 0 28
      examcloud-exchange-outer-service/src/main/java/cn/com/qmth/examcloud/exchange/outer/service/client/ExamClient.java
  30. 0 33
      examcloud-exchange-outer-service/src/main/java/cn/com/qmth/examcloud/exchange/outer/service/client/ExamStudentClient.java
  31. 0 19
      examcloud-exchange-outer-service/src/main/java/cn/com/qmth/examcloud/exchange/outer/service/client/OrgClient.java
  32. 0 25
      examcloud-exchange-outer-service/src/main/java/cn/com/qmth/examcloud/exchange/outer/service/client/StudentClient.java
  33. 0 34
      examcloud-exchange-outer-service/src/main/java/cn/com/qmth/examcloud/exchange/outer/service/client/StudentFaceInfoClient.java
  34. 58 0
      examcloud-exchange-outer-service/src/main/java/cn/com/qmth/examcloud/exchange/outer/service/impl/CourseGroupServiceImpl.java
  35. 261 0
      examcloud-exchange-outer-service/src/main/java/cn/com/qmth/examcloud/exchange/outer/service/impl/FaceServiceImpl.java
  36. 0 295
      examcloud-exchange-outer-service/src/main/java/cn/com/qmth/examcloud/exchange/outer/service/impl/StudentInfoServiceImpl.java
  37. 37 63
      examcloud-exchange-outer-service/src/main/java/cn/com/qmth/examcloud/exchange/outer/service/impl/UpyunServiceImpl.java

+ 29 - 20
examcloud-exchange-outer-api-provider/src/main/java/cn/com/qmth/examcloud/exchange/outer/api/controller/FaceppController.java → examcloud-exchange-outer-api-provider/src/main/java/cn/com/qmth/examcloud/exchange/outer/api/controller/FaceController.java

@@ -1,14 +1,14 @@
 package cn.com.qmth.examcloud.exchange.outer.api.controller;
 
 import java.io.File;
+import java.io.IOException;
 import java.util.List;
 import java.util.Map;
 
-import javax.servlet.http.HttpServletRequest;
-
 import org.apache.commons.fileupload.disk.DiskFileItem;
 import org.apache.tomcat.util.http.fileupload.FileUtils;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
 import org.springframework.web.bind.annotation.PostMapping;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RequestParam;
@@ -22,10 +22,11 @@ import cn.com.qmth.examcloud.commons.base.exception.StatusException;
 import cn.com.qmth.examcloud.commons.base.util.ZipUtil;
 import cn.com.qmth.examcloud.commons.web.security.bean.User;
 import cn.com.qmth.examcloud.commons.web.support.ControllerSupport;
-import cn.com.qmth.examcloud.exchange.outer.service.FaceppService;
+import cn.com.qmth.examcloud.exchange.outer.service.FaceService;
+import io.swagger.annotations.ApiOperation;
 
 /**
- * 学生照片接口
+ * 人脸 处理
  * 
  * @author chenken
  * @date 2018年4月3日 下午3:58:31
@@ -34,7 +35,10 @@ import cn.com.qmth.examcloud.exchange.outer.service.FaceppService;
  */
 @RestController
 @RequestMapping("${$rmp.cloud.exchange.outer}/facepp")
-public class FaceppController extends ControllerSupport {
+public class FaceController extends ControllerSupport {
+
+	@Value("${$tempDir}")
+	private String tempDir;
 
 	/**
 	 * ZIP最大50M
@@ -47,24 +51,25 @@ public class FaceppController extends ControllerSupport {
 	private static final int MAX_SIZE = 500;
 
 	@Autowired
-	private FaceppService faceppService;
+	private FaceService faceService;
 
 	/**
-	 * 重构
+	 * 方法注释
 	 *
 	 * @author WANGWEI
 	 * @param file
-	 * @throws Exception
 	 */
-	@PostMapping("/add")
-	public void add(@RequestParam CommonsMultipartFile file) throws Exception {
+	@ApiOperation(value = "保存学生照片")
+	@PostMapping("add")
+	public void addPhoto(@RequestParam CommonsMultipartFile file) {
 		User accessUser = getAccessUser();
+		Long rootOrgId = accessUser.getRootOrgId();
 
 		log.debug("fileName =" + file.getOriginalFilename());
 		DiskFileItem item = (DiskFileItem) file.getFileItem();
 		File storeLocation = item.getStoreLocation();
-		String filename = file.getOriginalFilename();
-		faceppService.uploadPhoto(accessUser, filename, storeLocation);
+		String fileName = file.getOriginalFilename();
+		faceService.processFace(rootOrgId, fileName, storeLocation, accessUser.getDisplayName());
 	}
 
 	/**
@@ -72,14 +77,14 @@ public class FaceppController extends ControllerSupport {
 	 *
 	 * @author WANGWEI
 	 * @param file
-	 * @param request
 	 * @return
-	 * @throws Exception
 	 */
-	@PostMapping("/import")
-	public List<Map<String, String>> batchAll(@RequestParam CommonsMultipartFile file,
-			HttpServletRequest request) throws Exception {
+	@ApiOperation(value = "导入学生照片")
+	@PostMapping("import")
+	public List<Map<String, String>> importPhotos(@RequestParam CommonsMultipartFile file) {
+
 		User accessUser = getAccessUser();
+		Long rootOrgId = accessUser.getRootOrgId();
 
 		DiskFileItem item = (DiskFileItem) file.getFileItem();
 		File storeLocation = item.getStoreLocation();
@@ -95,7 +100,7 @@ public class FaceppController extends ControllerSupport {
 
 		List<Map<String, String>> ret = Lists.newArrayList();
 
-		String tempDirPath = storeLocation.getParent() + File.separator
+		String tempDirPath = tempDir + File.separator + "photo_import" + File.separator
 				+ System.currentTimeMillis();
 		File tempDir = new File(tempDirPath);
 		try {
@@ -122,7 +127,7 @@ public class FaceppController extends ControllerSupport {
 			}
 			try {
 				map.put("file", f.getName());
-				faceppService.uploadPhoto(accessUser, f.getName(), f);
+				faceService.processFace(rootOrgId, f.getName(), f, accessUser.getDisplayName());
 				map.put("statusCode", "200");
 				map.put("statusDesc", "成功");
 			} catch (StatusException e) {
@@ -135,7 +140,11 @@ public class FaceppController extends ControllerSupport {
 			ret.add(map);
 		}
 
-		FileUtils.deleteDirectory(tempDir);
+		try {
+			FileUtils.deleteDirectory(tempDir);
+		} catch (IOException e) {
+			log.error("fail to clean temp dir.", e);
+		}
 
 		return ret;
 	}

+ 21 - 16
examcloud-exchange-outer-api-provider/src/main/java/cn/com/qmth/examcloud/exchange/outer/api/controller/swufe/ExamVerifyPhotoController.java

@@ -18,32 +18,37 @@ import cn.com.qmth.examcloud.exchange.base.response.SuccessBaseResponse;
 import cn.com.qmth.examcloud.exchange.outer.service.client.OeClient;
 
 /**
- * @author  	chenken
- * @date    	2018年5月7日 上午11:49:40
- * @company 	QMTH
+ * @author chenken
+ * @date 2018年5月7日 上午11:49:40
+ * @company QMTH
  * @description ExamVerifyPhotoController.java
  */
 @RestController
 @RequestMapping("${$rmp.cloud.exchange.outer}/examVerifyPhotos")
-public class ExamVerifyPhotoController  extends ControllerSupport{
-	
+public class ExamVerifyPhotoController extends ControllerSupport {
+
 	@Autowired
 	private OeClient oeClient;
-	
+
 	@GetMapping
-	public ResponseEntity<?> getExamVerifyPhotos(HttpServletRequest request,@RequestParam Long scoreId){
+	public ResponseEntity<?> getExamVerifyPhotos(HttpServletRequest request,
+			@RequestParam Long scoreId) {
 		User accessUser = getAccessUser();
-		if(accessUser == null){
-			return new ResponseEntity<FailureBaseResponse>(new FailureBaseResponse("请先登录"), HttpStatus.INTERNAL_SERVER_ERROR);
+		if (accessUser == null) {
+			return new ResponseEntity<FailureBaseResponse>(new FailureBaseResponse("请先登录"),
+					HttpStatus.INTERNAL_SERVER_ERROR);
 		}
-		try{
-			ExamPhotoVerifyData examPhotoVerifyData = oeClient.getExamPhotoVerifyData(accessUser.getUserToken(),scoreId);
-			return new ResponseEntity<SuccessBaseResponse>(new SuccessBaseResponse("查询成功",examPhotoVerifyData), HttpStatus.OK);
-		}catch(Exception e){
+		try {
+			String userToken = accessUser.getKey() + ":" + accessUser.getToken();
+			ExamPhotoVerifyData examPhotoVerifyData = oeClient.getExamPhotoVerifyData(userToken,
+					scoreId);
+			return new ResponseEntity<SuccessBaseResponse>(
+					new SuccessBaseResponse("查询成功", examPhotoVerifyData), HttpStatus.OK);
+		} catch (Exception e) {
 			e.printStackTrace();
-			return new ResponseEntity<FailureBaseResponse>(new FailureBaseResponse("查询失败"), HttpStatus.INTERNAL_SERVER_ERROR);
+			return new ResponseEntity<FailureBaseResponse>(new FailureBaseResponse("查询失败"),
+					HttpStatus.INTERNAL_SERVER_ERROR);
 		}
 	}
-	
-}
 
+}

+ 11 - 7
examcloud-exchange-outer-api-provider/src/main/java/cn/com/qmth/examcloud/exchange/outer/api/controller/swufe/StudentInfoController.java

@@ -3,6 +3,7 @@ package cn.com.qmth.examcloud.exchange.outer.api.controller.swufe;
 import java.util.List;
 import java.util.Map;
 
+import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.PostMapping;
 import org.springframework.web.bind.annotation.RequestBody;
@@ -16,8 +17,8 @@ import cn.com.qmth.examcloud.common.dto.core.enums.CourseLevel;
 import cn.com.qmth.examcloud.commons.web.security.bean.User;
 import cn.com.qmth.examcloud.commons.web.support.ControllerSupport;
 import cn.com.qmth.examcloud.core.basic.api.StudentCloudService;
-import cn.com.qmth.examcloud.core.basic.api.request.InsertOrUpdateStudentReq;
-import cn.com.qmth.examcloud.core.basic.api.response.InsertOrUpdateStudentResp;
+import cn.com.qmth.examcloud.core.basic.api.request.SaveStudentReq;
+import cn.com.qmth.examcloud.core.basic.api.response.SaveStudentResp;
 import cn.com.qmth.examcloud.examwork.api.ExamCloudService;
 import cn.com.qmth.examcloud.examwork.api.ExamStudentCloudService;
 import cn.com.qmth.examcloud.examwork.api.bean.ExamBean;
@@ -66,7 +67,7 @@ public class StudentInfoController extends ControllerSupport {
 			ExamBean examBean = resp.getExamBean();
 			String examName = examBean.getName();
 
-			InsertOrUpdateStudentReq saveStudentReq = new InsertOrUpdateStudentReq();
+			SaveStudentReq saveStudentReq = new SaveStudentReq();
 			saveStudentReq.setIdentityNumber(cur.getIdentityNumber());
 			saveStudentReq.setName(cur.getStudentName());
 			saveStudentReq.setOrgCode(cur.getOrgCode());
@@ -75,8 +76,8 @@ public class StudentInfoController extends ControllerSupport {
 			saveStudentReq.setRootOrgId(rootOrgId);
 			saveStudentReq.setStudentCode(cur.getStudentCode());
 
-			InsertOrUpdateStudentResp insertOrUpdateStudentResp = studentCloudService
-					.insertOrUpdateStudent(saveStudentReq);
+			SaveStudentResp insertOrUpdateStudentResp = studentCloudService
+					.saveStudent(saveStudentReq);
 
 			Long studentId = insertOrUpdateStudentResp.getStudentId();
 
@@ -92,11 +93,14 @@ public class StudentInfoController extends ControllerSupport {
 			sReq.setStudentId(studentId);
 			sReq.setExamName(examName);
 			sReq.setIdentityNumber(cur.getIdentityNumber());
-			sReq.setPaperType(cur.getPaperType());
+			if (StringUtils.isNotBlank(cur.getPaperType())) {
+				sReq.setPaperType(cur.getPaperType());
+			} else {
+				sReq.setPaperType("O");
+			}
 			sReq.setRootOrgId(rootOrgId);
 			sReq.setStudentCode(cur.getStudentCode());
 			sReq.setStudentName(cur.getStudentName());
-			sReq.setPaperType("O");
 			sReq.setRemark(cur.getRemark());
 			SaveExamStudentResp savedExamStudent = examStudentCloudService.saveExamStudent(sReq);
 			ExamStudentBean examStudentBean = savedExamStudent.getExamStudentBean();

+ 6 - 6
examcloud-exchange-outer-api-provider/src/main/java/cn/com/qmth/examcloud/exchange/outer/api/controller/sydx/StudentExamInfoController.java

@@ -21,8 +21,8 @@ import cn.com.qmth.examcloud.commons.base.util.DateUtil.DatePatterns;
 import cn.com.qmth.examcloud.commons.web.security.bean.User;
 import cn.com.qmth.examcloud.commons.web.support.ControllerSupport;
 import cn.com.qmth.examcloud.core.basic.api.StudentCloudService;
-import cn.com.qmth.examcloud.core.basic.api.request.InsertOrUpdateStudentReq;
-import cn.com.qmth.examcloud.core.basic.api.response.InsertOrUpdateStudentResp;
+import cn.com.qmth.examcloud.core.basic.api.request.SaveStudentReq;
+import cn.com.qmth.examcloud.core.basic.api.response.SaveStudentResp;
 import cn.com.qmth.examcloud.examwork.api.ExamCloudService;
 import cn.com.qmth.examcloud.examwork.api.ExamStudentCloudService;
 import cn.com.qmth.examcloud.examwork.api.bean.ExamBean;
@@ -107,7 +107,7 @@ public class StudentExamInfoController extends ControllerSupport {
 		List<Long> examStudentIdList = Lists.newArrayList();
 		for (OutletExamStudent cur : examStudentList) {
 
-			InsertOrUpdateStudentReq saveStudentReq = new InsertOrUpdateStudentReq();
+			SaveStudentReq saveStudentReq = new SaveStudentReq();
 			saveStudentReq.setIdentityNumber(cur.getIdentityNumber());
 			saveStudentReq.setName(cur.getName());
 			saveStudentReq.setPhoneNumber(cur.getPhone());
@@ -117,10 +117,10 @@ public class StudentExamInfoController extends ControllerSupport {
 			saveStudentReq.setRootOrgId(rootOrgId);
 			saveStudentReq.setStudentCode(cur.getStudentCode());
 
-			InsertOrUpdateStudentResp insertOrUpdateStudentResp = studentCloudService
-					.insertOrUpdateStudent(saveStudentReq);
+			SaveStudentResp saveStudentResp = studentCloudService
+					.saveStudent(saveStudentReq);
 
-			Long studentId = insertOrUpdateStudentResp.getStudentId();
+			Long studentId = saveStudentResp.getStudentId();
 
 			SaveExamStudentReq sReq = new SaveExamStudentReq();
 			sReq.setCourseLevel(cur.getCourseLevel());

+ 7 - 2
examcloud-exchange-outer-api-provider/src/main/java/cn/com/qmth/examcloud/exchange/outer/api/provider/ExamStudentOuterServiceProvider.java

@@ -2,6 +2,9 @@ package cn.com.qmth.examcloud.exchange.outer.api.provider;
 
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
 
 import cn.com.qmth.examcloud.commons.web.support.ControllerSupport;
 import cn.com.qmth.examcloud.examwork.api.ExamStudentCloudService;
@@ -18,6 +21,8 @@ import io.swagger.annotations.ApiOperation;
  * @date 2018年7月2日
  * @Copyright (c) 2018-? http://qmth.com.cn All Rights Reserved.
  */
+@RestController
+@RequestMapping("${$rmp.cloud.exchange.outer}/examStudent")
 public class ExamStudentOuterServiceProvider extends ControllerSupport
 		implements
 			ExamStudentOuterService {
@@ -28,9 +33,9 @@ public class ExamStudentOuterServiceProvider extends ControllerSupport
 	ExamStudentCloudService examStudentCloudService;
 
 	@ApiOperation(value = "保存考生信息")
-	@PostMapping("saveStudent")
+	@PostMapping("saveExamStudent")
 	@Override
-	public SaveExamStudentResp saveExamStudent(SaveExamStudentReq req) {
+	public SaveExamStudentResp saveExamStudent(@RequestBody SaveExamStudentReq req) {
 		cn.com.qmth.examcloud.examwork.api.request.SaveExamStudentReq request = new cn.com.qmth.examcloud.examwork.api.request.SaveExamStudentReq();
 
 		request.setCourseCode(req.getCourseCode());

+ 176 - 0
examcloud-exchange-outer-api-provider/src/main/java/cn/com/qmth/examcloud/exchange/outer/api/provider/FaceOuterServiceProvider.java

@@ -0,0 +1,176 @@
+package cn.com.qmth.examcloud.exchange.outer.api.provider;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.commons.fileupload.disk.DiskFileItem;
+import org.apache.commons.io.FileUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.multipart.commons.CommonsMultipartFile;
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+
+import cn.com.qmth.examcloud.commons.base.exception.StatusException;
+import cn.com.qmth.examcloud.commons.base.util.HttpClientUtil;
+import cn.com.qmth.examcloud.commons.base.util.ZipUtil;
+import cn.com.qmth.examcloud.commons.web.security.bean.User;
+import cn.com.qmth.examcloud.commons.web.support.ControllerSupport;
+import cn.com.qmth.examcloud.exchange.outer.api.FaceOuterService;
+import cn.com.qmth.examcloud.exchange.outer.service.FaceService;
+import io.swagger.annotations.ApiOperation;
+
+/**
+ * 人脸 处理
+ * 
+ * @author chenken
+ * @date 2018年4月3日 下午3:58:31
+ * @company QMTH
+ * @description FaceppController.java
+ */
+@RestController
+@RequestMapping("${$rmp.cloud.exchange.outer}/face")
+public class FaceOuterServiceProvider extends ControllerSupport implements FaceOuterService {
+
+	private static final long serialVersionUID = -6268268043341270752L;
+
+	@Value("${$tempDir}")
+	private String tempDir;
+
+	/**
+	 * ZIP最大50M
+	 */
+	private static final int ZIP_MAX_SIZE = 50;
+
+	/**
+	 * 每张照片最大尺寸 500KB
+	 */
+	private static final int MAX_SIZE = 500;
+
+	@Autowired
+	private FaceService faceService;
+
+	@ApiOperation(value = "保存学生照片")
+	@PostMapping("addByUrl")
+	@Override
+	public void addPhotoByUrl(@RequestParam Long rootOrgId, @RequestParam String photoUrl,
+			@RequestParam String operator) {
+
+		if (photoUrl.startsWith("http")) {
+			byte[] bs = HttpClientUtil.get(photoUrl);
+
+			int lastIndexOf = photoUrl.lastIndexOf(".");
+			if (0 > lastIndexOf) {
+				throw new StatusException("EX-100002",
+						"photoPath is not end with photo file suffix.");
+			}
+			String fileSuffix = photoUrl.substring(lastIndexOf);
+
+			String fileName = System.currentTimeMillis() + fileSuffix;
+			File temp = new File(
+					tempDir + File.separator + "student_photo" + File.separator + fileName);
+
+			try {
+				FileUtils.writeByteArrayToFile(temp, bs);
+			} catch (IOException e) {
+				throw new StatusException("EX-100003", "文件读写失败");
+			}
+
+			faceService.processFace(rootOrgId, fileName, temp, operator);
+		}
+
+	}
+
+	@ApiOperation(value = "保存学生照片")
+	@PostMapping("add")
+	@Override
+	public void addPhoto(@RequestParam CommonsMultipartFile file) {
+		User accessUser = getAccessUser();
+		Long rootOrgId = accessUser.getRootOrgId();
+
+		log.debug("fileName =" + file.getOriginalFilename());
+		DiskFileItem item = (DiskFileItem) file.getFileItem();
+		File storeLocation = item.getStoreLocation();
+		String fileName = file.getOriginalFilename();
+		faceService.processFace(rootOrgId, fileName, storeLocation, accessUser.getDisplayName());
+	}
+
+	@ApiOperation(value = "导入学生照片")
+	@PostMapping("importPhotos")
+	@Override
+	public List<Map<String, String>> importPhotos(@RequestParam CommonsMultipartFile file) {
+
+		User accessUser = getAccessUser();
+		Long rootOrgId = accessUser.getRootOrgId();
+
+		DiskFileItem item = (DiskFileItem) file.getFileItem();
+		File storeLocation = item.getStoreLocation();
+		String filename = file.getOriginalFilename();
+
+		if (!filename.endsWith(".zip")) {
+			throw new StatusException("EX-620001", "文件格式不正确,必须是zip格式的压缩包");
+		}
+		// 文件大小限制
+		if (file.getSize() > ZIP_MAX_SIZE * 1024 * 1024) {
+			throw new StatusException("EX-620002", "文件大小超过50M,请分批导入");
+		}
+
+		List<Map<String, String>> ret = Lists.newArrayList();
+
+		String tempDirPath = tempDir + File.separator + "photo_import" + File.separator
+				+ System.currentTimeMillis();
+		File tempDir = new File(tempDirPath);
+		try {
+			ZipUtil.unzip(storeLocation, new File(tempDirPath));
+		} catch (Exception e) {
+			throw new StatusException("EX-620003", "zip文件损坏");
+		}
+
+		File[] files = tempDir.listFiles();
+
+		if (null == files) {
+			throw new StatusException("EX-620004", "zip文件为空");
+		}
+
+		for (File f : files) {
+			Map<String, String> map = Maps.newHashMap();
+
+			if (f.length() > MAX_SIZE * 1024) {
+				map.put("file", f.getName());
+				map.put("statusCode", "EX-620005");
+				map.put("statusDesc", "文件大小超过500KB");
+				ret.add(map);
+				continue;
+			}
+			try {
+				map.put("file", f.getName());
+				faceService.processFace(rootOrgId, f.getName(), f, accessUser.getDisplayName());
+				map.put("statusCode", "200");
+				map.put("statusDesc", "成功");
+			} catch (StatusException e) {
+				map.put("statusCode", e.getCode());
+				map.put("statusDesc", e.getDesc());
+			} catch (Exception e) {
+				map.put("statusCode", "系统异常");
+				map.put("statusDesc", e.getCause().getMessage());
+			}
+			ret.add(map);
+		}
+
+		try {
+			FileUtils.deleteDirectory(tempDir);
+		} catch (IOException e) {
+			log.error("fail to clean temp dir.", e);
+		}
+
+		return ret;
+	}
+
+}

+ 44 - 25
examcloud-exchange-outer-api-provider/src/main/java/cn/com/qmth/examcloud/exchange/outer/api/provider/StudentOuterServiceProvider.java

@@ -1,21 +1,25 @@
 package cn.com.qmth.examcloud.exchange.outer.api.provider;
 
+import java.io.File;
+import java.io.IOException;
+
+import org.apache.commons.io.FileUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
 import org.springframework.web.bind.annotation.PostMapping;
 import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
 
 import cn.com.qmth.examcloud.commons.base.exception.StatusException;
 import cn.com.qmth.examcloud.commons.base.util.HttpClientUtil;
-import cn.com.qmth.examcloud.commons.base.util.UrlUtil;
 import cn.com.qmth.examcloud.commons.web.support.ControllerSupport;
 import cn.com.qmth.examcloud.core.basic.api.StudentCloudService;
-import cn.com.qmth.examcloud.core.basic.api.request.InsertOrUpdateStudentReq;
-import cn.com.qmth.examcloud.core.basic.api.response.InsertOrUpdateStudentResp;
 import cn.com.qmth.examcloud.exchange.outer.api.StudentOuterService;
 import cn.com.qmth.examcloud.exchange.outer.api.request.SaveStudentReq;
 import cn.com.qmth.examcloud.exchange.outer.api.response.SaveStudentResp;
-import cn.com.qmth.examcloud.exchange.outer.service.UpyunService;
+import cn.com.qmth.examcloud.exchange.outer.service.FaceService;
 import io.swagger.annotations.ApiOperation;
 
 /**
@@ -25,6 +29,8 @@ import io.swagger.annotations.ApiOperation;
  * @date 2018年6月29日
  * @Copyright (c) 2018-? http://qmth.com.cn All Rights Reserved.
  */
+@RestController
+@RequestMapping("${$rmp.cloud.exchange.outer}/student")
 public class StudentOuterServiceProvider extends ControllerSupport implements StudentOuterService {
 
 	private static final long serialVersionUID = -8252740695302763716L;
@@ -33,32 +39,20 @@ public class StudentOuterServiceProvider extends ControllerSupport implements St
 	StudentCloudService studentCloudService;
 
 	@Autowired
-	UpyunService upyunService;
+	private FaceService faceService;
+
+	@Value("${$tempDir}")
+	private String tempDir;
 
 	@ApiOperation(value = "保存学生信息")
 	@PostMapping("saveStudent")
 	@Override
 	public SaveStudentResp saveStudent(@RequestBody SaveStudentReq req) {
-		String identityNumber = req.getIdentityNumber();
-		Long rootOrgId = req.getRootOrgId();
+		trim(req);
 
-		String photoPath = req.getPhotoPath();
-		if (StringUtils.isNotBlank(photoPath)) {
-			if (photoPath.startsWith("http")) {
-				byte[] bs = HttpClientUtil.get(photoPath);
-
-				int lastIndexOf = photoPath.lastIndexOf(".");
-				if (0 > lastIndexOf) {
-					throw new StatusException("EX-100002",
-							"photoPath is not end with photo file suffix.");
-				}
-				String fileSuffix = photoPath.substring(lastIndexOf);
-				photoPath = upyunService.saveStudentPhoto(UrlUtil.encode(identityNumber), rootOrgId,
-						fileSuffix, bs);
-			}
-		}
+		Long rootOrgId = req.getRootOrgId();
 
-		InsertOrUpdateStudentReq request = new InsertOrUpdateStudentReq();
+		cn.com.qmth.examcloud.core.basic.api.request.SaveStudentReq request = new cn.com.qmth.examcloud.core.basic.api.request.SaveStudentReq();
 		request.setIdentityNumber(req.getIdentityNumber());
 		request.setName(req.getName());
 		request.setOrgCode(req.getOrgCode());
@@ -68,9 +62,34 @@ public class StudentOuterServiceProvider extends ControllerSupport implements St
 		request.setRemark(req.getRemark());
 		request.setRootOrgId(req.getRootOrgId());
 		request.setStudentCode(req.getStudentCode());
-		request.setPhotoPath(photoPath);
 
-		InsertOrUpdateStudentResp response = studentCloudService.insertOrUpdateStudent(request);
+		cn.com.qmth.examcloud.core.basic.api.response.SaveStudentResp response = studentCloudService
+				.saveStudent(request);
+
+		String photoUrl = req.getPhotoUrl();
+		if (StringUtils.isNotBlank(photoUrl)) {
+			byte[] bs = HttpClientUtil.get(photoUrl);
+
+			int lastIndexOf = photoUrl.lastIndexOf(".");
+			if (0 > lastIndexOf) {
+				throw new StatusException("EX-100002",
+						"photoPath is not end with photo file suffix.");
+			}
+			String fileSuffix = photoUrl.substring(lastIndexOf);
+
+			String fileName = System.currentTimeMillis() + fileSuffix;
+			File temp = new File(
+					tempDir + File.separator + "student_photo" + File.separator + fileName);
+
+			try {
+				FileUtils.writeByteArrayToFile(temp, bs);
+			} catch (IOException e) {
+				throw new StatusException("EX-100003", "文件读写失败");
+			}
+
+			faceService.processFace(rootOrgId, fileName, temp, req.getOperator());
+		}
+
 		SaveStudentResp resp = new SaveStudentResp();
 		resp.setOrgId(response.getOrgId());
 		resp.setOrgName(response.getOrgName());

+ 167 - 0
examcloud-exchange-outer-api-provider/src/main/java/cn/com/qmth/examcloud/exchange/outer/api/provider/cug/CugOuterServiceProvider.java

@@ -0,0 +1,167 @@
+package cn.com.qmth.examcloud.exchange.outer.api.provider.cug;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.List;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import com.google.common.collect.Lists;
+
+import cn.com.qmth.examcloud.commons.base.exception.StatusException;
+import cn.com.qmth.examcloud.commons.base.util.HttpClientUtil;
+import cn.com.qmth.examcloud.commons.web.support.ControllerSupport;
+import cn.com.qmth.examcloud.core.basic.api.StudentCloudService;
+import cn.com.qmth.examcloud.core.basic.api.request.SaveStudentReq;
+import cn.com.qmth.examcloud.core.basic.api.response.SaveStudentResp;
+import cn.com.qmth.examcloud.examwork.api.ExamCloudService;
+import cn.com.qmth.examcloud.examwork.api.ExamStudentCloudService;
+import cn.com.qmth.examcloud.examwork.api.bean.ExamStudentBean;
+import cn.com.qmth.examcloud.examwork.api.request.GetExamReq;
+import cn.com.qmth.examcloud.examwork.api.request.SaveExamStudentReq;
+import cn.com.qmth.examcloud.examwork.api.response.GetExamResp;
+import cn.com.qmth.examcloud.examwork.api.response.SaveExamStudentResp;
+import cn.com.qmth.examcloud.exchange.outer.api.CugOuterService;
+import cn.com.qmth.examcloud.exchange.outer.api.request.cug.SaveCugStudentAndExamStudentReq;
+import cn.com.qmth.examcloud.exchange.outer.api.response.cug.SaveCugStudentAndExamStudentResp;
+import cn.com.qmth.examcloud.exchange.outer.service.CourseGroupService;
+import cn.com.qmth.examcloud.exchange.outer.service.FaceService;
+import cn.com.qmth.examcloud.exchange.outer.service.bean.Course;
+import io.swagger.annotations.ApiOperation;
+
+/**
+ * 中国地质大学(武汉)
+ *
+ * @author WANGWEI
+ * @date 2018年9月4日
+ * @Copyright (c) 2018-? http://qmth.com.cn All Rights Reserved.
+ */
+@RestController
+@RequestMapping("${$rmp.cloud.exchange.outer}/cug")
+public class CugOuterServiceProvider extends ControllerSupport implements CugOuterService {
+
+	private static final long serialVersionUID = -2082287868965834214L;
+
+	@Autowired
+	StudentCloudService studentCloudService;
+
+	@Autowired
+	private FaceService faceService;
+
+	@Autowired
+	CourseGroupService courseGroupService;
+
+	@Autowired
+	ExamCloudService examCloudService;
+
+	@Autowired
+	ExamStudentCloudService examStudentCloudService;
+
+	@Value("${$tempDir}")
+	private String tempDir;
+
+	@ApiOperation(value = "保存考生信息")
+	@PostMapping("saveCugStudentAndExamStudent")
+	@Override
+	public SaveCugStudentAndExamStudentResp saveCugStudentAndExamStudent(
+			@RequestBody SaveCugStudentAndExamStudentReq req) {
+		trim(req);
+
+		Long rootOrgId = req.getRootOrgId();
+		String identityNumber = req.getIdentityNumber();
+
+		SaveStudentReq request = new SaveStudentReq();
+		request.setIdentityNumber(identityNumber);
+		request.setName(req.getName());
+		request.setOrgCode(req.getOrgCode());
+		request.setOrgName(req.getOrgName());
+		request.setPhoneNumber(req.getPhoneNumber());
+		request.setRemark(req.getRemark());
+		request.setRootOrgId(req.getRootOrgId());
+		request.setStudentCode(req.getStudentCode());
+
+		SaveStudentResp response = studentCloudService.saveStudent(request);
+
+		Long studentId = response.getStudentId();
+
+		String photoUrl = req.getPhotoUrl();
+		if (StringUtils.isNotBlank(photoUrl)) {
+			byte[] bs = HttpClientUtil.get(photoUrl);
+
+			int lastIndexOf = photoUrl.lastIndexOf(".");
+			if (0 > lastIndexOf) {
+				throw new StatusException("EX-100002",
+						"photoPath is not end with photo file suffix.");
+			}
+			String fileSuffix = photoUrl.substring(lastIndexOf);
+
+			String fileName = identityNumber + fileSuffix;
+			File temp = new File(
+					tempDir + File.separator + "student_photo" + File.separator + fileName);
+
+			try {
+				FileUtils.writeByteArrayToFile(temp, bs);
+			} catch (IOException e) {
+				throw new StatusException("EX-100003", "文件读写失败");
+			}
+
+			faceService.processFace(rootOrgId, fileName, temp, req.getOperator());
+		}
+
+		String courseGroupName = req.getCourseGroupName();
+		String examName = req.getExamName();
+		String specialtyName = req.getSpecialtyName();
+
+		List<Course> courseList = courseGroupService.getCourseList(rootOrgId, courseGroupName);
+
+		GetExamReq getExamReq = new GetExamReq();
+		getExamReq.setName(examName);
+		getExamReq.setRootOrgId(rootOrgId);
+		GetExamResp getExamResp = examCloudService.getExam(getExamReq);
+
+		Long examId = getExamResp.getId();
+
+		List<Long> examStudentIdList = Lists.newArrayList();
+
+		for (Course course : courseList) {
+			SaveExamStudentReq sReq = new SaveExamStudentReq();
+			sReq.setCourseLevel(course.getLevel());
+			sReq.setCourseCode(course.getCode());
+			sReq.setCourseName(course.getName());
+
+			sReq.setExamId(examId);
+			sReq.setExamName(examName);
+
+			sReq.setStudentId(studentId);
+			sReq.setIdentityNumber(req.getIdentityNumber());
+			sReq.setRootOrgId(rootOrgId);
+			sReq.setStudentCode(req.getStudentCode());
+			sReq.setStudentName(req.getName());
+			sReq.setSpecialtyName(specialtyName);
+
+			sReq.setRemark(req.getRemark());
+			sReq.setPaperType(req.getPaperType());
+
+			SaveExamStudentResp savedExamStudent = examStudentCloudService.saveExamStudent(sReq);
+			ExamStudentBean examStudentBean = savedExamStudent.getExamStudentBean();
+			examStudentIdList.add(examStudentBean.getId());
+		}
+
+		SaveCugStudentAndExamStudentResp resp = new SaveCugStudentAndExamStudentResp();
+		resp.setOrgId(response.getOrgId());
+		resp.setOrgName(response.getOrgName());
+		resp.setRootOrgId(response.getRootOrgId());
+		resp.setStudentId(response.getStudentId());
+		resp.setExamStudentIdList(examStudentIdList);
+
+		return resp;
+	}
+
+}

+ 26 - 0
examcloud-exchange-outer-api/src/main/java/cn/com/qmth/examcloud/exchange/outer/api/CugOuterService.java

@@ -0,0 +1,26 @@
+package cn.com.qmth.examcloud.exchange.outer.api;
+
+import cn.com.qmth.examcloud.commons.web.cloud.api.OuterService;
+import cn.com.qmth.examcloud.exchange.outer.api.request.cug.SaveCugStudentAndExamStudentReq;
+import cn.com.qmth.examcloud.exchange.outer.api.response.cug.SaveCugStudentAndExamStudentResp;
+
+/**
+ * 中国地质大学(武汉)
+ *
+ * @author WANGWEI
+ * @date 2018年9月4日
+ * @Copyright (c) 2018-? http://qmth.com.cn All Rights Reserved.
+ */
+public interface CugOuterService extends OuterService {
+
+	/**
+	 * 方法注释
+	 *
+	 * @author WANGWEI
+	 * @param req
+	 * @return
+	 */
+	SaveCugStudentAndExamStudentResp saveCugStudentAndExamStudent(
+			SaveCugStudentAndExamStudentReq req);
+
+}

+ 0 - 15
examcloud-exchange-outer-api/src/main/java/cn/com/qmth/examcloud/exchange/outer/api/DemoOuterService.java

@@ -1,15 +0,0 @@
-package cn.com.qmth.examcloud.exchange.outer.api;
-
-import cn.com.qmth.examcloud.commons.web.cloud.api.OuterService;
-import cn.com.qmth.examcloud.exchange.outer.api.request.GetXxxReq;
-import cn.com.qmth.examcloud.exchange.outer.api.response.GetXxxResp;
-
-/**
- * @author WANGWEI
- *
- */
-public interface DemoOuterService extends OuterService {
-
-	GetXxxResp getXxx(GetXxxReq req);
-
-}

+ 27 - 0
examcloud-exchange-outer-api/src/main/java/cn/com/qmth/examcloud/exchange/outer/api/FaceOuterService.java

@@ -0,0 +1,27 @@
+package cn.com.qmth.examcloud.exchange.outer.api;
+
+import java.util.List;
+import java.util.Map;
+
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.multipart.commons.CommonsMultipartFile;
+
+import cn.com.qmth.examcloud.commons.web.cloud.api.OuterService;
+
+/**
+ * 类注释
+ *
+ * @author WANGWEI
+ * @date 2018年9月4日
+ * @Copyright (c) 2018-? http://qmth.com.cn All Rights Reserved.
+ */
+public interface FaceOuterService extends OuterService {
+
+	void addPhotoByUrl(@RequestParam Long rootOrgId, @RequestParam String photoUrl,
+			@RequestParam String operator);
+
+	void addPhoto(@RequestParam CommonsMultipartFile file);
+
+	List<Map<String, String>> importPhotos(@RequestParam CommonsMultipartFile file);
+
+}

+ 0 - 33
examcloud-exchange-outer-api/src/main/java/cn/com/qmth/examcloud/exchange/outer/api/request/GetXxxReq.java

@@ -1,33 +0,0 @@
-package cn.com.qmth.examcloud.exchange.outer.api.request;
-
-import cn.com.qmth.examcloud.commons.web.cloud.api.BaseRequest;
-
-/**
- * @author WANGWEI
- *
- */
-public class GetXxxReq extends BaseRequest {
-
-	private static final long serialVersionUID = -6925630706679571172L;
-
-	private String f1;
-
-	private int f2;
-
-	public String getF1() {
-		return f1;
-	}
-
-	public void setF1(String f1) {
-		this.f1 = f1;
-	}
-
-	public int getF2() {
-		return f2;
-	}
-
-	public void setF2(int f2) {
-		this.f2 = f2;
-	}
-
-}

+ 139 - 139
examcloud-exchange-outer-api/src/main/java/cn/com/qmth/examcloud/exchange/outer/api/request/SaveExamStudentReq.java

@@ -1,139 +1,139 @@
-package cn.com.qmth.examcloud.exchange.outer.api.request;
-
-import cn.com.qmth.examcloud.commons.web.cloud.api.BaseRequest;
-
-public class SaveExamStudentReq extends BaseRequest {
-
-	private static final long serialVersionUID = -8455805881947392754L;
-
-	/**
-	 * 顶级机构ID
-	 */
-	private Long rootOrgId;
-
-	/**
-	 * 考试ID
-	 */
-	private Long examId;
-
-	/**
-	 * 考试名称
-	 */
-	private String examName;
-
-	/**
-	 * 学生姓名
-	 */
-	private String studentName;
-
-	/**
-	 * 学生学号
-	 */
-	private String studentCode;
-
-	/**
-	 * 学生身份证号
-	 */
-	private String identityNumber;
-
-	/**
-	 * 考试课程名称
-	 */
-	private String courseName;
-
-	/**
-	 * 考试课程code
-	 */
-	private String courseCode;
-
-	/**
-	 * 考试课程level
-	 */
-	private String courseLevel;
-
-	/**
-	 * 试卷类型
-	 */
-	private String paperType;
-
-	public Long getRootOrgId() {
-		return rootOrgId;
-	}
-
-	public void setRootOrgId(Long rootOrgId) {
-		this.rootOrgId = rootOrgId;
-	}
-
-	public Long getExamId() {
-		return examId;
-	}
-
-	public void setExamId(Long examId) {
-		this.examId = examId;
-	}
-
-	public String getExamName() {
-		return examName;
-	}
-
-	public void setExamName(String examName) {
-		this.examName = examName;
-	}
-
-	public String getStudentName() {
-		return studentName;
-	}
-
-	public void setStudentName(String studentName) {
-		this.studentName = studentName;
-	}
-
-	public String getStudentCode() {
-		return studentCode;
-	}
-
-	public void setStudentCode(String studentCode) {
-		this.studentCode = studentCode;
-	}
-
-	public String getIdentityNumber() {
-		return identityNumber;
-	}
-
-	public void setIdentityNumber(String identityNumber) {
-		this.identityNumber = identityNumber;
-	}
-
-	public String getCourseName() {
-		return courseName;
-	}
-
-	public void setCourseName(String courseName) {
-		this.courseName = courseName;
-	}
-
-	public String getCourseCode() {
-		return courseCode;
-	}
-
-	public void setCourseCode(String courseCode) {
-		this.courseCode = courseCode;
-	}
-
-	public String getCourseLevel() {
-		return courseLevel;
-	}
-
-	public void setCourseLevel(String courseLevel) {
-		this.courseLevel = courseLevel;
-	}
-
-	public String getPaperType() {
-		return paperType;
-	}
-
-	public void setPaperType(String paperType) {
-		this.paperType = paperType;
-	}
-
-}
+package cn.com.qmth.examcloud.exchange.outer.api.request;
+
+import cn.com.qmth.examcloud.commons.web.cloud.api.BaseRequest;
+
+public class SaveExamStudentReq extends BaseRequest {
+
+	private static final long serialVersionUID = -8455805881947392754L;
+
+	/**
+	 * 顶级机构ID
+	 */
+	private Long rootOrgId;
+
+	/**
+	 * 考试ID
+	 */
+	private Long examId;
+
+	/**
+	 * 考试名称
+	 */
+	private String examName;
+
+	/**
+	 * 学生姓名
+	 */
+	private String studentName;
+
+	/**
+	 * 学生学号
+	 */
+	private String studentCode;
+
+	/**
+	 * 学生身份证号
+	 */
+	private String identityNumber;
+
+	/**
+	 * 考试课程名称
+	 */
+	private String courseName;
+
+	/**
+	 * 考试课程code
+	 */
+	private String courseCode;
+
+	/**
+	 * 考试课程level
+	 */
+	private String courseLevel;
+
+	/**
+	 * 试卷类型
+	 */
+	private String paperType;
+
+	public Long getRootOrgId() {
+		return rootOrgId;
+	}
+
+	public void setRootOrgId(Long rootOrgId) {
+		this.rootOrgId = rootOrgId;
+	}
+
+	public Long getExamId() {
+		return examId;
+	}
+
+	public void setExamId(Long examId) {
+		this.examId = examId;
+	}
+
+	public String getExamName() {
+		return examName;
+	}
+
+	public void setExamName(String examName) {
+		this.examName = examName;
+	}
+
+	public String getStudentName() {
+		return studentName;
+	}
+
+	public void setStudentName(String studentName) {
+		this.studentName = studentName;
+	}
+
+	public String getStudentCode() {
+		return studentCode;
+	}
+
+	public void setStudentCode(String studentCode) {
+		this.studentCode = studentCode;
+	}
+
+	public String getIdentityNumber() {
+		return identityNumber;
+	}
+
+	public void setIdentityNumber(String identityNumber) {
+		this.identityNumber = identityNumber;
+	}
+
+	public String getCourseName() {
+		return courseName;
+	}
+
+	public void setCourseName(String courseName) {
+		this.courseName = courseName;
+	}
+
+	public String getCourseCode() {
+		return courseCode;
+	}
+
+	public void setCourseCode(String courseCode) {
+		this.courseCode = courseCode;
+	}
+
+	public String getCourseLevel() {
+		return courseLevel;
+	}
+
+	public void setCourseLevel(String courseLevel) {
+		this.courseLevel = courseLevel;
+	}
+
+	public String getPaperType() {
+		return paperType;
+	}
+
+	public void setPaperType(String paperType) {
+		this.paperType = paperType;
+	}
+
+}

+ 68 - 0
examcloud-exchange-outer-api/src/main/java/cn/com/qmth/examcloud/exchange/outer/api/request/SaveStudentPhotoReq.java

@@ -0,0 +1,68 @@
+package cn.com.qmth.examcloud.exchange.outer.api.request;
+
+import cn.com.qmth.examcloud.commons.web.cloud.api.BaseRequest;
+
+/**
+ * 类注释
+ *
+ * @author WANGWEI
+ * @date 2018年9月4日
+ * @Copyright (c) 2018-? http://qmth.com.cn All Rights Reserved.
+ */
+public class SaveStudentPhotoReq extends BaseRequest {
+
+	private static final long serialVersionUID = -6222466329184663417L;
+
+	/**
+	 * 顶级机构ID
+	 */
+	private Long rootOrgId;
+
+	/**
+	 * 身份证号码
+	 */
+	private String identityNumber;
+
+	/**
+	 * 图片地址
+	 */
+	private String photoUrl;
+
+	/**
+	 * 操作者
+	 */
+	private String operator;
+
+	public Long getRootOrgId() {
+		return rootOrgId;
+	}
+
+	public void setRootOrgId(Long rootOrgId) {
+		this.rootOrgId = rootOrgId;
+	}
+
+	public String getIdentityNumber() {
+		return identityNumber;
+	}
+
+	public void setIdentityNumber(String identityNumber) {
+		this.identityNumber = identityNumber;
+	}
+
+	public String getPhotoUrl() {
+		return photoUrl;
+	}
+
+	public void setPhotoUrl(String photoUrl) {
+		this.photoUrl = photoUrl;
+	}
+
+	public String getOperator() {
+		return operator;
+	}
+
+	public void setOperator(String operator) {
+		this.operator = operator;
+	}
+
+}

+ 18 - 5
examcloud-exchange-outer-api/src/main/java/cn/com/qmth/examcloud/exchange/outer/api/request/SaveStudentReq.java

@@ -56,13 +56,18 @@ public class SaveStudentReq extends BaseRequest {
 	/**
 	 * 图片地址
 	 */
-	private String photoPath;
+	private String photoUrl;
 
 	/**
 	 * 手机号码
 	 */
 	private String phoneNumber;
 
+	/**
+	 * 操作者
+	 */
+	private String operator;
+
 	public String getName() {
 		return name;
 	}
@@ -127,12 +132,12 @@ public class SaveStudentReq extends BaseRequest {
 		this.remark = remark;
 	}
 
-	public String getPhotoPath() {
-		return photoPath;
+	public String getPhotoUrl() {
+		return photoUrl;
 	}
 
-	public void setPhotoPath(String photoPath) {
-		this.photoPath = photoPath;
+	public void setPhotoUrl(String photoUrl) {
+		this.photoUrl = photoUrl;
 	}
 
 	public String getPhoneNumber() {
@@ -143,4 +148,12 @@ public class SaveStudentReq extends BaseRequest {
 		this.phoneNumber = phoneNumber;
 	}
 
+	public String getOperator() {
+		return operator;
+	}
+
+	public void setOperator(String operator) {
+		this.operator = operator;
+	}
+
 }

+ 182 - 0
examcloud-exchange-outer-api/src/main/java/cn/com/qmth/examcloud/exchange/outer/api/request/cug/SaveCugStudentAndExamStudentReq.java

@@ -0,0 +1,182 @@
+package cn.com.qmth.examcloud.exchange.outer.api.request.cug;
+
+import cn.com.qmth.examcloud.commons.web.cloud.api.BaseRequest;
+
+public class SaveCugStudentAndExamStudentReq extends BaseRequest {
+
+	private static final long serialVersionUID = 8293200048902081959L;
+
+	/**
+	 * 学生姓名
+	 */
+	private String name;
+
+	/**
+	 * 顶级机构ID
+	 */
+	private Long rootOrgId;
+
+	/**
+	 * 学习中心编码
+	 */
+	private String orgCode;
+
+	/**
+	 * 学习中心名称
+	 */
+	private String orgName;
+
+	/**
+	 * 学生code
+	 */
+	private String studentCode;
+
+	/**
+	 * 身份证号码
+	 */
+	private String identityNumber;
+
+	/**
+	 * 备注
+	 */
+	private String remark;
+
+	/**
+	 * 图片地址
+	 */
+	private String photoUrl;
+
+	/**
+	 * 手机号码
+	 */
+	private String phoneNumber;
+
+	/**
+	 * 操作者
+	 */
+	private String operator;
+
+	private String examName;
+
+	private String specialtyName;
+
+	private String courseGroupName;
+
+	/**
+	 * 试卷类型
+	 */
+	private String paperType;
+
+	public String getName() {
+		return name;
+	}
+
+	public void setName(String name) {
+		this.name = name;
+	}
+
+	public Long getRootOrgId() {
+		return rootOrgId;
+	}
+
+	public void setRootOrgId(Long rootOrgId) {
+		this.rootOrgId = rootOrgId;
+	}
+
+	public String getOrgCode() {
+		return orgCode;
+	}
+
+	public void setOrgCode(String orgCode) {
+		this.orgCode = orgCode;
+	}
+
+	public String getOrgName() {
+		return orgName;
+	}
+
+	public void setOrgName(String orgName) {
+		this.orgName = orgName;
+	}
+
+	public String getStudentCode() {
+		return studentCode;
+	}
+
+	public void setStudentCode(String studentCode) {
+		this.studentCode = studentCode;
+	}
+
+	public String getIdentityNumber() {
+		return identityNumber;
+	}
+
+	public void setIdentityNumber(String identityNumber) {
+		this.identityNumber = identityNumber;
+	}
+
+	public String getRemark() {
+		return remark;
+	}
+
+	public void setRemark(String remark) {
+		this.remark = remark;
+	}
+
+	public String getPhotoUrl() {
+		return photoUrl;
+	}
+
+	public void setPhotoUrl(String photoUrl) {
+		this.photoUrl = photoUrl;
+	}
+
+	public String getPhoneNumber() {
+		return phoneNumber;
+	}
+
+	public void setPhoneNumber(String phoneNumber) {
+		this.phoneNumber = phoneNumber;
+	}
+
+	public String getOperator() {
+		return operator;
+	}
+
+	public void setOperator(String operator) {
+		this.operator = operator;
+	}
+
+	public String getExamName() {
+		return examName;
+	}
+
+	public void setExamName(String examName) {
+		this.examName = examName;
+	}
+
+	public String getSpecialtyName() {
+		return specialtyName;
+	}
+
+	public void setSpecialtyName(String specialtyName) {
+		this.specialtyName = specialtyName;
+	}
+
+	public String getCourseGroupName() {
+		return courseGroupName;
+	}
+
+	public void setCourseGroupName(String courseGroupName) {
+		this.courseGroupName = courseGroupName;
+	}
+
+	public String getPaperType() {
+		return paperType;
+	}
+
+	public void setPaperType(String paperType) {
+		this.paperType = paperType;
+	}
+
+}

+ 0 - 23
examcloud-exchange-outer-api/src/main/java/cn/com/qmth/examcloud/exchange/outer/api/response/GetXxxResp.java

@@ -1,23 +0,0 @@
-package cn.com.qmth.examcloud.exchange.outer.api.response;
-
-import cn.com.qmth.examcloud.commons.web.cloud.api.BaseResponse;
-
-/**
- * @author WANGWEI
- *
- */
-public class GetXxxResp extends BaseResponse {
-
-	private static final long serialVersionUID = -6925630706679571172L;
-
-	private String s;
-
-	public String getS() {
-		return s;
-	}
-
-	public void setS(String s) {
-		this.s = s;
-	}
-
-}

+ 20 - 20
examcloud-exchange-outer-api/src/main/java/cn/com/qmth/examcloud/exchange/outer/api/response/SaveExamStudentResp.java

@@ -1,20 +1,20 @@
-package cn.com.qmth.examcloud.exchange.outer.api.response;
-
-import cn.com.qmth.examcloud.commons.web.cloud.api.BaseResponse;
-import cn.com.qmth.examcloud.exchange.outer.api.bean.ExamStudentBean;
-
-public class SaveExamStudentResp extends BaseResponse {
-
-	private static final long serialVersionUID = 5003024673163742249L;
-
-	private ExamStudentBean examStudentBean;
-
-	public ExamStudentBean getExamStudentBean() {
-		return examStudentBean;
-	}
-
-	public void setExamStudentBean(ExamStudentBean examStudentBean) {
-		this.examStudentBean = examStudentBean;
-	}
-
-}
+package cn.com.qmth.examcloud.exchange.outer.api.response;
+
+import cn.com.qmth.examcloud.commons.web.cloud.api.BaseResponse;
+import cn.com.qmth.examcloud.exchange.outer.api.bean.ExamStudentBean;
+
+public class SaveExamStudentResp extends BaseResponse {
+
+	private static final long serialVersionUID = 5003024673163742249L;
+
+	private ExamStudentBean examStudentBean;
+
+	public ExamStudentBean getExamStudentBean() {
+		return examStudentBean;
+	}
+
+	public void setExamStudentBean(ExamStudentBean examStudentBean) {
+		this.examStudentBean = examStudentBean;
+	}
+
+}

+ 16 - 0
examcloud-exchange-outer-api/src/main/java/cn/com/qmth/examcloud/exchange/outer/api/response/SaveStudentPhotoResp.java

@@ -0,0 +1,16 @@
+package cn.com.qmth.examcloud.exchange.outer.api.response;
+
+import cn.com.qmth.examcloud.commons.web.cloud.api.BaseResponse;
+
+/**
+ * 类注释
+ *
+ * @author WANGWEI
+ * @date 2018年9月4日
+ * @Copyright (c) 2018-? http://qmth.com.cn All Rights Reserved.
+ */
+public class SaveStudentPhotoResp extends BaseResponse {
+
+	private static final long serialVersionUID = 8401121486324558126L;
+
+}

+ 61 - 0
examcloud-exchange-outer-api/src/main/java/cn/com/qmth/examcloud/exchange/outer/api/response/cug/SaveCugStudentAndExamStudentResp.java

@@ -0,0 +1,61 @@
+package cn.com.qmth.examcloud.exchange.outer.api.response.cug;
+
+import java.util.List;
+
+import cn.com.qmth.examcloud.commons.web.cloud.api.BaseResponse;
+
+public class SaveCugStudentAndExamStudentResp extends BaseResponse {
+
+	private static final long serialVersionUID = -7321764983963904493L;
+
+	private Long studentId;
+
+	private Long rootOrgId;
+
+	private Long orgId;
+
+	private String orgName;
+
+	private List<Long> examStudentIdList;
+
+	public Long getStudentId() {
+		return studentId;
+	}
+
+	public void setStudentId(Long studentId) {
+		this.studentId = studentId;
+	}
+
+	public Long getRootOrgId() {
+		return rootOrgId;
+	}
+
+	public void setRootOrgId(Long rootOrgId) {
+		this.rootOrgId = rootOrgId;
+	}
+
+	public Long getOrgId() {
+		return orgId;
+	}
+
+	public void setOrgId(Long orgId) {
+		this.orgId = orgId;
+	}
+
+	public String getOrgName() {
+		return orgName;
+	}
+
+	public void setOrgName(String orgName) {
+		this.orgName = orgName;
+	}
+
+	public List<Long> getExamStudentIdList() {
+		return examStudentIdList;
+	}
+
+	public void setExamStudentIdList(List<Long> examStudentIdList) {
+		this.examStudentIdList = examStudentIdList;
+	}
+
+}

+ 19 - 0
examcloud-exchange-outer-service/src/main/java/cn/com/qmth/examcloud/exchange/outer/service/CourseGroupService.java

@@ -0,0 +1,19 @@
+package cn.com.qmth.examcloud.exchange.outer.service;
+
+import java.util.List;
+
+import cn.com.qmth.examcloud.exchange.outer.service.bean.Course;
+
+public interface CourseGroupService {
+
+	/**
+	 * 方法注释
+	 *
+	 * @author WANGWEI
+	 * @param rootOrgId
+	 * @param courseGroupName
+	 * @return
+	 */
+	List<Course> getCourseList(Long rootOrgId, String courseGroupName);
+
+}

+ 0 - 17
examcloud-exchange-outer-service/src/main/java/cn/com/qmth/examcloud/exchange/outer/service/ExamService.java

@@ -1,17 +0,0 @@
-package cn.com.qmth.examcloud.exchange.outer.service;
-
-import cn.com.qmth.examcloud.exchange.dao.bean.ExamReq;
-import cn.com.qmth.examcloud.exchange.dao.bean.OutletExam;
-
-/**
- * @author  	chenken
- * @date    	2018年5月7日 下午3:28:34
- * @company 	QMTH
- * @description ExamController.java
- */
-public interface ExamService{
-
-	public OutletExam createExam(ExamReq examReq,String userToken,Long rootOrgId)  throws Exception;
-	
-}
-

+ 25 - 0
examcloud-exchange-outer-service/src/main/java/cn/com/qmth/examcloud/exchange/outer/service/FaceService.java

@@ -0,0 +1,25 @@
+package cn.com.qmth.examcloud.exchange.outer.service;
+
+import java.io.File;
+
+/**
+ * 人脸 Service
+ *
+ * @author WANGWEI
+ * @date 2018年9月4日
+ * @Copyright (c) 2018-? http://qmth.com.cn All Rights Reserved.
+ */
+public interface FaceService {
+
+	/**
+	 * 方法注释
+	 *
+	 * @author WANGWEI
+	 * @param rootOrgId
+	 * @param fileName
+	 * @param file
+	 * @param operator
+	 */
+	void processFace(Long rootOrgId, String fileName, File file, String operator);
+
+}

+ 0 - 218
examcloud-exchange-outer-service/src/main/java/cn/com/qmth/examcloud/exchange/outer/service/FaceppService.java

@@ -1,218 +0,0 @@
-package cn.com.qmth.examcloud.exchange.outer.service;
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.InputStreamReader;
-import java.net.URI;
-
-import org.apache.http.HttpEntity;
-import org.apache.http.StatusLine;
-import org.apache.http.client.methods.CloseableHttpResponse;
-import org.apache.http.client.methods.HttpPost;
-import org.apache.http.client.utils.URIBuilder;
-import org.apache.http.impl.client.CloseableHttpClient;
-import org.apache.http.impl.client.HttpClients;
-import org.apache.http.util.EntityUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.annotation.Value;
-import org.springframework.stereotype.Service;
-
-import com.google.gson.Gson;
-import com.google.gson.GsonBuilder;
-
-import cn.com.qmth.examcloud.commons.base.exception.StatusException;
-import cn.com.qmth.examcloud.commons.base.util.HttpClientUtil;
-import cn.com.qmth.examcloud.commons.web.security.bean.User;
-import cn.com.qmth.examcloud.core.basic.api.StudentCloudService;
-import cn.com.qmth.examcloud.core.basic.api.StudentFaceCloudService;
-import cn.com.qmth.examcloud.core.basic.api.bean.StudentBean;
-import cn.com.qmth.examcloud.core.basic.api.request.GetStudentReq;
-import cn.com.qmth.examcloud.core.basic.api.request.SaveStudentFaceInfoReq;
-import cn.com.qmth.examcloud.core.basic.api.response.GetStudentResp;
-import cn.com.qmth.examcloud.exchange.dao.bean.FaceDetectResponse;
-import cn.com.qmth.examcloud.exchange.outer.service.client.ExamStudentClient;
-import cn.com.qmth.examcloud.exchange.outer.service.client.StudentFaceInfoClient;
-import cn.com.qmth.examcloud.exchange.outer.service.impl.UpyunServiceImpl;
-
-/**
- * Created by yuanpan on 2017/5/15.
- */
-@Service
-public class FaceppService {
-	private static final Logger LOG = LoggerFactory.getLogger(FaceppService.class);
-
-	@Value("${app.facepp.api_key}")
-	private String apiKey;
-
-	@Value("${app.facepp.api_secret}")
-	private String apiSecret;
-
-	@Autowired
-	ExamStudentClient examStudentClient;
-
-	@Autowired
-	UpyunServiceImpl upyunService;
-
-	@Autowired
-	StudentFaceInfoClient studentFaceInfoClient;
-
-	@Autowired
-	StudentCloudService studentCloudService;
-
-	@Autowired
-	StudentFaceCloudService studentFaceCloudService;
-
-	/**
-	 * 重构<br>
-	 * 调用人脸识别接口
-	 *
-	 * @author WANGWEI
-	 * @param imageUrl
-	 * @return
-	 */
-	public String detectSingleFace(String imageUrl) {
-		// 重新检测次数为3次
-		int time = 3;
-		String faceToken = null;
-		while (true) {
-			if (time < 1) {
-				throw new StatusException("EX-111010", "人脸检测失败");
-			}
-
-			CloseableHttpClient httpClient = HttpClients.createDefault();
-			CloseableHttpResponse httpResponse = null;
-			try {
-				URI uri = new URIBuilder().setScheme("https").setHost("api-cn.faceplusplus.com")
-						.setPath("/facepp/v3/detect").setParameter("api_key", apiKey)
-						.setParameter("api_secret", apiSecret).setParameter("image_url", imageUrl)
-						.build();
-				HttpPost httpPost = new HttpPost(uri);
-
-				httpResponse = httpClient.execute(httpPost);
-				HttpEntity responseEntity = httpResponse.getEntity();
-				int statusCode = httpResponse.getStatusLine().getStatusCode();
-				BufferedReader reader = new BufferedReader(
-						new InputStreamReader(responseEntity.getContent()));
-				if (statusCode == 200) {
-					Gson gson = new GsonBuilder().create();
-					FaceDetectResponse faceDetectResponse = gson.fromJson(reader,
-							FaceDetectResponse.class);
-					if (faceDetectResponse.getFaces() != null
-							&& faceDetectResponse.getFaces().size() > 0) {
-						faceToken = faceDetectResponse.getFaces().get(0).getFace_token();
-						break;
-					} else {
-						time--;
-					}
-				} else {
-					StringBuffer buffer = new StringBuffer();
-					String str = null;
-					while (null != (str = reader.readLine())) {
-						buffer.append(str);
-					}
-					String result = buffer.toString();
-					LOG.error("获取token失败:" + result);
-					time--;
-				}
-				httpClient.close();
-			} catch (Exception e) {
-				time--;
-				LOG.error("人脸检测失败", e);
-			} finally {
-				HttpClientUtil.close(httpResponse);
-			}
-		}
-
-		return faceToken;
-	}
-
-	/**
-	 * 添加faceToken至faceSet
-	 *
-	 * @author WANGWEI
-	 * @param faceToken
-	 * @param facesetToken
-	 */
-	public void addFaceToken2FaceTokenSet(String faceToken, String facesetToken) {
-
-		// 重新检测次数为3次
-		int time = 3;
-		while (time > 0) {
-			// 调用人脸识别接口
-			CloseableHttpClient httpClient = HttpClients.createDefault();
-			CloseableHttpResponse httpResponse = null;
-			try {
-				URI uri = new URIBuilder().setScheme("https").setHost("api-cn.faceplusplus.com")
-						.setPath("/facepp/v3/faceset/addface").setParameter("api_key", apiKey)
-						.setParameter("api_secret", apiSecret)
-						.setParameter("faceset_token", facesetToken)
-						.setParameter("face_tokens", faceToken).build();
-
-				HttpPost httpPost = new HttpPost(uri);
-				httpResponse = httpClient.execute(httpPost);
-				StatusLine statusLine = httpResponse.getStatusLine();
-				LOG.info("response: " + EntityUtils.toString(httpResponse.getEntity()));
-				if (statusLine.getStatusCode() == 200) {
-					break;
-				} else {
-					time--;
-				}
-			} catch (Exception e) {
-				LOG.error("添加faceToken至faceSet失败", e);
-				time--;
-			} finally {
-				HttpClientUtil.close(httpResponse);
-			}
-		}
-	}
-
-	/**
-	 * 重构
-	 *
-	 * @author WANGWEI
-	 * @param accessUser
-	 * @param fileName
-	 * @param file
-	 * @throws Exception
-	 */
-	public void uploadPhoto(User accessUser, String fileName, File file) throws Exception {
-		Long rootOrgId = accessUser.getRootOrgId();
-		String userToken = accessUser.getUserToken();
-		if (!(fileName.endsWith(".jpg") || fileName.endsWith(".png")
-				|| fileName.endsWith(".gif"))) {
-			throw new StatusException("EX-101001", "文件格式错误");
-		}
-
-		String identityNumber = fileName.substring(0, fileName.lastIndexOf("."));
-
-		GetStudentReq req = new GetStudentReq();
-		req.setIdentityNumber(identityNumber);
-		req.setRootOrgId(accessUser.getRootOrgId());
-		GetStudentResp resp = studentCloudService.getStudent(req);
-		StudentBean student = resp.getStudentInfo();
-
-		String fileSuffix = fileName.substring(fileName.lastIndexOf("."));
-		String newFileName = System.currentTimeMillis() + fileSuffix;
-		String photoPath = upyunService.saveStudentPhoto(identityNumber, rootOrgId, newFileName,
-				file);
-
-		String url = upyunService.getStudentPhotoUrl(identityNumber, rootOrgId, newFileName);
-		// 调用人脸识别接口
-		String faceToken = detectSingleFace(url);
-
-		String facesetToken = studentFaceInfoClient.getFaceSet(userToken);
-
-		addFaceToken2FaceTokenSet(faceToken, facesetToken);
-
-		SaveStudentFaceInfoReq saveStudentFaceInfoReq = new SaveStudentFaceInfoReq();
-		saveStudentFaceInfoReq.setStudentId(student.getId());
-		saveStudentFaceInfoReq.setPhotoPath(photoPath);
-		saveStudentFaceInfoReq.setFaceToken(faceToken);
-		saveStudentFaceInfoReq.setFaceSetToken(facesetToken);
-
-		studentFaceCloudService.saveStudentFaceInfo(saveStudentFaceInfoReq);
-	}
-
-}

+ 1 - 23
examcloud-exchange-outer-service/src/main/java/cn/com/qmth/examcloud/exchange/outer/service/UpyunService.java

@@ -11,28 +11,6 @@ import java.io.File;
  */
 public interface UpyunService {
 
-	/**
-	 * 新方案
-	 *
-	 * @author WANGWEI
-	 * @param identityNumber
-	 * @param rootOrgId
-	 * @param fileName
-	 * @param file
-	 * @return
-	 */
-	String saveStudentPhoto(String identityNumber, Long rootOrgId, String fileName, File file);
-
-	/**
-	 * 新方案
-	 *
-	 * @author WANGWEI
-	 * @param identityNumber
-	 * @param rootOrgId
-	 * @param fileName
-	 * @param bytes
-	 * @return
-	 */
-	String saveStudentPhoto(String identityNumber, Long rootOrgId, String fileName, byte[] bytes);
+	public String writeFile(Long rootOrgId, String identityNumber, String fileName, File file);
 
 }

+ 46 - 0
examcloud-exchange-outer-service/src/main/java/cn/com/qmth/examcloud/exchange/outer/service/bean/Course.java

@@ -0,0 +1,46 @@
+package cn.com.qmth.examcloud.exchange.outer.service.bean;
+
+import cn.com.qmth.examcloud.commons.web.cloud.api.JsonSerializable;
+
+/**
+ * 类注释
+ *
+ * @author WANGWEI
+ * @date 2018年9月4日
+ * @Copyright (c) 2018-? http://qmth.com.cn All Rights Reserved.
+ */
+public class Course implements JsonSerializable {
+
+	private static final long serialVersionUID = 2064501395377152957L;
+
+	private String code;
+
+	private String name;
+
+	private String level;
+
+	public String getCode() {
+		return code;
+	}
+
+	public void setCode(String code) {
+		this.code = code;
+	}
+
+	public String getName() {
+		return name;
+	}
+
+	public void setName(String name) {
+		this.name = name;
+	}
+
+	public String getLevel() {
+		return level;
+	}
+
+	public void setLevel(String level) {
+		this.level = level;
+	}
+
+}

+ 38 - 0
examcloud-exchange-outer-service/src/main/java/cn/com/qmth/examcloud/exchange/outer/service/bean/CourseGroup.java

@@ -0,0 +1,38 @@
+package cn.com.qmth.examcloud.exchange.outer.service.bean;
+
+import java.util.List;
+
+import cn.com.qmth.examcloud.commons.web.cloud.api.JsonSerializable;
+
+/**
+ * 类注释
+ *
+ * @author WANGWEI
+ * @date 2018年9月4日
+ * @Copyright (c) 2018-? http://qmth.com.cn All Rights Reserved.
+ */
+public class CourseGroup implements JsonSerializable {
+
+	private static final long serialVersionUID = -8448175294365570731L;
+
+	private String name;
+
+	private List<Course> courseList;
+
+	public String getName() {
+		return name;
+	}
+
+	public void setName(String name) {
+		this.name = name;
+	}
+
+	public List<Course> getCourseList() {
+		return courseList;
+	}
+
+	public void setCourseList(List<Course> courseList) {
+		this.courseList = courseList;
+	}
+
+}

+ 0 - 25
examcloud-exchange-outer-service/src/main/java/cn/com/qmth/examcloud/exchange/outer/service/client/CourseClient.java

@@ -1,25 +0,0 @@
-package cn.com.qmth.examcloud.exchange.outer.service.client;
-
-import org.springframework.cloud.netflix.feign.FeignClient;
-import org.springframework.http.ResponseEntity;
-import org.springframework.web.bind.annotation.RequestBody;
-import org.springframework.web.bind.annotation.RequestHeader;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RequestMethod;
-import org.springframework.web.bind.annotation.RequestParam;
-
-import cn.com.qmth.examcloud.exchange.dao.bean.OutletCourse;
-
-
-/**
- * Created by yuanpan on 2017/4/25.
- */
-@FeignClient(value = "ExamCloud-service-core")
-public interface CourseClient {
-
-    @RequestMapping(method = RequestMethod.GET, value = "${$rmp.ctr.basic}/course")
-    ResponseEntity<OutletCourse> getCourseByCode(@RequestHeader("user_token") String token, @RequestParam(value = "orgId") Long orgId, @RequestParam(value = "code") String code);
-
-    @RequestMapping(method = RequestMethod.POST, value = "${$rmp.ctr.basic}/course")
-    ResponseEntity<OutletCourse> save(@RequestHeader("user_token") String token, @RequestBody OutletCourse course);
-}

+ 0 - 28
examcloud-exchange-outer-service/src/main/java/cn/com/qmth/examcloud/exchange/outer/service/client/ExamClient.java

@@ -1,28 +0,0 @@
-package cn.com.qmth.examcloud.exchange.outer.service.client;
-
-import org.springframework.cloud.netflix.feign.FeignClient;
-import org.springframework.http.ResponseEntity;
-import org.springframework.web.bind.annotation.*;
-
-import cn.com.qmth.examcloud.exchange.dao.bean.OutletExam;
-
-import java.util.List;
-
-/**
- * Created by yuanpan on 2017/4/25.
- */
-@FeignClient(value = "ExamCloud-service-exam-work")
-public interface ExamClient {
-
-    @RequestMapping(method = RequestMethod.POST, value = "${$rmp.ctr.examwork}/exam")
-    ResponseEntity<OutletExam> save(@RequestHeader("user_token") String token, @RequestBody OutletExam exam);
-
-    @RequestMapping(method = RequestMethod.GET, value = "${$rmp.ctr.examwork}/exam/{id}")
-    ResponseEntity<OutletExam> getOne(@RequestHeader("user_token") String token, @PathVariable(value = "id") Long id);
-
-    @RequestMapping(method = RequestMethod.GET, value = "${$rmp.ctr.examwork}/exam/all")
-    ResponseEntity<List<OutletExam>> queryByRemark(@RequestHeader("user_token") String token, @RequestParam(value = "remark") String remark);
-    
-    @RequestMapping(method = RequestMethod.GET, value = "${$rmp.ctr.examwork}/exam/name")
-    ResponseEntity<List<OutletExam>> queryByName(@RequestHeader("user_token") String token, @RequestParam(value = "name") String name);
-}

+ 0 - 33
examcloud-exchange-outer-service/src/main/java/cn/com/qmth/examcloud/exchange/outer/service/client/ExamStudentClient.java

@@ -1,33 +0,0 @@
-package cn.com.qmth.examcloud.exchange.outer.service.client;
-
-import org.springframework.cloud.netflix.feign.FeignClient;
-import org.springframework.http.ResponseEntity;
-import org.springframework.web.bind.annotation.RequestBody;
-import org.springframework.web.bind.annotation.RequestHeader;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RequestMethod;
-import org.springframework.web.bind.annotation.RequestParam;
-
-import cn.com.qmth.examcloud.exchange.dao.bean.OutletExamStudent;
-
-import java.util.List;
-
-/**
- * Created by yuanpan on 2017/4/25.
- */
-@FeignClient(value = "ExamCloud-service-exam-work")
-public interface ExamStudentClient {
-
-    @RequestMapping(method = RequestMethod.POST, value = "${$rmp.ctr.examwork}/exam_student")
-    ResponseEntity<OutletExamStudent> save(@RequestHeader("user_token") String token, @RequestBody OutletExamStudent examStudent);
-
-
-    @RequestMapping(method = RequestMethod.PUT, value = "${$rmp.ctr.examwork}/exam_student")
-    ResponseEntity<OutletExamStudent> updateExamStudent(@RequestHeader("user_token") String token, @RequestBody OutletExamStudent examStudent);
-
-    @RequestMapping(method = RequestMethod.GET, value = "${$rmp.ctr.examwork}/exam_student/all")
-    String getExamStudentByIdentityNumber(@RequestHeader("user_token") String token, @RequestParam("identityNumber") String identityNumber);
-
-    @RequestMapping(method = RequestMethod.GET, value = "${$rmp.ctr.examwork}/exam_student/all")
-    ResponseEntity<List<OutletExamStudent>> queryExamStudent(@RequestHeader("user_token") String token, @RequestParam("identityNumber") String identityNumber, @RequestParam("examId") Long examId, @RequestParam("courseCode") String courseCode);
-}

+ 0 - 19
examcloud-exchange-outer-service/src/main/java/cn/com/qmth/examcloud/exchange/outer/service/client/OrgClient.java

@@ -1,19 +0,0 @@
-package cn.com.qmth.examcloud.exchange.outer.service.client;
-
-import org.springframework.cloud.netflix.feign.FeignClient;
-import org.springframework.http.ResponseEntity;
-import org.springframework.web.bind.annotation.*;
-
-import cn.com.qmth.examcloud.exchange.dao.bean.OutletOrg;
-
-
-@FeignClient(value = "ExamCloud-service-core")
-public interface OrgClient {
-
-    @RequestMapping(method = RequestMethod.GET, value = "${$rmp.ctr.basic}/org")
-    ResponseEntity<OutletOrg> findByParentIdAndCode(@RequestHeader("user_token") String token, @RequestParam("parentId") Long parentId, @RequestParam("code") String code);
-
-    @RequestMapping(method = RequestMethod.POST, value = "${$rmp.ctr.basic}/org")
-    ResponseEntity<OutletOrg> save(@RequestHeader("user_token") String token, @RequestBody OutletOrg org);
-
-}

+ 0 - 25
examcloud-exchange-outer-service/src/main/java/cn/com/qmth/examcloud/exchange/outer/service/client/StudentClient.java

@@ -1,25 +0,0 @@
-package cn.com.qmth.examcloud.exchange.outer.service.client;
-
-import org.springframework.cloud.netflix.feign.FeignClient;
-import org.springframework.http.ResponseEntity;
-import org.springframework.web.bind.annotation.*;
-
-import cn.com.qmth.examcloud.exchange.dao.bean.OutletStudent;
-
-import java.util.List;
-
-/**
- * Created by yuanpan on 2017/4/25.
- */
-@FeignClient(value = "ExamCloud-service-core")
-public interface StudentClient {
-
-    @RequestMapping(method = RequestMethod.POST, value = "${$rmp.ctr.basic}/student")
-    ResponseEntity<OutletStudent> save(@RequestHeader("user_token") String token, @RequestBody OutletStudent student);
-
-    @RequestMapping(method = RequestMethod.GET, value = "${$rmp.ctr.basic}/student")
-    ResponseEntity<List<OutletStudent>> getStudentByIdentityNumber(@RequestHeader("user_token") String token, @RequestParam("identityNumber") String identityNumber);
-
-    @RequestMapping(method = RequestMethod.PUT, value = "${$rmp.ctr.basic}/student")
-    ResponseEntity<OutletStudent> updateStudent(@RequestHeader("user_token") String token, @RequestBody OutletStudent student);
-}

+ 0 - 34
examcloud-exchange-outer-service/src/main/java/cn/com/qmth/examcloud/exchange/outer/service/client/StudentFaceInfoClient.java

@@ -1,34 +0,0 @@
-package cn.com.qmth.examcloud.exchange.outer.service.client;
-
-import org.springframework.cloud.netflix.feign.FeignClient;
-import org.springframework.http.ResponseEntity;
-import org.springframework.web.bind.annotation.RequestBody;
-import org.springframework.web.bind.annotation.RequestHeader;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RequestMethod;
-import org.springframework.web.bind.annotation.RequestParam;
-
-import cn.com.qmth.examcloud.common.dto.core.StudentFaceInfo;
-
-/**
- * Created by yuanpan on 2017/5/14.
- */
-@FeignClient(value = "ExamCloud-service-core")
-public interface StudentFaceInfoClient {
-	@RequestMapping(method = RequestMethod.POST, value = "${$rmp.ctr.basic}/studentFaceInfo")
-	ResponseEntity<StudentFaceInfo> save(@RequestHeader("user_token") String token,
-			@RequestBody StudentFaceInfo studentFaceInfo);
-
-	@RequestMapping(method = RequestMethod.GET, value = "${$rmp.ctr.basic}/studentFaceInfo/identityNumber")
-	ResponseEntity<StudentFaceInfo> getByIdentityNumber(@RequestHeader("user_token") String token,
-			@RequestParam("identityNumber") String identityNumber,
-			@RequestParam("orgId") Long orgId);
-
-	/**
-	 * 获取faceSetToken(人脸集合)
-	 * 
-	 * @return
-	 */
-	@RequestMapping(method = RequestMethod.GET, value = "${$rmp.ctr.basic}/faceSet/enableFaceSet")
-	String getFaceSet(@RequestHeader("user_token") String token);
-}

+ 58 - 0
examcloud-exchange-outer-service/src/main/java/cn/com/qmth/examcloud/exchange/outer/service/impl/CourseGroupServiceImpl.java

@@ -0,0 +1,58 @@
+package cn.com.qmth.examcloud.exchange.outer.service.impl;
+
+import java.io.File;
+import java.util.List;
+
+import org.springframework.stereotype.Service;
+
+import com.thoughtworks.xstream.XStream;
+
+import cn.com.qmth.examcloud.commons.base.exception.StatusException;
+import cn.com.qmth.examcloud.commons.base.helpers.XStreamBuilder;
+import cn.com.qmth.examcloud.commons.base.util.PathUtil;
+import cn.com.qmth.examcloud.exchange.outer.service.CourseGroupService;
+import cn.com.qmth.examcloud.exchange.outer.service.bean.Course;
+import cn.com.qmth.examcloud.exchange.outer.service.bean.CourseGroup;
+
+/**
+ * 类注释
+ *
+ * @author WANGWEI
+ * @date 2018年9月4日
+ * @Copyright (c) 2018-? http://qmth.com.cn All Rights Reserved.
+ */
+@Service
+public class CourseGroupServiceImpl implements CourseGroupService {
+
+	@Override
+	public List<Course> getCourseList(Long rootOrgId, String courseGroupName) {
+
+		String resoucePath = PathUtil
+				.getResoucePath("course-group/course-group-" + rootOrgId + ".xml");
+		File file = new File(resoucePath);
+
+		XStream xStream = XStreamBuilder.newInstance().build();
+		xStream.allowTypes(new Class[]{CourseGroup.class, Course.class, List.class});
+		xStream.alias("groups", List.class);
+		xStream.alias("group", CourseGroup.class);
+		xStream.alias("course", Course.class);
+
+		List<CourseGroup> list = null;
+		try {
+			@SuppressWarnings("unchecked")
+			List<CourseGroup> obj = (List<CourseGroup>) xStream.fromXML(file);
+			list = obj;
+		} catch (Exception e) {
+			throw new StatusException("EX-620001", "配置文件错误");
+		}
+
+		for (CourseGroup cur : list) {
+			if (courseGroupName.equals(cur.getName())) {
+				return cur.getCourseList();
+			}
+		}
+
+		throw new StatusException("EX-860001", "课程组未配置");
+	}
+
+}

+ 261 - 0
examcloud-exchange-outer-service/src/main/java/cn/com/qmth/examcloud/exchange/outer/service/impl/FaceServiceImpl.java

@@ -0,0 +1,261 @@
+package cn.com.qmth.examcloud.exchange.outer.service.impl;
+
+import java.io.File;
+import java.net.URI;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.commons.collections.CollectionUtils;
+import org.apache.commons.lang.math.RandomUtils;
+import org.apache.http.HttpEntity;
+import org.apache.http.HttpStatus;
+import org.apache.http.client.methods.CloseableHttpResponse;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.client.utils.URIBuilder;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClients;
+import org.apache.http.util.EntityUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Service;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.google.common.collect.Maps;
+
+import cn.com.qmth.examcloud.commons.base.exception.StatusException;
+import cn.com.qmth.examcloud.commons.base.logging.ExamCloudLog;
+import cn.com.qmth.examcloud.commons.base.logging.ExamCloudLogFactory;
+import cn.com.qmth.examcloud.commons.base.util.HttpClientUtil;
+import cn.com.qmth.examcloud.commons.base.util.JsonUtil;
+import cn.com.qmth.examcloud.core.basic.api.FaceCloudService;
+import cn.com.qmth.examcloud.core.basic.api.StudentCloudService;
+import cn.com.qmth.examcloud.core.basic.api.bean.FacesetBean;
+import cn.com.qmth.examcloud.core.basic.api.bean.StudentBean;
+import cn.com.qmth.examcloud.core.basic.api.request.GetStudentReq;
+import cn.com.qmth.examcloud.core.basic.api.request.GetUsableFacesetListReq;
+import cn.com.qmth.examcloud.core.basic.api.request.SaveStudentFaceReq;
+import cn.com.qmth.examcloud.core.basic.api.response.GetStudentResp;
+import cn.com.qmth.examcloud.core.basic.api.response.GetUsableFacesetListResp;
+import cn.com.qmth.examcloud.exchange.outer.service.FaceService;
+import cn.com.qmth.examcloud.exchange.outer.service.UpyunService;
+
+/**
+ * 类注释
+ *
+ * @author WANGWEI
+ * @date 2018年9月4日
+ * @Copyright (c) 2018-? http://qmth.com.cn All Rights Reserved.
+ */
+@Service
+public class FaceServiceImpl implements FaceService {
+
+	protected ExamCloudLog log = ExamCloudLogFactory.getLog(this.getClass());
+
+	@Autowired
+	StudentCloudService studentCloudService;
+
+	@Autowired
+	UpyunService upyunService;
+
+	@Autowired
+	FaceCloudService faceCloudService;
+
+	@Value("${$facepp.apiKey}")
+	private String apiKey;
+
+	@Value("${$facepp.apiSecret}")
+	private String apiSecret;
+
+	@Override
+	public void processFace(Long rootOrgId, String fileName, File file, String operator) {
+
+		String identityNumber = fileName.substring(0, fileName.lastIndexOf("."));
+		String fileSuffix = fileName.substring(fileName.lastIndexOf("."));
+		String randomFileName = System.currentTimeMillis() + fileSuffix;
+
+		GetStudentReq req = new GetStudentReq();
+		req.setIdentityNumber(identityNumber);
+		req.setRootOrgId(rootOrgId);
+		GetStudentResp resp = studentCloudService.getStudent(req);
+		StudentBean student = resp.getStudentInfo();
+
+		String photoUrl = upyunService.writeFile(rootOrgId, identityNumber, randomFileName, file);
+
+		String faceToken = detect(photoUrl);
+
+		Map<String, Object> map = addFaceToken2Faceset(rootOrgId, faceToken);
+
+		String facesetToken = (String) map.get("facesetToken");
+		Long faceCount = (Long) map.get("faceCount");
+
+		SaveStudentFaceReq request = new SaveStudentFaceReq();
+		request.setFacesetToken(facesetToken);
+		request.setFaceToken(faceToken);
+		request.setOperator(operator);
+		request.setPhotoName(randomFileName);
+		request.setRootOrgId(rootOrgId);
+		request.setStudentId(student.getId());
+		request.setFaceCount(faceCount);
+
+		faceCloudService.saveStudentFace(request);
+
+	}
+
+	/**
+	 * 方法注释
+	 *
+	 * @author WANGWEI
+	 * @param rootOrgId
+	 * @param faceToken
+	 * @return
+	 */
+	private Map<String, Object> addFaceToken2Faceset(Long rootOrgId, String faceToken) {
+
+		Map<String, Object> info = Maps.newHashMap();
+		info.put("rootOrgId", rootOrgId);
+		info.put("faceToken", faceToken);
+		int times = 0;
+		while (true) {
+			String facesetToken = getFacesetToken(rootOrgId);
+			info.put("facesetToken", facesetToken);
+
+			if (times > 5) {
+				log.error("添加faceToken至faceSet失败. info=" + JsonUtil.toJson(info));
+				return null;
+			}
+
+			CloseableHttpClient httpClient = HttpClients.createDefault();
+			CloseableHttpResponse httpResponse = null;
+			try {
+				URI uri = new URIBuilder().setScheme("https").setHost("api-cn.faceplusplus.com")
+						.setPath("/facepp/v3/faceset/addface").setParameter("api_key", apiKey)
+						.setParameter("api_secret", apiSecret)
+						.setParameter("faceset_token", facesetToken)
+						.setParameter("face_tokens", faceToken).build();
+
+				HttpPost httpPost = new HttpPost(uri);
+
+				httpResponse = httpClient.execute(httpPost);
+				HttpEntity entity = httpResponse.getEntity();
+				int statusCode = httpResponse.getStatusLine().getStatusCode();
+				String respBody = EntityUtils.toString(entity, "UTF-8");
+				log.info("responseBody=" + respBody);
+
+				if (respBody.contains("QUOTA_EXCEEDED")) {
+					throw new StatusException("EX-620006", "faceset is full");
+				}
+
+				if (statusCode == HttpStatus.SC_OK) {
+					JSONObject jsonObject = JSON.parseObject(respBody);
+					int faceAdded = jsonObject.getInteger("face_added");
+					int faceCount = jsonObject.getInteger("face_count");
+					if (1 == faceAdded) {
+						Map<String, Object> ret = Maps.newHashMap();
+						ret.put("facesetToken", facesetToken);
+						ret.put("faceCount", (long) faceCount);
+						return ret;
+					}
+				} else if (statusCode == HttpStatus.SC_FORBIDDEN) {
+					if (respBody.contains("CONCURRENCY_LIMIT_EXCEEDED")) {
+						continue;
+					}
+				}
+
+				times++;
+				continue;
+			} catch (Exception e) {
+				log.error("调用addface接口异常. info=" + JsonUtil.toJson(info), e);
+				times++;
+				continue;
+			} finally {
+				HttpClientUtil.close(httpResponse);
+			}
+		}
+
+	}
+
+	/**
+	 * 方法注释
+	 *
+	 * @author WANGWEI
+	 * @param rootOrgId
+	 * @return
+	 */
+	private String getFacesetToken(Long rootOrgId) {
+
+		GetUsableFacesetListReq req = new GetUsableFacesetListReq();
+		req.setRootOrgId(rootOrgId);
+		GetUsableFacesetListResp resp = faceCloudService.getUsableFacesetList(req);
+		List<FacesetBean> facesetBeanList = resp.getFacesetBeanList();
+
+		if (CollectionUtils.isEmpty(facesetBeanList)) {
+			throw new StatusException("B-630001", "无可用的faceset");
+		}
+
+		FacesetBean facesetBean = facesetBeanList
+				.get(RandomUtils.nextInt(facesetBeanList.size() - 1));
+		return facesetBean.getFacesetToken();
+	}
+
+	/**
+	 * 方法注释
+	 *
+	 * @author WANGWEI
+	 * @param photoUrl
+	 * @return
+	 */
+	private String detect(String photoUrl) {
+		int times = 0;
+		String faceToken = null;
+		while (true) {
+			if (times > 5) {
+				throw new StatusException("EX-620005", "人脸检测失败");
+			}
+			CloseableHttpClient httpClient = HttpClients.createDefault();
+			CloseableHttpResponse httpResponse = null;
+			try {
+				URI uri = new URIBuilder().setScheme("https").setHost("api-cn.faceplusplus.com")
+						.setPath("/facepp/v3/detect").setParameter("api_key", apiKey)
+						.setParameter("api_secret", apiSecret).setParameter("image_url", photoUrl)
+						.build();
+
+				HttpPost httpPost = new HttpPost(uri);
+
+				httpResponse = httpClient.execute(httpPost);
+				HttpEntity entity = httpResponse.getEntity();
+				int statusCode = httpResponse.getStatusLine().getStatusCode();
+				String respBody = EntityUtils.toString(entity, "UTF-8");
+				log.info("responseBody=" + respBody);
+
+				if (statusCode == HttpStatus.SC_OK) {
+					JSONObject jsonObject = JSON.parseObject(respBody);
+					JSONArray faces = jsonObject.getJSONArray("faces");
+					if (1 != faces.size()) {
+						throw new StatusException("EX-620009", "检测到多张人脸. photoUrl=" + photoUrl);
+					}
+
+					JSONObject face = faces.getJSONObject(0);
+					faceToken = face.getString("face_token");
+					return faceToken;
+				} else if (statusCode == HttpStatus.SC_FORBIDDEN) {
+					if (respBody.contains("CONCURRENCY_LIMIT_EXCEEDED")) {
+						continue;
+					}
+				}
+
+				times++;
+				continue;
+			} catch (Exception e) {
+				log.error("调用detect接口异常. photoUrl=" + photoUrl, e);
+				times++;
+				continue;
+			} finally {
+				HttpClientUtil.close(httpResponse);
+			}
+		}
+
+	}
+
+}

+ 0 - 295
examcloud-exchange-outer-service/src/main/java/cn/com/qmth/examcloud/exchange/outer/service/impl/StudentInfoServiceImpl.java

@@ -1,295 +0,0 @@
-package cn.com.qmth.examcloud.exchange.outer.service.impl;
-
-import java.util.Date;
-import java.util.HashSet;
-import java.util.List;
-
-import org.apache.commons.lang3.StringUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.http.ResponseEntity;
-import org.springframework.stereotype.Service;
-
-import cn.com.qmth.examcloud.common.dto.core.User;
-import cn.com.qmth.examcloud.common.dto.core.enums.CourseLevel;
-import cn.com.qmth.examcloud.exchange.base.enums.OutletOrgType;
-import cn.com.qmth.examcloud.exchange.base.exception.NoSuchCourseLevelException;
-import cn.com.qmth.examcloud.exchange.base.exception.SaveExamStudentException;
-import cn.com.qmth.examcloud.exchange.dao.bean.OutletCourse;
-import cn.com.qmth.examcloud.exchange.dao.bean.OutletExam;
-import cn.com.qmth.examcloud.exchange.dao.bean.OutletExamStudent;
-import cn.com.qmth.examcloud.exchange.dao.bean.OutletOrg;
-import cn.com.qmth.examcloud.exchange.dao.bean.OutletStudent;
-import cn.com.qmth.examcloud.exchange.dao.bean.StudentInfoReq;
-import cn.com.qmth.examcloud.exchange.outer.service.StudentInfoService;
-import cn.com.qmth.examcloud.exchange.outer.service.client.CourseClient;
-import cn.com.qmth.examcloud.exchange.outer.service.client.ExamClient;
-import cn.com.qmth.examcloud.exchange.outer.service.client.ExamStudentClient;
-import cn.com.qmth.examcloud.exchange.outer.service.client.OrgClient;
-import cn.com.qmth.examcloud.exchange.outer.service.client.StudentClient;
-
-/**
- * @author  	chenken
- * @date    	2018年5月7日 下午4:33:27
- * @company 	QMTH
- * @description StudentInfoServiceImpl.java
- */
-@Service("studentInfoService")
-public class StudentInfoServiceImpl implements StudentInfoService {
-
-	private static final Logger log = LoggerFactory.getLogger(StudentInfoServiceImpl.class);
-	
-    @Autowired
-    private OrgClient orgClient;
-
-    @Autowired
-    private ExamClient examClient;
-
-    @Autowired
-    private CourseClient courseClient;
-
-    @Autowired
-    private StudentClient studentClient;
-
-    @Autowired
-    private ExamStudentClient examStudentClient;
-	
-	@Override
-	public void saveStudentInfo(List<StudentInfoReq> studentInfoReqs,String userToken,Long rootOrgId) throws Exception {
-		log.info("创建考试和导入学生开始");
-		OutletExam exam = chechExamStudentInfo(studentInfoReqs,rootOrgId,userToken);
-        for (StudentInfoReq studentInfoReq : studentInfoReqs) {
-        	OutletOrg org = saveOrg(studentInfoReq,userToken,rootOrgId);
-            
-        	OutletCourse course = saveCourse(studentInfoReq,userToken,rootOrgId);
-        	
-        	OutletStudent student = saveStudent(studentInfoReq,org,userToken,rootOrgId);
-        	
-        	saveExamStudent(studentInfoReq,student,course,org,exam,userToken,rootOrgId);
-        }
-        log.info("创建考试和导入学生完成");
-	}
-
-	/**
-     * 保存学习中心
-     * @param studentInfoReq
-     * @param userToken
-     * @param rootOrgId
-     * @return
-     */
-    private OutletOrg saveOrg(StudentInfoReq studentInfoReq,String userToken,Long rootOrgId){
-    	log.info("2.保存学习中心,学习中心code:"+studentInfoReq.getOrgCode());
-    	//判断学习中心是否存在,不存在则创建
-        String orgCode = studentInfoReq.getOrgCode();
-        //根据orgCode,查询学习中心
-        ResponseEntity<OutletOrg> orgResponseEntity = orgClient.findByParentIdAndCode(userToken, rootOrgId, orgCode);
-        OutletOrg org = orgResponseEntity.getBody();
-        if (org == null) {
-            org = new OutletOrg();
-            org.setName(studentInfoReq.getOrgName());
-            org.setCode(studentInfoReq.getOrgCode());
-            org.setParentId(rootOrgId);
-            org.setRootId(rootOrgId);
-            org.setEnable(true);
-            org.setType(OutletOrgType.SCHOOL);
-            ResponseEntity<OutletOrg> saveOrgResp = orgClient.save(userToken, org);
-            org = saveOrgResp.getBody();
-        }
-        return org;
-    }
-    
-    /**
-     * 保存课程
-     * @param studentInfoReq
-     * @param userToken
-     * @param rootOrgId
-     * @throws NoSuchCourseLevelException
-     */
-    private OutletCourse saveCourse(StudentInfoReq studentInfoReq,String userToken,Long rootOrgId) throws NoSuchCourseLevelException{
-    	//判断课程是否存在,不存在则新增
-    	String courseCode = studentInfoReq.getCourseCode();
-    	if(StringUtils.isNotBlank(studentInfoReq.getCourseLevel())){
-    		CourseLevel courseLevel = getCourseLevelByCName(studentInfoReq.getCourseLevel());
-    		if(courseLevel!=null){
-    			courseCode = courseLevel.getAbbreviate()+studentInfoReq.getCourseCode();
-    		}
-    	}
-    	
-        log.info("3.保存课程,课程code:"+courseCode);
-        studentInfoReq.setCourseCode(courseCode);
-        ResponseEntity<OutletCourse> getCourseResp = courseClient.getCourseByCode(userToken, rootOrgId, studentInfoReq.getCourseCode());
-        OutletCourse course = getCourseResp.getBody();
-        if (course == null) {
-            course = new OutletCourse();
-            course.setOrgId(rootOrgId);
-            course.setEnable(true);
-            course.setCode(studentInfoReq.getCourseCode());
-            course.setCreateTime(new Date());
-            if(StringUtils.isNotBlank(studentInfoReq.getCourseLevel())){
-            	course.setLevel(getCourseLevelByCName(studentInfoReq.getCourseLevel()));
-            }
-            course.setName(studentInfoReq.getCourseName());
-            ResponseEntity<OutletCourse> saveCourseResp = courseClient.save(userToken, course);
-            course = saveCourseResp.getBody();
-        }
-        return course;
-    }
-    
-    /**
-     * 保存学生信息
-     * @param studentInfoReq
-     * @param org
-     * @param userToken
-     * @param rootOrgId
-     * @return
-     */
-    private OutletStudent saveStudent(StudentInfoReq studentInfoReq,OutletOrg org,String userToken,Long rootOrgId) {
-    	//保存学生信息,在保存学生信息的接口中会自动保存用户信息,所以不需要单独调用UserApi去保存用户信息
-    	log.info("4.保存学生信息,学生身份证号:"+studentInfoReq.getIdentityNumber());
-    	OutletStudent student = new OutletStudent();
-        student.setIdentityNumber(studentInfoReq.getIdentityNumber());
-        student.setName(studentInfoReq.getStudentName());
-        student.setStudentCode(studentInfoReq.getStudentCode());
-        User user = new User();
-        user.setOrgId(org.getId());
-        user.setRootOrgId(rootOrgId);
-        user.setEnable(true);
-        student.setUser(user);
-        //查询学生信息是否存在
-        List<OutletStudent> studentList = studentClient.getStudentByIdentityNumber(userToken, studentInfoReq.getIdentityNumber()).getBody();
-        if (studentList == null || studentList.size() < 1) {
-        	student.setCreateTime(new Date());
-            ResponseEntity<OutletStudent> saveStudentResp = studentClient.save(userToken, student);
-            student = saveStudentResp.getBody();
-        } else {
-        	OutletStudent stu = studentList.get(0);
-            student.setOrgId(org.getId());
-            student.setRootOrgId(rootOrgId);
-            student.setId(stu.getId());
-            student.setUser(stu.getUser());
-            ResponseEntity<OutletStudent> updateStudentResp = studentClient.updateStudent(userToken,student);
-            student = updateStudentResp.getBody();
-        }
-        return student;
-	}
-    
-    /**
-     * 保存考生信息
-     * @param studentInfoReq
-     * @param student
-     * @param org
-     * @param exam
-     * @param userToken
-     * @param rootOrgId
-     * @throws NoSuchCourseLevelException
-     * @throws SaveExamStudentException
-     */
-	private void saveExamStudent(StudentInfoReq studentInfoReq,OutletStudent student,OutletCourse course,OutletOrg org,OutletExam exam,String userToken,Long rootOrgId) throws NoSuchCourseLevelException, SaveExamStudentException {
-		log.info("5.保存考生信息,考试ID:"+exam.getId()
-							  +"课程code:"+studentInfoReq.getCourseCode()
-							  +",考生身份证号:"+studentInfoReq.getIdentityNumber());
-		//判断考生信息是否存在
-        ResponseEntity<List<OutletExamStudent>> examStudentListResp = examStudentClient.queryExamStudent(userToken, studentInfoReq.getIdentityNumber(), exam.getId(), studentInfoReq.getCourseCode());
-        if (examStudentListResp != null && examStudentListResp.getBody() != null && examStudentListResp.getBody().size() > 0) {
-        	//学生该门课程考试已经存在
-        	List<OutletExamStudent> examStudents = examStudentListResp.getBody();
-        	OutletExamStudent examStudentOld = examStudents.get(0);
-        	//更新相关的姓名、学习中心、专业
-        	examStudentOld.setName(student.getName());
-        	examStudentOld.setOrgId(org.getId());
-        	examStudentOld.setOrgCode(org.getCode());
-        	examStudentOld.setOrgName(org.getName());
-        	examStudentOld.setRootOrgId(rootOrgId);
-        	examStudentOld.setSpecialtyName(studentInfoReq.getSpecialtyName());
-        	 try {
-                 examStudentClient.save(userToken, examStudentOld);
-             } catch (Exception e) {
-                 throw new SaveExamStudentException("保存考生失败");
-             }
-        } else {
-        	//考生不存在
-        	OutletExamStudent examStudent =  initExamStudent(studentInfoReq,student,org,exam,course,rootOrgId);
-            try {
-                examStudentClient.save(userToken, examStudent);
-            } catch (Exception e) {
-                throw new SaveExamStudentException("保存考生失败");
-            }
-        }
-	}
-    
-    private OutletExamStudent initExamStudent(StudentInfoReq studentInfoReq,OutletStudent student, OutletOrg org, OutletExam exam,OutletCourse course,Long rootOrgId){
-    	OutletExamStudent examStudent = new OutletExamStudent();
-    	examStudent.setName(studentInfoReq.getStudentName());
-    	examStudent.setStudentCode(studentInfoReq.getStudentCode());
-    	examStudent.setIdentityNumber(studentInfoReq.getIdentityNumber());
-    	examStudent.setSpecialtyName(studentInfoReq.getSpecialtyName());
-    	examStudent.setPaperType(studentInfoReq.getPaperType());
-    	examStudent.setInfoCollector(studentInfoReq.getInfoCollector());
-    	examStudent.setRemark(studentInfoReq.getRemark());
-    	examStudent.setGrade(studentInfoReq.getGrade());
-    	examStudent.setGraduated(studentInfoReq.getGraduated());
-    	
-    	examStudent.setStudentId(student.getId());
-    	
-    	examStudent.setOrgId(org.getId());
-    	examStudent.setOrgCode(org.getCode());
-    	examStudent.setOrgName(org.getName());
-    	examStudent.setRootOrgId(rootOrgId);
-    	examStudent.setExam(exam);
-    	
-    	examStudent.setCourseCode(course.getCode());
-    	examStudent.setCourseName(course.getName());
-    	if(StringUtils.isNotBlank(studentInfoReq.getCourseLevel())){
-    		examStudent.setCourseLevel(getCourseLevelByCName(studentInfoReq.getCourseLevel())+"");
-    	}
-    	examStudent.setFinished(false);
-		return examStudent;
-	}
-
-    private CourseLevel getCourseLevelByCName(String cname){
-    	if(StringUtils.isBlank(cname)){
-    		return null;
-    	}
-        for(CourseLevel level:CourseLevel.values()){
-        	if(cname.equals(level.getName())){
-        		return level;
-        	}
-        }
-        return null;
-    }
-
-	/**
-	 * 检查数据
-	 * @param examStudentReqList
-	 */
-	private OutletExam chechExamStudentInfo(List<StudentInfoReq> examStudentReqList, Long rootOrgId,String userToken){
-		if(examStudentReqList==null||examStudentReqList.size()==0){
-			throw new SaveExamStudentException("集合不能为空");
-		}
-		if(examStudentReqList.size()>1000){
-			throw new SaveExamStudentException("单次推送集合长度不能大于1000");
-		}
-		HashSet<String> examNameSet = new HashSet<String>();
-		for(StudentInfoReq examStudentAllInfoReq:examStudentReqList){
-			examNameSet.add(examStudentAllInfoReq.getExamName());
-		}
-		if(examNameSet.size()>1){
-			throw new SaveExamStudentException("集合中不允许存在多个考试");
-		}
-		String examName = examStudentReqList.get(0).getExamName();
-		ResponseEntity<List<OutletExam>> examListResp = examClient.queryByName(userToken, examName);
-		
-		if (examListResp == null || examListResp.getBody() == null || examListResp.getBody().size() == 0) {
-			throw new SaveExamStudentException("考试不存在,请先创建考试");
-		}
-		
-		if(examListResp.getBody().size()>1){
-			throw new SaveExamStudentException("当前机构中存在多个名称为"+examName+"的考试,请重新创建考试");
-		}
-		
-		return examListResp.getBody().get(0);
-	}
-	
-}
-

+ 37 - 63
examcloud-exchange-outer-service/src/main/java/cn/com/qmth/examcloud/exchange/outer/service/impl/UpyunServiceImpl.java

@@ -1,105 +1,79 @@
 package cn.com.qmth.examcloud.exchange.outer.service.impl;
 
 import java.io.File;
+import java.io.IOException;
 
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Service;
 
 import cn.com.qmth.examcloud.commons.base.exception.StatusException;
+import cn.com.qmth.examcloud.commons.base.logging.ExamCloudLog;
+import cn.com.qmth.examcloud.commons.base.logging.ExamCloudLogFactory;
 import cn.com.qmth.examcloud.commons.base.util.UrlUtil;
 import cn.com.qmth.examcloud.exchange.outer.service.UpyunService;
 import main.java.com.UpYun;
 
 /**
- * Created by yuanpan on 2017/5/11.
+ * 类注释
+ *
+ * @author WANGWEI
+ * @date 2018年9月4日
+ * @Copyright (c) 2018-? http://qmth.com.cn All Rights Reserved.
  */
 @Service
 public class UpyunServiceImpl implements UpyunService {
 
+	protected ExamCloudLog log = ExamCloudLogFactory.getLog(this.getClass());
+
 	private final Object LOCK = new Object();
 
 	private UpYun upyun;
 
-	@Value("${app.upyun.path}")
-	private String path;
-
-	@Value("${app.upyun.bucket}")
-	private String bucket;
+	@Value("${$UpYun.bucketName}")
+	private String bucketName;
 
-	@Value("${app.upyun.operator}")
-	private String operator;
+	@Value("${$UpYun.userName}")
+	private String userName;
 
-	@Value("${app.upyun.password}")
+	@Value("${$UpYun.password}")
 	private String password;
 
+	@Value("${$UpYun.studentPhotoUrlBasePath}")
+	private String studentPhotoUrlBasePath;
+
+	/**
+	 * 方法注释
+	 *
+	 * @author WANGWEI
+	 * @return
+	 */
 	private UpYun getUpyun() {
-		// modified by wangwei.
 		if (null == upyun) {
 			synchronized (LOCK) {
 				if (null == upyun) {
-					upyun = new UpYun(bucket, operator, password);
+					upyun = new UpYun(bucketName, userName, password);
 				}
 			}
 		}
 		return upyun;
 	}
 
-	/**
-	 * 方法注释
-	 *
-	 * @author WANGWEI
-	 * @param identityNumber
-	 * @param rootOrgId
-	 * @param fileName
-	 * @return
-	 */
-	public String getStudentPhotoUrl(String identityNumber, Long rootOrgId, String fileName) {
-		identityNumber = UrlUtil.encode(identityNumber);
-		String url = "http://" + bucket + ".b0.upaiyun.com" + path + "/" + rootOrgId + "/"
-				+ identityNumber + "/" + fileName;
-		return url;
-	}
-
-	/*
-	 * 实现
-	 *
-	 * @author WANGWEI
-	 * 
-	 * @see cn.com.qmth.examcloud.exchange.outer.service.UpyunService#
-	 * saveStudentPhoto(java.lang.String, java.lang.Long, java.lang.String,
-	 * java.io.File)
-	 */
 	@Override
-	public String saveStudentPhoto(String identityNumber, Long rootOrgId, String fileName,
-			File file) {
-		identityNumber = UrlUtil.encode(identityNumber);
-		String filePath = path + "/" + rootOrgId + "/" + identityNumber + "/" + fileName;
+	public String writeFile(Long rootOrgId, String identityNumber, String fileName, File file) {
+		String photoPath = rootOrgId + "/" + UrlUtil.encode(identityNumber) + "/" + fileName;
+
+		String filePath = "/student_base_photo" + "/" + photoPath;
+
 		try {
 			getUpyun().writeFile(filePath, file, true);
-			return rootOrgId + "/" + identityNumber + "/" + fileName;
-		} catch (Exception e) {
-			throw new StatusException("EX-100001", "调用又拍云API写文件失败");
+		} catch (IOException e) {
+			log.error("[UpYun] fail to write file. filePath=" + filePath, e);
+			throw new StatusException("EX-360001", "上传文件到UpYun失败", e);
 		}
-	}
 
-	/*
-	 * 实现
-	 *
-	 * @author WANGWEI
-	 * 
-	 * @see cn.com.qmth.examcloud.exchange.outer.service.UpyunService#
-	 * saveStudentPhoto(java.lang.String, java.lang.Long, java.lang.String,
-	 * byte[])
-	 */
-	@Override
-	public String saveStudentPhoto(String identityNumber, Long rootOrgId, String fileName,
-			byte[] bytes) {
-		String filePath = path + "/" + rootOrgId + "/" + identityNumber + "/" + fileName;
-		try {
-			getUpyun().writeFile(filePath, bytes, true);
-			return rootOrgId + "/" + identityNumber + "/" + fileName;
-		} catch (Exception e) {
-			throw new StatusException("EX-100001", "调用又拍云API写文件失败");
-		}
+		String photoUrl = studentPhotoUrlBasePath + filePath;
+
+		return photoUrl;
 	}
+
 }