linee há 1 dia atrás
pai
commit
0529e58d35
37 ficheiros alterados com 2631 adições e 152 exclusões
  1. 47 51
      entry/src/main/java/com/fujica/abk/api/auth.java
  2. 4 33
      entry/src/main/java/com/fujica/abk/api/cache.java
  3. 4 1
      entry/src/main/java/com/fujica/abk/api/config.java
  4. 103 0
      entry/src/main/java/com/fujica/abk/component/OrderDetailComponent.java
  5. 184 0
      entry/src/main/java/com/fujica/abk/component/OrderItemComponent.java
  6. 99 0
      entry/src/main/java/com/fujica/abk/component/ParkDetailComponent.java
  7. 12 3
      entry/src/main/java/com/fujica/abk/component/ParkItemComponent.java
  8. 2 2
      entry/src/main/java/com/fujica/abk/component/nav/ChargeComponent.java
  9. 445 5
      entry/src/main/java/com/fujica/abk/component/nav/OrderComponent.java
  10. 74 9
      entry/src/main/java/com/fujica/abk/component/nav/ParkComponent.java
  11. 9 0
      entry/src/main/java/com/fujica/abk/model/response/LoginRes.java
  12. 54 0
      entry/src/main/java/com/fujica/abk/model/response/OrderRes.java
  13. 105 6
      entry/src/main/java/com/fujica/abk/slice/MainAbilitySlice.java
  14. 208 0
      entry/src/main/java/com/fujica/abk/utils/ConfirmDialog.java
  15. 257 0
      entry/src/main/java/com/fujica/abk/utils/CustomListDialog.java
  16. 133 0
      entry/src/main/java/com/fujica/abk/utils/DateDialog.java
  17. 94 15
      entry/src/main/java/com/fujica/abk/utils/DialogUtil.java
  18. 1 0
      entry/src/main/java/com/fujica/abk/utils/Toast.java
  19. 3 1
      entry/src/main/java/com/fujica/abk/utils/api.java
  20. 10 0
      entry/src/main/resources/base/graphic/background_circle_8.xml
  21. 12 0
      entry/src/main/resources/base/graphic/background_circle_8_top.xml
  22. 12 0
      entry/src/main/resources/base/graphic/background_circle_8_top_selected.xml
  23. 25 5
      entry/src/main/resources/base/layout/ability_main.xml
  24. 29 0
      entry/src/main/resources/base/layout/item_custom_list_dialog.xml
  25. 114 0
      entry/src/main/resources/base/layout/item_order.xml
  26. 1 1
      entry/src/main/resources/base/layout/layout_charge.xml
  27. 81 0
      entry/src/main/resources/base/layout/layout_confirm_dialog.xml
  28. 59 0
      entry/src/main/resources/base/layout/layout_custom_list_dialog.xml
  29. 99 0
      entry/src/main/resources/base/layout/layout_date_dialog.xml
  30. 10 4
      entry/src/main/resources/base/layout/layout_license_plate_dialog.xml
  31. 54 16
      entry/src/main/resources/base/layout/layout_order.xml
  32. 133 0
      entry/src/main/resources/base/layout/layout_order_detail.xml
  33. 154 0
      entry/src/main/resources/base/layout/layout_park_detail.xml
  34. BIN
      entry/src/main/resources/base/media/close.png
  35. BIN
      entry/src/main/resources/base/media/logout.png
  36. BIN
      entry/src/main/resources/base/media/tcjf.png
  37. BIN
      entry/src/main/resources/base/media/ykxf.png

+ 47 - 51
entry/src/main/java/com/fujica/abk/api/auth.java

