From b2b6776665ec34843c878023c7b35a0714fb9f28 Mon Sep 17 00:00:00 2001 From: sky121113 Date: Fri, 29 May 2026 12:17:42 +0800 Subject: [PATCH] =?UTF-8?q?[FIX]=20=E5=AF=A6=E4=BD=9C=E5=8D=8A=E9=80=94?= =?UTF-8?q?=E5=87=BA=E8=B2=A8=E5=A4=B1=E6=95=97=E7=9A=84=20MQTT=20Finalize?= =?UTF-8?q?=20=E7=B5=90=E6=A1=88=E5=9B=9E=E5=A0=B1=E6=A9=9F=E5=88=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. 遞增 app/build.gradle 修補版本號為 1.31。 2. 於 TransactionFinalizePayload 新增 delivery_status 出貨狀態欄位(0=失敗, 1=成功, 2=部分失敗)。 3. 於 TransactionFinalizeBuilder 實作自動計算出貨狀態與建構回報的邏輯。 4. 於 DispatchDialog 實作 finalizeFailedDispatch 機制,當多筆商品出貨至半途失敗時,自動將剩餘未出貨的商品標記為失敗並上報 MQTT Finalize 結案。 --- app/build.gradle | 2 +- .../mqtt/TransactionFinalizePayload.java | 13 ++++ .../tools/TransactionFinalizeBuilder.java | 25 ++++++++ .../smartdevice/ui/dialog/DispatchDialog.java | 60 +++++++++++++++++++ 4 files changed, 99 insertions(+), 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index ee530b6..8be4b55 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -9,7 +9,7 @@ plugins { // 避免不同尺寸機台間版本號產生衝突。 // ========================================================================= def verMinor = 1 -def verPatch = 30 +def verPatch = 31 android { diff --git a/app/src/main/java/com/unibuy/smartdevice/structure/mqtt/TransactionFinalizePayload.java b/app/src/main/java/com/unibuy/smartdevice/structure/mqtt/TransactionFinalizePayload.java index 568a5bb..f3d10bf 100644 --- a/app/src/main/java/com/unibuy/smartdevice/structure/mqtt/TransactionFinalizePayload.java +++ b/app/src/main/java/com/unibuy/smartdevice/structure/mqtt/TransactionFinalizePayload.java @@ -119,6 +119,11 @@ public class TransactionFinalizePayload { */ private int payment_status; + /** + * 訂單出貨狀態:0 = 全部失敗, 1 = 全部成功, 2 = 部分失敗 + */ + private int delivery_status; + /** 支付 Request 原始內容 (JSON String) */ private String payment_request; @@ -210,6 +215,14 @@ public class TransactionFinalizePayload { this.payment_status = payment_status; } + public int getDelivery_status() { + return delivery_status; + } + + public void setDelivery_status(int delivery_status) { + this.delivery_status = delivery_status; + } + public String getPayment_request() { return payment_request; } diff --git a/app/src/main/java/com/unibuy/smartdevice/tools/TransactionFinalizeBuilder.java b/app/src/main/java/com/unibuy/smartdevice/tools/TransactionFinalizeBuilder.java index 1a14406..9a9d3ff 100644 --- a/app/src/main/java/com/unibuy/smartdevice/tools/TransactionFinalizeBuilder.java +++ b/app/src/main/java/com/unibuy/smartdevice/tools/TransactionFinalizeBuilder.java @@ -29,6 +29,9 @@ public class TransactionFinalizeBuilder { private static final String TAG = "TransactionFinalizeBuilder"; private static final SimpleDateFormat SDF = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault()); + private static final int ORDER_STATUS_FAILED = 0; + private static final int ORDER_STATUS_SUCCESS = 1; + private static final int ORDER_STATUS_PARTIAL_FAILED = 2; /** 訂單建立時間(支付完成時的時間點) */ private final String orderMachineTime; @@ -116,6 +119,7 @@ public class TransactionFinalizeBuilder { // --- 組裝 order --- TransactionFinalizePayload.OrderPayload order = buildOrderPayload(flowInfo); + order.setDelivery_status(calculateOrderStatus()); payload.setOrder(order); // --- 出貨記錄 --- @@ -128,6 +132,27 @@ public class TransactionFinalizeBuilder { return payload; } + private int calculateOrderStatus() { + boolean hasSuccess = false; + boolean hasFailed = false; + + for (TransactionFinalizePayload.DispenseRecord record : dispenseRecords) { + if (record.getDispense_status() == 1) { + hasSuccess = true; + } else { + hasFailed = true; + } + } + + if (hasSuccess && hasFailed) { + return ORDER_STATUS_PARTIAL_FAILED; + } + if (hasSuccess) { + return ORDER_STATUS_SUCCESS; + } + return ORDER_STATUS_FAILED; + } + /** * 從 MyApp 的全域狀態組裝 OrderPayload。 */ diff --git a/app/src/main/java/com/unibuy/smartdevice/ui/dialog/DispatchDialog.java b/app/src/main/java/com/unibuy/smartdevice/ui/dialog/DispatchDialog.java index 70fd06d..8832dfc 100644 --- a/app/src/main/java/com/unibuy/smartdevice/ui/dialog/DispatchDialog.java +++ b/app/src/main/java/com/unibuy/smartdevice/ui/dialog/DispatchDialog.java @@ -196,6 +196,7 @@ public class DispatchDialog extends DialogAbstract { for (String logItem : deliveryLogs) { getLogs().info(logItem); } + finalizeFailedDispatch(message); new Handler().postDelayed(() -> { Context ctx = getContext(); @@ -955,6 +956,65 @@ public class DispatchDialog extends DialogAbstract { isGetProductByVMC = false; // 解鎖出貨成功判定 } + private void finalizeFailedDispatch(String message) { + if (isFinalizing) { + return; + } + isFinalizing = true; + + if (finalizeBuilder == null) { + getLogs().info("finalizeBuilder is null, cannot publish failed dispatch finalize: " + message); + return; + } + + addFailedDispenseRecordsFromCurrent(); + + if ("Cmuh".equalsIgnoreCase(com.unibuy.smartdevice.BuildConfig.FLAVOR_project)) { + insertDrgnoToMemo(); + } + + getLogs().info("出貨失敗,發送 MQTT Finalize 結案訊息: " + message); + MqttManager.getInstance().publishTransactionFinalize(finalizeBuilder.build()); + getSrcHandlerMain().send(getClass().getSimpleName(), FontendActivity.Option.RESET_DATA.getOption(), "update data"); + saveData(); + } + + private void addFailedDispenseRecordsFromCurrent() { + if (dispatchList == null || dispatchList.isEmpty()) { + return; + } + + int startIndex = Math.max(0, dispatchIndex); + for (int i = startIndex; i < dispatchList.size(); i++) { + DispatchStructure dispatch = dispatchList.get(i); + int failedQuantity = dispatch.getQuantity() - dispatch.getCount(); + if (failedQuantity <= 0) { + continue; + } + + ProductStructure product = dispatch.getProduct(); + int productId = 0; + try { + productId = Integer.parseInt(product.getProductID()); + } catch (Exception ignored) { + } + + int remaining = 0; + try { + remaining = MyApp.getInstance().getSlotData(dispatch.getField(), dispatch.getSlot()).getCount(); + } catch (LogsEmptyException e) { + getLogs().warning(e); + } + + int amount = product.getRealPrice() * failedQuantity; + finalizeBuilder.addDispenseRecord(dispatch.getSlot(), productId, amount, 0, false, remaining); + getLogs().info("[Finalize] 已累積出貨失敗記錄: slot=" + dispatch.getSlot() + + ", product=" + productId + + ", failedQuantity=" + failedQuantity + + ", remaining=" + remaining); + } + } + private void deliverylot(int msgflag){ String productId = dispatchList.get(dispatchIndex).getProduct().getProductID();