Files
xianyan/lib/features/discover/services/chat_attachment_service.dart
Developer 63a0559721 refactor: 重构项目路由与模块结构,统一发现页命名与路径
1. 全局替换tool_center/inspiration为discover模块,统一路由路径
2. 调整AppRoutes路由常量,将discover作为主Tab页,inspiration作为子页面
3. 更新页面注册表与路由配置,修正跳转目标
4. 调整启动页可选配置项,修正路由ID对应关系
5. 新增翻译服务、内容发现、热搜相关工具类与数据模型
6. 修复缓存清理后未刷新统计的问题,调整x86_64架构注释
7. 更新AGENTS.md文档约束规则
8. 新增一批调试用截图资源文件
2026-05-28 06:42:20 +08:00

176 lines
5.2 KiB
Dart

/// ============================================================
/// 闲言APP — 聊天附件服务
/// 创建时间: 2026-05-08
/// 更新时间: 2026-05-08
/// 作用: 附件的创建/查询/删除/云端同步状态管理
/// 上次更新: 初始创建
/// ============================================================
import 'package:drift/drift.dart' show Value;
import 'package:uuid/uuid.dart';
import 'package:xianyan/core/storage/database/app_database.dart';
import 'package:xianyan/core/utils/logger.dart';
import 'chat_file_service.dart';
class ChatAttachmentService {
ChatAttachmentService._();
static final _db = AppDatabase.instance;
static const _uuid = Uuid();
/// 创建附件记录(文件已由 ChatFileService 保存)
static Future<ChatAttachment> create({
required String messageId,
required String conversationId,
required String fileName,
required String filePath,
required String fileType,
required int fileSize,
String? thumbnailPath,
int? width,
int? height,
int? durationMs,
}) async {
final id = _uuid.v4();
final att = ChatAttachmentsCompanion.insert(
id: id,
messageId: messageId,
conversationId: conversationId,
fileName: fileName,
filePath: filePath,
fileType: fileType,
fileSize: fileSize,
thumbnailPath: Value(thumbnailPath),
width: Value(width),
height: Value(height),
durationMs: Value(durationMs),
createdAt: DateTime.now(),
);
await _db.insertChatAttachment(att);
Log.d('附件记录已创建: $fileName ($id)');
return (await _db.getChatAttachments(messageId)).first;
}
/// 保存图片附件(含缩略图)
static Future<ChatAttachment> saveImageAttachment({
required String messageId,
required String conversationId,
required String fileName,
required String filePath,
required int fileSize,
String? thumbnailPath,
int? width,
int? height,
}) async {
return create(
messageId: messageId,
conversationId: conversationId,
fileName: fileName,
filePath: filePath,
fileType: 'image/${_getExtension(fileName)}',
fileSize: fileSize,
thumbnailPath: thumbnailPath,
width: width,
height: height,
);
}
/// 保存文件附件
static Future<ChatAttachment> saveFileAttachment({
required String messageId,
required String conversationId,
required String fileName,
required String filePath,
required int fileSize,
required String mimeType,
}) async {
return create(
messageId: messageId,
conversationId: conversationId,
fileName: fileName,
filePath: filePath,
fileType: mimeType,
fileSize: fileSize,
);
}
/// 获取消息的所有附件
static Future<List<ChatAttachment>> getByMessage(String messageId) {
return _db.getChatAttachments(messageId);
}
/// 获取会话的所有附件
static Future<List<ChatAttachment>> getByConversation(
String conversationId, {
int limit = 100,
}) {
return _db.getChatAttachmentsByConversation(conversationId, limit: limit);
}
/// 删除消息的附件(同时删除文件)
static Future<void> deleteByMessage(String messageId) async {
final attachments = await _db.getChatAttachments(messageId);
for (final att in attachments) {
await ChatFileService.deleteFile(att.filePath);
if (att.thumbnailPath != null) {
await ChatFileService.deleteFile(att.thumbnailPath!);
}
}
await _db.deleteChatAttachmentsByMessage(messageId);
Log.d('消息附件已删除: msg=$messageId');
}
/// 删除会话的所有附件(同时删除文件)
static Future<void> deleteByConversation(String conversationId) async {
final attachments = await _db.getChatAttachmentsByConversation(conversationId);
for (final att in attachments) {
await ChatFileService.deleteFile(att.filePath);
if (att.thumbnailPath != null) {
await ChatFileService.deleteFile(att.thumbnailPath!);
}
}
await _db.deleteChatAttachmentsByConversation(conversationId);
await ChatFileService.deleteConversationFiles(conversationId);
Log.d('会话附件已全部删除: conv=$conversationId');
}
/// 更新云端同步状态
static Future<void> updateCloudSync({
required String attachmentId,
required String cloudUrl,
}) async {
await _db.updateChatAttachment(
ChatAttachmentsCompanion(
id: Value(attachmentId),
cloudUrl: Value(cloudUrl),
cloudSyncedAt: Value(DateTime.now()),
),
);
}
/// 获取未同步的附件数量
static Future<int> getUnsyncedCount() {
return _db.getUnsyncedChatAttachmentCount();
}
/// 获取附件数量
static Future<int> getCount(String conversationId) {
return _db.getChatAttachmentCount(conversationId);
}
/// 获取附件的绝对路径
static Future<String> getAbsolutePath(String relativePath) {
return ChatFileService.getAbsolutePath(relativePath);
}
/// 获取扩展名
static String _getExtension(String fileName) {
final dotIndex = fileName.lastIndexOf('.');
if (dotIndex >= 0 && dotIndex < fileName.length - 1) {
return fileName.substring(dotIndex + 1).toLowerCase();
}
return 'jpg';
}
}