|
@@ -0,0 +1,470 @@
|
|
|
+import 'package:flutter/material.dart';
|
|
|
+import 'package:get_it/get_it.dart';
|
|
|
+import 'package:ustest/Services/ConsultationService.dart';
|
|
|
+import 'package:ustest/Services/UserService.dart';
|
|
|
+import 'package:flutter_datetime_picker/flutter_datetime_picker.dart';
|
|
|
+import 'package:autocomplete_textfield/autocomplete_textfield.dart';
|
|
|
+
|
|
|
+import 'ConsultationList.dart';
|
|
|
+
|
|
|
+class CustomPicker extends CommonPickerModel {
|
|
|
+ String digits(int value, int length) {
|
|
|
+ return '$value'.padLeft(length, "0");
|
|
|
+ }
|
|
|
+
|
|
|
+ CustomPicker({DateTime? currentTime, LocaleType? locale})
|
|
|
+ : super(locale: locale) {
|
|
|
+ this.currentTime = currentTime ?? DateTime.now();
|
|
|
+ this.setLeftIndex(this.currentTime.hour);
|
|
|
+ this.setMiddleIndex(this.currentTime.minute);
|
|
|
+ this.setRightIndex(this.currentTime.second);
|
|
|
+ }
|
|
|
+
|
|
|
+ @override
|
|
|
+ String? leftStringAtIndex(int index) {
|
|
|
+ if (index >= 0 && index < 24) {
|
|
|
+ return this.digits(index, 2);
|
|
|
+ } else {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @override
|
|
|
+ String? middleStringAtIndex(int index) {
|
|
|
+ if (index >= 0 && index < 60) {
|
|
|
+ return this.digits(index, 2);
|
|
|
+ } else {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @override
|
|
|
+ String? rightStringAtIndex(int index) {
|
|
|
+ if (index >= 0 && index < 60) {
|
|
|
+ return this.digits(index, 2);
|
|
|
+ } else {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @override
|
|
|
+ String leftDivider() {
|
|
|
+ return "|";
|
|
|
+ }
|
|
|
+
|
|
|
+ @override
|
|
|
+ String rightDivider() {
|
|
|
+ return "|";
|
|
|
+ }
|
|
|
+
|
|
|
+ @override
|
|
|
+ List<int> layoutProportions() {
|
|
|
+ return [1, 2, 1];
|
|
|
+ }
|
|
|
+
|
|
|
+ @override
|
|
|
+ DateTime finalTime() {
|
|
|
+ return currentTime.isUtc
|
|
|
+ ? DateTime.utc(
|
|
|
+ currentTime.year,
|
|
|
+ currentTime.month,
|
|
|
+ currentTime.day,
|
|
|
+ this.currentLeftIndex(),
|
|
|
+ this.currentMiddleIndex(),
|
|
|
+ this.currentRightIndex())
|
|
|
+ : DateTime(
|
|
|
+ currentTime.year,
|
|
|
+ currentTime.month,
|
|
|
+ currentTime.day,
|
|
|
+ this.currentLeftIndex(),
|
|
|
+ this.currentMiddleIndex(),
|
|
|
+ this.currentRightIndex());
|
|
|
+ }
|
|
|
+}
|
|
|
+Consultation consultationModel=new Consultation(consultationStatus: 0, id: '', patientName: '', applyUserCode: '', expertUserCode: '');
|
|
|
+class ApprovalConsultationScreen extends StatelessWidget {
|
|
|
+ final Consultation model;
|
|
|
+ ApprovalConsultationScreen({required this.model})
|
|
|
+ {
|
|
|
+ consultationModel = model;
|
|
|
+ }
|
|
|
+
|
|
|
+ @override
|
|
|
+ Widget build(BuildContext context) {
|
|
|
+ return Scaffold(
|
|
|
+ backgroundColor: Colors.grey[200],
|
|
|
+ body: const Center(
|
|
|
+ child: SizedBox(
|
|
|
+ width: 400,
|
|
|
+ child: Card(
|
|
|
+ child: ApprovalConsultationForm(),
|
|
|
+ ),
|
|
|
+ ),
|
|
|
+ ),
|
|
|
+ );
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+class ApprovalConsultationForm extends StatefulWidget {
|
|
|
+ const ApprovalConsultationForm();
|
|
|
+ @override
|
|
|
+ _ApprovalConsultationFormState createState() => _ApprovalConsultationFormState();
|
|
|
+}
|
|
|
+
|
|
|
+class _ApprovalConsultationFormState extends State<ApprovalConsultationForm> {
|
|
|
+ final patientCodeController = TextEditingController();
|
|
|
+
|
|
|
+
|
|
|
+ List<Expert> selectedUsers = <Expert>[];
|
|
|
+ DateTime time = DateTime.now();
|
|
|
+ GlobalKey<AutoCompleteTextFieldState<Expert>> exportKey =
|
|
|
+ GlobalKey<AutoCompleteTextFieldState<Expert>>();
|
|
|
+
|
|
|
+ double _formProgress = 0;
|
|
|
+
|
|
|
+ _ApprovalConsultationFormState() {
|
|
|
+ }
|
|
|
+
|
|
|
+ @override
|
|
|
+ Widget build(BuildContext context) {
|
|
|
+ return Form(
|
|
|
+ child: FutureBuilder<AppConsultationDataModel>(
|
|
|
+ future: lodaDataAsync(),
|
|
|
+ builder: (context, snapshot) {
|
|
|
+ if (snapshot.hasError) {
|
|
|
+ return const Center(
|
|
|
+ child: Text('An error has occurred!'),
|
|
|
+ );
|
|
|
+ } else if (snapshot.hasData) {
|
|
|
+ return Column(
|
|
|
+ mainAxisSize: MainAxisSize.min,
|
|
|
+ children: [
|
|
|
+ LinearProgressIndicator(value: _formProgress),
|
|
|
+ Text('Approval', style: Theme.of(context).textTheme.headline4),
|
|
|
+ Padding(
|
|
|
+ padding: const EdgeInsets.all(24.0),
|
|
|
+ child: Row(
|
|
|
+ children: [
|
|
|
+ Expanded(
|
|
|
+ child: Text(time.toString()),
|
|
|
+ ),
|
|
|
+ TextButton(
|
|
|
+ onPressed: () {
|
|
|
+ DatePicker.showDatePicker(context,
|
|
|
+ showTitleActions: true,
|
|
|
+ minTime: DateTime(2022, 3, 5),
|
|
|
+ maxTime: DateTime(2024, 6, 7),
|
|
|
+ theme: DatePickerTheme(
|
|
|
+ headerColor: Colors.orange,
|
|
|
+ backgroundColor: Colors.blue,
|
|
|
+ itemStyle: TextStyle(
|
|
|
+ color: Colors.white,
|
|
|
+ fontWeight: FontWeight.bold,
|
|
|
+ fontSize: 18),
|
|
|
+ doneStyle: TextStyle(
|
|
|
+ color: Colors.white,
|
|
|
+ fontSize: 16)), onChanged: (date) {
|
|
|
+ print('change $date in time zone ' +
|
|
|
+ date.timeZoneOffset.inHours.toString());
|
|
|
+ }, onConfirm: (date) {
|
|
|
+ print('confirm $date');
|
|
|
+ setState(() {
|
|
|
+ this.time = date;
|
|
|
+ });
|
|
|
+ },
|
|
|
+ currentTime: DateTime.now(),
|
|
|
+ locale: LocaleType.en);
|
|
|
+ },
|
|
|
+ child: Text(
|
|
|
+ 'date',
|
|
|
+ style: TextStyle(color: Colors.blue),
|
|
|
+ )),
|
|
|
+ TextButton(
|
|
|
+ onPressed: () {
|
|
|
+ DatePicker.showTimePicker(context,
|
|
|
+ showTitleActions: true, onChanged: (date) {
|
|
|
+ print('change $date in time zone ' +
|
|
|
+ date.timeZoneOffset.inHours.toString());
|
|
|
+ }, onConfirm: (date) {
|
|
|
+ print('confirm $date');
|
|
|
+ setState(() {
|
|
|
+ this.time = date;
|
|
|
+ });
|
|
|
+ }, currentTime: DateTime.now());
|
|
|
+ },
|
|
|
+ child: Text(
|
|
|
+ 'time',
|
|
|
+ style: TextStyle(color: Colors.blue),
|
|
|
+ )),
|
|
|
+ ],
|
|
|
+ ),
|
|
|
+ ),
|
|
|
+ Padding(
|
|
|
+ padding: const EdgeInsets.all(24.0),
|
|
|
+ child: DropdownButtonFormField<Expert>(
|
|
|
+
|
|
|
+ decoration: InputDecoration(
|
|
|
+ hintText: "Select some users",
|
|
|
+ suffixIcon: Icon(Icons.search)),
|
|
|
+ onChanged: (item) {
|
|
|
+ setState(() => setSelectUsers(item) );
|
|
|
+ },
|
|
|
+ key: exportKey,
|
|
|
+ items: snapshot.data!.users
|
|
|
+ .map((e) => DropdownMenuItem<Expert>(
|
|
|
+ child: Text(e.userName),
|
|
|
+ value: e,
|
|
|
+ ))
|
|
|
+ .toList(),
|
|
|
+ )),
|
|
|
+ Padding(
|
|
|
+ padding: EdgeInsets.all(8.0),
|
|
|
+ child: Row(
|
|
|
+ children: [
|
|
|
+
|
|
|
+ Text(getSelectUsers()),
|
|
|
+ ],
|
|
|
+ ),
|
|
|
+ ),
|
|
|
+ Padding(
|
|
|
+ padding: const EdgeInsets.all(8.0),
|
|
|
+ child: Row(
|
|
|
+ mainAxisAlignment: MainAxisAlignment.center,
|
|
|
+ children: [
|
|
|
+ TextButton(
|
|
|
+ style: ButtonStyle(
|
|
|
+ foregroundColor:
|
|
|
+ MaterialStateProperty.resolveWith(
|
|
|
+ (Set<MaterialState> states) {
|
|
|
+ return states.contains(MaterialState.disabled)
|
|
|
+ ? null
|
|
|
+ : Colors.white;
|
|
|
+ }),
|
|
|
+ backgroundColor:
|
|
|
+ MaterialStateProperty.resolveWith(
|
|
|
+ (Set<MaterialState> states) {
|
|
|
+ return states.contains(MaterialState.disabled)
|
|
|
+ ? null
|
|
|
+ : Colors.blue;
|
|
|
+ }),
|
|
|
+ ),
|
|
|
+ onPressed: onSubmit,
|
|
|
+ child: const Text('Submit'),
|
|
|
+ ),
|
|
|
+ Padding(
|
|
|
+ padding: const EdgeInsets.all(8.0),
|
|
|
+ child: TextButton(
|
|
|
+ style: ButtonStyle(
|
|
|
+ foregroundColor:
|
|
|
+ MaterialStateProperty.resolveWith(
|
|
|
+ (Set<MaterialState> states) {
|
|
|
+ return states.contains(MaterialState.disabled)
|
|
|
+ ? null
|
|
|
+ : Colors.white;
|
|
|
+ }),
|
|
|
+ backgroundColor:
|
|
|
+ MaterialStateProperty.resolveWith(
|
|
|
+ (Set<MaterialState> states) {
|
|
|
+ return states.contains(MaterialState.disabled)
|
|
|
+ ? null
|
|
|
+ : Colors.blue;
|
|
|
+ }),
|
|
|
+ ),
|
|
|
+ onPressed: () => {Navigator.of(context).pop()},
|
|
|
+ child: const Text('Cancel'),
|
|
|
+ ),
|
|
|
+ ),
|
|
|
+ ],
|
|
|
+ )),
|
|
|
+ ],
|
|
|
+ );
|
|
|
+ } else {
|
|
|
+ return const Center(
|
|
|
+ child: CircularProgressIndicator(),
|
|
|
+ );
|
|
|
+ }
|
|
|
+ }),
|
|
|
+ );
|
|
|
+ }
|
|
|
+
|
|
|
+ void setSelectUsers(Expert? user)
|
|
|
+ {
|
|
|
+ if(!this.selectedUsers.contains(user))
|
|
|
+ {
|
|
|
+ this.selectedUsers.add(user!);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ String getSelectUsers()
|
|
|
+ {
|
|
|
+ var str = "";
|
|
|
+ this.selectedUsers.forEach((element) {
|
|
|
+ str+=element.userName+" ";
|
|
|
+ });
|
|
|
+
|
|
|
+ return str;
|
|
|
+ }
|
|
|
+
|
|
|
+ void onSubmit() async {
|
|
|
+ try {
|
|
|
+ var userCodes =<String>[];
|
|
|
+ selectedUsers.forEach((element) {
|
|
|
+ userCodes.add(element.code);
|
|
|
+ });
|
|
|
+ ApprovalConsultationRequest _model = new ApprovalConsultationRequest(
|
|
|
+ consultationModel.id,consultationModel.expertUserCode,this.time,userCodes,"");
|
|
|
+ print(_model.toString());
|
|
|
+ var service = GetIt.instance.get<ConsultationService>();
|
|
|
+ var result = await service.ApprovalConsultationAsync(
|
|
|
+ _model);
|
|
|
+ if (result) {
|
|
|
+ Navigator.of(context).pushNamed('/');
|
|
|
+ }
|
|
|
+ } catch (e) {
|
|
|
+ print('signInAsync ex: $e');
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ Future<AppConsultationDataModel> lodaDataAsync() async {
|
|
|
+ try {
|
|
|
+ var service = GetIt.instance.get<ConsultationService>();
|
|
|
+ var model = await service.LoadDataAsync();
|
|
|
+ return model;
|
|
|
+ } catch (ex) {
|
|
|
+ print('lodaDataAsync ex' + ex.toString());
|
|
|
+ return Future.error(ex);
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+class ExportInfo {
|
|
|
+ final String id;
|
|
|
+ final String name;
|
|
|
+
|
|
|
+ ExportInfo({required this.id, required this.name});
|
|
|
+
|
|
|
+ factory ExportInfo.fromJson(Map<String, dynamic> json) {
|
|
|
+ var item = ExportInfo(
|
|
|
+ id: json['id'] as String,
|
|
|
+ name: json['name'] as String,
|
|
|
+ );
|
|
|
+
|
|
|
+ return item;
|
|
|
+ }
|
|
|
+
|
|
|
+ Map<String, dynamic> toMap() {
|
|
|
+ return {
|
|
|
+ 'id': id,
|
|
|
+ 'name': name,
|
|
|
+ };
|
|
|
+ }
|
|
|
+
|
|
|
+ @override
|
|
|
+ String toString() {
|
|
|
+ return 'ExportInfo{id: $id}, {name: $name}';
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+enum NotificationTypeEnum {
|
|
|
+ Daiding,
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// ChatMsgNotification|1| 聊天通知
|
|
|
+ /// </summary>
|
|
|
+ ChatMsgNotification,
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// UpgradeVersionNotification|2| 版本更新通知
|
|
|
+ /// </summary>
|
|
|
+ UpgradeVersionNotification,
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// LogoffNotification|3| 登出通知
|
|
|
+ /// </summary>
|
|
|
+ LogoffNotification,
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// DisconnectNotification| 4|与服务器断开连接通知
|
|
|
+ /// </summary>
|
|
|
+ DisconnectNotification,
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// ConnectionNotification| 5| 与服务器已连接通知
|
|
|
+ /// </summary>
|
|
|
+ ConnectionNotification,
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ ///FinishNotifyRecordsMessage| 6 | 检查记录完成消息类型
|
|
|
+ /// </summary>
|
|
|
+ FinishNotifyRecordsMessage,
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ ///InvitedEnterRoomNotification| 7 | 邀请用户加入房间通知
|
|
|
+ /// </summary>
|
|
|
+ InvitedEnterRoomNotification,
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ ///CancelInvitedEnterRoomNotification| 8 |取消邀请用户通知
|
|
|
+ /// </summary>
|
|
|
+ CancelInvitedEnterRoomNotification,
|
|
|
+
|
|
|
+ placeholder9,
|
|
|
+ placeholder10,
|
|
|
+ placeholder11,
|
|
|
+ placeholder12,
|
|
|
+ placeholder13,
|
|
|
+ placeholder14,
|
|
|
+ placeholder15,
|
|
|
+ placeholder16,
|
|
|
+ placeholder17,
|
|
|
+ placeholder18,
|
|
|
+ placeholder19,
|
|
|
+ placeholder20,
|
|
|
+ placeholder21,
|
|
|
+ placeholder22,
|
|
|
+ placeholder23,
|
|
|
+ placeholder24,
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// InviteLiveConsultationNotification| 25 | 开始会诊的通知
|
|
|
+ /// </summary>
|
|
|
+ InviteLiveConsultationNotification,
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// AcceptLiveConsultationNotification| 26 | 接受会诊的通知
|
|
|
+ /// </summary>
|
|
|
+ AcceptLiveConsultationNotification,
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// RejectLiveConsultationNotification| 27 | 拒绝会诊的通知
|
|
|
+ /// </summary>
|
|
|
+ RejectLiveConsultationNotification,
|
|
|
+}
|
|
|
+
|
|
|
+class ConnectionNotification {
|
|
|
+ NotificationTypeEnum notificationType;
|
|
|
+ ConnectionNotification({
|
|
|
+ this.notificationType = NotificationTypeEnum.Daiding,
|
|
|
+ });
|
|
|
+ factory ConnectionNotification.fromJson(Map<String, dynamic> map) {
|
|
|
+ return ConnectionNotification(
|
|
|
+ notificationType: NotificationTypeEnum.values
|
|
|
+ .firstWhere((e) => e.index == map['NotificationType']),
|
|
|
+ );
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+class DisconnectNotification {
|
|
|
+ NotificationTypeEnum notificationType;
|
|
|
+ DisconnectNotification({
|
|
|
+ this.notificationType = NotificationTypeEnum.Daiding,
|
|
|
+ });
|
|
|
+ factory DisconnectNotification.fromJson(Map<String, dynamic> map) {
|
|
|
+ return DisconnectNotification(
|
|
|
+ notificationType: NotificationTypeEnum.values
|
|
|
+ .firstWhere((e) => e.index == map['NotificationType']),
|
|
|
+ );
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+class FinishNotifyRecordsMessage {}
|