李志伟 3 年前
父节点
当前提交
07b37a4787

二进制
images/login/VerificationCode.png 查看文件


二进制
images/login/checkedImg.png 查看文件


二进制
images/login/loginImg.png 查看文件


二进制
images/login/unChecked.png 查看文件


+ 28
- 103
lib/main.dart 查看文件

@@ -1,115 +1,40 @@
1 1
 import 'package:flutter/material.dart';
2
-
3
-void main() {
2
+import 'package:flutter_screenutil/flutter_screenutil.dart';
3
+import 'package:get_storage/get_storage.dart';
4
+import 'models/index.dart';
5
+import '../models/Store.dart';
6
+import 'package:get/get.dart';
7
+import 'routes/index.dart';
8
+
9
+Future<void> main() async {
10
+  await GetStorage.init();
4 11
   runApp(const MyApp());
5 12
 }
6 13
 
7 14
 class MyApp extends StatelessWidget {
8 15
   const MyApp({Key? key}) : super(key: key);
9
-
10
-  // This widget is the root of your application.
11
-  @override
12
-  Widget build(BuildContext context) {
13
-    return MaterialApp(
14
-      title: 'Flutter Demo',
15
-      theme: ThemeData(
16
-        // This is the theme of your application.
17
-        //
18
-        // Try running your application with "flutter run". You'll see the
19
-        // application has a blue toolbar. Then, without quitting the app, try
20
-        // changing the primarySwatch below to Colors.green and then invoke
21
-        // "hot reload" (press "r" in the console where you ran "flutter run",
22
-        // or simply save your changes to "hot reload" in a Flutter IDE).
23
-        // Notice that the counter didn't reset back to zero; the application
24
-        // is not restarted.
25
-        primarySwatch: Colors.blue,
26
-      ),
27
-      home: const MyHomePage(title: 'Flutter Demo Home Page'),
28
-    );
29
-  }
30
-}
31
-
32
-class MyHomePage extends StatefulWidget {
33
-  const MyHomePage({Key? key, required this.title}) : super(key: key);
34
-
35
-  // This widget is the home page of your application. It is stateful, meaning
36
-  // that it has a State object (defined below) that contains fields that affect
37
-  // how it looks.
38
-
39
-  // This class is the configuration for the state. It holds the values (in this
40
-  // case the title) provided by the parent (in this case the App widget) and
41
-  // used by the build method of the State. Fields in a Widget subclass are
42
-  // always marked "final".
43
-
44
-  final String title;
45
-
46
-  @override
47
-  State<MyHomePage> createState() => _MyHomePageState();
48
-}
49
-
50
-class _MyHomePageState extends State<MyHomePage> {
51
-  int _counter = 0;
52
-
53
-  void _incrementCounter() {
54
-    setState(() {
55
-      // This call to setState tells the Flutter framework that something has
56
-      // changed in this State, which causes it to rerun the build method below
57
-      // so that the display can reflect the updated values. If we changed
58
-      // _counter without calling setState(), then the build method would not be
59
-      // called again, and so nothing would appear to happen.
60
-      _counter++;
61
-    });
62
-  }
16
+// debugShowCheckerModeBanner:false,
63 17
 
64 18
   @override
65 19
   Widget build(BuildContext context) {
66
-    // This method is rerun every time setState is called, for instance as done
67
-    // by the _incrementCounter method above.
68
-    //
69
-    // The Flutter framework has been optimized to make rerunning build methods
70
-    // fast, so that you can just rebuild anything that needs updating rather
71
-    // than having to individually change instances of widgets.
72
-    return Scaffold(
73
-      appBar: AppBar(
74
-        // Here we take the value from the MyHomePage object that was created by
75
-        // the App.build method, and use it to set our appbar title.
76
-        title: Text(widget.title),
77
-      ),
78
-      body: Center(
79
-        // Center is a layout widget. It takes a single child and positions it
80
-        // in the middle of the parent.
81
-        child: Column(
82
-          // Column is also a layout widget. It takes a list of children and
83
-          // arranges them vertically. By default, it sizes itself to fit its
84
-          // children horizontally, and tries to be as tall as its parent.
85
-          //
86
-          // Invoke "debug painting" (press "p" in the console, choose the
87
-          // "Toggle Debug Paint" action from the Flutter Inspector in Android
88
-          // Studio, or the "Toggle Debug Paint" command in Visual Studio Code)
89
-          // to see the wireframe for each widget.
90
-          //
91
-          // Column has various properties to control how it sizes itself and
92
-          // how it positions its children. Here we use mainAxisAlignment to
93
-          // center the children vertically; the main axis here is the vertical
94
-          // axis because Columns are vertical (the cross axis would be
95
-          // horizontal).
96
-          mainAxisAlignment: MainAxisAlignment.center,
97
-          children: <Widget>[
98
-            const Text(
99
-              'You have pushed the button this many times:',
100
-            ),
101
-            Text(
102
-              '$_counter',
103
-              style: Theme.of(context).textTheme.headline4,
104
-            ),
105
-          ],
106
-        ),
107
-      ),
108
-      floatingActionButton: FloatingActionButton(
109
-        onPressed: _incrementCounter,
110
-        tooltip: 'Increment',
111
-        child: const Icon(Icons.add),
112
-      ), // This trailing comma makes auto-formatting nicer for build methods.
20
+    Store().init();
21
+
22
+    return ScreenUtilInit(
23
+      designSize: const Size(375, 812),
24
+      minTextAdapt: true,
25
+      splitScreenMode: true,
26
+      builder: (_) {
27
+        return GetMaterialApp(
28
+          initialRoute: '/splash',
29
+          defaultTransition: Transition.native,
30
+          routingCallback: routingCallback,
31
+          initialBinding: AppBindings(),
32
+          getPages: pages,
33
+        );
34
+      },
113 35
     );
36
+    // return const GetMaterialApp(
37
+    //   home: Login(),
38
+    // );
114 39
   }
115 40
 }

+ 11
- 0
lib/models/Store.dart 查看文件

@@ -0,0 +1,11 @@
1
+
2
+import '../models/User.dart';
3
+import 'package:get/get.dart';
4
+
5
+class Store {
6
+  Store();
7
+
8
+  init() {
9
+    Get.put(User(), tag: 'user');
10
+  }
11
+}

+ 15
- 0
lib/models/User.dart 查看文件

@@ -0,0 +1,15 @@
1
+
2
+import '/models/entities/person.dart';
3
+import 'package:get/get.dart';
4
+
5
+class User extends GetxController {
6
+  Person? _person;
7
+  Person? get person => _person;
8
+  set person (Person? p) {
9
+    _person = p;
10
+    update();
11
+  }
12
+
13
+  bool get isLogin => _person != null;
14
+
15
+}

+ 47
- 0
lib/models/app.dart 查看文件

@@ -0,0 +1,47 @@
1
+
2
+import 'dart:io';
3
+
4
+import './entities/person.dart';
5
+import 'package:get/get.dart';
6
+import 'package:location/location.dart';
7
+import '../services/user.dart';
8
+import '../utils/location.dart';
9
+
10
+class AppController extends GetxController {
11
+  // 有了这句, 可以直接 AppController.t 调用
12
+  static AppController t = Get.find();
13
+
14
+  final user = Rx<Person>(Person());
15
+  final location = Rxn<LocationData>();
16
+  final testInt = 1.obs;
17
+
18
+  @override
19
+  void onInit() {
20
+    super.onInit();
21
+
22
+    // 尝试获取 location
23
+    requireLocation().then((loc) async {
24
+      var _data = await loc.getLocation();
25
+      location(_data);
26
+
27
+      // 监听位置变化
28
+      loc.onLocationChanged.listen((LocationData currentLocation) {
29
+        location(currentLocation);
30
+      });
31
+    }).catchError((e) {
32
+      print(e);
33
+      Get.defaultDialog(
34
+        title: e.message,
35
+        onConfirm: () => exit(1),
36
+      );
37
+    });
38
+
39
+    // 尝试获取一次人员信息
40
+    // getCurrent().then((person) {
41
+    //   user(person);
42
+    // }).catchError((e) {
43
+    //   print(e);
44
+    // });
45
+  }
46
+
47
+}

+ 40
- 0
lib/models/entities/person.dart 查看文件

@@ -0,0 +1,40 @@
1
+
2
+class Person {
3
+  String? personId;
4
+  String? appId;
5
+  String? openid;
6
+  String? nickName;
7
+  String? avatar;
8
+  int? sex;
9
+  String? phone;
10
+  String? userId;
11
+  int? status;
12
+  String? createDate;
13
+
14
+  Person ();
15
+
16
+  Person.fromJson(Map<String, dynamic> json)
17
+      : personId = json["personId"],
18
+        appId = json["appId"],
19
+        openid = json["openid"],
20
+        nickName = json["nickName"],
21
+        avatar = json["avatar"],
22
+        sex = json["sex"],
23
+        phone = json["phone"],
24
+        userId = json["userId"],
25
+        status = json["status"],
26
+        createDate = json["createDate"];
27
+
28
+  Map<String, dynamic> toJson() => {
29
+    'personId' : personId,
30
+    'appId' : appId,
31
+    'openid' : openid,
32
+    'nickName' : nickName,
33
+    'avatar' : avatar,
34
+    'sex' : sex,
35
+    'phone' : phone,
36
+    'userId' : userId,
37
+    'status' : status,
38
+    'createDate' : createDate,
39
+  };
40
+}

+ 13
- 0
lib/models/index.dart 查看文件

@@ -0,0 +1,13 @@
1
+
2
+export 'app.dart';
3
+
4
+import '../models/app.dart';
5
+import 'package:get/get.dart';
6
+
7
+class AppBindings implements Bindings {
8
+  @override
9
+  void dependencies() {
10
+    Get.put(AppController());
11
+  }
12
+}
13
+

+ 330
- 0
lib/pages/Login/index.dart 查看文件

@@ -0,0 +1,330 @@
1
+import 'dart:async';
2
+
3
+import 'package:flutter/gestures.dart';
4
+import 'package:worker_client/models/app.dart';
5
+import 'package:fluttertoast/fluttertoast.dart';
6
+import 'package:flutter/material.dart';
7
+import 'package:flutter_screenutil/flutter_screenutil.dart';
8
+import 'package:get/get.dart';
9
+import 'package:worker_client/widgets/Cell.dart';
10
+import 'package:worker_client/widgets/GradientButton.dart';
11
+import '../../models/entities/person.dart';
12
+import '../../services/user.dart';
13
+
14
+class Login extends StatefulWidget {
15
+  const Login({Key? key}) : super(key: key);
16
+
17
+  @override
18
+  State<Login> createState() => _Login();
19
+}
20
+
21
+const String checkedImg = 'images/login/checkedImg.png';
22
+const String unCheckedImg = 'images/login/unChecked.png';
23
+
24
+class _Login extends State<Login> {
25
+  var userInfo = AppController.t.user;
26
+  @override
27
+  void initState() {
28
+    super.initState();
29
+  }
30
+
31
+  String phone = '';
32
+  RegExp exp = RegExp(r'^1[3456789]\d{9}$');
33
+  var timer;
34
+
35
+  String qCode = '';
36
+  String qCodeText = '获取验证码';
37
+  bool disableQcode = false;
38
+
39
+  bool isCheck = false;
40
+
41
+  bool disableLogin = false;
42
+
43
+  void setPhone(e) {
44
+    setState(() {
45
+      phone = e;
46
+    });
47
+  }
48
+
49
+  void initTimer() {
50
+    int count = 60;
51
+    timer = Timer.periodic(const Duration(seconds: 1), (Timer timer) {
52
+      count--;
53
+      setState(() {
54
+        if (count == 0) {
55
+          timer.cancel(); //倒计时结束取消定时器
56
+          disableQcode = false; //按钮可点击
57
+          count = 60; //重置时间
58
+          qCodeText = '获取验证码'; //重置按钮文本
59
+        } else {
60
+          qCodeText = '$count s后重发'; //更新文本内容
61
+        }
62
+      });
63
+    });
64
+  }
65
+
66
+  void handleQCode() {
67
+    if (exp.hasMatch(phone)) {
68
+      disableQcode = true;
69
+      initTimer();
70
+      getSMSCaptch(phone);
71
+    } else {
72
+      Fluttertoast.showToast(msg: '请输入正确的手机号!');
73
+    }
74
+  }
75
+
76
+  void handleLogin() {
77
+    if (isCheck) {
78
+      if (qCode != '') {
79
+        if (exp.hasMatch(phone)) {
80
+          setState(() {
81
+            disableLogin = true;
82
+          });
83
+
84
+          userLogin(phone, qCode).then((res) {
85
+            userInfo(Person.fromJson(res['person']));
86
+            // 一秒强弹窗
87
+            Fluttertoast.showToast(msg: '登录成功!');
88
+            Get.back();
89
+          }).catchError((err) {
90
+            Fluttertoast.showToast(msg: err);
91
+          });
92
+        } else {
93
+          Fluttertoast.showToast(msg: '请输入正确的手机号');
94
+        }
95
+      } else {
96
+        Fluttertoast.showToast(msg: '请输入手机短信验证码');
97
+      }
98
+    } else {
99
+      Fluttertoast.showToast(msg: '请确认文本协议');
100
+    }
101
+  }
102
+
103
+  @override
104
+  Widget build(BuildContext context) {
105
+    ScreenUtil.init(context,
106
+        designSize: const Size(375, 812),
107
+        minTextAdapt: true,
108
+        orientation: Orientation.portrait);
109
+
110
+    return Scaffold(
111
+      resizeToAvoidBottomInset: false,
112
+      body: Container(
113
+          padding: EdgeInsets.all(15.w),
114
+          decoration: const BoxDecoration(
115
+            image: DecorationImage(
116
+              image: AssetImage("images/login/loginImg.png"),
117
+              fit: BoxFit.cover,
118
+            ),
119
+          ),
120
+          child: Column(
121
+            crossAxisAlignment: CrossAxisAlignment.start,
122
+            children: [
123
+              Padding(
124
+                padding: EdgeInsets.fromLTRB(0, 20.h, 0, 11.5.h),
125
+                child: Center(
126
+                  child: Text(
127
+                    '登录',
128
+                    style: TextStyle(
129
+                      letterSpacing: 3,
130
+                      fontWeight: FontWeight.bold,
131
+                      color: const Color(0xFF333333),
132
+                      fontSize: 17.sp,
133
+                    ),
134
+                  ),
135
+                ),
136
+              ),
137
+              Container(
138
+                margin: EdgeInsets.fromLTRB(0, 49.h, 0, 22.h),
139
+                child: Text(
140
+                  '您好!',
141
+                  style: TextStyle(
142
+                    letterSpacing: 3,
143
+                    fontWeight: FontWeight.bold,
144
+                    fontSize: 33.sp,
145
+                    color: const Color(0xFF333333),
146
+                  ),
147
+                ),
148
+              ),
149
+              Text(
150
+                '欢迎进入农机手端小程序!',
151
+                style: TextStyle(
152
+                  letterSpacing: 3,
153
+                  fontWeight: FontWeight.bold,
154
+                  fontSize: 27.sp,
155
+                  color: const Color(0xFF333333),
156
+                ),
157
+              ),
158
+              Cell(
159
+                margin: EdgeInsets.fromLTRB(0, 43.h, 0, 16.h),
160
+                header: Text(
161
+                  "+86",
162
+                  style: TextStyle(
163
+                    fontWeight: FontWeight.w500,
164
+                    fontSize: 19.sp,
165
+                    color: const Color(0xFF333333),
166
+                  ),
167
+                ),
168
+                child: TextField(
169
+                  maxLength: 11,
170
+                  //数字文本框
171
+                  keyboardType: TextInputType.number,
172
+                  style: TextStyle(
173
+                    fontSize: 17.sp,
174
+                  ),
175
+                  decoration: InputDecoration(
176
+                    isCollapsed: true,
177
+                    contentPadding: EdgeInsets.symmetric(
178
+                        horizontal: 15.5.w, vertical: 19.h),
179
+                    labelText: "请输入手机号码",
180
+                    counterText: '', //去掉右下角的东西
181
+                    border: InputBorder.none,
182
+                    floatingLabelBehavior: FloatingLabelBehavior.never,
183
+                  ),
184
+                  onChanged: (val) {
185
+                    setPhone(val);
186
+                  },
187
+                ),
188
+                footer: SizedBox(
189
+                  width: 94.w,
190
+                  height: 34.h,
191
+                  child: GradientButton(
192
+                      colors: const [
193
+                        Color(0xFFA0E067),
194
+                        Color(0xFF00AE39),
195
+                      ],
196
+                      borderRadius: BorderRadius.all(Radius.circular(10.w)),
197
+                      onPressed: disableQcode ? null : handleQCode,
198
+                      child: Text(
199
+                        qCodeText,
200
+                        style: TextStyle(
201
+                          fontSize: 15.sp,
202
+                          fontWeight: FontWeight.bold,
203
+                        ),
204
+                      )),
205
+                ),
206
+              ),
207
+              Cell(
208
+                  header: Padding(
209
+                    padding: EdgeInsets.fromLTRB(9.5.w, 0, 0, 0),
210
+                    child: Stack(
211
+                      children: [
212
+                        Positioned(
213
+                          child: Image.asset(
214
+                            "images/login/VerificationCode.png",
215
+                            width: 20.h,
216
+                            height: 20.h,
217
+                          ),
218
+                        ),
219
+                      ],
220
+                    ),
221
+                  ),
222
+                  child: TextField(
223
+                    maxLength: 11,
224
+                    //数字文本框
225
+                    keyboardType: TextInputType.number,
226
+                    style: TextStyle(
227
+                      fontSize: 17.sp,
228
+                    ),
229
+                    decoration: InputDecoration(
230
+                      isCollapsed: true,
231
+                      contentPadding: EdgeInsets.symmetric(
232
+                          horizontal: 15.5.w, vertical: 19.h),
233
+                      labelText: "请输入验证码",
234
+                      counterText: '', //去掉右下角的东西
235
+                      border: InputBorder.none,
236
+                      floatingLabelBehavior: FloatingLabelBehavior.never,
237
+                    ),
238
+                    onChanged: (val) {
239
+                      setState(() {
240
+                        qCode = val;
241
+                      });
242
+                    },
243
+                  )),
244
+              //找到了 下面就是置底
245
+              const Spacer(),
246
+              Center(
247
+                child: SizedBox(
248
+                  width: 315.w,
249
+                  height: 49.h,
250
+                  child: GradientButton(
251
+                      colors: const [
252
+                        Color(0xFFA0E067),
253
+                        Color(0xFF00AE39),
254
+                      ],
255
+                      borderRadius: BorderRadius.all(Radius.circular(24.5.w)),
256
+                      onPressed: disableLogin ? null : handleLogin,
257
+                      child: Text(
258
+                        '登录',
259
+                        style: TextStyle(
260
+                          fontSize: 17.sp,
261
+                          fontWeight: FontWeight.bold,
262
+                        ),
263
+                      )),
264
+                ),
265
+              ),
266
+              Container(
267
+                margin: EdgeInsets.fromLTRB(0, 30.h, 0, 0),
268
+                child: GestureDetector(
269
+                  onTap: () {
270
+                    setState(() {
271
+                      isCheck = !isCheck;
272
+                    });
273
+                  },
274
+                  child: Row(
275
+                    children: <Widget>[
276
+                      Padding(
277
+                        padding: EdgeInsets.fromLTRB(0, 0, 5.5.w, 0),
278
+                        child: GestureDetector(
279
+                          onTap: () {
280
+                            setState(() {
281
+                              isCheck = !isCheck;
282
+                            });
283
+                          },
284
+                          child: Image.asset(
285
+                            isCheck ? checkedImg : unCheckedImg,
286
+                            width: 14.h,
287
+                            height: 14.h,
288
+                          ),
289
+                        ),
290
+                      ),
291
+                      RichText(
292
+                        text: TextSpan(
293
+                          children: <InlineSpan>[
294
+                            TextSpan(
295
+                              text: '请认真查看',
296
+                              style: TextStyle(
297
+                                color: const Color(0xFF999999),
298
+                                fontSize: 13.sp,
299
+                              ),
300
+                            ),
301
+                            TextSpan(
302
+                                text: '文本协议/隐私政策',
303
+                                style: TextStyle(
304
+                                  color: const Color(0xFF02902E),
305
+                                  fontSize: 13.sp,
306
+                                ),
307
+                                //给span添加点击事件厉害
308
+                                recognizer: TapGestureRecognizer()
309
+                                  ..onTap = () {
310
+                                    print(999);
311
+                                  }),
312
+                            TextSpan(
313
+                              text: ',确认之后选择此项!',
314
+                              style: TextStyle(
315
+                                color: const Color(0xFF999999),
316
+                                fontSize: 13.sp,
317
+                              ),
318
+                            ),
319
+                          ],
320
+                        ),
321
+                      ),
322
+                    ],
323
+                  ),
324
+                ),
325
+              ),
326
+            ],
327
+          )),
328
+    );
329
+  }
330
+}

+ 50
- 0
lib/pages/MyButton.dart 查看文件

@@ -0,0 +1,50 @@
1
+import 'package:flutter/material.dart';
2
+import 'package:flutter_screenutil/flutter_screenutil.dart';
3
+
4
+class MyButton extends StatefulWidget {
5
+  const MyButton({Key? key}) : super(key: key);
6
+
7
+  @override
8
+  State<MyButton> createState() => _MyButtonState();
9
+}
10
+
11
+class _MyButtonState extends State<MyButton> {
12
+
13
+  @override
14
+  Widget build(BuildContext context) {
15
+    return Container(
16
+      decoration: const BoxDecoration(
17
+        image: DecorationImage(
18
+          image: AssetImage("images/login/loginImg.png"),
19
+          fit: BoxFit.cover,
20
+        ),
21
+      ),
22
+      child: Scaffold(
23
+        backgroundColor: Colors.transparent,
24
+        appBar: AppBar(
25
+          centerTitle: true,
26
+          backgroundColor: Colors.transparent,
27
+          title: Text('登录',
28
+              style: TextStyle(
29
+                color: const Color(0xFF333333),
30
+                fontWeight: FontWeight.bold,
31
+                fontSize: 17.sp,
32
+              ),
33
+          ),
34
+          elevation: 0,
35
+        ),
36
+        body: Center(
37
+          child: Column(
38
+            crossAxisAlignment: CrossAxisAlignment.start,
39
+            children: const <Widget>[
40
+              Text(
41
+                'Hello World',
42
+                style: TextStyle(fontSize: 22.0, color: Colors.white),
43
+              ),
44
+            ],
45
+          ),
46
+        ),
47
+      ),
48
+    );
49
+  }
50
+}

+ 11
- 0
lib/pages/home/index.dart 查看文件

@@ -0,0 +1,11 @@
1
+
2
+import 'package:flutter/material.dart';
3
+
4
+class Home extends StatelessWidget {
5
+  @override
6
+  Widget build(BuildContext context) {
7
+    // controller.person
8
+    return const Scaffold(body: Text("首页"),);
9
+  }
10
+
11
+}

+ 4
- 0
lib/pages/index.dart 查看文件

@@ -0,0 +1,4 @@
1
+
2
+export 'home/index.dart';
3
+export 'splash/splash.dart';
4
+export 'Login/index.dart';

+ 16
- 0
lib/pages/splash/splash.dart 查看文件

@@ -0,0 +1,16 @@
1
+
2
+import '../splash/widgets/countdown.dart';
3
+import 'package:flutter/widgets.dart';
4
+import 'package:get/get.dart';
5
+
6
+import '../home/index.dart';
7
+
8
+class SplashScreen extends StatelessWidget {
9
+  handleOnFinish () {
10
+    Get.off(Home(), routeName: '/');
11
+  }
12
+  @override
13
+  Widget build(BuildContext context) {
14
+    return countdown(3, handleOnFinish);
15
+  }
16
+}

+ 45
- 0
lib/pages/splash/widgets/countdown.dart 查看文件

@@ -0,0 +1,45 @@
1
+
2
+import 'dart:async';
3
+
4
+import '../../../utils/timer.dart';
5
+import 'package:flutter/widgets.dart';
6
+import 'package:get/get.dart';
7
+
8
+// Widget countdown(void Function() onFinish) {
9
+//   int _countdown = 3;
10
+//   late StateSetter _update;
11
+//   late Timer _timer;
12
+//   _timer = setInterval((_) {
13
+//     if (_countdown <= 1) {
14
+//       _timer.cancel();
15
+//       onFinish();
16
+//       return;
17
+//     }
18
+//
19
+//     _update((){
20
+//       _countdown -= 1;
21
+//     });
22
+//   }, 1000);
23
+//
24
+//   return StatefulBuilder(builder: (context, setState) {
25
+//     _update = setState;
26
+//     return Text(_countdown.toString());
27
+//   });
28
+// }
29
+
30
+Widget countdown(int sec, void Function() onFinish) {
31
+  var _countdown = Rx<int>(sec);
32
+
33
+  late Timer _timer;
34
+  _timer = setInterval((_) {
35
+    if (_countdown.value <= 1) {
36
+      _timer.cancel();
37
+      onFinish();
38
+      return;
39
+    }
40
+
41
+    _countdown.value -= 1;
42
+  }, 1000);
43
+
44
+  return Obx(() =>Text(_countdown.value.toString()));
45
+}

+ 3
- 0
lib/routes/index.dart 查看文件

@@ -0,0 +1,3 @@
1
+
2
+export 'pages.dart';
3
+export 'middleWares.dart';

+ 16
- 0
lib/routes/middleWares.dart 查看文件

@@ -0,0 +1,16 @@
1
+
2
+import 'package:flutter/scheduler.dart';
3
+import 'package:get/get.dart';
4
+import 'package:get_storage/get_storage.dart';
5
+
6
+void routingCallback (routing) {
7
+  GetStorage box = GetStorage();
8
+  bool isLogin = box.hasData('token');
9
+  bool isSplashScreen = routing?.current == '/splash';
10
+  bool isLoginPage = routing?.current == '/login';
11
+  if (!isLogin && !isSplashScreen && !isLoginPage) {
12
+    // addPostFrameCallback 作用是等当前帧绘制完成之后再加载
13
+    // https://github.com/jonataslaw/getx/issues/262
14
+    SchedulerBinding.instance?.addPostFrameCallback((_) => Get.toNamed('/login'));
15
+  }
16
+}

+ 9
- 0
lib/routes/pages.dart 查看文件

@@ -0,0 +1,9 @@
1
+
2
+import 'package:get/get.dart';
3
+import '../pages/index.dart';
4
+
5
+List<GetPage> pages = [
6
+  GetPage(name: '/', page: () =>  Home()),
7
+  GetPage(name: '/splash', page: () => SplashScreen()),
8
+  GetPage(name: '/login', page: () =>  const Login()),
9
+];

+ 32
- 0
lib/services/user.dart 查看文件

@@ -0,0 +1,32 @@
1
+
2
+
3
+import 'package:dio/dio.dart';
4
+import '../utils/Request.dart';
5
+import 'package:fluttertoast/fluttertoast.dart';
6
+
7
+
8
+Future getSMSCaptch(String phone) async {
9
+  return request('/sms-captcha', options: Options(method: 'POST'), queryParameters: { 'phone': phone }).then((value) {
10
+    Fluttertoast.showToast(
11
+        msg: '验证码发送成功!'
12
+    );
13
+  }).catchError((error) {
14
+
15
+    Fluttertoast.showToast(
16
+        msg: error.error['message']
17
+    );
18
+  });
19
+}
20
+
21
+//登陆
22
+Future userLogin(String userName,String password) async {
23
+  return request('/login', options: Options(method: 'POST'),
24
+    data: { 'userName': userName, 'password': password},).catchError((error) =>
25
+  { Fluttertoast.showToast(
26
+      msg: error.error['message']
27
+  ),});
28
+}
29
+
30
+Future getCurrent() async {
31
+  return request('/person/current');
32
+}

+ 102
- 0
lib/utils/Request.dart 查看文件

@@ -0,0 +1,102 @@
1
+import 'dart:convert';
2
+
3
+import 'package:dio/dio.dart';
4
+import 'package:flutter/foundation.dart';
5
+import 'package:get/get.dart';
6
+import 'package:get_storage/get_storage.dart';
7
+
8
+class Response {
9
+  late int code;
10
+  String? message;
11
+  dynamic data;
12
+
13
+  Response({
14
+    required this.code,
15
+    this.message,
16
+    this.data,
17
+  });
18
+
19
+  factory Response.fromJson(dynamic str) =>
20
+      Response.fromMap(jsonDecode(str) as Map<String, dynamic>);
21
+
22
+  factory Response.fromMap(Map<String, dynamic> resp) => Response(
23
+    code: resp['code'],
24
+    message: resp['message'],
25
+    data: resp['data'],
26
+  );
27
+}
28
+
29
+final client = GetPlatform.isAndroid ? 'android' : 'ios';
30
+
31
+Dio createRequest() {
32
+  var options = BaseOptions(
33
+    baseUrl: 'https://machine.njyunzhi.com/api/' + client + '/worker',
34
+    connectTimeout: 5000,
35
+    receiveTimeout: 3000,
36
+  );
37
+
38
+  var dio = Dio(options);
39
+  dio.interceptors.add(InterceptorsWrapper(onRequest: (options, handler) {
40
+    // Do something before request is sent
41
+    options.headers['Authorization'] =  GetStorage().read("token");
42
+    return handler.next(options); //continue
43
+    // If you want to resolve the request with some custom data,
44
+    // you can resolve a `Response` object eg: `handler.resolve(response)`.
45
+    // If you want to reject the request with a error message,
46
+    // you can reject a `DioError` object eg: `handler.reject(dioError)`
47
+  }, onResponse: (response, handler) {
48
+    var resp = response.data as Map<String, dynamic>;
49
+    if (resp['code'] == 1000) {
50
+      response.data = resp['data'];
51
+
52
+      try {
53
+        var data = response.data as Map<String, dynamic>;
54
+        if (null != data['token']) {
55
+          GetStorage().write('token', data['token']); //取数据
56
+        }
57
+      } catch (e) {
58
+        //
59
+      }
60
+
61
+      return handler.next(response);
62
+    } else {
63
+      DioError error = DioError(requestOptions: response.requestOptions, error: response.data, response: response);
64
+      return handler.reject(error);
65
+    }
66
+  }, onError: (DioError e, handler) {
67
+    // Do something with response error
68
+    return handler.next(e); //continue
69
+    // If you want to resolve the request with some custom data,
70
+    // you can resolve a `Response` object eg: `handler.resolve(response)`.
71
+  }));
72
+
73
+  return dio;
74
+}
75
+
76
+var instance = createRequest();
77
+
78
+Future request(String path,
79
+    {data,
80
+      Map<String, dynamic>? queryParameters,
81
+      CancelToken? cancelToken,
82
+      Options? options,
83
+      ProgressCallback? onSendProgress,
84
+      ProgressCallback? onReceiveProgress}) async {
85
+
86
+  var resp = await instance.request(path,
87
+      data: data,
88
+      queryParameters: queryParameters,
89
+      cancelToken: cancelToken,
90
+      options: options);
91
+
92
+  if (resp.data.runtimeType == String) {
93
+    String dt = resp.data as String;
94
+    dt.trim();
95
+    if (dt.startsWith('{') && dt.endsWith('}')) {
96
+      return jsonDecode(dt);
97
+    }
98
+    return dt;
99
+  }
100
+
101
+  return resp.data;
102
+}

+ 25
- 0
lib/utils/location.dart 查看文件

@@ -0,0 +1,25 @@
1
+import 'package:location/location.dart';
2
+
3
+Future requireLocation() async {
4
+  Location location = Location();
5
+  bool _serviceEnabled;
6
+  PermissionStatus _permissionGranted;
7
+
8
+  _serviceEnabled = await location.serviceEnabled();
9
+  if (!_serviceEnabled) {
10
+    _serviceEnabled = await location.requestService();
11
+    if (!_serviceEnabled) {
12
+      throw Exception("请开启系统定位功能");
13
+    }
14
+  }
15
+
16
+  _permissionGranted = await location.hasPermission();
17
+  if (_permissionGranted == PermissionStatus.denied) {
18
+    _permissionGranted = await location.requestPermission();
19
+    if (_permissionGranted != PermissionStatus.granted) {
20
+      throw Exception("请设置允许当前程序定位功能");
21
+    }
22
+  }
23
+
24
+  return location;
25
+}

+ 12
- 0
lib/utils/timer.dart 查看文件

@@ -0,0 +1,12 @@
1
+
2
+import 'dart:async';
3
+
4
+Timer setInterval(void Function (Timer) f, int milliseconds) {
5
+  var duration = Duration(milliseconds: milliseconds);
6
+  return Timer.periodic(duration, f);
7
+}
8
+
9
+Timer setTimeout(void Function () f, int milliseconds) {
10
+  var duration = Duration(milliseconds: milliseconds);
11
+  return Timer(duration, f);
12
+}

+ 54
- 0
lib/widgets/Cell.dart 查看文件

@@ -0,0 +1,54 @@
1
+
2
+import 'package:flutter/cupertino.dart';
3
+import 'package:flutter/widgets.dart';
4
+import 'package:flutter_screenutil/flutter_screenutil.dart';
5
+
6
+class Cell extends StatelessWidget {
7
+  const Cell ({
8
+    Key? key,
9
+    this.header,
10
+    required this.child,
11
+    this.footer,
12
+    this.margin,
13
+  }) : super(key: key);
14
+
15
+  final Widget? header;
16
+  final Widget child;
17
+  final Widget? footer;
18
+  final EdgeInsetsGeometry? margin;
19
+
20
+  @override
21
+  Widget build(BuildContext context) {
22
+
23
+    return Container(
24
+      margin: margin,
25
+      padding: EdgeInsets.symmetric(vertical: 10.h, horizontal: 0.0),
26
+      decoration: const BoxDecoration(
27
+        border: Border(
28
+          bottom: BorderSide(width: 1.0, color: Color(0x1F000000)),
29
+        )
30
+      ),
31
+      child: Row(
32
+        children: [
33
+          if (null != header) SizedBox(
34
+            width: 53.w,
35
+            child: Container(
36
+              decoration: const BoxDecoration(
37
+                border: Border(
38
+                  right: BorderSide(width: 1, color: Color(0xFF333333))
39
+                )
40
+              ),
41
+              child: header,
42
+            ),
43
+          ),
44
+          Expanded(child: child,),
45
+          if (null != footer) ConstrainedBox (
46
+            constraints: BoxConstraints(maxWidth: 100.w),
47
+            child: footer,
48
+          )
49
+        ],
50
+      ),
51
+    );
52
+  }
53
+  
54
+}

+ 87
- 0
lib/widgets/GradientButton.dart 查看文件

@@ -0,0 +1,87 @@
1
+
2
+
3
+import 'package:flutter/material.dart';
4
+
5
+class GradientButton extends StatelessWidget {
6
+  const GradientButton({
7
+    Key? key,
8
+    this.colors,
9
+    this.linearStart,
10
+    this.linearEnd,
11
+    required this.onPressed,
12
+    required this.child,
13
+    this.padding,
14
+    this.borderRadius = const BorderRadius.all(Radius.circular(2)),
15
+    this.textColor,
16
+    this.splashColor,
17
+    this.disabledColor,
18
+    this.disabledTextColor,
19
+    this.onHighlightChanged,
20
+  }) : super(key: key);
21
+
22
+  // 渐变色数组
23
+  final List<Color>? colors;
24
+  final Color? textColor;
25
+  final Color? splashColor;
26
+  final Color? disabledTextColor;
27
+  final Color? disabledColor;
28
+  final EdgeInsetsGeometry? padding;
29
+  final Alignment? linearStart;
30
+  final Alignment? linearEnd;
31
+
32
+  final Widget child;
33
+  final BorderRadius? borderRadius;
34
+
35
+  final GestureTapCallback? onPressed;
36
+  final ValueChanged<bool>? onHighlightChanged;
37
+
38
+  @override
39
+  Widget build(BuildContext context) {
40
+    ThemeData theme = Theme.of(context);
41
+    //确保colors数组不空
42
+    List<Color> _colors =
43
+        colors ?? [theme.primaryColor, theme.primaryColorDark];
44
+    final radius = borderRadius;
45
+    bool disabled = onPressed == null;
46
+
47
+    return DecoratedBox(
48
+      decoration: BoxDecoration(
49
+        gradient: disabled ? null : LinearGradient(begin: linearStart??Alignment.topCenter, end: linearEnd??Alignment.bottomCenter, colors: _colors),
50
+        color: disabled ? disabledColor ?? theme.disabledColor : null,
51
+        borderRadius: radius,
52
+      ),
53
+      child: Material(
54
+        type: MaterialType.transparency,
55
+        borderRadius: radius,
56
+        clipBehavior: Clip.hardEdge,
57
+        child: ConstrainedBox(
58
+          constraints: const BoxConstraints(minWidth: 88.0, minHeight: 36.0),
59
+          child: InkWell(
60
+            splashColor: splashColor ?? _colors.last,
61
+            highlightColor: Colors.transparent,
62
+            onHighlightChanged: onHighlightChanged,
63
+            onTap: onPressed,
64
+            child: Padding(
65
+              padding: padding ?? theme.buttonTheme.padding,
66
+              child: DefaultTextStyle(
67
+                style: const TextStyle(fontWeight: FontWeight.bold),
68
+                child: Center(
69
+                  child: DefaultTextStyle(
70
+                    style: theme.textTheme.button!.copyWith(
71
+                      color: disabled
72
+                          ? disabledTextColor ?? Colors.black38
73
+                          : textColor ?? Colors.white,
74
+                    ),
75
+                    child: child,
76
+                  ),
77
+                  widthFactor: 1,
78
+                  heightFactor: 1,
79
+                ),
80
+              ),
81
+            ),
82
+          ),
83
+        ),
84
+      ),
85
+    );
86
+  }
87
+}

+ 314
- 0
pubspec.lock 查看文件

@@ -1,6 +1,27 @@
1 1
 # Generated by pub
2 2
 # See https://dart.dev/tools/pub/glossary#lockfile
3 3
 packages:
4
+  _fe_analyzer_shared:
5
+    dependency: transitive
6
+    description:
7
+      name: _fe_analyzer_shared
8
+      url: "https://pub.flutter-io.cn"
9
+    source: hosted
10
+    version: "38.0.0"
11
+  analyzer:
12
+    dependency: transitive
13
+    description:
14
+      name: analyzer
15
+      url: "https://pub.flutter-io.cn"
16
+    source: hosted
17
+    version: "3.4.1"
18
+  args:
19
+    dependency: transitive
20
+    description:
21
+      name: args
22
+      url: "https://pub.flutter-io.cn"
23
+    source: hosted
24
+    version: "2.3.0"
4 25
   async:
5 26
     dependency: transitive
6 27
     description:
@@ -15,6 +36,20 @@ packages:
15 36
       url: "https://pub.flutter-io.cn"
16 37
     source: hosted
17 38
     version: "2.1.0"
39
+  build:
40
+    dependency: transitive
41
+    description:
42
+      name: build
43
+      url: "https://pub.flutter-io.cn"
44
+    source: hosted
45
+    version: "2.2.1"
46
+  build_config:
47
+    dependency: transitive
48
+    description:
49
+      name: build_config
50
+      url: "https://pub.flutter-io.cn"
51
+    source: hosted
52
+    version: "1.0.0"
18 53
   characters:
19 54
     dependency: transitive
20 55
     description:
@@ -29,6 +64,13 @@ packages:
29 64
       url: "https://pub.flutter-io.cn"
30 65
     source: hosted
31 66
     version: "1.3.1"
67
+  checked_yaml:
68
+    dependency: transitive
69
+    description:
70
+      name: checked_yaml
71
+      url: "https://pub.flutter-io.cn"
72
+    source: hosted
73
+    version: "2.0.1"
32 74
   clock:
33 75
     dependency: transitive
34 76
     description:
@@ -43,6 +85,20 @@ packages:
43 85
       url: "https://pub.flutter-io.cn"
44 86
     source: hosted
45 87
     version: "1.15.0"
88
+  convert:
89
+    dependency: transitive
90
+    description:
91
+      name: convert
92
+      url: "https://pub.flutter-io.cn"
93
+    source: hosted
94
+    version: "3.0.1"
95
+  crypto:
96
+    dependency: transitive
97
+    description:
98
+      name: crypto
99
+      url: "https://pub.flutter-io.cn"
100
+    source: hosted
101
+    version: "3.0.1"
46 102
   cupertino_icons:
47 103
     dependency: "direct main"
48 104
     description:
@@ -50,6 +106,20 @@ packages:
50 106
       url: "https://pub.flutter-io.cn"
51 107
     source: hosted
52 108
     version: "1.0.4"
109
+  dart_style:
110
+    dependency: transitive
111
+    description:
112
+      name: dart_style
113
+      url: "https://pub.flutter-io.cn"
114
+    source: hosted
115
+    version: "2.2.2"
116
+  dio:
117
+    dependency: "direct main"
118
+    description:
119
+      name: dio
120
+      url: "https://pub.flutter-io.cn"
121
+    source: hosted
122
+    version: "4.0.6"
53 123
   fake_async:
54 124
     dependency: transitive
55 125
     description:
@@ -57,6 +127,20 @@ packages:
57 127
       url: "https://pub.flutter-io.cn"
58 128
     source: hosted
59 129
     version: "1.2.0"
130
+  ffi:
131
+    dependency: transitive
132
+    description:
133
+      name: ffi
134
+      url: "https://pub.flutter-io.cn"
135
+    source: hosted
136
+    version: "1.1.2"
137
+  file:
138
+    dependency: transitive
139
+    description:
140
+      name: file
141
+      url: "https://pub.flutter-io.cn"
142
+    source: hosted
143
+    version: "6.1.2"
60 144
   flutter:
61 145
     dependency: "direct main"
62 146
     description: flutter
@@ -69,11 +153,79 @@ packages:
69 153
       url: "https://pub.flutter-io.cn"
70 154
     source: hosted
71 155
     version: "1.0.4"
156
+  flutter_screenutil:
157
+    dependency: "direct main"
158
+    description:
159
+      name: flutter_screenutil
160
+      url: "https://pub.flutter-io.cn"
161
+    source: hosted
162
+    version: "5.4.0"
72 163
   flutter_test:
73 164
     dependency: "direct dev"
74 165
     description: flutter
75 166
     source: sdk
76 167
     version: "0.0.0"
168
+  flutter_web_plugins:
169
+    dependency: transitive
170
+    description: flutter
171
+    source: sdk
172
+    version: "0.0.0"
173
+  fluttertoast:
174
+    dependency: "direct main"
175
+    description:
176
+      name: fluttertoast
177
+      url: "https://pub.flutter-io.cn"
178
+    source: hosted
179
+    version: "8.0.9"
180
+  get:
181
+    dependency: "direct main"
182
+    description:
183
+      name: get
184
+      url: "https://pub.flutter-io.cn"
185
+    source: hosted
186
+    version: "4.6.1"
187
+  get_storage:
188
+    dependency: "direct main"
189
+    description:
190
+      name: get_storage
191
+      url: "https://pub.flutter-io.cn"
192
+    source: hosted
193
+    version: "2.0.3"
194
+  glob:
195
+    dependency: transitive
196
+    description:
197
+      name: glob
198
+      url: "https://pub.flutter-io.cn"
199
+    source: hosted
200
+    version: "2.0.2"
201
+  http_parser:
202
+    dependency: transitive
203
+    description:
204
+      name: http_parser
205
+      url: "https://pub.flutter-io.cn"
206
+    source: hosted
207
+    version: "4.0.0"
208
+  js:
209
+    dependency: transitive
210
+    description:
211
+      name: js
212
+      url: "https://pub.flutter-io.cn"
213
+    source: hosted
214
+    version: "0.6.3"
215
+  json_annotation:
216
+    dependency: transitive
217
+    description:
218
+      name: json_annotation
219
+      url: "https://pub.flutter-io.cn"
220
+    source: hosted
221
+    version: "4.4.0"
222
+  json_serializable:
223
+    dependency: "direct main"
224
+    description:
225
+      name: json_serializable
226
+      url: "https://pub.flutter-io.cn"
227
+    source: hosted
228
+    version: "6.1.5"
77 229
   lints:
78 230
     dependency: transitive
79 231
     description:
@@ -81,6 +233,34 @@ packages:
81 233
       url: "https://pub.flutter-io.cn"
82 234
     source: hosted
83 235
     version: "1.0.1"
236
+  location:
237
+    dependency: "direct main"
238
+    description:
239
+      name: location
240
+      url: "https://pub.flutter-io.cn"
241
+    source: hosted
242
+    version: "4.3.0"
243
+  location_platform_interface:
244
+    dependency: transitive
245
+    description:
246
+      name: location_platform_interface
247
+      url: "https://pub.flutter-io.cn"
248
+    source: hosted
249
+    version: "2.3.0"
250
+  location_web:
251
+    dependency: transitive
252
+    description:
253
+      name: location_web
254
+      url: "https://pub.flutter-io.cn"
255
+    source: hosted
256
+    version: "3.1.1"
257
+  logging:
258
+    dependency: transitive
259
+    description:
260
+      name: logging
261
+      url: "https://pub.flutter-io.cn"
262
+    source: hosted
263
+    version: "1.0.2"
84 264
   matcher:
85 265
     dependency: transitive
86 266
     description:
@@ -102,6 +282,13 @@ packages:
102 282
       url: "https://pub.flutter-io.cn"
103 283
     source: hosted
104 284
     version: "1.7.0"
285
+  package_config:
286
+    dependency: transitive
287
+    description:
288
+      name: package_config
289
+      url: "https://pub.flutter-io.cn"
290
+    source: hosted
291
+    version: "2.0.2"
105 292
   path:
106 293
     dependency: transitive
107 294
     description:
@@ -109,11 +296,109 @@ packages:
109 296
       url: "https://pub.flutter-io.cn"
110 297
     source: hosted
111 298
     version: "1.8.0"
299
+  path_provider:
300
+    dependency: transitive
301
+    description:
302
+      name: path_provider
303
+      url: "https://pub.flutter-io.cn"
304
+    source: hosted
305
+    version: "2.0.9"
306
+  path_provider_android:
307
+    dependency: transitive
308
+    description:
309
+      name: path_provider_android
310
+      url: "https://pub.flutter-io.cn"
311
+    source: hosted
312
+    version: "2.0.12"
313
+  path_provider_ios:
314
+    dependency: transitive
315
+    description:
316
+      name: path_provider_ios
317
+      url: "https://pub.flutter-io.cn"
318
+    source: hosted
319
+    version: "2.0.8"
320
+  path_provider_linux:
321
+    dependency: transitive
322
+    description:
323
+      name: path_provider_linux
324
+      url: "https://pub.flutter-io.cn"
325
+    source: hosted
326
+    version: "2.1.5"
327
+  path_provider_macos:
328
+    dependency: transitive
329
+    description:
330
+      name: path_provider_macos
331
+      url: "https://pub.flutter-io.cn"
332
+    source: hosted
333
+    version: "2.0.5"
334
+  path_provider_platform_interface:
335
+    dependency: transitive
336
+    description:
337
+      name: path_provider_platform_interface
338
+      url: "https://pub.flutter-io.cn"
339
+    source: hosted
340
+    version: "2.0.3"
341
+  path_provider_windows:
342
+    dependency: transitive
343
+    description:
344
+      name: path_provider_windows
345
+      url: "https://pub.flutter-io.cn"
346
+    source: hosted
347
+    version: "2.0.5"
348
+  platform:
349
+    dependency: transitive
350
+    description:
351
+      name: platform
352
+      url: "https://pub.flutter-io.cn"
353
+    source: hosted
354
+    version: "3.1.0"
355
+  plugin_platform_interface:
356
+    dependency: transitive
357
+    description:
358
+      name: plugin_platform_interface
359
+      url: "https://pub.flutter-io.cn"
360
+    source: hosted
361
+    version: "2.1.2"
362
+  process:
363
+    dependency: transitive
364
+    description:
365
+      name: process
366
+      url: "https://pub.flutter-io.cn"
367
+    source: hosted
368
+    version: "4.2.4"
369
+  pub_semver:
370
+    dependency: transitive
371
+    description:
372
+      name: pub_semver
373
+      url: "https://pub.flutter-io.cn"
374
+    source: hosted
375
+    version: "2.1.1"
376
+  pubspec_parse:
377
+    dependency: transitive
378
+    description:
379
+      name: pubspec_parse
380
+      url: "https://pub.flutter-io.cn"
381
+    source: hosted
382
+    version: "1.2.0"
112 383
   sky_engine:
113 384
     dependency: transitive
114 385
     description: flutter
115 386
     source: sdk
116 387
     version: "0.0.99"
388
+  source_gen:
389
+    dependency: transitive
390
+    description:
391
+      name: source_gen
392
+      url: "https://pub.flutter-io.cn"
393
+    source: hosted
394
+    version: "1.2.1"
395
+  source_helper:
396
+    dependency: transitive
397
+    description:
398
+      name: source_helper
399
+      url: "https://pub.flutter-io.cn"
400
+    source: hosted
401
+    version: "1.3.1"
117 402
   source_span:
118 403
     dependency: transitive
119 404
     description:
@@ -170,5 +455,34 @@ packages:
170 455
       url: "https://pub.flutter-io.cn"
171 456
     source: hosted
172 457
     version: "2.1.1"
458
+  watcher:
459
+    dependency: transitive
460
+    description:
461
+      name: watcher
462
+      url: "https://pub.flutter-io.cn"
463
+    source: hosted
464
+    version: "1.0.1"
465
+  win32:
466
+    dependency: transitive
467
+    description:
468
+      name: win32
469
+      url: "https://pub.flutter-io.cn"
470
+    source: hosted
471
+    version: "2.5.1"
472
+  xdg_directories:
473
+    dependency: transitive
474
+    description:
475
+      name: xdg_directories
476
+      url: "https://pub.flutter-io.cn"
477
+    source: hosted
478
+    version: "0.2.0+1"
479
+  yaml:
480
+    dependency: transitive
481
+    description:
482
+      name: yaml
483
+      url: "https://pub.flutter-io.cn"
484
+    source: hosted
485
+    version: "3.1.0"
173 486
 sdks:
174 487
   dart: ">=2.16.1 <3.0.0"
488
+  flutter: ">=2.8.0"

+ 16
- 3
pubspec.yaml 查看文件

@@ -34,6 +34,13 @@ dependencies:
34 34
   # The following adds the Cupertino Icons font to your application.
35 35
   # Use with the CupertinoIcons class for iOS style icons.
36 36
   cupertino_icons: ^1.0.2
37
+  json_serializable: ^6.1.5
38
+  get: ^4.6.1
39
+  dio: ^4.0.6
40
+  flutter_screenutil: ^5.3.1
41
+  location: ^4.3.0
42
+  fluttertoast: ^8.0.9
43
+  get_storage: ^2.0.3
37 44
 
38 45
 dev_dependencies:
39 46
   flutter_test:
@@ -45,7 +52,9 @@ dev_dependencies:
45 52
   # package. See that file for information about deactivating specific lint
46 53
   # rules and activating additional ones.
47 54
   flutter_lints: ^1.0.0
48
-
55
+  json_serializable: ^6.1.5
56
+  flutter_screenutil: ^5.3.1
57
+  fluttertoast: ^8.0.9
49 58
 # For information on the generic Dart part of this file, see the
50 59
 # following page: https://dart.dev/tools/pub/pubspec
51 60
 
@@ -56,13 +65,17 @@ flutter:
56 65
   # included with your application, so that you can use the icons in
57 66
   # the material Icons class.
58 67
   uses-material-design: true
59
-
68
+  assets:
69
+    - images/login/loginImg.png
70
+    - images/login/VerificationCode.png
71
+    - images/login/checkedImg.png
72
+    - images/login/unChecked.png
60 73
   # To add assets to your application, add an assets section, like this:
61 74
   # assets:
62 75
   #   - images/a_dot_burr.jpeg
63 76
   #   - images/a_dot_ham.jpeg
64 77
 
65
-  # An image asset can refer to one or more resolution-specific "variants", see
78
+  # An images asset can refer to one or more resolution-specific "variants", see
66 79
   # https://flutter.dev/assets-and-images/#resolution-aware.
67 80
 
68 81
   # For details regarding adding assets from package dependencies, see

+ 0
- 30
test/widget_test.dart 查看文件

@@ -1,30 +0,0 @@
1
-// This is a basic Flutter widget test.
2
-//
3
-// To perform an interaction with a widget in your test, use the WidgetTester
4
-// utility that Flutter provides. For example, you can send tap and scroll
5
-// gestures. You can also use WidgetTester to find child widgets in the widget
6
-// tree, read text, and verify that the values of widget properties are correct.
7
-
8
-import 'package:flutter/material.dart';
9
-import 'package:flutter_test/flutter_test.dart';
10
-
11
-import 'package:worker_client/main.dart';
12
-
13
-void main() {
14
-  testWidgets('Counter increments smoke test', (WidgetTester tester) async {
15
-    // Build our app and trigger a frame.
16
-    await tester.pumpWidget(const MyApp());
17
-
18
-    // Verify that our counter starts at 0.
19
-    expect(find.text('0'), findsOneWidget);
20
-    expect(find.text('1'), findsNothing);
21
-
22
-    // Tap the '+' icon and trigger a frame.
23
-    await tester.tap(find.byIcon(Icons.add));
24
-    await tester.pump();
25
-
26
-    // Verify that our counter has incremented.
27
-    expect(find.text('0'), findsNothing);
28
-    expect(find.text('1'), findsOneWidget);
29
-  });
30
-}