220 lines
7.7 KiB
Dart
220 lines
7.7 KiB
Dart
import 'package:hive/hive.dart';
|
||
import '../../../data/models/hive_inspiration_image.dart';
|
||
import '../../../domain/entities/inspiration_image.dart';
|
||
import '../local/hive_database.dart';
|
||
|
||
/// 图片数据访问对象 - 负责灵感图片的CRUD操作
|
||
/// 提供对Hive数据库中图片数据的直接访问接口
|
||
class ImageDao {
|
||
/// 获取图片数据盒 - 访问Hive图片存储
|
||
Box<HiveInspirationImage> get _imagesBox => HiveDatabase.imagesBox;
|
||
|
||
/// 添加单张图片 - 将图片实体保存到数据库
|
||
/// [image] 要保存的图片实体对象
|
||
/// 返回保存后的图片ID
|
||
Future<String> insertImage(InspirationImage image) async {
|
||
final hiveImage = HiveInspirationImage.fromEntity(image);
|
||
await _imagesBox.put(hiveImage.id, hiveImage);
|
||
return hiveImage.id;
|
||
}
|
||
|
||
/// 批量添加图片 - 一次性保存多张图片
|
||
/// [images] 要保存的图片实体列表
|
||
/// 返回保存成功的图片ID列表
|
||
Future<List<String>> insertImages(List<InspirationImage> images) async {
|
||
final hiveImages = images.map((image) => HiveInspirationImage.fromEntity(image)).toList();
|
||
|
||
// Hive Box没有batch方法,使用循环逐个保存
|
||
for (final hiveImage in hiveImages) {
|
||
await _imagesBox.put(hiveImage.id, hiveImage);
|
||
}
|
||
|
||
return hiveImages.map((image) => image.id).toList();
|
||
}
|
||
|
||
/// 根据ID获取单张图片 - 通过唯一标识符查找图片
|
||
/// [id] 图片的唯一标识符
|
||
/// 返回找到的图片实体,如果不存在则返回null
|
||
Future<InspirationImage?> getImageById(String id) async {
|
||
final hiveImage = _imagesBox.get(id);
|
||
return hiveImage?.toEntity();
|
||
}
|
||
|
||
/// 获取所有图片 - 按创建时间倒序排列
|
||
/// 返回所有图片实体列表,最新创建的图片在前
|
||
Future<List<InspirationImage>> getAllImages() async {
|
||
final hiveImages = _imagesBox.values
|
||
.toList()
|
||
..sort((a, b) => b.createdAt.compareTo(a.createdAt));
|
||
|
||
return hiveImages.map((hiveImage) => hiveImage.toEntity()).toList();
|
||
}
|
||
|
||
/// 分页获取图片 - 支持大数据集的懒加载
|
||
/// [offset] 起始位置,从0开始
|
||
/// [limit] 每页数量限制
|
||
/// 返回指定范围的图片列表
|
||
Future<List<InspirationImage>> getImagesPaginated(int offset, int limit) async {
|
||
final allImages = await getAllImages();
|
||
|
||
if (offset >= allImages.length) {
|
||
return [];
|
||
}
|
||
|
||
final endIndex = (offset + limit).clamp(0, allImages.length);
|
||
return allImages.sublist(offset, endIndex);
|
||
}
|
||
|
||
/// 根据文件夹ID获取图片 - 获取指定文件夹内的所有图片
|
||
/// [folderId] 文件夹的唯一标识符
|
||
/// 返回该文件夹内的图片列表,按创建时间倒序排列
|
||
Future<List<InspirationImage>> getImagesByFolder(String folderId) async {
|
||
final hiveImages = _imagesBox.values
|
||
.where((image) => image.folderId == folderId)
|
||
.toList()
|
||
..sort((a, b) => b.createdAt.compareTo(a.createdAt));
|
||
|
||
return hiveImages.map((hiveImage) => hiveImage.toEntity()).toList();
|
||
}
|
||
|
||
/// 根据标签获取图片 - 获取包含指定标签的所有图片
|
||
/// [tagId] 标签的唯一标识符
|
||
/// 返回包含该标签的图片列表,按创建时间倒序排列
|
||
Future<List<InspirationImage>> getImagesByTag(String tagId) async {
|
||
final hiveImages = _imagesBox.values
|
||
.where((image) => image.tags.contains(tagId))
|
||
.toList()
|
||
..sort((a, b) => b.createdAt.compareTo(a.createdAt));
|
||
|
||
return hiveImages.map((hiveImage) => hiveImage.toEntity()).toList();
|
||
}
|
||
|
||
/// 搜索图片 - 根据关键词模糊搜索
|
||
/// [query] 搜索关键词,会搜索文件夹名称、标签名称和备注内容
|
||
/// 返回匹配的图片列表,按相关性排序
|
||
Future<List<InspirationImage>> searchImages(String query) async {
|
||
final lowerQuery = query.toLowerCase();
|
||
|
||
final hiveImages = _imagesBox.values
|
||
.where((image) {
|
||
// 搜索备注内容
|
||
if (image.note?.toLowerCase().contains(lowerQuery) == true) {
|
||
return true;
|
||
}
|
||
|
||
// 搜索原始文件名
|
||
if (image.originalName?.toLowerCase().contains(lowerQuery) == true) {
|
||
return true;
|
||
}
|
||
|
||
return false;
|
||
})
|
||
.toList()
|
||
..sort((a, b) => b.createdAt.compareTo(a.createdAt));
|
||
|
||
return hiveImages.map((hiveImage) => hiveImage.toEntity()).toList();
|
||
}
|
||
|
||
/// 获取收藏图片 - 获取用户标记为收藏的所有图片
|
||
/// 返回收藏的图片列表,按收藏时间倒序排列
|
||
Future<List<InspirationImage>> getFavoriteImages() async {
|
||
final hiveImages = _imagesBox.values
|
||
.where((image) => image.isFavorite)
|
||
.toList()
|
||
..sort((a, b) => b.createdAt.compareTo(a.createdAt));
|
||
|
||
return hiveImages.map((hiveImage) => hiveImage.toEntity()).toList();
|
||
}
|
||
|
||
/// 更新图片信息 - 修改图片的元数据
|
||
/// [image] 包含更新数据的图片实体
|
||
/// 返回更新后的图片实体
|
||
Future<InspirationImage> updateImage(InspirationImage image) async {
|
||
final hiveImage = HiveInspirationImage.fromEntity(image.copyWith(
|
||
updatedAt: DateTime.now(),
|
||
));
|
||
|
||
await _imagesBox.put(hiveImage.id, hiveImage);
|
||
return hiveImage.toEntity();
|
||
}
|
||
|
||
/// 批量更新图片 - 一次性更新多张图片
|
||
/// [images] 要更新的图片实体列表
|
||
/// 返回更新后的图片实体列表
|
||
Future<List<InspirationImage>> updateImages(List<InspirationImage> images) async {
|
||
final updatedImages = images.map((image) => image.copyWith(
|
||
updatedAt: DateTime.now(),
|
||
)).toList();
|
||
|
||
final hiveImages = updatedImages.map((image) => HiveInspirationImage.fromEntity(image)).toList();
|
||
|
||
// Hive Box没有batch方法,使用循环逐个更新
|
||
for (final hiveImage in hiveImages) {
|
||
await _imagesBox.put(hiveImage.id, hiveImage);
|
||
}
|
||
|
||
return hiveImages.map((hiveImage) => hiveImage.toEntity()).toList();
|
||
}
|
||
|
||
/// 删除单张图片 - 从数据库中移除指定图片
|
||
/// [id] 要删除的图片ID
|
||
/// 返回是否删除成功
|
||
Future<bool> deleteImage(String id) async {
|
||
await _imagesBox.delete(id);
|
||
return true;
|
||
}
|
||
|
||
/// 批量删除图片 - 一次性删除多张图片
|
||
/// [ids] 要删除的图片ID列表
|
||
/// 返回是否删除成功
|
||
Future<bool> deleteImages(List<String> ids) async {
|
||
// Hive Box没有batch方法,使用循环逐个删除
|
||
for (final id in ids) {
|
||
await _imagesBox.delete(id);
|
||
}
|
||
return true;
|
||
}
|
||
|
||
/// 根据文件夹删除图片 - 删除指定文件夹内的所有图片
|
||
/// [folderId] 要清空的文件夹ID
|
||
/// 返回删除的图片数量
|
||
Future<int> deleteImagesByFolder(String folderId) async {
|
||
final imagesToDelete = _imagesBox.values
|
||
.where((image) => image.folderId == folderId)
|
||
.map((image) => image.id)
|
||
.toList();
|
||
|
||
if (imagesToDelete.isEmpty) {
|
||
return 0;
|
||
}
|
||
|
||
await deleteImages(imagesToDelete);
|
||
return imagesToDelete.length;
|
||
}
|
||
|
||
/// 获取图片总数 - 统计数据库中的图片数量
|
||
/// 返回图片总数
|
||
Future<int> getImageCount() async {
|
||
return _imagesBox.length;
|
||
}
|
||
|
||
/// 获取文件夹图片数量 - 统计指定文件夹内的图片数量
|
||
/// [folderId] 文件夹ID
|
||
/// 返回该文件夹内的图片数量
|
||
Future<int> getImageCountByFolder(String folderId) async {
|
||
return _imagesBox.values.where((image) => image.folderId == folderId).length;
|
||
}
|
||
|
||
/// 检查图片是否存在 - 验证指定ID的图片是否存在
|
||
/// [id] 图片ID
|
||
/// 返回图片是否存在
|
||
Future<bool> imageExists(String id) async {
|
||
return _imagesBox.containsKey(id);
|
||
}
|
||
|
||
/// 关闭数据盒 - 释放数据库资源
|
||
/// 通常在应用退出时调用
|
||
Future<void> close() async {
|
||
await _imagesBox.close();
|
||
}
|
||
} |