修复UI编辑器远端导入编译错误
将远端素材导入改为异步下载后加锁提交,消除 await 同步函数编译错误。 更新字体素材导入测试以使用当前筛选器与配置契约。
This commit is contained in:
@@ -2202,25 +2202,22 @@ mod ui_editor_font_tests {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn import_ui_editor_remote_assets(
|
||||
pub(crate) async fn import_ui_editor_remote_assets(
|
||||
project_path: String,
|
||||
assets: Vec<serde_json::Value>,
|
||||
) -> Result<RemoteImportResult, String> {
|
||||
let root = Path::new(project_path.trim());
|
||||
enforce_project_permission_policy(root, "canvas.asset_import")?;
|
||||
let _lock = acquire_project_write_lock(root, "canvas.asset_import")?;
|
||||
if assets.len() > UI_EDITOR_IMAGE_MAX_COUNT {
|
||||
return Err(format!("一次最多选择 {UI_EDITOR_IMAGE_MAX_COUNT} 张图片"));
|
||||
}
|
||||
// 远程素材导入保持与本地图片/字体相同的增量语义,不对已成功项目文件做整批回滚。
|
||||
// IPC 只传稳定引用/签名 URL,由 Rust 流式下载并限制响应体;下载期间不占有项目写锁。
|
||||
let mut total_size = 0u64;
|
||||
let mut imported = Vec::with_capacity(assets.len());
|
||||
let mut downloads = Vec::with_capacity(assets.len());
|
||||
for asset in assets {
|
||||
let asset_id = json_string_field(&asset, "assetId")
|
||||
.or_else(|| json_string_field(&asset, "objectKey"))
|
||||
.ok_or_else(|| "平台素材缺少稳定 assetId/objectKey,拒绝导入".to_string())?;
|
||||
// 参考资源同步流程:IPC 只传稳定引用/签名 URL,由 Rust 流式下载并限制响应体,
|
||||
// 避免把不受控的 Vec<u8> 在 IPC 反序列化阶段一次性放入内存。
|
||||
let download_url = json_string_field(&asset, "downloadUrl")
|
||||
.ok_or_else(|| format!("平台素材 {asset_id} 缺少 downloadUrl"))?;
|
||||
let remaining = UI_EDITOR_IMAGE_MAX_TOTAL_SIZE.saturating_sub(total_size);
|
||||
@@ -2243,6 +2240,13 @@ pub(crate) fn import_ui_editor_remote_assets(
|
||||
} else {
|
||||
return Err("平台素材不是受支持的 PNG/JPEG/WEBP 图片".to_string());
|
||||
};
|
||||
downloads.push((asset, asset_id, media_type.to_string(), bytes));
|
||||
}
|
||||
|
||||
let _lock = acquire_project_write_lock(root, "canvas.asset_import")?;
|
||||
// 远程素材导入保持与本地图片/字体相同的增量语义,不对已成功项目文件做整批回滚。
|
||||
let mut imported = Vec::with_capacity(downloads.len());
|
||||
for (asset, asset_id, media_type, bytes) in downloads {
|
||||
let extension = infer_file_extension(
|
||||
json_string_field(&asset, "objectKey")
|
||||
.or_else(|| json_string_field(&asset, "imageSrc"))
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { describe, expect, it } from 'vitest';
|
||||
|
||||
import { FONT_IMPORTER_SETTINGS } from '../src/components/AssetImporter/settings';
|
||||
import {
|
||||
buildProjectFiles,
|
||||
buildRootFiles,
|
||||
@@ -25,15 +26,16 @@ describe('AssetImporter font mode', () => {
|
||||
},
|
||||
];
|
||||
|
||||
const files = buildProjectFiles(assets, 'font').filter(
|
||||
(entry) => !entry.isDirectory,
|
||||
);
|
||||
const files = buildProjectFiles(
|
||||
assets,
|
||||
FONT_IMPORTER_SETTINGS.local.typeFilter,
|
||||
).filter((entry) => !entry.isDirectory);
|
||||
expect(files.map((entry) => entry.asset?.id)).toEqual([
|
||||
'font-1',
|
||||
'font-by-extension',
|
||||
]);
|
||||
expect(buildRootFiles('font').map((entry) => entry.name)).toEqual([
|
||||
'本地项目字体',
|
||||
]);
|
||||
expect(
|
||||
buildRootFiles(FONT_IMPORTER_SETTINGS).map((entry) => entry.name),
|
||||
).toEqual(['本地项目']);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user