支付宝刷脸初始化方法

This commit is contained in:
张雪 2025-04-16 22:01:34 +08:00
parent 67b48d209d
commit ee0b1ac055
9 changed files with 504 additions and 17 deletions

View File

@ -0,0 +1,27 @@
package com.dpkj.modules.scanface.ali.config;
import lombok.Data;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
/**
* @description: 支付宝刷脸配置信息
* @author: Zhangxue
* @time: 2025/4/16 20:23
*/
@Data
@Component
@ConfigurationProperties(prefix = "dpkj.ali.face")
public class AliFaceConfig {
private String appId;
private String appVersion;
private String merchantId;
private String deviceNum;
private String partnerId;
}

View File

@ -6,8 +6,11 @@ import com.dpkj.common.constant.ChsConst;
import com.dpkj.common.vo.Result; import com.dpkj.common.vo.Result;
import com.dpkj.modules.chs.dll.AlipayDll; import com.dpkj.modules.chs.dll.AlipayDll;
import com.dpkj.modules.chs.entity.AlipayEcRequestData; import com.dpkj.modules.chs.entity.AlipayEcRequestData;
import com.dpkj.modules.scanface.ali.config.AliFaceConfig;
import com.dpkj.modules.scanface.ali.dll.AbcpInvoke;
import com.dpkj.modules.scanface.ali.dll.AliScanFaceDll; import com.dpkj.modules.scanface.ali.dll.AliScanFaceDll;
import com.dpkj.modules.scanface.ali.service.IAliScanFaceService; import com.dpkj.modules.scanface.ali.service.IAliScanFaceService;
import com.dpkj.modules.scanface.vo.MyCallbackRsp;
import com.sun.jna.Callback; import com.sun.jna.Callback;
import com.sun.jna.Memory; import com.sun.jna.Memory;
import com.sun.jna.Pointer; import com.sun.jna.Pointer;
@ -17,6 +20,9 @@ import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import java.io.File;
/** /**
* @Auther: 萧道子 * @Auther: 萧道子
* @Date: 2025/4/16 16:47 * @Date: 2025/4/16 16:47
@ -30,27 +36,61 @@ public class AliScanFaceController {
private final IAliScanFaceService aliScanFaceService; private final IAliScanFaceService aliScanFaceService;
@Resource
private AliFaceConfig aliFaceConfig;
/**
* 初始化
* @return
* @throws AliScanFaceDll.DllRegistrationException
*/
@GetMapping("iniAbcp")
Result<Object> iniAbcp() throws AliScanFaceDll.DllRegistrationException {
return aliScanFaceService.iniAbcp();
}
//测试使用绝对路径
public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException, AliScanFaceDll.DllRegistrationException {
File dllFile = new File("C:\\opt\\ant-abcp\\bpaas_api.dll");
System.out.println("DLL 存在: " + dllFile.exists());
//System.setProperty("java.library.path", "C:/opt/ant-abcp");
// 加载DLL直接指定绝对路径
System.load("C:/opt/ant-abcp/bpaas_api.dll");
String appId = "2021005138692337";
String appVersion = "1.0.0.0";
JSONObject params = new JSONObject()
.fluentPut("appId", appId) //应用ID
.fluentPut("merchantId", "2088641941653700") //签约商家的 PID 2088 开头
.fluentPut("deviceNum", "P060003750")//商家机具终端编号每台设备保持唯一
.fluentPut("partnerId", "2088641941653700");//服务商的 PID
String json = params.toJSONString();
// 指定支付宝LOT SDK的本地库路径
AbcpInvoke.SetAPIPathFile("C:\\opt\\ant-abcp\\bpaas_api.dll");
// 2. 创建回调实例
MyCallbackRsp callback = new MyCallbackRsp();
AbcpInvoke.AbcpInit(appId, appVersion, json, callback);
}
@GetMapping("test") @GetMapping("test")
public Result<?> test() { public Result<?> test() {
try { try {
AliScanFaceDll.Dll dll = AliScanFaceDll.instance(); AliScanFaceDll.Dll dll = AliScanFaceDll.instance();
dll.bp_api_set_isv_lan(1); dll.bp_api_set_isv_lan(3);
dll.abcp_init(null, null, null, null, JSONObject params = new JSONObject()
new AliScanFaceDll.ProcessCallback() { .fluentPut("appId", "2021005138692337") //应用ID
@Override .fluentPut("merchantId", "2088641941653700") //签约商家的 PID 2088 开头
public void invoke(Object obj) { .fluentPut("deviceNum", "P060003750")//商家机具终端编号每台设备保持唯一
Console.log(obj); .fluentPut("partnerId", "2088641941653700");//服务商的 PID
} String json = params.toJSONString();
},
new AliScanFaceDll.FinishCallback() { AbcpInvoke.ABCPProcess msABCPProcess = new AbcpInvoke.ABCPProcess();
@Override AbcpInvoke.ABCPFinish msABCPFinish = new AbcpInvoke.ABCPFinish();
public void invoke(Object obj) { dll.abcp_init(256, "2021005138692337", "1.0.0.0", json, msABCPProcess, msABCPFinish);
Console.log(obj);
}
});
return Result.ok("成功"); return Result.ok("成功");
} catch (Exception e) { } catch (Exception e) {

View File

@ -0,0 +1,293 @@
package com.dpkj.modules.scanface.ali.dll;
import com.sun.jna.Callback;
import com.sun.jna.Native;
import lombok.extern.slf4j.Slf4j;
import java.io.File;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
@Slf4j
public class AbcpInvoke {
/**
* 获取 Dll 实例同时注册 Dll 控件
*
* @return AlipayDll 实例
* @throws AliScanFaceDll.DllRegistrationException 如果注册控件失败抛出此异常
*/
public static AliScanFaceDll.Dll instance() throws AliScanFaceDll.DllRegistrationException {
try {
return Native.load("AliScanFace", AliScanFaceDll.Dll.class);
} catch (UnsatisfiedLinkError e) {
log.info("[AliScanFaceDll][instance][阿里扫脸动态库] SDK注册失败{}", e.getMessage());
throw new AliScanFaceDll.DllRegistrationException("Failed to load AliScanFace library: ", e);
}
}
public interface CallbackStr {
public void OnString(String result);
}
public interface CallbackRsp {
public void OnProcess(int code, String subCode, String subMsg, String result);
public void OnFinish(int code, String subCode, String subMsg, String result);
}
public static void SetAPIPathFile(String fileDylib) {
if (msAbcpNativeDll == null) {
File file = new File(fileDylib);
if (file.exists()) {
try {
msAbcpNativeDll = (AbcpNativeDll) Native.load(fileDylib, AbcpNativeDll.class);
} catch (Throwable e) {
msAbcpNativeDll = null;
System.out.printf("## ERROR : load. ## [%s][%s] %n", fileDylib, e.getMessage());
}
} else {
System.out.printf("## ERROR : dylib NOT exist ## %s %n", fileDylib);
}
}
}
public static void AbcpInit(String appId, String appVersion, String json, CallbackRsp callback) {
if (msAbcpNativeDll == null) {
callback.OnFinish(3, "E69001", "[java] api load failed!", "");
return;
}
appId = FixNullString(appId); // involved null ptr!
appVersion = FixNullString(appVersion); // involved null ptr!
json = FixNullString(json); // involved null ptr!
msLock.lock();
Integer seedId = msSeedId++;
msMapAbcpReponse.put(seedId, callback);
msLock.unlock();
try {
msAbcpNativeDll.bp_api_set_isv_lan(3);// 0:cpp | 1:cshap | 2:jni | 3:jna
} catch (Throwable e) {
System.out.printf("## ERROR ## %s %n", e.getMessage());
}
try {
msAbcpNativeDll.abcp_init(seedId, appId, appVersion, json, msABCPProcess, msABCPFinish);
} catch (Throwable e) {
callback.OnFinish(3, "E69001", e.getMessage(), "");
System.out.printf("## ERROR ## %s %n", e.getMessage());
}
}
public static void AbcpGetMetaInfo(String appId, String json, CallbackRsp callback) {
if (msAbcpNativeDll == null) {
callback.OnFinish(3, "E69001", "[java] api load failed!", "");
return;
}
appId = FixNullString(appId); // involved null ptr!
json = FixNullString(json); // involved null ptr!
msLock.lock();
Integer seedId = msSeedId++;
msMapAbcpReponse.put(seedId, callback);
msLock.unlock();
try {
msAbcpNativeDll.abcp_get_meta_info(seedId, appId, json, msABCPProcess, msABCPFinish);
} catch (Throwable e) {
callback.OnFinish(3, "E69001", e.getMessage(), "");
System.out.printf("## ERROR ## %s %n", e.getMessage());
}
}
public static void AbcpStartService(String appId, String serviceCode, String json, CallbackRsp callback) {
if (msAbcpNativeDll == null) {
callback.OnFinish(3, "E69001", "[java] api load failed!", "");
return;
}
appId = FixNullString(appId); // involved null ptr!
serviceCode = FixNullString(serviceCode); // involved null ptr!
json = FixNullString(json); // involved null ptr!
msLock.lock();
Integer seedId = msSeedId++;
msMapAbcpReponse.put(seedId, callback);
msLock.unlock();
try {
msAbcpNativeDll.abcp_start_service(seedId, appId, serviceCode, json, msABCPProcess, msABCPFinish);
} catch (Throwable e) {
callback.OnFinish(3, "E69001", e.getMessage(), "");
System.out.printf("## ERROR ## %s %n", e.getMessage());
}
}
public static void AbcpTaskStopService(String appId, String serviceCode, String json, CallbackRsp callback) {
if (msAbcpNativeDll == null) {
callback.OnFinish(3, "E69001", "[java] api load failed!", "");
return;
}
appId = FixNullString(appId); // involved null ptr!
serviceCode = FixNullString(serviceCode); // involved null ptr!
json = FixNullString(json); // involved null ptr!
msLock.lock();
Integer seedId = msSeedId++;
msMapAbcpReponse.put(seedId, callback);
msLock.unlock();
try {
msAbcpNativeDll.abcp_stop_service(seedId, appId, serviceCode, json, msABCPProcess, msABCPFinish);
} catch (Throwable e) {
callback.OnFinish(3, "E69001", e.getMessage(), "");
System.out.printf("## ERROR ## %s %n", e.getMessage());
}
}
public static void AbcpZimIdInitTest(String metainfo, String smileType, String smileFlag, CallbackStr callback) {
if (msAbcpNativeDll == null) {
callback.OnString("{}");
return;
}
metainfo = FixNullString(metainfo); // involved null ptr!
smileType = FixNullString(smileType); // involved null ptr!
smileFlag = FixNullString(smileFlag); // involved null ptr!
msLock.lock();
Integer seedId = msSeedId++;
msMapAbcpString.put(seedId, callback);
msLock.unlock();
try {
msAbcpNativeDll.abcp_zimid_init_for_test(seedId, metainfo, smileType, smileFlag, msABCPString);
} catch (Throwable e) {
callback.OnString("{}");
System.out.printf("## ERROR ## %s %n", e.getMessage());
}
}
public static void AbcpTaskSubscribeEvent(String appId, String json, CallbackRsp callback) {
if (msAbcpNativeDll == null) {
callback.OnFinish(3, "E69001", "[java] api load failed!", "");
return;
}
appId = FixNullString(appId); // involved null ptr!
json = FixNullString(json); // involved null ptr!
msLock.lock();
Integer seedId = msSeedId++;
msMapAbcpReponse.put(seedId, callback);
msLock.unlock();
try {
msAbcpNativeDll.abcp_call(seedId, appId, "SubscribeEvent", json, msABCPProcess, msABCPFinish);
} catch (Throwable e) {
callback.OnFinish(3, "E69001", e.getMessage(), "");
System.out.printf("## ERROR ## %s %n", e.getMessage());
}
}
public static void AbcpTaskUnsubscribeEvent(String appId, String json, CallbackRsp callback) {
if (msAbcpNativeDll == null) {
callback.OnFinish(3, "E69001", "[java] api load failed!", "");
return;
}
appId = FixNullString(appId); // involved null ptr!
json = FixNullString(json); // involved null ptr!
msLock.lock();
Integer seedId = msSeedId++;
msMapAbcpReponse.put(seedId, callback);
msLock.unlock();
try {
msAbcpNativeDll.abcp_call(seedId, appId, "UnsubscribeEvent", json, msABCPProcess, msABCPFinish);
} catch (Throwable e) {
callback.OnFinish(3, "E69001", e.getMessage(), "");
System.out.printf("## ERROR ## %s %n", e.getMessage());
}
}
// =====================================
private static AbcpNativeDll msAbcpNativeDll = null;
private static ABCPProcess msABCPProcess = new ABCPProcess();
private static ABCPFinish msABCPFinish = new ABCPFinish();
private static ABCPString msABCPString = new ABCPString();
private static Lock msLock = new ReentrantLock();
private static Integer msSeedId = Integer.valueOf(256);
private static Map<Integer, CallbackStr> msMapAbcpString = new HashMap<Integer, CallbackStr>();
private static Map<Integer, CallbackRsp> msMapAbcpReponse = new HashMap<Integer, CallbackRsp>();
private static String FixNullString(String str) {
if (str.equals(null)) {
return "";
}
return str;
}
public static Integer getMsSeedId(){
return msSeedId;
}
// =====================================
public interface FuncProcess extends Callback {
public void onProcess(int seed_id, int code, String subCode, String subMsg, String result);
}
public interface FuncFinish extends Callback {
public void onFinish(int seed_id, int code, String subCode, String subMsg, String result);
}
public interface FuncString extends Callback {
public void onString(int seed_id, String result);
}
public static class ABCPProcess implements FuncProcess {
public void onProcess(int seed_id, int _code, String subCode, String subMsg, String result) {
Integer seedId = Integer.valueOf(seed_id);
CallbackRsp callback = null;
msLock.lock();
if (msMapAbcpReponse.containsKey(seedId)) {
callback = msMapAbcpReponse.get(seedId);
}
msLock.unlock();
if (callback != null) {
Integer code = Integer.valueOf(_code);
callback.OnProcess(code, subCode, subMsg, result);
}
}
}
public static class ABCPFinish implements FuncFinish {
public void onFinish(int seed_id, int _code, String subCode, String subMsg, String result) {
Integer seedId = Integer.valueOf(seed_id);
CallbackRsp callback = null;
msLock.lock();
if (msMapAbcpReponse.containsKey(seedId)) {
callback = msMapAbcpReponse.remove(seedId);
}
msLock.unlock();
if (callback != null) {
Integer code = Integer.valueOf(_code);
callback.OnFinish(code, subCode, subMsg, result);
}
}
}
public static class ABCPString implements FuncString {
public void onString(int seed_id, String result) {
Integer seedId = Integer.valueOf(seed_id);
CallbackStr callback = null;
msLock.lock();
if (msMapAbcpString.containsKey(seedId)) {
callback = msMapAbcpString.remove(seedId);
}
msLock.unlock();
if (callback != null) {
callback.OnString(result);
}
}
}
}

View File

@ -0,0 +1,22 @@
package com.dpkj.modules.scanface.ali.dll;
import com.sun.jna.Callback;
import com.sun.jna.Library;
public interface AbcpNativeDll extends Library {
void bp_api_set_isv_lan(Integer type_isv_language);// 0:cpp | 1:cshap | 2:jni | 3:jna
void abcp_init(Integer arg, String app_id, String app_version, String json_param, Callback on_process, Callback on_finish);
void abcp_start_service(Integer arg, String app_id, String service_code, String json_param, Callback on_process, Callback on_finish);
void abcp_stop_service(Integer arg, String app_id, String service_code, String json_param, Callback on_process, Callback on_finish);
void abcp_get_meta_info(Integer arg, String app_id, String json_param, Callback on_process, Callback on_finish);
void abcp_stop_smile(Integer arg, String app_id, String json_param, Callback on_process, Callback on_finish);
void abcp_zimid_init_for_test(Integer arg, String zimmetainfo, String smileType, String smileFlag, Callback callback);
void abcp_call(Integer arg, String app_id, String call_method, String json_param, Callback on_process, Callback on_finish);
}

View File

@ -1,4 +1,12 @@
package com.dpkj.modules.scanface.ali.service; package com.dpkj.modules.scanface.ali.service;
import com.dpkj.common.vo.Result;
import com.dpkj.modules.scanface.ali.dll.AliScanFaceDll;
public interface IAliScanFaceService { public interface IAliScanFaceService {
/**
* 初始化调用阿里的ABCP_SDK部署出来的代码中的API文件
*/
Result<Object> iniAbcp() throws AliScanFaceDll.DllRegistrationException;
} }

View File

@ -1,17 +1,60 @@
package com.dpkj.modules.scanface.ali.service.impl; package com.dpkj.modules.scanface.ali.service.impl;
import com.alibaba.fastjson.JSONObject;
import com.dpkj.common.config.PrinterConfig;
import com.dpkj.common.vo.Result;
import com.dpkj.modules.scanface.ali.config.AliFaceConfig;
import com.dpkj.modules.scanface.ali.dll.AbcpInvoke;
import com.dpkj.modules.scanface.ali.dll.AliScanFaceDll;
import com.dpkj.modules.scanface.ali.service.IAliScanFaceService; import com.dpkj.modules.scanface.ali.service.IAliScanFaceService;
import com.dpkj.modules.scanface.vo.MyCallbackRsp;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import javax.annotation.Resource;
/** /**
* @Auther: 萧道子 * @Auther: 萧道子
* @Date: 2025/4/16 16:47 * @Date: 2025/4/16 16:47
* @Description: * @Description:
*/ */
@Slf4j
@Service @Service
@AllArgsConstructor
public class AliScanFaceServiceImpl implements IAliScanFaceService { public class AliScanFaceServiceImpl implements IAliScanFaceService {
@Resource
private AliFaceConfig aliFaceConfig;
@Override
public Result<Object> iniAbcp() {
try {
log.info("[AliScanFaceServiceImpl][iniAbcpAli][26][appId:{}],[merchantId:{}],[deviceNum:{}],[partnerId:{}]",
aliFaceConfig.getAppId(), aliFaceConfig.getMerchantId(), aliFaceConfig.getDeviceNum(), aliFaceConfig.getPartnerId());
AliScanFaceDll.Dll dll = AliScanFaceDll.instance();
dll.bp_api_set_isv_lan(3);// 0:cpp | 1:cshap | 2:jni | 3:jna
JSONObject params = new JSONObject()
.fluentPut("appId", aliFaceConfig.getAppId()) //应用ID
.fluentPut("merchantId", aliFaceConfig.getMerchantId()) //签约商家的 PID 2088 开头
.fluentPut("deviceNum", aliFaceConfig.getDeviceNum())//商家机具终端编号每台设备保持唯一
.fluentPut("partnerId", aliFaceConfig.getPartnerId());//服务商的 PID
String json = params.toJSONString();
AbcpInvoke.ABCPProcess msABCPProcess = new AbcpInvoke.ABCPProcess();
AbcpInvoke.ABCPFinish msABCPFinish = new AbcpInvoke.ABCPFinish();
Integer seedId = AbcpInvoke.getMsSeedId();
dll.abcp_init(seedId, "aliFaceConfig.getAppId()", aliFaceConfig.getAppVersion(), json, msABCPProcess, msABCPFinish);
return Result.ok("成功");
} catch (Exception e) {
e.printStackTrace();
return Result.error("失败");
}
}
} }

View File

@ -0,0 +1,28 @@
package com.dpkj.modules.scanface.vo;
import com.dpkj.modules.scanface.ali.dll.AbcpInvoke;
/**
* @description: 自定义回调实现类
* @author: Zhangxue
* @time: 2025/4/15 20:41
*/
public class MyCallbackRsp implements AbcpInvoke.CallbackRsp {
@Override
public void OnProcess(int code, String subCode, String subMsg, String result) {
// 处理初始化过程中的中间状态如进度更新
System.out.printf("[OnProcess] code=%d, subCode=%s, subMsg=%s, result=%s%n",
code, subCode, subMsg, result);
}
@Override
public void OnFinish(int code, String subCode, String subMsg, String result) {
// 处理初始化完成结果
if (code == 0) {
System.out.println("初始化成功!");
System.out.println("返回结果: " + result);
} else {
System.err.printf("初始化失败!错误码: %s, 错误信息: %s%n", subCode, subMsg);
}
}
}

View File

@ -1,5 +1,5 @@
server: server:
port: 5946 port: 5948
dpkj: dpkj:
# 医保配置 # 医保配置
@ -23,6 +23,19 @@ dpkj:
baud-rate: baud-rate:
# 指定打印机第一层是a4还是a5 # 指定打印机第一层是a4还是a5
level-one: A5 level-one: A5
#支付宝刷脸
ali:
face:
#IOT 应用管理-appid
app-id: 2021005138692337
#IOT应用版本
app-version: 1.0.0
#签约商家的 PID以 2088 开头,企业主体
merchant-id: 2088641941653700
#商家机具终端编号,每台设备保持唯一
device-num: P060003750
#服务商的 PID
partner-id: 2088641941653700
# 自定义app参数 # 自定义app参数
app: app:

View File

@ -1,5 +1,5 @@
server: server:
port: 5946 port: 5948
dpkj: dpkj:
# 医保配置 # 医保配置
@ -23,6 +23,19 @@ dpkj:
baud-rate: baud-rate:
# 指定打印机第一层是a4还是a5 # 指定打印机第一层是a4还是a5
level-one: A5 level-one: A5
#支付宝刷脸
ali:
face:
#IOT 应用管理-appid
app-id: 2021005138692337
#IOT应用版本
app-version: 1.0.0
#签约商家的 PID以 2088 开头,企业主体
merchant-id: 2088641941653700
#商家机具终端编号,每台设备保持唯一
device-num: P060003750
#服务商的 PID
partner-id: 2088641941653700
# 自定义app参数 # 自定义app参数
app: app: