From b177f0647dae050307cfa8b4056af700f9bcb6f1 Mon Sep 17 00:00:00 2001 From: vipg Date: Thu, 13 Nov 2025 17:19:29 +0800 Subject: [PATCH] add --- .../asset_assistant/lib/login/login_page.dart | 226 +++++++++++++----- frontend/asset_assistant/lib/main.dart | 136 +++++++---- 2 files changed, 254 insertions(+), 108 deletions(-) diff --git a/frontend/asset_assistant/lib/login/login_page.dart b/frontend/asset_assistant/lib/login/login_page.dart index d76e35c..8545e63 100644 --- a/frontend/asset_assistant/lib/login/login_page.dart +++ b/frontend/asset_assistant/lib/login/login_page.dart @@ -13,6 +13,7 @@ class _LoginPageState extends State { final _usernameController = TextEditingController(); final _passwordController = TextEditingController(); bool _isLoading = false; + bool _obscurePassword = true; final _dio = Dio(); Future _submitForm() async { @@ -32,11 +33,13 @@ class _LoginPageState extends State { // 登录成功处理 if (response.statusCode == 200) { - // 这里根据实际返回的数据结构处理 if (mounted) { - ScaffoldMessenger.of( - context, - ).showSnackBar(const SnackBar(content: Text('登录成功'))); + ScaffoldMessenger.of(context).showSnackBar( + const SnackBar( + content: Text('登录成功'), + backgroundColor: Color(0xFF2E7D32), // 成功绿色 + ), + ); // 导航到主页或其他页面 // Navigator.pushReplacement(...); } @@ -44,9 +47,12 @@ class _LoginPageState extends State { } catch (e) { // 错误处理 if (mounted) { - ScaffoldMessenger.of( - context, - ).showSnackBar(SnackBar(content: Text('登录失败: ${e.toString()}'))); + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text('登录失败: ${e.toString()}'), + backgroundColor: Color(0xFFC62828), // 错误红色 + ), + ); } } finally { if (mounted) { @@ -61,57 +67,165 @@ class _LoginPageState extends State { @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('登录'), + // 增加顶部阴影效果 + appBar: AppBar( + title: const Text('账户登录'), + backgroundColor: Theme.of(context).colorScheme.primary, + elevation: 4, + shadowColor: Colors.black54, + ), + // 主体内容使用卡片包裹增加层次感 + body: Container( + decoration: const BoxDecoration( + gradient: LinearGradient( + begin: Alignment.topCenter, + end: Alignment.bottomCenter, + colors: [Color(0xFF121212), Color(0xFF1A1A2E)], + ), + ), + child: Center( + child: SingleChildScrollView( + padding: const EdgeInsets.all(16.0), + child: Card( + margin: const EdgeInsets.symmetric(horizontal: 16), + child: Padding( + padding: const EdgeInsets.all(24.0), + child: Form( + key: _formKey, + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + // 金融风格Logo位置(可替换为实际Logo) + const Icon( + Icons.account_balance, + size: 64, + color: Color(0xFFD4AF37), + ), + const SizedBox(height: 24), + const Text( + '资产助手', + style: TextStyle( + fontSize: 24, + fontWeight: FontWeight.bold, + color: Color(0xFFD4AF37), + ), + ), + const SizedBox(height: 32), + + TextFormField( + controller: _usernameController, + decoration: InputDecoration( + labelText: '用户名', + prefixIcon: const Icon(Icons.person), + border: const OutlineInputBorder(), + // 增加焦点效果 + focusedBorder: OutlineInputBorder( + borderSide: const BorderSide( + color: Color(0xFFD4AF37), + width: 2, + ), + borderRadius: BorderRadius.circular(8), + ), + ), + validator: (value) { + if (value == null || value.isEmpty) { + return '请输入用户名'; + } + return null; + }, + enabled: !_isLoading, + ), + const SizedBox(height: 16), + + TextFormField( + controller: _passwordController, + decoration: InputDecoration( + labelText: '密码', + prefixIcon: const Icon(Icons.lock), + border: const OutlineInputBorder(), + suffixIcon: IconButton( + icon: Icon( + _obscurePassword + ? Icons.visibility_off + : Icons.visibility, + color: Colors.white60, + ), + onPressed: () { + setState(() { + _obscurePassword = !_obscurePassword; + }); + }, + ), + focusedBorder: OutlineInputBorder( + borderSide: const BorderSide( + color: Color(0xFFD4AF37), + width: 2, + ), + borderRadius: BorderRadius.circular(8), + ), + ), + obscureText: _obscurePassword, + validator: (value) { + if (value == null || value.isEmpty) { + return '请输入密码'; + } + return null; + }, + enabled: !_isLoading, + ), + const SizedBox(height: 8), + + // 忘记密码链接 + Align( + alignment: Alignment.centerRight, + child: TextButton( + onPressed: _isLoading + ? null + : () { + // 忘记密码逻辑 + }, + child: const Text( + '忘记密码?', + style: TextStyle( + color: Color(0xFFD4AF37), + fontSize: 14, + ), + ), + ), + ), + const SizedBox(height: 16), + + SizedBox( + width: double.infinity, + child: ElevatedButton( + onPressed: _isLoading ? null : _submitForm, + style: ElevatedButton.styleFrom( + backgroundColor: const Color(0xFF0F3460), + padding: const EdgeInsets.symmetric(vertical: 16), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(8), + ), + ), + child: _isLoading + ? const CircularProgressIndicator( + valueColor: AlwaysStoppedAnimation( + Colors.white, + ), + ) + : const Text( + '安全登录', + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.w500, + ), + ), + ), + ), + ], + ), ), ), - ], + ), ), ), ), diff --git a/frontend/asset_assistant/lib/main.dart b/frontend/asset_assistant/lib/main.dart index fe44260..66a6858 100644 --- a/frontend/asset_assistant/lib/main.dart +++ b/frontend/asset_assistant/lib/main.dart @@ -10,60 +10,92 @@ class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { - return MaterialApp( - title: 'Flutter Demo', - theme: ThemeData( - colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple), + // 金融风格暗夜主题 + final darkTheme = ThemeData( + brightness: Brightness.dark, + primaryColor: const Color(0xFF0F3460), // 主色调:深蓝色 + colorScheme: ColorScheme.dark( + primary: const Color(0xFF0F3460), + secondary: const Color(0xFFD4AF37), + surface: const Color(0xFF121212), // 页面主背景 + surfaceContainerHighest: const Color(0xFF1E1E1E), // 卡片背景(分层色) + onPrimary: Colors.white, + onSecondary: Colors.black, + onSurface: Colors.white70, // 所有表面的默认文本色 ), - // 将home改为LoginPage + // 文本样式(继承 onSurface 颜色,增强可读性) + textTheme: TextTheme( + bodyLarge: TextStyle(color: Colors.white70, fontSize: 16, height: 1.5), + bodyMedium: TextStyle(color: Colors.white60, fontSize: 14, height: 1.5), + headlineLarge: TextStyle( + color: Colors.white, + fontSize: 24, + fontWeight: FontWeight.w600, + ), + headlineMedium: TextStyle( + color: Colors.white, + fontSize: 20, + fontWeight: FontWeight.w600, + ), + ), + // 输入框样式 + inputDecorationTheme: InputDecorationTheme( + border: OutlineInputBorder( + borderSide: const BorderSide(color: Color(0xFF333333)), + borderRadius: BorderRadius.circular(8), + ), + enabledBorder: OutlineInputBorder( + borderSide: const BorderSide(color: Color(0xFF333333)), + borderRadius: BorderRadius.circular(8), + ), + focusedBorder: OutlineInputBorder( + borderSide: const BorderSide(color: Color(0xFFD4AF37), width: 2), + borderRadius: BorderRadius.circular(8), + ), + labelStyle: const TextStyle(color: Colors.white60), + prefixIconColor: Colors.white60, + hintStyle: const TextStyle(color: Colors.white38), + contentPadding: const EdgeInsets.symmetric( + horizontal: 16, + vertical: 14, + ), + ), + // 按钮样式 + elevatedButtonTheme: ElevatedButtonThemeData( + style: ElevatedButton.styleFrom( + backgroundColor: const Color(0xFF0F3460), + foregroundColor: Colors.white, + padding: const EdgeInsets.symmetric(vertical: 16), + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)), + textStyle: const TextStyle(fontSize: 16, fontWeight: FontWeight.w500), + elevation: 2, + shadowColor: Colors.black54, + ), + ), + // 文本按钮样式(忘记密码) + textButtonTheme: TextButtonThemeData( + style: TextButton.styleFrom( + foregroundColor: const Color(0xFFD4AF37), // 金色文本,符合辅助色 + textStyle: const TextStyle(fontSize: 14), + ), + ), + // 卡片样式 + cardTheme: CardThemeData( + color: const Color(0xFF1E1E1E), + elevation: 4, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(12), + side: const BorderSide(color: Color(0xFF333333)), + ), + ), + // 去除页面默认边距 + scaffoldBackgroundColor: const Color(0xFF121212), + ); + + return MaterialApp( + title: '资产助手', + theme: darkTheme, home: const LoginPage(), ); } } - -// 以下MyHomePage代码可以保留或删除,根据实际需求决定 -class MyHomePage extends StatefulWidget { - const MyHomePage({super.key, required this.title}); - - final String title; - - @override - State createState() => _MyHomePageState(); -} - -class _MyHomePageState extends State { - int _counter = 0; - - void _incrementCounter() { - setState(() { - _counter++; - }); - } - - @override - Widget build(BuildContext context) { - return Scaffold( - appBar: AppBar( - backgroundColor: Theme.of(context).colorScheme.inversePrimary, - title: Text(widget.title), - ), - body: Center( - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - const Text('You have pushed the button this many times:'), - Text( - '$_counter', - style: Theme.of(context).textTheme.headlineMedium, - ), - ], - ), - ), - floatingActionButton: FloatingActionButton( - onPressed: _incrementCounter, - tooltip: 'Increment', - child: const Icon(Icons.add), - ), - ); - } -}