智慧水务管理系统 - 精河县供水工程综合管理平台

profile_page.dart 6.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. import 'package:flutter/material.dart';
  2. import 'package:provider/provider.dart';
  3. import '../../services/auth_service.dart';
  4. /// 个人中心
  5. class ProfilePage extends StatelessWidget {
  6. const ProfilePage({super.key});
  7. @override
  8. Widget build(BuildContext context) {
  9. final auth = context.watch<AuthService>();
  10. final theme = Theme.of(context);
  11. final colorScheme = theme.colorScheme;
  12. return Scaffold(
  13. appBar: AppBar(
  14. title: const Text('个人中心'),
  15. centerTitle: true,
  16. ),
  17. body: ListView(
  18. children: [
  19. // ---------- 用户头像卡片 ----------
  20. Container(
  21. padding: const EdgeInsets.all(24),
  22. child: Column(
  23. children: [
  24. CircleAvatar(
  25. radius: 40,
  26. backgroundColor: colorScheme.primaryContainer,
  27. backgroundImage: auth.avatarUrl.isNotEmpty ? NetworkImage(auth.avatarUrl) : null,
  28. child: auth.avatarUrl.isEmpty
  29. ? Text(
  30. auth.displayName.isNotEmpty ? auth.displayName[0] : '?',
  31. style: TextStyle(fontSize: 32, color: colorScheme.onPrimaryContainer),
  32. )
  33. : null,
  34. ),
  35. const SizedBox(height: 12),
  36. Text(
  37. auth.displayName,
  38. style: theme.textTheme.titleLarge?.copyWith(fontWeight: FontWeight.bold),
  39. ),
  40. const SizedBox(height: 4),
  41. Text(
  42. '@${auth.username}',
  43. style: theme.textTheme.bodyMedium?.copyWith(color: colorScheme.onSurfaceVariant),
  44. ),
  45. ],
  46. ),
  47. ),
  48. const Divider(height: 1),
  49. // ---------- 菜单列表 ----------
  50. const SizedBox(height: 8),
  51. _ProfileMenuItem(
  52. icon: Icons.person_outline,
  53. title: '个人信息',
  54. subtitle: '修改姓名、手机号、密码等',
  55. onTap: () {
  56. ScaffoldMessenger.of(context).showSnackBar(
  57. const SnackBar(content: Text('个人信息功能开发中...')),
  58. );
  59. },
  60. ),
  61. _ProfileMenuItem(
  62. icon: Icons.notifications_outlined,
  63. title: '消息通知',
  64. subtitle: '推送设置、告警订阅',
  65. onTap: () {
  66. ScaffoldMessenger.of(context).showSnackBar(
  67. const SnackBar(content: Text('消息通知功能开发中...')),
  68. );
  69. },
  70. ),
  71. _ProfileMenuItem(
  72. icon: Icons.settings_outlined,
  73. title: '系统设置',
  74. subtitle: '主题、语言、缓存管理',
  75. onTap: () {
  76. ScaffoldMessenger.of(context).showSnackBar(
  77. const SnackBar(content: Text('系统设置功能开发中...')),
  78. );
  79. },
  80. ),
  81. _ProfileMenuItem(
  82. icon: Icons.help_outline,
  83. title: '帮助与反馈',
  84. subtitle: '常见问题、意见反馈',
  85. onTap: () {
  86. ScaffoldMessenger.of(context).showSnackBar(
  87. const SnackBar(content: Text('帮助与反馈功能开发中...')),
  88. );
  89. },
  90. ),
  91. _ProfileMenuItem(
  92. icon: Icons.info_outline,
  93. title: '关于',
  94. subtitle: '版本 v1.0.0',
  95. onTap: () {
  96. showAboutDialog(
  97. context: context,
  98. applicationName: '智慧水务管理系统',
  99. applicationVersion: 'v1.0.0',
  100. applicationIcon: Icon(Icons.water_drop, size: 48, color: colorScheme.primary),
  101. children: const [
  102. Text('© 2024 智慧水务团队'),
  103. ],
  104. );
  105. },
  106. ),
  107. const SizedBox(height: 24),
  108. // ---------- 退出登录 ----------
  109. Padding(
  110. padding: const EdgeInsets.symmetric(horizontal: 16),
  111. child: OutlinedButton.icon(
  112. onPressed: () async {
  113. final confirm = await showDialog<bool>(
  114. context: context,
  115. builder: (ctx) => AlertDialog(
  116. title: const Text('退出登录'),
  117. content: const Text('确定要退出当前账号吗?'),
  118. actions: [
  119. TextButton(onPressed: () => Navigator.pop(ctx, false), child: const Text('取消')),
  120. TextButton(onPressed: () => Navigator.pop(ctx, true), child: const Text('确定')),
  121. ],
  122. ),
  123. );
  124. if (confirm == true && context.mounted) {
  125. await auth.logout();
  126. // AuthService.notifyListeners 会自动切换到 LoginPage
  127. }
  128. },
  129. icon: const Icon(Icons.logout),
  130. label: const Text('退出登录'),
  131. style: OutlinedButton.styleFrom(
  132. foregroundColor: Colors.red,
  133. side: const BorderSide(color: Colors.red),
  134. padding: const EdgeInsets.symmetric(vertical: 14),
  135. shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)),
  136. ),
  137. ),
  138. ),
  139. const SizedBox(height: 32),
  140. ],
  141. ),
  142. );
  143. }
  144. }
  145. class _ProfileMenuItem extends StatelessWidget {
  146. final IconData icon;
  147. final String title;
  148. final String subtitle;
  149. final VoidCallback onTap;
  150. const _ProfileMenuItem({
  151. required this.icon,
  152. required this.title,
  153. required this.subtitle,
  154. required this.onTap,
  155. });
  156. @override
  157. Widget build(BuildContext context) {
  158. return ListTile(
  159. leading: Icon(icon, color: Colors.blue.shade700),
  160. title: Text(title),
  161. subtitle: Text(subtitle, style: const TextStyle(fontSize: 12)),
  162. trailing: const Icon(Icons.chevron_right, color: Colors.grey),
  163. onTap: onTap,
  164. );
  165. }
  166. }