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 覆盖宿主模板的观影记录(编辑页简介/备注回填被清空)
This commit is contained in:
+110
@@ -0,0 +1,110 @@
|
||||
<?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';
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user