Files
laoyang 746f02581e v9: 观影对齐 MovieLog —— 瀑布流/影院管理/评价评论/起止时间
- events 起止时间精确到秒(starts_at DATE→DATETIME + ends_at),_datetime.php 复用
- 影院独立成表(cinemas,地方/名称/地址/主题色 + 50 色板),movie_details 归一为 cinema_id
- 评价模型 MovieLog 同款:movie_reviews 每账号每片一条(1-10 分+正文+感受 key),
  movie_review_comments 两级平铺评论(回复的回复规范化到顶层、跨评价回复拦截)
- 感受目录迁到 MovieReview::CATALOG(12 种,Emoji 11.0 老码位)
- 观影列表改瀑布流(CSS grid 海报墙),详情页五大块 + 灯箱 + 评价区
- 升级路径:v8 老数据自动归一(影院三段按 (family,place,name) 去重建行、
  评价回填、中文感受反查英文 key),回填全部幂等;老库补 cinema_id 列+索引+外键
- 修三 bug:建表顺序(cinemas 必须在 movie_details 前,否则全新安装 1215)、
  layout 导航用键名当路由(影院链接指向 r=cinemas)、
  _datetime.php 分钟循环变量 $m 覆盖宿主模板的观影记录(编辑页简介/备注回填被清空)
2026-10-01 00:12:04 +08:00

111 lines
4.4 KiB
PHP
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.
<?php
/**
* 影院(v9,MovieLog 同款独立管理):所在地方 / 名称 / 详细地址 / 主题色。
*
* 观影记录通过 movie_details.cinema_id 关联(外键 ON DELETE SET NULL:
* 删影院不停掉历史记录,只是它们的影院信息置空 —— 与 MovieLog 行为一致)。
* 去重键 (family_id, place, name):同一家影院不会存两份。
*/
declare(strict_types=1);
namespace App;
final class Cinema
{
/** 50 色预设板(MovieLog cinemas.php 同一套) */
public const PRESET_COLORS = [
'#e74c3c', '#c0392b', '#e67e22', '#d35400', '#f39c12',
'#f1c40f', '#f7dc6f', '#f5b041', '#f4d03f', '#f9e79f',
'#f8c471', '#2ecc71', '#27ae60', '#1abc9c', '#16a085',
'#58d68d', '#48c9b0', '#45b39d', '#82e0aa', '#a3e4d7',
'#3498db', '#2980b9', '#2e86c1', '#5dade2', '#85c1e9',
'#5499c7', '#aed6f1', '#9b59b6', '#8e44ad', '#af7ac5',
'#bb8fce', '#d2b4de', '#e84393', '#fd79a8', '#e91e63',
'#f06292', '#95a5a6', '#7f8c8d', '#bdc3c7', '#d5dbdb',
'#aab7b8', '#99a3a4', '#a67c52', '#8d6e63', '#d4a574',
'#c9a87c', '#00b894', '#0984e3', '#6c5ce7', '#fd79a8',
];
/** @return array<int,array> 按地方、名称排序的全部影院 */
public static function all(int $familyId): array
{
$st = Database::get()->prepare(
'SELECT c.*, (SELECT COUNT(*) FROM movie_details d WHERE d.cinema_id = c.id) AS movie_count
FROM cinemas c WHERE c.family_id = ? ORDER BY c.place, c.name'
);
$st->execute([$familyId]);
return $st->fetchAll();
}
public static function find(int $familyId, int $id): ?array
{
$st = Database::get()->prepare(
'SELECT * FROM cinemas WHERE id = ? AND family_id = ?'
);
$st->execute([$id, $familyId]);
return $st->fetch() ?: null;
}
/**
* 新建/更新影院。$place/$name/$address 已由调用方裁剪;
* 返回 ''(成功)或错误文案。同名(含同地方)判重靠 uk_cinema。
*/
public static function save(int $familyId, int $id, string $place, string $name,
?string $address, string $color): string
{
if ($name === '') {
return '影院名称不能为空';
}
if (mb_strlen($name, 'UTF-8') > 100) {
return '影院名称太长了';
}
$place = mb_substr($place, 0, 100, 'UTF-8');
$address = $address !== null ? mb_substr($address, 0, 200, 'UTF-8') : null;
$db = Database::get();
if ($id > 0) {
$st = $db->prepare(
'SELECT COUNT(*) FROM cinemas
WHERE family_id = ? AND place = ? AND name = ? AND id <> ?'
);
$st->execute([$familyId, $place, $name, $id]);
if ((int)$st->fetchColumn() > 0) {
return '已经有同地方同名的影院了';
}
$db->prepare('UPDATE cinemas SET place = ?, name = ?, address = ?, color = ? WHERE id = ? AND family_id = ?')
->execute([$place, $name, $address, $color, $id, $familyId]);
} else {
$st = $db->prepare(
'SELECT COUNT(*) FROM cinemas WHERE family_id = ? AND place = ? AND name = ?'
);
$st->execute([$familyId, $place, $name]);
if ((int)$st->fetchColumn() > 0) {
return '已经有同地方同名的影院了';
}
$db->prepare('INSERT INTO cinemas (family_id, place, name, address, color) VALUES (?, ?, ?, ?, ?)')
->execute([$familyId, $place, $name, $address, $color]);
}
return '';
}
/** 删除影院;关联的观影记录 cinema_id 置空(外键级联),历史记录本身保留 */
public static function destroy(int $familyId, int $id): void
{
Database::get()->prepare('DELETE FROM cinemas WHERE id = ? AND family_id = ?')
->execute([$id, $familyId]);
}
/** 把表单提交的颜色规范化成 #rrggbb(非法值回默认灰) */
public static function normalizeColor(string $raw): string
{
$raw = trim($raw);
if (preg_match('/^#([0-9a-fA-F]{6})$/', $raw, $m)) {
return '#' . strtolower($m[1]);
}
if (preg_match('/^([0-9a-fA-F]{6})$/', $raw, $m)) {
return '#' . strtolower($m[1]);
}
return '#888888';
}
}