feat(s3): 图片上传到 S3——设置/自动上传/右键单张/批量上传(docs/30)

Rust 新增 s3.rs:SigV4 签名 + PUT Object(reqwest blocking+rustls,
签名对照 AWS 官方示例向量逐字一致;同份代码对本地模拟 S3 端到端
实测通过)。命令 s3_upload_image / s3_test_connection(总数 30 对账)。
配置存 UiState.s3(本机偏好),设置弹窗含测试连接与自动上传开关。
未上传判定 = src 非 http/data/blob 的本地引用;上传成功后同 src 的
图片节点一次事务回换为 S3 地址,本地 .assets 文件保留。
入口:粘贴/插入后自动上传回换(扑空重试一次、失败必提示);右键
命中本地图片多一项「上传到 S3」;文件菜单 + 状态栏批量上传带进度
弹窗。验证:vitest 133+2、tsc、构建通过,设置弹窗截图核对。
This commit is contained in:
Muse
2026-11-15 08:38:47 +08:00
parent 03c6c15439
commit 967aada3ca
19 changed files with 1444 additions and 30 deletions

View File

@@ -13,7 +13,7 @@ async function renderMenu(props: Record<string, unknown> = {}) {
await act(async () => {
root.render(
<EditorContextMenu
x={10} y={10} hasSelection={false} sourceMode={false}
x={10} y={10} hasSelection={false} imageSrc={null} sourceMode={false}
onAction={(a) => actions.push(a)}
onClose={() => { closed += 1 }}
{...props}
@@ -38,6 +38,20 @@ describe('编辑区右键菜单', () => {
container.remove()
})
it('命中本地图片时多一项「上传到 S3」;网络图片不出现', async () => {
const local = await renderMenu({ imageSrc: 'doc.assets/a.png' })
const up = btn(local.container, '上传到 S3')
expect(up).toBeTruthy()
await act(async () => { up?.dispatchEvent(new MouseEvent('click', { bubbles: true })) })
expect(local.actions).toEqual(['uploadS3'])
await act(async () => { local.root.unmount() })
local.container.remove()
const remote = await renderMenu({ imageSrc: 'https://cdn.example.com/a.png' })
expect(btn(remote.container, '上传到 S3')).toBeUndefined()
await act(async () => { remote.root.unmount() })
remote.container.remove()
})
it('源码模式只出编辑命令与「即时渲染」', async () => {
const { container, root } = await renderMenu({ sourceMode: true, hasSelection: true })
expect(btn(container, '加粗')).toBeUndefined()