|
@@ -6,21 +6,30 @@ package com.ruoyi.common.utils;
|
|
|
* @Describe:
|
|
|
*/
|
|
|
|
|
|
+import cn.hutool.http.HttpUtil;
|
|
|
+import com.ruoyi.common.core.redis.RedisCache;
|
|
|
import com.alibaba.fastjson2.JSON;
|
|
|
import com.alibaba.fastjson2.JSONObject;
|
|
|
-import com.ruoyi.common.utils.FileUtil;
|
|
|
-import com.ruoyi.common.utils.HttpUtil;
|
|
|
-import okhttp3.*;
|
|
|
+import com.ruoyi.common.core.domain.AjaxResult;
|
|
|
+import com.ruoyi.common.core.domain.IdCardVo;
|
|
|
+import org.springframework.beans.factory.annotation.Autowired;
|
|
|
+import org.springframework.stereotype.Component;
|
|
|
|
|
|
import javax.crypto.Cipher;
|
|
|
import javax.crypto.spec.SecretKeySpec;
|
|
|
import java.io.IOException;
|
|
|
+import java.io.UnsupportedEncodingException;
|
|
|
import java.net.URLEncoder;
|
|
|
+import java.nio.file.Files;
|
|
|
+import java.nio.file.Paths;
|
|
|
import java.util.Base64;
|
|
|
+import java.util.HashMap;
|
|
|
import java.util.Map;
|
|
|
+import java.util.concurrent.TimeUnit;
|
|
|
|
|
|
-public class IdCardUtil {
|
|
|
+import static com.ruoyi.common.constant.CommonConstants.*;
|
|
|
|
|
|
+public class IdCardUtil {
|
|
|
/**
|
|
|
* 重要提示代码中所需工具类
|
|
|
* FileUtil,HttpUtil请从
|
|
@@ -31,11 +40,8 @@ public class IdCardUtil {
|
|
|
* https://cloud.baidu.com/doc/OCR/s/rk3h7xzck 文档地址
|
|
|
*/
|
|
|
|
|
|
- // 请求url
|
|
|
- static String url = "https://aip.baidubce.com/rest/2.0/ocr/v1/idcard";
|
|
|
-
|
|
|
- // aes key 从console控制台获取
|
|
|
- static String aesKey = "[16位 aeskey]";
|
|
|
+ // aes key 从console控制台获取 身份证识别使用
|
|
|
+ static String aesKey = "ce539dc069ad0908";
|
|
|
|
|
|
static byte[] originAesKey = null;
|
|
|
|
|
@@ -117,46 +123,47 @@ public class IdCardUtil {
|
|
|
* },
|
|
|
* "words_result_num": 6
|
|
|
* }
|
|
|
+ * <p>
|
|
|
+ * <p>
|
|
|
+ * {
|
|
|
+ * "words_result": {
|
|
|
+ * "失效日期": {
|
|
|
+ * "words": "20390711",
|
|
|
+ * "location": {
|
|
|
+ * "top": 445,
|
|
|
+ * "left": 523,
|
|
|
+ * "width": 153,
|
|
|
+ * "height": 38
|
|
|
+ * }
|
|
|
+ * },
|
|
|
+ * "签发机关": {
|
|
|
+ * "words": "陆丰市公安局",
|
|
|
+ * "location": {
|
|
|
+ * "top": 377,
|
|
|
+ * "left": 339,
|
|
|
+ * "width": 195,
|
|
|
+ * "height": 38
|
|
|
+ * }
|
|
|
+ * },
|
|
|
+ * "签发日期": {
|
|
|
+ * "words": "20190606",
|
|
|
+ * "location": {
|
|
|
+ * "top": 445,
|
|
|
+ * "left": 343,
|
|
|
+ * "width": 152,
|
|
|
+ * "height": 38
|
|
|
+ * }
|
|
|
+ * }
|
|
|
+ * },
|
|
|
+ * "log_id": "1559208562721579328",
|
|
|
+ * "words_result_num": 3,
|
|
|
+ * "error_code": 0,
|
|
|
+ * "image_status": "normal"
|
|
|
+ * }
|
|
|
*
|
|
|
- *
|
|
|
- {
|
|
|
- "words_result": {
|
|
|
- "失效日期": {
|
|
|
- "words": "20390711",
|
|
|
- "location": {
|
|
|
- "top": 445,
|
|
|
- "left": 523,
|
|
|
- "width": 153,
|
|
|
- "height": 38
|
|
|
- }
|
|
|
- },
|
|
|
- "签发机关": {
|
|
|
- "words": "陆丰市公安局",
|
|
|
- "location": {
|
|
|
- "top": 377,
|
|
|
- "left": 339,
|
|
|
- "width": 195,
|
|
|
- "height": 38
|
|
|
- }
|
|
|
- },
|
|
|
- "签发日期": {
|
|
|
- "words": "20190606",
|
|
|
- "location": {
|
|
|
- "top": 445,
|
|
|
- "left": 343,
|
|
|
- "width": 152,
|
|
|
- "height": 38
|
|
|
- }
|
|
|
- }
|
|
|
- },
|
|
|
- "log_id": "1559208562721579328",
|
|
|
- "words_result_num": 3,
|
|
|
- "error_code": 0,
|
|
|
- "image_status": "normal"
|
|
|
- }
|
|
|
* @return
|
|
|
*/
|
|
|
- public static JSONObject idCard(String image) {
|
|
|
+ public static AjaxResult idCard(String image, String idCardSide) {
|
|
|
try {
|
|
|
// 文件路径
|
|
|
byte[] imgData = FileUtil.readFileByBytes(image);
|
|
@@ -164,22 +171,38 @@ public class IdCardUtil {
|
|
|
String imgStr = encryptImg(aesKey, imgData);
|
|
|
|
|
|
String imgParam = URLEncoder.encode(imgStr, "UTF-8");
|
|
|
-
|
|
|
- String param = "id_card_side=" + "front" +
|
|
|
+ String url = "https://aip.baidubce.com/rest/2.0/ocr/v1/idcard";
|
|
|
+ //-front:身份证含照片的一面
|
|
|
+ //-back:身份证带国徽的一面
|
|
|
+ //自动检测身份证正反面,如果传参指定方向与图片相反,支持正常识别,返回参数image_status字段为"reversed_side"
|
|
|
+ String param = "id_card_side=" + idCardSide +
|
|
|
"&image=" + imgParam +
|
|
|
"&AESEncry=" + true;
|
|
|
-
|
|
|
- String accessToken = getAccessToken();
|
|
|
-
|
|
|
- String encryptResult = HttpUtil.post(url, accessToken, param);
|
|
|
-
|
|
|
+ String accessToken = getAccessToken("TvvuZOOh7MgnlDFnw11ln67n", "CY47OI0eKAzYBD2LO55SM3OITzsyq6DK");
|
|
|
+ String encryptResult = HttpUtils.post(url, accessToken, param);
|
|
|
String decryptResult = parseResult(encryptResult);
|
|
|
JSONObject jsonObject = JSON.parseObject(decryptResult);
|
|
|
- return jsonObject;
|
|
|
+ String wordsResult = jsonObject.getString("words_result");
|
|
|
+ Map<String,Object> map = new HashMap<>(3);
|
|
|
+ if (StringUtils.isNotEmpty(wordsResult)){
|
|
|
+ JSONObject jsonObjectWordsResult = JSON.parseObject(wordsResult);
|
|
|
+ if (FRONT.equals(idCardSide)){
|
|
|
+ String name = JSON.parseObject(jsonObjectWordsResult.getString("姓名")).getString("words");
|
|
|
+ String address = JSON.parseObject(jsonObjectWordsResult.getString("住址")).getString("words");
|
|
|
+ String idCard = JSON.parseObject(jsonObjectWordsResult.getString("公民身份号码")).getString("words");
|
|
|
+ map.put("realName",name);
|
|
|
+ map.put("address",address);
|
|
|
+ map.put("idCard",idCard);
|
|
|
+ }else if (BACK.equals(idCardSide)){
|
|
|
+ String date = JSON.parseObject(jsonObjectWordsResult.getString("失效日期")).getString("words");
|
|
|
+ map.put("expirationDate",date);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return AjaxResult.success(map);
|
|
|
} catch (Exception e) {
|
|
|
e.printStackTrace();
|
|
|
}
|
|
|
- return null;
|
|
|
+ return AjaxResult.error();
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -320,9 +343,6 @@ public class IdCardUtil {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-
|
|
|
- static final OkHttpClient HTTP_CLIENT = new OkHttpClient().newBuilder().build();
|
|
|
-
|
|
|
/**
|
|
|
* 营业执照识别
|
|
|
* 重要提示代码中所需工具类
|
|
@@ -333,7 +353,7 @@ public class IdCardUtil {
|
|
|
* https://ai.baidu.com/file/470B3ACCA3FE43788B5A963BF0B625F3
|
|
|
* 下载
|
|
|
*/
|
|
|
- public static JSONObject businessLicense(String image) {
|
|
|
+ public static AjaxResult businessLicense(String image) {
|
|
|
// 请求url
|
|
|
String url = "https://aip.baidubce.com/rest/2.0/ocr/v1/business_license";
|
|
|
try {
|
|
@@ -341,13 +361,9 @@ public class IdCardUtil {
|
|
|
byte[] imgData = FileUtil.readFileByBytes(image);
|
|
|
String imgStr = com.ruoyi.common.utils.Base64Util.encode(imgData);
|
|
|
String imgParam = URLEncoder.encode(imgStr, "UTF-8");
|
|
|
-
|
|
|
String param = "image=" + imgParam;
|
|
|
-
|
|
|
- // 注意这里仅为了简化编码每一次请求都去获取access_token,线上环境access_token有过期时间, 客户端可自行缓存,过期后重新获取。
|
|
|
- String accessToken = IdCardUtil.getAccessToken();
|
|
|
-
|
|
|
- String result = HttpUtil.post(url, accessToken, param);
|
|
|
+ String accessToken = getAccessToken("TvvuZOOh7MgnlDFnw11ln67n", "CY47OI0eKAzYBD2LO55SM3OITzsyq6DK");
|
|
|
+ String result = HttpUtils.post(url, accessToken, param);
|
|
|
/**
|
|
|
*
|
|
|
{
|
|
@@ -503,51 +519,123 @@ public class IdCardUtil {
|
|
|
}
|
|
|
*/
|
|
|
JSONObject jsonObject = JSONObject.parseObject(result);
|
|
|
- return jsonObject;
|
|
|
+ String wordsResult = jsonObject.getString("words_result");
|
|
|
+ Map<String,Object> map = new HashMap<>(8);
|
|
|
+ if (StringUtils.isNotEmpty(wordsResult)){
|
|
|
+ JSONObject jsonObjectWordsResult = JSON.parseObject(wordsResult);
|
|
|
+ String creditCode = JSON.parseObject(jsonObjectWordsResult.getString("社会信用代码")).getString("words");
|
|
|
+ String enterpriseName = JSON.parseObject(jsonObjectWordsResult.getString("单位名称")).getString("words");
|
|
|
+ String enterpriseType = JSON.parseObject(jsonObjectWordsResult.getString("类型")).getString("words");
|
|
|
+ String enterpriseAddress = JSON.parseObject(jsonObjectWordsResult.getString("地址")).getString("words");
|
|
|
+ String legalName = JSON.parseObject(jsonObjectWordsResult.getString("法人")).getString("words");
|
|
|
+ String registeredCapital = JSON.parseObject(jsonObjectWordsResult.getString("注册资本")).getString("words");
|
|
|
+ String establishData = JSON.parseObject(jsonObjectWordsResult.getString("成立日期")).getString("words");
|
|
|
+ String businessTerm = JSON.parseObject(jsonObjectWordsResult.getString("有效期")).getString("words");
|
|
|
+ map.put("creditCode",creditCode);
|
|
|
+ map.put("enterpriseName",enterpriseName);
|
|
|
+ map.put("enterpriseType",enterpriseType);
|
|
|
+ map.put("enterpriseAddress",enterpriseAddress);
|
|
|
+ map.put("legalName",legalName);
|
|
|
+ map.put("registeredCapital",registeredCapital);
|
|
|
+ map.put("establishData",establishData);
|
|
|
+ map.put("businessTerm",businessTerm);
|
|
|
+ }
|
|
|
+ return AjaxResult.success(map);
|
|
|
} catch (Exception e) {
|
|
|
e.printStackTrace();
|
|
|
}
|
|
|
- return null;
|
|
|
+ return AjaxResult.error();
|
|
|
}
|
|
|
+
|
|
|
/**
|
|
|
- * 获取百度开放平台的AccessToken
|
|
|
- * @return
|
|
|
+ * 人脸识别
|
|
|
+ *
|
|
|
+ * @throws IOException
|
|
|
*/
|
|
|
- public static String getAccessToken() {
|
|
|
- MediaType mediaType = MediaType.parse("application/json");
|
|
|
- RequestBody body = RequestBody.create(mediaType, "");
|
|
|
- String url = "https://aip.baidubce.com/oauth/2.0/token";
|
|
|
+ public static AjaxResult sample(IdCardVo idCardVo) {
|
|
|
+ String image = idCardVo.getImage();
|
|
|
+ String idCardNumber = idCardVo.getIdCard();
|
|
|
+ String name = idCardVo.getName();
|
|
|
+ if (StringUtils.isEmpty(image) || StringUtils.isEmpty(idCardNumber) || StringUtils.isEmpty(name)) {
|
|
|
+ return AjaxResult.error("参数不完整");
|
|
|
+ }
|
|
|
+ // image 可以通过 getFileContentAsBase64("C:\fakepath\1675840208844.png") 方法获取,如果Content-Type是application/x-www-form-urlencoded时,第二个参数传true
|
|
|
+ HashMap<String, Object> paramMap = new HashMap<>();
|
|
|
+ paramMap.put("access_token", getAccessToken("OmTDmo9hv4wll1ReYiRNJEfz", "vqnio9p7C17nbrkVar0MrHU4KOz2OXOr"));
|
|
|
+ paramMap.put("image", getFileContentAsBase64(image, false));
|
|
|
+ paramMap.put("image_type", "BASE64");
|
|
|
+ paramMap.put("id_card_number", idCardNumber);
|
|
|
+ paramMap.put("name", name);
|
|
|
+ paramMap.put("spoofing_control", "NORMAL");
|
|
|
+ paramMap.put("quality_control", "NORMAL");
|
|
|
+ //返回值
|
|
|
+ String post = HttpUtil.post("https://aip.baidubce.com/rest/2.0/face/v4/mingjing/verify", paramMap);
|
|
|
/**
|
|
|
- * grant_type: 必须参数,固定为client_credentials;
|
|
|
- * client_id: 必须参数,应用的API Key;
|
|
|
- * client_secret: 必须参数,应用的Secret Key;
|
|
|
+ * {
|
|
|
+ * "log_id": 1370579072568000512,
|
|
|
+ * "result": {
|
|
|
+ * "score": 40.884,
|
|
|
+ * "verify_status": 0
|
|
|
+ * },
|
|
|
+ * "dec_image": "/9j/4AAQSkZJRgABAgAAAQABAAD",
|
|
|
+ * "risk_level": "3",
|
|
|
+ * "risk_tag": [
|
|
|
+ * "若判断为有风险,则会有风险标签json 数组告知风险类型,如:general_inject"
|
|
|
+ * ]
|
|
|
+ * }
|
|
|
*/
|
|
|
- String grantType = "client_credentials";
|
|
|
- String clientId = "11111111111111";
|
|
|
- String clientSecret = "22222222222222222";
|
|
|
- String apiUrl = String.format("%s?grant_type=%s&client_id=%s&client_secret=%s",
|
|
|
- url, grantType, clientId, clientSecret);
|
|
|
-
|
|
|
- Request request = new Request.Builder()
|
|
|
- .url(apiUrl)
|
|
|
- .method("POST", body)
|
|
|
- .addHeader("Content-Type", "application/json")
|
|
|
- .addHeader("Accept", "application/json")
|
|
|
- .build();
|
|
|
- Response response = null;
|
|
|
+ JSONObject jsonObject = JSONObject.parseObject(post);
|
|
|
+ Map<String, Object> map = new HashMap<>();
|
|
|
+ return AjaxResult.success(map);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取文件base64编码
|
|
|
+ *
|
|
|
+ * @param path 文件路径
|
|
|
+ * @param urlEncode 如果Content-Type是application/x-www-form-urlencoded时,传true
|
|
|
+ * @return base64编码信息,不带文件头
|
|
|
+ * @throws IOException IO异常
|
|
|
+ */
|
|
|
+ static String getFileContentAsBase64(String path, boolean urlEncode) {
|
|
|
+ byte[] b = new byte[0];
|
|
|
try {
|
|
|
- response = HTTP_CLIENT.newCall(request).execute();
|
|
|
+ b = Files.readAllBytes(Paths.get(path));
|
|
|
} catch (IOException e) {
|
|
|
e.printStackTrace();
|
|
|
}
|
|
|
- //todo 判断是否成功调用
|
|
|
- //取出返回的access_token
|
|
|
- JSONObject jsonObject = null;
|
|
|
- String accessToken = null;
|
|
|
- if (response != null) {
|
|
|
- jsonObject = JSON.parseObject(response.toString());
|
|
|
- accessToken = jsonObject.getString("access_token");
|
|
|
+ String base64 = Base64.getEncoder().encodeToString(b);
|
|
|
+ if (urlEncode) {
|
|
|
+ try {
|
|
|
+ base64 = URLEncoder.encode(base64, "utf-8");
|
|
|
+ } catch (UnsupportedEncodingException e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
}
|
|
|
+ return base64;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取百度开放平台的AccessToken
|
|
|
+ * client_id: 必须参数,应用的API Key;
|
|
|
+ * client_secret: 必须参数,应用的Secret Key;不同的功能不同
|
|
|
+ *
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ public static String getAccessToken(String apiKey, String secretKey) {
|
|
|
+ String url = "https://aip.baidubce.com/oauth/2.0/token";
|
|
|
+ /**
|
|
|
+ *grant_type: 必须参数,固定为client_credentials;
|
|
|
+ *client_id: 必须参数,应用的API Key;
|
|
|
+ *client_secret: 必须参数,应用的Secret Key;
|
|
|
+ */
|
|
|
+ HashMap<String, Object> paramMap = new HashMap<>(3);
|
|
|
+ paramMap.put("grant_type", "client_credentials");
|
|
|
+ paramMap.put("client_id", apiKey);
|
|
|
+ paramMap.put("client_secret", secretKey);
|
|
|
+ String post = cn.hutool.http.HttpUtil.post(url, paramMap);
|
|
|
+ JSONObject jsonObject = JSONObject.parseObject(post);
|
|
|
+ String accessToken = jsonObject.getString("access_token");
|
|
|
return accessToken;
|
|
|
}
|
|
|
}
|