diff --git a/entry/src/main/ets/components/FbMovieDetailSheet.ets b/entry/src/main/ets/components/FbMovieDetailSheet.ets index 8a532b4..cd84485 100644 --- a/entry/src/main/ets/components/FbMovieDetailSheet.ets +++ b/entry/src/main/ets/components/FbMovieDetailSheet.ets @@ -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。 diff --git a/entry/src/main/ets/components/FbMovieNewSheet.ets b/entry/src/main/ets/components/FbMovieNewSheet.ets index 0f4b0ee..6ccdc15 100644 --- a/entry/src/main/ets/components/FbMovieNewSheet.ets +++ b/entry/src/main/ets/components/FbMovieNewSheet.ets @@ -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) diff --git a/entry/src/main/ets/data/FbMovieRepo.ets b/entry/src/main/ets/data/FbMovieRepo.ets index e6e5d85..584c3cb 100644 --- a/entry/src/main/ets/data/FbMovieRepo.ets +++ b/entry/src/main/ets/data/FbMovieRepo.ets @@ -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), diff --git a/entry/src/main/ets/data/FbSyncAll.ets b/entry/src/main/ets/data/FbSyncAll.ets index 0d9d43e..b28f267 100644 --- a/entry/src/main/ets/data/FbSyncAll.ets +++ b/entry/src/main/ets/data/FbSyncAll.ets @@ -429,7 +429,8 @@ async function pingReachable(): Promise { * * 来源三处(都在本地,不额外发请求): * · `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 { @@ -444,18 +445,13 @@ async function collectAttachKeys(): Promise { 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 <> ''");