复制自助机模块的完善

This commit is contained in:
张雪 2025-07-02 09:28:50 +08:00
parent 11b684294d
commit 91c7818dee
4 changed files with 105 additions and 45 deletions

View File

@ -1,19 +1,13 @@
package com.dpkj.modules.scanface.ali.controller; 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.alibaba.fastjson.JSONObject;
import com.dpkj.common.vo.Result; import com.dpkj.common.vo.Result;
import com.dpkj.modules.scanface.ali.config.AliFaceConfig; import com.dpkj.modules.scanface.ali.config.AliFaceConfig;
import com.dpkj.modules.scanface.ali.constants.AliFaceConstants; 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.service.IAliScanFaceService;
import com.dpkj.modules.scanface.ali.vo.AliOrderVo; import com.dpkj.modules.scanface.ali.vo.AliOrderVo;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j; 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.GetMapping;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody; 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 org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.io.File;
import java.util.Map;
/** /**
* @Auther: 萧道子 * @Auther: 萧道子

View File

@ -1,6 +1,5 @@
package com.dpkj.modules.scanface.ali.dll; package com.dpkj.modules.scanface.ali.dll;
import com.dpkj.common.vo.Result;
import com.sun.jna.Callback; import com.sun.jna.Callback;
import com.sun.jna.Native; import com.sun.jna.Native;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
@ -33,7 +32,7 @@ public class AbcpInvoke {
msAbcpNativeDll = (AbcpNativeDll) Native.load(fileDylib, AbcpNativeDll.class); msAbcpNativeDll = (AbcpNativeDll) Native.load(fileDylib, AbcpNativeDll.class);
} catch (Throwable e) { } catch (Throwable e) {
msAbcpNativeDll = null; msAbcpNativeDll = null;
log.error("## 本地库未加载,返回错误 ERROR :{},{} ", fileDylib, e.getMessage()); log.error("## 本地库未加载,返回错误 ERROR : load. ## [%s][%s] %n", fileDylib, e.getMessage());
} }
} else { } else {
log.error("## ERROR : dylib NOT exist ## %s %n", fileDylib); log.error("## ERROR : dylib NOT exist ## %s %n", fileDylib);

View File

@ -4,8 +4,8 @@ import cn.hutool.core.util.CharsetUtil;
import cn.hutool.http.ContentType; import cn.hutool.http.ContentType;
import cn.hutool.http.Header; import cn.hutool.http.Header;
import cn.hutool.http.HttpRequest; import cn.hutool.http.HttpRequest;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.dpkj.common.vo.Result; import com.dpkj.common.vo.Result;
import com.dpkj.modules.scanface.ali.config.AliFaceConfig; import com.dpkj.modules.scanface.ali.config.AliFaceConfig;
import com.dpkj.modules.scanface.ali.constants.AliFaceConstants; 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.beans.factory.annotation.Value;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.thymeleaf.util.StringUtils;
import javax.annotation.PostConstruct;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.io.File; import java.io.File;
import java.util.HashMap; import java.util.HashMap;
@ -44,6 +44,20 @@ public class AliScanFaceServiceImpl implements IAliScanFaceService {
private AliFaceConfig aliFaceConfig; 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: * 完整的统一的支付宝刷脸支付 * @description: * 完整的统一的支付宝刷脸支付
* 1调用硬件刷脸获取到ftoken * 1调用硬件刷脸获取到ftoken
@ -56,10 +70,14 @@ public class AliScanFaceServiceImpl implements IAliScanFaceService {
@Override @Override
public Result<JSONObject> aliFacePay(AliOrderVo aliOrderVo) { public Result<JSONObject> aliFacePay(AliOrderVo aliOrderVo) {
try { try {
/**
* 0执行ABCP初始化
*/
Result<Object> result = this.iniAbcpAbsolute();
if (result.isSuccess()) {
/** /**
* 1获取刷脸"刷脸去初始化服务"的ftoken返回值 * 1获取刷脸"刷脸去初始化服务"的ftoken返回值
*/ */
this.iniAbcpAbsolute();
//参数 //参数
JSONObject zolozConfig = new JSONObject().fluentPut("installAngle", 90); JSONObject zolozConfig = new JSONObject().fluentPut("installAngle", 90);
JSONObject params = new JSONObject() JSONObject params = new JSONObject()
@ -68,23 +86,28 @@ public class AliScanFaceServiceImpl implements IAliScanFaceService {
String json = params.toJSONString(); String json = params.toJSONString();
String service_code = AliFaceConstants.SMILEVERIFYNIN_V1; //调用的组件编码:初始化 String service_code = AliFaceConstants.SMILEVERIFYNIN_V1; //调用的组件编码:初始化
Result<Object> startServiceIniResult = this.startServiceIni(json, service_code); Result<Object> startServiceIniResult = this.startServiceIni(json, service_code);
log.info("[AliScanFaceServiceImpl][aliFacePay][72][1、获取刷脸去初始化服务的结果] {}", startServiceIniResult.toString());
if (startServiceIniResult.isSuccess()) { if (startServiceIniResult.isSuccess()) {
Map<String, String> res = (Map<String, String>) startServiceIniResult.getResult(); Map<String, String> res = (Map<String, String>) startServiceIniResult.getResult();
String ftoken = res.get("ftoken"); String ftoken = res.get("ftoken");
log.info("[AliScanFaceServiceImpl][aliFacePay][76][[1、获取刷脸去初始化服务的结果-ftoken值] {}", ftoken);
/** /**
* 2调用后端的支付宝统一收单交易支付接口存入hisPay * 2调用后端的支付宝统一收单交易支付接口存入hisPay
*/ */
aliOrderVo.setAuthCode(ftoken);//Demo值"fp128d26333fa66e66e7f34c493d30cdh76" aliOrderVo.setAuthCode(ftoken);//Demo值"fp128d26333fa66e66e7f34c493d30cdh76"
JSONObject serverParams = (JSONObject) JSON.toJSON(aliOrderVo); JSONObject serverParams = (JSONObject) JSON.toJSON(aliOrderVo);
log.info("[AliScanFaceServiceImpl][aliFacePay][83][调用后端的支付宝统一收单交易支付接口参数] {}", serverParams.toString());
String url = serverUrl + "openapi/aliPayOrderApi/createOrder"; String url = serverUrl + "openapi/aliPayOrderApi/createOrder";
log.info("[AliScanFaceServiceImpl][aliFacePay][86][调用后端的支付宝统一收单交易支付接口路径] {}", url);
String req = HttpRequest.post(url) String req = HttpRequest.post(url)
.header(Header.CONTENT_TYPE, ContentType.JSON.toString(CharsetUtil.CHARSET_UTF_8)) .header(Header.CONTENT_TYPE, ContentType.JSON.toString(CharsetUtil.CHARSET_UTF_8))
.body(serverParams.toJSONString()) .body(serverParams.toJSONString())
.execute() .execute()
.body(); .body();
JSONObject serverResult = JSONObject.parseObject(req); JSONObject serverResult = JSONObject.parseObject(req);
log.info("[AliScanFaceServiceImpl][aliFacePay][93][调用后端的支付宝统一收单交易支付接口结果] {}", serverResult.toString());
return Result.ok(serverResult); return Result.ok(serverResult);
} else { } else {
@ -92,6 +115,9 @@ public class AliScanFaceServiceImpl implements IAliScanFaceService {
log.error("[AliScanFaceServiceImpl][aliFacePay][299]调用ABCP 刷脸初始化服务失败 {}", startServiceIniResult.getMessage()); log.error("[AliScanFaceServiceImpl][aliFacePay][299]调用ABCP 刷脸初始化服务失败 {}", startServiceIniResult.getMessage());
return Result.error(startServiceIniResult.getMessage()); return Result.error(startServiceIniResult.getMessage());
} }
}else {
return Result.error("执行iniAbcpAbsolute初始化失败");
}
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
log.error("[AliScanFaceServiceImpl][aliFacePay][302][整个支付宝刷脸模块出现失败:] {}", e.getMessage()); log.error("[AliScanFaceServiceImpl][aliFacePay][302][整个支付宝刷脸模块出现失败:] {}", e.getMessage());
@ -126,23 +152,59 @@ public class AliScanFaceServiceImpl implements IAliScanFaceService {
//指定支付宝LOT SDK的本地库路径 //指定支付宝LOT SDK的本地库路径
AbcpInvoke.SetAPIPathFile(aliFaceConfig.getDllPath()); AbcpInvoke.SetAPIPathFile(aliFaceConfig.getDllPath());
// 使用 CountDownLatch 实现线程同步
CountDownLatch latch = new CountDownLatch(1);
CountDownLatch latchFinish = new CountDownLatch(1);
//获取返回数据
AtomicReference<Integer> processCode = new AtomicReference<>();
AtomicReference<String> processResult = new AtomicReference<>();
AtomicReference<Integer> finishCode = new AtomicReference<>();
AtomicReference<String> finishResult = new AtomicReference<>();
//创建回调实例 //创建回调实例
AbcpInvoke.CallbackRsp callbackRsp = new AbcpInvoke.CallbackRsp() { AbcpInvoke.CallbackRsp callbackRsp = new AbcpInvoke.CallbackRsp() {
@Override @Override
public void OnProcess(int code, String subCode, String subMsg, String result) { 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 @Override
public void OnFinish(int code, String subCode, String subMsg, String result) { 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); 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 { } else {
log.info("[AliScanFaceServiceImpl][iniAbcpAbsolute][55][{} :文件不存在]", aliFaceConfig.getDllPath()); log.info("[AliScanFaceServiceImpl][iniAbcpAbsolute][55][{} :文件不存在]", aliFaceConfig.getDllPath());
return Result.error("支付宝ABCP初始化失败" + aliFaceConfig.getDllPath() + "不存在"); return Result.error("支付宝ABCP初始化失败" + aliFaceConfig.getDllPath() + "不存在");
@ -217,10 +279,13 @@ public class AliScanFaceServiceImpl implements IAliScanFaceService {
// 等待process回调完成设置超时避免死锁 // 等待process回调完成设置超时避免死锁
boolean awaitSuccess = latch.await(10, TimeUnit.SECONDS); boolean awaitSuccess = latch.await(10, TimeUnit.SECONDS);
if (!awaitSuccess) { if (!awaitSuccess) {
log.info("[AliScanFaceServiceImpl][startServiceIni][226][10秒-等待process回调超时]");
return Result.error("等待process回调超时"); return Result.error("等待process回调超时");
} else { } else {
log.info("[AliScanFaceServiceImpl][startServiceIni][229][ABCP调用刷脸初始化服务-process回调结果-processCode] {}", processCode);
if (processCode.get() == 0) { if (processCode.get() == 0) {
JSONObject jsonObject = JSONObject.parseObject(processResult.get()); JSONObject jsonObject = JSONObject.parseObject(processResult.get());
log.info("[AliScanFaceServiceImpl][startServiceIni][232][ABCP调用刷脸初始化服务-process回调结果] {}", jsonObject.toString());
if (jsonObject.containsKey("traceId")) { if (jsonObject.containsKey("traceId")) {
res.put("traceId", jsonObject.getString("traceId")); res.put("traceId", jsonObject.getString("traceId"));
} else { } else {
@ -234,10 +299,13 @@ public class AliScanFaceServiceImpl implements IAliScanFaceService {
// 等待finish回调完成设置超时避免死锁 // 等待finish回调完成设置超时避免死锁
boolean awaitFinishSuccess = latchFinish.await(120, TimeUnit.SECONDS); boolean awaitFinishSuccess = latchFinish.await(120, TimeUnit.SECONDS);
if (!awaitFinishSuccess) { if (!awaitFinishSuccess) {
log.info("[AliScanFaceServiceImpl][startServiceIni][246][120秒-等待finish回调超时]");
return Result.error("等待finish回调超时"); return Result.error("等待finish回调超时");
} else { } else {
log.info("[AliScanFaceServiceImpl][startServiceIni][249][ABCP调用刷脸初始化服务-finish回调结果-finishCode] {}", finishCode);
if (finishCode.get() == 1000) { if (finishCode.get() == 1000) {
JSONObject jsonObject = JSONObject.parseObject(finishResult.get()); JSONObject jsonObject = JSONObject.parseObject(finishResult.get());
log.info("[AliScanFaceServiceImpl][startServiceIni][252][ABCP调用刷脸初始化服务-finish回调结果] {}", jsonObject.toString());
if (jsonObject.containsKey("ftoken")) { if (jsonObject.containsKey("ftoken")) {
res.put("ftoken", jsonObject.getString("ftoken"));//ftoken参数的有效期为2分钟 res.put("ftoken", jsonObject.getString("ftoken"));//ftoken参数的有效期为2分钟
res.put("barCode", jsonObject.getString("barCode")); 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(); return finishResultRef.get();
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();

View File

@ -37,7 +37,7 @@ public class AliOrderVo implements Serializable {
private String outTradeNo; private String outTradeNo;
/** /**
* 用户支付金额 * 用户支付金额 单位元
*/ */
//@ApiModelProperty(value = "用户支付金额") //@ApiModelProperty(value = "用户支付金额")
private String totalAmount; private String totalAmount;