新增影评海报功能

This commit is contained in:
DelLevin-Home
2026-03-06 16:09:56 +08:00
parent 17de976d4b
commit f2ab6a17ba
18 changed files with 2260 additions and 698 deletions

View File

@@ -20,7 +20,7 @@ class DatabaseHelper {
return await openDatabase(
path,
version: 4,
version: 5,
onCreate: _createDB,
onUpgrade: _onUpgrade,
);
@@ -40,6 +40,43 @@ class DatabaseHelper {
// 升级notes表结构
await _upgradeNotesTableV4(db);
}
if (oldVersion < 5) {
// 创建影评表和海报墙表
await _createMovieReviewsTable(db);
await _createMoviePostersTable(db);
}
}
/// 创建影评表
Future<void> _createMovieReviewsTable(Database db) async {
await db.execute('''
CREATE TABLE IF NOT EXISTS movie_reviews (
id TEXT PRIMARY KEY,
movie_id TEXT NOT NULL,
content TEXT NOT NULL,
reviewer TEXT,
source TEXT,
review_type INTEGER DEFAULT 1,
is_deleted INTEGER DEFAULT 0,
created_at TEXT NOT NULL,
updated_at TEXT NOT NULL,
FOREIGN KEY (movie_id) REFERENCES movies (id)
)
''');
}
/// 创建影视海报墙表
Future<void> _createMoviePostersTable(Database db) async {
await db.execute('''
CREATE TABLE IF NOT EXISTS movie_posters (
id TEXT PRIMARY KEY,
movie_id TEXT NOT NULL,
poster_path TEXT NOT NULL,
is_deleted INTEGER DEFAULT 0,
created_at TEXT NOT NULL,
FOREIGN KEY (movie_id) REFERENCES movies (id)
)
''');
}
/// 升级notes表到V4
@@ -251,6 +288,34 @@ class DatabaseHelper {
updated_at TEXT NOT NULL
)
''');
// 影评表
await db.execute('''
CREATE TABLE movie_reviews (
id TEXT PRIMARY KEY,
movie_id TEXT NOT NULL,
content TEXT NOT NULL,
reviewer TEXT,
source TEXT,
review_type INTEGER DEFAULT 1,
is_deleted INTEGER DEFAULT 0,
created_at TEXT NOT NULL,
updated_at TEXT NOT NULL,
FOREIGN KEY (movie_id) REFERENCES movies (id)
)
''');
// 影视海报墙表
await db.execute('''
CREATE TABLE movie_posters (
id TEXT PRIMARY KEY,
movie_id TEXT NOT NULL,
poster_path TEXT NOT NULL,
is_deleted INTEGER DEFAULT 0,
created_at TEXT NOT NULL,
FOREIGN KEY (movie_id) REFERENCES movies (id)
)
''');
}
// 关闭数据库

View File

@@ -0,0 +1,61 @@
import 'package:sqflite/sqflite.dart';
import '../models/data_models.dart';
import 'database_helper.dart';
/// 影视海报墙数据访问对象
class MoviePosterDao {
final DatabaseHelper _dbHelper = DatabaseHelper.instance;
/// 获取影视的所有海报
Future<List<MoviePoster>> getPostersByMovieId(String movieId) async {
final db = await _dbHelper.database;
final List<Map<String, dynamic>> maps = await db.query(
'movie_posters',
where: 'movie_id = ? AND is_deleted = 0',
whereArgs: [movieId],
orderBy: 'created_at DESC',
);
return List.generate(maps.length, (i) => MoviePoster.fromJson(maps[i]));
}
/// 根据ID获取海报
Future<MoviePoster?> getPosterById(String id) async {
final db = await _dbHelper.database;
final List<Map<String, dynamic>> maps = await db.query(
'movie_posters',
where: 'id = ? AND is_deleted = 0',
whereArgs: [id],
);
if (maps.isEmpty) return null;
return MoviePoster.fromJson(maps.first);
}
/// 添加海报
Future<int> insertPoster(MoviePoster poster) async {
final db = await _dbHelper.database;
return await db.insert('movie_posters', poster.toJson());
}
/// 软删除海报
Future<int> deletePoster(String id) async {
final db = await _dbHelper.database;
return await db.update(
'movie_posters',
{'is_deleted': 1},
where: 'id = ?',
whereArgs: [id],
);
}
/// 获取影视的海报数量
Future<int> getPosterCount(String movieId) async {
final db = await _dbHelper.database;
final result = await db.rawQuery(
'SELECT COUNT(*) as count FROM movie_posters WHERE movie_id = ? AND is_deleted = 0',
[movieId],
);
return result.first['count'] as int;
}
}

View File

@@ -0,0 +1,98 @@
import 'package:sqflite/sqflite.dart';
import '../models/data_models.dart';
import 'database_helper.dart';
/// 影评数据访问对象
class MovieReviewDao {
final DatabaseHelper _dbHelper = DatabaseHelper.instance;
/// 获取影视的所有影评
Future<List<MovieReview>> getReviewsByMovieId(String movieId) async {
final db = await _dbHelper.database;
final List<Map<String, dynamic>> maps = await db.query(
'movie_reviews',
where: 'movie_id = ? AND is_deleted = 0',
whereArgs: [movieId],
orderBy: 'created_at DESC',
);
return List.generate(maps.length, (i) => MovieReview.fromJson(maps[i]));
}
/// 根据ID获取影评
Future<MovieReview?> getReviewById(String id) async {
final db = await _dbHelper.database;
final List<Map<String, dynamic>> maps = await db.query(
'movie_reviews',
where: 'id = ? AND is_deleted = 0',
whereArgs: [id],
);
if (maps.isEmpty) return null;
return MovieReview.fromJson(maps.first);
}
/// 添加影评
Future<int> insertReview(MovieReview review) async {
final db = await _dbHelper.database;
return await db.insert('movie_reviews', review.toJson());
}
/// 更新影评
Future<int> updateReview(MovieReview review) async {
final db = await _dbHelper.database;
return await db.update(
'movie_reviews',
review.toJson(),
where: 'id = ?',
whereArgs: [review.id],
);
}
/// 软删除影评
Future<int> deleteReview(String id) async {
final db = await _dbHelper.database;
return await db.update(
'movie_reviews',
{'is_deleted': 1},
where: 'id = ?',
whereArgs: [id],
);
}
/// 获取影视的影评数量
Future<int> getReviewCount(String movieId) async {
final db = await _dbHelper.database;
final result = await db.rawQuery(
'SELECT COUNT(*) as count FROM movie_reviews WHERE movie_id = ? AND is_deleted = 0',
[movieId],
);
return result.first['count'] as int;
}
/// 获取短评列表
Future<List<MovieReview>> getShortReviews(String movieId) async {
final db = await _dbHelper.database;
final List<Map<String, dynamic>> maps = await db.query(
'movie_reviews',
where: 'movie_id = ? AND review_type = 1 AND is_deleted = 0',
whereArgs: [movieId],
orderBy: 'created_at DESC',
);
return List.generate(maps.length, (i) => MovieReview.fromJson(maps[i]));
}
/// 获取长评列表
Future<List<MovieReview>> getLongReviews(String movieId) async {
final db = await _dbHelper.database;
final List<Map<String, dynamic>> maps = await db.query(
'movie_reviews',
where: 'movie_id = ? AND review_type = 2 AND is_deleted = 0',
whereArgs: [movieId],
orderBy: 'created_at DESC',
);
return List.generate(maps.length, (i) => MovieReview.fromJson(maps[i]));
}
}

View File

@@ -24,11 +24,11 @@ class UserPrefs {
// ========== 用户信息 ==========
/// 昵称
String get nickname => prefs.getString('nickname') ?? '记录者';
String get nickname => prefs.getString('nickname') ?? 'Mook';
Future<bool> setNickname(String value) => prefs.setString('nickname', value);
/// 座右铭
String get motto => prefs.getString('motto') ?? '记录生活,沉淀思考';
String get motto => prefs.getString('motto') ?? '好运不会眷顾一无所有之人。';
Future<bool> setMotto(String value) => prefs.setString('motto', value);
/// 头像路径