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