laoyang
|
835f2846f2
|
取消「票根」概念,并入观影照片(数据迁移 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。
|
2026-11-06 11:25:47 +08:00 |
|
laoyang
|
c6e4191bb3
|
观影照片支持视频:转 H.264 + 抽首帧封面 (#84)
用户:确认一下观影照片是不是允许上传视频,如果不允许需要修改,
要求能上传视频、视频需要转码,参考旅程中的行程做法。
事实核查:原来不允许 —— POST /movies/<id>/photos 走 Upload::image(),
那条管线只收 JPG/PNG/GIF/WebP(要裁剪缩转运 JPEG),传视频直接拒。
旅程走 Attachment::save(),内部对 video/* 调 Video::toH264()。
Schema VERSION 35→36:
- event_photos 加 kind / thumb_key / mime 三列;
kind 默认 image —— 老数据全是照片,默认值即正确,不需要回填 UPDATE;
- 建表语句同步改(新库直接是新结构)。
Video.php:
- 新增 poster() 抽首帧。取第 1 秒(手机视频开头常是黑场/对焦),
宽 480 足够列表缩略;失败返回空 path 且**不阻断上传**。
ApiHandler.php 上传分支按 MIME 分流:
- 视频 → toH264 转码 + poster 抽封面 + Storage 落盘 videos/ 与 thumbs/;
转码失败不阻断(存原视频,至少能下载后用本地播放器看);
- 图片 → 仍走 Upload::image(),裁剪压缩行为完全不变。
- 返回值加了 kind / thumb / mime,端上靠它画播放按钮。
Movie.php:
- photos() 带出 kind/thumb_key/mime;
- addPhotos() 兼容裸键数组与结构化数组,只有一条 INSERT 路径;
- deletePhoto() / destroy() 补删 thumb_key,否则删视频留孤儿封面。
验证(服务器实测):造 H.265 视频 → needsTranscode=true,toH264 成功
转成 h264/yuv420p,poster 抽出 13KB 封面;完整上传后接口返回 5 条
(4 image + 1 video 带 thumb)。迁移已跑(35→36),字段与数据核实无误,
测试视频及封面已清理,videos/ 与 thumbs/ 目录确认为空。
|
2026-11-06 10:53:02 +08:00 |
|
laoyang
|
3459eea8f3
|
v64:观影豆瓣自动获取 + 海报/多图上传(移动端 API)
端上「记一场」要与网页端同步实现(用户 2026-10-19 六条),
服务端这一半只加**移动端入口**,网页端(index.php 那条路由)一行没动。
- ApiHandler:新增 `/movies/douban` 子路由(action=suggest / action=thumb /
默认抓详情+海报落盘),逻辑与网页端 `movies/douban` 逐条对齐;
新增 `/movies/<id>/poster` 与 `/movies/<id>/photos`(multipart 上传),
字段名与端上一致(poster / photo);
新增 `normalizeFiles()` 把 `photo[]` 的多文件从"按字段竖切"转成"一行一个";
`movieData()` 认 `poster_key` 并**校验形态**(只接受 posters/xxx 形式);
features 声明 movies_douban / movie_media(端上可探测老服务端)。
- Douban:新增 `apiThumbUrl()` —— 端上打不到 `index.php?r=...`,
把豆瓣图片代理换成 `/api/v1/...` 形式(拼法只此一处);
联想候选带上**过白名单后**的原始图片地址(未过白名单给空串,不下发 SSRF 跳板)。
- Movie:新增 `setPoster()`(单字段更新 —— 端上是"先建记录再传图"两段式,
用 update() 要拼一份完整草稿,漏一个字段就静默覆盖用户刚填的内容)与
`addPhotos()`(**追加**语义,与网页表单用的 savePhotos() 替换语义并存不混用)。
验证:接口 e2e 57/0(自带豆瓣 mock,离线可跑)· 反向验证 18/0 ·
本地全量 e2e 1521/0 · 线上部署 + 站点自检 19 条全过 +
`/api/v1/movies/douban` 401(路由通)· ping.features 已含两条新能力
|
2026-10-19 23:41:15 +08:00 |
|
laoyang
|
5c81f1991f
|
v35 第 35 批:日期控件改用原生(Semi 时间面板不可用)+ 观影附件上传真修好 + 票根/合影归并成「观影照片」
用户原话(三段):
①「选择日期那个地方给,非常不好用。如果我不选日期,只选时间,框里面仍然是空白的,
也没有确定按钮,这个需要重新调整一下。」
②「现在上传附件,也就是在观影模块里面上传附件,怎么还是有问题?上传的附件现在
都没有保存,有时候我上传两个附件,它只保存一张。」
③「除了海报之外,票根、现场照片等等都不分类别,都只分一个类,放在一块。…
只有海报是单独的,因为它是从豆瓣里面下载回来的。其他的都放在一个模块就行,
然后所有照片都上传到一起,直接写"观影照片"就可以了。」
① 日期控件:**Semi 的时间面板根本不可用**(这条最费时间)
实测(独立最小复现页 + 真机):Semi 的 dateTimeRange 面板**只给日期网格**,
时间藏在 `.semi-datepicker-switch-time` 那个小时钟按钮后面;**点了它切到时间面板,
面板仍然是空的**(timeLists=0、无选项、无 footer、无"确定")→ 根本无法"只选时间"。
单点 dateTime 同样。⇒ 与用户描述完全一致。
修:弃用 Semi 的时间选择,改用**原生** date + time(step=1)
(24 小时制、精确到秒、点了就选、不选日期也有值、**不需要**确认按钮)。
原来的 时/分/秒 三个下拉**仍留在 DOM**(POST 契约 *_date/_hour/_minute/_second
一字不改),只是加 .dt-merged 视觉收起。
app.js 的 upgradeRange()/upgrade() 都不再挂 Semi;CSS 加 .is-native-range 系列
把 Semi 时代的"藏原生 / 两端让位"规则覆盖回来。
② 观影附件上传丢文件:**两条路径都断了**
· 暂存路径(拖放):上传框走"拖进来即刻上传到暂存区",令牌进 stage_token[];
而 movies/create|update 与 movies/photo_add **只读 $_FILES['photo']**
⇒ stage_token[] **从来没人认领** ⇒ 拖进去的一个都没存。
· Movie::update() **完全不写 photos**(那句"photos 由单独的删除路由维护"的注释下
根本没写),而路由明明算好了 $d['photos'] 传进来 ⇒ 编辑保存丢照片。
修:路由新增 stage_token[] 认领循环(与 $_FILES 路径并存);photo_add 加兜底;
Movie::update 补上 savePhotos。
③ 归并:表单去掉独立"票根"上传框,"现场合影"并入**一个**「观影照片」块;
详情页「影像记录」→「观影照片」、去掉票根/照片分类标签。
数据层本来就是平的(event_photos 只有 key/position);
⚠️ 旧数据 movie_details.ticket_key **仍要显示**(历史票根不能丢)+ 服务端仍接收
$_FILES['ticket'](向后兼容,直接 POST 仍可存)。
验证(全部真机跑,不是"看代码觉得对"):
· _fb_b34_dtrange.py 33/0(四个表单页:组可见 + 两端日期框可见 + 两端时间框
可见且 step=1 + 三个原生下拉仍在 DOM + 只选时间也能写回 *_hour/_minute/_second);
· _fb_b35_movie_media.py 14/0(点击上传 2 张→库里 2 行;真 HTTP 打 upload_stage.php
拿 stoken→随表单提交→落库;编辑补传→3 行;详情页补传→4 行;归并断言);
· 反向验证:_fb_b34_dtrange_falsify 4/0、_fb_b35_media_falsify 8/0;
· e2e 1503/0(两条断言随 v35 语义更新)、几何交互 92/0、各批真机/反向全绿、
部署脚本静态断言空跑通过;线上 app.js / form.php 的 SHA256 与本地一致。
顺带修掉的工具链脆弱(本轮暴露):
· push.sh 开头加"确保本地测试库在跑"的守卫(长时间跑流水线时 mysqld 会被环境
回收 → e2e/真机探针全崩,看着像代码坏了);
· 探针别用固定字符窗口找函数体(注释一长就假红)、断言别写死字段名前缀
(改期表单是 rev_ends_at_*)、set_input_files 的 id 要照 _stage_drop 的净化规则
(photo[] → sd-photo)、提交按钮要精确定位(编辑页有多个 submit)。
|
2026-10-09 20:23:09 +08:00 |
|
laoyang
|
71a7ec35a0
|
v14: 观影/家谱/日程/旅程/资源/任务六模块统一,首页改 dashboard
用户 14 条需求一次交付(1-13 功能 + 14 工作方式)。
观影(1-4)
- 返回文案全模块统一为「返回观影」(不再有「返回列表」「返回观影记录」三种叫法)
- 观影人一律用彩色人物标签 person_chip:底色由头像主色算出来(上传时存库),
瀑布流卡片也按人显示;五处观影模板全部改用它
- 人员显示统一走 person_name()(shown → 我给他起的称呼 → 姓名)
- 影院管理页与年度报告页的上下两块用 .card + .card 统一给间距(原来紧贴成一整块)
家谱(5)
- 树根从「我」换成**辈分最高的祖先**:库画的是"树根的祖先链+后代+树根的兄弟姐妹",
根=我 时伯父/堂兄/嫂子/侄子一个都不画(12 人夹具只画出 8 人)
- focusMap 按**代数**圈定三代(不再按步数),normalizeLinks 把子女对称挂到父母双方
—— 修掉"母亲登录看不到孩子"
- 新增「看全部 / 回到我」两个按钮,放在画布外(画布整块被库接管了手势)
统一事件原语(6-9)
- 旅程:TripLog 全量迁入(3 趟旅程 / 21 段行程 / 72 张照片 / 5 个人)。
复用 events(kind='trip') + trip_details + trip_nodes(计划/执行双轨保留)
- 日程:每人可建日历本(自定义色)+ 共享只读/可写;观影与旅行是每人默认两本,
内容是**从各模块实时派生**的(不复制,所以改了观影日期日历立刻跟着变);
没有具体时分 = 全天;月视图参照群晖 Calendar
- 资源:挂在某人名下的附属信息(标题+正文+多附件),可共享给多人并设只读/读写,
默认折叠、可搜标题与正文
- 任务:看板三列 + 两级子任务 + 评论@人 + 共享 + 循环(完成时按原截止日推下一期)
- 统一附件表:四个模块的附件共用一张,下载地址不落库、一律由 media.php 现算
模块化(10-11)
- App\Module 是模块的唯一来源(加一行 = 导航条/主题色/个人设置三处自动出现)
- 个人设置里可勾选要显示哪些模块、拖动排序(关掉的模块**不会**被兜底补回来)
- 每个模块一套主题色(家庭级),只覆盖 --brand 三兄弟,不碰纸墨底色
其他(12-13)
- 新增成员表单可选所属分组(编辑表单没有:分组是"我和他的关系",只归我自己)
- 首页改 dashboard:接下来的日子 / 未来七天 / 手头在做 / 往年今日。
家人卡片从首页撤走(看人去名册)
验证(全部通过)
- e2e 542 条(新增 4 模块端到端 60+ 条)
- 桌面几何 368 / 移动端几何 520 / 家谱 12 / 交互 97 / 老库升级 123
- SQL 列名静态校验 0 处可疑(对着真实表结构)
- 反向验证 18 条新注入全部抓住
顺带修掉的既有问题
- 老库升级回填 SQL 按实际存在的列动态拼(缺列不再 1054 炸断升级)
- 全新安装时 Schema::ensure 跑在"人还没建"之前 → 补建日历本三处齐备
- 窄屏导航横向溢出(模块从 4 个加到 8 个后顶栏撑破视口)
|
2026-10-02 09:28:07 +08:00 |
|
laoyang
|
2c36335c3e
|
v10: 修影院编辑回填布尔化 bug;评分改 10 星制;观影人改弹窗+拼音首字母联想;豆瓣自动补充迁移(movie_details.douban_meta,schema v10)
|
2026-10-01 10:21:45 +08:00 |
|
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 |
|
laoyang
|
ff353b1eee
|
v8:观影落地(MovieLog 整体迁入统一事件原语)+ 三处 UI 撤除
- 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/影院三段/照片全量搬
|
2026-09-30 20:22:46 +08:00 |
|