haogh 11 kuukautta sitten
commit
a24d7935bd
100 muutettua tiedostoa jossa 1375 lisäystä ja 0 poistoa
  1. 54 0
      .gitignore
  2. 3 0
      WebRoot/META-INF/MANIFEST.MF
  3. 6 0
      WebRoot/WEB-INF/classes/app.properties
  4. 21 0
      WebRoot/WEB-INF/classes/frame-res.properties
  5. 8 0
      WebRoot/WEB-INF/classes/jdbc.properties
  6. 8 0
      WebRoot/WEB-INF/classes/redis.properties
  7. BIN
      WebRoot/WEB-INF/lib/baidu-aip-sdk-4.11.1.jar
  8. BIN
      WebRoot/WEB-INF/lib/bcprov-jdk15on-1.62.jar
  9. BIN
      WebRoot/WEB-INF/lib/commons-codec-1.10.jar
  10. BIN
      WebRoot/WEB-INF/lib/commons-collections4-4.3.jar
  11. BIN
      WebRoot/WEB-INF/lib/commons-compress-1.18.jar
  12. BIN
      WebRoot/WEB-INF/lib/commons-fileupload-1.4.jar
  13. BIN
      WebRoot/WEB-INF/lib/commons-io-2.6.jar
  14. BIN
      WebRoot/WEB-INF/lib/commons-logging-1.2.jar
  15. BIN
      WebRoot/WEB-INF/lib/commons-pool2-2.9.0.jar
  16. BIN
      WebRoot/WEB-INF/lib/druid-1.1.9.jar
  17. BIN
      WebRoot/WEB-INF/lib/fastjson-1.2.28.jar
  18. BIN
      WebRoot/WEB-INF/lib/gson-2.8.5.jar
  19. BIN
      WebRoot/WEB-INF/lib/httpclient-4.5.7.jar
  20. BIN
      WebRoot/WEB-INF/lib/httpcore-4.4.11.jar
  21. BIN
      WebRoot/WEB-INF/lib/httpcore-nio-4.4.1.jar
  22. BIN
      WebRoot/WEB-INF/lib/httpmime-4.5.11.jar
  23. BIN
      WebRoot/WEB-INF/lib/itext7-barcodes-7.0.1.jar
  24. BIN
      WebRoot/WEB-INF/lib/itext7-font-asian-7.0.1.jar
  25. BIN
      WebRoot/WEB-INF/lib/itext7-forms-7.0.1.jar
  26. BIN
      WebRoot/WEB-INF/lib/itext7-hyph-7.0.1.jar
  27. BIN
      WebRoot/WEB-INF/lib/itext7-io-7.0.1.jar
  28. BIN
      WebRoot/WEB-INF/lib/itext7-itext-rups-7.0.1.jar
  29. BIN
      WebRoot/WEB-INF/lib/itext7-kernel-7.0.1.jar
  30. BIN
      WebRoot/WEB-INF/lib/itext7-layout-7.0.1.jar
  31. BIN
      WebRoot/WEB-INF/lib/itext7-pdfa-7.0.1.jar
  32. BIN
      WebRoot/WEB-INF/lib/itext7-pdftest-7.0.1.jar
  33. BIN
      WebRoot/WEB-INF/lib/itext7-sign-7.0.1.jar
  34. BIN
      WebRoot/WEB-INF/lib/javadbf.jar
  35. BIN
      WebRoot/WEB-INF/lib/jedis-3.2.0.jar
  36. BIN
      WebRoot/WEB-INF/lib/log4j-api-2.17.2.jar
  37. BIN
      WebRoot/WEB-INF/lib/log4j-core-2.17.2.jar
  38. BIN
      WebRoot/WEB-INF/lib/log4j-jcl-2.17.2.jar
  39. BIN
      WebRoot/WEB-INF/lib/log4j-slf4j-impl-2.17.2.jar
  40. BIN
      WebRoot/WEB-INF/lib/mysql-connector-j-8.0.32.jar
  41. BIN
      WebRoot/WEB-INF/lib/ojdbc8.jar
  42. BIN
      WebRoot/WEB-INF/lib/pay-chinapayfilesecure.jar
  43. BIN
      WebRoot/WEB-INF/lib/pay-chinapaysecure.jar
  44. BIN
      WebRoot/WEB-INF/lib/poi-4.1.0.jar
  45. BIN
      WebRoot/WEB-INF/lib/poi-excelant-4.1.0.jar
  46. BIN
      WebRoot/WEB-INF/lib/poi-ooxml-4.1.0.jar
  47. BIN
      WebRoot/WEB-INF/lib/poi-ooxml-schemas-4.1.0.jar
  48. BIN
      WebRoot/WEB-INF/lib/poi-scratchpad-4.1.0.jar
  49. BIN
      WebRoot/WEB-INF/lib/quartz-2.3.1.jar
  50. BIN
      WebRoot/WEB-INF/lib/quartz-jobs-2.3.1.jar
  51. BIN
      WebRoot/WEB-INF/lib/slf4j-api-1.7.25.jar
  52. BIN
      WebRoot/WEB-INF/lib/spring-aop-5.1.6.jar
  53. BIN
      WebRoot/WEB-INF/lib/spring-aspectjweaver-1.9.3.jar
  54. BIN
      WebRoot/WEB-INF/lib/spring-aspects-5.1.6.jar
  55. BIN
      WebRoot/WEB-INF/lib/spring-beans-5.1.6.jar
  56. BIN
      WebRoot/WEB-INF/lib/spring-context-5.1.6.jar
  57. BIN
      WebRoot/WEB-INF/lib/spring-context-indexer-5.1.6.jar
  58. BIN
      WebRoot/WEB-INF/lib/spring-context-support-5.1.6.jar
  59. BIN
      WebRoot/WEB-INF/lib/spring-core-5.1.6.jar
  60. BIN
      WebRoot/WEB-INF/lib/spring-expression-5.1.6.jar
  61. BIN
      WebRoot/WEB-INF/lib/spring-instrument-5.1.6.jar
  62. BIN
      WebRoot/WEB-INF/lib/spring-jdbc-5.1.6.jar
  63. BIN
      WebRoot/WEB-INF/lib/spring-jms-5.1.6.jar
  64. BIN
      WebRoot/WEB-INF/lib/spring-messaging-5.1.6.jar
  65. BIN
      WebRoot/WEB-INF/lib/spring-orm-5.1.6.jar
  66. BIN
      WebRoot/WEB-INF/lib/spring-oxm-5.1.6.jar
  67. BIN
      WebRoot/WEB-INF/lib/spring-tx-5.1.6.jar
  68. BIN
      WebRoot/WEB-INF/lib/spring-web-5.1.6.jar
  69. BIN
      WebRoot/WEB-INF/lib/spring-webmvc-5.1.6.jar
  70. BIN
      WebRoot/WEB-INF/lib/spring-websocket-5.1.6.jar
  71. BIN
      WebRoot/WEB-INF/lib/sqlite-jdbc-3.23.1.jar
  72. BIN
      WebRoot/WEB-INF/lib/thumbnailator-0.4.8.jar
  73. BIN
      WebRoot/WEB-INF/lib/xmlbeans-3.1.0.jar
  74. BIN
      WebRoot/WEB-INF/lib/zxing-core-3.2.1.jar
  75. BIN
      WebRoot/WEB-INF/lib/zxing-javase-3.2.1.jar
  76. BIN
      WebRoot/fonts/STSONG.TTF
  77. BIN
      WebRoot/fonts/cert.jpg
  78. BIN
      WebRoot/template/OpenReport120.doc
  79. BIN
      WebRoot/template/PaperPayInfo.xlsx
  80. 1 0
      WebRoot/template/ThreadTest.txt
  81. BIN
      WebRoot/template/WriteRequire120.doc
  82. 6 0
      src/app.properties
  83. 16 0
      src/cn/hmsoft/SpringAppTest.java
  84. 100 0
      src/cn/hmsoft/ai/baidu/BaiduTokenService.java
  85. 51 0
      src/cn/hmsoft/ai/face/FaceAI.java
  86. 30 0
      src/cn/hmsoft/ai/face/FaceGroup.java
  87. 31 0
      src/cn/hmsoft/ai/face/FaceManager.java
  88. 14 0
      src/cn/hmsoft/ai/face/FaceNoAI.java
  89. 275 0
      src/cn/hmsoft/ai/face/FacePhoto.java
  90. 38 0
      src/cn/hmsoft/ai/face/FaceSearch.java
  91. 19 0
      src/cn/hmsoft/ai/face/baidu/BaiduFaceGroup.java
  92. 37 0
      src/cn/hmsoft/ai/face/baidu/BaiduFaceManager.java
  93. 115 0
      src/cn/hmsoft/ai/face/baidu/BaiduIdPhotoAI.java
  94. 56 0
      src/cn/hmsoft/ai/face/baidu/BaiduPhotoSearchAI.java
  95. 110 0
      src/cn/hmsoft/ai/idcard/IdCard.java
  96. 67 0
      src/cn/hmsoft/ai/idcard/IdCardBack.java
  97. 78 0
      src/cn/hmsoft/ai/idcard/IdCardOcr.java
  98. 148 0
      src/cn/hmsoft/ai/idcard/baidu/BaiduIdCardOcr.java
  99. 33 0
      src/cn/hmsoft/ai/identity/IdentifiedResult.java
  100. 50 0
      src/cn/hmsoft/ai/identity/IdentityAI.java

