diff --git a/src/main/java/com/dpkj/modules/scanface/ali/controller/AliScanFaceController.java b/src/main/java/com/dpkj/modules/scanface/ali/controller/AliScanFaceController.java index 895c899..9765772 100644 --- a/src/main/java/com/dpkj/modules/scanface/ali/controller/AliScanFaceController.java +++ b/src/main/java/com/dpkj/modules/scanface/ali/controller/AliScanFaceController.java @@ -1,19 +1,13 @@ package com.dpkj.modules.scanface.ali.controller; -import cn.hutool.core.util.CharsetUtil; -import cn.hutool.http.ContentType; -import cn.hutool.http.Header; -import cn.hutool.http.HttpRequest; import com.alibaba.fastjson.JSONObject; import com.dpkj.common.vo.Result; import com.dpkj.modules.scanface.ali.config.AliFaceConfig; import com.dpkj.modules.scanface.ali.constants.AliFaceConstants; -import com.dpkj.modules.scanface.ali.dll.AbcpInvoke; import com.dpkj.modules.scanface.ali.service.IAliScanFaceService; import com.dpkj.modules.scanface.ali.vo.AliOrderVo; import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; -import org.springframework.beans.factory.annotation.Value; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; @@ -22,8 +16,6 @@ import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import javax.annotation.Resource; -import java.io.File; -import java.util.Map; /** * @Auther: 萧道子 diff --git a/src/main/java/com/dpkj/modules/scanface/ali/dll/AbcpInvoke.java b/src/main/java/com/dpkj/modules/scanface/ali/dll/AbcpInvoke.java index bf8b6c3..0189970 100644 --- a/src/main/java/com/dpkj/modules/scanface/ali/dll/AbcpInvoke.java +++ b/src/main/java/com/dpkj/modules/scanface/ali/dll/AbcpInvoke.java @@ -1,6 +1,5 @@ package com.dpkj.modules.scanface.ali.dll; -import com.dpkj.common.vo.Result; import com.sun.jna.Callback; import com.sun.jna.Native; import lombok.extern.slf4j.Slf4j; @@ -33,7 +32,7 @@ public class AbcpInvoke { msAbcpNativeDll = (AbcpNativeDll) Native.load(fileDylib, AbcpNativeDll.class); } catch (Throwable e) { msAbcpNativeDll = null; - log.error("## 本地库未加载,返回错误 ERROR :{},{} ", fileDylib, e.getMessage()); + log.error("## 本地库未加载,返回错误 ERROR : load. ## [%s][%s] %n", fileDylib, e.getMessage()); } } else { log.error("## ERROR : dylib NOT exist ## %s %n", fileDylib); diff --git a/src/main/java/com/dpkj/modules/scanface/ali/service/impl/AliScanFaceServiceImpl.java b/src/main/java/com/dpkj/modules/scanface/ali/service/impl/AliScanFaceServiceImpl.java index cbeadbc..316cfd3 100644 --- a/src/main/java/com/dpkj/modules/scanface/ali/service/impl/AliScanFaceServiceImpl.java +++ b/src/main/java/com/dpkj/modules/scanface/ali/service/impl/AliScanFaceServiceImpl.java @@ -4,8 +4,8 @@ import cn.hutool.core.util.CharsetUtil; import cn.hutool.http.ContentType; import cn.hutool.http.Header; import cn.hutool.http.HttpRequest; -import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; import com.dpkj.common.vo.Result; import com.dpkj.modules.scanface.ali.config.AliFaceConfig; import com.dpkj.modules.scanface.ali.constants.AliFaceConstants; @@ -16,8 +16,8 @@ import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; import org.springframework.stereotype.Service; -import org.thymeleaf.util.StringUtils; +import javax.annotation.PostConstruct; import javax.annotation.Resource; import java.io.File; import java.util.HashMap; @@ -44,6 +44,20 @@ public class AliScanFaceServiceImpl implements IAliScanFaceService { private AliFaceConfig aliFaceConfig; + /** + * 资源初始化 + * 把刷脸初始化加到项目启动时先初始化一次,防止首次调用刷脸初始化过慢的问题 + */ + @PostConstruct + public void postConstruct() { + log.info("[AliScanFaceServiceImpl][postConstruct][支付宝刷脸DLL] 初始化动态链接库"); + try { + this.iniAbcpAbsolute(); + } catch (Exception e) { + log.info("[AliScanFaceServiceImpl][postConstruct][56][支付宝刷脸初始化失败:] :{}", e.getMessage()); + } + } + /** * @description: * 完整的统一的支付宝刷脸支付 * 1、调用硬件刷脸获取到ftoken @@ -57,40 +71,52 @@ public class AliScanFaceServiceImpl implements IAliScanFaceService { public Result aliFacePay(AliOrderVo aliOrderVo) { try { /** - * 1、获取刷脸"刷脸去初始化服务"的ftoken返回值 + * 0、执行ABCP初始化 */ - this.iniAbcpAbsolute(); - //参数 - JSONObject zolozConfig = new JSONObject().fluentPut("installAngle", 90); - JSONObject params = new JSONObject() - .fluentPut("serviceId", aliFaceConfig.getServiceId()) - .fluentPut("zolozConfig", zolozConfig); - String json = params.toJSONString(); - String service_code = AliFaceConstants.SMILEVERIFYNIN_V1; //调用的组件编码:初始化 - Result startServiceIniResult = this.startServiceIni(json, service_code); - if (startServiceIniResult.isSuccess()) { - Map res = (Map) startServiceIniResult.getResult(); - String ftoken = res.get("ftoken"); - + Result result = this.iniAbcpAbsolute(); + if (result.isSuccess()) { /** - * 2、调用后端的支付宝统一收单交易支付接口、存入hisPay + * 1、获取刷脸"刷脸去初始化服务"的ftoken返回值 */ - aliOrderVo.setAuthCode(ftoken);//Demo值:"fp128d26333fa66e66e7f34c493d30cdh76" - JSONObject serverParams = (JSONObject) JSON.toJSON(aliOrderVo); + //参数 + JSONObject zolozConfig = new JSONObject().fluentPut("installAngle", 90); + JSONObject params = new JSONObject() + .fluentPut("serviceId", aliFaceConfig.getServiceId()) + .fluentPut("zolozConfig", zolozConfig); + String json = params.toJSONString(); + String service_code = AliFaceConstants.SMILEVERIFYNIN_V1; //调用的组件编码:初始化 + Result startServiceIniResult = this.startServiceIni(json, service_code); + log.info("[AliScanFaceServiceImpl][aliFacePay][72][1、获取刷脸去初始化服务的结果] :{}", startServiceIniResult.toString()); + if (startServiceIniResult.isSuccess()) { + Map res = (Map) startServiceIniResult.getResult(); + String ftoken = res.get("ftoken"); + log.info("[AliScanFaceServiceImpl][aliFacePay][76][[1、获取刷脸去初始化服务的结果-ftoken值] :{}", ftoken); - String url = serverUrl + "openapi/aliPayOrderApi/createOrder"; - String req = HttpRequest.post(url) - .header(Header.CONTENT_TYPE, ContentType.JSON.toString(CharsetUtil.CHARSET_UTF_8)) - .body(serverParams.toJSONString()) - .execute() - .body(); - JSONObject serverResult = JSONObject.parseObject(req); + /** + * 2、调用后端的支付宝统一收单交易支付接口、存入hisPay + */ + aliOrderVo.setAuthCode(ftoken);//Demo值:"fp128d26333fa66e66e7f34c493d30cdh76" + JSONObject serverParams = (JSONObject) JSON.toJSON(aliOrderVo); + log.info("[AliScanFaceServiceImpl][aliFacePay][83][调用后端的支付宝统一收单交易支付接口参数] :{}", serverParams.toString()); - return Result.ok(serverResult); - } else { - //调用ABCP 刷脸初始化服务失败 - log.error("[AliScanFaceServiceImpl][aliFacePay][299]调用ABCP 刷脸初始化服务失败 :{}", startServiceIniResult.getMessage()); - return Result.error(startServiceIniResult.getMessage()); + String url = serverUrl + "openapi/aliPayOrderApi/createOrder"; + log.info("[AliScanFaceServiceImpl][aliFacePay][86][调用后端的支付宝统一收单交易支付接口路径] :{}", url); + String req = HttpRequest.post(url) + .header(Header.CONTENT_TYPE, ContentType.JSON.toString(CharsetUtil.CHARSET_UTF_8)) + .body(serverParams.toJSONString()) + .execute() + .body(); + JSONObject serverResult = JSONObject.parseObject(req); + log.info("[AliScanFaceServiceImpl][aliFacePay][93][调用后端的支付宝统一收单交易支付接口结果] :{}", serverResult.toString()); + + return Result.ok(serverResult); + } else { + //调用ABCP 刷脸初始化服务失败 + log.error("[AliScanFaceServiceImpl][aliFacePay][299]调用ABCP 刷脸初始化服务失败 :{}", startServiceIniResult.getMessage()); + return Result.error(startServiceIniResult.getMessage()); + } + }else { + return Result.error("执行iniAbcpAbsolute初始化失败"); } } catch (Exception e) { e.printStackTrace(); @@ -126,23 +152,59 @@ public class AliScanFaceServiceImpl implements IAliScanFaceService { //指定支付宝LOT SDK的本地库路径 AbcpInvoke.SetAPIPathFile(aliFaceConfig.getDllPath()); + // 使用 CountDownLatch 实现线程同步 + CountDownLatch latch = new CountDownLatch(1); + CountDownLatch latchFinish = new CountDownLatch(1); + + //获取返回数据 + AtomicReference processCode = new AtomicReference<>(); + AtomicReference processResult = new AtomicReference<>(); + AtomicReference finishCode = new AtomicReference<>(); + AtomicReference finishResult = new AtomicReference<>(); + //创建回调实例 AbcpInvoke.CallbackRsp callbackRsp = new AbcpInvoke.CallbackRsp() { @Override public void OnProcess(int code, String subCode, String subMsg, String result) { - log.info("[AliScanFaceServiceImpl][OnProcess][123][ABCP调用iniAbcpAbsolute][code:{}][subCode:{}][subMsg:{}][result:{}]", code, subCode, subMsg, result); + log.info("[AliScanFaceServiceImpl][OnProcess][155][0、ABCP调用iniAbcpAbsolute-OnProcess][code:{}][subCode:{}][subMsg:{}][result:{}] ", code, subCode, subMsg, result); + try { + processCode.set(code); + processResult.set(result); + } finally { + latch.countDown(); // 确保无论如何都释放锁 + } } @Override public void OnFinish(int code, String subCode, String subMsg, String result) { - log.info("[AliScanFaceServiceImpl][OnFinish][128][ABCP调用iniAbcpAbsolute][code:{}][subCode:{}][subMsg:{}][result:{}]", code, subCode, subMsg, result); + log.info("[AliScanFaceServiceImpl][OnFinish][167][0、ABCP调用iniAbcpAbsolute-OnFinish][code:{}][subCode:{}][subMsg:{}][result:{}]", code, subCode, subMsg, result); + try { + finishCode.set(code); + finishResult.set(result); + } finally { + latchFinish.countDown(); // 确保无论如何都释放锁 + } } }; //初始化 + log.info("[AliScanFaceServiceImpl][iniAbcpAbsolute][175][0、ABCP调用iniAbcpAbsolute初始化参数][appId:{}][appVersion:{}][json:{}] ", aliFaceConfig.getAppId(), aliFaceConfig.getAppVersion(), json); AbcpInvoke.AbcpInit(aliFaceConfig.getAppId(), aliFaceConfig.getAppVersion(), json, callbackRsp); - return Result.ok("支付宝ABCP初始化成功"); + // 等待finish回调完成(设置超时避免死锁) + boolean awaitFinishSuccess = latchFinish.await(120, TimeUnit.SECONDS); + if (!awaitFinishSuccess) { + log.info("[AliScanFaceServiceImpl][iniAbcpAbsolute][181] [0、ABCP调用iniAbcpAbsolute初始化-120秒-等待finish回调超时]"); + return Result.error("初始化等待finish回调超时"); + } else { + JSONObject jsonObject = JSONObject.parseObject(finishResult.get()); + log.info("[AliScanFaceServiceImpl][iniAbcpAbsolute][184][0、ABCP调用iniAbcpAbsolute初始化-finish回调结果-finishCode :{}] [返回结果:{}]", finishCode, jsonObject.toString()); + if (finishCode.get() == 1000) { + return Result.ok("ABCP调用iniAbcpAbsolute初始化成功"); + } else { + return Result.error("ABCP调用刷脸初始化服务finish失败"); + } + } } else { log.info("[AliScanFaceServiceImpl][iniAbcpAbsolute][55][{} :文件不存在]", aliFaceConfig.getDllPath()); return Result.error("支付宝ABCP初始化失败:" + aliFaceConfig.getDllPath() + "不存在"); @@ -217,10 +279,13 @@ public class AliScanFaceServiceImpl implements IAliScanFaceService { // 等待process回调完成(设置超时避免死锁) boolean awaitSuccess = latch.await(10, TimeUnit.SECONDS); if (!awaitSuccess) { + log.info("[AliScanFaceServiceImpl][startServiceIni][226][10秒-等待process回调超时]"); return Result.error("等待process回调超时"); } else { + log.info("[AliScanFaceServiceImpl][startServiceIni][229][ABCP调用刷脸初始化服务-process回调结果-processCode] :{}", processCode); if (processCode.get() == 0) { JSONObject jsonObject = JSONObject.parseObject(processResult.get()); + log.info("[AliScanFaceServiceImpl][startServiceIni][232][ABCP调用刷脸初始化服务-process回调结果] :{}", jsonObject.toString()); if (jsonObject.containsKey("traceId")) { res.put("traceId", jsonObject.getString("traceId")); } else { @@ -234,10 +299,13 @@ public class AliScanFaceServiceImpl implements IAliScanFaceService { // 等待finish回调完成(设置超时避免死锁) boolean awaitFinishSuccess = latchFinish.await(120, TimeUnit.SECONDS); if (!awaitFinishSuccess) { + log.info("[AliScanFaceServiceImpl][startServiceIni][246][120秒-等待finish回调超时]"); return Result.error("等待finish回调超时"); } else { + log.info("[AliScanFaceServiceImpl][startServiceIni][249][ABCP调用刷脸初始化服务-finish回调结果-finishCode] :{}", finishCode); if (finishCode.get() == 1000) { JSONObject jsonObject = JSONObject.parseObject(finishResult.get()); + log.info("[AliScanFaceServiceImpl][startServiceIni][252][ABCP调用刷脸初始化服务-finish回调结果] :{}", jsonObject.toString()); if (jsonObject.containsKey("ftoken")) { res.put("ftoken", jsonObject.getString("ftoken"));//ftoken参数的有效期为2分钟 res.put("barCode", jsonObject.getString("barCode")); @@ -251,6 +319,7 @@ public class AliScanFaceServiceImpl implements IAliScanFaceService { } //结果返回 + log.info("[AliScanFaceServiceImpl][startServiceIni][266][][ABCP调用刷脸初始化服务成功返回结果:] :{}", finishResultRef.get()); return finishResultRef.get(); } catch (Exception e) { e.printStackTrace(); diff --git a/src/main/java/com/dpkj/modules/scanface/ali/vo/AliOrderVo.java b/src/main/java/com/dpkj/modules/scanface/ali/vo/AliOrderVo.java index 7eeb922..8bc91c2 100644 --- a/src/main/java/com/dpkj/modules/scanface/ali/vo/AliOrderVo.java +++ b/src/main/java/com/dpkj/modules/scanface/ali/vo/AliOrderVo.java @@ -37,7 +37,7 @@ public class AliOrderVo implements Serializable { private String outTradeNo; /** - * 用户支付金额 + * 用户支付金额 单位元 */ //@ApiModelProperty(value = "用户支付金额") private String totalAmount;