默认时间段修改

This commit is contained in:
2025-12-01 17:03:16 +08:00
parent 4f99ab4164
commit 4cdedff654
2 changed files with 110 additions and 41 deletions

View File

@@ -22,8 +22,10 @@ class TimeSlot {
TimeSlot(this.start, this.end); TimeSlot(this.start, this.end);
String get display { String get display {
final startStr = '${start.hour.toString().padLeft(2, '0')}:${start.minute.toString().padLeft(2, '0')}'; final startStr =
final endStr = '${end.hour.toString().padLeft(2, '0')}:${end.minute.toString().padLeft(2, '0')}'; '${start.hour.toString().padLeft(2, '0')}:${start.minute.toString().padLeft(2, '0')}';
final endStr =
'${end.hour.toString().padLeft(2, '0')}:${end.minute.toString().padLeft(2, '0')}';
return '$startStr - $endStr'; return '$startStr - $endStr';
} }
} }
@@ -32,11 +34,33 @@ class C_ReservationController extends GetxController with BaseControllerMixin {
@override @override
String get builderId => 'reservation'; String get builderId => 'reservation';
final Rx<DateTime> selectedDate = DateTime.now().obs; final DateTime _now = DateTime.now();
final Rx<TimeOfDay> startTime = TimeOfDay.now().obs;
final Rx<TimeOfDay> endTime = TimeOfDay.fromDateTime( // 计算当前时间属于哪个半小时区间
DateTime.now().add(const Duration(minutes: 30)), late final TimeOfDay _initialStartTime = _calculateInitialStartTime(_now);
).obs; late final TimeOfDay _initialEndTime = TimeOfDay.fromDateTime(
_getDateTimeFromTimeOfDay(_initialStartTime).add(const Duration(minutes: 30)),
);
late final Rx<DateTime> selectedDate = DateTime(_now.year, _now.month, _now.day).obs;
late final Rx<TimeOfDay> startTime = _initialStartTime.obs;
late final Rx<TimeOfDay> endTime = _initialEndTime.obs;
/// 静态辅助方法,用于计算初始的开始时间
static TimeOfDay _calculateInitialStartTime(DateTime now) {
if (now.minute < 30) {
// 如果当前分钟小于30则开始时间为当前小时的0分
return TimeOfDay(hour: now.hour, minute: 0);
} else {
// 如果当前分钟大于等于30则开始时间为当前小时的30分
return TimeOfDay(hour: now.hour, minute: 30);
}
}
/// 静态辅助方法将TimeOfDay转换为DateTime
static DateTime _getDateTimeFromTimeOfDay(TimeOfDay time) {
final now = DateTime.now();
return DateTime(now.year, now.month, now.day, time.hour, time.minute);
}
final TextEditingController amountController = TextEditingController(); final TextEditingController amountController = TextEditingController();
TextEditingController plateNumberController = TextEditingController(); TextEditingController plateNumberController = TextEditingController();
@@ -46,9 +70,9 @@ class C_ReservationController extends GetxController with BaseControllerMixin {
String get formattedDate => DateFormat('yyyy-MM-dd').format(selectedDate.value); String get formattedDate => DateFormat('yyyy-MM-dd').format(selectedDate.value);
String get formattedStartTime => _formatTimeOfDay(startTime.value); /// 时间段
String get formattedTimeSlot =>
String get formattedEndTime => _formatTimeOfDay(endTime.value); '${_formatTimeOfDay(startTime.value)} - ${_formatTimeOfDay(endTime.value)}';
void pickDate(BuildContext context) { void pickDate(BuildContext context) {
DateTime tempDate = selectedDate.value; DateTime tempDate = selectedDate.value;
@@ -73,14 +97,23 @@ class C_ReservationController extends GetxController with BaseControllerMixin {
children: [ children: [
CupertinoButton( CupertinoButton(
onPressed: () => Get.back(), onPressed: () => Get.back(),
child: const Text('取消', style: TextStyle(color: CupertinoColors.systemGrey)), child: const Text(
'取消',
style: TextStyle(color: CupertinoColors.systemGrey),
),
), ),
CupertinoButton( CupertinoButton(
onPressed: () { onPressed: () {
selectedDate.value = tempDate; selectedDate.value = tempDate;
Get.back(); Get.back();
}, },
child: const Text('确认', style: TextStyle(color: AppTheme.themeColor, fontWeight: FontWeight.bold)), child: const Text(
'确认',
style: TextStyle(
color: AppTheme.themeColor,
fontWeight: FontWeight.bold,
),
),
), ),
], ],
), ),
@@ -90,7 +123,11 @@ class C_ReservationController extends GetxController with BaseControllerMixin {
child: CupertinoDatePicker( child: CupertinoDatePicker(
mode: CupertinoDatePickerMode.date, mode: CupertinoDatePickerMode.date,
initialDateTime: selectedDate.value, initialDateTime: selectedDate.value,
minimumDate: DateTime(DateTime.now().year, DateTime.now().month, DateTime.now().day), minimumDate: DateTime(
DateTime.now().year,
DateTime.now().month,
DateTime.now().day,
),
maximumDate: DateTime.now().add(const Duration(days: 365)), maximumDate: DateTime.now().add(const Duration(days: 365)),
onDateTimeChanged: (DateTime newDate) { onDateTimeChanged: (DateTime newDate) {
tempDate = newDate; tempDate = newDate;
@@ -107,7 +144,8 @@ class C_ReservationController extends GetxController with BaseControllerMixin {
///30 分钟为间隔 时间选择器 ///30 分钟为间隔 时间选择器
void pickTime(BuildContext context) { void pickTime(BuildContext context) {
final now = DateTime.now(); final now = DateTime.now();
final isToday = selectedDate.value.year == now.year && final isToday =
selectedDate.value.year == now.year &&
selectedDate.value.month == now.month && selectedDate.value.month == now.month &&
selectedDate.value.day == now.day; selectedDate.value.day == now.day;
@@ -127,8 +165,24 @@ class C_ReservationController extends GetxController with BaseControllerMixin {
startTime.minute, startTime.minute,
); );
if (!isToday || slotStartDateTime.isAfter(now)) { // 如果不是今天,所有时间段都有效
if (!isToday) {
availableSlots.add(TimeSlot(startTime, endTime)); availableSlots.add(TimeSlot(startTime, endTime));
} else {
// 如果是今天,需要判断该时间段是否可选
// 创建时间段的结束时间对象
final slotEndDateTime = DateTime(
selectedDate.value.year,
selectedDate.value.month,
selectedDate.value.day,
endTime.hour,
endTime.minute,
);
// 只要时间段的结束时间晚于当前时间,这个时间段就是可预约的
if (slotEndDateTime.isAfter(now)) {
availableSlots.add(TimeSlot(startTime, endTime));
}
} }
} }
@@ -137,17 +191,22 @@ class C_ReservationController extends GetxController with BaseControllerMixin {
return; return;
} }
int initialItem = availableSlots.indexWhere((slot) => int initialItem = availableSlots.indexWhere(
(slot) =>
slot.start.hour == startTime.value.hour && slot.start.hour == startTime.value.hour &&
(startTime.value.minute < 30 ? slot.start.minute == 0 : slot.start.minute == 30)); (startTime.value.minute < 30
? slot.start.minute == 0
: slot.start.minute == 30),
);
if (initialItem == -1) { if (initialItem == -1) {
initialItem = 0; initialItem = 0;
} }
TimeSlot tempSlot = availableSlots[initialItem]; TimeSlot tempSlot = availableSlots[initialItem];
final FixedExtentScrollController scrollController = final FixedExtentScrollController scrollController = FixedExtentScrollController(
FixedExtentScrollController(initialItem: initialItem); initialItem: initialItem,
);
Get.bottomSheet( Get.bottomSheet(
Container( Container(
@@ -168,7 +227,10 @@ class C_ReservationController extends GetxController with BaseControllerMixin {
children: [ children: [
CupertinoButton( CupertinoButton(
onPressed: () => Get.back(), onPressed: () => Get.back(),
child: const Text('取消', style: TextStyle(color: CupertinoColors.systemGrey)), child: const Text(
'取消',
style: TextStyle(color: CupertinoColors.systemGrey),
),
), ),
CupertinoButton( CupertinoButton(
onPressed: () { onPressed: () {
@@ -176,7 +238,13 @@ class C_ReservationController extends GetxController with BaseControllerMixin {
endTime.value = tempSlot.end; endTime.value = tempSlot.end;
Get.back(); Get.back();
}, },
child: const Text('确认', style: TextStyle(color: AppTheme.themeColor, fontWeight: FontWeight.bold)), child: const Text(
'确认',
style: TextStyle(
color: AppTheme.themeColor,
fontWeight: FontWeight.bold,
),
),
), ),
], ],
), ),
@@ -189,8 +257,9 @@ class C_ReservationController extends GetxController with BaseControllerMixin {
onSelectedItemChanged: (index) { onSelectedItemChanged: (index) {
tempSlot = availableSlots[index]; tempSlot = availableSlots[index];
}, },
children: children: availableSlots
availableSlots.map((slot) => Center(child: Text(slot.display))).toList(), .map((slot) => Center(child: Text(slot.display)))
.toList(),
), ),
), ),
], ],
@@ -200,8 +269,6 @@ class C_ReservationController extends GetxController with BaseControllerMixin {
); );
} }
// 用于存储上一次成功预约的信息 // 用于存储上一次成功预约的信息
ReservationModel? lastSuccessfulReservation; ReservationModel? lastSuccessfulReservation;
@@ -232,7 +299,9 @@ class C_ReservationController extends GetxController with BaseControllerMixin {
} }
final dateStr = formattedDate; final dateStr = formattedDate;
final startTimeStr = '$dateStr ${formattedStartTime}:00'; final startTimeStr =
'$dateStr ${_formatTimeOfDay(startTime.value)}:00'; // Use helper directly
if (lastSuccessfulReservation != null && if (lastSuccessfulReservation != null &&
lastSuccessfulReservation!.id == selectedStationId.value && lastSuccessfulReservation!.id == selectedStationId.value &&
lastSuccessfulReservation!.startTime == startTimeStr) { lastSuccessfulReservation!.startTime == startTimeStr) {
@@ -240,35 +309,36 @@ class C_ReservationController extends GetxController with BaseControllerMixin {
return; return;
} }
// 将选择的日期和时间组合成一个完整的 DateTime 对象 final reservationEndDateTime = DateTime(
final reservationStartDateTime = DateTime(
selectedDate.value.year, selectedDate.value.year,
selectedDate.value.month, selectedDate.value.month,
selectedDate.value.day, selectedDate.value.day,
startTime.value.hour, endTime.value.hour,
startTime.value.minute, endTime.value.minute,
); );
// 检查预约时间是否当前时间之前 //判断预约区间的结束时间是否早于当前时间留出1分钟缓冲
if (reservationStartDateTime.isBefore(DateTime.now())) { if (reservationEndDateTime.isBefore(
showToast("不可预约过去的时间"); DateTime.now().subtract(const Duration(minutes: 1)),
)) {
showToast("无法预约已过去的时间段");
return; return;
} }
try { try {
final selectedStation = stationOptions.firstWhere( final selectedStation = stationOptions.firstWhere(
(s) => s.hydrogenId == selectedStationId.value, (s) => s.hydrogenId == selectedStationId.value,
); );
if(selectedStation.siteStatusName != "营运中"){ if (selectedStation.siteStatusName != "营运中") {
showToast("该站点${selectedStation.siteStatusName},暂无法预约"); showToast("该站点${selectedStation.siteStatusName},暂无法预约");
return; return;
} }
showLoading("提交中"); showLoading("提交中");
final dateStr = formattedDate; // "yyyy-MM-dd" final endTimeStr =
final startTimeStr = '$dateStr ${formattedStartTime}:00'; // "yyyy-MM-dd HH:mm:ss" '$dateStr ${_formatTimeOfDay(endTime.value)}:00'; // Use helper directly
final endTimeStr = '$dateStr ${formattedEndTime}:00';
var responseData = await HttpService.to.post( var responseData = await HttpService.to.post(
'appointment/orderAddHyd/saveOrUpdate', 'appointment/orderAddHyd/saveOrUpdate',
@@ -296,7 +366,6 @@ class C_ReservationController extends GetxController with BaseControllerMixin {
if (result.code == 0) { if (result.code == 0) {
showSuccessToast("预约成功"); showSuccessToast("预约成功");
// 预约成功后,保存当前预约信息
lastSuccessfulReservation = ReservationModel( lastSuccessfulReservation = ReservationModel(
id: selectedStationId.value!, id: selectedStationId.value!,
hydAmount: ampuntStr, hydAmount: ampuntStr,

View File

@@ -259,7 +259,7 @@ class ReservationPage extends GetView<C_ReservationController> {
), ),
_buildPickerRow( _buildPickerRow(
label: '预约时间', label: '预约时间',
value: controller.formattedStartTime, value: controller.formattedTimeSlot,
icon: Icons.access_time_outlined, icon: Icons.access_time_outlined,
onTap: () => controller.pickTime(context), onTap: () => controller.pickTime(context),
), ),