|
|
3 maanden geleden | |
|---|---|---|
| .. | ||
| src | 3 maanden geleden | |
| EXAMPLES.md | 4 maanden geleden | |
| README.md | 3 maanden geleden | |
| pom.xml | 3 maanden geleden | |
哈哈零售系统 Java SDK,为智能视觉识别售卖机系统提供完整的API接口封装。
✅ 完整接口覆盖 - 支持哈哈零售平台全部31个API接口
✅ 自动令牌管理 - 自动获取、刷新和管理access_token(15天有效期)
✅ 自动签名 - 内置MD5签名算法,无需手动处理
✅ 类型安全 - 提供完整的类型定义和泛型支持
✅ 日志支持 - 集成SLF4J日志框架
✅ 连接池管理 - 基于OkHttp的高性能HTTP客户端
<dependency>
<groupId>com.haha</groupId>
<artifactId>haha-sdk</artifactId>
<version>1.0.0</version>
</dependency>
import com.haha.sdk.HahaClient;
import com.haha.sdk.config.HahaConfig;
// 创建配置
HahaConfig config = HahaConfig.builder()
.apiBaseUrl("http://api.hahabianli.com") // API地址(默认值)
.appId("your_app_id") // 商家AppId
.appSecret("your_app_secret") // 商家AppSecret
.connectTimeout(10) // 连接超时(秒)
.readTimeout(30) // 读取超时(秒)
.build();
// 创建客户端
HahaClient client = new HahaClient(config);
// 使用完毕后关闭(可选)
// client.shutdown();
import com.haha.sdk.exception.HahaException;
try {
// 获取设备列表
List<DeviceInfo> devices = client.getDeviceApi().getDeviceList(1, 20);
// 开门
OpenDoorResult result = client.getDeviceApi()
.openDoor("device001", "ORDER" + System.currentTimeMillis(), null);
System.out.println("订单号: " + result.getOrderNo());
} catch (HahaException e) {
System.err.println("错误: " + e.getMessage());
}
通过 client.getDeviceApi() 访问设备相关接口:
// 获取第1页,每页20条
List<DeviceInfo> devices = client.getDeviceApi().getDeviceList(1, 20);
for (DeviceInfo device : devices) {
System.out.println("设备ID: " + device.getId());
System.out.println("设备名称: " + device.getName());
System.out.println("设备地址: " + device.getAddress());
System.out.println("设备状态: " + device.getStatus()); // 1-正常, 2-冻结
}
String deviceId = "device001";
Integer multiDoorType = client.getDeviceApi().isMultiDoorUnique(deviceId);
// 返回值:0-非多门单开,2-双门单开,3-三门单开,4-四门单开
if (multiDoorType == 2) {
System.out.println("这是双门单开设备");
}
String deviceId = "device001";
String outTradeNo = "ORDER" + System.currentTimeMillis(); // 商户订单号
Integer doorIndex = null; // 多门单开时必传:0-A门,1-B门
OpenDoorResult result = client.getDeviceApi().openDoor(deviceId, outTradeNo, doorIndex);
System.out.println("哈哈平台订单号: " + result.getOrderNo());
DeviceOnlineStatus status = client.getDeviceApi().getOnlineStatus("device001");
System.out.println("在线状态: " + status.getOnlineStatus()); // 0-离线, 1-在线
System.out.println("最后在线时间: " + status.getLastOnlineTime());
// 音量范围:0-100,0表示静音
boolean success = client.getDeviceApi().setVolume("device001", 80);
Map<String, Object> status = client.getDeviceApi().getDeviceStatus("device001");
System.out.println("设备状态: " + status.get("device_status")); // 0-离线, 1-在线, 2-故障
System.out.println("门状态: " + status.get("door_status")); // 0-关闭, 1-打开
System.out.println("锁状态: " + status.get("lock_status")); // 0-未锁, 1-已锁
System.out.println("摄像头: " + status.get("camera_status")); // 0-异常, 1-正常
System.out.println("网络: " + status.get("network_status")); // 0-断开, 1-连接
通过 client.getGoodsApi() 访问商品相关接口:
List<Map<String, Object>> goodsList = client.getGoodsApi()
.getDeviceGoodsList("device001");
for (Map<String, Object> goods : goodsList) {
System.out.println("商品ID: " + goods.get("goods_id"));
System.out.println("商品名: " + goods.get("goods_name"));
System.out.println("价格: " + goods.get("price"));
System.out.println("库存: " + goods.get("stock"));
}
// 分页查询,支持关键词搜索
Map<String, Object> result = client.getGoodsApi()
.getTotalList(1, 20, "可乐");
int total = (int) result.get("total");
List<Map<String, Object>> list = (List<Map<String, Object>>) result.get("list");
String goodsId = "goods001"; // 来自商品总库的商品ID
String price = "3.50"; // 售价
boolean success = client.getGoodsApi().addToMerchant(goodsId, price);
Map<String, Object> result = client.getGoodsApi().getMerchantList(1, 20);
int total = (int) result.get("total");
List<Map<String, Object>> list = (List<Map<String, Object>>) result.get("list");
String deviceId = "device001";
String goodsId = "goods001";
int status = 1; // 0-下架, 1-上架
boolean success = client.getGoodsApi().setStatus(deviceId, goodsId, status);
// 获取层模板
Map<String, Object> template = client.getGoodsApi().getLayerTemplate("device001");
// 更新层模板(layers为JSON格式的层级配置)
String layersJson = "[{\"layer_no\":1,\"layer_name\":\"第一层\",\"goods_list\":[]}]";
boolean success = client.getGoodsApi().updateLayerTemplate("device001", layersJson);
boolean success = client.getGoodsApi().applyNew(
"新商品名称",
"6901234567890",
"http://example.com/image.jpg",
"商品描述(可选)"
);
// 通过商家商品ID查询
Map<String, Object> mapping = client.getGoodsApi()
.getIdMapping("merchant_001", null);
// 或通过哈哈平台商品ID查询
mapping = client.getGoodsApi().getIdMapping(null, "haha_001");
String targetGoodsId = "goods001"; // 保留的商品
String sourceGoodsIds = "goods002,goods003"; // 要合并的商品(逗号分隔)
boolean success = client.getGoodsApi().mergeGoods(targetGoodsId, sourceGoodsIds);
通过 client.getOrderApi() 访问订单相关接口:
// 方式1:通过哈哈平台订单号查询
Map<String, Object> result = client.getOrderApi()
.getRecognizeResult("HH202401240001", null);
// 方式2:通过商户订单号查询
result = client.getOrderApi()
.getRecognizeResult(null, "ORDER123456");
// 解析结果
List<Map<String, Object>> goodsList = (List) result.get("goods_list");
Double totalAmount = (Double) result.get("total_amount");
Double confidence = (Double) result.get("confidence");
String videoUrl = (String) result.get("video_url");
System.out.println("总金额: " + totalAmount);
System.out.println("置信度: " + confidence);
Map<String, Object> order = client.getOrderApi()
.queryOrder("HH202401240001", null);
String orderStatus = (String) order.get("order_status"); // paying, paid, refund, closed
System.out.println("订单状态: " + orderStatus);
String orderNo = "HH202401240001";
int payStatus = 1; // 1-支付成功, 2-支付失败
String payTime = "2024-01-24 15:30:00";
String transactionId = "WX123456789"; // 第三方支付流水号
boolean success = client.getOrderApi()
.setPayStatus(orderNo, payStatus, payTime, transactionId);
Map<String, Object> media = client.getOrderApi()
.getOrderMedia("HH202401240001");
String beforeImage = (String) media.get("before_image");
String afterImage = (String) media.get("after_image");
String videoUrl = (String) media.get("video_url");
Map<String, Object> callbackStatus = client.getOrderApi()
.getCallbackStatus("HH202401240001");
int status = (int) callbackStatus.get("callback_status"); // 0-未推送, 1-成功, 2-失败
int retryCount = (int) callbackStatus.get("retry_count");
Map<String, Object> layerResult = client.getOrderApi()
.getLayerRecognize("HH202401240001");
List<Map<String, Object>> layers = (List) layerResult.get("layers");
for (Map<String, Object> layer : layers) {
int layerNo = (int) layer.get("layer_no");
String beforeImage = (String) layer.get("before_image");
String afterImage = (String) layer.get("after_image");
List<Map<String, Object>> goodsList = (List) layer.get("goods_list");
}
SDK会自动管理token,但如果需要手动设置:
// 手动设置token(如果你已经有token并自行管理)
client.setAccessToken("your_access_token", 1296000); // 15天有效期(秒)
// 或者让SDK自动获取token
String token = client.getAccessToken();
HahaConfig config = HahaConfig.builder()
.apiBaseUrl("http://api.hahabianli.com")
.appId("your_app_id")
.appSecret("your_app_secret")
.connectTimeout(15) // 连接超时15秒
.readTimeout(60) // 读取超时60秒
.writeTimeout(60) // 写入超时60秒
.enableLog(true) // 启用日志
.build();
HahaClient client = new HahaClient(config);
// 程序退出前关闭客户端,释放连接池资源
client.shutdown();
SDK统一使用 HahaException 异常:
import com.haha.sdk.exception.HahaException;
try {
OpenDoorResult result = client.getDeviceApi()
.openDoor("device001", "ORDER001", null);
} catch (HahaException e) {
// 错误码(对应API文档的错误码)
Integer errorCode = e.getCode();
// 错误信息
String errorMsg = e.getMessage();
System.err.println("错误码: " + errorCode + ", 错误信息: " + errorMsg);
// 如果需要查看底层异常
if (e.getCause() != null) {
e.getCause().printStackTrace();
}
}
| 错误码 | 说明 | 处理方案 |
|---|---|---|
| 1 | SUCCESS | 操作成功 |
| 0 | FAIL | 操作失败 |
| -1 | 参数错误 | 检查请求参数 |
| -2 | 签名错误 | 检查AppSecret |
| -3 | token无效 | 重新获取token |
| -4 | token过期 | SDK会自动刷新 |
| -100 | 设备不存在 | 检查设备ID |
| -101 | 设备离线 | 等待设备上线 |
| -103 | 设备使用中 | 等待购物结束 |
| 方法 | 说明 |
|---|---|
getDeviceList |
获取设备列表 |
isMultiDoorUnique |
查询是否多门单开 |
openDoor |
设备开门 |
getOnlineStatus |
查询在线状态 |
setVolume |
设置音量 |
getDeviceStatus |
查询设备和锁状态 |
| 方法 | 说明 |
|---|---|
getDeviceGoodsList |
设备可售商品列表 |
getTotalList |
商品总库列表 |
addToMerchant |
添加至商家库 |
getMerchantList |
商家商品库列表 |
setStatus |
商品上下架 |
getLayerTemplate |
获取层模板 |
updateLayerTemplate |
更新层模板 |
applyNew |
新品申请 |
getIdMapping |
商品ID对应关系 |
mergeGoods |
商品合并 |
| 方法 | 说明 |
|---|---|
getRecognizeResult |
查询识别结果 |
queryOrder |
查询订单详情 |
setPayStatus |
设置支付状态 |
getOrderMedia |
获取图片/视频 |
getCallbackStatus |
查询回调状态 |
getLayerRecognize |
静态柜分层结果 |
A: 15天(1296000秒)。SDK会自动管理,到期前2天内会自动刷新。
A: 哈哈平台会通过回调地址推送识别结果。商户需要:
setPayStatus接口告知支付结果A: 建议通过getOrderMedia接口获取购物视频进行人工审核。
A: 先调用isMultiDoorUnique判断设备类型,如果返回2(双门),开门时需传递doorIndex参数(0或1)。
A: 是的。HahaClient可以在多线程环境中安全使用,建议作为单例管理。
Apache License 2.0
版本: 1.0.0
更新时间: 2024-01-24