瀏覽代碼

add login for deploy system

arthur.wu 1 年之前
父節點
當前提交
785571eba4

+ 3 - 0
Tools/Flyinsono.Deployment/.vscode/settings.json

@@ -0,0 +1,3 @@
+{
+    "cmake.sourceDirectory": "D:/Flyinsono/WingCloudServer/Tools/Flyinsono.Deployment/windows"
+}

+ 29 - 0
Tools/Flyinsono.Deployment/lib/Controls/PasswordInput.dart

@@ -0,0 +1,29 @@
+import 'package:flutter/material.dart';
+
+class PasswordInput extends StatefulWidget {
+  @override
+  _PasswordInputState createState() => _PasswordInputState();
+}
+
+class _PasswordInputState extends State<PasswordInput> {
+  String _password = '';
+
+  @override
+  Widget build(BuildContext context) {
+    return Padding(
+      padding: const EdgeInsets.all(16.0),
+      child: TextField(
+        obscureText: true,
+        onChanged: (value) {
+          setState(() {
+            _password = value;
+          });
+        },
+        decoration: InputDecoration(
+          border: OutlineInputBorder(),
+          labelText: 'Password',
+        ),
+      ),
+    );
+  }
+}

+ 47 - 36
Tools/Flyinsono.Deployment/lib/MyView.dart

@@ -1,18 +1,27 @@
 import 'package:colorize_logger/colorize_logger.dart';
 import 'package:flutter/material.dart';
 import 'package:get_it/get_it.dart';
-import 'package:ustest/Services/OperatorService.dart';
+import 'package:ustest/Services/ProfileService.dart';
+import 'package:flutter_gen/gen_l10n/app_localizations.dart';
 
