Browse Source

时间选择

周睿 2 years ago
parent
commit
84e48e09f1
1 changed files with 261 additions and 38 deletions
  1. 261 38
      app_business/lib/view/home/dialog_event_register.dart

+ 261 - 38
app_business/lib/view/home/dialog_event_register.dart

@@ -13,6 +13,12 @@ class _ArgEdit {
   EventRegisterInfo old = EventRegisterInfo();
 }
 
+extension DateTimeExt on DateTime {
+  (DateTime, TimeOfDay) split() {
+    return (DateTime(year, month, day), TimeOfDay.fromDateTime(this));
+  }
+}
+
 Future<EventRegisterInfo?> showEventRegisterDialog(
     int mapId, Iterable<EventInfo> eventList) async {
   return await Get.dialog(const RegisterDialog(),
@@ -31,9 +37,7 @@ Future<EventRegisterInfo?> showEventEditDialog(
 
 class RegisterDialogController extends GetxController {
   var registerName = '';
-  // final date = Rx<DateTime?>(null);
-  // final registerStartAt = Rx<TimeOfDay?>(null);
-  // final registerStopAt = Rx<TimeOfDay?>(null);
+
   final selected = Rx<EventInfo?>(null);
   final hasPasswordQuery = false.obs;
   final hasPasswordEvent = false.obs;
@@ -47,18 +51,11 @@ class RegisterDialogController extends GetxController {
   TimeOfDay? eventStartAt;
   TimeOfDay? eventEndAt;
 
-  Rx<DateTime?> showDate = Rx(null);
+  Rx<DateTime?> showDateStart = Rx(null);
   TimeOfDay? showStartAt;
+  Rx<DateTime?> showDateEnd = Rx(null);
   TimeOfDay? showEndAt;
 
-  // String? get dateString {
-  //   final d = date.value;
-  //   if (d != null) {
-  //     return '${d.month}/${d.day}';
-  //   }
-  //   return null;
-  // }
-
   @override
   void onInit() {
     final args = Get.arguments;
@@ -72,16 +69,23 @@ class RegisterDialogController extends GetxController {
       eventList = null;
       mapId = args.mapId;
       registerName = args.old.name;
-      var d = args.old.eventStartAt;
-
-      eventDate.value = DateTime(d.year, d.month, d.day);
-      d = args.old.showStartAt;
-      showDate.value = DateTime(d.year, d.month, d.day);
-      eventStartAt = TimeOfDay.fromDateTime(args.old.eventStartAt);
-      eventEndAt = TimeOfDay.fromDateTime(args.old.eventStopAt);
 
-      showStartAt = TimeOfDay.fromDateTime(args.old.showStartAt);
-      showEndAt = TimeOfDay.fromDateTime(args.old.showStopAt);
+      {
+        final (date, time) = args.old.eventStartAt.split();
+        eventDate.value = date;
+        eventStartAt = time;
+        eventEndAt = TimeOfDay.fromDateTime(args.old.eventStopAt);
+      }
+      {
+        final (date, time) = args.old.showStartAt.split();
+        showDateStart.value = date;
+        showStartAt = time;
+      }
+      {
+        final (date, time) = args.old.showStopAt.split();
+        showDateEnd.value = date;
+        showEndAt = time;
+      }
 
       passwordQuery = args.old.passwordQuery ?? '';
       hasPasswordQuery.value = args.old.passwordQuery != null;
@@ -91,9 +95,10 @@ class RegisterDialogController extends GetxController {
     super.onInit();
   }
 
-  void updateShowTime(DateTime? date, TimeOfDay? startAt, TimeOfDay? endAt) {
-    if (date != null) {
-      showDate.value = date;
+  void updateShowTime(DateTime? dateStart, TimeOfDay? startAt,
+      DateTime? dateEnd, TimeOfDay? endAt) {
+    if (dateStart != null) {
+      showDateStart.value = dateStart;
     }
     if (startAt != null) {
       showStartAt = startAt;
@@ -101,6 +106,9 @@ class RegisterDialogController extends GetxController {
     if (endAt != null) {
       showEndAt = endAt;
     }
+    if (dateEnd != null) {
+      showDateEnd.value = dateEnd;
+    }
   }
 
   void updateEventTime(DateTime? date, TimeOfDay? startAt, TimeOfDay? endAt) {
@@ -116,6 +124,8 @@ class RegisterDialogController extends GetxController {
   }
 }
 
+const double dialogWidth = 400.0;
+
 class RegisterDialog extends GetView<RegisterDialogController> {
   const RegisterDialog({super.key});
 
@@ -132,7 +142,7 @@ class RegisterDialog extends GetView<RegisterDialogController> {
               SizedBox(
                   child: DropdownMenu<EventInfo>(
                       key: GlobalKey(),
-                      width: 320,
+                      width: dialogWidth,
                       hintText: '请选择活动',
                       onSelected: (one) {
                         controller.selected.value = one;
@@ -159,17 +169,16 @@ class RegisterDialog extends GetView<RegisterDialogController> {
                   : controller.registerName,
             ),
             const SizedBox(height: 21.34),
-            Obx(() => _DateTimeSelect(
-                title: '比赛时间',
+            Obx(() => _EventTimeSelect(
                 date: c.eventDate.value,
                 startAt: c.eventStartAt,
                 endAt: c.eventEndAt,
                 onChanged: c.updateEventTime)),
             const SizedBox(height: 12),
-            Obx(() => _DateTimeSelect(
-                title: '显示时间',
-                date: c.showDate.value,
+            Obx(() => _ShowTimeSelect(
+                dateStart: c.showDateStart.value,
                 startAt: c.showStartAt,
+                dateEnd: c.showDateEnd.value,
                 endAt: c.showEndAt,
                 onChanged: c.updateShowTime)),
             password('查询密码', c.hasPasswordQuery, (v) {
@@ -196,7 +205,7 @@ class RegisterDialog extends GetView<RegisterDialogController> {
             shape: RoundedRectangleBorder(
                 borderRadius: BorderRadius.circular(17.78)),
             content: SizedBox(
-                width: 320,
+                width: dialogWidth,
                 child: ListView(shrinkWrap: true, children: children)),
           );
         });
@@ -225,7 +234,9 @@ class RegisterDialog extends GetView<RegisterDialogController> {
   }
 
   void _onRegister() {
-    final showDate = controller.showDate;
+    final showDateStart = controller.showDateStart.value;
+    final showDateEnd = controller.showDateEnd.value;
+
     final showTimeStartAt = controller.showStartAt;
     final showTimeStopAt = controller.showEndAt;
     final evenDate = controller.eventDate;
@@ -250,8 +261,12 @@ class RegisterDialog extends GetView<RegisterDialogController> {
       return;
     }
 
-    if (showDate.value == null) {
-      Get.snackbar('错误', '请选择日期');
+    if (showDateStart == null) {
+      Get.snackbar('错误', '请选择显示开始日期');
+      return;
+    }
+    if (showDateEnd == null) {
+      Get.snackbar('错误', '请选择显示结束日期');
       return;
     }
     if (showTimeStartAt == null) {
@@ -286,10 +301,10 @@ class RegisterDialog extends GetView<RegisterDialogController> {
       return;
     }
 
-    final showStartAt = showDate.value!
-        .copyWith(hour: showTimeStartAt.hour, minute: showTimeStartAt.minute);
-    final showStopAt = showDate.value!
-        .copyWith(hour: showTimeStopAt.hour, minute: showTimeStopAt.minute);
+    final showStartAt = showDateStart.copyWith(
+        hour: showTimeStartAt.hour, minute: showTimeStartAt.minute);
+    final showStopAt = showDateEnd.copyWith(
+        hour: showTimeStopAt.hour, minute: showTimeStopAt.minute);
 
     if (showStartAt.isAfter(showStopAt)) {
       Get.snackbar('错误', '结束时间应晚于开始时间');
@@ -370,6 +385,214 @@ class _TextField extends StatelessWidget {
   }
 }
 
+const timeColor = Color(0xff6e6e6e);
+
+class _TimeSelect extends StatelessWidget {
+  const _TimeSelect({required this.children, required this.title});
+
+  final String title;
+  final List<Widget> children;
+
+  @override
+  Widget build(BuildContext context) {
+    return Column(
+      mainAxisSize: MainAxisSize.min,
+      crossAxisAlignment: CrossAxisAlignment.start,
+      children: [
+        Text(
+          title,
+          style: const TextStyle(color: Colors.black),
+        ),
+        Container(
+            height: 54,
+            width: double.infinity,
+            decoration: BoxDecoration(
+                borderRadius: BorderRadius.circular(2.5),
+                border: Border.all(color: timeColor, width: 1)),
+            child: DefaultTextStyle(
+                style: const TextStyle(color: timeColor),
+                child: Row(
+                  children: children,
+                )))
+      ],
+    );
+  }
+}
+
+class _TimeButton extends StatelessWidget {
+  const _TimeButton(
+      {required this.onPressed, required this.hint, required this.value});
+
+  final VoidCallback onPressed;
+  final String hint;
+  final String? value;
+
+  @override
+  Widget build(BuildContext context) {
+    return TextButton(
+        onPressed: onPressed,
+        child: Text(value ?? hint, style: const TextStyle(color: timeColor)));
+  }
+}
+
+class _EventTimeSelect extends StatefulWidget {
+  const _EventTimeSelect(
+      {this.date, this.startAt, this.endAt, required this.onChanged});
+  final DateTime? date;
+  final TimeOfDay? startAt;
+  final TimeOfDay? endAt;
+  final void Function(DateTime? date, TimeOfDay? startAt, TimeOfDay? endAt)
+      onChanged;
+  @override
+  State<StatefulWidget> createState() {
+    return _EventTimeSelectState();
+  }
+}
+
+class _EventTimeSelectState extends State<_EventTimeSelect> {
+  DateTime? date;
+  TimeOfDay? startAt;
+  TimeOfDay? endAt;
+
+  @override
+  void initState() {
+    date = widget.date;
+    startAt = widget.startAt;
+    endAt = widget.endAt;
+    super.initState();
+  }
+
+  @override
+  Widget build(BuildContext context) {
+    return _TimeSelect(
+      title: '比赛时间',
+      children: [
+        Expanded(
+            child: _TimeButton(
+                onPressed: () async {
+                  date = await _showDatePicker(context, date);
+                  setState(() {});
+                  widget.onChanged(date, null, null);
+                },
+                hint: '比赛日期',
+                value: dateString(date))),
+        const Text('-'),
+        Expanded(
+            child: _TimeButton(
+                onPressed: () async {
+                  startAt = await _showTimePicker(context, startAt);
+                  setState(() {});
+                  widget.onChanged(null, startAt, null);
+                },
+                hint: '开始时间',
+                value: startAt?.format(context))),
+        const Text("-"),
+        Expanded(
+            child: _TimeButton(
+                onPressed: () async {
+                  endAt = await _showTimePicker(context, endAt);
+                  setState(() {});
+                  widget.onChanged(null, null, endAt);
+                },
+                hint: '结束时间',
+                value: endAt?.format(context))),
+        const Text(' '),
+        Expanded(child: TextButton(onPressed: () {}, child: const SizedBox()))
+      ],
+    );
+  }
+}
+
+class _ShowTimeSelect extends StatefulWidget {
+  const _ShowTimeSelect(
+      {this.dateStart,
+      this.dateEnd,
+      this.startAt,
+      this.endAt,
+      required this.onChanged});
+  final DateTime? dateStart;
+  final DateTime? dateEnd;
+  final TimeOfDay? startAt;
+  final TimeOfDay? endAt;
+  final void Function(DateTime? dateStart, TimeOfDay? startAt,
+      DateTime? dateEnd, TimeOfDay? endAt) onChanged;
+  @override
+  State<StatefulWidget> createState() {
+    return _ShowTimeSelectState();
+  }
+}
+
+class _ShowTimeSelectState extends State<_ShowTimeSelect> {
+  DateTime? dateStart;
+  DateTime? dateEnd;
+  TimeOfDay? startAt;
+  TimeOfDay? endAt;
+
+  @override
+  void initState() {
+    dateStart = widget.dateStart;
+    dateEnd = widget.dateEnd;
+    startAt = widget.startAt;
+    endAt = widget.endAt;
+    super.initState();
+  }
+
+  @override
+  Widget build(BuildContext context) {
+    return _TimeSelect(
+      title: '显示时间',
+      children: [
+        Expanded(
+            child: _TimeButton(
+                onPressed: () async {
+                  dateStart = await _showDatePicker(context, dateStart);
+                  setState(() {});
+                  widget.onChanged(dateStart, null, null, null);
+                },
+                hint: '开始日期',
+                value: dateString(dateStart))),
+        const Text('-'),
+        Expanded(
+            child: _TimeButton(
+                onPressed: () async {
+                  startAt = await _showTimePicker(context, startAt);
+                  setState(() {});
+                  widget.onChanged(null, startAt, null, null);
+                },
+                hint: '开始时间',
+                value: startAt?.format(context))),
+        const Text('至'),
+        Expanded(
+            child: _TimeButton(
+                onPressed: () async {
+                  dateEnd = await _showDatePicker(context, dateEnd);
+                  setState(() {});
+                  widget.onChanged(null, null, dateEnd, null);
+                },
+                hint: '结束日期',
+                value: dateString(dateEnd))),
+        const Text("-"),
+        Expanded(
+            child: _TimeButton(
+                onPressed: () async {
+                  endAt = await _showTimePicker(context, endAt);
+                  setState(() {});
+                  widget.onChanged(null, null, null, endAt);
+                },
+                hint: '结束时间',
+                value: endAt?.format(context))),
+      ],
+    );
+  }
+}
+
+String? dateString(DateTime? d) {
+  if (d != null) {
+    return '${d.month}/${d.day}';
+  }
+  return null;
+}
+
 class _DateTimeSelect extends StatefulWidget {
   const _DateTimeSelect(
       {required this.title,