From f94a6584a40feb26a550ed8817ec12e579e96857 Mon Sep 17 00:00:00 2001 From: xiyidaiwa Date: Tue, 18 Aug 2026 15:04:08 +0800 Subject: [PATCH] =?UTF-8?q?fix(store):=20=E4=BF=AE=E5=A4=8D=E5=BA=94?= =?UTF-8?q?=E7=94=A8=E6=88=AA=E5=9B=BE=E5=8A=A0=E8=BD=BD=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 截图候选 URL 改为按固定路径拼接 screen_1~5.png,不再依赖后端 img_urls - 打开详情页时先清空截图,避免残留上一个应用的图片 - 更新生产环境 APM_STORE_BASE_URL 域名 - 修正 debian/changelog 版本号 --- .env.production | 2 +- debian/changelog | 2 +- src/composables/useAppDetail.ts | 39 +++++++++++++++++---------------- 3 files changed, 22 insertions(+), 21 deletions(-) diff --git a/.env.production b/.env.production index 2d0a583d..41883f93 100644 --- a/.env.production +++ b/.env.production @@ -1,3 +1,3 @@ -VITE_APM_STORE_BASE_URL=https://erotica.spark-app.store +VITE_APM_STORE_BASE_URL=https://d.spark-app.store VITE_APM_STORE_STATS_BASE_URL=https://feedback.spark-app.store VITE_SPARK_BACKEND_BASE_URL=https://account.spark-app.store diff --git a/debian/changelog b/debian/changelog index 27ec7629..32025234 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,4 +1,4 @@ -spark-store (5.3.0.7-test) UNRELEASED; urgency=medium +spark-store (5.3.0.2) UNRELEASED; urgency=medium * Initial release. diff --git a/src/composables/useAppDetail.ts b/src/composables/useAppDetail.ts index 6a9721a1..2b9414d4 100644 --- a/src/composables/useAppDetail.ts +++ b/src/composables/useAppDetail.ts @@ -342,7 +342,9 @@ const openDetail = async (app: App | OpenDetailInput) => { currentApp.value = finalApp; currentScreenIndex.value = 0; - // 截图以后端 img_urls 为候选并探测真实存在性;异步进行,详情页先打开不阻塞。 + // 先清空截图,避免详情页渲染时残留上一个应用的图片(新图需异步探测后才填充)。 + screenshots.value = []; + // 截图按固定路径拼接 screen_1~5.png 并探测真实存在性;异步进行,详情页先打开不阻塞。 // 每次打开取消上一轮探测,避免陈旧结果覆盖当前应用。 if (screenshotAbortController) screenshotAbortController.abort(); screenshotAbortController = new AbortController(); @@ -439,26 +441,25 @@ const checkScreenshotExists = async ( } }; -// 截图来源以后端 img_urls 为候选(权威意图列表),但后端元数据可能"声明 N 张实存 M 张" -// (如飞书声明 5 张仅上传 3 张)。因此对候选逐一探测存在性,仅保留真实可用的 URL, -// 既保证"实际有几张就预览几张",又兜底过滤后端脏数据导致的空白页。 -// 探测结果经内存缓存复用,同一应用多次打开不再重复请求。 +// 截图候选 URL 一律按固定规则前端拼接,最多 5 张(screen_1~5.png),并对每张探测真实存在性, +// 仅保留真实可用的 URL,保证"实际有几张就预览几张"。 +// 注意:以下拼接路径(APM_STORE_BASE_URL / finalArch / category / pkgname / screen_N.png) +// 直接对应服务器静态资源布局,属于权威路径,禁止修改或替换为 app.img_urls 等其它来源, +// 否则会导致截图全部 404(历史已踩坑:后端 img_urls 不准确)。 const loadScreenshots = async (app: App, signal?: AbortSignal) => { - const raw = app.img_urls as unknown; - let candidates: string[] = []; - if (Array.isArray(raw)) { - candidates = raw as string[]; - } else if (typeof raw === "string" && raw.length > 0) { - try { - const parsed = JSON.parse(raw); - if (Array.isArray(parsed)) candidates = parsed as string[]; - } catch { - candidates = []; - } + if (!app.category || app.category === "unknown") { + screenshots.value = []; + return; + } + const arch = window.apm_store.arch || "amd64"; + const finalArch = app.origin === "spark" ? `${arch}-store` : `${arch}-apm`; + + const candidates: string[] = []; + for (let i = 1; i <= 5; i++) { + candidates.push( + `${APM_STORE_BASE_URL}/${finalArch}/${app.category}/${app.pkgname}/screen_${i}.png`, + ); } - candidates = candidates.filter( - (u): u is string => typeof u === "string" && u.length > 0, - ); // 先按缓存/同步填充已知结果,未知项异步探测;避免详情页打开后长时间空白 const results = await Promise.all(