浏览代码

增加照片导入,照片检查

ting.yin 8 年之前
父节点
当前提交
ff60ceaf1f

+ 10 - 0
exam-work-api/pom.xml

@@ -48,6 +48,16 @@
             <groupId>cn.com.qmth.examcloud.common</groupId>
             <artifactId>common-uac</artifactId>
              <version>${exam.cloud.version}</version>
+        </dependency>
+        		<dependency>
+            <groupId>cn.com.qmth.examcloud.common</groupId>
+            <artifactId>common-dto</artifactId>
+             <version>${exam.cloud.version}</version>
+        </dependency>
+		<dependency>
+            <groupId>com.facepp</groupId>
+            <artifactId>faceppsdk</artifactId>
+            <version>1.0</version>
         </dependency>
     </dependencies>
 

+ 25 - 0
exam-work-api/src/main/java/cn/com/qmth/examcloud/service/examwork/api/ExamStudentApi.java

@@ -21,6 +21,7 @@ import org.springframework.web.bind.annotation.RequestParam;
 import org.springframework.web.bind.annotation.RestController;
 import org.springframework.web.multipart.MultipartFile;
 
+import cn.com.qmth.examcloud.common.util.ErrorMsg;
 import cn.com.qmth.examcloud.common.util.excel.ExcelError;
 import cn.com.qmth.examcloud.service.examwork.dao.ExamStudentRepo;
 import cn.com.qmth.examcloud.service.examwork.entity.ExamStudent;
@@ -94,4 +95,28 @@ public class ExamStudentApi {
 			return new ResponseEntity(HttpStatus.INTERNAL_SERVER_ERROR);
 		}
     }
+    
+    @ApiOperation(value="导入学生照片",notes = "导入")
+    @PostMapping("/exam_student/import_photo")
+    public ResponseEntity importPhoto(@RequestParam Long examId,@RequestParam MultipartFile file){
+    	try {
+    		List<ErrorMsg> errorMsgs = examStudentService.importPhoto(examId,file.getInputStream());
+    		return new ResponseEntity(errorMsgs,HttpStatus.OK);
+		} catch (IOException e) {
+			e.printStackTrace();
+			return new ResponseEntity(HttpStatus.INTERNAL_SERVER_ERROR);
+		}
+    }
+    
+    @ApiOperation(value="照片检验",notes = "检验")
+    @PostMapping("/photo_check")
+    public ResponseEntity photoCheck(@RequestParam Long examId){
+    	try {
+    		List<ErrorMsg> errorMsgs = examStudentService.photoCheck(examId);
+    		return new ResponseEntity(errorMsgs,HttpStatus.OK);
+		} catch (Exception e) {
+			e.printStackTrace();
+			return new ResponseEntity(HttpStatus.INTERNAL_SERVER_ERROR);
+		}
+    }
 }

+ 142 - 2
exam-work-api/src/main/java/cn/com/qmth/examcloud/service/examwork/service/ExamStudentService.java

@@ -2,17 +2,29 @@ package cn.com.qmth.examcloud.service.examwork.service;
 
 import static org.springframework.data.domain.ExampleMatcher.GenericPropertyMatchers.startsWith;
 
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
 import java.io.InputStream;
+import java.io.OutputStream;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipInputStream;
 
+import org.json.JSONArray;
+import org.json.JSONObject;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
 import org.springframework.data.domain.Example;
 import org.springframework.data.domain.ExampleMatcher;
 import org.springframework.data.domain.Page;
 import org.springframework.data.domain.Pageable;
 import org.springframework.stereotype.Service;
+import org.springframework.util.StringUtils;
 
+import cn.com.qmth.examcloud.common.util.ErrorMsg;
 import cn.com.qmth.examcloud.common.util.excel.ExcelError;
 import cn.com.qmth.examcloud.common.util.excel.ExcelReader;
 import cn.com.qmth.examcloud.common.util.excel.ExcelReaderHandle;
@@ -20,6 +32,10 @@ import cn.com.qmth.examcloud.service.examwork.dao.ExamRepo;
 import cn.com.qmth.examcloud.service.examwork.dao.ExamStudentRepo;
 import cn.com.qmth.examcloud.service.examwork.entity.Exam;
 import cn.com.qmth.examcloud.service.examwork.entity.ExamStudent;
