package tencentoss import ( "bytes" "context" "errors" "fmt" "io" "io/fs" "mime/multipart" "net/http" "net/url" "os" "path" "management/internal/config" fileutil "management/internal/pkg/file" "github.com/h2non/filetype" "github.com/tencentyun/cos-go-sdk-v5" ) var engine *cos.Client func Init() error { u, err := url.Parse(fmt.Sprintf("https://%s.cos.%s.myqcloud.com", config.File.TencentUpload.Bucket, config.File.TencentUpload.Region)) if err != nil { return err } b := &cos.BaseURL{BucketURL: u} engine = cos.NewClient(b, &http.Client{ Transport: &cos.AuthorizationTransport{ // 通过环境变量获取密钥 // 环境变量 SECRETID 表示用户的 SecretId,登录访问管理控制台查看密钥,https://console.cloud.tencent.com/cam/capi SecretID: config.File.TencentUpload.AccessKeyID, // 用户的 SecretId,建议使用子账号密钥,授权遵循最小权限指引,降低使用风险。子账号密钥获取可参见 https://cloud.tencent.com/document/product/598/37140 // 环境变量 SECRETKEY 表示用户的 SecretKey,登录访问管理控制台查看密钥,https://console.cloud.tencent.com/cam/capi SecretKey: config.File.TencentUpload.AccessKeySecret, // 用户的 SecretKey,建议使用子账号密钥,授权遵循最小权限指引,降低使用风险。子账号密钥获取可参见 https://cloud.tencent.com/document/product/598/37140 }, }) return nil } func UploadFile(ctx context.Context, file *multipart.FileHeader, t fileutil.FileType) (string, error) { if file.Size > config.File.TencentUpload.AllowFileMaxSize { return "", errors.New("failed to receive file too large") } fileOpen, err := file.Open() if err != nil { return "", errors.New("failed to file open") } defer func(fileOpen multipart.File) { _ = fileOpen.Close() }(fileOpen) fileBytes, err := io.ReadAll(fileOpen) if err != nil { return "", errors.New("failed to read file") } if t == fileutil.IMG { // 判断是不是图片 if !filetype.IsImage(fileBytes) { return "", fileutil.ErrUnsupported } } kind, err := filetype.Match(fileBytes) if err != nil || kind == filetype.Unknown { return "", errors.New("failed to get file type") } filename := fileutil.GenFilename(kind.Extension) imgPath := path.Join(fileutil.GetPath(), filename) _, err = engine.Object.Put(ctx, imgPath, bytes.NewReader(fileBytes), nil) if err != nil { return "", err } return imgPath, nil } func UploadFileOther(ctx context.Context, p string, t fileutil.FileType) (string, error) { file, err := os.Open(p) if err != nil { return "", err } defer func(file *os.File) { _ = file.Close() }(file) fileBytes, err := io.ReadAll(file) if err != nil { return "", errors.New("failed to read file") } if t == fileutil.IMG { // 判断是不是图片 if !filetype.IsImage(fileBytes) { return "", fileutil.ErrUnsupported } } kind, err := filetype.Match(fileBytes) if err != nil || kind == filetype.Unknown { return "", errors.New("failed to get file type") } filename := fileutil.GenFilename(kind.Extension) imgPath := path.Join(fileutil.GetPath(), filename) _, err = engine.Object.Put(ctx, imgPath, bytes.NewReader(fileBytes), nil) if err != nil { return "", err } return imgPath, nil } func UploadFileByFS(ctx context.Context, file fs.File, t fileutil.FileType) (string, error) { fileBytes, err := io.ReadAll(file) if err != nil { return "", errors.New("failed to read file") } if t == fileutil.IMG { // 判断是不是图片 if !filetype.IsImage(fileBytes) { return "", fileutil.ErrUnsupported } } kind, err := filetype.Match(fileBytes) if err != nil || kind == filetype.Unknown { return "", errors.New("failed to get file type") } filename := fileutil.GenFilename(kind.Extension) imgPath := path.Join(fileutil.GetPath(), filename) _, err = engine.Object.Put(ctx, imgPath, bytes.NewReader(fileBytes), nil) if err != nil { return "", err } return imgPath, nil } func DownloadFile(ctx context.Context, name string) ([]byte, error) { resp, err := engine.Object.Get(ctx, name, nil) if err != nil { return nil, err } defer resp.Body.Close() bs, err := io.ReadAll(resp.Body) if err != nil { return nil, err } return bs, nil }