fix(web): 产品视频静态探测改为批量(2次),支持 VITE_PROMOTION_API_ONLY
Made-with: Cursor
This commit is contained in:
@@ -5,3 +5,4 @@ VITE_APP_DOMAIN=https://yuheng.yuxindazhineng.com
|
|||||||
VITE_API_BASE=
|
VITE_API_BASE=
|
||||||
# 可选:与 Mongo 站点 _id 一致;静态 /promotion 缺文件时用于 promotion-media 回退(见 promotionVideos.js)
|
# 可选:与 Mongo 站点 _id 一致;静态 /promotion 缺文件时用于 promotion-media 回退(见 promotionVideos.js)
|
||||||
# VITE_DEFAULT_SITE_ID=69ba1f1f41aeb82acfd609ef
|
# VITE_DEFAULT_SITE_ID=69ba1f1f41aeb82acfd609ef
|
||||||
|
# 仅走 API、跳过静态探测(无 Network 404 噪音):VITE_PROMOTION_API_ONLY=true
|
||||||
|
|||||||
@@ -6,3 +6,4 @@ VITE_APP_DOMAIN=https://yuheng.yuxindazhineng.com
|
|||||||
VITE_API_BASE=
|
VITE_API_BASE=
|
||||||
# 可选:填官网 Mongo site_id,静态 /promotion 无视频时强制走 promotion-media 回退
|
# 可选:填官网 Mongo site_id,静态 /promotion 无视频时强制走 promotion-media 回退
|
||||||
# VITE_DEFAULT_SITE_ID=
|
# VITE_DEFAULT_SITE_ID=
|
||||||
|
# 素材只在上传目录、不想探测静态时:VITE_PROMOTION_API_ONLY=true
|
||||||
|
|||||||
@@ -24,6 +24,8 @@
|
|||||||
线上访问示例:`https://你的域名/promotion/social/douyin.png`
|
线上访问示例:`https://你的域名/promotion/social/douyin.png`
|
||||||
(须将 `web/promotion` 同步到 **`deploy/web/dist/promotion`**,见 `pull-and-restart.sh`。)
|
(须将 `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/`(给静态站用):**
|
**仅同步到源码 `social/`(给静态站用):**
|
||||||
|
|||||||
@@ -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} siteId
|
||||||
* @param {string} relPath promotion 下相对路径,如 social/xxx.mov
|
* @param {string} relPath promotion 下相对路径,如 social/xxx.mov
|
||||||
*/
|
*/
|
||||||
export async function pickPromotionAssetUrl(siteId, relPath) {
|
export async function pickPromotionAssetUrl(siteId, relPath) {
|
||||||
|
const sid = String(siteId || defaultWebSiteId || '').trim()
|
||||||
|
if (apiOnly && sid) {
|
||||||
|
return promotionMediaApiUrl(sid, relPath)
|
||||||
|
}
|
||||||
const staticUrl = promotionUrl(relPath)
|
const staticUrl = promotionUrl(relPath)
|
||||||
const hasStatic = await promotionStaticUrlExists(staticUrl)
|
const hasStatic = await promotionStaticUrlExists(staticUrl)
|
||||||
if (hasStatic) return staticUrl
|
if (hasStatic) return staticUrl
|
||||||
const sid = String(siteId || defaultWebSiteId || '').trim()
|
|
||||||
if (sid) return promotionMediaApiUrl(sid, relPath)
|
if (sid) return promotionMediaApiUrl(sid, relPath)
|
||||||
return staticUrl
|
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
|
* @param {string} siteId
|
||||||
*/
|
*/
|
||||||
export async function buildPromotionVideosAsync(siteId) {
|
export async function buildPromotionVideosAsync(siteId) {
|
||||||
const id = siteId || ''
|
const id = String(siteId || defaultWebSiteId || '').trim()
|
||||||
return Promise.all(
|
const first = PROMOTION_VIDEOS_BASE[0]
|
||||||
PROMOTION_VIDEOS_BASE.map(async (v) => {
|
|
||||||
const [cover, src] = await Promise.all([
|
let useStatic = false
|
||||||
pickPromotionAssetUrl(id, v.relCover),
|
if (apiOnly && id) {
|
||||||
pickPromotionAssetUrl(id, v.relVideo)
|
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 */
|
/** @deprecated 请用 buildPromotionVideos() 或 buildPromotionVideosAsync */
|
||||||
|
|||||||
Reference in New Issue
Block a user