feat: init auv-locker-sdk
- Maven + JDK 8 project - HmacMD5 signature utility - Apache HttpClient wrapper - Storage API (11 endpoints) + Aux API (4 endpoints) - Unified AuvClient entry point - 20 unit tests
This commit is contained in:
parent
a1ebd52990
commit
f2727dbc35
100
pom.xml
Normal file
100
pom.xml
Normal file
@ -0,0 +1,100 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>com.auv</groupId>
|
||||
<artifactId>auv-locker-sdk</artifactId>
|
||||
<version>1.0.0</version>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name>AUV Locker SDK</name>
|
||||
<description>Java SDK for AUV Smart Locker API</description>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.source>1.8</maven.compiler.source>
|
||||
<maven.compiler.target>1.8</maven.compiler.target>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<httpclient.version>4.5.14</httpclient.version>
|
||||
<jackson.version>2.15.2</jackson.version>
|
||||
<slf4j.version>1.7.36</slf4j.version>
|
||||
<junit.version>4.13.2</junit.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<!-- Apache HttpClient -->
|
||||
<dependency>
|
||||
<groupId>org.apache.httpcomponents</groupId>
|
||||
<artifactId>httpclient</artifactId>
|
||||
<version>${httpclient.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Jackson -->
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-databind</artifactId>
|
||||
<version>${jackson.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- SLF4J -->
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-api</artifactId>
|
||||
<version>${slf4j.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Logging (for testing) -->
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-simple</artifactId>
|
||||
<version>${slf4j.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- JUnit -->
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>${junit.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.11.0</version>
|
||||
<configuration>
|
||||
<source>1.8</source>
|
||||
<target>1.8</target>
|
||||
<encoding>UTF-8</encoding>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-source-plugin</artifactId>
|
||||
<version>3.2.1</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>attach-sources</id>
|
||||
<goals>
|
||||
<goal>jar-no-fork</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-javadoc-plugin</artifactId>
|
||||
<version>3.5.0</version>
|
||||
<configuration>
|
||||
<encoding>UTF-8</encoding>
|
||||
<charset>UTF-8</charset>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
130
src/main/java/com/auv/locker/AuvClient.java
Normal file
130
src/main/java/com/auv/locker/AuvClient.java
Normal file
@ -0,0 +1,130 @@
|
||||
package com.auv.locker;
|
||||
|
||||
import com.auv.locker.config.AuvConfig;
|
||||
import com.auv.locker.http.AuvHttpClient;
|
||||
import com.auv.locker.service.AuxApiService;
|
||||
import com.auv.locker.service.AuxApiServiceImpl;
|
||||
import com.auv.locker.service.StorageApiService;
|
||||
import com.auv.locker.service.StorageApiServiceImpl;
|
||||
|
||||
/**
|
||||
* AUV 智能取餐柜 Java SDK 统一入口。
|
||||
*
|
||||
* <p>内部根据 API 类型自动路由到对应的网关:
|
||||
* <ul>
|
||||
* <li>存取业务 API -> plat.58auv.com</li>
|
||||
* <li>辅助功能 API -> openapi.58auv.com</li>
|
||||
* </ul>
|
||||
*
|
||||
* <pre>
|
||||
* AuvClient client = AuvClient.builder()
|
||||
* .appId("66666")
|
||||
* .secretKey("mySecret")
|
||||
* .build();
|
||||
*
|
||||
* CreateOrderResponse resp = client.storage().createOrder(request);
|
||||
* DeviceStatusResponse status = client.aux().queryDeviceStatus(request);
|
||||
* </pre>
|
||||
*/
|
||||
public class AuvClient {
|
||||
|
||||
private final AuvHttpClient httpClient;
|
||||
private final StorageApiService storage;
|
||||
private final AuxApiService aux;
|
||||
|
||||
private AuvClient(AuvConfig config) {
|
||||
this.httpClient = new AuvHttpClient(config);
|
||||
this.storage = new StorageApiServiceImpl(httpClient, config);
|
||||
this.aux = new AuxApiServiceImpl(httpClient, config);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建 Builder。
|
||||
*/
|
||||
public static Builder builder() {
|
||||
return new Builder();
|
||||
}
|
||||
|
||||
/**
|
||||
* 存取业务 API。
|
||||
*/
|
||||
public StorageApiService storage() {
|
||||
return storage;
|
||||
}
|
||||
|
||||
/**
|
||||
* 辅助功能 API。
|
||||
*/
|
||||
public AuxApiService aux() {
|
||||
return aux;
|
||||
}
|
||||
|
||||
/**
|
||||
* 关闭 HTTP 连接池。
|
||||
*/
|
||||
public void close() {
|
||||
try { httpClient.close(); } catch (java.io.IOException ignored) {}
|
||||
}
|
||||
|
||||
/**
|
||||
* Client 构建器。
|
||||
*/
|
||||
public static class Builder {
|
||||
|
||||
private String appId;
|
||||
private String secretKey;
|
||||
private String storageBaseUrl;
|
||||
private String auxBaseUrl;
|
||||
private int connectTimeoutMs = 5000;
|
||||
private int socketTimeoutMs = 10000;
|
||||
private int connectionRequestTimeoutMs = 5000;
|
||||
|
||||
public Builder appId(String appId) {
|
||||
this.appId = appId;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder secretKey(String secretKey) {
|
||||
this.secretKey = secretKey;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder storageBaseUrl(String storageBaseUrl) {
|
||||
this.storageBaseUrl = storageBaseUrl;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder auxBaseUrl(String auxBaseUrl) {
|
||||
this.auxBaseUrl = auxBaseUrl;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder connectTimeoutMs(int connectTimeoutMs) {
|
||||
this.connectTimeoutMs = connectTimeoutMs;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder socketTimeoutMs(int socketTimeoutMs) {
|
||||
this.socketTimeoutMs = socketTimeoutMs;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder connectionRequestTimeoutMs(int connectionRequestTimeoutMs) {
|
||||
this.connectionRequestTimeoutMs = connectionRequestTimeoutMs;
|
||||
return this;
|
||||
}
|
||||
|
||||
public AuvClient build() {
|
||||
AuvConfig.Builder configBuilder = AuvConfig.builder()
|
||||
.appId(appId)
|
||||
.secretKey(secretKey)
|
||||
.connectTimeoutMs(connectTimeoutMs)
|
||||
.socketTimeoutMs(socketTimeoutMs)
|
||||
.connectionRequestTimeoutMs(connectionRequestTimeoutMs);
|
||||
if (storageBaseUrl != null) configBuilder.customStorageBaseUrl(storageBaseUrl);
|
||||
if (auxBaseUrl != null) configBuilder.customAuxBaseUrl(auxBaseUrl);
|
||||
AuvConfig config = configBuilder.build();
|
||||
return new AuvClient(config);
|
||||
}
|
||||
}
|
||||
}
|
||||
115
src/main/java/com/auv/locker/config/AuvConfig.java
Normal file
115
src/main/java/com/auv/locker/config/AuvConfig.java
Normal file
@ -0,0 +1,115 @@
|
||||
package com.auv.locker.config;
|
||||
|
||||
/**
|
||||
* AUV 取餐柜 API 配置。
|
||||
*/
|
||||
public class AuvConfig {
|
||||
|
||||
private final String appId;
|
||||
private final String secretKey;
|
||||
private GatewayType gatewayType;
|
||||
private String customStorageBaseUrl;
|
||||
private String customAuxBaseUrl;
|
||||
private int connectTimeoutMs = 5000;
|
||||
private int socketTimeoutMs = 10000;
|
||||
private int connectionRequestTimeoutMs = 5000;
|
||||
|
||||
private AuvConfig(Builder builder) {
|
||||
this.appId = builder.appId;
|
||||
this.secretKey = builder.secretKey;
|
||||
this.gatewayType = builder.gatewayType;
|
||||
this.customStorageBaseUrl = builder.customStorageBaseUrl;
|
||||
this.customAuxBaseUrl = builder.customAuxBaseUrl;
|
||||
this.connectTimeoutMs = builder.connectTimeoutMs;
|
||||
this.socketTimeoutMs = builder.socketTimeoutMs;
|
||||
this.connectionRequestTimeoutMs = builder.connectionRequestTimeoutMs;
|
||||
}
|
||||
|
||||
public String getAppId() { return appId; }
|
||||
public String getSecretKey() { return secretKey; }
|
||||
public GatewayType getGatewayType() { return gatewayType; }
|
||||
public int getConnectTimeoutMs() { return connectTimeoutMs; }
|
||||
public int getSocketTimeoutMs() { return socketTimeoutMs; }
|
||||
public int getConnectionRequestTimeoutMs() { return connectionRequestTimeoutMs; }
|
||||
|
||||
/**
|
||||
* 获取存储业务 API 网关地址。
|
||||
*/
|
||||
public String getStorageBaseUrl() {
|
||||
if (customStorageBaseUrl != null) return customStorageBaseUrl;
|
||||
return "https://" + GatewayType.STORAGE.getHost() + GatewayType.STORAGE.getPath();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取辅助功能 API 网关地址。
|
||||
*/
|
||||
public String getAuxBaseUrl() {
|
||||
if (customAuxBaseUrl != null) return customAuxBaseUrl;
|
||||
return "https://" + GatewayType.AUX.getHost() + GatewayType.AUX.getPath();
|
||||
}
|
||||
|
||||
public static Builder builder() {
|
||||
return new Builder();
|
||||
}
|
||||
|
||||
public static class Builder {
|
||||
private String appId;
|
||||
private String secretKey;
|
||||
private GatewayType gatewayType = GatewayType.STORAGE;
|
||||
private String customStorageBaseUrl;
|
||||
private String customAuxBaseUrl;
|
||||
private int connectTimeoutMs = 5000;
|
||||
private int socketTimeoutMs = 10000;
|
||||
private int connectionRequestTimeoutMs = 5000;
|
||||
|
||||
public Builder appId(String appId) {
|
||||
this.appId = appId;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder secretKey(String secretKey) {
|
||||
this.secretKey = secretKey;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder gatewayType(GatewayType gatewayType) {
|
||||
this.gatewayType = gatewayType;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder customStorageBaseUrl(String customStorageBaseUrl) {
|
||||
this.customStorageBaseUrl = customStorageBaseUrl;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder customAuxBaseUrl(String customAuxBaseUrl) {
|
||||
this.customAuxBaseUrl = customAuxBaseUrl;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder connectTimeoutMs(int connectTimeoutMs) {
|
||||
this.connectTimeoutMs = connectTimeoutMs;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder socketTimeoutMs(int socketTimeoutMs) {
|
||||
this.socketTimeoutMs = socketTimeoutMs;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder connectionRequestTimeoutMs(int connectionRequestTimeoutMs) {
|
||||
this.connectionRequestTimeoutMs = connectionRequestTimeoutMs;
|
||||
return this;
|
||||
}
|
||||
|
||||
public AuvConfig build() {
|
||||
if (appId == null || appId.isEmpty()) {
|
||||
throw new IllegalArgumentException("appId must not be null or empty");
|
||||
}
|
||||
if (secretKey == null || secretKey.isEmpty()) {
|
||||
throw new IllegalArgumentException("secretKey must not be null or empty");
|
||||
}
|
||||
return new AuvConfig(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
34
src/main/java/com/auv/locker/config/GatewayType.java
Normal file
34
src/main/java/com/auv/locker/config/GatewayType.java
Normal file
@ -0,0 +1,34 @@
|
||||
package com.auv.locker.config;
|
||||
|
||||
/**
|
||||
* API 网关类型枚举。
|
||||
*
|
||||
* 两套网关响应格式不同:
|
||||
* - STORAGE: code=10000 表示成功
|
||||
* - AUX: code=1 且 success=true 表示成功
|
||||
*/
|
||||
public enum GatewayType {
|
||||
|
||||
STORAGE("plat.58auv.com", "/OpenApi"),
|
||||
AUX("openapi.58auv.com", "/gateway.do");
|
||||
|
||||
private final String host;
|
||||
private final String path;
|
||||
|
||||
GatewayType(String host, String path) {
|
||||
this.host = host;
|
||||
this.path = path;
|
||||
}
|
||||
|
||||
public String getHost() {
|
||||
return host;
|
||||
}
|
||||
|
||||
public String getPath() {
|
||||
return path;
|
||||
}
|
||||
|
||||
public String getBaseUrl() {
|
||||
return "https://" + host + path;
|
||||
}
|
||||
}
|
||||
101
src/main/java/com/auv/locker/http/AuvHttpClient.java
Normal file
101
src/main/java/com/auv/locker/http/AuvHttpClient.java
Normal file
@ -0,0 +1,101 @@
|
||||
package com.auv.locker.http;
|
||||
|
||||
import com.auv.locker.config.AuvConfig;
|
||||
import com.auv.locker.model.common.AuvResponse;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import org.apache.http.client.config.RequestConfig;
|
||||
import org.apache.http.client.methods.CloseableHttpResponse;
|
||||
import org.apache.http.client.methods.HttpGet;
|
||||
import org.apache.http.client.utils.URIBuilder;
|
||||
import org.apache.http.impl.client.CloseableHttpClient;
|
||||
import org.apache.http.impl.client.HttpClients;
|
||||
import org.apache.http.util.EntityUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.Closeable;
|
||||
import java.net.URLEncoder;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
/**
|
||||
* AUV API HTTP 客户端,封装连接池、超时、签名与请求发送。
|
||||
*/
|
||||
public class AuvHttpClient implements Closeable {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(AuvHttpClient.class);
|
||||
private static final ObjectMapper MAPPER = new ObjectMapper();
|
||||
|
||||
private final AuvConfig config;
|
||||
private final CloseableHttpClient httpClient;
|
||||
|
||||
public AuvHttpClient(AuvConfig config) {
|
||||
this.config = config;
|
||||
RequestConfig requestConfig = RequestConfig.custom()
|
||||
.setConnectTimeout(config.getConnectTimeoutMs())
|
||||
.setSocketTimeout(config.getSocketTimeoutMs())
|
||||
.setConnectionRequestTimeout(config.getConnectionRequestTimeoutMs())
|
||||
.build();
|
||||
this.httpClient = HttpClients.custom()
|
||||
.setDefaultRequestConfig(requestConfig)
|
||||
.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送 GET 请求到 AUV 网关。
|
||||
*
|
||||
* @param baseUrl 网关地址
|
||||
* @param method 接口方法名
|
||||
* @param bizDataJson bizData JSON 字符串(未 URL Encode)
|
||||
* @return 统一响应,resultObject 为 JsonNode(可转为任意类型)
|
||||
*/
|
||||
public AuvResponse<JsonNode> get(String baseUrl, String method, String bizDataJson) {
|
||||
try {
|
||||
String timestamp = java.time.format.DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")
|
||||
.format(java.time.LocalDateTime.now());
|
||||
|
||||
// 签名用未 Encode 的 bizData
|
||||
java.util.TreeMap<String, String> signParams = new java.util.TreeMap<>();
|
||||
signParams.put("appId", config.getAppId());
|
||||
signParams.put("method", method);
|
||||
signParams.put("timestamp", timestamp);
|
||||
signParams.put("version", "1.0");
|
||||
signParams.put("bizData", bizDataJson != null ? bizDataJson : "{}");
|
||||
String signContent = HmacMD5Util.buildSignContent(signParams);
|
||||
String digest = HmacMD5Util.sign(signContent, config.getSecretKey());
|
||||
|
||||
// URL 构建时用 URL Encode 的 bizData
|
||||
URIBuilder uriBuilder = new URIBuilder(baseUrl);
|
||||
uriBuilder.addParameter("appId", config.getAppId());
|
||||
uriBuilder.addParameter("method", method);
|
||||
uriBuilder.addParameter("timestamp", timestamp);
|
||||
uriBuilder.addParameter("version", "1.0");
|
||||
uriBuilder.addParameter("bizData",
|
||||
URLEncoder.encode(bizDataJson != null ? bizDataJson : "{}", StandardCharsets.UTF_8.name()));
|
||||
uriBuilder.addParameter("digest", digest);
|
||||
|
||||
String url = uriBuilder.build().toString();
|
||||
return execute(url);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("AUV API request failed: " + e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
private AuvResponse<JsonNode> execute(String url) {
|
||||
try {
|
||||
HttpGet httpGet = new HttpGet(url);
|
||||
try (CloseableHttpResponse response = httpClient.execute(httpGet)) {
|
||||
String body = EntityUtils.toString(response.getEntity(), StandardCharsets.UTF_8);
|
||||
log.debug("AUV API response: {}", body);
|
||||
return MAPPER.readValue(body, AuvResponse.class);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("AUV API request failed: " + e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws java.io.IOException {
|
||||
httpClient.close();
|
||||
}
|
||||
}
|
||||
92
src/main/java/com/auv/locker/http/HmacMD5Util.java
Normal file
92
src/main/java/com/auv/locker/http/HmacMD5Util.java
Normal file
@ -0,0 +1,92 @@
|
||||
package com.auv.locker.http;
|
||||
|
||||
import javax.crypto.Mac;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
|
||||
/**
|
||||
* HmacMD5 签名工具。
|
||||
*
|
||||
* 签名步骤:
|
||||
* 1. 将所有参数(除 digest 外)按 key 的 ASCII 字典序排序
|
||||
* 2. 用 & 连接成 key=value 字符串
|
||||
* 3. 用 secretKey 做 HmacMD5 加密
|
||||
*/
|
||||
public final class HmacMD5Util {
|
||||
|
||||
private static final String ALGORITHM = "HmacMD5";
|
||||
|
||||
private HmacMD5Util() {}
|
||||
|
||||
/**
|
||||
* 计算 HmacMD5 签名。
|
||||
*
|
||||
* @param params 待签名字符串(已按 key 排序拼接)
|
||||
* @param secretKey 密钥
|
||||
* @return 小写十六进制签名串
|
||||
*/
|
||||
public static String sign(String params, String secretKey) {
|
||||
try {
|
||||
Mac mac = Mac.getInstance(ALGORITHM);
|
||||
mac.init(new SecretKeySpec(secretKey.getBytes(StandardCharsets.UTF_8), ALGORITHM));
|
||||
byte[] bytes = mac.doFinal(params.getBytes(StandardCharsets.UTF_8));
|
||||
return toHexString(bytes);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("HmacMD5 sign failed", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 从参数 Map 构建待签名字符串(按 key ASCII 排序)。
|
||||
*
|
||||
* @param params 参数 Map
|
||||
* @return 排序后的 key=value&key2=value2 字符串
|
||||
*/
|
||||
public static String buildSignContent(Map<String, String> params) {
|
||||
TreeMap<String, String> sorted = new TreeMap<>(params);
|
||||
StringBuilder sb = new StringBuilder();
|
||||
boolean first = true;
|
||||
for (Map.Entry<String, String> entry : sorted.entrySet()) {
|
||||
if (!first) sb.append('&');
|
||||
sb.append(entry.getKey()).append('=').append(entry.getValue());
|
||||
first = false;
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 从参数 Map 构建待签名字符串,自动排除指定 key。
|
||||
*
|
||||
* @param params 原始参数 Map
|
||||
* @param excludeKeys 需要排除的 key 集合
|
||||
* @return 排序后的签名字符串
|
||||
*/
|
||||
public static String buildSignContent(Map<String, String> params, String... excludeKeys) {
|
||||
Map<String, String> filtered = new LinkedHashMap<>();
|
||||
for (Map.Entry<String, String> entry : params.entrySet()) {
|
||||
boolean excluded = false;
|
||||
for (String key : excludeKeys) {
|
||||
if (key.equals(entry.getKey())) {
|
||||
excluded = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!excluded) {
|
||||
filtered.put(entry.getKey(), entry.getValue());
|
||||
}
|
||||
}
|
||||
return buildSignContent(filtered);
|
||||
}
|
||||
|
||||
private static String toHexString(byte[] bytes) {
|
||||
StringBuilder sb = new StringBuilder(bytes.length * 2);
|
||||
for (byte b : bytes) {
|
||||
sb.append(Character.forDigit((b >>> 4) & 0xf, 16));
|
||||
sb.append(Character.forDigit(b & 0xf, 16));
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,28 @@
|
||||
package com.auv.locker.model.aux;
|
||||
|
||||
/**
|
||||
* 辅助 API 通用响应封装。
|
||||
*/
|
||||
public class AuxCellOpResponse {
|
||||
|
||||
private final String rawData;
|
||||
private final Integer code;
|
||||
private final String msg;
|
||||
private final Boolean success;
|
||||
|
||||
public AuxCellOpResponse(String rawData, Integer code, String msg, Boolean success) {
|
||||
this.rawData = rawData;
|
||||
this.code = code;
|
||||
this.msg = msg;
|
||||
this.success = success;
|
||||
}
|
||||
|
||||
public String getRawData() { return rawData; }
|
||||
public Integer getCode() { return code; }
|
||||
public String getMsg() { return msg; }
|
||||
public Boolean isSuccess() { return success != null && success; }
|
||||
|
||||
public boolean isOk() {
|
||||
return success != null && success && code != null && code == 1;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,28 @@
|
||||
package com.auv.locker.model.aux;
|
||||
|
||||
/**
|
||||
* 辅助 API 设备列表查询响应。
|
||||
*/
|
||||
public class AuxDeviceListQueryResponse {
|
||||
|
||||
private final String rawData;
|
||||
private final Integer code;
|
||||
private final String msg;
|
||||
private final Boolean success;
|
||||
|
||||
public AuxDeviceListQueryResponse(String rawData, Integer code, String msg, Boolean success) {
|
||||
this.rawData = rawData;
|
||||
this.code = code;
|
||||
this.msg = msg;
|
||||
this.success = success;
|
||||
}
|
||||
|
||||
public String getRawData() { return rawData; }
|
||||
public Integer getCode() { return code; }
|
||||
public String getMsg() { return msg; }
|
||||
public Boolean isSuccess() { return success != null && success; }
|
||||
|
||||
public boolean isOk() {
|
||||
return success != null && success && code != null && code == 1;
|
||||
}
|
||||
}
|
||||
40
src/main/java/com/auv/locker/model/aux/CellOpRequest.java
Normal file
40
src/main/java/com/auv/locker/model/aux/CellOpRequest.java
Normal file
@ -0,0 +1,40 @@
|
||||
package com.auv.locker.model.aux;
|
||||
|
||||
/**
|
||||
* 单元格操作(单指令)请求。
|
||||
* method: device.cell.op
|
||||
*/
|
||||
public class CellOpRequest {
|
||||
|
||||
private final String deviceId;
|
||||
private final String cellNo;
|
||||
private final String op; // DOOR_OPEN, LIGHT_OPEN, LIGHT_CLOSE, WARM_START, WARM_STOP, DISINFECT_START, DISINFECT_STOP
|
||||
|
||||
private CellOpRequest(Builder builder) {
|
||||
this.deviceId = builder.deviceId;
|
||||
this.cellNo = builder.cellNo;
|
||||
this.op = builder.op;
|
||||
}
|
||||
|
||||
public String getDeviceId() { return deviceId; }
|
||||
public String getCellNo() { return cellNo; }
|
||||
public String getOp() { return op; }
|
||||
|
||||
public static Builder builder() {
|
||||
return new Builder();
|
||||
}
|
||||
|
||||
public static class Builder {
|
||||
private String deviceId;
|
||||
private String cellNo;
|
||||
private String op;
|
||||
|
||||
public Builder deviceId(String deviceId) { this.deviceId = deviceId; return this; }
|
||||
public Builder cellNo(String cellNo) { this.cellNo = cellNo; return this; }
|
||||
public Builder op(String op) { this.op = op; return this; }
|
||||
|
||||
public CellOpRequest build() {
|
||||
return new CellOpRequest(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
37
src/main/java/com/auv/locker/model/aux/CellOpResponse.java
Normal file
37
src/main/java/com/auv/locker/model/aux/CellOpResponse.java
Normal file
@ -0,0 +1,37 @@
|
||||
package com.auv.locker.model.aux;
|
||||
|
||||
/**
|
||||
* 单元格操作响应 (resultObject)。
|
||||
*/
|
||||
public class CellOpResponse {
|
||||
|
||||
private String deviceId;
|
||||
private String appId;
|
||||
private String deviceName;
|
||||
private String deviceStatus;
|
||||
private Integer cellNumCount;
|
||||
private java.util.List<CellInfo> cells;
|
||||
|
||||
public String getDeviceId() { return deviceId; }
|
||||
public String getAppId() { return appId; }
|
||||
public String getDeviceName() { return deviceName; }
|
||||
public String getDeviceStatus() { return deviceStatus; }
|
||||
public Integer getCellNumCount() { return cellNumCount; }
|
||||
public java.util.List<CellInfo> getCells() { return cells; }
|
||||
|
||||
public static class CellInfo {
|
||||
private Integer cellId;
|
||||
private String cellNo;
|
||||
private String cellNoAlias;
|
||||
private Integer cellOrder;
|
||||
private Integer cellStatus;
|
||||
private String cellInfo; // JSON string: {"door":"0","warm":"1","light":"0","disinfect":"0"}
|
||||
|
||||
public Integer getCellId() { return cellId; }
|
||||
public String getCellNo() { return cellNo; }
|
||||
public String getCellNoAlias() { return cellNoAlias; }
|
||||
public Integer getCellOrder() { return cellOrder; }
|
||||
public Integer getCellStatus() { return cellStatus; }
|
||||
public String getCellInfo() { return cellInfo; }
|
||||
}
|
||||
}
|
||||
40
src/main/java/com/auv/locker/model/aux/CellStatusNotify.java
Normal file
40
src/main/java/com/auv/locker/model/aux/CellStatusNotify.java
Normal file
@ -0,0 +1,40 @@
|
||||
package com.auv.locker.model.aux;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 单元格状态变更通知回调参数模型。
|
||||
* notifyType: cell_status_sync
|
||||
*/
|
||||
public class CellStatusNotify {
|
||||
|
||||
private String notifyTime;
|
||||
private String notifyType;
|
||||
private String appId;
|
||||
private String charset;
|
||||
private String version;
|
||||
private String signType;
|
||||
private String sign;
|
||||
private String deviceId;
|
||||
private List<CellInfoItem> cellInfoList;
|
||||
|
||||
public String getNotifyTime() { return notifyTime; }
|
||||
public String getNotifyType() { return notifyType; }
|
||||
public String getAppId() { return appId; }
|
||||
public String getCharset() { return charset; }
|
||||
public String getVersion() { return version; }
|
||||
public String getSignType() { return signType; }
|
||||
public String getSign() { return sign; }
|
||||
public String getDeviceId() { return deviceId; }
|
||||
public List<CellInfoItem> getCellInfoList() { return cellInfoList; }
|
||||
|
||||
public static class CellInfoItem {
|
||||
private String cellNo;
|
||||
private String propName; // door, light, warm, disinfect
|
||||
private String propValue; // opened, opening, closed, started, starting, stopped, stopping
|
||||
|
||||
public String getCellNo() { return cellNo; }
|
||||
public String getPropName() { return propName; }
|
||||
public String getPropValue() { return propValue; }
|
||||
}
|
||||
}
|
||||
54
src/main/java/com/auv/locker/model/aux/CellsOpsRequest.java
Normal file
54
src/main/java/com/auv/locker/model/aux/CellsOpsRequest.java
Normal file
@ -0,0 +1,54 @@
|
||||
package com.auv.locker.model.aux;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 单元格操作(多指令)请求。
|
||||
* method: device.cells.ops
|
||||
*/
|
||||
public class CellsOpsRequest {
|
||||
|
||||
private final String deviceId;
|
||||
private final List<OpItem> opList;
|
||||
|
||||
private CellsOpsRequest(Builder builder) {
|
||||
this.deviceId = builder.deviceId;
|
||||
this.opList = builder.opList;
|
||||
}
|
||||
|
||||
public String getDeviceId() { return deviceId; }
|
||||
public List<OpItem> getOpList() { return opList; }
|
||||
|
||||
public static Builder builder() {
|
||||
return new Builder();
|
||||
}
|
||||
|
||||
public static class OpItem {
|
||||
@JsonProperty("cellNo")
|
||||
private String cellNo;
|
||||
|
||||
private List<String> ops;
|
||||
|
||||
public OpItem(String cellNo, List<String> ops) {
|
||||
this.cellNo = cellNo;
|
||||
this.ops = ops;
|
||||
}
|
||||
|
||||
public String getCellNo() { return cellNo; }
|
||||
public List<String> getOps() { return ops; }
|
||||
}
|
||||
|
||||
public static class Builder {
|
||||
private String deviceId;
|
||||
private List<OpItem> opList;
|
||||
|
||||
public Builder deviceId(String deviceId) { this.deviceId = deviceId; return this; }
|
||||
public Builder opList(List<OpItem> opList) { this.opList = opList; return this; }
|
||||
|
||||
public CellsOpsRequest build() {
|
||||
return new CellsOpsRequest(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,35 @@
|
||||
package com.auv.locker.model.aux;
|
||||
|
||||
/**
|
||||
* 设备列表查询请求。
|
||||
* method: device.list.query
|
||||
*/
|
||||
public class DeviceListQueryRequest {
|
||||
|
||||
private final Integer pageSize;
|
||||
private final Integer pageNo;
|
||||
|
||||
private DeviceListQueryRequest(Builder builder) {
|
||||
this.pageSize = builder.pageSize;
|
||||
this.pageNo = builder.pageNo;
|
||||
}
|
||||
|
||||
public Integer getPageSize() { return pageSize; }
|
||||
public Integer getPageNo() { return pageNo; }
|
||||
|
||||
public static Builder builder() {
|
||||
return new Builder();
|
||||
}
|
||||
|
||||
public static class Builder {
|
||||
private Integer pageSize = 10;
|
||||
private Integer pageNo = 1;
|
||||
|
||||
public Builder pageSize(Integer pageSize) { this.pageSize = pageSize; return this; }
|
||||
public Builder pageNo(Integer pageNo) { this.pageNo = pageNo; return this; }
|
||||
|
||||
public DeviceListQueryRequest build() {
|
||||
return new DeviceListQueryRequest(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,37 @@
|
||||
package com.auv.locker.model.aux;
|
||||
|
||||
/**
|
||||
* 设备列表查询响应 (resultObject)。
|
||||
*/
|
||||
public class DeviceListQueryResponse {
|
||||
|
||||
private java.util.List<DevicePageItem> pageData;
|
||||
private Integer totalCount;
|
||||
private Boolean lastPage;
|
||||
private Integer currentPage;
|
||||
|
||||
public java.util.List<DevicePageItem> getPageData() { return pageData; }
|
||||
public Integer getTotalCount() { return totalCount; }
|
||||
public Boolean isLastPage() { return lastPage; }
|
||||
public Integer getCurrentPage() { return currentPage; }
|
||||
|
||||
public static class DevicePageItem {
|
||||
private String deviceId;
|
||||
private String appId;
|
||||
private String deviceName;
|
||||
private String deviceStatus; // ONLINE / OFFLINE
|
||||
private Integer cellNumCount;
|
||||
private Long createTime;
|
||||
private Long statusUpdateTime;
|
||||
private String deviceType;
|
||||
|
||||
public String getDeviceId() { return deviceId; }
|
||||
public String getAppId() { return appId; }
|
||||
public String getDeviceName() { return deviceName; }
|
||||
public String getDeviceStatus() { return deviceStatus; }
|
||||
public Integer getCellNumCount() { return cellNumCount; }
|
||||
public Long getCreateTime() { return createTime; }
|
||||
public Long getStatusUpdateTime() { return statusUpdateTime; }
|
||||
public String getDeviceType() { return deviceType; }
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,28 @@
|
||||
package com.auv.locker.model.aux;
|
||||
|
||||
/**
|
||||
* 设备状态变更通知回调参数模型。
|
||||
* notifyType: device_status_sync
|
||||
*/
|
||||
public class DeviceStatusNotify {
|
||||
|
||||
private String notifyTime;
|
||||
private String notifyType;
|
||||
private String appId;
|
||||
private String charset;
|
||||
private String version;
|
||||
private String signType;
|
||||
private String sign;
|
||||
private String deviceId;
|
||||
private String deviceStatus; // ONLINE / OFFLINE
|
||||
|
||||
public String getNotifyTime() { return notifyTime; }
|
||||
public String getNotifyType() { return notifyType; }
|
||||
public String getAppId() { return appId; }
|
||||
public String getCharset() { return charset; }
|
||||
public String getVersion() { return version; }
|
||||
public String getSignType() { return signType; }
|
||||
public String getSign() { return sign; }
|
||||
public String getDeviceId() { return deviceId; }
|
||||
public String getDeviceStatus() { return deviceStatus; }
|
||||
}
|
||||
@ -0,0 +1,47 @@
|
||||
package com.auv.locker.model.aux;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 设备状态查询请求。
|
||||
* method: device.status.query
|
||||
*/
|
||||
public class DeviceStatusQueryRequest {
|
||||
|
||||
private final String deviceId;
|
||||
private final List<CellRef> cells;
|
||||
|
||||
private DeviceStatusQueryRequest(Builder builder) {
|
||||
this.deviceId = builder.deviceId;
|
||||
this.cells = builder.cells;
|
||||
}
|
||||
|
||||
public String getDeviceId() { return deviceId; }
|
||||
public List<CellRef> getCells() { return cells; }
|
||||
|
||||
public static Builder builder() {
|
||||
return new Builder();
|
||||
}
|
||||
|
||||
public static class CellRef {
|
||||
@JsonProperty("cellNo")
|
||||
private String cellNo;
|
||||
|
||||
public CellRef(String cellNo) { this.cellNo = cellNo; }
|
||||
public String getCellNo() { return cellNo; }
|
||||
}
|
||||
|
||||
public static class Builder {
|
||||
private String deviceId;
|
||||
private List<CellRef> cells;
|
||||
|
||||
public Builder deviceId(String deviceId) { this.deviceId = deviceId; return this; }
|
||||
public Builder cells(List<CellRef> cells) { this.cells = cells; return this; }
|
||||
|
||||
public DeviceStatusQueryRequest build() {
|
||||
return new DeviceStatusQueryRequest(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,39 @@
|
||||
package com.auv.locker.model.aux;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
|
||||
/**
|
||||
* 设备状态查询响应 (resultObject)。
|
||||
*/
|
||||
public class DeviceStatusQueryResponse {
|
||||
|
||||
private String deviceId;
|
||||
private String appId;
|
||||
private String deviceName;
|
||||
private String deviceStatus; // ONLINE / OFFLINE
|
||||
private Integer cellNumCount;
|
||||
private java.util.List<CellDetail> cells;
|
||||
|
||||
public String getDeviceId() { return deviceId; }
|
||||
public String getAppId() { return appId; }
|
||||
public String getDeviceName() { return deviceName; }
|
||||
public String getDeviceStatus() { return deviceStatus; }
|
||||
public Integer getCellNumCount() { return cellNumCount; }
|
||||
public java.util.List<CellDetail> getCells() { return cells; }
|
||||
|
||||
public static class CellDetail {
|
||||
private Integer cellId;
|
||||
private String cellNo;
|
||||
private String cellNoAlias;
|
||||
private Integer cellOrder;
|
||||
private Integer cellStatus;
|
||||
private String cellInfo; // JSON: {"door":"opening","warm":"starting","light":"opening","disinfect":"0"}
|
||||
|
||||
public Integer getCellId() { return cellId; }
|
||||
public String getCellNo() { return cellNo; }
|
||||
public String getCellNoAlias() { return cellNoAlias; }
|
||||
public Integer getCellOrder() { return cellOrder; }
|
||||
public Integer getCellStatus() { return cellStatus; }
|
||||
public String getCellInfo() { return cellInfo; }
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,85 @@
|
||||
package com.auv.locker.model.common;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 请求构建器,用于组装 bizData 参数。
|
||||
*/
|
||||
public class AuvRequestBuilder {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(AuvRequestBuilder.class);
|
||||
private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
|
||||
|
||||
private final Map<String, Object> bizData = new LinkedHashMap<>();
|
||||
|
||||
public AuvRequestBuilder() {}
|
||||
|
||||
/**
|
||||
* 添加参数。
|
||||
*/
|
||||
public AuvRequestBuilder add(String key, Object value) {
|
||||
if (value != null && value instanceof String) {
|
||||
String str = (String) value;
|
||||
if (!str.isEmpty()) {
|
||||
bizData.put(key, str);
|
||||
}
|
||||
} else if (value != null) {
|
||||
bizData.put(key, value);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加 String 参数,空字符串不添加。
|
||||
*/
|
||||
public AuvRequestBuilder addString(String key, String value) {
|
||||
if (value != null && !value.isEmpty()) {
|
||||
bizData.put(key, value);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加 Integer 参数,null 不添加。
|
||||
*/
|
||||
public AuvRequestBuilder addInt(String key, Integer value) {
|
||||
if (value != null) {
|
||||
bizData.put(key, value);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加 Boolean 参数,null 不添加。
|
||||
*/
|
||||
public AuvRequestBuilder addBool(String key, Boolean value) {
|
||||
if (value != null) {
|
||||
bizData.put(key, value);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建 bizData JSON 字符串。
|
||||
*/
|
||||
public String build() {
|
||||
try {
|
||||
return OBJECT_MAPPER.writeValueAsString(bizData);
|
||||
} catch (JsonProcessingException e) {
|
||||
throw new RuntimeException("build bizData JSON failed", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取原始参数 Map。
|
||||
*/
|
||||
public Map<String, Object> getBizData() {
|
||||
return bizData;
|
||||
}
|
||||
}
|
||||
52
src/main/java/com/auv/locker/model/common/AuvResponse.java
Normal file
52
src/main/java/com/auv/locker/model/common/AuvResponse.java
Normal file
@ -0,0 +1,52 @@
|
||||
package com.auv.locker.model.common;
|
||||
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
|
||||
/**
|
||||
* AUV API 统一响应模型。
|
||||
*
|
||||
* <p>两套网关响应格式:
|
||||
* <ul>
|
||||
* <li>存取 API: { code(10000=成功), msg, resultObject, time, mem }</li>
|
||||
* <li>辅助 API: { code(1=成功), msg, success, timestamp, resultObject }</li>
|
||||
* </ul>
|
||||
*
|
||||
* <p>resultObject 以 JsonNode 形式存储,由 Service 层按需转换为具体类型。
|
||||
*/
|
||||
public class AuvResponse<T> {
|
||||
|
||||
private Integer code;
|
||||
private String msg;
|
||||
private Boolean success;
|
||||
private JsonNode resultObject;
|
||||
private String time;
|
||||
private Long timestamp;
|
||||
|
||||
public Integer getCode() { return code; }
|
||||
public void setCode(Integer code) { this.code = code; }
|
||||
|
||||
public String getMsg() { return msg; }
|
||||
public void setMsg(String msg) { this.msg = msg; }
|
||||
|
||||
public Boolean getSuccess() { return success; }
|
||||
public void setSuccess(Boolean success) { this.success = success; }
|
||||
|
||||
public JsonNode getResultObject() { return resultObject; }
|
||||
public void setResultObject(JsonNode resultObject) { this.resultObject = resultObject; }
|
||||
|
||||
public String getTime() { return time; }
|
||||
public void setTime(String time) { this.time = time; }
|
||||
|
||||
public Long getTimestamp() { return timestamp; }
|
||||
public void setTimestamp(Long timestamp) { this.timestamp = timestamp; }
|
||||
|
||||
/**
|
||||
* 判断是否成功(存取 API: code==10000, 辅助 API: code==1 && success==true)。
|
||||
*/
|
||||
public boolean isSuccess() {
|
||||
if (code == null) return false;
|
||||
if (code == 10000) return true;
|
||||
if (code == 1 && Boolean.TRUE.equals(success)) return true;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,73 @@
|
||||
package com.auv.locker.model.storage;
|
||||
|
||||
import com.auv.locker.model.common.AuvRequestBuilder;
|
||||
|
||||
/**
|
||||
* 为现有订单增加格子请求。
|
||||
* method: addCell
|
||||
*/
|
||||
public class AddCellRequest {
|
||||
|
||||
private final Integer orderId;
|
||||
private final String deviceId;
|
||||
private final Integer type;
|
||||
private final String isWarm;
|
||||
private final String isLight;
|
||||
private final String isDisinfect;
|
||||
private final String cellId;
|
||||
|
||||
private AddCellRequest(Builder builder) {
|
||||
this.orderId = builder.orderId;
|
||||
this.deviceId = builder.deviceId;
|
||||
this.type = builder.type;
|
||||
this.isWarm = builder.isWarm;
|
||||
this.isLight = builder.isLight;
|
||||
this.isDisinfect = builder.isDisinfect;
|
||||
this.cellId = builder.cellId;
|
||||
}
|
||||
|
||||
public Integer getOrderId() { return orderId; }
|
||||
public String getDeviceId() { return deviceId; }
|
||||
public Integer getType() { return type; }
|
||||
public String getIsWarm() { return isWarm; }
|
||||
public String getIsLight() { return isLight; }
|
||||
public String getIsDisinfect() { return isDisinfect; }
|
||||
public String getCellId() { return cellId; }
|
||||
|
||||
public AuvRequestBuilder toBuilder() {
|
||||
return new AuvRequestBuilder()
|
||||
.addInt("orderId", orderId)
|
||||
.addString("deviceId", deviceId)
|
||||
.addInt("type", type)
|
||||
.addString("isWarm", isWarm)
|
||||
.addString("isLight", isLight)
|
||||
.addString("isDisinfect", isDisinfect)
|
||||
.addString("cellId", cellId);
|
||||
}
|
||||
|
||||
public static Builder builder() {
|
||||
return new Builder();
|
||||
}
|
||||
|
||||
public static class Builder {
|
||||
private Integer orderId;
|
||||
private String deviceId;
|
||||
private Integer type;
|
||||
private String isWarm;
|
||||
private String isLight;
|
||||
private String isDisinfect;
|
||||
private String cellId;
|
||||
|
||||
public Builder orderId(Integer orderId) { this.orderId = orderId; return this; }
|
||||
public Builder deviceId(String deviceId) { this.deviceId = deviceId; return this; }
|
||||
public Builder type(Integer type) { this.type = type; return this; }
|
||||
public Builder isWarm(String isWarm) { this.isWarm = isWarm; return this; }
|
||||
public Builder isLight(String isLight) { this.isLight = isLight; return this; }
|
||||
public Builder isDisinfect(String isDisinfect) { this.isDisinfect = isDisinfect; return this; }
|
||||
public Builder cellId(String cellId) { this.cellId = cellId; return this; }
|
||||
|
||||
public AddCellRequest build() {
|
||||
return new AddCellRequest(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,19 @@
|
||||
package com.auv.locker.model.storage;
|
||||
|
||||
/**
|
||||
* 为现有订单增加格子响应 (resultObject)。
|
||||
*/
|
||||
public class AddCellResponse {
|
||||
|
||||
private String deviceId;
|
||||
private String cellId;
|
||||
private String cellAlias;
|
||||
private String newCellId;
|
||||
private String newCellAlias;
|
||||
|
||||
public String getDeviceId() { return deviceId; }
|
||||
public String getCellId() { return cellId; }
|
||||
public String getCellAlias() { return cellAlias; }
|
||||
public String getNewCellId() { return newCellId; }
|
||||
public String getNewCellAlias() { return newCellAlias; }
|
||||
}
|
||||
@ -0,0 +1,35 @@
|
||||
package com.auv.locker.model.storage;
|
||||
|
||||
/**
|
||||
* 撤餐操作请求。
|
||||
* method: cancelOrder
|
||||
*/
|
||||
public class CancelOrderRequest {
|
||||
|
||||
private final String deviceId;
|
||||
private final String orderId;
|
||||
|
||||
private CancelOrderRequest(Builder builder) {
|
||||
this.deviceId = builder.deviceId;
|
||||
this.orderId = builder.orderId;
|
||||
}
|
||||
|
||||
public String getDeviceId() { return deviceId; }
|
||||
public String getOrderId() { return orderId; }
|
||||
|
||||
public static Builder builder() {
|
||||
return new Builder();
|
||||
}
|
||||
|
||||
public static class Builder {
|
||||
private String deviceId;
|
||||
private String orderId;
|
||||
|
||||
public Builder deviceId(String deviceId) { this.deviceId = deviceId; return this; }
|
||||
public Builder orderId(String orderId) { this.orderId = orderId; return this; }
|
||||
|
||||
public CancelOrderRequest build() {
|
||||
return new CancelOrderRequest(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,15 @@
|
||||
package com.auv.locker.model.storage;
|
||||
|
||||
/**
|
||||
* 撤餐操作响应 (resultObject)。
|
||||
*/
|
||||
public class CancelOrderResponse {
|
||||
|
||||
private String deviceId;
|
||||
private String orderId;
|
||||
private Boolean result;
|
||||
|
||||
public String getDeviceId() { return deviceId; }
|
||||
public String getOrderId() { return orderId; }
|
||||
public Boolean getResult() { return result; }
|
||||
}
|
||||
@ -0,0 +1,35 @@
|
||||
package com.auv.locker.model.storage;
|
||||
|
||||
/**
|
||||
* 预订单转正式单请求。
|
||||
* method: changePreorderToFormal
|
||||
*/
|
||||
public class ChangePreorderToFormalRequest {
|
||||
|
||||
private final Integer id;
|
||||
private final String deviceId;
|
||||
|
||||
private ChangePreorderToFormalRequest(Builder builder) {
|
||||
this.id = builder.id;
|
||||
this.deviceId = builder.deviceId;
|
||||
}
|
||||
|
||||
public Integer getId() { return id; }
|
||||
public String getDeviceId() { return deviceId; }
|
||||
|
||||
public static Builder builder() {
|
||||
return new Builder();
|
||||
}
|
||||
|
||||
public static class Builder {
|
||||
private Integer id;
|
||||
private String deviceId;
|
||||
|
||||
public Builder id(Integer id) { this.id = id; return this; }
|
||||
public Builder deviceId(String deviceId) { this.deviceId = deviceId; return this; }
|
||||
|
||||
public ChangePreorderToFormalRequest build() {
|
||||
return new ChangePreorderToFormalRequest(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
package com.auv.locker.model.storage;
|
||||
|
||||
/**
|
||||
* 预订单转正式单响应 (resultObject)。
|
||||
*/
|
||||
public class ChangePreorderToFormalResponse {
|
||||
|
||||
private Boolean result;
|
||||
|
||||
public Boolean getResult() { return result; }
|
||||
}
|
||||
@ -0,0 +1,85 @@
|
||||
package com.auv.locker.model.storage;
|
||||
|
||||
import com.auv.locker.model.common.AuvRequestBuilder;
|
||||
|
||||
/**
|
||||
* 创建存餐订单请求。
|
||||
* method: createOrder
|
||||
*/
|
||||
public class CreateOrderRequest {
|
||||
|
||||
private final String deviceId;
|
||||
private final String shopOrderId;
|
||||
private final Integer type;
|
||||
private final String isWarm;
|
||||
private final String isLight;
|
||||
private final String isDisinfect;
|
||||
private final String isRandom;
|
||||
private final String takeCode;
|
||||
private final String cellId;
|
||||
|
||||
private CreateOrderRequest(Builder builder) {
|
||||
this.deviceId = builder.deviceId;
|
||||
this.shopOrderId = builder.shopOrderId;
|
||||
this.type = builder.type;
|
||||
this.isWarm = builder.isWarm;
|
||||
this.isLight = builder.isLight;
|
||||
this.isDisinfect = builder.isDisinfect;
|
||||
this.isRandom = builder.isRandom;
|
||||
this.takeCode = builder.takeCode;
|
||||
this.cellId = builder.cellId;
|
||||
}
|
||||
|
||||
public String getDeviceId() { return deviceId; }
|
||||
public String getShopOrderId() { return shopOrderId; }
|
||||
public Integer getType() { return type; }
|
||||
public String getIsWarm() { return isWarm; }
|
||||
public String getIsLight() { return isLight; }
|
||||
public String getIsDisinfect() { return isDisinfect; }
|
||||
public String getIsRandom() { return isRandom; }
|
||||
public String getTakeCode() { return takeCode; }
|
||||
public String getCellId() { return cellId; }
|
||||
|
||||
public AuvRequestBuilder toBuilder() {
|
||||
return new AuvRequestBuilder()
|
||||
.addString("deviceId", deviceId)
|
||||
.addString("shopOrderId", shopOrderId)
|
||||
.addInt("type", type)
|
||||
.addString("isWarm", isWarm)
|
||||
.addString("isLight", isLight)
|
||||
.addString("isDisinfect", isDisinfect)
|
||||
.addString("isRandom", isRandom)
|
||||
.addString("takeCode", takeCode)
|
||||
.addString("cellId", cellId);
|
||||
}
|
||||
|
||||
public static Builder builder() {
|
||||
return new Builder();
|
||||
}
|
||||
|
||||
public static class Builder {
|
||||
private String deviceId;
|
||||
private String shopOrderId;
|
||||
private Integer type = 1;
|
||||
private String isWarm;
|
||||
private String isLight;
|
||||
private String isDisinfect;
|
||||
private String isRandom = "1";
|
||||
private String takeCode;
|
||||
private String cellId;
|
||||
|
||||
public Builder deviceId(String deviceId) { this.deviceId = deviceId; return this; }
|
||||
public Builder shopOrderId(String shopOrderId) { this.shopOrderId = shopOrderId; return this; }
|
||||
public Builder type(Integer type) { this.type = type; return this; }
|
||||
public Builder isWarm(String isWarm) { this.isWarm = isWarm; return this; }
|
||||
public Builder isLight(String isLight) { this.isLight = isLight; return this; }
|
||||
public Builder isDisinfect(String isDisinfect) { this.isDisinfect = isDisinfect; return this; }
|
||||
public Builder isRandom(String isRandom) { this.isRandom = isRandom; return this; }
|
||||
public Builder takeCode(String takeCode) { this.takeCode = takeCode; return this; }
|
||||
public Builder cellId(String cellId) { this.cellId = cellId; return this; }
|
||||
|
||||
public CreateOrderRequest build() {
|
||||
return new CreateOrderRequest(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,21 @@
|
||||
package com.auv.locker.model.storage;
|
||||
|
||||
/**
|
||||
* 创建存餐订单响应 (resultObject)。
|
||||
*/
|
||||
public class CreateOrderResponse {
|
||||
|
||||
private String deviceId;
|
||||
private String shopOrderId;
|
||||
private String orderId;
|
||||
private String cellId;
|
||||
private String code;
|
||||
private String cellAlias;
|
||||
|
||||
public String getDeviceId() { return deviceId; }
|
||||
public String getShopOrderId() { return shopOrderId; }
|
||||
public String getOrderId() { return orderId; }
|
||||
public String getCellId() { return cellId; }
|
||||
public String getCode() { return code; }
|
||||
public String getCellAlias() { return cellAlias; }
|
||||
}
|
||||
@ -0,0 +1,70 @@
|
||||
package com.auv.locker.model.storage;
|
||||
|
||||
/**
|
||||
* 创建预订单请求。
|
||||
* method: createPreOrder
|
||||
*/
|
||||
public class CreatePreOrderRequest {
|
||||
|
||||
private final String deviceId;
|
||||
private final String shopOrderId;
|
||||
private final Integer type;
|
||||
private final String expiryTime;
|
||||
private final String isWarm;
|
||||
private final String isLight;
|
||||
private final String isDisinfect;
|
||||
private final String takeCode;
|
||||
private final String cellId;
|
||||
|
||||
private CreatePreOrderRequest(Builder builder) {
|
||||
this.deviceId = builder.deviceId;
|
||||
this.shopOrderId = builder.shopOrderId;
|
||||
this.type = builder.type;
|
||||
this.expiryTime = builder.expiryTime;
|
||||
this.isWarm = builder.isWarm;
|
||||
this.isLight = builder.isLight;
|
||||
this.isDisinfect = builder.isDisinfect;
|
||||
this.takeCode = builder.takeCode;
|
||||
this.cellId = builder.cellId;
|
||||
}
|
||||
|
||||
public String getDeviceId() { return deviceId; }
|
||||
public String getShopOrderId() { return shopOrderId; }
|
||||
public Integer getType() { return type; }
|
||||
public String getExpiryTime() { return expiryTime; }
|
||||
public String getIsWarm() { return isWarm; }
|
||||
public String getIsLight() { return isLight; }
|
||||
public String getIsDisinfect() { return isDisinfect; }
|
||||
public String getTakeCode() { return takeCode; }
|
||||
public String getCellId() { return cellId; }
|
||||
|
||||
public static Builder builder() {
|
||||
return new Builder();
|
||||
}
|
||||
|
||||
public static class Builder {
|
||||
private String deviceId;
|
||||
private String shopOrderId;
|
||||
private Integer type = 1;
|
||||
private String expiryTime;
|
||||
private String isWarm;
|
||||
private String isLight;
|
||||
private String isDisinfect;
|
||||
private String takeCode;
|
||||
private String cellId;
|
||||
|
||||
public Builder deviceId(String deviceId) { this.deviceId = deviceId; return this; }
|
||||
public Builder shopOrderId(String shopOrderId) { this.shopOrderId = shopOrderId; return this; }
|
||||
public Builder type(Integer type) { this.type = type; return this; }
|
||||
public Builder expiryTime(String expiryTime) { this.expiryTime = expiryTime; return this; }
|
||||
public Builder isWarm(String isWarm) { this.isWarm = isWarm; return this; }
|
||||
public Builder isLight(String isLight) { this.isLight = isLight; return this; }
|
||||
public Builder isDisinfect(String isDisinfect) { this.isDisinfect = isDisinfect; return this; }
|
||||
public Builder takeCode(String takeCode) { this.takeCode = takeCode; return this; }
|
||||
public Builder cellId(String cellId) { this.cellId = cellId; return this; }
|
||||
|
||||
public CreatePreOrderRequest build() {
|
||||
return new CreatePreOrderRequest(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,23 @@
|
||||
package com.auv.locker.model.storage;
|
||||
|
||||
/**
|
||||
* 创建预订单响应 (resultObject)。
|
||||
*/
|
||||
public class CreatePreOrderResponse {
|
||||
|
||||
private String deviceId;
|
||||
private String shopOrderId;
|
||||
private String orderId;
|
||||
private String cellId;
|
||||
private String cellAlias;
|
||||
private String code;
|
||||
private String expiryTime;
|
||||
|
||||
public String getDeviceId() { return deviceId; }
|
||||
public String getShopOrderId() { return shopOrderId; }
|
||||
public String getOrderId() { return orderId; }
|
||||
public String getCellId() { return cellId; }
|
||||
public String getCellAlias() { return cellAlias; }
|
||||
public String getCode() { return code; }
|
||||
public String getExpiryTime() { return expiryTime; }
|
||||
}
|
||||
@ -0,0 +1,30 @@
|
||||
package com.auv.locker.model.storage;
|
||||
|
||||
/**
|
||||
* 获取格子列表请求。
|
||||
* method: getCellList
|
||||
*/
|
||||
public class GetCellListRequest {
|
||||
|
||||
private final String deviceId;
|
||||
|
||||
private GetCellListRequest(Builder builder) {
|
||||
this.deviceId = builder.deviceId;
|
||||
}
|
||||
|
||||
public String getDeviceId() { return deviceId; }
|
||||
|
||||
public static Builder builder() {
|
||||
return new Builder();
|
||||
}
|
||||
|
||||
public static class Builder {
|
||||
private String deviceId;
|
||||
|
||||
public Builder deviceId(String deviceId) { this.deviceId = deviceId; return this; }
|
||||
|
||||
public GetCellListRequest build() {
|
||||
return new GetCellListRequest(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,23 @@
|
||||
package com.auv.locker.model.storage;
|
||||
|
||||
/**
|
||||
* 获取格子列表响应元素 (resultObject 数组元素)。
|
||||
*/
|
||||
public class GetCellListResponse {
|
||||
|
||||
private Integer cellId;
|
||||
private Integer type; // 1-小格, 2-大格
|
||||
private String orderId;
|
||||
private String createTime;
|
||||
private Integer isPreOrder;
|
||||
private String expiryTime;
|
||||
private Integer lockOpen; // 1-已锁定, 0-未锁定
|
||||
|
||||
public Integer getCellId() { return cellId; }
|
||||
public Integer getType() { return type; }
|
||||
public String getOrderId() { return orderId; }
|
||||
public String getCreateTime() { return createTime; }
|
||||
public Integer getIsPreOrder() { return isPreOrder; }
|
||||
public String getExpiryTime() { return expiryTime; }
|
||||
public Integer getLockOpen() { return lockOpen; }
|
||||
}
|
||||
@ -0,0 +1,30 @@
|
||||
package com.auv.locker.model.storage;
|
||||
|
||||
/**
|
||||
* 获取设备信息请求。
|
||||
* method: getDeviceInfo
|
||||
*/
|
||||
public class GetDeviceInfoRequest {
|
||||
|
||||
private final String deviceId;
|
||||
|
||||
private GetDeviceInfoRequest(Builder builder) {
|
||||
this.deviceId = builder.deviceId;
|
||||
}
|
||||
|
||||
public String getDeviceId() { return deviceId; }
|
||||
|
||||
public static Builder builder() {
|
||||
return new Builder();
|
||||
}
|
||||
|
||||
public static class Builder {
|
||||
private String deviceId;
|
||||
|
||||
public Builder deviceId(String deviceId) { this.deviceId = deviceId; return this; }
|
||||
|
||||
public GetDeviceInfoRequest build() {
|
||||
return new GetDeviceInfoRequest(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,23 @@
|
||||
package com.auv.locker.model.storage;
|
||||
|
||||
/**
|
||||
* 获取设备信息响应 (resultObject)。
|
||||
*/
|
||||
public class GetDeviceInfoResponse {
|
||||
|
||||
private String deviceId;
|
||||
private String deviceName;
|
||||
private Integer smallTotal;
|
||||
private Integer bigTotal;
|
||||
private Integer small;
|
||||
private Integer big;
|
||||
private String lgdeLade; // 百度地图经纬度信息
|
||||
|
||||
public String getDeviceId() { return deviceId; }
|
||||
public String getDeviceName() { return deviceName; }
|
||||
public Integer getSmallTotal() { return smallTotal; }
|
||||
public Integer getBigTotal() { return bigTotal; }
|
||||
public Integer getSmall() { return small; }
|
||||
public Integer getBig() { return big; }
|
||||
public String getLgdeLade() { return lgdeLade; }
|
||||
}
|
||||
@ -0,0 +1,55 @@
|
||||
package com.auv.locker.model.storage;
|
||||
|
||||
/**
|
||||
* 查询存餐订单请求。
|
||||
* method: getOrderList
|
||||
*/
|
||||
public class GetOrderListRequest {
|
||||
|
||||
private final Integer status;
|
||||
private final Integer page;
|
||||
private final String deviceId;
|
||||
private final Integer orderId;
|
||||
private final String timeStart;
|
||||
private final String timeEnd;
|
||||
|
||||
private GetOrderListRequest(Builder builder) {
|
||||
this.status = builder.status;
|
||||
this.page = builder.page;
|
||||
this.deviceId = builder.deviceId;
|
||||
this.orderId = builder.orderId;
|
||||
this.timeStart = builder.timeStart;
|
||||
this.timeEnd = builder.timeEnd;
|
||||
}
|
||||
|
||||
public Integer getStatus() { return status; }
|
||||
public Integer getPage() { return page; }
|
||||
public String getDeviceId() { return deviceId; }
|
||||
public Integer getOrderId() { return orderId; }
|
||||
public String getTimeStart() { return timeStart; }
|
||||
public String getTimeEnd() { return timeEnd; }
|
||||
|
||||
public static Builder builder() {
|
||||
return new Builder();
|
||||
}
|
||||
|
||||
public static class Builder {
|
||||
private Integer status;
|
||||
private Integer page = 1;
|
||||
private String deviceId;
|
||||
private Integer orderId;
|
||||
private String timeStart;
|
||||
private String timeEnd;
|
||||
|
||||
public Builder status(Integer status) { this.status = status; return this; }
|
||||
public Builder page(Integer page) { this.page = page; return this; }
|
||||
public Builder deviceId(String deviceId) { this.deviceId = deviceId; return this; }
|
||||
public Builder orderId(Integer orderId) { this.orderId = orderId; return this; }
|
||||
public Builder timeStart(String timeStart) { this.timeStart = timeStart; return this; }
|
||||
public Builder timeEnd(String timeEnd) { this.timeEnd = timeEnd; return this; }
|
||||
|
||||
public GetOrderListRequest build() {
|
||||
return new GetOrderListRequest(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,41 @@
|
||||
package com.auv.locker.model.storage;
|
||||
|
||||
/**
|
||||
* 查询存餐订单响应 (resultObject)。
|
||||
*/
|
||||
public class GetOrderListResponse {
|
||||
|
||||
private Integer total;
|
||||
private Integer per_page;
|
||||
private Integer current_page;
|
||||
private Integer last_page;
|
||||
private java.util.List<OrderItem> data;
|
||||
|
||||
public Integer getTotal() { return total; }
|
||||
public Integer getPerPage() { return per_page; }
|
||||
public Integer getCurrentPage() { return current_page; }
|
||||
public Integer getLastPage() { return last_page; }
|
||||
public java.util.List<OrderItem> getData() { return data; }
|
||||
|
||||
public static class OrderItem {
|
||||
private Integer id;
|
||||
private String shopOrderId;
|
||||
private String deviceId;
|
||||
private String cellId;
|
||||
private Integer status; // 1-待取, 2-已取, 3-已撤餐
|
||||
private String createTime;
|
||||
private String takeTime;
|
||||
private Integer preOrder;
|
||||
private String expiryTime;
|
||||
|
||||
public Integer getId() { return id; }
|
||||
public String getShopOrderId() { return shopOrderId; }
|
||||
public String getDeviceId() { return deviceId; }
|
||||
public String getCellId() { return cellId; }
|
||||
public Integer getStatus() { return status; }
|
||||
public String getCreateTime() { return createTime; }
|
||||
public String getTakeTime() { return takeTime; }
|
||||
public Integer getPreOrder() { return preOrder; }
|
||||
public String getExpiryTime() { return expiryTime; }
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,28 @@
|
||||
package com.auv.locker.model.storage;
|
||||
|
||||
/**
|
||||
* 订单状态被动变更通知回调参数模型。
|
||||
* notifyType: orderCompleted / orderCancel
|
||||
*/
|
||||
public class OrderStatusNotify {
|
||||
|
||||
private String appId;
|
||||
private String charset;
|
||||
private String deviceId;
|
||||
private String notifyTime;
|
||||
private String notifyType; // orderCompleted / orderCancel
|
||||
private String signType;
|
||||
private String version;
|
||||
private String notifyContent; // JSON string of takeByCode response
|
||||
private String sign;
|
||||
|
||||
public String getAppId() { return appId; }
|
||||
public String getCharset() { return charset; }
|
||||
public String getDeviceId() { return deviceId; }
|
||||
public String getNotifyTime() { return notifyTime; }
|
||||
public String getNotifyType() { return notifyType; }
|
||||
public String getSignType() { return signType; }
|
||||
public String getVersion() { return version; }
|
||||
public String getNotifyContent() { return notifyContent; }
|
||||
public String getSign() { return sign; }
|
||||
}
|
||||
@ -0,0 +1,41 @@
|
||||
package com.auv.locker.model.storage;
|
||||
|
||||
/**
|
||||
* 临时开门请求。
|
||||
* method: reOpenDoor
|
||||
* 注意:存餐或取餐成功的 60 秒内有效。
|
||||
*/
|
||||
public class ReOpenDoorRequest {
|
||||
|
||||
private final String orderId;
|
||||
private final String deviceId;
|
||||
private final String type; // save / take
|
||||
|
||||
private ReOpenDoorRequest(Builder builder) {
|
||||
this.orderId = builder.orderId;
|
||||
this.deviceId = builder.deviceId;
|
||||
this.type = builder.type;
|
||||
}
|
||||
|
||||
public String getOrderId() { return orderId; }
|
||||
public String getDeviceId() { return deviceId; }
|
||||
public String getType() { return type; }
|
||||
|
||||
public static Builder builder() {
|
||||
return new Builder();
|
||||
}
|
||||
|
||||
public static class Builder {
|
||||
private String orderId;
|
||||
private String deviceId;
|
||||
private String type;
|
||||
|
||||
public Builder orderId(String orderId) { this.orderId = orderId; return this; }
|
||||
public Builder deviceId(String deviceId) { this.deviceId = deviceId; return this; }
|
||||
public Builder type(String type) { this.type = type; return this; }
|
||||
|
||||
public ReOpenDoorRequest build() {
|
||||
return new ReOpenDoorRequest(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
package com.auv.locker.model.storage;
|
||||
|
||||
/**
|
||||
* 临时开门响应 (resultObject)。
|
||||
*/
|
||||
public class ReOpenDoorResponse {
|
||||
|
||||
private Boolean result;
|
||||
|
||||
public Boolean getResult() { return result; }
|
||||
}
|
||||
@ -0,0 +1,35 @@
|
||||
package com.auv.locker.model.storage;
|
||||
|
||||
/**
|
||||
* 根据取餐码取餐请求。
|
||||
* method: takeByCode
|
||||
*/
|
||||
public class TakeByCodeRequest {
|
||||
|
||||
private final String deviceId;
|
||||
private final String code;
|
||||
|
||||
private TakeByCodeRequest(Builder builder) {
|
||||
this.deviceId = builder.deviceId;
|
||||
this.code = builder.code;
|
||||
}
|
||||
|
||||
public String getDeviceId() { return deviceId; }
|
||||
public String getCode() { return code; }
|
||||
|
||||
public static Builder builder() {
|
||||
return new Builder();
|
||||
}
|
||||
|
||||
public static class Builder {
|
||||
private String deviceId;
|
||||
private String code;
|
||||
|
||||
public Builder deviceId(String deviceId) { this.deviceId = deviceId; return this; }
|
||||
public Builder code(String code) { this.code = code; return this; }
|
||||
|
||||
public TakeByCodeRequest build() {
|
||||
return new TakeByCodeRequest(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,35 @@
|
||||
package com.auv.locker.model.storage;
|
||||
|
||||
/**
|
||||
* 根据订单取餐请求。
|
||||
* method: takeByOrder
|
||||
*/
|
||||
public class TakeByOrderRequest {
|
||||
|
||||
private final String deviceId;
|
||||
private final String orderId;
|
||||
|
||||
private TakeByOrderRequest(Builder builder) {
|
||||
this.deviceId = builder.deviceId;
|
||||
this.orderId = builder.orderId;
|
||||
}
|
||||
|
||||
public String getDeviceId() { return deviceId; }
|
||||
public String getOrderId() { return orderId; }
|
||||
|
||||
public static Builder builder() {
|
||||
return new Builder();
|
||||
}
|
||||
|
||||
public static class Builder {
|
||||
private String deviceId;
|
||||
private String orderId;
|
||||
|
||||
public Builder deviceId(String deviceId) { this.deviceId = deviceId; return this; }
|
||||
public Builder orderId(String orderId) { this.orderId = orderId; return this; }
|
||||
|
||||
public TakeByOrderRequest build() {
|
||||
return new TakeByOrderRequest(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,17 @@
|
||||
package com.auv.locker.model.storage;
|
||||
|
||||
/**
|
||||
* 根据订单取餐 / 根据取餐码取餐响应 (resultObject)。
|
||||
*/
|
||||
public class TakeByOrderResponse {
|
||||
|
||||
private String deviceId;
|
||||
private String orderId;
|
||||
private String shopOrderId;
|
||||
private String cellId;
|
||||
|
||||
public String getDeviceId() { return deviceId; }
|
||||
public String getOrderId() { return orderId; }
|
||||
public String getShopOrderId() { return shopOrderId; }
|
||||
public String getCellId() { return cellId; }
|
||||
}
|
||||
29
src/main/java/com/auv/locker/service/AuxApiService.java
Normal file
29
src/main/java/com/auv/locker/service/AuxApiService.java
Normal file
@ -0,0 +1,29 @@
|
||||
package com.auv.locker.service;
|
||||
|
||||
import com.auv.locker.model.aux.*;
|
||||
|
||||
/**
|
||||
* 辅助功能 API 服务接口。
|
||||
*/
|
||||
public interface AuxApiService {
|
||||
|
||||
/**
|
||||
* 单元格操作(单指令)。
|
||||
*/
|
||||
AuxCellOpResponse cellOp(CellOpRequest request);
|
||||
|
||||
/**
|
||||
* 单元格操作(多指令,仅安卓方案支持)。
|
||||
*/
|
||||
AuxCellOpResponse cellsOps(CellsOpsRequest request);
|
||||
|
||||
/**
|
||||
* 设备状态查询。
|
||||
*/
|
||||
AuxCellOpResponse queryDeviceStatus(DeviceStatusQueryRequest request);
|
||||
|
||||
/**
|
||||
* 设备列表查询。
|
||||
*/
|
||||
AuxDeviceListQueryResponse queryDeviceList(DeviceListQueryRequest request);
|
||||
}
|
||||
110
src/main/java/com/auv/locker/service/AuxApiServiceImpl.java
Normal file
110
src/main/java/com/auv/locker/service/AuxApiServiceImpl.java
Normal file
@ -0,0 +1,110 @@
|
||||
package com.auv.locker.service;
|
||||
|
||||
import com.auv.locker.config.AuvConfig;
|
||||
import com.auv.locker.http.AuvHttpClient;
|
||||
import com.auv.locker.model.aux.*;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
|
||||
/**
|
||||
* 辅助功能 API 实现。
|
||||
*/
|
||||
public class AuxApiServiceImpl implements AuxApiService {
|
||||
|
||||
private static final ObjectMapper MAPPER = new ObjectMapper();
|
||||
|
||||
private final AuvHttpClient httpClient;
|
||||
private final AuvConfig config;
|
||||
|
||||
public AuxApiServiceImpl(AuvHttpClient httpClient, AuvConfig config) {
|
||||
this.httpClient = httpClient;
|
||||
this.config = config;
|
||||
}
|
||||
|
||||
private AuxCellOpResponse doRequest(String method, String bizDataJson) {
|
||||
try {
|
||||
com.auv.locker.model.common.AuvResponse raw = httpClient.get(config.getAuxBaseUrl(), method, bizDataJson);
|
||||
if (raw.isSuccess() && raw.getResultObject() != null && !raw.getResultObject().isNull()) {
|
||||
return new AuxCellOpResponse(raw.getResultObject().toString(),
|
||||
raw.getCode(), raw.getMsg(), true);
|
||||
}
|
||||
return new AuxCellOpResponse(null, raw.getCode(), raw.getMsg(), false);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("aux api " + method + " failed: " + e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
private AuxDeviceListQueryResponse doListRequest(String method, String bizDataJson) {
|
||||
try {
|
||||
com.auv.locker.model.common.AuvResponse raw = httpClient.get(config.getAuxBaseUrl(), method, bizDataJson);
|
||||
if (raw.isSuccess() && raw.getResultObject() != null && !raw.getResultObject().isNull()) {
|
||||
JsonNode data = raw.getResultObject();
|
||||
DeviceListQueryResponse resp = MAPPER.convertValue(data, DeviceListQueryResponse.class);
|
||||
return new AuxDeviceListQueryResponse(MAPPER.writeValueAsString(resp),
|
||||
raw.getCode(), raw.getMsg(), true);
|
||||
}
|
||||
return new AuxDeviceListQueryResponse(null, raw.getCode(), raw.getMsg(), false);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("aux api " + method + " failed: " + e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public AuxCellOpResponse cellOp(CellOpRequest request) {
|
||||
try {
|
||||
String bizDataJson = MAPPER.writeValueAsString(
|
||||
new java.util.LinkedHashMap<String, Object>() {{
|
||||
put("deviceId", request.getDeviceId());
|
||||
put("cellNo", request.getCellNo());
|
||||
put("op", request.getOp());
|
||||
}});
|
||||
return doRequest("device.cell.op", bizDataJson);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("cellOp failed: " + e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public AuxCellOpResponse cellsOps(CellsOpsRequest request) {
|
||||
try {
|
||||
String bizDataJson = MAPPER.writeValueAsString(
|
||||
new java.util.LinkedHashMap<String, Object>() {{
|
||||
put("deviceId", request.getDeviceId());
|
||||
put("opList", request.getOpList());
|
||||
}});
|
||||
return doRequest("device.cells.ops", bizDataJson);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("cellsOps failed: " + e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public AuxCellOpResponse queryDeviceStatus(DeviceStatusQueryRequest request) {
|
||||
try {
|
||||
String bizDataJson = MAPPER.writeValueAsString(
|
||||
new java.util.LinkedHashMap<String, Object>() {{
|
||||
put("deviceId", request.getDeviceId());
|
||||
if (request.getCells() != null && !request.getCells().isEmpty()) {
|
||||
put("cells", request.getCells());
|
||||
}
|
||||
}});
|
||||
return doRequest("device.status.query", bizDataJson);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("queryDeviceStatus failed: " + e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public AuxDeviceListQueryResponse queryDeviceList(DeviceListQueryRequest request) {
|
||||
try {
|
||||
String bizDataJson = MAPPER.writeValueAsString(
|
||||
new java.util.LinkedHashMap<String, Object>() {{
|
||||
put("pageSize", request.getPageSize());
|
||||
put("pageNo", request.getPageNo());
|
||||
}});
|
||||
return doListRequest("device.list.query", bizDataJson);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("queryDeviceList failed: " + e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
67
src/main/java/com/auv/locker/service/StorageApiService.java
Normal file
67
src/main/java/com/auv/locker/service/StorageApiService.java
Normal file
@ -0,0 +1,67 @@
|
||||
package com.auv.locker.service;
|
||||
|
||||
import com.auv.locker.model.common.AuvResponse;
|
||||
import com.auv.locker.model.storage.*;
|
||||
|
||||
/**
|
||||
* 存取业务 API 服务接口。
|
||||
*
|
||||
* 所有方法返回 AuvResponse<T>,调用者通过 response.isSuccess() 判断成功与否。
|
||||
*/
|
||||
public interface StorageApiService {
|
||||
|
||||
/**
|
||||
* 创建存餐订单。
|
||||
*/
|
||||
AuvResponse<CreateOrderResponse> createOrder(CreateOrderRequest request);
|
||||
|
||||
/**
|
||||
* 为现有订单增加格子。
|
||||
*/
|
||||
AuvResponse<AddCellResponse> addCell(AddCellRequest request);
|
||||
|
||||
/**
|
||||
* 撤餐操作。
|
||||
*/
|
||||
AuvResponse<CancelOrderResponse> cancelOrder(CancelOrderRequest request);
|
||||
|
||||
/**
|
||||
* 根据订单取餐。
|
||||
*/
|
||||
AuvResponse<TakeByOrderResponse> takeByOrder(TakeByOrderRequest request);
|
||||
|
||||
/**
|
||||
* 根据取餐码取餐。
|
||||
*/
|
||||
AuvResponse<TakeByOrderResponse> takeByCode(TakeByCodeRequest request);
|
||||
|
||||
/**
|
||||
* 临时开门(60 秒内有效)。
|
||||
*/
|
||||
AuvResponse<ReOpenDoorResponse> reOpenDoor(ReOpenDoorRequest request);
|
||||
|
||||
/**
|
||||
* 获取设备信息。
|
||||
*/
|
||||
AuvResponse<GetDeviceInfoResponse> getDeviceInfo(GetDeviceInfoRequest request);
|
||||
|
||||
/**
|
||||
* 获取格子列表。
|
||||
*/
|
||||
AuvResponse<java.util.List<GetCellListResponse>> getCellList(GetCellListRequest request);
|
||||
|
||||
/**
|
||||
* 查询存餐订单。
|
||||
*/
|
||||
AuvResponse<GetOrderListResponse> getOrderList(GetOrderListRequest request);
|
||||
|
||||
/**
|
||||
* 创建预订单。
|
||||
*/
|
||||
AuvResponse<CreatePreOrderResponse> createPreOrder(CreatePreOrderRequest request);
|
||||
|
||||
/**
|
||||
* 预订单转正式单。
|
||||
*/
|
||||
AuvResponse<ChangePreorderToFormalResponse> changePreorderToFormal(ChangePreorderToFormalRequest request);
|
||||
}
|
||||
196
src/main/java/com/auv/locker/service/StorageApiServiceImpl.java
Normal file
196
src/main/java/com/auv/locker/service/StorageApiServiceImpl.java
Normal file
@ -0,0 +1,196 @@
|
||||
package com.auv.locker.service;
|
||||
|
||||
import com.auv.locker.config.AuvConfig;
|
||||
import com.auv.locker.http.AuvHttpClient;
|
||||
import com.auv.locker.model.common.AuvResponse;
|
||||
import com.auv.locker.model.storage.*;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
|
||||
/**
|
||||
* 存取业务 API 实现。
|
||||
*/
|
||||
public class StorageApiServiceImpl implements StorageApiService {
|
||||
|
||||
private static final ObjectMapper MAPPER = new ObjectMapper();
|
||||
|
||||
private final AuvHttpClient httpClient;
|
||||
private final AuvConfig config;
|
||||
|
||||
public StorageApiServiceImpl(AuvHttpClient httpClient, AuvConfig config) {
|
||||
this.httpClient = httpClient;
|
||||
this.config = config;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private AuvResponse doRequest(String method,
|
||||
com.auv.locker.model.common.AuvRequestBuilder builder,
|
||||
Class<?> resultType) {
|
||||
String bizData = builder.build();
|
||||
AuvResponse raw = httpClient.get(config.getStorageBaseUrl(), method, bizData);
|
||||
if (raw.isSuccess() && raw.getResultObject() != null && !raw.getResultObject().isNull()) {
|
||||
AuvResponse resp = new AuvResponse();
|
||||
resp.setCode(raw.getCode());
|
||||
resp.setMsg(raw.getMsg());
|
||||
resp.setSuccess(raw.getSuccess());
|
||||
JsonNode node = raw.getResultObject();
|
||||
Object result = MAPPER.convertValue(node, resultType);
|
||||
resp.setResultObject(MAPPER.valueToTree(result));
|
||||
return resp;
|
||||
}
|
||||
return raw;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private AuvResponse doListRequest(String method,
|
||||
com.auv.locker.model.common.AuvRequestBuilder builder) {
|
||||
String bizData = builder.build();
|
||||
AuvResponse raw = httpClient.get(config.getStorageBaseUrl(), method, bizData);
|
||||
if (raw.isSuccess() && raw.getResultObject() != null && !raw.getResultObject().isNull()) {
|
||||
AuvResponse resp = new AuvResponse();
|
||||
resp.setCode(raw.getCode());
|
||||
resp.setMsg(raw.getMsg());
|
||||
resp.setSuccess(raw.getSuccess());
|
||||
JsonNode node = raw.getResultObject();
|
||||
java.util.List<GetCellListResponse> list = MAPPER.convertValue(
|
||||
node,
|
||||
new com.fasterxml.jackson.core.type.TypeReference<java.util.List<GetCellListResponse>>() {});
|
||||
resp.setResultObject(MAPPER.valueToTree(list));
|
||||
return resp;
|
||||
}
|
||||
return raw;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AuvResponse<CreateOrderResponse> createOrder(CreateOrderRequest request) {
|
||||
com.auv.locker.model.common.AuvRequestBuilder builder = request.toBuilder();
|
||||
AuvResponse resp = (AuvResponse) doRequest("createOrder", builder, CreateOrderResponse.class);
|
||||
return wrap(resp, CreateOrderResponse.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AuvResponse<AddCellResponse> addCell(AddCellRequest request) {
|
||||
com.auv.locker.model.common.AuvRequestBuilder builder = request.toBuilder();
|
||||
AuvResponse resp = (AuvResponse) doRequest("addCell", builder, AddCellResponse.class);
|
||||
return wrap(resp, AddCellResponse.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AuvResponse<CancelOrderResponse> cancelOrder(CancelOrderRequest request) {
|
||||
com.auv.locker.model.common.AuvRequestBuilder builder = new com.auv.locker.model.common.AuvRequestBuilder()
|
||||
.addString("deviceId", request.getDeviceId())
|
||||
.addString("orderId", request.getOrderId());
|
||||
AuvResponse resp = (AuvResponse) doRequest("cancelOrder", builder, CancelOrderResponse.class);
|
||||
return wrap(resp, CancelOrderResponse.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AuvResponse<TakeByOrderResponse> takeByOrder(TakeByOrderRequest request) {
|
||||
com.auv.locker.model.common.AuvRequestBuilder builder = new com.auv.locker.model.common.AuvRequestBuilder()
|
||||
.addString("deviceId", request.getDeviceId())
|
||||
.addString("orderId", request.getOrderId());
|
||||
AuvResponse resp = (AuvResponse) doRequest("takeByOrder", builder, TakeByOrderResponse.class);
|
||||
return wrap(resp, TakeByOrderResponse.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AuvResponse<TakeByOrderResponse> takeByCode(TakeByCodeRequest request) {
|
||||
com.auv.locker.model.common.AuvRequestBuilder builder = new com.auv.locker.model.common.AuvRequestBuilder()
|
||||
.addString("deviceId", request.getDeviceId())
|
||||
.addString("code", request.getCode());
|
||||
AuvResponse resp = (AuvResponse) doRequest("takeByCode", builder, TakeByOrderResponse.class);
|
||||
return wrap(resp, TakeByOrderResponse.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AuvResponse<ReOpenDoorResponse> reOpenDoor(ReOpenDoorRequest request) {
|
||||
com.auv.locker.model.common.AuvRequestBuilder builder = new com.auv.locker.model.common.AuvRequestBuilder()
|
||||
.addString("orderId", request.getOrderId())
|
||||
.addString("deviceId", request.getDeviceId())
|
||||
.addString("type", request.getType());
|
||||
AuvResponse resp = (AuvResponse) doRequest("reOpenDoor", builder, ReOpenDoorResponse.class);
|
||||
return wrap(resp, ReOpenDoorResponse.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AuvResponse<GetDeviceInfoResponse> getDeviceInfo(GetDeviceInfoRequest request) {
|
||||
com.auv.locker.model.common.AuvRequestBuilder builder = new com.auv.locker.model.common.AuvRequestBuilder()
|
||||
.addString("deviceId", request.getDeviceId());
|
||||
AuvResponse resp = (AuvResponse) doRequest("getDeviceInfo", builder, GetDeviceInfoResponse.class);
|
||||
return wrap(resp, GetDeviceInfoResponse.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AuvResponse<java.util.List<GetCellListResponse>> getCellList(GetCellListRequest request) {
|
||||
com.auv.locker.model.common.AuvRequestBuilder builder = new com.auv.locker.model.common.AuvRequestBuilder()
|
||||
.addString("deviceId", request.getDeviceId());
|
||||
AuvResponse resp = (AuvResponse) doListRequest("getCellList", builder);
|
||||
return wrapList(resp);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AuvResponse<GetOrderListResponse> getOrderList(GetOrderListRequest request) {
|
||||
com.auv.locker.model.common.AuvRequestBuilder builder = new com.auv.locker.model.common.AuvRequestBuilder()
|
||||
.addInt("status", request.getStatus())
|
||||
.addInt("page", request.getPage())
|
||||
.addString("deviceId", request.getDeviceId())
|
||||
.addInt("orderId", request.getOrderId())
|
||||
.addString("timeStart", request.getTimeStart())
|
||||
.addString("timeEnd", request.getTimeEnd());
|
||||
AuvResponse resp = (AuvResponse) doRequest("getOrderList", builder, GetOrderListResponse.class);
|
||||
return wrap(resp, GetOrderListResponse.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AuvResponse<CreatePreOrderResponse> createPreOrder(CreatePreOrderRequest request) {
|
||||
com.auv.locker.model.common.AuvRequestBuilder builder = new com.auv.locker.model.common.AuvRequestBuilder()
|
||||
.addString("deviceId", request.getDeviceId())
|
||||
.addString("shopOrderId", request.getShopOrderId())
|
||||
.addInt("type", request.getType())
|
||||
.addString("expiryTime", request.getExpiryTime())
|
||||
.addString("isWarm", request.getIsWarm())
|
||||
.addString("isLight", request.getIsLight())
|
||||
.addString("isDisinfect", request.getIsDisinfect())
|
||||
.addString("takeCode", request.getTakeCode())
|
||||
.addString("cellId", request.getCellId());
|
||||
AuvResponse resp = (AuvResponse) doRequest("createPreOrder", builder, CreatePreOrderResponse.class);
|
||||
return wrap(resp, CreatePreOrderResponse.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AuvResponse<ChangePreorderToFormalResponse> changePreorderToFormal(ChangePreorderToFormalRequest request) {
|
||||
com.auv.locker.model.common.AuvRequestBuilder builder = new com.auv.locker.model.common.AuvRequestBuilder()
|
||||
.addInt("id", request.getId())
|
||||
.addString("deviceId", request.getDeviceId());
|
||||
AuvResponse resp = (AuvResponse) doRequest("changePreorderToFormal", builder, ChangePreorderToFormalResponse.class);
|
||||
return wrap(resp, ChangePreorderToFormalResponse.class);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private <T> AuvResponse<T> wrap(AuvResponse raw, Class<T> type) {
|
||||
AuvResponse<T> resp = new AuvResponse<>();
|
||||
resp.setCode(raw.getCode());
|
||||
resp.setMsg(raw.getMsg());
|
||||
resp.setSuccess(raw.getSuccess());
|
||||
if (raw.getResultObject() != null && !raw.getResultObject().isNull()) {
|
||||
T result = MAPPER.convertValue(raw.getResultObject(), type);
|
||||
resp.setResultObject(MAPPER.valueToTree(result));
|
||||
}
|
||||
return resp;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private AuvResponse<java.util.List<GetCellListResponse>> wrapList(AuvResponse raw) {
|
||||
AuvResponse<java.util.List<GetCellListResponse>> resp = new AuvResponse<>();
|
||||
resp.setCode(raw.getCode());
|
||||
resp.setMsg(raw.getMsg());
|
||||
resp.setSuccess(raw.getSuccess());
|
||||
if (raw.getResultObject() != null && !raw.getResultObject().isNull()) {
|
||||
java.util.List<GetCellListResponse> list = MAPPER.convertValue(
|
||||
raw.getResultObject(),
|
||||
new com.fasterxml.jackson.core.type.TypeReference<java.util.List<GetCellListResponse>>() {});
|
||||
resp.setResultObject(MAPPER.valueToTree(list));
|
||||
}
|
||||
return resp;
|
||||
}
|
||||
}
|
||||
116
src/test/java/com/auv/locker/AuvClientTest.java
Normal file
116
src/test/java/com/auv/locker/AuvClientTest.java
Normal file
@ -0,0 +1,116 @@
|
||||
package com.auv.locker;
|
||||
|
||||
import com.auv.locker.config.AuvConfig;
|
||||
import com.auv.locker.config.GatewayType;
|
||||
import com.auv.locker.http.HmacMD5Util;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
public class AuvClientTest {
|
||||
|
||||
@Test
|
||||
public void testBuilderBuildsClient() {
|
||||
AuvClient client = AuvClient.builder()
|
||||
.appId("test-app")
|
||||
.secretKey("test-secret")
|
||||
.build();
|
||||
assertNotNull(client);
|
||||
client.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBuilderWithCustomTimeouts() {
|
||||
AuvClient client = AuvClient.builder()
|
||||
.appId("test")
|
||||
.secretKey("test")
|
||||
.connectTimeoutMs(3000)
|
||||
.socketTimeoutMs(15000)
|
||||
.connectionRequestTimeoutMs(8000)
|
||||
.build();
|
||||
assertNotNull(client);
|
||||
client.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBuilderWithCustomBaseUrls() {
|
||||
AuvClient client = AuvClient.builder()
|
||||
.appId("test")
|
||||
.secretKey("test")
|
||||
.storageBaseUrl("http://custom.storage/gateway")
|
||||
.auxBaseUrl("http://custom.aux/api")
|
||||
.build();
|
||||
assertNotNull(client);
|
||||
client.close();
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testBuilderWithoutAppIdThrows() {
|
||||
AuvClient.builder()
|
||||
.secretKey("test")
|
||||
.build();
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testBuilderWithoutSecretKeyThrows() {
|
||||
AuvClient.builder()
|
||||
.appId("test")
|
||||
.build();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAuvConfigDefaultStorageBaseUrl() {
|
||||
AuvConfig config = AuvConfig.builder()
|
||||
.appId("test")
|
||||
.secretKey("test")
|
||||
.build();
|
||||
assertEquals("https://plat.58auv.com/OpenApi", config.getStorageBaseUrl());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAuvConfigDefaultAuxBaseUrl() {
|
||||
AuvConfig config = AuvConfig.builder()
|
||||
.appId("test")
|
||||
.secretKey("test")
|
||||
.build();
|
||||
assertEquals("https://openapi.58auv.com/gateway.do", config.getAuxBaseUrl());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAuvConfigCustomBaseUrl() {
|
||||
AuvConfig config = AuvConfig.builder()
|
||||
.appId("test")
|
||||
.secretKey("test")
|
||||
.customStorageBaseUrl("http://custom.storage/api")
|
||||
.customAuxBaseUrl("http://custom.aux/api")
|
||||
.build();
|
||||
assertEquals("http://custom.storage/api", config.getStorageBaseUrl());
|
||||
assertEquals("http://custom.aux/api", config.getAuxBaseUrl());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGatewayTypeStorage() {
|
||||
assertEquals("plat.58auv.com", GatewayType.STORAGE.getHost());
|
||||
assertEquals("/OpenApi", GatewayType.STORAGE.getPath());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGatewayTypeAux() {
|
||||
assertEquals("openapi.58auv.com", GatewayType.AUX.getHost());
|
||||
assertEquals("/gateway.do", GatewayType.AUX.getPath());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHmacMD5SignWithRealParams() {
|
||||
java.util.TreeMap<String, String> params = new java.util.TreeMap<>();
|
||||
params.put("appId", "66666");
|
||||
params.put("method", "createOrder");
|
||||
params.put("timestamp", "2024-01-01 12:00:00");
|
||||
params.put("version", "1.0");
|
||||
params.put("bizData", "{\"deviceId\":\"12345\"}");
|
||||
String content = HmacMD5Util.buildSignContent(params);
|
||||
String sign = HmacMD5Util.sign(content, "testSecret");
|
||||
assertNotNull(sign);
|
||||
assertEquals(32, sign.length());
|
||||
}
|
||||
}
|
||||
87
src/test/java/com/auv/locker/HmacMD5UtilTest.java
Normal file
87
src/test/java/com/auv/locker/HmacMD5UtilTest.java
Normal file
@ -0,0 +1,87 @@
|
||||
package com.auv.locker;
|
||||
|
||||
import com.auv.locker.http.HmacMD5Util;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.ExpectedException;
|
||||
|
||||
import java.util.TreeMap;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
public class HmacMD5UtilTest {
|
||||
|
||||
@Rule
|
||||
public ExpectedException exceptionRule = ExpectedException.none();
|
||||
|
||||
@Test
|
||||
public void testSignGeneratesHexDigest() {
|
||||
String result = HmacMD5Util.sign("hello", "secret");
|
||||
assertNotNull(result);
|
||||
assertEquals(32, result.length());
|
||||
assertFalse(result.isEmpty());
|
||||
// verify all chars are lowercase hex
|
||||
for (char c : result.toCharArray()) {
|
||||
assertTrue((c >= 'a' && c <= 'f') || (c >= '0' && c <= '9'));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSignDeterministic() {
|
||||
String s1 = HmacMD5Util.sign("hello", "secret");
|
||||
String s2 = HmacMD5Util.sign("hello", "secret");
|
||||
assertEquals(s1, s2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSignDifferentKeyDifferentResult() {
|
||||
String s1 = HmacMD5Util.sign("hello", "secret1");
|
||||
String s2 = HmacMD5Util.sign("hello", "secret2");
|
||||
assertNotEquals(s1, s2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSignDifferentContentDifferentResult() {
|
||||
String s1 = HmacMD5Util.sign("hello", "secret");
|
||||
String s2 = HmacMD5Util.sign("world", "secret");
|
||||
assertNotEquals(s1, s2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBuildSignContent() {
|
||||
TreeMap<String, String> params = new TreeMap<>();
|
||||
params.put("b", "2");
|
||||
params.put("a", "1");
|
||||
params.put("c", "3");
|
||||
String result = HmacMD5Util.buildSignContent(params);
|
||||
assertEquals("a=1&b=2&c=3", result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBuildSignContentWithEmptyMap() {
|
||||
TreeMap<String, String> params = new TreeMap<>();
|
||||
String result = HmacMD5Util.buildSignContent(params);
|
||||
assertEquals("", result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBuildSignContentWithNullValue() {
|
||||
TreeMap<String, String> params = new TreeMap<>();
|
||||
params.put("a", "1");
|
||||
params.put("b", null);
|
||||
String result = HmacMD5Util.buildSignContent(params);
|
||||
assertEquals("a=1&b=null", result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSignWithNullSecretThrows() {
|
||||
exceptionRule.expect(RuntimeException.class);
|
||||
HmacMD5Util.sign("hello", null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSignWithNullContentThrows() {
|
||||
exceptionRule.expect(RuntimeException.class);
|
||||
HmacMD5Util.sign(null, "secret");
|
||||
}
|
||||
}
|
||||
BIN
target/classes/com/auv/locker/AuvClient$1.class
Normal file
BIN
target/classes/com/auv/locker/AuvClient$1.class
Normal file
Binary file not shown.
BIN
target/classes/com/auv/locker/AuvClient$Builder.class
Normal file
BIN
target/classes/com/auv/locker/AuvClient$Builder.class
Normal file
Binary file not shown.
BIN
target/classes/com/auv/locker/AuvClient.class
Normal file
BIN
target/classes/com/auv/locker/AuvClient.class
Normal file
Binary file not shown.
BIN
target/classes/com/auv/locker/config/AuvConfig$1.class
Normal file
BIN
target/classes/com/auv/locker/config/AuvConfig$1.class
Normal file
Binary file not shown.
BIN
target/classes/com/auv/locker/config/AuvConfig$Builder.class
Normal file
BIN
target/classes/com/auv/locker/config/AuvConfig$Builder.class
Normal file
Binary file not shown.
BIN
target/classes/com/auv/locker/config/AuvConfig.class
Normal file
BIN
target/classes/com/auv/locker/config/AuvConfig.class
Normal file
Binary file not shown.
BIN
target/classes/com/auv/locker/config/GatewayType.class
Normal file
BIN
target/classes/com/auv/locker/config/GatewayType.class
Normal file
Binary file not shown.
BIN
target/classes/com/auv/locker/http/AuvHttpClient.class
Normal file
BIN
target/classes/com/auv/locker/http/AuvHttpClient.class
Normal file
Binary file not shown.
BIN
target/classes/com/auv/locker/http/HmacMD5Util.class
Normal file
BIN
target/classes/com/auv/locker/http/HmacMD5Util.class
Normal file
Binary file not shown.
BIN
target/classes/com/auv/locker/model/aux/AuxCellOpResponse.class
Normal file
BIN
target/classes/com/auv/locker/model/aux/AuxCellOpResponse.class
Normal file
Binary file not shown.
Binary file not shown.
BIN
target/classes/com/auv/locker/model/aux/CellOpRequest$1.class
Normal file
BIN
target/classes/com/auv/locker/model/aux/CellOpRequest$1.class
Normal file
Binary file not shown.
Binary file not shown.
BIN
target/classes/com/auv/locker/model/aux/CellOpRequest.class
Normal file
BIN
target/classes/com/auv/locker/model/aux/CellOpRequest.class
Normal file
Binary file not shown.
Binary file not shown.
BIN
target/classes/com/auv/locker/model/aux/CellOpResponse.class
Normal file
BIN
target/classes/com/auv/locker/model/aux/CellOpResponse.class
Normal file
Binary file not shown.
Binary file not shown.
BIN
target/classes/com/auv/locker/model/aux/CellStatusNotify.class
Normal file
BIN
target/classes/com/auv/locker/model/aux/CellStatusNotify.class
Normal file
Binary file not shown.
BIN
target/classes/com/auv/locker/model/aux/CellsOpsRequest$1.class
Normal file
BIN
target/classes/com/auv/locker/model/aux/CellsOpsRequest$1.class
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
target/classes/com/auv/locker/model/aux/CellsOpsRequest.class
Normal file
BIN
target/classes/com/auv/locker/model/aux/CellsOpsRequest.class
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
target/classes/com/auv/locker/model/aux/DeviceStatusNotify.class
Normal file
BIN
target/classes/com/auv/locker/model/aux/DeviceStatusNotify.class
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
target/classes/com/auv/locker/model/common/AuvResponse.class
Normal file
BIN
target/classes/com/auv/locker/model/common/AuvResponse.class
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
target/classes/com/auv/locker/model/storage/AddCellRequest.class
Normal file
BIN
target/classes/com/auv/locker/model/storage/AddCellRequest.class
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user