@@ -27,23 +27,28 @@ import java.util.concurrent.CompletableFuture;
 public class auth {
     /**
      * 登录
+     *
      * @param context 上下文
      * @return CompletableFuture<Boolean> 登录是否成功
      */
     public static CompletableFuture<Boolean> login(Context context) {
         CompletableFuture<Boolean> future = new CompletableFuture<>();
-        
+
         if (cache.isAuth(context)) {
             future.complete(true);
             return future;
         }
 
-        if(true){
+        if (true) {
             HWResult hwResult = new HWResult();
 
-            //dev环境
             hwResult.setAppId(config.appId);
-            hwResult.setOpenId("AAAjdc3utGbjvCsmhASifWUoEpmH");
+
+            //dev环境
+//            hwResult.setOpenId("AAAjdc3utGbjvCsmhASifWUoEpmH");
+
+            //dev环境
+            hwResult.setOpenId("oq5PA6YFGAqRhTuipxFpZNK_EN04");
 
             ApiOption option = new ApiOption();
             option.setUrl("/member/hw/login");
@@ -67,12 +72,12 @@ public class auth {
                     future.complete(false);
                     return;
                 }
-                
+
                 // 使用授权码登录
                 ApiOption option = new ApiOption();
                 option.setUrl("/member/hw/code/login");
                 option.setMethod(ApiOption.POST);
-                
+
                 // 注意:HMS SDK可能不直接提供authorizationCode,这里需要根据实际情况调整
                 // 如果HMS SDK不提供code,可能需要使用其他方式获取
                 java.util.Map<String, String> data = new java.util.HashMap<>();
@@ -81,7 +86,7 @@ public class auth {
                 data.put("openId", hwResult.getOpenId());
                 data.put("unionId", hwResult.getUnionId());
                 option.setData(data);
-                
+
                 processCodeLogin(context, option, hwResult, future);
             }).exceptionally(e -> {
                 Log.error(e);
@@ -92,41 +97,31 @@ public class auth {
             Log.error(e);
             future.complete(false);
         }
-        
+
         return future;
     }
-    
+
     /**
      * 处理授权码登录
-     * @param context 上下文
-     * @param option API选项
+     *
+     * @param context  上下文
+     * @param option   API选项
      * @param hwResult 华为账号信息
-     * @param future 异步结果
+     * @param future   异步结果
      */
     private static void processCodeLogin(Context context, ApiOption option, HWResult hwResult, CompletableFuture<Boolean> future) {
-        api.http(context, option, new TypeToken<R<HWResult>>(){}).thenAccept((R<HWResult> result) -> {
+        api.http(context, option, new TypeToken<R<LoginRes>>() {
+        }).thenAccept((R<LoginRes> result) -> {
             if (result != null && result.isSuccess() && result.getData() != null) {
-                HWResult loginResult = result.getData();
-                
-                if (loginResult != null) {
-                    String openId = loginResult.getOpenId() != null && !loginResult.getOpenId().isEmpty() 
-                            ? loginResult.getOpenId() : hwResult.getOpenId();
-                    String token = loginResult.getCode() != null ? loginResult.getCode() : "";
-                    String mobile = loginResult.getPhone() != null ? loginResult.getPhone() : "";
-                    
-                    cache.setOpenId(context, openId);
-                    cache.setToken(context, token);
-                    cache.setMobile(context, mobile);
-                    // 发布登录成功事件,通知UI更新
-                    EventBus.getInstance().emit("onLoginSuccess");
-                    future.complete(true);
-                } else {
-                    // 如果登录失败,尝试使用手机号+验证码登录
-                    handlePhoneLogin(context, hwResult, future);
-                }
+                LoginRes res = result.getData();
+                cache.setOpenId(context, res.getOpenId());
+                cache.setToken(context, res.getToken());
+                cache.setMobile(context, res.getMobile());
+                // 发布登录成功事件,通知UI更新
+                EventBus.getInstance().emit("onLoginSuccess");
+                future.complete(true);
             } else {
-                // 登录失败,尝试使用手机号+验证码登录
-                handlePhoneLogin(context, hwResult, future);
+                future.complete(false);
             }
         }).exceptionally(e -> {
             Log.error(e);
@@ -134,7 +129,7 @@ public class auth {
             return null;
         });
     }
-    
+
     /**
      * 处理手机号登录
      */
@@ -142,7 +137,7 @@ public class auth {
         // 这里需要显示手机号输入对话框
         // 由于PhoneDialog可能不存在,这里提供一个占位实现
         // 实际使用时需要根据项目中的对话框实现进行调整
-        
+
         // 示例:假设有一个PhoneDialog.show方法
         // PhoneDialog.show(context, (phone, code) -> {
         //     hwResult.setPhone(phone);
@@ -170,25 +165,26 @@ public class auth {
         //         return false;
         //     });
         // });
-        
+
         // 暂时返回false,需要根据实际项目中的PhoneDialog实现进行调整
         future.complete(false);
     }
-    
+
     /**
      * 获取华为账号信息
+     *
      * @param context 上下文
      * @return CompletableFuture<HWResult> 华为账号信息
      */
     public static CompletableFuture<HWResult> getHuaWeiAccount(Context context) {
         CompletableFuture<HWResult> future = new CompletableFuture<>();
-        
+
         try {
             // 创建授权请求参数
             AccountAuthParams accountAuthParams = new AccountAuthParamsHelper(
                     AccountAuthParams.DEFAULT_AUTH_REQUEST_PARAM)
                     .createParams();
-            
+
             AccountAuthService accountAuthService;
             try {
                 accountAuthService = AccountAuthManager.getService(accountAuthParams);
@@ -197,12 +193,12 @@ public class auth {
                 future.complete(new HWResult(false));
                 return future;
             }
-            
+
             if (accountAuthService == null) {
                 future.complete(new HWResult(false));
                 return future;
             }
-            
+
             // 先尝试静默登录
             Task<AuthAccount> taskSilentSignIn = accountAuthService.silentSignIn();
             taskSilentSignIn.addOnSuccessListener(new OnSuccessListener<AuthAccount>() {
@@ -217,14 +213,14 @@ public class auth {
                     future.complete(result);
                 }
             });
-            
+
             taskSilentSignIn.addOnFailureListener(new OnFailureListener() {
                 @Override
                 public void onFailure(Exception e) {
                     if (e instanceof ApiException) {
                         ApiException apiException = (ApiException) e;
                         int statusCode = apiException.getStatusCode();
-                        
+
                         // 静默登录失败,尝试前台登录
                         if (statusCode == 8) { // 需要用户授权
                             Task<AuthAccount> taskSignIn = accountAuthService.signIn();
@@ -239,7 +235,7 @@ public class auth {
                                     future.complete(result);
                                 }
                             });
-                            
+
                             taskSignIn.addOnFailureListener(new OnFailureListener() {
                                 @Override
                                 public void onFailure(Exception e) {
@@ -254,14 +250,14 @@ public class auth {
                     }
                 }
             });
-            
+
         } catch (Exception e) {
             handleAuthError(context, e, future);
         }
-        
+
         return future;
     }
-    
+
     /**
      * 处理认证错误
      */
@@ -269,7 +265,7 @@ public class auth {
         if (error instanceof ApiException) {
             ApiException apiException = (ApiException) error;
             int code = apiException.getStatusCode();
-            
+
             // 模拟器调试模式
             if (code == 12300001 && config.isDebug) {
                 HWResult result = new HWResult(true);
@@ -280,21 +276,21 @@ public class auth {
                 future.complete(result);
                 return;
             }
-            
+
             // 用户取消
             if (code == 1001502012) {
                 Toast.error(context, "已取消关联");
                 future.complete(new HWResult(false));
                 return;
             }
-            
+
             Toast.error(context, "关联失败: " + code + ", " + apiException.getMessage());
             Log.error("Failed to auth. Code: " + code + ", message: " + apiException.getMessage());
         } else {
             Toast.error(context, "关联失败: " + error.getMessage());
             Log.error(error);
         }
-        
+
         future.complete(new HWResult(false));
     }
 }

+ 4 - 33
entry/src/main/java/com/fujica/abk/api/cache.java

@@ -59,7 +59,7 @@ public class cache {
      */
     public static String get(Context context, String key) {
         try {
-            Preferences pref = getPref(context);
+            Preferences pref = getPref(context.getApplicationContext());
             if (pref != null && pref.hasKey(key)) {
                 String val = pref.getString(key, "");
                 return val == null ? "" : val;
@@ -76,7 +76,7 @@ public class cache {
      */
     public static void set(Context context, String key, String value) {
         try {
-            Preferences pref = getPref(context);
+            Preferences pref = getPref(context.getApplicationContext());
             if (pref != null) {
                 pref.putString(key, value);
                 pref.flushSync();
@@ -387,7 +387,8 @@ public class cache {
      * 获取车牌号(兼容旧代码)
      */
     public static String getLicensePlate(Context context) {
-        return getPlateNo(context);
+        return "粤B11111";
+//        return getPlateNo(context);
     }
 
     /**
@@ -397,36 +398,6 @@ public class cache {
         setPlateNo(context, licensePlate);
     }
 
-    /**
-     * 获取停车状态(是否正在停车)
-     */
-    public static boolean getParkingStatus(Context context) {
-        try {
-            Preferences preferences = getPref(context);
-            if (preferences != null) {
-                return preferences.getBoolean("parking_status", false);
-            }
-            return false;
-        } catch (Exception e) {
-            return false;
-        }
-    }
-
-    /**
-     * 保存停车状态
-     */
-    public static void setParkingStatus(Context context, boolean isParking) {
-        try {
-            Preferences preferences = getPref(context);
-            if (preferences != null) {
-                preferences.putBoolean("parking_status", isParking);
-                preferences.flushSync();
-            }
-        } catch (Exception e) {
-            e.printStackTrace();
-        }
-    }
-
     /**
      * 清除车牌相关缓存
      */

+ 4 - 1
entry/src/main/java/com/fujica/abk/api/config.java

@@ -4,7 +4,10 @@ package com.fujica.abk.api;
  * 配置类
  */
 public class config {
-    public static String appId = "6917567451779658527"; // 需要替换为实际的appId
+//    public static String appId = "6917567451779658527"; // 需要替换为实际的appId
+    public static String appId = "wxd3598cc7953b6a59"; // 查询支付记录
+
+
     public static boolean isDebug = true; // 是否调试模式
 }
 

+ 103 - 0
entry/src/main/java/com/fujica/abk/component/OrderDetailComponent.java

@@ -0,0 +1,103 @@
+package com.fujica.abk.component;
+
+import com.fujica.abk.ResourceTable;
+import com.fujica.abk.model.response.OrderRes;
+import com.fujica.abk.utils.Log;
+import ohos.agp.components.*;
+import ohos.app.Context;
+
+import java.text.DecimalFormat;
+
+/**
+ * 订单详情组件
+ */
+public class OrderDetailComponent extends DirectionalLayout {
+    private Component rootLayout;
+    private OrderRes orderData;
+
+    /**
+     * 构造函数
+     */
+    public OrderDetailComponent(Context context) {
+        super(context);
+        initComponent(context);
+    }
+
+    /**
+     * 初始化组件
+     */
+    private void initComponent(Context context) {
+        // 设置布局属性
+        setWidth(ComponentContainer.LayoutConfig.MATCH_PARENT);
+        setHeight(ComponentContainer.LayoutConfig.MATCH_PARENT);
+        setOrientation(VERTICAL);
+
+        // 加载布局文件
+        rootLayout = LayoutScatter.getInstance(context)
+                .parse(ResourceTable.Layout_layout_order_detail, null, false);
+        addComponent(rootLayout);
+    }
+
+    /**
+     * 设置订单数据并更新UI
+     */
+    public void setOrderData(OrderRes order) {
+        this.orderData = order;
+        bindData();
+    }
+
+    /**
+     * 绑定数据到 UI
+     */
+    private void bindData() {
+        if (orderData == null || rootLayout == null) {
+            return;
+        }
+
+        try {
+            // 设置商品名称
+            Text goodsNameText = (Text) rootLayout.findComponentById(ResourceTable.Id_detail_goods_name);
+            if (goodsNameText != null) {
+                goodsNameText.setText(orderData.getGoodsName() != null ? orderData.getGoodsName() : "--");
+            }
+
+            // 设置业务类型
+            Text bizTypeText = (Text) rootLayout.findComponentById(ResourceTable.Id_detail_biz_type);
+            if (bizTypeText != null) {
+                String bizTypeStr = "--";
+                if (orderData.getBizType() != null) {
+                    if (orderData.getBizType() == 1) {
+                        bizTypeStr = "停车";
+                    } else if (orderData.getBizType() == 2) {
+                        bizTypeStr = "月卡";
+                    }
+                }
+                bizTypeText.setText(bizTypeStr);
+            }
+
+            // 设置车场名称
+            Text parkNameText = (Text) rootLayout.findComponentById(ResourceTable.Id_detail_park_name);
+            if (parkNameText != null) {
+                parkNameText.setText(orderData.getParkName() != null ? orderData.getParkName() : "--");
+            }
+
+            // 设置支付时间
+            Text timeText = (Text) rootLayout.findComponentById(ResourceTable.Id_detail_pay_time);
+            if (timeText != null) {
+                timeText.setText(orderData.getPaySuccessTime() != null ? orderData.getPaySuccessTime() : "--");
+            }
+
+            // 设置金额
+            Text amountText = (Text) rootLayout.findComponentById(ResourceTable.Id_detail_amount);
+            if (amountText != null) {
+                DecimalFormat df = new DecimalFormat("0.00");
+                double amount = orderData.getActualAmount() != null ? orderData.getActualAmount() : 0.0;
+                amountText.setText("¥" + df.format(amount));
+            }
+        } catch (Exception e) {
+            Log.error("绑定订单详情数据失败: " + e.getMessage());
+            e.printStackTrace();
+        }
+    }
+}
+

+ 184 - 0
entry/src/main/java/com/fujica/abk/component/OrderItemComponent.java

@@ -0,0 +1,184 @@
+package com.fujica.abk.component;
+
+import com.fujica.abk.ResourceTable;
+import com.fujica.abk.model.response.OrderRes;
+import com.fujica.abk.utils.Log;
+import ohos.agp.components.*;
+import ohos.agp.components.element.Element;
+import ohos.agp.components.element.ElementScatter;
+import ohos.app.Context;
+
+import java.text.DecimalFormat;
+
+/**
+ * 订单列表项组件
+ */
+public class OrderItemComponent extends DirectionalLayout {
+    private OrderRes orderData;
+    private Component rootLayout;
+    private OnItemSelectedListener onItemSelectedListener;
+    private boolean isSelected = false;
+
+    /**
+     * 选中状态监听器
+     */
+    public interface OnItemSelectedListener {
+        void onItemSelected(OrderItemComponent component, OrderRes order);
+        void onItemDeselected(OrderItemComponent component);
+    }
+
+    /**
+     * 构造函数(通过 OrderRes 对象创建)
+     */
+    public OrderItemComponent(Context context, OrderRes order) {
+        super(context);
+        this.orderData = order;
+        initComponent(context);
+        bindData();
+    }
+
+    /**
+     * 初始化组件
+     */
+    private void initComponent(Context context) {
+        // 设置布局属性
+        setWidth(ComponentContainer.LayoutConfig.MATCH_PARENT);
+        setHeight(ComponentContainer.LayoutConfig.MATCH_CONTENT);
+        setOrientation(VERTICAL);
+
+        // 加载布局文件
+        rootLayout = LayoutScatter.getInstance(context)
+                .parse(ResourceTable.Layout_item_order, null, false);
+        addComponent(rootLayout);
+        
+        // 初始化背景为普通状态
+        updateBackground(false);
+
+        // 设置整个列表项的点击事件
+        setClickedListener(component -> {
+            if (orderData != null) {
+                // 如果已选中,则取消选中;否则选中
+                if (isSelected) {
+                    setSelected(false);
+                    if (onItemSelectedListener != null) {
+                        onItemSelectedListener.onItemDeselected(this);
+                    }
+                } else {
+                    setSelected(true);
+                    if (onItemSelectedListener != null) {
+                        onItemSelectedListener.onItemSelected(this, orderData);
+                    }
+                }
+            }
+        });
+    }
+
+    /**
+     * 绑定数据到 UI
+     */
+    private void bindData() {
+        if (orderData == null || rootLayout == null) {
+            return;
+        }
+
+        try {
+            // 设置商品名称
+            Text goodsNameText = (Text) rootLayout.findComponentById(ResourceTable.Id_text_goods_name);
+            if (goodsNameText != null) {
+                goodsNameText.setText(orderData.getGoodsName() != null ? orderData.getGoodsName() : "--");
+            }
+
+            // 设置状态
+            Text statusText = (Text) rootLayout.findComponentById(ResourceTable.Id_text_status);
+            if (statusText != null) {
+                statusText.setText("已完成");
+            }
+
+            // 设置图标显示
+            Boolean ykxf = orderData.getBizType() != null && orderData.getBizType() == 2;
+            Component iconYkxf = rootLayout.findComponentById(ResourceTable.Id_icon_ykxf);
+            Component iconTcjf = rootLayout.findComponentById(ResourceTable.Id_icon_tcjf);
+            if (iconYkxf != null) {
+                iconYkxf.setVisibility(ykxf ? VISIBLE : HIDE);
+            }
+            if (iconTcjf != null) {
+                iconTcjf.setVisibility(ykxf ? HIDE : VISIBLE);
+            }
+
+            // 设置车场名称
+            Text parkNameText = (Text) rootLayout.findComponentById(ResourceTable.Id_text_park_name);
+            if (parkNameText != null) {
+                parkNameText.setText(orderData.getParkName() != null ? orderData.getParkName() : "--");
+            }
+
+            // 设置支付时间
+            Text timeText = (Text) rootLayout.findComponentById(ResourceTable.Id_text_pay_time);
+            if (timeText != null) {
+                timeText.setText(orderData.getPaySuccessTime() != null ? orderData.getPaySuccessTime() : "--");
+            }
+
+            // 设置金额
+            Text amountText = (Text) rootLayout.findComponentById(ResourceTable.Id_text_amount);
+            if (amountText != null) {
+                DecimalFormat df = new DecimalFormat("0.00");
+                double amount = orderData.getActualAmount() != null ? orderData.getActualAmount() : 0.0;
+                amountText.setText("¥" + df.format(amount));
+            }
+        } catch (Exception e) {
+            Log.error("绑定数据失败: " + e.getMessage());
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     * 更新背景
+     */
+    private void updateBackground(boolean selected) {
+        if (rootLayout == null) {
+            return;
+        }
+        try {
+            int backgroundResId = selected 
+                ? ResourceTable.Graphic_background_circle_8_top_selected
+                : ResourceTable.Graphic_background_circle_8_top;
+            Element element = ElementScatter.getInstance(getContext()).parse(backgroundResId);
+            rootLayout.setBackground(element);
+        } catch (Exception e) {
+            Log.error("更新背景失败: " + e.getMessage());
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     * 设置选中状态
+     */
+    public void setSelected(boolean selected) {
+        if (isSelected == selected) {
+            return;
+        }
+        isSelected = selected;
+        updateBackground(selected);
+    }
+
+    /**
+     * 获取选中状态
+     */
+    public boolean isSelected() {
+        return isSelected;
+    }
+
+    /**
+     * 设置选中监听器
+     */
+    public void setOnItemSelectedListener(OnItemSelectedListener listener) {
+        this.onItemSelectedListener = listener;
+    }
+
+    /**
+     * 获取订单数据
+     */
+    public OrderRes getOrderData() {
+        return orderData;
+    }
+}
+

+ 99 - 0
entry/src/main/java/com/fujica/abk/component/ParkDetailComponent.java

@@ -0,0 +1,99 @@
+package com.fujica.abk.component;
+
+import com.fujica.abk.ResourceTable;
+import com.fujica.abk.model.response.ParkNearRes;
+import com.fujica.abk.utils.Log;
+import ohos.agp.components.*;
+import ohos.app.Context;
+
+/**
+ * 停车场详情组件
+ */
+public class ParkDetailComponent extends DirectionalLayout {
+    private Component rootLayout;
+    private ParkNearRes parkData;
+
+    /**
+     * 构造函数
+     */
+    public ParkDetailComponent(Context context) {
+        super(context);
+        initComponent(context);
+    }
+
+    /**
+     * 初始化组件
+     */
+    private void initComponent(Context context) {
+        // 设置布局属性
+        setWidth(ComponentContainer.LayoutConfig.MATCH_PARENT);
+        setHeight(ComponentContainer.LayoutConfig.MATCH_PARENT);
+        setOrientation(VERTICAL);
+
+        // 加载布局文件
+        rootLayout = LayoutScatter.getInstance(context)
+                .parse(ResourceTable.Layout_layout_park_detail, null, false);
+        addComponent(rootLayout);
+    }
+
+    /**
+     * 设置停车场数据并更新UI
+     */
+    public void setParkData(ParkNearRes park) {
+        this.parkData = park;
+        bindData();
+    }
+
+    /**
+     * 绑定数据到 UI
+     */
+    private void bindData() {
+        if (parkData == null || rootLayout == null) {
+            return;
+        }
+
+        try {
+            // 设置停车场名称
+            Text nameText = (Text) rootLayout.findComponentById(ResourceTable.Id_detail_park_name);
+            if (nameText != null && parkData.getParkName() != null) {
+                nameText.setText(parkData.getParkName());
+            }
+
+            // 设置地址
+            Text addressText = (Text) rootLayout.findComponentById(ResourceTable.Id_detail_address);
+            if (addressText != null) {
+                addressText.setText(parkData.getAddress() != null ? parkData.getAddress() : "--");
+            }
+
+            // 设置距离
+            Text distanceText = (Text) rootLayout.findComponentById(ResourceTable.Id_detail_distance);
+            if (distanceText != null) {
+                String distanceStr = parkData.getDistance() != null ?
+                        String.format("%.1fkm", parkData.getDistance() / 1000.0) : "0km";
+                distanceText.setText(distanceStr);
+            }
+
+            // 设置总车位
+            Text totalPlaceText = (Text) rootLayout.findComponentById(ResourceTable.Id_detail_total_place);
+            if (totalPlaceText != null && parkData.getTotalPlace() != null) {
+                totalPlaceText.setText(String.valueOf(parkData.getTotalPlace()));
+            }
+
+            // 设置剩余车位
+            Text residuePlaceText = (Text) rootLayout.findComponentById(ResourceTable.Id_detail_residue_place);
+            if (residuePlaceText != null && parkData.getResiduePlace() != null) {
+                residuePlaceText.setText(String.valueOf(parkData.getResiduePlace()));
+            }
+
+            // 设置免费时长
+            Text freeTimeText = (Text) rootLayout.findComponentById(ResourceTable.Id_detail_free_time);
+            if (freeTimeText != null) {
+                freeTimeText.setText(parkData.getFreeTime() != null ? parkData.getFreeTime() + "分" : "--");
+            }
+        } catch (Exception e) {
+            Log.error("绑定停车场详情数据失败: " + e.getMessage());
+            e.printStackTrace();
+        }
+    }
+}
+

+ 12 - 3
entry/src/main/java/com/fujica/abk/component/ParkItemComponent.java

@@ -26,6 +26,7 @@ public class ParkItemComponent extends DirectionalLayout {
      */
     public interface OnItemSelectedListener {
         void onItemSelected(ParkItemComponent component, ParkNearRes park);
+        void onItemDeselected(ParkItemComponent component);
     }
 
     /**
@@ -67,9 +68,17 @@ public class ParkItemComponent extends DirectionalLayout {
         // 设置整个列表项的点击事件
         setClickedListener(component -> {
             if (parkData != null) {
-                setSelected(true);
-                if (onItemSelectedListener != null) {
-                    onItemSelectedListener.onItemSelected(this, parkData);
+                // 如果已选中,则取消选中;否则选中
+                if (isSelected) {
+                    setSelected(false);
+                    if (onItemSelectedListener != null) {
+                        onItemSelectedListener.onItemDeselected(this);
+                    }
+                } else {
+                    setSelected(true);
+                    if (onItemSelectedListener != null) {
+                        onItemSelectedListener.onItemSelected(this, parkData);
+                    }
                 }
             }
         });

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

@@ -118,7 +118,8 @@ public class ChargeComponent extends DirectionalLayout {
      */
     private void checkCacheAndUpdateUI() {
         String licensePlate = cache.getLicensePlate(context);
-        boolean isParking = cache.getParkingStatus(context);
+        textLicensePlate.setText(licensePlate);
+        boolean isParking = licensePlate != null && licensePlate != "";
 
         if (licensePlate != null && !licensePlate.isEmpty() && isParking) {
             // 有缓存,显示停车信息卡片
@@ -161,7 +162,6 @@ public class ChargeComponent extends DirectionalLayout {
     private void simulateLicensePlateInput(String licensePlate) {
         // 保存车牌到缓存
         cache.setLicensePlate(context, licensePlate);
-        cache.setParkingStatus(context, true);
 
         // 更新UI
         showParkingInfoCard();

+ 445 - 5
entry/src/main/java/com/fujica/abk/component/nav/OrderComponent.java

@@ -1,23 +1,79 @@
 package com.fujica.abk.component.nav;
 
 import com.fujica.abk.ResourceTable;
-import ohos.agp.components.Component;
-import ohos.agp.components.ComponentContainer;
-import ohos.agp.components.DirectionalLayout;
-import ohos.agp.components.LayoutScatter;
+import com.fujica.abk.component.LoadingComponent;
+import com.fujica.abk.component.OrderItemComponent;
+import com.fujica.abk.model.response.OrderRes;
+import com.fujica.abk.model.response.Page;
+import com.fujica.abk.utils.*;
+import com.google.gson.Gson;
+import com.google.gson.reflect.TypeToken;
+import ohos.agp.components.*;
+import ohos.agp.components.element.ShapeElement;
+import ohos.agp.utils.Color;
+import com.fujica.abk.utils.CustomListDialog;
 import ohos.app.Context;
+import ohos.eventhandler.EventHandler;
+import ohos.eventhandler.EventRunner;
+
+import java.lang.reflect.Type;
+import java.text.DecimalFormat;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.CompletableFuture;
 
 /**
  * 缴费记录页面组件
  */
 public class OrderComponent extends DirectionalLayout {
+    // 页面组件
     private Component rootLayout;
+    private DirectionalLayout btnBizTypeFilter; // 业务类型筛选按钮
+    private Text textBizType; // 业务类型文本
+    private DirectionalLayout btnDateFilter; // 日期筛选按钮
+    private Text textDate; // 日期文本
+    private ScrollView orderListScroll; // 订单列表滚动视图
+    private DirectionalLayout orderListContainer; // 订单列表容器
+
+    // 筛选参数
+    private String bizType = "全部"; // 业务类型:全部、停车、月卡
+    private String paySuccessTime = ""; // 支付成功时间(格式:YYYY-MM)
+
+    // 分页相关
+    private int currentPage = 1; // 当前页码
+    private static final int PAGE_SIZE = 10; // 每页数量
+    private boolean isLoading = false; // 是否正在加载
+    private boolean hasMore = true; // 是否还有更多数据
+    private long lastLoadTime = 0; // 上次加载时间,用于防抖
+    private static final long LOAD_THROTTLE_MS = 500; // 防抖时间间隔(毫秒)
+
+    // 数据
+    private List<OrderRes> orderList = new ArrayList<>(); // 订单列表数据
+    private OrderItemComponent selectedOrderItem = null; // 当前选中的订单列表项
+
+    // 外部依赖
+    private Context context;
+    private LoadingComponent loadingComponent; // Loading组件
+    private DateDialog dateDialog; // 日期选择对话框
+    private OnOrderSelectedListener onOrderSelectedListener; // 订单选中监听器
+
+    /**
+     * 订单选中监听器
+     */
+    public interface OnOrderSelectedListener {
+        void onOrderSelected(OrderRes order);
+        void onOrderDeselected();
+    }
 
     /**
      * 构造函数
      */
     public OrderComponent(Context context) {
         super(context);
+        this.context = context;
         initComponent(context);
     }
 
@@ -30,10 +86,394 @@ public class OrderComponent extends DirectionalLayout {
         setHeight(ComponentContainer.LayoutConfig.MATCH_PARENT);
         setOrientation(VERTICAL);
 
+        // 初始化日期(当前年月)
+        Calendar calendar = Calendar.getInstance();
+        int year = calendar.get(Calendar.YEAR);
+        int month = calendar.get(Calendar.MONTH) + 1;
+
+        year = 2024;
+        month = 8;
+
+        paySuccessTime = String.format("%d-%02d", year, month);
+
         // 加载布局文件
         rootLayout = LayoutScatter.getInstance(context)
                 .parse(ResourceTable.Layout_layout_order, null, false);
         addComponent(rootLayout);
+
+        // 初始化组件引用
+        initViews();
+
+        // 设置事件监听
+        setupListeners();
+
+        // 加载数据
+        reset();
+    }
+
+    /**
+     * 初始化视图组件
+     */
+    private void initViews() {
+        btnBizTypeFilter = (DirectionalLayout) rootLayout.findComponentById(ResourceTable.Id_btn_biz_type_filter);
+        if (btnBizTypeFilter != null && btnBizTypeFilter.getChildCount() > 0) {
+            Component firstChild = btnBizTypeFilter.getComponentAt(0);
+            if (firstChild instanceof Text) {
+                textBizType = (Text) firstChild;
+            }
+        }
+
+        btnDateFilter = (DirectionalLayout) rootLayout.findComponentById(ResourceTable.Id_btn_date_filter);
+        if (btnDateFilter != null && btnDateFilter.getChildCount() > 0) {
+            Component firstChild = btnDateFilter.getComponentAt(0);
+            if (firstChild instanceof Text) {
+                textDate = (Text) firstChild;
+                if (textDate != null) {
+                    textDate.setText(paySuccessTime);
+                }
+            }
+        }
+
+        orderListScroll = (ScrollView) rootLayout.findComponentById(ResourceTable.Id_order_list_scroll);
+        orderListContainer = (DirectionalLayout) rootLayout.findComponentById(ResourceTable.Id_order_list_container);
+    }
+
+    /**
+     * 设置事件监听
+     */
+    private void setupListeners() {
+        // 设置业务类型筛选点击事件
+        if (btnBizTypeFilter != null) {
+            btnBizTypeFilter.setClickedListener(component -> showBizTypeFilterDialog());
+        }
+
+        // 设置日期筛选点击事件
+        if (btnDateFilter != null) {
+            btnDateFilter.setClickedListener(component -> showDateFilterDialog());
+        }
+
+        // 设置滚动监听,实现分页加载
+        if (orderListScroll != null) {
+            orderListScroll.setReboundEffect(false);
+            // 监听滚动到底部
+            orderListScroll.addScrolledListener(new Component.ScrolledListener() {
+                @Override
+                public void onContentScrolled(Component component, int x, int y, int oldX, int oldY) {
+                    // 防抖:避免频繁触发
+                    long currentTime = System.currentTimeMillis();
+                    if (currentTime - lastLoadTime < LOAD_THROTTLE_MS) {
+                        return;
+                    }
+
+                    // 如果正在加载或没有更多数据,直接返回
+                    if (isLoading || !hasMore) {
+                        return;
+                    }
+
+                    // 计算是否滚动到底部
+                    int scrollY = orderListScroll.getScrollValue(1);
+                    int viewHeight = orderListScroll.getHeight();
+
+                    // 获取内容高度
+                    int contentHeight = 0;
+                    if (orderListContainer != null) {
+                        contentHeight = orderListContainer.getHeight();
+                    }
+
+                    // 如果容器高度为0,尝试使用EstimatedHeight
+                    if (contentHeight == 0) {
+                        contentHeight = orderListScroll.getEstimatedHeight();
+                    }
+
+                    // 如果内容高度或视图高度为0,无法计算,直接返回
+                    if (contentHeight == 0 || viewHeight == 0) {
+                        return;
+                    }
+
+                    // 计算剩余滚动距离
+                    int remainingDistance = contentHeight - scrollY - viewHeight;
+
+                    // 计算阈值(50像素),当剩余距离小于等于阈值时触发加载
+                    int threshold = 50;
+
+                    // 当滚动到底部(剩余距离小于等于阈值)时,触发加载
+                    if (remainingDistance <= threshold && remainingDistance >= 0) {
+                        lastLoadTime = currentTime;
+                        // 加载下一页
+                        loadOrderData(false);
+                    }
+                }
+            });
+        }
+    }
+
+    /**
+     * 显示业务类型筛选下拉对话框
+     */
+    private void showBizTypeFilterDialog() {
+        String[] options = {"全部", "停车", "月卡"};
+        
+        // 找到当前选中的索引
+        int currentIndex = -1;
+        for (int i = 0; i < options.length; i++) {
+            if (options[i].equals(bizType)) {
+                currentIndex = i;
+                break;
+            }
+        }
+        
+        CustomListDialog listDialog = DialogUtil.createListDialog(context, options, (iDialog, index) -> {
+            bizType = options[index];
+            if (textBizType != null) {
+                textBizType.setText(bizType);
+            }
+            // 重新加载数据
+            reset();
+            iDialog.destroy();
+        });
+        
+        // 设置当前选中项
+        if (currentIndex >= 0) {
+            listDialog.setSelectedIndex(currentIndex);
+        }
+        
+        listDialog.show();
+    }
+
+    /**
+     * 显示日期筛选对话框
+     */
+    private void showDateFilterDialog() {
+        if (dateDialog != null) {
+            dateDialog.destroy();
+        }
+        dateDialog = new DateDialog(context, paySuccessTime, date -> {
+                paySuccessTime = date;
+                if (textDate != null) {
+                    textDate.setText(paySuccessTime);
+                }
+                reset();
+        });
+        dateDialog.show();
     }
-}
 
+    /**
+     * 重置数据并加载
+     */
+    public void reset() {
+        orderList.clear();
+        if (orderListContainer != null) {
+            orderListContainer.removeAllComponents();
+        }
+        // 清除选中状态
+        selectedOrderItem = null;
+        currentPage = 1;
+        hasMore = true;
+        isLoading = false;
+        lastLoadTime = 0;
+        loadOrderData(true);
+    }
+
+    /**
+     * 加载订单数据
+     */
+    private void loadOrderData(boolean isRefresh) {
+        if (isLoading) {
+            return;
+        }
+
+        if (isRefresh) {
+            currentPage = 1;
+            hasMore = true;
+            lastLoadTime = 0;
+            orderList.clear();
+            if (orderListContainer != null) {
+                orderListContainer.removeAllComponents();
+            }
+        }
+
+        if (!hasMore) {
+            return;
+        }
+
+        // 锁定当前页码,避免并发问题
+        final int requestPage = currentPage;
+        isLoading = true;
+
+        // 构建请求参数
+        Map<String, Object> params = new HashMap<>();
+        params.put("current", requestPage);
+        params.put("size", PAGE_SIZE);
+        params.put("paySuccessTime", paySuccessTime);
+
+        // 业务类型:全部=0, 停车=1, 月卡=2
+        int bizTypeValue = 0;
+        if ("停车".equals(bizType)) {
+            bizTypeValue = 1;
+        } else if ("月卡".equals(bizType)) {
+            bizTypeValue = 2;
+        }
+        if (bizTypeValue != 0) {
+            params.put("bizType", bizTypeValue);
+        }
+
+        // 构建请求URL
+        ApiOption option = new ApiOption();
+        option.setUrl("/order/page");
+        option.setMethod(ApiOption.GET);
+        option.setData(params);
+
+
+        // 发送请求
+        CompletableFuture<R<Page<OrderRes>>> future = api.http(context, option, new TypeToken<R<Page<OrderRes>>>(){});
+        if (loadingComponent != null) {
+            loadingComponent.show();
+        }
+        future.thenAccept(res -> {
+            try {
+                if (res == null || !res.isSuccess()) {
+                    String errorMsg = res != null ? res.getMsg() : "请求失败";
+                    Log.error("加载订单数据失败: " + errorMsg);
+                    return;
+                }
+
+                // 解析响应数据
+                List<OrderRes> records = res.getData().getRecords();
+                if (records.isEmpty()) {
+                    hasMore = false;
+                    return;
+                }
+
+                // 更新分页信息
+                boolean hasMoreData = true;
+                int nextPage = requestPage + 1;
+                if (res.getData().getCurrent() != null && res.getData().getPages() != null) {
+                    int serverCurrent = res.getData().getCurrent();
+                    int totalPages = res.getData().getPages();
+                    if (serverCurrent >= totalPages) {
+                        hasMoreData = false;
+                    } else {
+                        nextPage = serverCurrent + 1;
+                    }
+                } else {
+                    if (records.size() < PAGE_SIZE) {
+                        hasMoreData = false;
+                    }
+                }
+
+                // 保存最终的分页信息
+                final boolean finalHasMore = hasMoreData;
+                final int finalNextPage = nextPage;
+                final List<OrderRes> finalRecords = records;
+
+                // 只在UI线程更新界面
+                new EventHandler(EventRunner.getMainEventRunner()).postTask(() -> {
+                    // 检查currentPage是否已经被其他请求更新
+                    if (currentPage > requestPage) {
+                        Log.info("忽略过期请求,当前页码: " + currentPage + ", 请求页码: " + requestPage);
+                        return;
+                    }
+
+                    // 添加到列表
+                    orderList.addAll(finalRecords);
+
+                    // 批量渲染列表项
+                    if (orderListContainer != null && !finalRecords.isEmpty()) {
+                        for (OrderRes order : finalRecords) {
+                            Component item = createOrderItem(order);
+                            if (item != null) {
+                                orderListContainer.addComponent(item);
+                            }
+                        }
+                    }
+
+                    // 更新分页信息
+                    hasMore = finalHasMore;
+                    if (finalHasMore) {
+                        currentPage = finalNextPage;
+                    }
+                });
+
+            } catch (Exception e) {
+                Log.error("解析订单数据失败: " + e.getMessage());
+                e.printStackTrace();
+            } finally {
+                isLoading = false;
+                if (loadingComponent != null) {
+                    loadingComponent.hide();
+                }
+            }
+        });
+    }
+
+    /**
+     * 创建订单列表项组件
+     */
+    private Component createOrderItem(OrderRes order) {
+        if (orderListContainer == null) {
+            return null;
+        }
+
+        try {
+            // 使用 OrderItemComponent 组件
+            OrderItemComponent item = new OrderItemComponent(context, order);
+            
+            // 设置选中监听器,实现全局选中状态管理
+            item.setOnItemSelectedListener(new OrderItemComponent.OnItemSelectedListener() {
+                @Override
+                public void onItemSelected(OrderItemComponent component, OrderRes orderData) {
+                    // 如果之前有选中的项,取消其选中状态
+                    if (selectedOrderItem != null && selectedOrderItem != component) {
+                        selectedOrderItem.setSelected(false);
+                    }
+                    // 更新当前选中的项
+                    selectedOrderItem = component;
+                    // 通知外部监听器
+                    if (onOrderSelectedListener != null) {
+                        onOrderSelectedListener.onOrderSelected(orderData);
+                    }
+                }
+
+                @Override
+                public void onItemDeselected(OrderItemComponent component) {
+                    // 如果取消的是当前选中的项,清除选中状态
+                    if (selectedOrderItem == component) {
+                        selectedOrderItem = null;
+                    }
+                    // 通知外部监听器
+                    if (onOrderSelectedListener != null) {
+                        onOrderSelectedListener.onOrderDeselected();
+                    }
+                }
+            });
+
+            return item;
+
+        } catch (Exception e) {
+            Log.error("创建订单列表项失败: " + e.getMessage());
+            e.printStackTrace();
+            return null;
+        }
+    }
+
+    /**
+     * 设置Loading组件
+     */
+    public void setLoadingComponent(LoadingComponent loadingComponent) {
+        this.loadingComponent = loadingComponent;
+    }
+
+    /**
+     * 刷新数据
+     */
+    public void refresh() {
+        reset();
+    }
+
+    /**
+     * 设置订单选中监听器
+     */
+    public void setOnOrderSelectedListener(OnOrderSelectedListener listener) {
+        this.onOrderSelectedListener = listener;
+    }
+}

+ 74 - 9
entry/src/main/java/com/fujica/abk/component/nav/ParkComponent.java

@@ -9,7 +9,7 @@ import com.fujica.abk.utils.*;
 import com.google.gson.Gson;
 import com.google.gson.reflect.TypeToken;
 import ohos.agp.components.*;
-import ohos.agp.window.dialog.ListDialog;
+import com.fujica.abk.utils.CustomListDialog;
 import ohos.app.Context;
 import ohos.eventhandler.EventHandler;
 import ohos.eventhandler.EventRunner;
@@ -55,6 +55,15 @@ public class ParkComponent extends DirectionalLayout {
     private Context context;
     private Location currentLocation; // 当前定位坐标
     private LoadingComponent loadingComponent; // Loading组件
+    private OnParkSelectedListener onParkSelectedListener; // 停车场选中监听器
+
+    /**
+     * 停车场选中监听器
+     */
+    public interface OnParkSelectedListener {
+        void onParkSelected(ParkNearRes park);
+        void onParkDeselected();
+    }
 
     /**
      * 构造函数
@@ -215,7 +224,16 @@ public class ParkComponent extends DirectionalLayout {
         String[] options = {"500m", "1km", "3km"};
         int[] values = {500, 1000, 3000};
         
-        ListDialog listDialog = DialogUtil.createListDialog(context, options, (iDialog, index) -> {
+        // 找到当前选中的索引
+        int currentIndex = -1;
+        for (int i = 0; i < values.length; i++) {
+            if (values[i] == selectedDistance) {
+                currentIndex = i;
+                break;
+            }
+        }
+        
+        CustomListDialog listDialog = DialogUtil.createListDialog(context, options, (iDialog, index) -> {
             selectedDistance = values[index];
             if (btnDistanceFilter != null && btnDistanceFilter.getChildCount() > 0) {
                 Component textComponent = btnDistanceFilter.getComponentAt(0);
@@ -227,6 +245,12 @@ public class ParkComponent extends DirectionalLayout {
             switchTab(filterType);
             iDialog.destroy();
         });
+        
+        // 设置当前选中项
+        if (currentIndex >= 0) {
+            listDialog.setSelectedIndex(currentIndex);
+        }
+        
         listDialog.show();
     }
 
@@ -237,7 +261,16 @@ public class ParkComponent extends DirectionalLayout {
         String[] options = {"车位最多", "距离最近", "免费时长最长"};
         int[] values = {1, 2, 3};
         
-        ListDialog listDialog = DialogUtil.createListDialog(context, options, (iDialog, index) -> {
+        // 找到当前选中的索引
+        int currentIndex = -1;
+        for (int i = 0; i < values.length; i++) {
+            if (values[i] == selectedFilter) {
+                currentIndex = i;
+                break;
+            }
+        }
+        
+        CustomListDialog listDialog = DialogUtil.createListDialog(context, options, (iDialog, index) -> {
             selectedFilter = values[index];
             if (btnDistanceSort != null && btnDistanceSort.getChildCount() > 0) {
                 Component textComponent = btnDistanceSort.getComponentAt(0);
@@ -249,6 +282,12 @@ public class ParkComponent extends DirectionalLayout {
             switchTab(filterType);
             iDialog.destroy();
         });
+        
+        // 设置当前选中项
+        if (currentIndex >= 0) {
+            listDialog.setSelectedIndex(currentIndex);
+        }
+        
         listDialog.show();
     }
 
@@ -428,13 +467,32 @@ public class ParkComponent extends DirectionalLayout {
             ParkItemComponent item = new ParkItemComponent(context, park);
             
             // 设置选中监听器,实现全局选中状态管理
-            item.setOnItemSelectedListener((component, parkData) -> {
-                // 如果之前有选中的项,取消其选中状态
-                if (selectedParkingItem != null && selectedParkingItem != component) {
-                    selectedParkingItem.setSelected(false);
+            item.setOnItemSelectedListener(new ParkItemComponent.OnItemSelectedListener() {
+                @Override
+                public void onItemSelected(ParkItemComponent component, ParkNearRes parkData) {
+                    // 如果之前有选中的项,取消其选中状态
+                    if (selectedParkingItem != null && selectedParkingItem != component) {
+                        selectedParkingItem.setSelected(false);
+                    }
+                    // 更新当前选中的项
+                    selectedParkingItem = component;
+                    // 通知外部监听器
+                    if (onParkSelectedListener != null) {
+                        onParkSelectedListener.onParkSelected(parkData);
+                    }
+                }
+
+                @Override
+                public void onItemDeselected(ParkItemComponent component) {
+                    // 如果取消的是当前选中的项,清除选中状态
+                    if (selectedParkingItem == component) {
+                        selectedParkingItem = null;
+                    }
+                    // 通知外部监听器
+                    if (onParkSelectedListener != null) {
+                        onParkSelectedListener.onParkDeselected();
+                    }
                 }
-                // 更新当前选中的项
-                selectedParkingItem = component;
             });
 
             return item;
@@ -470,5 +528,12 @@ public class ParkComponent extends DirectionalLayout {
     public void refresh() {
         loadParkingData(true);
     }
+
+    /**
+     * 设置停车场选中监听器
+     */
+    public void setOnParkSelectedListener(OnParkSelectedListener listener) {
+        this.onParkSelectedListener = listener;
+    }
 }
 

+ 9 - 0
entry/src/main/java/com/fujica/abk/model/response/LoginRes.java

@@ -5,6 +5,7 @@ package com.fujica.abk.model.response;
  */
 public class LoginRes {
     private String token;
+    private String name;
     private String openId;
     private String mobile;
 
@@ -31,5 +32,13 @@ public class LoginRes {
     public void setMobile(String mobile) {
         this.mobile = mobile;
     }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
 }
 

+ 54 - 0
entry/src/main/java/com/fujica/abk/model/response/OrderRes.java

@@ -0,0 +1,54 @@
+package com.fujica.abk.model.response;
+
+/**
+ * 订单响应数据
+ */
+public class OrderRes {
+    private String goodsName;
+    private Integer bizType; // 1=停车, 2=月卡
+    private String parkName;
+    private String paySuccessTime;
+    private Double actualAmount;
+
+    public String getGoodsName() {
+        return goodsName;
+    }
+
+    public void setGoodsName(String goodsName) {
+        this.goodsName = goodsName;
+    }
+
+    public Integer getBizType() {
+//        return bizType;
+        return  1;
+    }
+
+    public void setBizType(Integer bizType) {
+        this.bizType = bizType;
+    }
+
+    public String getParkName() {
+        return parkName;
+    }
+
+    public void setParkName(String parkName) {
+        this.parkName = parkName;
+    }
+
+    public String getPaySuccessTime() {
+        return paySuccessTime;
+    }
+
+    public void setPaySuccessTime(String paySuccessTime) {
+        this.paySuccessTime = paySuccessTime;
+    }
+
+    public Double getActualAmount() {
+        return actualAmount;
+    }
+
+    public void setActualAmount(Double actualAmount) {
+        this.actualAmount = actualAmount;
+    }
+}
+

+ 105 - 6
entry/src/main/java/com/fujica/abk/slice/MainAbilitySlice.java

@@ -5,6 +5,10 @@ import com.fujica.abk.api.auth;
 import com.fujica.abk.api.cache;
 import com.fujica.abk.common.EventBus;
 import com.fujica.abk.component.LoadingComponent;
+import com.fujica.abk.component.OrderDetailComponent;
+import com.fujica.abk.component.ParkDetailComponent;
+import com.fujica.abk.model.response.OrderRes;
+import com.fujica.abk.model.response.ParkNearRes;
 import com.fujica.abk.utils.*;
 import com.fujica.abk.component.nav.ParkComponent;
 import com.fujica.abk.component.nav.ChargeComponent;
@@ -73,6 +77,12 @@ public class MainAbilitySlice extends AbilitySlice {
     // 页面组件
     private ChargeComponent chargeComponent;
     private ParkComponent parkComponent; // 找车位页面组件
+    private OrderComponent orderComponent; // 缴费记录页面组件
+
+    // 详情区域
+    private DirectionalLayout mainRight; // 右侧详情区域
+    private OrderDetailComponent orderDetailComponent; // 订单详情组件
+    private ParkDetailComponent parkDetailComponent; // 停车场详情组件
 
     DataAbilityHelper dataAbilityHelper;
     IDataAbilityObserver dataAbilityObserver;
@@ -107,10 +117,20 @@ public class MainAbilitySlice extends AbilitySlice {
         // 初始化Loading组件并添加到根布局
         loadingComponent = findComponentById(ResourceTable.Id_loading_component);
 
+        // 初始化详情区域
+        mainRight = findComponentById(ResourceTable.Id_main_right);
+        if (mainRight != null) {
+            // 创建详情组件
+            orderDetailComponent = new OrderDetailComponent(this);
+            parkDetailComponent = new ParkDetailComponent(this);
+        }
+
         quit = findComponentById(ResourceTable.Id_quit);
         quit.setClickedListener(v -> {
-            cache.logout(getContext());
-            quit.setVisibility(Component.HIDE);
+            DialogUtil.confirm(getContext(), "确认要退出吗?", () -> {
+                cache.logout(getContext());
+                quit.setVisibility(Component.HIDE);
+            });
         });
         quit.setVisibility(cache.isAuth(getContext()) ? Component.VISIBLE : Component.HIDE);
 
@@ -285,10 +305,36 @@ public class MainAbilitySlice extends AbilitySlice {
                                 if (currentLocation != null) {
                                     parkComponent.setCurrentLocation(currentLocation);
                                 }
+                                // 设置停车场选中监听器
+                                parkComponent.setOnParkSelectedListener(new ParkComponent.OnParkSelectedListener() {
+                                    @Override
+                                    public void onParkSelected(ParkNearRes park) {
+                                        showParkDetail(park);
+                                    }
+
+                                    @Override
+                                    public void onParkDeselected() {
+                                        hideDetail();
+                                    }
+                                });
                                 page = parkComponent;
                                 break;
                             case 2: // 缴费记录
-                                page = new OrderComponent(MainAbilitySlice.this);
+                                orderComponent = new OrderComponent(MainAbilitySlice.this);
+                                orderComponent.setLoadingComponent(loadingComponent);
+                                // 设置订单选中监听器
+                                orderComponent.setOnOrderSelectedListener(new OrderComponent.OnOrderSelectedListener() {
+                                    @Override
+                                    public void onOrderSelected(OrderRes order) {
+                                        showOrderDetail(order);
+                                    }
+
+                                    @Override
+                                    public void onOrderDeselected() {
+                                        hideDetail();
+                                    }
+                                });
+                                page = orderComponent;
                                 break;
                         }
                         if (page != null) {
@@ -329,6 +375,8 @@ public class MainAbilitySlice extends AbilitySlice {
                     currentTab = index;
                     updateBottomNavState(index);
                     Log.info("切换到页面: " + index);
+                    // 切换页面时隐藏详情
+                    hideDetail();
                     // 如果切换到我的页面,刷新数据
                     if (index == 0 && chargeComponent != null) {
                         chargeComponent.refresh();
@@ -337,6 +385,10 @@ public class MainAbilitySlice extends AbilitySlice {
                     if (index == 1 && parkComponent != null) {
                         parkComponent.refresh();
                     }
+                    // 如果切换到缴费记录页面,刷新数据(从第一页开始)
+                    if (index == 2 && orderComponent != null) {
+                        orderComponent.reset();
+                    }
                 }
 
                 @Override
@@ -583,7 +635,7 @@ public class MainAbilitySlice extends AbilitySlice {
             if (mainRunner != null) {
                 EventHandler mainHandler = new EventHandler(mainRunner);
                 mainHandler.postTask(() -> {
-                    Log.info("收到认证状态变化事件,更新UI");
+                    Log.error("收到认证状态变化事件,更新UI");
                     // 隐藏退出按钮
                     if (quit != null) {
                         quit.setVisibility(Component.HIDE);
@@ -596,7 +648,7 @@ public class MainAbilitySlice extends AbilitySlice {
                 });
             }
         };
-        EventBus.getInstance().on("onAuthChanged", authChangedListener);
+        EventBus.getInstance().on("onLoginExpired", authChangedListener);
     }
 
     @Override
@@ -608,7 +660,7 @@ public class MainAbilitySlice extends AbilitySlice {
         }
         // 取消订阅认证状态变化事件
         if (authChangedListener != null) {
-            EventBus.getInstance().off("onAuthChanged", authChangedListener);
+            EventBus.getInstance().off("onLoginExpired", authChangedListener);
         }
 
         // 停止定位
@@ -626,4 +678,51 @@ public class MainAbilitySlice extends AbilitySlice {
         dataAbilityHelper.unregisterObserver(SystemSettings.getUri(SystemSettings.Date.TIME_FORMAT), dataAbilityObserver);
     }
 
+    /**
+     * 显示订单详情
+     */
+    private void showOrderDetail(OrderRes order) {
+        if (mainRight == null || orderDetailComponent == null) {
+            return;
+        }
+        // 移除所有子组件
+        mainRight.removeAllComponents();
+        // 设置订单数据
+        orderDetailComponent.setOrderData(order);
+        // 添加详情组件
+        mainRight.addComponent(orderDetailComponent);
+        // 显示详情区域
+        mainRight.setVisibility(Component.VISIBLE);
+    }
+
+    /**
+     * 显示停车场详情
+     */
+    private void showParkDetail(ParkNearRes park) {
+        if (mainRight == null || parkDetailComponent == null) {
+            return;
+        }
+        // 移除所有子组件
+        mainRight.removeAllComponents();
+        // 设置停车场数据
+        parkDetailComponent.setParkData(park);
+        // 添加详情组件
+        mainRight.addComponent(parkDetailComponent);
+        // 显示详情区域
+        mainRight.setVisibility(Component.VISIBLE);
+    }
+
+    /**
+     * 隐藏详情
+     */
+    private void hideDetail() {
+        if (mainRight == null) {
+            return;
+        }
+        // 移除所有子组件
+        mainRight.removeAllComponents();
+        // 隐藏详情区域
+        mainRight.setVisibility(Component.HIDE);
+    }
+
 }

+ 208 - 0
entry/src/main/java/com/fujica/abk/utils/ConfirmDialog.java

@@ -0,0 +1,208 @@
+package com.fujica.abk.utils;
+
+import ohos.agp.components.Button;
+import ohos.agp.components.Component;
+import ohos.agp.components.ComponentContainer;
+import ohos.agp.components.LayoutScatter;
+import ohos.agp.components.Text;
+import ohos.agp.window.dialog.CommonDialog;
+import ohos.app.Context;
+import com.fujica.abk.ResourceTable;
+
+/**
+ * 自定义确认对话框
+ * 
+ * 使用示例:
+ * <pre>
+ * // 基础用法
+ * new ConfirmDialog(context)
+ *     .setTitle("温馨提示")
+ *     .setMessage("确定要退出登录吗?")
+ *     .setConfirmListener(dialog -> {
+ *         // 执行确定操作
+ *         dialog.dismiss();
+ *     })
+ *     .setCancelListener(dialog -> {
+ *         // 执行取消操作
+ *         dialog.dismiss();
+ *     })
+ *     .show();
+ * 
+ * // 自定义按钮文字
+ * new ConfirmDialog(context)
+ *     .setMessage("是否删除该记录?")
+ *     .setConfirmText("删除")
+ *     .setCancelText("保留")
+ *     .setConfirmListener(dialog -> {
+ *         deleteRecord();
+ *         dialog.dismiss();
+ *     })
+ *     .show();
+ * </pre>
+ * 
+ * 特点:
+ * - 使用 XML 布局文件,取消按钮在左,确定按钮在右
+ * - 确定按钮使用 button.xml(橙色),取消按钮使用 button_cancel.xml(灰色)
+ * - 弹框宽度固定 280vp,背景半透明黑色遮罩
+ * - 支持链式调用,使用方便
+ */
+public class ConfirmDialog {
+    
+    private Context context;
+    private CommonDialog dialog;
+    private Component rootView;
+    private Text titleText;
+    private Text messageText;
+    private Button confirmButton;
+    private Button cancelButton;
+    
+    private String title = "提示";
+    private String message = "确认要执行此操作吗?";
+    private String confirmText = "确定";
+    private String cancelText = "取消";
+    private OnClickListener confirmListener;
+    private OnClickListener cancelListener;
+    
+    /**
+     * 点击监听器接口
+     */
+    public interface OnClickListener {
+        void onClick(ConfirmDialog dialog);
+    }
+    
+    public ConfirmDialog(Context context) {
+        this.context = context;
+        initDialog();
+    }
+    
+    /**
+     * 初始化对话框
+     */
+    private void initDialog() {
+        dialog = new CommonDialog(context);
+        
+        // 加载自定义布局
+        rootView = LayoutScatter.getInstance(context)
+                .parse(ResourceTable.Layout_layout_confirm_dialog, null, false);
+        
+        // 查找组件
+        titleText = (Text) rootView.findComponentById(ResourceTable.Id_dialog_title);
+        messageText = (Text) rootView.findComponentById(ResourceTable.Id_dialog_message);
+        confirmButton = (Button) rootView.findComponentById(ResourceTable.Id_btn_confirm);
+        cancelButton = (Button) rootView.findComponentById(ResourceTable.Id_btn_cancel);
+        
+        // 设置按钮点击事件
+        confirmButton.setClickedListener(component -> {
+            if (confirmListener != null) {
+                confirmListener.onClick(this);
+            } else {
+                dismiss();
+            }
+        });
+        
+        cancelButton.setClickedListener(component -> {
+            if (cancelListener != null) {
+                cancelListener.onClick(this);
+            } else {
+                dismiss();
+            }
+        });
+        
+        // 设置对话框内容
+        dialog.setContentCustomComponent(rootView);
+        
+        // 设置对话框属性
+        dialog.setTransparent(true); // 设置透明背景
+        dialog.setSize(ComponentContainer.LayoutConfig.MATCH_PARENT, 
+                      ComponentContainer.LayoutConfig.MATCH_PARENT);
+    }
+    
+    /**
+     * 设置标题
+     */
+    public ConfirmDialog setTitle(String title) {
+        this.title = title;
+        if (titleText != null) {
+            titleText.setText(title);
+        }
+        return this;
+    }
+    
+    /**
+     * 设置消息内容
+     */
+    public ConfirmDialog setMessage(String message) {
+        this.message = message;
+        if (messageText != null) {
+            messageText.setText(message);
+        }
+        return this;
+    }
+    
+    /**
+     * 设置确定按钮文本
+     */
+    public ConfirmDialog setConfirmText(String text) {
+        this.confirmText = text;
+        if (confirmButton != null) {
+            confirmButton.setText(text);
+        }
+        return this;
+    }
+    
+    /**
+     * 设置取消按钮文本
+     */
+    public ConfirmDialog setCancelText(String text) {
+        this.cancelText = text;
+        if (cancelButton != null) {
+            cancelButton.setText(text);
+        }
+        return this;
+    }
+    
+    /**
+     * 设置确定按钮点击监听器
+     */
+    public ConfirmDialog setConfirmListener(OnClickListener listener) {
+        this.confirmListener = listener;
+        return this;
+    }
+    
+    /**
+     * 设置取消按钮点击监听器
+     */
+    public ConfirmDialog setCancelListener(OnClickListener listener) {
+        this.cancelListener = listener;
+        return this;
+    }
+    
+    /**
+     * 显示对话框
+     */
+    public void show() {
+        if (dialog != null) {
+            dialog.show();
+        }
+    }
+    
+    /**
+     * 关闭对话框
+     */
+    public void dismiss() {
+        if (dialog != null) {
+            dialog.hide();
+        }
+    }
+    
+    /**
+     * 销毁对话框
+     */
+    public void destroy() {
+        if (dialog != null) {
+            dialog.destroy();
+            dialog = null;
+        }
+    }
+}
+

+ 257 - 0
entry/src/main/java/com/fujica/abk/utils/CustomListDialog.java

@@ -0,0 +1,257 @@
+package com.fujica.abk.utils;
+
+import ohos.agp.components.*;
+import ohos.agp.window.dialog.CommonDialog;
+import ohos.app.Context;
+import com.fujica.abk.ResourceTable;
+
+/**
+ * 自定义列表对话框
+ * 
+ * 使用示例:
+ * <pre>
+ * String[] options = {"选项1", "选项2", "选项3"};
+ * new CustomListDialog(context)
+ *     .setTitle("请选择")
+ *     .setItems(options)
+ *     .setOnItemClickListener((dialog, index) -> {
+ *         // 处理选择
+ *         dialog.dismiss();
+ *     })
+ *     .show();
+ * </pre>
+ * 
+ * 特点:
+ * - 使用 XML 布局文件,弹框宽度固定 280vp
+ * - 列表项使用自定义布局,居中显示
+ * - 背景半透明黑色遮罩,圆角白色卡片
+ * - 支持链式调用,使用方便
+ */
+public class CustomListDialog {
+    
+    private Context context;
+    private CommonDialog dialog;
+    private Component rootView;
+    private Text titleText;
+    private ListContainer listContainer;
+    private Button cancelButton;
+    
+    private String title = "请选择";
+    private String[] items;
+    private OnItemClickListener itemClickListener;
+    private int selectedIndex = -1; // 记录当前选中项的索引,-1表示未选中
+    
+    /**
+     * 列表项点击监听器接口
+     */
+    public interface OnItemClickListener {
+        void onItemClick(CustomListDialog dialog, int index);
+    }
+    
+    public CustomListDialog(Context context) {
+        this.context = context;
+        initDialog();
+    }
+    
+    /**
+     * 初始化对话框
+     */
+    private void initDialog() {
+        dialog = new CommonDialog(context);
+        
+        // 加载自定义布局
+        rootView = LayoutScatter.getInstance(context)
+                .parse(ResourceTable.Layout_layout_custom_list_dialog, null, false);
+        
+        // 查找组件
+        titleText = (Text) rootView.findComponentById(ResourceTable.Id_dialog_title);
+        listContainer = (ListContainer) rootView.findComponentById(ResourceTable.Id_list_container);
+        cancelButton = (Button) rootView.findComponentById(ResourceTable.Id_btn_cancel);
+        
+        // 设置取消按钮点击事件
+        cancelButton.setClickedListener(component -> dismiss());
+        
+        // 设置对话框内容
+        dialog.setContentCustomComponent(rootView);
+        
+        // 设置对话框属性
+        dialog.setTransparent(true); // 设置透明背景
+        dialog.setSize(ComponentContainer.LayoutConfig.MATCH_PARENT, 
+                      ComponentContainer.LayoutConfig.MATCH_PARENT);
+    }
+    
+    /**
+     * 设置标题
+     */
+    public CustomListDialog setTitle(String title) {
+        this.title = title;
+        if (titleText != null) {
+            titleText.setText(title);
+        }
+        return this;
+    }
+    
+    /**
+     * 设置列表项
+     */
+    public CustomListDialog setItems(String[] items) {
+        this.items = items;
+        updateList();
+        return this;
+    }
+    
+    /**
+     * 设置列表项点击监听器
+     */
+    public CustomListDialog setOnItemClickListener(OnItemClickListener listener) {
+        this.itemClickListener = listener;
+        return this;
+    }
+    
+    /**
+     * 设置当前选中项
+     */
+    public CustomListDialog setSelectedIndex(int index) {
+        this.selectedIndex = index;
+        updateList();
+        return this;
+    }
+    
+    /**
+     * 获取当前选中项索引
+     */
+    public int getSelectedIndex() {
+        return selectedIndex;
+    }
+    
+    /**
+     * 更新列表
+     */
+    private void updateList() {
+        if (listContainer == null || items == null || items.length == 0) {
+            return;
+        }
+        
+        // 创建并设置适配器
+        CustomListAdapter adapter = new CustomListAdapter(context, items, selectedIndex);
+        listContainer.setItemProvider(adapter);
+        
+        // 设置列表项点击事件
+        listContainer.setItemClickedListener((listContainer, component, position, id) -> {
+            // 更新选中项
+            selectedIndex = position;
+            // 刷新列表以更新颜色
+            updateList();
+            
+            if (itemClickListener != null) {
+                itemClickListener.onItemClick(this, position);
+            }
+        });
+    }
+    
+    /**
+     * 显示对话框
+     */
+    public void show() {
+        if (dialog != null) {
+            dialog.show();
+        }
+    }
+    
+    /**
+     * 关闭对话框
+     */
+    public void dismiss() {
+        if (dialog != null) {
+            dialog.hide();
+        }
+    }
+    
+    /**
+     * 销毁对话框
+     */
+    public void destroy() {
+        if (dialog != null) {
+            dialog.destroy();
+            dialog = null;
+        }
+    }
+    
+    /**
+     * 自定义列表适配器
+     */
+    private static class CustomListAdapter extends BaseItemProvider {
+        private Context context;
+        private String[] items;
+        private int selectedIndex; // 当前选中项索引
+        
+        public CustomListAdapter(Context context, String[] items, int selectedIndex) {
+            this.context = context;
+            this.items = items;
+            this.selectedIndex = selectedIndex;
+        }
+        
+        @Override
+        public int getCount() {
+            return items != null ? items.length : 0;
+        }
+        
+        @Override
+        public Object getItem(int position) {
+            return items != null && position < items.length ? items[position] : null;
+        }
+        
+        @Override
+        public long getItemId(int position) {
+            return position;
+        }
+        
+        @Override
+        public Component getComponent(int position, Component convertComponent, ComponentContainer componentContainer) {
+            ViewHolder holder;
+            Component component = convertComponent;
+            
+            if (component == null) {
+                component = LayoutScatter.getInstance(context)
+                        .parse(ResourceTable.Layout_item_custom_list_dialog, null, false);
+                holder = new ViewHolder();
+                holder.textItem = (Text) component.findComponentById(ResourceTable.Id_text_item);
+                holder.divider = component.findComponentById(ResourceTable.Id_divider);
+                component.setTag(holder);
+            } else {
+                holder = (ViewHolder) component.getTag();
+            }
+            
+            // 设置文本
+            if (holder.textItem != null && items != null && position < items.length) {
+                holder.textItem.setText(items[position]);
+                
+                // 根据是否选中设置文本颜色
+                if (position == selectedIndex) {
+                    // 选中项设置为橙色
+                    holder.textItem.setTextColor(new ohos.agp.utils.Color(0xFFFF6600));
+                } else {
+                    // 未选中项设置为默认颜色
+                    holder.textItem.setTextColor(new ohos.agp.utils.Color(0xFF333333));
+                }
+            }
+            
+            // 最后一项隐藏分割线
+            if (holder.divider != null) {
+                holder.divider.setVisibility(position == getCount() - 1 ? 
+                        Component.HIDE : Component.VISIBLE);
+            }
+            
+            return component;
+        }
+        
+        /**
+         * ViewHolder 模式
+         */
+        private static class ViewHolder {
+            Text textItem;
+            Component divider;
+        }
+    }
+}
+

+ 133 - 0
entry/src/main/java/com/fujica/abk/utils/DateDialog.java

@@ -0,0 +1,133 @@
+package com.fujica.abk.utils;
+
+import com.fujica.abk.ResourceTable;
+import ohos.agp.components.DirectionalLayout;
+import ohos.agp.components.LayoutScatter;
+import ohos.agp.components.Picker;
+import ohos.agp.components.Text;
+import ohos.agp.window.dialog.CommonDialog;
+import ohos.app.Context;
+
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.List;
+
+/**
+ * 日期选择对话框
+ * 用于选择年月(格式:YYYY-MM)
+ */
+public class DateDialog extends CommonDialog {
+    private Context context;
+    private Picker yearPicker;
+    private Picker monthPicker;
+    private String selectedDate;
+    private OnDateSelectedListener listener;
+
+    // 回调接口
+    public interface OnDateSelectedListener {
+        void onDateSelected(String date);
+    }
+
+    /**
+     * 构造函数
+     */
+    public DateDialog(Context context, String currentDate, OnDateSelectedListener listener) {
+        super(context);
+        this.context = context;
+        this.selectedDate = currentDate;
+        this.listener = listener;
+        initDialog();
+    }
+
+    /**
+     * 初始化对话框
+     */
+    private void initDialog() {
+        setAutoClosable(true);
+        setCornerRadius(ScreenUtil.vp2px(context, 10));
+        setTransparent(true);
+        // 加载XML布局
+        DirectionalLayout mainLayout = (DirectionalLayout) LayoutScatter.getInstance(context)
+                .parse(ResourceTable.Layout_layout_date_dialog, null, false);
+        
+        // 获取组件引用
+        yearPicker = (Picker) mainLayout.findComponentById(ResourceTable.Id_year_picker);
+        monthPicker = (Picker) mainLayout.findComponentById(ResourceTable.Id_month_picker);
+        Text btnConfirm = (Text) mainLayout.findComponentById(ResourceTable.Id_btn_confirm);
+        mainLayout.findComponentById(ResourceTable.Id_close).setClickedListener(v->{
+            destroy();
+        });
+
+        // 初始化数据
+        initPickerData();
+
+        // 设置确认按钮点击事件
+        btnConfirm.setClickedListener(component -> {
+            int yearIndex = yearPicker.getValue();
+            int monthIndex = monthPicker.getValue();
+            String year = String.valueOf(Calendar.getInstance().get(Calendar.YEAR) - 10 + yearIndex);
+            String month = String.format("%02d", monthIndex + 1);
+            String date = year + "-" + month;
+            if (listener != null) {
+                listener.onDateSelected(date);
+            }
+            destroy();
+        });
+
+        setContentCustomComponent(mainLayout);
+    }
+
+    /**
+     * 初始化选择器数据
+     */
+    private void initPickerData() {
+        Calendar calendar = Calendar.getInstance();
+        int currentYear = calendar.get(Calendar.YEAR);
+        int currentMonth = calendar.get(Calendar.MONTH);
+
+        // 初始化年份数据(当前年份前后各10年)
+        List<String> yearList = new ArrayList<>();
+        for (int i = currentYear - 10; i <= currentYear + 10; i++) {
+            yearList.add(String.valueOf(i));
+        }
+        yearPicker.setDisplayedData(yearList.toArray(new String[0]));
+        yearPicker.setMinValue(0);
+        yearPicker.setMaxValue(yearList.size() - 1);
+        yearPicker.setValue(10); // 默认选中当前年份
+
+        // 初始化月份数据
+        List<String> monthList = new ArrayList<>();
+        for (int i = 1; i <= 12; i++) {
+            monthList.add(String.format("%02d月", i));
+        }
+        monthPicker.setDisplayedData(monthList.toArray(new String[0]));
+        monthPicker.setMinValue(0);
+        monthPicker.setMaxValue(11);
+        monthPicker.setValue(currentMonth); // 默认选中当前月份
+
+        // 如果传入了当前日期,设置选中值
+        if (selectedDate != null && !selectedDate.isEmpty()) {
+            try {
+                String[] parts = selectedDate.split("-");
+                if (parts.length == 2) {
+                    int year = Integer.parseInt(parts[0]);
+                    int month = Integer.parseInt(parts[1]);
+                    
+                    // 设置年份
+                    int yearIndex = year - (currentYear - 10);
+                    if (yearIndex >= 0 && yearIndex < yearList.size()) {
+                        yearPicker.setValue(yearIndex);
+                    }
+                    
+                    // 设置月份
+                    if (month >= 1 && month <= 12) {
+                        monthPicker.setValue(month - 1);
+                    }
+                }
+            } catch (Exception e) {
+                // 忽略解析错误,使用默认值
+            }
+        }
+    }
+}
+

+ 94 - 15
entry/src/main/java/com/fujica/abk/utils/DialogUtil.java

@@ -1,8 +1,9 @@
 package com.fujica.abk.utils;
 
 import ohos.agp.window.dialog.IDialog;
-import ohos.agp.window.dialog.ListDialog;
 import ohos.app.Context;
+import ohos.eventhandler.EventHandler;
+import ohos.eventhandler.EventRunner;
 
 /**
  * 对话框工具类
@@ -25,29 +26,107 @@ public class DialogUtil {
     }
     
     /**
-     * 创建并配置 ListDialog(公共方法)
-     * 统一设置样式,使对话框内容左右居中
+     * 创建并配置自定义 ListDialog(公共方法)
+     * 使用 XML 布局,美化显示,固定宽度 280vp
      * 
      * @param context 上下文
      * @param options 选项数组
      * @param listener 选择监听器
-     * @return 配置好的 ListDialog
+     * @return 配置好的 CustomListDialog
      */
-    public static ListDialog createListDialog(Context context, String[] options, 
-                                              SingleSelectListener listener) {
-        ListDialog listDialog = new ListDialog(context);
-        listDialog.setItems(options);
-        listDialog.setOnSingleSelectListener((iDialog, index) -> {
+    public static CustomListDialog createListDialog(Context context, String[] options, 
+                                                    SingleSelectListener listener) {
+        CustomListDialog customListDialog = new CustomListDialog(context);
+        customListDialog.setItems(options);
+        customListDialog.setOnItemClickListener((dialog, index) -> {
             if (listener != null) {
-                listener.onSelect(iDialog, index);
+                // 转换 CustomListDialog 为 IDialog 的适配
+                listener.onSelect(new IDialog() {
+                    @Override
+                    public void show() {
+                        dialog.show();
+                    }
+
+                    @Override
+                    public void hide() {
+                        dialog.dismiss();
+                    }
+
+                    @Override
+                    public void destroy() {
+                        dialog.destroy();
+                    }
+
+                    @Override
+                    public void remove() {
+                        dialog.dismiss();
+                    }
+
+                }, index);
             }
         });
         
-        // 在 HarmonyOS 中,ListDialog 默认会居中显示
-        // 如果需要自定义样式,可以在这里添加相关配置
-        // 注意:ListDialog 在 HarmonyOS 中默认就是居中的,无需额外设置
-        
-        return listDialog;
+        return customListDialog;
+    }
+
+
+
+    /**
+     * 显示确认对话框
+     * @param context 上下文
+     * @param message 提示信息
+     * @param onConfirm 确定按钮回调
+     */
+    public static void confirm(Context context, String message, Runnable onConfirm) {
+        confirm(context, message, onConfirm, null);
+    }
+
+    /**
+     * 显示确认对话框
+     * @param context 上下文
+     * @param message 提示信息
+     * @param onConfirm 确定按钮回调
+     * @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(() -> {
+            showConfirmDialog(context, message, onConfirm, onCancel);
+        });
+    }
+
+    /**
+     * 显示确认对话框的实际实现
+     */
+    private static void showConfirmDialog(Context context, String message, Runnable onConfirm, Runnable onCancel) {
+        ConfirmDialog confirmDialog = new ConfirmDialog(context);
+        confirmDialog.setMessage(message)
+                .setConfirmListener(dialog -> {
+                    if (onConfirm != null) {
+                        onConfirm.run();
+                    }
+                    dialog.dismiss();
+                })
+                .setCancelListener(dialog -> {
+                    if (onCancel != null) {
+                        onCancel.run();
+                    }
+                    dialog.dismiss();
+                })
+                .show();
     }
 }
 

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

@@ -1,5 +1,6 @@
 package com.fujica.abk.utils;
 
+import ohos.agp.window.dialog.CommonDialog;
 import ohos.agp.window.dialog.ToastDialog;
 import ohos.app.Context;
 import ohos.eventhandler.EventHandler;

+ 3 - 1
entry/src/main/java/com/fujica/abk/utils/api.java

@@ -97,6 +97,7 @@ public class api {
 
         String url = mergeUrl(option.getUrl(), option.getMethod(), option.getData());
         String token = cache.getToken(context);
+        Log.error("token:" + token);
         final String _url = url;
         return CompletableFuture.supplyAsync(() -> {
             HttpURLConnection connection = null;
@@ -131,9 +132,10 @@ public class api {
                 try {
                     R<T> result;
                     if (responseCode == 401) {
+                        Log.error("响应:" + +responseCode);
                         Toast.error(context, "登录过期,请重试");
                         cache.logout(context);
-                        EventBus.getInstance().emit("onAuthChanged");
+                        EventBus.getInstance().emit("onLoginExpired");
                         result = new R<>("登录过期,请重试 ");
                     } else if (responseCode != 200) {
                         String msg = "操作失败:" + responseCode;

+ 10 - 0
entry/src/main/resources/base/graphic/background_circle_8.xml

@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape
+    xmlns:ohos="http://schemas.huawei.com/res/ohos"
+    ohos:shape="rectangle">
+    <corners
+        ohos:radius="8vp"/>
+    <solid
+        ohos:color="#FFFFFFFF"/>
+</shape>
+

+ 12 - 0
entry/src/main/resources/base/graphic/background_circle_8_top.xml

@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape
+    xmlns:ohos="http://schemas.huawei.com/res/ohos"
+    ohos:shape="rectangle">
+    <corners
+        ohos:left_bottom_x="0"
+        ohos:right_bottom_x="0"
+        ohos:radius="8vp"/>
+    <solid
+        ohos:color="#FFFFFFFF"/>
+</shape>
+

+ 12 - 0
entry/src/main/resources/base/graphic/background_circle_8_top_selected.xml

@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape
+    xmlns:ohos="http://schemas.huawei.com/res/ohos"
+    ohos:shape="rectangle">
+    <corners
+        ohos:left_bottom_x="0"
+        ohos:right_bottom_x="0"
+        ohos:radius="8vp"/>
+    <solid
+        ohos:color="#FFECE6"/>
+</shape>
+

+ 25 - 5
entry/src/main/resources/base/layout/ability_main.xml

@@ -11,12 +11,19 @@
         ohos:width="match_parent">
     </PositionLayout>
 
-    <!-- 主内容区域 - 垂直布局 -->
+    <!-- 主内容区域 - 水平布局 -->
     <DirectionalLayout
         ohos:height="match_parent"
-        ohos:width="400vp"
-        ohos:margin="10vp"
-        ohos:orientation="vertical">
+        ohos:width="match_parent"
+        ohos:orientation="horizontal"
+        ohos:margin="10vp">
+
+        <!-- 左侧内容区域 - 垂直布局 -->
+        <DirectionalLayout
+            ohos:id="$+id:main_left"
+            ohos:height="match_parent"
+            ohos:width="400vp"
+            ohos:orientation="vertical">
 
         <DirectionalLayout
             ohos:height="40vp"
@@ -57,7 +64,7 @@
                     ohos:id="$+id:quit"
                     ohos:height="25vp"
                     ohos:width="25vp"
-                    ohos:image_src="$media:logo_white"
+                    ohos:image_src="$media:logout"
                     ohos:scale_mode="stretch"
 
                     ></Image>
@@ -230,6 +237,19 @@
             ohos:layout_alignment="right|horizontal_center"
             ohos:text="华为账号登录"
             ohos:visibility="hide"></Button>
+        </DirectionalLayout>
+
+        <!-- 右侧详情区域 -->
+        <DirectionalLayout
+            ohos:id="$+id:main_right"
+            ohos:height="match_parent"
+            ohos:width="0vp"
+            ohos:weight="1"
+            ohos:left_margin="10vp"
+            ohos:background_element="#FFFFFFFF"
+            ohos:visibility="hide">
+            <!-- 详情组件将动态添加到这里 -->
+        </DirectionalLayout>
     </DirectionalLayout>
 
     <!-- Loading组件放在最后,确保在最上层显示 -->

+ 29 - 0
entry/src/main/resources/base/layout/item_custom_list_dialog.xml

@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<DirectionalLayout
+    xmlns:ohos="http://schemas.huawei.com/res/ohos"
+    ohos:height="match_content"
+    ohos:width="match_parent"
+    ohos:orientation="vertical"
+    ohos:padding="16vp"
+    ohos:clickable="true"
+    ohos:focusable="focus_enable">
+
+    <!-- 选项文本 -->
+    <Text
+        ohos:id="$+id:text_item"
+        ohos:height="match_content"
+        ohos:width="match_parent"
+        ohos:text="选项"
+        ohos:text_size="16fp"
+        ohos:text_alignment="center"/>
+
+    <!-- 分割线 -->
+    <Component
+        ohos:id="$+id:divider"
+        ohos:height="1px"
+        ohos:width="match_parent"
+        ohos:top_margin="16vp"
+        ohos:background_element="#E5E5E5"/>
+
+</DirectionalLayout>
+

+ 114 - 0
entry/src/main/resources/base/layout/item_order.xml

@@ -0,0 +1,114 @@
+<?xml version="1.0" encoding="utf-8"?>
+<DirectionalLayout
+    xmlns:ohos="http://schemas.huawei.com/res/ohos"
+    ohos:height="match_content"
+    ohos:width="match_parent"
+    ohos:orientation="vertical"
+    ohos:padding="12vp"
+    ohos:left_margin="10vp"
+    ohos:right_margin="10vp"
+    ohos:bottom_margin="10vp"
+    ohos:background_element="$graphic:background_circle_8_top">
+
+    <!-- 第一行:商品名称和状态 -->
+    <DirectionalLayout
+        ohos:height="match_content"
+        ohos:width="match_parent"
+        ohos:orientation="horizontal"
+        ohos:alignment="center">
+
+        <!-- 商品名称 -->
+        <Text
+            ohos:id="$+id:text_goods_name"
+            ohos:height="match_content"
+            ohos:width="0vp"
+            ohos:weight="0.8"
+            ohos:text="商品名称"
+            ohos:text_size="16fp"
+            ohos:text_color="#FF000000"
+            ohos:max_text_lines="2"/>
+
+        <!-- 占位 -->
+        <Component
+            ohos:height="match_content"
+            ohos:width="0vp"
+            ohos:weight="1.0"/>
+
+        <!-- 状态文本 -->
+        <Text
+            ohos:id="$+id:text_status"
+            ohos:height="match_content"
+            ohos:width="match_content"
+            ohos:text="已完成"
+            ohos:text_size="14fp"
+            ohos:text_color="#FF999999"/>
+    </DirectionalLayout>
+
+    <!-- 分割线 -->
+    <Component
+        ohos:height="1vp"
+        ohos:width="match_parent"
+        ohos:top_margin="12vp"
+        ohos:background_element="#FFE5E5E5"/>
+
+    <!-- 第二行:图标、车场名称、时间、金额 -->
+    <DirectionalLayout
+        ohos:height="match_content"
+        ohos:width="match_parent"
+        ohos:orientation="horizontal"
+        ohos:alignment="center"
+        ohos:top_margin="12vp">
+
+        <!-- 图标 -->
+        <Image
+            ohos:id="$+id:icon_tcjf"
+            ohos:height="56vp"
+            ohos:width="56vp"
+            ohos:image_src="$media:tcjf"
+            ohos:right_margin="10vp"/>
+        <Image
+            ohos:id="$+id:icon_ykxf"
+            ohos:height="56vp"
+            ohos:width="56vp"
+            ohos:image_src="$media:ykxf"
+            ohos:right_margin="10vp"/>
+
+        <!-- 车场名称和时间容器 -->
+        <DirectionalLayout
+            ohos:height="match_content"
+            ohos:width="0vp"
+            ohos:weight="1.0"
+            ohos:orientation="vertical">
+
+            <!-- 车场名称 -->
+            <Text
+                ohos:id="$+id:text_park_name"
+                ohos:height="match_content"
+                ohos:width="match_parent"
+                ohos:text="车场名称"
+                ohos:text_size="14fp"
+                ohos:text_color="#FF000000"/>
+
+            <!-- 支付时间 -->
+            <Text
+                ohos:id="$+id:text_pay_time"
+                ohos:height="match_content"
+                ohos:width="match_parent"
+                ohos:text="支付时间"
+                ohos:text_size="14fp"
+                ohos:text_color="#FF000000"
+                ohos:top_margin="12vp"/>
+        </DirectionalLayout>
+
+        <!-- 金额 -->
+        <Text
+            ohos:id="$+id:text_amount"
+            ohos:height="match_content"
+            ohos:width="match_content"
+            ohos:text="¥0.00"
+            ohos:text_size="18fp"
+            ohos:text_color="#FA6332"
+            ohos:top_margin="-20vp"/>
+    </DirectionalLayout>
+</DirectionalLayout>
+

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

@@ -37,7 +37,7 @@
                         ohos:height="match_content"
                         ohos:width="0vp"
                         ohos:weight="1"
-                        ohos:text="京N8P8F8"
+                        ohos:text=""
                         ohos:text_size="18fp"
                         ohos:text_color="#FF000000"
                         ohos:text_alignment="center"/>

+ 81 - 0
entry/src/main/resources/base/layout/layout_confirm_dialog.xml

@@ -0,0 +1,81 @@
+<?xml version="1.0" encoding="utf-8"?>
+<DirectionalLayout
+    xmlns:ohos="http://schemas.huawei.com/res/ohos"
+    ohos:height="match_parent"
+    ohos:width="match_parent"
+    ohos:alignment="center"
+    ohos:orientation="vertical"
+    ohos:background_element="#80000000">
+    <!-- 半透明黑色背景 -->
+
+    <!-- 对话框内容容器(白色圆角卡片) -->
+    <DirectionalLayout
+        ohos:id="$+id:dialog_container"
+        ohos:height="match_content"
+        ohos:width="280vp"
+        ohos:orientation="vertical"
+        ohos:background_element="$graphic:background_circle_16"
+        ohos:padding="24vp">
+
+        <!-- 标题 -->
+        <Text
+            ohos:id="$+id:dialog_title"
+            ohos:height="match_content"
+            ohos:width="match_parent"
+            ohos:text="提示"
+            ohos:text_size="18fp"
+            ohos:text_color="#666666"
+            ohos:text_weight="700"
+            ohos:text_alignment="center"
+            ohos:margin="0vp"/>
+
+        <!-- 消息内容 -->
+        <Text
+            ohos:id="$+id:dialog_message"
+            ohos:height="match_content"
+            ohos:width="match_parent"
+            ohos:text="确认要执行此操作吗?"
+            ohos:text_size="15fp"
+            ohos:text_color="#333333"
+            ohos:text_alignment="center"
+            ohos:top_margin="16vp"
+            ohos:multiple_lines="true"/>
+
+        <!-- 按钮容器 -->
+        <DirectionalLayout
+            ohos:height="match_content"
+            ohos:width="match_parent"
+            ohos:orientation="horizontal"
+            ohos:top_margin="24vp"
+            ohos:alignment="center">
+
+            <!-- 取消按钮(左边) -->
+            <Button
+                ohos:id="$+id:btn_cancel"
+                ohos:height="40vp"
+                ohos:width="0vp"
+                ohos:weight="1"
+                ohos:text="取消"
+                ohos:text_size="15fp"
+                ohos:text_color="#FFFFFF"
+                ohos:background_element="$graphic:button_cancel"
+                ohos:right_margin="8vp"/>
+
+            <!-- 确定按钮(右边) -->
+            <Button
+                ohos:id="$+id:btn_confirm"
+                ohos:height="40vp"
+                ohos:width="0vp"
+                ohos:weight="1"
+                ohos:text="确定"
+                ohos:text_size="15fp"
+                ohos:text_color="#FFFFFF"
+                ohos:background_element="$graphic:button"
+                ohos:left_margin="8vp"/>
+
+        </DirectionalLayout>
+
+    </DirectionalLayout>
+
+</DirectionalLayout>
+

+ 59 - 0
entry/src/main/resources/base/layout/layout_custom_list_dialog.xml

@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="utf-8"?>
+<DirectionalLayout
+    xmlns:ohos="http://schemas.huawei.com/res/ohos"
+    ohos:height="match_parent"
+    ohos:width="match_parent"
+    ohos:alignment="center"
+    ohos:orientation="vertical"
+    ohos:background_element="#80000000">
+    <!-- 半透明黑色背景 -->
+
+    <!-- 对话框内容容器(白色圆角卡片) -->
+    <DirectionalLayout
+        ohos:id="$+id:dialog_container"
+        ohos:height="match_content"
+        ohos:width="280vp"
+        ohos:orientation="vertical"
+        ohos:background_element="$graphic:background_circle_16">
+
+        <!-- 标题 -->
+        <Text
+            ohos:id="$+id:dialog_title"
+            ohos:height="match_content"
+            ohos:width="match_parent"
+            ohos:text="请选择"
+            ohos:text_size="18fp"
+            ohos:text_color="#333"
+            ohos:text_weight="700"
+            ohos:text_alignment="center"
+            ohos:top_padding="24vp"
+            ohos:left_padding="24vp"
+            ohos:right_padding="24vp"
+            ohos:bottom_padding="12vp"/>
+
+        <!-- 列表容器 -->
+        <ListContainer
+            ohos:id="$+id:list_container"
+            ohos:height="match_content"
+            ohos:width="match_parent"
+            ohos:max_height="400vp"
+            ohos:top_margin="4vp"
+            ohos:bottom_margin="4vp"/>
+
+        <!-- 取消按钮 -->
+        <Button
+            ohos:id="$+id:btn_cancel"
+            ohos:height="48vp"
+            ohos:width="match_parent"
+            ohos:text="取消"
+            ohos:text_size="16fp"
+            ohos:text_color="#999999"
+            ohos:background_element="#00000000"
+            ohos:top_margin="8vp"
+            ohos:top_padding="8vp"
+            ohos:bottom_padding="8vp"/>
+
+    </DirectionalLayout>
+
+</DirectionalLayout>
+

+ 99 - 0
entry/src/main/resources/base/layout/layout_date_dialog.xml

@@ -0,0 +1,99 @@
+<?xml version="1.0" encoding="utf-8"?>
+<DirectionalLayout
+    xmlns:ohos="http://schemas.huawei.com/res/ohos"
+    ohos:height="match_content"
+    ohos:width="match_parent"
+    ohos:alignment="center">
+
+    <DirectionalLayout
+        ohos:height="match_content"
+        ohos:width="400vp"
+        ohos:alignment="center"
+        ohos:background_element="$graphic:background_circle_16"
+        ohos:orientation="vertical"
+        ohos:padding="20vp">
+
+
+        <DirectionalLayout
+            ohos:height="match_content"
+            ohos:width="match_parent"
+            ohos:orientation="horizontal">
+
+            <!-- 标题 -->
+            <Text
+                ohos:id="$+id:title_text"
+                ohos:height="match_content"
+                ohos:width="0"
+                ohos:weight="1"
+                ohos:bottom_margin="20vp"
+                ohos:text="选择日期"
+                ohos:text_color="#FF000000"
+                ohos:text_size="18fp"/>
+            <Image ohos:id="$+id:close" ohos:image_src="$media:close"
+                   ohos:scale_mode="stretch"
+                   ohos:padding="5vp"
+                ohos:width="26vp"
+                   ohos:height="26vp"
+                />
+        </DirectionalLayout>
+
+
+        <!-- 日期选择器容器 -->
+        <DirectionalLayout
+            ohos:height="match_content"
+            ohos:width="match_parent"
+            ohos:alignment="center"
+            ohos:orientation="horizontal">
+
+            <!-- 年份选择器 -->
+            <Picker
+                ohos:id="$+id:year_picker"
+                ohos:height="match_content"
+                ohos:width="0"
+                ohos:normal_text_color="#FF666666"
+                ohos:normal_text_size="20fp"
+                ohos:selected_text_color="#FFFA6332"
+                ohos:selected_text_size="24fp"
+                ohos:weight="1"/>
+
+            <!-- 月份选择器 -->
+            <Picker
+                ohos:id="$+id:month_picker"
+                ohos:height="match_content"
+                ohos:width="0"
+                ohos:normal_text_color="#FF666666"
+                ohos:normal_text_size="20fp"
+                ohos:selected_text_color="#FFFA6332"
+                ohos:selected_text_size="24fp"
+                ohos:weight="1"/>
+
+        </DirectionalLayout>
+
+        <!-- 按钮容器 -->
+        <DirectionalLayout
+            ohos:height="match_content"
+            ohos:width="match_parent"
+            ohos:alignment="center"
+            ohos:orientation="horizontal"
+            ohos:top_margin="20vp">
+
+            <!-- 确认按钮 -->
+            <Text
+                ohos:id="$+id:btn_confirm"
+                ohos:height="48vp"
+                ohos:width="match_parent"
+                ohos:background_element="$graphic:button"
+                ohos:clickable="true"
+                ohos:focusable="focus_enable"
+                ohos:left_margin="20vp"
+                ohos:right_margin="20vp"
+                ohos:text="确认"
+                ohos:text_alignment="center"
+                ohos:text_color="#FFFFFFFF"
+                ohos:text_size="16fp"/>
+
+        </DirectionalLayout>
+
+    </DirectionalLayout>
+</DirectionalLayout>
+

+ 10 - 4
entry/src/main/resources/base/layout/layout_license_plate_dialog.xml

@@ -16,11 +16,13 @@
 
         <DirectionalLayout
             ohos:height="match_content"
-            ohos:width="500vp"
+            ohos:width="match_content"
+            ohos:left_margin="150vp"
             ohos:orientation="vertical">
 
             <!-- 车牌输入区域 -->
             <DirectionalLayout
+
                 ohos:height="80vp"
                 ohos:width="match_parent"
                 ohos:alignment="center"
@@ -212,9 +214,11 @@
             <Button
                 ohos:id="$+id:btn_confirm"
                 ohos:height="48vp"
-                ohos:width="match_parent"
+                ohos:width="360vp"
                 ohos:background_element="$graphic:button"
                 ohos:text="确认"
+                ohos:right_margin="20vp"
+                ohos:left_margin="20vp"
                 ohos:bottom_margin="10vp"
                 ohos:text_color="#FFFFFFFF"
                 ohos:text_size="16fp"/>
@@ -222,15 +226,17 @@
         </DirectionalLayout>
 
         <Image
+
             ohos:id="$+id:btn_close"
             ohos:top_margin="20vp"
-            ohos:layout_alignment="right|top"
+            ohos:left_margin="100vp"
+            ohos:layout_alignment="left"
             ohos:scale_mode="stretch"
             ohos:height="24vp"
             ohos:width="24vp"
             ohos:clickable="true"
             ohos:focusable="focus_enable"
-            ohos:image_src="$media:quit"/>
+            ohos:image_src="$media:close"/>
     </DirectionalLayout>
 
 

+ 54 - 16
entry/src/main/resources/base/layout/layout_order.xml

@@ -4,37 +4,75 @@
     ohos:height="match_parent"
     ohos:width="match_parent"
     ohos:orientation="vertical"
-    ohos:background_element="#FFFFFFFF">
+    ohos:background_element="#F5F5F5">
 
-    <ScrollView
-        ohos:height="0vp"
+    <!-- 日期筛选 -->
+    <DirectionalLayout
+        ohos:id="$+id:filter_date_container"
+        ohos:height="match_content"
         ohos:width="match_parent"
-        ohos:weight="1"
-        ohos:background_element="#FFFFFFFF">
+        ohos:orientation="horizontal"
+        ohos:background_element="#F5F5F5"
+        ohos:padding="12vp">
 
         <DirectionalLayout
+            ohos:id="$+id:btn_biz_type_filter"
             ohos:height="match_content"
-            ohos:width="match_parent"
-            ohos:orientation="vertical"
-            ohos:padding="16vp"
+            ohos:width="match_content"
+            ohos:orientation="horizontal"
             ohos:alignment="center">
-
+            <Text
+                ohos:id="$+id:text_biz_type"
+                ohos:height="match_content"
+                ohos:width="match_content"
+                ohos:text="全部"
+                ohos:text_size="16fp"
+                ohos:text_color="#FF000000"/>
             <Text
                 ohos:height="match_content"
                 ohos:width="match_content"
-                ohos:text="缴费记录"
-                ohos:text_size="24fp"
-                ohos:text_color="#FF000000"
-                ohos:margin_top="100vp"/>
+                ohos:text="▼"
+                ohos:text_size="10fp"
+                ohos:text_color="#FF666666"
+                ohos:left_margin="4vp"/>
+        </DirectionalLayout>
 
+        <DirectionalLayout
+            ohos:id="$+id:btn_date_filter"
+            ohos:height="match_content"
+            ohos:width="match_content"
+            ohos:orientation="horizontal"
+            ohos:left_margin="24vp"
+            ohos:alignment="center">
             <Text
+                ohos:id="$+id:text_date"
                 ohos:height="match_content"
                 ohos:width="match_content"
-                ohos:text="缴费记录功能开发中..."
+                ohos:text="2024-01"
                 ohos:text_size="16fp"
+                ohos:text_color="#FF000000"/>
+            <Text
+                ohos:height="match_content"
+                ohos:width="match_content"
+                ohos:text="▼"
+                ohos:text_size="10fp"
                 ohos:text_color="#FF666666"
-                ohos:margin_top="20vp"/>
+                ohos:left_margin="4vp"/>
+        </DirectionalLayout>
+    </DirectionalLayout>
+
+    <!-- 订单列表 -->
+    <ScrollView
+        ohos:id="$+id:order_list_scroll"
+        ohos:height="0vp"
+        ohos:width="match_parent"
+        ohos:weight="1"
+        ohos:background_element="#F5F5F5">
+        <DirectionalLayout
+            ohos:id="$+id:order_list_container"
+            ohos:height="match_content"
+            ohos:width="match_parent"
+            ohos:orientation="vertical">
         </DirectionalLayout>
     </ScrollView>
 </DirectionalLayout>
-

+ 133 - 0
entry/src/main/resources/base/layout/layout_order_detail.xml

@@ -0,0 +1,133 @@
+<?xml version="1.0" encoding="utf-8"?>
+<DirectionalLayout
+    xmlns:ohos="http://schemas.huawei.com/res/ohos"
+    ohos:height="match_parent"
+    ohos:width="match_parent"
+    ohos:orientation="vertical"
+    ohos:background_element="#FFFFFFFF"
+    ohos:padding="16vp">
+
+    <!-- 标题 -->
+    <Text
+        ohos:id="$+id:detail_title"
+        ohos:height="match_content"
+        ohos:width="match_parent"
+        ohos:text="订单详情"
+        ohos:text_size="18fp"
+        ohos:text_color="#FF000000"
+        ohos:text_weight="600"
+        ohos:bottom_margin="16vp"/>
+
+    <!-- 商品名称 -->
+    <DirectionalLayout
+        ohos:height="match_content"
+        ohos:width="match_parent"
+        ohos:orientation="horizontal"
+        ohos:bottom_margin="12vp">
+        <Text
+            ohos:height="match_content"
+            ohos:width="80vp"
+            ohos:text="商品名称:"
+            ohos:text_size="14fp"
+            ohos:text_color="#FF666666"/>
+        <Text
+            ohos:id="$+id:detail_goods_name"
+            ohos:height="match_content"
+            ohos:width="0vp"
+            ohos:weight="1"
+            ohos:text="--"
+            ohos:text_size="14fp"
+            ohos:text_color="#FF000000"/>
+    </DirectionalLayout>
+
+    <!-- 业务类型 -->
+    <DirectionalLayout
+        ohos:height="match_content"
+        ohos:width="match_parent"
+        ohos:orientation="horizontal"
+        ohos:bottom_margin="12vp">
+        <Text
+            ohos:height="match_content"
+            ohos:width="80vp"
+            ohos:text="业务类型:"
+            ohos:text_size="14fp"
+            ohos:text_color="#FF666666"/>
+        <Text
+            ohos:id="$+id:detail_biz_type"
+            ohos:height="match_content"
+            ohos:width="0vp"
+            ohos:weight="1"
+            ohos:text="--"
+            ohos:text_size="14fp"
+            ohos:text_color="#FF000000"/>
+    </DirectionalLayout>
+
+    <!-- 车场名称 -->
+    <DirectionalLayout
+        ohos:height="match_content"
+        ohos:width="match_parent"
+        ohos:orientation="horizontal"
+        ohos:bottom_margin="12vp">
+        <Text
+            ohos:height="match_content"
+            ohos:width="80vp"
+            ohos:text="车场名称:"
+            ohos:text_size="14fp"
+            ohos:text_color="#FF666666"/>
+        <Text
+            ohos:id="$+id:detail_park_name"
+            ohos:height="match_content"
+            ohos:width="0vp"
+            ohos:weight="1"
+            ohos:text="--"
+            ohos:text_size="14fp"
+            ohos:text_color="#FF000000"/>
+    </DirectionalLayout>
+
+    <!-- 支付时间 -->
+    <DirectionalLayout
+        ohos:height="match_content"
+        ohos:width="match_parent"
+        ohos:orientation="horizontal"
+        ohos:bottom_margin="12vp">
+        <Text
+            ohos:height="match_content"
+            ohos:width="80vp"
+            ohos:text="支付时间:"
+            ohos:text_size="14fp"
+            ohos:text_color="#FF666666"/>
+        <Text
+            ohos:id="$+id:detail_pay_time"
+            ohos:height="match_content"
+            ohos:width="0vp"
+            ohos:weight="1"
+            ohos:text="--"
+            ohos:text_size="14fp"
+            ohos:text_color="#FF000000"/>
+    </DirectionalLayout>
+
+    <!-- 金额 -->
+    <DirectionalLayout
+        ohos:height="match_content"
+        ohos:width="match_parent"
+        ohos:orientation="horizontal"
+        ohos:bottom_margin="12vp">
+        <Text
+            ohos:height="match_content"
+            ohos:width="80vp"
+            ohos:text="支付金额:"
+            ohos:text_size="14fp"
+            ohos:text_color="#FF666666"/>
+        <Text
+            ohos:id="$+id:detail_amount"
+            ohos:height="match_content"
+            ohos:width="0vp"
+            ohos:weight="1"
+            ohos:text="¥0.00"
+            ohos:text_size="16fp"
+            ohos:text_color="#FA6332"
+            ohos:text_weight="600"/>
+    </DirectionalLayout>
+
+</DirectionalLayout>
+

+ 154 - 0
entry/src/main/resources/base/layout/layout_park_detail.xml

@@ -0,0 +1,154 @@
+<?xml version="1.0" encoding="utf-8"?>
+<DirectionalLayout
+    xmlns:ohos="http://schemas.huawei.com/res/ohos"
+    ohos:height="match_parent"
+    ohos:width="match_parent"
+    ohos:orientation="vertical"
+    ohos:background_element="#FFFFFFFF"
+    ohos:padding="16vp">
+
+    <!-- 标题 -->
+    <Text
+        ohos:id="$+id:detail_title"
+        ohos:height="match_content"
+        ohos:width="match_parent"
+        ohos:text="停车场详情"
+        ohos:text_size="18fp"
+        ohos:text_color="#FF000000"
+        ohos:text_weight="600"
+        ohos:bottom_margin="16vp"/>
+
+    <!-- 停车场名称 -->
+    <DirectionalLayout
+        ohos:height="match_content"
+        ohos:width="match_parent"
+        ohos:orientation="horizontal"
+        ohos:bottom_margin="12vp">
+        <Text
+            ohos:height="match_content"
+            ohos:width="80vp"
+            ohos:text="停车场:"
+            ohos:text_size="14fp"
+            ohos:text_color="#FF666666"/>
+        <Text
+            ohos:id="$+id:detail_park_name"
+            ohos:height="match_content"
+            ohos:width="0vp"
+            ohos:weight="1"
+            ohos:text="--"
+            ohos:text_size="14fp"
+            ohos:text_color="#FF000000"/>
+    </DirectionalLayout>
+
+    <!-- 地址 -->
+    <DirectionalLayout
+        ohos:height="match_content"
+        ohos:width="match_parent"
+        ohos:orientation="horizontal"
+        ohos:bottom_margin="12vp">
+        <Text
+            ohos:height="match_content"
+            ohos:width="80vp"
+            ohos:text="地址:"
+            ohos:text_size="14fp"
+            ohos:text_color="#FF666666"/>
+        <Text
+            ohos:id="$+id:detail_address"
+            ohos:height="match_content"
+            ohos:width="0vp"
+            ohos:weight="1"
+            ohos:text="--"
+            ohos:text_size="14fp"
+            ohos:text_color="#FF000000"/>
+    </DirectionalLayout>
+
+    <!-- 距离 -->
+    <DirectionalLayout
+        ohos:height="match_content"
+        ohos:width="match_parent"
+        ohos:orientation="horizontal"
+        ohos:bottom_margin="12vp">
+        <Text
+            ohos:height="match_content"
+            ohos:width="80vp"
+            ohos:text="距离:"
+            ohos:text_size="14fp"
+            ohos:text_color="#FF666666"/>
+        <Text
+            ohos:id="$+id:detail_distance"
+            ohos:height="match_content"
+            ohos:width="0vp"
+            ohos:weight="1"
+            ohos:text="--"
+            ohos:text_size="14fp"
+            ohos:text_color="#FF000000"/>
+    </DirectionalLayout>
+
+    <!-- 总车位 -->
+    <DirectionalLayout
+        ohos:height="match_content"
+        ohos:width="match_parent"
+        ohos:orientation="horizontal"
+        ohos:bottom_margin="12vp">
+        <Text
+            ohos:height="match_content"
+            ohos:width="80vp"
+            ohos:text="总车位:"
+            ohos:text_size="14fp"
+            ohos:text_color="#FF666666"/>
+        <Text
+            ohos:id="$+id:detail_total_place"
+            ohos:height="match_content"
+            ohos:width="0vp"
+            ohos:weight="1"
+            ohos:text="--"
+            ohos:text_size="14fp"
+            ohos:text_color="#FF000000"/>
+    </DirectionalLayout>
+
+    <!-- 剩余车位 -->
+    <DirectionalLayout
+        ohos:height="match_content"
+        ohos:width="match_parent"
+        ohos:orientation="horizontal"
+        ohos:bottom_margin="12vp">
+        <Text
+            ohos:height="match_content"
+            ohos:width="80vp"
+            ohos:text="剩余车位:"
+            ohos:text_size="14fp"
+            ohos:text_color="#FF666666"/>
+        <Text
+            ohos:id="$+id:detail_residue_place"
+            ohos:height="match_content"
+            ohos:width="0vp"
+            ohos:weight="1"
+            ohos:text="--"
+            ohos:text_size="14fp"
+            ohos:text_color="#FF000000"/>
+    </DirectionalLayout>
+
+    <!-- 免费时长 -->
+    <DirectionalLayout
+        ohos:height="match_content"
+        ohos:width="match_parent"
+        ohos:orientation="horizontal"
+        ohos:bottom_margin="12vp">
+        <Text
+            ohos:height="match_content"
+            ohos:width="80vp"
+            ohos:text="免费时长:"
+            ohos:text_size="14fp"
+            ohos:text_color="#FF666666"/>
+        <Text
+            ohos:id="$+id:detail_free_time"
+            ohos:height="match_content"
+            ohos:width="0vp"
+            ohos:weight="1"
+            ohos:text="--"
+            ohos:text_size="14fp"
+            ohos:text_color="#FF000000"/>
+    </DirectionalLayout>
+
+</DirectionalLayout>
+

BIN
entry/src/main/resources/base/media/close.png


BIN
entry/src/main/resources/base/media/logout.png


BIN
entry/src/main/resources/base/media/tcjf.png


BIN
entry/src/main/resources/base/media/ykxf.png