linee před 2 dny
rodič
revize
85f8bd0bc4

+ 3 - 4
entry/src/main/java/com/fujica/abk/component/LoadingComponent.java

@@ -1,6 +1,7 @@
 package com.fujica.abk.component;
 
 import com.fujica.abk.ResourceTable;
+import com.fujica.abk.utils.DialogUtil;
 import ohos.agp.animation.Animator;
 import ohos.agp.animation.AnimatorProperty;
 import ohos.agp.components.AttrSet;
@@ -118,8 +119,7 @@ public class LoadingComponent extends DirectionalLayout {
                 if (loadingImage != null && rotationAnimator != null && getVisibility() == VISIBLE) {
                     loadingImage.setRotation(0f);
                     // 延迟一小段时间后重新启动动画,实现连续旋转
-                    EventHandler mainHandler = new EventHandler(EventRunner.getMainEventRunner());
-                    mainHandler.postTask(() -> {
+                    DialogUtil.postTask(() -> {
                         if (rotationAnimator != null && loadingImage != null && getVisibility() == VISIBLE) {
                             rotationAnimator.start();
                         }
@@ -143,8 +143,7 @@ public class LoadingComponent extends DirectionalLayout {
     public void show() {
         setVisibility(VISIBLE);
         // 延迟启动旋转动画,确保组件已完全渲染
-        EventHandler mainHandler = new EventHandler(EventRunner.getMainEventRunner());
-        mainHandler.postTask(() -> {
+        DialogUtil.postTask(() -> {
             if (rotationAnimator != null && loadingImage != null) {
                 // 重置旋转角度
                 loadingImage.setRotation(0f);

+ 422 - 78
entry/src/main/java/com/fujica/abk/component/nav/ChargeComponent.java

@@ -2,9 +2,10 @@ package com.fujica.abk.component.nav;
 
 import com.fujica.abk.ResourceTable;
 import com.fujica.abk.api.cache;
-import com.fujica.abk.utils.LicensePlateInputDialog;
-import com.fujica.abk.utils.R;
-import com.fujica.abk.utils.api;
+import com.fujica.abk.component.LoadingComponent;
+import com.fujica.abk.utils.*;
+import com.google.gson.Gson;
+import com.google.gson.reflect.TypeToken;
 import ohos.agp.components.*;
 import ohos.agp.components.ComponentContainer;
 import ohos.agp.components.DirectionalLayout;
@@ -16,23 +17,66 @@ import ohos.eventhandler.EventRunner;
 import java.util.concurrent.CompletableFuture;
 
 /**
- * 我的页面组件
+ * 计费页面组件
  */
 public class ChargeComponent extends DirectionalLayout {
     private Component rootLayout;
     private Context context;
 
-    // 有车牌缓存时的UI组件
-    private DirectionalLayout parkingInfoCard;
-    private Text textLicensePlate;
-    private Text textParkingDuration;
-    private Text textTotalFee;
+    private DirectionalLayout filterPlateNo;
+    private Text textPlateNo;
+
+    // 不同状态的卡片
+    private DirectionalLayout cardNormalFee;      // feeType 0或16: 正常缴费
+    private DirectionalLayout cardNoEntry;        // feeType 10或12: 未入场
+    private DirectionalLayout cardBlacklist;      // feeType 14: 黑名单
+    private DirectionalLayout cardMonthly;        // feeType 3: 月卡车辆
+    private DirectionalLayout cardNoFee;          // feeType 1/2/4/5/13: 无需缴费
+    private DirectionalLayout cardFullDiscount;   // feeType 6: 全额优惠
+    private DirectionalLayout addVehicleCard;     // 无车牌缓存
+
+    // 正常缴费卡片的组件
+    private Text textParkName;
+    private Text textStayTime;
+    private Text textActualAmount;
+    private Text textDiscountAmount;
     private Button btnPayNow;
 
-    // 无车牌缓存时的UI组件
-    private DirectionalLayout addVehicleCard;
+    // 未入场卡片的组件
+    private Button btnRefresh;
+
+    // 黑名单卡片的组件
+    private Text textParkNameBlacklist;
+    private Text textStayTimeBlacklist;
+
+    // 月卡卡片的组件
+    private Text textParkNameMonthly;
+    private Text textStayTimeMonthly;
+    private Button btnRenew;
+
+    // 无需缴费卡片的组件
+    private Text textParkNameNoFee;
+    private Text textStayTimeNoFee;
+
+    // 全额优惠卡片的组件
+    private Text textParkNameFullDiscount;
+    private Text textStayTimeFullDiscount;
+
+    // 无车牌缓存卡片的组件
     private Button btnInputLicensePlate;
 
+    // 当前停车费信息
+    private api.ParkingFeeInfo currentFeeInfo;
+
+    private LoadingComponent loadingComponent; // Loading组件
+
+    /**
+     * 设置Loading组件
+     */
+    public void setLoadingComponent(LoadingComponent loadingComponent) {
+        this.loadingComponent = loadingComponent;
+    }
+
     /**
      * 构造函数
      */
@@ -40,13 +84,6 @@ public class ChargeComponent extends DirectionalLayout {
         super(context);
         this.context = context;
         initComponent(context);
-
-        LicensePlateInputDialog licensePlateInputDialog = new LicensePlateInputDialog(context);
-        licensePlateInputDialog.setOnConfirmListener(licensePlate -> {
-            // 确认后保存车牌并查询计费
-            simulateLicensePlateInput(licensePlate);
-        });
-//        licensePlateInputDialog.show(); //测试
     }
 
     /**
@@ -77,15 +114,46 @@ public class ChargeComponent extends DirectionalLayout {
      * 初始化视图组件
      */
     private void initViews() {
-        // 有车牌缓存时的UI组件
-        parkingInfoCard = rootLayout.findComponentById(ResourceTable.Id_parking_info_card);
-        textLicensePlate = rootLayout.findComponentById(ResourceTable.Id_text_license_plate);
-        textParkingDuration = rootLayout.findComponentById(ResourceTable.Id_text_parking_duration);
-        textTotalFee = rootLayout.findComponentById(ResourceTable.Id_text_total_fee);
-        btnPayNow = rootLayout.findComponentById(ResourceTable.Id_btn_pay_now);
+        filterPlateNo = rootLayout.findComponentById(ResourceTable.Id_filter_plateNo);
+        textPlateNo = rootLayout.findComponentById(ResourceTable.Id_text_plateNo);
 
-        // 无车牌缓存时的UI组件
+        // 获取所有卡片容器
+        cardNormalFee = rootLayout.findComponentById(ResourceTable.Id_card_normal_fee);
+        cardNoEntry = rootLayout.findComponentById(ResourceTable.Id_card_no_entry);
+        cardBlacklist = rootLayout.findComponentById(ResourceTable.Id_card_blacklist);
+        cardMonthly = rootLayout.findComponentById(ResourceTable.Id_card_monthly);
+        cardNoFee = rootLayout.findComponentById(ResourceTable.Id_card_no_fee);
+        cardFullDiscount = rootLayout.findComponentById(ResourceTable.Id_card_full_discount);
         addVehicleCard = rootLayout.findComponentById(ResourceTable.Id_add_vehicle_card);
+
+        // 正常缴费卡片的组件
+        textParkName = rootLayout.findComponentById(ResourceTable.Id_text_park_name);
+        textStayTime = rootLayout.findComponentById(ResourceTable.Id_text_stay_time);
+        textActualAmount = rootLayout.findComponentById(ResourceTable.Id_text_actual_amount);
+        textDiscountAmount = rootLayout.findComponentById(ResourceTable.Id_text_discount_amount);
+        btnPayNow = rootLayout.findComponentById(ResourceTable.Id_btn_pay_now);
+
+        // 未入场卡片的组件
+        btnRefresh = rootLayout.findComponentById(ResourceTable.Id_btn_refresh);
+
+        // 黑名单卡片的组件
+        textParkNameBlacklist = rootLayout.findComponentById(ResourceTable.Id_text_park_name_blacklist);
+        textStayTimeBlacklist = rootLayout.findComponentById(ResourceTable.Id_text_stay_time_blacklist);
+
+        // 月卡卡片的组件
+        textParkNameMonthly = rootLayout.findComponentById(ResourceTable.Id_text_park_name_monthly);
+        textStayTimeMonthly = rootLayout.findComponentById(ResourceTable.Id_text_stay_time_monthly);
+        btnRenew = rootLayout.findComponentById(ResourceTable.Id_btn_renew);
+
+        // 无需缴费卡片的组件
+        textParkNameNoFee = rootLayout.findComponentById(ResourceTable.Id_text_park_name_no_fee);
+        textStayTimeNoFee = rootLayout.findComponentById(ResourceTable.Id_text_stay_time_no_fee);
+
+        // 全额优惠卡片的组件
+        textParkNameFullDiscount = rootLayout.findComponentById(ResourceTable.Id_text_park_name_full_discount);
+        textStayTimeFullDiscount = rootLayout.findComponentById(ResourceTable.Id_text_stay_time_full_discount);
+
+        // 无车牌缓存卡片的组件
         btnInputLicensePlate = rootLayout.findComponentById(ResourceTable.Id_btn_input_license_plate);
     }
 
@@ -93,67 +161,91 @@ public class ChargeComponent extends DirectionalLayout {
      * 设置事件监听
      */
     private void setupListeners() {
+        filterPlateNo.setClickedListener(v -> showLicensePlateInputDialog());
+
         // 输入车牌缴费按钮点击事件
-        if (btnInputLicensePlate != null) {
-            btnInputLicensePlate.setClickedListener(component -> {
-                LicensePlateInputDialog licensePlateInputDialog = new LicensePlateInputDialog(context);
-                licensePlateInputDialog.setOnConfirmListener(licensePlate -> {
-                    // 确认后保存车牌并查询计费
-                    simulateLicensePlateInput(licensePlate);
-                });
-                licensePlateInputDialog.show();
-            });
-        }
+        btnInputLicensePlate.setClickedListener(component -> showLicensePlateInputDialog());
 
         // 立即缴费按钮点击事件
         if (btnPayNow != null) {
             btnPayNow.setClickedListener(component -> {
-                // TODO: 实现缴费逻辑
+                if (currentFeeInfo != null) {
+                    // TODO: 跳转到支付页面
+                    Toast.info(context, "跳转到支付页面");
+                }
+            });
+        }
+
+        // 刷新按钮点击事件
+        if (btnRefresh != null) {
+            btnRefresh.setClickedListener(component -> {
+                checkCacheAndUpdateUI();
+            });
+        }
+
+        // 立即续费按钮点击事件
+        if (btnRenew != null) {
+            btnRenew.setClickedListener(component -> {
+                if (currentFeeInfo != null) {
+                    // TODO: 跳转到续费页面
+                    Toast.info(context, "跳转到续费页面");
+                }
             });
         }
     }
 
+    /**
+     * 显示车牌输入对话框
+     */
+    private void showLicensePlateInputDialog() {
+        LicensePlateInputDialog licensePlateInputDialog = new LicensePlateInputDialog(context);
+        licensePlateInputDialog.setOnConfirmListener(licensePlate -> {
+            // 确认后保存车牌并查询计费
+            simulateLicensePlateInput(licensePlate);
+        });
+        licensePlateInputDialog.show();
+    }
+
     /**
      * 检查缓存并更新UI
      */
     private void checkCacheAndUpdateUI() {
         String licensePlate = cache.getLicensePlate(context);
-        textLicensePlate.setText(licensePlate);
-        boolean isParking = licensePlate != null && licensePlate != "";
 
-        if (licensePlate != null && !licensePlate.isEmpty() && isParking) {
-            // 有缓存,显示停车信息卡片
-            showParkingInfoCard();
-            // 直接查询计费
+        if (licensePlate != null && !licensePlate.isEmpty()) {
+            // 有缓存,直接查询计费
             queryParkingFee(licensePlate);
+            filterPlateNo.setVisibility(VISIBLE);
+            textPlateNo.setText(licensePlate);
         } else {
             // 无缓存,显示添加车辆卡片
             showAddVehicleCard();
+            filterPlateNo.setVisibility(HIDE);
+            textPlateNo.setText("");
         }
     }
 
     /**
-     * 显示停车信息卡片
+     * 显示添加车辆卡片
      */
-    private void showParkingInfoCard() {
-        if (parkingInfoCard != null) {
-            parkingInfoCard.setVisibility(VISIBLE);
-        }
+    private void showAddVehicleCard() {
+        hideAllCards();
         if (addVehicleCard != null) {
-            addVehicleCard.setVisibility(HIDE);
+            addVehicleCard.setVisibility(VISIBLE);
         }
     }
 
     /**
-     * 显示添加车辆卡片
+     * 隐藏所有卡片
      */
-    private void showAddVehicleCard() {
-        if (parkingInfoCard != null) {
-            parkingInfoCard.setVisibility(HIDE);
-        }
-        if (addVehicleCard != null) {
-            addVehicleCard.setVisibility(VISIBLE);
-        }
+    private void hideAllCards() {
+        if (cardNormalFee != null) cardNormalFee.setVisibility(HIDE);
+        if (cardNoEntry != null) cardNoEntry.setVisibility(HIDE);
+        if (cardBlacklist != null) cardBlacklist.setVisibility(HIDE);
+        if (cardMonthly != null) cardMonthly.setVisibility(HIDE);
+        if (cardNoFee != null) cardNoFee.setVisibility(HIDE);
+        if (cardFullDiscount != null) cardFullDiscount.setVisibility(HIDE);
+        if (addVehicleCard != null) addVehicleCard.setVisibility(HIDE);
     }
 
     /**
@@ -163,8 +255,9 @@ public class ChargeComponent extends DirectionalLayout {
         // 保存车牌到缓存
         cache.setLicensePlate(context, licensePlate);
 
-        // 更新UI
-        showParkingInfoCard();
+        // 更新顶部车牌显示
+        filterPlateNo.setVisibility(VISIBLE);
+        textPlateNo.setText(licensePlate);
 
         // 查询计费
         queryParkingFee(licensePlate);
@@ -172,42 +265,293 @@ public class ChargeComponent extends DirectionalLayout {
 
     /**
      * 查询停车费用
+     * 参考 index.vue 中的 getCharge 方法实现
      */
     private void queryParkingFee(String licensePlate) {
         CompletableFuture<R<api.ParkingFeeInfo>> future = api.queryParkingFee(context, licensePlate);
-        future.thenAccept(result -> {
+        if (loadingComponent != null) {
+            loadingComponent.show();
+        }
+        future.thenAccept(result1 -> {
             // 在主线程更新UI
-            EventRunner mainRunner = EventRunner.getMainEventRunner();
-            if (mainRunner != null) {
-                EventHandler mainHandler = new EventHandler(mainRunner);
-                mainHandler.postTask(() -> {
-                    if (result != null && result.isSuccess() && result.getData() != null) {
-                        api.ParkingFeeInfo feeInfo = result.getData();
-                        updateParkingInfo(feeInfo);
-                    }
+            DialogUtil.postTask(() -> {
+                String json = "{\"code\":0,\"data\":{\"actualAmount\":1400,\"discountAmount\":110,\"feeType\":12,\"followList\":[],\"parkId\":\"559581682204741\",\"parkName\":\"车场0818\",\"parkingDays\":0,\"parkingHours\":0,\"parkingMinutes\":0,\"plateColor\":\"6\",\"plateNo\":\"粤B11111\",\"rzStatus\":false,\"stayTime\":\"0天6小时39分\",\"totalFee\":0},\"success\":true}";
+                R<api.ParkingFeeInfo> result = new Gson().fromJson(json, new TypeToken<R<api.ParkingFeeInfo>>() {
                 });
-            }
+
+
+                if (result == null || "timeout".equals(result.getMsg())) {
+                    // 查询结果为空或超时:按照未入场处理(feeType=10)
+                    // 参考 Charge.ets 第467行的实现
+                    api.ParkingFeeInfo emptyFeeInfo = new api.ParkingFeeInfo();
+                    emptyFeeInfo.setFeeType(10);
+                    emptyFeeInfo.setPlateNo(licensePlate);
+                    updateParkingInfo(emptyFeeInfo);
+                } else if (result.isSuccess() && result.getData() != null) {
+                    api.ParkingFeeInfo feeInfo = result.getData();
+                    currentFeeInfo = feeInfo;
+
+                    // 更新停车信息显示
+                    updateParkingInfo(feeInfo);
+
+                    // 处理 feeType 16:有历史欠费订单(临停加欠费补缴)
+                    if (feeInfo.getFeeType() == 16 && feeInfo.getFollowList() != null && !feeInfo.getFollowList().isEmpty()) {
+                        int arrearageCount = feeInfo.getFollowList().size();
+                        String message = "您有" + arrearageCount + "笔历史欠费订单(不含本次停车订单)尚未支付,请尽快处理";
+                        showArrearageDialog(message, feeInfo, "立即补缴");
+                    }
+                    // 处理 feeType 13:本次停车未产生费用,但有历史欠费订单
+                    else if (feeInfo.getFeeType() == 13 && feeInfo.getFollowList() != null && !feeInfo.getFollowList().isEmpty()) {
+                        int arrearageCount = feeInfo.getFollowList().size();
+                        String message = "本次停车未产生费用,但您仍有" + arrearageCount + "笔历史欠费订单尚未支付,请尽快处理";
+                        showArrearageDialog(message, feeInfo, "立即补缴");
+                    }
+
+                    // TODO: 检查车辆认证状态
+                    // 这里需要获取用户的车辆列表,检查当前车牌是否已认证(status == 2)
+                    // 如果未认证,设置 rzStatus = false
+                    // if (user.cars.findIndex(item => item.plateNo == feeInfo.getPlateNo() && item.status == 2) == -1) {
+                    //     feeInfo.setRzStatus(false);
+                    // } else {
+                    //     feeInfo.setRzStatus(true);
+                    // }
+
+                } else {
+                    // 查询失败
+                    Toast.error(context, "查询失败,请稍后重试");
+                    showAddVehicleCard();
+                }
+            });
+        }).exceptionally(throwable -> {
+            // 异常处理(包括超时)
+            // 参考 Vue 中的实现:计费超时按照未入场处理(feeType=10)
+            EventRunner mainRunner = EventRunner.getMainEventRunner();
+            DialogUtil.postTask(() -> {
+                // 异常按照未入场处理
+                api.ParkingFeeInfo errorFeeInfo = new api.ParkingFeeInfo();
+                errorFeeInfo.setFeeType(10);
+                errorFeeInfo.setPlateNo(licensePlate);
+                updateParkingInfo(errorFeeInfo);
+            });
+            return null;
+        }).whenComplete((result, throwable) -> {
+            // finally 块:无论成功还是失败都隐藏 loading
+            DialogUtil.postTask(() -> {
+                if (loadingComponent != null) {
+                    loadingComponent.hide();
+                }
+            });
         });
     }
 
+    /**
+     * 显示欠费订单提示对话框
+     * 参考 Vue 中的 uni.showModal 实现
+     */
+    private void showArrearageDialog(String message, api.ParkingFeeInfo feeInfo, String confirmText) {
+        com.fujica.abk.utils.ConfirmDialog dialog = new com.fujica.abk.utils.ConfirmDialog(context);
+        dialog.setTitle("温馨提示")
+                .setMessage(message)
+                .setConfirmText(confirmText)
+                .setConfirmListener(dialogInstance -> {
+                    // 点击确定按钮:跳转到欠费补缴页面
+                    handleArrearagePayment(feeInfo);
+                    dialogInstance.dismiss();
+                })
+                .setCancelListener(dialogInstance -> {
+                    // 点击取消按钮:关闭对话框
+                    dialogInstance.dismiss();
+                })
+                .show();
+    }
+
+    /**
+     * 处理欠费补缴
+     * 根据欠费订单数量跳转到不同页面
+     */
+    private void handleArrearagePayment(api.ParkingFeeInfo feeInfo) {
+        if (feeInfo.getFollowList() == null || feeInfo.getFollowList().isEmpty()) {
+            return;
+        }
+
+        // TODO: 实现跳转逻辑
+        // 如果只有一笔欠费订单,跳转到订单详情页
+        if (feeInfo.getFollowList().size() == 1) {
+            // storage.set('arrearageDetail', feeInfo.getFollowList().get(0));
+            // pageTo('/pages/pay/arrearage/detail', { type: "pay" });
+            Toast.info(context, "跳转到欠费订单详情页");
+        } else {
+            // 如果有多笔欠费订单,跳转到订单列表页
+            // storage.set('arrearageList', feeInfo);
+            // pageTo('/pages/pay/arrearage/list', { type: "singlePay" });
+            Toast.info(context, "跳转到欠费订单列表页");
+        }
+    }
+
     /**
      * 更新停车信息显示
+     * 根据 feeType 显示不同的界面,参考 index.vue 的实现
      */
     private void updateParkingInfo(api.ParkingFeeInfo feeInfo) {
-        if (textLicensePlate != null && feeInfo.getLicensePlate() != null) {
-            textLicensePlate.setText(feeInfo.getLicensePlate());
+        hideAllCards();
+
+        int feeType = feeInfo.getFeeType();
+
+        switch (feeType) {
+            case 0:  // 正常缴费
+            case 16: // 临停加欠费补缴
+                showNormalFeeCard(feeInfo);
+                break;
+
+            case 10: // 未入场
+            case 12: // 场外月卡
+                showNoEntryCard();
+                break;
+
+            case 14: // 黑名单车辆
+                showBlacklistCard(feeInfo);
+                break;
+
+            case 3:  // 月卡车辆
+                showMonthlyCard(feeInfo);
+                break;
+
+            case 1:  // 无需缴费
+            case 2:  // 已缴费免费离场时间内
+            case 4:  // 免费时间内
+            case 5:  // 无需缴费
+            case 13: // 欠费补缴(本次无需缴费)
+                showNoFeeCard(feeInfo);
+                break;
+
+            case 6:  // 全额优惠,无需缴费
+                showFullDiscountCard(feeInfo);
+                break;
+
+            default:
+                showAddVehicleCard();
+                break;
+        }
+    }
+
+    /**
+     * 显示正常缴费卡片 (feeType 0或16)
+     */
+    private void showNormalFeeCard(api.ParkingFeeInfo feeInfo) {
+        if (cardNormalFee == null) return;
+
+        cardNormalFee.setVisibility(VISIBLE);
+
+        // 设置车场名称(如果未认证,显示提示)
+        if (textParkName != null) {
+            String parkName = feeInfo.getParkName() != null ? feeInfo.getParkName() : "未知车场";
+            textParkName.setText(parkName);
         }
 
-        if (textParkingDuration != null) {
-            String duration = String.format("已停%d天%d小时%d分",
-                    feeInfo.getParkingDays(),
-                    feeInfo.getParkingHours(),
-                    feeInfo.getParkingMinutes());
-            textParkingDuration.setText(duration);
+        // 设置停车时长
+        if (textStayTime != null) {
+            String stayTime = feeInfo.getStayTime() != null ? "已停" + feeInfo.getStayTime() : "已停0小时0分";
+            textStayTime.setText(stayTime);
+        }
+
+        // 设置实际金额(分转元)
+        if (textActualAmount != null) {
+            double amount = feeInfo.getActualAmount() / 100.0;
+            textActualAmount.setText(String.format("%.2f", amount));
+        }
+
+        // 设置减免金额
+        if (textDiscountAmount != null && feeInfo.getDiscountAmount() > 0) {
+            double discountAmount = feeInfo.getDiscountAmount() / 100.0;
+            textDiscountAmount.setText(String.format("已减免%.2f元", discountAmount));
+            textDiscountAmount.setVisibility(VISIBLE);
+        } else {
+            textDiscountAmount.setVisibility(HIDE);
+        }
+    }
+
+    /**
+     * 显示未入场卡片 (feeType 10或12)
+     */
+    private void showNoEntryCard() {
+        if (cardNoEntry != null) {
+            cardNoEntry.setVisibility(VISIBLE);
+        }
+    }
+
+    /**
+     * 显示黑名单卡片 (feeType 14)
+     */
+    private void showBlacklistCard(api.ParkingFeeInfo feeInfo) {
+        if (cardBlacklist == null) return;
+
+        cardBlacklist.setVisibility(VISIBLE);
+
+        if (textParkNameBlacklist != null) {
+            String parkName = feeInfo.getParkName() != null ? feeInfo.getParkName() : "";
+            textParkNameBlacklist.setText(parkName);
+        }
+
+        if (textStayTimeBlacklist != null) {
+            String stayTime = feeInfo.getStayTime() != null ? "已停" + feeInfo.getStayTime() : "";
+            textStayTimeBlacklist.setText(stayTime);
+        }
+    }
+
+    /**
+     * 显示月卡卡片 (feeType 3)
+     */
+    private void showMonthlyCard(api.ParkingFeeInfo feeInfo) {
+        if (cardMonthly == null) return;
+
+        cardMonthly.setVisibility(VISIBLE);
+
+        if (textParkNameMonthly != null) {
+            String parkName = feeInfo.getParkName() != null ? feeInfo.getParkName() : "";
+            textParkNameMonthly.setText(parkName);
+        }
+
+        if (textStayTimeMonthly != null) {
+            String stayTime = feeInfo.getStayTime() != null ? "已停" + feeInfo.getStayTime() : "";
+            textStayTimeMonthly.setText(stayTime);
+        }
+    }
+
+    /**
+     * 显示无需缴费卡片 (feeType 1/2/4/5/13)
+     */
+    private void showNoFeeCard(api.ParkingFeeInfo feeInfo) {
+        if (cardNoFee == null) return;
+
+        cardNoFee.setVisibility(VISIBLE);
+
+        if (textParkNameNoFee != null) {
+            String parkName = feeInfo.getParkName() != null ? feeInfo.getParkName() : "";
+            textParkNameNoFee.setText(parkName);
+        }
+
+        if (textStayTimeNoFee != null) {
+            String stayTime = feeInfo.getStayTime() != null ? "已停" + feeInfo.getStayTime() : "";
+            textStayTimeNoFee.setText(stayTime);
+        }
+    }
+
+    /**
+     * 显示全额优惠卡片 (feeType 6)
+     */
+    private void showFullDiscountCard(api.ParkingFeeInfo feeInfo) {
+        if (cardFullDiscount == null) return;
+
+        cardFullDiscount.setVisibility(VISIBLE);
+
+        if (textParkNameFullDiscount != null) {
+            String parkName = feeInfo.getParkName() != null ? feeInfo.getParkName() : "";
+            textParkNameFullDiscount.setText(parkName);
         }
 
-        if (textTotalFee != null) {
-            textTotalFee.setText("¥" + feeInfo.getTotalFee());
+        if (textStayTimeFullDiscount != null) {
+            String stayTime = feeInfo.getStayTime() != null ? "已停" + feeInfo.getStayTime() : "";
+            textStayTimeFullDiscount.setText(stayTime);
         }
     }
 

+ 23 - 34
entry/src/main/java/com/fujica/abk/slice/MainAbilitySlice.java

@@ -296,6 +296,7 @@ public class MainAbilitySlice extends AbilitySlice {
                         switch (position) {
                             case 0: // 我的
                                 chargeComponent = new ChargeComponent(MainAbilitySlice.this);
+                                chargeComponent.setLoadingComponent(loadingComponent);
                                 page = chargeComponent;
                                 break;
                             case 1: // 找车位
@@ -443,11 +444,7 @@ public class MainAbilitySlice extends AbilitySlice {
                         if (success) {
                             Log.info("登录成功,切换到缴费记录页面");
                             // 登录成功后切换到缴费记录页面
-                            EventRunner mainRunner = EventRunner.getMainEventRunner();
-                            if (mainRunner != null) {
-                                EventHandler mainHandler = new EventHandler(mainRunner);
-                                mainHandler.postTask(() -> switchToPage(2));
-                            }
+                            DialogUtil.postTask(() -> switchToPage(2));
                         } else {
                             Toast.error(this, "登录失败,请重试");
                         }
@@ -608,19 +605,15 @@ public class MainAbilitySlice extends AbilitySlice {
     private void subscribeLoginSuccessEvent() {
         loginSuccessListener = event -> {
             // 在主线程更新UI
-            EventRunner mainRunner = EventRunner.getMainEventRunner();
-            if (mainRunner != null) {
-                EventHandler mainHandler = new EventHandler(mainRunner);
-                mainHandler.postTask(() -> {
-                    Log.info("收到登录成功事件,更新UI");
-                    // 刷新我的页面
-                    if (chargeComponent != null) {
-                        chargeComponent.refresh();
-                    }
-                    quit.setVisibility(Component.VISIBLE);
-                    // 可以在这里添加其他需要更新的UI逻辑
-                });
-            }
+            DialogUtil.postTask(() -> {
+                Log.info("收到登录成功事件,更新UI");
+                // 刷新我的页面
+                if (chargeComponent != null) {
+                    chargeComponent.refresh();
+                }
+                quit.setVisibility(Component.VISIBLE);
+                // 可以在这里添加其他需要更新的UI逻辑
+            });
         };
         EventBus.getInstance().on("onLoginSuccess", loginSuccessListener);
     }
@@ -631,22 +624,18 @@ public class MainAbilitySlice extends AbilitySlice {
     private void subscribeAuthChangedEvent() {
         authChangedListener = event -> {
             // 在主线程更新UI
-            EventRunner mainRunner = EventRunner.getMainEventRunner();
-            if (mainRunner != null) {
-                EventHandler mainHandler = new EventHandler(mainRunner);
-                mainHandler.postTask(() -> {
-                    Log.error("收到认证状态变化事件,更新UI");
-                    // 隐藏退出按钮
-                    if (quit != null) {
-                        quit.setVisibility(Component.HIDE);
-                    }
-                    // 刷新我的页面
-                    if (chargeComponent != null) {
-                        chargeComponent.refresh();
-                    }
-                    // 可以在这里添加其他需要更新的UI逻辑
-                });
-            }
+            DialogUtil.postTask(() -> {
+                Log.error("收到认证状态变化事件,更新UI");
+                // 隐藏退出按钮
+                if (quit != null) {
+                    quit.setVisibility(Component.HIDE);
+                }
+                // 刷新我的页面
+                if (chargeComponent != null) {
+                    chargeComponent.refresh();
+                }
+                // 可以在这里添加其他需要更新的UI逻辑
+            });
         };
         EventBus.getInstance().on("onLoginExpired", authChangedListener);
     }

+ 33 - 25
entry/src/main/java/com/fujica/abk/utils/DialogUtil.java

@@ -11,7 +11,7 @@ import ohos.eventhandler.EventRunner;
  * 统一设置样式,使对话框内容左右居中显示
  */
 public class DialogUtil {
-    
+
     /**
      * 单选监听器接口
      */
@@ -19,22 +19,23 @@ public class DialogUtil {
     public interface SingleSelectListener {
         /**
          * 当选择某个选项时调用
+         *
          * @param dialog 对话框对象
-         * @param index 选中的索引
+         * @param index  选中的索引
          */
         void onSelect(IDialog dialog, int index);
     }
-    
+
     /**
      * 创建并配置自定义 ListDialog(公共方法)
      * 使用 XML 布局,美化显示,固定宽度 280vp
-     * 
-     * @param context 上下文
-     * @param options 选项数组
+     *
+     * @param context  上下文
+     * @param options  选项数组
      * @param listener 选择监听器
      * @return 配置好的 CustomListDialog
      */
-    public static CustomListDialog createListDialog(Context context, String[] options, 
+    public static CustomListDialog createListDialog(Context context, String[] options,
                                                     SingleSelectListener listener) {
         CustomListDialog customListDialog = new CustomListDialog(context);
         customListDialog.setItems(options);
@@ -65,16 +66,15 @@ public class DialogUtil {
                 }, index);
             }
         });
-        
+
         return customListDialog;
     }
 
-
-
     /**
      * 显示确认对话框
-     * @param context 上下文
-     * @param message 提示信息
+     *
+     * @param context   上下文
+     * @param message   提示信息
      * @param onConfirm 确定按钮回调
      */
     public static void confirm(Context context, String message, Runnable onConfirm) {
@@ -83,27 +83,19 @@ public class DialogUtil {
 
     /**
      * 显示确认对话框
-     * @param context 上下文
-     * @param message 提示信息
+     *
+     * @param context   上下文
+     * @param message   提示信息
      * @param onConfirm 确定按钮回调
-     * @param onCancel 取消按钮回调
+     * @param onCancel  取消按钮回调
      */
     public static void confirm(Context context, String message, Runnable onConfirm, Runnable onCancel) {
         if (context == null) {
             return;
         }
 
-        // 获取主线程的 EventRunner
-        EventRunner mainRunner = EventRunner.getMainEventRunner();
-        if (mainRunner == null) {
-            // 如果获取不到主线程,直接在当前线程显示
-            showConfirmDialog(context, message, onConfirm, onCancel);
-            return;
-        }
-
         // 创建主线程的 EventHandler,在主线程显示对话框
-        EventHandler mainHandler = new EventHandler(mainRunner);
-        mainHandler.postTask(() -> {
+        DialogUtil.postTask(() -> {
             showConfirmDialog(context, message, onConfirm, onCancel);
         });
     }
@@ -128,5 +120,21 @@ public class DialogUtil {
                 })
                 .show();
     }
+
+    public static void postTask(Runnable task) {
+        EventRunner mainRunner = EventRunner.getMainEventRunner();
+        if (mainRunner != null) {
+            EventHandler mainHandler = new EventHandler(mainRunner);
+            mainHandler.postTask(task);
+        }
+    }
+
+    public static void postTask(Runnable task, long delayTime) throws IllegalArgumentException {
+        EventRunner mainRunner = EventRunner.getMainEventRunner();
+        if (mainRunner != null) {
+            EventHandler mainHandler = new EventHandler(mainRunner);
+            mainHandler.postTask(task, delayTime);
+        }
+    }
 }
 

+ 1 - 10
entry/src/main/java/com/fujica/abk/utils/Toast.java

@@ -14,17 +14,8 @@ public class Toast {
         if (context == null) {
             return;
         }
-        // 获取主线程的 EventRunner
-        EventRunner mainRunner = EventRunner.getMainEventRunner();
-        if (mainRunner == null) {
-            // 如果获取不到主线程,直接在当前线程显示(可能已经是主线程)
-            new ToastDialog(context).setText(message).show();
-            return;
-        }
-        
         // 创建主线程的 EventHandler
-        EventHandler mainHandler = new EventHandler(mainRunner);
-        mainHandler.postTask(() -> {
+        DialogUtil.postTask(() -> {
             new ToastDialog(context).setText(message).show();
         });
     }

+ 288 - 23
entry/src/main/java/com/fujica/abk/utils/api.java

@@ -199,7 +199,8 @@ public class api {
     }
 
     /**
-     * 模拟查询停车费用API
+     * 查询停车费用API (真实接口)
+     * 参考 TypeScript 版本的 pay.getChargeData 实现
      *
      * @param context      上下文
      * @param licensePlate 车牌号
@@ -208,34 +209,103 @@ public class api {
     public static CompletableFuture<R<ParkingFeeInfo>> queryParkingFee(Context context, String licensePlate) {
         return CompletableFuture.supplyAsync(() -> {
             try {
-                // 模拟网络延迟
-                Thread.sleep(500);
-
-                // 模拟返回数据
-                ParkingFeeInfo feeInfo = new ParkingFeeInfo();
-                feeInfo.setLicensePlate(licensePlate);
-                feeInfo.setParkingLotName("认证后查看车场名称");
-                feeInfo.setParkingDays(48);
-                feeInfo.setParkingHours(20);
-                feeInfo.setParkingMinutes(48);
-                feeInfo.setTotalFee(490);
-
-                R<ParkingFeeInfo> result = new R<>();
-                result.setSuccess(true);
-                result.setMsg("查询成功");
-                result.setCode(200);
-                result.setData(feeInfo);
-
-                return result;
-            } catch (InterruptedException e) {
-                Thread.currentThread().interrupt();
-                return new R<>("查询失败: " + e.getMessage());
+                // 构建请求参数
+                ChargeQuery query = new ChargeQuery();
+                query.setChargeScene(2);  // 计费场景: 2
+                query.setPlateNo(licensePlate);
+
+                // 第一步: 调用 /cg/chargeByUnify 接口
+                ApiOption option = new ApiOption("/cg/chargeByUnify", query);
+                option.setMethod(ApiOption.POST);
+                option.setToast(false);  // 不显示错误提示
+
+                TypeToken<R<ParkingFeeInfo>> typeToken = new TypeToken<R<ParkingFeeInfo>>() {};
+                R<ParkingFeeInfo> result = http(context, option, typeToken).get();
+
+                // 判断是否需要轮询
+                if (result != null && result.isSuccess() && result.getData() != null) {
+                    String resultKey = result.getData().getResultKey();
+                    
+                    if (resultKey != null && !resultKey.isEmpty()) {
+                        // 第二步: 有 resultKey,需要轮询 /cg/getChargeResult
+                        return pollChargeResult(context, resultKey);
+                    } else {
+                        // 直接返回结果
+                        return result;
+                    }
+                } else {
+                    return result;
+                }
             } catch (Exception e) {
+                Log.error("查询停车费用失败: " + e.getMessage());
                 return new R<>("查询失败: " + e.getMessage());
             }
         });
     }
 
+    /**
+     * 轮询获取计费结果
+     * 参考 TypeScript 版本的 getLocalCharge 实现
+     *
+     * @param context   上下文
+     * @param resultKey 结果key
+     * @return 停车费用信息
+     */
+    private static R<ParkingFeeInfo> pollChargeResult(Context context, String resultKey) {
+        int maxAttempts = 10;  // 最多轮询10次
+        int pollInterval = 500;  // 每次间隔500ms
+
+        for (int count = 0; count < maxAttempts; count++) {
+            try {
+                // 延迟
+                if (count > 0) {
+                    Thread.sleep(pollInterval);
+                }
+
+                // 构建请求参数
+                java.util.HashMap<String, Object> params = new java.util.HashMap<>();
+                params.put("resultKey", resultKey);
+
+                ApiOption option = new ApiOption("/cg/getChargeResult", params);
+                option.setMethod(ApiOption.GET);
+                option.setToast(false);
+
+                TypeToken<R<ParkingFeeInfo>> typeToken = new TypeToken<R<ParkingFeeInfo>>() {};
+                R<ParkingFeeInfo> result = http(context, option, typeToken).get();
+
+                if (result != null) {
+                    if (!result.isSuccess()) {
+                        // 请求失败但有数据,返回结果
+                        if (result.getData() != null) {
+                            return result;
+                        } else {
+                            return new R<>("计费信息为空");
+                        }
+                    } else {
+                        // 请求成功
+                        if (result.getData() != null) {
+                            // 有数据,返回结果
+                            return result;
+                        } else {
+                            // 没有数据,继续轮询
+                            if (count >= maxAttempts - 1) {
+                                // 已达到最大轮询次数,超时
+                                return new R<>("timeout");
+                            }
+                            // 继续下一次轮询
+                        }
+                    }
+                }
+            } catch (Exception e) {
+                Log.error("轮询计费结果失败: " + e.getMessage());
+                return new R<>("轮询失败: " + e.getMessage());
+            }
+        }
+
+        // 超时
+        return new R<>("timeout");
+    }
+
     /**
      * 停车费用信息类
      */
@@ -246,6 +316,20 @@ public class api {
         private int parkingHours;
         private int parkingMinutes;
         private int totalFee;
+        
+        // 新增字段,参考 index.vue 中的 chargeData
+        private int feeType; // 费用类型: 0-正常缴费, 1-无需缴费, 2-已缴费免费离场时间内, 3-月卡车辆, 4-免费时间内, 5-无需缴费, 6-全额优惠, 10-未入场, 12-场外月卡, 13-欠费补缴, 14-黑名单, 16-临停加欠费补缴
+        private String parkName; // 车场名称
+        private String stayTime; // 停车时长(格式化后的字符串)
+        private int actualAmount; // 实际金额(分)
+        private int discountAmount; // 减免金额(分)
+        private String plateNo; // 车牌号
+        private String plateColor; // 车牌颜色
+        private String parkId; // 车场ID
+        private String cardId; // 月卡ID
+        private boolean rzStatus; // 认证状态
+        private java.util.List<ArrearageOrder> followList; // 历史欠费订单列表
+        private String resultKey; // 计费结果key (用于轮询)
 
         public String getLicensePlate() {
             return licensePlate;
@@ -294,5 +378,186 @@ public class api {
         public void setTotalFee(int totalFee) {
             this.totalFee = totalFee;
         }
+
+        public int getFeeType() {
+            return feeType;
+        }
+
+        public void setFeeType(int feeType) {
+            this.feeType = feeType;
+        }
+
+        public String getParkName() {
+            return parkName;
+        }
+
+        public void setParkName(String parkName) {
+            this.parkName = parkName;
+        }
+
+        public String getStayTime() {
+            return stayTime;
+        }
+
+        public void setStayTime(String stayTime) {
+            this.stayTime = stayTime;
+        }
+
+        public int getActualAmount() {
+            return actualAmount;
+        }
+
+        public void setActualAmount(int actualAmount) {
+            this.actualAmount = actualAmount;
+        }
+
+        public int getDiscountAmount() {
+            return discountAmount;
+        }
+
+        public void setDiscountAmount(int discountAmount) {
+            this.discountAmount = discountAmount;
+        }
+
+        public String getPlateNo() {
+            return plateNo;
+        }
+
+        public void setPlateNo(String plateNo) {
+            this.plateNo = plateNo;
+        }
+
+        public String getPlateColor() {
+            return plateColor;
+        }
+
+        public void setPlateColor(String plateColor) {
+            this.plateColor = plateColor;
+        }
+
+        public String getParkId() {
+            return parkId;
+        }
+
+        public void setParkId(String parkId) {
+            this.parkId = parkId;
+        }
+
+        public String getCardId() {
+            return cardId;
+        }
+
+        public void setCardId(String cardId) {
+            this.cardId = cardId;
+        }
+
+        public boolean isRzStatus() {
+            return rzStatus;
+        }
+
+        public void setRzStatus(boolean rzStatus) {
+            this.rzStatus = rzStatus;
+        }
+
+        public java.util.List<ArrearageOrder> getFollowList() {
+            return followList;
+        }
+
+        public void setFollowList(java.util.List<ArrearageOrder> followList) {
+            this.followList = followList;
+        }
+
+        public String getResultKey() {
+            return resultKey;
+        }
+
+        public void setResultKey(String resultKey) {
+            this.resultKey = resultKey;
+        }
+    }
+
+    /**
+     * 欠费订单信息类
+     */
+    public static class ArrearageOrder {
+        private String orderId;        // 订单ID
+        private String parkName;       // 车场名称
+        private int amount;            // 欠费金额(分)
+        private String createTime;     // 创建时间
+        private String plateNo;        // 车牌号
+
+        public String getOrderId() {
+            return orderId;
+        }
+
+        public void setOrderId(String orderId) {
+            this.orderId = orderId;
+        }
+
+        public String getParkName() {
+            return parkName;
+        }
+
+        public void setParkName(String parkName) {
+            this.parkName = parkName;
+        }
+
+        public int getAmount() {
+            return amount;
+        }
+
+        public void setAmount(int amount) {
+            this.amount = amount;
+        }
+
+        public String getCreateTime() {
+            return createTime;
+        }
+
+        public void setCreateTime(String createTime) {
+            this.createTime = createTime;
+        }
+
+        public String getPlateNo() {
+            return plateNo;
+        }
+
+        public void setPlateNo(String plateNo) {
+            this.plateNo = plateNo;
+        }
+    }
+
+    /**
+     * 计费查询请求参数类
+     * 对应 TypeScript 的 ChargeQuery
+     */
+    public static class ChargeQuery {
+        private int chargeScene;  // 计费场景: 2-临停缴费
+        private String plateNo;   // 车牌号
+        private String parkId;    // 车场ID (可选)
+
+        public int getChargeScene() {
+            return chargeScene;
+        }
+
+        public void setChargeScene(int chargeScene) {
+            this.chargeScene = chargeScene;
+        }
+
+        public String getPlateNo() {
+            return plateNo;
+        }
+
+        public void setPlateNo(String plateNo) {
+            this.plateNo = plateNo;
+        }
+
+        public String getParkId() {
+            return parkId;
+        }
+
+        public void setParkId(String parkId) {
+            this.parkId = parkId;
+        }
     }
 }

+ 406 - 101
entry/src/main/resources/base/layout/layout_charge.xml

@@ -6,146 +6,451 @@
     ohos:background_element="#FFF"
     ohos:orientation="vertical">
 
-    <ScrollView
-        ohos:height="match_parent"
-        ohos:width="match_parent">
-            <!-- 有车牌缓存时显示的停车信息卡片 -->
+    <!-- 日期筛选 -->
+    <DirectionalLayout
+        ohos:id="$+id:filter_plateNo"
+        ohos:height="match_content"
+        ohos:width="match_parent"
+        ohos:background_element="#F5F5F5"
+        ohos:bottom_padding="12vp"
+        ohos:left_padding="20vp"
+        ohos:orientation="horizontal"
+        ohos:right_padding="20vp"
+        ohos:alignment="start|center"
+        ohos:top_padding="12vp"
+        >
+
+        <Text
+            ohos:id="$+id:text_plateNo"
+            ohos:height="match_content"
+            ohos:width="match_content"
+            ohos:text="粤B11111"
+            ohos:text_color="#FF000000"
+            ohos:text_size="16fp"/>
+        <Image ohos:width="15vp" ohos:left_margin="8vp" ohos:height="15vp" ohos:image_src="$media:change" ohos:scale_mode="stretch"></Image>
+
+    </DirectionalLayout>
+
+    <DirectionalLayout
+        ohos:height="0"
+        ohos:width="match_parent"
+        ohos:bottom_margin="20vp"
+        ohos:left_margin="20vp"
+        ohos:orientation="vertical"
+        ohos:right_margin="20vp"
+        ohos:weight="1">
+
+
+        <!-- feeType 0或16: 正常缴费或临停加欠费补缴 -->
+        <DirectionalLayout
+            ohos:id="$+id:card_normal_fee"
+            ohos:height="match_parent"
+            ohos:width="match_parent"
+            ohos:orientation="vertical"
+            ohos:visibility="hide">
+
+            <!-- 车场名称和停车时长 -->
             <DirectionalLayout
-                ohos:id="$+id:parking_info_card"
                 ohos:height="match_content"
                 ohos:width="match_parent"
-                ohos:orientation="vertical"
-                ohos:background_element="#FFFFFFFF"
-                ohos:corner_radius="12vp"
-                ohos:margin="16vp"
-                ohos:padding="16vp"
-                ohos:visibility="hide">
+                ohos:bottom_margin="16vp"
+                ohos:orientation="horizontal"
+                ohos:top_padding="12vp">
 
-                <!-- 车牌号头部 -->
-                <DirectionalLayout
+                <Text
+                    ohos:id="$+id:text_park_name"
                     ohos:height="match_content"
-                    ohos:width="match_parent"
-                    ohos:orientation="horizontal"
-                    ohos:alignment="center"
-                    ohos:background_element="#FFF5F5F5"
-                    ohos:corner_radius="8vp"
-                    ohos:padding="12vp"
-                    ohos:bottom_margin="16vp">
+                    ohos:width="0vp"
+                    ohos:text="车场名称"
+                    ohos:text_alignment="start"
+                    ohos:text_color="#FF555555"
+                    ohos:text_size="14fp"
+                    ohos:weight="1"/>
 
-                    <Text
-                        ohos:id="$+id:text_license_plate"
-                        ohos:height="match_content"
-                        ohos:width="0vp"
-                        ohos:weight="1"
-                        ohos:text=""
-                        ohos:text_size="18fp"
-                        ohos:text_color="#FF000000"
-                        ohos:text_alignment="center"/>
-
-                    <Image
-                        ohos:id="$+id:img_dropdown"
-                        ohos:height="20vp"
-                        ohos:width="20vp"
-                        ohos:image_src="media:icon"
-                        ohos:start_margin="8vp"/>
-                </DirectionalLayout>
+                <Text
+                    ohos:id="$+id:text_stay_time"
+                    ohos:height="match_content"
+                    ohos:width="match_content"
+                    ohos:text="已停0小时0分"
+                    ohos:text_alignment="end"
+                    ohos:text_color="#FF555555"
+                    ohos:text_size="14fp"/>
+            </DirectionalLayout>
+
+            <!-- 金额显示 -->
+            <DirectionalLayout
+                ohos:height="0"
+                ohos:width="match_parent"
+                ohos:alignment="center"
+                ohos:bottom_margin="16vp"
+                ohos:orientation="vertical"
+                ohos:weight="1">
 
-                <!-- 停车信息 -->
                 <DirectionalLayout
                     ohos:height="match_content"
-                    ohos:width="match_parent"
-                    ohos:orientation="vertical"
-                    ohos:bottom_margin="16vp">
+                    ohos:width="match_content"
+                    ohos:alignment="bottom"
+                    ohos:orientation="horizontal">
 
-                    <DirectionalLayout
+                    <Text
                         ohos:height="match_content"
-                        ohos:width="match_parent"
-                        ohos:orientation="horizontal"
-                        ohos:bottom_margin="8vp">
-
-                        <Text
-                            ohos:height="match_content"
-                            ohos:width="0vp"
-                            ohos:weight="1"
-                            ohos:text="认证后查看车场名称>"
-                            ohos:text_size="14fp"
-                            ohos:text_color="#FF0066FF"
-                            ohos:text_alignment="start"/>
-
-                        <Text
-                            ohos:id="$+id:text_parking_duration"
-                            ohos:height="match_content"
-                            ohos:width="match_content"
-                            ohos:text="已停48天20小时48分"
-                            ohos:text_size="14fp"
-                            ohos:text_color="#FA6332"
-                            ohos:text_alignment="end"/>
-                    </DirectionalLayout>
+                        ohos:width="match_content"
+                        ohos:text="¥"
+                        ohos:text_color="#FFFF7B0B"
+                        ohos:text_size="24fp"/>
 
                     <Text
-                        ohos:id="$+id:text_total_fee"
+                        ohos:id="$+id:text_actual_amount"
                         ohos:height="match_content"
-                        ohos:width="match_parent"
-                        ohos:text="¥490"
-                        ohos:text_size="32fp"
-                        ohos:text_color="#FA6332"
-                        ohos:text_alignment="center"
-                        ohos:top_margin="8vp"/>
+                        ohos:width="match_content"
+                        ohos:text="0"
+                        ohos:text_color="#FFFF7B0B"
+                        ohos:text_size="40fp"
+                        ohos:text_weight="700"/>
                 </DirectionalLayout>
 
-                <!-- 立即缴费按钮 -->
-                <Button
-                    ohos:id="$+id:btn_pay_now"
-                    ohos:height="48vp"
-                    ohos:width="match_parent"
-                    ohos:text="立即缴费"
-                    ohos:text_size="16fp"
-                    ohos:text_color="#FFFFFFFF"
-                    ohos:background_element="#FA6332"
-                    ohos:corner_radius="24vp"/>
+                <Text
+                    ohos:id="$+id:text_discount_amount"
+                    ohos:height="match_content"
+                    ohos:width="match_content"
+                    ohos:text="sdfdsfs"
+                    ohos:text_color="#FFFF7B0B"
+                    ohos:text_size="14fp"
+                    />
+            </DirectionalLayout>
+
+            <!-- 立即缴费按钮 -->
+            <Button
+                ohos:id="$+id:btn_pay_now"
+                ohos:height="48vp"
+                ohos:width="match_parent"
+                ohos:background_element="$graphic:button"
+                ohos:text="立即缴费"
+                ohos:text_color="#FFFFFFFF"
+                ohos:text_size="16fp"
+                />
+        </DirectionalLayout>
+
+        <!-- feeType 10或12: 未入场或场外月卡 -->
+        <DirectionalLayout
+            ohos:id="$+id:card_no_entry"
+            ohos:height="match_parent"
+            ohos:width="match_parent"
+            ohos:alignment="center"
+            ohos:orientation="vertical"
+            ohos:visibility="hide">
+
+            <DirectionalLayout
+                ohos:height="match_parent"
+                ohos:width="match_parent"
+                ohos:alignment="center"
+                ohos:bottom_margin="20vp"
+                ohos:orientation="vertical"
+                ohos:top_margin="20vp"
+                ohos:weight="1">
+
+                <Text
+                    ohos:height="match_content"
+                    ohos:width="match_content"
+                    ohos:bottom_margin="10vp"
+                    ohos:text="未查询到车辆入场信息"
+                    ohos:text_color="#FF222222"
+                    ohos:text_size="16fp"/>
+
+                <Text
+                    ohos:height="match_content"
+                    ohos:width="match_content"
+                    ohos:text="如在场内请咨询管理处"
+                    ohos:text_color="#FF888888"
+                    ohos:text_size="14fp"/>
             </DirectionalLayout>
 
-            <!-- 无车牌缓存时显示的添加车辆卡片 -->
+            <Button
+                ohos:id="$+id:btn_refresh"
+                ohos:height="48vp"
+                ohos:width="match_parent"
+                ohos:background_element="$graphic:button"
+                ohos:text="刷新试试"
+                ohos:text_color="#FFFFFFFF"
+                ohos:text_size="16fp"/>
+        </DirectionalLayout>
+
+        <!-- feeType 14: 黑名单车辆 -->
+        <DirectionalLayout
+            ohos:id="$+id:card_blacklist"
+            ohos:height="match_parent"
+            ohos:width="match_parent"
+            ohos:orientation="vertical"
+            ohos:visibility="hide"
+            >
+
             <DirectionalLayout
-                ohos:layout_alignment="center"
-                ohos:id="$+id:add_vehicle_card"
                 ohos:height="match_content"
                 ohos:width="match_parent"
+                ohos:orientation="horizontal"
+                ohos:top_padding="12vp">
+
+                <Text
+                    ohos:id="$+id:text_park_name_blacklist"
+                    ohos:height="match_content"
+                    ohos:width="0vp"
+                    ohos:text="车场名称"
+                    ohos:text_alignment="start"
+                    ohos:text_color="#FF555555"
+                    ohos:text_size="14fp"
+                    ohos:weight="1"
+                    />
+
+                <Text
+                    ohos:id="$+id:text_stay_time_blacklist"
+                    ohos:height="match_content"
+                    ohos:width="match_content"
+                    ohos:text="停车时长"
+                    ohos:text_alignment="end"
+                    ohos:text_color="#FF555555"
+                    ohos:text_size="14fp"
+                    />
+            </DirectionalLayout>
+
+            <DirectionalLayout
+                ohos:height="0"
+                ohos:weight="1"
+                ohos:width="match_parent"
+                ohos:alignment="center"
+                ohos:bottom_margin="20vp"
                 ohos:orientation="vertical"
+                ohos:top_margin="20vp">
+
+                <Text
+                    ohos:height="match_content"
+                    ohos:width="match_content"
+                    ohos:bottom_margin="10vp"
+                    ohos:text="不支持手机缴费"
+                    ohos:text_color="#FF222222"
+                    ohos:text_size="16fp"/>
+
+                <Text
+                    ohos:height="match_content"
+                    ohos:width="match_content"
+                    ohos:text="请到收费处缴费"
+                    ohos:text_color="#FF888888"
+                    ohos:text_size="14fp"/>
+            </DirectionalLayout>
+        </DirectionalLayout>
+
+        <!-- feeType 3: 月卡车辆 -->
+        <DirectionalLayout
+            ohos:id="$+id:card_monthly"
+            ohos:height="match_parent"
+            ohos:width="match_parent"
+            ohos:orientation="vertical"
+            ohos:visibility="hide"
+
+            >
+
+            <DirectionalLayout
+                ohos:height="match_content"
+                ohos:width="match_parent"
+                ohos:bottom_margin="16vp"
+                ohos:orientation="horizontal"
+                ohos:top_padding="12vp">
+
+                <Text
+                    ohos:id="$+id:text_park_name_monthly"
+                    ohos:height="match_content"
+                    ohos:width="0vp"
+                    ohos:text="车场名称"
+                    ohos:text_alignment="start"
+                    ohos:text_color="#FF555555"
+                    ohos:text_size="14fp"
+                    ohos:weight="1"
+                    />
+
+                <Text
+                    ohos:id="$+id:text_stay_time_monthly"
+                    ohos:height="match_content"
+                    ohos:width="match_content"
+                    ohos:text="停车时长"
+                    ohos:text_alignment="end"
+                    ohos:text_color="#FF555555"
+                    ohos:text_size="14fp"
+                    />
+            </DirectionalLayout>
+
+            <Text
+                ohos:height="0"
+                ohos:weight="1"
+                ohos:width="match_parent"
+                ohos:bottom_margin="30vp"
+                ohos:text="月卡车辆"
+                ohos:text_alignment="center"
+                ohos:text_color="#FF222222"
+                ohos:text_size="18fp"
+                ohos:text_weight="700"
+                ohos:top_margin="20vp"/>
+
+            <Button
+                ohos:id="$+id:btn_renew"
+                ohos:height="48vp"
+                ohos:width="match_parent"
+                ohos:background_element="$graphic:button"
+                ohos:text="立即续费"
+                ohos:text_color="#FFFFFFFF"
+                ohos:text_size="16fp"
+                />
+        </DirectionalLayout>
+
+        <!-- feeType 1/2/4/5/13: 无需缴费 -->
+        <DirectionalLayout
+            ohos:id="$+id:card_no_fee"
+            ohos:height="match_parent"
+            ohos:width="match_parent"
+            ohos:orientation="vertical"
+            ohos:visibility="hide">
+
+            <DirectionalLayout
+                ohos:height="match_content"
+                ohos:width="match_parent"
+                ohos:bottom_margin="16vp"
+                ohos:orientation="horizontal"
+                ohos:top_padding="12vp">
+
+                <Text
+                    ohos:id="$+id:text_park_name_no_fee"
+                    ohos:height="match_content"
+                    ohos:width="0vp"
+                    ohos:text="车场名称"
+                    ohos:text_alignment="start"
+                    ohos:text_color="#FF555555"
+                    ohos:text_size="14fp"
+                    ohos:weight="1"
+                    />
+
+                <Text
+                    ohos:id="$+id:text_stay_time_no_fee"
+                    ohos:height="match_content"
+                    ohos:width="match_content"
+                    ohos:text="停车时长"
+                    ohos:text_alignment="end"
+                    ohos:text_color="#FF555555"
+                    ohos:text_size="14fp"
+                    />
+            </DirectionalLayout>
+
+            <Text
+                ohos:height="0"
+                ohos:weight="1"
+                ohos:width="match_parent"
+                ohos:bottom_margin="40vp"
+                ohos:text="无需缴费"
+                ohos:text_alignment="center"
+                ohos:text_color="#FF222222"
+                ohos:text_size="18fp"
+                ohos:text_weight="700"
+                ohos:top_margin="40vp"/>
+        </DirectionalLayout>
+
+        <!-- feeType 6: 全额优惠,无需缴费 -->
+        <DirectionalLayout
+            ohos:id="$+id:card_full_discount"
+            ohos:height="match_parent"
+            ohos:width="match_parent"
+            ohos:orientation="vertical"
+            ohos:visibility="hide">
+
+            <DirectionalLayout
+                ohos:height="match_content"
+                ohos:width="match_parent"
+                ohos:bottom_margin="16vp"
+                ohos:orientation="horizontal"
+                ohos:top_padding="12vp">
+
+                <Text
+                    ohos:id="$+id:text_park_name_full_discount"
+                    ohos:height="match_content"
+                    ohos:width="0vp"
+                    ohos:text="车场名称"
+                    ohos:text_alignment="start"
+                    ohos:text_color="#FF555555"
+                    ohos:text_size="14fp"
+                    ohos:weight="1"
+                    />
+
+                <Text
+                    ohos:id="$+id:text_stay_time_full_discount"
+                    ohos:height="match_content"
+                    ohos:width="match_content"
+                    ohos:text="停车时长"
+                    ohos:text_alignment="end"
+                    ohos:text_color="#FF555555"
+                    ohos:text_size="14fp"
+                    />
+            </DirectionalLayout>
+
+            <Text
+                ohos:height="0"
+                ohos:weight="1"
+                ohos:width="match_parent"
+                ohos:bottom_margin="40vp"
+                ohos:text="全额优惠,无需缴费"
+                ohos:text_alignment="center"
+                ohos:text_color="#FF222222"
+                ohos:text_size="16fp"
+                ohos:top_margin="40vp"/>
+        </DirectionalLayout>
+
+        <!-- 无车牌缓存时显示的添加车辆卡片 -->
+        <DirectionalLayout
+            ohos:id="$+id:add_vehicle_card"
+            ohos:height="match_parent"
+            ohos:width="match_parent"
+            ohos:alignment="center"
+            ohos:layout_alignment="center"
+            ohos:orientation="vertical"
+            ohos:visibility="visible">
+
+
+            <DirectionalLayout
+                ohos:height="0"
+                ohos:weight="1"
+                ohos:width="match_parent"
                 ohos:alignment="center"
-                ohos:visibility="visible">
+                ohos:layout_alignment="center"
+                ohos:orientation="vertical">
 
                 <!-- 汽车图标 -->
                 <Image
                     ohos:id="$+id:img_car"
                     ohos:height="40vp"
                     ohos:width="50vp"
-                    ohos:scale_mode="stretch"
-                    ohos:image_src="$media:nocar"/>
+                    ohos:image_src="$media:nocar"
+                    ohos:scale_mode="stretch"/>
 
                 <!-- 提示文字 -->
                 <Text
-                    ohos:top_margin="24vp"
                     ohos:id="$+id:text_add_vehicle_tip"
                     ohos:height="match_content"
                     ohos:width="match_parent"
+                    ohos:bottom_margin="24vp"
                     ohos:text="添加车辆快捷缴费,免排队、免找零"
-                    ohos:text_size="16fp"
+                    ohos:text_alignment="center"
                     ohos:text_color="#FF333333"
-                    ohos:text_alignment="center"/>
-
-                <!-- 输入车牌缴费按钮 -->
-                <Button
-                    ohos:margin="24vp"
-                    ohos:id="$+id:btn_input_license_plate"
-                    ohos:height="48vp"
-                    ohos:width="match_parent"
-                    ohos:text="输入车牌缴费"
                     ohos:text_size="16fp"
-                    ohos:text_color="#FFFFFFFF"
-                    ohos:background_element="$graphic:button"/>
+                    ohos:top_margin="24vp"/>
+
             </DirectionalLayout>
+            <!-- 输入车牌缴费按钮 -->
+            <Button
+                ohos:id="$+id:btn_input_license_plate"
+                ohos:height="48vp"
+                ohos:width="match_parent"
+                ohos:background_element="$graphic:button"
+                ohos:text="输车牌缴费"
+                ohos:text_color="#FFFFFFFF"
+                ohos:text_size="16fp"
+                />
+        </DirectionalLayout>
 
-    </ScrollView>
+    </DirectionalLayout>
 </DirectionalLayout>
 

binární
entry/src/main/resources/base/media/change.png