Просмотр исходного кода

已扦样单信息修改。发布27版。

liujq 1 месяц назад
Родитель
Сommit
5c1006fc49

+ 30 - 10
lib/model/rsp/sample_task_rsp.dart

@@ -29,6 +29,7 @@ class SampleTaskItem {
29 29
   String? ypbh; // 样品编号
30 30
   String? jtpzmc; // 具体品种名称
31 31
   num? deliveryStatus; // 任务单任务状态:0是待领取,1是待扦样,2已扦样
32
+  bool get isReapSample => deliveryStatus == 2;
32 33
   num? ypdj; // 样品等级--字典获取
33 34
   String? jyzb; // 检验指标:质量/品质/食安
34 35
   String? qydq; // 扦样地区
@@ -244,7 +245,7 @@ class SampleTaskItem {
244 245
     return switch (deliveryStatus) { 0 => '待领取', 1 => '待扦样', 2 => '已扦样', _ => '' };
245 246
   }
246 247
 
247
-  Map<String, dynamic> getReqJson({int isConformity = 0}) {
248
+  Map<String, dynamic> getReqJson({int isConformity = 0, bool isChange = false}) {
248 249
     Map<String, dynamic> map = {};
249 250
     map['state'] = state;
250 251
     map['id'] = id;
@@ -287,15 +288,34 @@ class SampleTaskItem {
287 288
     map['zjdswrlx'] = zjdswrlx;
288 289
     map['jnlbdsfzjswr'] = jnlbdsfzjswr;
289 290
     map['zjswrlx'] = zjswrlx;
290
-    List<UseMedicineItem>? medicineList = codeUseMedicineList?.where((e) => e.id == null).toList();
291
-    if (medicineList != null && medicineList.isNotEmpty) {
292
-      map['codeUseMedicineList'] = medicineList.map((e) => e.toReqJson()).toList();
293
-    }
294 291
     map['dgryName'] = dgryName;
295 292
     map['tqqk'] = tqqk;
296
-    List<NonghuItem>? nonghuList = codeSamplingNonghuList?.where((e) => e.id == null).toList();
297
-    if (nonghuList != null && nonghuList.isNotEmpty) {
298
-      map['codeSamplingNonghuList'] = nonghuList.map((e) => e.toReqJson()).toList();
293
+    if(isChange){
294
+      List<UseMedicineItem>? medicineList = codeUseMedicineList;
295
+      if (medicineList != null && medicineList.isNotEmpty) {
296
+        for(UseMedicineItem item in medicineList){
297
+          item.id = null;
298
+        }
299
+        map['codeUseMedicineList'] = medicineList.map((e) => e.toReqJson()).toList();
300
+      }
301
+
302
+      List<NonghuItem>? nonghuList = codeSamplingNonghuList;
303
+      if (nonghuList != null && nonghuList.isNotEmpty) {
304
+        for(NonghuItem item in nonghuList){
305
+          item.id = null;
306
+        }
307
+        map['codeSamplingNonghuList'] = nonghuList.map((e) => e.toReqJson()).toList();
308
+      }
309
+    }else {
310
+      List<UseMedicineItem>? medicineList = codeUseMedicineList?.where((e) => e.id == null).toList();
311
+      if (medicineList != null && medicineList.isNotEmpty) {
312
+        map['codeUseMedicineList'] = medicineList.map((e) => e.toReqJson()).toList();
313
+      }
314
+
315
+      List<NonghuItem>? nonghuList = codeSamplingNonghuList?.where((e) => e.id == null).toList();
316
+      if (nonghuList != null && nonghuList.isNotEmpty) {
317
+        map['codeSamplingNonghuList'] = nonghuList.map((e) => e.toReqJson()).toList();
318
+      }
299 319
     }
300 320
     map['filePictureList'] = filePictureList;
301 321
     return map;
@@ -305,9 +325,9 @@ class SampleTaskItem {
305 325
 @JsonSerializable(converters: [NumConverter(), StringConverter()])
306 326
 class UrlItem {
307 327
   final String? name;
308
-  final String? url;
328
+  String? url;
309 329
 
310
-  const UrlItem({this.name,this.url});
330
+  UrlItem({this.name,this.url});
311 331
 
312 332
   factory UrlItem.fromJson(Map<String, dynamic> json) => _$UrlItemFromJson(json);
313 333
 

+ 9 - 0
lib/network/api.dart

@@ -56,6 +56,11 @@ abstract class Api {
56 56
   @GET('/admin-api/zj/base-file/getAppDownLoadUrl')
57 57
   Future<ApiRsp<String?>> getAppDownloadUrl();
58 58
 
59
+  /// 获取app下载地址 和 更新内容
60
+  @GET('/admin-api/zj/base-file/getAppDownLoadUrlAndName')
61
+  Future<ApiRsp<UrlItem?>> getAppDownLoadUrlAndName();
62
+
63
+
59 64
   /// 扦样任务单更新-收购
60 65
   @PUT('/admin-api/zj/code-sampling-task-details-sgjc/update')
61 66
   Future<ApiRsp<DeviationLoactionRsp?>> updateSampleTaskSgjc(@Body() Map<String, dynamic> map);
@@ -122,4 +127,8 @@ abstract class Api {
122 127
     @Query('offsetRange') double? offsetRange,
123 128
   });
124 129
 
130
+  /// 已扦样信息修改
131
+  @PUT('/admin-api/zj/code-sampling-task-details-sgjc/appSgjcUpdate')
132
+  Future<ApiRsp<bool?>> changeSampleTaskKcjc(@Body() Map<String, dynamic> map);
133
+
125 134
 }

+ 62 - 0
lib/network/api.g.dart

@@ -248,6 +248,37 @@ class _Api implements Api {
248 248
   }
249 249
 
250 250
   @override
251
+  Future<ApiRsp<UrlItem?>> getAppDownLoadUrlAndName() async {
252
+    const _extra = <String, dynamic>{};
253
+    final queryParameters = <String, dynamic>{};
254
+    final _headers = <String, dynamic>{};
255
+    final Map<String, dynamic>? _data = null;
256
+    final _result = await _dio
257
+        .fetch<Map<String, dynamic>>(_setStreamType<ApiRsp<UrlItem>>(Options(
258
+      method: 'GET',
259
+      headers: _headers,
260
+      extra: _extra,
261
+    )
262
+            .compose(
263
+              _dio.options,
264
+              '/admin-api/zj/base-file/getAppDownLoadUrlAndName',
265
+              queryParameters: queryParameters,
266
+              data: _data,
267
+            )
268
+            .copyWith(
269
+                baseUrl: _combineBaseUrls(
270
+              _dio.options.baseUrl,
271
+              baseUrl,
272
+            ))));
273
+    final value = ApiRsp<UrlItem?>.fromJson(
274
+      _result.data!,
275
+      (json) =>
276
+          json == null ? null : UrlItem.fromJson(json as Map<String, dynamic>),
277
+    );
278
+    return value;
279
+  }
280
+
281
+  @override
251 282
   Future<ApiRsp<DeviationLoactionRsp?>> updateSampleTaskSgjc(
252 283
       Map<String, dynamic> map) async {
253 284
     const _extra = <String, dynamic>{};
@@ -730,6 +761,37 @@ class _Api implements Api {
730 761
     return value;
731 762
   }
732 763
 
764
+  @override
765
+  Future<ApiRsp<bool?>> changeSampleTaskKcjc(Map<String, dynamic> map) async {
766
+    const _extra = <String, dynamic>{};
767
+    final queryParameters = <String, dynamic>{};
768
+    final _headers = <String, dynamic>{};
769
+    final _data = <String, dynamic>{};
770
+    _data.addAll(map);
771
+    final _result = await _dio
772
+        .fetch<Map<String, dynamic>>(_setStreamType<ApiRsp<bool>>(Options(
773
+      method: 'PUT',
774
+      headers: _headers,
775
+      extra: _extra,
776
+    )
777
+            .compose(
778
+              _dio.options,
779
+              '/admin-api/zj/code-sampling-task-details-sgjc/appSgjcUpdate',
780
+              queryParameters: queryParameters,
781
+              data: _data,
782
+            )
783
+            .copyWith(
784
+                baseUrl: _combineBaseUrls(
785
+              _dio.options.baseUrl,
786
+              baseUrl,
787
+            ))));
788
+    final value = ApiRsp<bool?>.fromJson(
789
+      _result.data!,
790
+      (json) => json as bool?,
791
+    );
792
+    return value;
793
+  }
794
+
733 795
   RequestOptions _setStreamType<T>(RequestOptions requestOptions) {
734 796
     if (T != dynamic &&
735 797
         !(requestOptions.responseType == ResponseType.bytes ||

+ 4 - 4
lib/network/my_api.dart

@@ -7,14 +7,14 @@ class MyApi {
7 7
   MyApi._();
8 8
 
9 9
   /// 华为 生产url
10
-  //static String productUrl = 'http://121.36.17.6:39099';
10
+  static String productUrl = 'http://121.36.17.6:9399';
11 11
 
12 12
   /// 紫光 生产正式 url
13
-  static String productUrl = 'http://101.36.160.117:39099';
13
+ // static String productUrl = 'http://101.36.160.117:39099';
14 14
 
15 15
   /// 测试url
16
-   static String testUrl = 'http://101.36.160.117:31070';
17
- // static String testUrl = 'http://223.71.72.182:9399';
16
+  // static String testUrl = 'http://101.36.160.117:31070';
17
+  static String testUrl = 'http://121.36.17.6:9398';
18 18
 
19 19
 
20 20
   static late String globalUrl;

+ 2 - 2
lib/page/login/login_page.dart

@@ -121,8 +121,8 @@ class _LoginPageState extends BaseLifecycleState<LoginPage> {
121 121
     LocationUtils.updatePrivacyAgree(true);
122 122
     LocationUtils.setApiKey(
123 123
         AppConfig.env == AppEnvironment.product
124
-            ? '2c783509376e267b24d63b21681686fa'
125
-            : '7d0c033909f84adc14a0e60a835f044f',
124
+            ? '8e72f096764c13f2b35dbd88c22d3346'
125
+            : 'a86e6903c698f11743a9120989f4b67d',
126 126
         '');
127 127
 
128 128
     /// 获取手机设备信息

+ 165 - 100
lib/page/sample_task/reap_sample_detail/reap_sample_basic_detail_page.dart

@@ -4,6 +4,7 @@ import 'dart:typed_data';
4 4
 import 'package:amap_flutter_location/amap_location_option.dart';
5 5
 import 'package:cached_network_image/cached_network_image.dart';
6 6
 import 'package:card_swiper/card_swiper.dart';
7
+import 'package:device_info_plus/device_info_plus.dart';
7 8
 import 'package:flutter/material.dart';
8 9
 import 'package:image_gallery_saver/image_gallery_saver.dart';
9 10
 import 'package:lszlgl/main.dart';
@@ -167,10 +168,12 @@ class _ReapSampleBasicDetailPageState extends BaseLifecycleState<ReapSampleBasic
167 168
           for (var name in nameList) {
168 169
             if (person.name == name) {
169 170
               person.isChose = true;
171
+              nameList.remove(name);
170 172
               break;
171 173
             }
172 174
           }
173 175
         }
176
+        otherStr = nameList.join(','); // 输入人员名字赋值
174 177
       }
175 178
     } catch (e) {
176 179
       logger.e(e);
@@ -343,14 +346,14 @@ class _ReapSampleBasicDetailPageState extends BaseLifecycleState<ReapSampleBasic
343 346
     }
344 347
     MyNavigator.showDialog(
345 348
       builder: (_) => Container(
346
-        padding: const EdgeInsets.all(16),
347
-        margin: const EdgeInsets.all(24),
349
+        padding: const EdgeInsets.all(8),
350
+        margin: const EdgeInsets.all(8),
348 351
         decoration: const BoxDecoration(
349 352
           color: Colors.white,
350
-          borderRadius: BorderRadius.all(Radius.circular(24)),
353
+          borderRadius: BorderRadius.all(Radius.circular(12)),
351 354
         ),
352 355
         child: AspectRatio(
353
-          aspectRatio: 1 / 1,
356
+          aspectRatio: 5 / 4,
354 357
           child: Swiper(
355 358
             itemCount: data!.filePictureList!.length,
356 359
             itemBuilder: (_, index) => CachedNetworkImage(
@@ -359,12 +362,29 @@ class _ReapSampleBasicDetailPageState extends BaseLifecycleState<ReapSampleBasic
359 362
               placeholder: (_, __) => const Center(child: CircularProgressIndicator()),
360 363
               errorWidget: (context, url, error) => const Center(child: Icon(Icons.error)),
361 364
             ),
362
-            viewportFraction: 0.8,
363 365
             scale: 0.9,
364 366
             fade: 0.0,
365 367
             loop: false,
366
-            pagination: const FractionPaginationBuilder(color: Colors.grey),
367
-            // control: const SwiperControl(padding: EdgeInsets.zero, size: 25),
368
+            plugins: const [
369
+              SwiperPagination(
370
+                  margin: EdgeInsets.all(0),
371
+                  alignment: Alignment.topRight,
372
+                  builder: FractionPaginationBuilder(
373
+                    activeFontSize: 24,
374
+                    fontSize: 16,
375
+                    activeColor: Color(0xFF25A6EE),
376
+                    color: Colors.black,
377
+                  )),
378
+              SwiperPagination(
379
+                alignment: Alignment.bottomCenter,
380
+                builder: DotSwiperPaginationBuilder(
381
+                  activeColor: Color(0xFF25A6EE),
382
+                  color: Color(0xFFBDBDBD),
383
+                  activeSize: 12,
384
+                  size: 8
385
+                )
386
+              )
387
+            ],
368 388
           ),
369 389
         ),
370 390
       ),
@@ -382,11 +402,11 @@ class _ReapSampleBasicDetailPageState extends BaseLifecycleState<ReapSampleBasic
382 402
     UrlItem picInfo = data!.ewmfilePictureList!.first;
383 403
     MyNavigator.showDialog(
384 404
       builder: (_) => Container(
385
-        padding: const EdgeInsets.all(16),
405
+        padding: const EdgeInsets.fromLTRB(16,16,16,24),
386 406
         margin: const EdgeInsets.all(24),
387 407
         decoration: const BoxDecoration(
388 408
           color: Colors.white,
389
-          borderRadius: BorderRadius.all(Radius.circular(24)),
409
+          borderRadius: BorderRadius.all(Radius.circular(12)),
390 410
         ),
391 411
         child: Column(
392 412
           mainAxisSize: MainAxisSize.min,
@@ -441,9 +461,15 @@ class _ReapSampleBasicDetailPageState extends BaseLifecycleState<ReapSampleBasic
441 461
             ),
442 462
             Row(
443 463
               children: [
444
-                Expanded(child: MyButton('打印', onTap: () => printPic(picInfo.name))),
464
+                Expanded(child: MyButton('打印',
465
+                    radius: 8,
466
+                    gradient: const LinearGradient(colors: [Color(0xFF3BD2E5), Color(0xFF247AF8)]),
467
+                    onTap: () => printPic(picInfo.name))),
445 468
                 const SizedBox(width: 16),
446
-                Expanded(child: MyButton('保存图片', onTap: () => savePic(picInfo.name))),
469
+                Expanded(child: MyButton('保存图片',
470
+                    radius: 8,
471
+                    gradient: const LinearGradient(colors: [Color(0xFF3BD2E5), Color(0xFF247AF8)]),
472
+                    onTap: () => savePic(picInfo.name))),
447 473
               ],
448 474
             ),
449 475
           ],
@@ -460,7 +486,12 @@ class _ReapSampleBasicDetailPageState extends BaseLifecycleState<ReapSampleBasic
460 486
   }
461 487
 
462 488
   void savePic(String? name) async {
463
-    bool res = await PermissionHandler.handleWith(Permission.storage);
489
+    final androidInfo = await DeviceInfoPlugin().androidInfo;
490
+    int sdkVersion = androidInfo.version.sdkInt;
491
+    bool res = true;
492
+    if (sdkVersion <= 32) {
493
+      res = await PermissionHandler.handleWith(Permission.storage);
494
+    }
464 495
     if (!res) {
465 496
       return ;
466 497
     }
@@ -558,7 +589,9 @@ class _ReapSampleBasicDetailPageState extends BaseLifecycleState<ReapSampleBasic
558 589
     otherpeople.value = data?.dgryName;
559 590
     // 编辑数据
560 591
     if (!isDetail) {
561
-      initLocation();
592
+      if(data?.deliveryStatus != 2){ // 已扦样,省市县不可修改
593
+        initLocation();
594
+      }
562 595
       getPersonData();
563 596
     }
564 597
   }
@@ -584,98 +617,130 @@ class _ReapSampleBasicDetailPageState extends BaseLifecycleState<ReapSampleBasic
584 617
   Widget buildList() {
585 618
     return Column(
586 619
       children: [
587
-        CardItemWidget('样品单号', rightText: data?.qyrwdh, bottomLine: true),
588
-        CardItemWidget('扦样人员', rightText: data?.name, bottomLine: true),
589
-
590
-        otherpeople.builder((v) => CardItemWidget(
591
-              '陪同人员',
592
-              rightText: v,
593
-              bottomLine: true,
594
-              onTap: isDetail ? null : showPopView,
595
-              trailing: isDetail ? null : const Icon(Icons.keyboard_arrow_down, size: 24, color: Color(0xFF01B2C8),),
596
-            )),
597
-        //
598
-        // name.builder(
599
-        //   (v) => CardWidgets.buildMenuDialog(
600
-        //     isDetail,
601
-        //     '扦样/陪同人员',
602
-        //     v,
603
-        //     personList,
604
-        //     personSelCallback,
605
-        //     multiple: true,
606
-        //     selectCountMax: 3,
607
-        //   ),
608
-        // ),
609
-        sheng.builder((v) => CardItemWidget('省份', rightText: v?.name, bottomLine: true)),
610
-        if(!isXJ)
611
-        shi.builder((v) => CardItemWidget('市/州', rightText: v?.name, bottomLine: true)),
612
-
613
-        if(isXJ)
614
-          CardWidgets.buildMenu(
615
-            isDetail,
616
-            '市/州',
617
-            xjCityList,
618
-            xjcitysel,
619
-                (_, sel) => data?.shiXzqh = sel.value,
620
+        Container(
621
+          clipBehavior: Clip.hardEdge,
622
+          decoration: const BoxDecoration(
623
+            borderRadius: BorderRadius.all(Radius.circular(8)),
620 624
           ),
621
-
622
-        qu.builder((v) => CardItemWidget('区县', rightText: v?.name, bottomLine: true)),
623
-        // xian.builder((v) => CardItemWidget('乡镇', rightText: v?.name, bottomLine: true)),
624
-        // cun.builder((v) => CardItemWidget('村', rightText: v?.name, bottomLine: true)),
625
-        CardWidgets.buildEdit(
626
-          isDetail,
627
-          ctrl: xian,
628
-          '乡镇',
629
-          data?.xiangXzqhName?.toString(),
630
-          onChanged: (value) => data?.xiangXzqhName = value.isEmpty ? null : value,
631
-        ),
632
-        CardWidgets.buildEdit(
633
-          isDetail,
634
-          ctrl: cun,
635
-          '村',
636
-          data?.cunXzqhName?.toString(),
637
-          onChanged: (value) => data?.cunXzqhName = value.isEmpty ? null : value,
638
-        ),
639
-        qyddjwd.builder(
640
-          (v) => CardItemWidget(
641
-            '扦样地点经纬度',
642
-            rightText: v,
643
-            bottomLine: true,
644
-            trailing: isDetail || v != null ? null : const MyButton('获取经纬度', alignment: null),
645
-            onTap: isDetail ? null : getLocation,
625
+          child: Column(
626
+            children: [
627
+              CardItemWidget('样品单号', rightText: data?.qyrwdh),
628
+              CardItemWidget('扦样人员', rightText: data?.name, bottomLine: true),
629
+              otherpeople.builder((v) => CardItemWidget(
630
+                '陪同人员',
631
+                rightText: v,
632
+                onTap: isDetail ? null : showPopView,
633
+                trailing: isDetail ? null : const Icon(Icons.keyboard_arrow_down, size: 24, color: Color(0xFF01B2C8),),
634
+              )),
635
+            ],
646 636
           ),
647 637
         ),
648
-        CardWidgets.buildEdit(
649
-          isDetail,
650
-          '种植面积(亩地)',
651
-          data?.zzmj?.toString(),
652
-          inputType: const TextInputType.numberWithOptions(decimal: true),
653
-          formatters: [XNumberTextInputFormatter()],
654
-          onChanged: (value) => data?.zzmj = value.isEmpty ? null : num.parse(value),
655
-        ),
656
-        CardWidgets.buildMenu(
657
-          isDetail,
658
-          '土壤地理类型',
659
-          trxxList,
660
-          trxx,
661
-          (_, sel) => data?.trdllx = sel.value,
638
+
639
+        const SizedBox(height: 12),
640
+
641
+        Container(
642
+          clipBehavior: Clip.hardEdge,
643
+          decoration: const BoxDecoration(
644
+            borderRadius: BorderRadius.all(Radius.circular(8)),
645
+          ),
646
+          child: Column(
647
+            children: [
648
+              sheng.builder((v) => CardItemWidget('省份', rightText: v?.name, bottomLine: true)),
649
+              if(!isXJ)
650
+                shi.builder((v) => CardItemWidget('市/州', rightText: v?.name, bottomLine: true)),
651
+
652
+              if(isXJ)
653
+                CardWidgets.buildMenu(
654
+                  isDetail || data?.deliveryStatus == 2,
655
+                  '市/州',
656
+                  xjCityList,
657
+                  xjcitysel,
658
+                      (_, sel) => data?.shiXzqh = sel.value,
659
+                ),
660
+
661
+              qu.builder((v) => CardItemWidget('区县', rightText: v?.name, bottomLine: true)),
662
+              CardWidgets.buildEdit(
663
+                isDetail,
664
+                ctrl: xian,
665
+                '乡镇',
666
+                data?.xiangXzqhName?.toString(),
667
+                onChanged: (value) => data?.xiangXzqhName = value.isEmpty ? null : value,
668
+              ),
669
+              CardWidgets.buildEdit(
670
+                isDetail,
671
+                ctrl: cun,
672
+                '村',
673
+                data?.cunXzqhName?.toString(),
674
+                onChanged: (value) => data?.cunXzqhName = value.isEmpty ? null : value,
675
+              ),
676
+              qyddjwd.builder(
677
+                    (v) => CardItemWidget(
678
+                  '扦样地点经纬度',
679
+                  rightText: v,
680
+                  bottomLine: true,
681
+                  trailing: isDetail || v != null ? null : const MyButton('获取经纬度', alignment: null),
682
+                  onTap: isDetail || data?.deliveryStatus == 2 ? null : getLocation,
683
+                ),
684
+              ),
685
+              CardWidgets.buildEdit(
686
+                isDetail,
687
+                '种植面积(亩地)',
688
+                data?.zzmj?.toString(),
689
+                inputType: const TextInputType.numberWithOptions(decimal: true),
690
+                formatters: [XNumberTextInputFormatter()],
691
+                onChanged: (value) => data?.zzmj = value.isEmpty ? null : num.parse(value),
692
+              ),
693
+              CardWidgets.buildMenu(
694
+                isDetail,
695
+                '土壤地理类型',
696
+                trxxList,
697
+                trxx,
698
+                    (_, sel) => data?.trdllx = sel.value,
699
+              ),
700
+            ],
701
+          ),
662 702
         ),
663
-        isDetail
664
-            ? CardItemWidget(
665
-                '电子签名',
666
-                rightText: '点击查看',
667
-                bottomLine: true,
668
-                onTap: showSignature,
669
-              )
670
-            : const SizedBox.shrink(),
671
-        isDetail
672
-            ? CardItemWidget(
673
-                '样品二维码',
674
-                rightText: '点击查看',
675
-                bottomLine: true,
676
-                onTap: showQRCode,
703
+
704
+        const SizedBox(height: 12),
705
+
706
+        Container(
707
+          clipBehavior: Clip.hardEdge,
708
+          decoration: const BoxDecoration(
709
+            borderRadius: BorderRadius.all(Radius.circular(8)),
710
+          ),
711
+          child: Column(
712
+            children: [
713
+              isDetail
714
+                  ? Stack(
715
+                alignment: Alignment.centerLeft,
716
+                    children: [
717
+                      CardItemWidget(
718
+                        '电子签名',
719
+                        rightText: '点击查看',
720
+                        bottomLine: true,
721
+                        onTap: showSignature,
722
+                      ),
723
+                      Container(width: 4,height: 4,color:const Color(0xFF01B2C8))
724
+                    ],
725
+                  )
726
+                  : const SizedBox.shrink(),
727
+              isDetail
728
+                  ? Stack(
729
+                alignment: Alignment.centerLeft,
730
+                children: [
731
+                  CardItemWidget(
732
+                    '样品二维码',
733
+                    rightText: '点击查看',
734
+                    bottomLine: true,
735
+                    onTap: showQRCode,
736
+                  ),
737
+                  Container(width: 4,height: 4,color:const Color(0xFF01B2C8))
738
+                ],
677 739
               )
678
-            : const SizedBox.shrink(),
740
+                  : const SizedBox.shrink(),
741
+            ],
742
+          ),
743
+        ),
679 744
 
680 745
         // CardWidgets.buildEdit(
681 746
         //   isDetail,

+ 7 - 7
lib/page/sample_task/reap_sample_detail/reap_sample_medicine_detail_page.dart

@@ -139,9 +139,9 @@ class _ReapSampleMedicineDetailPageState extends BaseLifecycleState<ReapSampleMe
139 139
   }
140 140
 
141 141
   Widget buildItem(int index, UseMedicineItem item) {
142
-    bool detail = item.id != null;
142
+   // bool detail = item.id != null;
143 143
     return GestureDetector(
144
-      onLongPress: detail ? null : () => onRemove(item),
144
+      onLongPress: isDetail ? null : () => onRemove(item),
145 145
       child: Container(
146 146
         clipBehavior: Clip.hardEdge,
147 147
         decoration: const BoxDecoration(
@@ -167,14 +167,14 @@ class _ReapSampleMedicineDetailPageState extends BaseLifecycleState<ReapSampleMe
167 167
                   mainAxisSize: MainAxisSize.min,
168 168
                   children: [
169 169
                     CardWidgets.buildEdit(
170
-                      detail,
170
+                      isDetail,
171 171
                       '使用农药品种',
172 172
                       item.synypz,
173 173
                       backgroundColor: null,
174 174
                       onChanged: (value) => item.synypz = value,
175 175
                     ),
176 176
                     CardWidgets.buildEdit(
177
-                      detail,
177
+                      isDetail,
178 178
                       '使用农药的数量(毫升/每亩地)',
179 179
                       item.synysl?.toString(),
180 180
                       backgroundColor: null,
@@ -185,15 +185,15 @@ class _ReapSampleMedicineDetailPageState extends BaseLifecycleState<ReapSampleMe
185 185
                     CardItemWidget(
186 186
                       '施药时间',
187 187
                       rightText: item.sysj,
188
-                      trailing: detail || item.sysj != null
188
+                      trailing: isDetail || item.sysj != null
189 189
                           ? null
190 190
                           : const Icon(Icons.keyboard_arrow_down, size: 24, color: Color(0xFF01B2C8),),
191 191
                       bottomLine: true,
192 192
                       backgroundColor: null,
193
-                      onTap: detail ? null : () => showDate(item),
193
+                      onTap: isDetail ? null : () => showDate(item),
194 194
                     ),
195 195
                     CardWidgets.buildEdit(
196
-                      detail,
196
+                      isDetail,
197 197
                       '施药方法',
198 198
                       item.syff,
199 199
                       backgroundColor: null,

+ 225 - 7
lib/page/sample_task/reap_sample_detail/reap_sample_task_page.dart

@@ -2,6 +2,8 @@ import 'dart:io';
2 2
 import 'dart:typed_data';
3 3
 
4 4
 import 'package:cached_network_image/cached_network_image.dart';
5
+import 'package:card_swiper/card_swiper.dart';
6
+import 'package:device_info_plus/device_info_plus.dart';
5 7
 import 'package:flutter/material.dart';
6 8
 import 'package:flutter_keyboard_visibility/flutter_keyboard_visibility.dart';
7 9
 import 'package:image_gallery_saver/image_gallery_saver.dart';
@@ -31,10 +33,12 @@ import '../../../widget/page_widget.dart';
31 33
 class ReapSampleTaskPageArgs {
32 34
   final bool detail;
33 35
   final num? id;
36
+  final num? deliveryStatus;
34 37
 
35 38
   ReapSampleTaskPageArgs({
36 39
     this.detail = false,
37 40
     this.id,
41
+    this.deliveryStatus,
38 42
   });
39 43
 
40 44
   @override
@@ -74,6 +78,7 @@ class _ReapSampleTaskPageState extends BaseLifecycleState<ReapSampleTaskPage> wi
74 78
   late List<Widget> pageList;
75 79
 
76 80
   ValueNotifier<int> tabIndex = ValueNotifier(0);
81
+  int signatureIndex = 0; // 重签名时用
77 82
 
78 83
   void startEdit() async {
79 84
     bool? success = await MyRouter.startReapSampleTask(args: ReapSampleTaskPageArgs(id: args.id));
@@ -93,6 +98,178 @@ class _ReapSampleTaskPageState extends BaseLifecycleState<ReapSampleTaskPage> wi
93 98
     pageCtrl.jumpToPage(tabIndex.value - 1);
94 99
   }
95 100
 
101
+  // 单个重新签名
102
+  void reSignature() async{
103
+    SampleTaskItem req = pageStatus.value.data!;
104
+    List<Uint8List?>? list = await MyRouter.startSignature(args: SignaturePageArgs(count: 1 ));
105
+    if (list == null || list.isEmpty) return;
106
+    MyNavigator.showLoading(msg: '提交中...');
107
+    // 上传图片
108
+    try {
109
+      // 字节转文件
110
+      List<File> fileList = [];
111
+      for (int i = 0; i < list.length; i++) {
112
+        fileList.add(await FileUtils.convertUint8ListToFile(list[i]!, 'signatrue_$i.png'));
113
+      }
114
+      var rspList = await Future.wait(fileList.map((file) => MyApi.get().upload(file)));
115
+      logger.d('图片url:${rspList.map((e) => e.data)}');
116
+      req.filePictureList![signatureIndex].url = rspList.first.data;
117
+      MyNavigator.dismissLoading();
118
+      MyNavigator.showToast('签名上传成功');
119
+      changeSubmit();
120
+    } catch (e) {
121
+      logger.e(e);
122
+      MyNavigator.dismissLoading();
123
+      MyNavigator.showToast('签名上传失败');
124
+      return;
125
+    }
126
+  }
127
+
128
+  // 已扦样修改信息验证
129
+  void changeSubmit() async{
130
+    // 空值判断
131
+    for (int i = 0; i < ctrlList.length; i++) {
132
+      if (!(ctrlList[i].verifyData?.call() ?? true)) {
133
+        pageCtrl.jumpToPage(i);
134
+        return;
135
+      }
136
+    }
137
+
138
+    // 处理签名  看是否有增加或删除
139
+    SampleTaskItem req = pageStatus.value.data!;
140
+    int? sCount = req.dgryName?.split(',').length;
141
+    if(sCount == null){
142
+      sCount = 1;
143
+    }else{
144
+      sCount = sCount + 1 ;
145
+    }
146
+
147
+    if(sCount == req.filePictureList!.length){ // 没有增加或删除
148
+      MyNavigator.showDialog(
149
+        tag: 'sign',
150
+        builder: (_) => Column(
151
+          mainAxisSize: MainAxisSize.min,
152
+          children: [
153
+            Container(
154
+              padding: const EdgeInsets.all(8),
155
+              margin: const EdgeInsets.all(8),
156
+              decoration: const BoxDecoration(
157
+                color: Colors.white,
158
+                borderRadius: BorderRadius.all(Radius.circular(12)),
159
+              ),
160
+              child: Stack(
161
+                alignment: Alignment.bottomCenter,
162
+                children: [
163
+                  AspectRatio(
164
+                    aspectRatio: 5 / 4,
165
+                    child: Swiper(
166
+                      itemCount: req.filePictureList!.length,
167
+                      itemBuilder: (_, index) => CachedNetworkImage(
168
+                        fit: BoxFit.contain,
169
+                        imageUrl: req.filePictureList![index].url ?? '',
170
+                        placeholder: (_, __) => const Center(child: CircularProgressIndicator()),
171
+                        errorWidget: (context, url, error) => const Center(child: Icon(Icons.error)),
172
+                      ),
173
+                      scale: 0.9,
174
+                      fade: 0.0,
175
+                      loop: false,
176
+                      index: signatureIndex,
177
+                      onIndexChanged: (index){
178
+                        signatureIndex = index;
179
+                      },
180
+                      plugins: const [
181
+                        SwiperPagination(
182
+                            margin: EdgeInsets.all(0),
183
+                            alignment: Alignment.topRight,
184
+                            builder: FractionPaginationBuilder(
185
+                              activeFontSize: 24,
186
+                              fontSize: 16,
187
+                              activeColor: Color(0xFF25A6EE),
188
+                              color: Colors.black,
189
+                            )),
190
+                      ],
191
+                    ),
192
+                  ),
193
+
194
+                  TextButton(
195
+                    style: ButtonStyle(
196
+                        backgroundColor: WidgetStateProperty.all(MyColor.c_25A6EE),
197
+                        shape: WidgetStateProperty.all(
198
+                          RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)),
199
+                        ),
200
+                        padding: WidgetStateProperty.all(const EdgeInsets.symmetric(horizontal: 26,vertical: 0))
201
+                    ),
202
+                    onPressed: () {
203
+                      MyNavigator.dismiss(tag: 'sign');
204
+                      reSignature();
205
+                    },
206
+                    child: const Text("重 签",style: TextStyle(fontSize: 14,color: Colors.white),),
207
+                  )
208
+                ],
209
+              ),
210
+            ),
211
+           const SizedBox(height: 8),
212
+            MyButton(
213
+              '提交',
214
+              fountSize: 18,
215
+              fontWeight: FontWeight.bold,
216
+              radius: 8,
217
+              margin: const EdgeInsets.symmetric(horizontal: 8),
218
+              gradient: const LinearGradient(colors: [Color(0xFF3BD2E5), Color(0xFF247AF8)]),
219
+              onTap: (){
220
+                MyNavigator.dismiss(tag: 'sign');
221
+                MyNavigator.showLoading(msg: '提交中...');
222
+                postChangeData();
223
+              },
224
+            )
225
+          ],
226
+        )
227
+      );
228
+    } else {
229
+      MyNavigator.showToast('扦样人员发生变动');
230
+      List<Uint8List?>? list = await MyRouter.startSignature(args: SignaturePageArgs(count: sCount ));
231
+      if (list == null || list.isEmpty) return;
232
+      MyNavigator.showLoading(msg: '提交中...');
233
+      // 上传图片
234
+      try {
235
+        // 字节转文件
236
+        List<File> fileList = [];
237
+        for (int i = 0; i < list.length; i++) {
238
+          fileList.add(await FileUtils.convertUint8ListToFile(list[i]!, 'signatrue_$i.png'));
239
+        }
240
+        var rspList = await Future.wait(fileList.map((file) => MyApi.get().upload(file)));
241
+        logger.d('图片url:${rspList.map((e) => e.data)}');
242
+        req.filePictureList = rspList.map((e) => UrlItem(url: e.data)).toList();
243
+
244
+        postChangeData();
245
+      } catch (e) {
246
+        logger.e(e);
247
+        MyNavigator.dismissLoading();
248
+        MyNavigator.showToast('签名上传失败');
249
+        return;
250
+      }
251
+    }
252
+  }
253
+
254
+  // 修改后的数据提交
255
+  void postChangeData() async{
256
+    SampleTaskItem req = pageStatus.value.data!;
257
+    pageStatus.value.data?.state = 2;
258
+    try {
259
+      var rsp = await MyApi.get().changeSampleTaskKcjc(req.getReqJson(isChange: true));
260
+      if (!mounted) return;
261
+      if (rsp.data ?? false) {
262
+        MyNavigator.showToast('修改成功');
263
+        MyNavigator.pop(true);
264
+      } else {
265
+        MyNavigator.showToast('修改失败');
266
+      }
267
+    } catch (e) {
268
+      logger.e(e);
269
+    }
270
+    MyNavigator.dismissLoading();
271
+  }
272
+
96 273
   void submit() async {
97 274
     // 空值判断
98 275
     for (int i = 0; i < ctrlList.length; i++) {
@@ -221,11 +398,11 @@ class _ReapSampleTaskPageState extends BaseLifecycleState<ReapSampleTaskPage> wi
221 398
     UrlItem picInfo = pageStatus.value.data!.ewmfilePictureList!.first;
222 399
     MyNavigator.showDialog(
223 400
       builder: (_) => Container(
224
-        padding: const EdgeInsets.all(16),
401
+        padding: const EdgeInsets.fromLTRB(16,16,16,24),
225 402
         margin: const EdgeInsets.all(24),
226 403
         decoration: const BoxDecoration(
227 404
           color: Colors.white,
228
-          borderRadius: BorderRadius.all(Radius.circular(24)),
405
+          borderRadius: BorderRadius.all(Radius.circular(12)),
229 406
         ),
230 407
         child: Column(
231 408
           mainAxisSize: MainAxisSize.min,
@@ -243,10 +420,34 @@ class _ReapSampleTaskPageState extends BaseLifecycleState<ReapSampleTaskPage> wi
243 420
                       placeholder: (_, __) => const Center(child: CircularProgressIndicator()),
244 421
                       errorWidget: (context, url, error) => const Center(child: Icon(Icons.error)),
245 422
                     ),
423
+                    const Row(
424
+                      mainAxisAlignment: MainAxisAlignment.spaceEvenly,
425
+                      children: [
426
+                        Row(
427
+                          children: [
428
+                            Icon(Icons.check_box_outline_blank_outlined,size: 18),
429
+                            Text('质量',textScaler: TextScaler.noScaling,style: TextStyle(fontSize: 14)),
430
+                          ],
431
+                        ),
432
+                        Row(
433
+                          children: [
434
+                            Icon(Icons.check_box_outline_blank_outlined,size: 18),
435
+                            Text('品质',textScaler: TextScaler.noScaling,style: TextStyle(fontSize: 14)),
436
+                          ],
437
+                        ),
438
+                        Row(
439
+                          children: [
440
+                            Icon(Icons.check_box_outline_blank_outlined,size: 18),
441
+                            Text('食安',textScaler: TextScaler.noScaling,style: TextStyle(fontSize: 14)),
442
+                          ],
443
+                        ),
444
+                      ],
445
+                    ),
246 446
                     Padding(
247 447
                       padding: const EdgeInsets.symmetric(vertical: 16),
248 448
                       child: Text(
249 449
                         picInfo.name ?? '',
450
+                        textScaler:TextScaler.noScaling,
250 451
                         style: const TextStyle(fontSize: 18, color: MyColor.c_333333),
251 452
                       ),
252 453
                     ),
@@ -256,9 +457,18 @@ class _ReapSampleTaskPageState extends BaseLifecycleState<ReapSampleTaskPage> wi
256 457
             ),
257 458
             Row(
258 459
               children: [
259
-                Expanded(child: MyButton('打印', onTap: () => printPic(picInfo.name))),
460
+                Expanded(child: MyButton(
461
+                    '打印',
462
+                    onTap: () => printPic(picInfo.name),
463
+                    radius: 8,
464
+                    gradient: const LinearGradient(colors: [Color(0xFF3BD2E5), Color(0xFF247AF8)]),
465
+                )),
260 466
                 const SizedBox(width: 16),
261
-                Expanded(child: MyButton('保存图片', onTap: () => savePic(picInfo.name))),
467
+                Expanded(child: MyButton('保存图片',
468
+                    onTap: () => savePic(picInfo.name),
469
+                    radius: 8,
470
+                  gradient: const LinearGradient(colors: [Color(0xFF3BD2E5), Color(0xFF247AF8)]),
471
+                )),
262 472
               ],
263 473
             ),
264 474
           ],
@@ -277,7 +487,12 @@ class _ReapSampleTaskPageState extends BaseLifecycleState<ReapSampleTaskPage> wi
277 487
   }
278 488
 
279 489
   void savePic(String? name) async {
280
-    bool res = await PermissionHandler.handleWith(Permission.storage);
490
+    final androidInfo = await DeviceInfoPlugin().androidInfo;
491
+    int sdkVersion = androidInfo.version.sdkInt;
492
+    bool res = true;
493
+    if (sdkVersion <= 32) {
494
+      res = await PermissionHandler.handleWith(Permission.storage);
495
+    }
281 496
     if (!res) {
282 497
       return ;
283 498
     }
@@ -366,7 +581,7 @@ class _ReapSampleTaskPageState extends BaseLifecycleState<ReapSampleTaskPage> wi
366 581
       dismissOnCapturedTaps: true,
367 582
       child: Column(
368 583
         children: [
369
-          myAppBar(title: args.detail ? '扦样完成详情' : '扦样任务单'),
584
+          myAppBar(title: args.detail ? '扦样完成详情' : args.deliveryStatus==2 ? '扦样单修改':'扦样任务单'),
370 585
           pageStatus.builder((v) {
371 586
             return switch (v.status) {
372 587
               DataStatus.loading => const PageLoadingWidget.loading(),
@@ -490,7 +705,10 @@ class _ReapSampleTaskPageState extends BaseLifecycleState<ReapSampleTaskPage> wi
490 705
             children: [
491 706
               Expanded(child: MyButton('上一步', onTap: previous, margin: margin)),
492 707
               Expanded(child: MyButton('查看二维码', onTap: showQRCode, margin: margin)),
493
-              Expanded(child: MyButton('提交', onTap: submit, margin: margin)),
708
+              if(args.deliveryStatus==2)
709
+                Expanded(child: MyButton('保存', onTap: changeSubmit, margin: margin))
710
+              else
711
+                Expanded(child: MyButton('提交', onTap: submit, margin: margin))
494 712
             ],
495 713
           );
496 714
         }

+ 6 - 6
lib/page/sample_task/reap_sample_detail/reap_sample_variety_detail_page.dart

@@ -327,9 +327,9 @@ class _ReapSampleVarietyDetailPageState extends BaseLifecycleState<ReapSampleVar
327 327
   }
328 328
 
329 329
   Widget buildNonghu(int index, NonghuItem item) {
330
-    bool detail = item.id != null;
330
+   // bool detail = item.id != null;
331 331
     return GestureDetector(
332
-      onLongPress: detail ? null : () => onRemove(index, item),
332
+      onLongPress: isDetail ? null : () => onRemove(index, item),
333 333
       child: Container(
334 334
         clipBehavior: Clip.hardEdge,
335 335
         decoration: const BoxDecoration(
@@ -341,7 +341,7 @@ class _ReapSampleVarietyDetailPageState extends BaseLifecycleState<ReapSampleVar
341 341
           mainAxisSize: MainAxisSize.min,
342 342
           children: [
343 343
             CardWidgets.buildEdit(
344
-              detail,
344
+              isDetail,
345 345
               '扦样数量(公斤)',
346 346
               item.qysl?.toString(),
347 347
               inputType: const TextInputType.numberWithOptions(decimal: true),
@@ -350,7 +350,7 @@ class _ReapSampleVarietyDetailPageState extends BaseLifecycleState<ReapSampleVar
350 350
               backgroundColor: null,
351 351
             ),
352 352
             CardWidgets.buildEdit(
353
-              detail,
353
+              isDetail,
354 354
               '扦样代表数量(公斤)',
355 355
               item.qydbsl?.toString(),
356 356
               inputType: const TextInputType.numberWithOptions(decimal: true),
@@ -359,14 +359,14 @@ class _ReapSampleVarietyDetailPageState extends BaseLifecycleState<ReapSampleVar
359 359
               backgroundColor: null,
360 360
             ),
361 361
             CardWidgets.buildEdit(
362
-              detail,
362
+              isDetail,
363 363
               '被调查农户或合作社',
364 364
               item.bdcnhhhzs,
365 365
               onChanged: (value) => item.bdcnhhhzs = value,
366 366
               backgroundColor: null,
367 367
             ),
368 368
             CardWidgets.buildEdit(
369
-              detail,
369
+              isDetail,
370 370
               '联系方式',
371 371
               inputType: TextInputType.number,
372 372
               item.lxfs,

+ 59 - 29
lib/page/sample_task/sample_task_list_page.dart

@@ -33,18 +33,21 @@ class SampleTaskListPage extends StatefulWidget {
33 33
   State<SampleTaskListPage> createState() => _SampleTaskListPageState();
34 34
 }
35 35
 
36
-class _SampleTaskListPageState extends BaseLifecycleState<SampleTaskListPage> with AutomaticKeepAliveClientMixin {
36
+class _SampleTaskListPageState extends BaseLifecycleState<SampleTaskListPage>
37
+    with AutomaticKeepAliveClientMixin {
37 38
   late SampleListVM vm;
38 39
 
39 40
   /// 详情
40
-  void startTaskDetail(bool detail, SampleTaskItem data) async {
41
+  void startTaskDetail(bool detail, SampleTaskItem data, {num? deliveryStatus}) async {
41 42
     bool? success;
42 43
     switch (widget.type) {
43 44
       case StepType.reap:
44
-        success = await MyRouter.startReapSampleTask(args: ReapSampleTaskPageArgs(detail: detail, id: data.id));
45
+        success = await MyRouter.startReapSampleTask(
46
+            args: ReapSampleTaskPageArgs(detail: detail, id: data.id,deliveryStatus: deliveryStatus));
45 47
         break;
46 48
       case StepType.stock:
47
-        success = await MyRouter.startStockSampleTask(args: StockSampleTaskPageArgs(detail: detail, id: data.id));
49
+        success = await MyRouter.startStockSampleTask(
50
+            args: StockSampleTaskPageArgs(detail: detail, id: data.id));
48 51
         break;
49 52
     }
50 53
     if (success ?? false) {
@@ -125,7 +128,8 @@ class _SampleTaskListPageState extends BaseLifecycleState<SampleTaskListPage> wi
125 128
       var list = v.data;
126 129
       if (v.status == DataStatus.error) {
127 130
         // 加载失败
128
-        return SliverToBoxAdapter(child: PageLoadingWidget.error(onTap: () => vm.refresh(widget.tabIndex)));
131
+        return SliverToBoxAdapter(
132
+            child: PageLoadingWidget.error(onTap: () => vm.refresh(widget.tabIndex)));
129 133
       } else if (list == null || list.isEmpty) {
130 134
         // 无数据
131 135
         return const SliverToBoxAdapter(child: PageLoadingWidget.empty());
@@ -182,7 +186,12 @@ class _SampleTaskListPageState extends BaseLifecycleState<SampleTaskListPage> wi
182 186
   Widget buildTop() {
183 187
     return Row(
184 188
       children: [
185
-        Image.asset(imgListTitleIcon,width: 4,height: 20,fit: BoxFit.fill,),
189
+        Image.asset(
190
+          imgListTitleIcon,
191
+          width: 4,
192
+          height: 20,
193
+          fit: BoxFit.fill,
194
+        ),
186 195
         const SizedBox(width: 4),
187 196
         const Text(
188 197
           '扦样任务单号',
@@ -192,19 +201,16 @@ class _SampleTaskListPageState extends BaseLifecycleState<SampleTaskListPage> wi
192 201
     );
193 202
   }
194 203
 
195
-
196 204
   Widget buildState(String state) {
197 205
     String img = imgQYStateOff;
198 206
     Color color = const Color(0xFF149723);
199
-    if(state != '已扦样'){
207
+    if (state != '已扦样') {
200 208
       img = imgQYStateOn;
201 209
       color = const Color(0xFFDEA70A);
202 210
     }
203 211
     return Container(
204 212
       padding: const EdgeInsets.fromLTRB(40, 4, 20, 16),
205
-      decoration: BoxDecoration(
206
-        image: DecorationImage(image: AssetImage(img), fit: BoxFit.fill)
207
-      ),
213
+      decoration: BoxDecoration(image: DecorationImage(image: AssetImage(img), fit: BoxFit.fill)),
208 214
       child: Text(
209 215
         state,
210 216
         style: TextStyle(color: color, fontSize: 15),
@@ -231,7 +237,10 @@ class _SampleTaskListPageState extends BaseLifecycleState<SampleTaskListPage> wi
231 237
         inList.add(ItemMsgModel(tit: '检验指标', content: item.jyzb, img: imgIconJYZB));
232 238
       }
233 239
       if (item.ypdj != null) {
234
-        inList.add(ItemMsgModel(tit: '样品层级', content: DictService.getDict(DictType.ypdj, value: item.ypdj)?.label, img: imgIconYPDJ));
240
+        inList.add(ItemMsgModel(
241
+            tit: '样品层级',
242
+            content: DictService.getDict(DictType.ypdj, value: item.ypdj)?.label,
243
+            img: imgIconYPDJ));
235 244
       }
236 245
       inList.add(ItemMsgModel(tit: '扦样地区', content: item.qydq, img: imgIconQYDQ));
237 246
     } else {
@@ -241,7 +250,10 @@ class _SampleTaskListPageState extends BaseLifecycleState<SampleTaskListPage> wi
241 250
         inList.add(ItemMsgModel(tit: '检验指标', content: item.jyzb, img: imgIconJYZB));
242 251
       }
243 252
       if (item.ypdj != null) {
244
-        inList.add(ItemMsgModel(tit: '样品层级', content: DictService.getDict(DictType.ypdj, value: item.ypdj)?.label, img: imgIconYPDJ));
253
+        inList.add(ItemMsgModel(
254
+            tit: '样品层级',
255
+            content: DictService.getDict(DictType.ypdj, value: item.ypdj)?.label,
256
+            img: imgIconYPDJ));
245 257
       }
246 258
       inList.add(ItemMsgModel(tit: '扦样地区', content: item.qydq, img: imgIconQYDQ));
247 259
       inList.add(ItemMsgModel(tit: '扦样人员', content: item.name, img: imgIconQYRY));
@@ -261,14 +273,18 @@ class _SampleTaskListPageState extends BaseLifecycleState<SampleTaskListPage> wi
261 273
                 children: [
262 274
                   Padding(
263 275
                     padding: const EdgeInsets.fromLTRB(0, 4, 6, 0),
264
-                    child: Image.asset(item.img,width: 36),
276
+                    child: Image.asset(item.img, width: 36),
265 277
                   ),
266 278
                   Expanded(
267 279
                     child: Column(
268 280
                       crossAxisAlignment: CrossAxisAlignment.start,
269 281
                       children: [
270
-                        Text(item.tit,style: const TextStyle(color: MyColor.c_666666)),
271
-                        Text(item.content ?? '', style: const TextStyle(color: MyColor.c_666666,fontWeight: FontWeight.bold),)
282
+                        Text(item.tit, style: const TextStyle(color: MyColor.c_666666)),
283
+                        Text(
284
+                          item.content ?? '',
285
+                          style:
286
+                              const TextStyle(color: MyColor.c_666666, fontWeight: FontWeight.bold),
287
+                        )
272 288
                       ],
273 289
                     ),
274 290
                   )
@@ -282,7 +298,6 @@ class _SampleTaskListPageState extends BaseLifecycleState<SampleTaskListPage> wi
282 298
   }
283 299
 
284 300
   Widget buildBottom(SampleTaskItem item) {
285
-    if (item.deliveryStatus == 2) return const SizedBox.shrink();
286 301
     Widget button = const SizedBox.shrink();
287 302
     if (widget.type == StepType.reap && item.deliveryStatus == 0) {
288 303
       button = MyButton(
@@ -293,7 +308,7 @@ class _SampleTaskListPageState extends BaseLifecycleState<SampleTaskListPage> wi
293 308
         alignment: null,
294 309
         padding: const EdgeInsets.symmetric(vertical: 4, horizontal: 12),
295 310
       );
296
-    } else {
311
+    } else if (widget.type == StepType.reap && item.deliveryStatus == 1) {
297 312
       button = MyButton(
298 313
         '开始扦样',
299 314
         onTap: () => startTaskDetail(false, item),
@@ -302,25 +317,40 @@ class _SampleTaskListPageState extends BaseLifecycleState<SampleTaskListPage> wi
302 317
         alignment: null,
303 318
         padding: const EdgeInsets.symmetric(vertical: 4, horizontal: 12),
304 319
       );
320
+    } else {
321
+      button = MyButton(
322
+        '修改信息',
323
+        onTap: () => startTaskDetail(false, item,deliveryStatus: item.deliveryStatus),
324
+        fountSize: 13,
325
+        radius: 6,
326
+        alignment: null,
327
+        padding: const EdgeInsets.symmetric(vertical: 4, horizontal: 12),
328
+      );
305 329
     }
306 330
     return Container(
307 331
       padding: const EdgeInsets.fromLTRB(8, 14, 12, 14),
308 332
       decoration: const BoxDecoration(
309
-        gradient: LinearGradient(
310
-            begin: Alignment.topCenter,
311
-            end: Alignment.bottomCenter,
312
-            colors: [Color(0xFFE4F5FC), Color(0xFFF5FDFD)])
313
-      ),
333
+          gradient: LinearGradient(
334
+              begin: Alignment.topCenter,
335
+              end: Alignment.bottomCenter,
336
+              colors: [Color(0xFFE4F5FC), Color(0xFFF5FDFD)])),
314 337
       child: Row(
315 338
         children: [
316
-          Image.asset(imgIconEdit,width: 10,),
339
+          Image.asset(
340
+            imgIconEdit,
341
+            width: 10,
342
+          ),
317 343
           const SizedBox(width: 4),
318 344
           Expanded(
319
-            child: Text(
320
-              '扦样单据创建于${DateTimeUtils.yyyymmdd(timestamp: item.createTime) ?? ''}',
321
-              style: const TextStyle(fontSize: 14, color: MyColor.c_666666),
322
-            ),
323
-          ),
345
+              child: item.deliveryStatus == 2
346
+                  ? Text(
347
+                      '扦样单据完成于${item.qysj ?? ''}',
348
+                      style: const TextStyle(fontSize: 14, color: MyColor.c_666666),
349
+                    )
350
+                  : Text(
351
+                      '扦样单据创建于${DateTimeUtils.yyyymmdd(timestamp: item.createTime) ?? ''}',
352
+                      style: const TextStyle(fontSize: 14, color: MyColor.c_666666),
353
+                    )),
324 354
           const SizedBox(width: 4),
325 355
           button,
326 356
         ],

+ 8 - 0
lib/page/user_center/setting_page.dart

@@ -2,6 +2,8 @@ import 'package:flutter/cupertino.dart';
2 2
 import 'package:flutter/material.dart';
3 3
 import 'package:lszlgl/base/base_state.dart';
4 4
 import 'package:lszlgl/config/app_config.dart';
5
+import 'package:lszlgl/config/colors.dart';
6
+import 'package:lszlgl/network/my_api.dart';
5 7
 import 'package:lszlgl/service/upgrade_service.dart';
6 8
 import 'package:lszlgl/widget/button.dart';
7 9
 import 'package:lszlgl/widget/card_item.dart';
@@ -52,6 +54,12 @@ class _SettingPageState extends BaseState<SettingPage> {
52 54
           minHeight: 40,
53 55
           margin: const EdgeInsets.symmetric(horizontal: 12),
54 56
         ),
57
+
58
+        if(AppConfig.env == AppEnvironment.develop)
59
+          Padding(
60
+            padding: const EdgeInsets.only(top: 38.0),
61
+            child: Text(MyApi.testUrl,style: const TextStyle(color: Color(0xFFA4A4A4),fontSize: 12),),
62
+          )
55 63
       ],
56 64
     );
57 65
   }

+ 0 - 2
lib/service/print_service.dart

@@ -1,6 +1,5 @@
1 1
 
2 2
 
3
-import 'dart:ffi';
4 3
 import 'dart:io';
5 4
 import 'package:device_info_plus/device_info_plus.dart';
6 5
 import 'package:lszlgl/utils/permission_utils.dart';
@@ -9,7 +8,6 @@ import 'package:permission_handler/permission_handler.dart';
9 8
 import '../model/rsp/sample_task_rsp.dart';
10 9
 import '../plugin/bluetooth_plugin.dart';
11 10
 import '../router/my_navigator.dart';
12
-import 'package:flutter/material.dart';
13 11
 import 'package:flutter/services.dart';
14 12
 
15 13
 import 'dict_service.dart';

+ 4 - 2
lib/service/upgrade_service.dart

@@ -64,7 +64,9 @@ class UpgradeService {
64 64
     if (showLoading) MyNavigator.showLoading(msg: '正在获取版本更新');
65 65
     try {
66 66
       // 获取apk下载地址
67
-      var path = (await MyApi.get().getAppDownloadUrl()).data;
67
+      var rsp = await MyApi.get().getAppDownLoadUrlAndName();
68
+      var path = rsp.data?.url;
69
+      var contents = rsp.data?.name ?? '';
68 70
       if (showLoading) MyNavigator.dismissLoading();
69 71
       if (path != null) {
70 72
         // 获取线上版本 lszlgl_release_0.0.2_2.apk
@@ -76,7 +78,7 @@ class UpgradeService {
76 78
           if (showLoading) MyNavigator.showToast('已是最新版本');
77 79
         } else {
78 80
           // 版本更新
79
-          UpgradeDialog.showDialog(path);
81
+          UpgradeDialog.showDialog(path,contents);
80 82
         }
81 83
       }
82 84
     } catch (e) {

+ 2 - 2
lib/widget/card_item.dart

@@ -97,9 +97,9 @@ class CardItemWidget extends StatelessWidget {
97 97
     return Text(
98 98
       title,
99 99
       style: const TextStyle(
100
-        color: Color(0xFF333333),
100
+        color: Color(0xFF515151),
101 101
         fontSize: 14,
102
-        fontWeight: FontWeight.w500,
102
+        fontWeight: FontWeight.w300,
103 103
       ),
104 104
     );
105 105
   }

+ 16 - 17
lib/widget/upgrade_dialog.dart

@@ -1,3 +1,5 @@
1
+import 'dart:convert';
2
+
1 3
 import 'package:flutter/material.dart';
2 4
 import 'package:lszlgl/main.dart';
3 5
 import 'package:lszlgl/service/upgrade_service.dart';
@@ -7,19 +9,20 @@ import 'package:lszlgl/ext/value_notifier_ext.dart';
7 9
 import '../router/my_navigator.dart';
8 10
 
9 11
 class UpgradeDialog extends StatelessWidget {
10
-  static void showDialog(String path) {
12
+  static void showDialog(String path,String contents) {
11 13
     MyNavigator.showDialog(
12
-      builder: (_) => UpgradeDialog(path),
14
+      builder: (_) => UpgradeDialog(path,contents),
13 15
       tag: 'upgrade',
14 16
       clickDismiss: false,
15 17
     );
16 18
   }
17 19
 
18 20
   final String path;
21
+  final String contents;
19 22
   final String versionName;
20 23
 
21 24
   UpgradeDialog(
22
-    this.path, {
25
+    this.path,this.contents, {
23 26
     super.key,
24 27
   }) : versionName = path.split('_')[path.split('_').length - 2];
25 28
 
@@ -77,6 +80,7 @@ class UpgradeDialog extends StatelessWidget {
77 80
         borderRadius: BorderRadius.all(Radius.circular(8)),
78 81
       ),
79 82
       child: Column(
83
+       // crossAxisAlignment: CrossAxisAlignment.stretch,
80 84
         mainAxisSize: MainAxisSize.min,
81 85
         children: [
82 86
           Container(
@@ -86,20 +90,15 @@ class UpgradeDialog extends StatelessWidget {
86 90
               style: const TextStyle(color: Color(0xFF333333), fontSize: 16, fontWeight: FontWeight.w500),
87 91
             ),
88 92
           ),
89
-          // Row(
90
-          //   children: [
91
-          //     const Spacer(),
92
-          //     progress.builder((v) => v == -1
93
-          //         ? GestureDetector(
94
-          //             onTap: dismiss,
95
-          //             child: const Text(
96
-          //               '取消',
97
-          //               style: TextStyle(color: Color(0xFF333333), fontSize: 14),
98
-          //             ),
99
-          //           )
100
-          //         : const SizedBox.shrink()),
101
-          //   ],
102
-          // ),
93
+
94
+          SizedBox(
95
+            width: double.infinity,
96
+            child: Text(
97
+             '更新内容:\n$contents',
98
+             style: const TextStyle(fontSize: 14,color: Color(0xFF333333)),
99
+                     ),
100
+          ),
101
+
103 102
           const SizedBox(height: 24),
104 103
           progress.builder((v) => v == -1 ? MyButton('立即下载安装', onTap: onDownload, alignment: null) : buildProgress(v)),
105 104
         ],

+ 1 - 1
pubspec.yaml

@@ -16,7 +16,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev
16 16
 # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
17 17
 # In Windows, build-name is used as the major, minor, and patch parts
18 18
 # of the product and file versions while build-number is used as the build suffix.
19
-version: 0.0.25+25
19
+version: 0.0.27+27
20 20
 
21 21
 environment:
22 22
   sdk: '>=3.1.5 <4.0.0'