- Schema v8:events / movie_details / event_attendees / event_photos 四张表, uk_event_source(family_id, source_ref) 作迁移幂等锚 - Movie 模型:时间线/详情/增删改、同行人整组替换、照片逐张管理、感受英→中映射 - ImageSlot 新增 poster(2:3) / ticket(free) / photo(free) 三槽位; free 槽位不裁剪、整图等比缩进框(只缩不放大) - OssDriver::copyObject:同桶 CopyObject(手写 V1 签名,x-oss-* 头按字典序进签名串) - 路由:movies 时间线/详情/新增/编辑/删除/补照片/删照片;同行人按家庭过滤; 访客只读(requireWrite) - UI 撤除:首页「我的一句话」、家谱页「补充我的亲属关系 / 看整个名册」两个按钮; 顶栏加「观影」入口 - 修潜伏 bug:ImageSlot::parseRatio 的正则用 / 作分隔符,字符类里的 / 把模式 提前截断(Unknown modifier ']')—— ratio() 只在上传 POST 里被调到,一直没被观察到 - 线上数据迁移(临时 token 门禁页,用完即删):MovieLog 219 条观影 → events, 14 位观影人新增进名册(带 MovieLog 头像),431 个 OSS 对象同桶拷贝 (movielog/uploads/<dir>/x → family/<dir>/x),review/feelings/影院三段/照片全量搬
62 lines
2.5 KiB
PHP
62 lines
2.5 KiB
PHP
<?php
|
||
/**
|
||
* 观影时间线 —— 按年分组倒序(v8,MovieLog 迁入后的新家)。
|
||
*
|
||
* 没填日期的记录落在键 0,沉到最底下单独一组「日期待补」,
|
||
* 不让它混进任何一个年份里(跟名册「未分类」栏是同一个思路)。
|
||
*/
|
||
$canWrite = \App\Auth::canWrite();
|
||
?>
|
||
<div class="page-head">
|
||
<h1>观影记录</h1>
|
||
<span class="sub">一共 <?= (int)$total ?> 场</span>
|
||
<div class="actions">
|
||
<?php if ($canWrite): ?>
|
||
<a class="btn" href="<?= e(url('movies/new')) ?>">记一场电影</a>
|
||
<?php endif; ?>
|
||
</div>
|
||
</div>
|
||
|
||
<?php if ($total === 0): ?>
|
||
<div class="card card-pad empty">
|
||
<b>还没有观影记录</b>
|
||
一家人一起看过的电影,都会按年份排在这里。
|
||
</div>
|
||
<?php else: ?>
|
||
<?php foreach ($years as $y => $list): ?>
|
||
<section class="section">
|
||
<h2 class="section-title"><?= $y > 0 ? (int)$y : '日期待补' ?> <span class="hint"><?= count($list) ?> 场</span></h2>
|
||
<div class="movie-list">
|
||
<?php foreach ($list as $mv): ?>
|
||
<?php
|
||
// 评分统一一位小数内显示:9 → "9",8.5 → "8.5"(库里是 0-10 整数,这里只做展示兜底)
|
||
$rtTxt = $mv['rating'] !== null
|
||
? rtrim(rtrim(number_format((float)$mv['rating'], 1, '.', ''), '0'), '.')
|
||
: '';
|
||
?>
|
||
<a class="movie-card" href="<?= e(url('movies/show', ['id' => (int)$mv['id']])) ?>">
|
||
<?php if (!empty($mv['poster_key'])): ?>
|
||
<img class="m-poster" src="<?= e(media_url($mv['poster_key'])) ?>" alt="" loading="lazy">
|
||
<?php else: ?>
|
||
<span class="m-poster m-poster-empty" aria-hidden="true">影</span>
|
||
<?php endif; ?>
|
||
<span class="m-main">
|
||
<span class="m-title">
|
||
<?= e($mv['title']) ?>
|
||
<?php if ($rtTxt !== ''): ?><span class="rating"><?= e($rtTxt) ?></span><?php endif; ?>
|
||
</span>
|
||
<span class="m-meta">
|
||
<?= e((string)($mv['starts_at'] ?? '日期待补')) ?>
|
||
<?php if (!empty($mv['cinema_name'])): ?> · <?= e($mv['cinema_name']) ?><?php endif; ?>
|
||
</span>
|
||
<?php if (!empty($mv['attendee_names'])): ?>
|
||
<span class="m-who">和 <?= e($mv['attendee_names']) ?></span>
|
||
<?php endif; ?>
|
||
</span>
|
||
</a>
|
||
<?php endforeach; ?>
|
||
</div>
|
||
</section>
|
||
<?php endforeach; ?>
|
||
<?php endif; ?>
|