Browse Source

优化选项菜单

maqiang 1 year ago
parent
commit
620955b007

+ 2 - 0
lib/config/reresh_config.dart

@@ -22,6 +22,7 @@ class RefreshConfig {
22 22
           noMoreText: '已加载全部',
23 23
           failedText: '刷新失败',
24 24
           messageText: '最后更新于 %T',
25
+          processedDuration: Duration(milliseconds: 200),
25 26
         );
26 27
     EasyRefresh.defaultFooterBuilder = () =>
27 28
         footer ??
@@ -34,6 +35,7 @@ class RefreshConfig {
34 35
           noMoreText: '已加载全部',
35 36
           failedText: '加载失败',
36 37
           messageText: '最后更新于 %T',
38
+          processedDuration: Duration(milliseconds: 200),
37 39
         );
38 40
   }
39 41
 }

+ 6 - 2
lib/network/api.dart

@@ -39,9 +39,13 @@ abstract class Api {
39 39
   @GET('/admin-api/zj/base-file/getAppDownLoadUrl')
40 40
   Future<ApiRsp<String?>> getAppDownloadUrl();
41 41
 
42
-  /// 扦样任务更新
42
+  /// 扦样任务更新-收购
43 43
   @PUT('/admin-api/zj/code-sampling-task-details-sgjc/update')
44
-  Future<ApiRsp<bool?>> updateSampleTask(@Body() Map<String, dynamic> map);
44
+  Future<ApiRsp<bool?>> updateSampleTaskSgjc(@Body() Map<String, dynamic> map);
45
+
46
+  /// 扦样任务单详情-收购
47
+  @GET('/admin-api/zj/code-sampling-task-details-sgjc/getSamplingTaskDetails')
48
+  Future<ApiRsp<SampleTaskItem?>> sampleTaskDetailSgjc(@Query('id') num id);
45 49
 
46 50
   /// 省市县
47 51
   @GET('/admin-api/zj/base-administrative-division/list')

+ 15 - 0
lib/network/my_api.dart

@@ -0,0 +1,15 @@
1
+import 'package:dio/dio.dart';
2
+
3
+import 'api.dart';
4
+
5
+class MyApi {
6
+  MyApi._();
7
+
8
+  static String productUrl = 'http://121.36.17.6:49099';
9
+  static String testUrl = 'http://121.36.17.6:19090';
10
+
11
+  static Api get({Dio? dio, String? baseUrl}) {
12
+    baseUrl ??= testUrl;
13
+    return Api(dio: dio, baseUrl: baseUrl);
14
+  }
15
+}

+ 3 - 7
lib/page/home/home_page.dart

@@ -20,20 +20,16 @@ class _HomePageState extends BaseState<HomePage> with AutomaticKeepAliveClientMi
20 20
 
21 21
   late List<ServiceModel> serviceList;
22 22
 
23
-  void startReap() {
23
+  void startSampleList(StepType type) async{
24 24
     MyRouter.startSampleTaskList(const SampleTaskListTabPageArgs(type: StepType.reap));
25 25
   }
26 26
 
27
-  void startStore() {
28
-    MyRouter.startSampleTaskList(const SampleTaskListTabPageArgs(type: StepType.stock));
29
-  }
30
-
31 27
   @override
32 28
   void initState() {
33 29
     super.initState();
34 30
     serviceList = [
35
-      ServiceModel(name: '收获环节', icon: imgHomeListPzjc, onTap: startReap),
36
-      ServiceModel(name: '库存环节', icon: imgHomeListZcjy, onTap: startStore),
31
+      ServiceModel(name: '收获环节', icon: imgHomeListPzjc, onTap: () => startSampleList(StepType.reap)),
32
+      ServiceModel(name: '库存环节', icon: imgHomeListZcjy, onTap: () => startSampleList(StepType.stock)),
37 33
     ];
38 34
   }
39 35
 

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

@@ -3,7 +3,7 @@ import 'package:flutter/material.dart';
3 3
 import 'package:flutter_keyboard_visibility/flutter_keyboard_visibility.dart';
4 4
 import 'package:lszlgl/base/base_lifecycle_state.dart';
5 5
 import 'package:lszlgl/model/req/login_req.dart';
6
-import 'package:lszlgl/network/api.dart';
6
+import 'package:lszlgl/network/my_api.dart';
7 7
 import 'package:lszlgl/service/dict_service.dart';
8 8
 import 'package:lszlgl/service/upgrade_service.dart';
9 9
 import 'package:lszlgl/service/user_service.dart';
@@ -31,7 +31,7 @@ class _LoginPageState extends BaseLifecycleState<LoginPage> {
31 31
     MyNavigator.showLoading();
32 32
     try {
33 33
       // 登录
34
-      var login = await Api().login(LoginReq(username: account, password: pwd));
34
+      var login = await MyApi.get().login(LoginReq(username: account, password: pwd));
35 35
       await UserService.get().saveLogin(login.data);
36 36
       getSystemData();
37 37
     } on DioException catch (_) {
@@ -44,10 +44,10 @@ class _LoginPageState extends BaseLifecycleState<LoginPage> {
44 44
     MyNavigator.showLoading(clickDismiss: false);
45 45
     try {
46 46
       // 获取用户数据
47
-      var user = await Api().userProfile();
47
+      var user = await MyApi.get().userProfile();
48 48
       await UserService.get().saveUser(user.data);
49 49
       // 获取字典
50
-      var dictData = await Api().getAllDict();
50
+      var dictData = await MyApi.get().getAllDict();
51 51
       DictService.saveDictList(dictData.data);
52 52
       UpgradeService.checkUpgrade(false);
53 53
       // 进入主页

+ 135 - 226
lib/page/sample_task/reap_sample_detail/reap_sample_basic_detail_page.dart

@@ -1,11 +1,8 @@
1 1
 import 'package:flutter/material.dart';
2
-import 'package:lszlgl/network/api.dart';
3 2
 import '../../../base/base_lifecycle_state.dart';
4
-import '../../../config/colors.dart';
5
-import '../../../model/rsp/district_rsp.dart';
6 3
 import '../../../model/rsp/sample_task_rsp.dart';
4
+import '../../../network/my_api.dart';
7 5
 import '../../../service/dict_service.dart';
8
-import '../../../widget/button.dart';
9 6
 import '../../../widget/card_item.dart';
10 7
 
11 8
 /// 收获扦样-基础信息
@@ -25,28 +22,120 @@ class ReapSampleBasicDetailPage extends StatefulWidget {
25 22
   State<ReapSampleBasicDetailPage> createState() => _ReapSampleBasicDetailPageState();
26 23
 }
27 24
 
28
-class _ReapSampleBasicDetailPageState extends BaseLifecycleState<ReapSampleBasicDetailPage>
29
-    with AutomaticKeepAliveClientMixin {
25
+class _ReapSampleBasicDetailPageState extends BaseLifecycleState<ReapSampleBasicDetailPage> with AutomaticKeepAliveClientMixin {
30 26
   SampleTaskItem? data;
27
+  late bool isDetail;
31 28
 
32
-  late Widget arrowDown;
33
-  final sfList = <DistrictRsp>[].notifier<List<DistrictRsp>>();
34
-  final sqList = <DistrictRsp>[].notifier<List<DistrictRsp>>();
35
-  final qxList = <DistrictRsp>[].notifier<List<DistrictRsp>>();
36
-  final xzList = <DistrictRsp>[].notifier<List<DistrictRsp>>();
37
-  final czList = <DistrictRsp>[].notifier<List<DistrictRsp>>();
38
-  final sf = null.notifier<int?>();
39
-  final sq = null.notifier<int?>();
40
-  final qx = null.notifier<int?>();
41
-  final xz = null.notifier<int?>();
42
-  final cz = null.notifier<int?>();
29
+  final shengList = <CardMenuData>[].notifier<List<CardMenuData>>();
30
+  final shiList = <CardMenuData>[].notifier<List<CardMenuData>>();
31
+  final quList = <CardMenuData>[].notifier<List<CardMenuData>>();
32
+  final xianList = <CardMenuData>[].notifier<List<CardMenuData>>();
33
+  final cunList = <CardMenuData>[].notifier<List<CardMenuData>>();
34
+  final sheng = null.notifier<CardMenuData?>();
35
+  final shi = null.notifier<CardMenuData?>();
36
+  final qu = null.notifier<CardMenuData?>();
37
+  final xian = null.notifier<CardMenuData?>();
38
+  final cun = null.notifier<CardMenuData?>();
43 39
 
44
-  final dllx = null.notifier<int?>();
40
+  final dllx = null.notifier<CardMenuData?>();
41
+
42
+  Future<void> districtList(num level, {num? id}) async {
43
+    MyNavigator.showLoading();
44
+    try {
45
+      var rsp = await MyApi.get().districtList(level, id: id);
46
+      List<CardMenuData> list = (rsp.data ?? []).map((e) => CardMenuData(e.uname, e.id)).toList();
47
+      if (level == 1) {
48
+        shengList.value = list;
49
+      } else if (level == 2) {
50
+        shiList.value = list;
51
+      } else if (level == 3) {
52
+        quList.value = list;
53
+      } else if (level == 4) {
54
+        xianList.value = list;
55
+      } else if (level == 5) {
56
+        cunList.value = list;
57
+      }
58
+    } catch (e) {}
59
+    MyNavigator.dismissLoading();
60
+  }
61
+
62
+  void onSelect(ValueNotifier<CardMenuData?> selNotifier, CardMenuData selData) {
63
+    num level = 100;
64
+    if (selNotifier == sheng) {
65
+      level = 1;
66
+      data?.sheng = selData.name;
67
+      data?.shengXzqh = selData.value;
68
+      data?.shi = null;
69
+      data?.shiXzqh = null;
70
+      data?.qu = null;
71
+      data?.quXzqh = null;
72
+      data?.xian = null;
73
+      data?.xiangXzqh = null;
74
+      data?.cun = null;
75
+      data?.cunXzqh = null;
76
+      shi.value = null;
77
+      qu.value = null;
78
+      xian.value = null;
79
+      cun.value = null;
80
+      shiList.value = [];
81
+      quList.value = [];
82
+      xianList.value = [];
83
+      cunList.value = [];
84
+    } else if (selNotifier == shi) {
85
+      level = 2;
86
+      data?.shi = selData.name;
87
+      data?.shiXzqh = selData.value;
88
+      data?.qu = null;
89
+      data?.quXzqh = null;
90
+      data?.xian = null;
91
+      data?.xiangXzqh = null;
92
+      data?.cun = null;
93
+      data?.cunXzqh = null;
94
+      qu.value = null;
95
+      xian.value = null;
96
+      cun.value = null;
97
+      quList.value = [];
98
+      xianList.value = [];
99
+      cunList.value = [];
100
+    } else if (selNotifier == qu) {
101
+      level = 3;
102
+      data?.qu = selData.name;
103
+      data?.quXzqh = selData.value;
104
+      data?.xian = null;
105
+      data?.xiangXzqh = null;
106
+      data?.cun = null;
107
+      data?.cunXzqh = null;
108
+      xian.value = null;
109
+      cun.value = null;
110
+      xianList.value = [];
111
+      cunList.value = [];
112
+    } else if (selNotifier == xian) {
113
+      level = 4;
114
+      data?.xian = selData.name;
115
+      data?.xiangXzqh = selData.value;
116
+      data?.cun = null;
117
+      data?.cunXzqh = null;
118
+      cun.value = null;
119
+      cunList.value = [];
120
+    } else if (selNotifier == cun) {
121
+      level = 5;
122
+      data?.cun = selData.name;
123
+      data?.cunXzqh = selData.value;
124
+    }
125
+    if (level < 5) {
126
+      // 获取下一个等级的菜单数据
127
+      districtList(level + 1, id: selData.value ?? 0);
128
+    }
129
+  }
130
+
131
+  /// 获取编辑数据
132
+  void getEditData() {
133
+    if (data?.sheng != null) sheng.value = CardMenuData(data?.sheng, data?.shengXzqh);
134
+    if (data?.shi != null) shi.value = CardMenuData(data?.shi, data?.shiXzqh);
135
+    if (data?.qu != null) qu.value = CardMenuData(data?.qu, data?.quXzqh);
136
+    if (data?.xian != null) xian.value = CardMenuData(data?.xian, data?.xiangXzqh);
137
+    if (data?.cun != null) cun.value = CardMenuData(data?.cun, data?.cunXzqh);
45 138
 
46
-  @override
47
-  void onInit() {
48
-    data = widget.data;
49
-    arrowDown = Image.asset(imgItemArrowDown, width: 20);
50 139
     // 省
51 140
     districtList(1);
52 141
     // 市
@@ -67,96 +156,22 @@ class _ReapSampleBasicDetailPageState extends BaseLifecycleState<ReapSampleBasic
67 156
     }
68 157
   }
69 158
 
70
-  Future<void> districtList(num level, {num? id}) async {
71
-    MyNavigator.showLoading();
72
-    try {
73
-      var rsp = await Api().districtList(level, id: id);
74
-      if (level == 1) {
75
-        sfList.value = rsp.data ?? [];
76
-      } else if (level == 2) {
77
-        sqList.value = rsp.data ?? [];
78
-      } else if (level == 3) {
79
-        qxList.value = rsp.data ?? [];
80
-      } else if (level == 4) {
81
-        xzList.value = rsp.data ?? [];
82
-      } else if (level == 5) {
83
-        czList.value = rsp.data ?? [];
84
-      }
85
-    } catch (e) {}
86
-    MyNavigator.dismissLoading();
87
-  }
159
+  @override
160
+  bool get wantKeepAlive => true;
88 161
 
89
-  void onSelect(ValueNotifier<int?> selNotifier, int index) {
90
-    late DistrictRsp item;
91
-    if (selNotifier == sf) {
92
-      item = sfList.value[index];
93
-      data?.sheng = item.uname;
94
-      data?.shengXzqh = item.id;
95
-      sq.value = null;
96
-      qx.value = null;
97
-      xz.value = null;
98
-      cz.value = null;
99
-      sqList.value = [];
100
-      qxList.value = [];
101
-      xzList.value = [];
102
-      czList.value = [];
103
-    } else if (selNotifier == sq) {
104
-      item = sqList.value[index];
105
-      data?.shi = item.uname;
106
-      data?.shiXzqh = item.id;
107
-      qx.value = null;
108
-      xz.value = null;
109
-      cz.value = null;
110
-      qxList.value = [];
111
-      xzList.value = [];
112
-      czList.value = [];
113
-    } else if (selNotifier == qx) {
114
-      item = qxList.value[index];
115
-      data?.qu = item.uname;
116
-      data?.quXzqh = item.id;
117
-      xz.value = null;
118
-      cz.value = null;
119
-      xzList.value = [];
120
-      czList.value = [];
121
-    } else if (selNotifier == xz) {
122
-      item = xzList.value[index];
123
-      data?.xian = item.uname;
124
-      data?.xiangXzqh = item.id;
125
-      cz.value = null;
126
-      czList.value = [];
127
-    } else if (selNotifier == cz) {
128
-      item = sfList.value[index];
129
-      widget.data?.cun = item.uname;
130
-      data?.cun = item.uname;
131
-      data?.cunXzqh = item.id;
132
-    }
133
-    if ((item.ulevel ?? 100) < 5) {
134
-      districtList((item.ulevel ?? 100) + 1, id: item.id ?? 0);
162
+  @override
163
+  void onInit() {
164
+    data = widget.data;
165
+    isDetail = widget.detail;
166
+    if (!isDetail) {
167
+      getEditData();
135 168
     }
136 169
   }
137 170
 
138
-  Future<void> updateTask() async {
139
-    // widget.nextCallback?.call();
140
-    MyNavigator.showLoading();
141
-    try {
142
-      var rsp = await Api().updateSampleTask(data?.toJson() ?? {});
143
-      MyNavigator.showToast((rsp.data ?? false) ? '提交成功' : '提交失败');
144
-    } catch (e) {}
145
-    MyNavigator.dismissLoading();
146
-  }
147
-
148
-  @override
149
-  bool get wantKeepAlive => true;
150
-
151 171
   @override
152 172
   Widget build(BuildContext context) {
153 173
     super.build(context);
154
-    return Column(
155
-      children: [
156
-        Expanded(child: SingleChildScrollView(child: buildList())),
157
-        buildButton(),
158
-      ],
159
-    );
174
+    return SingleChildScrollView(child: buildList());
160 175
   }
161 176
 
162 177
   Widget buildList() {
@@ -182,36 +197,21 @@ class _ReapSampleBasicDetailPageState extends BaseLifecycleState<ReapSampleBasic
182 197
           rightText: DictService.getLabel(DictType.jclb, value: data?.jclb),
183 198
           bottomLine: true,
184 199
         ),
185
-        CardItemWidget(
186
-          '省份',
187
-          rightText: widget.detail ? data?.sheng : null,
188
-          rightChild: widget.detail ? null : buildMenu(sfList, sf, onSelect),
189
-          bottomLine: true,
190
-        ),
191
-        CardItemWidget(
192
-          '市区',
193
-          rightText: widget.detail ? data?.shi : null,
194
-          rightChild: widget.detail ? null : buildMenu(sqList, sq, onSelect),
195
-          bottomLine: true,
196
-        ),
197
-        CardItemWidget(
198
-          '区县',
199
-          rightText: widget.detail ? data?.qu : null,
200
-          rightChild: widget.detail ? null : buildMenu(qxList, qx, onSelect),
201
-          bottomLine: true,
202
-        ),
203
-        CardItemWidget(
204
-          '乡镇',
205
-          rightText: widget.detail ? data?.xian : null,
206
-          rightChild: widget.detail ? null : buildMenu(xzList, xz, onSelect),
207
-          bottomLine: true,
208
-        ),
209
-        CardItemWidget(
210
-          '村',
211
-          rightText: widget.detail ? data?.cun : null,
212
-          rightChild: widget.detail ? null : buildMenu(czList, cz, onSelect),
213
-          bottomLine: true,
214
-        ),
200
+        isDetail
201
+            ? CardItemWidget('省份', rightText: data?.sheng, bottomLine: true)
202
+            : CardItemMenuWidget('省份', shengList, sheng, onSelectTap: onSelect, bottomLine: true),
203
+        isDetail
204
+            ? CardItemWidget('市区', rightText: data?.shi, bottomLine: true)
205
+            : CardItemMenuWidget('市区', shiList, shi, onSelectTap: onSelect, bottomLine: true),
206
+        isDetail
207
+            ? CardItemWidget('区县', rightText: data?.qu, bottomLine: true)
208
+            : CardItemMenuWidget('区县', quList, qu, onSelectTap: onSelect, bottomLine: true),
209
+        isDetail
210
+            ? CardItemWidget('乡镇', rightText: data?.xian, bottomLine: true)
211
+            : CardItemMenuWidget('乡镇', xianList, xian, onSelectTap: onSelect, bottomLine: true),
212
+        isDetail
213
+            ? CardItemWidget('村', rightText: data?.cun, bottomLine: true)
214
+            : CardItemMenuWidget('村', cunList, cun, onSelectTap: onSelect, bottomLine: true),
215 215
         CardItemWidget(
216 216
           '扦样地点经纬度',
217 217
           rightText: data?.qyddjwd,
@@ -240,95 +240,4 @@ class _ReapSampleBasicDetailPageState extends BaseLifecycleState<ReapSampleBasic
240 240
       ],
241 241
     );
242 242
   }
243
-
244
-  Widget buildButton() {
245
-    return Container(
246
-      color: const Color(0xFFF1F7F6),
247
-      padding: const EdgeInsets.all(12),
248
-      child: MyButton(
249
-        widget.detail ? '重新录入' : '下一步',
250
-        onTap: () => widget.detail ? MyRouter.startReapSampleTask() : updateTask(),
251
-      ),
252
-    );
253
-  }
254
-
255
-  Widget buildMenu(
256
-    ValueNotifier<List<DistrictRsp>> listNotifier,
257
-    ValueNotifier<int?> selNotifier,
258
-    Function(ValueNotifier<int?>, int) onItemTap,
259
-  ) {
260
-    return listNotifier.builder(
261
-      (list) => selNotifier.builder(
262
-        (sel) {
263
-          return MenuAnchor(
264
-            style: const MenuStyle(
265
-              padding: MaterialStatePropertyAll(EdgeInsets.zero),
266
-              alignment: Alignment.bottomRight,
267
-            ),
268
-            builder: (_, ctrl, __) => buildMenuText(ctrl, list, sel),
269
-            menuChildren: List.generate(list.length, (index) {
270
-              return buildMenuItem(
271
-                list[index],
272
-                index == sel,
273
-                () {
274
-                  if (selNotifier.value == index) return;
275
-                  selNotifier.value = index;
276
-                  onItemTap.call(selNotifier, index);
277
-                },
278
-              );
279
-            }).toList(),
280
-          );
281
-        },
282
-      ),
283
-    );
284
-  }
285
-
286
-  Widget buildMenuText(MenuController ctrl, List<DistrictRsp> list, int? index) {
287
-    return GestureDetector(
288
-      behavior: HitTestBehavior.opaque,
289
-      onTap: () {
290
-        if (list.isEmpty) {
291
-          MyNavigator.showToast('请先选择上级选项');
292
-          return;
293
-        }
294
-        if (ctrl.isOpen) {
295
-          ctrl.close();
296
-        } else {
297
-          ctrl.open();
298
-        }
299
-      },
300
-      child: Row(
301
-        mainAxisSize: MainAxisSize.min,
302
-        children: [
303
-          Expanded(
304
-            child: Text(
305
-              index == null ? '' : list[index].uname ?? '',
306
-              textAlign: TextAlign.right,
307
-              style: const TextStyle(
308
-                color: Color(0xFF01B2C8),
309
-                fontSize: 14,
310
-                fontWeight: FontWeight.w500,
311
-              ),
312
-            ),
313
-          ),
314
-          const SizedBox(width: 8),
315
-          arrowDown,
316
-        ],
317
-      ),
318
-    );
319
-  }
320
-
321
-  Widget buildMenuItem(DistrictRsp value, bool isSelect, VoidCallback? onPressed) {
322
-    return MenuItemButton(
323
-      onPressed: onPressed,
324
-      child: Container(
325
-        constraints: const BoxConstraints(minWidth: 120),
326
-        alignment: Alignment.center,
327
-        child: Text(
328
-          value.uname ?? '',
329
-          style: TextStyle(color: isSelect ? const Color(0xFF01B2C8) : MyColor.c_666666),
330
-        ),
331
-      ),
332
-    );
333
-  }
334 243
 }

+ 1 - 19
lib/page/sample_task/reap_sample_detail/reap_sample_disaster_detail_page.dart

@@ -1,8 +1,6 @@
1 1
 import 'package:flutter/material.dart';
2 2
 import 'package:lszlgl/base/base_lifecycle_state.dart';
3
-import 'package:lszlgl/base/base_state.dart';
4 3
 import 'package:lszlgl/utils/string_utils.dart';
5
-import 'package:lszlgl/widget/button.dart';
6 4
 import 'package:lszlgl/widget/card_item.dart';
7 5
 
8 6
 import '../../../model/rsp/sample_task_rsp.dart';
@@ -31,12 +29,7 @@ class _ReapSampleDisasterDetailPageState extends BaseLifecycleState<ReapSampleDi
31 29
   @override
32 30
   Widget build(BuildContext context) {
33 31
     super.build(context);
34
-    return Column(
35
-      children: [
36
-        Expanded(child: SingleChildScrollView(child: buildList())),
37
-        buildButton(),
38
-      ],
39
-    );
32
+    return SingleChildScrollView(child: buildList());
40 33
   }
41 34
 
42 35
   Widget buildList() {
@@ -105,15 +98,4 @@ class _ReapSampleDisasterDetailPageState extends BaseLifecycleState<ReapSampleDi
105 98
       ],
106 99
     );
107 100
   }
108
-
109
-  Widget buildButton() {
110
-    return Container(
111
-      color: const Color(0xFFF1F7F6),
112
-      padding: const EdgeInsets.all(12),
113
-      child: MyButton(
114
-        '重新录入',
115
-        onTap: () => MyRouter.startReapSampleTask(),
116
-      ),
117
-    );
118
-  }
119 101
 }

+ 1 - 19
lib/page/sample_task/reap_sample_detail/reap_sample_medicine_detail_page.dart

@@ -1,7 +1,5 @@
1 1
 import 'package:flutter/material.dart';
2 2
 import 'package:lszlgl/base/base_lifecycle_state.dart';
3
-import 'package:lszlgl/base/base_state.dart';
4
-import 'package:lszlgl/widget/button.dart';
5 3
 import 'package:lszlgl/widget/card_item.dart';
6 4
 
7 5
 import '../../../model/rsp/sample_task_rsp.dart';
@@ -30,12 +28,7 @@ class _ReapSampleMedicineDetailPageState extends BaseLifecycleState<ReapSampleMe
30 28
   @override
31 29
   Widget build(BuildContext context) {
32 30
     super.build(context);
33
-    return Column(
34
-      children: [
35
-        Expanded(child: SingleChildScrollView(child: buildList())),
36
-        buildButton(),
37
-      ],
38
-    );
31
+    return SingleChildScrollView(child: buildList());
39 32
   }
40 33
 
41 34
   Widget buildList() {
@@ -103,15 +96,4 @@ class _ReapSampleMedicineDetailPageState extends BaseLifecycleState<ReapSampleMe
103 96
       ),
104 97
     );
105 98
   }
106
-
107
-  Widget buildButton() {
108
-    return Container(
109
-      color: const Color(0xFFF1F7F6),
110
-      padding: const EdgeInsets.all(12),
111
-      child: MyButton(
112
-        '重新录入',
113
-        onTap: () => MyRouter.startReapSampleTask(),
114
-      ),
115
-    );
116
-  }
117 99
 }

+ 1 - 19
lib/page/sample_task/reap_sample_detail/reap_sample_org_detail_page.dart

@@ -1,7 +1,5 @@
1 1
 import 'package:flutter/material.dart';
2 2
 import 'package:lszlgl/base/base_lifecycle_state.dart';
3
-import 'package:lszlgl/base/base_state.dart';
4
-import 'package:lszlgl/widget/button.dart';
5 3
 import 'package:lszlgl/widget/card_item.dart';
6 4
 
7 5
 import '../../../model/rsp/sample_task_rsp.dart';
@@ -47,12 +45,7 @@ class _ReapSampleOrgDetailPageState extends BaseLifecycleState<ReapSampleOrgDeta
47 45
   @override
48 46
   Widget build(BuildContext context) {
49 47
     super.build(context);
50
-    return Column(
51
-      children: [
52
-        Expanded(child: SingleChildScrollView(child: buildList())),
53
-        buildButton(),
54
-      ],
55
-    );
48
+    return SingleChildScrollView(child: buildList());
56 49
   }
57 50
 
58 51
   Widget buildList() {
@@ -80,15 +73,4 @@ class _ReapSampleOrgDetailPageState extends BaseLifecycleState<ReapSampleOrgDeta
80 73
       ],
81 74
     );
