package com.fujica.abk.component.nav; import com.fujica.abk.ResourceTable; import com.fujica.abk.api.cache; import com.fujica.abk.api.common; import com.fujica.abk.component.LoadingComponent; import com.fujica.abk.model.in.ChargeQuery; import com.fujica.abk.model.out.MemberPlateH5Dto; import com.fujica.abk.model.out.ParkingFeeInfo; import com.fujica.abk.utils.*; import com.google.gson.reflect.TypeToken; import ohos.aafwk.ability.DataAbilityHelper; import ohos.aafwk.ability.IDataAbilityObserver; import ohos.agp.components.*; import ohos.app.Context; import ohos.sysappcomponents.settings.SystemSettings; import java.util.concurrent.CompletableFuture; /** * 计费页面组件 */ public class ChargeComponent extends DirectionalLayout { private Component rootLayout; private Context context; private DirectionalLayout filterPlateNo; private Text textPlateNo; // 不同状态的卡片 private DirectionalLayout cardNormalFee; // feeType 0或16: 正常缴费 private DirectionalLayout cardNoEntry; // feeType 10或12: 未入场 private DirectionalLayout cardBlacklist; // feeType 14: 黑名单 private DirectionalLayout cardMonthly; // feeType 3: 月卡车辆 private DirectionalLayout cardNoFee; // feeType 1/2/4/5/13: 无需缴费 private DirectionalLayout cardFullDiscount; // feeType 6: 全额优惠 private DirectionalLayout addVehicleCard; // 无车牌缓存 // 正常缴费卡片的组件 private Text textParkName; private Text textStayTime; private Text textActualAmount; private Text textDiscountAmount; private Button btnPayNow; // 未入场卡片的组件 private Button btnRefresh; // 黑名单卡片的组件 private Text textParkNameBlacklist; private Text textStayTimeBlacklist; // 月卡卡片的组件 private Text textParkNameMonthly; private Text textStayTimeMonthly; private Button btnRenew; // 无需缴费卡片的组件 private Text textParkNameNoFee; private Text textStayTimeNoFee; // 全额优惠卡片的组件 private Text textParkNameFullDiscount; private Text textStayTimeFullDiscount; // 无车牌缓存卡片的组件 private Button btnInputLicensePlate; // 当前停车费信息 private ParkingFeeInfo currentFeeInfo; private LoadingComponent loadingComponent; // Loading组件 private OnPayDetailShowListener onPayDetailShowListener; // 支付详情展示监听器 /** * 支付详情展示监听器 */ public interface OnPayDetailShowListener { void onShowPayDetail(ParkingFeeInfo feeInfo); } /** * 设置Loading组件 */ public void setLoadingComponent(LoadingComponent loadingComponent) { this.loadingComponent = loadingComponent; } /** * 设置支付详情展示监听器 */ public void setOnPayDetailShowListener(OnPayDetailShowListener listener) { this.onPayDetailShowListener = listener; } /** * 构造函数 */ public ChargeComponent(Context context) { super(context); this.context = 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_charge, null, false); addComponent(rootLayout); // 初始化UI组件 initViews(); // 设置事件监听 setupListeners(); // 根据缓存状态显示不同UI checkCacheAndUpdateUI(); } /** * 初始化视图组件 */ private void initViews() { filterPlateNo = rootLayout.findComponentById(ResourceTable.Id_filter_plateNo); textPlateNo = rootLayout.findComponentById(ResourceTable.Id_text_plateNo); // 获取所有卡片容器 cardNormalFee = rootLayout.findComponentById(ResourceTable.Id_card_normal_fee); cardNoEntry = rootLayout.findComponentById(ResourceTable.Id_card_no_entry); cardBlacklist = rootLayout.findComponentById(ResourceTable.Id_card_blacklist); cardMonthly = rootLayout.findComponentById(ResourceTable.Id_card_monthly); cardNoFee = rootLayout.findComponentById(ResourceTable.Id_card_no_fee); cardFullDiscount = rootLayout.findComponentById(ResourceTable.Id_card_full_discount); addVehicleCard = rootLayout.findComponentById(ResourceTable.Id_add_vehicle_card); // 正常缴费卡片的组件 textParkName = rootLayout.findComponentById(ResourceTable.Id_text_park_name); textStayTime = rootLayout.findComponentById(ResourceTable.Id_text_stay_time); textActualAmount = rootLayout.findComponentById(ResourceTable.Id_text_actual_amount); textDiscountAmount = rootLayout.findComponentById(ResourceTable.Id_text_discount_amount); btnPayNow = rootLayout.findComponentById(ResourceTable.Id_btn_pay_now); // 未入场卡片的组件 btnRefresh = rootLayout.findComponentById(ResourceTable.Id_btn_refresh); // 黑名单卡片的组件 textParkNameBlacklist = rootLayout.findComponentById(ResourceTable.Id_text_park_name_blacklist); textStayTimeBlacklist = rootLayout.findComponentById(ResourceTable.Id_text_stay_time_blacklist); // 月卡卡片的组件 textParkNameMonthly = rootLayout.findComponentById(ResourceTable.Id_text_park_name_monthly); textStayTimeMonthly = rootLayout.findComponentById(ResourceTable.Id_text_stay_time_monthly); btnRenew = rootLayout.findComponentById(ResourceTable.Id_btn_renew); // 无需缴费卡片的组件 textParkNameNoFee = rootLayout.findComponentById(ResourceTable.Id_text_park_name_no_fee); textStayTimeNoFee = rootLayout.findComponentById(ResourceTable.Id_text_stay_time_no_fee); // 全额优惠卡片的组件 textParkNameFullDiscount = rootLayout.findComponentById(ResourceTable.Id_text_park_name_full_discount); textStayTimeFullDiscount = rootLayout.findComponentById(ResourceTable.Id_text_stay_time_full_discount); // 无车牌缓存卡片的组件 btnInputLicensePlate = rootLayout.findComponentById(ResourceTable.Id_btn_input_license_plate); } /** * 设置事件监听 */ private void setupListeners() { filterPlateNo.setClickedListener(v -> showLicensePlateInputDialog()); // 输入车牌缴费按钮点击事件 btnInputLicensePlate.setClickedListener(component -> showLicensePlateInputDialog()); // 立即缴费按钮点击事件 if (btnPayNow != null) { btnPayNow.setClickedListener(component -> { // if(true){ // Runnable payRunnable = new Runnable() { // @Override // public void run() { // com.huawei.hms.a // AggrPayClient client = Pay.getPayClient(this); // PayResult payResult = client.carPay(orderStr); // mHandler.post(() -> dealPayResult(payResult)); // } // }; // Thread payThread = new Thread(payRunnable); // payThread.start(); // return; // } if (currentFeeInfo != null) { // 展示支付详情 if (onPayDetailShowListener != null) { onPayDetailShowListener.onShowPayDetail(currentFeeInfo); } else { Toast.info(context, "请稍后重试"); } } }); } // 刷新按钮点击事件 if (btnRefresh != null) { btnRefresh.setClickedListener(component -> { checkCacheAndUpdateUI(); }); } // 立即续费按钮点击事件 if (btnRenew != null) { btnRenew.setClickedListener(component -> { if (currentFeeInfo != null) { // TODO: 跳转到续费页面 Toast.info(context, "跳转到续费页面"); } }); } } /** * 显示车牌输入对话框 */ private void showLicensePlateInputDialog() { LicensePlateInputDialog licensePlateInputDialog = new LicensePlateInputDialog(context); licensePlateInputDialog.setOnConfirmListener(licensePlate -> { // 确认后保存车牌并查询计费 simulateLicensePlateInput(licensePlate); }); licensePlateInputDialog.show(); } private String plateNo = ""; DataAbilityHelper dataAbilityHelper; IDataAbilityObserver dataAbilityObserver; // if (dataAbilityHelper != null) { // dataAbilityHelper.unregisterObserver(SystemSettings.getUri(SystemSettings.Date.TIME_FORMAT), dataAbilityObserver); // } /** * 检查缓存并更新UI */ private void checkCacheAndUpdateUI() { if (plateNo == null || plateNo.isEmpty()) { if (dataAbilityHelper == null) { dataAbilityHelper = DataAbilityHelper.creator(getContext()); } // 发起异步请求获取默认车牌 CompletableFuture> future = api.http(context, new ApiOption("/member/plate/default"), new TypeToken>() {}); future.thenAccept(result -> { // 处理响应结果 if (result != null && result.isSuccess() && result.getData() != null) { MemberPlateH5Dto plateData = result.getData(); if (plateData.getPlateNo() != null && !plateData.getPlateNo().isEmpty()) { plateNo = plateData.getPlateNo(); cache.setDefaultPlateNo(getContext(), plateNo); } } if(plateNo == null || plateNo.isEmpty()){ plateNo = SystemSettings.getValue(dataAbilityHelper, "car_license_plate_number"); common.updateDefaultPlateNo(context, plateNo); } // 异步请求完成后,更新UI(确保在主线程执行) DialogUtil.postTask(() -> { updateUIAfterPlateNoLoaded(); }); }).exceptionally(throwable -> { // 异常情况下也要更新UI(确保在主线程执行) DialogUtil.postTask(() -> { updateUIAfterPlateNoLoaded(); }); return null; }); } else { // 已经有plateNo,直接更新UI updateUIAfterPlateNoLoaded(); } } /** * 加载plateNo后更新UI */ private void updateUIAfterPlateNoLoaded() { if (plateNo != null && !plateNo.isEmpty()) { // 有缓存,直接查询计费 queryParkingFee(plateNo); filterPlateNo.setVisibility(VISIBLE); textPlateNo.setText(plateNo); } else { // 无缓存,显示添加车辆卡片 showAddVehicleCard(); filterPlateNo.setVisibility(HIDE); textPlateNo.setText(""); } } /** * 显示添加车辆卡片 */ private void showAddVehicleCard() { hideAllCards(); if (addVehicleCard != null) { addVehicleCard.setVisibility(VISIBLE); } } /** * 隐藏所有卡片 */ private void hideAllCards() { if (cardNormalFee != null) cardNormalFee.setVisibility(HIDE); if (cardNoEntry != null) cardNoEntry.setVisibility(HIDE); if (cardBlacklist != null) cardBlacklist.setVisibility(HIDE); if (cardMonthly != null) cardMonthly.setVisibility(HIDE); if (cardNoFee != null) cardNoFee.setVisibility(HIDE); if (cardFullDiscount != null) cardFullDiscount.setVisibility(HIDE); if (addVehicleCard != null) addVehicleCard.setVisibility(HIDE); } /** * 模拟车牌输入(后续会被实际输入逻辑替换) */ private void simulateLicensePlateInput(String licensePlate) { // 更新顶部车牌显示 filterPlateNo.setVisibility(VISIBLE); textPlateNo.setText(licensePlate); this.plateNo = licensePlate; // 查询计费 queryParkingFee(this.plateNo); } /** * 查询停车费用 * 参考 index.vue 中的 getCharge 方法实现 */ private void queryParkingFee(String licensePlate) { // 构建请求参数 ChargeQuery query = new ChargeQuery(); query.setChargeScene(2); // 计费场景: 2 query.setPlateNo(licensePlate); CompletableFuture> future = common.queryParkingFee(getContext(), query); if (loadingComponent != null) { loadingComponent.show(); } future.thenAccept(result1 -> { // 在主线程更新UI DialogUtil.postTask(() -> { // String json = "{\"code\":0,\"data\":{\"actualAmount\":1400,\"discountAmount\":110,\"feeType\":12,\"followList\":[],\"parkId\":\"559581682204741\",\"parkName\":\"车场0818\",\"parkingDays\":0,\"parkingHours\":0,\"parkingMinutes\":0,\"plateColor\":\"6\",\"plateNo\":\"粤B11111\",\"rzStatus\":false,\"stayTime\":\"0天6小时39分\",\"totalFee\":0},\"success\":true}"; // R result = new Gson().fromJson(json, new TypeToken>() { // }); R result = result1; if (result == null || "timeout".equals(result.getMsg())) { // 查询结果为空或超时:按照未入场处理(feeType=10) // 参考 Charge.ets 第467行的实现 ParkingFeeInfo emptyFeeInfo = new ParkingFeeInfo(); emptyFeeInfo.setFeeType(10); emptyFeeInfo.setPlateNo(licensePlate); updateParkingInfo(emptyFeeInfo); } else if (result.isSuccess() && result.getData() != null) { ParkingFeeInfo feeInfo = result.getData(); currentFeeInfo = feeInfo; // 更新停车信息显示 updateParkingInfo(feeInfo); // 处理 feeType 16:有历史欠费订单(临停加欠费补缴) // if (feeInfo.getFeeType() == 16 && feeInfo.getFollowList() != null && !feeInfo.getFollowList().isEmpty()) { // int arrearageCount = feeInfo.getFollowList().size(); // String message = "您有" + arrearageCount + "笔历史欠费订单(不含本次停车订单)尚未支付,请尽快处理"; // showArrearageDialog(message, feeInfo, "立即补缴"); // } // // 处理 feeType 13:本次停车未产生费用,但有历史欠费订单 // else if (feeInfo.getFeeType() == 13 && feeInfo.getFollowList() != null && !feeInfo.getFollowList().isEmpty()) { // int arrearageCount = feeInfo.getFollowList().size(); // String message = "本次停车未产生费用,但您仍有" + arrearageCount + "笔历史欠费订单尚未支付,请尽快处理"; // showArrearageDialog(message, feeInfo, "立即补缴"); // } // TODO: 检查车辆认证状态 // 这里需要获取用户的车辆列表,检查当前车牌是否已认证(status == 2) // 如果未认证,设置 rzStatus = false // if (user.cars.findIndex(item => item.plateNo == feeInfo.getPlateNo() && item.status == 2) == -1) { // feeInfo.setRzStatus(false); // } else { // feeInfo.setRzStatus(true); // } } else { // 查询失败 Toast.error(context, "查询失败,请稍后重试"); showAddVehicleCard(); } }); }).exceptionally(throwable -> { // 异常处理(包括超时) // 参考 Vue 中的实现:计费超时按照未入场处理(feeType=10) DialogUtil.postTask(() -> { // 异常按照未入场处理 ParkingFeeInfo errorFeeInfo = new ParkingFeeInfo(); errorFeeInfo.setFeeType(10); errorFeeInfo.setPlateNo(licensePlate); updateParkingInfo(errorFeeInfo); }); return null; }).whenComplete((result, throwable) -> { // finally 块:无论成功还是失败都隐藏 loading DialogUtil.postTask(() -> { if (loadingComponent != null) { loadingComponent.hide(); } }); }); } /** * 显示欠费订单提示对话框 * 参考 Vue 中的 uni.showModal 实现 */ private void showArrearageDialog(String message, ParkingFeeInfo feeInfo, String confirmText) { com.fujica.abk.utils.ConfirmDialog dialog = new com.fujica.abk.utils.ConfirmDialog(context); dialog.setTitle("温馨提示") .setMessage(message) .setConfirmText(confirmText) .setConfirmListener(dialogInstance -> { // 点击确定按钮:跳转到欠费补缴页面 handleArrearagePayment(feeInfo); dialogInstance.dismiss(); }) .setCancelListener(dialogInstance -> { // 点击取消按钮:关闭对话框 dialogInstance.dismiss(); }) .show(); } /** * 处理欠费补缴 * 根据欠费订单数量跳转到不同页面 */ private void handleArrearagePayment(ParkingFeeInfo feeInfo) { if (feeInfo.getFollowList() == null || feeInfo.getFollowList().isEmpty()) { return; } // TODO: 实现跳转逻辑 // 如果只有一笔欠费订单,跳转到订单详情页 if (feeInfo.getFollowList().size() == 1) { // storage.set('arrearageDetail', feeInfo.getFollowList().get(0)); // pageTo('/pages/pay/arrearage/detail', { type: "pay" }); Toast.info(context, "跳转到欠费订单详情页"); } else { // 如果有多笔欠费订单,跳转到订单列表页 // storage.set('arrearageList', feeInfo); // pageTo('/pages/pay/arrearage/list', { type: "singlePay" }); Toast.info(context, "跳转到欠费订单列表页"); } } /** * 更新停车信息显示 * 根据 feeType 显示不同的界面,参考 index.vue 的实现 */ private void updateParkingInfo(ParkingFeeInfo feeInfo) { hideAllCards(); int feeType = feeInfo.getFeeType(); switch (feeType) { case 0: // 正常缴费 case 16: // 临停加欠费补缴 showNormalFeeCard(feeInfo); break; case 10: // 未入场 case 12: // 场外月卡 showNoEntryCard(); break; case 14: // 黑名单车辆 showBlacklistCard(feeInfo); break; case 3: // 月卡车辆 showMonthlyCard(feeInfo); break; case 1: // 无需缴费 case 2: // 已缴费免费离场时间内 case 4: // 免费时间内 case 5: // 无需缴费 case 13: // 欠费补缴(本次无需缴费) showNoFeeCard(feeInfo); break; case 6: // 全额优惠,无需缴费 showFullDiscountCard(feeInfo); break; default: showAddVehicleCard(); break; } } /** * 显示正常缴费卡片 (feeType 0或16) */ private void showNormalFeeCard(ParkingFeeInfo feeInfo) { if (cardNormalFee == null) return; cardNormalFee.setVisibility(VISIBLE); // 设置车场名称(如果未认证,显示提示) if (textParkName != null) { String parkName = feeInfo.getParkName() != null ? feeInfo.getParkName() : "未知车场"; textParkName.setText(parkName); } // 设置停车时长 if (textStayTime != null) { String stayTime = feeInfo.getStayTime() != null ? "已停" + feeInfo.getStayTime() : "已停0小时0分"; textStayTime.setText(stayTime); } // 设置实际金额(分转元) if (textActualAmount != null) { double amount = feeInfo.getActualAmount() / 100.0; textActualAmount.setText(String.format("%.2f", amount)); } // 设置减免金额 if (textDiscountAmount != null && feeInfo.getDiscountAmount() > 0) { double discountAmount = feeInfo.getDiscountAmount() / 100.0; textDiscountAmount.setText(String.format("已减免%.2f元", discountAmount)); textDiscountAmount.setVisibility(VISIBLE); } else { textDiscountAmount.setVisibility(HIDE); } } /** * 显示未入场卡片 (feeType 10或12) */ private void showNoEntryCard() { if (cardNoEntry != null) { cardNoEntry.setVisibility(VISIBLE); } } /** * 显示黑名单卡片 (feeType 14) */ private void showBlacklistCard(ParkingFeeInfo feeInfo) { if (cardBlacklist == null) return; cardBlacklist.setVisibility(VISIBLE); if (textParkNameBlacklist != null) { String parkName = feeInfo.getParkName() != null ? feeInfo.getParkName() : ""; textParkNameBlacklist.setText(parkName); } if (textStayTimeBlacklist != null) { String stayTime = feeInfo.getStayTime() != null ? "已停" + feeInfo.getStayTime() : ""; textStayTimeBlacklist.setText(stayTime); } } /** * 显示月卡卡片 (feeType 3) */ private void showMonthlyCard(ParkingFeeInfo feeInfo) { if (cardMonthly == null) return; cardMonthly.setVisibility(VISIBLE); if (textParkNameMonthly != null) { String parkName = feeInfo.getParkName() != null ? feeInfo.getParkName() : ""; textParkNameMonthly.setText(parkName); } if (textStayTimeMonthly != null) { String stayTime = feeInfo.getStayTime() != null ? "已停" + feeInfo.getStayTime() : ""; textStayTimeMonthly.setText(stayTime); } } /** * 显示无需缴费卡片 (feeType 1/2/4/5/13) */ private void showNoFeeCard(ParkingFeeInfo feeInfo) { if (cardNoFee == null) return; cardNoFee.setVisibility(VISIBLE); if (textParkNameNoFee != null) { String parkName = feeInfo.getParkName() != null ? feeInfo.getParkName() : ""; textParkNameNoFee.setText(parkName); } if (textStayTimeNoFee != null) { String stayTime = feeInfo.getStayTime() != null ? "已停" + feeInfo.getStayTime() : ""; textStayTimeNoFee.setText(stayTime); } } /** * 显示全额优惠卡片 (feeType 6) */ private void showFullDiscountCard(ParkingFeeInfo feeInfo) { if (cardFullDiscount == null) return; cardFullDiscount.setVisibility(VISIBLE); if (textParkNameFullDiscount != null) { String parkName = feeInfo.getParkName() != null ? feeInfo.getParkName() : ""; textParkNameFullDiscount.setText(parkName); } if (textStayTimeFullDiscount != null) { String stayTime = feeInfo.getStayTime() != null ? "已停" + feeInfo.getStayTime() : ""; textStayTimeFullDiscount.setText(stayTime); } } /** * 刷新页面数据 * 当页面切换过来时调用,重新检查缓存并更新UI */ public void refresh() { checkCacheAndUpdateUI(); } }