6 Commits 3e5f03540e ... cb51615392

Auteur SHA1 Message Date
  gjh cb51615392 Merge branch 'master' into develop il y a 4 jours
  gjh 7bf4bca45a 照片视频选择页面 il y a 4 jours
  gjh 6d4290d01c loading和无数据widget il y a 5 jours
  gjh 936f242fc1 MaterialApp设置title,解决在某些设备的任务列表里不显示app名字的问题 il y a 5 jours
  gjh 6087631821 Merge branch 'develop' into future_照片视频选择页面 il y a 5 jours
  gjh 003f755b5c 选择历史记录页面 il y a 5 jours

+ 1 - 0
lib/app_router.dart

@@ -25,5 +25,6 @@ class AppRouter extends RootStackRouter {
25 25
         AutoRoute(page: AddPatientRoute.page),
26 26
         AutoRoute(page: PhotoPreviewRoute.page),
27 27
         AutoRoute(page: VideoPreviewRoute.page),
28
+        AutoRoute(page: SelectHistoryRoute.page),
28 29
       ];
29 30
 }

+ 183 - 117
lib/app_router.gr.dart

@@ -8,18 +8,20 @@
8 8
 // coverage:ignore-file
9 9
 
10 10
 // ignore_for_file: no_leading_underscores_for_library_prefixes
11
-import 'dart:async' as _i24;
11
+import 'dart:async' as _i25;
12 12
 
13
-import 'package:auto_route/auto_route.dart' as _i18;
14
-import 'package:eitc_erm_dental_flutter/entity/clinic_info.dart' as _i23;
13
+import 'package:auto_route/auto_route.dart' as _i19;
14
+import 'package:eitc_erm_dental_flutter/entity/clinic_info.dart' as _i24;
15 15
 import 'package:eitc_erm_dental_flutter/entity/db/local_patient_info.dart'
16
-    as _i21;
17
-import 'package:eitc_erm_dental_flutter/entity/history_item_info.dart' as _i22;
16
+    as _i22;
17
+import 'package:eitc_erm_dental_flutter/entity/history_item_info.dart' as _i23;
18 18
 import 'package:eitc_erm_dental_flutter/pages/history/history_page.dart' as _i4;
19 19
 import 'package:eitc_erm_dental_flutter/pages/history/photo_view_page.dart'
20 20
     as _i9;
21
+import 'package:eitc_erm_dental_flutter/pages/history/select_history_page.dart'
22
+    as _i10;
21 23
 import 'package:eitc_erm_dental_flutter/pages/history/video_player_page.dart'
22
-    as _i14;
24
+    as _i15;
23 25
 import 'package:eitc_erm_dental_flutter/pages/login/login_page.dart' as _i5;
24 26
 import 'package:eitc_erm_dental_flutter/pages/main/main_page.dart' as _i6;
25 27
 import 'package:eitc_erm_dental_flutter/pages/patient/add_patient_page.dart'
@@ -30,26 +32,26 @@ import 'package:eitc_erm_dental_flutter/pages/settings/delay_shot_settings_page.
30 32
     as _i2;
31 33
 import 'package:eitc_erm_dental_flutter/pages/settings/faqs_page.dart' as _i3;
32 34
 import 'package:eitc_erm_dental_flutter/pages/settings/settings_page.dart'
33
-    as _i10;
34
-import 'package:eitc_erm_dental_flutter/pages/splash/splash_page.dart' as _i11;
35
-import 'package:eitc_erm_dental_flutter/pages/upload/upload_page.dart' as _i12;
35
+    as _i11;
36
+import 'package:eitc_erm_dental_flutter/pages/splash/splash_page.dart' as _i12;
37
+import 'package:eitc_erm_dental_flutter/pages/upload/upload_page.dart' as _i13;
36 38
 import 'package:eitc_erm_dental_flutter/pages/upload/upload_select_clinic_page.dart'
37
-    as _i13;
39
+    as _i14;
38 40
 import 'package:eitc_erm_dental_flutter/pages/view/photo_preview_page.dart'
39 41
     as _i8;
40 42
 import 'package:eitc_erm_dental_flutter/pages/view/video_preview_page.dart'
41
-    as _i15;
42
-import 'package:eitc_erm_dental_flutter/pages/view/video_view_page.dart'
43 43
     as _i16;
44
-import 'package:eitc_erm_dental_flutter/pages/web/webview_page.dart' as _i17;
45
-import 'package:flutter/foundation.dart' as _i19;
46
-import 'package:flutter/material.dart' as _i20;
47
-import 'package:retrofit/dio.dart' as _i25;
44
+import 'package:eitc_erm_dental_flutter/pages/view/video_view_page.dart'
45
+    as _i17;
46
+import 'package:eitc_erm_dental_flutter/pages/web/webview_page.dart' as _i18;
47
+import 'package:flutter/foundation.dart' as _i20;
48
+import 'package:flutter/material.dart' as _i21;
49
+import 'package:retrofit/dio.dart' as _i26;
48 50
 
49 51
 /// generated route for
50 52
 /// [_i1.AddPatientPage]
