|
|
package com.yohoufo.user.service.impl;
|
|
|
|
|
|
|
|
|
import com.alibaba.fastjson.JSON;
|
|
|
import com.alipay.api.AlipayApiException;
|
|
|
import com.alipay.api.AlipayClient;
|
|
|
import com.alipay.api.DefaultAlipayClient;
|
...
|
...
|
@@ -9,8 +10,14 @@ import com.alipay.api.request.AlipayUserInfoShareRequest; |
|
|
import com.alipay.api.response.AlipaySystemOauthTokenResponse;
|
|
|
import com.alipay.api.response.AlipayUserInfoShareResponse;
|
|
|
import com.alipay.api.response.ZhimaCustomerCertificationQueryResponse;
|
|
|
import com.google.common.collect.Lists;
|
|
|
import com.yoho.core.redis.cluster.operations.serializer.RedisKeyBuilder;
|
|
|
import com.yoho.error.exception.ServiceException;
|
|
|
import com.yoho.service.model.reviewed.request.ImageBO;
|
|
|
import com.yoho.service.model.reviewed.request.ImageReviewedReq;
|
|
|
import com.yoho.service.model.reviewed.response.ImageReviewResp;
|
|
|
import com.yoho.tools.common.beans.ApiResponse;
|
|
|
import com.yoho.tools.common.service.IQNUploadService;
|
|
|
import com.yohobuy.ufo.model.user.resp.AuthorizeResultRespVO;
|
|
|
import com.yohoufo.common.exception.GatewayException;
|
|
|
import com.yohoufo.common.exception.UfoServiceException;
|
...
|
...
|
@@ -25,16 +32,26 @@ import com.yohoufo.user.common.AlipayConfigInfo; |
|
|
import com.yohoufo.user.helper.HideDataUtil;
|
|
|
import com.yohoufo.user.requestVO.RealNameAuthorizeReqVO;
|
|
|
import com.yohoufo.user.service.IRealNameAuthorizeService;
|
|
|
import org.apache.commons.codec.digest.DigestUtils;
|
|
|
import org.apache.commons.io.FileUtils;
|
|
|
import org.apache.commons.lang.StringUtils;
|
|
|
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 org.springframework.web.multipart.MultipartFile;
|
|
|
|
|
|
import javax.imageio.ImageIO;
|
|
|
import java.awt.image.BufferedImage;
|
|
|
import java.io.File;
|
|
|
import java.io.FileNotFoundException;
|
|
|
import java.io.IOException;
|
|
|
import java.text.DecimalFormat;
|
|
|
import java.text.SimpleDateFormat;
|
|
|
import java.time.LocalDateTime;
|
|
|
import java.time.ZoneOffset;
|
|
|
import java.util.ArrayList;
|
|
|
import java.util.Date;
|
|
|
import java.util.List;
|
|
|
|
...
|
...
|
@@ -58,27 +75,22 @@ public class RealNameAuthorizeServiceImpl implements IRealNameAuthorizeService { |
|
|
@Autowired
|
|
|
private HttpClient httpClient;
|
|
|
|
|
|
@Value("${web.context}")
|
|
|
private String contextPath;
|
|
|
|
|
|
|
|
|
@Value("${zhimacert.switch:true}")
|
|
|
private boolean zhiMaCertSwitch;
|
|
|
/* @Autowired
|
|
|
private GraphVerifyService graphVerifyService;*/
|
|
|
|
|
|
/* @Resource(name="authorizeBankRestTemplate")
|
|
|
private RestTemplate restTemplate;*/
|
|
|
// 需要放到zk上
|
|
|
private Integer maxPhotoCheckCount = 10;
|
|
|
|
|
|
/* @Resource(name = "core-config-reader")
|
|
|
private ConfigReader configReader;*/
|
|
|
//@Value("${file.saveDir}")
|
|
|
private String saveDir="D:/pic";
|
|
|
|
|
|
/* @Autowired
|
|
|
private IUserAuthorizeHistoryDao userAuthorizeHistoryDao;*/
|
|
|
//private final static DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
|
|
|
//@Autowired
|
|
|
private IQNUploadService iqnUploadService;
|
|
|
|
|
|
//请求实名认证银联接口url 测试环境
|
|
|
//private final String requestUrl="http://58.247.0.18:29015/v1/datacenter/smartverification/bankcard/verify";
|
|
|
//请求实名认证银联接口url 生产环境
|
|
|
//private final String requestUrl="https://api-mop.chinaums.com/v1/datacenter/smartverification/bankcard/verify";
|
|
|
|
|
|
//ExecutorService executeService = Executors.newFixedThreadPool(10);
|
|
|
|
|
|
|
|
|
public UserAuthorizeInfo getValidAuthorizeInfo(int uid){
|
...
|
...
|
@@ -352,6 +364,201 @@ public class RealNameAuthorizeServiceImpl implements IRealNameAuthorizeService { |
|
|
System.out.println(getStringDate());
|
|
|
}
|
|
|
|
|
|
|
|
|
@Override
|
|
|
public List<String> zhiMaCertUploadPhotoAndCheck(MultipartFile[] multipartFiles, String bucket, Integer limitType, RealNameAuthorizeReqVO reqVO) throws Exception{
|
|
|
List<String> imgUrls = new ArrayList<>();
|
|
|
//判断file数组不能为空并且长度大于0
|
|
|
if(multipartFiles==null||multipartFiles.length!=2){
|
|
|
throw new GatewayException(400, "请上传身份证正反面!");
|
|
|
}
|
|
|
|
|
|
//每天:记录一个累加的次数 ,超过一定的数量不允许继续调
|
|
|
Date currentTime = new Date();
|
|
|
SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMdd");
|
|
|
String dayStr = formatter.format(currentTime);
|
|
|
Long count = cacheService.getPhotoCheckCount(dayStr,reqVO.getUid());
|
|
|
logger.info("zhiMaCertUploadPhotoAndCheck getPhotoCheckCount count {},reqVO {} ",count,reqVO);
|
|
|
if(count!=null&&count>=maxPhotoCheckCount){
|
|
|
throw new GatewayException(400, "超过当日最大调用次数!");
|
|
|
}
|
|
|
|
|
|
//次数加1
|
|
|
cacheService.incrementPhotoCheckCount(dayStr,reqVO.getUid());
|
|
|
|
|
|
//循环获取file数组中得文件
|
|
|
ImageBO frontUploadModel=null;
|
|
|
ImageBO backUploadModel=null;
|
|
|
for (int i = 0; i < multipartFiles.length; i++) {
|
|
|
MultipartFile multipartFile = multipartFiles[i];
|
|
|
//保存文件
|
|
|
ImageBO tmpBO = getUploadImagePath(multipartFile, bucket, String.valueOf(reqVO.getUid()), limitType);
|
|
|
imgUrls.add(tmpBO.getImageUrl());
|
|
|
if(i==0){
|
|
|
tmpBO.setImageSide("front");
|
|
|
frontUploadModel = tmpBO;
|
|
|
}else{
|
|
|
tmpBO.setImageSide("back");
|
|
|
backUploadModel = tmpBO;
|
|
|
}
|
|
|
}
|
|
|
//调用接口,ocr验证
|
|
|
boolean pass = checkCertPhoto(Lists.newArrayList(frontUploadModel ,backUploadModel) ,reqVO);
|
|
|
if(!pass){
|
|
|
throw new GatewayException(400, "身份证图片校验不通过!");
|
|
|
}
|
|
|
|
|
|
return imgUrls;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 调用通用的图片验证ocr
|
|
|
* @param imageBOList
|
|
|
* @param reqVO
|
|
|
* @return
|
|
|
*/
|
|
|
private boolean checkCertPhoto(List<ImageBO> imageBOList,RealNameAuthorizeReqVO reqVO){
|
|
|
try{
|
|
|
ImageReviewedReq req=new ImageReviewedReq();
|
|
|
req.setUid(reqVO.getUid());
|
|
|
req.setImageBOList(imageBOList);
|
|
|
req.setBusinessLine("ufo");
|
|
|
req.setSceneName("SELLER_IDCARD_RECOGNIZE");
|
|
|
req.setContext(contextPath);
|
|
|
|
|
|
//调用校验,然后直接返回
|
|
|
logger.info("checkCertPhoto call begin reqVO {} ,req {}",reqVO, JSON.toJSONString(req));
|
|
|
|
|
|
ImageReviewResp resp =null;
|
|
|
logger.info("checkCertPhoto call end reqVO {} ,req {} ,resp {} ",reqVO,JSON.toJSONString(req),JSON.toJSONString(resp));
|
|
|
//比较信息
|
|
|
|
|
|
}catch (Exception e){
|
|
|
logger.warn("checkCertPhoto error reqVO {}",reqVO,e);
|
|
|
throw new UfoServiceException(400,"图片检查异常");
|
|
|
}
|
|
|
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
public ImageBO getUploadImagePath(MultipartFile multipartFile, String bucket, String uid, Integer limitType) throws Exception {
|
|
|
//文件为空
|
|
|
if (multipartFile.isEmpty()) {
|
|
|
logger.warn("upload file is empty");
|
|
|
throw new FileNotFoundException("上传文件为空");
|
|
|
}
|
|
|
|
|
|
// bucket必须为系统已定义常量
|
|
|
if (!"yohocard".equals(bucket)) {
|
|
|
logger.warn("can't find upload bucket {}", bucket);
|
|
|
throw new Exception("上传Bucket:" + bucket + "无效");
|
|
|
}
|
|
|
|
|
|
String imageFileName = multipartFile.getOriginalFilename();
|
|
|
long imageFileSize = multipartFile.getSize();
|
|
|
//产品需求:百度云要求图片大小4M
|
|
|
boolean flag = StringUtils.contains(imageFileName, ".jpeg") ||
|
|
|
StringUtils.contains(imageFileName, ".jpg") || StringUtils.contains(imageFileName, ".png");
|
|
|
if(!flag){
|
|
|
logger.warn("upload file type not correct {}",imageFileName);
|
|
|
throw new FileNotFoundException("上传文件为空");
|
|
|
}
|
|
|
if (imageFileSize >= 4*1024*1024) {
|
|
|
logger.warn("upload images exceeded imageSize {}", imageFileSize);
|
|
|
DecimalFormat decimalFormat = new DecimalFormat("#.00");
|
|
|
throw new Exception("上传图片实际大小:" + decimalFormat.format(imageFileSize / 1024.0) + "KB,超过了图片默认值" );
|
|
|
}
|
|
|
|
|
|
String fileMode = "01";
|
|
|
logger.info("upload image bucket is {}, fileMode is {}", bucket, fileMode);
|
|
|
|
|
|
String saveName = new SimpleDateFormat("/yyyy/MM/dd/HH/").format(new Date());
|
|
|
String fileName = fileMode
|
|
|
+ DigestUtils.md5Hex(uid + "_" + System.currentTimeMillis() + multipartFile.getOriginalFilename())
|
|
|
+ multipartFile.getOriginalFilename().substring(multipartFile.getOriginalFilename().indexOf("."));
|
|
|
// 文件保存路径
|
|
|
String filePath = saveDir + File.separator + fileName;
|
|
|
File uploadFile = new File(filePath);
|
|
|
multipartFile.transferTo(uploadFile);
|
|
|
|
|
|
checkFilePixels(uploadFile, limitType);
|
|
|
|
|
|
String imgUrl = iqnUploadService.upload(uploadFile, bucket, saveName + fileName);
|
|
|
|
|
|
ImageBO imageBO = new ImageBO();
|
|
|
imageBO.setFileByte(FileUtils.readFileToByteArray(uploadFile));
|
|
|
imageBO.setImageUrl(imgUrl);
|
|
|
//删除文件
|
|
|
uploadFile.delete();
|
|
|
return imageBO;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 根据配置,校验每种场景的图片是否符合规范
|
|
|
*
|
|
|
* @param uploadFile
|
|
|
* @param limitType
|
|
|
*/
|
|
|
private void checkFilePixels(File uploadFile, Integer limitType) throws Exception {
|
|
|
if (null == limitType) {
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
logger.info("method checkFilePixels exceute.");
|
|
|
|
|
|
BufferedImage sourceImg = null;
|
|
|
|
|
|
try {
|
|
|
sourceImg = ImageIO.read(java.nio.file.Files.newInputStream(uploadFile.toPath()));
|
|
|
|
|
|
} catch (IOException e) {
|
|
|
logger.warn("ImageIO read find wrong uploadFile {}",uploadFile , e);
|
|
|
throw new GatewayException( 400,"上传文件失败");
|
|
|
}
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
public AuthorizeResultRespVO zhiMaCertWithPhotoInit(RealNameAuthorizeReqVO reqVO){
|
|
|
logger.info("real name zhiMaCertWithPhotoInit reqVO {}", reqVO);
|
|
|
boolean justCheckPhoto = false;
|
|
|
int uid = reqVO.getUid();
|
|
|
ZhiMaCert zhiMaCert = this.getValidZhiMaCert(uid);
|
|
|
if(zhiMaCert!=null){
|
|
|
if(1==zhiMaCert.getValidPhoto()){
|
|
|
//已经有照片了
|
|
|
throw new UfoServiceException(400, "已实名认证!");
|
|
|
}else{
|
|
|
//只是缺少照片,只是验证照片即可
|
|
|
justCheckPhoto = true;
|
|
|
}
|
|
|
}else{
|
|
|
//检查身份证号认证信息是否已经存在,存在则不允许再次使用
|
|
|
if (null != zhiMaCertDao.selectValidByCertNo(reqVO.getCertNo())) {
|
|
|
throw new UfoServiceException(400, "身份证号已被占用!");
|
|
|
}
|
|
|
}
|
|
|
|
|
|
logger.info("real name zhiMaCertWithPhotoInit reqVO {} ,justCheckPhoto {}", reqVO,justCheckPhoto);
|
|
|
|
|
|
String imgUrl = reqVO.getFrontImageUrl()+","+reqVO.getBackImageUrl();
|
|
|
|
|
|
if(justCheckPhoto){
|
|
|
//TODO 兼容原来老数据,只需要更新照片信息
|
|
|
zhiMaCertDao.updatePhotoToValidByPK(zhiMaCert.getId(),imgUrl);
|
|
|
AuthorizeResultRespVO vo = new AuthorizeResultRespVO();
|
|
|
vo.setCallZhiMa("0");
|
|
|
return vo;
|
|
|
}
|
|
|
|
|
|
//新的芝麻认证
|
|
|
AuthorizeResultRespVO vo = callZhiMaForUrl(reqVO,imgUrl);
|
|
|
vo.setCallZhiMa("1");
|
|
|
return vo;
|
|
|
}
|
|
|
|
|
|
|
|
|
@Override
|
|
|
public AuthorizeResultRespVO zhiMaCertInit(RealNameAuthorizeReqVO reqVO) {
|
|
|
logger.info("real name zhiMaCertInit reqVO {}", reqVO);
|
...
|
...
|
@@ -364,6 +571,11 @@ public class RealNameAuthorizeServiceImpl implements IRealNameAuthorizeService { |
|
|
throw new UfoServiceException(400, "身份证号已被占用!");
|
|
|
}
|
|
|
|
|
|
AuthorizeResultRespVO vo = callZhiMaForUrl(reqVO,"");
|
|
|
return vo;
|
|
|
}
|
|
|
|
|
|
private AuthorizeResultRespVO callZhiMaForUrl(RealNameAuthorizeReqVO reqVO,String imgUrl){
|
|
|
//调用芝麻接口,返回biz_no
|
|
|
//构建唯一的 transaction_id : ufoCert+id
|
|
|
Long nowSecond = LocalDateTime.now().toEpochSecond(ZoneOffset.of("+8"));
|
...
|
...
|
@@ -377,6 +589,14 @@ public class RealNameAuthorizeServiceImpl implements IRealNameAuthorizeService { |
|
|
zhiMaCert.setCreateTime(nowSecond);
|
|
|
zhiMaCert.setUpdateTime(nowSecond);
|
|
|
|
|
|
//图片信息
|
|
|
if(StringUtils.isNotBlank(imgUrl)){
|
|
|
zhiMaCert.setValidPhoto(1);
|
|
|
zhiMaCert.setImageUrl(imgUrl);
|
|
|
}else{
|
|
|
zhiMaCert.setValidPhoto(0);
|
|
|
}
|
|
|
|
|
|
zhiMaCertDao.insertAndGetID(zhiMaCert);
|
|
|
|
|
|
if(zhiMaCert.getId()==null||zhiMaCert.getId()<1){
|
...
|
...
|
|