按地方、名称排序的全部影院 */ 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'; } }