+ 54 - 0
.gitignore

@@ -0,0 +1,54 @@
+
+### IntelliJ IDEA ###
+.idea
+*.iws
+*.iml
+*.ipr
+*.class
+*.log
+/out/
+
+
+### Eclipse & STS ###
+.apt_generated
+.classpath
+.factorypath
+.project
+.settings
+.springBeans
+.sts4-cache
+/logs/
+/log/
+/data/
+
+
+### NetBeans ###
+/nbproject/private/
+/nbbuild/
+/dist/
+/nbdist/
+/.nb-gradle/
+build/
+!**/src/main/**/build/
+!**/src/test/**/build/
+
+
+### VS Code ###
+.vscode
+node_modules
+package-lock.json
+yarn.lock
+
+
+### Package Files ###
+*.zip
+*.war
+*.ear
+!.mvn/wrapper/maven-wrapper.jar
+!**/src/main/**/target/
+!**/src/test/**/target/
+target/
+
+.flattened-pom.xml
+.DS_Store
+

+ 3 - 0
WebRoot/META-INF/MANIFEST.MF

@@ -0,0 +1,3 @@
+Manifest-Version: 1.0
+Class-Path: 
+

+ 6 - 0
WebRoot/WEB-INF/classes/app.properties

@@ -0,0 +1,6 @@
+AppDebug=true
+AppParamUtil=cn.hmsoft.art.helper.ArtParamHelper
+AppListener=cn.hmsoft.art.control.ArtInitializeLisener
+AppName=ArtEnrol
+
+RedisOpen=false

+ 21 - 0
WebRoot/WEB-INF/classes/frame-res.properties

@@ -0,0 +1,21 @@
+/frame/res/page=1010,资源管理
+/frame/param/page=1020,系统参数
+/frame/dict/page=1030,系统字典
+/frame/dept/page=1040,部门管理
+/frame/role/page=1080,角色管理
+/frame/optr/page=1090,操作员管理
+/frame/module/page=1904,插件管理
+/frame/report/page=1905,报表管理
+/frame/thread/page=1906,系统线程
+/frame/timer/page=1907,系统定时器
+/weixin/define/page=10110,微信公众号
+/weixin/param/page=10120,微信参数
+/weixin/menu/page=10130,微信菜单
+/weixin/reply/page=10140,自动回复
+/weixin/tag/page=10150,标签管理
+/weixin/user/page=10160,微信用户
+/weixin/template/page=10170,模板消息
+/weixin/processor/page=10180,消息处理器
+hmpay/bill/page=10201,支付管理
+hmpay/channel/page=10202,渠道管理
+hmpay/merchant/page=10203,商户管理

+ 8 - 0
WebRoot/WEB-INF/classes/jdbc.properties

@@ -0,0 +1,8 @@
+JdbcDriverClass=com.mysql.cj.jdbc.Driver
+JdbcUrl=jdbc:mysql://127.0.0.1:3306/art_v3?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf8&characterSetResults=utf8&useSSL=false&verifyServerCertificate=false&autoReconnct=true&autoReconnectForPools=true&allowMultiQueries=true 
+#JdbcUrl=jdbc:mysql://39.105.12.211:3306/art2020?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf8&characterSetResults=utf8&useSSL=false&verifyServerCertificate=false&autoReconnct=true&autoReconnectForPools=true&allowMultiQueries=true 
+JdbcUser=root
+JdbcPassword=localhost
+#JdbcPassword=hm@123456
+JdbcCheckouttimeout=30000
+JdbcMaxpoolsize=200

+ 8 - 0
WebRoot/WEB-INF/classes/redis.properties

@@ -0,0 +1,8 @@
+Host = 127.0.0.1
+#Password = 123456
+#Port = 6379
+#Timeout = 300
+#PoolMaxTotal = 500
+#PoolMaxIdle = 100
+#PoolMinIdle = 50
+#PoolMaxWait = 10000

BIN
WebRoot/WEB-INF/lib/baidu-aip-sdk-4.11.1.jar


BIN
WebRoot/WEB-INF/lib/bcprov-jdk15on-1.62.jar


BIN
WebRoot/WEB-INF/lib/commons-codec-1.10.jar


BIN
WebRoot/WEB-INF/lib/commons-collections4-4.3.jar


BIN
WebRoot/WEB-INF/lib/commons-compress-1.18.jar


BIN
WebRoot/WEB-INF/lib/commons-fileupload-1.4.jar


BIN
WebRoot/WEB-INF/lib/commons-io-2.6.jar


BIN
WebRoot/WEB-INF/lib/commons-logging-1.2.jar


BIN
WebRoot/WEB-INF/lib/commons-pool2-2.9.0.jar


BIN
WebRoot/WEB-INF/lib/druid-1.1.9.jar


BIN
WebRoot/WEB-INF/lib/fastjson-1.2.28.jar


BIN
WebRoot/WEB-INF/lib/gson-2.8.5.jar


BIN
WebRoot/WEB-INF/lib/httpclient-4.5.7.jar


BIN
WebRoot/WEB-INF/lib/httpcore-4.4.11.jar


BIN
WebRoot/WEB-INF/lib/httpcore-nio-4.4.1.jar


BIN
WebRoot/WEB-INF/lib/httpmime-4.5.11.jar


BIN
WebRoot/WEB-INF/lib/itext7-barcodes-7.0.1.jar


BIN
WebRoot/WEB-INF/lib/itext7-font-asian-7.0.1.jar


BIN
WebRoot/WEB-INF/lib/itext7-forms-7.0.1.jar


BIN
WebRoot/WEB-INF/lib/itext7-hyph-7.0.1.jar


BIN
WebRoot/WEB-INF/lib/itext7-io-7.0.1.jar


BIN
WebRoot/WEB-INF/lib/itext7-itext-rups-7.0.1.jar


BIN
WebRoot/WEB-INF/lib/itext7-kernel-7.0.1.jar


BIN
WebRoot/WEB-INF/lib/itext7-layout-7.0.1.jar


BIN
WebRoot/WEB-INF/lib/itext7-pdfa-7.0.1.jar


BIN
WebRoot/WEB-INF/lib/itext7-pdftest-7.0.1.jar


BIN
WebRoot/WEB-INF/lib/itext7-sign-7.0.1.jar


BIN
WebRoot/WEB-INF/lib/javadbf.jar


