主要变更: 1. 移除摇一摇相关功能代码与依赖 2. 新增自定义频道导入与管理功能 3. 优化iOS/macOS平台配置与适配 4. 重构路由转场逻辑为原生Cupertino风格 5. 修复设备发现与文件传输相关bug 6. 调整深色模式默认值为纯黑AMOLED 7. 新增运行模式标签与Spotlight搜索优化 8. 清理废弃的本地化字符串与设置项
119 lines
3.5 KiB
Dart
119 lines
3.5 KiB
Dart
// ============================================================
|
||
// 闲言APP — 频道分享导出/导入服务
|
||
// 创建时间: 2026-06-10
|
||
// 更新时间: 2026-06-10
|
||
// 作用: 导出频道配置+数据为JSON,导入分享的频道
|
||
// 上次更新: 初始创建
|
||
// ============================================================
|
||
|
||
import 'dart:convert';
|
||
import 'dart:io';
|
||
import 'package:path_provider/path_provider.dart';
|
||
import 'package:share_plus/share_plus.dart';
|
||
import '../models/custom_channel.dart';
|
||
import '../models/imported_sentence.dart';
|
||
import '../models/share_data.dart';
|
||
|
||
/// 分享导出服务
|
||
class ShareExportService {
|
||
static final ShareExportService _instance = ShareExportService._();
|
||
factory ShareExportService() => _instance;
|
||
ShareExportService._();
|
||
|
||
/// 导出频道分享数据
|
||
Future<String> exportChannel({
|
||
required CustomChannel channel,
|
||
required List<ImportedSentence> sentences,
|
||
ShareMode mode = ShareMode.configWithData,
|
||
ChannelAnalysis? analysis,
|
||
}) async {
|
||
final data = ChannelShareData(
|
||
type: mode,
|
||
channel: channel,
|
||
data: mode == ShareMode.configWithData ? sentences : [],
|
||
analysis: analysis ?? _generateAnalysis(sentences),
|
||
);
|
||
|
||
final jsonStr = const JsonEncoder.withIndent(' ')
|
||
.convert(data.toJson());
|
||
|
||
// 写入临时文件
|
||
final dir = await getTemporaryDirectory();
|
||
final fileName = 'xianyan_channel_${channel.id}.json';
|
||
final file = File('${dir.path}/$fileName');
|
||
await file.writeAsString(jsonStr);
|
||
|
||
return file.path;
|
||
}
|
||
|
||
/// 通过系统分享
|
||
Future<void> shareChannel({
|
||
required CustomChannel channel,
|
||
required List<ImportedSentence> sentences,
|
||
ShareMode mode = ShareMode.configWithData,
|
||
}) async {
|
||
final filePath = await exportChannel(
|
||
channel: channel,
|
||
sentences: sentences,
|
||
mode: mode,
|
||
);
|
||
await SharePlus.instance.share(ShareParams(
|
||
files: [XFile(filePath)],
|
||
text: '闲言频道: ${channel.name}',
|
||
));
|
||
}
|
||
|
||
/// 导入频道分享数据
|
||
Future<ChannelShareData?> importChannel(String filePath) async {
|
||
try {
|
||
final file = File(filePath);
|
||
if (!await file.exists()) return null;
|
||
final content = await file.readAsString();
|
||
final json = jsonDecode(content) as Map<String, dynamic>;
|
||
return ChannelShareData.fromJson(json);
|
||
} catch (e) {
|
||
return null;
|
||
}
|
||
}
|
||
|
||
/// 生成内容分析
|
||
ChannelAnalysis _generateAnalysis(List<ImportedSentence> sentences) {
|
||
if (sentences.isEmpty) {
|
||
return const ChannelAnalysis();
|
||
}
|
||
|
||
// 分类分布
|
||
final categoryDist = <String, int>{};
|
||
for (final s in sentences) {
|
||
final cat = s.category.isEmpty ? '未分类' : s.category;
|
||
categoryDist[cat] = (categoryDist[cat] ?? 0) + 1;
|
||
}
|
||
|
||
// 平均内容长度
|
||
final avgLen = sentences
|
||
.map((s) => s.content.length)
|
||
.reduce((a, b) => a + b) /
|
||
sentences.length;
|
||
|
||
// 热门作者
|
||
final authorCount = <String, int>{};
|
||
for (final s in sentences) {
|
||
if (s.author.isNotEmpty) {
|
||
authorCount[s.author] = (authorCount[s.author] ?? 0) + 1;
|
||
}
|
||
}
|
||
final topAuthors = authorCount.entries
|
||
.toList()
|
||
..sort((a, b) => b.value.compareTo(a.value));
|
||
final top5 = topAuthors.take(5).map((e) => e.key).toList();
|
||
|
||
return ChannelAnalysis(
|
||
totalCount: sentences.length,
|
||
categoryDistribution: categoryDist,
|
||
qualityScore: 92, // 简化评分
|
||
avgContentLength: avgLen.toInt(),
|
||
topAuthors: top5,
|
||
);
|
||
}
|
||
}
|