fix: preserve video extensions on AI design downloads
This commit is contained in:
@@ -160,9 +160,19 @@ function sendData(res: ServerResponse, data: unknown): void {
|
||||
sendJson(res, 200, { success: true, status: 200, data });
|
||||
}
|
||||
|
||||
const IMAGE_FILE_EXTENSIONS = new Set(['.gif', '.jpeg', '.jpg', '.png', '.svg', '.webp']);
|
||||
const ASSET_FILE_EXTENSIONS = new Set([
|
||||
'.gif',
|
||||
'.jpeg',
|
||||
'.jpg',
|
||||
'.mov',
|
||||
'.mp4',
|
||||
'.png',
|
||||
'.svg',
|
||||
'.webm',
|
||||
'.webp',
|
||||
]);
|
||||
|
||||
function safeImageFileName(value: string, assetId: string): string {
|
||||
function safeAssetFileName(value: string, assetId: string): string {
|
||||
const fallbackId = assetId
|
||||
.replace(/[^a-zA-Z0-9_-]+/g, '-')
|
||||
.replace(/^-+|-+$/g, '')
|
||||
@@ -173,7 +183,7 @@ function safeImageFileName(value: string, assetId: string): string {
|
||||
.join('')
|
||||
.replace(/[. ]+$/g, '')
|
||||
.slice(0, 120);
|
||||
if (!sanitized || !IMAGE_FILE_EXTENSIONS.has(extname(sanitized).toLowerCase())) {
|
||||
if (!sanitized || !ASSET_FILE_EXTENSIONS.has(extname(sanitized).toLowerCase())) {
|
||||
return fallback;
|
||||
}
|
||||
return sanitized;
|
||||
@@ -186,12 +196,12 @@ async function saveAssetContent(
|
||||
assetId: string,
|
||||
defaultFileName: string,
|
||||
): Promise<void> {
|
||||
const fileName = safeImageFileName(defaultFileName, assetId);
|
||||
const fileName = safeAssetFileName(defaultFileName, assetId);
|
||||
const extension = extname(fileName).slice(1);
|
||||
const options: SaveDialogOptions = {
|
||||
defaultPath: join(app.getPath('downloads'), fileName),
|
||||
filters: [
|
||||
{ name: '图片', extensions: [extension] },
|
||||
{ name: '设计资产', extensions: [extension] },
|
||||
{ name: '所有文件', extensions: ['*'] },
|
||||
],
|
||||
};
|
||||
@@ -207,11 +217,14 @@ async function saveAssetContent(
|
||||
}
|
||||
|
||||
const content = await ctx.imageWorkspace!.openAssetContent(workspaceId, assetId);
|
||||
if (!content.ok || !content.body || !content.headers.get('content-type')?.startsWith('image/')) {
|
||||
const contentType = content.headers.get('content-type');
|
||||
if (!content.ok
|
||||
|| !content.body
|
||||
|| (!contentType?.startsWith('image/') && !contentType?.startsWith('video/'))) {
|
||||
throw new DesignWorkspaceModuleError(
|
||||
content.status >= 400 ? content.status : 502,
|
||||
'DESIGN_ASSET_DOWNLOAD_FAILED',
|
||||
'生成图片暂时无法下载,请稍后重试',
|
||||
'生成资产暂时无法下载,请稍后重试',
|
||||
);
|
||||
}
|
||||
|
||||
@@ -230,7 +243,7 @@ async function saveAssetContent(
|
||||
throw new DesignWorkspaceModuleError(
|
||||
500,
|
||||
'DESIGN_ASSET_SAVE_FAILED',
|
||||
'图片保存失败,请重新选择位置后重试',
|
||||
'资产保存失败,请重新选择位置后重试',
|
||||
);
|
||||
}
|
||||
sendData(res, { status: 'saved' });
|
||||
|
||||
Reference in New Issue
Block a user