82 75
   }
83
-
84
-  Widget buildButton() {
85
-    return Container(
86
-      color: const Color(0xFFF1F7F6),
87
-      padding: const EdgeInsets.all(12),
88
-      child: MyButton(
89
-        '重新录入',
90
-        onTap: () => MyRouter.startReapSampleTask(),
91
-      ),
92
-    );
93
-  }
94 76
 }

+ 2 - 21
lib/page/sample_task/reap_sample_detail/reap_sample_variety_detail_page.dart

@@ -1,7 +1,5 @@
1 1
 import 'package:flutter/material.dart';
2 2
 import 'package:lszlgl/base/base_lifecycle_state.dart';
3
-import 'package:lszlgl/base/base_state.dart';
4
-import 'package:lszlgl/widget/button.dart';
5 3
 import 'package:lszlgl/widget/card_item.dart';
6 4
 
7 5
 import '../../../model/rsp/sample_task_rsp.dart';
@@ -16,8 +14,7 @@ class ReapSampleVarietyDetailPage extends StatefulWidget {
16 14
   State<ReapSampleVarietyDetailPage> createState() => _ReapSampleVarietyDetailPageState();
17 15
 }
18 16
 
19
-class _ReapSampleVarietyDetailPageState extends BaseLifecycleState<ReapSampleVarietyDetailPage>
20
-    with AutomaticKeepAliveClientMixin {
17
+class _ReapSampleVarietyDetailPageState extends BaseLifecycleState<ReapSampleVarietyDetailPage> with AutomaticKeepAliveClientMixin {
21 18
   SampleTaskItem? data;
22 19
 
23 20
   @override
@@ -31,12 +28,7 @@ class _ReapSampleVarietyDetailPageState extends BaseLifecycleState<ReapSampleVar
31 28
   @override
32 29
   Widget build(BuildContext context) {
33 30
     super.build(context);
34
-    return Column(
35
-      children: [
36
-        Expanded(child: SingleChildScrollView(child: buildList())),
37
-        buildButton(),
38
-      ],
39
-    );
31
+    return SingleChildScrollView(child: buildList());
40 32
   }
41 33
 
42 34
   Widget buildList() {
@@ -57,15 +49,4 @@ class _ReapSampleVarietyDetailPageState extends BaseLifecycleState<ReapSampleVar
57 49
       ],
58 50
     );
59 51
   }
