Files
MookNote/lib/utils/image_path_helper.dart
2026-08-09 01:22:35 +08:00

281 lines
8.9 KiB
Dart
Raw Permalink 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 'dart:io';
import 'package:flutter/foundation.dart';
import 'package:path_provider/path_provider.dart';
import 'package:path/path.dart' as p;
/// 图片路径管理助手 - 按分类和ID组织图片存储
///
/// 存储结构:
/// images/movies/{movieId}/xxxx.jpg - 影视海报
/// images/movies/{movieId}/posterimgs/xxxx.jpg - 影视海报墙图片
/// images/books/{bookId}/xxxx.jpg - 书籍封面
/// images/notes/{noteId}/xxxx.jpg - 笔记图片
/// images/games/{gameId}/xxxx.jpg - 游戏封面
/// images/games/{gameId}/screenshots/xxxx.jpg - 游戏截图
/// images/people/{personId}/xxxx.jpg - 人物图片
class ImagePathHelper {
static final ImagePathHelper instance = ImagePathHelper._init();
ImagePathHelper._init();
static String? _appDirPath;
/// 获取应用数据根目录Windows 下统一到 mooknote 子目录)
/// 所有需要访问 images/、epub_books/ 等目录的代码都应使用此方法
static Future<String> getAppDir() async {
if (_appDirPath != null) return _appDirPath!;
final appDir = await getApplicationDocumentsDirectory();
if (Platform.isWindows) {
_appDirPath = p.join(appDir.path, 'mooknote');
} else {
_appDirPath = appDir.path;
}
return _appDirPath!;
}
/// 获取图片根目录
Future<String> get imagesRoot async {
final appDir = await getAppDir();
return p.join(appDir, 'images');
}
// ==================== 影视相关路径 ====================
/// 获取影视图片目录
/// 路径: images/movies/{movieId}/
Future<String> getMovieImagesDir(String movieId) async {
final root = await imagesRoot;
return p.join(root, 'movies', movieId);
}
/// 获取影视海报路径
/// 路径: images/movies/{movieId}/{fileName}
Future<String> getMoviePosterPath(String movieId, String fileName) async {
final dir = await getMovieImagesDir(movieId);
return p.join(dir, fileName);
}
/// 获取影视海报墙目录
/// 路径: images/movies/{movieId}/posterimgs/
Future<String> getMoviePosterImgsDir(String movieId) async {
final dir = await getMovieImagesDir(movieId);
return p.join(dir, 'posterimgs');
}
/// 获取影视海报墙图片路径
/// 路径: images/movies/{movieId}/posterimgs/{fileName}
Future<String> getMoviePosterImgPath(String movieId, String fileName) async {
final dir = await getMoviePosterImgsDir(movieId);
return p.join(dir, fileName);
}
// ==================== 书籍相关路径 ====================
/// 获取书籍图片目录
/// 路径: images/books/{bookId}/
Future<String> getBookImagesDir(String bookId) async {
final root = await imagesRoot;
return p.join(root, 'books', bookId);
}
/// 获取书籍封面路径
/// 路径: images/books/{bookId}/{fileName}
Future<String> getBookCoverPath(String bookId, String fileName) async {
final dir = await getBookImagesDir(bookId);
return p.join(dir, fileName);
}
// ==================== 笔记相关路径 ====================
/// 获取笔记图片目录
/// 路径: images/notes/{noteId}/
Future<String> getNoteImagesDir(String noteId) async {
final root = await imagesRoot;
return p.join(root, 'notes', noteId);
}
/// 获取笔记图片路径
/// 路径: images/notes/{noteId}/{fileName}
Future<String> getNoteImagePath(String noteId, String fileName) async {
final dir = await getNoteImagesDir(noteId);
return p.join(dir, fileName);
}
// ==================== 游戏相关路径 ====================
/// 获取游戏图片目录
/// 路径: images/games/{gameId}/
Future<String> getGameImagesDir(String gameId) async {
final root = await imagesRoot;
return p.join(root, 'games', gameId);
}
/// 获取游戏封面路径
/// 路径: images/games/{gameId}/{fileName}
Future<String> getGameCoverPath(String gameId, String fileName) async {
final dir = await getGameImagesDir(gameId);
return p.join(dir, fileName);
}
/// 获取游戏截图目录
/// 路径: images/games/{gameId}/screenshots/
Future<String> getGameScreenshotImgsDir(String gameId) async {
final dir = await getGameImagesDir(gameId);
return p.join(dir, 'screenshots');
}
/// 获取游戏截图图片路径
/// 路径: images/games/{gameId}/screenshots/{fileName}
Future<String> getGameScreenshotImgPath(String gameId, String fileName) async {
final dir = await getGameScreenshotImgsDir(gameId);
return p.join(dir, fileName);
}
// ==================== 人物相关路径 ====================
/// 获取人物图片目录
/// 路径: images/people/{personId}/
Future<String> getPersonImagesDir(String personId) async {
final root = await imagesRoot;
return p.join(root, 'people', personId);
}
/// 获取人物图片路径
/// 路径: images/people/{personId}/{fileName}
Future<String> getPersonPhotoPath(String personId, String fileName) async {
final dir = await getPersonImagesDir(personId);
return p.join(dir, fileName);
}
// ==================== 角色相关路径 ====================
/// 获取角色图片目录
/// 路径: images/characters/{characterId}/
Future<String> getCharacterImagesDir(String characterId) async {
final root = await imagesRoot;
return p.join(root, 'characters', characterId);
}
/// 获取角色图片路径
/// 路径: images/characters/{characterId}/{fileName}
Future<String> getCharacterImagePath(String characterId, String fileName) async {
final dir = await getCharacterImagesDir(characterId);
return p.join(dir, fileName);
}
/// 删除角色图片目录
/// 删除路径: images/characters/{characterId}/
Future<void> deleteCharacterImages(String characterId) async {
final dirPath = await getCharacterImagesDir(characterId);
await _deleteDirectory(dirPath);
}
// ==================== 目录操作 ====================
/// 确保目录存在
Future<void> ensureDirExists(String dirPath) async {
try {
final dir = Directory(dirPath);
if (!await dir.exists()) {
await dir.create(recursive: true);
}
} catch (e) {
debugPrint('[ImagePathHelper] ensureDirExists($dirPath) error: $e');
rethrow;
}
}
/// 删除影视图片目录(包括海报和海报墙)
/// 删除路径: images/movies/{movieId}/
Future<void> deleteMovieImages(String movieId) async {
final dirPath = await getMovieImagesDir(movieId);
await _deleteDirectory(dirPath);
}
/// 删除书籍图片目录
/// 删除路径: images/books/{bookId}/
Future<void> deleteBookImages(String bookId) async {
final dirPath = await getBookImagesDir(bookId);
await _deleteDirectory(dirPath);
}
/// 删除笔记图片目录
/// 删除路径: images/notes/{noteId}/
Future<void> deleteNoteImages(String noteId) async {
final dirPath = await getNoteImagesDir(noteId);
await _deleteDirectory(dirPath);
}
/// 删除游戏图片目录
/// 删除路径: images/games/{gameId}/
Future<void> deleteGameImages(String gameId) async {
final dirPath = await getGameImagesDir(gameId);
await _deleteDirectory(dirPath);
}
/// 删除人物图片目录
/// 删除路径: images/people/{personId}/
Future<void> deletePersonImages(String personId) async {
final dirPath = await getPersonImagesDir(personId);
await _deleteDirectory(dirPath);
}
/// 删除目录及其内容
Future<void> _deleteDirectory(String dirPath) async {
try {
final dir = Directory(dirPath);
if (await dir.exists()) {
await dir.delete(recursive: true);
}
} catch (e) {
debugPrint('[ImagePathHelper] deleteDirectory($dirPath) error: $e');
rethrow;
}
}
/// 移动文件到新位置
Future<String> moveFile(String sourcePath, String targetDir, String fileName) async {
try {
await ensureDirExists(targetDir);
final targetPath = p.join(targetDir, fileName);
final sourceFile = File(sourcePath);
if (await sourceFile.exists()) {
await sourceFile.rename(targetPath);
}
return targetPath;
} catch (e) {
debugPrint('[ImagePathHelper] moveFile($sourcePath) error: $e');
rethrow;
}
}
/// 复制文件到新位置
Future<String> copyFile(String sourcePath, String targetDir, String fileName) async {
try {
await ensureDirExists(targetDir);
final targetPath = p.join(targetDir, fileName);
final sourceFile = File(sourcePath);
if (await sourceFile.exists()) {
await sourceFile.copy(targetPath);
}
return targetPath;
} catch (e) {
debugPrint('[ImagePathHelper] copyFile($sourcePath) error: $e');
rethrow;
}
}
/// 删除单个文件
Future<void> deleteFile(String filePath) async {
try {
final file = File(filePath);
if (await file.exists()) {
await file.delete();
}
} catch (e) {
debugPrint('[ImagePathHelper] deleteFile($filePath) error: $e');
rethrow;
}
}
}