From c5b6d81de20ad90848071c085655a30732082fe7 Mon Sep 17 00:00:00 2001 From: MTing Date: Tue, 9 Sep 2025 13:35:25 +0800 Subject: [PATCH] fix api post --- .../com/ouxuan/oxface/OXFaceOnlineActivity.java | 66 +++++++++++++-- .../com/ouxuan/oxface/network/NetworkManager.java | 65 ++++++++++++++- .../oxface/network/NetworkStabilityManager.java | 19 ++++- .../ouxuan/oxface/network/api/PadApiService.java | 93 +++++++++++++++++----- .../ouxuan/oxface/network/utils/NetworkUtils.java | 84 +++++++++++++++++-- 5 files changed, 288 insertions(+), 39 deletions(-) diff --git a/app/src/main/java/com/ouxuan/oxface/OXFaceOnlineActivity.java b/app/src/main/java/com/ouxuan/oxface/OXFaceOnlineActivity.java index caea3ad..155b9e8 100644 --- a/app/src/main/java/com/ouxuan/oxface/OXFaceOnlineActivity.java +++ b/app/src/main/java/com/ouxuan/oxface/OXFaceOnlineActivity.java @@ -1711,8 +1711,28 @@ public class OXFaceOnlineActivity extends BaseActivity implements View.OnClickLi resultData.put("v_code", firstItem.getVCode() != null && !firstItem.getVCode().isEmpty() ? firstItem.getVCode().get(0) : ""); resultData.put("order_type", firstItem.getOrderType()); - resultData.put("card_no", firstItem.getInfo() != null ? - (firstItem.getInfo().getUserId() != null ? firstItem.getInfo().getUserId() : "") : ""); + + // 使用辅助方法处理info字段,因为info可能是字符串或对象 + String cardNo = ""; + Object info = firstItem.getInfo(); + if (info != null) { + if (info instanceof String) { + // 如果info是字符串,直接使用 + cardNo = (String) info; + } else if (info instanceof com.ouxuan.oxface.network.api.PadApiService.OrderInfo) { + // 如果info是OrderInfo对象,获取userId + com.ouxuan.oxface.network.api.PadApiService.OrderInfo orderInfo = + (com.ouxuan.oxface.network.api.PadApiService.OrderInfo) info; + cardNo = orderInfo.getUserId() != null ? orderInfo.getUserId() : ""; + } else if (info instanceof com.google.gson.JsonObject) { + // 如果info是JsonObject,尝试获取card_no字段 + com.google.gson.JsonObject jsonObject = (com.google.gson.JsonObject) info; + if (jsonObject.has("card_no")) { + cardNo = jsonObject.get("card_no").getAsString(); + } + } + } + resultData.put("card_no", cardNo); // 模拟跳转到验证结果页面 LogManager.logInfo(TAG, "准备跳转到验证结果页面: " + resultData.toString()); @@ -1751,10 +1771,41 @@ public class OXFaceOnlineActivity extends BaseActivity implements View.OnClickLi * 处理订单查验错误响应 */ private void handleCheckOrderError(int errorCode, String errorMessage, int type) { - LogManager.logError(TAG, "订单查验失败,类型: " + type + ", 错误: " + errorMessage); + LogManager.logError(TAG, "订单查验失败,类型: " + type + ", 错误码: " + errorCode + ", 错误信息: " + errorMessage); + + // 当人脸验证返回303错误码时,不显示任何提示 + if (type == 2 && errorCode == 303) { + LogManager.logInfo(TAG, "人脸验证返回303,不显示提示"); + return; + } + + // 当服务器有正确的返回时,如果code不为0,应该显示服务器返回的message,而不是使用自定义的错误信息 + String displayMessage = errorMessage; + + // 只有在错误信息为空或null时,才使用默认的错误信息 + if (errorMessage == null || errorMessage.isEmpty()) { + // 如果没有错误信息,根据错误码显示默认信息 + switch (errorCode) { + case 404: + displayMessage = "请求的资源未找到"; + break; + case 500: + displayMessage = "服务器内部错误"; + break; + case 401: + displayMessage = "认证失败,请重新登录"; + break; + case 403: + displayMessage = "权限不足,无法访问"; + break; + default: + displayMessage = "请求失败,错误码: " + errorCode; + break; + } + } if (type == 4) { // 扫码器验证 - showToast(errorMessage != null && !errorMessage.isEmpty() ? errorMessage : "核销码不可用!"); + showToast(displayMessage != null && !displayMessage.isEmpty() ? displayMessage : "核销码不可用!"); // 模拟返回上一页 LogManager.logInfo(TAG, "扫码器验证失败,准备返回上一页"); @@ -1762,7 +1813,7 @@ public class OXFaceOnlineActivity extends BaseActivity implements View.OnClickLi } else if (type == 3 && "抱歉! 暂无可核销订单".equals(errorMessage)) { // clearAllTimer(); // 需要实现此方法 - showToast(errorMessage); + showToast(displayMessage); // 准备订单核销选择页信息 java.util.Map queryData = new java.util.HashMap<>(); @@ -1774,9 +1825,10 @@ public class OXFaceOnlineActivity extends BaseActivity implements View.OnClickLi // 这里需要实现实际的页面跳转逻辑 } else if (type == 1) { // 验证码验证 - showToast(errorMessage != null && !errorMessage.isEmpty() ? errorMessage : "验证失败"); + showToast(displayMessage != null && !displayMessage.isEmpty() ? displayMessage : "验证失败"); } else { - showToast("验证失败: " + errorMessage); + // 对于其他人脸验证等类型,显示具体的错误信息而不是"网络请求异常" + showToast(displayMessage != null && !displayMessage.isEmpty() ? displayMessage : "验证失败"); } } diff --git a/app/src/main/java/com/ouxuan/oxface/network/NetworkManager.java b/app/src/main/java/com/ouxuan/oxface/network/NetworkManager.java index b1cc97d..4af9c16 100644 --- a/app/src/main/java/com/ouxuan/oxface/network/NetworkManager.java +++ b/app/src/main/java/com/ouxuan/oxface/network/NetworkManager.java @@ -222,14 +222,39 @@ public class NetworkManager { if (apiResponse.isSuccess()) { callback.onSuccess(apiResponse.getData()); } else { + // 当服务器有正确的返回时,如果code不为0,应该显示服务器返回的message,而不是使用自定义的错误信息 callback.onError(apiResponse.getCode(), apiResponse.getMessage()); } callback.onComplete(); }); } else { - // HTTP错误 + // 尝试解析响应体中的JSON数据,即使HTTP状态码不是2xx + try { + ApiResponse apiResponse = gson.fromJson(responseBody, ApiResponse.class); + if (apiResponse != null) { + // 如果能成功解析API响应,根据code值处理 + mainHandler.post(() -> { + if (apiResponse.isSuccess()) { + callback.onSuccess(apiResponse.getData()); + } else { + // 当服务器有正确的返回时,如果code不为0,应该显示服务器返回的message + callback.onError(apiResponse.getCode(), apiResponse.getMessage()); + } + callback.onComplete(); + }); + return; + } + } catch (Exception parseException) { + // JSON解析失败,继续使用HTTP错误处理 + LogManager.logWarning(TAG, "无法解析响应体为API响应格式: " + parseException.getMessage()); + } + + // HTTP错误,根据状态码生成合适的错误信息 + String errorMessage = getHttpErrorMessage(response.code()); + LogManager.logError(TAG, "HTTP Error: " + response.code() + " - " + errorMessage + + ", URL: " + request.url()); mainHandler.post(() -> { - callback.onError(response.code(), "HTTP Error: " + response.message()); + callback.onError(response.code(), errorMessage); callback.onComplete(); }); } @@ -245,8 +270,12 @@ public class NetworkManager { @Override public void onFailure(Call call, java.io.IOException e) { - // 网络请求失败 - android.util.Log.e(TAG, "网络请求失败: " + e.getMessage(), e); + // 网络请求失败,显示具体的错误信息而不是笼统的"网络请求异常" + String errorMessage = e.getMessage(); + if (errorMessage == null || errorMessage.isEmpty()) { + errorMessage = "网络请求失败"; + } + android.util.Log.e(TAG, "网络请求失败: " + errorMessage + ", URL: " + call.request().url(), e); mainHandler.post(() -> { callback.onException(e); callback.onComplete(); @@ -256,6 +285,34 @@ public class NetworkManager { } /** + * 根据HTTP状态码获取错误信息 + * @param httpCode HTTP状态码 + * @return 错误信息 + */ + private String getHttpErrorMessage(int httpCode) { + switch (httpCode) { + case 400: + return "请求参数错误"; + case 401: + return "未授权访问"; + case 403: + return "禁止访问"; + case 404: + return "请求的资源未找到"; + case 500: + return "服务器内部错误"; + case 502: + return "网关错误"; + case 503: + return "服务暂时不可用"; + case 504: + return "网关超时"; + default: + return "HTTP错误: " + httpCode; + } + } + + /** * 处理API响应中的extension字段 * @param apiResponse API响应对象 * @param request 请求对象 diff --git a/app/src/main/java/com/ouxuan/oxface/network/NetworkStabilityManager.java b/app/src/main/java/com/ouxuan/oxface/network/NetworkStabilityManager.java index 06de9f5..b964b12 100644 --- a/app/src/main/java/com/ouxuan/oxface/network/NetworkStabilityManager.java +++ b/app/src/main/java/com/ouxuan/oxface/network/NetworkStabilityManager.java @@ -252,12 +252,22 @@ public class NetworkStabilityManager { throw new IOException("重试被中断", e); } } else { + // 对于4xx错误,不进行重试,直接返回响应 return response; } } catch (IOException e) { lastException = e; + // 对于某些特定的网络错误(如stream was reset: CANCEL),不进行重试 + String errorMessage = e.getMessage(); + if (errorMessage != null && (errorMessage.contains("stream was reset: CANCEL") || + errorMessage.contains("Canceled"))) { + Log.w(TAG, "遇到不可重试的网络错误: " + errorMessage); + // 抛出原始异常,不进行重试 + throw e; + } + if (retryCount < maxRetryCount) { Log.w(TAG, "网络请求失败,准备重试 " + (retryCount + 1) + ": " + e.getMessage()); @@ -272,10 +282,15 @@ public class NetworkStabilityManager { } } - // 所有重试都失败了 + // 所有重试都失败了,抛出最后一个异常,确保具体的错误信息能传递给调用者 Log.e(TAG, "网络请求重试 " + maxRetryCount + " 次后仍然失败"); if (lastException != null) { - throw lastException; + // 添加重试次数信息到异常消息中 + String errorMessage = lastException.getMessage(); + if (errorMessage == null) { + errorMessage = "未知错误"; + } + throw new IOException("网络请求重试 " + maxRetryCount + " 次后仍然失败: " + errorMessage, lastException); } else { return response; } diff --git a/app/src/main/java/com/ouxuan/oxface/network/api/PadApiService.java b/app/src/main/java/com/ouxuan/oxface/network/api/PadApiService.java index 9a87e12..f882742 100644 --- a/app/src/main/java/com/ouxuan/oxface/network/api/PadApiService.java +++ b/app/src/main/java/com/ouxuan/oxface/network/api/PadApiService.java @@ -66,24 +66,11 @@ public interface PadApiService { /** * 订单列表接口 (增强版,支持多种验证类型) * 对应旧接口: /v3/pad/checkOrder - * @param token 访问令牌(必需) - * @param type 验证类型 1验证码验证 2人脸验证 3扫码验证 4扫码器验证 - * @param hardwareId 硬件ID(必需) - * @param vCode 验证码(type=1时必需) - * @param faceBase64 人脸base64数据(type=2时必需) - * @param checkType 检查类型(type=2时必需) - * @param decryptText 解密文本(type=4时必需) + * @param request 订单查询请求体 * @return 订单列表响应 */ - @GET("v3/pad/checkOrder") - Call> checkOrder( - @Query("token") String token, - @Query("type") int type, - @Query("hardware_id") int hardwareId, - @Query("v_code") String vCode, - @Query("face_base64") String faceBase64, - @Query("check_type") String checkType, - @Query("decrypt_text") String decryptText); + @POST("v3/pad/checkOrder") + Call> checkOrder(@Body CheckOrderRequest request); /** * 订单列表接口 @@ -93,7 +80,7 @@ public interface PadApiService { * @param pageSize 每页数量(可选) * @return 订单列表响应 */ - @GET("v3/pad/checkOrder") + @POST("v3/pad/checkOrder") Call> checkOrder(@Query("token") String token, @Query("page") Integer page, @Query("page_size") Integer pageSize); @@ -1056,7 +1043,7 @@ public interface PadApiService { private String orderType; // 订单类型 @SerializedName("info") - private OrderInfo info; // 订单信息 + private Object info; // 订单信息(可能是字符串或对象) // Getters and Setters public String getOrderNo() { return orderNo; } @@ -1068,8 +1055,26 @@ public interface PadApiService { public String getOrderType() { return orderType; } public void setOrderType(String orderType) { this.orderType = orderType; } - public OrderInfo getInfo() { return info; } - public void setInfo(OrderInfo info) { this.info = info; } + public Object getInfo() { return info; } + public void setInfo(Object info) { this.info = info; } + + // 辅助方法,用于获取字符串类型的info + public String getInfoAsString() { + if (info instanceof String) { + return (String) info; + } else { + return info != null ? info.toString() : ""; + } + } + + // 辅助方法,用于获取对象类型的info(需要进一步解析) + public com.google.gson.JsonObject getInfoAsJsonObject() { + if (info instanceof com.google.gson.JsonObject) { + return (com.google.gson.JsonObject) info; + } else { + return null; + } + } } /** @@ -1127,6 +1132,54 @@ public interface PadApiService { } /** + * 订单查询请求模型 + */ + public static class CheckOrderRequest { + @SerializedName("token") + private String token; // 访问令牌 + + @SerializedName("type") + private int type; // 验证类型 1验证码验证 2人脸验证 3扫码验证 4扫码器验证 + + @SerializedName("hardware_id") + private int hardwareId; // 硬件ID + + @SerializedName("v_code") + private String vCode; // 验证码(type=1时必需) + + @SerializedName("face_base64") + private String faceBase64; // 人脸base64数据(type=2时必需) + + @SerializedName("check_type") + private String checkType; // 检查类型(type=2时必需) + + @SerializedName("decrypt_text") + private String decryptText; // 解密文本(type=4时必需) + + // Getters and Setters + public String getToken() { return token; } + public void setToken(String token) { this.token = token; } + + public int getType() { return type; } + public void setType(int type) { this.type = type; } + + public int getHardwareId() { return hardwareId; } + public void setHardwareId(int hardwareId) { this.hardwareId = hardwareId; } + + public String getVCode() { return vCode; } + public void setVCode(String vCode) { this.vCode = vCode; } + + public String getFaceBase64() { return faceBase64; } + public void setFaceBase64(String faceBase64) { this.faceBase64 = faceBase64; } + + public String getCheckType() { return checkType; } + public void setCheckType(String checkType) { this.checkType = checkType; } + + public String getDecryptText() { return decryptText; } + public void setDecryptText(String decryptText) { this.decryptText = decryptText; } + } + + /** * 小程序码响应模型 */ public static class MiniQrcodeResponse { diff --git a/app/src/main/java/com/ouxuan/oxface/network/utils/NetworkUtils.java b/app/src/main/java/com/ouxuan/oxface/network/utils/NetworkUtils.java index cd768b9..0df9b93 100644 --- a/app/src/main/java/com/ouxuan/oxface/network/utils/NetworkUtils.java +++ b/app/src/main/java/com/ouxuan/oxface/network/utils/NetworkUtils.java @@ -557,9 +557,18 @@ public class NetworkUtils { return; } + // 创建请求体 + PadApiService.CheckOrderRequest request = new PadApiService.CheckOrderRequest(); + request.setToken(token); + request.setType(type); + request.setHardwareId(hardwareId); + request.setVCode(vCode); + request.setFaceBase64(faceBase64); + request.setCheckType(checkType); + request.setDecryptText(decryptText); + callback.onStart(); - padApiService.checkOrder(token, type, hardwareId, vCode, faceBase64, checkType, decryptText) - .enqueue(new Callback>() { + padApiService.checkOrder(request).enqueue(new Callback>() { @Override public void onResponse(Call> call, Response> response) { @@ -570,12 +579,40 @@ public class NetworkUtils { if (apiResponse.isSuccess()) { callback.onSuccess(apiResponse.getData()); } else { - // 打印详细的错误日志 - logApiError("checkOrder", apiResponse.getCode(), apiResponse.getMessage()); + // 当服务器有正确的返回时,如果code不为0,应该显示服务器返回的message,而不是使用自定义的错误信息 callback.onError(apiResponse.getCode(), apiResponse.getMessage()); } + } else if (response.errorBody() != null) { + // 尝试解析错误响应体中的JSON数据 + try { + String errorBody = response.errorBody().string(); + ApiResponse apiResponse = + new com.google.gson.Gson().fromJson(errorBody, ApiResponse.class); + if (apiResponse != null) { + // 如果能成功解析API响应,根据code值处理 + if (apiResponse.isSuccess()) { + callback.onSuccess(apiResponse.getData()); + } else { + // 当服务器有正确的返回时,如果code不为0,应该显示服务器返回的message + callback.onError(apiResponse.getCode(), apiResponse.getMessage()); + } + } else { + // 无法解析为API响应格式,使用HTTP错误状态码 + String errorMessage = getHttpErrorMessage(response.code()); + android.util.Log.e("NetworkUtils", "HTTP Error: " + response.code() + " - " + errorMessage); + callback.onError(response.code(), errorMessage); + } + } catch (Exception parseException) { + // JSON解析失败,使用HTTP错误状态码 + String errorMessage = getHttpErrorMessage(response.code()); + android.util.Log.e("NetworkUtils", "HTTP Error: " + response.code() + " - " + errorMessage); + callback.onError(response.code(), errorMessage); + } } else { - callback.onError(response.code(), "请求失败: " + response.message()); + // 处理HTTP错误状态码,如404、500等 + String errorMessage = getHttpErrorMessage(response.code()); + android.util.Log.e("NetworkUtils", "HTTP Error: " + response.code() + " - " + errorMessage); + callback.onError(response.code(), errorMessage); } } catch (Exception e) { callback.onException(e); @@ -586,13 +623,48 @@ public class NetworkUtils { @Override public void onFailure(Call> call, Throwable t) { - callback.onException(t); + // 网络请求失败,记录详细日志并显示具体的错误信息 + android.util.Log.e("NetworkUtils", "网络请求失败: " + t.getMessage(), t); + // 显示具体的网络错误信息而不是笼统的"网络请求异常" + String errorMessage = t.getMessage(); + if (errorMessage == null || errorMessage.isEmpty()) { + errorMessage = "网络请求失败"; + } + callback.onError(-1, "网络请求异常: " + errorMessage); callback.onComplete(); } }); } /** + * 根据HTTP状态码获取错误信息 + * @param httpCode HTTP状态码 + * @return 错误信息 + */ + private static String getHttpErrorMessage(int httpCode) { + switch (httpCode) { + case 400: + return "请求参数错误"; + case 401: + return "未授权访问"; + case 403: + return "禁止访问"; + case 404: + return "请求的资源未找到"; + case 500: + return "服务器内部错误"; + case 502: + return "网关错误"; + case 503: + return "服务暂时不可用"; + case 504: + return "网关超时"; + default: + return "HTTP错误: " + httpCode; + } + } + + /** * 获取订单列表 * @param token 访问令牌(必需) * @param page 页码(可选)