121 lines
2.3 KiB
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
|
|
}
|