-class MyView extends StatelessWidget {
-  const MyView();
+class MyView extends StatefulWidget {
+  @override
+  State<StatefulWidget> createState() {
+    // TODO: implement createState
+    return _MyViewState();
+  }
+}
+
+class _MyViewState extends State<MyView> {
+  _MyViewState();
 
   @override
   Widget build(BuildContext context) {
-    print("build Myview");
+    final localizations = AppLocalizations.of(context)!;
     GlobalKey myViewKey = GlobalKey();
     return Scaffold(
       body: Center(
-          child: FutureBuilder<Operator?>(
+          child: FutureBuilder<Profile?>(
         key: myViewKey,
         future: loadUserData(),
         builder: (context, snapshot) {
@@ -22,7 +31,7 @@ class MyView extends StatelessWidget {
             );
           } else if (snapshot.hasData) {
             var user = snapshot.data!;
-            if (OperatorService.DefaultNotLoginId == user.id) {
+            if (ProfileService.DefaultNotLoginId == user.id) {
               return Column(
                 children: [
                   CircleAvatar(
@@ -30,41 +39,33 @@ class MyView extends StatelessWidget {
                     radius: 40,
                     child: Text(
                       'Not Login',
-                      style: TextStyle(fontSize: 25, color: Colors.white),
+                      textAlign: TextAlign.center,
+                      style: TextStyle(fontSize: 20, color: Colors.white),
                     ), //Text
                   ),
                   TextButton(
-                      child: const Text("Sign in"),
+                      child: Text(localizations.logIn),
                       onPressed: () => _showSignInScreen(context))
                 ],
               );
             } else {
               return Column(
                 children: [
-                  Row(
-                    children: [
-                      CircleAvatar(
-                        backgroundColor: Colors.greenAccent[400],
-                        radius: 40,
-                        child: Text(
-                          'GeeksForGeeks',
-                          style: TextStyle(fontSize: 25, color: Colors.white),
-                        ), //Text
-                      ),
-                      Column(
-                        children: [Text(user.name)],
-                      )
-                    ],
+                  CircleAvatar(
+                    backgroundColor: Colors.greenAccent[400],
+                    radius: 40,
+                    child: Text(
+                      user.userName,
+                      style: TextStyle(fontSize: 25, color: Colors.white),
+                    ), //Text
+                  ),
+                  SizedBox(
+                    height: 12,
                   ),
-                  Row(
-                    children: [
-                      Text('Name:${user.name}'),
-                      TextButton.icon(
-                          onPressed: () => onLogout(context),
-                          icon: Icon(Icons.logout),
-                          label: Text("注銷"))
-                    ],
-                  )
+                  TextButton.icon(
+                      onPressed: () => onLogout(context),
+                      icon: Icon(Icons.logout),
+                      label: Text(localizations.logout))
                 ],
               );
             }
@@ -78,9 +79,9 @@ class MyView extends StatelessWidget {
     );
   }
 
-  Future<Operator?> loadUserData() async {
+  Future<Profile?> loadUserData() async {
     try {
-      var service = GetIt.instance.get<OperatorService>();
+      var service = GetIt.instance.get<ProfileService>();
       var profile = await service.getCurrentUserAsyc();
       return profile;
     } catch (ex) {
@@ -91,13 +92,23 @@ class MyView extends StatelessWidget {
 
   void _showSignInScreen(BuildContext context) {
     Future.delayed(Duration.zero, () {
-      Navigator.of(context).pushNamed('/signin');
+      Navigator.of(context).pushNamed('/signin').then((value) {
+        _refreshCurrentPage();
+      });
+    });
+  }
+
+  void _refreshCurrentPage() {
+    setState(() {
+      // 在这里添加刷新当前页面所需的逻辑代码
     });
   }
 
   void onLogout(context) {
-    var service = GetIt.instance.get<OperatorService>();
+    var service = GetIt.instance.get<ProfileService>();
     service.logout();
-    Navigator.of(context).pushNamed('/signin');
+    Navigator.of(context).pushNamed('/signin').then((value) {
+      _refreshCurrentPage();
+    });
   }
 }

+ 8 - 8
Tools/Flyinsono.Deployment/lib/Services/DatabaseService.dart

@@ -4,9 +4,9 @@ import 'package:colorize_logger/colorize_logger.dart';
 import 'package:flutter/material.dart';
 import 'package:sqflite/sqflite.dart';
 import 'package:path/path.dart';
-import 'package:ustest/Services/OperatorService.dart';
 import 'package:sqflite_common_ffi/sqflite_ffi.dart';
 import 'package:path_provider/path_provider.dart';
+import 'package:ustest/Services/ProfileService.dart';
 
 class DatabaseService {
   late final Database database;
@@ -32,7 +32,7 @@ class DatabaseService {
         //TODO
       } else {
         await database.execute(
-            'CREATE TABLE $ProfilesTableName(id TEXT PRIMARY KEY, userName TEXT, accessToken TEXT, organizationCode TEXT, host TEXT)');
+            'CREATE TABLE $ProfilesTableName(id TEXT PRIMARY KEY, userName TEXT, accessToken TEXT)');
         Logger.info('CREATE TABLE profiles');
       }
     } else {
@@ -53,30 +53,30 @@ class DatabaseService {
 
   static void _createDb(Database db) {
     db.execute(
-        'CREATE TABLE $ProfilesTableName(id TEXT PRIMARY KEY, userName TEXT, accessToken TEXT, organizationCode TEXT, host TEXT)');
+        'CREATE TABLE $ProfilesTableName(id TEXT PRIMARY KEY, userName TEXT, accessToken TEXT)');
     Logger.info('CREATE TABLE profiles');
     // db.execute(
     //     'CREATE TABLE productItems(id TEXT PRIMARY KEY, title TEXT, subtitle TEXT, url TEXT, thumbnailUrl TEXT, qty INTEGER)');
   }
 
-  Future<Operator?> getProfile() async {
+  Future<Profile?> getProfile() async {
     final List<Map<String, dynamic>> maps =
         await database.query(ProfilesTableName);
     if (maps.isNotEmpty) {
-      var profile = Operator.fromJson(maps.first);
+      var profile = Profile.fromJson(maps.first);
       return profile;
     }
 
     return null;
   }
 
-  Future<void> createOrUpdateProfile(Operator profile) async {
+  Future<void> createOrUpdateProfile(Profile profile) async {
     var where = 'userName=?';
-    var whereArgs = [profile.name];
+    var whereArgs = [profile.userName];
     final List<Map<String, dynamic>> maps = await database
         .query(ProfilesTableName, where: where, whereArgs: whereArgs);
     if (maps.isNotEmpty) {
-      var profile = Operator.fromJson(maps.first);
+      var profile = Profile.fromJson(maps.first);
       await database.update(ProfilesTableName, profile.toJson(),
           where: where, whereArgs: whereArgs);
     } else {

+ 10 - 10
Tools/Flyinsono.Deployment/lib/Services/LocalStorageService.dart

@@ -2,18 +2,18 @@ import 'package:colorize_logger/colorize_logger.dart';
 import 'package:get_it/get_it.dart';
 import 'package:localstorage/localstorage.dart';
 import 'package:ustest/Services/DatabaseService.dart';
-import 'package:ustest/Services/OperatorService.dart';
+import 'package:ustest/Services/ProfileService.dart';
 
 class LocalStorageService {
   late LocalStorager storage;
   LocalStorageService(bool isWeb) {
     storage = isWeb ? new WebLocalStorage() : new AppLocalStorage();
   }
-  Future<Operator?> getProfile() async {
+  Future<Profile?> getProfile() async {
     return storage.getProfile();
   }
 
-  Future<void> setProfile(Operator value) async {
+  Future<void> setProfile(Profile value) async {
     return storage.setProfile(value);
   }
 
@@ -23,11 +23,11 @@ class LocalStorageService {
 }
 
 class LocalStorager {
-  Future<Operator?> getProfile() async {
+  Future<Profile?> getProfile() async {
     //this.storage.getItem(key);
   }
 
-  Future<void> setProfile(Operator value) async {
+  Future<void> setProfile(Profile value) async {
     //this.storage.setItem(key, value);
   }
 
@@ -39,11 +39,11 @@ class WebLocalStorage implements LocalStorager {
   static const String ProfileKey = "MyProfile";
 
   @override
-  Future<Operator?> getProfile() async {
+  Future<Profile?> getProfile() async {
     var value = this.storage.getItem(ProfileKey);
     if (value != null) {
       Logger.info('getCurrentUser from localstorage:' + value.toString());
-      var profile = Operator.fromJson(value);
+      var profile = Profile.fromJson(value);
       return profile;
     }
 
@@ -51,7 +51,7 @@ class WebLocalStorage implements LocalStorager {
   }
 
   @override
-  Future<void> setProfile(Operator value) async {
+  Future<void> setProfile(Profile value) async {
     return this.storage.setItem(ProfileKey, value.toJson());
   }
 
@@ -63,13 +63,13 @@ class WebLocalStorage implements LocalStorager {
 
 class AppLocalStorage implements LocalStorager {
   @override
-  Future<Operator?> getProfile() async {
+  Future<Profile?> getProfile() async {
     var service = GetIt.instance.get<DatabaseService>();
     return await service.getProfile();
   }
 
   @override
-  Future<void> setProfile(Operator value) async {
+  Future<void> setProfile(Profile value) async {
     var service = GetIt.instance.get<DatabaseService>();
     await service.createOrUpdateProfile(value);
   }

+ 0 - 25
Tools/Flyinsono.Deployment/lib/Services/OperatorService.dart

@@ -1,15 +1,10 @@
-import 'package:colorize_logger/colorize_logger.dart';
 import 'package:flutter/material.dart';
 import 'package:get_it/get_it.dart';
-import 'package:ustest/Services/LocalStorageService.dart';
 
 import '../GeneratedCode/rpc.dart';
 import 'package:flutter_gen/gen_l10n/app_localizations.dart';
 
 class OperatorService {
-  static const String DefaultNotLoginId = "notlogin";
-  late Operator? currentUser = null;
-
   List<Operator> operators = [];
 
   OperatorService() {}
@@ -76,26 +71,6 @@ class OperatorService {
       operators.removeAt(index);
     }
   }
-
-  void logout() {}
-
-  Future<Operator?> getCurrentUserAsyc() async {
-    var service = GetIt.instance.get<LocalStorageService>();
-    currentUser = await service.getProfile();
-    if (currentUser == null) {
-      Logger.info('getCurrentUser value: null, set a not login default user');
-      currentUser = new Operator(
-          id: DefaultNotLoginId,
-          name: 'notlogin',
-          accessToken: '',
-          createTime: DateTime.now(),
-          updateTime: DateTime.now());
-    }
-
-    return currentUser;
-  }
-
-  signInAsync(String userName, String password) {}
 }
 
 enum OperatorStatus { Inactive, Active }

+ 72 - 0
Tools/Flyinsono.Deployment/lib/Services/ProfileService.dart

@@ -0,0 +1,72 @@
+import 'package:colorize_logger/colorize_logger.dart';
+import 'package:get_it/get_it.dart';
+import 'package:ustest/Services/LocalStorageService.dart';
+
+import '../GeneratedCode/rpc.dart';
+
+class ProfileService {
+  static const String DefaultNotLoginId = "notlogin";
+  late Profile? currentUser = null;
+
+  ProfileService() {}
+
+  void logout() {
+    var service = GetIt.instance.get<LocalStorageService>();
+    service.deleteProfile();
+  }
+
+  Future<Profile?> getCurrentUserAsyc() async {
+    var service = GetIt.instance.get<LocalStorageService>();
+    currentUser = await service.getProfile();
+    if (currentUser == null) {
+      Logger.info('getCurrentUser value: null, set a not login default user');
+      currentUser = new Profile(
+        id: DefaultNotLoginId,
+        userName: 'notlogin',
+        accessToken: '',
+      );
+    }
+
+    return currentUser;
+  }
+
+  Future<String> signInAsync(String userName, String password) async {
+    try {
+      final rpc = GetIt.instance.get<JsonRpcProxy>();
+      var result = await rpc.deployPlatform.loginAsync(
+          new OperatorLoginRequest(name: userName, password: password));
+      if (result) {
+        var service = GetIt.instance.get<LocalStorageService>();
+        await service
+            .setProfile(Profile(id: '', userName: userName, accessToken: ''));
+        return 'ok';
+      }
+
+      return 'failed';
+    } catch (ex) {
+      return 'Login failed : ex ${ex}';
+    }
+  }
+}
+
+class Profile {
+  final String id;
+  final String userName;
+  final String accessToken;
+
+  Profile(
+      {required this.id, required this.userName, required this.accessToken});
+  factory Profile.fromJson(Map<String, dynamic> json) {
+    return Profile(
+      id: json['id'] as String,
+      userName: json['userName'] as String,
+      accessToken: json['accessToken'] as String,
+    );
+  }
+
+  Map<String, dynamic> toJson() => {
+        'id': id,
+        "userName": userName,
+        "accessToken": accessToken,
+      };
+}

+ 26 - 13
Tools/Flyinsono.Deployment/lib/SignInScreen.dart

@@ -1,10 +1,8 @@
+import 'package:colorize_logger/colorize_logger.dart';
 import 'package:flutter/material.dart';
 import 'package:get_it/get_it.dart';
-import 'package:ustest/Services/OperatorService.dart';
-import 'package:web_socket_channel/web_socket_channel.dart';
-import 'dart:convert';
-import 'dart:typed_data';
-import 'package:flutter/services.dart';
+import 'package:ustest/Services/ProfileService.dart';
+import 'package:flutter_gen/gen_l10n/app_localizations.dart';
 
 class SignInScreen extends StatelessWidget {
   const SignInScreen();
@@ -36,19 +34,20 @@ class _SignInFormState extends State<SignInForm> {
   final _userNameTextController = TextEditingController(text: "fly11");
   final _userPasswordTextController =
       TextEditingController(text: "7a9da7f9ffc92a1d9e3b9d87137eb3c1");
-  final _statusContoller = Text('');
+  String status = '';
 
   double _formProgress = 0;
 
   @override
   Widget build(BuildContext context) {
-    print("build Signin");
+    final localizations = AppLocalizations.of(context)!;
     return Form(
       child: Column(
         mainAxisSize: MainAxisSize.min,
         children: [
           LinearProgressIndicator(value: _formProgress),
-          Text('Sign In', style: Theme.of(context).textTheme.headline4),
+          Text(localizations.logIn,
+              style: Theme.of(context).textTheme.headline4),
           Padding(
             padding: const EdgeInsets.all(8.0),
             child: TextFormField(
@@ -59,10 +58,18 @@ class _SignInFormState extends State<SignInForm> {
           Padding(
             padding: const EdgeInsets.all(8.0),
             child: TextFormField(
+              obscureText: true,
               controller: _userPasswordTextController,
               decoration: const InputDecoration(hintText: 'Password'),
             ),
           ),
+          SizedBox(height: 12),
+          Center(
+            child: Text(
+              status,
+              style: TextStyle(color: Colors.red),
+            ),
+          ),
           Padding(
               padding: const EdgeInsets.all(8.0),
               child: Row(
@@ -84,7 +91,7 @@ class _SignInFormState extends State<SignInForm> {
                       }),
                     ),
                     onPressed: _showWelcomeScreen,
-                    child: const Text('Sign In'),
+                    child: Text(localizations.logIn),
                   ),
                   Padding(
                     padding: const EdgeInsets.all(8.0),
@@ -104,7 +111,7 @@ class _SignInFormState extends State<SignInForm> {
                         }),
                       ),
                       onPressed: () => {Navigator.of(context).pop()},
-                      child: const Text('Cancel'),
+                      child: Text(localizations.cancel),
                     ),
                   ),
                 ],
@@ -116,12 +123,18 @@ class _SignInFormState extends State<SignInForm> {
 
   void _showWelcomeScreen() async {
     try {
-      var service = GetIt.instance.get<OperatorService>();
+      var service = GetIt.instance.get<ProfileService>();
       var userName = _userNameTextController.text;
       var password = _userPasswordTextController.text;
       var result = await service.signInAsync(userName, password);
-      if (result != null) {
-        Navigator.of(context).pushNamed('/');
+      Logger.info('Login result : ${result}');
+
+      if (result == 'ok') {
+        Navigator.of(context).pop();
+      } else {
+        setState(() {
+          status = result;
+        });
       }
     } catch (e) {
       print('signInAsync ex: $e');

+ 1 - 0
Tools/Flyinsono.Deployment/lib/UserList.dart

@@ -122,6 +122,7 @@ class _UserListState extends State<UserList> {
                   onChanged: (value) => name = value,
                   decoration: InputDecoration(hintText: '操作人名称'),
                 ),
+                SizedBox(height: 24.0),
                 StatefulBuilder(
                   builder: (BuildContext context, StateSetter setState) {
                     return DropdownButton<OperatorStatus>(

+ 3 - 1
Tools/Flyinsono.Deployment/lib/l10n/app_en.arb

@@ -104,5 +104,7 @@
   "noUpgrade": "No update required",
   "normal": "Regular update",
   "force": "Forced update",
-  "autoAfterRestart": "Automatic update"
+  "autoAfterRestart": "Automatic update",
+  "logIn":"Log in", 
+  "logout":"Log out" 
 }

+ 3 - 1
Tools/Flyinsono.Deployment/lib/l10n/app_zh.arb

@@ -104,5 +104,7 @@
   "noUpgrade":"无需更新",
   "normal":"常规更新",
   "force":"强制更新",
-  "autoAfterRestart":"自动更新"
+  "autoAfterRestart":"自动更新",
+  "logIn":"登录", 
+  "logout":"注销" 
 }

+ 3 - 1
Tools/Flyinsono.Deployment/lib/main.dart

@@ -5,6 +5,7 @@ import 'package:flutter/material.dart';
 import 'package:ustest/Services/DatabaseService.dart';
 import 'package:ustest/Services/LocalStorageService.dart';
 import 'package:ustest/Services/OperatorService.dart';
+import 'package:ustest/Services/ProfileService.dart';
 import 'package:ustest/SignInScreen.dart';
 import 'package:ustest/MainScreen.dart';
 import 'package:get_it/get_it.dart';
@@ -83,12 +84,13 @@ Future<void> initialize() async {
     getIt.registerSingleton<PublishService>(new PublishService());
     getIt.registerSingleton<AutoTestService>(new AutoTestService());
     getIt.registerSingleton<OperatorService>(new OperatorService());
+    getIt.registerSingleton<ProfileService>(new ProfileService());
     final rpc = JsonRpcProxy(host: AppSettings.host);
     getIt.registerSingleton<JsonRpcProxy>(rpc);
     runApp(const MyApp());
     doWhenWindowReady(() {
       final initialSize = Size(800, 750);
-      appWindow.title="杏聆荟部署工具";
+      appWindow.title = "杏聆荟部署工具";
       appWindow.minSize = initialSize;
       appWindow.maxSize = initialSize;
       appWindow.alignment = Alignment.center;

+ 101 - 5
Tools/Flyinsono.Deployment/pubspec.lock

@@ -33,6 +33,46 @@ packages:
       url: "https://pub.flutter-io.cn"
     source: hosted
     version: "2.0.1"
+  bitsdojo_window:
+    dependency: "direct main"
+    description:
+      name: bitsdojo_window
+      sha256: "1118bc1cd16e6f358431ca4473af57cc1b287d2ceab46dfab6d59a9463160622"
+      url: "https://pub.flutter-io.cn"
+    source: hosted
+    version: "0.1.5"
+  bitsdojo_window_linux:
+    dependency: transitive
+    description:
+      name: bitsdojo_window_linux
+      sha256: d3804a30315fcbb43b28acc86d1180ce0be22c0c738ad2da9e5ade4d8dbd9655
+      url: "https://pub.flutter-io.cn"
+    source: hosted
+    version: "0.1.3"
+  bitsdojo_window_macos:
+    dependency: transitive
+    description:
+      name: bitsdojo_window_macos
+      sha256: d2a9886c74516c5b84c1dd65ab8ee5d1c52055b265ebf0e7d664dee28366b521
+      url: "https://pub.flutter-io.cn"
+    source: hosted
+    version: "0.1.3"
+  bitsdojo_window_platform_interface:
+    dependency: transitive
+    description:
+      name: bitsdojo_window_platform_interface
+      sha256: "65daa015a0c6dba749bdd35a0f092e7a8ba8b0766aa0480eb3ef808086f6e27c"
+      url: "https://pub.flutter-io.cn"
+    source: hosted
+    version: "0.1.2"
+  bitsdojo_window_windows:
+    dependency: transitive
+    description:
+      name: bitsdojo_window_windows
+      sha256: "8766a40aac84a6d7bdcaa716b24997e028fc9a9a1800495fc031721fd5a22ed0"
+      url: "https://pub.flutter-io.cn"
+    source: hosted
+    version: "0.1.5"
   boolean_selector:
     dependency: transitive
     description:
@@ -149,10 +189,10 @@ packages:
     dependency: "direct main"
     description:
       name: file_picker
-      sha256: e6c7ad8e572379df86ea64ef0a5395889fba3954411d47ca021b888d79f8e798
+      sha256: d8e9ca7e5d1983365c277f12c21b4362df6cf659c99af146ad4d04eb33033013
       url: "https://pub.flutter-io.cn"
     source: hosted
-    version: "5.2.11"
+    version: "5.2.6"
   fis_common:
     dependency: transitive
     description:
@@ -208,6 +248,54 @@ packages:
       url: "https://pub.flutter-io.cn"
     source: hosted
     version: "2.0.4"
+  flutter_keyboard_visibility:
+    dependency: transitive
+    description:
+      name: flutter_keyboard_visibility
+      sha256: "4983655c26ab5b959252ee204c2fffa4afeb4413cd030455194ec0caa3b8e7cb"
+      url: "https://pub.flutter-io.cn"
+    source: hosted
+    version: "5.4.1"
+  flutter_keyboard_visibility_linux:
+    dependency: transitive
+    description:
+      name: flutter_keyboard_visibility_linux
+      sha256: "6fba7cd9bb033b6ddd8c2beb4c99ad02d728f1e6e6d9b9446667398b2ac39f08"
+      url: "https://pub.flutter-io.cn"
+    source: hosted
+    version: "1.0.0"
+  flutter_keyboard_visibility_macos:
+    dependency: transitive
+    description:
+      name: flutter_keyboard_visibility_macos
+      sha256: c5c49b16fff453dfdafdc16f26bdd8fb8d55812a1d50b0ce25fc8d9f2e53d086
+      url: "https://pub.flutter-io.cn"
+    source: hosted
+    version: "1.0.0"
+  flutter_keyboard_visibility_platform_interface:
+    dependency: transitive
+    description:
+      name: flutter_keyboard_visibility_platform_interface
+      sha256: e43a89845873f7be10cb3884345ceb9aebf00a659f479d1c8f4293fcb37022a4
+      url: "https://pub.flutter-io.cn"
+    source: hosted
+    version: "2.0.0"
+  flutter_keyboard_visibility_web:
+    dependency: transitive
+    description:
+      name: flutter_keyboard_visibility_web
+      sha256: d3771a2e752880c79203f8d80658401d0c998e4183edca05a149f5098ce6e3d1
+      url: "https://pub.flutter-io.cn"
+    source: hosted
+    version: "2.0.0"
+  flutter_keyboard_visibility_windows:
+    dependency: transitive
+    description:
+      name: flutter_keyboard_visibility_windows
+      sha256: fc4b0f0b6be9b93ae527f3d527fb56ee2d918cd88bbca438c478af7bcfd0ef73
+      url: "https://pub.flutter-io.cn"
+    source: hosted
+    version: "1.0.0"
   flutter_localizations:
     dependency: "direct main"
     description: flutter
@@ -234,6 +322,14 @@ packages:
     description: flutter
     source: sdk
     version: "0.0.0"
+  flutter_typeahead:
+    dependency: "direct main"
+    description:
+      name: flutter_typeahead
+      sha256: "721610b3d61814efa13fb5f720a6781bc123cd51b7e01f5a45d7c92124376644"
+      url: "https://pub.flutter-io.cn"
+    source: hosted
+    version: "4.3.8"
   flutter_web_plugins:
     dependency: transitive
     description: flutter
@@ -616,10 +712,10 @@ packages:
     dependency: transitive
     description:
       name: win32
-      sha256: dd8f9344bc305ae2923e3d11a2a911d9a4e2c7dd6fe0ed10626d63211a69676e
+      sha256: a6f0236dbda0f63aa9a25ad1ff9a9d8a4eaaa5012da0dc59d21afdb1dc361ca4
       url: "https://pub.flutter-io.cn"
     source: hosted
-    version: "4.1.3"
+    version: "3.1.4"
   xdg_directories:
     dependency: transitive
     description:
@@ -629,5 +725,5 @@ packages:
     source: hosted
     version: "1.0.0"
 sdks:
-  dart: ">=2.18.0 <3.0.0"
+  dart: ">=2.19.0 <3.0.0"
   flutter: ">=3.3.0"