feat(profile): 添加退出登录和切换账号功能
- 在版本信息栏添加构建模式显示(Debug/Release/Profile) - 在版本信息栏下方添加切换账号按钮(暂显示即将上线提示) - 在版本信息栏下方添加退出登录按钮(带确认对话框) - 退出登录后清除本地数据并跳转到向导页 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
09e66cef10
commit
04644ea3f8
|
|
@ -1,5 +1,6 @@
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
|
|
@ -802,66 +803,71 @@ class _ProfilePageState extends ConsumerState<ProfilePage> {
|
||||||
return Container(
|
return Container(
|
||||||
height: 48,
|
height: 48,
|
||||||
padding: const EdgeInsets.only(top: 8),
|
padding: const EdgeInsets.only(top: 8),
|
||||||
child: Row(
|
child: Stack(
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
alignment: Alignment.center,
|
||||||
children: [
|
children: [
|
||||||
// 页面标题
|
// 页面标题(居中显示)
|
||||||
const Text(
|
const Center(
|
||||||
'我的',
|
child: Text(
|
||||||
style: TextStyle(
|
'我的',
|
||||||
fontSize: 20,
|
style: TextStyle(
|
||||||
fontFamily: 'Inter',
|
fontSize: 20,
|
||||||
fontWeight: FontWeight.w700,
|
fontFamily: 'Inter',
|
||||||
color: Color(0xFF5D4037),
|
fontWeight: FontWeight.w700,
|
||||||
|
color: Color(0xFF5D4037),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
// 通知图标(带未读角标)
|
// 通知图标(右侧,带未读角标)
|
||||||
GestureDetector(
|
Positioned(
|
||||||
onTap: _goToNotifications,
|
right: 0,
|
||||||
child: Container(
|
child: GestureDetector(
|
||||||
width: 40,
|
onTap: _goToNotifications,
|
||||||
height: 40,
|
child: Container(
|
||||||
alignment: Alignment.center,
|
width: 40,
|
||||||
child: Stack(
|
height: 40,
|
||||||
clipBehavior: Clip.none,
|
alignment: Alignment.center,
|
||||||
children: [
|
child: Stack(
|
||||||
const Icon(
|
clipBehavior: Clip.none,
|
||||||
Icons.notifications_outlined,
|
children: [
|
||||||
size: 26,
|
const Icon(
|
||||||
color: Color(0xFF5D4037),
|
Icons.notifications_outlined,
|
||||||
),
|
size: 26,
|
||||||
// 未读角标
|
color: Color(0xFF5D4037),
|
||||||
if (_unreadNotificationCount > 0)
|
),
|
||||||
Positioned(
|
// 未读角标
|
||||||
top: -4,
|
if (_unreadNotificationCount > 0)
|
||||||
right: -4,
|
Positioned(
|
||||||
child: Container(
|
top: -4,
|
||||||
padding: const EdgeInsets.symmetric(
|
right: -4,
|
||||||
horizontal: 5,
|
child: Container(
|
||||||
vertical: 2,
|
padding: const EdgeInsets.symmetric(
|
||||||
),
|
horizontal: 5,
|
||||||
decoration: BoxDecoration(
|
vertical: 2,
|
||||||
color: const Color(0xFFD4AF37),
|
),
|
||||||
borderRadius: BorderRadius.circular(10),
|
decoration: BoxDecoration(
|
||||||
),
|
color: const Color(0xFFD4AF37),
|
||||||
constraints: const BoxConstraints(
|
borderRadius: BorderRadius.circular(10),
|
||||||
minWidth: 18,
|
),
|
||||||
minHeight: 18,
|
constraints: const BoxConstraints(
|
||||||
),
|
minWidth: 18,
|
||||||
child: Text(
|
minHeight: 18,
|
||||||
_unreadNotificationCount > 99
|
),
|
||||||
? '99+'
|
child: Text(
|
||||||
: _unreadNotificationCount.toString(),
|
_unreadNotificationCount > 99
|
||||||
style: const TextStyle(
|
? '99+'
|
||||||
fontSize: 10,
|
: _unreadNotificationCount.toString(),
|
||||||
fontWeight: FontWeight.w600,
|
style: const TextStyle(
|
||||||
color: Colors.white,
|
fontSize: 10,
|
||||||
|
fontWeight: FontWeight.w600,
|
||||||
|
color: Colors.white,
|
||||||
|
),
|
||||||
|
textAlign: TextAlign.center,
|
||||||
),
|
),
|
||||||
textAlign: TextAlign.center,
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
],
|
||||||
],
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
@ -1309,6 +1315,9 @@ class _ProfilePageState extends ConsumerState<ProfilePage> {
|
||||||
const SizedBox(height: 16),
|
const SizedBox(height: 16),
|
||||||
// 应用版本信息
|
// 应用版本信息
|
||||||
_buildAppVersionInfo(),
|
_buildAppVersionInfo(),
|
||||||
|
const SizedBox(height: 16),
|
||||||
|
// 账号操作按钮
|
||||||
|
_buildAccountActionButtons(),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
@ -2711,6 +2720,8 @@ class _ProfilePageState extends ConsumerState<ProfilePage> {
|
||||||
const SizedBox(height: 8),
|
const SizedBox(height: 8),
|
||||||
_buildVersionInfoRow('构建号', _buildNumber),
|
_buildVersionInfoRow('构建号', _buildNumber),
|
||||||
const SizedBox(height: 8),
|
const SizedBox(height: 8),
|
||||||
|
_buildVersionInfoRow('构建模式', kReleaseMode ? 'Release' : (kDebugMode ? 'Debug' : 'Profile')),
|
||||||
|
const SizedBox(height: 8),
|
||||||
_buildVersionInfoRow('包名', _packageName),
|
_buildVersionInfoRow('包名', _packageName),
|
||||||
const Divider(
|
const Divider(
|
||||||
height: 24,
|
height: 24,
|
||||||
|
|
@ -2771,4 +2782,152 @@ class _ProfilePageState extends ConsumerState<ProfilePage> {
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// 构建账号操作按钮(切换账号、退出登录)
|
||||||
|
Widget _buildAccountActionButtons() {
|
||||||
|
return Column(
|
||||||
|
children: [
|
||||||
|
// 切换账号按钮
|
||||||
|
GestureDetector(
|
||||||
|
onTap: _onSwitchAccount,
|
||||||
|
child: Container(
|
||||||
|
width: double.infinity,
|
||||||
|
height: 48,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: const Color(0xFFFFF5E6),
|
||||||
|
borderRadius: BorderRadius.circular(8),
|
||||||
|
border: Border.all(
|
||||||
|
color: const Color(0x33D4AF37),
|
||||||
|
width: 1,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: const Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
Icon(
|
||||||
|
Icons.swap_horiz,
|
||||||
|
size: 20,
|
||||||
|
color: Color(0xFF8B5A2B),
|
||||||
|
),
|
||||||
|
SizedBox(width: 8),
|
||||||
|
Text(
|
||||||
|
'切换账号',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 15,
|
||||||
|
fontFamily: 'Inter',
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
height: 1.5,
|
||||||
|
color: Color(0xFF5D4037),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 12),
|
||||||
|
// 退出登录按钮
|
||||||
|
GestureDetector(
|
||||||
|
onTap: _onLogout,
|
||||||
|
child: Container(
|
||||||
|
width: double.infinity,
|
||||||
|
height: 48,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: const Color(0xFFFFF5E6),
|
||||||
|
borderRadius: BorderRadius.circular(8),
|
||||||
|
border: Border.all(
|
||||||
|
color: const Color(0x33E57373),
|
||||||
|
width: 1,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: const Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
Icon(
|
||||||
|
Icons.logout,
|
||||||
|
size: 20,
|
||||||
|
color: Color(0xFFE57373),
|
||||||
|
),
|
||||||
|
SizedBox(width: 8),
|
||||||
|
Text(
|
||||||
|
'退出登录',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 15,
|
||||||
|
fontFamily: 'Inter',
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
height: 1.5,
|
||||||
|
color: Color(0xFFE57373),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 32), // 底部留白
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 切换账号
|
||||||
|
void _onSwitchAccount() {
|
||||||
|
showDialog(
|
||||||
|
context: context,
|
||||||
|
builder: (context) => AlertDialog(
|
||||||
|
title: const Text('切换账号'),
|
||||||
|
content: const Text('多账号管理功能即将上线,敬请期待。'),
|
||||||
|
actions: [
|
||||||
|
TextButton(
|
||||||
|
onPressed: () => Navigator.of(context).pop(),
|
||||||
|
child: const Text('确定'),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 退出登录
|
||||||
|
void _onLogout() {
|
||||||
|
showDialog(
|
||||||
|
context: context,
|
||||||
|
builder: (context) => AlertDialog(
|
||||||
|
title: const Text('退出登录'),
|
||||||
|
content: const Text('确定要退出当前账号吗?\n\n退出后需要重新导入助记词才能恢复账号。'),
|
||||||
|
actions: [
|
||||||
|
TextButton(
|
||||||
|
onPressed: () => Navigator.of(context).pop(),
|
||||||
|
child: const Text('取消'),
|
||||||
|
),
|
||||||
|
TextButton(
|
||||||
|
onPressed: () {
|
||||||
|
Navigator.of(context).pop();
|
||||||
|
_performLogout();
|
||||||
|
},
|
||||||
|
style: TextButton.styleFrom(
|
||||||
|
foregroundColor: const Color(0xFFE57373),
|
||||||
|
),
|
||||||
|
child: const Text('退出'),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 执行退出登录
|
||||||
|
Future<void> _performLogout() async {
|
||||||
|
try {
|
||||||
|
final accountService = ref.read(accountServiceProvider);
|
||||||
|
// 清除所有本地数据
|
||||||
|
await accountService.logout();
|
||||||
|
// 导航到向导页
|
||||||
|
if (mounted) {
|
||||||
|
context.go(RoutePaths.guide);
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
debugPrint('[ProfilePage] 退出登录失败: $e');
|
||||||
|
if (mounted) {
|
||||||
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
|
SnackBar(content: Text('退出登录失败: $e')),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue