84 lines
2.5 KiB
Go
84 lines
2.5 KiB
Go
package file
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"io"
|
|
"mime/multipart"
|
|
"net/http"
|
|
"net/url"
|
|
"path/filepath"
|
|
"strings"
|
|
|
|
"github.com/google/uuid"
|
|
"github.com/tencentyun/cos-go-sdk-v5"
|
|
"knowlege-lsxd/internal/types/interfaces"
|
|
)
|
|
|
|
// cosFileService implements the FileService interface for Tencent Cloud COS
|
|
type cosFileService struct {
|
|
client *cos.Client
|
|
bucketURL string
|
|
cosPathPrefix string
|
|
}
|
|
|
|
// NewCosFileService creates a new COS file service instance
|
|
func NewCosFileService(appId, region, secretId, secretKey, cosPathPrefix string) (interfaces.FileService, error) {
|
|
bucketURL := fmt.Sprintf("https://%s.cos.%s.myqcloud.com", appId, region)
|
|
u, err := url.Parse(bucketURL)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to parse bucketURL: %w", err)
|
|
}
|
|
b := &cos.BaseURL{BucketURL: u}
|
|
client := cos.NewClient(b, &http.Client{
|
|
Transport: &cos.AuthorizationTransport{
|
|
SecretID: secretId,
|
|
SecretKey: secretKey,
|
|
},
|
|
})
|
|
return &cosFileService{
|
|
client: client,
|
|
bucketURL: bucketURL,
|
|
cosPathPrefix: cosPathPrefix,
|
|
}, nil
|
|
}
|
|
|
|
// SaveFile saves a file to COS storage
|
|
// It generates a unique name for the file and organizes it by tenant and knowledge ID
|
|
func (s *cosFileService) SaveFile(ctx context.Context,
|
|
file *multipart.FileHeader, tenantID uint, knowledgeID string,
|
|
) (string, error) {
|
|
ext := filepath.Ext(file.Filename)
|
|
objectName := fmt.Sprintf("%s/%d/%s/%s%s", s.cosPathPrefix, tenantID, knowledgeID, uuid.New().String(), ext)
|
|
src, err := file.Open()
|
|
if err != nil {
|
|
return "", fmt.Errorf("failed to open file: %w", err)
|
|
}
|
|
defer src.Close()
|
|
_, err = s.client.Object.Put(ctx, objectName, src, nil)
|
|
if err != nil {
|
|
return "", fmt.Errorf("failed to upload file to COS: %w", err)
|
|
}
|
|
return fmt.Sprintf("https://%s/%s", s.bucketURL, objectName), nil
|
|
}
|
|
|
|
// GetFile retrieves a file from COS storage by its path URL
|
|
func (s *cosFileService) GetFile(ctx context.Context, filePathUrl string) (io.ReadCloser, error) {
|
|
objectName := strings.TrimPrefix(filePathUrl, s.bucketURL)
|
|
resp, err := s.client.Object.Get(ctx, objectName, nil)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to get file from COS: %w", err)
|
|
}
|
|
return resp.Body, nil
|
|
}
|
|
|
|
// DeleteFile removes a file from COS storage
|
|
func (s *cosFileService) DeleteFile(ctx context.Context, filePath string) error {
|
|
objectName := strings.TrimPrefix(filePath, s.bucketURL)
|
|
_, err := s.client.Object.Delete(ctx, objectName)
|
|
if err != nil {
|
|
return fmt.Errorf("failed to delete file: %w", err)
|
|
}
|
|
return nil
|
|
}
|