import 'package:flutter/material.dart'; import 'package:go_router/go_router.dart'; import '../../../../core/theme/design_tokens.dart'; import '../../../../core/di/injection.dart'; import '../../../../shared/widgets/app_button.dart'; import '../../../../shared/widgets/app_loading_indicator.dart'; import '../../../../shared/widgets/toast/toast.dart'; import '../../../../shared/widgets/toast/toast_type.dart'; import '../../data/services/settings_user_cache.dart'; import '../../../users/data/models/user_response.dart'; import '../../../users/data/users_api.dart'; import '../widgets/account_section_card.dart'; import '../widgets/settings_page_scaffold.dart'; class EditProfileScreen extends StatefulWidget { const EditProfileScreen({super.key}); @override State createState() => _EditProfileScreenState(); } class _EditProfileScreenState extends State { final _usernameController = TextEditingController(); final _bioController = TextEditingController(); final _usersApi = sl(); final _userCache = sl(); UserResponse? _user; bool _isLoading = true; bool _isSaving = false; bool _hasChanges = false; @override void initState() { super.initState(); _loadUser(); } Future _loadUser() async { final cached = _userCache.cachedUser; if (cached != null) { setState(() { _user = cached; _usernameController.text = cached.username; _bioController.text = cached.bio ?? ''; _isLoading = false; }); return; } try { final user = await _usersApi.getMe(); if (mounted) { _userCache.set(user); setState(() { _user = user; _usernameController.text = user.username; _bioController.text = user.bio ?? ''; _isLoading = false; }); } } catch (e) { if (mounted) { setState(() { _isLoading = false; }); Toast.show(context, '加载用户信息失败', type: ToastType.error); } } } void _onFieldChanged() { if (_user == null) return; final usernameChanged = _usernameController.text != _user!.username; final bioChanged = _bioController.text != (_user!.bio ?? ''); if ((usernameChanged || bioChanged) != _hasChanges) { setState(() { _hasChanges = usernameChanged || bioChanged; }); } } Future _saveProfile() async { if (!_hasChanges || _user == null) return; final newUsername = _usernameController.text.trim(); final newBio = _bioController.text.trim(); if (newUsername.isEmpty) { Toast.show(context, '用户名不能为空', type: ToastType.warning); return; } if (newUsername.length < 3 || newUsername.length > 30) { Toast.show(context, '用户名需要3-30个字符', type: ToastType.warning); return; } setState(() { _isSaving = true; }); try { final request = UserUpdateRequest( username: newUsername, bio: newBio.isEmpty ? null : newBio, ); final updatedUser = await _usersApi.updateMe(request); _userCache.set(updatedUser); if (mounted) { Toast.show(context, '保存成功', type: ToastType.success); context.pop(true); } } catch (e) { if (mounted) { Toast.show(context, '保存失败,请重试', type: ToastType.error); } } finally { if (mounted) { setState(() { _isSaving = false; }); } } } @override void dispose() { _usernameController.dispose(); _bioController.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return SettingsPageScaffold( title: '编辑资料', onBack: () => context.pop(), resizeOnKeyboard: false, maintainBottomViewPadding: true, body: _isLoading ? const Center( child: AppLoadingIndicator(variant: AppLoadingVariant.surface), ) : Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ _buildBasicInfoSection(), const SizedBox(height: AppSpacing.lg), _buildBioSection(), ], ), footer: SizedBox( width: double.infinity, height: 52, child: AppButton( text: '保存修改', onPressed: _hasChanges && !_isSaving ? _saveProfile : null, isLoading: _isSaving, ), ), ); } Widget _buildBasicInfoSection() { return AccountSectionCard( title: '基础信息', backgroundColor: AppColors.white, borderColor: AppColors.borderSecondary, child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ const Text( '用户名', style: TextStyle( fontSize: 13, fontWeight: FontWeight.w700, color: AppColors.slate700, ), ), const SizedBox(height: AppSpacing.sm), TextField( controller: _usernameController, onChanged: (_) => _onFieldChanged(), style: const TextStyle(fontSize: 15, color: AppColors.slate900), decoration: _buildInputDecoration('请输入用户名'), ), ], ), ); } Widget _buildBioSection() { return AccountSectionCard( title: '个人简介', backgroundColor: AppColors.white, borderColor: AppColors.borderSecondary, child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ const Text( '简介内容', style: TextStyle( fontSize: 13, fontWeight: FontWeight.w700, color: AppColors.slate700, ), ), const SizedBox(height: AppSpacing.sm), TextField( controller: _bioController, onChanged: (_) => _onFieldChanged(), maxLines: 4, maxLength: 200, style: const TextStyle(fontSize: 15, color: AppColors.slate900), decoration: _buildInputDecoration( '介绍一下自己吧', ).copyWith(contentPadding: const EdgeInsets.all(AppSpacing.lg)), ), ], ), ); } InputDecoration _buildInputDecoration(String hintText) { return InputDecoration( hintText: hintText, hintStyle: const TextStyle(fontSize: 14, color: AppColors.slate400), filled: true, fillColor: AppColors.surfaceSecondary, contentPadding: const EdgeInsets.symmetric( horizontal: AppSpacing.lg, vertical: AppSpacing.lg, ), border: OutlineInputBorder( borderRadius: BorderRadius.circular(AppRadius.lg), borderSide: BorderSide.none, ), enabledBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(AppRadius.lg), borderSide: const BorderSide(color: AppColors.borderTertiary), ), focusedBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(AppRadius.lg), borderSide: const BorderSide(color: AppColors.blue500), ), ); } }