file-system/internal/api/handlers/query_handlers.go
root d861be0d6e feat: 新增文件文本内容接口,修复Markdown预览
- 新增 GET /files/content 接口,后端直接读取S3文件文本内容返回
- Repository 新增 GetFileContent 方法
- CQRS: 新增 GetFileContentQuery / GetFileContentHandler
- 前端 Markdown 预览改为调用后端接口获取内容,用 marked.js 渲染
- 解决 presigned URL CORS 和下载头导致 MD 文件无法预览的问题
- config.go: AuthAPIKey 默认值恢复为 xn001624.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-05-06 18:08:42 +08:00

111 lines
2.5 KiB
Go

package handlers
import (
"context"
"file-system/internal/common"
"file-system/internal/domain/repository"
"io"
"time"
)
// Queries & Commands
type ListFilesQuery struct {
BucketName string
Prefix string
MaxKeys int32
Token *string
}
type GetFilePreviewQuery struct {
BucketName string
ObjectKey string
Expiry time.Duration
}
// GetFileContentQuery 获取文件文本内容查询
type GetFileContentQuery struct {
BucketName string
ObjectKey string
}
type InitMultipartCommand struct {
BucketName string
ObjectKey string
}
type UploadPartCommand struct {
BucketName string
ObjectKey string
UploadId string
PartNumber int32
Data io.Reader
}
type CompleteMultipartCommand struct {
BucketName string
ObjectKey string
UploadId string
Parts []common.Part
}
// Handlers
type ListFilesHandler struct {
Repo repository.FileRepository
}
func NewListFilesHandler(repo repository.FileRepository) *ListFilesHandler {
return &ListFilesHandler{Repo: repo}
}
func (h *ListFilesHandler) Handle(ctx context.Context, q ListFilesQuery) (*repository.ListFilesResult, error) {
return h.Repo.ListObjectsV2(ctx, q.BucketName, q.Prefix, q.MaxKeys, q.Token)
}
type GetFilePreviewHandler struct {
Repo repository.FileRepository
}
func NewGetFilePreviewHandler(repo repository.FileRepository) *GetFilePreviewHandler {
return &GetFilePreviewHandler{Repo: repo}
}
func (h *GetFilePreviewHandler) Handle(ctx context.Context, q GetFilePreviewQuery) (string, error) {
return h.Repo.GeneratePresignedURL(ctx, q.BucketName, q.ObjectKey, q.Expiry)
}
// GetFileContentHandler 获取文件文本内容处理器
type GetFileContentHandler struct {
Repo repository.FileRepository
}
func NewGetFileContentHandler(repo repository.FileRepository) *GetFileContentHandler {
return &GetFileContentHandler{Repo: repo}
}
func (h *GetFileContentHandler) Handle(ctx context.Context, q GetFileContentQuery) (string, error) {
return h.Repo.GetFileContent(ctx, q.BucketName, q.ObjectKey)
}
// DeleteFileCommand 删除文件命令
type DeleteFileCommand struct {
BucketName string
ObjectKey string
}
type DeleteFileHandler struct {
Repo repository.FileRepository
}
func NewDeleteFileHandler(repo repository.FileRepository) *DeleteFileHandler {
return &DeleteFileHandler{Repo: repo}
}
func (h *DeleteFileHandler) Handle(ctx context.Context, cmd DeleteFileCommand) (string, error) {
err := h.Repo.DeleteFile(ctx, cmd.BucketName, cmd.ObjectKey)
if err != nil {
return "", err
}
return "File deleted successfully", nil
}