package com.feng1.foundation.service.impl;
import com.alibaba.fastjson.JSONException;
import com.alibaba.fastjson.JSONObject;
import com.feng1.foundation.dto.BankCardInfoDTO;
import com.feng1.foundation.dto.IdentityCardInfoDTO;
import com.feng1.foundation.po.*;
import com.feng1.foundation.service.IDictionaryService;
import com.feng1.foundation.service.IImageRecognitionService;
import com.feng1.foundation.service.vo.DictionaryItemVO;
import com.feng1.framework.common.domain.result.ModelResult;
import com.feng1.framework.common.domain.result.ModelResultClient;
import com.feng1.framework.common.http.HttpClient;
import com.feng1.framework.util.DateUtil;
import com.feng1.framework.util.JsonUtils;
import com.google.common.collect.Lists;
import okhttp3.MediaType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RestController;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.*;
import static org.apache.commons.codec.binary.Base64.encodeBase64;
@RestController
public class ImageRecognitionServiceImpl implements IImageRecognitionService {
private static final Logger LOGGER = LoggerFactory.getLogger(ImageRecognitionServiceImpl.class);
@Autowired
HttpClient httpClient;
@Autowired
IDictionaryService dictionaryService;
@Value("${imageRecognition.idCardHost}")
private String idCardHost;
@Value("${imageRecognition.idCardServicePath}")
private String idCardServicePath;
@Value("${imageRecognition.appcode}")
private String appcode;
@Value("${imageRecognition.qiniuPath}")
private String qiniuPath;
@Value("${imageRecognition.bankCardHost}")
private String bankCardHost;
@Value("${imageRecognition.bankCardServicePath}")
private String bankCardServicePath;
/**
* 获取参数的json对象
*/
public static JSONObject getParam(int type, String dataValue) {
JSONObject obj = new JSONObject();
try {
obj.put("dataType", type);
obj.put("dataValue", dataValue);
} catch (JSONException e) {
LOGGER.error("JSONException",e);
}
return obj;
}
@Override
public ModelResult<IdentityCardInfoDTO> identityCardRecognition(String imagePath) {
String imgFilePath = qiniuPath +"/"+ imagePath;
//String imgFilePath ="https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1531919752737&di=8f489a54cd0e4beb43c424858cdb9a09&imgtype=0&src=http%3A%2F%2Fcq.focus.cn%2Fupload%2Fphotos%2F1760%2F7Nh8JmKZ.jpg";
//如果文档的输入中含有inputs字段,设置为True, 否则设置为False
//获取图片文件
File imageFile = getImageFile(imgFilePath);
//请根据线上文档修改configure字段
JSONObject configObj = new JSONObject();
configObj.put("side", "face");
String config_str = configObj.toString();
// 对图像进行base64编码
String imgBase64 = "";
try {
byte[] content = new byte[(int) imageFile.length()];
FileInputStream finputstream = new FileInputStream(imageFile);
finputstream.read(content);
finputstream.close();
imgBase64 = new String(encodeBase64(content));
} catch (IOException e) {
e.printStackTrace();
return new ModelResultClient<IdentityCardInfoDTO>().failFactory("-1","IO异常");
}
// 拼装请求body的json字符串
JSONObject requestObj = new JSONObject();
try {
requestObj.put("image", imgBase64);
if(config_str.length() > 0) {
requestObj.put("configure", config_str);
}
} catch (JSONException e) {
e.printStackTrace();
}
String bodys = requestObj.toString();
IdentityCardInfoResult identityCardInfoResult =null;
try {
String res = httpClient.httpPostForImageRecog(idCardHost + idCardServicePath, bodys, MediaType.parse("application/x-www-form-urlencoded"),appcode);
identityCardInfoResult = JsonUtils.jsonToBean(res, IdentityCardInfoResult.class);
} catch (Exception e) {
e.printStackTrace();
}
if(!"true".equalsIgnoreCase(identityCardInfoResult.getSuccess())){
imageFile.delete();
return new ModelResultClient<IdentityCardInfoDTO>().failFactory(identityCardInfoResult.getCode(),identityCardInfoResult.getMessage());
}
IdentityCardInfoDTO identityCardInfoDTO = new IdentityCardInfoDTO();
String birth = identityCardInfoResult.getBirth();
Date yyyyMMdd = DateUtil.parseDate(birth, "yyyy-MM-dd");
int diffMonth = DateUtil.diffMonth(yyyyMMdd,new Date());
int age = diffMonth / 12;
BeanUtils.copyProperties(identityCardInfoResult,identityCardInfoDTO);
identityCardInfoDTO.setAge(age);
imageFile.delete();
return new ModelResultClient<IdentityCardInfoDTO>().successFactory(identityCardInfoDTO);
}
@Override
public ModelResult<BankCardInfoDTO> bankCardRecognition(String imagePath) {
String imgFilePath = qiniuPath +"/"+ imagePath;
File imageFile = getImageFile(imgFilePath);
String imgBase64 = "";
try {
byte[] content = new byte[(int) imageFile.length()];
FileInputStream finputstream = new FileInputStream(imageFile);
finputstream.read(content);
finputstream.close();
imgBase64 = new String(encodeBase64(content));
} catch (IOException e) {
e.printStackTrace();
return new ModelResultClient<BankCardInfoDTO>().failFactory("-1","IO异常");
}
JSONObject imageBody = new JSONObject();
imageBody.put("dataType",50);
imageBody.put("dataValue",imgBase64);
JSONObject imageBodyOutSide = new JSONObject();
imageBodyOutSide.put("image",imageBody);
List<JSONObject> objects = Lists.newArrayList();
objects.add(imageBodyOutSide);
JSONObject requestBody = new JSONObject();
requestBody.put("inputs",objects);
String requestString = requestBody.toString();
BankCardInfoResult bankCardInfoResult = new BankCardInfoResult();
try {
//最后在header中的格式(中间是英文空格)为Authorization:APPCODE 83359fd73fe94948385f570e3c139105
String res = httpClient.httpPostForImageRecog(bankCardHost + bankCardServicePath, requestString, MediaType.parse("application/json;charset=utf-8"),appcode);
bankCardInfoResult= JsonUtils.jsonToBean(res, BankCardInfoResult.class);
} catch (Exception e) {
LOGGER.error("调用阿里银行卡图像识别接口失败",e);
}
List<BankCardOutput> outputs = bankCardInfoResult.getOutputs();
BankCardOutput bankCardOutput = outputs.get(0);
BankCardOutputValue outputValue = bankCardOutput.getOutputValue();
String dataValue = outputValue.getDataValue();
BankCardDataValue bankCardDataValue = JsonUtils.jsonToBean(dataValue, BankCardDataValue.class);
String successRes = bankCardDataValue.getSuccess();
if(!"true".equalsIgnoreCase(successRes)){
imageFile.delete();
return new ModelResultClient<BankCardInfoDTO>().failFactory();
}
//获取银行卡号
String card_num = bankCardDataValue.getCard_num();
String res =null;
try {
res = httpClient.httpGet("https://ccdcapi.alipay.com/validateAndCacheCardInfo.json?cardNo="+card_num+"&cardBinCheck=true");
} catch (IOException e) {
LOGGER.error("根据银行卡号调用接口查询银行信息失败",e);
}
BankNamePO bankNamePO = JsonUtils.jsonToBean(res, BankNamePO.class);
if("true".equalsIgnoreCase(successRes) && "false".equalsIgnoreCase(bankNamePO.getValidated())){
imageFile.delete();
return new ModelResultClient<BankCardInfoDTO>().failFactory("未找到匹配的银行信息");
}
//获取的是银行缩写,须查询数据字典
String bank = bankNamePO.getBank();
BankCardInfoDTO bankCardInfoDTO = new BankCardInfoDTO();
bankCardInfoDTO.setBankCardNum(card_num);
bankCardInfoDTO.setBankCode(bank);
ModelResult<List<DictionaryItemVO>> bankNameResult = dictionaryService.getDictItems("BankName");
List<DictionaryItemVO> bankList = bankNameResult.getData();
for (DictionaryItemVO dictionaryItemVO : bankList) {
if(dictionaryItemVO.getValue().equalsIgnoreCase(bank)){
bankCardInfoDTO.setBankName(dictionaryItemVO.getLabel());
break;
}
}
imageFile.delete();
return new ModelResultClient<BankCardInfoDTO>().successFactory(bankCardInfoDTO);
}
private File getImageFile(String imgFilePath){
URL url = null;
File imageFile =null;
try {
//new一个URL对象
url = new URL(imgFilePath);
//打开链接
HttpURLConnection conn = (HttpURLConnection)url.openConnection();
//设置请求方式为"GET"
conn.setRequestMethod("GET");
//超时响应时间为5秒
conn.setConnectTimeout(5 * 1000);
//通过输入流获取图片数据
InputStream inStream = conn.getInputStream();
//得到图片的二进制数据,以二进制封装得到数据,具有通用性
byte[] data = readInputStream(inStream);
//new一个文件对象用来保存图片,默认保存当前工程根目录
imageFile = new File("BeautyGirl"+UUID.randomUUID()+".jpg");
//创建输出流
FileOutputStream outStream = new FileOutputStream(imageFile);
//写入数据
outStream.write(data);
//关闭输出流
outStream.close();
} catch (Exception e) {
LOGGER.error("根据七牛云图片url生成图片文件异常"+e);
}
return imageFile;
}
private static byte[] readInputStream(InputStream inStream) throws Exception{
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
//创建一个Buffer字符串
byte[] buffer = new byte[1024];
//每次读取的字符串长度,如果为-1,代表全部读取完毕
int len = 0;
//使用一个输入流从buffer里把数据读取出来
while( (len=inStream.read(buffer)) != -1 ){
//用输出流往buffer里写入数据,中间参数代表从哪个位置开始读,len代表读取的长度
outStream.write(buffer, 0, len);
}
//关闭输入流
inStream.close();
//把outStream里的数据写入内存
return outStream.toByteArray();
}
}