BIN
WebRoot/WEB-INF/lib/jedis-3.2.0.jar


BIN
WebRoot/WEB-INF/lib/log4j-api-2.17.2.jar


BIN
WebRoot/WEB-INF/lib/log4j-core-2.17.2.jar


BIN
WebRoot/WEB-INF/lib/log4j-jcl-2.17.2.jar


BIN
WebRoot/WEB-INF/lib/log4j-slf4j-impl-2.17.2.jar


BIN
WebRoot/WEB-INF/lib/mysql-connector-j-8.0.32.jar


BIN
WebRoot/WEB-INF/lib/ojdbc8.jar


BIN
WebRoot/WEB-INF/lib/pay-chinapayfilesecure.jar


BIN
WebRoot/WEB-INF/lib/pay-chinapaysecure.jar


BIN
WebRoot/WEB-INF/lib/poi-4.1.0.jar


BIN
WebRoot/WEB-INF/lib/poi-excelant-4.1.0.jar


BIN
WebRoot/WEB-INF/lib/poi-ooxml-4.1.0.jar


BIN
WebRoot/WEB-INF/lib/poi-ooxml-schemas-4.1.0.jar


BIN
WebRoot/WEB-INF/lib/poi-scratchpad-4.1.0.jar


BIN
WebRoot/WEB-INF/lib/quartz-2.3.1.jar


BIN
WebRoot/WEB-INF/lib/quartz-jobs-2.3.1.jar


BIN
WebRoot/WEB-INF/lib/slf4j-api-1.7.25.jar


BIN
WebRoot/WEB-INF/lib/spring-aop-5.1.6.jar


BIN
WebRoot/WEB-INF/lib/spring-aspectjweaver-1.9.3.jar


BIN
WebRoot/WEB-INF/lib/spring-aspects-5.1.6.jar


BIN
WebRoot/WEB-INF/lib/spring-beans-5.1.6.jar


BIN
WebRoot/WEB-INF/lib/spring-context-5.1.6.jar


BIN
WebRoot/WEB-INF/lib/spring-context-indexer-5.1.6.jar


BIN
WebRoot/WEB-INF/lib/spring-context-support-5.1.6.jar


BIN
WebRoot/WEB-INF/lib/spring-core-5.1.6.jar


BIN
WebRoot/WEB-INF/lib/spring-expression-5.1.6.jar


BIN
WebRoot/WEB-INF/lib/spring-instrument-5.1.6.jar


BIN
WebRoot/WEB-INF/lib/spring-jdbc-5.1.6.jar


BIN
WebRoot/WEB-INF/lib/spring-jms-5.1.6.jar


BIN
WebRoot/WEB-INF/lib/spring-messaging-5.1.6.jar


BIN
WebRoot/WEB-INF/lib/spring-orm-5.1.6.jar


BIN
WebRoot/WEB-INF/lib/spring-oxm-5.1.6.jar


BIN
WebRoot/WEB-INF/lib/spring-tx-5.1.6.jar


BIN
WebRoot/WEB-INF/lib/spring-web-5.1.6.jar


BIN
WebRoot/WEB-INF/lib/spring-webmvc-5.1.6.jar


BIN
WebRoot/WEB-INF/lib/spring-websocket-5.1.6.jar


BIN
WebRoot/WEB-INF/lib/sqlite-jdbc-3.23.1.jar


BIN
WebRoot/WEB-INF/lib/thumbnailator-0.4.8.jar


BIN
WebRoot/WEB-INF/lib/xmlbeans-3.1.0.jar


BIN
WebRoot/WEB-INF/lib/zxing-core-3.2.1.jar


BIN
WebRoot/WEB-INF/lib/zxing-javase-3.2.1.jar


BIN
WebRoot/fonts/STSONG.TTF


BIN
WebRoot/fonts/cert.jpg


BIN
WebRoot/template/OpenReport120.doc


BIN
WebRoot/template/PaperPayInfo.xlsx


+ 1 - 0
WebRoot/template/ThreadTest.txt

@@ -0,0 +1 @@
+this is frame thread test file.

BIN
WebRoot/template/WriteRequire120.doc


+ 6 - 0
src/app.properties

@@ -0,0 +1,6 @@
+AppDebug=true
+AppParamUtil=cn.hmsoft.art.helper.ArtParamHelper
+AppListener=cn.hmsoft.art.control.ArtInitializeLisener
+AppName=ArtEnrol
+
+RedisOpen=false

+ 16 - 0
src/cn/hmsoft/SpringAppTest.java

@@ -0,0 +1,16 @@
+package cn.hmsoft;
+
+/*****************
+ * 测试用类
+ * 
+ * @author zxq
+ * @create 2019-05-06 10:00:39
+ * @version 2.0.0
+ * @email: revisit@126.com
+ * @Company: www.hmsoft.cn
+ */
+public class SpringAppTest {
+
+	public static void main(String[] args) throws Exception {
+	}
+}

+ 100 - 0
src/cn/hmsoft/ai/baidu/BaiduTokenService.java

@@ -0,0 +1,100 @@
+package cn.hmsoft.ai.baidu;
+
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.time.LocalDateTime;
+import java.util.Map;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Isolation;
+import org.springframework.transaction.annotation.Transactional;
+
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParser;
+
+import cn.hmsoft.ai.util.AiParamUtil;
+import cn.hmsoft.frame.data.dao.FrameModuleDao;
+import cn.hmsoft.frame.data.model.FrameModule;
+import cn.hmsoft.helper.CollectionHelper;
+import cn.hmsoft.helper.LocalDateHelper;
+import cn.hmsoft.helper.StringHelper;
+
+/**************************
+ * 获取百度toketn的服务,确保唯一访问
+ */
+@Service
+public class BaiduTokenService {
+	public static String ACCESS_TOKEN = "";
+	public static LocalDateTime ACCESS_TOKEN_EXPIRES = null;
+
+	@Autowired
+	private FrameModuleDao daoModule;
+
+	@Transactional(isolation = Isolation.SERIALIZABLE)
+	public boolean getBaiduToken() {
+		if (ACCESS_TOKEN == null || ACCESS_TOKEN_EXPIRES == null
+				|| ACCESS_TOKEN_EXPIRES.isBefore(LocalDateTime.now())) {
+			
+		}else {
+			return true;
+		}
+		FrameModule module = this.daoModule.find(FrameModule.class, "module_name", AiParamUtil.ModuleName);
+		Map<String, String> paramMap = StringHelper.toMap(module.getModule_param());
+		String access_token = CollectionHelper.getParamValue(paramMap, AiParamUtil.ParamName_BaiduIdPhotoToken, "");
+		String access_token_expired = CollectionHelper.getParamValue(paramMap,
+				AiParamUtil.ParamName_BaiduIdPhotoTokenExpireTime, "");
+		ACCESS_TOKEN = access_token;
+		ACCESS_TOKEN_EXPIRES = LocalDateHelper.parseDateTime(access_token_expired);
+
+		if (ACCESS_TOKEN == null || ACCESS_TOKEN_EXPIRES == null
+				|| ACCESS_TOKEN_EXPIRES.isBefore(LocalDateTime.now())) {
+			String authHost = "https://aip.baidubce.com/oauth/2.0/token?";
+			String getAccessTokenUrl = authHost
+					// 1. grant_type为固定参数
+					+ "grant_type=client_credentials"
+					// 2. 官网获取的 API Key
+					+ "&client_id=" + AiParamUtil.ParamMap.get(AiParamUtil.ParamName_BaiduIdPhotoAppKey).trim()
+					// 3. 官网获取的 Secret Key
+					+ "&client_secret=" + AiParamUtil.ParamMap.get(AiParamUtil.ParamName_BaiduIdPhotoSecretKey).trim();
+			try {
+				URL realUrl = new URL(getAccessTokenUrl);
+				// 打开和URL之间的连接
+				HttpURLConnection connection = (HttpURLConnection) realUrl.openConnection();
+				connection.setRequestMethod("GET");
+				connection.connect();
+
+				// 定义 BufferedReader输入流来读取URL的响应
+				BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
+				String result = "";
+				String line;
+				while ((line = in.readLine()) != null) {
+					result += line;
+				}
+				/**
+				 * 返回结果示例
+				 */
+				JsonObject jsonObject = new JsonParser().parse(result).getAsJsonObject();
+				ACCESS_TOKEN = jsonObject.get("access_token").getAsString();
+				ACCESS_TOKEN_EXPIRES = LocalDateTime.now().plusSeconds(jsonObject.get("expires_in").getAsInt());
+				// 更新数据库
+				module.setModule_param(module.getModule_param()
+						.replace("BaiduIdPhotoToken:" + access_token, "BaiduIdPhotoToken:" + ACCESS_TOKEN)
+						.replace("BaiduIdPhotoTokenExpireTime:" + access_token_expired,
+								"BaiduIdPhotoTokenExpireTime:" + LocalDateHelper.format(ACCESS_TOKEN_EXPIRES)));
+				this.daoModule.update(module);
+				return true;
+			} catch (Exception e) {
+				System.err.printf("获取token失败!");
+				e.printStackTrace(System.err);
+			}
+			return false;
+		}
+
+		return true;
+
+	}
+
+}

