|
@@ -5,6 +5,8 @@ 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");
|
|
@@ -106,173 +108,225 @@ class ApplyConsultationForm extends StatefulWidget {
|
|
|
}
|
|
|
|
|
|
class _ApplyConsultationFormState extends State<ApplyConsultationForm> {
|
|
|
- final expertCodeController = TextEditingController();
|
|
|
- final deviceCodeController = TextEditingController();
|
|
|
- final scanPositionController = TextEditingController();
|
|
|
- final timeController = TextEditingController(text: DateTime.now().toString());
|
|
|
final patientCodeController = TextEditingController();
|
|
|
|
|
|
- GlobalKey<AutoCompleteTextFieldState<String>> exportKey = GlobalKey();
|
|
|
+ Expert? selectedExpert;
|
|
|
+ Device? selectedDevice;
|
|
|
+ String? selectedOrgan;
|
|
|
+ DateTime time = DateTime.now();
|
|
|
+ GlobalKey<AutoCompleteTextFieldState<Expert>> exportKey =
|
|
|
+ GlobalKey<AutoCompleteTextFieldState<Expert>>();
|
|
|
+ GlobalKey<AutoCompleteTextFieldState<Device>> deviceKey =
|
|
|
+ GlobalKey<AutoCompleteTextFieldState<Device>>();
|
|
|
+ GlobalKey<AutoCompleteTextFieldState<String>> organKey = GlobalKey();
|
|
|
+
|
|
|
double _formProgress = 0;
|
|
|
|
|
|
+ _ApplyConsultationFormState() {}
|
|
|
+
|
|
|
@override
|
|
|
Widget build(BuildContext context) {
|
|
|
return Form(
|
|
|
- child: Column(
|
|
|
- mainAxisSize: MainAxisSize.min,
|
|
|
- children: [
|
|
|
- LinearProgressIndicator(value: _formProgress),
|
|
|
- Text('Apply', style: Theme.of(context).textTheme.headline4),
|
|
|
- Padding(
|
|
|
- padding: const EdgeInsets.all(8.0),
|
|
|
- child: FutureBuilder<List<String>>(
|
|
|
- future: fetchExperts(),
|
|
|
- builder: (context, snapshot) {
|
|
|
- if (snapshot.hasError) {
|
|
|
- return const Center(
|
|
|
- child: Text('An error has occurred!'),
|
|
|
- );
|
|
|
- } else if (snapshot.hasData) {
|
|
|
- return SimpleAutoCompleteTextField(
|
|
|
- key: exportKey,
|
|
|
- suggestions: snapshot.data!,
|
|
|
- controller: expertCodeController,
|
|
|
- decoration: const InputDecoration(hintText: 'export'),
|
|
|
- );
|
|
|
- } else {
|
|
|
- return const Center(
|
|
|
- child: CircularProgressIndicator(),
|
|
|
- );
|
|
|
- }
|
|
|
- }),
|
|
|
- ),
|
|
|
- Padding(
|
|
|
- padding: const EdgeInsets.all(8.0),
|
|
|
- child: TextFormField(
|
|
|
- controller: deviceCodeController,
|
|
|
- decoration: const InputDecoration(hintText: 'device'),
|
|
|
- ),
|
|
|
- ),
|
|
|
- Padding(
|
|
|
- padding: const EdgeInsets.all(8.0),
|
|
|
- child: TextFormField(
|
|
|
- controller: scanPositionController,
|
|
|
- decoration: const InputDecoration(hintText: 'scan position'),
|
|
|
- ),
|
|
|
- ),
|
|
|
- Padding(
|
|
|
- padding: const EdgeInsets.all(8.0),
|
|
|
- child: Row(
|
|
|
- children: [
|
|
|
- Expanded(
|
|
|
- child: TextFormField(
|
|
|
- controller: timeController,
|
|
|
- decoration: const InputDecoration(hintText: 'time'),
|
|
|
- )),
|
|
|
- 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');
|
|
|
- }, 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');
|
|
|
- }, currentTime: DateTime.now());
|
|
|
- },
|
|
|
- child: Text(
|
|
|
- 'time',
|
|
|
- style: TextStyle(color: Colors.blue),
|
|
|
- )),
|
|
|
- ],
|
|
|
- ),
|
|
|
- ),
|
|
|
- Padding(
|
|
|
- padding: const EdgeInsets.all(8.0),
|
|
|
- child: Row(
|
|
|
- mainAxisAlignment: MainAxisAlignment.center,
|
|
|
+ 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: [
|
|
|
- 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: _showWelcomeScreen,
|
|
|
- child: const Text('Submit'),
|
|
|
- ),
|
|
|
+ LinearProgressIndicator(value: _formProgress),
|
|
|
+ Text('Apply', style: Theme.of(context).textTheme.headline4),
|
|
|
+ Padding(
|
|
|
+ padding: const EdgeInsets.all(24.0),
|
|
|
+ child: DropdownButtonFormField<Expert>(
|
|
|
+ value: selectedExpert,
|
|
|
+ decoration: InputDecoration(
|
|
|
+ hintText: "Select an expert",
|
|
|
+ suffixIcon: Icon(Icons.search)),
|
|
|
+ onChanged: (item) {
|
|
|
+ setState(() => this.selectedExpert = item);
|
|
|
+ },
|
|
|
+ key: exportKey,
|
|
|
+ items: snapshot.data!.experts
|
|
|
+ .map((e) => DropdownMenuItem<Expert>(
|
|
|
+ child: Text(e.userName),
|
|
|
+ value: e,
|
|
|
+ ))
|
|
|
+ .toList(),
|
|
|
+ )),
|
|
|
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'),
|
|
|
+ child: Padding(
|
|
|
+ child: Container(
|
|
|
+ child: DropdownButtonFormField<Device>(
|
|
|
+ value: selectedDevice,
|
|
|
+ decoration: InputDecoration(
|
|
|
+ hintText: "Select a device",
|
|
|
+ suffixIcon: Icon(Icons.search)),
|
|
|
+ onChanged: (item) {
|
|
|
+ setState(() => this.selectedDevice = item);
|
|
|
+ },
|
|
|
+ key: deviceKey,
|
|
|
+ items: snapshot.data!.devices
|
|
|
+ .map((e) => DropdownMenuItem<Device>(
|
|
|
+ child: Text(e.deviceName),
|
|
|
+ value: e,
|
|
|
+ ))
|
|
|
+ .toList(),
|
|
|
+ )),
|
|
|
+ padding: EdgeInsets.all(16.0)),
|
|
|
+ ),
|
|
|
+ Padding(
|
|
|
+ padding: const EdgeInsets.all(24.0),
|
|
|
+ child: DropdownButtonFormField<String>(
|
|
|
+ key: organKey,
|
|
|
+ value: selectedOrgan,
|
|
|
+ decoration:
|
|
|
+ InputDecoration(hintText: "Select one organ"),
|
|
|
+ items: snapshot.data!.organs
|
|
|
+ .map((e) => DropdownMenuItem<String>(
|
|
|
+ child: Text(e),
|
|
|
+ value: e,
|
|
|
+ ))
|
|
|
+ .toList(),
|
|
|
+ onChanged: (value) {
|
|
|
+ selectedOrgan = value;
|
|
|
+ },
|
|
|
+ )),
|
|
|
+ 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(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 _showWelcomeScreen() async {
|
|
|
+ void onSubmit() async {
|
|
|
try {
|
|
|
ApplyConsultationRequest _model = new ApplyConsultationRequest(
|
|
|
"expertusercode", "d", "s", DateTime.now(), List.empty(), "", "");
|
|
|
- var service = GetIt.instance.get<UserService>();
|
|
|
- var userName = expertCodeController.text;
|
|
|
- var password = deviceCodeController.text;
|
|
|
- var host = scanPositionController.text;
|
|
|
- var result = await service.signInAsync(host, userName, password);
|
|
|
- if (result != null) {
|
|
|
+ var service = GetIt.instance.get<ConsultationService>();
|
|
|
+ var expertCode = selectedExpert?.code;
|
|
|
+ var deviceCode = selectedDevice?.code;
|
|
|
+ var organ = selectedOrgan;
|
|
|
+ var result = await service.ApplyConsultationAsync(
|
|
|
+ expertCode!, deviceCode!, selectedOrgan!, time);
|
|
|
+ if (result) {
|
|
|
Navigator.of(context).pushNamed('/');
|
|
|
}
|
|
|
} catch (e) {
|
|
@@ -280,7 +334,16 @@ class _ApplyConsultationFormState extends State<ApplyConsultationForm> {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- fetchExperts() {}
|
|
|
+ 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 {
|