diff --git a/ln_jq_app/lib/pages/b_page/site/controller.dart b/ln_jq_app/lib/pages/b_page/site/controller.dart index e9eca10..6773838 100644 --- a/ln_jq_app/lib/pages/b_page/site/controller.dart +++ b/ln_jq_app/lib/pages/b_page/site/controller.dart @@ -1,7 +1,9 @@ import 'dart:async'; +import 'package:flutter/material.dart'; import 'package:getx_scaffold/getx_scaffold.dart'; import 'package:ln_jq_app/common/model/base_model.dart'; +import 'package:ln_jq_app/common/styles/theme.dart'; import 'package:ln_jq_app/storage_service.dart'; enum ReservationStatus { @@ -216,37 +218,282 @@ class SiteController extends GetxController with BaseControllerMixin { /// 确认预约 Future confirmReservation(String id) async { - final item = reservationList.firstWhere((item) => item.id == id); - DialogX.to.showConfirmDialog( - title: '确认预约', - message: '确定要确认车牌号${item.plateNumber}的预约吗', - onConfirm: () { - upDataService(id, 1, item); - }, - onCancel: () {}, + final item = reservationList.firstWhere( + (item) => item.id == id, + orElse: () => throw Exception('Reservation not found'), + ); + final TextEditingController amountController = TextEditingController( + text: item.hydAmount, + ); + Get.dialog( + Dialog( + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)), // 圆角 + child: Padding( + padding: const EdgeInsets.only(top: 24.0), + child: Column( + mainAxisSize: MainAxisSize.min, // 高度自适应 + children: [ + const Text( + '确认加氢状态', + style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold), + ), + const SizedBox(height: 5), + // content 部分 + Padding( + padding: const EdgeInsets.symmetric(horizontal: 24), + child: Column( + children: [ + Text( + '车牌号 ${item.plateNumber}', + style: const TextStyle( + fontSize: 16, + color: AppTheme.themeColor, + fontWeight: FontWeight.bold, + ), + ), + const SizedBox(height: 12), + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + const Text( + '加氢量', + style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold), + ), + const SizedBox(width: 16), + SizedBox( + width: 100, + child: TextField( + controller: amountController, + textAlign: TextAlign.center, + keyboardType: const TextInputType.numberWithOptions( + decimal: true, + ), + style: TextStyle( + fontSize: 22, + fontWeight: FontWeight.bold, + color: Get.theme.primaryColor, + ), + decoration: const InputDecoration( + suffixText: 'kg', + suffixStyle: TextStyle(fontSize: 16, color: Colors.grey), + enabledBorder: UnderlineInputBorder( + borderSide: BorderSide(color: Colors.grey), + ), + focusedBorder: UnderlineInputBorder( + borderSide: BorderSide(color: Colors.grey, width: 2), + ), + ), + ), + ), + ], + ), + const SizedBox(height: 12), + const Text( + '请选择本次加氢的实际状态\n用于更新预约记录。', + textAlign: TextAlign.center, + style: TextStyle(fontSize: 14, color: Colors.grey), + ), + ], + ), + ), + const SizedBox(height: 24), + // actions 部分 (按钮) + Padding( + padding: const EdgeInsets.only(left: 24, right: 24, bottom: 24), + child: Column( + children: [ + ElevatedButton( + onPressed: () { + Get.back(); // 关闭弹窗 + final num addHydAmount = num.tryParse(amountController.text) ?? 0; + upDataService(id, 0, 1, addHydAmount, "", item); + }, + style: ElevatedButton.styleFrom( + minimumSize: const Size(double.infinity, 48), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(5), + ), + ), + child: const Text('加氢完成', style: TextStyle(fontSize: 16)), + ), + const SizedBox(height: 12), + ElevatedButton( + onPressed: () { + Get.back(); // 关闭弹窗 + upDataService(id, 0, 2, 0, "", item); + }, + style: ElevatedButton.styleFrom( + backgroundColor: Colors.orange, + minimumSize: const Size(double.infinity, 48), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(5), + ), + ), + child: const Text('未加氢', style: TextStyle(fontSize: 16)), + ), + const SizedBox(height: 12), + TextButton( + onPressed: () => Get.back(), // 只关闭弹窗 + child: const Text( + '暂不处理', + style: TextStyle(color: Colors.grey, fontSize: 14), + ), + ), + ], + ), + ), + ], + ), + ), + ), + barrierDismissible: false, // 点击外部不关闭弹窗 ); } - /// 拒绝预约 Future rejectReservation(String id) async { final item = reservationList.firstWhere((item) => item.id == id); - DialogX.to.showConfirmDialog( - title: '拒绝预约', - message: '确定要拒绝车牌号${item.plateNumber}的预约吗', - onConfirm: () { - upDataService(id, 2, item); - }, - onCancel: () {}, + final TextEditingController reasonController = TextEditingController(); + final RxString selectedReason = ''.obs; + + // 预设的拒绝原因列表 + final List presetReasons = ['车辆未到场', '司机联系不上', '设备故障无法加氢']; + + Get.dialog( + Dialog( + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(16)), + child: SingleChildScrollView( + child: Padding( + padding: const EdgeInsets.all(24.0), + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + const Text( + '拒绝预约', + textAlign: TextAlign.center, + style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold), + ), + const SizedBox(height: 16), + Text( + '正在处理车牌号 ${item.plateNumber} 的预约', + textAlign: TextAlign.center, + style: const TextStyle(fontSize: 16, color: AppTheme.themeColor), + ), + const SizedBox(height: 24), + + // 4. 预设原因选择区域 + const Text('选择或填写拒绝原因:', style: TextStyle(color: Colors.grey)), + const SizedBox(height: 8), + Obx( + () => Wrap( + // 使用 Wrap 自动换行 + spacing: 8.0, // 水平间距 + children: presetReasons.map((reason) { + final isSelected = selectedReason.value == reason; + return ChoiceChip( + label: Text(reason), + selected: isSelected, + onSelected: (selected) { + if (selected) { + selectedReason.value = reason; + reasonController.clear(); // 选择预设原因时,清空自定义输入 + } + }, + selectedColor: Get.theme.primaryColor.withOpacity(0.2), + labelStyle: TextStyle( + color: isSelected ? Get.theme.primaryColor : Colors.black, + ), + ); + }).toList(), + ), + ), + const SizedBox(height: 16), + + // 5. 自定义原因输入框 + TextField( + controller: reasonController, + maxLines: 2, + decoration: InputDecoration( + hintText: '输入其它原因', + border: OutlineInputBorder( + borderRadius: BorderRadius.circular(8), + borderSide: BorderSide(color: Colors.grey.shade300), + ), + ), + onChanged: (text) { + if (text.isNotEmpty) { + selectedReason.value = ''; // 输入自定义原因时,取消预设选择 + } + }, + ), + const SizedBox(height: 24), + + // 6. 按钮区域 + Row( + children: [ + Expanded( + child: TextButton( + onPressed: () { + // 获取最终的拒绝原因 + String finalReason = reasonController.text.trim(); + if (finalReason.isEmpty) { + finalReason = selectedReason.value; + } + + if (finalReason.isEmpty) { + showToast('请选择或填写一个拒绝原因'); + return; + } + + Get.back(); // 关闭弹窗 + upDataService(id, 1, -1, 0, finalReason, item); + }, + child: const Text('确认拒绝', style: TextStyle(color: Colors.red)), + ), + ), + const SizedBox(width: 16), + Expanded( + child: TextButton( + onPressed: () => Get.back(), + child: const Text('暂不处理', style: TextStyle(color: Colors.grey)), + ), + ), + ], + ), + ], + ), + ), + ), + ), + barrierDismissible: false, ); } - void upDataService(String id, int status, ReservationModel item) async { + //addStatus 1完成 2未加 -1拒绝 + void upDataService( + String id, + int status, + int addStatus, + num addHydAmount, + String rejectReason, + ReservationModel item, + ) async { showLoading("确认中"); try { var responseData = await HttpService.to.post( 'appointment/orderAddHyd/completeOrder', - data: {'id': id, 'addStatus': status}, + data: status == 0 + ? { + 'id': id, + 'addStatus': addStatus, //完成使用 完成1,未加2 + "addHydAmount": addHydAmount, + } + : { + 'id': id, + 'state': addStatus, //拒绝使用 -1 + "rejectReason": rejectReason, + }, ); if (responseData == null && responseData!.data == null) { @@ -260,10 +507,12 @@ class SiteController extends GetxController with BaseControllerMixin { } dismissLoading(); - if (status == 1) { + if (addStatus == 1) { item.status = ReservationStatus.completed; - } else if (status == 2) { + } else if (addStatus == -1) { item.status = ReservationStatus.rejected; + } else if (addStatus == -2) { + item.status = ReservationStatus.pending; } updateUi(); } catch (e) { diff --git a/ln_jq_app/lib/pages/b_page/site/view.dart b/ln_jq_app/lib/pages/b_page/site/view.dart index 840b55a..f6f01ff 100644 --- a/ln_jq_app/lib/pages/b_page/site/view.dart +++ b/ln_jq_app/lib/pages/b_page/site/view.dart @@ -408,7 +408,7 @@ class SitePage extends GetView { child: ElevatedButton( onPressed: () => controller.confirmReservation(item.id), style: ElevatedButton.styleFrom(backgroundColor: Colors.blue), - child: const Text('确定'), + child: const Text('确认'), ), ), const SizedBox(width: 16), 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 a94c0ab..3e21532 100644 --- a/ln_jq_app/lib/pages/c_page/reservation/controller.dart +++ b/ln_jq_app/lib/pages/c_page/reservation/controller.dart @@ -307,7 +307,7 @@ class C_ReservationController extends GetxController with BaseControllerMixin { if (lastSuccessfulReservation != null && lastSuccessfulReservation!.id == selectedStationId.value && lastSuccessfulReservation!.startTime == startTimeStr) { - showToast("请勿重复提交相同的预约"); + showToast("请勿重复提交相同时间段的预约,可在“查看预约”中修改"); return; }