Files
blog-server/internal/service/admin/file.go

121 lines
2.3 KiB
Go

package admin
import (
"context"
"mime/multipart"
"os"
"path/filepath"
"server/internal/db"
"server/internal/db/sqlc"
"server/internal/model/common"
"server/internal/pkg/httputil"
gonanoid "github.com/matoous/go-nanoid/v2"
)
type FileService struct {
store *db.Store
}
func NewFileService(store *db.Store) *FileService {
return &FileService{
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 *FileService) List(ctx context.Context, p *common.Pagination) (*common.PageResult[sqlc.File], error) {
params := sqlc.ListFilesParams{
Limit: p.PageSize,
Offset: (p.Page - 1) * p.PageSize,
}
total, err := s.store.CountFiles(ctx)
if err != nil {
return nil, err
}
list, err := s.store.ListFiles(ctx, params)
if err != nil {
return nil, err
}
return &common.PageResult[sqlc.File]{
List: list,
Total: total,
}, nil
}
func (s *FileService) 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,
FileUrl: httputil.BuildFileUrl(&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
}
return &result, nil
}