60
-
61
-  Widget buildButton() {
62
-    return Container(
63
-      color: const Color(0xFFF1F7F6),
64
-      padding: const EdgeInsets.all(12),
65
-      child: MyButton(
66
-        '重新录入',
67
-        onTap: () => MyRouter.startReapSampleTask(),
68
-      ),
69
-    );
70
-  }
71 52
 }

+ 1 - 33
lib/page/sample_task/reap_sample_task/reap_sample_disaster_page.dart

@@ -1,6 +1,5 @@
1 1
 import 'package:flutter/material.dart';
2 2
 import 'package:lszlgl/base/base_state.dart';
3
-import 'package:lszlgl/widget/button.dart';
4 3
 import 'package:lszlgl/widget/card_item.dart';
5 4
 
6 5
 /// 收获扦样-灾害污染
@@ -60,12 +59,7 @@ class _ReapSampleDisasterPageState extends BaseState<ReapSampleDisasterPage> wit
60 59
   @override
61 60
   Widget build(BuildContext context) {
62 61
     super.build(context);
63
-    return Column(
64
-      children: [
65
-        Expanded(child: SingleChildScrollView(child: buildList())),
66
-        buildButton(),
67
-      ],
68
-    );
62
+    return SingleChildScrollView(child: buildList());
69 63
   }
