import 'package:eitc_erm_app/select_department.dart'; import 'package:eitc_erm_app/utils/Component.dart'; import 'package:eitc_erm_app/utils/Constants.dart'; import 'package:eitc_erm_app/utils/DateUtils.dart'; import 'package:eitc_erm_app/utils/logger.dart'; import 'package:eitc_erm_app/widget/loading.dart'; import 'package:eitc_erm_app/widget/user_header.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:http/http.dart' as http; import 'bean/doctor_list.dart' as dcl; import 'bean/user_list.dart'; import 'confirm_registration.dart'; import 'doctor_detail.dart'; // void main() => runApp(Registration()); UserListEntity mUserListEntity = new UserListEntity(); int mWhichPatient = 0; class Registration extends StatefulWidget { Registration( {required Key key, required userListEntity, required whichPatient}) : super(key: key) { mUserListEntity = userListEntity; mWhichPatient = whichPatient; } @override State createState() => RegistrationState(); } class RegistrationState extends State { DateTime now = DateTime.now(); ValueNotifier result = ValueNotifier(null); late Future? _future = null; String searchDeptName = ""; int selectItem = -1; String selectDateStr = ""; String halfHourLater = ""; @override void initState() { super.initState(); _future = fetchData(); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text('预约挂号', style: TextStyle( color: Colors.white, )), centerTitle: true, elevation: 0.5, backgroundColor: Global.StatusBarColor, leading: IconButton( tooltip: '返回上一页', icon: const Icon( Icons.arrow_back_ios, color: Colors.white, ), onPressed: () { Navigator.of(context).pop(); //_nextPage(-1); }, ), ), body: Column(children: [ Row(children: [ GestureDetector( onTap: () { _showDatePicker(0); }, child: Container( alignment: Alignment.center, height: 50.0, width: 50, color: Global.StatusBarColor, child: const Column( mainAxisSize: MainAxisSize.min, children: [ Icon( Icons.calendar_month_outlined, size: 15, color: Colors.white, ), Text( '全部', style: TextStyle(fontSize: 12, color: Colors.white), ), ], ), )), Expanded( child: Container( height: 50.0, width: 350, color: Global.StatusBarColor, child: ListView( scrollDirection: Axis.horizontal, children: [ GestureDetector( onTap: () { setState(() { selectItem = 0; _showDatePicker(0); }); }, child: Container( alignment: Alignment.center, margin: const EdgeInsets.all(3), padding: const EdgeInsets.only(right: 5.0, left: 5.0), decoration: selectItem == 0 ? const BoxDecoration( borderRadius: BorderRadius.all(Radius.circular(10.0)), color: Colors.white) : null, child: Text( "今天\n ${LocalDateUtils.getMMDD(now, "-")} ", textAlign: TextAlign.center, style: TextStyle( fontSize: 10, color: (selectItem == 0) ? Global.StatusBarColor : Colors.white, ), ), ), ), GestureDetector( onTap: () { setState(() { _showDatePicker(1); selectItem = 1; }); }, child: Container( alignment: Alignment.center, margin: const EdgeInsets.all(3), padding: const EdgeInsets.only(right: 5.0, left: 5.0), decoration: selectItem == 1 ? const BoxDecoration( borderRadius: BorderRadius.all(Radius.circular(10.0)), color: Colors.white) : null, child: Text( "${LocalDateUtils.getWeekday(now.add(const Duration(days: 1)))}\n ${LocalDateUtils.getMMDD(now.add(const Duration(days: 1)), "-")} ", style: TextStyle( fontSize: 10, color: (selectItem == 1) ? Global.StatusBarColor : Colors.white, ), ), ), ), GestureDetector( onTap: () { setState(() { _showDatePicker(2); selectItem = 2; }); }, child: Container( alignment: Alignment.center, margin: const EdgeInsets.all(3), padding: const EdgeInsets.only(right: 5.0, left: 5.0), decoration: selectItem == 2 ? const BoxDecoration( borderRadius: BorderRadius.all(Radius.circular(10.0)), color: Colors.white) : null, child: Text( "${LocalDateUtils.getWeekday(now.add(const Duration(days: 2)))}\n ${LocalDateUtils.getMMDD(now.add(const Duration(days: 2)), "-")} ", style: TextStyle( fontSize: 10, color: (selectItem == 2) ? Global.StatusBarColor : Colors.white, ), ), ), ), GestureDetector( onTap: () { setState(() { _showDatePicker(3); selectItem = 3; }); }, child: Container( alignment: Alignment.center, margin: const EdgeInsets.all(3), padding: const EdgeInsets.only(right: 5.0, left: 5.0), decoration: selectItem == 3 ? const BoxDecoration( borderRadius: BorderRadius.all(Radius.circular(10.0)), color: Colors.white) : null, child: Text( "${LocalDateUtils.getWeekday(now.add(const Duration(days: 3)))}\n ${LocalDateUtils.getMMDD(now.add(const Duration(days: 3)), "-")} ", style: TextStyle( fontSize: 10, color: (selectItem == 3) ? Global.StatusBarColor : Colors.white, ), ), ), ), GestureDetector( onTap: () { setState(() { _showDatePicker(4); selectItem = 4; }); }, child: Container( alignment: Alignment.center, margin: const EdgeInsets.all(3), padding: const EdgeInsets.only(right: 5.0, left: 5.0), decoration: selectItem == 4 ? const BoxDecoration( borderRadius: BorderRadius.all(Radius.circular(10.0)), color: Colors.white) : null, child: Text( "${LocalDateUtils.getWeekday(now.add(const Duration(days: 4)))}\n ${LocalDateUtils.getMMDD(now.add(const Duration(days: 4)), "-")} ", style: TextStyle( fontSize: 10, color: (selectItem == 4) ? Global.StatusBarColor : Colors.white, ), ), ), ), GestureDetector( onTap: () { setState(() { _showDatePicker(5); selectItem = 5; }); }, child: Container( alignment: Alignment.center, margin: const EdgeInsets.all(3), padding: const EdgeInsets.only(right: 5.0, left: 5.0), decoration: selectItem == 5 ? const BoxDecoration( borderRadius: BorderRadius.all(Radius.circular(10.0)), color: Colors.white) : null, child: Text( "${LocalDateUtils.getWeekday(now.add(const Duration(days: 5)))}\n ${LocalDateUtils.getMMDD(now.add(const Duration(days: 5)), "-")} ", style: TextStyle( fontSize: 10, color: (selectItem == 5) ? Global.StatusBarColor : Colors.white, ), ), ), ), GestureDetector( onTap: () { setState(() { _showDatePicker(6); selectItem = 6; }); }, child: Container( alignment: Alignment.center, margin: const EdgeInsets.all(3), padding: const EdgeInsets.only(right: 5.0, left: 5.0), decoration: selectItem == 6 ? const BoxDecoration( borderRadius: BorderRadius.all(Radius.circular(10.0)), color: Colors.white) : null, child: Text( "${LocalDateUtils.getWeekday(now.add(const Duration(days: 6)))}\n ${LocalDateUtils.getMMDD(now.add(const Duration(days: 6)), "-")} ", style: TextStyle( fontSize: 10, color: (selectItem == 6) ? Global.StatusBarColor : Colors.white, ), ), ), ), // 更多的子Widget根据需要添加 ], ), ), ), ]), InkWell( onTap: () async { final result = await Navigator.push( context, MaterialPageRoute(builder: (context) => SelectDepartment()), ); setState(() { searchDeptName = result; _future = fetchData(); }); }, child: Container( width: double.infinity, alignment: Alignment.center, padding: const EdgeInsets.symmetric(vertical: 15), child: const Text( "点击查找科室", style: TextStyle(fontSize: 18, color: Colors.blue), ), ), ), const Divider( indent: 5, endIndent: 5, height: 0, ), const SizedBox( height: 5, ), Align( alignment: Alignment.centerLeft, child: Padding( padding: const EdgeInsets.only(left: 5), child: Text( "坐诊医生", style: Theme.of(context).textTheme.titleMedium, ), ), ), const SizedBox( height: 5, ), Expanded( child: FutureBuilder( future: _future, builder: (context, snapshot) { if (snapshot.hasData) { dcl.DoctorListEntity data = snapshot.data; return ListView.builder( itemCount: data.data!.length, itemBuilder: (context, index) { return _getListItem( context, index, data, data.data?[index]); }, ); } else if (snapshot.hasError) { return Text('Error: ${snapshot.error}'); } return const ColorLoader(); }, ), ), ]), ); } Widget _getListItem(BuildContext context, int index, dcl.DoctorListEntity listEntity, dcl.Data? data) { if (data == null) { return const SizedBox(); } return Container( color: Colors.white, margin: const EdgeInsets.all(5.0), child: Container( padding: const EdgeInsets.all(10.0), child: Column( mainAxisSize: MainAxisSize.min, children: [ Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ UserHeader(url: "${Global.ImageUrl}${data.avatar}"), const SizedBox( width: 5, ), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row(children: [ Expanded( child: Text.rich( TextSpan(children: [ TextSpan( text: data.nickName, style: Theme.of(context).textTheme.titleSmall), TextSpan( text: " ${data.deptName}", style: Theme.of(context).textTheme.bodySmall), ]), overflow: TextOverflow.ellipsis, ), ), OutlinedButton( style: ButtonStyle( padding: const WidgetStatePropertyAll( EdgeInsets.fromLTRB(10, 3, 10, 3)), minimumSize: const WidgetStatePropertyAll(Size.zero), side: const WidgetStatePropertyAll( BorderSide(color: Colors.blue)), tapTargetSize: MaterialTapTargetSize.shrinkWrap, shape: WidgetStatePropertyAll( RoundedRectangleBorder( borderRadius: BorderRadius.circular(5)))), child: const Text( "查看详情", style: TextStyle(fontSize: 12, color: Colors.blue), ), onPressed: () { Navigator.push( context, MaterialPageRoute( builder: (context) => DoctorDetail( doctorListEntity: listEntity, key: const Key(''), which: index)), ); }, ), ]), data.doctorBlurb == null ? const SizedBox() : Text(data.doctorBlurb!, style: Theme.of(context) .textTheme .bodySmall ?.copyWith(color: Colors.black54)), ], ), ), ], ), Column( crossAxisAlignment: CrossAxisAlignment.end, mainAxisSize: MainAxisSize.min, children: [ const Divider(), ElevatedButton( style: ButtonStyle( padding: const WidgetStatePropertyAll( EdgeInsets.fromLTRB(10, 3, 10, 3)), minimumSize: const WidgetStatePropertyAll(Size.zero), backgroundColor: const WidgetStatePropertyAll(Colors.blue), tapTargetSize: MaterialTapTargetSize.shrinkWrap, shape: WidgetStatePropertyAll(RoundedRectangleBorder( borderRadius: BorderRadius.circular(5)))), onPressed: () { logd(selectDateStr); if (selectDateStr.isEmpty) { Component.toast("请选择预约时间", 0); return; } Navigator.push( context, MaterialPageRoute( builder: (context) => ConfirmRegistration( visitTime: selectDateStr, visitTimeEnd: halfHourLater, userListEntity: mUserListEntity, whichPatient: mWhichPatient, doctorListEntity: listEntity, key: const Key(''), which: index))); }, child: const Text("挂号", style: TextStyle(color: Colors.white, fontSize: 12)), ), ], ) ], ), ), ); } void _showDatePicker(int addDay) async { /*DateTime now = DateTime.now(); DateTime late = now.add(const Duration(days: 365)); showBoardDateTimePicker( context: context, pickerType: DateTimePickerType.datetime, options: const BoardDateTimeOptions( languages: BoardPickerLanguages( today: "今天", tomorrow: "明天", now: "现在", locale: "zh"))); return;*/ DateTime dateTime = DateTime( DateTime.now().year, DateTime.now().month, DateTime.now().day + addDay, DateTime.now().minute > 30 ? DateTime.now().hour + 1 : DateTime.now().hour, DateTime.now().minute > 30 ? 0 : 30); // 默认时间 selectDateStr = dateTime.toString().replaceAll(":00.000", ""); halfHourLater = dateTime .add(const Duration(minutes: 30)) .toString() .replaceAll(":00.000", ""); // 显示对话框 await showCupertinoModalPopup( context: context, builder: (BuildContext context) { return Column( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ SizedBox(height: 500), Expanded( child: Container( alignment: Alignment.center, decoration: BoxDecoration( borderRadius: BorderRadius.only( topLeft: Radius.circular(10), topRight: Radius.circular(10)), color: Colors.white), child: Column( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Padding( padding: const EdgeInsets.fromLTRB(30, 10, 30, 0), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Material( color: Colors.grey, borderRadius: BorderRadius.circular(5), child: InkWell( onTap: () { selectDateStr = ""; Navigator.of(context).pop(); }, child: Container( height: 30, width: 50, alignment: Alignment.center, child: Text( "取消", style: TextStyle( color: Colors.white, ), )), ), ), Material( color: Colors.green, borderRadius: BorderRadius.circular(5), child: InkWell( onTap: () { _future = fetchData(); Navigator.of(context).pop(); }, child: Container( height: 30, width: 50, alignment: Alignment.center, child: const Text( "确定", style: TextStyle( color: Colors.white, ), )), ), ), ], ), ), Expanded( child: CupertinoDatePicker( mode: CupertinoDatePickerMode.dateAndTime, // 日期选择器模式 `time`,`date`,`dateAndTime`, 默认`dateAndTime` initialDateTime: DateTime( DateTime.now().year, DateTime.now().month, DateTime.now().day + addDay, DateTime.now().minute > 30 ? DateTime.now().hour + 1 : DateTime.now().hour, DateTime.now().minute > 30 ? 0 : 30), // 初始化日期 minimumDate: DateTime(2024, 07, 09), // 最小可选日期 maximumDate: DateTime(2025, 07, 22), // 最大可选日期 minimumYear: 2024, // 最小年份 maximumYear: 2025, // 最大年份 minuteInterval: 30, // 分钟间隔 initialDateTime.minute 必须可以整除 minuteInterval 必须是 60 的整数因子 use24hFormat: true, // 是否使用24小时制 dateOrder: DatePickerDateOrder.dmy, // 日期选择器排序方式 默认年/月/日 backgroundColor: Colors.white, // 选中日期变化回调 onDateTimeChanged: (dateTime) { logd(dateTime); selectDateStr = dateTime.toString().replaceAll(":00.000", ""); halfHourLater = dateTime .add(const Duration(minutes: 30)) .toString() .replaceAll(":00.000", ""); // _chooseDateTime = dateTime; }, ), ), ]), ), ), ]); }, ); } Future fetchData() async { Map headers = { 'token': Global.token, }; const timeout = Duration(seconds: 30); final response = await http .get( Uri.parse( '${Global.BaseUrl}doctor/list?deptName=$searchDeptName&selectDateStr=$selectDateStr'), headers: jsonHeaders(withToken: true)) .timeout(timeout); logd( '${Global.BaseUrl}doctor/list?deptName=$searchDeptName&selectDateStr=$selectDateStr'); if (response.statusCode == 200) { final json = decodeBodyToJson(response.bodyBytes); logd("医生列表=$json"); dcl.DoctorListEntity mDoctorListEntity = dcl.DoctorListEntity.fromJson(json); return mDoctorListEntity; } else { Component.toast("出错了,请稍后再试!", 0); } } }