diff --git a/backend-java/src/main/java/com/competition/modules/leai/service/LeaiSyncService.java b/backend-java/src/main/java/com/competition/modules/leai/service/LeaiSyncService.java index 62a83fd..ccb3ffa 100644 --- a/backend-java/src/main/java/com/competition/modules/leai/service/LeaiSyncService.java +++ b/backend-java/src/main/java/com/competition/modules/leai/service/LeaiSyncService.java @@ -129,6 +129,13 @@ public class LeaiSyncService implements ILeaiSyncService { if (coverUrl == null) coverUrl = remoteData.get("cover_url"); if (coverUrl != null) work.setCoverUrl(coverUrl.toString()); + // 兜底:如果 originalImageUrl 没传但 coverUrl 传了,把 coverUrl 也写入 originalImageUrl + // 当前 leai webhook 大多只传 coverUrl(实际就是用户上传的原图),不传独立的 originalImageUrl 字段 + // 这里兜底让前端 PIP / 详情页「画作原图」卡片能正确展示 + if (originalImageUrl == null && coverUrl != null) { + work.setOriginalImageUrl(coverUrl.toString()); + } + // 通过手机号查找用户ID(多租户场景) if (phone != null && work.getUserId() == null) { Long userId = findUserIdByPhone(phone); @@ -189,6 +196,10 @@ public class LeaiSyncService implements ILeaiSyncService { if (coverUrl != null) { wrapper.set(UgcWork::getCoverUrl, coverUrl.toString()); } + // 兜底:originalImageUrl 没传但 coverUrl 传了,把 coverUrl 也写入 originalImageUrl + if (originalImageUrl == null && coverUrl != null) { + wrapper.set(UgcWork::getOriginalImageUrl, coverUrl.toString()); + } wrapper.set(UgcWork::getModifyTime, LocalDateTime.now()); ugcWorkMapper.update(null, wrapper); @@ -237,6 +248,10 @@ public class LeaiSyncService implements ILeaiSyncService { if (coverUrl != null) { wrapper.set(UgcWork::getCoverUrl, coverUrl.toString()); } + // 兜底:originalImageUrl 没传但 coverUrl 传了,把 coverUrl 也写入 originalImageUrl + if (originalImageUrl == null && coverUrl != null) { + wrapper.set(UgcWork::getOriginalImageUrl, coverUrl.toString()); + } wrapper.set(UgcWork::getModifyTime, LocalDateTime.now()); diff --git a/backend-java/src/main/resources/db/migration/V13__backfill_original_image_url.sql b/backend-java/src/main/resources/db/migration/V13__backfill_original_image_url.sql new file mode 100644 index 0000000..6f5b3fe --- /dev/null +++ b/backend-java/src/main/resources/db/migration/V13__backfill_original_image_url.sql @@ -0,0 +1,29 @@ +-- ======================================================== +-- V13: 回填 t_ugc_work.original_image_url 字段 +-- ======================================================== +-- 背景: +-- leai webhook 同步作品时,大多数情况下只传了 cover_url, +-- 没有单独传 originalImageUrl 字段,导致 LeaiSyncService +-- 把 cover_url 写入了 cover 字段,但 original_image_url 字段为 null。 +-- +-- 实际情况: +-- 当前所有作品的 cover_url 实际上就是用户上传的原图, +-- AI 生成的独立绘本封面字段尚未在 leai webhook 中拆分提供。 +-- +-- 影响: +-- 前端作品库 / 发现页 PIP 画中画功能、详情页「画作原图」卡片 +-- 需要 original_image_url 字段才能展示,当前为 null 时这些 UI +-- 全部不渲染,用户看不到原图。 +-- +-- 修复: +-- 把 original_image_url 为 null 但 cover_url 有值的数据, +-- 统一回填为 cover_url。 +-- 同时 LeaiSyncService 已加 fallback,新数据自动写入。 +-- +-- 详见 docs/design/public/ugc-work-status-redesign.md +-- ======================================================== + +UPDATE t_ugc_work +SET original_image_url = cover_url +WHERE original_image_url IS NULL + AND cover_url IS NOT NULL; diff --git a/backend-java/src/main/resources/db/migration/V14__force_backfill_original_image_url.sql b/backend-java/src/main/resources/db/migration/V14__force_backfill_original_image_url.sql new file mode 100644 index 0000000..e04b197 --- /dev/null +++ b/backend-java/src/main/resources/db/migration/V14__force_backfill_original_image_url.sql @@ -0,0 +1,15 @@ +-- ======================================================== +-- V14: 强制回填 t_ugc_work.original_image_url +-- ======================================================== +-- 背景: +-- V13 因 Flyway schema_history 表残留同版本号脏数据被 repair 跳过, +-- 实际 SQL 没真正执行。新建 V14 强制重跑同样的 UPDATE 逻辑。 +-- +-- 详见 docs/design/public/ugc-work-status-redesign.md +-- 详见 V13__backfill_original_image_url.sql +-- ======================================================== + +UPDATE t_ugc_work +SET original_image_url = cover_url +WHERE original_image_url IS NULL + AND cover_url IS NOT NULL; diff --git a/backend-java/src/main/resources/db/migration/V15__backfill_original_image_url_empty_string.sql b/backend-java/src/main/resources/db/migration/V15__backfill_original_image_url_empty_string.sql new file mode 100644 index 0000000..c2a81e5 --- /dev/null +++ b/backend-java/src/main/resources/db/migration/V15__backfill_original_image_url_empty_string.sql @@ -0,0 +1,22 @@ +-- ======================================================== +-- V15: 回填 t_ugc_work.original_image_url 空字符串数据 +-- ======================================================== +-- 背景: +-- V14 用 `WHERE original_image_url IS NULL` 回填了 NULL 的数据, +-- 但部分作品的 original_image_url 字段是空字符串 '' 而不是 NULL +-- (JS 前端经常把空字段当 '' 传给后端),V14 的 IS NULL 条件没匹配到。 +-- +-- 前端 v-if="work.originalImageUrl" 在空字符串时是 falsy, +-- 导致这些作品的「画作原图」卡片和 PIP 不显示。 +-- +-- 修复: +-- 把 original_image_url 为 NULL 或空字符串的数据,统一回填为 cover_url。 +-- +-- 详见 V13、V14 历史 +-- ======================================================== + +UPDATE t_ugc_work +SET original_image_url = cover_url +WHERE (original_image_url IS NULL OR original_image_url = '') + AND cover_url IS NOT NULL + AND cover_url != '';