51
-class AddPatientRoute extends _i18.PageRouteInfo<void> {
52
-  const AddPatientRoute({List<_i18.PageRouteInfo>? children})
53
+class AddPatientRoute extends _i19.PageRouteInfo<void> {
54
+  const AddPatientRoute({List<_i19.PageRouteInfo>? children})
53 55
       : super(
54 56
           AddPatientRoute.name,
55 57
           initialChildren: children,
@@ -57,7 +59,7 @@ class AddPatientRoute extends _i18.PageRouteInfo<void> {
57 59
 
58 60
   static const String name = 'AddPatientRoute';
59 61
 
60
-  static _i18.PageInfo page = _i18.PageInfo(
62
+  static _i19.PageInfo page = _i19.PageInfo(
61 63
     name,
62 64
     builder: (data) {
63 65
       return const _i1.AddPatientPage();
@@ -67,8 +69,8 @@ class AddPatientRoute extends _i18.PageRouteInfo<void> {
67 69
 
68 70
 /// generated route for
69 71
 /// [_i2.DelayShotSettingsPage]
70
-class DelayShotSettingsRoute extends _i18.PageRouteInfo<void> {
71
-  const DelayShotSettingsRoute({List<_i18.PageRouteInfo>? children})
72
+class DelayShotSettingsRoute extends _i19.PageRouteInfo<void> {
73
+  const DelayShotSettingsRoute({List<_i19.PageRouteInfo>? children})
72 74
       : super(
73 75
           DelayShotSettingsRoute.name,
74 76
           initialChildren: children,
@@ -76,7 +78,7 @@ class DelayShotSettingsRoute extends _i18.PageRouteInfo<void> {
76 78
 
77 79
   static const String name = 'DelayShotSettingsRoute';
78 80
 
79
-  static _i18.PageInfo page = _i18.PageInfo(
81
+  static _i19.PageInfo page = _i19.PageInfo(
80 82
     name,
81 83
     builder: (data) {
82 84
       return const _i2.DelayShotSettingsPage();
@@ -86,8 +88,8 @@ class DelayShotSettingsRoute extends _i18.PageRouteInfo<void> {
86 88
 
87 89
 /// generated route for
88 90
 /// [_i3.FaqsPage]
89
-class FaqsRoute extends _i18.PageRouteInfo<void> {
90
-  const FaqsRoute({List<_i18.PageRouteInfo>? children})
91
+class FaqsRoute extends _i19.PageRouteInfo<void> {
92
+  const FaqsRoute({List<_i19.PageRouteInfo>? children})
91 93
       : super(
92 94
           FaqsRoute.name,
93 95
           initialChildren: children,
@@ -95,7 +97,7 @@ class FaqsRoute extends _i18.PageRouteInfo<void> {
95 97
 
96 98
   static const String name = 'FaqsRoute';
97 99
 
98
-  static _i18.PageInfo page = _i18.PageInfo(
100
+  static _i19.PageInfo page = _i19.PageInfo(
99 101
     name,
100 102
     builder: (data) {
101 103
       return const _i3.FaqsPage();
@@ -105,8 +107,8 @@ class FaqsRoute extends _i18.PageRouteInfo<void> {
105 107
 
106 108
 /// generated route for
107 109
 /// [_i4.HistoryPage]
108
-class HistoryRoute extends _i18.PageRouteInfo<void> {
109
-  const HistoryRoute({List<_i18.PageRouteInfo>? children})
110
+class HistoryRoute extends _i19.PageRouteInfo<void> {
111
+  const HistoryRoute({List<_i19.PageRouteInfo>? children})
110 112
       : super(
111 113
           HistoryRoute.name,
112 114
           initialChildren: children,
@@ -114,7 +116,7 @@ class HistoryRoute extends _i18.PageRouteInfo<void> {
114 116
 
115 117
   static const String name = 'HistoryRoute';
116 118
 
117
-  static _i18.PageInfo page = _i18.PageInfo(
119
+  static _i19.PageInfo page = _i19.PageInfo(
118 120
     name,
119 121
     builder: (data) {
120 122
       return const _i4.HistoryPage();
@@ -124,11 +126,11 @@ class HistoryRoute extends _i18.PageRouteInfo<void> {
124 126
 
125 127
 /// generated route for
126 128
 /// [_i5.LoginPage]
127
-class LoginRoute extends _i18.PageRouteInfo<LoginRouteArgs> {
129
+class LoginRoute extends _i19.PageRouteInfo<LoginRouteArgs> {
128 130
   LoginRoute({
129
-    _i19.Key? key,
131
+    _i20.Key? key,
130 132
     required bool cancelable,
131
-    List<_i18.PageRouteInfo>? children,
133
+    List<_i19.PageRouteInfo>? children,
132 134
   }) : super(
133 135
           LoginRoute.name,
134 136
           args: LoginRouteArgs(
@@ -140,7 +142,7 @@ class LoginRoute extends _i18.PageRouteInfo<LoginRouteArgs> {
140 142
 
141 143
   static const String name = 'LoginRoute';
142 144
 
143
-  static _i18.PageInfo page = _i18.PageInfo(
145
+  static _i19.PageInfo page = _i19.PageInfo(
144 146
     name,
145 147
     builder: (data) {
146 148
       final args = data.argsAs<LoginRouteArgs>();
@@ -158,7 +160,7 @@ class LoginRouteArgs {
158 160
     required this.cancelable,
159 161
   });
160 162
 
161
-  final _i19.Key? key;
163
+  final _i20.Key? key;
162 164
 
163 165
   final bool cancelable;
164 166
 
@@ -170,8 +172,8 @@ class LoginRouteArgs {
170 172
 
171 173
 /// generated route for
172 174
 /// [_i6.MainPage]
173
-class MainRoute extends _i18.PageRouteInfo<void> {
174
-  const MainRoute({List<_i18.PageRouteInfo>? children})
175
+class MainRoute extends _i19.PageRouteInfo<void> {
176
+  const MainRoute({List<_i19.PageRouteInfo>? children})
175 177
       : super(
176 178
           MainRoute.name,
177 179
           initialChildren: children,
@@ -179,7 +181,7 @@ class MainRoute extends _i18.PageRouteInfo<void> {
179 181
 
180 182
   static const String name = 'MainRoute';
181 183
 
182
-  static _i18.PageInfo page = _i18.PageInfo(
184
+  static _i19.PageInfo page = _i19.PageInfo(
183 185
     name,
184 186
     builder: (data) {
185 187
       return const _i6.MainPage();
@@ -189,11 +191,11 @@ class MainRoute extends _i18.PageRouteInfo<void> {
189 191
 
190 192
 /// generated route for
191 193
 /// [_i7.PatientListPage]
192
-class PatientListRoute extends _i18.PageRouteInfo<PatientListRouteArgs> {
194
+class PatientListRoute extends _i19.PageRouteInfo<PatientListRouteArgs> {
193 195
   PatientListRoute({
194
-    _i20.Key? key,
196
+    _i21.Key? key,
195 197
     bool selectable = true,
196
-    List<_i18.PageRouteInfo>? children,
198
+    List<_i19.PageRouteInfo>? children,
197 199
   }) : super(
198 200
           PatientListRoute.name,
199 201
           args: PatientListRouteArgs(
@@ -205,7 +207,7 @@ class PatientListRoute extends _i18.PageRouteInfo<PatientListRouteArgs> {
205 207
 
206 208
   static const String name = 'PatientListRoute';
207 209
 
208
-  static _i18.PageInfo page = _i18.PageInfo(
210
+  static _i19.PageInfo page = _i19.PageInfo(
209 211
     name,
210 212
     builder: (data) {
211 213
       final args = data.argsAs<PatientListRouteArgs>(
@@ -224,7 +226,7 @@ class PatientListRouteArgs {
224 226
     this.selectable = true,
225 227
   });
226 228
 
227
-  final _i20.Key? key;
229
+  final _i21.Key? key;
228 230
 
229 231
   final bool selectable;
230 232
 
@@ -236,17 +238,17 @@ class PatientListRouteArgs {
236 238
 
237 239
 /// generated route for
238 240
 /// [_i8.PhotoPreviewPage]
239
-class PhotoPreviewRoute extends _i18.PageRouteInfo<PhotoPreviewRouteArgs> {
241
+class PhotoPreviewRoute extends _i19.PageRouteInfo<PhotoPreviewRouteArgs> {
240 242
   PhotoPreviewRoute({
241
-    _i20.Key? key,
242
-    required _i21.LocalPatientInfo info,
243
+    _i21.Key? key,
244
+    required _i22.LocalPatientInfo info,
243 245
     required String path,
244 246
     required String area,
245 247
     required DateTime time,
246 248
     required String mobile,
247 249
     required String deviceModel,
248 250
     required String wifi,
249
-    List<_i18.PageRouteInfo>? children,
251
+    List<_i19.PageRouteInfo>? children,
250 252
   }) : super(
251 253
           PhotoPreviewRoute.name,
252 254
           args: PhotoPreviewRouteArgs(
@@ -264,7 +266,7 @@ class PhotoPreviewRoute extends _i18.PageRouteInfo<PhotoPreviewRouteArgs> {
264 266
 
265 267
   static const String name = 'PhotoPreviewRoute';
266 268
 
267
-  static _i18.PageInfo page = _i18.PageInfo(
269
+  static _i19.PageInfo page = _i19.PageInfo(
268 270
     name,
269 271
     builder: (data) {
270 272
       final args = data.argsAs<PhotoPreviewRouteArgs>();
@@ -294,9 +296,9 @@ class PhotoPreviewRouteArgs {
294 296
     required this.wifi,
295 297
   });
296 298
 
297
-  final _i20.Key? key;
299
+  final _i21.Key? key;
298 300
 
299
-  final _i21.LocalPatientInfo info;
301
+  final _i22.LocalPatientInfo info;
300 302
 
301 303
   final String path;
302 304
 
@@ -318,11 +320,11 @@ class PhotoPreviewRouteArgs {
318 320
 
319 321
 /// generated route for
320 322
 /// [_i9.PhotoViewPage]
321
-class PhotoViewRoute extends _i18.PageRouteInfo<PhotoViewRouteArgs> {
323
+class PhotoViewRoute extends _i19.PageRouteInfo<PhotoViewRouteArgs> {
322 324
   PhotoViewRoute({
323
-    _i20.Key? key,
324
-    required _i22.HistoryItemInfo? info,
325
-    List<_i18.PageRouteInfo>? children,
325
+    _i21.Key? key,
326
+    required _i23.HistoryItemInfo? info,
327
+    List<_i19.PageRouteInfo>? children,
326 328
   }) : super(
327 329
           PhotoViewRoute.name,
328 330
           args: PhotoViewRouteArgs(
@@ -334,7 +336,7 @@ class PhotoViewRoute extends _i18.PageRouteInfo<PhotoViewRouteArgs> {
334 336
 
335 337
   static const String name = 'PhotoViewRoute';
336 338
 
337
-  static _i18.PageInfo page = _i18.PageInfo(
339
+  static _i19.PageInfo page = _i19.PageInfo(
338 340
     name,
339 341
     builder: (data) {
340 342
       final args = data.argsAs<PhotoViewRouteArgs>();
@@ -352,9 +354,9 @@ class PhotoViewRouteArgs {
352 354
     required this.info,
353 355
   });
354 356
 
355
-  final _i20.Key? key;
357
+  final _i21.Key? key;
356 358
 
357
-  final _i22.HistoryItemInfo? info;
359
+  final _i23.HistoryItemInfo? info;
358 360
 
359 361
   @override
360 362
   String toString() {
@@ -363,9 +365,73 @@ class PhotoViewRouteArgs {
363 365
 }
364 366
 
365 367
 /// generated route for
366
-/// [_i10.SettingsPage]
367
-class SettingsRoute extends _i18.PageRouteInfo<void> {
368
-  const SettingsRoute({List<_i18.PageRouteInfo>? children})
368
+/// [_i10.SelectHistoryPage]
369
+class SelectHistoryRoute extends _i19.PageRouteInfo<SelectHistoryRouteArgs> {
370
+  SelectHistoryRoute({
371
+    _i21.Key? key,
372
+    required _i10.SelectHistoryType selectType,
373
+    required bool isFillterPatient,
374
+    bool isMultiSelect = false,
375
+    int maxCount = 0,
376
+    List<_i19.PageRouteInfo>? children,
377
+  }) : super(
378
+          SelectHistoryRoute.name,
379
+          args: SelectHistoryRouteArgs(
380
+            key: key,
381
+            selectType: selectType,
382
+            isFillterPatient: isFillterPatient,
383
+            isMultiSelect: isMultiSelect,
384
+            maxCount: maxCount,
385
+          ),
386
+          initialChildren: children,
387
+        );
388
+
389
+  static const String name = 'SelectHistoryRoute';
390
+
391
+  static _i19.PageInfo page = _i19.PageInfo(
392
+    name,
393
+    builder: (data) {
394
+      final args = data.argsAs<SelectHistoryRouteArgs>();
395
+      return _i10.SelectHistoryPage(
396
+        key: args.key,
397
+        selectType: args.selectType,
398
+        isFillterPatient: args.isFillterPatient,
399
+        isMultiSelect: args.isMultiSelect,
400
+        maxCount: args.maxCount,
401
+      );
402
+    },
403
+  );
404
+}
405
+
406
+class SelectHistoryRouteArgs {
407
+  const SelectHistoryRouteArgs({
408
+    this.key,
409
+    required this.selectType,
410
+    required this.isFillterPatient,
411
+    this.isMultiSelect = false,
412
+    this.maxCount = 0,
413
+  });
414
+
415
+  final _i21.Key? key;
416
+
417
+  final _i10.SelectHistoryType selectType;
418
+
419
+  final bool isFillterPatient;
420
+
421
+  final bool isMultiSelect;
422
+
423
+  final int maxCount;
424
+
425
+  @override
426
+  String toString() {
427
+    return 'SelectHistoryRouteArgs{key: $key, selectType: $selectType, isFillterPatient: $isFillterPatient, isMultiSelect: $isMultiSelect, maxCount: $maxCount}';
428
+  }
429
+}
430
+
431
+/// generated route for
432
+/// [_i11.SettingsPage]
433
+class SettingsRoute extends _i19.PageRouteInfo<void> {
434
+  const SettingsRoute({List<_i19.PageRouteInfo>? children})
369 435
       : super(
370 436
           SettingsRoute.name,
371 437
           initialChildren: children,
@@ -373,18 +439,18 @@ class SettingsRoute extends _i18.PageRouteInfo<void> {
373 439
 
374 440
   static const String name = 'SettingsRoute';
375 441
 
376
-  static _i18.PageInfo page = _i18.PageInfo(
442
+  static _i19.PageInfo page = _i19.PageInfo(
377 443
     name,
378 444
     builder: (data) {
379
-      return const _i10.SettingsPage();
445
+      return const _i11.SettingsPage();
380 446
     },
381 447
   );
382 448
 }
383 449
 
384 450
 /// generated route for
385
-/// [_i11.SplashPage]
386
-class SplashRoute extends _i18.PageRouteInfo<void> {
387
-  const SplashRoute({List<_i18.PageRouteInfo>? children})
451
+/// [_i12.SplashPage]
452
+class SplashRoute extends _i19.PageRouteInfo<void> {
453
+  const SplashRoute({List<_i19.PageRouteInfo>? children})
388 454
       : super(
389 455
           SplashRoute.name,
390 456
           initialChildren: children,
@@ -392,23 +458,23 @@ class SplashRoute extends _i18.PageRouteInfo<void> {
392 458
 
393 459
   static const String name = 'SplashRoute';
394 460
 
395
-  static _i18.PageInfo page = _i18.PageInfo(
461
+  static _i19.PageInfo page = _i19.PageInfo(
396 462
     name,
397 463
     builder: (data) {
398
-      return const _i11.SplashPage();
464
+      return const _i12.SplashPage();
399 465
     },
400 466
   );
401 467
 }
402 468
 
403 469
 /// generated route for
404
-/// [_i12.UploadPage]
405
-class UploadRoute extends _i18.PageRouteInfo<UploadRouteArgs> {
470
+/// [_i13.UploadPage]
471
+class UploadRoute extends _i19.PageRouteInfo<UploadRouteArgs> {
406 472
   UploadRoute({
407
-    _i20.Key? key,
408
-    required List<_i22.HistoryItemInfo> uploadList,
409
-    required _i23.ClinicInfo clinicInfo,
473
+    _i21.Key? key,
474
+    required List<_i23.HistoryItemInfo> uploadList,
475
+    required _i24.ClinicInfo clinicInfo,
410 476
     required bool isFromView,
411
-    List<_i18.PageRouteInfo>? children,
477
+    List<_i19.PageRouteInfo>? children,
412 478
   }) : super(
413 479
           UploadRoute.name,
414 480
           args: UploadRouteArgs(
@@ -422,11 +488,11 @@ class UploadRoute extends _i18.PageRouteInfo<UploadRouteArgs> {
422 488
 
423 489
   static const String name = 'UploadRoute';
424 490
 
425
-  static _i18.PageInfo page = _i18.PageInfo(
491
+  static _i19.PageInfo page = _i19.PageInfo(
426 492
     name,
427 493
     builder: (data) {
428 494
       final args = data.argsAs<UploadRouteArgs>();
429
-      return _i12.UploadPage(
495
+      return _i13.UploadPage(
430 496
         key: args.key,
431 497
         uploadList: args.uploadList,
432 498
         clinicInfo: args.clinicInfo,
@@ -444,11 +510,11 @@ class UploadRouteArgs {
444 510
     required this.isFromView,
445 511
   });
446 512
 
447
-  final _i20.Key? key;
513
+  final _i21.Key? key;
448 514
 
449
-  final List<_i22.HistoryItemInfo> uploadList;
515
+  final List<_i23.HistoryItemInfo> uploadList;
450 516
 
451
-  final _i23.ClinicInfo clinicInfo;
517
+  final _i24.ClinicInfo clinicInfo;
452 518
 
453 519
   final bool isFromView;
454 520
 
@@ -459,14 +525,14 @@ class UploadRouteArgs {
459 525
 }
460 526
 
461 527
 /// generated route for
462
-/// [_i13.UploadSelectClinicPage]
528
+/// [_i14.UploadSelectClinicPage]
463 529
 class UploadSelectClinicRoute
464
-    extends _i18.PageRouteInfo<UploadSelectClinicRouteArgs> {
530
+    extends _i19.PageRouteInfo<UploadSelectClinicRouteArgs> {
465 531
   UploadSelectClinicRoute({
466
-    _i20.Key? key,
467
-    required List<_i22.HistoryItemInfo> uploadList,
532
+    _i21.Key? key,
533
+    required List<_i23.HistoryItemInfo> uploadList,
468 534
     required bool isFromView,
469
-    List<_i18.PageRouteInfo>? children,
535
+    List<_i19.PageRouteInfo>? children,
470 536
   }) : super(
471 537
           UploadSelectClinicRoute.name,
472 538
           args: UploadSelectClinicRouteArgs(
@@ -479,11 +545,11 @@ class UploadSelectClinicRoute
479 545
 
480 546
   static const String name = 'UploadSelectClinicRoute';
481 547
 
482
-  static _i18.PageInfo page = _i18.PageInfo(
548
+  static _i19.PageInfo page = _i19.PageInfo(
483 549
     name,
484 550
     builder: (data) {
485 551
       final args = data.argsAs<UploadSelectClinicRouteArgs>();
486
-      return _i13.UploadSelectClinicPage(
552
+      return _i14.UploadSelectClinicPage(
487 553
         key: args.key,
488 554
         uploadList: args.uploadList,
489 555
         isFromView: args.isFromView,
@@ -499,9 +565,9 @@ class UploadSelectClinicRouteArgs {
499 565
     required this.isFromView,
500 566
   });
501 567
 
502
-  final _i20.Key? key;
568
+  final _i21.Key? key;
503 569
 
504
-  final List<_i22.HistoryItemInfo> uploadList;
570
+  final List<_i23.HistoryItemInfo> uploadList;
505 571
 
506 572
   final bool isFromView;
507 573
 
@@ -512,12 +578,12 @@ class UploadSelectClinicRouteArgs {
512 578
 }
513 579
 
514 580
 /// generated route for
515
-/// [_i14.VideoPlayerPage]
516
-class VideoPlayerRoute extends _i18.PageRouteInfo<VideoPlayerRouteArgs> {
581
+/// [_i15.VideoPlayerPage]
582
+class VideoPlayerRoute extends _i19.PageRouteInfo<VideoPlayerRouteArgs> {
517 583
   VideoPlayerRoute({
518
-    _i20.Key? key,
519
-    required _i22.HistoryItemInfo? info,
520
-    List<_i18.PageRouteInfo>? children,
584
+    _i21.Key? key,
585
+    required _i23.HistoryItemInfo? info,
586
+    List<_i19.PageRouteInfo>? children,
521 587
   }) : super(
522 588
           VideoPlayerRoute.name,
523 589
           args: VideoPlayerRouteArgs(
@@ -529,11 +595,11 @@ class VideoPlayerRoute extends _i18.PageRouteInfo<VideoPlayerRouteArgs> {
529 595
 
530 596
   static const String name = 'VideoPlayerRoute';
531 597
 
532
-  static _i18.PageInfo page = _i18.PageInfo(
598
+  static _i19.PageInfo page = _i19.PageInfo(
533 599
     name,
534 600
     builder: (data) {
535 601
       final args = data.argsAs<VideoPlayerRouteArgs>();
536
-      return _i14.VideoPlayerPage(
602
+      return _i15.VideoPlayerPage(
537 603
         key: args.key,
538 604
         info: args.info,
539 605
       );
@@ -547,9 +613,9 @@ class VideoPlayerRouteArgs {
547 613
     required this.info,
548 614
   });
549 615
 
550
-  final _i20.Key? key;
616
+  final _i21.Key? key;
551 617
 
552
-  final _i22.HistoryItemInfo? info;
618
+  final _i23.HistoryItemInfo? info;
553 619
 
554 620
   @override
555 621
   String toString() {
@@ -558,18 +624,18 @@ class VideoPlayerRouteArgs {
558 624
 }
559 625
 
560 626
 /// generated route for
561
-/// [_i15.VideoPreviewPage]
562
-class VideoPreviewRoute extends _i18.PageRouteInfo<VideoPreviewRouteArgs> {
627
+/// [_i16.VideoPreviewPage]
628
+class VideoPreviewRoute extends _i19.PageRouteInfo<VideoPreviewRouteArgs> {
563 629
   VideoPreviewRoute({
564
-    _i20.Key? key,
565
-    required _i21.LocalPatientInfo info,
630
+    _i21.Key? key,
631
+    required _i22.LocalPatientInfo info,
566 632
     required String path,
567 633
     required String area,
568 634
     required DateTime time,
569 635
     required String mobile,
570 636
     required String wifi,
571 637
     required String deviceModel,
572
-    List<_i18.PageRouteInfo>? children,
638
+    List<_i19.PageRouteInfo>? children,
573 639
   }) : super(
574 640
           VideoPreviewRoute.name,
575 641
           args: VideoPreviewRouteArgs(
@@ -587,11 +653,11 @@ class VideoPreviewRoute extends _i18.PageRouteInfo<VideoPreviewRouteArgs> {
587 653
 
588 654
   static const String name = 'VideoPreviewRoute';
589 655
 
590
-  static _i18.PageInfo page = _i18.PageInfo(
656
+  static _i19.PageInfo page = _i19.PageInfo(
591 657
     name,
592 658
     builder: (data) {
593 659
       final args = data.argsAs<VideoPreviewRouteArgs>();
594
-      return _i15.VideoPreviewPage(
660
+      return _i16.VideoPreviewPage(
595 661
         key: args.key,
596 662
         info: args.info,
597 663
         path: args.path,
@@ -617,9 +683,9 @@ class VideoPreviewRouteArgs {
617 683
     required this.deviceModel,
618 684
   });
619 685
 
620
-  final _i20.Key? key;
686
+  final _i21.Key? key;
621 687
 
622
-  final _i21.LocalPatientInfo info;
688
+  final _i22.LocalPatientInfo info;
623 689
 
624 690
   final String path;
625 691
 
@@ -640,9 +706,9 @@ class VideoPreviewRouteArgs {
640 706
 }
641 707
 
642 708
 /// generated route for
643
-/// [_i16.VideoViewPage]
644
-class VideoViewRoute extends _i18.PageRouteInfo<void> {
645
-  const VideoViewRoute({List<_i18.PageRouteInfo>? children})
709
+/// [_i17.VideoViewPage]
710
+class VideoViewRoute extends _i19.PageRouteInfo<void> {
711
+  const VideoViewRoute({List<_i19.PageRouteInfo>? children})
646 712
       : super(
647 713
           VideoViewRoute.name,
648 714
           initialChildren: children,
@@ -650,23 +716,23 @@ class VideoViewRoute extends _i18.PageRouteInfo<void> {
650 716
 
651 717
   static const String name = 'VideoViewRoute';
652 718
 
653
-  static _i18.PageInfo page = _i18.PageInfo(
719
+  static _i19.PageInfo page = _i19.PageInfo(
654 720
     name,
655 721
     builder: (data) {
656
-      return const _i16.VideoViewPage();
722
+      return const _i17.VideoViewPage();
657 723
     },
658 724
   );
659 725
 }
660 726
 
661 727
 /// generated route for
662
-/// [_i17.WebviewPage]
663
-class WebviewRoute extends _i18.PageRouteInfo<WebviewRouteArgs> {
728
+/// [_i18.WebviewPage]
729
+class WebviewRoute extends _i19.PageRouteInfo<WebviewRouteArgs> {
664 730
   WebviewRoute({
665
-    _i19.Key? key,
731
+    _i20.Key? key,
666 732
     required String url,
667 733
     String? title,
668
-    _i24.Future<_i25.HttpResponse<String>>? htmlFuture,
669
-    List<_i18.PageRouteInfo>? children,
734
+    _i25.Future<_i26.HttpResponse<String>>? htmlFuture,
735
+    List<_i19.PageRouteInfo>? children,
670 736
   }) : super(
671 737
           WebviewRoute.name,
672 738
           args: WebviewRouteArgs(
@@ -680,11 +746,11 @@ class WebviewRoute extends _i18.PageRouteInfo<WebviewRouteArgs> {
680 746
 
681 747
   static const String name = 'WebviewRoute';
682 748
 
683
-  static _i18.PageInfo page = _i18.PageInfo(
749
+  static _i19.PageInfo page = _i19.PageInfo(
684 750
     name,
685 751
     builder: (data) {
686 752
       final args = data.argsAs<WebviewRouteArgs>();
687
-      return _i17.WebviewPage(
753
+      return _i18.WebviewPage(
688 754
         key: args.key,
689 755
         url: args.url,
690 756
         title: args.title,
@@ -702,13 +768,13 @@ class WebviewRouteArgs {
702 768
     this.htmlFuture,
703 769
   });
704 770
 
705
-  final _i19.Key? key;
771
+  final _i20.Key? key;
706 772
 
707 773
   final String url;
708 774
 
709 775
   final String? title;
710 776
 
711
-  final _i24.Future<_i25.HttpResponse<String>>? htmlFuture;
777
+  final _i25.Future<_i26.HttpResponse<String>>? htmlFuture;
712 778
 
713 779
   @override
714 780
   String toString() {

+ 3 - 0
lib/entity/history_item_info.dart

@@ -90,4 +90,7 @@ class HistoryItemInfo {
90 90
     _isSelectMode = value;
91 91
     isSelected = false;
92 92
   }
93
+
94
+  ///文件URI,如果path为空就返回null
95
+  Uri? get fileUri => path.isEmpty ? null : Uri.file(path);
93 96
 }

+ 18 - 8
lib/generated/intl/messages_en.dart

@@ -26,15 +26,17 @@ class MessageLookup extends MessageLookupByLibrary {
26 26
 
27 27
   static String m2(selected) => "${selected} has been selected";
28 28
 
29
-  static String m3(appName) =>
29
+  static String m3(count) => "You can choose up to ${count}";
30
+
31
+  static String m4(appName) =>
30 32
       "Welcome to ${appName}!\n\nWe have formulated the User Agreement and Privacy Policy in accordance with relevant laws to help you understand how we collect, store and use your personal information. \n\nBased on your express authorization, we may call your device permissions, and you have the right to refuse or cancel the authorization, please refer to the \"Permission Description\" for specific permission acquisition";
31 33
 
32
-  static String m4(area) =>
34
+  static String m5(area) =>
33 35
       "Please photograph the oral ${area}, and the best distance is 1.5 cm";
34 36
 
35
-  static String m5(age) => "${age} years old";
37
+  static String m6(age) => "${age} years old";
36 38
 
37
-  static String m6(second) => "${second}Second";
39
+  static String m7(second) => "${second}Second";
38 40
 
39 41
   final messages = _notInlinedMessages(_notInlinedMessages);
40 42
   static Map<String, Function> _notInlinedMessages(_) => <String, Function>{
@@ -146,6 +148,7 @@ class MessageLookup extends MessageLookupByLibrary {
146 148
         "male": MessageLookupByLibrary.simpleMessage("Male"),
147 149
         "maxPatientCount": MessageLookupByLibrary.simpleMessage(
148 150
             "You\'ve already added four patients and can\'t add any more."),
151
+        "maxSelectCountXx": m3,
149 152
         "mobileColon": MessageLookupByLibrary.simpleMessage("Mobile:"),
150 153
         "mobileFormatError": MessageLookupByLibrary.simpleMessage(
151 154
             "Please enter a valid mobile phone number"),
@@ -176,7 +179,7 @@ class MessageLookup extends MessageLookupByLibrary {
176 179
             "The network is not connected"),
177 180
         "open": MessageLookupByLibrary.simpleMessage("Open"),
178 181
         "patientList": MessageLookupByLibrary.simpleMessage("Patient list"),
179
-        "permissionDescDialogContent": m3,
182
+        "permissionDescDialogContent": m4,
180 183
         "permissionDescDialogTitle": MessageLookupByLibrary.simpleMessage(
181 184
             "User Agreement and Privacy Policy Reminder"),
182 185
         "permissionDescription":
@@ -196,6 +199,8 @@ class MessageLookup extends MessageLookupByLibrary {
196 199
             MessageLookupByLibrary.simpleMessage("Please enter your real name"),
197 200
         "pleaseInputValidIdCard": MessageLookupByLibrary.simpleMessage(
198 201
             "Please enter a valid ID number"),
202
+        "pleaseSelectAtLastOne":
203
+            MessageLookupByLibrary.simpleMessage("Please select at least one"),
199 204
         "pleaseSelectPatient":
200 205
             MessageLookupByLibrary.simpleMessage("Please select a patient"),
201 206
         "pleaseSelectRelation": MessageLookupByLibrary.simpleMessage(
@@ -245,6 +250,11 @@ class MessageLookup extends MessageLookupByLibrary {
245 250
         "selectAll": MessageLookupByLibrary.simpleMessage("Select all"),
246 251
         "selectPatient":
247 252
             MessageLookupByLibrary.simpleMessage("Select the patient"),
253
+        "selectPhoto": MessageLookupByLibrary.simpleMessage("Select Photos"),
254
+        "selectPhotoAndRecord": MessageLookupByLibrary.simpleMessage(
255
+            "Select Photo & Video Recording"),
256
+        "selectRecord":
257
+            MessageLookupByLibrary.simpleMessage("Select Recording"),
248 258
         "selectToothAreaHint": MessageLookupByLibrary.simpleMessage(
249 259
             "Please select the tooth area"),
250 260
         "send": MessageLookupByLibrary.simpleMessage("Send"),
@@ -281,7 +291,7 @@ class MessageLookup extends MessageLookupByLibrary {
281 291
         "syncDataWaiting": MessageLookupByLibrary.simpleMessage(
282 292
             "Data is syncing, please wait"),
283 293
         "takePhoto": MessageLookupByLibrary.simpleMessage("Take photo"),
284
-        "takePhotoAreaHint": m4,
294
+        "takePhotoAreaHint": m5,
285 295
         "takePhotoFailed":
286 296
             MessageLookupByLibrary.simpleMessage("Failed to take a photo"),
287 297
         "takePhotoSuccess": MessageLookupByLibrary.simpleMessage(
@@ -311,7 +321,7 @@ class MessageLookup extends MessageLookupByLibrary {
311 321
         "video": MessageLookupByLibrary.simpleMessage("Video"),
312 322
         "waitingConnectDevice": MessageLookupByLibrary.simpleMessage(
313 323
             "Waiting for the device to connect"),
314
-        "xxAge": m5,
315
-        "xxSecond": m6
324
+        "xxAge": m6,
325
+        "xxSecond": m7
316 326
       };
317 327
 }

+ 16 - 8
lib/generated/intl/messages_zh.dart

@@ -26,14 +26,16 @@ class MessageLookup extends MessageLookupByLibrary {
26 26
 
27 27
   static String m2(selected) => "已选择${selected}";
28 28
 
29
-  static String m3(appName) =>
29
+  static String m3(count) => "最多可以选择${count}项";
30
+
31
+  static String m4(appName) =>
30 32
       "欢迎使用${appName}!\n\n我们根据相关法律制定了《用户协议》和《隐私政策》,帮助您了解我们如何收集、保存、使用您的个人信息,请您在同意之前仔细阅读并充分理解相关条款。\n\n基于您的明示授权,我们将可能调用您的设备权限,您有权拒绝或取消授权,具体权限获取情况详见《权限说明》";
31 33
 
32
-  static String m4(area) => "请对口腔${area}域进行拍摄,最佳拍摄距离为1.5cm";
34
+  static String m5(area) => "请对口腔${area}域进行拍摄,最佳拍摄距离为1.5cm";
33 35
 
34
-  static String m5(age) => "${age}岁";
36
+  static String m6(age) => "${age}岁";
35 37
 
36
-  static String m6(second) => "${second}秒";
38
+  static String m7(second) => "${second}秒";
37 39
 
38 40
   final messages = _notInlinedMessages(_notInlinedMessages);
39 41
   static Map<String, Function> _notInlinedMessages(_) => <String, Function>{
@@ -117,6 +119,7 @@ class MessageLookup extends MessageLookupByLibrary {
117 119
         "male": MessageLookupByLibrary.simpleMessage("男"),
118 120
         "maxPatientCount":
119 121
             MessageLookupByLibrary.simpleMessage("您已经添加了四位咨询人,无法再添加更多咨询人了。"),
122
+        "maxSelectCountXx": m3,
120 123
         "mobileColon": MessageLookupByLibrary.simpleMessage("手机号:"),
121 124
         "mobileFormatError": MessageLookupByLibrary.simpleMessage("请输入正确的手机号"),
122 125
         "mobileInputHint": MessageLookupByLibrary.simpleMessage("请输入手机号"),
@@ -140,7 +143,7 @@ class MessageLookup extends MessageLookupByLibrary {
140 143
         "notworkNotConnect": MessageLookupByLibrary.simpleMessage("网络未连接"),
141 144
         "open": MessageLookupByLibrary.simpleMessage("开启"),
142 145
         "patientList": MessageLookupByLibrary.simpleMessage("咨询人列表"),
143
-        "permissionDescDialogContent": m3,
146
+        "permissionDescDialogContent": m4,
144 147
         "permissionDescDialogTitle":
145 148
             MessageLookupByLibrary.simpleMessage("用户协议及隐私政策提示"),
146 149
         "permissionDescription": MessageLookupByLibrary.simpleMessage("权限说明"),
@@ -156,6 +159,8 @@ class MessageLookup extends MessageLookupByLibrary {
156 159
         "pleaseInputRealName": MessageLookupByLibrary.simpleMessage("请输入真实姓名"),
157 160
         "pleaseInputValidIdCard":
158 161
             MessageLookupByLibrary.simpleMessage("请输入有效的身份证号"),
162
+        "pleaseSelectAtLastOne":
163
+            MessageLookupByLibrary.simpleMessage("请至少选择一项"),
159 164
         "pleaseSelectPatient": MessageLookupByLibrary.simpleMessage("请选择咨询人"),
160 165
         "pleaseSelectRelation":
161 166
             MessageLookupByLibrary.simpleMessage("请选择与您本人关系"),
@@ -192,6 +197,9 @@ class MessageLookup extends MessageLookupByLibrary {
192 197
         "saveSuccess": MessageLookupByLibrary.simpleMessage("保存成功"),
193 198
         "selectAll": MessageLookupByLibrary.simpleMessage("全选"),
194 199
         "selectPatient": MessageLookupByLibrary.simpleMessage("选择咨询人"),
200
+        "selectPhoto": MessageLookupByLibrary.simpleMessage("选择照片"),
201
+        "selectPhotoAndRecord": MessageLookupByLibrary.simpleMessage("选择照片和录像"),
202
+        "selectRecord": MessageLookupByLibrary.simpleMessage("选择录像"),
195 203
         "selectToothAreaHint": MessageLookupByLibrary.simpleMessage("请选择牙齿区域"),
196 204
         "send": MessageLookupByLibrary.simpleMessage("发送"),
197 205
         "serverError": MessageLookupByLibrary.simpleMessage("服务器异常"),
@@ -218,7 +226,7 @@ class MessageLookup extends MessageLookupByLibrary {
218 226
         "switchPatient": MessageLookupByLibrary.simpleMessage("切换咨询人"),
219 227
         "syncDataWaiting": MessageLookupByLibrary.simpleMessage("正在同步数据,请稍候"),
220 228
         "takePhoto": MessageLookupByLibrary.simpleMessage("拍照"),
221
-        "takePhotoAreaHint": m4,
229
+        "takePhotoAreaHint": m5,
222 230
         "takePhotoFailed": MessageLookupByLibrary.simpleMessage("拍照失败"),
223 231
         "takePhotoSuccess": MessageLookupByLibrary.simpleMessage("拍照成功"),
224 232
         "tapAgainExit": MessageLookupByLibrary.simpleMessage("再次点击退出程序"),
@@ -243,7 +251,7 @@ class MessageLookup extends MessageLookupByLibrary {
243 251
         "video": MessageLookupByLibrary.simpleMessage("视频"),
244 252
         "waitingConnectDevice":
245 253
             MessageLookupByLibrary.simpleMessage("正在等待设备连接"),
246
-        "xxAge": m5,
247
-        "xxSecond": m6
254
+        "xxAge": m6,
255
+        "xxSecond": m7
248 256
       };
249 257
 }

+ 50 - 0
lib/generated/l10n.dart

@@ -1789,6 +1789,56 @@ class S {
1789 1789
       args: [],
1790 1790
     );
1791 1791
   }
1792
+
1793
+  /// `Select Photos`
1794
+  String get selectPhoto {
1795
+    return Intl.message(
1796
+      'Select Photos',
1797
+      name: 'selectPhoto',
1798
+      desc: '',
1799
+      args: [],
1800
+    );
1801
+  }
1802
+
1803
+  /// `Select Recording`
1804
+  String get selectRecord {
1805
+    return Intl.message(
1806
+      'Select Recording',
1807
+      name: 'selectRecord',
1808
+      desc: '',
1809
+      args: [],
1810
+    );
1811
+  }
1812
+
1813
+  /// `Select Photo & Video Recording`
1814
+  String get selectPhotoAndRecord {
1815
+    return Intl.message(
1816
+      'Select Photo & Video Recording',
1817
+      name: 'selectPhotoAndRecord',
1818
+      desc: '',
1819
+      args: [],
1820
+    );
1821
+  }
1822
+
1823
+  /// `You can choose up to {count}`
1824
+  String maxSelectCountXx(Object count) {
1825
+    return Intl.message(
1826
+      'You can choose up to $count',
1827
+      name: 'maxSelectCountXx',
1828
+      desc: '',
1829
+      args: [count],
1830
+    );
1831
+  }
1832
+
1833
+  /// `Please select at least one`
1834
+  String get pleaseSelectAtLastOne {
1835
+    return Intl.message(
1836
+      'Please select at least one',
1837
+      name: 'pleaseSelectAtLastOne',
1838
+      desc: '',
1839
+      args: [],
1840
+    );
1841
+  }
1792 1842
 }
1793 1843
 
1794 1844
 class AppLocalizationDelegate extends LocalizationsDelegate<S> {

+ 6 - 1
lib/l10n/intl_en.arb

@@ -172,5 +172,10 @@
172 172
   "permissionDescDialogContent": "Welcome to {appName}!\n\nWe have formulated the User Agreement and Privacy Policy in accordance with relevant laws to help you understand how we collect, store and use your personal information. \n\nBased on your express authorization, we may call your device permissions, and you have the right to refuse or cancel the authorization, please refer to the \"Permission Description\" for specific permission acquisition",
173 173
   "read": "Read",
174 174
   "agreeContinue": "Agree",
175
-  "requestLocationHint": "Since the application companion instrument uses WiFi connection, you need to judge whether you have connected to the WiFi of the instrument through the location permission, and request your location permission, please click Allow in the next pop-up window."
175
+  "requestLocationHint": "Since the application companion instrument uses WiFi connection, you need to judge whether you have connected to the WiFi of the instrument through the location permission, and request your location permission, please click Allow in the next pop-up window.",
176
+  "selectPhoto": "Select Photos",
177
+  "selectRecord": "Select Recording",
178
+  "selectPhotoAndRecord": "Select Photo & Video Recording",
179
+  "maxSelectCountXx": "You can choose up to {count}",
180
+  "pleaseSelectAtLastOne": "Please select at least one"
176 181
 }

+ 6 - 1
lib/l10n/intl_zh.arb

@@ -172,5 +172,10 @@
172 172
   "permissionDescDialogContent": "欢迎使用{appName}!\n\n我们根据相关法律制定了《用户协议》和《隐私政策》,帮助您了解我们如何收集、保存、使用您的个人信息,请您在同意之前仔细阅读并充分理解相关条款。\n\n基于您的明示授权,我们将可能调用您的设备权限,您有权拒绝或取消授权,具体权限获取情况详见《权限说明》",
173 173
   "read": "阅读",
174 174
   "agreeContinue": "同意并继续",
175
-  "requestLocationHint": "因应用配套仪器使用WiFi连接,需通过位置权限判断您是否已连接仪器WiFi,请求获取您的位置权限,请在下个弹窗中点击允许。"
175
+  "requestLocationHint": "因应用配套仪器使用WiFi连接,需通过位置权限判断您是否已连接仪器WiFi,请求获取您的位置权限,请在下个弹窗中点击允许。",
176
+  "selectPhoto": "选择照片",
177
+  "selectRecord": "选择录像",
178
+  "selectPhotoAndRecord": "选择照片和录像",
179
+  "maxSelectCountXx": "最多可以选择{count}项",
180
+  "pleaseSelectAtLastOne": "请至少选择一项"
176 181
 }

+ 4 - 0
lib/main.dart

@@ -93,6 +93,10 @@ class MyApp extends StatelessWidget {
93 93
           designSize: size,
94 94
           child: MaterialApp.router(
95 95
             //debugShowCheckedModeBanner: false,
96
+            onGenerateTitle: (ctx) => switch (appFlavor) {
97
+              flavorHst => S.of(ctx).appNameHst,
98
+              _ => S.of(ctx).appName
99
+            },
96 100
             builder: (ctx, child) {
97 101
               return botToastBuilder(ctx, child);
98 102
             },

+ 8 - 44
lib/pages/history/history_page.dart

@@ -6,6 +6,8 @@ import 'package:eitc_erm_dental_flutter/entity/history_item_info.dart';
6 6
 import 'package:eitc_erm_dental_flutter/funcs.dart';
7 7
 import 'package:eitc_erm_dental_flutter/pages/history/vm/history_view_model.dart';
8 8
 import 'package:eitc_erm_dental_flutter/pages/history/widget/history_item_view.dart';
9
+import 'package:eitc_erm_dental_flutter/widget/empty_widget.dart';
10
+import 'package:eitc_erm_dental_flutter/widget/loading_widget.dart';
9 11
 import 'package:eitc_erm_dental_flutter/widget/main_button.dart';
10 12
 import 'package:flutter/material.dart';
11 13
 import 'package:flutter_riverpod/flutter_riverpod.dart';
@@ -190,57 +192,19 @@ class _HistoryPageState extends ConsumerState<HistoryPage> {
190 192
     });
191 193
   }
192 194
 
193
-  Widget _getLoading() {
194
-    return Center(
195
-      child: Row(
196
-        mainAxisSize: MainAxisSize.min,
197
-        crossAxisAlignment: CrossAxisAlignment.center,
198
-        children: [
199
-          Icon(
200
-            Icons.downloading,
201
-            size: 35.r,
202
-          ),
203
-          SizedBox(
204
-            width: 10.w,
205
-          ),
206
-          Text(
207
-            getS().loadingHistories,
208
-          )
209
-        ],
210
-      ),
211
-    );
212
-  }
213
-
214
-  Widget _getEmpty() {
215
-    return Center(
216
-      child: Row(
217
-        mainAxisSize: MainAxisSize.min,
218
-        crossAxisAlignment: CrossAxisAlignment.center,
219
-        children: [
220
-          Icon(
221
-            Icons.sentiment_dissatisfied,
222
-            size: 35.r,
223
-          ),
224
-          SizedBox(
225
-            width: 10.w,
226
-          ),
227
-          Text(
228
-            getS().noHistories,
229
-          )
230
-        ],
231
-      ),
232
-    );
233
-  }
234
-
235 195
   Widget _getListWidget(BuildContext context) {
236 196
     return Consumer(builder: (ctx, ref, _) {
237 197
       AsyncValue<HistoryListData> value = ref.watch(historyListProvider);
238 198
       int viewType = ref.watch(historyViewTypeProvider);
239 199
       return switch (value) {
240 200
         AsyncData<HistoryListData>(value: var data) => data.isEmpty
241
-            ? _getEmpty()
201
+            ? EmptyWidget(
202
+                text: getS().noHistories,
203
+              )
242 204
             : (viewType == 0 ? _getTimeList(data) : _getTypeList(ctx, data)),
243
-        _ => _getLoading()
205
+        _ => LoadingWidget(
206
+            text: getS().loadingHistories,
207
+          )
244 208
       };
245 209
     });
246 210
   }

+ 299 - 0
lib/pages/history/select_history_page.dart

@@ -0,0 +1,299 @@
1
+import 'dart:io';
2
+
3
+import 'package:auto_route/annotations.dart';
4
+import 'package:eitc_erm_dental_flutter/db_util.dart';
5
+import 'package:eitc_erm_dental_flutter/entity/db/local_patient_info.dart';
6
+import 'package:eitc_erm_dental_flutter/global.dart';
7
+import 'package:eitc_erm_dental_flutter/pages/history/vm/history_view_model.dart';
8
+import 'package:eitc_erm_dental_flutter/pages/history/widget/history_item_view.dart';
9
+import 'package:eitc_erm_dental_flutter/widget/empty_widget.dart';
10
+import 'package:eitc_erm_dental_flutter/widget/loading_widget.dart';
11
+import 'package:flutter/material.dart';
12
+import 'package:flutter_riverpod/flutter_riverpod.dart';
13
+import 'package:flutter_screenutil/flutter_screenutil.dart';
14
+
15
+import '../../entity/history_item_info.dart';
16
+import '../../funcs.dart';
17
+import '../../widget/main_button.dart';
18
+
19
+///选择历史记录类型
20
+enum SelectHistoryType {
21
+  ///照片
22
+  photo,
23
+
24
+  ///录像
25
+  record,
26
+
27
+  ///所有
28
+  all;
29
+}
30
+
31
+///历史记录选择页面
32
+@RoutePage(name: "SelectHistoryRoute")
33
+class SelectHistoryPage extends ConsumerStatefulWidget {
34
+  ///选择类型
35
+  final SelectHistoryType selectType;
36
+
37
+  ///是否过滤咨询人
38
+  final bool isFillterPatient;
39
+
40
+  ///是否多选
41
+  final bool isMultiSelect;
42
+
43
+  ///多选最大数量,0表示没有限制
44
+  final int maxCount;
45
+
46
+  const SelectHistoryPage(
47
+      {super.key,
48
+      required this.selectType,
49
+      required this.isFillterPatient,
50
+      this.isMultiSelect = false,
51
+      this.maxCount = 0});
52
+
53
+  @override
54
+  ConsumerState createState() => _SelectHistoryPageState();
55
+}
56
+
57
+class _SelectHistoryPageState extends ConsumerState<SelectHistoryPage> {
58
+  ///咨询人信息
59
+  LocalPatientInfo? _patientInfo;
60
+
61
+  ///记录数量
62
+  int _historyCount = 0;
63
+
64
+  @override
65
+  void initState() {
66
+    super.initState();
67
+    _initPatientInfo();
68
+    _initMultiSelect();
69
+  }
70
+
71
+  ///初始化咨询人信息
72
+  void _initPatientInfo() async {
73
+    if (selectedPatientId < 0) {
74
+      _patientInfo = null;
75
+    }
76
+    _patientInfo = await DbUtil.instance.getLocalPatientById(selectedPatientId);
77
+  }
78
+
79
+  ///初始化多选
80
+  void _initMultiSelect() {
81
+    ProviderSubscription<AsyncValue<HistoryListData>>? listenner;
82
+    //需要在读取到数据后,渲染完一帧才设置选择模式,否则读取不到historySelectModeProvider
83
+    listenner = ref.listenManual(historyListProvider, (_, value) {
84
+      if (value is! AsyncData<HistoryListData>) {
85
+        return;
86
+      }
87
+      listenner?.close();
88
+      WidgetsBinding.instance.addPostFrameCallback((_) {
89
+        ref
90
+            .read(historySelectModeProvider.notifier)
91
+            .setSelectMode(widget.isMultiSelect);
92
+      });
93
+    });
94
+  }
95
+
96
+  @override
97
+  Widget build(BuildContext context) {
98
+    return Scaffold(
99
+      appBar: _getAppBar(context),
100
+      body: SafeArea(
101
+          child: Padding(
102
+        padding: EdgeInsets.symmetric(horizontal: 16.w),
103
+        child: Column(
104
+          children: [
105
+            _getSelectedCount(context),
106
+            Expanded(child: _getListWidget(context)),
107
+            _getBottomButtons(context),
108
+            SizedBox(
109
+              height: 5.h,
110
+            )
111
+          ],
112
+        ),
113
+      )),
114
+    );
115
+  }
116
+
117
+  ///获取appbar
118
+  AppBar _getAppBar(BuildContext context) {
119
+    String title = switch (widget.selectType) {
120
+      SelectHistoryType.photo => getS().selectPhoto,
121
+      SelectHistoryType.record => getS().selectRecord,
122
+      SelectHistoryType.all => getS().selectPhotoAndRecord,
123
+    };
124
+
125
+    return AppBar(
126
+      centerTitle: true,
127
+      forceMaterialTransparency: true,
128
+      title: Text(title),
129
+      leading: IconButton(
130
+          onPressed: () {
131
+            Navigator.pop(context);
132
+          },
133
+          icon: Icon(
134
+              Platform.isIOS ? Icons.arrow_back_ios_new : Icons.arrow_back)),
135
+    );
136
+  }
137
+
138
+  ///获取已选择数量widget
139
+  Widget _getSelectedCount(BuildContext context) {
140
+    if (!widget.isMultiSelect) {
141
+      return SizedBox();
142
+    }
143
+    return Row(
144
+      children: [
145
+        Consumer(builder: (_, tref, __) {
146
+          int count = tref.watch(historySelectedCountProvider);
147
+          return Text(getS().hasSelectCountItem(count));
148
+        }),
149
+        SizedBox(
150
+          width: 6.w,
151
+        ),
152
+        const Spacer(),
153
+        SizedBox(
154
+            width: 25.w,
155
+            child: Consumer(builder: (_, cref, __) {
156
+              int count = cref.watch(historySelectedCountProvider);
157
+              int totalCount = 0;
158
+              HistoryListData? data = cref.read(historyListProvider).value;
159
+              if (data != null) {
160
+                totalCount = switch (widget.selectType) {
161
+                  SelectHistoryType.photo => data.photoList.length,
162
+                  SelectHistoryType.record => data.videoList.length,
163
+                  SelectHistoryType.all => data.getMergedList(false).length,
164
+                };
165
+              }
166
+              return Checkbox(
167
+                  value: totalCount > 0 && count == totalCount,
168
+                  shape: const CircleBorder(),
169
+                  onChanged: _onSelectAll);
170
+            })),
171
+        Text(getS().selectAll),
172
+        SizedBox(
173
+          width: 5.w,
174
+        ),
175
+      ],
176
+    );
177
+  }
178
+
179
+  ///获取底部按钮
180
+  Widget _getBottomButtons(BuildContext context) {
181
+    return widget.isMultiSelect
182
+        ? SizedBox(
183
+            width: double.infinity,
184
+            child: MainButton(
185
+                text: getS().confirm, onPressed: () => _onConfirm(context)),
186
+          )
187
+        : SizedBox();
188
+  }
189
+
190
+  Widget _getListWidget(BuildContext context) {
191
+    return Consumer(builder: (ctx, ref, _) {
192
+      AsyncValue<HistoryListData> value = ref.watch(historyListProvider);
193
+      return switch (value) {
194
+        AsyncData<HistoryListData>(value: var data) => data.isEmpty
195
+            ? EmptyWidget(
196
+                text: getS().noHistories,
197
+              )
198
+            : _getGridView(switch (widget.selectType) {
199
+                SelectHistoryType.photo => data.photoList,
200
+                SelectHistoryType.record => data.videoList,
201
+                SelectHistoryType.all => data.getMergedList(true)
202
+              }),
203
+        _ => LoadingWidget(
204
+            text: getS().loadingHistories,
205
+          )
206
+      };
207
+    });
208
+  }
209
+
210
+  ///获取GridView
211
+  Widget _getGridView(List<HistoryItemInfo> list,
212
+      {bool shinkWarp = false, bool scrollable = true}) {
213
+    //是否过滤咨询人
214
+    if (widget.isFillterPatient) {
215
+      if (_patientInfo == null) {
216
+        list = [];
217
+      } else {
218
+        list = list
219
+            .where((info) =>
220
+                info.prefixInfo != null &&
221
+                info.prefixInfo!.name.isNotEmpty &&
222
+                info.prefixInfo!.name == _patientInfo!.name)
223
+            .toList();
224
+      }
225
+    }
226
+
227
+    _historyCount = list.length;
228
+
229
+    return GridView.builder(
230
+      shrinkWrap: shinkWarp,
231
+      physics: scrollable
232
+          ? const ClampingScrollPhysics()
233
+          : const NeverScrollableScrollPhysics(),
234
+      gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
235
+          crossAxisCount: 2,
236
+          childAspectRatio: 164.0 / 120.0,
237
+          mainAxisSpacing: 8.r,
238
+          crossAxisSpacing: 15.r),
239
+      itemBuilder: (ctx, index) {
240
+        HistoryItemInfo item = list[index];
241
+        return GestureDetector(
242
+          child: HistoryItemView(
243
+            index: index,
244
+            name: item.name,
245
+            path: item.path,
246
+            type: item.type,
247
+          ),
248
+          onTap: () => _onTap(ctx, item),
249
+        );
250
+      },
251
+      itemCount: list.length,
252
+    );
253
+  }
254
+
255
+  ///全选
256
+  void _onSelectAll(bool? isSelect) {
257
+    if (isSelect == null || !isSelect) {
258
+      ref.read(historyListProvider.notifier).selectAll(false);
259
+    } else {
260
+      if (_historyCount <= 0) {
261
+        return;
262
+      }
263
+      if (_historyCount > widget.maxCount) {
264
+        showToast(text: getS().maxSelectCountXx(widget.maxCount));
265
+        return;
266
+      }
267
+      ref.read(historyListProvider.notifier).selectAll(true);
268
+    }
269
+  }
270
+
271
+  ///点击
272
+  void _onTap(BuildContext context, HistoryItemInfo info) {
273
+    if (widget.isMultiSelect) {
274
+      if (widget.maxCount > 0 &&
275
+          ref.read(historySelectedCountProvider) >= widget.maxCount) {
276
+        showToast(text: getS().maxSelectCountXx(widget.maxCount));
277
+        return;
278
+      }
279
+      ref.read(historyListProvider.notifier).select(info, !info.isSelected);
280
+      return;
281
+    }
282
+    _onSelected(context, [info]);
283
+  }
284
+
285
+  ///确定
286
+  void _onConfirm(BuildContext context) {
287
+    List<HistoryItemInfo> list =
288
+        ref.read(historyListProvider.notifier).getSelectedItems();
289
+    if (list.isEmpty) {
290
+      showToast(text: getS().pleaseSelectAtLastOne);
291
+      return;
292
+    }
293
+    _onSelected(context, list);
294
+  }
295
+
296
+  void _onSelected(BuildContext context, List<HistoryItemInfo> list) {
297
+    Navigator.pop(context, list);
298
+  }
299
+}

+ 1 - 1
lib/pages/history/vm/history_view_model.g.dart

@@ -186,7 +186,7 @@ final historySelectedCountProvider = AutoDisposeProvider<int>.internal(
186 186
 );
187 187
 
188 188
 typedef HistorySelectedCountRef = AutoDisposeProviderRef<int>;
189
-String _$historyListHash() => r'0658bd2360975795200912466323578419bdd50a';
189
+String _$historyListHash() => r'06fc47638ef14fffaebc2992072f4a4460aceb0f';
190 190
 
191 191
 ///历史记录列表
192 192
 ///

+ 36 - 0
lib/widget/empty_widget.dart

@@ -0,0 +1,36 @@
1
+import 'package:flutter/material.dart';
2
+import 'package:flutter_screenutil/flutter_screenutil.dart';
3
+
4
+///无数据Widget
5
+class EmptyWidget extends StatelessWidget {
6
+  final Widget? icon;
7
+  final String? text;
8
+
9
+  const EmptyWidget({super.key, this.text, this.icon});
10
+
11
+  @override
12
+  Widget build(BuildContext context) {
13
+    return Center(
14
+      child: Row(
15
+        mainAxisSize: MainAxisSize.min,
16
+        crossAxisAlignment: CrossAxisAlignment.center,
17
+        children: [
18
+          icon == null
19
+              ? Icon(
20
+                  Icons.sentiment_dissatisfied,
21
+                  size: 35.r,
22
+                )
23
+              : icon!,
24
+          SizedBox(
25
+            width: 10.w,
26
+          ),
27
+          text == null
28
+              ? SizedBox()
29
+              : Text(
30
+                  text!,
31
+                )
32
+        ],
33
+      ),
34
+    );
35
+  }
36
+}

+ 36 - 0
lib/widget/loading_widget.dart

@@ -0,0 +1,36 @@
1
+import 'package:flutter/material.dart';
2
+import 'package:flutter_screenutil/flutter_screenutil.dart';
3
+
4
+///加载Widget
5
+class LoadingWidget extends StatelessWidget {
6
+  final Widget? icon;
7
+  final String? text;
8
+
9
+  const LoadingWidget({super.key, this.text, this.icon});
10
+
11
+  @override
12
+  Widget build(BuildContext context) {
13
+    return Center(
14
+      child: Row(
15
+        mainAxisSize: MainAxisSize.min,
16
+        crossAxisAlignment: CrossAxisAlignment.center,
17
+        children: [
18
+          icon == null
19
+              ? Icon(
20
+                  Icons.downloading,
21
+                  size: 35.r,
22
+                )
23
+              : icon!,
24
+          SizedBox(
25
+            width: 10.w,
26
+          ),
27
+          text == null
28
+              ? SizedBox()
29
+              : Text(
30
+                  text!,
31
+                )
32
+        ],
33
+      ),
34
+    );
35
+  }
36
+}