70 64
 
71 65
   Widget buildList() {
@@ -87,32 +81,6 @@ class _ReapSampleDisasterPageState extends BaseState<ReapSampleDisasterPage> wit
87 81
     );
88 82
   }
89 83
 
90
-  Widget buildButton() {
91
-    return Container(
92
-      color: const Color(0xFFF1F7F6),
93
-      padding: const EdgeInsets.all(12),
94
-      child: Row(
95
-        children: [
96
-          Expanded(
97
-            flex: 2,
98
-            child: MyButton(
99
-              '上一步',
100
-              onTap: widget.previousCallback,
101
-            ),
102
-          ),
103
-          const Spacer(flex: 1),
104
-          Expanded(
105
-            flex: 2,
106
-            child: MyButton(
107
-              '下一步',
108
-              onTap: widget.nextCallback,
109
-            ),
110
-          ),
111
-        ],
112
-      ),
113
-    );
114
-  }
115
-
116 84
   Widget buildField({String? hint, TextInputType? inputType}) {
117 85
     return TextField(
118 86
       keyboardType: inputType,

+ 1 - 32
lib/page/sample_task/reap_sample_task/reap_sample_medicine_page.dart

@@ -41,12 +41,7 @@ class _ReapSampleMedicinePageState extends BaseState<ReapSampleMedicinePage> wit
41 41
   @override
42 42
   Widget build(BuildContext context) {
43 43
     super.build(context);
44
-    return Column(
45
-      children: [
46
-        Expanded(child: SingleChildScrollView(child: buildList())),
47
-        buildButton(),
48
-      ],
49
-    );
44
+    return SingleChildScrollView(child: buildList());
50 45
   }
51 46
 
52 47
   Widget buildList() {
@@ -127,32 +122,6 @@ class _ReapSampleMedicinePageState extends BaseState<ReapSampleMedicinePage> wit
127 122
     );
128 123
   }
129 124
 
130
-  Widget buildButton() {
131
-    return Container(
132
-      color: const Color(0xFFF1F7F6),
133
-      padding: const EdgeInsets.all(12),
134
-      child: Row(
135
-        children: [
136
-          Expanded(
137
-            flex: 2,
138
-            child: MyButton(
139
-              '上一步',
140
-              onTap: widget.previousCallback,
141
-            ),
142
-          ),
143
-          const Spacer(flex: 1),
144
-          Expanded(
145
-            flex: 2,
146
-            child: MyButton(
147
-              '下一步',
148
-              onTap: widget.nextCallback,
149
-            ),
150
-          ),
151
-        ],
152
-      ),
153
-    );
154
-  }
155
-
156 125
   Widget buildField({String? hint, TextInputType? inputType}) {
157 126
     return TextField(
158 127
       keyboardType: inputType,

+ 1 - 33
lib/page/sample_task/reap_sample_task/reap_sample_org_page.dart

@@ -1,6 +1,5 @@
1 1
 import 'package:flutter/material.dart';
2 2
 import 'package:lszlgl/base/base_state.dart';
3
-import 'package:lszlgl/widget/button.dart';
4 3
 import 'package:lszlgl/widget/card_item.dart';
5 4
 
6 5
 /// 收获扦样-检验机构
@@ -25,12 +24,7 @@ class _ReapSampleOrgPageState extends BaseState<ReapSampleOrgPage> with Automati
25 24
   @override
26 25
   Widget build(BuildContext context) {
27 26
     super.build(context);
28
-    return Column(
29
-      children: [
30
-        Expanded(child: SingleChildScrollView(child: buildList())),
31
-        buildButton(),
32
-      ],
33
-    );
27
+    return SingleChildScrollView(child: buildList());
34 28
   }
35 29
 
36 30
   Widget buildList() {
@@ -43,30 +37,4 @@ class _ReapSampleOrgPageState extends BaseState<ReapSampleOrgPage> with Automati
43 37
       ],
44 38
     );
45 39
   }
46
-
47
-  Widget buildButton() {
48
-    return Container(
49
-      color: const Color(0xFFF1F7F6),
50
-      padding: const EdgeInsets.all(12),
51
-      child: Row(
52
-        children: [
53
-          Expanded(
54
-            flex: 2,
55
-            child: MyButton(
56
-              '上一步',
57
-              onTap: widget.previousCallback,
58
-            ),
59
-          ),
60
-          const Spacer(flex: 1),
61
-          Expanded(
62
-            flex: 2,
63
-            child: MyButton(
64
-              '提交',
65
-              onTap: widget.submitCallback,
66
-            ),
67
-          ),
68
-        ],
69
-      ),
70
-    );
71
-  }
72 40
 }

