feat: 初始提交云印享付费打印服务后端
This commit is contained in:
141
cloudprint-backend/internal/grpc/service/file_service.go
Normal file
141
cloudprint-backend/internal/grpc/service/file_service.go
Normal file
@@ -0,0 +1,141 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io"
|
||||
|
||||
"github.com/cloudprint/cloudprint-backend/internal/service"
|
||||
pb "github.com/cloudprint/cloudprint-backend/proto/generated"
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/status"
|
||||
)
|
||||
|
||||
type FileServiceServer struct {
|
||||
pb.UnimplementedFileServiceServer
|
||||
fileService *service.FileService
|
||||
}
|
||||
|
||||
func NewFileServiceServer(fileService *service.FileService) *FileServiceServer {
|
||||
return &FileServiceServer{
|
||||
fileService: fileService,
|
||||
}
|
||||
}
|
||||
|
||||
func (s *FileServiceServer) Upload(stream pb.FileService_UploadServer) (*pb.UploadResponse, error) {
|
||||
var fileName, fileType, uploaderType string
|
||||
var uploaderID int32
|
||||
var totalSize int64
|
||||
var chunks [][]byte
|
||||
|
||||
for {
|
||||
req, err := stream.Recv()
|
||||
if err == io.EOF {
|
||||
break
|
||||
}
|
||||
if err != nil {
|
||||
return nil, status.Errorf(codes.Internal, "receive chunk failed: %v", err)
|
||||
}
|
||||
|
||||
if fileName == "" {
|
||||
fileName = req.FileName
|
||||
fileType = req.FileType
|
||||
uploaderType = "user" // Extract from context in production
|
||||
uploaderID = 1 // Extract from context in production
|
||||
totalSize = req.FileSize
|
||||
}
|
||||
|
||||
chunks = append(chunks, req.Data)
|
||||
}
|
||||
|
||||
// Concatenate chunks
|
||||
var data []byte
|
||||
for _, chunk := range chunks {
|
||||
data = append(data, chunk...)
|
||||
}
|
||||
|
||||
file, err := s.fileService.Upload(stream.Context(), fileName, fileType, uploaderType, uploaderID, data)
|
||||
if err != nil {
|
||||
return nil, status.Errorf(codes.Internal, "upload failed: %v", err)
|
||||
}
|
||||
|
||||
return &pb.UploadResponse{
|
||||
FileId: file.ID,
|
||||
FilePath: file.FilePath,
|
||||
FileUrl: file.FilePath,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *FileServiceServer) GetFile(req *pb.GetFileRequest, stream pb.FileService_GetFileServer) error {
|
||||
file, err := s.fileService.GetFile(stream.Context(), req.FileId)
|
||||
if err != nil || file == nil {
|
||||
return status.Errorf(codes.NotFound, "file not found")
|
||||
}
|
||||
|
||||
reader, err := s.fileService.GetFileReader(stream.Context(), file)
|
||||
if err != nil {
|
||||
return status.Errorf(codes.Internal, "read file failed: %v", err)
|
||||
}
|
||||
defer reader.Close()
|
||||
|
||||
buf := make([]byte, 4096)
|
||||
for {
|
||||
n, err := reader.Read(buf)
|
||||
if n > 0 {
|
||||
if err := stream.Send(&pb.FileData{Data: buf[:n], IsLast: false}); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if err == io.EOF {
|
||||
break
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return stream.Send(&pb.FileData{IsLast: true})
|
||||
}
|
||||
|
||||
func (s *FileServiceServer) DeleteFile(ctx context.Context, req *pb.DeleteFileRequest) (*pb.Empty, error) {
|
||||
err := s.fileService.DeleteFile(ctx, req.FileId, "user", 1)
|
||||
if err != nil {
|
||||
return nil, status.Errorf(codes.Internal, "delete file failed: %v", err)
|
||||
}
|
||||
|
||||
return &pb.Empty{}, nil
|
||||
}
|
||||
|
||||
func (s *FileServiceServer) AddWatermark(ctx context.Context, req *pb.WatermarkRequest) (*pb.WatermarkResponse, error) {
|
||||
file, err := s.fileService.AddWatermark(ctx, req.FileId, req.Text, req.Opacity, int(req.Position), int(req.FontSize))
|
||||
if err != nil {
|
||||
return nil, status.Errorf(codes.Internal, "add watermark failed: %v", err)
|
||||
}
|
||||
|
||||
return &pb.WatermarkResponse{
|
||||
FileId: file.ID,
|
||||
FilePath: file.FilePath,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *FileServiceServer) GetFileList(ctx context.Context, req *pb.GetFileListRequest) (*pb.FileListResponse, error) {
|
||||
files, total, err := s.fileService.GetFileList(ctx, req.UploaderType, req.UploaderId, int(req.Page), int(req.PageSize))
|
||||
if err != nil {
|
||||
return nil, status.Errorf(codes.Internal, "get file list failed: %v", err)
|
||||
}
|
||||
|
||||
pbFiles := make([]*pb.FileInfo, 0, len(files))
|
||||
for _, f := range files {
|
||||
pbFiles = append(pbFiles, &pb.FileInfo{
|
||||
Id: f.ID,
|
||||
FileName: f.FileName,
|
||||
FilePath: f.FilePath,
|
||||
FileType: f.FileType,
|
||||
FileSize: f.FileSize,
|
||||
})
|
||||
}
|
||||
|
||||
return &pb.FileListResponse{
|
||||
Files: pbFiles,
|
||||
Total: int32(total),
|
||||
}, nil
|
||||
}
|
||||
Reference in New Issue
Block a user