feat(m8): P1 MinIO 对象存储与文件管理
- 迁移 000023 gateway.file_objects(personal/system 归属隔离 + 部分索引) - internal/platform/storage:minio-go 适配(端点 scheme 剥离、流式 PutObject/Open/Delete) - internal/workbench/files.go:FileService(sha256 校验、PutObject-then-insert 回滚、delete 先删行再删对象) - admin /api/v1/admin/files + portal /api/v1/portal/files 处理器(流式上传下载、Content-Disposition) - RBAC file:read/file:manage;菜单加文件管理 + 门户文件仓库 - compose 增 minio 服务(S3_* anchor、不暴露端口);nginx client_max_body_size 32m→256m - 管理端文件管理页 + 门户个人文件仓;集成测试 TestFileObjectLifecycle 连真 MinIO 通过 - healthz object_storage:true;README/PRODUCTION/进展文档同步 Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,41 @@
|
||||
import axios from 'axios'
|
||||
import request from '@/utils/http'
|
||||
import { useUserStore } from '@/store/modules/user'
|
||||
|
||||
export interface FileObject {
|
||||
id: string
|
||||
original_name: string
|
||||
content_type: string
|
||||
size_bytes: number
|
||||
content_sha256: string
|
||||
scope: string
|
||||
owner_user_id?: string
|
||||
created_by: string
|
||||
created_at: string
|
||||
updated_at: string
|
||||
}
|
||||
|
||||
export const fetchFiles = () => request.get<FileObject[]>({ url: '/api/v1/admin/files' })
|
||||
export const uploadFile = (file: File) => {
|
||||
const form = new FormData()
|
||||
form.append('file', file)
|
||||
return request.post<FileObject>({ url: '/api/v1/admin/files', data: form, timeout: 120000 })
|
||||
}
|
||||
export const deleteFile = (id: string) => request.del({ url: `/api/v1/admin/files/${id}` })
|
||||
|
||||
// 文件体以 blob 流式下载,绕开统一响应拦截器(其期望 JSON envelope)。
|
||||
export async function downloadFile(id: string, filename: string) {
|
||||
const { accessToken } = useUserStore()
|
||||
const token = accessToken.startsWith('Bearer ') ? accessToken : `Bearer ${accessToken}`
|
||||
const res = await axios.get(`/api/v1/admin/files/${id}/download`, {
|
||||
baseURL: import.meta.env.VITE_API_URL,
|
||||
headers: { Authorization: token },
|
||||
responseType: 'blob'
|
||||
})
|
||||
const url = URL.createObjectURL(res.data)
|
||||
const anchor = document.createElement('a')
|
||||
anchor.href = url
|
||||
anchor.download = filename
|
||||
anchor.click()
|
||||
URL.revokeObjectURL(url)
|
||||
}
|
||||
Reference in New Issue
Block a user