+ 130 - 36
lib/page/sample_task/reap_sample_task/reap_sample_task_page.dart

@@ -1,5 +1,6 @@
1 1
 import 'package:flutter/material.dart';
2 2
 import 'package:flutter_keyboard_visibility/flutter_keyboard_visibility.dart';
3
+import 'package:lszlgl/base/base_lifecycle_state.dart';
3 4
 import 'package:lszlgl/base/base_state.dart';
4 5
 import 'package:lszlgl/config/colors.dart';
5 6
 import 'package:lszlgl/model/rsp/sample_task_rsp.dart';
@@ -13,21 +14,23 @@ import 'package:lszlgl/page/sample_task/reap_sample_task/reap_sample_medicine_pa
13 14
 import 'package:lszlgl/page/sample_task/reap_sample_task/reap_sample_org_page.dart';
14 15
 import 'package:lszlgl/page/sample_task/reap_sample_task/reap_sample_variety_page.dart';
15 16
 
17
+import '../../../base/base_vm.dart';
18
+import '../../../network/my_api.dart';
19
+import '../../../widget/button.dart';
20
+import '../../../widget/page_widget.dart';
21
+
16 22
 class ReapSampleTaskPageArgs {
17 23
   final bool detail;
18
-  final SampleTaskItem? data;
24
+  final num? id;
19 25
 
20 26
   ReapSampleTaskPageArgs({
21 27
     this.detail = false,
22
-    this.data,
28
+    this.id,
23 29
   });
24 30
 
25 31
   @override
26 32
   String toString() {
27
-    return {
28
-      'detail': detail,
29
-      'data': data != null ? '...' : null,
30
-    }.toString();
33
+    return {'detail': detail, 'id': id}.toString();
31 34
   }
32 35
 }
