root 00a0e583a8 添加存储桶删除功能
- 新增 DeleteBucketHandler 处理存储桶删除请求
- 添加 DELETE /buckets API 端点
- 在前端界面添加删除存储桶按钮功能
- 添加存储桶删除请求验证器

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-19 16:40:09 +08:00

118 lines
4.4 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package main
import (
_ "file-system/docs" // Import generated docs
"file-system/internal/api/endpoints"
"file-system/internal/api/handlers"
"file-system/internal/api/validators"
"file-system/internal/common"
"file-system/internal/domain/repository"
"file-system/internal/infrastructure/mediator"
"file-system/internal/infrastructure/s3"
"io"
"net/http"
"github.com/gin-gonic/gin"
swaggerFiles "github.com/swaggo/files"
ginSwagger "github.com/swaggo/gin-swagger"
)
// @title RustFS File System API
// @version 1.1
// @description RustFS 文件存储系统 API支持分片上传、文件预览、分页查询等高级功能。
// @host localhost:8080
// @BasePath /
func main() {
cfg := common.LoadConfig()
// Infrastructure
rustfsClient := s3.NewRustFSClient(cfg)
s3Repo := s3.NewS3FileRepository(rustfsClient)
m := mediator.NewMediator()
// Handlers
uploadHandler := handlers.NewUploadFileHandler(s3Repo)
downloadHandler := handlers.NewDownloadFileHandler(s3Repo)
createBucketHandler := handlers.NewCreateBucketHandler(s3Repo)
listBucketsHandler := handlers.NewListBucketsHandler(s3Repo)
deleteBucketHandler := handlers.NewDeleteBucketHandler(s3Repo)
// New Handlers
listFilesHandler := handlers.NewListFilesHandler(s3Repo)
previewHandler := handlers.NewGetFilePreviewHandler(s3Repo)
initMultipartHandler := handlers.NewInitMultipartHandler(s3Repo)
uploadPartHandler := handlers.NewUploadPartHandler(s3Repo)
completeMultipartHandler := handlers.NewCompleteMultipartHandler(s3Repo)
deleteFileHandler := handlers.NewDeleteFileHandler(s3Repo)
// Register Handlers
mediator.Register[handlers.UploadFileCommand, string](m, uploadHandler)
mediator.Register[handlers.DownloadFileQuery, io.ReadCloser](m, downloadHandler)
mediator.Register[handlers.CreateBucketCommand, string](m, createBucketHandler)
mediator.Register[handlers.ListBucketsQuery, []string](m, listBucketsHandler)
mediator.Register[handlers.DeleteBucketCommand, string](m, deleteBucketHandler)
// New Registrations
mediator.Register[handlers.ListFilesQuery, *repository.ListFilesResult](m, listFilesHandler)
mediator.Register[handlers.GetFilePreviewQuery, string](m, previewHandler)
mediator.Register[handlers.InitMultipartCommand, string](m, initMultipartHandler)
mediator.Register[handlers.UploadPartCommand, string](m, uploadPartHandler)
mediator.Register[handlers.CompleteMultipartCommand, string](m, completeMultipartHandler)
mediator.Register[handlers.DeleteFileCommand, string](m, deleteFileHandler)
// Validators
uploadValidator := validators.NewUploadFileValidator()
downloadValidator := validators.NewDownloadFileValidator()
createBucketValidator := validators.NewCreateBucketValidator()
newFeaturesValidator := validators.NewNewFeaturesValidator()
// Endpoints
fileEndpoint := endpoints.NewFileEndpoint(m, uploadValidator, downloadValidator, newFeaturesValidator)
bucketEndpoint := endpoints.NewBucketEndpoint(m, createBucketValidator)
// Router
r := gin.Default()
// CORS
r.Use(func(c *gin.Context) {
c.Writer.Header().Set("Access-Control-Allow-Origin", "*")
c.Writer.Header().Set("Access-Control-Allow-Credentials", "true")
c.Writer.Header().Set("Access-Control-Allow-Headers", "Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization, accept, origin, Cache-Control, X-Requested-With")
c.Writer.Header().Set("Access-Control-Allow-Methods", "POST, OPTIONS, GET, PUT, DELETE")
if c.Request.Method == "OPTIONS" {
c.AbortWithStatus(204)
return
}
c.Next()
})
// Routes
// File operations
r.POST("/files/upload", fileEndpoint.UploadFile)
r.GET("/files/download", fileEndpoint.DownloadFile)
r.GET("/files/list", fileEndpoint.ListFiles)
r.GET("/files/preview", fileEndpoint.GetPreviewURL)
// Delete file
r.DELETE("/files/delete", fileEndpoint.DeleteFile)
// Multipart Upload
r.POST("/files/multipart/init", fileEndpoint.InitMultipart)
r.PUT("/files/multipart/part", fileEndpoint.UploadPart)
r.POST("/files/multipart/complete", fileEndpoint.CompleteMultipart)
// Bucket operations
r.POST("/buckets", bucketEndpoint.CreateBucket)
r.GET("/buckets", bucketEndpoint.ListBuckets)
r.DELETE("/buckets", bucketEndpoint.DeleteBucket)
// Swagger
r.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler))
// Web UI
r.Static("/web", "./web")
r.GET("/", func(c *gin.Context) {
c.Redirect(http.StatusMovedPermanently, "/web")
})
r.Run(":" + cfg.ServerPort)
}