import 'package:app_business/service/api.dart'; import 'package:app_business/view/home/dialog_event_register.dart'; import 'package:pretty_qr_code/pretty_qr_code.dart'; import 'package:track_common/widget.dart'; import 'package:track_common/widget/prelude.dart'; import 'event_manage_controller.dart'; class EventManage extends GetView { const EventManage({super.key}); @override Widget build(BuildContext context) { return Level2View( level1: level1(), level2: level2(), level1Title: '赛事列表', level1Action: wDate(context), level2Title: '用户列表', level2SubTitle: Row( children: [ Obx(() => Text( controller.selected?.name != null ? '(${controller.selected!.name})' : '', style: const TextStyle(color: Colors.grey, fontSize: 14.22), )), const Spacer(), SizedBox( height: 27.73, width: 260, child: Row( mainAxisSize: MainAxisSize.min, mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ SizedBox( width: 70, child: SmallButton( isOutline: true, color: Colors.orange, onPressed: controller.userRestartAll, child: const Text('一键重赛'), )), SizedBox( width: 70, child: SmallButton( isOutline: true, color: Colors.blue, onPressed: controller.routeAllocAll, child: const Text('一键分发'), )), SizedBox( width: 70, child: SmallButton( isOutline: true, color: Colors.green, onPressed: controller.userStartAll, child: const Text('一键开始'), )) ], ), ), const SizedBox(width: 20) ], )); } Widget wDate(BuildContext context) { return GestureDetector( onTap: () => _onTapDate(context), child: Obx(() => Container( height: 22.04, padding: const EdgeInsets.symmetric(horizontal: 8), decoration: BoxDecoration( border: Border.all(color: const Color(0xffe3e3e3), width: 0.71), borderRadius: BorderRadius.circular(2.13)), child: Text(controller.dateStr), ))); } Future _onTapDate(BuildContext context) async { final date = await showDatePicker( context: context, initialDate: controller.filterDate.value, firstDate: DateTime.now(), lastDate: DateTime.now().add(365.days)); if (date != null) { controller.filterDate.value = date; controller.flushList(); } } Widget level1() { return Obx(() => ListView( children: controller.eventList .map((e) => EventTitle( data: e, selected: controller.selectedId.value == e.id, onTap: () => controller.selectedId.value = e.id, )) .toList())); } Widget level2() { return Column( children: [ Expanded( child: Obx( () => LineChart(titles: rightTitles(), children: rightUsers()))) ], ); } Iterable rightTitles() { return [ LineChartTitle( title: Checkbox( value: false, onChanged: (v) { controller.selectedUser.update((val) { final all = controller.userList.map((e) => e.checkId); val?.assignAll(all); }); }), width: 32), const LineChartTitle(title: Text('序号'), width: 42), const LineChartTitle(title: Text('用户名'), width: 70), const LineChartTitle(title: Text('手机号'), width: 98), const LineChartTitle(title: Text('签到时间'), width: 78), const LineChartTitle(title: Text('手环'), width: 67), const LineChartTitle(title: Text('路线'), flex: 1), const LineChartTitle(title: Text('状态'), width: 67), const LineChartTitle(title: Text('操作'), width: 67), ]; } Iterable rightUsers() { return controller.userList.indexed.map((e) { final (i, one) = e; var stateStr = ''; var stateColor = Colors.white; var optStr = '删除'; var optColor = Colors.red; VoidCallback? opt; if (one.isAllowDel) { opt = () => controller.deleteSignIn(one); } switch (one.state) { case UserState.idle: stateStr = '未分发'; stateColor = Colors.blue; break; case UserState.isStart: stateStr = '已开始'; stateColor = Colors.green; optStr = '结束'; opt = () => controller.userStopGame(one); break; case UserState.isFinish: stateStr = '已结束'; stateColor = Colors.orange; optStr = '重赛'; optColor = Colors.orange; opt = () => controller.userRestartGame(one); break; default: } var snStr = '--'; const n = 4; if (one.bandSN.length > n) { snStr = '-${one.bandSN.substring(one.bandSN.length - n)}'; } else if (one.bandSN.isNotEmpty) { snStr = one.bandSN; } return LineChartElem([ Checkbox( value: controller.selectedUser.value.contains(one.checkId), onChanged: (v) { controller.selectedUser.update((val) { if (v == true) { val?.add(one.checkId); } else { val?.remove(one.checkId); } }); }), Text('${i + 1}'), Text(one.name), Text(one.phone), Text(one.checkTime), Text(snStr), one.state == UserState.idle ? button( color: Colors.blue, onPressed: () => routeSelect(one), text: '分发') : Row(mainAxisSize: MainAxisSize.min, children: [ Expanded( child: Text( one.routeName, maxLines: 1, style: const TextStyle(overflow: TextOverflow.ellipsis), )), SizedBox( width: 32, child: one.state == UserState.hasRoute ? GestureDetector( onTap: () => routeSelect(one), child: const Icon(Icons.mode_edit_outline)) : const SizedBox()) ]), one.state == UserState.hasRoute ? button( color: Colors.green, onPressed: () => controller.userStart(one), text: '开始') : Text(stateStr, style: TextStyle(color: stateColor)), button(text: optStr, color: optColor, isOutline: true, onPressed: opt) ]); }); } Widget button( {Color? color, VoidCallback? onPressed, isOutline = false, required String text}) { return SizedBox( height: 22.78, width: 51.2, child: SmallButton( color: color, onPressed: onPressed, isOutline: isOutline, child: Text(text), )); } Future routeSelect(UserInManage user) async { final list = await controller.routeList(user); await Get.dialog(_RouteSelectDialog(list: list)); final route = controller.tmpSelectRoute; if (route != null) { await controller.routeAlloc(user, route); } } } class _RouteSelectDialog extends GetView { const _RouteSelectDialog({required this.list}); final Iterable list; @override Widget build(BuildContext context) { return AlertDialog( title: const Center( child: Text( '选择路线', style: TextStyle(fontSize: 17), )), backgroundColor: Colors.white, shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(17.78)), content: Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.center, children: [ SizedBox( width: 303.64, child: DropdownMenu( key: GlobalKey(), width: 303, hintText: '请选择路线', onSelected: (one) { controller.tmpSelectRoute = one; }, inputDecorationTheme: InputDecorationTheme( border: textBorder, isDense: true, ), dropdownMenuEntries: list .map((e) => DropdownMenuEntry(value: e, label: e.name)) .toList())), const SizedBox(height: 30), Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ SizedBox( height: 38, width: 106.67, child: SmallButton( onPressed: () { Get.back(); }, color: Colors.orange, child: const Text('随机'))), SizedBox( height: 38, width: 106.67, child: SmallButton( onPressed: () { Get.back(); }, color: Colors.blue, child: const Text('确认'))), ], ) ], ), ); } } class EventTitle extends GetView { final bool selected; final EventInManage data; final VoidCallback onTap; const EventTitle( {super.key, required this.selected, required this.data, required this.onTap}); @override Widget build(BuildContext context) { var children = [ AppTitleList( title: data.name, tail: Text('${data.userList.length}'), subtitle: Text.rich(TextSpan( text: '比赛时间:${data.startAt} - ${data.endAt} ', style: const TextStyle( fontSize: 9.9, fontWeight: FontWeight.w500, color: Color(0xff818181)), children: [ TextSpan( text: data.state.toString(), style: TextStyle(color: data.state.toColor())) ])), isSelected: selected, onTap: onTap, ) ]; if (selected) { children.add(const SizedBox(height: 2)); children.add(Container( decoration: const BoxDecoration( color: Color(0xfff1f1f1), borderRadius: BorderRadius.only( bottomLeft: Radius.circular(14.22), bottomRight: Radius.circular(14.22))), padding: const EdgeInsets.all(16.3), width: 221.87, child: Column( mainAxisSize: MainAxisSize.min, children: [ Row( children: [ DarkButton( onPressed: data.isAllowDel ? () => controller.deleteEvent(data) : null, child: const Text('删除')), const Spacer(), DarkButton( color: Colors.blue, onPressed: data.isAllowEdit ? () async { final r = await showEventEditDialog( controller.mapId!, EventRegisterInfo()..name = data.name); if (r != null) { controller.eventEdit(data.id, r); } } : null, child: const Text('修改')), ], ), const SizedBox(height: 24), SizedBox.square( dimension: 128, child: PrettyQrView.data(data: data.qrCode)), const SizedBox(height: 12), const Text( '用彩图奔跑APP扫码签到', style: TextStyle(color: Colors.red, fontSize: 14.22), ) ], ), )); } return Column( mainAxisSize: MainAxisSize.min, children: children, ); } }