feat: 三栏比例缩放 + SeedanceContent视频上传 + 本地存储基建 (0.0.22)

三栏布局
- ResizeObserver 等比例分配替代固定默认值恢复
- 修复拖拽+窗口调整竞态卡死(needsRecalcRef 延迟补算)
- containerRef.current 动态读取 DOM 替代闭包 el

Seedance2Content
- 从占位文本重构为内容编排控件(文本+图片/视频/音频上传)
- 根据 spec.image_files/video_files/audio_files 动态渲染上传区域
- 值 JSON 序列化 → 提交时转 ContentItem[](text/image_url/video_url/audio_url)

图片上传兼容视频文件
- buildAccept 根据 file_filter 区分 image/video 前缀
- createMediaBeforeUpload 动态放行 video/* MIME
- 公共模块 media-upload-utils.ts

本地存储基建
- sql.js (WASM SQLite) + safeStorage 加密持久化
- 8个IPC文件操作通道 + resolveSafe 路径穿越防护
- <userData>/heixiu-data/ 沙箱 + JWT用户隔离
- 7表DDL + 游标分页 + LRU媒体淘汰

其他
- 修复 errorMessageRef 渲染期写入警告
- 媒体预览回退直接URL(<img>无CORS限制)+ output_type类型补充
- CSP wasm-unsafe-eval + https: CDN媒体源
This commit is contained in:
2026-06-18 19:22:28 +08:00
parent e1c8eff946
commit e4c9ae8fc6
42 changed files with 2640 additions and 126 deletions

View File

@@ -43,3 +43,47 @@ contextBridge.exposeInMainWorld('safeStorage', {
return result?.success ? result.data : null;
},
});
// --------- 本地存储文件 API主进程 fs 桥接)---------
contextBridge.exposeInMainWorld('fileStorage', {
/** 获取 heixiu-data 根目录路径 */
getDataDir(): Promise<string | null> {
return ipcRenderer.invoke(BIDIRECTIONAL.GET_DATA_DIR)
.then((r: { success: boolean; data: string }) => r?.success ? r.data : null);
},
/** 写入文件Base64 → 磁盘),返回写入的绝对路径 */
writeFile(relativePath: string, data: string, encoding?: 'base64' | 'utf8'): Promise<string | null> {
return ipcRenderer.invoke(BIDIRECTIONAL.FILE_WRITE, { relativePath, data, encoding })
.then((r: { success: boolean; data: string }) => r?.success ? r.data : null);
},
/** 读取文件(磁盘 → Base64 */
readFile(relativePath: string): Promise<string | null> {
return ipcRenderer.invoke(BIDIRECTIONAL.FILE_READ, { relativePath })
.then((r: { success: boolean; data: string }) => r?.success ? r.data : null);
},
/** 删除文件 */
deleteFile(relativePath: string): Promise<boolean> {
return ipcRenderer.invoke(BIDIRECTIONAL.FILE_DELETE, { relativePath })
.then((r: { success: boolean }) => r?.success ?? false);
},
/** 递归创建目录 */
makeDir(relativePath: string): Promise<string | null> {
return ipcRenderer.invoke(BIDIRECTIONAL.MAKE_DIR, { relativePath })
.then((r: { success: boolean; data: string }) => r?.success ? r.data : null);
},
/** 在文件管理器中显示文件(绝对路径) */
showItemInFolder(filePath: string): Promise<boolean> {
return ipcRenderer.invoke(BIDIRECTIONAL.SHOW_ITEM_IN_FOLDER, { filePath })
.then((r: { success: boolean }) => r?.success ?? false);
},
/** 获取文件大小(字节) */
fileSize(relativePath: string): Promise<number | null> {
return ipcRenderer.invoke(BIDIRECTIONAL.FILE_SIZE, { relativePath })
.then((r: { success: boolean; data: number }) => r?.success ? r.data : null);
},
/** 检查文件/目录是否存在 */
fileExists(relativePath: string): Promise<boolean> {
return ipcRenderer.invoke(BIDIRECTIONAL.FILE_EXISTS, { relativePath })
.then((r: { success: boolean; data: boolean }) => r?.success ? r.data : false);
},
});