import 'package:flutter/material.dart'; import 'package:go_router/go_router.dart'; import 'package:social_app/core/di/injection.dart'; import 'package:social_app/core/theme/design_tokens.dart'; import 'package:social_app/core/router/app_routes.dart'; import 'package:social_app/shared/widgets/app_loading_indicator.dart'; import 'package:social_app/shared/widgets/app_pressable.dart'; import '../widgets/settings_page_scaffold.dart'; import '../../data/models/memory_models.dart'; import '../../data/services/memory_service.dart'; class MemoryScreen extends StatefulWidget { const MemoryScreen({super.key}); @override State createState() => _MemoryScreenState(); } class _MemoryScreenState extends State { final MemoryService _memoryService = sl(); MemoryListResponse? _memoryData; bool _isLoading = true; String? _error; @override void initState() { super.initState(); _loadMemories(); } Future _loadMemories() async { if (!mounted) return; setState(() { _isLoading = true; _error = null; }); try { final data = await _memoryService.getAllMemories(); if (!mounted) return; setState(() { _memoryData = data; _isLoading = false; }); } catch (e) { if (!mounted) return; setState(() { _error = '加载失败,请重试'; _isLoading = false; }); } } @override Widget build(BuildContext context) { return SettingsPageScaffold( title: '我的记忆', onBack: () => context.pop(), body: Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ _buildToggleCard(), const SizedBox(height: AppSpacing.lg), if (_isLoading) ...[ const SizedBox(height: AppSpacing.xxl), _buildLoadingState(), ] else if (_error != null) ...[ const SizedBox(height: AppSpacing.xxl), _buildErrorState(), ] else ...[ const SizedBox(height: AppSpacing.sm), _buildMemoryCards(), ], ], ), ); } Widget _buildToggleCard() { return Container( padding: const EdgeInsets.all(AppSpacing.lg), decoration: BoxDecoration( gradient: const LinearGradient( begin: Alignment.topLeft, end: Alignment.bottomRight, colors: [AppColors.white, AppColors.surfaceInfoLight], ), borderRadius: BorderRadius.circular(AppRadius.xl), border: Border.all(color: AppColors.borderTertiary), boxShadow: [ BoxShadow( color: AppColors.blue100.withValues(alpha: 0.35), blurRadius: 14, offset: const Offset(0, 4), ), ], ), child: Row( crossAxisAlignment: CrossAxisAlignment.center, children: [ Container( width: 44, height: 44, decoration: BoxDecoration( gradient: const LinearGradient( begin: Alignment.topLeft, end: Alignment.bottomRight, colors: [AppColors.blue100, AppColors.blue50], ), borderRadius: BorderRadius.circular(12), boxShadow: [ BoxShadow( color: AppColors.blue200.withValues(alpha: 0.45), blurRadius: 8, offset: const Offset(0, 2), ), ], ), child: const Icon( Icons.auto_awesome, size: 22, color: AppColors.blue600, ), ), const SizedBox(width: AppSpacing.md), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ const Text( '智能记忆', style: TextStyle( fontSize: 16, fontWeight: FontWeight.w600, color: AppColors.slate900, ), ), const SizedBox(height: 2), Text( '持续学习你的偏好和习惯', style: TextStyle( fontSize: 13, fontWeight: FontWeight.w500, color: AppColors.slate500, ), ), ], ), ), ], ), ); } Widget _buildLoadingState() { return Center( child: Container( padding: const EdgeInsets.all(AppSpacing.xxl), child: const AppLoadingIndicator(size: 32), ), ); } Widget _buildErrorState() { return Center( child: Column( mainAxisSize: MainAxisSize.min, children: [ Icon(Icons.error_outline, size: 48, color: AppColors.slate300), const SizedBox(height: AppSpacing.md), Text( _error ?? '加载失败', style: TextStyle(fontSize: 14, color: AppColors.slate500), ), const SizedBox(height: AppSpacing.lg), AppPressable( onTap: _loadMemories, borderRadius: BorderRadius.circular(AppRadius.md), child: Container( padding: const EdgeInsets.symmetric( horizontal: AppSpacing.lg, vertical: AppSpacing.sm, ), decoration: BoxDecoration( color: AppColors.blue50, borderRadius: BorderRadius.circular(AppRadius.md), border: Border.all(color: AppColors.blue100), ), child: const Text( '重新加载', style: TextStyle( fontSize: 14, fontWeight: FontWeight.w500, color: AppColors.blue600, ), ), ), ), ], ), ); } Widget _buildMemoryCards() { return Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ _buildSectionLabel('用户记忆'), const SizedBox(height: AppSpacing.sm), _buildUserMemoryCard(), const SizedBox(height: AppSpacing.md), _buildSectionLabel('工作记忆'), const SizedBox(height: AppSpacing.sm), _buildWorkMemoryCard(), ], ); } Widget _buildSectionLabel(String label) { return Padding( padding: const EdgeInsets.symmetric(horizontal: AppSpacing.xs), child: Text( label, style: const TextStyle( fontSize: 12, fontWeight: FontWeight.w600, color: AppColors.slate500, ), ), ); } Widget _buildUserMemoryCard() { final userMemory = _memoryData?.userMemory; final hasData = userMemory != null; return AppPressable( onTap: () => context.push(AppRoutes.settingsMemoryUser), borderRadius: BorderRadius.circular(AppRadius.xl), child: Container( padding: const EdgeInsets.all(AppSpacing.lg), decoration: BoxDecoration( gradient: const LinearGradient( begin: Alignment.topLeft, end: Alignment.bottomRight, colors: [AppColors.white, AppColors.surfaceInfoLight], ), borderRadius: BorderRadius.circular(AppRadius.xl), border: Border.all(color: AppColors.borderTertiary), boxShadow: [ BoxShadow( color: AppColors.slate200.withValues(alpha: 0.45), blurRadius: 8, offset: const Offset(0, 2), ), ], ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( children: [ Container( width: 40, height: 40, decoration: BoxDecoration( gradient: LinearGradient( begin: Alignment.topLeft, end: Alignment.bottomRight, colors: [ AppColors.blue100.withValues(alpha: 0.8), AppColors.blue50.withValues(alpha: 0.8), ], ), borderRadius: BorderRadius.circular(10), ), child: const Icon( Icons.person, size: 20, color: AppColors.blue600, ), ), const SizedBox(width: AppSpacing.md), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ const Text( '个人偏好', style: TextStyle( fontSize: 16, fontWeight: FontWeight.w600, color: AppColors.slate900, ), ), const SizedBox(height: 2), Text( hasData ? userMemory.summary : '暂无信息', style: TextStyle( fontSize: 13, fontWeight: FontWeight.w500, color: AppColors.slate500, ), maxLines: 1, overflow: TextOverflow.ellipsis, ), ], ), ), Icon(Icons.chevron_right, size: 20, color: AppColors.slate400), ], ), if (hasData) ...[ const SizedBox(height: AppSpacing.md), _buildMemoryStatsRow( icons: [ Icons.people_outline, Icons.place_outlined, Icons.interests_outlined, Icons.schedule_outlined, ], values: [ '${userMemory.people.length}', '${userMemory.places.length}', '${userMemory.interests.length}', '${userMemory.recurringRoutines.length}', ], labels: ['联系人', '地点', '兴趣', '日程'], ), ], ], ), ), ); } Widget _buildWorkMemoryCard() { final workMemory = _memoryData?.workMemory; final hasData = workMemory != null; return AppPressable( onTap: () => context.push(AppRoutes.settingsMemoryWork), borderRadius: BorderRadius.circular(AppRadius.xl), child: Container( padding: const EdgeInsets.all(AppSpacing.lg), decoration: BoxDecoration( gradient: const LinearGradient( begin: Alignment.topLeft, end: Alignment.bottomRight, colors: [AppColors.white, AppColors.surfaceTertiary], ), borderRadius: BorderRadius.circular(AppRadius.xl), border: Border.all(color: AppColors.borderSecondary), boxShadow: [ BoxShadow( color: AppColors.slate200.withValues(alpha: 0.4), blurRadius: 8, offset: const Offset(0, 2), ), ], ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( children: [ Container( width: 40, height: 40, decoration: BoxDecoration( gradient: LinearGradient( begin: Alignment.topLeft, end: Alignment.bottomRight, colors: [ AppColors.violet500.withValues(alpha: 0.15), AppColors.violet500.withValues(alpha: 0.05), ], ), borderRadius: BorderRadius.circular(10), ), child: const Icon( Icons.work_outline, size: 20, color: AppColors.violet600, ), ), const SizedBox(width: AppSpacing.md), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ const Text( '工作画像', style: TextStyle( fontSize: 16, fontWeight: FontWeight.w600, color: AppColors.slate900, ), ), const SizedBox(height: 2), Text( hasData ? workMemory.summary : '暂无信息', style: TextStyle( fontSize: 13, fontWeight: FontWeight.w500, color: AppColors.slate500, ), maxLines: 1, overflow: TextOverflow.ellipsis, ), ], ), ), Icon(Icons.chevron_right, size: 20, color: AppColors.slate400), ], ), if (hasData) ...[ const SizedBox(height: AppSpacing.md), _buildMemoryStatsRow( icons: [ Icons.psychology_outlined, Icons.build_outlined, Icons.folder_outlined, Icons.groups_outlined, ], values: [ '${workMemory.expertise.length}', '${workMemory.preferredTools.length}', '${workMemory.currentProjects.length}', '${workMemory.teamMembers.length}', ], labels: ['专长', '工具', '项目', '团队'], ), ], ], ), ), ); } Widget _buildMemoryStatsRow({ required List icons, required List values, required List labels, }) { return Row( children: List.generate(icons.length, (index) { return Expanded( child: Container( padding: const EdgeInsets.symmetric(vertical: AppSpacing.sm), margin: EdgeInsets.only( right: index < icons.length - 1 ? AppSpacing.sm : 0, ), decoration: BoxDecoration( color: AppColors.surfaceSecondary, borderRadius: BorderRadius.circular(AppRadius.md), ), child: Column( children: [ Icon(icons[index], size: 16, color: AppColors.slate400), const SizedBox(height: 4), Text( values[index], style: const TextStyle( fontSize: 14, fontWeight: FontWeight.w600, color: AppColors.slate700, ), ), const SizedBox(height: 2), Text( labels[index], style: TextStyle( fontSize: 10, fontWeight: FontWeight.w500, color: AppColors.slate400, ), ), ], ), ), ); }), ); } }