- AI 提示词拆分为 markdown 模块(Prompts/global + modules + rag + router) - 新增 AI 同意门控(用户需同意后才能使用 AI 功能) - 新增 AI 录入草稿存储(AiEntryDraftContracts/EfAiEntryDraftStore/AiEntryDraftRecord) - 新增 AI 意图路由(ai_intent_router) - 新增医疗引用知识库(MedicalCitationKnowledge) - 重构 prompt_manager 和 ai_chat_endpoints - 优化聊天/趋势/档案/抽屉/医生端等多个页面 UI - 新增 agent 插画和趋势指标图标资源 - 删除 HANDOFF-2026-07-17.md
134 lines
5.0 KiB
Dart
134 lines
5.0 KiB
Dart
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<void> _revoke(BuildContext context, WidgetRef ref) async {
|
||
final userId = ref.read(authProvider).user?.id;
|
||
if (userId == null || userId.isEmpty) return;
|
||
|
||
final confirmed = await showDialog<bool>(
|
||
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;
|
||
|
||
await ref.read(aiConsentProvider.notifier).revoke(userId);
|
||
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,
|
||
),
|
||
),
|
||
),
|
||
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: () => _revoke(context, ref),
|
||
style: OutlinedButton.styleFrom(
|
||
foregroundColor: AppColors.error,
|
||
side: BorderSide(
|
||
color: AppColors.error.withValues(alpha: 0.4),
|
||
),
|
||
minimumSize: const Size.fromHeight(50),
|
||
),
|
||
child: 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,
|
||
),
|
||
),
|
||
],
|
||
),
|
||
);
|
||
}
|
||
}
|