import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import '../../core/app_colors.dart'; import '../../core/app_design_tokens.dart'; import '../../providers/ai_consent_provider.dart'; import '../../providers/auth_provider.dart'; class AiConsentDetailsPage extends ConsumerWidget { const AiConsentDetailsPage({super.key}); Future _revoke(BuildContext context, WidgetRef ref) async { final userId = ref.read(authProvider).user?.id; if (userId == null || userId.isEmpty) return; final confirmed = await showDialog( context: context, builder: (ctx) => AlertDialog( title: const Text('撤回 AI 授权?'), content: const Text('撤回后将退出当前账号,重新使用 App 前需要再次完成 AI 数据授权。'), actions: [ TextButton( onPressed: () => Navigator.pop(ctx, false), child: const Text('取消'), ), FilledButton( onPressed: () => Navigator.pop(ctx, true), child: const Text('撤回并退出'), ), ], ), ); if (confirmed != true || !context.mounted) return; final revoked = await ref.read(aiConsentProvider.notifier).revoke(userId); if (!revoked) { if (context.mounted) { ScaffoldMessenger.of( context, ).showSnackBar(const SnackBar(content: Text('撤回授权失败,请稍后重试'))); } return; } await ref.read(authProvider.notifier).logout(); } @override Widget build(BuildContext context, WidgetRef ref) { final consent = ref.watch(aiConsentProvider); final canRevoke = consent.granted && ref.watch(authProvider).user != null; return Scaffold( backgroundColor: AppColors.background, appBar: AppBar( backgroundColor: Colors.white, elevation: 0, scrolledUnderElevation: 0, leading: IconButton( icon: const Icon(Icons.arrow_back, color: AppColors.textPrimary), onPressed: () => Navigator.of(context).maybePop(), ), title: const Text( 'AI 数据授权说明', style: TextStyle( fontSize: 19, fontWeight: FontWeight.w700, color: AppColors.textPrimary, ), ), centerTitle: true, ), body: SafeArea( child: SingleChildScrollView( padding: const EdgeInsets.fromLTRB(20, 20, 20, 32), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ _section( '我们会处理什么数据', '当你使用 AI 对话、饮食识别或报告预整理功能时,可能会处理你主动输入的文字、健康数据、健康档案摘要、图片和 PDF 报告。', ), _section( '发送给哪些服务商', 'DeepSeek:用于生成 AI 对话和健康信息整理。\n\n通义千问视觉服务:用于识别你主动上传的饮食图片、报告图片或 PDF 内容。\n\nFastGPT:用于检索与问题相关的医学参考资料。', ), _section( '使用目的', '上述数据仅用于提供 AI 对话、健康记录辅助、饮食图片识别、医学报告预整理和医学资料检索功能。AI 内容仅供健康管理参考,不能替代医生诊断或治疗。', ), _section( '你的选择', '你可以在首次进入首页时选择是否授权。未授权时无法进入本 App 的主要服务。你也可以在设置中撤回授权;撤回后将退出当前账号,再次使用前需要重新授权。', ), _section( '更多信息', '数据保存、删除、第三方服务保护措施和联系方式,请同时查看 App 内《隐私政策》和《第三方 SDK 共享清单》。', ), if (canRevoke) ...[ const SizedBox(height: 12), SizedBox( width: double.infinity, child: OutlinedButton( onPressed: consent.isSaving ? null : () => _revoke(context, ref), style: OutlinedButton.styleFrom( backgroundColor: Colors.white, foregroundColor: AppColors.error, side: BorderSide( color: AppColors.error.withValues(alpha: 0.4), ), minimumSize: const Size.fromHeight(50), ), child: consent.isSaving ? const SizedBox( width: 20, height: 20, child: CircularProgressIndicator( strokeWidth: 2.2, color: AppColors.error, ), ) : const Text('撤回 AI 数据授权'), ), ), ], ], ), ), ), ); } static Widget _section(String title, String body) { return Padding( padding: const EdgeInsets.only(bottom: 22), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text(title, style: AppTextStyles.sectionTitle), const SizedBox(height: 8), Text( body, style: const TextStyle( fontSize: 15, height: 1.65, color: AppColors.textSecondary, ), ), ], ), ); } }