feat: 完成全部接口替换为新后端接口
This commit is contained in:
@@ -0,0 +1,65 @@
|
||||
/** 与后端及 asset-sync 的公开资源配置保持一致;此处不包含上传凭据。 */
|
||||
export const assetConfig = {
|
||||
publicDomain: 'https://cdn.joeyone.cn',
|
||||
keyPrefix: 'doodle-assets/',
|
||||
};
|
||||
|
||||
/** 固定字体和页面预览使用相对路径;接口返回的资源 URL 直接使用。 */
|
||||
export function publicAssetUrl(relativePath: string): string {
|
||||
const parts = relativePath.split('/');
|
||||
if (
|
||||
relativePath.includes('\\') ||
|
||||
[...relativePath].some(
|
||||
(char) => char.charCodeAt(0) < 32 || char.charCodeAt(0) === 127,
|
||||
) ||
|
||||
parts.some((part) => !part || part === '.' || part === '..')
|
||||
)
|
||||
throw new Error('资源相对路径不正确');
|
||||
const domain = assetConfig.publicDomain.replace(/\/+$/, '');
|
||||
const prefix = assetConfig.keyPrefix.replace(/\/+$/, '');
|
||||
return `${domain}/${[...(prefix ? prefix.split('/') : []), ...parts].map(encodeURIComponent).join('/')}`;
|
||||
}
|
||||
|
||||
const LEGACY_PREVIEW_PREFIX =
|
||||
'cloud://cloud1-9gifs7a2756e2c87.636c-cloud1-9gifs7a2756e2c87-1351593184/';
|
||||
const LEGACY_PREVIEW_HTTPS =
|
||||
/^https?:\/\/636c-cloud1-9gifs7a2756e2c87-1351593184\.tcb\.qcloud\.la\/([^?#]+)(?:[?#].*)?$/;
|
||||
|
||||
/** 旧预拉取、缓存和云函数中的预览图指向已迁移的公开目录;其他资源不作替换。 */
|
||||
export function resolvePreviewUrl(value: unknown): string {
|
||||
if (typeof value !== 'string') return '';
|
||||
const raw = value.trim();
|
||||
let path: string;
|
||||
if (raw.startsWith(LEGACY_PREVIEW_PREFIX)) {
|
||||
path = raw.slice(LEGACY_PREVIEW_PREFIX.length);
|
||||
if (/[?#]/.test(path)) return '';
|
||||
} else {
|
||||
const match = raw.match(LEGACY_PREVIEW_HTTPS);
|
||||
if (!match) return raw;
|
||||
path = match[1];
|
||||
}
|
||||
try {
|
||||
path = path.split('/').map(decodeURIComponent).join('/');
|
||||
if (!path.startsWith('assets/previews/')) return raw;
|
||||
return publicAssetUrl(path);
|
||||
} catch {
|
||||
// 畸形路径不继续请求旧云存储,也不生成越界的 CDN 地址。
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
/** 统一处理预拉取/缓存中的嵌套 previewImg;不修改原数据、头像和其他云文件引用。 */
|
||||
export function normalizePreviewImages<T>(value: T): T {
|
||||
if (Array.isArray(value)) {
|
||||
return value.map((item) => normalizePreviewImages(item)) as T;
|
||||
}
|
||||
if (!value || typeof value !== 'object') return value;
|
||||
const result = { ...value } as Record<string, unknown>;
|
||||
for (const key of Object.keys(result)) {
|
||||
result[key] =
|
||||
key === 'previewImg'
|
||||
? resolvePreviewUrl(result[key])
|
||||
: normalizePreviewImages(result[key]);
|
||||
}
|
||||
return result as T;
|
||||
}
|
||||
Reference in New Issue
Block a user