调整预约时间格式
This commit is contained in:
@@ -3,7 +3,7 @@
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="initial-scale=1.0, user-scalable=no, width=device-width">
|
||||
<title>导航规划</title>
|
||||
<title>路径规划</title>
|
||||
<style>
|
||||
html, body, #container { width: 100%; height: 100%; margin: 0; }
|
||||
|
||||
|
||||
@@ -45,8 +45,6 @@ class B_BaseWidgetsPage extends GetView<B_BaseWidgetsController> {
|
||||
label: '加氢预约',
|
||||
icon: AntdIcon.orderedlist,
|
||||
selectedIcon: AntdIcon.calendar_fill,
|
||||
badge: '99+',
|
||||
dot: true,
|
||||
),
|
||||
NavigationItemModel(
|
||||
label: '站点信息',
|
||||
|
||||
@@ -71,7 +71,7 @@ class ReservationPage extends GetView<ReservationController> {
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||||
children: [
|
||||
_buildHeaderStat(controller.costPrice, '氢气价格'),
|
||||
_buildHeaderStat(controller.customerPrice, '氢气价格'),
|
||||
_buildHeaderStat(controller.timeStr, '营业时间'),
|
||||
_buildHeaderStat('98%', '设备状态'),
|
||||
],
|
||||
@@ -119,7 +119,7 @@ class ReservationPage extends GetView<ReservationController> {
|
||||
|
||||
// --- 价格信息 ---
|
||||
_buildSectionTitle('价格信息'),
|
||||
_buildDisplayField(label: '氢气价格 (元/kg)', value: controller.costPrice),
|
||||
// _buildDisplayField(label: '氢气价格 (元/kg)', value: controller.costPrice),
|
||||
_buildDisplayField(label: '官方价格 (元/kg)', value: controller.customerPrice),
|
||||
const SizedBox(height: 16),
|
||||
|
||||
|
||||
@@ -51,14 +51,11 @@ class BaseWidgetsPage extends GetView<BaseWidgetsController> {
|
||||
label: '地图',
|
||||
icon: AntdIcon.location,
|
||||
selectedIcon: AntdIcon.location_fill,
|
||||
dot: false,
|
||||
),
|
||||
NavigationItemModel(
|
||||
label: '加氢预约',
|
||||
icon: AntdIcon.orderedlist,
|
||||
selectedIcon: AntdIcon.calendar_fill,
|
||||
badge: '99+',
|
||||
dot: true,
|
||||
),
|
||||
NavigationItemModel(
|
||||
label: '车辆信息',
|
||||
|
||||
@@ -119,68 +119,55 @@ class C_ReservationController extends GetxController with BaseControllerMixin {
|
||||
}
|
||||
|
||||
void pickTime(BuildContext context, bool isStartTime) {
|
||||
// 确定当前操作的时间和初始值
|
||||
// 1. 确定当前操作的时间和初始值
|
||||
TimeOfDay initialTime = isStartTime ? startTime.value : endTime.value;
|
||||
DateTime now = DateTime.now();
|
||||
|
||||
// 计算最小可选时间
|
||||
DateTime? minimumDateTime; // 默认为 null,即可选任意时间
|
||||
// 2. 准备小时和分钟的数据源
|
||||
List<int> hours = List<int>.generate(24, (index) => index);
|
||||
List<int> minutes = [0, 30];
|
||||
|
||||
// 获取当前选择的日期(年月日)
|
||||
final selectedDay = DateTime(
|
||||
selectedDate.value.year,
|
||||
selectedDate.value.month,
|
||||
selectedDate.value.day,
|
||||
);
|
||||
// 3. 计算初始选中的索引
|
||||
int initialHour = initialTime.hour;
|
||||
// 将初始分钟校准到0或30,并找到对应的索引
|
||||
int initialMinute = initialTime.minute;
|
||||
int minuteIndex = initialMinute < 30 ? 0 : 1;
|
||||
initialMinute = minutes[minuteIndex]; // 校准后的分钟
|
||||
|
||||
// 获取今天的日期(年月日)
|
||||
// 如果校准后导致时间早于当前时间,需要向上调整
|
||||
final selectedDay = DateTime(selectedDate.value.year, selectedDate.value.month, selectedDate.value.day);
|
||||
final today = DateTime(now.year, now.month, now.day);
|
||||
|
||||
if (isStartTime) {
|
||||
// 如果是选择开始时间并且日期是 今天
|
||||
if (selectedDay.isAtSameMomentAs(today)) {
|
||||
minimumDateTime = now; // 最小可选时间就是现在
|
||||
}
|
||||
if (initialHour < now.hour || (initialHour == now.hour && initialMinute < now.minute)) {
|
||||
initialHour = now.hour;
|
||||
if (now.minute > 30) {
|
||||
// 如果当前分钟>30, 则进位到下一小时的0分
|
||||
initialHour = (now.hour + 1) % 24;
|
||||
initialMinute = 0;
|
||||
} else {
|
||||
// 如果是选择结束时间
|
||||
// 将开始时间转换为 DateTime 对象
|
||||
final startDateTime = DateTime(
|
||||
selectedDate.value.year,
|
||||
selectedDate.value.month,
|
||||
selectedDate.value.day,
|
||||
startTime.value.hour,
|
||||
startTime.value.minute,
|
||||
);
|
||||
|
||||
// 结束时间的最小值必须晚于开始时间
|
||||
minimumDateTime = startDateTime;
|
||||
|
||||
// 如果日期是今天,并且开始时间早于现在,那么结束时间的最小值也应该是现在
|
||||
if (selectedDay.isAtSameMomentAs(today) && startDateTime.isBefore(now)) {
|
||||
minimumDateTime = now;
|
||||
// 否则,取30分
|
||||
initialMinute = 30;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 初始显示时间
|
||||
DateTime initialDateTime = DateTime(
|
||||
selectedDate.value.year,
|
||||
selectedDate.value.month,
|
||||
selectedDate.value.day,
|
||||
initialTime.hour,
|
||||
initialTime.minute,
|
||||
);
|
||||
// 重新获取校准后的索引
|
||||
minuteIndex = minutes.indexOf(initialMinute);
|
||||
|
||||
// 确保初始时间不早于最小时间
|
||||
if (minimumDateTime != null && initialDateTime.isBefore(minimumDateTime)) {
|
||||
initialDateTime = minimumDateTime;
|
||||
}
|
||||
|
||||
DateTime tempTime = initialDateTime;
|
||||
// 4. 创建 FixedExtentScrollController 来控制滚轮的初始位置
|
||||
final FixedExtentScrollController hourController =
|
||||
FixedExtentScrollController(initialItem: hours.indexOf(initialHour));
|
||||
final FixedExtentScrollController minuteController =
|
||||
FixedExtentScrollController(initialItem: minuteIndex);
|
||||
|
||||
// 5. 存储临时选择的值
|
||||
int tempHour = initialHour;
|
||||
int tempMinute = initialMinute;
|
||||
|
||||
Get.bottomSheet(
|
||||
Container(
|
||||
height: 300,
|
||||
padding: const EdgeInsets.only(top: 6.0),
|
||||
decoration: const BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.only(
|
||||
@@ -197,75 +184,55 @@ class C_ReservationController extends GetxController with BaseControllerMixin {
|
||||
children: [
|
||||
CupertinoButton(
|
||||
onPressed: () => Get.back(),
|
||||
child: const Text(
|
||||
'取消',
|
||||
style: TextStyle(color: CupertinoColors.systemGrey),
|
||||
),
|
||||
child: const Text('取消', style: TextStyle(color: CupertinoColors.systemGrey)),
|
||||
),
|
||||
CupertinoButton(
|
||||
onPressed: () {
|
||||
final pickedTempTime = TimeOfDay.fromDateTime(tempTime);
|
||||
final pickedTempTime = TimeOfDay(hour: tempHour, minute: tempMinute);
|
||||
final now = DateTime.now();
|
||||
|
||||
// 验证条件1:不能选择过去的时间
|
||||
// 这个验证只在选择【今天】的【开始时间】或【结束时间】时有意义
|
||||
final selectedDay = DateTime(
|
||||
// --- 合并和简化校验逻辑 ---
|
||||
final selectedDateTime = DateTime(
|
||||
selectedDate.value.year,
|
||||
selectedDate.value.month,
|
||||
selectedDate.value.day,
|
||||
);
|
||||
final today = DateTime(
|
||||
DateTime.now().year,
|
||||
DateTime.now().month,
|
||||
DateTime.now().day,
|
||||
pickedTempTime.hour,
|
||||
pickedTempTime.minute,
|
||||
);
|
||||
|
||||
if (selectedDay.isAtSameMomentAs(today) &&
|
||||
tempTime.isBefore(DateTime.now())) {
|
||||
// 验证1: 不能选择过去的时间(留出一分钟缓冲)
|
||||
if (selectedDateTime.isBefore(now.subtract(const Duration(minutes: 1)))) {
|
||||
showToast('不能选择过去的时间');
|
||||
return; // 中断执行,不关闭弹窗
|
||||
return;
|
||||
}
|
||||
|
||||
//结束时间必须晚于开始时间
|
||||
// 验证2: 结束时间必须晚于开始时间
|
||||
if (isStartTime) {
|
||||
// 已有的结束时间 比较
|
||||
final pickedStartInMinutes =
|
||||
pickedTempTime.hour * 60 + pickedTempTime.minute;
|
||||
final endInMinutes =
|
||||
endTime.value.hour * 60 + endTime.value.minute;
|
||||
|
||||
if (pickedStartInMinutes >= endInMinutes) {
|
||||
// 整结束时间
|
||||
startTime.value = pickedTempTime;
|
||||
final newEndDateTime = tempTime.add(
|
||||
const Duration(minutes: 30),
|
||||
);
|
||||
final startInMinutes = pickedTempTime.hour * 60 + pickedTempTime.minute;
|
||||
final endInMinutes = endTime.value.hour * 60 + endTime.value.minute;
|
||||
|
||||
// 如果新的开始时间大于等于结束时间,自动将结束时间设置为开始时间+30分钟
|
||||
if (startInMinutes >= endInMinutes) {
|
||||
final newEndDateTime = selectedDateTime.add(const Duration(minutes: 30));
|
||||
endTime.value = TimeOfDay.fromDateTime(newEndDateTime);
|
||||
} else {
|
||||
//设置开始时间
|
||||
startTime.value = pickedTempTime;
|
||||
}
|
||||
} else {
|
||||
// 如果当前正在设置结束时间,我们来和已有的开始时间比较
|
||||
final pickedEndInMinutes =
|
||||
pickedTempTime.hour * 60 + pickedTempTime.minute;
|
||||
final startInMinutes =
|
||||
startTime.value.hour * 60 + startTime.value.minute;
|
||||
} else { // 正在设置结束时间
|
||||
final startInMinutes = startTime.value.hour * 60 + startTime.value.minute;
|
||||
final endInMinutes = pickedTempTime.hour * 60 + pickedTempTime.minute;
|
||||
|
||||
if (pickedEndInMinutes <= startInMinutes) {
|
||||
if (endInMinutes <= startInMinutes) {
|
||||
showToast('结束时间必须晚于开始时间');
|
||||
return; // 中断执行,不关闭弹窗
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
endTime.value = pickedTempTime;
|
||||
}
|
||||
}
|
||||
|
||||
Get.back();
|
||||
},
|
||||
child: const Text(
|
||||
'确认',
|
||||
style: TextStyle(
|
||||
color: AppTheme.themeColor,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
style: TextStyle(color: AppTheme.themeColor, fontWeight: FontWeight.bold),
|
||||
),
|
||||
),
|
||||
],
|
||||
@@ -273,14 +240,36 @@ class C_ReservationController extends GetxController with BaseControllerMixin {
|
||||
),
|
||||
const Divider(height: 1, color: Color(0xFFE5E5E5)),
|
||||
Expanded(
|
||||
child: CupertinoDatePicker(
|
||||
mode: CupertinoDatePickerMode.time,
|
||||
use24hFormat: true,
|
||||
initialDateTime: initialDateTime,
|
||||
minimumDate: minimumDateTime,
|
||||
onDateTimeChanged: (DateTime newTime) {
|
||||
tempTime = newTime;
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
// 小时选择器
|
||||
Expanded(
|
||||
child: CupertinoPicker(
|
||||
scrollController: hourController,
|
||||
itemExtent: 32.0,
|
||||
onSelectedItemChanged: (index) {
|
||||
tempHour = hours[index];
|
||||
},
|
||||
children: hours
|
||||
.map((h) => Center(child: Text(h.toString().padLeft(2, '0'))))
|
||||
.toList(),
|
||||
),
|
||||
),
|
||||
// 分钟选择器
|
||||
Expanded(
|
||||
child: CupertinoPicker(
|
||||
scrollController: minuteController,
|
||||
itemExtent: 32.0,
|
||||
onSelectedItemChanged: (index) {
|
||||
tempMinute = minutes[index];
|
||||
},
|
||||
children: minutes
|
||||
.map((m) => Center(child: Text(m.toString().padLeft(2, '0'))))
|
||||
.toList(),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
@@ -290,6 +279,8 @@ class C_ReservationController extends GetxController with BaseControllerMixin {
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// 用于存储上一次成功预约的信息
|
||||
ReservationModel? lastSuccessfulReservation;
|
||||
|
||||
@@ -323,7 +314,6 @@ class C_ReservationController extends GetxController with BaseControllerMixin {
|
||||
final startTimeStr = '$dateStr ${formattedStartTime}:00';
|
||||
if (lastSuccessfulReservation != null &&
|
||||
lastSuccessfulReservation!.id == selectedStationId.value &&
|
||||
lastSuccessfulReservation!.hydAmount == ampuntStr &&
|
||||
lastSuccessfulReservation!.startTime == startTimeStr) {
|
||||
showToast("请勿重复提交相同的预约");
|
||||
return;
|
||||
|
||||
Reference in New Issue
Block a user