wangwei před 7 roky
rodič
revize
e15d982201

+ 32 - 152
examcloud-exchange-outer-api-provider/src/main/java/cn/com/qmth/examcloud/exchange/outer/api/provider/FaceppController.java

@@ -1,38 +1,23 @@
 package cn.com.qmth.examcloud.exchange.outer.api.provider;
 
-import java.io.IOException;
-import java.net.URISyntaxException;
-import java.security.NoSuchAlgorithmException;
+import java.io.File;
 import java.util.List;
-import java.util.zip.ZipEntry;
-import java.util.zip.ZipInputStream;
 
 import javax.servlet.http.HttpServletRequest;
 
-import org.apache.commons.io.output.ByteArrayOutputStream;
+import org.apache.commons.fileupload.disk.DiskFileItem;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.http.HttpStatus;
-import org.springframework.http.ResponseEntity;
-import org.springframework.util.StringUtils;
 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.MultipartFile;
+import org.springframework.web.multipart.commons.CommonsMultipartFile;
+
+import com.google.common.collect.Lists;
 
-import cn.com.qmth.examcloud.common.dto.core.StudentFaceInfo;
-import cn.com.qmth.examcloud.common.dto.em.ExamStudent;
 import cn.com.qmth.examcloud.commons.base.exception.StatusException;
-import cn.com.qmth.examcloud.commons.base.util.GsonUtil;
 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.base.exception.DetectNoFaceException;
-import cn.com.qmth.examcloud.exchange.base.exception.ExamStudentNotExistException;
-import cn.com.qmth.examcloud.exchange.base.exception.FaceppException;
-import cn.com.qmth.examcloud.exchange.base.exception.InvalidJpgException;
-import cn.com.qmth.examcloud.exchange.base.exception.UpYunException;
-import cn.com.qmth.examcloud.exchange.base.response.FailureBaseResponse;
-import cn.com.qmth.examcloud.exchange.base.response.IBaseResponse;
 import cn.com.qmth.examcloud.exchange.outer.service.FaceppService;
 import cn.com.qmth.examcloud.exchange.outer.service.client.ExamStudentClient;
 import cn.com.qmth.examcloud.exchange.outer.service.client.StudentFaceInfoClient;
