取消「票根」概念,并入观影照片(数据迁移 220 条)(#87)
用户:现在不是已经没有票根的概念了吗?全部都换成观影照片了。别管是票根 还是观影照片,都在一起。现在只分两类:一类是海报,一类是观影照片。 海报是来自豆瓣的,这个不用管它,主要就是观影照片,所有的都在观影照片里边。 事实核查:概念取消了,数据没取消。网页端 v35 只在**模板层**把它们画进 同一个网格,数据层仍是两条路:票根在 movie_details.ticket_key(单张槽位), 不在 event_photos 里 ⇒ 没有 id ⇒ 删不掉,端上得写"票根另算"特判。 线上数据:有票根 220 条,其中 209 条只有票根、没有任何照片; event_photos 总数才 14 —— 也就是说「观影照片」里装的几乎全是票根。 ① 数据迁移(已执行,220/220 成功,失败 0): 逐条把 ticket_key 插进 event_photos(position 取比现有最小值再小 10, ⇒ 排第一,因为票根是"这场电影的凭证",用户认知里排最前),然后置 NULL。 event_photos 14 → 234,旧票根残留 0。 ⚠️ 幂等:靠"该 key 已在该 event 的 event_photos 里"判断,重复跑不插重复行; ⚠️ 不删存储对象:只搬引用,图片原地不动,失败也不丢图。 ② 同一段逻辑写进 Schema VERSION 36→37,让新库/重装库走同一套, 不靠"记得手工跑脚本"。对线上是空操作(已验证 234→234)。 ③ 服务端停止读写票根字段(字段保留作历史审计,代码不再碰): - Movie::find 不再 SELECT ticket_key; - Movie::saveDetails UPSERT 去掉 ticket_key; - Movie::destroy 不再单独查/删票根对象(已并入 photos 循环); - index.php:上传槽位 [poster,ticket] → [poster], stage_ticket 不再认领,media_del 白名单只剩 poster; - form.php:删票根特殊格子 + mv-del-ticket 表单 + $mHasTicket; - show.php:删票根格子 + 灯箱 ticket 项 + $hasTicket。 验证:find(1,1)/find(1,224) 已不返回 ticket_key,photos 3/4 条票根在首位; 直接 include 模板无 Fatal,form.php 里 mv-del-ticket / stage_ticket 各 0 次; 6 个文件 md5 逐个核对一致、php -l 全过、已上线且升级到 37。
This commit is contained in:
+21
-10
@@ -95,8 +95,12 @@ final class Movie
|
||||
/** 一条完整记录(详情/编辑页用):事件 + 卫星 + 影院 + 同行人 + 照片 */
|
||||
public static function find(int $familyId, int $id, int $viewerId = 0): ?array
|
||||
{
|
||||
/* 🔴 2026-11-06:**不再 SELECT `ticket_key`**。
|
||||
用户要求"只分两类:海报、观影照片",旧票根已经一次性迁进
|
||||
`event_photos`(见迁移脚本与 Schema VERSION 37 的说明),
|
||||
字段本身也置 NULL 了。继续查它出来只会让上层又长出第三个概念。 */
|
||||
$st = Database::get()->prepare(
|
||||
'SELECT e.*, d.info, d.poster_key, d.ticket_key, d.cinema_id, d.douban_meta,
|
||||
'SELECT e.*, d.info, d.poster_key, d.cinema_id, d.douban_meta,
|
||||
c.place AS cinema_place, c.name AS cinema_name,
|
||||
c.address AS cinema_address, c.color AS cinema_color
|
||||
FROM events e
|
||||
@@ -151,7 +155,8 @@ final class Movie
|
||||
/**
|
||||
* 新建一条观影记录,返回事件 id。
|
||||
* $d 字段:title, starts_at(Y-m-d H:i:s), ends_at, location, note, info,
|
||||
* cinema_id(int|null), poster_key, ticket_key, attendees(int[]), photos(string[])
|
||||
* cinema_id(int|null), poster_key, attendees(int[]), photos(string[])
|
||||
* ⚠️ 2026-11-06:`ticket_key` 已取消(票根并入 photos)。
|
||||
*/
|
||||
public static function create(int $familyId, ?int $creatorId, array $d): int
|
||||
{
|
||||
@@ -211,17 +216,20 @@ final class Movie
|
||||
$row = [
|
||||
self::textOrNull($d['info'] ?? ''),
|
||||
self::keyOrNull($d['poster_key'] ?? ''),
|
||||
self::keyOrNull($d['ticket_key'] ?? ''),
|
||||
$cid > 0 ? $cid : null,
|
||||
$meta,
|
||||
];
|
||||
$has = $db->prepare('SELECT COUNT(*) FROM movie_details WHERE event_id = ?');
|
||||
$has->execute([$eventId]);
|
||||
/* 🔴 2026-11-06:`ticket_key` 从这条 UPSERT 里**移除**了。
|
||||
票根概念已取消(迁进 `event_photos`),再写它等于把它复活。
|
||||
⚠️ 列还留在表里(不清字段,留作历史审计),但代码不再碰它;
|
||||
迁移已把存量置 NULL,所以它现在是全 NULL 的死列。 */
|
||||
if ((int)$has->fetchColumn() > 0) {
|
||||
$db->prepare('UPDATE movie_details SET info=?, poster_key=?, ticket_key=?, cinema_id=?, douban_meta=? WHERE event_id=?')
|
||||
$db->prepare('UPDATE movie_details SET info=?, poster_key=?, cinema_id=?, douban_meta=? WHERE event_id=?')
|
||||
->execute([...$row, $eventId]);
|
||||
} else {
|
||||
$db->prepare('INSERT INTO movie_details (info, poster_key, ticket_key, cinema_id, douban_meta, event_id) VALUES (?,?,?,?,?,?)')
|
||||
$db->prepare('INSERT INTO movie_details (info, poster_key, cinema_id, douban_meta, event_id) VALUES (?,?,?,?,?)')
|
||||
->execute([...$row, $eventId]);
|
||||
}
|
||||
}
|
||||
@@ -386,15 +394,18 @@ final class Movie
|
||||
$keys[] = $tk;
|
||||
}
|
||||
}
|
||||
/* 🔴 2026-11-06:票根已并入 `event_photos`,上面的 photos() 循环就把
|
||||
它收集进来了 —— 原来这里还要单独查一次 `ticket_key` 并删对象,
|
||||
现在**不需要且不该要**(字段已置 NULL,查出来也是空)。
|
||||
⚠️ 海报仍单独存在 `movie_details.poster_key`,所以要留这一段。 */
|
||||
$st = Database::get()->prepare(
|
||||
'SELECT poster_key, ticket_key FROM movie_details WHERE event_id = ?'
|
||||
'SELECT poster_key FROM movie_details WHERE event_id = ?'
|
||||
);
|
||||
$st->execute([$id]);
|
||||
if ($row = $st->fetch()) {
|
||||
foreach ([$row['poster_key'], $row['ticket_key']] as $k) {
|
||||
if ($k) {
|
||||
$keys[] = (string)$k;
|
||||
}
|
||||
$k = (string)($row['poster_key'] ?? '');
|
||||
if ($k !== '') {
|
||||
$keys[] = $k;
|
||||
}
|
||||
}
|
||||
Database::get()->prepare('DELETE FROM events WHERE id = ? AND family_id = ? AND kind = "movie"')
|
||||
|
||||
+52
-1
@@ -188,7 +188,7 @@ final class Schema
|
||||
* ⚠️ 它**不再**作为"要不要跑升级"的判据 —— 见 fingerprint() 的说明。
|
||||
* 它仍然要手工维护,因为它给人看(排查时一眼知道代码到哪一版了)。
|
||||
*/
|
||||
public const VERSION = '36';
|
||||
public const VERSION = '37';
|
||||
|
||||
/**
|
||||
* 「源码指纹」:拿**本文件自身的内容**算一个哈希,作为"要不要跑升级"的判据。
|
||||
@@ -1887,6 +1887,57 @@ SQL);
|
||||
self::addColumn($db, 'event_photos', 'mime',
|
||||
"ADD COLUMN `mime` VARCHAR(100) DEFAULT NULL COMMENT 'MIME(视频转码后是 video/mp4;图片可空)' AFTER `thumb_key`");
|
||||
|
||||
// ---- 「票根」概念取消,并入观影照片(版本 37,2026-11-06)----
|
||||
/* 🔴 用户原话:「现在不是已经没有票根的概念了吗?全部都换成观影照片了。
|
||||
别管是票根还是观影照片,都在一起。现在只分两类:一类是海报,
|
||||
一类是观影照片。海报是来自豆瓣的,这个不用管它,主要就是观影照片,
|
||||
所有的都在观影照片里边。」
|
||||
|
||||
背景:早年「票根」是 `movie_details.ticket_key` 的**单张**槽位,
|
||||
和 `event_photos`(现场照片)是两条并行的路径。v35 用户在网页端就说过
|
||||
"不分类别,放一块",但当时只在**模板层**把它画进同一个网格,
|
||||
数据层仍然两条路 —— 结果是端上永远得写"票根另算"的特判,
|
||||
而且票根没有 `event_photos` 行 id,**删不掉**。
|
||||
|
||||
这一版把数据也统一:
|
||||
① 把每条记录的 `ticket_key` 插进 `event_photos`(position 排最前,
|
||||
因为票根是"这场电影的凭证",用户认知里它排第一);
|
||||
② `ticket_key` 置 NULL(字段保留,仅作历史审计,代码不再读写)。
|
||||
|
||||
⚠️ **幂等**:靠"该 key 是否已在该 event 的 event_photos 里"判断,
|
||||
重复跑不会插重复行 —— 迁移在每次升级检查时都可能被调到。
|
||||
⚠️ **不删存储对象**:只是搬引用,文件原地不动,失败也不会丢图。
|
||||
⚠️ 2026-11-06 线上已手工跑过同一段逻辑(220 条全部搬完,
|
||||
复核剩余旧票根=0、event_photos 234 条),所以这里对老库是空操作;
|
||||
写进来是为了让**新库/重装库**走同一套,不靠"记得手工跑脚本"。 */
|
||||
$tkRows = $db->query(
|
||||
"SELECT event_id, ticket_key FROM movie_details
|
||||
WHERE ticket_key IS NOT NULL AND ticket_key <> ''"
|
||||
)->fetchAll();
|
||||
if (count($tkRows) > 0) {
|
||||
$hasPhoto = $db->prepare('SELECT COUNT(*) FROM event_photos WHERE event_id = ? AND `key` = ?');
|
||||
$minPos = $db->prepare('SELECT COALESCE(MIN(position), 100) FROM event_photos WHERE event_id = ?');
|
||||
$insPhoto = $db->prepare(
|
||||
'INSERT INTO event_photos (event_id, `key`, position, kind, thumb_key, mime)
|
||||
VALUES (?, ?, ?, ?, ?, ?)'
|
||||
);
|
||||
foreach ($tkRows as $tk) {
|
||||
$eid = (int)$tk['event_id'];
|
||||
$key = (string)$tk['ticket_key'];
|
||||
$hasPhoto->execute([$eid, $key]);
|
||||
if ((int)$hasPhoto->fetchColumn() > 0) {
|
||||
continue;
|
||||
}
|
||||
$minPos->execute([$eid]);
|
||||
$pos = max(0, (int)$minPos->fetchColumn() - 10);
|
||||
$insPhoto->execute([$eid, $key, $pos, 'image', '', 'image/jpeg']);
|
||||
}
|
||||
/* 搬完清空旧槽位 —— 「只分两类」必须在数据层成立,
|
||||
否则下一版又会有人写"票根另算"的特判。 */
|
||||
$db->exec("UPDATE movie_details SET ticket_key = NULL
|
||||
WHERE ticket_key IS NOT NULL AND ticket_key <> ''");
|
||||
}
|
||||
|
||||
// ---- 纪念日(版本 13,用户第 13 条)----
|
||||
// ⚠️ 名册里每个人的生日**不入这张表** —— 它们是实时从 persons 派生的
|
||||
// (见 Anniversary::birthdays),改了生日纪念日就跟着变。
|
||||
|
||||
@@ -3536,7 +3536,11 @@ switch ($r) {
|
||||
// 存不进去,看起来像功能坏了)。现在是先存记录,图片的事单独提示。
|
||||
// 海报 / 票根:free 槽位,不需要裁剪框;编辑时换新图就顺带删掉旧对象。
|
||||
$warns = [];
|
||||
foreach (['poster', 'ticket'] as $slot) {
|
||||
/* 🔴 2026-11-06:只处理 `poster`。票根槽位取消 —— 静态票根已并入
|
||||
`event_photos`,新的照片统一走「观影照片」那条多选通道。
|
||||
⚠️ 别再把它加回这个数组:加了就会往 `ticket_key` 死列里写,
|
||||
而那些图永远不会出现在「观影照片」里(看着像上传丢了)。 */
|
||||
foreach (['poster'] as $slot) {
|
||||
$up = Upload::image($familyId, $_FILES[$slot] ?? [], $slot);
|
||||
if ($up['ok']) {
|
||||
$oldKey = $isEdit ? (string)($m[$slot === 'poster' ? 'poster_key' : 'ticket_key'] ?? '') : '';
|
||||
@@ -3641,17 +3645,19 @@ switch ($r) {
|
||||
$d['photos'] = $photoKeys;
|
||||
}
|
||||
|
||||
/* ---- v24 第 20 批 第 4 条:拖动**即时上传**的海报 / 票根 ----
|
||||
/* ---- v24 第 20 批 第 4 条:拖动**即时上传**的海报 ----
|
||||
用户原话:「拖动一个进去,就开始上传…最后统一保存即可。」
|
||||
拖动会上传到暂存区并回一个 stoken,前端放进隐藏字段 `stage_poster` /
|
||||
`stage_ticket`(**海报/票根各一个字段名**,因为它们要区分槽位)。
|
||||
拖动会上传到暂存区并回一个 stoken,前端放进隐藏字段 `stage_poster`。
|
||||
🔴 2026-11-06:**票根那条取消了**(`stage_ticket` 不再认领)。
|
||||
票根概念并入「观影照片」,新图一律走通用那组 `stage_token[]`
|
||||
(多选、可多次拖),与现场照片同一条管道。
|
||||
⚠️ 这里直接取 stoken 对应的暂存文件来重跑 Upload::image(按该槽位的比例),
|
||||
而不是把暂存文件原样搬过去 —— 海报是 2:3、票根是 free,
|
||||
而不是把暂存文件原样搬过去 —— 海报是 2:3,
|
||||
不按槽位处理就会存成比例不对的图(页面上会变形)。
|
||||
⚠️ 临时文件上传(`$_FILES[$slot]`)优先:用户**又选又拖**时以"选"的为准
|
||||
(那是他更明确的动作),免得两个来源打架。
|
||||
⚠️ 认领失败要记进 $warns(不静默丢),且**不影响保存**(与既有口径一致)。 */
|
||||
foreach (['poster' => 'stage_poster', 'ticket' => 'stage_ticket'] as $slotKey => $fieldName) {
|
||||
foreach (['poster' => 'stage_poster'] as $slotKey => $fieldName) {
|
||||
if (!empty($_FILES[$slotKey]) && (int)($_FILES[$slotKey]['error'] ?? 4) === UPLOAD_ERR_OK) {
|
||||
continue; // 选了新文件 → 上面的常规路径已经处理过了
|
||||
}
|
||||
@@ -3846,8 +3852,11 @@ switch ($r) {
|
||||
flash('err', '找不到这条观影记录。');
|
||||
redirect('movies');
|
||||
}
|
||||
// 白名单:只认这两个槽位(表单可以被改,不能凭它去删别的字段/别的对象)
|
||||
$col = ['poster' => 'poster_key', 'ticket' => 'ticket_key'][$slot] ?? '';
|
||||
/* 白名单:只认 `poster` 这一个槽位。
|
||||
🔴 2026-11-06:`ticket` 取消了 —— 票根已并入 `event_photos`,
|
||||
要删它走 `movies/photo_del`(按 photo_id 删,与其它照片同一条路)。
|
||||
⚠️ 表单能被改,所以白名单必须留着,不能凭它去删别的字段/别的对象。 */
|
||||
$col = ['poster' => 'poster_key'][$slot] ?? '';
|
||||
if ($col === '') {
|
||||
flash('err', '不知道要删哪一样。');
|
||||
redirect('movies/edit', ['id' => $id]);
|
||||
@@ -3858,7 +3867,7 @@ switch ($r) {
|
||||
if ($old !== '') {
|
||||
\App\Storage\Storage::delete($familyId, $old);
|
||||
}
|
||||
flash('ok', ($slot === 'poster' ? '海报' : '票根') . '已删除。');
|
||||
flash('ok', '海报已删除。');
|
||||
redirect('movies/edit', ['id' => $id]);
|
||||
break;
|
||||
|
||||
|
||||
+11
-23
@@ -289,7 +289,8 @@ $fbAdd = !empty($fbAddModalAttr);
|
||||
* 按钮留在原位、用 HTML5 的 `form="id"` 关联到外面那个表单。
|
||||
*/
|
||||
$mHasPoster = $isEdit && !empty($m['poster_key']);
|
||||
$mHasTicket = $isEdit && !empty($m['ticket_key']);
|
||||
/* 🔴 2026-11-06:`$mHasTicket` 取消。票根概念已并入「观影照片」,
|
||||
旧字段迁完置 NULL,页面不再有第三个分类。 */
|
||||
$mPhotos = $isEdit ? (array)($m['photos'] ?? []) : [];
|
||||
$mDelForms = []; // 收集起来,在表单**外面**统一渲染
|
||||
?>
|
||||
@@ -355,21 +356,13 @@ $mDelForms = []; // 收集起来,在表单**外面**统一渲染
|
||||
<div class="mv-row mv-row-media">
|
||||
<span class="mv-lb no-colon">观影照片</span>
|
||||
<div class="mv-media-body">
|
||||
<?php if ($mHasTicket || $mPhotos): ?>
|
||||
<?php if ($mPhotos): ?>
|
||||
<div class="photo-grid">
|
||||
<?php if ($mHasTicket): /* 历史数据:旧票根(不在 event_photos 里,只展示) */ ?>
|
||||
<?php $mDelForms['ticket'] = 'movies/media_del'; ?>
|
||||
<figure class="photo-cell">
|
||||
<a href="<?= e(media_url((string)$m['ticket_key'])) ?>" data-prev="image"
|
||||
data-src="<?= e(media_url((string)$m['ticket_key'])) ?>"
|
||||
data-dl="<?= e(media_url((string)$m['ticket_key'], ['dl' => 1])) ?>"
|
||||
data-name="票根">
|
||||
<img src="<?= e(media_url((string)$m['ticket_key'])) ?>" alt="票根">
|
||||
</a>
|
||||
<button class="btn btn-ghost btn-sm" type="submit" form="mv-del-ticket"
|
||||
onclick="return confirm('删掉这张旧票根?')">删除</button>
|
||||
</figure>
|
||||
<?php endif; ?>
|
||||
<?php /* 🔴 2026-11-06:**票根那个特殊格子删掉了**。用户要求只分两类
|
||||
(海报 / 观影照片),旧票根已经一次性迁进 `event_photos`
|
||||
(220 条,position 排最前),现在它就是下面 foreach 里的
|
||||
一条普通照片 —— 有 id、能删、能拖进灯箱。
|
||||
⚠️ 别再把它加回来。留着就等于承认还有第三类。 */ ?>
|
||||
<?php foreach ($mPhotos as $mp): $mpId = (int)$mp['id']; ?>
|
||||
<figure class="photo-cell">
|
||||
<a href="<?= e(media_url((string)$mp['key'])) ?>" data-prev="image"
|
||||
@@ -450,13 +443,8 @@ $mDelForms = []; // 收集起来,在表单**外面**统一渲染
|
||||
<input type="hidden" name="slot" value="poster">
|
||||
</form>
|
||||
<?php endif; ?>
|
||||
<?php if ($mHasTicket): ?>
|
||||
<form id="mv-del-ticket" method="post" action="<?= e(url('movies/media_del')) ?>" class="form-outside">
|
||||
<?= csrf_field() ?>
|
||||
<input type="hidden" name="id" value="<?= (int)$m['id'] ?>">
|
||||
<input type="hidden" name="slot" value="ticket">
|
||||
</form>
|
||||
<?php endif; ?>
|
||||
<?php /* 🔴 2026-11-06:`mv-del-ticket` 这个表单删掉了 —— 票根已并入
|
||||
`event_photos`,走下面那条按 photo_id 删的通用表单。 */ ?>
|
||||
<?php foreach ($mPhotos as $mp): ?>
|
||||
<form id="mv-del-photo-<?= (int)$mp['id'] ?>" method="post"
|
||||
action="<?= e(url('movies/photo_del')) ?>" class="form-outside">
|
||||
@@ -467,7 +455,7 @@ $mDelForms = []; // 收集起来,在表单**外面**统一渲染
|
||||
<input type="hidden" name="back" value="edit">
|
||||
</form>
|
||||
<?php endforeach; ?>
|
||||
<?php unset($mHasPoster, $mHasTicket, $mPhotos, $mDelForms, $mp, $mpId); ?>
|
||||
<?php unset($mHasPoster, $mPhotos, $mDelForms, $mp, $mpId); ?>
|
||||
|
||||
<?php /* ---- 新建影院:弹框(不跳转,见上)---- */ ?>
|
||||
<div class="cn-modal" id="cinemaNewModal" hidden>
|
||||
|
||||
+16
-28
@@ -3,13 +3,14 @@
|
||||
* 观影详情页(v9,展示方式照搬 MovieLog 的 detail.php)。
|
||||
*
|
||||
* 五大块:英雄区(左海报右信息)→ 一起看的人 → 电影院信息 → 观影照片(灯箱)→ 评价与评论。
|
||||
* 海报/票根/照片一律走 media_url() 代理;感受标签只存 key,emoji 与文案查 CATALOG。
|
||||
* 海报/观影照片一律走 media_url() 代理;感受标签只存 key,emoji 与文案查 CATALOG。
|
||||
* 访客(只读)看不到编辑/删除/传照片/评价表单 —— 与名册同一口径。
|
||||
* 评价人是「登录账号背后的人」,与同行观影人无关(MovieLog 同款规则)。
|
||||
*/
|
||||
$canWrite = \App\Auth::canWrite();
|
||||
$hasPoster = !empty($m['poster_key']);
|
||||
$hasTicket = !empty($m['ticket_key']);
|
||||
/* 🔴 2026-11-06:`$hasTicket` 取消 —— 票根已并入 `event_photos`,
|
||||
只分「海报 / 观影照片」两类。 */
|
||||
// 豆瓣元数据(v10):整体 JSON 存 douban_meta,随用随解;解不开就当没有
|
||||
$doubanMeta = [];
|
||||
if (!empty($m['douban_meta'])) {
|
||||
@@ -160,7 +161,7 @@ $commentBox = static function (int $reviewId, int $parentId, string $summary) us
|
||||
<button class="btn" type="button" id="mvEditBtn" aria-haspopup="dialog" aria-expanded="false"
|
||||
data-href="<?= e(url('movies/edit', ['id' => (int)$m['id']])) ?>">编辑</button>
|
||||
<form method="post" action="<?= e(url('movies/destroy')) ?>"
|
||||
onsubmit="return confirm('删除这条观影记录?海报、票根、照片也会一并删除,不可恢复。')">
|
||||
onsubmit="return confirm('删除这条观影记录?海报、观影照片也会一并删除,不可恢复。')">
|
||||
<?= csrf_field() ?>
|
||||
<input type="hidden" name="id" value="<?= (int)$m['id'] ?>">
|
||||
<button type="submit" class="btn btn-del">删除</button>
|
||||
@@ -258,30 +259,19 @@ $commentBox = static function (int $reviewId, int $parentId, string $summary) us
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
<!-- 观影照片(v35:票根 + 现场照片 + 其它相关图片,**不再分类**,合成一块) -->
|
||||
<?php if ($hasTicket || $m['photos']): ?>
|
||||
<!-- 观影照片(v38:**只此一类**,票根已并入 event_photos) -->
|
||||
<?php if ($m['photos']): ?>
|
||||
<div class="detail-section">
|
||||
<h3>观影照片 <span class="badge"><?= count($m['photos']) + ($hasTicket ? 1 : 0) ?> 张</span></h3>
|
||||
<h3>观影照片 <span class="badge"><?= count($m['photos']) ?> 张</span></h3>
|
||||
<div class="gallery-grid">
|
||||
<?php /* ⚠️ 旧票根(movie_details.ticket_key)是历史数据,仍要能看到;
|
||||
归并后它跟 event_photos 里的照片**同一块展示、同一套灯箱**,
|
||||
但删除要走它自己的槽位表单(media_del)。 */ ?>
|
||||
<?php if ($hasTicket): $lbIdx = 1; ?>
|
||||
<div class="gallery-item lb-openable" data-lb-index="<?= $lbIdx ?>" role="button" tabindex="0" aria-label="放大查看" title="点击查看大图">
|
||||
<img src="<?= e(media_url($m['ticket_key'])) ?>" alt="" loading="lazy">
|
||||
<?php if ($canWrite): ?>
|
||||
<form method="post" action="<?= e(url('movies/media_del')) ?>"
|
||||
onsubmit="return confirm('删除这张照片?')">
|
||||
<?= csrf_field() ?>
|
||||
<input type="hidden" name="id" value="<?= (int)$m['id'] ?>">
|
||||
<input type="hidden" name="slot" value="ticket">
|
||||
<button type="submit" class="photo-del" title="删除这张照片">×</button>
|
||||
</form>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<?php /* 🔴 2026-11-06:**票根那个特殊格子删掉了**。用户要求只分两类
|
||||
(海报 / 观影照片);旧 `movie_details.ticket_key` 里的票根
|
||||
已经一次性迁进 `event_photos`(220 条,position 排最前),
|
||||
现在它就是下面 foreach 里的普通一张 —— 同一个灯箱、同一个删除路由。
|
||||
⚠️ 别再把它加回来,留着就等于承认还有第三类。
|
||||
⚠️ `$lbIdx` 也因此从 1 起直接算,不再需要 `+ ($hasTicket ? 2 : 1)`。 */ ?>
|
||||
<?php foreach ($m['photos'] as $i => $ph): ?>
|
||||
<div class="gallery-item lb-openable" data-lb-index="<?= $i + ($hasTicket ? 2 : 1) ?>" role="button" tabindex="0" aria-label="放大查看照片" title="点击查看大图">
|
||||
<div class="gallery-item lb-openable" data-lb-index="<?= $i + 1 ?>" role="button" tabindex="0" aria-label="放大查看照片" title="点击查看大图">
|
||||
<img src="<?= e(media_url((string)$ph['key'])) ?>" alt="" loading="lazy">
|
||||
<?php if ($canWrite): ?>
|
||||
<form method="post" action="<?= e(url('movies/photo_del')) ?>"
|
||||
@@ -434,7 +424,7 @@ $commentBox = static function (int $reviewId, int $parentId, string $summary) us
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
<?php if ($hasPoster || $hasTicket || $m['photos']): ?>
|
||||
<?php if ($hasPoster || $m['photos']): ?>
|
||||
<!-- 图片灯箱:点任意一张图在当前页弹出,可左右翻看 / Esc 关闭(MovieLog 同款) -->
|
||||
<div class="lightbox" id="lightbox" role="dialog" aria-modal="true" aria-hidden="true" aria-label="图片查看器">
|
||||
<?php /* v24 第 3 条:预览层右上角恒有下载按钮(与全局附件预览一个规矩) */ ?>
|
||||
@@ -454,9 +444,7 @@ $commentBox = static function (int $reviewId, int $parentId, string $summary) us
|
||||
<?php if ($hasPoster): ?>
|
||||
items.push({url: <?= json_encode(media_url((string)$m['poster_key']), JSON_UNESCAPED_UNICODE | JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX_APOS | JSON_HEX_QUOT) ?>, cap: <?= json_encode('海报 · ' . $m['title'], JSON_UNESCAPED_UNICODE | JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX_APOS | JSON_HEX_QUOT) ?>});
|
||||
<?php endif; ?>
|
||||
<?php if ($hasTicket): ?>
|
||||
items.push({url: <?= json_encode(media_url((string)$m['ticket_key']), JSON_UNESCAPED_UNICODE | JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX_APOS | JSON_HEX_QUOT) ?>, cap: <?= json_encode('观影照片 · ' . $m['title'], JSON_UNESCAPED_UNICODE | JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX_APOS | JSON_HEX_QUOT) ?>});
|
||||
<?php endif; ?>
|
||||
<?php /* 🔴 2026-11-06:票根那条 items.push 删掉了 —— 它已在 `$m['photos']` 里 */ ?>
|
||||
<?php foreach ($m['photos'] as $ph): ?>
|
||||
items.push({url: <?= json_encode(media_url((string)$ph['key']), JSON_UNESCAPED_UNICODE | JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX_APOS | JSON_HEX_QUOT) ?>, cap: <?= json_encode('观影照片 · ' . $m['title'], JSON_UNESCAPED_UNICODE | JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX_APOS | JSON_HEX_QUOT) ?>});
|
||||
<?php endforeach; ?>
|
||||
|
||||
Reference in New Issue
Block a user