feat(software-version): 安装包改浏览器直传 MinIO,支持批量删除

- 后端新增 /api/admin/version/presign、confirm、delete 端点;直传后服务端校验对象并写 web_config
- OSS 层新增软件版本对象 presign PUT/大小校验/删除与 client 桶 URL 识别
- 后台前端上传改 presign→PUT→confirm 三段式直传,带进度条;成功提示精简为"发布成功"
- 版本列表加勾选/表头全选、批量删除与单行删除;操作按钮样式对齐其他子菜单
This commit is contained in:
2026-09-08 23:51:18 +08:00
parent 5fad0ae027
commit 45fdd8a294
9 changed files with 440 additions and 30 deletions
@@ -9,8 +9,8 @@ test('align_software_version_page_wiring', () => {
// 下载按钮:<a download> 强制下载(对齐 admin.js:6301)。
assert.match(page, /download/, '下载链接带 download 强制下载')
assert.match(page, /download\s*>\s*下载\s*<\/a>/, '操作列下载为强制下载链接')
// 上传成功:弹窗保持打开,成功文案留驻可复制(对齐 admin.js:6484-6488)。
assert.match(page, /发布成功。版本:/, '成功文案留驻弹窗')
// 上传成功:弹窗保持打开,成功提示为“发布成功”(对齐新版精简提示)。
assert.match(page, /发布成功/, '成功提示留驻弹窗')
assert.match(page, /uploadMsg/, '成功/失败文案在弹窗内展示')
// 上传弹窗文案(对齐 admin.html:6094-6110)。
assert.match(page, /上传软件 ZIP 包,系统会自动计算 MD5 并存储到 OSS。/, '弹窗描述对齐')
+4 -2
View File
@@ -56,11 +56,13 @@ test('test_task_128_version_upload_invalid_input_rejected', () => {
})
test('test_task_128_version_upload_dependency_failure_returns_actionable_message', () => {
// 依赖失败/提交走 adapter:上传表单纯逻辑;POST /api/admin/version multipart
// 依赖失败/提交走 adapter:上传表单纯逻辑;浏览器直传(presign 签发 → PUT 到 MinIO)由 version-api 编排
const mod = readSource('src/pages/records/version-upload-model.ts')
assert.equal(/axios|http\.|vue/.test(mod), false, '上传表单保持纯逻辑')
const api = readSource('src/pages/records/version-api.ts')
assert.match(api, /uploadSoftwareVersion/)
assert.match(api, /\/api\/admin\/version/)
assert.match(api, /FormData/)
// 直传改造后不再走 multipart FormData,改 presign 预签名地址 + 独立 PUT 直传 MinIO。
assert.match(api, /presign/)
assert.match(api, /\.put\(/)
})
+3 -3
View File
@@ -62,10 +62,10 @@ test('test_task_260_version_invalid_input_rejected', () => {
})
test('test_task_260_version_dependency_failure_returns_actionable_message', () => {
// 依赖失败:成功文案含版本与链接;上传经 API 适配并解析新版本;空态兜底。
// 依赖失败:成功提示精简为“发布成功”;上传经 API 适配并解析新版本;空态兜底。
const page = readSource('src/pages/records/RecordsSoftwareVersionPage.vue')
assert.match(page, /发布成功。版本:/, '成功文案需含版本')
assert.match(page, /,链接:/, '成功文案需含链接')
assert.match(page, /发布成功/, '成功提示留驻弹窗')
assert.match(page, /正在上传/, '上传过程提示含进度')
assert.match(page, /暂无版本/, '空态文案')
const api = readSource('src/pages/records/version-api.ts')
assert.match(api, /parseSoftwareVersionUpload/, '上传适配解析新版本行')