package service import ( "context" "mime/multipart" "os" "path/filepath" "server/internal/db" "server/internal/db/sqlc" "server/internal/model/common" "server/internal/model/response" "server/internal/pkg/httputil" gonanoid "github.com/matoous/go-nanoid/v2" ) type SysFileService struct { store *db.Store } func NewSysFileService(store *db.Store) *SysFileService { return &SysFileService{ store: store, } } // MakeSavedDir 创建目录并返回 func MakeSavedDir(folder string) (string, error) { rootDir, err := os.Getwd() if err != nil { return "", err } uploadDir := filepath.Join(rootDir, "uploads", folder) if err = os.MkdirAll(uploadDir, 0755); err != nil { return "", err } return uploadDir, nil } func (s *SysFileService) ListPage(ctx context.Context, p *common.Pagination) ([]sqlc.File, int64, error) { params := sqlc.GetFilesParams{ Limit: p.PageSize, Offset: (p.Page - 1) * p.PageSize, } total, err := s.store.CountFiles(ctx) if err != nil { return nil, 0, err } list, err := s.store.GetFiles(ctx, params) if err != nil { return nil, 0, err } return response.ToFiles(list), total, nil } func (s *SysFileService) Upload(ctx context.Context, folder string, file *multipart.FileHeader) (*sqlc.CreateFileRow, error) { // 生成文件名 fileID, err := gonanoid.New() if err != nil { return nil, err } savedDir, err := MakeSavedDir(folder) if err != nil { return nil, err } fileExt := filepath.Ext(file.Filename) filename := fileID + fileExt filePath := filepath.Join(folder, filename) // 用于保存文件 savedPath := filepath.Join(savedDir, filename) // 打开上传的文件 src, err := file.Open() if err != nil { return nil, err } defer src.Close() // 创建目标文件 dst, err := os.Create(savedPath) if err != nil { return nil, err } defer dst.Close() // 复制文件内容 if _, err = dst.ReadFrom(src); err != nil { return nil, err } params := sqlc.CreateFileParams{ FileName: filename, FilePath: filePath, OriginalName: file.Filename, FolderName: folder, MimeType: file.Header.Get("Content-Type"), FileSize: file.Size, } result, err := s.store.CreateFile(ctx, params) if err != nil { return nil, err } result.FilePath = httputil.BuildFileUrl(&result.FilePath) return &result, nil }