103 lines
2.1 KiB
Go
103 lines
2.1 KiB
Go
package service
|
||
|
||
import (
|
||
"fmt"
|
||
"mime/multipart"
|
||
"os"
|
||
"path"
|
||
"runtime"
|
||
"slices"
|
||
"strings"
|
||
"time"
|
||
err2 "yintai-api/app/common/err"
|
||
"yintai-api/app/common/service"
|
||
|
||
"github.com/gin-gonic/gin"
|
||
log "github.com/sirupsen/logrus"
|
||
"github.com/smbrave/goutil"
|
||
)
|
||
|
||
type Files struct{}
|
||
|
||
// 直接上传到七牛云上。返回保存的地址,访问的url每次都用新的
|
||
|
||
func (f Files) UploadToken() string {
|
||
return service.NewQiniu().UploadToken()
|
||
}
|
||
|
||
func (f Files) Upload(file *multipart.FileHeader, ctx *gin.Context) any {
|
||
start := time.Now()
|
||
defer log.Debug(" [all] time cost:", time.Since(start))
|
||
if file == nil {
|
||
err2.ParamErr("file is nil")
|
||
return nil
|
||
}
|
||
|
||
// support check
|
||
if err := f.Support(path.Ext(file.Filename), file.Size); err != nil {
|
||
err2.ParamErr(err)
|
||
}
|
||
|
||
// 保存本地临时文件
|
||
dst := f.Dst(file.Filename)
|
||
if runtime.GOOS == "windows" {
|
||
dst = dst[1:]
|
||
}
|
||
|
||
err := ctx.SaveUploadedFile(file, dst)
|
||
if err != nil {
|
||
err2.InnerErr(err)
|
||
}
|
||
|
||
objectKey := service.NewQiniu().Save(dst, f.ObjectKey(file.Filename))
|
||
|
||
defer func() {
|
||
_ = os.Remove(dst)
|
||
}()
|
||
|
||
return service.NewQiniu().ForeverUrl(objectKey)
|
||
}
|
||
|
||
func (f Files) ObjectKey(ext string) string {
|
||
return fmt.Sprintf("yintai/%s", f.Name(ext))
|
||
}
|
||
|
||
func (f Files) Dst(ext string) string {
|
||
return "/tmp/" + f.Name(ext)
|
||
}
|
||
|
||
func (f Files) Name(ext string) string {
|
||
now := time.Now().Format("20060102150405")
|
||
return fmt.Sprintf("%s_%s%s", now, goutil.RandomStr(4), ext)
|
||
|
||
}
|
||
|
||
func (f Files) Support(ext string, size int64) error {
|
||
video := []string{"mp4", "m3u8"}
|
||
audio := []string{"mp3"}
|
||
img := []string{"png", "jpg", "jpeg", "jpg", "svg", "gif", "webp"}
|
||
doc := []string{"ppt", "xls", "xlsx", "pptx", "pdf"}
|
||
|
||
type T struct {
|
||
support []string
|
||
size int64
|
||
}
|
||
|
||
x := make([]T, 0)
|
||
x = append(x, T{support: video, size: 30 << 20})
|
||
x = append(x, T{support: audio, size: 30 << 20})
|
||
x = append(x, T{support: img, size: 10 << 20})
|
||
x = append(x, T{support: doc, size: 120 << 20})
|
||
|
||
for _, t := range x {
|
||
ext = strings.TrimLeft(ext, ".")
|
||
if slices.Contains(t.support, ext) {
|
||
if size > t.size {
|
||
return fmt.Errorf("file too large")
|
||
}
|
||
}
|
||
}
|
||
|
||
return nil
|
||
}
|