33 36
 
@@ -44,8 +47,11 @@ class ReapSampleTaskPage extends StatefulWidget {
44 47
   State<ReapSampleTaskPage> createState() => _ReapSampleTaskPageState();
45 48
 }
46 49
 
47
-class _ReapSampleTaskPageState extends BaseState<ReapSampleTaskPage> with TickerProviderStateMixin {
50
+class _ReapSampleTaskPageState extends BaseLifecycleState<ReapSampleTaskPage> with TickerProviderStateMixin {
48 51
   late ReapSampleTaskPageArgs args;
52
+
53
+  final pageStatus = DataStatusModel<SampleTaskItem?>().notifier<DataStatusModel<SampleTaskItem?>>();
54
+
49 55
   late PageController pageCtrl;
50 56
 
51 57
   late List<String> tabTextList;
@@ -53,6 +59,13 @@ class _ReapSampleTaskPageState extends BaseState<ReapSampleTaskPage> with Ticker
53 59
 
54 60
   ValueNotifier<int> tabIndex = ValueNotifier(0);
55 61
 
62
+  void startEdit() async {
63
+    bool? success = await MyRouter.startReapSampleTask(args: ReapSampleTaskPageArgs(id: args.id));
64
+    if (success ?? false) {
65
+      MyNavigator.pop(true);
66
+    }
67
+  }
68
+
56 69
   void next() {
57 70
     if (tabIndex.value < tabTextList.length - 1) {
58 71
       pageCtrl.jumpToPage(tabIndex.value + 1);
@@ -64,27 +77,49 @@ class _ReapSampleTaskPageState extends BaseState<ReapSampleTaskPage> with Ticker
64 77
     pageCtrl.jumpToPage(tabIndex.value - 1);
65 78
   }
66 79
 
67
-  void submit() {
68
-    MyNavigator.pop();
69
-    MyNavigator.showToast('提交成功');
80
+  void submit() async {
81
+    MyNavigator.showLoading();
82
+    try {
83
+      var rsp = await MyApi.get().updateSampleTaskSgjc((pageStatus.value.data ?? SampleTaskItem()).toJson());
84
+      if (!mounted) return;
85
+      if (rsp.data ?? false) {
86
+        MyNavigator.showToast('提交成功');
87
+        MyNavigator.pop(true);
88
+      } else {
89
+        MyNavigator.showToast('提交失败');
90
+      }
91
+    } catch (e) {}
92
+    MyNavigator.dismissLoading();
70 93
   }
71 94
 
72
-  @override
73
-  void initState() {
74
-    super.initState();
75
-    args = widget.args;
76
-    tabTextList = ['基础信息', '品种信息', '灾害污染', '用药情况', '检验机构'];
95
+  void getDetailData() async {
96
+    pageStatus.update(pageStatus.value.loading());
97
+    try {
98
+      var rsp = await MyApi.get().sampleTaskDetailSgjc(args.id ?? -1);
99
+      var data = rsp.data;
100
+      if (data == null) {
101
+        pageStatus.update(pageStatus.value.empty());
102
+      } else {
103
+        cratePageList(data);
104
+        pageStatus.update(pageStatus.value.success(data: data));
105
+      }
106
+    } catch (e) {
107
+      pageStatus.update(pageStatus.value.error());
108
+    }
109
+  }
110
+
111
+  void cratePageList(SampleTaskItem data) {
77 112
     if (args.detail) {
78 113
       pageList = [
79
-        ReapSampleBasicDetailPage(args.data),
80
-        ReapSampleVarietyDetailPage(args.data),
81
-        ReapSampleDisasterDetailPage(args.data),
82
-        ReapSampleMedicineDetailPage(args.data),
83
-        ReapSampleOrgDetailPage(args.data),
114
+        ReapSampleBasicDetailPage(data),
115
+        ReapSampleVarietyDetailPage(data),
116
+        ReapSampleDisasterDetailPage(data),
117
+        ReapSampleMedicineDetailPage(data),
118
+        ReapSampleOrgDetailPage(data),
84 119
       ];
85 120
     } else {
86 121
       pageList = [
87
-        ReapSampleBasicDetailPage(args.data, detail: false, nextCallback: next),
122
+        ReapSampleBasicDetailPage(data, detail: false, nextCallback: next),
88 123
         // ReapSampleBasicPage(nextCallback: next),
89 124
         ReapSampleVarietyPage(nextCallback: next, previousCallback: previous),
90 125
         ReapSampleDisasterPage(nextCallback: next, previousCallback: previous),
@@ -92,11 +127,28 @@ class _ReapSampleTaskPageState extends BaseState<ReapSampleTaskPage> with Ticker
92 127
         ReapSampleOrgPage(previousCallback: previous, submitCallback: submit),
93 128
       ];
94 129
     }
130
+  }
95 131
 
132
+  @override
133
+  void initState() {
134
+    super.initState();
135
+    args = widget.args;
136
+    tabTextList = ['基础信息', '品种信息', '灾害污染', '用药情况', '检验机构'];
96 137
     pageCtrl = PageController();
97 138
   }
98 139
 
99 140
   @override
141
+  void onFirstShow(Duration timeStamp) {
142
+    getDetailData();
143
+  }
144
+
145
+  @override
146
+  void onDestroy() {
147
+    pageStatus.dispose();
148
+    pageCtrl.dispose();
149
+  }
150
+
151
+  @override
100 152
   Widget build(BuildContext context) {
101 153
     return myScaffold(child: buildBody());
102 154
   }
@@ -107,21 +159,29 @@ class _ReapSampleTaskPageState extends BaseState<ReapSampleTaskPage> with Ticker
107 159
       child: Column(
108 160
         children: [
109 161
           myAppBar(title: args.detail ? '扦样完成详情' : '扦样任务单'),
110
-          Expanded(
111
-            child: Container(
112
-              clipBehavior: Clip.hardEdge,
113
-              decoration: const BoxDecoration(
114
-                color: Colors.white,
115
-                borderRadius: BorderRadius.vertical(top: Radius.circular(16)),
116
-              ),
117
-              child: Column(
118
-                children: [
119
-                  buildTab(),
120
-                  Expanded(child: buildPage()),
121
-                ],
122
-              ),
123
-            ),
124
-          ),
162
+          pageStatus.builder((v) {
163
+            return switch (v.status) {
164
+              DataStatus.loading => const PageLoadingWidget.loading(),
165
+              DataStatus.error => PageLoadingWidget.error(onTap: getDetailData),
166
+              DataStatus.success => Expanded(
167
+                  child: Container(
168
+                    clipBehavior: Clip.hardEdge,
169
+                    decoration: const BoxDecoration(
170
+                      color: Colors.white,
171
+                      borderRadius: BorderRadius.vertical(top: Radius.circular(16)),
172
+                    ),
173
+                    child: Column(
174
+                      children: [
175
+                        buildTab(),
176
+                        Expanded(child: buildPage()),
177
+                        buildButton(),
178
+                      ],
179
+                    ),
180
+                  ),
181
+                ),
182
+              _ => const PageLoadingWidget.empty(),
183
+            };
184
+          }),
125 185
         ],
126 186
       ),
127 187
     );
@@ -205,4 +265,38 @@ class _ReapSampleTaskPageState extends BaseState<ReapSampleTaskPage> with Ticker
205 265
       itemBuilder: (_, index) => pageList[index],
206 266
     );
207 267
   }
268
+
269
+  Widget buildButton() {
270
+    Widget child;
271
+    if (args.detail) {
272
+      child = MyButton('重新录入', onTap: startEdit);
273
+    } else {
274
+      child = tabIndex.builder((v) {
275
+        // 第一页
276
+        if (v == 0) return MyButton('下一步', onTap: next);
277
+        // 最后一页
278
+        if (v == tabTextList.length - 1) {
279
+          return Row(
280
+            children: [
281
+              Expanded(flex: 2, child: MyButton('上一步', onTap: previous)),
282
+              const Spacer(flex: 1),
283
+              Expanded(flex: 2, child: MyButton('提交', onTap: submit)),
284
+            ],
285
+          );
286
+        }
287
+        return Row(
288
+          children: [
289
+            Expanded(flex: 2, child: MyButton('上一步', onTap: previous)),
290
+            const Spacer(flex: 1),
291
+            Expanded(flex: 2, child: MyButton('下一步', onTap: next)),
292
+          ],
293
+        );
294
+      });
295
+    }
296
+    return Container(
297
+      color: const Color(0xFFF1F7F6),
298
+      padding: const EdgeInsets.all(12),
299
+      child: child,
300
+    );
301
+  }
208 302
 }

+ 1 - 33
lib/page/sample_task/reap_sample_task/reap_sample_variety_page.dart

@@ -1,7 +1,6 @@
1 1
 import 'package:flutter/material.dart';
2 2
 import 'package:lszlgl/base/base_state.dart';
3 3
 import 'package:lszlgl/utils/date_time_utils.dart';
4
-import 'package:lszlgl/widget/button.dart';
5 4
 import 'package:lszlgl/widget/card_item.dart';
6 5
 
7 6
 /// 收获扦样-品种信息
@@ -51,12 +50,7 @@ class _ReapSampleVarietyPageState extends BaseState<ReapSampleVarietyPage> with
51 50
   @override
52 51
   Widget build(BuildContext context) {
53 52
     super.build(context);
54
-    return Column(
55
-      children: [
56
-        Expanded(child: SingleChildScrollView(child: buildList())),
57
-        buildButton(),
58
-      ],
59
-    );
53
+    return SingleChildScrollView(child: buildList());
60 54
   }
61 55
 
62 56
   Widget buildList() {
@@ -96,32 +90,6 @@ class _ReapSampleVarietyPageState extends BaseState<ReapSampleVarietyPage> with
96 90
     );
97 91
   }
