From fe2ce75cecb99d87ddb0d073c78b700fe9bf39f8 Mon Sep 17 00:00:00 2001 From: userGyl Date: Wed, 17 Dec 2025 09:18:34 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E7=BB=91=E5=AE=9A=E8=BD=A6?= =?UTF-8?q?=E8=BE=86=E6=8E=A5=E5=8F=A3=20=E7=99=BB=E5=BD=95=E5=90=8E?= =?UTF-8?q?=E6=9F=A5=E8=AF=A2=E8=BD=A6=E8=BE=86=E4=BF=A1=E6=81=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../lib/pages/c_page/car_info/controller.dart | 18 ++--- .../pages/c_page/reservation/controller.dart | 20 +++--- ln_jq_app/lib/pages/login/view.dart | 18 +++++ ln_jq_app/lib/pages/qr_code/controller.dart | 72 ++++++++++++++----- 4 files changed, 95 insertions(+), 33 deletions(-) diff --git a/ln_jq_app/lib/pages/c_page/car_info/controller.dart b/ln_jq_app/lib/pages/c_page/car_info/controller.dart index ac95c15..b88a5f1 100644 --- a/ln_jq_app/lib/pages/c_page/car_info/controller.dart +++ b/ln_jq_app/lib/pages/c_page/car_info/controller.dart @@ -28,11 +28,14 @@ class CarInfoController extends GetxController with BaseControllerMixin { super.onInit(); getUserBindCarInfo(); } + @override void onReady() { super.onReady(); // 如果未绑定车辆,且本次会话尚未提示过,则弹出提示 - if (!StorageService.to.hasShownBindVehicleDialog && StorageService.to.isLoggedIn) { + if (!StorageService.to.hasShownBindVehicleDialog && + StorageService.to.isLoggedIn && + !StorageService.to.hasVehicleInfo) { Future.delayed(const Duration(milliseconds: 500), () { DialogX.to.showConfirmDialog( title: '当前尚未绑定车辆', @@ -71,7 +74,7 @@ class CarInfoController extends GetxController with BaseControllerMixin { final response = await HttpService.to.get( 'appointment/vehicle/getPicInfoByVin?vin=$vin', ); - + if (response != null && response.data != null) { final result = BaseModel.fromJson(response.data); if (result.code == 0 && result.data != null) { @@ -88,7 +91,9 @@ class CarInfoController extends GetxController with BaseControllerMixin { // 将解析出的 URL 列表赋值给对应的 RxList drivingAttachments.assignAll(parseAttachments(data['drivingAttachment'])); operationAttachments.assignAll(parseAttachments(data['operationAttachment'])); - hydrogenationAttachments.assignAll(parseAttachments(data['hydrogenationAttachment'])); + hydrogenationAttachments.assignAll( + parseAttachments(data['hydrogenationAttachment']), + ); registerAttachments.assignAll(parseAttachments(data['registerAttachment'])); } } @@ -98,7 +103,7 @@ class CarInfoController extends GetxController with BaseControllerMixin { /// 跳转到证件查看页面 void navigateToCertificateViewer(String title, List attachments) { - if(!StorageService.to.hasVehicleInfo){ + if (!StorageService.to.hasVehicleInfo) { showToast('请先绑定车辆'); return; } @@ -108,10 +113,7 @@ class CarInfoController extends GetxController with BaseControllerMixin { } Get.to( () => const CertificateViewerPage(), - arguments: { - 'title': title, - 'attachments': attachments, - }, + arguments: {'title': title, 'attachments': attachments}, ); } } diff --git a/ln_jq_app/lib/pages/c_page/reservation/controller.dart b/ln_jq_app/lib/pages/c_page/reservation/controller.dart index 62f66b5..d558341 100644 --- a/ln_jq_app/lib/pages/c_page/reservation/controller.dart +++ b/ln_jq_app/lib/pages/c_page/reservation/controller.dart @@ -447,9 +447,11 @@ class C_ReservationController extends GetxController with BaseControllerMixin { /// 状态变量:是否有预约数据 final RxBool hasReservationData = false.obs; + // 新增预约数据列表 final RxList reservationList = [].obs; final RxBool shouldShowReservationList = false.obs; + // --- 用于防抖的 Timer --- Timer? _debounce; @@ -464,7 +466,6 @@ class C_ReservationController extends GetxController with BaseControllerMixin { showLoading("加载中"); try { - final Map requestData = { 'phone': StorageService.to.phone, 'pageNum': 1, @@ -523,7 +524,6 @@ class C_ReservationController extends GetxController with BaseControllerMixin { if (showPopup) { shouldShowReservationList.value = true; } - } else { showToast(baseModel.message); hasReservationData.value = false; @@ -538,7 +538,6 @@ class C_ReservationController extends GetxController with BaseControllerMixin { } } - String workEfficiency = "0"; String fillingWeight = "0"; String fillingTimes = "0"; @@ -637,14 +636,16 @@ class C_ReservationController extends GetxController with BaseControllerMixin { } void getSiteList() async { - if(StorageService.to.phone == "13344444444"){ + if (StorageService.to.phone == "13344444444") { //该账号给stationOptions手动添加一个数据 final testStation = StationModel( hydrogenId: '1142167389150920704', name: '羚牛氢能演示加氢站', address: '上海市嘉定区于田南路111号于田大厦', - price: '35.00', // 价格 - siteStatusName: '营运中', // 状态 + price: '35.00', + // 价格 + siteStatusName: '营运中', + // 状态 isSelect: 1, // 默认可选 ); // 使用 assignAll 可以确保列表只包含这个测试数据 @@ -700,7 +701,7 @@ class C_ReservationController extends GetxController with BaseControllerMixin { // 找到第一个可选的站点作为默认值 if (stationOptions.isNotEmpty) { final firstSelectable = stationOptions.firstWhere( - (station) => station.isSelect == 1, + (station) => station.isSelect == 1, orElse: () => stationOptions.first, // 降级:如果没有可选的,就用第一个 ); selectedStationId.value = firstSelectable.hydrogenId; @@ -708,7 +709,6 @@ class C_ReservationController extends GetxController with BaseControllerMixin { // 如果列表为空,确保 selectedStationId 也为空 selectedStationId.value = null; } - } catch (e) { showToast('数据异常'); } @@ -719,7 +719,9 @@ class C_ReservationController extends GetxController with BaseControllerMixin { HttpService.to.dio.options.headers = originalHeaders; // 如果未绑定车辆,且本次会话尚未提示过,则弹出提示 - if (!StorageService.to.hasShownBindVehicleDialog && StorageService.to.isLoggedIn) { + if (!StorageService.to.hasShownBindVehicleDialog && + StorageService.to.isLoggedIn && + !StorageService.to.hasVehicleInfo) { Future.delayed(const Duration(milliseconds: 500), () { DialogX.to.showConfirmDialog( title: '当前尚未绑定车辆', diff --git a/ln_jq_app/lib/pages/login/view.dart b/ln_jq_app/lib/pages/login/view.dart index d47b141..2201a04 100644 --- a/ln_jq_app/lib/pages/login/view.dart +++ b/ln_jq_app/lib/pages/login/view.dart @@ -2,6 +2,7 @@ import 'package:flutter/material.dart'; import 'package:getx_scaffold/getx_scaffold.dart'; import 'package:ln_jq_app/common/login_util.dart'; import 'package:ln_jq_app/common/model/base_model.dart'; +import 'package:ln_jq_app/common/model/vehicle_info.dart'; import 'package:ln_jq_app/common/styles/theme.dart'; import 'package:ln_jq_app/pages/b_page/base_widgets/view.dart'; import 'package:ln_jq_app/pages/c_page/base_widgets/view.dart'; @@ -174,6 +175,7 @@ class _LoginPageState extends State with SingleTickerProviderStateMix showToast('登录失败:无法获取凭证'); return; } + //登录信息处理 try { var result = BaseModel.fromJson(responseData.data); String token = result.data['token'] ?? ''; @@ -188,6 +190,22 @@ class _LoginPageState extends State with SingleTickerProviderStateMix name: name, phone: phone, ); + + //登录后查询已绑定车辆信息 + var carInfo = await HttpService.to.get( + "appointment/driver/getTruckInfoByDriver?phone=$phone" + ); + if (carInfo != null) { + var carInforesult = BaseModel.fromJson(carInfo.data); + if (carInforesult.data != null) { + final vehicle = VehicleInfo.fromJson(carInforesult.data as Map); + //保存使用 + await StorageService.to.saveVehicleInfo(vehicle); + } + } + + + //页面操作 dismissLoading(); showToast('登录成功,欢迎您'); Get.offAll(() => BaseWidgetsPage()); diff --git a/ln_jq_app/lib/pages/qr_code/controller.dart b/ln_jq_app/lib/pages/qr_code/controller.dart index 40f0e6d..6367afb 100644 --- a/ln_jq_app/lib/pages/qr_code/controller.dart +++ b/ln_jq_app/lib/pages/qr_code/controller.dart @@ -2,7 +2,6 @@ import 'dart:io'; import 'dart:typed_data'; import 'package:flutter/material.dart'; -import 'package:get/get.dart'; import 'package:getx_scaffold/getx_scaffold.dart'; import 'package:image/image.dart' as img; import 'package:image_picker/image_picker.dart'; @@ -125,14 +124,12 @@ class QrCodeController extends GetxController } void requestPermission() async { - if(Platform.isIOS){ + if (Platform.isIOS) { var status = await Permission.camera.request(); if (status.isGranted) { - } - else if (status.isPermanentlyDenied) { + } else if (status.isPermanentlyDenied) { openAppSettings(); - } - else { + } else { showErrorToast('需要相机权限才能扫描二维码'); } return; @@ -153,36 +150,51 @@ class QrCodeController extends GetxController scanFromGallery(); } } - if(Platform.isIOS){ + if (Platform.isIOS) { var status = await Permission.photos.request(); print("权限状态: $status"); // 在控制台看这个输出 if (status.isGranted) { scanFromGallery(); - } - else if (status.isPermanentlyDenied) { + } else if (status.isPermanentlyDenied) { openAppSettings(); - } - else { + } else { showErrorToast('需要相册权限才能从相册中选择图片'); } } } - //扫码结果处理 - void renderResult(String resultStr) async { + //扫码结果处理 //如果绑定接口返回的data为null 需要手动编辑车牌 + void renderResult(String resultStr, {plateNumber}) async { showLoading("正在获取车辆信息..."); try { - var responseData = await HttpService.to.get( + /*var responseData = await HttpService.to.get( "appointment/truck/base-info?vin=$resultStr", + );*/ + + final Map requestData = { + "code": resultStr, + "phone": StorageService.to.phone, + }; + if (plateNumber != null && plateNumber.isNotEmpty) { + requestData['plateNumber'] = plateNumber; + } + var responseData = await HttpService.to.post( + "appointment/truck/bindTruck", + data: requestData, ); - if (responseData == null || responseData.data == null) { + if (responseData == null) { showToast('无法获取车辆信息,请检查网络或稍后重试'); resumeScanner(); return; } - var result = BaseModel.fromJson(responseData.data); + + if (result.data == null) { + showBindDialog(resultStr); + return; + } + final vehicle = VehicleInfo.fromJson(result.data as Map); //保存使用 await StorageService.to.saveVehicleInfo(vehicle); @@ -199,6 +211,34 @@ class QrCodeController extends GetxController } } + void showBindDialog(String resultStr) { + final TextEditingController plateNumberController = TextEditingController(); + DialogX.to.showNoticeDialog( + icon: DialogIcon.info, + title: '请输入车牌号', + barrierDismissible: false, + content: TextField( + controller: plateNumberController, // 绑定 controller + autofocus: false, // 弹窗出现时自动获取焦点,方便用户直接输入 + decoration: const InputDecoration( + hintText: '请输入完整的车牌号', + border: OutlineInputBorder(), + contentPadding: EdgeInsets.symmetric(horizontal: 12.0), + ), + ), + confirmText: '确认', + onConfirm: () { + final String plateNumber = plateNumberController.text.trim(); + if (plateNumber.isEmpty) { + resumeScanner(); + showToast("请输入车牌号"); + return; + } + renderResult(resultStr, plateNumber: plateNumber); + }, + ); + } + @override void onClose() { qrViewController?.dispose();