Sfoglia il codice sorgente

增加修改密码。

liujq 1 anno fa
parent
commit
c585f16846

+ 5 - 0
android/build.gradle

@@ -1,4 +1,9 @@
1
 allprojects {
1
 allprojects {
2
+    gradle.projectsEvaluated {
3
+        tasks.withType(JavaCompile) {
4
+            options.compilerArgs << "-Xlint:unchecked"
5
+        }
6
+    }
2
     repositories {
7
     repositories {
3
         google()
8
         google()
4
         mavenCentral()
9
         mavenCentral()

+ 1 - 1
ios/Flutter/AppFrameworkInfo.plist

@@ -21,6 +21,6 @@
21
   <key>CFBundleVersion</key>
21
   <key>CFBundleVersion</key>
22
   <string>1.0</string>
22
   <string>1.0</string>
23
   <key>MinimumOSVersion</key>
23
   <key>MinimumOSVersion</key>
24
-  <string>11.0</string>
24
+  <string>12.0</string>
25
 </dict>
25
 </dict>
26
 </plist>
26
 </plist>

+ 1 - 1
ios/Podfile

@@ -1,5 +1,5 @@
1
 # Uncomment this line to define a global platform for your project
1
 # Uncomment this line to define a global platform for your project
2
-# platform :ios, '11.0'
2
+platform :ios, '12.0'
3
 
3
 
4
 # CocoaPods analytics sends network stats synchronously affecting flutter build latency.
4
 # CocoaPods analytics sends network stats synchronously affecting flutter build latency.
5
 ENV['COCOAPODS_DISABLE_STATS'] = 'true'
5
 ENV['COCOAPODS_DISABLE_STATS'] = 'true'

+ 4 - 4
ios/Runner.xcodeproj/project.pbxproj

@@ -169,7 +169,7 @@
169
 			isa = PBXProject;
169
 			isa = PBXProject;
170
 			attributes = {
170
 			attributes = {
171
 				BuildIndependentTargetsInParallel = YES;
171
 				BuildIndependentTargetsInParallel = YES;
172
-				LastUpgradeCheck = 1430;
172
+				LastUpgradeCheck = 1510;
173
 				ORGANIZATIONNAME = "";
173
 				ORGANIZATIONNAME = "";
174
 				TargetAttributes = {
174
 				TargetAttributes = {
175
 					331C8080294A63A400263BE5 = {
175
 					331C8080294A63A400263BE5 = {
@@ -345,7 +345,7 @@
345
 				GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
345
 				GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
346
 				GCC_WARN_UNUSED_FUNCTION = YES;
346
 				GCC_WARN_UNUSED_FUNCTION = YES;
347
 				GCC_WARN_UNUSED_VARIABLE = YES;
347
 				GCC_WARN_UNUSED_VARIABLE = YES;
348
-				IPHONEOS_DEPLOYMENT_TARGET = 11.0;
348
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
349
 				MTL_ENABLE_DEBUG_INFO = NO;
349
 				MTL_ENABLE_DEBUG_INFO = NO;
350
 				SDKROOT = iphoneos;
350
 				SDKROOT = iphoneos;
351
 				SUPPORTED_PLATFORMS = iphoneos;
351
 				SUPPORTED_PLATFORMS = iphoneos;
@@ -472,7 +472,7 @@
472
 				GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
472
 				GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
473
 				GCC_WARN_UNUSED_FUNCTION = YES;
473
 				GCC_WARN_UNUSED_FUNCTION = YES;
474
 				GCC_WARN_UNUSED_VARIABLE = YES;
474
 				GCC_WARN_UNUSED_VARIABLE = YES;
475
-				IPHONEOS_DEPLOYMENT_TARGET = 11.0;
475
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
476
 				MTL_ENABLE_DEBUG_INFO = YES;
476
 				MTL_ENABLE_DEBUG_INFO = YES;
477
 				ONLY_ACTIVE_ARCH = YES;
477
 				ONLY_ACTIVE_ARCH = YES;
478
 				SDKROOT = iphoneos;
478
 				SDKROOT = iphoneos;
@@ -521,7 +521,7 @@
521
 				GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
521
 				GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
522
 				GCC_WARN_UNUSED_FUNCTION = YES;
522
 				GCC_WARN_UNUSED_FUNCTION = YES;
523
 				GCC_WARN_UNUSED_VARIABLE = YES;
523
 				GCC_WARN_UNUSED_VARIABLE = YES;
524
-				IPHONEOS_DEPLOYMENT_TARGET = 11.0;
524
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
525
 				MTL_ENABLE_DEBUG_INFO = NO;
525
 				MTL_ENABLE_DEBUG_INFO = NO;
526
 				SDKROOT = iphoneos;
526
 				SDKROOT = iphoneos;
527
 				SUPPORTED_PLATFORMS = iphoneos;
527
 				SUPPORTED_PLATFORMS = iphoneos;

+ 1 - 1
ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme

@@ -1,6 +1,6 @@
1
 <?xml version="1.0" encoding="UTF-8"?>
1
 <?xml version="1.0" encoding="UTF-8"?>
2
 <Scheme
2
 <Scheme
3
-   LastUpgradeVersion = "1430"
3
+   LastUpgradeVersion = "1510"
4
    version = "1.3">
4
    version = "1.3">
5
    <BuildAction
5
    <BuildAction
6
       parallelizeBuildables = "YES"
6
       parallelizeBuildables = "YES"

+ 9 - 1
lib/network/api.dart

@@ -8,6 +8,7 @@ import 'package:lszlgl/model/rsp/login_rsp.dart';
8
 import 'package:lszlgl/model/rsp/sample_task_rsp.dart';
8
 import 'package:lszlgl/model/rsp/sample_task_rsp.dart';
9
 import 'package:lszlgl/model/rsp/user_rsp.dart';
9
 import 'package:lszlgl/model/rsp/user_rsp.dart';
10
 import 'package:lszlgl/network/base_dio.dart';
10
 import 'package:lszlgl/network/base_dio.dart';
11
+import 'package:retrofit/http.dart';
11
 import 'package:retrofit/retrofit.dart';
12
 import 'package:retrofit/retrofit.dart';
12
 
13
 
13
 import '../model/req/device_req.dart';
14
 import '../model/req/device_req.dart';
@@ -94,5 +95,12 @@ abstract class Api {
94
   /// 提交设备绑定信息
95
   /// 提交设备绑定信息
95
   @POST('/admin-api/zj/base-device/createBatch')
96
   @POST('/admin-api/zj/base-device/createBatch')
96
   Future<ApiRsp> postDeviceInfos(@Body() List<DeviceReq> req);
97
   Future<ApiRsp> postDeviceInfos(@Body() List<DeviceReq> req);
97
-
98
+  
99
+  /// 获取手机验证码
100
+  @POST('/admin-api/system/auth/reset_password_send_sms_code')
101
+  Future<ApiRsp<bool?>> postPhoneMsg(@Body() Map<String, dynamic> map);
102
+
103
+  ///忘记密码
104
+  @POST('/admin-api/system/auth/reset_password')
105
+  Future<ApiRsp<bool?>> resetPassword(@Body() Map<String, dynamic> map);
98
 }
106
 }

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

@@ -574,6 +574,68 @@ class _Api implements Api {
574
     return value;
574
     return value;
575
   }
575
   }
576
 
576
 
577
+  @override
578
+  Future<ApiRsp<bool?>> postPhoneMsg(Map<String, dynamic> map) async {
579
+    const _extra = <String, dynamic>{};
580
+    final queryParameters = <String, dynamic>{};
581
+    final _headers = <String, dynamic>{};
582
+    final _data = <String, dynamic>{};
583
+    _data.addAll(map);
584
+    final _result = await _dio
585
+        .fetch<Map<String, dynamic>>(_setStreamType<ApiRsp<bool>>(Options(
586
+      method: 'POST',
587
+      headers: _headers,
588
+      extra: _extra,
589
+    )
590
+            .compose(
591
+              _dio.options,
592
+              '/admin-api/system/auth/reset_password_send_sms_code',
593
+              queryParameters: queryParameters,
594
+              data: _data,
595
+            )
596
+            .copyWith(
597
+                baseUrl: _combineBaseUrls(
598
+              _dio.options.baseUrl,
599
+              baseUrl,
600
+            ))));
601
+    final value = ApiRsp<bool?>.fromJson(
602
+      _result.data!,
603
+      (json) => json as bool?,
604
+    );
605
+    return value;
606
+  }
607
+
608
+  @override
609
+  Future<ApiRsp<bool?>> resetPassword(Map<String, dynamic> map) async {
610
+    const _extra = <String, dynamic>{};
611
+    final queryParameters = <String, dynamic>{};
612
+    final _headers = <String, dynamic>{};
613
+    final _data = <String, dynamic>{};
614
+    _data.addAll(map);
615
+    final _result = await _dio
616
+        .fetch<Map<String, dynamic>>(_setStreamType<ApiRsp<bool>>(Options(
617
+      method: 'POST',
618
+      headers: _headers,
619
+      extra: _extra,
620
+    )
621
+            .compose(
622
+              _dio.options,
623
+              '/admin-api/system/auth/reset_password',
624
+              queryParameters: queryParameters,
625
+              data: _data,
626
+            )
627
+            .copyWith(
628
+                baseUrl: _combineBaseUrls(
629
+              _dio.options.baseUrl,
630
+              baseUrl,
631
+            ))));
632
+    final value = ApiRsp<bool?>.fromJson(
633
+      _result.data!,
634
+      (json) => json as bool?,
635
+    );
636
+    return value;
637
+  }
638
+
577
   RequestOptions _setStreamType<T>(RequestOptions requestOptions) {
639
   RequestOptions _setStreamType<T>(RequestOptions requestOptions) {
578
     if (T != dynamic &&
640
     if (T != dynamic &&
579
         !(requestOptions.responseType == ResponseType.bytes ||
641
         !(requestOptions.responseType == ResponseType.bytes ||

+ 1 - 1
lib/network/my_api.dart

@@ -7,7 +7,7 @@ class MyApi {
7
   MyApi._();
7
   MyApi._();
8
 
8
 
9
   /// 生产url
9
   /// 生产url
10
-  static String productUrl = 'http://121.36.17.6:49099';
10
+  static String productUrl = 'http://121.36.17.6:39099';
11
 
11
 
12
   /// 测试url
12
   /// 测试url
13
   static String testUrl = 'http://121.36.17.6:19090';
13
   static String testUrl = 'http://121.36.17.6:19090';

+ 37 - 11
lib/page/login/login_page.dart

@@ -28,6 +28,7 @@ class LoginPage extends StatefulWidget {
28
 class _LoginPageState extends BaseLifecycleState<LoginPage> {
28
 class _LoginPageState extends BaseLifecycleState<LoginPage> {
29
   late TextEditingController accountCtrl;
29
   late TextEditingController accountCtrl;
30
   late TextEditingController pwdCtrl;
30
   late TextEditingController pwdCtrl;
31
+  late ValueNotifier<bool> _showPwd;
31
 
32
 
32
   void onLogin() async {
33
   void onLogin() async {
33
     var account = accountCtrl.text;
34
     var account = accountCtrl.text;
@@ -94,6 +95,7 @@ class _LoginPageState extends BaseLifecycleState<LoginPage> {
94
   void onInit() {
95
   void onInit() {
95
     accountCtrl = TextEditingController();
96
     accountCtrl = TextEditingController();
96
     pwdCtrl = TextEditingController();
97
     pwdCtrl = TextEditingController();
98
+    _showPwd = ValueNotifier<bool>(true);
97
   }
99
   }
98
 
100
 
99
   @override
101
   @override
@@ -106,7 +108,8 @@ class _LoginPageState extends BaseLifecycleState<LoginPage> {
106
     RefreshConfig.get().initDefault();
108
     RefreshConfig.get().initDefault();
107
     LocationUtils.updatePrivacyShow(true, true);
109
     LocationUtils.updatePrivacyShow(true, true);
108
     LocationUtils.updatePrivacyAgree(true);
110
     LocationUtils.updatePrivacyAgree(true);
109
-    LocationUtils.setApiKey(kReleaseMode ? '2c783509376e267b24d63b21681686fa' : '7d0c033909f84adc14a0e60a835f044f', '');
111
+    LocationUtils.setApiKey(
112
+        kReleaseMode ? '2c783509376e267b24d63b21681686fa' : '7d0c033909f84adc14a0e60a835f044f', '');
110
 
113
 
111
     /// 获取手机设备信息
114
     /// 获取手机设备信息
112
     PrintService.getDeviceInfo();
115
     PrintService.getDeviceInfo();
@@ -214,7 +217,8 @@ class _LoginPageState extends BaseLifecycleState<LoginPage> {
214
       child: Container(
217
       child: Container(
215
         padding: const EdgeInsets.symmetric(horizontal: 24),
218
         padding: const EdgeInsets.symmetric(horizontal: 24),
216
         alignment: Alignment.center,
219
         alignment: Alignment.center,
217
-        decoration: const BoxDecoration(color: Colors.white, borderRadius: BorderRadius.all(Radius.circular(32))),
220
+        decoration: const BoxDecoration(
221
+            color: Colors.white, borderRadius: BorderRadius.all(Radius.circular(32))),
218
         child: Column(
222
         child: Column(
219
           children: [
223
           children: [
220
             const SizedBox(height: 56),
224
             const SizedBox(height: 56),
@@ -225,16 +229,36 @@ class _LoginPageState extends BaseLifecycleState<LoginPage> {
225
               action: TextInputAction.next,
229
               action: TextInputAction.next,
226
             ),
230
             ),
227
             const SizedBox(height: 32),
231
             const SizedBox(height: 32),
228
-            buildEdit(
229
-              ctrl: pwdCtrl,
230
-              hint: '请输入登录密码',
231
-              icon: imgLoginPwd,
232
-              obscure: true,
233
-              onSubmit: (value) => onLogin(),
234
-            ),
235
-            const SizedBox(height: 64),
232
+            ValueListenableBuilder(
233
+                valueListenable: _showPwd,
234
+                builder: (BuildContext ctx, bool show, Widget? child) {
235
+                  return buildEdit(
236
+                    ctrl: pwdCtrl,
237
+                    hint: '请输入登录密码',
238
+                    icon: imgLoginPwd,
239
+                    obscure: show,
240
+                    onSubmit: (value) => onLogin(),
241
+                    rightIcon: child,
242
+                  );
243
+                },
244
+                child: IconButton(
245
+                  icon: const Icon(Icons.remove_red_eye_outlined, size: 16, color: Color(0xFFBBBBBB)),
246
+                  onPressed: () {
247
+                    _showPwd.value = !_showPwd.value;
248
+                  },
249
+                )),
250
+            const SizedBox(height: 44),
236
             buildLoginBtn(),
251
             buildLoginBtn(),
237
-            const SizedBox(height: 48),
252
+            SizedBox(
253
+              width: double.infinity,
254
+              child: TextButton(
255
+                  onPressed: () {
256
+                    MyRouter.forgetPwd();
257
+                  },
258
+                  style: const ButtonStyle(alignment: Alignment.centerRight),
259
+                  child: const Text('忘记密码', style: TextStyle(color: Color(0xFF25A6EE), fontSize: 14))),
260
+            ),
261
+            const SizedBox(height: 18),
238
           ],
262
           ],
239
         ),
263
         ),
240
       ),
264
       ),
@@ -248,6 +272,7 @@ class _LoginPageState extends BaseLifecycleState<LoginPage> {
248
     TextInputAction action = TextInputAction.done,
272
     TextInputAction action = TextInputAction.done,
249
     bool obscure = false,
273
     bool obscure = false,
250
     ValueChanged? onSubmit,
274
     ValueChanged? onSubmit,
275
+    Widget? rightIcon,
251
   }) {
276
   }) {
252
     return TextField(
277
     return TextField(
253
       controller: ctrl,
278
       controller: ctrl,
@@ -268,6 +293,7 @@ class _LoginPageState extends BaseLifecycleState<LoginPage> {
268
         hintStyle: const TextStyle(color: Color(0xFFBBBBBB)),
293
         hintStyle: const TextStyle(color: Color(0xFFBBBBBB)),
269
         isDense: true,
294
         isDense: true,
270
         contentPadding: EdgeInsets.zero,
295
         contentPadding: EdgeInsets.zero,
296
+        suffixIcon: rightIcon,
271
       ),
297
       ),
272
       style: const TextStyle(fontSize: 14),
298
       style: const TextStyle(fontSize: 14),
273
       textInputAction: action,
299
       textInputAction: action,

+ 11 - 2
lib/page/print/print_page.dart

@@ -234,16 +234,25 @@ class _PrintPageState extends BaseLifecycleState<PrintPage> {
234
           myAppBar(title: '打印二维码'),
234
           myAppBar(title: '打印二维码'),
235
           const SizedBox(height: 18),
235
           const SizedBox(height: 18),
236
           buildServiceItem(serviceList[0]),
236
           buildServiceItem(serviceList[0]),
237
-          const Text('已连接打印机'),
237
+
238
+          Offstage(
239
+            offstage: PrintService.connectedDeviceList.isEmpty,
240
+            child: const Text('已连接打印机'),
241
+          ),
238
           ...List.generate(
242
           ...List.generate(
239
             PrintService.connectedDeviceList.length,
243
             PrintService.connectedDeviceList.length,
240
                 (index) => buildDeviceItem(PrintService.connectedDeviceList[index]),
244
                 (index) => buildDeviceItem(PrintService.connectedDeviceList[index]),
241
           ).toList(),
245
           ).toList(),
242
-          const Text('可用打印机'),
246
+
247
+          Offstage(
248
+            offstage: deviceList.isEmpty,
249
+            child: const Text('可用打印机'),
250
+          ),
243
           ...List.generate(
251
           ...List.generate(
244
             deviceList.length,
252
             deviceList.length,
245
                 (index) => buildDeviceItem(deviceList[index]),
253
                 (index) => buildDeviceItem(deviceList[index]),
246
           ).toList(),
254
           ).toList(),
255
+
247
           Offstage(
256
           Offstage(
248
             offstage: PrintService.connectedDeviceList.isEmpty,
257
             offstage: PrintService.connectedDeviceList.isEmpty,
249
             child: buildServiceItem(serviceList[1]),
258
             child: buildServiceItem(serviceList[1]),

+ 18 - 9
lib/page/user_center/change_pwd_page.dart

@@ -142,16 +142,25 @@ class _ChangePwdPageState extends BaseState<ChangePwdPage> {
142
     return Column(
142
     return Column(
143
       children: [
143
       children: [
144
         myAppBar(title: '修改密码'),
144
         myAppBar(title: '修改密码'),
145
-        buildList(),
146
-        const SizedBox(height: 32),
147
-        MyButton(
148
-          '确认修改',
149
-          onTap: onChange,
150
-          gradient: const LinearGradient(colors: [Color(0xFF3BD2E5), Color(0xFF247AF8)]),
151
-          alignment: Alignment.center,
152
-          minHeight: 40,
153
-          margin: const EdgeInsets.symmetric(horizontal: 24),
145
+        Expanded(
146
+          child: SingleChildScrollView(
147
+            child: Column(
148
+              children: [
149
+                buildList(),
150
+                const SizedBox(height: 32),
151
+                MyButton(
152
+                  '确认修改',
153
+                  onTap: onChange,
154
+                  gradient: const LinearGradient(colors: [Color(0xFF3BD2E5), Color(0xFF247AF8)]),
155
+                  alignment: Alignment.center,
156
+                  minHeight: 40,
157
+                  margin: const EdgeInsets.symmetric(horizontal: 24),
158
+                ),
159
+              ],
160
+            ),
161
+          ),
154
         ),
162
         ),
163
+
155
       ],
164
       ],
156
     );
165
     );
157
   }
166
   }

+ 9 - 0
lib/router/my_router.dart

@@ -1,4 +1,5 @@
1
 import 'package:lszlgl/base/base_lifecycle_state.dart';
1
 import 'package:lszlgl/base/base_lifecycle_state.dart';
2
+import 'package:lszlgl/page/login/forget_password_page.dart';
2
 import 'package:lszlgl/page/login/login_page.dart';
3
 import 'package:lszlgl/page/login/login_page.dart';
3
 import 'package:lszlgl/page/main_tab_page.dart';
4
 import 'package:lszlgl/page/main_tab_page.dart';
4
 import 'package:lszlgl/page/print/connect_print_page.dart';
5
 import 'package:lszlgl/page/print/connect_print_page.dart';
@@ -38,6 +39,8 @@ const rPrintPage = '/PrintPage';
38
 const rConnectPrintPage = '/ConnectPrintPage';
39
 const rConnectPrintPage = '/ConnectPrintPage';
39
 // 扫一扫
40
 // 扫一扫
40
 const rQrCodeScanPage = '/QrCodeScanPage';
41
 const rQrCodeScanPage = '/QrCodeScanPage';
42
+// 忘记密码
43
+const rForgetPasswordPage = '/ForgetPasswordPage';
41
 
44
 
42
 final Map<String, MyNavigatorBuilder> rRouteMap = {
45
 final Map<String, MyNavigatorBuilder> rRouteMap = {
43
   // 根页面
46
   // 根页面
@@ -53,6 +56,7 @@ final Map<String, MyNavigatorBuilder> rRouteMap = {
53
   rPrintPage: (context, args) => PrintPage(args: args as PrintPageArgs),
56
   rPrintPage: (context, args) => PrintPage(args: args as PrintPageArgs),
54
   rConnectPrintPage: (context, args) => ConnectPrintPage(args: args as ConnectPrintPageArgs),
57
   rConnectPrintPage: (context, args) => ConnectPrintPage(args: args as ConnectPrintPageArgs),
55
   rQrCodeScanPage: (context, args) => const QrCodeScanPage(),
58
   rQrCodeScanPage: (context, args) => const QrCodeScanPage(),
59
+  rForgetPasswordPage:(context,args) => const ForgetPasswordPage(),
56
 };
60
 };
57
 
61
 
58
 class MyRouter {
62
 class MyRouter {
@@ -91,6 +95,11 @@ class MyRouter {
91
     MyNavigator.push(rChangePwdPage, args: startHome);
95
     MyNavigator.push(rChangePwdPage, args: startHome);
92
   }
96
   }
93
 
97
 
98
+  /// 忘记密码
99
+  static void forgetPwd(){
100
+    MyNavigator.push(rForgetPasswordPage);
101
+  }
102
+
94
   /// 收获环节列表
103
   /// 收获环节列表
95
   static Future<dynamic> startSampleTaskList(SampleTaskListTabPageArgs args) {
104
   static Future<dynamic> startSampleTaskList(SampleTaskListTabPageArgs args) {
96
     return MyNavigator.push(rSampleTaskListTabPage, args: args);
105
     return MyNavigator.push(rSampleTaskListTabPage, args: args);

+ 12 - 0
lib/utils/string_utils.dart

@@ -17,4 +17,16 @@ class StringUtils {
17
       _ => '',
17
       _ => '',
18
     };
18
     };
19
   }
19
   }
20
+
21
+  /// 判断是否是手机号
22
+  static bool isPhoneNum(String? nums) {
23
+    if(nums == null){
24
+      return false;
25
+    }
26
+
27
+    RegExp mobile = RegExp(
28
+        r'^((13[0-9])|(14[0-9])|(15[0-9])|(16[0-9])|(17[0-9])|(18[0-9])|(19[0-9]))\d{8}$');
29
+    return mobile.hasMatch(nums);
30
+  }
31
+
20
 }
32
 }

+ 1 - 1
pubspec.yaml

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