评价本身也能填「观后感受」

- lib/db.php:reviews 表新增 feelings 列。建表语句里带上,同时补一条
  ALTER TABLE 迁移 —— 上一版已经上线过没有该列的 reviews 表,老库要能自动补列。
- lib/reviews.php:saveReview() 接收感受并落库;getMovieReviews()/getMyReview()
  把 feelings 解析成 key 列表(旧记录为 NULL → 空数组,不报错)。
- detail.php:评价表单加了「我看完的感受(可多选)」,与讨论用的是同一套感受;
  修改评价时原勾选自动回填,取消勾选即清空;已保存的感受在评价正文下方以只读标签展示。

感受仍然只存 key(happy/sad/…),emoji 与文案统一在 feelingCatalog() 里维护。
This commit is contained in:
2026-09-22 13:03:04 +08:00
parent a2c26ad002
commit dc5e788f27
4 changed files with 71 additions and 21 deletions
+4
View File
@@ -103,6 +103,7 @@ function initDB() {
// 电影评价表
// 评价人是「登录账号」(admins)——不是观影人(persons / viewers):
// 没一起去看的人只要有账号,也能打分、写评价并参与讨论。
// feelings:写评价时选的「观后感受」,与评论里的感受同一套目录、同一种存法。
$db->exec("
CREATE TABLE IF NOT EXISTS reviews (
id INTEGER PRIMARY KEY AUTOINCREMENT,
@@ -110,6 +111,7 @@ function initDB() {
admin_id INTEGER NOT NULL,
rating INTEGER NOT NULL,
content TEXT NOT NULL,
feelings TEXT,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (movie_id) REFERENCES movies(id) ON DELETE CASCADE,
@@ -146,6 +148,8 @@ function initDB() {
try { $db->exec("ALTER TABLE viewers ADD COLUMN person_id INTEGER REFERENCES persons(id) ON DELETE SET NULL"); } catch (PDOException $e) {}
// 新增:管理员关联观影人
try { $db->exec("ALTER TABLE admins ADD COLUMN person_id INTEGER REFERENCES persons(id) ON DELETE SET NULL"); } catch (PDOException $e) {}
// 新增:评价本身也可以带观后感受(评价表先于该字段上线过一版,故需要迁移)
try { $db->exec("ALTER TABLE reviews ADD COLUMN feelings TEXT"); } catch (PDOException $e) {}
// ===== 迁移旧数据 =====
// 将 viewers.name 迁移到 persons
+18 -7
View File
@@ -115,6 +115,11 @@ function getMovieReviews($movie_id) {
");
$stmt->execute([$movie_id]);
$reviews = $stmt->fetchAll();
foreach ($reviews as &$review) {
// 评价本身带的观后感受(JSON 字符串 → key 列表)
$review['feelings'] = parseStoredFeelings($review['feelings'] ?? '');
}
unset($review);
attachCommentsToReviews($reviews);
return $reviews;
}
@@ -155,6 +160,9 @@ function getMyReview($movie_id, $admin_id) {
$stmt = $db->prepare("SELECT * FROM reviews WHERE movie_id = ? AND admin_id = ?");
$stmt->execute([$movie_id, $admin_id]);
$row = $stmt->fetch();
if ($row) {
$row['feelings'] = parseStoredFeelings($row['feelings'] ?? '');
}
return $row ?: null;
}
@@ -213,13 +221,15 @@ function attachReviewStatsToMovies(array &$movies) {
/**
* 发表 / 修改评价。一个账号对一部电影只保留一条:已有则更新,没有则插入。
* $feelings 是评价人自己选的观后感受 key 数组(可以为空)。
* 调用前请自行校验 rating 在 1-10、content 非空且未超长。
* 成功返回 true。
*/
function saveReview($movie_id, $admin_id, $rating, $content) {
function saveReview($movie_id, $admin_id, $rating, $content, array $feelings = []) {
$db = getDB();
$rating = (int)$rating;
$content = trim((string)$content);
$rating = (int)$rating;
$content = trim((string)$content);
$feelings = normalizeFeelings($feelings);
if ($rating < 1 || $rating > 10 || $content === '' || (int)$admin_id <= 0) {
return false;
}
@@ -232,15 +242,16 @@ function saveReview($movie_id, $admin_id, $rating, $content) {
if ($existing) {
$stmt = $db->prepare("
UPDATE reviews SET rating = ?, content = ?, updated_at = CURRENT_TIMESTAMP
UPDATE reviews SET rating = ?, content = ?, feelings = ?, updated_at = CURRENT_TIMESTAMP
WHERE id = ?
");
$stmt->execute([$rating, $content, $existing['id']]);
$stmt->execute([$rating, $content, feelingsToJson($feelings), $existing['id']]);
} else {
$stmt = $db->prepare("
INSERT INTO reviews (movie_id, admin_id, rating, content) VALUES (?, ?, ?, ?)
INSERT INTO reviews (movie_id, admin_id, rating, content, feelings)
VALUES (?, ?, ?, ?, ?)
");
$stmt->execute([$movie_id, $admin_id, $rating, $content]);
$stmt->execute([$movie_id, $admin_id, $rating, $content, feelingsToJson($feelings)]);
}
$db->commit();
return true;