kra/pkg/upload/upload.go

217 lines
4.7 KiB
Go

package upload
import (
"errors"
"mime/multipart"
"path"
"strings"
"time"
"github.com/google/uuid"
)
var (
ErrFileEmpty = errors.New("文件为空")
ErrFileTooLarge = errors.New("文件过大")
ErrFileTypeError = errors.New("文件类型不允许")
)
// OSS 对象存储接口
type OSS interface {
UploadFile(file *multipart.FileHeader) (string, string, error)
DeleteFile(key string) error
}
// Config 上传配置
type Config struct {
Type string // local, aliyun, tencent, qiniu, minio, aws-s3, huawei-obs, cloudflare-r2
Path string
MaxSize int64
}
// OSSConfig 完整的OSS配置
type OSSConfig struct {
OssType string
// Local配置
LocalPath string
LocalStorePath string
// 七牛云配置
QiniuZone string
QiniuBucket string
QiniuImgPath string
QiniuAccessKey string
QiniuSecretKey string
QiniuUseHTTPS bool
QiniuUseCdnDomains bool
// 腾讯云COS配置
TencentBucket string
TencentRegion string
TencentSecretID string
TencentSecretKey string
TencentBaseURL string
TencentPathPrefix string
// 阿里云OSS配置
AliyunEndpoint string
AliyunAccessKeyID string
AliyunAccessKeySecret string
AliyunBucketName string
AliyunBucketURL string
AliyunBasePath string
// 华为云OBS配置
HuaweiPath string
HuaweiBucket string
HuaweiEndpoint string
HuaweiAccessKey string
HuaweiSecretKey string
// AWS S3配置
AwsBucket string
AwsRegion string
AwsEndpoint string
AwsSecretID string
AwsSecretKey string
AwsBaseURL string
AwsPathPrefix string
AwsS3ForcePathStyle bool
AwsDisableSSL bool
// Cloudflare R2配置
CloudflareBucket string
CloudflareBaseURL string
CloudflarePath string
CloudflareAccountID string
CloudflareAccessKeyID string
CloudflareSecretAccessKey string
// MinIO配置
MinioEndpoint string
MinioAccessKeyID string
MinioAccessKeySecret string
MinioBucketName string
MinioUseSSL bool
MinioBasePath string
MinioBucketURL string
}
// NewOSS 根据配置创建OSS实例
func NewOSS(cfg *OSSConfig) (OSS, error) {
switch cfg.OssType {
case "local":
return NewLocal(cfg.LocalStorePath, cfg.LocalPath), nil
case "qiniu":
return NewQiniu(
cfg.QiniuZone,
cfg.QiniuBucket,
cfg.QiniuImgPath,
cfg.QiniuAccessKey,
cfg.QiniuSecretKey,
cfg.QiniuUseHTTPS,
cfg.QiniuUseCdnDomains,
), nil
case "tencent-cos":
return NewTencent(
cfg.TencentBucket,
cfg.TencentRegion,
cfg.TencentSecretID,
cfg.TencentSecretKey,
cfg.TencentBaseURL,
cfg.TencentPathPrefix,
), nil
case "aliyun-oss":
return NewAliyun(
cfg.AliyunEndpoint,
cfg.AliyunAccessKeyID,
cfg.AliyunAccessKeySecret,
cfg.AliyunBucketName,
cfg.AliyunBucketURL,
cfg.AliyunBasePath,
), nil
case "huawei-obs":
return NewHuaweiObs(
cfg.HuaweiPath,
cfg.HuaweiBucket,
cfg.HuaweiEndpoint,
cfg.HuaweiAccessKey,
cfg.HuaweiSecretKey,
), nil
case "aws-s3":
return NewAwsS3(
cfg.AwsBucket,
cfg.AwsRegion,
cfg.AwsEndpoint,
cfg.AwsSecretID,
cfg.AwsSecretKey,
cfg.AwsBaseURL,
cfg.AwsPathPrefix,
cfg.AwsS3ForcePathStyle,
cfg.AwsDisableSSL,
), nil
case "cloudflare-r2":
return NewCloudflareR2(
cfg.CloudflareBucket,
cfg.CloudflareBaseURL,
cfg.CloudflarePath,
cfg.CloudflareAccountID,
cfg.CloudflareAccessKeyID,
cfg.CloudflareSecretAccessKey,
), nil
case "minio":
return NewMinio(
cfg.MinioAccessKeyID,
cfg.MinioAccessKeySecret,
cfg.MinioBucketName,
cfg.MinioEndpoint,
cfg.MinioBasePath,
cfg.MinioUseSSL,
), nil
default:
return NewLocal(cfg.LocalStorePath, cfg.LocalPath), nil
}
}
// GenerateFileName 生成文件名
func GenerateFileName(originalName string) string {
ext := path.Ext(originalName)
name := uuid.New().String()
return name + ext
}
// GeneratePath 生成存储路径
func GeneratePath(basePath string) string {
now := time.Now()
return path.Join(basePath, now.Format("2006/01/02"))
}
// CheckFileSize 检查文件大小
func CheckFileSize(size int64, maxSize int64) error {
if size > maxSize {
return ErrFileTooLarge
}
return nil
}
// CheckFileType 检查文件类型
func CheckFileType(filename string, allowTypes []string) error {
ext := strings.ToLower(path.Ext(filename))
for _, t := range allowTypes {
if ext == t || t == "*" {
return nil
}
}
return ErrFileTypeError
}
// DefaultAllowTypes 默认允许的文件类型
var DefaultAllowTypes = []string{
".jpg", ".jpeg", ".png", ".gif", ".bmp", ".webp",
".pdf", ".doc", ".docx", ".xls", ".xlsx", ".ppt", ".pptx",
".txt", ".md", ".json", ".xml", ".csv",
".zip", ".rar", ".7z", ".tar", ".gz",
".mp3", ".mp4", ".avi", ".mov", ".wmv",
}