+ 51 - 0
src/cn/hmsoft/ai/face/FaceAI.java

@@ -0,0 +1,51 @@
+package cn.hmsoft.ai.face;
+
+import java.io.File;
+
+import cn.hmsoft.ai.idcard.IdCardOcr;
+import cn.hmsoft.ai.util.AiParamUtil;
+
+/******************
+ * ai 免冠照识别
+ *
+ */
+public abstract class FaceAI {
+	private static FaceAI ai = null;
+
+	public static FaceAI instance() {
+		if (ai == null) {
+			synchronized (IdCardOcr.class) {
+				try {
+					ai = (FaceAI) Class.forName(AiParamUtil.IdPhotoAIClass).newInstance();
+				} catch (Exception e) {
+					try {
+						ai = FaceNoAI.class.newInstance();
+					} catch (Exception ex) {
+
+					}
+				}
+			}
+		}
+		return ai;
+	}
+
+	public FacePhoto distFace(String idphoto_image_path, String id_card) {
+		FacePhoto photo = null;
+		try {
+			photo = this.distFaceByFile(new File(idphoto_image_path), id_card);
+		} catch (Exception e) {
+
+		}
+		if (photo == null) {
+			photo = new FacePhoto();
+			photo.setError_msg("unknow error");
+		}
+		return photo;
+	}
+
+	public FacePhoto distFace(File idphoto_image_file, String id_card) {
+		return distFace(idphoto_image_file.getPath(), id_card);
+	}
+
+	protected abstract FacePhoto distFaceByFile(File file, String id_card);
+}

+ 30 - 0
src/cn/hmsoft/ai/face/FaceGroup.java

@@ -0,0 +1,30 @@
+package cn.hmsoft.ai.face;
+
+import java.io.File;
+
+/******************
+ * 组维护
+ *
+ */
+public abstract class FaceGroup {
+	private static FaceGroup ai = null;
+
+	public static FaceGroup instance() {
+		if (ai == null) {
+			synchronized (FaceGroup.class) {
+				try {
+					ai = FaceGroup.class.newInstance();
+				} catch (InstantiationException | IllegalAccessException e) {
+					e.printStackTrace();
+				}
+			}
+		}
+		return ai;
+	}
+
+	public String addFaceGroup(String groupId) {
+		return addGroup(groupId);
+	}
+
+	protected abstract String addGroup(String groupIds);
+}

+ 31 - 0
src/cn/hmsoft/ai/face/FaceManager.java

@@ -0,0 +1,31 @@
+package cn.hmsoft.ai.face;
+
+import java.io.File;
+
+import cn.hmsoft.ai.face.baidu.BaiduFaceManager;
+
+/******************
+ * 人脸信息维护
+ *
+ */
+public abstract class FaceManager {
+	private static FaceManager ai = null;
+
+	public static FaceManager instance() {
+		if (ai == null) {
+			synchronized (FaceManager.class) {
+				try {
+					ai = BaiduFaceManager.class.newInstance();
+				} catch (InstantiationException | IllegalAccessException e) {
+					e.printStackTrace();
+				}
+			}
+		}
+		return ai;
+	}
+
+
+	protected abstract String addFace(File file, String userId);
+	
+	protected abstract String delFace(String userId);
+}

+ 14 - 0
src/cn/hmsoft/ai/face/FaceNoAI.java

@@ -0,0 +1,14 @@
+package cn.hmsoft.ai.face;
+
+import java.io.File;
+
+import cn.hmsoft.frame.exception.BusinessException;
+
+public class FaceNoAI extends FaceAI{
+
+	@Override
+	protected FacePhoto distFaceByFile(File file,String id_card) {
+		throw new BusinessException("尚未实现该ai算法");
+	}
+
+}

+ 275 - 0
src/cn/hmsoft/ai/face/FacePhoto.java

