From 5e4d7509fd98b2051f5ab64e8ca51abcc7ffc4ab Mon Sep 17 00:00:00 2001 From: vipg Date: Thu, 13 Nov 2025 17:10:01 +0800 Subject: [PATCH] add --- .../asset_assistant/lib/login/login_page.dart | 128 ++++++++++++++++++ frontend/asset_assistant/lib/main.dart | 63 +-------- frontend/asset_assistant/pubspec.lock | 48 +++++++ frontend/asset_assistant/pubspec.yaml | 5 +- 4 files changed, 183 insertions(+), 61 deletions(-) create mode 100644 frontend/asset_assistant/lib/login/login_page.dart diff --git a/frontend/asset_assistant/lib/login/login_page.dart b/frontend/asset_assistant/lib/login/login_page.dart new file mode 100644 index 0000000..d76e35c --- /dev/null +++ b/frontend/asset_assistant/lib/login/login_page.dart @@ -0,0 +1,128 @@ +import 'package:flutter/material.dart'; +import 'package:dio/dio.dart'; + +class LoginPage extends StatefulWidget { + const LoginPage({super.key}); + + @override + State createState() => _LoginPageState(); +} + +class _LoginPageState extends State { + final _formKey = GlobalKey(); + final _usernameController = TextEditingController(); + final _passwordController = TextEditingController(); + bool _isLoading = false; + final _dio = Dio(); + + Future _submitForm() async { + if (_formKey.currentState!.validate()) { + setState(() { + _isLoading = true; + }); + + try { + final response = await _dio.post( + 'https://api.fishestlife.com/user/login', + data: { + 'username': _usernameController.text.trim(), + 'password': _passwordController.text.trim(), + }, + ); + + // 登录成功处理 + if (response.statusCode == 200) { + // 这里根据实际返回的数据结构处理 + if (mounted) { + ScaffoldMessenger.of( + context, + ).showSnackBar(const SnackBar(content: Text('登录成功'))); + // 导航到主页或其他页面 + // Navigator.pushReplacement(...); + } + } + } catch (e) { + // 错误处理 + if (mounted) { + ScaffoldMessenger.of( + context, + ).showSnackBar(SnackBar(content: Text('登录失败: ${e.toString()}'))); + } + } finally { + if (mounted) { + setState(() { + _isLoading = false; + }); + } + } + } + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar(title: const Text('登录')), + body: Padding( + padding: const EdgeInsets.all(16.0), + child: Form( + key: _formKey, + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + TextFormField( + controller: _usernameController, + decoration: const InputDecoration( + labelText: '用户名', + prefixIcon: Icon(Icons.person), + border: OutlineInputBorder(), + ), + validator: (value) { + if (value == null || value.isEmpty) { + return '请输入用户名'; + } + return null; + }, + enabled: !_isLoading, + ), + const SizedBox(height: 16), + TextFormField( + controller: _passwordController, + decoration: const InputDecoration( + labelText: '密码', + prefixIcon: Icon(Icons.lock), + border: OutlineInputBorder(), + ), + obscureText: true, + validator: (value) { + if (value == null || value.isEmpty) { + return '请输入密码'; + } + return null; + }, + enabled: !_isLoading, + ), + const SizedBox(height: 24), + SizedBox( + width: double.infinity, + child: ElevatedButton( + onPressed: _isLoading ? null : _submitForm, + child: _isLoading + ? const CircularProgressIndicator() + : const Text('登录'), + ), + ), + ], + ), + ), + ), + ); + } + + @override + void dispose() { + _usernameController.dispose(); + _passwordController.dispose(); + _dio.close(); + super.dispose(); + } +} diff --git a/frontend/asset_assistant/lib/main.dart b/frontend/asset_assistant/lib/main.dart index 7b7f5b6..fe44260 100644 --- a/frontend/asset_assistant/lib/main.dart +++ b/frontend/asset_assistant/lib/main.dart @@ -1,3 +1,4 @@ +import 'package:asset_assistant/login/login_page.dart'; import 'package:flutter/material.dart'; void main() { @@ -7,46 +8,23 @@ void main() { class MyApp extends StatelessWidget { const MyApp({super.key}); - // This widget is the root of your application. @override Widget build(BuildContext context) { return MaterialApp( title: 'Flutter Demo', theme: ThemeData( - // This is the theme of your application. - // - // TRY THIS: Try running your application with "flutter run". You'll see - // the application has a purple toolbar. Then, without quitting the app, - // try changing the seedColor in the colorScheme below to Colors.green - // and then invoke "hot reload" (save your changes or press the "hot - // reload" button in a Flutter-supported IDE, or press "r" if you used - // the command line to start the app). - // - // Notice that the counter didn't reset back to zero; the application - // state is not lost during the reload. To reset the state, use hot - // restart instead. - // - // This works for code too, not just values: Most code changes can be - // tested with just a hot reload. colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple), ), - home: const MyHomePage(title: 'Flutter Demo Home Page'), + // 将home改为LoginPage + home: const LoginPage(), ); } } +// 以下MyHomePage代码可以保留或删除,根据实际需求决定 class MyHomePage extends StatefulWidget { const MyHomePage({super.key, required this.title}); - // This widget is the home page of your application. It is stateful, meaning - // that it has a State object (defined below) that contains fields that affect - // how it looks. - - // This class is the configuration for the state. It holds the values (in this - // case the title) provided by the parent (in this case the App widget) and - // used by the build method of the State. Fields in a Widget subclass are - // always marked "final". - final String title; @override @@ -58,50 +36,19 @@ class _MyHomePageState extends State { void _incrementCounter() { setState(() { - // This call to setState tells the Flutter framework that something has - // changed in this State, which causes it to rerun the build method below - // so that the display can reflect the updated values. If we changed - // _counter without calling setState(), then the build method would not be - // called again, and so nothing would appear to happen. _counter++; }); } @override Widget build(BuildContext context) { - // This method is rerun every time setState is called, for instance as done - // by the _incrementCounter method above. - // - // The Flutter framework has been optimized to make rerunning build methods - // fast, so that you can just rebuild anything that needs updating rather - // than having to individually change instances of widgets. return Scaffold( appBar: AppBar( - // TRY THIS: Try changing the color here to a specific color (to - // Colors.amber, perhaps?) and trigger a hot reload to see the AppBar - // change color while the other colors stay the same. backgroundColor: Theme.of(context).colorScheme.inversePrimary, - // Here we take the value from the MyHomePage object that was created by - // the App.build method, and use it to set our appbar title. title: Text(widget.title), ), body: Center( - // Center is a layout widget. It takes a single child and positions it - // in the middle of the parent. child: Column( - // Column is also a layout widget. It takes a list of children and - // arranges them vertically. By default, it sizes itself to fit its - // children horizontally, and tries to be as tall as its parent. - // - // Column has various properties to control how it sizes itself and - // how it positions its children. Here we use mainAxisAlignment to - // center the children vertically; the main axis here is the vertical - // axis because Columns are vertical (the cross axis would be - // horizontal). - // - // TRY THIS: Invoke "debug painting" (choose the "Toggle Debug Paint" - // action in the IDE, or press "p" in the console), to see the - // wireframe for each widget. mainAxisAlignment: MainAxisAlignment.center, children: [ const Text('You have pushed the button this many times:'), @@ -116,7 +63,7 @@ class _MyHomePageState extends State { onPressed: _incrementCounter, tooltip: 'Increment', child: const Icon(Icons.add), - ), // This trailing comma makes auto-formatting nicer for build methods. + ), ); } } diff --git a/frontend/asset_assistant/pubspec.lock b/frontend/asset_assistant/pubspec.lock index c1b51d3..ae0926d 100644 --- a/frontend/asset_assistant/pubspec.lock +++ b/frontend/asset_assistant/pubspec.lock @@ -49,6 +49,22 @@ packages: url: "https://pub.dev" source: hosted version: "1.0.8" + dio: + dependency: "direct main" + description: + name: dio + sha256: d90ee57923d1828ac14e492ca49440f65477f4bb1263575900be731a3dac66a9 + url: "https://pub.dev" + source: hosted + version: "5.9.0" + dio_web_adapter: + dependency: transitive + description: + name: dio_web_adapter + sha256: "7586e476d70caecaf1686d21eee7247ea43ef5c345eab9e0cc3583ff13378d78" + url: "https://pub.dev" + source: hosted + version: "2.1.1" fake_async: dependency: transitive description: @@ -75,6 +91,14 @@ packages: description: flutter source: sdk version: "0.0.0" + http_parser: + dependency: transitive + description: + name: http_parser + sha256: "178d74305e7866013777bab2c3d8726205dc5a4dd935297175b19a23a2e66571" + url: "https://pub.dev" + source: hosted + version: "4.1.2" leak_tracker: dependency: transitive description: @@ -131,6 +155,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.16.0" + mime: + dependency: transitive + description: + name: mime + sha256: "41a20518f0cb1256669420fdba0cd90d21561e560ac240f26ef8322e45bb7ed6" + url: "https://pub.dev" + source: hosted + version: "2.0.0" path: dependency: transitive description: @@ -192,6 +224,14 @@ packages: url: "https://pub.dev" source: hosted version: "0.7.6" + typed_data: + dependency: transitive + description: + name: typed_data + sha256: f9049c039ebfeb4cf7a7104a675823cd72dba8297f264b6637062516699fa006 + url: "https://pub.dev" + source: hosted + version: "1.4.0" vector_math: dependency: transitive description: @@ -208,6 +248,14 @@ packages: url: "https://pub.dev" source: hosted version: "15.0.2" + web: + dependency: transitive + description: + name: web + sha256: "868d88a33d8a87b18ffc05f9f030ba328ffefba92d6c127917a2ba740f9cfe4a" + url: "https://pub.dev" + source: hosted + version: "1.1.1" sdks: dart: ">=3.9.2 <4.0.0" flutter: ">=3.18.0-18.0.pre.54" diff --git a/frontend/asset_assistant/pubspec.yaml b/frontend/asset_assistant/pubspec.yaml index 543368b..2ffdcf8 100644 --- a/frontend/asset_assistant/pubspec.yaml +++ b/frontend/asset_assistant/pubspec.yaml @@ -30,9 +30,8 @@ environment: dependencies: flutter: sdk: flutter - - # The following adds the Cupertino Icons font to your application. - # Use with the CupertinoIcons class for iOS style icons. + + dio: ^5.3.3 # 网络请求库 cupertino_icons: ^1.0.8 dev_dependencies: