From 3b3b1a8807da7a2eb0a75139a96dc65355b321c9 Mon Sep 17 00:00:00 2001 From: vipg Date: Sat, 15 Nov 2025 16:31:50 +0800 Subject: [PATCH] add --- .../lib/pages/country_home.dart | 396 ------------------ .../asset_assistant/lib/pages/home_page.dart | 286 ++++--------- .../asset_assistant/lib/pages/login_page.dart | 2 +- 3 files changed, 86 insertions(+), 598 deletions(-) delete mode 100644 frontend/asset_assistant/lib/pages/country_home.dart diff --git a/frontend/asset_assistant/lib/pages/country_home.dart b/frontend/asset_assistant/lib/pages/country_home.dart deleted file mode 100644 index 5575a50..0000000 --- a/frontend/asset_assistant/lib/pages/country_home.dart +++ /dev/null @@ -1,396 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:dio/dio.dart'; -import 'dart:developer'; // 引入日志工具 - -// 国家数据模型 -class Country { - final String countryId; - final String name; - final String code; - - Country({required this.countryId, required this.name, required this.code}); - - // 从JSON构建对象 - factory Country.fromJson(Map json) { - return Country( - countryId: json['country_id'], - name: json['name'], - code: json['code'], - ); - } - - // 转换为JSON - Map toJson() { - return {'country_id': countryId, 'name': name, 'code': code}; - } -} - -class CountryHomePage extends StatefulWidget { - const CountryHomePage({super.key}); - - @override - State createState() => _CountryHomePageState(); -} - -class _CountryHomePageState extends State { - // 文本编辑控制器 - final TextEditingController _nameController = TextEditingController(); - final TextEditingController _codeController = TextEditingController(); - - // 国家列表 - List _countries = []; - bool _isLoading = false; - - // Dio实例 - final Dio _dio = Dio(); - final String _baseUrl = 'https://api.fishestlife.com'; - - @override - void initState() { - super.initState(); - _fetchCountries(); - } - - // 获取国家列表 - Future _fetchCountries() async { - setState(() { - _isLoading = true; - }); - - try { - final response = await _dio.post( - '$_baseUrl/country/read', - data: {}, // 空参数表示获取所有国家 - ); - - if (response.data['success'] == true) { - final List items = response.data['data']['items']; - setState(() { - _countries = items.map((item) => Country.fromJson(item)).toList(); - }); - } else { - _showErrorDialog('获取失败', response.data['message'] ?? '未知错误'); - } - } catch (e) { - // 添加网络异常日志 - log('获取国家列表网络异常', error: e, stackTrace: StackTrace.current); - _showErrorDialog('网络错误', e.toString()); - } finally { - setState(() { - _isLoading = false; - }); - } - } - - // 创建新国家 - Future _createCountry() async { - final name = _nameController.text.trim(); - final code = _codeController.text.trim(); - - if (name.isEmpty || code.isEmpty) { - _showErrorDialog('输入错误', '国家名称和代码不能为空'); - return; - } - - setState(() { - _isLoading = true; - }); - - try { - final response = await _dio.post( - '$_baseUrl/country/create', - data: {'name': name, 'code': code}, - ); - - if (response.data['success'] == true) { - // 清空输入框 - _nameController.clear(); - _codeController.clear(); - // 重新获取列表 - _fetchCountries(); - ScaffoldMessenger.of( - context, - ).showSnackBar(const SnackBar(content: Text('创建成功'))); - } else { - _showErrorDialog('创建失败', response.data['message'] ?? '未知错误'); - } - } catch (e) { - // 添加网络异常日志 - log('创建国家网络异常', error: e, stackTrace: StackTrace.current); - _showErrorDialog('网络错误', e.toString()); - } finally { - setState(() { - _isLoading = false; - }); - } - } - - // 更新国家信息 - Future _updateCountry(Country country) async { - setState(() { - _isLoading = true; - }); - - try { - final response = await _dio.post( - '$_baseUrl/country/update', - data: country.toJson(), - ); - - if (response.data['success'] == true) { - _fetchCountries(); - ScaffoldMessenger.of( - context, - ).showSnackBar(const SnackBar(content: Text('更新成功'))); - } else { - _showErrorDialog('更新失败', response.data['message'] ?? '未知错误'); - } - } catch (e) { - // 添加网络异常日志 - log('更新国家网络异常', error: e, stackTrace: StackTrace.current); - _showErrorDialog('网络错误', e.toString()); - } finally { - setState(() { - _isLoading = false; - }); - } - } - - // 删除国家 - Future _deleteCountry(String countryId) async { - if (!await _showConfirmationDialog('确认删除', '确定要删除这个国家吗?')) { - return; - } - - setState(() { - _isLoading = true; - }); - - try { - final response = await _dio.post( - '$_baseUrl/country/delete', - data: {'country_id': countryId}, - ); - - if (response.data['success'] == true) { - _fetchCountries(); - ScaffoldMessenger.of( - context, - ).showSnackBar(const SnackBar(content: Text('删除成功'))); - } else { - _showErrorDialog('删除失败', response.data['message'] ?? '未知错误'); - } - } catch (e) { - // 添加网络异常日志 - log('删除国家网络异常', error: e, stackTrace: StackTrace.current); - _showErrorDialog('网络错误', e.toString()); - } finally { - setState(() { - _isLoading = false; - }); - } - } - - // 显示编辑对话框 - void _showEditDialog(Country country) { - final TextEditingController nameController = TextEditingController( - text: country.name, - ); - final TextEditingController codeController = TextEditingController( - text: country.code, - ); - - showDialog( - context: context, - builder: (context) => AlertDialog( - title: const Text('编辑国家'), - content: Column( - mainAxisSize: MainAxisSize.min, - children: [ - TextField( - controller: nameController, - decoration: const InputDecoration(labelText: '国家名称'), - ), - TextField( - controller: codeController, - decoration: const InputDecoration(labelText: '国家代码'), - ), - ], - ), - actions: [ - TextButton( - onPressed: () => Navigator.pop(context), - child: const Text('取消'), - ), - TextButton( - onPressed: () { - final updatedCountry = Country( - countryId: country.countryId, - name: nameController.text.trim(), - code: codeController.text.trim(), - ); - _updateCountry(updatedCountry); - Navigator.pop(context); - }, - child: const Text('保存'), - ), - ], - ), - ); - } - - // 显示错误对话框 - void _showErrorDialog(String title, String message) { - showDialog( - context: context, - builder: (context) => AlertDialog( - title: Text(title), - content: Text(message), - actions: [ - TextButton( - onPressed: () => Navigator.pop(context), - child: const Text('确定'), - ), - ], - ), - ); - } - - // 显示确认对话框 - Future _showConfirmationDialog(String title, String message) async { - return await showDialog( - context: context, - builder: (context) => AlertDialog( - title: Text(title), - content: Text(message), - actions: [ - TextButton( - onPressed: () => Navigator.pop(context, false), - child: const Text('取消'), - ), - TextButton( - onPressed: () => Navigator.pop(context, true), - child: const Text('确认'), - ), - ], - ), - ) ?? - false; - } - - @override - Widget build(BuildContext context) { - return Scaffold( - appBar: AppBar(title: const Text('国家管理')), - body: Column( - children: [ - // 顶部输入区域 - Padding( - padding: const EdgeInsets.all(16.0), - child: Card( - elevation: 4, - child: Padding( - padding: const EdgeInsets.all(16.0), - child: Column( - crossAxisAlignment: CrossAxisAlignment.stretch, - children: [ - const Text( - '添加新国家', - style: TextStyle( - fontSize: 18, - fontWeight: FontWeight.bold, - ), - ), - const SizedBox(height: 16), - TextField( - controller: _nameController, - decoration: const InputDecoration( - labelText: '国家名称', - border: OutlineInputBorder(), - ), - ), - const SizedBox(height: 16), - TextField( - controller: _codeController, - decoration: const InputDecoration( - labelText: '国家代码', - border: OutlineInputBorder(), - ), - ), - const SizedBox(height: 16), - ElevatedButton( - onPressed: _isLoading ? null : _createCountry, - child: _isLoading - ? const CircularProgressIndicator() - : const Text('保存'), - ), - ], - ), - ), - ), - ), - - // 底部列表区域 - Expanded( - child: _isLoading - ? const Center(child: CircularProgressIndicator()) - : _countries.isEmpty - ? const Center(child: Text('没有国家数据')) - : GridView.builder( - padding: const EdgeInsets.all(16), - gridDelegate: - const SliverGridDelegateWithFixedCrossAxisCount( - crossAxisCount: 1, - childAspectRatio: 4, - crossAxisSpacing: 10, - mainAxisSpacing: 10, - ), - itemCount: _countries.length, - itemBuilder: (context, index) { - final country = _countries[index]; - return Card( - elevation: 2, - child: Padding( - padding: const EdgeInsets.all(16), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - // 国家名称(可点击编辑) - InkWell( - onTap: () => _showEditDialog(country), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Text( - country.name, - style: const TextStyle( - fontSize: 18, - fontWeight: FontWeight.bold, - ), - ), - Text('代码: ${country.code}'), - ], - ), - ), - // 删除按钮 - IconButton( - icon: const Icon( - Icons.delete, - color: Colors.red, - ), - onPressed: () => - _deleteCountry(country.countryId), - ), - ], - ), - ), - ); - }, - ), - ), - ], - ), - ); - } -} diff --git a/frontend/asset_assistant/lib/pages/home_page.dart b/frontend/asset_assistant/lib/pages/home_page.dart index 962a52c..557fa16 100644 --- a/frontend/asset_assistant/lib/pages/home_page.dart +++ b/frontend/asset_assistant/lib/pages/home_page.dart @@ -1,216 +1,100 @@ -import 'package:asset_assistant/pages/country_home.dart'; import 'package:flutter/material.dart'; -import 'package:shared_preferences/shared_preferences.dart'; -// 定义功能和子功能数据模型 -class FunctionItem { - final String name; - final List subFunctions; - - FunctionItem({required this.name, required this.subFunctions}); -} - -class SubFunctionItem { - final String name; - final Widget page; - - SubFunctionItem({required this.name, required this.page}); -} - -class HomePage extends StatefulWidget { - const HomePage({super.key}); - - @override - State createState() => _HomePageState(); -} - -class _HomePageState extends State { - // 功能列表数据 - 初始只包含"系统"功能 - final List _functions = [ - FunctionItem( - name: "系统", - subFunctions: [ - SubFunctionItem(name: "国家", page: CountryHomePage()), - SubFunctionItem( - name: "货币", - page: const Center(child: Text("系统参数设置页面内容")), - ), - SubFunctionItem( - name: "交易所", - page: const Center(child: Text("系统日志管理页面内容")), - ), - ], - ), +class HomePage extends StatelessWidget { + // 功能列表数据 + final List> features = [ + {'icon': Icons.home, 'title': '首页'}, + {'icon': Icons.search, 'title': '搜索'}, + {'icon': Icons.notifications, 'title': '通知'}, + {'icon': Icons.message, 'title': '消息'}, + {'icon': Icons.person, 'title': '个人中心'}, + {'icon': Icons.settings, 'title': '设置'}, + {'icon': Icons.help, 'title': '帮助中心'}, + {'icon': Icons.share, 'title': '分享'}, ]; - // 选中状态跟踪 - int _selectedFunctionIndex = 0; - int _selectedSubFunctionIndex = 0; - - Future _logout(BuildContext context) async { - final prefs = await SharedPreferences.getInstance(); - final hasUserID = prefs.getString('user_id') != null; - - if (hasUserID) { - await prefs.remove('user_id'); - debugPrint('移除的用户ID: $hasUserID'); - } - - await prefs.reload(); - - if (!context.mounted) return; - - Navigator.pushNamedAndRemoveUntil(context, '/login', (route) => false); - } + HomePage({super.key}); @override Widget build(BuildContext context) { - // 获取当前选中的功能和子功能 - final currentFunction = _functions[_selectedFunctionIndex]; - final currentSubFunction = - currentFunction.subFunctions[_selectedSubFunctionIndex]; + final theme = Theme.of(context); return Scaffold( - backgroundColor: Theme.of(context).colorScheme.surface, - // 移除顶部导航栏 - body: Row( - children: [ - // 左侧功能导航栏 - Container( - width: 180, - decoration: BoxDecoration( - color: Theme.of(context).colorScheme.surfaceContainerHighest, - border: Border( - right: BorderSide( - color: Theme.of( - context, - ).colorScheme.onSurface.withValues(alpha: 0.1), + appBar: AppBar( + title: const Text('功能列表'), + centerTitle: true, + elevation: 4, + shadowColor: Colors.black12, + ), + body: Container( + color: theme.scaffoldBackgroundColor, + child: ListView.separated( + padding: const EdgeInsets.symmetric(vertical: 8), + itemCount: features.length, + // 添加分割线 + separatorBuilder: (context, index) => Divider( + height: 1, + thickness: 1, + indent: 72, + endIndent: 16, + color: theme.dividerColor, + ), + itemBuilder: (context, index) { + return _buildFeatureItem( + context: context, + icon: features[index]['icon'], + title: features[index]['title'], + ); + }, + ), + ), + ); + } + + // 功能项组件 - 优化为列表项样式 + Widget _buildFeatureItem({ + required BuildContext context, + required IconData icon, + required String title, + }) { + final theme = Theme.of(context); + + return Material( + color: Colors.transparent, + child: InkWell( + onTap: () { + // 可以添加点击事件 + }, + borderRadius: BorderRadius.circular(8), + child: Container( + height: 64, + padding: const EdgeInsets.symmetric(horizontal: 16), + child: Row( + children: [ + // 图标容器 + Container( + width: 40, + height: 40, + decoration: BoxDecoration( + color: theme.primaryColor.withOpacity(0.1), + borderRadius: BorderRadius.circular(8), + ), + child: Icon(icon, size: 24, color: theme.primaryColor), + ), + const SizedBox(width: 16), + // 标题 + Text( + title, + style: theme.textTheme.titleMedium?.copyWith( + fontWeight: FontWeight.w500, ), ), - ), - child: Column( - children: [ - // 功能列表 - Expanded( - child: ListView.builder( - itemCount: _functions.length, - itemBuilder: (context, index) { - final function = _functions[index]; - return ListTile( - title: Text( - function.name, - style: TextStyle( - color: _selectedFunctionIndex == index - ? Theme.of(context).colorScheme.secondary - : Theme.of(context).colorScheme.onSurface, - fontWeight: _selectedFunctionIndex == index - ? FontWeight.bold - : FontWeight.normal, - ), - ), - selected: _selectedFunctionIndex == index, - selectedTileColor: Theme.of( - context, - ).colorScheme.primary.withValues(alpha: 0.1), - onTap: () { - setState(() { - _selectedFunctionIndex = index; - _selectedSubFunctionIndex = 0; // 切换功能时默认选中第一个子功能 - }); - }, - ); - }, - ), - ), - // 底部退出登录功能 - const Divider(height: 1), // 分隔线 - ListTile( - title: const Text( - '退出登录', - textAlign: TextAlign.center, // 文案居中展示 - ), - // 设置文本颜色为灰白色 - textColor: Theme.of(context).colorScheme.onSurfaceVariant, - onTap: () => _logout(context), - tileColor: Theme.of( - context, - ).colorScheme.surfaceContainerHighest, - // 移除默认内边距,使居中更美观 - contentPadding: EdgeInsets.zero, - ), - ], - ), + const Spacer(), + // 箭头图标,指示可点击 + Icon(Icons.arrow_forward_ios, size: 18, color: theme.hintColor), + ], ), - - // 右侧内容区域 - Expanded( - child: Column( - children: [ - // 顶部子功能导航栏 - Container( - height: 60, - decoration: BoxDecoration( - color: Theme.of( - context, - ).colorScheme.surfaceContainerHighest, - border: Border( - bottom: BorderSide( - color: Theme.of( - context, - ).colorScheme.onSurface.withValues(alpha: 0.1), - ), - ), - ), - child: ListView.builder( - scrollDirection: Axis.horizontal, - itemCount: currentFunction.subFunctions.length, - itemBuilder: (context, index) { - final subFunction = currentFunction.subFunctions[index]; - return InkWell( - onTap: () { - setState(() { - _selectedSubFunctionIndex = index; - }); - }, - child: Container( - padding: const EdgeInsets.symmetric( - horizontal: 20, - vertical: 16, - ), - decoration: BoxDecoration( - border: Border( - bottom: BorderSide( - color: _selectedSubFunctionIndex == index - ? Theme.of(context).colorScheme.primary - : Colors.transparent, - width: 2, - ), - ), - ), - child: Text( - subFunction.name, - style: TextStyle( - color: _selectedSubFunctionIndex == index - ? Theme.of(context).colorScheme.primary - : Theme.of( - context, - ).colorScheme.onSurfaceVariant, - fontSize: 16, - ), - ), - ), - ); - }, - ), - ), - - // 子功能操作页面区域 - Expanded(child: currentSubFunction.page), - Expanded(child: currentSubFunction.page), - ], - ), - ), - ], + ), ), ); } diff --git a/frontend/asset_assistant/lib/pages/login_page.dart b/frontend/asset_assistant/lib/pages/login_page.dart index 0dca7a8..e1302d3 100644 --- a/frontend/asset_assistant/lib/pages/login_page.dart +++ b/frontend/asset_assistant/lib/pages/login_page.dart @@ -93,7 +93,7 @@ class _LoginPageState extends State { if (mounted) { Navigator.pushReplacement( context, - MaterialPageRoute(builder: (context) => const HomePage()), + MaterialPageRoute(builder: (context) => HomePage()), ); } } else {