Files
admin/www/app/utils/resolveAssetUrl.ts
T
2026-08-04 19:18:35 +08:00

50 lines
2.0 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* 资源 URL 解析
*
* dashboard 后台填写素材地址时支持相对路径(如 /uploads/2026/07/xxx.mp4),
* www 端渲染时自动拼接资源服务地址(NUXT_PUBLIC_ASSET_BASE_URL
* 未配置时默认取 apiBaseUrl 去掉 /api 后缀的 origin)。
* 完整 URLhttp(s)://、//、data: 等)保持原样。
* 仅解析 /uploads/ 开头的素材路径;其他相对路径(如 /products/luxsin-x8
* 是站内路由链接(CTA 按钮等),保持原样由 NuxtLink 消费。
*/
// 匹配 *_url / *_path / url 字段(如 cover_url、file_path、gallery 的 url
const ASSET_KEY_RE = /^url$|_(url|path)$/;
export function resolveAssetUrl(url?: string | null): string {
if (!url) return '';
// 绝对地址(协议开头 / 协议相对 // / data: / blob:)保持原样
if (/^([a-z][a-z0-9+.-]*:|\/\/)/i.test(url)) return url;
// 仅解析 /uploads/ 下的素材相对路径;其他 / 开头路径是站内路由链接,不能拼后端基地址
if (!url.startsWith('/uploads/')) return url;
const config = useRuntimeConfig();
const assetBase =
(config.public.assetBaseUrl as string) ||
(config.public.apiBaseUrl as string).replace(/\/api\/?$/, '');
return assetBase.replace(/\/+$/, '') + url;
}
/**
* 深度遍历响应数据,将所有 *_url / *_path 字段的相对路径解析为完整地址。
* 在 useRequest 统一调用,页面/组件无需逐个处理。
*/
export function resolveAssetUrls<T>(data: T): T {
if (!data || typeof data !== 'object') return data;
if (Array.isArray(data)) {
return data.map(item => resolveAssetUrls(item)) as unknown as T;
}
const result: Record<string, unknown> = {};
for (const [key, value] of Object.entries(data as Record<string, unknown>)) {
if (typeof value === 'string' && ASSET_KEY_RE.test(key)) {
result[key] = resolveAssetUrl(value);
} else if (value && typeof value === 'object') {
result[key] = resolveAssetUrls(value);
} else {
result[key] = value;
}
}
return result as T;
}