Browse Source

继续完善track页面

liuyuqi-dellpc 2 years ago
parent
commit
50ef3b8f45

+ 2 - 1
android/app/src/main/AndroidManifest.xml

@@ -8,7 +8,8 @@
     <uses-permission android:name="android.permission.BLUETOOTH" />
     <uses-permission android:name="android.permission.BLUETOOTH_PRIVILEGED" />
     <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
-
+    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
+    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
 
     <application
         android:icon="@drawable/ic_launcher"

BIN
assets/images/add.png


BIN
assets/images/corona.png


BIN
assets/images/green.jpg


BIN
assets/images/ic_launcher.png


BIN
assets/images/red.jpg


BIN
assets/images/yellow.jpg


+ 1 - 1
lib/dio/api.dart

@@ -1,7 +1,7 @@
 import 'package:flutter_tracker/model/user_model.dart';
 
 abstract class Api {
-  static const String _host = "http://flutter.yoqi.me/API/flutter_tracker";
+  static const String _host = "http://flutter.yoqi.me/Track";
   static String loginUrl = _host + "/login";
   static String logoutUrl = _host + "/logout";
   static String registerUrl = _host + "/register";

+ 18 - 5
lib/dio/login_dao.dart

@@ -3,7 +3,7 @@ import 'package:flutter_tracker/dio/api.dart';
 import 'package:flutter_tracker/model/user_model.dart';
 
 class LoginDao {
-  static Map<String, dynamic> params = Map<String, dynamic>();
+  static Map<String, dynamic> params = <String, dynamic>{};
 
   static Future<UserModel> login(String username, String password) async {
     params.addAll({"username": username, "password": password});
@@ -13,14 +13,27 @@ class LoginDao {
 
   static Future<bool> logout(String token) async {
     params.addAll({"token": token});
-    Response response = await Dio().get(Api.logoutUrl);
-    return true;
+    try {
+      Response response = await Dio().get(Api.logoutUrl);
+      if (response.statusCode == 200) {
+        if (response.data["success"] == "true") {
+          return true;
+        } else {
+          return false;
+        }
+      }
+    } catch (e) {
+      return false;
+    }
   }
 
   static Future<UserModel> register(String username, String password) async {
     params.addAll({"username": username, "password": password});
-    Response response = await Dio().post(Api.registerUrl, queryParameters: params);
-    return UserModel.fromJson(response.data);
+    try {
+      Response response =
+          await Dio().post(Api.registerUrl, queryParameters: params);
+      return UserModel.fromJson(response.data);
+    } catch (e) {}
   }
 
   static Future<UserModel> getUserInfo(String token) async {

+ 9 - 9
lib/main.dart

@@ -1,7 +1,6 @@
 import 'package:flutter/material.dart';
 import 'package:flutter_screenutil/flutter_screenutil.dart';
 import 'package:flutter_tracker/pages/login_page.dart';
-import 'package:flutter_tracker/pages/welcome_page.dart';
 import 'package:shared_preferences/shared_preferences.dart';
 
 import 'index_page.dart';
@@ -29,14 +28,15 @@ class MyApp extends StatelessWidget {
   Widget build(BuildContext context) {
     return ScreenUtilInit(
       designSize: const Size(750, 1344),
-      builder: () => MaterialApp(
-        title: '追踪者',
-        theme: ThemeData(
-          primarySwatch: Colors.blue,
-        ),
-        debugShowCheckedModeBanner: false,
-        home: true ? IndexPage() : WelComePage(),
-      ),
+      builder: () =>
+          MaterialApp(
+            title: '追踪者',
+            theme: ThemeData(
+              primarySwatch: Colors.blue,
+            ),
+            debugShowCheckedModeBanner: false,
+            home: isLogin ? IndexPage() : LoginPage(),
+          ),
     );
   }
 }

+ 69 - 66
lib/pages/mine_page.dart

@@ -61,76 +61,77 @@ class _MinePageState extends State<MinePage> {
               const SizedBox(
                 height: 10,
               ),
+              Text("健康状态:"),
               Image.asset(
-                "assets/images/head.jpg",
-                width: 150,
-                height: 150,
+                "assets/images/green.jpg",
+                width: 200,
+                height: 200,
               ),
               const SizedBox(
                 height: 10,
               ),
-              Container(
-                width: _size.width * 0.9,
-                height: _size.width * 0.4,
-                decoration: BoxDecoration(
-                    color: Colors.white,
-                    borderRadius: BorderRadius.circular(20)),
-                child: Column(
-                  crossAxisAlignment: CrossAxisAlignment.start,
-                  children: [
-                    Container(
-                      child: Text(
-                        "更多",
-                        style: TextStyle(
-                            fontSize: 20, fontWeight: FontWeight.bold),
-                      ),
-                      margin: EdgeInsets.only(left: 10, top: 5),
-                    ),
-                    Row(
-                      children: [
-                        Expanded(
-                          child: InkWell(
-                            onTap: () {
-                              goSetting();
-                            },
-                            child: Column(
-                              children: [
-                                SizedBox(
-                                  height: 10,
-                                ),
-                                Image.asset("assets/images/setting.png"),
-                                const SizedBox(
-                                  height: 10,
-                                ),
-                                const Text("设置")
-                              ],
-                            ),
-                          ),
-                        ),
-                        Expanded(
-                          child: InkWell(
-                            onTap: () {
-                              aboutUs();
-                            },
-                            child: Column(
-                              children: [
-                                SizedBox(
-                                  height: 10,
-                                ),
-                                Image.asset("assets/images/about.png"),
-                                const SizedBox(
-                                  height: 10,
-                                ),
-                                const Text("关于我们")
-                              ],
-                            ),
-                          ),
-                        ),
-                      ],
-                    ),
-                  ],
-                ),
-              ),
+              // Container(
+              //   width: _size.width * 0.9,
+              //   height: _size.width * 0.4,
+              //   decoration: BoxDecoration(
+              //       color: Colors.white,
+              //       borderRadius: BorderRadius.circular(20)),
+              //   child: Column(
+              //     crossAxisAlignment: CrossAxisAlignment.start,
+              //     children: [
+              //       Container(
+              //         child: Text(
+              //           "更多",
+              //           style: TextStyle(
+              //               fontSize: 20, fontWeight: FontWeight.bold),
+              //         ),
+              //         margin: EdgeInsets.only(left: 10, top: 5),
+              //       ),
+              //       Row(
+              //         children: [
+              //           Expanded(
+              //             child: InkWell(
+              //               onTap: () {
+              //                 goSetting();
+              //               },
+              //               child: Column(
+              //                 children: [
+              //                   SizedBox(
+              //                     height: 10,
+              //                   ),
+              //                   Image.asset("assets/images/setting.png"),
+              //                   const SizedBox(
+              //                     height: 10,
+              //                   ),
+              //                   const Text("设置")
+              //                 ],
+              //               ),
+              //             ),
+              //           ),
+              //           Expanded(
+              //             child: InkWell(
+              //               onTap: () {
+              //                 aboutUs();
+              //               },
+              //               child: Column(
+              //                 children: [
+              //                   SizedBox(
+              //                     height: 10,
+              //                   ),
+              //                   Image.asset("assets/images/about.png"),
+              //                   const SizedBox(
+              //                     height: 10,
+              //                   ),
+              //                   const Text("关于我们")
+              //                 ],
+              //               ),
+              //             ),
+              //           ),
+              //         ],
+              //       ),
+              //     ],
+              //   ),
+              // ),
               SizedBox(
                 height: 50,
               ),
@@ -178,7 +179,9 @@ class _MinePageState extends State<MinePage> {
     super.initState();
   }
 
-  void getUserInfo(String token) {}
+  void getUserInfo(String token) {
+
+  }
 
   void logout() async {
     var sharedPreferences = await SharedPreferences.getInstance();

+ 165 - 1
lib/pages/submit_page.dart

@@ -1,4 +1,6 @@
 import 'package:flutter/material.dart';
+import 'package:flutter_tracker/model/config.dart';
+import 'package:flutter_tracker/utils/app_util.dart';
 
 class SubmitPage extends StatefulWidget {
   const SubmitPage({Key key}) : super(key: key);
@@ -8,8 +10,170 @@ class SubmitPage extends StatefulWidget {
 }
 
 class _SubmitPageState extends State<SubmitPage> {
+  Size get _size => MediaQuery.of(context).size;
+  final TextEditingController _controllerUsn = TextEditingController();
+  final TextEditingController _controllerTel = TextEditingController();
+  final TextEditingController _controllerAddress = TextEditingController();
+  final GlobalKey _formKey = GlobalKey<FormState>();
+
+  String _userName = "";
+  String _tel = "";
+  String _addresds = "";
+
   @override
   Widget build(BuildContext context) {
-    return Container();
+    return Scaffold(
+      appBar: AppBar(
+        title: Text("疫情上报"),
+      ),
+      body: SizedBox(
+        width: _size.width,
+        child: SingleChildScrollView(
+          child: Padding(
+            padding:
+                const EdgeInsets.symmetric(vertical: 16.0, horizontal: 24.0),
+            child: Column(
+              children: [
+                TextFormField(
+                  autofocus: true,
+                  controller: _controllerUsn,
+                  decoration: const InputDecoration(
+                      labelText: "姓名:",
+                      hintText: "请输入真实姓名",
+                      icon: Icon(Icons.person)),
+                  // 校验用户名
+                  validator: (v) {
+                    return v.trim().length > 0 ? null : "姓名不能为空";
+                  },
+                  onChanged: (inputStr) {
+                    _userName = inputStr;
+                  },
+                ),
+                TextFormField(
+                  controller: _controllerTel,
+                  decoration: const InputDecoration(
+                      labelText: "电话:",
+                      hintText: "联系电话",
+                      icon: Icon(Icons.phone)),
+                  validator: (v) {
+                    return v.trim().length > 11 ? null : "手机号错误";
+                  },
+                  onChanged: (inputStr) {
+                    _tel = inputStr;
+                  },
+                ),
+                TextFormField(
+                  controller: _controllerAddress,
+                  decoration: const InputDecoration(
+                      labelText: "住址:",
+                      hintText: "请输入家庭住址",
+                      icon: Icon(Icons.house)),
+                  validator: (v) {
+                    return v.trim().length > 0 ? null : "请输入地址";
+                  },
+                  onChanged: (inputStr) {
+                    _addresds = inputStr;
+                  },
+                ),
+                SizedBox(
+                  height: 10,
+                ),
+                Align(
+                  child: Text(
+                    "健康状态:",
+                    style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold),
+                  ),
+                  alignment: Alignment.centerLeft,
+                ),
+                Row(
+                  children: [
+                    RadioListTile(
+                      title: Text("阴性"),
+                      value: 0,
+                      groupValue: 0,
+                      onChanged: (value) {},
+                    ),
+                    RadioListTile(
+                      title: Text("阳性"),
+                      value: 1,
+                      groupValue: 0,
+                      onChanged: (value) {},
+                    ),
+                  ],
+                ),
+                SizedBox(
+                  height: 10,
+                ),
+                Align(
+                  child: Text(
+                    "核酸检测:",
+                    style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold),
+                  ),
+                  alignment: Alignment.centerLeft,
+                ),
+                Text("请拍照上传清晰的核酸证明图片"),
+                InkWell(
+                  onTap: () {
+                    chooseImg();
+                  },
+                  child: Container(
+                    child: Image.asset(
+                      "assets/images/add.png",
+                      width: 160,
+                      height: 160,
+                    ),
+                  ),
+                ),
+                SizedBox(
+                  height: 10,
+                ),
+                Container(
+                  width: 150,
+                  child: InkWell(
+                    onTap: () {
+                      // 登录
+                      submitInfo();
+                    },
+                    child: Container(
+                      width: double.infinity,
+                      height: AppUtil.height(80),
+                      padding: EdgeInsets.only(
+                          right: AppUtil.width(20), left: AppUtil.width(20)),
+                      decoration: BoxDecoration(
+                          gradient: const LinearGradient(colors: [
+                            ThemeColor.loignColor,
+                            ThemeColor.loignColor
+                          ]),
+                          borderRadius: BorderRadius.circular(10),
+                          boxShadow: const [
+                            BoxShadow(
+                              offset: Offset(1.0, 5.0),
+                              color: ThemeColor.loignColor,
+                              blurRadius: 5.0,
+                            )
+                          ]),
+                      child: const Center(
+                        child: Text(
+                          "登录",
+                          style: TextStyle(fontSize: 20, color: Colors.white),
+                        ),
+                      ),
+                    ),
+                  ),
+                ),
+              ],
+            ),
+          ),
+        ),
+      ),
+    );
+  }
+
+  void submitInfo() {
+
+  }
+
+  void chooseImg() {
+
   }
 }

+ 122 - 2
lib/pages/track_page.dart

@@ -1,4 +1,6 @@
 import 'package:flutter/material.dart';
+import 'package:flutter_tracker/utils/app_util.dart';
+import 'package:flutter_tracker/views/contact_card.dart';
 
 class TrackPage extends StatefulWidget {
   const TrackPage({Key key}) : super(key: key);
@@ -8,10 +10,128 @@ class TrackPage extends StatefulWidget {
 }
 
 class _TrackPageState extends State<TrackPage> {
+  String testText = '';
+  List<dynamic> contactTraces = [];
+  List<dynamic> contactTimes = [];
+  List<dynamic> contactLocations = [];
+
   @override
   Widget build(BuildContext context) {
-    return Container(
-      child: Center(child: Text('Track')),
+    return Column(
+      children: <Widget>[
+        Expanded(
+          child: Padding(
+            padding: EdgeInsets.only(
+              left: 25.0,
+              right: 25.0,
+              bottom: 10.0,
+              top: 30.0,
+            ),
+            child: Container(
+              height: 50.0,
+              width: double.infinity,
+              decoration: BoxDecoration(
+                color: Colors.deepPurple[500],
+                borderRadius: BorderRadius.circular(20.0),
+                boxShadow: const [
+                  BoxShadow(
+                    color: Colors.black,
+                    blurRadius: 4.0,
+                    spreadRadius: 0.0,
+                    offset: Offset(2.0, 2.0), // shadow direction: bottom right
+                  )
+                ],
+              ),
+              child: Row(
+                children: const <Widget>[
+                  Expanded(
+                    child: Image(
+                      image: AssetImage('assets/images/corona.png'),
+                    ),
+                  ),
+                  Expanded(
+                    flex: 2,
+                    child: Text(
+                      '附近用户',
+                      textAlign: TextAlign.left,
+                      style: TextStyle(
+                        fontSize: 21.0,
+                        color: Colors.white,
+                        fontWeight: FontWeight.w500,
+                      ),
+                    ),
+                  )
+                ],
+              ),
+            ),
+          ),
+        ),
+        Padding(
+          padding: EdgeInsets.only(bottom: 200.0),
+          child: RaisedButton(
+            shape: RoundedRectangleBorder(
+                borderRadius: BorderRadius.circular(20.0)),
+            elevation: 5.0,
+            color: Colors.deepPurple[400],
+            onPressed: () async {
+              startTrack();
+            },
+            child: const Text(
+              '开始追踪',
+              style: TextStyle(
+                fontSize: 20.0,
+                fontWeight: FontWeight.bold,
+                color: Colors.white,
+              ),
+            ),
+          ),
+        ),
+        Expanded(
+          flex: 2,
+          child: Padding(
+            padding: const EdgeInsets.symmetric(horizontal: 25.0),
+            child: ListView.builder(
+              itemBuilder: (context, index) {
+                return ContactCard(
+                  imagePath: 'assets/images/head.jpg',
+                  email: contactTraces[index],
+                  infection: 'Not-Infected',
+                  contactUsername: contactTraces[index],
+                  contactTime: contactTimes[index],
+                  contactLocation: contactLocations[index],
+                );
+              },
+              itemCount: contactTraces.length,
+            ),
+          ),
+        ),
+      ],
     );
   }
+
+  void startTrack() async {
+    // try {
+    //   bool a = await Nearby().startAdvertising(
+    //     loggedInUser.email,
+    //     strategy,
+    //     onConnectionInitiated: null,
+    //     onConnectionResult: (id, status) {
+    //       print(status);
+    //     },
+    //     onDisconnected: (id) {
+    //       print('Disconnected $id');
+    //     },
+    //   );
+    //
+    //   print('ADVERTISING ${a.toString()}');
+    // } catch (e) {
+    //   print(e);
+    // }
+
+    discovery();
+    AppUtil.buildToast("正在搜索附近的人...");
+    AppUtil.buildToast("追踪用户状态中...");
+  }
+
+  void discovery() {}
 }

+ 34 - 0
lib/views/bottom_sheet_text.dart

@@ -0,0 +1,34 @@
+import 'package:flutter/material.dart';
+
+class BottomSheetText extends StatelessWidget {
+  const BottomSheetText({
+    this.question,
+    this.result,
+  });
+
+  final String question;
+  final String result;
+
+  @override
+  Widget build(BuildContext context) {
+    return RichText(
+      text: TextSpan(
+        style: DefaultTextStyle.of(context).style,
+        children: <TextSpan>[
+          TextSpan(
+              text: '$question: ',
+              style: TextStyle(
+                fontWeight: FontWeight.bold,
+                fontSize: 22.0,
+              )),
+          TextSpan(
+            text: '$result',
+            style: TextStyle(
+              fontSize: 20.0,
+            ),
+          ),
+        ],
+      ),
+    );
+  }
+}

+ 64 - 0
lib/views/contact_card.dart

@@ -0,0 +1,64 @@
+import 'package:flutter/material.dart';
+
+import 'bottom_sheet_text.dart';
+
+class ContactCard extends StatelessWidget {
+  ContactCard(
+      {this.imagePath,
+      this.email,
+      this.infection,
+      this.contactUsername,
+      this.contactTime,
+      this.contactLocation});
+
+  final String imagePath;
+  final String email;
+  final String infection;
+  final String contactUsername;
+  final DateTime contactTime;
+  final String contactLocation;
+
+  @override
+  Widget build(BuildContext context) {
+    return Card(
+      elevation: 3.0,
+      shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10.0)),
+      child: ListTile(
+        leading: CircleAvatar(
+          backgroundImage: AssetImage(imagePath),
+        ),
+        trailing: Icon(Icons.more_horiz),
+        title: Text(
+          email,
+          style: TextStyle(
+            color: Colors.deepPurple[700],
+            fontWeight: FontWeight.bold,
+          ),
+        ),
+        subtitle: Text(infection),
+        onTap: () => showModalBottomSheet(
+            context: context,
+            builder: (builder) {
+              return Padding(
+                padding: EdgeInsets.symmetric(vertical: 50.0, horizontal: 10.0),
+                child: Column(
+                  children: <Widget>[
+                    BottomSheetText(
+                        question: 'Username', result: contactUsername),
+                    SizedBox(height: 5.0),
+                    BottomSheetText(
+                        question: 'Contact Time',
+                        result: contactTime.toString()),
+                    SizedBox(height: 5.0),
+                    BottomSheetText(
+                        question: 'Contact Location', result: contactLocation),
+                    SizedBox(height: 5.0),
+                    BottomSheetText(question: 'Times Contacted', result: '3'),
+                  ],
+                ),
+              );
+            }),
+      ),
+    );
+  }
+}