feat(app): 家长端数据导出 — 添加 JSON 文件下载 + 预览

- 新建 file_download.dart 跨平台下载工具(conditional import)
- download_impl_web.dart: Web 平台通过 html.AnchorElement + Blob 下载
- download_impl.dart: 非 Web 平台 stub(Phase 2 扩展 path_provider)
- _ExportDataView: 添加下载按钮 + JSON 折叠预览 + PIPL 提示
- 移除 'Phase 1 预览' 占位文案,替换为完整下载功能
This commit is contained in:
iven
2026-06-02 23:36:35 +08:00
parent c9a69d0be1
commit f0741450bc
4 changed files with 178 additions and 4 deletions

View File

@@ -0,0 +1,9 @@
// 文件下载 — 非 Web 平台 stub
//
// 非 Web 平台暂不支持文件下载,返回 false。
// Phase 2 扩展:使用 path_provider + File 实现。
/// 下载文件stub 实现)
Future<bool> downloadFile(String content, String filename, String mimeType) async {
return false;
}

View File

@@ -0,0 +1,21 @@
// 文件下载 — Web 平台实现
//
// 使用 dart:html 的 AnchorElement + Blob 触发浏览器下载。
// 通过 conditional import 自动选择此实现。
import 'dart:html' as html;
/// 下载文件Web 实现)
Future<bool> downloadFile(String content, String filename, String mimeType) async {
try {
final blob = html.Blob([content], mimeType);
final url = html.Url.createObjectUrlFromBlob(blob);
html.AnchorElement(href: url)
..setAttribute('download', filename)
..click();
html.Url.revokeObjectUrl(url);
return true;
} catch (e) {
return false;
}
}

View File

@@ -0,0 +1,23 @@
// 文件下载工具 — 跨平台接口
//
// Web: 通过 html.AnchorElement + Blob 触发浏览器下载
// 非 Web: 返回 falsePhase 2 扩展 path_provider
import 'dart:convert';
import 'download_impl.dart'
if (dart.library.html) 'download_impl_web.dart';
/// 下载 JSON 数据为文件
///
/// [data] — 要导出的 JSON 数据
/// [filename] — 下载文件名(如 "export_2026-06-02.json"
///
/// 返回 true 表示下载成功。
Future<bool> downloadJsonFile(
Map<String, dynamic> data,
String filename,
) async {
final jsonStr = const JsonEncoder.withIndent(' ').convert(data);
return downloadFile(jsonStr, filename, 'application/json');
}