Files
AI-Health/health_app/lib/pages/settings/ai_consent_details_page.dart
MingNian 3b5cec10a6 feat: AI 提示词模块化 + AI 同意门控 + AI 草稿存储 + 意图路由 + 医疗引用知识库 + 多页面 UI 优化
- 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
2026-07-27 16:53:20 +08:00

134 lines
5.0 KiB
Dart
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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,
),
),
],
),
);
}
}