fix(web): 产品视频静态探测改为批量(2次),支持 VITE_PROMOTION_API_ONLY

Made-with: Cursor
This commit is contained in:
whm
2026-03-21 13:20:10 +08:00
parent dd05748c85
commit c1fb5f3440
4 changed files with 56 additions and 13 deletions

View File

@@ -5,3 +5,4 @@ VITE_APP_DOMAIN=https://yuheng.yuxindazhineng.com
VITE_API_BASE=
# 可选:与 Mongo 站点 _id 一致;静态 /promotion 缺文件时用于 promotion-media 回退(见 promotionVideos.js
# VITE_DEFAULT_SITE_ID=69ba1f1f41aeb82acfd609ef
# 仅走 API、跳过静态探测无 Network 404 噪音VITE_PROMOTION_API_ONLY=true

View File

@@ -6,3 +6,4 @@ VITE_APP_DOMAIN=https://yuheng.yuxindazhineng.com
VITE_API_BASE=
# 可选:填官网 Mongo site_id静态 /promotion 无视频时强制走 promotion-media 回退
# VITE_DEFAULT_SITE_ID=
# 素材只在上传目录、不想探测静态时VITE_PROMOTION_API_ONLY=true

View File

@@ -24,6 +24,8 @@
线上访问示例:`https://你的域名/promotion/social/douyin.png`
(须将 `web/promotion` 同步到 **`deploy/web/dist/promotion`**,见 `pull-and-restart.sh`。)
首页产品视频:只对**第一条**的封面与视频各探测一次静态;若任一不存在则**全部**走 `promotion-media` API避免 Network 里 10+ 条 404。若素材**只在上传目录**,可在 `web/.env.production`**`VITE_PROMOTION_API_ONLY=true`** 并配合 **`VITE_DEFAULT_SITE_ID`**,不再发静态探测请求。
## 从旧「视频发布」目录迁移
**仅同步到源码 `social/`(给静态站用):**

View File

@@ -87,16 +87,23 @@ export async function promotionStaticUrlExists(url) {
}
}
const apiOnly =
import.meta.env.VITE_PROMOTION_API_ONLY === '1' ||
import.meta.env.VITE_PROMOTION_API_ONLY === 'true'
/**
* 有静态则静态,否则(需 siteId走 promotion-media API
* 有静态则静态,否则(需 siteId走 promotion-media API(单资源;列表请用 buildPromotionVideosAsync 批量逻辑)
* @param {string} siteId
* @param {string} relPath promotion 下相对路径,如 social/xxx.mov
*/
export async function pickPromotionAssetUrl(siteId, relPath) {
const sid = String(siteId || defaultWebSiteId || '').trim()
if (apiOnly && sid) {
return promotionMediaApiUrl(sid, relPath)
}
const staticUrl = promotionUrl(relPath)
const hasStatic = await promotionStaticUrlExists(staticUrl)
if (hasStatic) return staticUrl
const sid = String(siteId || defaultWebSiteId || '').trim()
if (sid) return promotionMediaApiUrl(sid, relPath)
return staticUrl
}
@@ -116,20 +123,52 @@ export function buildPromotionVideos(_siteId) {
}
/**
* 静态优先:存在 /promotion/... 则用静态,否则用 uploads API需 siteId
* 静态优先:只对「示例封面 + 示例视频」各探测一次,避免 Network 里出现 10+ 条 404。
* 二者在静态均存在则全套走 /promotion/;否则有 siteId 时全套走 promotion-media API。
* @param {string} siteId
*/
export async function buildPromotionVideosAsync(siteId) {
const id = siteId || ''
return Promise.all(
PROMOTION_VIDEOS_BASE.map(async (v) => {
const [cover, src] = await Promise.all([
pickPromotionAssetUrl(id, v.relCover),
pickPromotionAssetUrl(id, v.relVideo)
const id = String(siteId || defaultWebSiteId || '').trim()
const first = PROMOTION_VIDEOS_BASE[0]
let useStatic = false
if (apiOnly && id) {
useStatic = false
} else if (!apiOnly) {
const [coverOk, videoOk] = await Promise.all([
promotionStaticUrlExists(promotionUrl(first.relCover)),
promotionStaticUrlExists(promotionUrl(first.relVideo))
])
return { id: v.id, title: v.title, desc: v.desc, cover, src }
useStatic = coverOk && videoOk
}
return PROMOTION_VIDEOS_BASE.map((v) => {
if (useStatic) {
return {
id: v.id,
title: v.title,
desc: v.desc,
cover: promotionUrl(v.relCover),
src: promotionUrl(v.relVideo)
}
}
if (id) {
return {
id: v.id,
title: v.title,
desc: v.desc,
cover: promotionMediaApiUrl(id, v.relCover),
src: promotionMediaApiUrl(id, v.relVideo)
}
}
return {
id: v.id,
title: v.title,
desc: v.desc,
cover: promotionUrl(v.relCover),
src: promotionUrl(v.relVideo)
}
})
)
}
/** @deprecated 请用 buildPromotionVideos() 或 buildPromotionVideosAsync */