+import cn.com.qmth.examcloud.service.examwork.service.rpc.StudentService;
+
+import com.facepp.http.HttpRequests;
+import com.facepp.http.PostParameters;
 
 /**
  * 考试学生服务类
@@ -31,7 +47,18 @@ public class ExamStudentService {
     ExamStudentRepo examStudentRepo;
     @Autowired
     ExamRepo examRepo;
-
+    @Autowired
+    StudentService studentService;
+    
+    @Value("${app.em.photo.path}")
+    private String PHOTO_PATH ;
+    @Value("${app.em.facepp.key}")
+    private String FACEPP_KEY;
+    @Value("${app.em.facepp.secret}")
+    private String FACEPP_SECRET;
+    
+    private static final String JPG = ".jpg";
+    
     /**
      * 获取所有考试学生(分页)
      * @param examCriteria
@@ -122,7 +149,10 @@ public class ExamStudentService {
                 if (error == null) {
                 	examStudents.add(dto);
                 }
-                
+                if (examStudents.size() % 1000 == 0) {
+                    examStudentRepo.save(examStudents);
+                    examStudents.removeAll(examStudents);
+                }
                 return error;
             }
         });
@@ -136,6 +166,116 @@ public class ExamStudentService {
 	 * @return
 	 */
 	public ExcelError importCheck(ExamStudent dto){
+		
 		return null;
 	}
+
+	/**
+	 * 导入照片
+	 * @param examId 
+	 * @param photoFile
+	 * @throws IOException 
+	 */
+	public List<ErrorMsg> importPhoto(Long examId, InputStream inputStream) throws IOException {
+		List<ErrorMsg> errorMsgs = new ArrayList<ErrorMsg>();
+		Exam exam = examRepo.findOne(examId);
+		ZipInputStream zin = new ZipInputStream(inputStream);
+		ZipEntry ze;
+		try {
+			while ((ze = zin.getNextEntry()) != null) {
+				if (ze.isDirectory()) {
+					
+				} else {
+					if(!ze.getName().endsWith(JPG)){
+						errorMsgs.add(new ErrorMsg(ze.getName()+"格式错误,文件名格式必须是jpg(小写)"));
+					}
+					if(ze.getSize()>300000){
+						errorMsgs.add(new ErrorMsg(ze.getName()+"大于300KB,请处理后重新上传"));
+					}
+					String savePath = PHOTO_PATH + File.separator + exam.getOrgId() + File.separator + "photo";
+					uploadPhoto(savePath, zin, ze);
+				}
+			}
+		} catch (Exception e) {
+			e.printStackTrace();
+			errorMsgs.add(new ErrorMsg("压缩文件中有中文名称文件或文件夹,请修改后重新上传"));
+		}finally{
+			zin.closeEntry();
+		}
+		return errorMsgs;
+	}
+	
+	/**
+	 * 考生照片上传照片到服务器
+	 */
+	public void uploadPhoto(String filePath,ZipInputStream zin,ZipEntry ze){
+		try {
+			File out = new File(filePath);
+			if (!out.exists()) {
+				out.mkdirs();
+			}
+			File outFile = new File(filePath + File.separator + ze.getName());
+			if (!outFile.exists()) {
+				outFile.createNewFile();
+			}
+			OutputStream output = new FileOutputStream(outFile);
+			int temp = 0;
+			while ((temp = zin.read()) != -1) {
+				output.write(temp);
+			}
+			output.close();
+		} catch (FileNotFoundException e) {
+			e.printStackTrace();
+		} catch (IOException e) {
+			e.printStackTrace();
+		}
+	}
+	
+	/**
+	 * 照片检验
+	 * @param examId
+	 * @return
+	 */
+	public List<ErrorMsg> photoCheck(Long examId) {
+		List<ErrorMsg> msgs = new ArrayList<ErrorMsg>();
+		List<ExamStudent> examStudents = examStudentRepo.findByExamId(examId);
+		for (ExamStudent examStudent : examStudents) {
+			ErrorMsg errorMsg = null;
+			if(!StringUtils.isEmpty(examStudent.getIdentityNumber())){
+				errorMsg = checkExamStudent(examStudent.getOrgId(),examStudent.getIdentityNumber());
+				msgs.add(errorMsg);
+			}
+		}
+		return msgs;
+	}
+
+	/**
+	 * 身份证号检查
+	 * @param orgId
+	 * @param identityNumber
+	 * @return
+	 */
+	private ErrorMsg checkExamStudent(Long orgId,String identityNumber) {
+		ErrorMsg error = null;
+		String filePath = PHOTO_PATH + File.separator + orgId + File.separator+"photo"+ File.separator;
+		HttpRequests httpRequests = new HttpRequests(FACEPP_KEY, FACEPP_SECRET);
+		try {
+			JSONObject face = httpRequests.detectionDetect(new PostParameters()
+					.setImg(new File(filePath + identityNumber + JPG)));
+			JSONArray faceArray = face.getJSONArray("face");
+			if (faceArray.length() > 0) {
+				//人脸识别成功
+				studentService.updatePhoto(identityNumber);
+			} else {
+				error = new ErrorMsg(identityNumber + JPG + "不能被识别人脸,请换一张清晰的照片重新上传!");
+			}
+		} catch (Exception e) {
+			e.printStackTrace();
+			error = new ErrorMsg("人脸识别服务器错误,请联系技术人员!");
+		}
+		return error;
+	}
+
+	
+	
 }

