From 2c401bad77285b33a7e1956e8e698c713160c1d8 Mon Sep 17 00:00:00 2001 From: MTing Date: Thu, 4 Sep 2025 14:30:50 +0800 Subject: [PATCH] updata miniQr into face detect view --- .../main/java/com/ouxuan/oxface/MainActivity.java | 62 ++++++- .../com/ouxuan/oxface/OXFaceOnlineActivity.java | 104 +++++++++++ .../oxface/data/DeviceSelectDataManager.java | 83 +++++++++ .../ouxuan/oxface/network/api/PadApiService.java | 197 +++++++++++++++++++++ .../ouxuan/oxface/network/utils/NetworkUtils.java | 166 ++++++++++++++++- .../idl/face/main/finance/utils/BitmapUtils.java | 48 ++++- 6 files changed, 650 insertions(+), 10 deletions(-) diff --git a/app/src/main/java/com/ouxuan/oxface/MainActivity.java b/app/src/main/java/com/ouxuan/oxface/MainActivity.java index 7d853d2..0874625 100644 --- a/app/src/main/java/com/ouxuan/oxface/MainActivity.java +++ b/app/src/main/java/com/ouxuan/oxface/MainActivity.java @@ -741,8 +741,8 @@ public class MainActivity extends AppCompatActivity { android.util.Log.d("MainActivity", "API Message: " + deviceSelectDataManager.getApiResponseMessage()); android.util.Log.d("MainActivity", "==============================="); - // 新增:检查并初始化人脸SDK - initializeFaceSDKIfNeeded(dialog, buttonEnter, buttonText, originalText); + // 新增:调用获取小程序码接口 + fetchAndSaveMiniQrcode(token, hardwareId, dialog, buttonEnter, buttonText, originalText); } @Override @@ -1187,6 +1187,64 @@ public class MainActivity extends AppCompatActivity { LogManager.logOperation("MainActivity", "应用退出,停止保持活跃功能"); } } + + /** + * 获取并保存小程序码 + * @param token 访问令牌 + * @param hardwareId 硬件ID + * @param dialog 弹框实例 + * @param buttonEnter 进入按钮 + * @param buttonText 按钮文字视图 + * @param originalText 原始按钮文字 + */ + private void fetchAndSaveMiniQrcode(String token, int hardwareId, Dialog dialog, View buttonEnter, TextView buttonText, String originalText) { + // 调用获取小程序码接口 + NetworkUtils.miniQrcode(token, hardwareId, new NetworkCallback() { + @Override + public void onStart() { + // 开始请求 + android.util.Log.d("MainActivity", "开始请求小程序码"); + } + + @Override + public void onSuccess(PadApiService.MiniQrcodeResponse data) { + // 获取小程序码成功 + if (data != null && data.getQrcodeUrl() != null && !data.getQrcodeUrl().isEmpty()) { + // 保存小程序码链接到本地 + deviceSelectDataManager.saveMiniQrcodeUrl(data.getQrcodeUrl()); + + android.util.Log.d("MainActivity", "小程序码获取并保存成功: " + data.getQrcodeUrl()); + LogManager.logOperation("MainActivity", "小程序码获取并保存成功"); + + // 添加调试日志,验证保存是否成功 + String savedUrl = deviceSelectDataManager.getMiniQrcodeUrl(); + boolean hasUrl = deviceSelectDataManager.hasMiniQrcodeUrl(); + android.util.Log.d("MainActivity", "验证保存结果 - 是否存在: " + hasUrl + ", 保存的URL: " + savedUrl); + } else { + android.util.Log.w("MainActivity", "获取到的小程序码数据为空或URL为空"); + LogManager.logWarning("MainActivity", "获取到的小程序码数据为空或URL为空"); + } + + // 继续执行后续流程 + initializeFaceSDKIfNeeded(dialog, buttonEnter, buttonText, originalText); + } + + @Override + public void onError(int errorCode, String errorMessage) { + // 获取小程序码失败 + android.util.Log.e("MainActivity", "获取小程序码失败 - 错误码: " + errorCode + ", 错误信息: " + errorMessage); + LogManager.logError("MainActivity", "获取小程序码失败 - 错误码: " + errorCode + ", 错误信息: " + errorMessage); + + // 即使获取小程序码失败,也继续执行后续流程 + initializeFaceSDKIfNeeded(dialog, buttonEnter, buttonText, originalText); + } + + @Override + public void onComplete() { + // 请求完成 + } + }); + } /** * 设置日志路径调试功能(长按登录按钮) diff --git a/app/src/main/java/com/ouxuan/oxface/OXFaceOnlineActivity.java b/app/src/main/java/com/ouxuan/oxface/OXFaceOnlineActivity.java index 7d1ce0a..106c50c 100644 --- a/app/src/main/java/com/ouxuan/oxface/OXFaceOnlineActivity.java +++ b/app/src/main/java/com/ouxuan/oxface/OXFaceOnlineActivity.java @@ -161,6 +161,9 @@ public class OXFaceOnlineActivity extends BaseActivity implements View.OnClickLi protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_oxface_online); + + android.util.Log.d(TAG, "onCreate方法开始执行"); + LogManager.logInfo(TAG, "OXFaceOnlineActivity onCreate开始"); mContext = this; initView(); @@ -183,7 +186,13 @@ public class OXFaceOnlineActivity extends BaseActivity implements View.OnClickLi // 启动内存优化周期性任务 startMemoryOptimizationTask(); + // 更新小程序码 + android.util.Log.d(TAG, "准备调用updateMiniQrcode方法"); + updateMiniQrcode(); + android.util.Log.d(TAG, "updateMiniQrcode方法调用完成"); + LogManager.logInfo(TAG, "OXFaceOnlineActivity onCreate"); + android.util.Log.d(TAG, "onCreate方法执行结束"); } /** @@ -191,6 +200,7 @@ public class OXFaceOnlineActivity extends BaseActivity implements View.OnClickLi */ private void initView() { LogManager.logInfo(TAG, "初始化界面视图"); + android.util.Log.d(TAG, "初始化界面视图开始"); // 获取整个布局 relativeLayout = findViewById(R.id.all_relative); @@ -241,6 +251,12 @@ public class OXFaceOnlineActivity extends BaseActivity implements View.OnClickLi btnVerificationCode = findViewById(R.id.btn_verification_code); btnScannerDoor = findViewById(R.id.btn_scanner_door); + // 添加调试日志,检查控件是否正确初始化 + android.util.Log.d(TAG, "imgMiniProgramCode初始化: " + (imgMiniProgramCode != null)); + android.util.Log.d(TAG, "imgScanDoorQRCode初始化: " + (imgScanDoorQRCode != null)); + android.util.Log.d(TAG, "btnVerificationCode初始化: " + (btnVerificationCode != null)); + android.util.Log.d(TAG, "btnScannerDoor初始化: " + (btnScannerDoor != null)); + // 设置二维码区域控件的点击事件 if (imgMiniProgramCode != null) { imgMiniProgramCode.setOnClickListener(this); @@ -289,6 +305,7 @@ public class OXFaceOnlineActivity extends BaseActivity implements View.OnClickLi // 初始化测试弹窗 initTestPopWindow(); + android.util.Log.d(TAG, "初始化界面视图结束"); } /** @@ -1149,6 +1166,93 @@ public class OXFaceOnlineActivity extends BaseActivity implements View.OnClickLi } /** + * 更新小程序码显示 + */ + private void updateMiniQrcode() { + android.util.Log.d(TAG, "updateMiniQrcode方法开始执行"); + LogManager.logInfo(TAG, "开始更新小程序码"); + android.util.Log.d(TAG, "开始更新小程序码"); // 添加系统日志 + try { + // 获取DeviceSelectDataManager实例 + DeviceSelectDataManager deviceSelectDataManager = DeviceSelectDataManager.getInstance(this); + LogManager.logInfo(TAG, "DeviceSelectDataManager实例获取成功"); + android.util.Log.d(TAG, "DeviceSelectDataManager实例获取成功"); + + // 检查是否存在小程序码链接 + LogManager.logInfo(TAG, "检查小程序码链接是否存在"); + android.util.Log.d(TAG, "检查小程序码链接是否存在"); + boolean hasQrcode = deviceSelectDataManager.hasMiniQrcodeUrl(); + LogManager.logInfo(TAG, "小程序码链接是否存在: " + hasQrcode); + android.util.Log.d(TAG, "小程序码链接是否存在: " + hasQrcode); + + if (hasQrcode) { + String base64Qrcode = deviceSelectDataManager.getMiniQrcodeUrl(); + LogManager.logInfo(TAG, "获取到小程序码数据,长度: " + (base64Qrcode != null ? base64Qrcode.length() : 0)); + android.util.Log.d(TAG, "获取到小程序码数据,长度: " + (base64Qrcode != null ? base64Qrcode.length() : 0)); + + // 检查base64数据是否有效 + if (base64Qrcode != null && !base64Qrcode.isEmpty()) { + LogManager.logInfo(TAG, "小程序码数据不为空,准备更新UI"); + android.util.Log.d(TAG, "小程序码数据不为空,准备更新UI"); + + // 在主线程中更新UI + runOnUiThread(new Runnable() { + @Override + public void run() { + try { + LogManager.logInfo(TAG, "在主线程中更新小程序码UI"); + android.util.Log.d(TAG, "在主线程中更新小程序码UI"); + // 将base64字符串转换为Bitmap并显示在扫码开门按钮区域 + if (imgScanDoorQRCode != null) { + LogManager.logInfo(TAG, "开始转换base64到Bitmap"); + android.util.Log.d(TAG, "开始转换base64到Bitmap"); + // 先检查base64字符串是否需要解码 + String decodedBase64 = base64Qrcode; + // 如果是data URL格式,提取base64部分 + if (base64Qrcode.startsWith("data:image")) { + int commaIndex = base64Qrcode.indexOf(','); + if (commaIndex > 0) { + decodedBase64 = base64Qrcode.substring(commaIndex + 1); + LogManager.logInfo(TAG, "提取到的base64数据长度: " + decodedBase64.length()); + android.util.Log.d(TAG, "提取到的base64数据长度: " + decodedBase64.length()); + } + } + + Bitmap qrcodeBitmap = BitmapUtils.base64ToBitmap(decodedBase64); + if (qrcodeBitmap != null) { + imgScanDoorQRCode.setImageBitmap(qrcodeBitmap); + LogManager.logInfo(TAG, "小程序码更新成功"); + android.util.Log.d(TAG, "小程序码更新成功"); + } else { + LogManager.logWarning(TAG, "小程序码Bitmap转换失败"); + android.util.Log.w(TAG, "小程序码Bitmap转换失败"); + } + } else { + LogManager.logWarning(TAG, "imgScanDoorQRCode为null"); + android.util.Log.w(TAG, "imgScanDoorQRCode为null"); + } + } catch (Exception e) { + LogManager.logError(TAG, "更新小程序码时发生异常: " + e.getMessage(), e); + android.util.Log.e(TAG, "更新小程序码时发生异常", e); + } + } + }); + } else { + LogManager.logWarning(TAG, "小程序码数据为空"); + android.util.Log.w(TAG, "小程序码数据为空"); + } + } else { + LogManager.logWarning(TAG, "未找到小程序码链接"); + android.util.Log.w(TAG, "未找到小程序码链接"); + } + } catch (Exception e) { + LogManager.logError(TAG, "获取小程序码时发生异常: " + e.getMessage(), e); + android.util.Log.e(TAG, "获取小程序码时发生异常", e); + } + android.util.Log.d(TAG, "updateMiniQrcode方法执行结束"); + } + + /** * 获取并显示店铺名称 */ private void loadAndDisplayStoreName() { diff --git a/app/src/main/java/com/ouxuan/oxface/data/DeviceSelectDataManager.java b/app/src/main/java/com/ouxuan/oxface/data/DeviceSelectDataManager.java index 5f8af34..5d3f56a 100644 --- a/app/src/main/java/com/ouxuan/oxface/data/DeviceSelectDataManager.java +++ b/app/src/main/java/com/ouxuan/oxface/data/DeviceSelectDataManager.java @@ -35,6 +35,9 @@ public class DeviceSelectDataManager { // 新增:人脸识别许可证存储常量 private static final String KEY_FACE_LICENSE = "face_license"; + // 新增:小程序码链接存储常量 + private static final String KEY_MINI_QRCODE_URL = "mini_qrcode_url"; + private SharedPreferences preferences; private Gson gson; @@ -47,6 +50,8 @@ public class DeviceSelectDataManager { private boolean isDeviceSelected = false; // 新增:人脸识别许可证内存缓存 private String faceLicense; + // 新增:小程序码链接内存缓存 + private String miniQrcodeUrl; // API响应存储 private int apiResponseCode; @@ -135,6 +140,11 @@ public class DeviceSelectDataManager { editor.putString(KEY_FACE_LICENSE, faceLicense); } + // 新增:保存小程序码链接(如果已存在) + if (miniQrcodeUrl != null && !miniQrcodeUrl.isEmpty()) { + editor.putString(KEY_MINI_QRCODE_URL, miniQrcodeUrl); + } + editor.apply(); Log.d(TAG, "完整API响应数据保存成功"); @@ -252,6 +262,8 @@ public class DeviceSelectDataManager { this.apiFullResponse = null; // 新增:清除人脸识别许可证内存缓存 this.faceLicense = null; + // 新增:清除小程序码链接内存缓存 + this.miniQrcodeUrl = null; // 清除持久化存储 SharedPreferences.Editor editor = preferences.edit(); @@ -272,6 +284,9 @@ public class DeviceSelectDataManager { // 新增:清除人脸识别许可证持久化存储 editor.remove(KEY_FACE_LICENSE); + // 新增:清除小程序码链接持久化存储 + editor.remove(KEY_MINI_QRCODE_URL); + editor.apply(); Log.d(TAG, "设备选择数据已清除"); @@ -312,6 +327,9 @@ public class DeviceSelectDataManager { // 新增:加载人脸识别许可证 faceLicense = preferences.getString(KEY_FACE_LICENSE, null); + // 新增:加载小程序码链接 + miniQrcodeUrl = preferences.getString(KEY_MINI_QRCODE_URL, null); + if (apiResponseCode > 0 || (apiResponseDataJson != null && !apiResponseDataJson.isEmpty())) { Log.d(TAG, "从本地存储恢复API响应数据成功"); } @@ -401,6 +419,11 @@ public class DeviceSelectDataManager { editor.putString(KEY_FACE_LICENSE, faceLicense); } + // 新增:保存小程序码链接(如果已存在) + if (miniQrcodeUrl != null && !miniQrcodeUrl.isEmpty()) { + editor.putString(KEY_MINI_QRCODE_URL, miniQrcodeUrl); + } + editor.apply(); Log.d(TAG, "设备选择数据保存成功"); @@ -570,4 +593,64 @@ public class DeviceSelectDataManager { String license = getFaceLicense(); return license != null && !license.isEmpty(); } + + /** + * 保存小程序码链接 + * @param qrcodeUrl 小程序码链接 + */ + public void saveMiniQrcodeUrl(String qrcodeUrl) { + android.util.Log.d(TAG, "开始保存小程序码链接: " + qrcodeUrl); + + if (qrcodeUrl == null || qrcodeUrl.isEmpty()) { + Log.w(TAG, "小程序码链接为空,无法保存"); + android.util.Log.w(TAG, "小程序码链接为空,无法保存"); + return; + } + + try { + // 保存到内存缓存 + this.miniQrcodeUrl = qrcodeUrl; + + // 保存到持久化存储 + SharedPreferences.Editor editor = preferences.edit(); + editor.putString(KEY_MINI_QRCODE_URL, qrcodeUrl); + boolean commitResult = editor.commit(); // 使用commit确保立即保存 + + android.util.Log.d(TAG, "小程序码链接保存结果: " + commitResult); + + Log.d(TAG, "小程序码链接保存成功: " + qrcodeUrl); + android.util.Log.d(TAG, "小程序码链接保存成功: " + qrcodeUrl); + } catch (Exception e) { + Log.e(TAG, "保存小程序码链接失败: " + e.getMessage(), e); + android.util.Log.e(TAG, "保存小程序码链接失败: " + e.getMessage(), e); + } + } + + /** + * 获取小程序码链接 + * @return 小程序码链接 + */ + public String getMiniQrcodeUrl() { + android.util.Log.d(TAG, "开始获取小程序码链接"); + + if (miniQrcodeUrl != null) { + android.util.Log.d(TAG, "从内存缓存获取小程序码链接: " + miniQrcodeUrl); + return miniQrcodeUrl; + } + + String url = preferences.getString(KEY_MINI_QRCODE_URL, ""); + android.util.Log.d(TAG, "从持久化存储获取小程序码链接: " + url); + return url; + } + + /** + * 检查是否存在有效的小程序码链接 + * @return true如果存在有效的小程序码链接 + */ + public boolean hasMiniQrcodeUrl() { + String url = getMiniQrcodeUrl(); + boolean result = url != null && !url.isEmpty(); + android.util.Log.d(TAG, "检查是否存在小程序码链接: " + result + ", URL: " + url); + return result; + } } \ No newline at end of file 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 c8262ad..a3e05c2 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 @@ -3,6 +3,7 @@ package com.ouxuan.oxface.network.api; import com.google.gson.annotations.SerializedName; import com.ouxuan.oxface.network.model.ApiResponse; +import okhttp3.ResponseBody; import retrofit2.Call; import retrofit2.http.Body; import retrofit2.http.GET; @@ -62,6 +63,39 @@ public interface PadApiService { @POST("v3/pad/select") Call> padSelect(@Body PadSelectRequest selectRequest); + /** + * 订单列表接口 + * 对应旧接口: /v3/pad/checkOrder + * @param token 访问令牌(必需) + * @param page 页码(可选) + * @param pageSize 每页数量(可选) + * @return 订单列表响应 + */ + @GET("v3/pad/checkOrder") + Call> checkOrder(@Query("token") String token, + @Query("page") Integer page, + @Query("page_size") Integer pageSize); + + /** + * 核销订单接口 + * 对应旧接口: /v3/pad/verifyOrder + * @param verifyRequest 核销订单请求体 + * @return 核销订单响应 + */ + @POST("v3/pad/verifyOrder") + Call> verifyOrder(@Body VerifyOrderRequest verifyRequest); + + /** + * 获取小程序码接口 + * 对应旧接口: /v3/pad/miniQrcode + * @param token 访问令牌(必需) + * @param hardwareId 硬件ID(必需) + * @return 小程序码响应 + */ + @GET("v3/pad/miniQrcode") + Call miniQrcode(@Query("token") String token, + @Query("hardware_id") int hardwareId); + // ==================== 请求和响应数据模型 ==================== /** @@ -657,4 +691,167 @@ public interface PadApiService { public String getGateName() { return gateName; } public void setGateName(String gateName) { this.gateName = gateName; } } + + /** + * 订单列表响应模型 + */ + public static class CheckOrderResponse { + @SerializedName("orders") + private java.util.List orders; // 订单列表 + + @SerializedName("total") + private int total; // 总数 + + @SerializedName("page") + private int page; // 当前页 + + @SerializedName("page_size") + private int pageSize; // 每页数量 + + // Getters and Setters + public java.util.List getOrders() { return orders; } + public void setOrders(java.util.List orders) { this.orders = orders; } + + public int getTotal() { return total; } + public void setTotal(int total) { this.total = total; } + + public int getPage() { return page; } + public void setPage(int page) { this.page = page; } + + public int getPageSize() { return pageSize; } + public void setPageSize(int pageSize) { this.pageSize = pageSize; } + } + + /** + * 订单信息模型 + */ + public static class OrderInfo { + @SerializedName("order_id") + private String orderId; // 订单ID + + @SerializedName("order_no") + private String orderNo; // 订单编号 + + @SerializedName("user_id") + private String userId; // 用户ID + + @SerializedName("user_name") + private String userName; // 用户名 + + @SerializedName("product_name") + private String productName; // 产品名称 + + @SerializedName("amount") + private double amount; // 金额 + + @SerializedName("status") + private String status; // 状态 + + @SerializedName("create_time") + private String createTime; // 创建时间 + + @SerializedName("update_time") + private String updateTime; // 更新时间 + + // Getters and Setters + public String getOrderId() { return orderId; } + public void setOrderId(String orderId) { this.orderId = orderId; } + + public String getOrderNo() { return orderNo; } + public void setOrderNo(String orderNo) { this.orderNo = orderNo; } + + public String getUserId() { return userId; } + public void setUserId(String userId) { this.userId = userId; } + + public String getUserName() { return userName; } + public void setUserName(String userName) { this.userName = userName; } + + public String getProductName() { return productName; } + public void setProductName(String productName) { this.productName = productName; } + + public double getAmount() { return amount; } + public void setAmount(double amount) { this.amount = amount; } + + public String getStatus() { return status; } + public void setStatus(String status) { this.status = status; } + + public String getCreateTime() { return createTime; } + public void setCreateTime(String createTime) { this.createTime = createTime; } + + public String getUpdateTime() { return updateTime; } + public void setUpdateTime(String updateTime) { this.updateTime = updateTime; } + } + + /** + * 核销订单请求模型 + */ + public static class VerifyOrderRequest { + @SerializedName("token") + private String token; // 访问令牌 + + @SerializedName("order_id") + private String orderId; // 订单ID + + @SerializedName("verify_code") + private String verifyCode; // 核销码 + + public VerifyOrderRequest(String token, String orderId, String verifyCode) { + this.token = token; + this.orderId = orderId; + this.verifyCode = verifyCode; + } + + // Getters and Setters + public String getToken() { return token; } + public void setToken(String token) { this.token = token; } + + public String getOrderId() { return orderId; } + public void setOrderId(String orderId) { this.orderId = orderId; } + + public String getVerifyCode() { return verifyCode; } + public void setVerifyCode(String verifyCode) { this.verifyCode = verifyCode; } + } + + /** + * 核销订单响应模型 + */ + public static class VerifyOrderResponse { + @SerializedName("result") + private boolean result; // 核销结果 + + @SerializedName("message") + private String message; // 响应消息 + + @SerializedName("order_info") + private OrderInfo orderInfo; // 订单信息 + + // Getters and Setters + public boolean isResult() { return result; } + public void setResult(boolean result) { this.result = result; } + + public String getMessage() { return message; } + public void setMessage(String message) { this.message = message; } + + public OrderInfo getOrderInfo() { return orderInfo; } + public void setOrderInfo(OrderInfo orderInfo) { this.orderInfo = orderInfo; } + } + + /** + * 小程序码响应模型 + */ + public static class MiniQrcodeResponse { + // 服务器直接返回base64字符串数据 + private String data; // base64图片数据 + + // Getters and Setters + public String getData() { return data; } + public void setData(String data) { this.data = data; } + + // 兼容旧代码的方法 + public String getQrcodeUrl() { return data; } + public void setQrcodeUrl(String qrcodeUrl) { this.data = qrcodeUrl; } + + public String getQrcodeData() { return data; } + public void setQrcodeData(String qrcodeData) { this.data = qrcodeData; } + } } \ No newline at end of file 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 4c17806..600ca4f 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 @@ -9,13 +9,11 @@ import com.ouxuan.oxface.network.callback.CompleteApiResponseCallback; import com.ouxuan.oxface.network.callback.NetworkCallback; import com.ouxuan.oxface.network.model.ApiResponse; +import okhttp3.ResponseBody; import retrofit2.Call; import retrofit2.Callback; import retrofit2.Response; - -import retrofit2.Call; -import retrofit2.Callback; -import retrofit2.Response; +import org.json.JSONObject; /** * 网络请求工具类 @@ -539,4 +537,164 @@ public class NetworkUtils { } }); } + + /** + * 获取订单列表 + * @param token 访问令牌(必需) + * @param page 页码(可选) + * @param pageSize 每页数量(可选) + * @param callback 回调接口 + */ + public static void checkOrder(String token, Integer page, Integer pageSize, + NetworkCallback callback) { + if (padApiService == null) { + callback.onError(-1, "NetworkUtils未初始化,请先调用init()方法"); + return; + } + + callback.onStart(); + padApiService.checkOrder(token, page, pageSize).enqueue(new Callback>() { + @Override + public void onResponse(Call> call, + Response> response) { + try { + if (response.isSuccessful() && response.body() != null) { + ApiResponse apiResponse = response.body(); + + if (apiResponse.isSuccess()) { + callback.onSuccess(apiResponse.getData()); + } else { + // 打印详细的错误日志 + logApiError("checkOrder", apiResponse.getCode(), apiResponse.getMessage()); + callback.onError(apiResponse.getCode(), apiResponse.getMessage()); + } + } else { + callback.onError(response.code(), "请求失败: " + response.message()); + } + } catch (Exception e) { + callback.onException(e); + } finally { + callback.onComplete(); + } + } + + @Override + public void onFailure(Call> call, Throwable t) { + callback.onException(t); + callback.onComplete(); + } + }); + } + + /** + * 核销订单 + * @param token 访问令牌 + * @param orderId 订单ID + * @param verifyCode 核销码 + * @param callback 回调接口 + */ + public static void verifyOrder(String token, String orderId, String verifyCode, + NetworkCallback callback) { + if (padApiService == null) { + callback.onError(-1, "NetworkUtils未初始化,请先调用init()方法"); + return; + } + + PadApiService.VerifyOrderRequest request = new PadApiService.VerifyOrderRequest(token, orderId, verifyCode); + + callback.onStart(); + padApiService.verifyOrder(request).enqueue(new Callback>() { + @Override + public void onResponse(Call> call, + Response> response) { + try { + if (response.isSuccessful() && response.body() != null) { + ApiResponse apiResponse = response.body(); + + if (apiResponse.isSuccess()) { + callback.onSuccess(apiResponse.getData()); + } else { + // 打印详细的错误日志 + logApiError("verifyOrder", apiResponse.getCode(), apiResponse.getMessage()); + callback.onError(apiResponse.getCode(), apiResponse.getMessage()); + } + } else { + callback.onError(response.code(), "请求失败: " + response.message()); + } + } catch (Exception e) { + callback.onException(e); + } finally { + callback.onComplete(); + } + } + + @Override + public void onFailure(Call> call, Throwable t) { + callback.onException(t); + callback.onComplete(); + } + }); + } + + /** + * 获取小程序码 + * @param token 访问令牌 + * @param hardwareId 硬件ID + * @param callback 回调接口 + */ + public static void miniQrcode(String token, int hardwareId, + NetworkCallback callback) { + if (padApiService == null) { + callback.onError(-1, "NetworkUtils未初始化,请先调用init()方法"); + return; + } + + callback.onStart(); + padApiService.miniQrcode(token, hardwareId).enqueue(new Callback() { + @Override + public void onResponse(Call call, + Response response) { + try { + if (response.isSuccessful() && response.body() != null) { + // 服务器返回JSON格式字符串: {"code":0,"data":"data:image/png;base64,..."} + String responseBody = response.body().string(); + android.util.Log.d("NetworkUtils", "小程序码响应: " + responseBody); + + // 解析JSON响应 + JSONObject jsonObject = new JSONObject(responseBody); + int code = jsonObject.getInt("code"); + + if (code == 0) { + // 成功响应,提取data字段中的base64数据 + String base64Data = jsonObject.getString("data"); + android.util.Log.d("NetworkUtils", "提取到的base64数据长度: " + base64Data.length()); + + // 创建MiniQrcodeResponse对象并设置数据 + PadApiService.MiniQrcodeResponse miniQrcodeResponse = new PadApiService.MiniQrcodeResponse(); + miniQrcodeResponse.setData(base64Data); + + callback.onSuccess(miniQrcodeResponse); + } else { + // 服务器返回错误 + String message = jsonObject.optString("message", "获取小程序码失败"); + callback.onError(code, message); + } + } else { + callback.onError(response.code(), "请求失败: " + response.message()); + } + } catch (Exception e) { + android.util.Log.e("NetworkUtils", "解析小程序码响应失败", e); + callback.onException(e); + } finally { + callback.onComplete(); + } + } + + @Override + public void onFailure(Call call, Throwable t) { + callback.onException(t); + callback.onComplete(); + } + }); + } } \ No newline at end of file diff --git a/financelibrary/src/main/java/com/baidu/idl/face/main/finance/utils/BitmapUtils.java b/financelibrary/src/main/java/com/baidu/idl/face/main/finance/utils/BitmapUtils.java index 3d4ab34..d866899 100644 --- a/financelibrary/src/main/java/com/baidu/idl/face/main/finance/utils/BitmapUtils.java +++ b/financelibrary/src/main/java/com/baidu/idl/face/main/finance/utils/BitmapUtils.java @@ -488,10 +488,50 @@ public final class BitmapUtils { } public static Bitmap base64ToBitmap(String base64String) { - base64String = Uri.decode(base64String); - byte[] decode = Base64.decode(base64String, Base64.DEFAULT); - Bitmap bitmap = BitmapFactory.decodeByteArray(decode, 0, decode.length); - return bitmap; + try { + // 添加调试日志 + android.util.Log.d("BitmapUtils", "开始转换base64到Bitmap,数据长度: " + (base64String != null ? base64String.length() : 0)); + + if (base64String == null || base64String.isEmpty()) { + android.util.Log.w("BitmapUtils", "base64字符串为空"); + return null; + } + + // 解码URL编码的字符串 + base64String = android.net.Uri.decode(base64String); + + // 检查是否是data URL格式 + if (base64String.startsWith("data:image")) { + int commaIndex = base64String.indexOf(','); + if (commaIndex > 0) { + base64String = base64String.substring(commaIndex + 1); + } + } + + // 添加调试日志 + android.util.Log.d("BitmapUtils", "处理后的base64字符串长度: " + base64String.length()); + + // 解码base64字符串 + byte[] decode = android.util.Base64.decode(base64String, android.util.Base64.DEFAULT); + + // 添加调试日志 + android.util.Log.d("BitmapUtils", "解码后的字节数组长度: " + decode.length); + + // 创建Bitmap + Bitmap bitmap = android.graphics.BitmapFactory.decodeByteArray(decode, 0, decode.length); + + // 添加调试日志 + if (bitmap != null) { + android.util.Log.d("BitmapUtils", "Bitmap创建成功,尺寸: " + bitmap.getWidth() + "x" + bitmap.getHeight()); + } else { + android.util.Log.w("BitmapUtils", "Bitmap创建失败"); + } + + return bitmap; + } catch (Exception e) { + android.util.Log.e("BitmapUtils", "base64转Bitmap时发生异常: " + e.getMessage(), e); + return null; + } } public static byte[] bitmapToBytes(Bitmap bm) {