票根并入观影照片:端上不再「票根另算」(#87)
用户:现在不是已经没有票根的概念了吗?全部都换成观影照片了。
现在只分两类:一类是海报,一类是观影照片。
数据层已迁移(服务端 #87):220 条 ticket_key 搬进 event_photos,
旧字段置 NULL,Movie::find 也不再返回它。
端上跟着收:
- allPhotos() 不再把 ticketKey 拼进列表,直接 return d.photos.slice();
原来那段还特意给它 id=0("删不掉"的标记),现在没这个特殊项了;
- FbMovieRepo 不再写/解析 ticket_key(本地列留着不改 schema,
但恒为空串,字段标 @deprecated);
- FbSyncAll 收附件时 SQL 去掉 ticket_key(票根的 key 会在
module_cache.payload 递归扫描里被收进来,不丢附件)。
⚠️ 特别注意 allPhotos 里**不留** ticketKey 兜底分支:留着就等于承认
还有第三类,而那正是用户要消灭的东西。若线上还有残留(迁移漏跑),
症状是"某些老记录照片变少",应该去补跑迁移,不是在这里兜。
hvigorw assembleHap BUILD SUCCESSFUL。真机验证待做(当时手机锁屏)。
This commit is contained in:
@@ -103,29 +103,24 @@ export struct FbMovieDetailSheet {
|
||||
@Local viewerVideoError: boolean = false;
|
||||
|
||||
/**
|
||||
* 详情里所有可看的图:**票根在前 + 现场照片**。
|
||||
* 详情里所有可看的图 = `event_photos` 全量(**票根已经并进来了**)。
|
||||
*
|
||||
* ⚠️ 与 Web 端口径一致(`templates/movies/show.php` 把票根和照片
|
||||
* "合成一块展示、同一套灯箱",注释里写明了不再分类)。
|
||||
* 端上也别分类 —— 用户关心的是"这次观影的照片",不是它的来源。
|
||||
* 🔴 2026-11-06(用户):「现在不是已经没有票根的概念了吗?全部都换成
|
||||
* 观影照片了。别管是票根还是观影照片,都在一起。现在只分两类:
|
||||
* 一类是海报,一类是观影照片。海报是来自豆瓣的,这个不用管它,
|
||||
* 主要就是观影照片,所有的都在观影照片里边。」
|
||||
*
|
||||
* ⇒ 数据层已经做过一次性迁移:`movie_details.ticket_key` 里的旧票根
|
||||
* 逐条搬进了 `event_photos`(220 条,position 排在最前),
|
||||
* 旧字段置 NULL。所以这里**不再需要**"票根另算"那段逻辑 ——
|
||||
* 它现在就是一条普通照片,有 id、能滑、能删。
|
||||
*
|
||||
* ⚠️ 留 `d.ticketKey` 的兜底分支?**不留**。留着就等于承认还有第三类,
|
||||
* 而这正是用户要消灭的东西。若线上还有残留(迁移漏跑),
|
||||
* 症状是"某些老记录照片变少了" —— 那应该去补跑迁移,不是在这里兜。
|
||||
*/
|
||||
private allPhotos(d: FbMovieDetail): FbMovieMedia[] {
|
||||
const out: FbMovieMedia[] = [];
|
||||
/* 票根:历史数据里它就是一张图(`ticket_key` 单独存在 movie_details),
|
||||
这里归并进同一个列表 —— 与网页端"合成一块展示"同口径。
|
||||
⚠️ 票根永远是图片,不会是视频。 */
|
||||
if (d.ticketKey !== '') {
|
||||
/* ⚠️ `id` 给 0:票根存在 `movie_details.ticket_key` 上,**不是**
|
||||
`event_photos` 的行,没有照片 id。查看器只用 id 来标"第几项",
|
||||
0 不影响显示;但编辑表单里"删这张"是按 id 调的,
|
||||
所以票根那边(表单的 `existingPhotos`)本来也不含票根。
|
||||
—— 删票根请用「换海报/票根」入口,不在照片列表里删。 */
|
||||
out.push({ id: 0, key: d.ticketKey, kind: 'image', thumb: '', mime: '' });
|
||||
}
|
||||
for (const m of d.photos) {
|
||||
out.push(m);
|
||||
}
|
||||
return out;
|
||||
return d.photos.slice();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -689,7 +684,7 @@ export struct FbMovieDetailSheet {
|
||||
.alignItems(HorizontalAlign.Start)
|
||||
}
|
||||
|
||||
// ---- 照片(票根 + 现场照片合成一块,与 Web 端一致)----
|
||||
// ---- 观影照片(**只此一类**:票根已并入 event_photos)----
|
||||
if (this.allPhotos(d).length > 0) {
|
||||
Column({ space: 6 }) {
|
||||
/* 同样按《全局表单规范》:主题色 + Bold + fontSmall。
|
||||
|
||||
@@ -234,7 +234,8 @@ export struct FbMovieNewSheet {
|
||||
⚠️ 别塞进 doubanPosterKey —— 那个会被 PATCH 带上去,
|
||||
虽然值相同不出错,但语义就乱了,后人容易改错。 */
|
||||
this.existingPosterKey = d.posterKey;
|
||||
/* 已有观影照片(票根另算,它是 movie_details.ticket_key,不在这里) */
|
||||
/* 已有观影照片。2026-11-06 起**票根也在这里**了 —— 它已经迁进
|
||||
`event_photos`,与现场照片同一类,可看可删。 */
|
||||
this.existingPhotos = d.photos.slice();
|
||||
const ids: number[] = [];
|
||||
/* ⚠️ 必须显式标类型(`arkts-no-any-unknown`):
|
||||
@@ -1333,7 +1334,7 @@ export struct FbMovieNewSheet {
|
||||
Row({ space: 8 }) {
|
||||
Text(this.photoUris.length > 0
|
||||
? ('已新选 ' + this.photoUris.length.toString() + ' 张')
|
||||
: '票根、合影、随手拍都可以放这儿')
|
||||
: '合影、票根、随手拍都可以放这儿')
|
||||
.fontSize(FbMetric.fontSmall)
|
||||
.fontColor(this.photoUris.length > 0 ? FbColors.ink : FbColors.muted)
|
||||
.maxLines(1)
|
||||
|
||||
@@ -272,7 +272,11 @@ export interface FbMovieDetail {
|
||||
/** 剧情简介(movie_details.info) */
|
||||
info: string;
|
||||
posterKey: string;
|
||||
/** 票根图(movie_details.ticket_key) */
|
||||
/**
|
||||
* @deprecated 2026-11-06:票根概念取消,已并入 `photos`(`event_photos`)。
|
||||
* 「只分两类:海报 / 观影照片」。字段留着只为不动本地库 schema,
|
||||
* **恒为空串**,任何新代码都不要再读它。
|
||||
*/
|
||||
ticketKey: string;
|
||||
cinemaName: string;
|
||||
cinemaPlace: string;
|
||||
@@ -618,7 +622,10 @@ export class FbMovieRepo {
|
||||
b['event_id'] = m.id;
|
||||
b['info'] = m.movieInfo;
|
||||
b['poster_key'] = m.posterKey;
|
||||
b['ticket_key'] = m.ticketKey;
|
||||
/* 🔴 2026-11-06:`ticket_key` **不再写入**(票根已并入 `event_photos`,
|
||||
服务端也置 NULL 且不再 SELECT 它)。本地列留着(改 schema 要迁移,
|
||||
收益为零),但恒为 NULL —— 写入空串会让"死列里有值"看着像还有票根。 */
|
||||
b['ticket_key'] = '';
|
||||
b['cinema_id'] = cinemaId;
|
||||
b['douban_meta'] = m.doubanMeta;
|
||||
b['updated_at'] = m.updatedAt;
|
||||
@@ -1684,7 +1691,8 @@ function parseDetail(id: number, json: string): FbMovieDetail {
|
||||
note: strOf(o.note),
|
||||
info: strOf(o.info),
|
||||
posterKey: strOf(o.poster_key),
|
||||
ticketKey: strOf(o.ticket_key),
|
||||
/* 2026-11-06:票根并入 photos,不再解析 ticket_key(服务端也不返回了) */
|
||||
ticketKey: '',
|
||||
cinemaName: strOf(o.cinema_name),
|
||||
cinemaPlace: strOf(o.cinema_place),
|
||||
cinemaAddress: strOf(o.cinema_address),
|
||||
|
||||
@@ -429,7 +429,8 @@ async function pingReachable(): Promise<boolean> {
|
||||
*
|
||||
* 来源三处(都在本地,不额外发请求):
|
||||
* · `module_cache.payload` —— 9 个模块的完整 JSON(递归扫,见 `FbAttachQueue.collectFromJson`);
|
||||
* · `movie_details.poster_key` / `ticket_key` —— 海报与票根;
|
||||
* · `movie_details.poster_key` —— 海报(票根已并入 event_photos,
|
||||
* 它的 key 会在上面那条 `module_cache.payload` 递归扫描里被收进来);
|
||||
* · `persons.avatar` —— 名册头像。
|
||||
*/
|
||||
async function collectAttachKeys(): Promise<void> {
|
||||
@@ -444,18 +445,13 @@ async function collectAttachKeys(): Promise<void> {
|
||||
FB_ATTACH.collectFromJson(r.strOr('payload', ''), keys);
|
||||
}
|
||||
const posters: FbRow[] = await db.queryRows(
|
||||
"SELECT poster_key, ticket_key FROM movie_details "
|
||||
+ "WHERE (poster_key IS NOT NULL AND poster_key <> '') "
|
||||
+ " OR (ticket_key IS NOT NULL AND ticket_key <> '')");
|
||||
"SELECT poster_key FROM movie_details "
|
||||
+ "WHERE poster_key IS NOT NULL AND poster_key <> ''");
|
||||
for (const r of posters) {
|
||||
const p: string = r.strOr('poster_key', '');
|
||||
const t: string = r.strOr('ticket_key', '');
|
||||
if (p !== '') {
|
||||
keys.push(p);
|
||||
}
|
||||
if (t !== '') {
|
||||
keys.push(t);
|
||||
}
|
||||
}
|
||||
const avatars: FbRow[] = await db.queryRows(
|
||||
"SELECT avatar FROM persons WHERE avatar IS NOT NULL AND avatar <> ''");
|
||||
|
||||
Reference in New Issue
Block a user