feat: 初始提交云印享付费打印服务后端
This commit is contained in:
105
cloudprint-backend/internal/service/file_service.go
Normal file
105
cloudprint-backend/internal/service/file_service.go
Normal file
@@ -0,0 +1,105 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/cloudprint/cloudprint-backend/internal/model"
|
||||
"github.com/cloudprint/cloudprint-backend/internal/repository"
|
||||
"github.com/cloudprint/cloudprint-backend/pkg/upload"
|
||||
)
|
||||
|
||||
type FileService struct {
|
||||
fileRepo *repository.FileRepository
|
||||
uploader *upload.FileUploader
|
||||
uploadDir string
|
||||
}
|
||||
|
||||
func NewFileService(fileRepo *repository.FileRepository, uploader *upload.FileUploader, uploadDir string) *FileService {
|
||||
return &FileService{
|
||||
fileRepo: fileRepo,
|
||||
uploader: uploader,
|
||||
uploadDir: uploadDir,
|
||||
}
|
||||
}
|
||||
|
||||
func (s *FileService) Upload(ctx context.Context, fileName string, fileType string, uploaderType string, uploaderID int32, data []byte) (*model.File, error) {
|
||||
if !s.uploader.ValidateFileType(fileName) {
|
||||
return nil, fmt.Errorf("file type not allowed")
|
||||
}
|
||||
|
||||
// Save file
|
||||
filePath := s.uploader.GenerateFilePath(fileName)
|
||||
fullPath := s.uploader.GetFilePath(filePath)
|
||||
|
||||
if err := os.WriteFile(fullPath, data, 0644); err != nil {
|
||||
return nil, fmt.Errorf("failed to write file: %w", err)
|
||||
}
|
||||
|
||||
// Create file record
|
||||
file := &model.File{
|
||||
FileName: fileName,
|
||||
FilePath: filePath,
|
||||
FileType: strings.ToLower(fileType),
|
||||
FileSize: int64(len(data)),
|
||||
UploaderType: uploaderType,
|
||||
UploaderID: uploaderID,
|
||||
}
|
||||
|
||||
if err := s.fileRepo.Create(ctx, file); err != nil {
|
||||
// Clean up file on error
|
||||
os.Remove(fullPath)
|
||||
return nil, fmt.Errorf("failed to create file record: %w", err)
|
||||
}
|
||||
|
||||
return file, nil
|
||||
}
|
||||
|
||||
func (s *FileService) GetFile(ctx context.Context, fileID int32) (*model.File, error) {
|
||||
return s.fileRepo.GetByID(ctx, fileID)
|
||||
}
|
||||
|
||||
func (s *FileService) GetFileReader(ctx context.Context, file *model.File) (io.ReadCloser, error) {
|
||||
fullPath := filepath.Join(s.uploadDir, file.FilePath)
|
||||
return os.Open(fullPath)
|
||||
}
|
||||
|
||||
func (s *FileService) DeleteFile(ctx context.Context, fileID int32, uploaderType string, uploaderID int32) error {
|
||||
file, err := s.fileRepo.GetByID(ctx, fileID)
|
||||
if err != nil || file == nil {
|
||||
return fmt.Errorf("file not found")
|
||||
}
|
||||
|
||||
// Verify ownership
|
||||
if file.UploaderType != uploaderType || file.UploaderID != uploaderID {
|
||||
return fmt.Errorf("unauthorized")
|
||||
}
|
||||
|
||||
// Delete physical file
|
||||
fullPath := s.uploader.GetFilePath(file.FilePath)
|
||||
os.Remove(fullPath)
|
||||
|
||||
// Delete record
|
||||
return s.fileRepo.Delete(ctx, fileID)
|
||||
}
|
||||
|
||||
func (s *FileService) GetFileList(ctx context.Context, uploaderType string, uploaderID int32, page, pageSize int) ([]*model.File, int64, error) {
|
||||
return s.fileRepo.GetListByUploader(ctx, uploaderType, uploaderID, page, pageSize)
|
||||
}
|
||||
|
||||
func (s *FileService) AddWatermark(ctx context.Context, fileID int32, text string, opacity float32, position int, fontSize int) (*model.File, error) {
|
||||
file, err := s.fileRepo.GetByID(ctx, fileID)
|
||||
if err != nil || file == nil {
|
||||
return nil, fmt.Errorf("file not found")
|
||||
}
|
||||
|
||||
// In production, use a PDF library to add watermark
|
||||
// For now, just return the original file
|
||||
// TODO: Implement actual watermark using pdf-lib or similar
|
||||
|
||||
return file, nil
|
||||
}
|
||||
Reference in New Issue
Block a user