+ 27 - 0
exam-work-api/src/main/java/cn/com/qmth/examcloud/service/examwork/service/rpc/StudentService.java

@@ -0,0 +1,27 @@
+package cn.com.qmth.examcloud.service.examwork.service.rpc;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import cn.com.qmth.examcloud.common.dto.core.Student;
+import cn.com.qmth.examcloud.common.util.GsonUtil;
+import cn.com.qmth.examcloud.service.examwork.service.rpc.client.StudentClient;
+
+/**
+ * 
+ * @author ting.yin
+ * @date 2017年1月14日
+ */
+@Service
+public class StudentService {
+
+	@Autowired
+	StudentClient studentClient;
+
+	public Student updatePhoto(String identityNumber) {
+		String json = studentClient.updatePhoto(identityNumber);
+		Student domain = GsonUtil.getInstanceByJson(json, Student.class);
+		return domain;
+	}
+
+}

+ 19 - 0
exam-work-api/src/main/java/cn/com/qmth/examcloud/service/examwork/service/rpc/client/StudentClient.java

@@ -0,0 +1,19 @@
+package cn.com.qmth.examcloud.service.examwork.service.rpc.client;
+
+import org.springframework.cloud.netflix.feign.FeignClient;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RequestParam;
+
+/**
+ * @Description: TODO
+ * @author ting.yin
+ * @date 2017年1月14日
+ */
+@FeignClient(value = "ExamCloud-service-core")
+public interface StudentClient {
+
+	@RequestMapping(method = RequestMethod.PUT, value = "${app.api.core}/student/update")
+	String updatePhoto(@RequestParam("identityNumber") String identityNumber);
+
+}

+ 5 - 0
exam-work-domain/src/main/java/cn/com/qmth/examcloud/service/examwork/dao/ExamStudentRepo.java

@@ -1,12 +1,17 @@
 package cn.com.qmth.examcloud.service.examwork.dao;
 
+import java.util.List;
+
 import org.springframework.data.domain.Page;
 import org.springframework.data.domain.Pageable;
 import org.springframework.data.jpa.repository.JpaRepository;
 
 import cn.com.qmth.examcloud.service.examwork.entity.ExamStudent;
+
 import org.springframework.data.repository.query.QueryByExampleExecutor;
 
 public interface ExamStudentRepo extends JpaRepository<ExamStudent, Long>,QueryByExampleExecutor<ExamStudent> {
     Page<ExamStudent> findByExamId(Long examId, Pageable pageable);
+
+	List<ExamStudent> findByExamId(Long examId);
 }

+ 6 - 26
exam-work-domain/src/main/java/cn/com/qmth/examcloud/service/examwork/entity/ExamStudent.java

@@ -71,11 +71,7 @@ public class ExamStudent implements Serializable {
 	/**
 	 * 是否毕业
 	 */
-	private boolean isGraduate;
-
-	private String status;
-
-	private String photoPath;
+	private boolean graduated;
 
 	private String remark;
 	
@@ -176,22 +172,6 @@ public class ExamStudent implements Serializable {
 		this.specialtyName = specialtyName;
 	}
 
-	public String getStatus() {
-		return status;
-	}
-
-	public void setStatus(String status) {
-		this.status = status;
-	}
-
-	public String getPhotoPath() {
-		return photoPath;
-	}
-
-	public void setPhotoPath(String photoPath) {
-		this.photoPath = photoPath;
-	}
-
 	public String getRemark() {
 		return remark;
 	}
@@ -200,7 +180,7 @@ public class ExamStudent implements Serializable {
 		this.remark = remark;
 	}
 
-	public boolean getFinished() {
+	public boolean isFinished() {
 		return finished;
 	}
 
@@ -232,12 +212,12 @@ public class ExamStudent implements Serializable {
 		this.grade = grade;
 	}
 
-	public boolean isGraduate() {
-		return isGraduate;
+	public boolean isGraduated() {
+		return graduated;
 	}
 
-	public void setGraduate(boolean isGraduate) {
-		this.isGraduate = isGraduate;
+	public void setGraduated(boolean graduated) {
+		this.graduated = graduated;
 	}
 
 	public static long getSerialversionuid() {

+ 4 - 0
exam-work-main/src/main/resources/application.properties

@@ -26,4 +26,8 @@ spring.application.name=ExamCloud-service-exam-work
 server.port=8001
 eureka.client.serviceUrl.defaultZone=http://localhost:1111/eureka/
 app.api.root=/api/ecs_exam_work
+#\u5b66\u751f\u7167\u7247\u4e0a\u4f20\u5730\u5740
+app.em.photo.path=/Users/ting.yin/Downloads
+app.em.facepp.key=e94d4a6a1ea8749144328be96a40e388
+app.em.facepp.secret=H65RT9miQqCal00jpxdUAreAufxxusUv