This commit is contained in:
vipg
2025-11-13 17:19:29 +08:00
parent 5e4d7509fd
commit b177f0647d
2 changed files with 254 additions and 108 deletions

View File

@@ -13,6 +13,7 @@ class _LoginPageState extends State<LoginPage> {
final _usernameController = TextEditingController(); final _usernameController = TextEditingController();
final _passwordController = TextEditingController(); final _passwordController = TextEditingController();
bool _isLoading = false; bool _isLoading = false;
bool _obscurePassword = true;
final _dio = Dio(); final _dio = Dio();
Future<void> _submitForm() async { Future<void> _submitForm() async {
@@ -32,11 +33,13 @@ class _LoginPageState extends State<LoginPage> {
// 登录成功处理 // 登录成功处理
if (response.statusCode == 200) { if (response.statusCode == 200) {
// 这里根据实际返回的数据结构处理
if (mounted) { if (mounted) {
ScaffoldMessenger.of( ScaffoldMessenger.of(context).showSnackBar(
context, const SnackBar(
).showSnackBar(const SnackBar(content: Text('登录成功'))); content: Text('登录成功'),
backgroundColor: Color(0xFF2E7D32), // 成功绿色
),
);
// 导航到主页或其他页面 // 导航到主页或其他页面
// Navigator.pushReplacement(...); // Navigator.pushReplacement(...);
} }
@@ -44,9 +47,12 @@ class _LoginPageState extends State<LoginPage> {
} catch (e) { } catch (e) {
// 错误处理 // 错误处理
if (mounted) { if (mounted) {
ScaffoldMessenger.of( ScaffoldMessenger.of(context).showSnackBar(
context, SnackBar(
).showSnackBar(SnackBar(content: Text('登录失败: ${e.toString()}'))); content: Text('登录失败: ${e.toString()}'),
backgroundColor: Color(0xFFC62828), // 错误红色
),
);
} }
} finally { } finally {
if (mounted) { if (mounted) {
@@ -61,57 +67,165 @@ class _LoginPageState extends State<LoginPage> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
appBar: AppBar(title: const Text('登录')), // 增加顶部阴影效果
body: Padding( appBar: AppBar(
padding: const EdgeInsets.all(16.0), title: const Text('账户登录'),
child: Form( backgroundColor: Theme.of(context).colorScheme.primary,
key: _formKey, elevation: 4,
child: Column( shadowColor: Colors.black54,
mainAxisAlignment: MainAxisAlignment.center, ),
children: [ // 主体内容使用卡片包裹增加层次感
TextFormField( body: Container(
controller: _usernameController, decoration: const BoxDecoration(
decoration: const InputDecoration( gradient: LinearGradient(
labelText: '用户名', begin: Alignment.topCenter,
prefixIcon: Icon(Icons.person), end: Alignment.bottomCenter,
border: OutlineInputBorder(), colors: [Color(0xFF121212), Color(0xFF1A1A2E)],
), ),
validator: (value) { ),
if (value == null || value.isEmpty) { child: Center(
return '请输入用户名'; child: SingleChildScrollView(
} padding: const EdgeInsets.all(16.0),
return null; child: Card(
}, margin: const EdgeInsets.symmetric(horizontal: 16),
enabled: !_isLoading, child: Padding(
), padding: const EdgeInsets.all(24.0),
const SizedBox(height: 16), child: Form(
TextFormField( key: _formKey,
controller: _passwordController, child: Column(
decoration: const InputDecoration( mainAxisSize: MainAxisSize.min,
labelText: '密码', children: [
prefixIcon: Icon(Icons.lock), // 金融风格Logo位置可替换为实际Logo
border: OutlineInputBorder(), const Icon(
), Icons.account_balance,
obscureText: true, size: 64,
validator: (value) { color: Color(0xFFD4AF37),
if (value == null || value.isEmpty) { ),
return '请输入密码'; const SizedBox(height: 24),
} const Text(
return null; '资产助手',
}, style: TextStyle(
enabled: !_isLoading, fontSize: 24,
), fontWeight: FontWeight.bold,
const SizedBox(height: 24), color: Color(0xFFD4AF37),
SizedBox( ),
width: double.infinity, ),
child: ElevatedButton( const SizedBox(height: 32),
onPressed: _isLoading ? null : _submitForm,
child: _isLoading TextFormField(
? const CircularProgressIndicator() controller: _usernameController,
: const Text('登录'), 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<Color>(
Colors.white,
),
)
: const Text(
'安全登录',
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.w500,
),
),
),
),
],
),
), ),
), ),
], ),
), ),
), ),
), ),

View File

@@ -10,60 +10,92 @@ class MyApp extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return MaterialApp( // 金融风格暗夜主题
title: 'Flutter Demo', final darkTheme = ThemeData(
theme: ThemeData( brightness: Brightness.dark,
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple), 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(), home: const LoginPage(),
); );
} }
} }
// 以下MyHomePage代码可以保留或删除根据实际需求决定
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key, required this.title});
final String title;
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
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: <Widget>[
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),
),
);
}
}