98 92
 
99
-  Widget buildButton() {
100
-    return Container(
101
-      color: const Color(0xFFF1F7F6),
102
-      padding: const EdgeInsets.all(12),
103
-      child: Row(
104
-        children: [
105
-          Expanded(
106
-            flex: 2,
107
-            child: MyButton(
108
-              '上一步',
109
-              onTap: widget.previousCallback,
110
-            ),
111
-          ),
112
-          const Spacer(flex: 1),
113
-          Expanded(
114
-            flex: 2,
115
-            child: MyButton(
116
-              '下一步',
117
-              onTap: widget.nextCallback,
118
-            ),
119
-          ),
120
-        ],
121
-      ),
122
-    );
123
-  }
124
-
125 93
   Widget buildField({String? hint, TextInputType? inputType}) {
126 94
     return TextField(
127 95
       keyboardType: inputType,

+ 3 - 2
lib/page/sample_task/sample_list_vm.dart

@@ -5,7 +5,8 @@ import 'package:lszlgl/base/base_vm.dart';
5 5
 import 'package:lszlgl/main.dart';
6 6
 import 'package:lszlgl/model/req/sample_task_list_req.dart';
7 7
 import 'package:lszlgl/model/rsp/sample_task_rsp.dart';
8
-import 'package:lszlgl/network/api.dart';
8
+
9
+import '../../network/my_api.dart';
9 10
 
10 11
 class SampleListVM extends BaseVM {
11 12
   SampleListVM() {
@@ -62,7 +63,7 @@ class SampleListVM extends BaseVM {
62 63
       req.pageNo = 1;
63 64
     }
64 65
     try {
65
-      var value = await Api().sampleTaskList(req.toJson());
66
+      var value = await MyApi.get().sampleTaskList(req.toJson());
66 67
       List<SampleTaskItem> data = value.data?.list ?? [];
67 68
       var list = pageState.value.data ?? [];
68 69
       if (refresh) {

+ 11 - 13
lib/page/sample_task/sample_task_list_page.dart

@@ -34,25 +34,20 @@ class _SampleTaskListPageState extends BaseLifecycleState<SampleTaskListPage> wi
34 34
   late SampleListVM vm;
35 35
 
36 36
   /// 详情
37
-  void startDetail(SampleTaskItem data) {
38
-    if (!widget.complete) return;
37
+  void startTaskDetail(bool detail, SampleTaskItem data) {
39 38
     switch (widget.type) {
40 39
       case StepType.reap:
41
-        MyRouter.startReapSampleTask(args: ReapSampleTaskPageArgs(detail: true, data: data));
40
+        startDetail(ReapSampleTaskPageArgs(detail: detail, id: data.id));
42 41
         break;
43 42
       case StepType.stock:
44 43
         break;
45 44
     }
46 45
   }
47 46
 
48
-  /// 扦样
49
-  void startSample(SampleTaskItem data) {
50
-    switch (widget.type) {
51
-      case StepType.reap:
52
-        MyRouter.startReapSampleTask(args: ReapSampleTaskPageArgs(detail: false, data: data));
53
-        break;
54
-      case StepType.stock:
55
-        break;
47
+  void startDetail(ReapSampleTaskPageArgs args) async {
48
+    bool? success = await MyRouter.startReapSampleTask(args: args);
49
+    if (success ?? false) {
50
+      vm.refreshAll();
56 51
     }
57 52
   }
58 53
 
@@ -114,7 +109,10 @@ class _SampleTaskListPageState extends BaseLifecycleState<SampleTaskListPage> wi
114 109
   Widget buildItem(int index, SampleTaskItem item) {
115 110
     return GestureDetector(
116 111
       behavior: HitTestBehavior.opaque,
117
-      onTap: () => startDetail(item),
112
+      onTap: () {
113
+        if (!widget.complete) return;
114
+        startTaskDetail(true, item);
115
+      },
118 116
       child: Container(
119 117
         margin: const EdgeInsets.only(left: 12, right: 12, top: 12),
120 118
         decoration: const BoxDecoration(
@@ -244,7 +242,7 @@ class _SampleTaskListPageState extends BaseLifecycleState<SampleTaskListPage> wi
244 242
             const SizedBox(width: 4),
245 243
             MyButton(
246 244
               '开始扦样',
247
-              onTap: () => startSample(item),
245
+              onTap: () => startTaskDetail(false, item),
248 246
               fountSize: 13,
249 247
               alignment: null,
250 248
               padding: const EdgeInsets.symmetric(vertical: 6, horizontal: 12),

+ 3 - 2
lib/page/user_center/user_center_page.dart

@@ -4,10 +4,11 @@ import 'package:flutter/material.dart';
4 4
 import 'package:lszlgl/base/base_lifecycle_state.dart';
5 5
 import 'package:lszlgl/base/base_state.dart';
6 6
 import 'package:lszlgl/model/rsp/user_rsp.dart';
7
-import 'package:lszlgl/network/api.dart';
8 7
 import 'package:lszlgl/service/user_service.dart';
9 8
 import 'package:lszlgl/widget/card_item.dart';
10 9
 
10
+import '../../network/my_api.dart';
11
+
11 12
 /// 用户中心
12 13
 class UserCenterPage extends StatefulWidget {
13 14
   const UserCenterPage({Key? key}) : super(key: key);
@@ -29,7 +30,7 @@ class _UserCenterPageState extends BaseLifecycleState<UserCenterPage> with Autom
29 30
 
30 31
   Future<void> onRefresh() async {
31 32
     try {
32
-      var value = await Api().userProfile();
33
+      var value = await MyApi.get().userProfile();
33 34
       if (value.data != null) userNotify.value = value.data;
34 35
     } catch (err) {}
35 36
   }

+ 4 - 4
lib/router/my_router.dart

@@ -70,12 +70,12 @@ class MyRouter {
70 70
   }
71 71
 
72 72
   /// 收获环节列表
73
-  static void startSampleTaskList(SampleTaskListTabPageArgs args) {
74
-    MyNavigator.push(rSampleTaskListTabPage, args: args);
73
+  static Future<dynamic> startSampleTaskList(SampleTaskListTabPageArgs args) {
74
+    return MyNavigator.push(rSampleTaskListTabPage, args: args);
75 75
   }
76 76
 
77 77
   /// 收获扦样任务
78
-  static void startReapSampleTask({ReapSampleTaskPageArgs? args}) {
79
-    MyNavigator.push(rReapSampleTaskPage, args: args ?? ReapSampleTaskPageArgs());
78
+  static Future<dynamic> startReapSampleTask({ReapSampleTaskPageArgs? args}) {
79
+    return MyNavigator.push(rReapSampleTaskPage, args: args ?? ReapSampleTaskPageArgs());
80 80
   }
81 81
 }

+ 2 - 2
lib/service/upgrade_service.dart

@@ -7,7 +7,7 @@ import 'package:path_provider/path_provider.dart';
7 7
 import 'package:permission_handler/permission_handler.dart';
8 8
 
9 9
 import '../main.dart';
10
-import '../network/api.dart';
10
+import '../network/my_api.dart';
11 11
 import '../router/my_navigator.dart';
12 12
 import '../widget/upgrade_dialog.dart';
13 13
 
@@ -64,7 +64,7 @@ class UpgradeService {
64 64
     if (showLoading) MyNavigator.showLoading();
65 65
     try {
66 66
       // 获取apk下载地址
67
-      var path = (await Api().getAppDownloadUrl()).data;
67
+      var path = (await MyApi.get().getAppDownloadUrl()).data;
68 68
       if (showLoading) MyNavigator.dismissLoading();
69 69
       if (path != null) {
70 70
         // 获取线上版本 lszlgl_release_0.0.2_2.apk

+ 133 - 0
lib/widget/card_item.dart

@@ -1,5 +1,9 @@
1 1
 import 'package:flutter/material.dart';
2 2
 import 'package:lszlgl/config/colors.dart';
3
+import 'package:lszlgl/ext/value_notifier_ext.dart';
4
+
5
+import '../config/pics.dart';
6
+import '../router/my_navigator.dart';
3 7
 
4 8
 class CardItemWidget extends StatelessWidget {
5 9
   /// 标题文本
@@ -124,3 +128,132 @@ class CardItemWidget extends StatelessWidget {
124 128
     );
125 129
   }
126 130
 }
131
+
132
+class CardItemMenuWidget extends StatelessWidget {
133
+  /// 标题文本
134
+  final String title;
135
+
136
+  /// 左侧icon
137
+  final Widget? leading;
138
+
139
+  final String? hint;
140
+
141
+  /// 右侧组件对齐方式
142
+  final AlignmentGeometry rightAlign;
143
+  final bool showTopLine;
144
+  final bool bottomLine;
145
+
146
+  final Color? backgroundColor;
147
+
148
+  final ValueNotifier<List<CardMenuData>> listNotifier;
149
+  final ValueNotifier<CardMenuData?> selNotifier;
150
+
151
+  final void Function(ValueNotifier<CardMenuData?>, CardMenuData)? onSelectTap;
152
+
153
+  const CardItemMenuWidget(
154
+    this.title,
155
+    this.listNotifier,
156
+    this.selNotifier, {
157
+    Key? key,
158
+    this.leading,
159
+    this.hint,
160
+    this.rightAlign = Alignment.centerRight,
161
+    this.showTopLine = false,
162
+    this.bottomLine = false,
163
+    this.backgroundColor = Colors.white,
164
+    this.onSelectTap,
165
+  }) : super(key: key);
166
+
167
+  @override
168
+  Widget build(BuildContext context) {
169
+    return CardItemWidget(
170
+      title,
171
+      leading: leading,
172
+      rightAlign: rightAlign,
173
+      showTopLine: showTopLine,
174
+      bottomLine: bottomLine,
175
+      backgroundColor: backgroundColor,
176
+      rightChild: buildMenu(),
177
+    );
178
+  }
179
+
180
+  Widget buildMenu() {
181
+    return listNotifier.builder(
182
+      (list) => selNotifier.builder(
183
+        (selData) {
184
+          return MenuAnchor(
185
+            style: const MenuStyle(
186
+              padding: MaterialStatePropertyAll(EdgeInsets.zero),
187
+              alignment: Alignment.bottomRight,
188
+            ),
189
+            builder: (_, ctrl, __) => buildMenuLabel(ctrl, selData),
190
+            menuChildren: List.generate(list.length, (index) {
191
+              return buildMenuItem(list[index], selData);
192
+            }).toList(),
193
+          );
194
+        },
195
+      ),
196
+    );
197
+  }
198
+
199
+  /// 菜单栏
200
+  Widget buildMenuLabel(MenuController ctrl, CardMenuData? selData) {
201
+    return GestureDetector(
202
+      behavior: HitTestBehavior.opaque,
203
+      onTap: () {
204
+        if (listNotifier.value.isEmpty) {
205
+          MyNavigator.showToast('没有选项数据');
206
+          return;
207
+        }
208
+        if (ctrl.isOpen) {
209
+          ctrl.close();
210
+        } else {
211
+          ctrl.open();
212
+        }
213
+      },
214
+      child: Row(
215
+        mainAxisSize: MainAxisSize.min,
216
+        children: [
217
+          Expanded(
218
+            child: Text(
219
+              selData?.name ?? '',
220
+              textAlign: TextAlign.right,
221
+              style: const TextStyle(
222
+                color: Color(0xFF01B2C8),
223
+                fontSize: 14,
224
+                fontWeight: FontWeight.w500,
225
+              ),
226
+            ),
227
+          ),
228
+          const SizedBox(width: 8),
229
+          Image.asset(imgItemArrowDown, width: 20),
230
+        ],
231
+      ),
232
+    );
233
+  }
234
+
235
+  Widget buildMenuItem(CardMenuData item, CardMenuData? selData) {
236
+    return MenuItemButton(
237
+      onPressed: () {
238
+        if (item.value == selData?.value) return;
239
+        selNotifier.value = item;
240
+        onSelectTap?.call(selNotifier, item);
241
+      },
242
+      child: Container(
243
+        constraints: const BoxConstraints(minWidth: 120),
244
+        alignment: Alignment.center,
245
+        child: Text(
246
+          item.name ?? '',
247
+          style: TextStyle(color: item.value == selData?.value ? const Color(0xFF01B2C8) : MyColor.c_666666),
248
+        ),
249
+      ),
250
+    );
251
+  }
252
+}
253
+
254
+class CardMenuData {
255
+  String? name;
256
+  dynamic value;
257
+
258
+  CardMenuData(this.name, this.value);
259
+}

File diff suppressed because it is too large
+ 140 - 140
pubspec.lock