@@ -0,0 +1,275 @@
+package cn.hmsoft.ai.face;
+
+import cn.hmsoft.frame.constants.FrameSex;
+
+/******************
+ * 证件照
+ * 
+ * @author Administrator
+ *
+ */
+public class FacePhoto {
+	/*****************
+	 * 照片ID号
+	 */
+	private String photo_id;
+	/******************
+	 * 人脸概率
+	 */
+	private int face_probability;
+
+	/*************
+	 * 人脸旋转度
+	 */
+	private int face_rotation;
+
+	/*************
+	 * 人脸高度
+	 */
+	private double face_height;
+	/**************
+	 * 人脸宽度
+	 */
+
+	private double face_width;
+
+	/*************
+	 * 人脸高度百分比
+	 */
+	private double face_height_percent;
+	/**************
+	 * 人脸宽度百分比
+	 */
+
+	private double face_width_percent;
+	/**************
+	 * 人脸左边距
+	 */
+
+	private double face_left;
+	/**************
+	 * 人脸上边距
+	 */
+
+	private double face_top;
+
+	/**************
+	 * 美颜程度
+	 */
+	private double person_beauty;
+
+	/*****************
+	 * 年龄
+	 */
+	private int person_age;
+
+	/****************
+	 * 性别
+	 */
+	private FrameSex person_sex;
+
+	/************
+	 * 性别概率
+	 */
+	private int person_sex_probability;
+
+	/********************
+	 * 是否识别成功
+	 */
+	private boolean success = false;
+	/**************
+	 * 是否是证件照
+	 */
+	private boolean id_photo = false;
+
+	private double photo_height;
+	private double photo_width;
+
+	/****************
+	 * 图片中一共有几个人
+	 */
+	private Integer person_total;
+
+	/**************
+	 * 是否居中
+	 */
+	private boolean person_center;
+
+	/****************
+	 * 人像占比
+	 */
+	private Integer person_percent;
+	/**************
+	 * 错误信息
+	 */
+	private String error_msg;
+
+	public boolean isSuccess() {
+		return success;
+	}
+
+	public void setSuccess(boolean success) {
+		this.success = success;
+	}
+
+	public boolean isId_photo() {
+		return id_photo;
+	}
+
+	public void setId_photo(boolean id_photo) {
+		this.id_photo = id_photo;
+	}
+
+	public Integer getPerson_total() {
+		return person_total;
+	}
+
+	public void setPerson_total(Integer person_total) {
+		this.person_total = person_total;
+	}
+
+	public boolean isPerson_center() {
+		return person_center;
+	}
+
+	public void setPerson_center(boolean person_center) {
+		this.person_center = person_center;
+	}
+
+	public Integer getPerson_percent() {
+		return person_percent;
+	}
+
+	public void setPerson_percent(Integer person_percent) {
+		this.person_percent = person_percent;
+	}
+
+	public String getError_msg() {
+		return error_msg;
+	}
+
+	public void setError_msg(String error_msg) {
+		this.error_msg = error_msg;
+	}
+
+	public String getPhoto_id() {
+		return photo_id;
+	}
+
+	public void setPhoto_id(String photo_id) {
+		this.photo_id = photo_id;
+	}
+
+	public int getFace_probability() {
+		return face_probability;
+	}
+
+	public void setFace_probability(int face_probability) {
+		this.face_probability = face_probability;
+	}
+
+	public int getPerson_age() {
+		return person_age;
+	}
+
+	public void setPerson_age(int person_age) {
+		this.person_age = person_age;
+	}
+
+	public FrameSex getPerson_sex() {
+		return person_sex;
+	}
+
+	public void setPerson_sex(FrameSex person_sex) {
+		this.person_sex = person_sex;
+	}
+
+	public int getPerson_sex_probability() {
+		return person_sex_probability;
+	}
+
+	public void setPerson_sex_probability(int person_sex_probability) {
+		this.person_sex_probability = person_sex_probability;
+	}
+
+	public int getFace_rotation() {
+		return face_rotation;
+	}
+
+	public void setFace_rotation(int face_rotation) {
+		this.face_rotation = face_rotation;
+	}
+
+	public double getFace_height() {
+		return face_height;
+	}
+
+	public void setFace_height(double face_height) {
+		this.face_height = face_height;
+	}
+
+	public double getFace_width() {
+		return face_width;
+	}
+
+	public void setFace_width(double face_width) {
+		this.face_width = face_width;
+	}
+
+	public double getFace_left() {
+		return face_left;
+	}
+
+	public void setFace_left(double face_left) {
+		this.face_left = face_left;
+	}
+
+	public double getFace_top() {
+		return face_top;
+	}
+
+	public void setFace_top(double face_top) {
+		this.face_top = face_top;
+	}
+
+	public double getPhoto_height() {
+		return photo_height;
+	}
+
+	public void setPhoto_height(double photo_height) {
+		this.photo_height = photo_height;
+	}
+
+	public double getPhoto_width() {
+		return photo_width;
+	}
+
+	public void setPhoto_width(double photo_width) {
+		this.photo_width = photo_width;
+	}
+
+	public double getPerson_beauty() {
+		return person_beauty;
+	}
+
+	public void setPerson_beauty(double person_beauty) {
+		this.person_beauty = person_beauty;
+	}
+
+	public double getFace_height_percent() {
+		return face_height_percent;
+	}
+
+	public void setFace_height_percent(double face_height_percent) {
+		this.face_height_percent = face_height_percent;
+	}
+
+	public double getFace_width_percent() {
+		return face_width_percent;
+	}
+
+	public void setFace_width_percent(double face_width_percent) {
+		this.face_width_percent = face_width_percent;
+	}
+
+}

+ 38 - 0
src/cn/hmsoft/ai/face/FaceSearch.java

@@ -0,0 +1,38 @@
+package cn.hmsoft.ai.face;
+
+import java.io.File;
+
+import cn.hmsoft.ai.util.AiParamUtil;
+
+/******************
+ * ai 按照片查找人
+ *
+ */
+public abstract class FaceSearch {
+	private static FaceSearch ai = null;
+
+	public static FaceSearch instance() {
+		if (ai == null) {
+			synchronized (FaceSearch.class) {
+				try {
+					ai = (FaceSearch) Class.forName(AiParamUtil.PhotoSearchAIClass).newInstance();
+				} catch (Exception e) {
+					try {
+						ai = FaceSearch.class.newInstance();
+					} catch (Exception ex) {
+
+					}
+				}
+			}
+		}
+		return ai;
+	}
+
+	/**
+	 * 根据照片查找用户信息
+	 * @param photoImage
+	 * @param groupIds
+	 * @return 用户信息(身份证号)
+	 */
+	public abstract String searchFace(File file, String groupIds);
+}

+ 19 - 0
src/cn/hmsoft/ai/face/baidu/BaiduFaceGroup.java

@@ -0,0 +1,19 @@
+package cn.hmsoft.ai.face.baidu;
+
+import cn.hmsoft.ai.baidu.BaiduTokenService;
+import cn.hmsoft.ai.face.FaceGroup;
+import cn.hmsoft.application.SpringHelper;
+
+public class BaiduFaceGroup extends FaceGroup {
+	private final static String url_group_add = "https://aip.baidubce.com/rest/2.0/face/v3/faceset/group/add";
+
+	private String url_group_add() {
+		return url_group_add + "?access_token=" + SpringHelper.getBean(BaiduTokenService.class).getBaiduToken();
+	}
+
+	@Override
+	protected String addGroup(String groupIds) {
+		// TODO Auto-generated method stub
+		return null;
+	}
+}

+ 37 - 0
src/cn/hmsoft/ai/face/baidu/BaiduFaceManager.java

