Browse Source

[new]增加登录逻辑&mmkv&启动图标

zk 1 year ago
parent
commit
0003344465

+ 6 - 6
android/app/build.gradle

@@ -25,7 +25,7 @@ if (flutterVersionName == null) {
 
 android {
     namespace = "com.atmob.elec_asst"
-    compileSdk = flutter.compileSdkVersion
+    compileSdk = rootProject.ext.compileSdkVersion
     ndkVersion = flutter.ndkVersion
 
     compileOptions {
@@ -35,13 +35,13 @@ android {
 
     defaultConfig {
         // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
-        applicationId = "com.atmob.elec_asst"
+        applicationId = rootProject.ext.applicationId
         // You can update the following values to match your application needs.
         // For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-gradle-build-configuration.
-        minSdk = flutter.minSdkVersion
-        targetSdk = flutter.targetSdkVersion
-        versionCode = flutterVersionCode.toInteger()
-        versionName = flutterVersionName
+        minSdk = rootProject.ext.minSdkVersion
+        targetSdk = rootProject.ext.targetSdkVersion
+        versionCode = flutter.versionCode
+        versionName = flutter.versionName
     }
 
     signingConfigs {

BIN
android/app/src/main/res/mipmap-hdpi/ic_launcher.png


BIN
android/app/src/main/res/mipmap-mdpi/ic_launcher.png


BIN
android/app/src/main/res/mipmap-xhdpi/ic_launcher.png


BIN
android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png


BIN
android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png


+ 6 - 0
android/build.gradle

@@ -1,4 +1,10 @@
 allprojects {
+    ext {
+        compileSdkVersion = 34
+        applicationId = "com.atmob.elec_asst"
+        minSdkVersion = 23
+        targetSdkVersion = 32
+    }
     repositories {
         google()
         mavenCentral()

BIN
assets/images/logo.png


+ 1 - 0
assets/string/base/string.xml

@@ -24,4 +24,5 @@
     <string name="main_drawer_check_updates">检查更新</string>
     <string name="main_drawer_complaint_and_report">投诉举报</string>
     <string name="main_drawer_record_number">备案号216545885</string>
+    <string name="network_error">网络异常</string>
 </resources>

+ 35 - 0
lib/data/repositories/account_repository.dart

@@ -0,0 +1,35 @@
+import 'dart:async';
+
+import 'package:electronic_assistant/data/api/atmob_api.dart';
+import 'package:flutter/cupertino.dart';
+
+import '../../utils/http_handler.dart';
+import '../api/request/login_request.dart';
+import '../api/request/verification_code_request.dart';
+import '../api/response/login_response.dart';
+
+class AccountRepository {
+  AccountRepository._() {
+    debugPrint('AccountRepository init');
+  }
+
+  String? token;
+
+  Future<void> getVerificationCode(String phone) {
+    return atmobApi
+        .getVerificationCode(VerificationCodeRequest(phone))
+        .then(HttpHandler.handle(false));
+  }
+
+  Future<LoginResponse> login(String phone, String code) {
+    return atmobApi
+        .login(LoginRequest(phone, code))
+        .then(HttpHandler.handle(true))
+        .then((response) {
+      token = response.authToken;
+      return response;
+    });
+  }
+}
+
+final accountRepository = AccountRepository._();

+ 10 - 1
lib/main.dart

@@ -1,12 +1,21 @@
 import 'package:electronic_assistant/resource/string_source.dart';
 import 'package:electronic_assistant/router/app_pages.dart';
+import 'package:electronic_assistant/utils/app_info_util.dart';
+import 'package:electronic_assistant/utils/mmkv_util.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter_screenutil/flutter_screenutil.dart';
 import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
 import 'package:get/get.dart';
 import 'package:get/get_navigation/src/root/get_material_app.dart';
 
-void main() {
+void main() async {
+  WidgetsFlutterBinding.ensureInitialized();
+
+  //获取包信息
+  appInfoUtil.init();
+  //mmkv
+  await KVUtil.init();
+
   runApp(const MyApp());
 }
 

+ 3 - 1
lib/module/home/view.dart

@@ -10,6 +10,7 @@ import 'package:flutter_screenutil/flutter_screenutil.dart';
 import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
 import 'package:get/get.dart';
 
+import '../../router/app_pages.dart';
 import 'controller.dart';
 
 class HomePage extends BasePage<HomePageController> {
@@ -151,7 +152,8 @@ class HomePage extends BasePage<HomePageController> {
   GestureDetector buildGoLogin() {
     return GestureDetector(
       onTap: () {
-        controller.showLoginDrawer();
+        Get.toNamed(RoutePath.login);
+        // controller.showLoginDrawer();
       },
       child: Row(
         children: [

+ 39 - 0
lib/module/login/controller.dart

@@ -0,0 +1,39 @@
+import 'package:electronic_assistant/base/base_controller.dart';
+import 'package:electronic_assistant/data/repositories/account_repository.dart';
+import 'package:electronic_assistant/utils/error_handler.dart';
+import 'package:electronic_assistant/utils/toast_util.dart';
+import 'package:get/get.dart';
+
+class LoginController extends BaseController {
+  final phone = "".obs;
+  final code = "".obs;
+
+  @override
+  void onInit() {
+    // TODO: implement onInit
+    super.onInit();
+  }
+
+  void getUserCode() {
+    if (phone.value.isEmpty) {
+      ToastUtil.showToast("请输入手机号");
+      return;
+    }
+    accountRepository.getVerificationCode(phone.value).then((data) {
+      ToastUtil.showToast("验证码已发送");
+    }).catchError((error) {
+      ErrorHandler.toastError(error);
+    });
+  }
+
+  void login() {
+    if (phone.value.isEmpty || code.value.isEmpty) {
+      return;
+    }
+    accountRepository.login(phone.value, code.value).then((data) {
+      ToastUtil.showToast("登录成功");
+    }).catchError((error) {
+      ErrorHandler.toastError(error);
+    });
+  }
+}

+ 33 - 3
lib/module/login/view.dart

@@ -1,12 +1,42 @@
 import 'package:electronic_assistant/base/base_page.dart';
 import 'package:flutter/material.dart';
 
-class LoginPage extends BasePage {
+import 'controller.dart';
+
+class LoginPage extends BasePage<LoginController> {
   const LoginPage({super.key});
 
   @override
   Widget buildBody(BuildContext context) {
-    // TODO: implement buildBody
-    throw UnimplementedError();
+    return Scaffold(
+      body: Column(
+        children: <Widget>[
+          const TextField(
+            decoration: InputDecoration(
+                labelText: "手机号",
+                hintText: "您的手机号",
+                prefixIcon: Icon(Icons.person)),
+          ),
+          const TextField(
+            decoration: InputDecoration(
+                labelText: "验证码",
+                hintText: "您的验证码",
+                prefixIcon: Icon(Icons.lock)),
+          ),
+          ElevatedButton(
+            child: const Text("获取验证码"),
+            onPressed: () {
+              controller.getUserCode();
+            },
+          ),
+          ElevatedButton(
+            child: const Text("登录"),
+            onPressed: () {
+              controller.login();
+            },
+          )
+        ],
+      ),
+    );
   }
 }

+ 27 - 18
lib/module/main/drawer_view.dart

@@ -9,6 +9,7 @@ import 'package:get/get.dart';
 import '../../resource/assets.gen.dart';
 import '../../resource/colors.gen.dart';
 import '../../resource/string.gen.dart';
+import '../../router/app_pages.dart';
 
 Widget buildDrawerContent(MainController controller) {
   return SafeArea(
@@ -17,24 +18,7 @@ Widget buildDrawerContent(MainController controller) {
       child: Column(
         children: [
           SizedBox(height: 12.h),
-          Row(
-            crossAxisAlignment: CrossAxisAlignment.center,
-            children: [
-              SizedBox(
-                  width: 44.w,
-                  height: 44.w,
-                  child: Assets.images.iconHomeNoLogin.image()),
-              SizedBox(width: 10.w),
-              Text(StringName.homeGoLogin.tr,
-                  style: TextStyle(
-                      fontSize: 20.sp,
-                      color: ColorName.primaryTextColor,
-                      fontWeight: FontWeight.bold)),
-              SizedBox(width: 8.w),
-              SizedBox(
-                  height: 20.w, child: Assets.images.iconGoLoginArrow.image()),
-            ],
-          ),
+          buildUserInfoView(),
           SizedBox(height: 12.h),
           Container(
             height: 72.w,
@@ -160,6 +144,31 @@ Widget buildDrawerContent(MainController controller) {
   );
 }
 
+Widget buildUserInfoView() {
+  return GestureDetector(
+    onTap: () {
+      Get.toNamed(RoutePath.login);
+    },
+    child: Row(
+      crossAxisAlignment: CrossAxisAlignment.center,
+      children: [
+        SizedBox(
+            width: 44.w,
+            height: 44.w,
+            child: Assets.images.iconHomeNoLogin.image()),
+        SizedBox(width: 10.w),
+        Text(StringName.homeGoLogin.tr,
+            style: TextStyle(
+                fontSize: 20.sp,
+                color: ColorName.primaryTextColor,
+                fontWeight: FontWeight.bold)),
+        SizedBox(width: 8.w),
+        SizedBox(height: 20.w, child: Assets.images.iconGoLoginArrow.image()),
+      ],
+    ),
+  );
+}
+
 Widget buildOperationItem(Image icon, String title, Function onTap,
     {Widget? rightView = const SizedBox.shrink()}) {
   return GestureDetector(

+ 2 - 0
lib/router/app_pages.dart

@@ -4,6 +4,7 @@ import 'package:get/get.dart';
 import '../module/files/search/view.dart';
 import '../module/files/view.dart';
 import '../module/home/controller.dart';
+import '../module/login/controller.dart';
 import '../module/login/view.dart';
 import '../module/main/view.dart';
 import '../module/splash/view.dart';
@@ -31,6 +32,7 @@ class AppBinding extends Bindings {
   void dependencies() {
     lazyPut(() => MainController());
     lazyPut(() => HomePageController());
+    lazyPut(() => LoginController());
   }
 
   void lazyPut<S>(InstanceBuilderCallback<S> builder) {

+ 26 - 0
lib/utils/error_handler.dart

@@ -0,0 +1,26 @@
+import 'package:electronic_assistant/utils/http_handler.dart';
+import 'package:electronic_assistant/utils/toast_util.dart';
+import 'package:get/get.dart';
+
+import '../resource/string.gen.dart';
+
+class ErrorHandler {
+  ErrorHandler._();
+
+  static void toastError(dynamic error, {String? message}) {
+    String toastMessage = (error is ServerErrorException)
+        ? _getToastMessageFromError(error)
+        : _getDefaultToastMessage(message);
+    ToastUtil.showToast(toastMessage);
+  }
+
+  static String _getToastMessageFromError(ServerErrorException error) {
+    return error.message ?? StringName.networkError.tr;
+  }
+
+  static String _getDefaultToastMessage(String? message) {
+    return message ?? StringName.networkError.tr;
+  }
+}
+
+abstract class ErrorCode {}

+ 26 - 0
lib/utils/http_handler.dart

@@ -0,0 +1,26 @@
+import 'dart:async';
+import 'package:electronic_assistant/base/base_response.dart';
+
+class HttpHandler {
+  static FutureOr<T> Function(BaseResponse<T> value) handle<T>(
+      bool allowEmptyData) {
+    return (BaseResponse<T> response) {
+      if (response.code == 0) {
+        if (response.data != null || allowEmptyData) {
+          return response.data!;
+        } else {
+          throw Exception('data is null');
+        }
+      } else {
+        throw ServerErrorException(response.code, response.message);
+      }
+    };
+  }
+}
+
+class ServerErrorException implements Exception {
+  final int? code;
+  final String? message;
+
+  ServerErrorException(this.code, this.message);
+}

+ 44 - 0
lib/utils/mmkv_util.dart

@@ -0,0 +1,44 @@
+import 'package:mmkv/mmkv.dart';
+
+class KVUtil {
+  KVUtil._();
+
+  static MMKV? mmkv;
+
+  static init() async {
+    await MMKV.initialize();
+    mmkv = MMKV.defaultMMKV();
+  }
+
+  static void setString(String key, String value) {
+    mmkv?.encodeString(key, value);
+  }
+
+  static String? getString(String key, String? defaultValue) {
+    return mmkv?.decodeString(key) ?? defaultValue;
+  }
+
+  static void setInt(String key, int value) {
+    mmkv?.encodeInt(key, value);
+  }
+
+  static int? getInt(String key, int defaultValue) {
+    return mmkv?.decodeInt(key, defaultValue: defaultValue);
+  }
+
+  static void setBool(String key, bool value) {
+    mmkv?.encodeBool(key, value);
+  }
+
+  static bool? getBool(String key, bool defaultValue) {
+    return mmkv?.decodeBool(key, defaultValue: defaultValue);
+  }
+
+  static void setDouble(String key, double value) {
+    mmkv?.encodeDouble(key, value);
+  }
+
+  static double? getDouble(String key, double defaultValue) {
+    return mmkv?.decodeDouble(key, defaultValue: defaultValue);
+  }
+}

+ 165 - 13
pubspec.lock

@@ -17,6 +17,14 @@ packages:
       url: "https://pub.dev"
     source: hosted
     version: "6.4.1"
+  archive:
+    dependency: transitive
+    description:
+      name: archive
+      sha256: cb6a278ef2dbb298455e1a713bda08524a175630ec643a242c399c932a0a1f7d
+      url: "https://pub.dev"
+    source: hosted
+    version: "3.6.1"
   args:
     dependency: transitive
     description:
@@ -121,6 +129,14 @@ packages:
       url: "https://pub.dev"
     source: hosted
     version: "2.0.3"
+  cli_util:
+    dependency: transitive
+    description:
+      name: cli_util
+      sha256: c05b7406fdabc7a49a3929d4af76bcaccbbffcbcdcf185b082e1ae07da323d19
+      url: "https://pub.dev"
+    source: hosted
+    version: "0.4.1"
   clock:
     dependency: transitive
     description:
@@ -217,6 +233,14 @@ packages:
       url: "https://pub.dev"
     source: hosted
     version: "1.3.1"
+  ffi:
+    dependency: transitive
+    description:
+      name: ffi
+      sha256: "16ed7b077ef01ad6170a3d0c57caa4a112a38d7a2ed5602e0aca9ca6f3d98da6"
+      url: "https://pub.dev"
+    source: hosted
+    version: "2.1.3"
   file:
     dependency: transitive
     description:
@@ -254,6 +278,14 @@ packages:
       url: "https://pub.dev"
     source: hosted
     version: "5.6.0"
+  flutter_launcher_icons:
+    dependency: "direct dev"
+    description:
+      name: flutter_launcher_icons
+      sha256: "526faf84284b86a4cb36d20a5e45147747b7563d921373d4ee0559c54fcdbcea"
+      url: "https://pub.dev"
+    source: hosted
+    version: "0.13.1"
   flutter_lints:
     dependency: "direct dev"
     description:
@@ -339,6 +371,14 @@ packages:
       url: "https://pub.dev"
     source: hosted
     version: "4.0.2"
+  image:
+    dependency: transitive
+    description:
+      name: image
+      sha256: "2237616a36c0d69aef7549ab439b833fb7f9fb9fc861af2cc9ac3eedddd69ca8"
+      url: "https://pub.dev"
+    source: hosted
+    version: "4.2.0"
   image_size_getter:
     dependency: transitive
     description:
@@ -383,18 +423,18 @@ packages:
     dependency: transitive
     description:
       name: leak_tracker
-      sha256: "7f0df31977cb2c0b88585095d168e689669a2cc9b97c309665e3386f3e9d341a"
+      sha256: "3f87a60e8c63aecc975dda1ceedbc8f24de75f09e4856ea27daf8958f2f0ce05"
       url: "https://pub.dev"
     source: hosted
-    version: "10.0.4"
+    version: "10.0.5"
   leak_tracker_flutter_testing:
     dependency: transitive
     description:
       name: leak_tracker_flutter_testing
-      sha256: "06e98f569d004c1315b991ded39924b21af84cf14cc94791b8aea337d25b57f8"
+      sha256: "932549fb305594d82d7183ecd9fa93463e9914e1b67cacc34bc40906594a1806"
       url: "https://pub.dev"
     source: hosted
-    version: "3.0.3"
+    version: "3.0.5"
   leak_tracker_testing:
     dependency: transitive
     description:
@@ -431,18 +471,18 @@ packages:
     dependency: transitive
     description:
       name: material_color_utilities
-      sha256: "0e0a020085b65b6083975e499759762399b4475f766c21668c4ecca34ea74e5a"
+      sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec
       url: "https://pub.dev"
     source: hosted
-    version: "0.8.0"
+    version: "0.11.1"
   meta:
     dependency: transitive
     description:
       name: meta
-      sha256: "7687075e408b093f36e6bbf6c91878cc0d4cd10f409506f7bc996f68220b9136"
+      sha256: bdb68674043280c3428e9ec998512fb681678676b3c54e773629ffe74419f8c7
       url: "https://pub.dev"
     source: hosted
-    version: "1.12.0"
+    version: "1.15.0"
   mime:
     dependency: transitive
     description:
@@ -451,6 +491,46 @@ packages:
       url: "https://pub.dev"
     source: hosted
     version: "1.0.5"
+  mmkv:
+    dependency: "direct main"
+    description:
+      name: mmkv
+      sha256: feaf601749734a36cbfb840df45f9ece6e0d3b619959a5f63f002feca0518c1a
+      url: "https://pub.dev"
+    source: hosted
+    version: "1.3.9"
+  mmkv_android:
+    dependency: transitive
+    description:
+      name: mmkv_android
+      sha256: d54fed971a8918c6084012bb99be4262fdf0081a4bcbc9b44362598b01087a0b
+      url: "https://pub.dev"
+    source: hosted
+    version: "1.0.5"
+  mmkv_ios:
+    dependency: transitive
+    description:
+      name: mmkv_ios
+      sha256: "26cba4ca68cfe9c1480481518865c973110b3331698c0ccbce1bc6ba1eb08e02"
+      url: "https://pub.dev"
+    source: hosted
+    version: "1.0.5"
+  mmkv_ohos:
+    dependency: transitive
+    description:
+      name: mmkv_ohos
+      sha256: "33854328ffb2daf6b286eb8e08fc2d93fcb7efba46aa30ecd5906f6cc4ef79f3"
+      url: "https://pub.dev"
+    source: hosted
+    version: "1.0.1"
+  mmkv_platform_interface:
+    dependency: transitive
+    description:
+      name: mmkv_platform_interface
+      sha256: "86d862638e75e6a1696066798b2672339e22bd42077d7dc18a7f1aa50c545446"
+      url: "https://pub.dev"
+    source: hosted
+    version: "1.0.1"
   package_config:
     dependency: transitive
     description:
@@ -483,6 +563,54 @@ packages:
       url: "https://pub.dev"
     source: hosted
     version: "1.0.1"
+  path_provider:
+    dependency: transitive
+    description:
+      name: path_provider
+      sha256: fec0d61223fba3154d87759e3cc27fe2c8dc498f6386c6d6fc80d1afdd1bf378
+      url: "https://pub.dev"
+    source: hosted
+    version: "2.1.4"
+  path_provider_android:
+    dependency: transitive
+    description:
+      name: path_provider_android
+      sha256: "6f01f8e37ec30b07bc424b4deabac37cacb1bc7e2e515ad74486039918a37eb7"
+      url: "https://pub.dev"
+    source: hosted
+    version: "2.2.10"
+  path_provider_foundation:
+    dependency: transitive
+    description:
+      name: path_provider_foundation
+      sha256: f234384a3fdd67f989b4d54a5d73ca2a6c422fa55ae694381ae0f4375cd1ea16
+      url: "https://pub.dev"
+    source: hosted
+    version: "2.4.0"
+  path_provider_linux:
+    dependency: transitive
+    description:
+      name: path_provider_linux
+      sha256: f7a1fe3a634fe7734c8d3f2766ad746ae2a2884abe22e241a8b301bf5cac3279
+      url: "https://pub.dev"
+    source: hosted
+    version: "2.2.1"
+  path_provider_platform_interface:
+    dependency: transitive
+    description:
+      name: path_provider_platform_interface
+      sha256: "88f5779f72ba699763fa3a3b06aa4bf6de76c8e5de842cf6f29e2e06476c2334"
+      url: "https://pub.dev"
+    source: hosted
+    version: "2.1.2"
+  path_provider_windows:
+    dependency: transitive
+    description:
+      name: path_provider_windows
+      sha256: bd6f00dbd873bfb70d0761682da2b3a2c2fccc2b9e84c495821639601d81afe7
+      url: "https://pub.dev"
+    source: hosted
+    version: "2.3.0"
   petitparser:
     dependency: transitive
     description:
@@ -491,6 +619,22 @@ packages:
       url: "https://pub.dev"
     source: hosted
     version: "6.0.2"
+  platform:
+    dependency: transitive
+    description:
+      name: platform
+      sha256: "9b71283fc13df574056616011fb138fd3b793ea47cc509c189a6c3fa5f8a1a65"
+      url: "https://pub.dev"
+    source: hosted
+    version: "3.1.5"
+  plugin_platform_interface:
+    dependency: transitive
+    description:
+      name: plugin_platform_interface
+      sha256: "4820fbfdb9478b1ebae27888254d445073732dae3d6ea81f0b7e06d5dedc3f02"
+      url: "https://pub.dev"
+    source: hosted
+    version: "2.1.8"
   pool:
     dependency: transitive
     description:
@@ -628,10 +772,10 @@ packages:
     dependency: transitive
     description:
       name: test_api
-      sha256: "9955ae474176f7ac8ee4e989dadfb411a58c30415bcfb648fa04b2b8a03afa7f"
+      sha256: "5b8a98dafc4d5c4c9c72d8b31ab2b23fc13422348d2997120294d3bac86b4ddb"
       url: "https://pub.dev"
     source: hosted
-    version: "0.7.0"
+    version: "0.7.2"
   time:
     dependency: transitive
     description:
@@ -692,10 +836,10 @@ packages:
     dependency: transitive
     description:
       name: vm_service
-      sha256: "3923c89304b715fb1eb6423f017651664a03bf5f4b29983627c4da791f74a4ec"
+      sha256: f652077d0bdf60abe4c1f6377448e8655008eef28f128bc023f7b5e8dfeb48fc
       url: "https://pub.dev"
     source: hosted
-    version: "14.2.1"
+    version: "14.2.4"
   watcher:
     dependency: transitive
     description:
@@ -728,6 +872,14 @@ packages:
       url: "https://pub.dev"
     source: hosted
     version: "3.0.1"
+  xdg_directories:
+    dependency: transitive
+    description:
+      name: xdg_directories
+      sha256: faea9dee56b520b55a566385b84f2e8de55e7496104adada9962e0bd11bcff1d
+      url: "https://pub.dev"
+    source: hosted
+    version: "1.0.4"
   xml:
     dependency: transitive
     description:
@@ -746,4 +898,4 @@ packages:
     version: "3.1.2"
 sdks:
   dart: ">=3.4.3 <4.0.0"
-  flutter: ">=3.18.0-18.0.pre.54"
+  flutter: ">=3.22.0"

+ 13 - 0
pubspec.yaml

@@ -51,6 +51,12 @@ dependencies:
   # dialog
   flutter_smart_dialog: ^4.9.8
 
+  #tencent mmkv
+  mmkv: ^1.3.9
+
+
+
+
 dev_dependencies:
   flutter_test:
     sdk: flutter
@@ -66,8 +72,15 @@ dev_dependencies:
   build_runner: '>=2.3.0 <4.0.0'
   json_serializable: ^6.6.2
   flutter_gen_runner:
+  flutter_launcher_icons: "^0.13.1"
 
 
+#----------启动图标配置---------------
+flutter_launcher_icons:
+  android: true
+  ios: true
+  image_path: "assets/images/logo.png"
+  min_sdk_android: 21
 #----------gen配置---------------
 flutter_gen:
   output: lib/resource/