@@ -78,159 +63,54 @@ public class FaceppController extends ControllerSupport {
 	private StudentFaceInfoClient studentFaceInfoClient;
 
 	/**
-	 * 单个上传
-	 * 
+	 * 重构
+	 *
+	 * @author WANGWEI
 	 * @param file
-	 * @param request
-	 * @return
-	 * @throws IOException
-	 * @throws UpYunException
-	 * @throws FaceppException
-	 * @throws URISyntaxException
-	 * @throws NoSuchAlgorithmException
+	 * @throws Exception
 	 */
 	@PostMapping("/add")
-	public void add(@RequestParam MultipartFile file, HttpServletRequest request) throws Exception {
+	public void add(@RequestParam CommonsMultipartFile file) throws Exception {
 		User accessUser = getAccessUser();
-		try {
-			log.debug("fileName =" + file.getOriginalFilename());
-			faceppService.processOne(accessUser, file.getOriginalFilename(), file.getBytes(),
-					accessUser.getRootOrgId());
-		} catch (InvalidJpgException e) {
-			throw new StatusException("EX-111001", "不是一个图片文件");
-		} catch (ExamStudentNotExistException e) {
-			throw new StatusException("EX-111002", "考生不存在");
-		} catch (DetectNoFaceException e) {
-			throw new StatusException("EX-111003", "检测不到人脸");
-		}
+
+		log.debug("fileName =" + file.getOriginalFilename());
+		DiskFileItem item = (DiskFileItem) file.getFileItem();
+		File storeLocation = item.getStoreLocation();
+		String filename = file.getOriginalFilename();
+		faceppService.uploadPhoto(accessUser, filename, storeLocation);
 	}
 
 	/**
-	 * 学生照片打包成ZIP文件批量上传
-	 * 
+	 * 方法注释
+	 *
+	 * @author WANGWEI
 	 * @param file
 	 * @param request
 	 * @return
 	 * @throws Exception
 	 */
 	@PostMapping("/import")
-	public ResponseEntity<IBaseResponse> batchAllFace(@RequestParam MultipartFile file,
+	public List<String> batchAll(@RequestParam CommonsMultipartFile file,
 			HttpServletRequest request) throws Exception {
 		User accessUser = getAccessUser();
-		if (accessUser == null) {
-			return new ResponseEntity<>(new FailureBaseResponse("请先登录", null),
-					HttpStatus.BAD_REQUEST);
-		}
+
+		DiskFileItem item = (DiskFileItem) file.getFileItem();
+		File storeLocation = item.getStoreLocation();
+		String filename = file.getOriginalFilename();
+
 		String userToken = accessUser.getToken();
-		Long rootOrgId = accessUser.getRootOrgId();
 
-		if (!file.getOriginalFilename().endsWith(".zip")) {
-			return new ResponseEntity<>(new FailureBaseResponse("文件格式不正确,必须是zip格式的压缩包", null),
-					HttpStatus.BAD_REQUEST);
+		if (!filename.endsWith(".zip")) {
+			throw new StatusException("EX-620001", "文件格式不正确,必须是zip格式的压缩包");
 		}
 		// 文件大小限制
 		if (file.getSize() > ZIP_MAX_SIZE * 1024 * 1024) {
-			return new ResponseEntity<>(new FailureBaseResponse("文件大小超过50M,请分批导入", null),
-					HttpStatus.BAD_REQUEST);
+			throw new StatusException("EX-620002", "文件大小超过50M,请分批导入");
 		}
-		ZipInputStream zin = new ZipInputStream(file.getInputStream());
-		ZipEntry ze;
-		// 一次最多处理10个照片
-		int count = 0;
-		String identityNumber = "";
-		String suffix = "";
-		try {
-			while ((ze = zin.getNextEntry()) != null && count < MAX_COUNT) {
-				if (!ze.isDirectory()) {
-					count++;
-					if (ze.getSize() > MAX_SIZE * 1024) {
-						throw new InvalidJpgException(
-								ze.getName() + "超过了" + MAX_SIZE + "KB,请压缩后上传");
-					}
-					// 计算出身份证号
-					String[] nameAndSuffix = ze.getName().split("\\.");
-					if (nameAndSuffix.length < 2) {
-						throw new InvalidJpgException(ze.getName() + "不是一个照片文件");
-					}
-					identityNumber = (nameAndSuffix[0].startsWith("/")
-							|| nameAndSuffix[0].startsWith("\\"))
-									? nameAndSuffix[0].substring(1)
-									: nameAndSuffix[0];
-					suffix = nameAndSuffix[1];
-					log.info("文件名为 :" + identityNumber + ",后缀名为:" + suffix);
-					// 根据身份证号码,查询考生是否存在
-					log.info("查询身份证号码为 :" + identityNumber + "的学生");
-					String json = examStudentClient.getExamStudentByIdentityNumber(userToken,
-							identityNumber);
-					if (StringUtils.isEmpty(json)) {
-						log.error("身份证号为:" + identityNumber + "的考生不存在");
-						continue;
-					} else {
-						List<ExamStudent> examStudentList = GsonUtil.jsonToArrayList(json,
-								ExamStudent.class);
-						if (examStudentList.size() < 1) {
-							log.error("身份证号为:" + identityNumber + "的考生不存在");
-							// 如果找不到学生信息,则跳过
-							continue;
-						}
-						ExamStudent examStudent = examStudentList.get(0);
-						ByteArrayOutputStream output = new ByteArrayOutputStream();
-						// 保存学生照片到又拍云
-						int len = -1;
-						byte[] bytes = new byte[4096];
-						while ((len = zin.read(bytes)) != -1) {
-							output.write(bytes, 0, len);
-						}
-						output.close();
-						byte[] dataBytes = output.toByteArray();
-						String fileName = upyunService.getMd5(dataBytes);
-						if (upyunService.saveStudentPhoto(identityNumber, dataBytes, fileName,
-								"." + suffix)) {
-							log.info("保存" + identityNumber + "的照片到又拍云成功");
-							// 调用人脸识别接口
-							String faceToken = null;
-							try {
-								faceToken = faceppService.detectSingleFace(upyunService
-										.getDownloadUrl(identityNumber, fileName, "." + suffix));
-							} catch (DetectNoFaceException e) {
-								log.error(identityNumber + "检测人脸失败");
-								continue;
-							}
-							ResponseEntity<StudentFaceInfo> studentFaceInfoResponseEntity = studentFaceInfoClient
-									.getByIdentityNumber(userToken, identityNumber, rootOrgId);
-							StudentFaceInfo studentFaceInfo = studentFaceInfoResponseEntity
-									.getBody();
-							// 获取faceSet,并将faceToken添加进facesetToken
-							String facesetToken = studentFaceInfoClient
-									.getFaceSet(accessUser.getUserToken());
-							if (faceppService.addFace(faceToken, facesetToken)) {
-								String photoMD5 = fileName + "." + suffix;
-								faceppService.saveStudentFaceInfo(studentFaceInfo, photoMD5,
-										faceToken, facesetToken, examStudent.getStudentId(),
-										accessUser.getDisplayName(), "INTERFACE_IMPORT", userToken);
-							} else {
-								log.error(identityNumber + "添加照片到人脸集合失败");
-								continue;
-							}
-						} else {
-							log.error("身份证号为:" + identityNumber + "的考生照片保存到又拍云失败");
-							continue;
-						}
-					}
-				}
-			}
-		} catch (InvalidJpgException e) {
-			log.error("导入照片出现格式错误:", e);
-			return new ResponseEntity<>(new FailureBaseResponse(e.getMessage(), identityNumber),
-					HttpStatus.BAD_REQUEST);
-		} catch (IOException e) {
-			log.error("导入照片出现IO错误:", e);
-			return new ResponseEntity<>(new FailureBaseResponse(e.getMessage(), identityNumber),
-					HttpStatus.INTERNAL_SERVER_ERROR);
-		} finally {
-			zin.closeEntry();
-		}
-		return new ResponseEntity<>(HttpStatus.OK);
+
+		List<String> errDatas = Lists.newArrayList();
+
+		return errDatas;
 	}
 
 }

+ 96 - 178
examcloud-exchange-outer-service/src/main/java/cn/com/qmth/examcloud/exchange/outer/service/FaceppService.java

@@ -1,15 +1,10 @@
 package cn.com.qmth.examcloud.exchange.outer.service;
 
 import java.io.BufferedReader;
-import java.io.IOException;
+import java.io.File;
 import java.io.InputStreamReader;
 import java.net.URI;
-import java.net.URISyntaxException;
-import java.security.NoSuchAlgorithmException;
-import java.util.Date;
-import java.util.List;
 
-import org.apache.commons.lang3.StringUtils;
 import org.apache.http.HttpEntity;
 import org.apache.http.StatusLine;
 import org.apache.http.client.methods.CloseableHttpResponse;
@@ -22,22 +17,20 @@ 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.http.ResponseEntity;
 import org.springframework.stereotype.Service;
 
 import com.google.gson.Gson;
 import com.google.gson.GsonBuilder;
 
-import cn.com.qmth.examcloud.common.dto.core.Student;
-import cn.com.qmth.examcloud.common.dto.core.StudentFaceInfo;
-import cn.com.qmth.examcloud.common.dto.em.ExamStudent;
-import cn.com.qmth.examcloud.commons.base.util.GsonUtil;
+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.exchange.base.exception.DetectNoFaceException;
-import cn.com.qmth.examcloud.exchange.base.exception.ExamStudentNotExistException;
-import cn.com.qmth.examcloud.exchange.base.exception.FaceppException;
-import cn.com.qmth.examcloud.exchange.base.exception.InvalidJpgException;
-import cn.com.qmth.examcloud.exchange.base.exception.UpYunException;
+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;
@@ -65,41 +58,38 @@ public class FaceppService {
 	@Autowired
 	StudentFaceInfoClient studentFaceInfoClient;
 
-	private void closeResponse(CloseableHttpResponse httpResponse) {
-		if (httpResponse != null) {
-			try {
-				httpResponse.close();
-			} catch (IOException e) {
-				e.printStackTrace();
-			} finally {
-				httpResponse = null;
-			}
-		}
-	}
+	@Autowired
+	StudentCloudService studentCloudService;
+
+	@Autowired
+	StudentFaceCloudService studentFaceCloudService;
 
 	/**
-	 * 检测人脸
+	 * 重构<br>
+	 * 调用人脸识别接口
 	 *
+	 * @author WANGWEI
 	 * @param imageUrl
-	 * @return 检测到的人脸的face_token
-	 * @throws URISyntaxException
-	 * @throws DetectNoFaceException
+	 * @return
 	 */
-	public String detectSingleFace(String imageUrl)
-			throws URISyntaxException, DetectNoFaceException {
-		int time = 3;// 重新检测次数为3次
-		String faceToken = "";
-		while (time > 0) {
-			// 调用人脸识别接口
-			CloseableHttpClient httpClient = HttpClients.createDefault();
-			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();
+	public String detectSingleFace(String imageUrl) {
+		// 重新检测次数为3次
+		int time = 3;
+		String faceToken = null;
+		while (true) {
+			if (time < 1) {
+				throw new StatusException("EX--111010", "人脸检测失败");
+			}
 
-			HttpPost httpPost = new HttpPost(uri);
+			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();
@@ -114,186 +104,114 @@ public class FaceppService {
 						faceToken = faceDetectResponse.getFaces().get(0).getFace_token();
 						break;
 					} else {
-						throw new DetectNoFaceException();
+						time--;
 					}
 				} else {
 					StringBuffer buffer = new StringBuffer();
-					String str = "";
-					while (StringUtils.isNoneBlank((str = reader.readLine()))) {
+					String str = null;
+					while (null != (str = reader.readLine())) {
 						buffer.append(str);
 					}
 					String result = buffer.toString();
-					LOG.info("获取token失败:" + result);
+					LOG.error("获取token失败:" + result);
 					time--;
 				}
 				httpClient.close();
-			} catch (IOException e) {
-				// 重试
-				LOG.error("检测人脸失败,剩余次数:" + (time - 1), e);
+			} catch (Exception e) {
 				time--;
-				if (time < 1) {
-					throw new DetectNoFaceException();
-				}
+				LOG.error("人脸检测失败", e);
 			} finally {
-				closeResponse(httpResponse);
+				HttpClientUtil.close(httpResponse);
 			}
 		}
-		LOG.info("检测到人脸token:" + faceToken);
+
 		return faceToken;
 	}
 
 	/**
-	 * 将人脸加入到人脸集合
+	 * 添加faceToken至faceSet
 	 *
+	 * @author WANGWEI
 	 * @param faceToken
 	 * @param facesetToken
-	 * @throws URISyntaxException
 	 */
-	public boolean addFace(String faceToken, String facesetToken) throws URISyntaxException {
-		boolean success = false;
-		int time = 3;// 重新检测次数为3次
+	public void addFaceToken2FaceTokenSet(String faceToken, String facesetToken) {
+
+		// 重新检测次数为3次
+		int time = 3;
 		while (time > 0) {
 			// 调用人脸识别接口
 			CloseableHttpClient httpClient = HttpClients.createDefault();
-			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);
 			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("添加人脸到集合响应:" + EntityUtils.toString(httpResponse.getEntity()));
+				LOG.info("response: " + EntityUtils.toString(httpResponse.getEntity()));
 				if (statusLine.getStatusCode() == 200) {
-					success = true;
-					// 加入成功
 					break;
 				} else {
 					time--;
 				}
-			} catch (IOException e) {
-				LOG.error("添加人脸失败,剩余次数:" + (time - 1), e);
+			} catch (Exception e) {
+				LOG.error("添加faceToken至faceSet失败", e);
 				time--;
 			} finally {
-				closeResponse(httpResponse);
-			}
-		}
-		return success;
-	}
-
-	public void processOne(User accessUser, String fileName, byte[] dataBytes, Long rootOrgId)
-			throws InvalidJpgException, ExamStudentNotExistException, NoSuchAlgorithmException,
-			DetectNoFaceException, URISyntaxException, FaceppException, UpYunException {
-		String userToken = accessUser.getUserToken();
-		String[] nameAndSuffix = fileName.split("\\.");
-		if (nameAndSuffix.length < 2) {
-			throw new InvalidJpgException(fileName + "不是一个照片文件");
-		}
-		String identityNumber = (nameAndSuffix[0].startsWith("/")
-				|| nameAndSuffix[0].startsWith("\\"))
-						? nameAndSuffix[0].substring(1)
-						: nameAndSuffix[0];
-		String suffix = nameAndSuffix[1];
-		LOG.info("文件名为 :" + identityNumber + ",后缀名为:" + suffix);
-		// 根据身份证号码,查询考生是否存在
-		LOG.info("查询身份证号码为 :" + identityNumber + "的学生");
-		String json = examStudentClient.getExamStudentByIdentityNumber(userToken, identityNumber);
-		// LOG.info("查询结果为 :" + json);
-		if (StringUtils.isEmpty(json)) {
-			LOG.error("身份证号为:" + identityNumber + "的考生不存在");
-			throw new ExamStudentNotExistException();
-		} else {
-			List<ExamStudent> examStudentList = GsonUtil.jsonToArrayList(json, ExamStudent.class);
-
-			if (examStudentList.size() < 1) {
-				LOG.error("身份证号为:" + identityNumber + "的考生不存在");
-				throw new ExamStudentNotExistException();
-			}
-			ExamStudent examStudent = examStudentList.get(0);
-			// 保存学生照片到又拍云
-			String upyunFileName = upyunService.getMd5(dataBytes);
-			try {
-				if (upyunService.saveStudentPhoto(identityNumber, dataBytes, upyunFileName,
-						"." + suffix)) {
-					// 调用人脸识别接口
-					String faceToken = detectSingleFace(upyunService.getDownloadUrl(identityNumber,
-							upyunFileName, "." + suffix));
-					if (StringUtils.isBlank(faceToken)) {
-						throw new FaceppException(identityNumber + "获取token失败");
-					}
-					String facesetToken = studentFaceInfoClient.getFaceSet(userToken);
-					StudentFaceInfo studentFaceInfo = getStudentFaceInfo(userToken, identityNumber,
-							rootOrgId);
-					if (addFace(faceToken, facesetToken)) {
-						String photoMD5 = upyunFileName + "." + suffix;
-						saveStudentFaceInfo(studentFaceInfo, photoMD5, faceToken, facesetToken,
-								examStudent.getStudentId(), accessUser.getDisplayName(),
-								"INTERFACE_ADD", userToken);
-					} else {
-						throw new FaceppException(identityNumber + "保存当前faceToken到人脸集合(faceSet)失败");
-					}
-				} else {
-					throw new UpYunException("身份证号为:" + identityNumber + "的考生照片保存到又拍云失败");
-				}
-			} catch (IOException e) {
-				throw new RuntimeException("身份证号为:" + identityNumber + "的考生照片保存失败", e);
+				HttpClientUtil.close(httpResponse);
 			}
 		}
 	}
 
 	/**
-	 * 方法注释
+	 * 重构
 	 *
 	 * @author WANGWEI
-	 * @param userToken
-	 * @param identityNumber
-	 * @param rootOrgId
-	 * @return
+	 * @param accessUser
+	 * @param fileName
+	 * @param file
+	 * @throws Exception
 	 */
-	private StudentFaceInfo getStudentFaceInfo(String userToken, String identityNumber,
-			Long rootOrgId) {
-		ResponseEntity<StudentFaceInfo> respEntity = studentFaceInfoClient
-				.getByIdentityNumber(userToken, identityNumber, rootOrgId);
+	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"))) {
+			throw new StatusException("B-101001", "文件格式错误");
+		}
 
-		StudentFaceInfo studentFaceInfo = respEntity.getBody();
+		String identityNumber = fileName.substring(0, fileName.lastIndexOf(fileName));
 
-		return studentFaceInfo;
-	}
+		GetStudentReq req = new GetStudentReq();
+		req.setIdentityNumber(identityNumber);
+		req.setRootOrgId(accessUser.getRootOrgId());
+		GetStudentResp resp = studentCloudService.getStudent(req);
+		StudentBean student = resp.getStudentInfo();
 
-	/**
-	 * 保存studentFaceInfo
-	 * 
-	 * @param studentFaceInfo
-	 * @param photoMD5
-	 * @param faceToken
-	 * @param facesetToken
-	 * @param studentId
-	 * @param accessUserName
-	 * @param createType
-	 * @param userToken
-	 */
-	public void saveStudentFaceInfo(StudentFaceInfo studentFaceInfo, String photoMD5,
-			String faceToken, String facesetToken, Long studentId, String accessUserName,
-			String createType, String userToken) {
-		if (studentFaceInfo == null) {
-			studentFaceInfo = new StudentFaceInfo();
-			Student student = new Student();
-			student.setId(studentId);
-			studentFaceInfo.setStudent(student);
-			studentFaceInfo.setCreateUser(accessUserName);
-			studentFaceInfo.setCreateTime(new Date());
-		} else {
-			studentFaceInfo.setUpdateUser(accessUserName);
-			studentFaceInfo.setUpdateTime(new Date());
-		}
-		studentFaceInfo.setFaceToken(faceToken);
-		studentFaceInfo.setFaceSetToken(facesetToken);
-		studentFaceInfo.setPhotoMD5(photoMD5);
-		studentFaceInfo.setCreateType(createType);
-		studentFaceInfoClient.save(userToken, studentFaceInfo);
+		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);
 	}
+
 }

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

@@ -17,11 +17,11 @@ public interface UpyunService {
 	 * @author WANGWEI
 	 * @param identityNumber
 	 * @param rootOrgId
-	 * @param fileSuffix
+	 * @param fileName
 	 * @param file
 	 * @return
 	 */
-	String saveStudentPhoto(String identityNumber, Long rootOrgId, String fileSuffix, File file);
+	String saveStudentPhoto(String identityNumber, Long rootOrgId, String fileName, File file);
 
 	/**
 	 * 新方案
@@ -29,10 +29,10 @@ public interface UpyunService {
 	 * @author WANGWEI
 	 * @param identityNumber
 	 * @param rootOrgId
-	 * @param fileSuffix
+	 * @param fileName
 	 * @param bytes
 	 * @return
 	 */
-	String saveStudentPhoto(String identityNumber, Long rootOrgId, String fileSuffix, byte[] bytes);
+	String saveStudentPhoto(String identityNumber, Long rootOrgId, String fileName, byte[] bytes);
 
 }

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

@@ -1,9 +1,6 @@
 package cn.com.qmth.examcloud.exchange.outer.service.impl;
 
 import java.io.File;
-import java.io.IOException;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
 
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Service;
@@ -46,83 +43,58 @@ public class UpyunServiceImpl implements UpyunService {
 		return upyun;
 	}
 
-	public String getDownloadUrl(String identityNumber, String fileName, String fileSuffix) {
-
-		if (fileSuffix.startsWith(".")) {
-			return "http://" + bucket + ".b0.upaiyun.com/student_base_photo/" + identityNumber + "/"
-					+ fileName + "" + fileSuffix;
-		} else {
-			return "http://" + bucket + ".b0.upaiyun.com/student_base_photo/" + identityNumber + "/"
-					+ fileName + "." + fileSuffix;
-		}
-
-	}
-
-	public String getMd5(byte[] bytes) throws NoSuchAlgorithmException {
-		// 用来计算md5摘要的
-		char[] hexDigits = new char[]{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b',
-				'c', 'd', 'e', 'f'};
-
-		MessageDigest md5 = MessageDigest.getInstance("MD5");
-		md5.update(bytes);
-
-		byte[] md5DigestBytes = md5.digest();
-		int dlen = md5DigestBytes.length;
-
-		char[] md5val = new char[dlen * 2];
-		int k = 0;
-		for (byte encoded : md5DigestBytes) {
-			md5val[k++] = hexDigits[encoded >> 4 & 15];
-			md5val[k++] = hexDigits[encoded & 5];
-		}
-
-		return new String(md5val);
-	}
-
-	public boolean saveStudentPhoto(String identityNumber, byte[] bytes, String fileName,
-			String fileSuffix) throws IOException {
-
-		if (fileSuffix.startsWith(".")) {
-			return getUpyun().writeFile(path + "/" + identityNumber + "/" + fileName + fileSuffix,
-					bytes, true);
-		} else {
-			return getUpyun().writeFile(
-					path + "/" + identityNumber + "/" + fileName + "." + fileSuffix, bytes, true);
-		}
-
+	/**
+	 * 方法注释
+	 *
+	 * @author WANGWEI
+	 * @param identityNumber
+	 * @param rootOrgId
+	 * @param fileName
+	 * @return
+	 */
+	public String getStudentPhotoUrl(String identityNumber, Long rootOrgId, String fileName) {
+		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 fileSuffix,
+	public String saveStudentPhoto(String identityNumber, Long rootOrgId, String fileName,
 			File file) {
-		String filePath = path + "/" + rootOrgId + "/" + identityNumber + "/"
-				+ System.currentTimeMillis();
-		if (fileSuffix.startsWith(".")) {
-			filePath += fileSuffix;
-		} else {
-			filePath += "." + fileSuffix;
-		}
+		String filePath = path + "/" + rootOrgId + "/" + identityNumber + "/" + fileName;
 		try {
 			getUpyun().writeFile(filePath, file, true);
-			return filePath;
+			return rootOrgId + "/" + identityNumber + "/" + fileName;
 		} catch (Exception e) {
 			throw new StatusException("EX-100001", "调用又拍云API写文件失败");
 		}
 	}
 
+	/*
+	 * 实现
+	 *
+	 * @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 fileSuffix,
+	public String saveStudentPhoto(String identityNumber, Long rootOrgId, String fileName,
 			byte[] bytes) {
-		String filePath = path + "/" + rootOrgId + "/" + identityNumber + "/"
-				+ System.currentTimeMillis();
-		if (fileSuffix.startsWith(".")) {
-			filePath += fileSuffix;
-		} else {
-			filePath += "." + fileSuffix;
-		}
+		String filePath = path + "/" + rootOrgId + "/" + identityNumber + "/" + fileName;
 		try {
 			getUpyun().writeFile(filePath, bytes, true);
-			return filePath;
+			return rootOrgId + "/" + identityNumber + "/" + fileName;
 		} catch (Exception e) {
 			throw new StatusException("EX-100001", "调用又拍云API写文件失败");
 		}

+ 1 - 1
examcloud-exchange-starter/src/main/java/cn/com/qmth/examcloud/exchange/ExchangeApp.java

@@ -86,7 +86,7 @@ public class ExchangeApp {
 		CommonsMultipartResolver resolver = new CommonsMultipartResolver();
 		resolver.setDefaultEncoding("UTF-8");
 		resolver.setResolveLazily(true);
-		resolver.setMaxInMemorySize(32);
+		resolver.setMaxInMemorySize(2);
 		resolver.setMaxUploadSize(200 * 1024 * 1024);
 		return resolver;
 	}