diff --git a/.agents/rules/versioning.md b/.agents/rules/versioning.md index 2fdf7ab..dbf6b57 100644 --- a/.agents/rules/versioning.md +++ b/.agents/rules/versioning.md @@ -68,8 +68,17 @@ S _ 12 _ XY _ U _ Chengwai _ 10 _ 08 _ 8 _ R * **`Cmuh`** (中國醫客製):支援 QR Code 掃碼、處方籤醫令離線 AES 解密與解析領藥流程。 2. **`hardware` 維度 (硬體與系統規格區隔)**: * **`S12XYU`**:代表 `S` (來源) + `12` (安卓號) + `XY` (主板號) + `U` (機器系列/機型規格)。 + * **`S9XYU`**:代表中國醫現場使用的 Android 9 / 21.5 吋硬體規格;除非明確指定中國醫 10 吋或 `S12XYU`,中國醫 (`Cmuh`) 相關修正與驗證預設必須使用此硬體 flavor。 -### 4.2 實體機台 APK 命名鐵律 +### 4.2 Flavor 驗證與編譯指令選擇 + +針對特定客戶或現場問題修改後,必須編譯對應的 Gradle variant,不可只用通用 `assembleDebug` 或錯誤硬體 flavor 代替。 + +* **中國醫現場版 (`Cmuh`) 驗證指令**:`./gradlew :app:assembleCmuhS9XYUDebug --no-daemon` +* **晟崴版 (`Chengwai`) 預設驗證指令**:`./gradlew :app:assembleChengwaiS12XYUDebug --no-daemon` +* **通用版 (`General`) 預設驗證指令**:`./gradlew :app:assembleGeneralS12XYUDebug --no-daemon` + +### 4.3 實體機台 APK 命名鐵律 為了符合實體機台 OTA 平台發佈規範,打包輸出的 APK 檔名必須嚴格連動雙維度,並遵循以下格式: `app-[格式化硬體規格]_[專案名稱]-[版本號]-[BuildType].apk` diff --git a/AGENTS.md b/AGENTS.md index 45d7b68..bacc403 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -24,6 +24,7 @@ - 禁止直接手改成品 `versionCode`/`versionName` 值。 - 版號管理透過 `verMajor`、`verMinor`、`verPatch` 變數。 - OTA 發版時,`versionCode` 必須嚴格遞增。 +- 中國醫現場版 (`Cmuh`) 修正預設以 `:app:assembleCmuhS9XYUDebug` 驗證。 ## When Rules Conflict diff --git a/app/build.gradle b/app/build.gradle index 6507b9b..97dadd0 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -9,7 +9,8 @@ plugins { // 避免不同尺寸機台間版本號產生衝突。 // ========================================================================= def verMinor = 1 -def verPatch = 65 +def verPatch = 67 + android { diff --git a/app/src/Cmuh/java/com/unibuy/smartdevice/ui/SaleFlowHandler.java b/app/src/Cmuh/java/com/unibuy/smartdevice/ui/SaleFlowHandler.java index 218ce96..2c94e2e 100644 --- a/app/src/Cmuh/java/com/unibuy/smartdevice/ui/SaleFlowHandler.java +++ b/app/src/Cmuh/java/com/unibuy/smartdevice/ui/SaleFlowHandler.java @@ -322,14 +322,36 @@ public class SaleFlowHandler { haveValuestate = true; if (requestQty > 1) { - int checkcount = 0; - int slotnum = 0; + class TempSlot { + int slotNo; + int stock; + TempSlot(int slotNo, int stock) { + this.slotNo = slotNo; + this.stock = stock; + } + } + String[] slotPairs = medicineList.get(i).getMedicineSlot().split(","); + java.util.List tempSlots = new java.util.ArrayList<>(); + for (String pair : slotPairs) { + if (pair.trim().isEmpty()) continue; + String[] parts = pair.split("-"); + if (parts.length == 2) { + tempSlots.add(new TempSlot(Integer.parseInt(parts[0]), Integer.parseInt(parts[1]))); + } + } + + int slotIdx = 0; for (int j = 0; j < requestQty; j++) { - checkcount += 1; - if (checkcount > Integer.valueOf(medicineList.get(i).getMedicineSlot().split(",")[0].split("-")[1])) { - slotnum = Integer.valueOf(medicineList.get(i).getMedicineSlot().split(",")[1].split("-")[0]); + while (slotIdx < tempSlots.size() && tempSlots.get(slotIdx).stock <= 0) { + slotIdx++; + } + int slotnum; + if (slotIdx < tempSlots.size()) { + TempSlot activeSlot = tempSlots.get(slotIdx); + slotnum = activeSlot.slotNo; + activeSlot.stock--; } else { - slotnum = Integer.valueOf(medicineList.get(i).getMedicineSlot().split(",")[0].split("-")[0]); + slotnum = tempSlots.get(tempSlots.size() - 1).slotNo; } addMedicineToBuyList( medicineList.get(i).getProductId(), diff --git a/app/src/main/java/com/unibuy/smartdevice/service/MqttService.java b/app/src/main/java/com/unibuy/smartdevice/service/MqttService.java index 9d6409a..19fa136 100644 --- a/app/src/main/java/com/unibuy/smartdevice/service/MqttService.java +++ b/app/src/main/java/com/unibuy/smartdevice/service/MqttService.java @@ -138,7 +138,7 @@ public class MqttService extends Service { new android.os.Handler(android.os.Looper.getMainLooper()).post(() -> { Intent lockIntent = new Intent(getApplicationContext(), com.unibuy.smartdevice.ui.MaintenanceActivity.class); - lockIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP); + lockIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); startActivity(lockIntent); }); } else if ("unlock".equals(cmd)) { diff --git a/app/src/main/java/com/unibuy/smartdevice/tools/AppUtils.java b/app/src/main/java/com/unibuy/smartdevice/tools/AppUtils.java index 52d8ee6..8a91dca 100644 --- a/app/src/main/java/com/unibuy/smartdevice/tools/AppUtils.java +++ b/app/src/main/java/com/unibuy/smartdevice/tools/AppUtils.java @@ -1,26 +1,23 @@ -package com.unibuy.smartdevice.tools; - -import android.app.AlarmManager; -import android.app.PendingIntent; -import android.content.Context; -import android.content.Intent; - -import com.unibuy.smartdevice.external.mqtt.MqttManager; -import com.unibuy.smartdevice.ui.FontendActivity; - -public class AppUtils { - public static void resetApp(Context context) { - Intent intent = new Intent(context, FontendActivity.class); - intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); - - PendingIntent pendingIntent = PendingIntent.getActivity( - context, 0, intent, PendingIntent.FLAG_IMMUTABLE); - - AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); - alarmManager.setExact(AlarmManager.RTC, System.currentTimeMillis() + 500, pendingIntent); - - - - android.os.Process.killProcess(android.os.Process.myPid()); - } -} +package com.unibuy.smartdevice.tools; + +import android.app.AlarmManager; +import android.app.PendingIntent; +import android.content.Context; +import android.content.Intent; + +import com.unibuy.smartdevice.ui.FontendActivity; + +public class AppUtils { + public static void resetApp(Context context) { + Intent intent = new Intent(context, FontendActivity.class); + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); + + PendingIntent pendingIntent = PendingIntent.getActivity( + context, 0, intent, PendingIntent.FLAG_IMMUTABLE); + + AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); + alarmManager.setExact(AlarmManager.RTC, System.currentTimeMillis() + 500, pendingIntent); + + android.os.Process.killProcess(android.os.Process.myPid()); + } +} diff --git a/app/src/main/java/com/unibuy/smartdevice/ui/FontendActivity.java b/app/src/main/java/com/unibuy/smartdevice/ui/FontendActivity.java index 0d16ca5..94a58bd 100644 --- a/app/src/main/java/com/unibuy/smartdevice/ui/FontendActivity.java +++ b/app/src/main/java/com/unibuy/smartdevice/ui/FontendActivity.java @@ -45,6 +45,7 @@ import androidx.fragment.app.FragmentManager; import com.unibuy.smartdevice.R; import com.unibuy.smartdevice.controller.DevController; import com.unibuy.smartdevice.controller.DevXinYuanController; +import com.unibuy.smartdevice.database.SettingsDao; import com.unibuy.smartdevice.database.SlotsDao; import com.unibuy.smartdevice.databinding.ActivityFontendBinding; import com.unibuy.smartdevice.devices.DevNFCPay; @@ -407,6 +408,18 @@ public class FontendActivity extends AppCompatActivityAbstract implements SaleFl @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); + + SettingsDao settingsDao = new SettingsDao(getApplicationContext()); + if (settingsDao.isMachineLocked()) { + settingsDao.close(); + Intent intent = new Intent(this, MaintenanceActivity.class); + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); + startActivity(intent); + finish(); + return; + } + settingsDao.close(); + // 讀取最後設定語言的設定 // LanguageHelper.applySavedLanguage(this); binding = ActivityFontendBinding.inflate(getLayoutInflater());