@@ -0,0 +1,37 @@
+package cn.hmsoft.ai.face.baidu;
+
+import java.io.File;
+import java.util.HashMap;
+import java.util.Map;
+
+import com.baidu.aip.util.Base64Util;
+import com.google.gson.GsonBuilder;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParser;
+
+import cn.hmsoft.ai.baidu.BaiduTokenService;
+import cn.hmsoft.ai.face.FaceManager;
+import cn.hmsoft.application.SpringHelper;
+import cn.hmsoft.helper.FileHelper;
+import cn.hmsoft.helper.http.HttpHelper;
+
+public class BaiduFaceManager extends FaceManager {
+	private final static String url = "https://aip.baidubce.com/rest/2.0/face/v3/faceset/user/add";
+
+	private String url() {
+		return url + "?access_token=" + SpringHelper.getBean(BaiduTokenService.class).getBaiduToken();
+	}
+
+	@Override
+	protected String addFace(File file, String userId) {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	@Override
+	protected String delFace(String userId) {
+		// TODO Auto-generated method stub
+		return null;
+	}
+	
+}

+ 115 - 0
src/cn/hmsoft/ai/face/baidu/BaiduIdPhotoAI.java

@@ -0,0 +1,115 @@
+package cn.hmsoft.ai.face.baidu;
+
+import java.awt.image.BufferedImage;
+import java.io.File;
+import java.io.FileInputStream;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.imageio.ImageIO;
+
+import com.baidu.aip.util.Base64Util;
+import com.google.gson.GsonBuilder;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParser;
+
+import cn.hmsoft.ai.baidu.BaiduTokenService;
+import cn.hmsoft.ai.face.FaceAI;
+import cn.hmsoft.ai.face.FacePhoto;
+import cn.hmsoft.application.SpringHelper;
+import cn.hmsoft.frame.constants.FrameSex;
+import cn.hmsoft.helper.FileHelper;
+import cn.hmsoft.helper.http.HttpHelper;
+
+public class BaiduIdPhotoAI extends FaceAI {
+
+	@Override
+	protected FacePhoto distFaceByFile(File file, String id_card) {
+		SpringHelper.getBean(BaiduTokenService.class).getBaiduToken();
+		// 请求url
+		String url = "https://aip.baidubce.com/rest/2.0/face/v3/detect?access_token=" + BaiduTokenService.ACCESS_TOKEN;
+		try {
+			Map<String, Object> map = new HashMap<String, Object>();
+			map.put("image", Base64Util.encode(FileHelper.readFileByBytes(file.getPath())));
+			map.put("max_face_num", "10");
+			map.put("image_type", "BASE64");
+			map.put("face_type", "CERT");
+			map.put("face_field", "faceshape,facetype,age,gender,beauty");
+
+			String param = new GsonBuilder().create().toJson(map);
+
+			String result = HttpHelper.post(url, "application/json", param);
+			//System.out.println(result);
+			JsonObject json = new JsonParser().parse(result).getAsJsonObject();
+			FacePhoto photo = new FacePhoto();
+
+			BufferedImage sourceImg = ImageIO.read(new FileInputStream(file));
+			photo.setPhoto_width(sourceImg.getWidth());
+			photo.setPhoto_height(sourceImg.getHeight());
+			int error_code = json.get("error_code").getAsInt();
+			if (error_code == 0) {
+				// {"error_code":0,"error_msg":"SUCCESS","log_id":305486828495045361,"timestamp":1572849504,"cached":0,"result":{"face_num":3,"face_list":[{"face_token":"459973baa9a22ccde3be486923cc00f6","location":{"left":419.15,"top":578.18,"width":59,"height":51,"rotation":-3},"face_probability":0.83,"angle":{"yaw":-14.12,"pitch":11.59,"roll":-0.8},"face_shape":{"type":"round","probability":0.48},"face_type":{"type":"human","probability":1},"age":19,"gender":{"type":"male","probability":1}},{"face_token":"da81263b4d9ded68611cedcee114b80d","location":{"left":780.6,"top":576.82,"width":54,"height":47,"rotation":-2},"face_probability":1,"angle":{"yaw":-17.43,"pitch":13.92,"roll":-0.03},"face_shape":{"type":"round","probability":0.62},"face_type":{"type":"human","probability":1},"age":31,"gender":{"type":"male","probability":1}},{"face_token":"53129bca7f94bbecf5e47f9b0f5368dd","location":{"left":1134.12,"top":575.5,"width":52,"height":40,"rotation":6},"face_probability":0.69,"angle":{"yaw":-34.6,"pitch":28.32,"roll":17.56},"face_shape":{"type":"round","probability":0.7},"face_type":{"type":"human","probability":1},"age":37,"gender":{"type":"male","probability":0.99}}]}}
+
+				photo.setSuccess(true);
+				JsonObject rs = json.getAsJsonObject("result");
+				photo.setPerson_total(rs.get("face_num").getAsInt());
+				if (photo.getPerson_total() > 0) {
+					// 处理第一个人脸
+					// {"face_token":"459973baa9a22ccde3be486923cc00f6","location":{"left":419.15,"top":578.18,"width":59,"height":51,"rotation":-3},"face_probability":0.83,"angle":{"yaw":-14.12,"pitch":11.59,"roll":-0.8},"face_shape":{"type":"round","probability":0.48},"face_type":{"type":"human","probability":1},"age":19,"gender":{"type":"male","probability":1}}
+					JsonObject p = rs.getAsJsonArray("face_list").get(0).getAsJsonObject();
+					// 图片ID
+					photo.setPhoto_id(p.get("face_token").getAsString());
+					// 人脸概率
+					photo.setFace_probability((int) (p.get("face_probability").getAsDouble() * 100));
+					// 年龄
+					photo.setPerson_age((int) (p.get("age").getAsDouble() * 100));
+
+					JsonObject g = p.get("gender").getAsJsonObject();
+					// 性别
+					String sex = g.get("type").getAsString();
+					if ("male".equals(sex)) {
+						photo.setPerson_sex(FrameSex.Male);
+					} else
+						photo.setPerson_sex(FrameSex.Female);
+					// 性别可靠度
+					photo.setPerson_sex_probability((int) (g.get("probability").getAsDouble() * 100));
+
+					// 美颜
+					photo.setPerson_beauty(p.get("beauty").getAsDouble());
+					// 人脸旋转度
+					JsonObject loc = p.get("location").getAsJsonObject();
+					photo.setFace_rotation(loc.get("rotation").getAsInt());
+					photo.setFace_height(loc.get("height").getAsDouble());
+					photo.setFace_width(loc.get("width").getAsDouble());
+					photo.setFace_left(loc.get("left").getAsDouble());
+					photo.setFace_top(loc.get("top").getAsDouble());
+
+					photo.setFace_height_percent(photo.getFace_height() / photo.getPhoto_height() * 100);
+					photo.setFace_width_percent(photo.getFace_width() / photo.getPhoto_width() * 100);
+
+				}
+//				System.out.println("原图大小(高、宽):" + photo.getPhoto_height() + " * " + photo.getPhoto_width());
+//				System.out.println("头像大小(高、宽):" + photo.getFace_height() + " * " + photo.getFace_width());
+//				System.out
+//						.println("头像占比(高、宽):" + photo.getFace_height_percent() + " * " + photo.getFace_width_percent());
+//				System.out.println("头像边距(上、左):" + photo.getFace_left() + " * " + photo.getFace_top());
+//
+//				System.out.println("美丑打分分值:" + photo.getPerson_beauty());
+//				System.out.println("美丑倾斜度:" + photo.getFace_rotation());
+
+			} else {
+				photo.setSuccess(false);
+				if (error_code == 222202) {
+					photo.setError_msg("未识别出头像信息,请重新上传照片!");
+				}
+			}
+			return photo; 
+
+		} catch (Exception e) {
+			// e.printStackTrace();
+		}
+
+		return null;
+	}
+
+}

+ 56 - 0
src/cn/hmsoft/ai/face/baidu/BaiduPhotoSearchAI.java

@@ -0,0 +1,56 @@
+package cn.hmsoft.ai.face.baidu;
+
+import java.io.File;
+import java.util.HashMap;
+import java.util.Map;
+
+import com.baidu.aip.util.Base64Util;
+import com.google.gson.GsonBuilder;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParser;
+
+import cn.hmsoft.ai.baidu.BaiduTokenService;
+import cn.hmsoft.ai.face.FaceSearch;
+import cn.hmsoft.application.SpringHelper;
+import cn.hmsoft.helper.FileHelper;
+import cn.hmsoft.helper.http.HttpHelper;
+
+public class BaiduPhotoSearchAI extends FaceSearch {
+	private final static String url = "https://aip.baidubce.com/rest/2.0/face/v3/search";
+
+	@Override
+	public String searchFace(File file, String groupIds) {
+		Map<String, Object> options = new HashMap<String, Object>();
+		try {
+			options.put("image", Base64Util.encode(FileHelper.readFileByBytes(file.getPath())));
+
+			options.put("image_type", "BASE64");
+			options.put("match_threshold", "50");
+			options.put("liveness_control", "NORMAL");
+			options.put("quality_control", "LOW");
+			options.put("group_id_list", groupIds);
+
+			String param = new GsonBuilder().create().toJson(options);
+
+			String result = HttpHelper.post(url(), "application/json", param);
+			// System.out.println(result);
+			JsonObject json = new JsonParser().parse(result).getAsJsonObject();
+
+			int error_code = json.get("error_code").getAsInt();
+			if (error_code == 0) {
+				JsonObject r =json.get("result").getAsJsonObject();
+				JsonObject p = r.getAsJsonArray("user_list").get(0).getAsJsonObject();
+				return p.get("user_id").getAsString();
+			}else {
+				
+			}
+		} catch (Exception e) {
+			e.printStackTrace();
+		}
+		return null;
+	}
+
+	private String url() {
+		return url + "?access_token=" + SpringHelper.getBean(BaiduTokenService.class).getBaiduToken();
+	}
+}

+ 110 - 0
src/cn/hmsoft/ai/idcard/IdCard.java

@@ -0,0 +1,110 @@
+package cn.hmsoft.ai.idcard;
+
+import java.time.LocalDate;
+
+/******************
+ * 身份证识别结果
+ * 
+ * @author zxq
+ * @create 2019-08-23 16:47:02
+ * @version 2.0.0
+ * @email: revisit@126.com
+ * @Company: www.hmsoft.cn
+ */
+public class IdCard {
+
+	private boolean ocr_success = false;
+	private String error_msg;
+	// 图片旋转度
+	private int direction = 0;
+
+	private String person_name;
+	private String person_nation;
+	private String person_addr;
+	private String person_code;
+	private String person_sex;
+	// 图片信息
+	private String photo;
+	private LocalDate birthday;
+
+	public boolean isOcr_success() {
+		return ocr_success;
+	}
+
+	public void setOcr_success(boolean ocr_success) {
+		this.ocr_success = ocr_success;
+	}
+
+	public String getError_msg() {
+		return error_msg;
+	}
+
+	public void setError_msg(String error_msg) {
+		this.error_msg = error_msg;
+	}
+
+	public String getPerson_name() {
+		return person_name;
+	}
+
+	public void setPerson_name(String person_name) {
+		this.person_name = person_name;
+	}
+
+	public String getPerson_nation() {
+		return person_nation;
+	}
+
+	public void setPerson_nation(String person_nation) {
+		this.person_nation = person_nation;
+	}
+
+	public String getPerson_addr() {
+		return person_addr;
+	}
+
+	public void setPerson_addr(String person_addr) {
+		this.person_addr = person_addr;
+	}
+
+	public String getPerson_code() {
+		return person_code;
+	}
+
+	public void setPerson_code(String person_code) {
+		this.person_code = person_code;
+	}
+
+	public String getPerson_sex() {
+		return person_sex;
+	}
+
+	public void setPerson_sex(String person_sex) {
+		this.person_sex = person_sex;
+	}
+
+	public int getDirection() {
+		return direction;
+	}
+
+	public void setDirection(int direction) {
+		this.direction = direction;
+	}
+
+	public String getPhoto() {
+		return photo;
+	}
+
+	public void setPhoto(String photo) {
+		this.photo = photo;
+	}
+
+	public LocalDate getBirthday() {
+		return birthday;
+	}
+
+	public void setBirthday(LocalDate birthday) {
+		this.birthday = birthday;
+	}
+
+}

+ 67 - 0
src/cn/hmsoft/ai/idcard/IdCardBack.java

@@ -0,0 +1,67 @@
+package cn.hmsoft.ai.idcard;
+
+/**
+ * @Description: 身份证-反面
+ * @author hgh
+ * @date 2023-11-09 03:47:07
+ */
+public class IdCardBack {
+
+	private String sign_organization; // 签发机关
+	private String expire_date; // 失效日期
+	private String issue_date;// 签发日期
+	
+	// 图片旋转度
+	private int direction = 0;
+	private boolean ocr_success = false;
+	private String error_msg;
+
+	public String getSign_organization() {
+		return sign_organization;
+	}
+
+	public void setSign_organization(String sign_organization) {
+		this.sign_organization = sign_organization;
+	}
+
+	public String getExpire_date() {
+		return expire_date;
+	}
+
+	public void setExpire_date(String expire_date) {
+		this.expire_date = expire_date;
+	}
+
+	public String getIssue_date() {
+		return issue_date;
+	}
+
+	public void setIssue_date(String issue_date) {
+		this.issue_date = issue_date;
+	}
+
+	public int getDirection() {
+		return direction;
+	}
+
+	public void setDirection(int direction) {
+		this.direction = direction;
+	}
+
+	public boolean isOcr_success() {
+		return ocr_success;
+	}
+
+	public void setOcr_success(boolean ocr_success) {
+		this.ocr_success = ocr_success;
+	}
+
+	public String getError_msg() {
+		return error_msg;
+	}
+
+	public void setError_msg(String error_msg) {
+		this.error_msg = error_msg;
+	}
+
+}

+ 78 - 0
src/cn/hmsoft/ai/idcard/IdCardOcr.java

@@ -0,0 +1,78 @@
+package cn.hmsoft.ai.idcard;
+
+import java.io.File;
+
+import cn.hmsoft.ai.idcard.baidu.BaiduIdCardOcr;
+import cn.hmsoft.ai.util.AiParamUtil;
+
+/***************************
+ * 身份证识别
+ * 
+ * @author zxq
+ * @create 2019-08-22 22:33:53
+ * @version 2.0.0
+ * @email: revisit@126.com
+ * @Company: www.hmsoft.cn
+ */
+public abstract class IdCardOcr {
+
+	private static IdCardOcr ocr = null;
+
+	public static IdCardOcr instance() {
+		if (ocr == null) {
+			synchronized (IdCardOcr.class) {
+				try {
+					ocr = (IdCardOcr) Class.forName(AiParamUtil.IdCardOcrClass).newInstance();
+				} catch (Exception e) {
+					try {
+						ocr = BaiduIdCardOcr.class.newInstance();
+					} catch (Exception ex) {
+
+					}
+				}
+			}
+		}
+		return ocr;
+	}
+
+	public IdCard ocrIdCard(String idcard_image_path) {
+		IdCard card = null;
+		try {
+			card = this.ocrIdCardByFile(new File(idcard_image_path));
+		} catch (Exception e) {
+
+		}
+		if (card == null) {
+			card = new IdCard();
+			card.setError_msg("unknow error");
+		}
+		return card;
+	}
+
+	public IdCard ocrIdCard(File idcard_image_file) {
+		return ocrIdCard(idcard_image_file.getPath());
+	}
+
+	protected abstract IdCard ocrIdCardByFile(File file);
+	
+	public IdCardBack ocrIdCardBack(String idcard_image_path) {
+		IdCardBack card = null;
+		try {
+			card = this.ocrIdCardBackByFile(new File(idcard_image_path));
+		} catch (Exception e) {
+
+		}
+		if (card == null) {
+			card = new IdCardBack();
+			card.setError_msg("unknow error");
+		}
+		return card;
+	}
+	
+	public IdCardBack ocrIdCardBack(File idcard_image_file) {
+		return ocrIdCardBack(idcard_image_file.getPath());
+	}
+
+	
+	protected abstract IdCardBack ocrIdCardBackByFile(File file);
+}

+ 148 - 0
src/cn/hmsoft/ai/idcard/baidu/BaiduIdCardOcr.java

@@ -0,0 +1,148 @@
+package cn.hmsoft.ai.idcard.baidu;
+
+import java.io.File;
+import java.util.HashMap;
+
+import com.baidu.aip.ocr.AipOcr;
+import com.google.gson.JsonObject;
+
+import cn.hmsoft.ai.idcard.IdCard;
+import cn.hmsoft.ai.idcard.IdCardBack;
+import cn.hmsoft.ai.idcard.IdCardOcr;
+import cn.hmsoft.ai.util.AiParamUtil;
+import cn.hmsoft.helper.CollectionHelper;
+import cn.hmsoft.helper.LocalDateHelper;
+
+/**************************
+ * 使用百度api实现身份证识别
+ * 
+ * @author zxq
+ * @create 2019-08-23 16:52:28
+ * @version 2.0.0
+ * @email: revisit@126.com
+ * @Company: www.hmsoft.cn
+ * 
+ *           { "log_id": 1140563900576588182, "words_result": { "姓名": { "words":
+ *           "张小庆", "location": { "top": 435, "left": 843, "width": 460,
+ *           "height": 159 } }, "民族": { "words": "汉", "location": { "top": 750,
+ *           "left": 1553, "width": 92, "height": 112 } }, "住址": { "words":
+ *           "杭州市上城区大学路新村6幢14号601室", "location": { "top": 1298, "left": 853,
+ *           "width": 1408, "height": 291 } }, "公民身份号码": { "words":
+ *           "352622198007091515", "location": { "top": 1974, "left": 1408,
+ *           "width": 1812, "height": 126 } }, "出生": { "words": "19800709",
+ *           "location": { "top": 1015, "left": 852, "width": 1133, "height":
+ *           119 } }, "性别": { "words": "男", "location": { "top": 754, "left":
+ *           864, "width": 92, "height": 117 } } }, "words_result_num": 6,
+ *           "image_status": "normal", "direction": 0 }
+ */
+public class BaiduIdCardOcr extends IdCardOcr {
+
+	@Override
+	public IdCard ocrIdCardByFile(File idcard_image_file) {
+		// 每次访问一次实例,防止token串的问题
+		String appId = AiParamUtil.ParamMap.get(AiParamUtil.ParamName_BaiduOcrAppId).trim();
+		String appKey = AiParamUtil.ParamMap.get(AiParamUtil.ParamName_BaiduOcrAppKey).trim();
+		String secretKey = AiParamUtil.ParamMap.get(AiParamUtil.ParamName_BaiduOcrSecretKey).trim();
+		// System.out.println(appId);
+		// System.out.println(appKey);
+		// System.out.println(secretKey);
+		AipOcr client = new AipOcr(appId, appKey, secretKey);
+		// 设置参数
+		// 网络超时,默认5秒
+		client.setConnectionTimeoutInMillis(CollectionHelper.getParamValue(AiParamUtil.ParamMap,
+				AiParamUtil.ParamName_BaiduOcrConnectionTimeoutInMillis, 5) * 1000);
+
+		// 传入可选参数调用接口
+		HashMap<String, String> options = new HashMap<String, String>();
+		options.put("detect_direction", "true");
+		options.put("detect_risk", "true");
+		// detect_photo 图片信息
+		options.put("detect_photo", "true");
+		String idCardSide = "front";
+
+		// 参数为本地路径
+		JsonObject res = client.idcard(idcard_image_file.getPath(), idCardSide, options);
+		IdCard card = new IdCard();
+		try {
+			card.setDirection(res.get("direction").getAsInt());
+			if (card.getDirection() == 1) {
+				card.setDirection(90);
+			} else if (card.getDirection() == 2) {
+				card.setDirection(180);
+			} else if (card.getDirection() == 3) {
+				card.setDirection(270);
+			}
+		} catch (Exception e) {
+
+		}
+		try {
+			card.setPhoto(res.get("photo").getAsString());
+		} catch (Exception e) {
+
+		}
+		if (res.get("image_status").getAsString().equals("normal")) {
+			// 成功识别
+			card.setPerson_name(
+					res.get("words_result").getAsJsonObject().get("姓名").getAsJsonObject().get("words").getAsString());
+			card.setPerson_nation(
+					res.get("words_result").getAsJsonObject().get("民族").getAsJsonObject().get("words").getAsString());
+			card.setPerson_addr(
+					res.get("words_result").getAsJsonObject().get("住址").getAsJsonObject().get("words").getAsString());
+			card.setPerson_code(res.get("words_result").getAsJsonObject().get("公民身份号码").getAsJsonObject().get("words")
+					.getAsString());
+			card.setBirthday(LocalDateHelper.parseDateNoSplit(
+					res.get("words_result").getAsJsonObject().get("出生").getAsJsonObject().get("words").getAsString()));
+			card.setPerson_sex(
+					res.get("words_result").getAsJsonObject().get("性别").getAsJsonObject().get("words").getAsString());
+			card.setOcr_success(true);
+		} else
+			card.setError_msg(res.get("image_status").getAsString());
+		return card;
+
+	}
+
+	/**  
+	 * @Description: 身份证反面识别
+	 * @date 2023-11-09 04:13:27 
+	 */
+	@Override
+	public IdCardBack ocrIdCardBackByFile(File idcard_image_file) {
+		String appId = AiParamUtil.ParamMap.get(AiParamUtil.ParamName_BaiduOcrAppId).trim();
+		String appKey = AiParamUtil.ParamMap.get(AiParamUtil.ParamName_BaiduOcrAppKey).trim();
+		String secretKey = AiParamUtil.ParamMap.get(AiParamUtil.ParamName_BaiduOcrSecretKey).trim();
+		AipOcr client = new AipOcr(appId, appKey, secretKey);
+		client.setConnectionTimeoutInMillis(CollectionHelper.getParamValue(AiParamUtil.ParamMap,
+				AiParamUtil.ParamName_BaiduOcrConnectionTimeoutInMillis, 5) * 1000);
+		HashMap<String, String> options = new HashMap<String, String>();
+		options.put("detect_direction", "true");
+		options.put("detect_risk", "true");
+		// detect_photo 图片信息
+		options.put("detect_photo", "true");
+		String idCardSide = "back";
+		// 参数为本地路径
+		JsonObject res = client.idcard(idcard_image_file.getPath(), idCardSide, options);
+		IdCardBack back = new IdCardBack();
+		try {
+			back.setDirection(res.get("direction").getAsInt());
+			if (back.getDirection() == 1) {
+				back.setDirection(90);
+			} else if (back.getDirection() == 2) {
+				back.setDirection(180);
+			} else if (back.getDirection() == 3) {
+				back.setDirection(270);
+			}
+		} catch (Exception e) {
+
+		}
+		if (res.get("image_status").getAsString().equals("normal")) {
+			back.setSign_organization(res.get("words_result").getAsJsonObject().get("签发机关").getAsJsonObject().get("words").getAsString());
+			back.setIssue_date(res.get("words_result").getAsJsonObject().get("签发日期").getAsJsonObject().get("words").getAsString());
+			back.setExpire_date(res.get("words_result").getAsJsonObject().get("失效日期").getAsJsonObject().get("words").getAsString());
+			back.setOcr_success(true);
+		} else {
+			back.setError_msg(res.get("image_status").getAsString());
+		}
+		return back;
+	}
+
+}

+ 33 - 0
src/cn/hmsoft/ai/identity/IdentifiedResult.java

@@ -0,0 +1,33 @@
+package cn.hmsoft.ai.identity;
+
+public class IdentifiedResult {
+
+	private boolean success;
+	private String error_msg = "出现未知错误!请稍后再试";
+	private double percent;
+
+	public boolean isSuccess() {
+		return success;
+	}
+
+	public void setSuccess(boolean success) {
+		this.success = success;
+	}
+
+	public String getError_msg() {
+		return error_msg;
+	}
+
+	public void setError_msg(String error_msg) {
+		this.error_msg = error_msg;
+	}
+
+	public double getPercent() {
+		return percent;
+	}
+
+	public void setPercent(double percent) {
+		this.percent = percent;
+	}
+
+}

+ 50 - 0
src/cn/hmsoft/ai/identity/IdentityAI.java

@@ -0,0 +1,50 @@
+package cn.hmsoft.ai.identity;
+
+import java.io.File;
+
+import cn.hmsoft.ai.idcard.IdCardOcr;
+import cn.hmsoft.ai.util.AiParamUtil;
+
+public abstract class IdentityAI {
+	private static IdentityAI ai = null;
+
+	public static IdentityAI instance() {
+		if (ai == null) {
+			synchronized (IdCardOcr.class) {
+				try {
+					ai = (IdentityAI) Class.forName(AiParamUtil.IdentityAIClass).newInstance();
+				} catch (Exception e) {
+					try {
+						ai = IdentityNoAI.class.newInstance();
+					} catch (Exception ex) {
+
+					}
+				}
+			}
+		}
+		return ai;
+	}
+
+	public IdentifiedResult verify(String idphoto_image_path, String id_card, String std_name) {
+		return this.verifyByFile(new File(idphoto_image_path), id_card, std_name);
+
+	}
+
+	public IdentifiedResult verify(File idphoto_image_file, String id_card, String std_name) {
+		return verify(idphoto_image_file.getPath(), id_card, std_name);
+	}
+	
+	public IdentifiedResult verify(File id_photo, File snap_photo) {
+		return this.verifyFiles(id_photo, snap_photo);
+	}
+	public IdentifiedResult verify(String url1, String url2) {
+		return this.verifyFiles(url1, url2);
+	}
+	
+
+	protected abstract IdentifiedResult verifyByFile(File file, String id_card, String std_name);
+	
+	protected abstract IdentifiedResult verifyFiles(File sourceFile, File destFile);
+	
+	protected abstract IdentifiedResult verifyFiles(String url1, String url2);
+}

Kaikkia tiedostoja ei voida näyttää, sillä liian monta tiedostoa muuttui tässä diffissä