mirror of https://github.com/rocboss/paopao-ce
parent
20d9f182ce
commit
5d119c3e25
@ -1,259 +0,0 @@
|
||||
// Copyright 2022 ROC. All rights reserved.
|
||||
// Use of this source code is governed by a MIT style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package api
|
||||
|
||||
import (
|
||||
"image"
|
||||
|
||||
"github.com/disintegration/imaging"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/gofrs/uuid"
|
||||
"github.com/rocboss/paopao-ce/internal/core"
|
||||
"github.com/rocboss/paopao-ce/internal/servants/web/broker"
|
||||
"github.com/rocboss/paopao-ce/pkg/app"
|
||||
"github.com/rocboss/paopao-ce/pkg/convert"
|
||||
"github.com/rocboss/paopao-ce/pkg/errcode"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
var uploadAttachmentTypeMap = map[string]core.AttachmentType{
|
||||
"public/image": core.AttachmentTypeImage,
|
||||
"public/avatar": core.AttachmentTypeImage,
|
||||
"public/video": core.AttachmentTypeVideo,
|
||||
"attachment": core.AttachmentTypeOther,
|
||||
}
|
||||
|
||||
func GeneratePath(s string) string {
|
||||
n := len(s)
|
||||
if n <= 2 {
|
||||
return s
|
||||
}
|
||||
|
||||
return GeneratePath(s[:n-2]) + "/" + s[n-2:]
|
||||
}
|
||||
|
||||
func GetFileExt(s string) (string, error) {
|
||||
switch s {
|
||||
case "image/png":
|
||||
return ".png", nil
|
||||
case "image/jpg":
|
||||
return ".jpg", nil
|
||||
case "image/jpeg":
|
||||
return ".jpeg", nil
|
||||
case "image/gif":
|
||||
return ".gif", nil
|
||||
case "video/mp4":
|
||||
return ".mp4", nil
|
||||
case "video/quicktime":
|
||||
return ".mov", nil
|
||||
case "application/zip",
|
||||
"application/x-zip",
|
||||
"application/octet-stream",
|
||||
"application/x-zip-compressed":
|
||||
return ".zip", nil
|
||||
default:
|
||||
return "", errcode.FileInvalidExt.WithDetails("仅允许 png/jpg/gif/mp4/mov/zip 类型")
|
||||
}
|
||||
}
|
||||
func GetImageSize(img image.Rectangle) (int, int) {
|
||||
b := img.Bounds()
|
||||
width := b.Max.X
|
||||
height := b.Max.Y
|
||||
return width, height
|
||||
}
|
||||
|
||||
func fileCheck(uploadType string, size int64) error {
|
||||
if uploadType != "public/video" &&
|
||||
uploadType != "public/image" &&
|
||||
uploadType != "public/avatar" &&
|
||||
uploadType != "attachment" {
|
||||
return errcode.InvalidParams
|
||||
}
|
||||
|
||||
if size > 1024*1024*100 {
|
||||
return errcode.FileInvalidSize.WithDetails("最大允许100MB")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func UploadAttachment(c *gin.Context) {
|
||||
response := app.NewResponse(c)
|
||||
|
||||
uploadType := c.Request.FormValue("type")
|
||||
file, fileHeader, err := c.Request.FormFile("file")
|
||||
if err != nil {
|
||||
logrus.Errorf("api.UploadAttachment err: %v", err)
|
||||
response.ToErrorResponse(errcode.FileUploadFailed)
|
||||
return
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
if err = fileCheck(uploadType, fileHeader.Size); err != nil {
|
||||
cErr, _ := err.(*errcode.Error)
|
||||
response.ToErrorResponse(cErr)
|
||||
return
|
||||
}
|
||||
|
||||
contentType := fileHeader.Header.Get("Content-Type")
|
||||
fileExt, err := GetFileExt(fileHeader.Header.Get("Content-Type"))
|
||||
if err != nil {
|
||||
logrus.Errorf("GetFileExt err: %v", err)
|
||||
response.ToErrorResponse(err.(*errcode.Error))
|
||||
return
|
||||
}
|
||||
|
||||
// 生成随机路径
|
||||
randomPath := uuid.Must(uuid.NewV4()).String()
|
||||
ossSavePath := uploadType + "/" + GeneratePath(randomPath[:8]) + "/" + randomPath[9:] + fileExt
|
||||
|
||||
objectUrl, err := objectStorage.PutObject(ossSavePath, file, fileHeader.Size, contentType, false)
|
||||
if err != nil {
|
||||
logrus.Errorf("putObject err: %v", err)
|
||||
response.ToErrorResponse(errcode.FileUploadFailed)
|
||||
return
|
||||
}
|
||||
|
||||
// 构造附件Model
|
||||
attachment := &core.Attachment{
|
||||
FileSize: fileHeader.Size,
|
||||
Content: objectUrl,
|
||||
}
|
||||
|
||||
if userID, exists := c.Get("UID"); exists {
|
||||
attachment.UserID = userID.(int64)
|
||||
}
|
||||
|
||||
attachment.Type = uploadAttachmentTypeMap[uploadType]
|
||||
if attachment.Type == core.AttachmentTypeImage {
|
||||
var src image.Image
|
||||
src, err = imaging.Decode(file)
|
||||
if err == nil {
|
||||
attachment.ImgWidth, attachment.ImgHeight = GetImageSize(src.Bounds())
|
||||
}
|
||||
}
|
||||
|
||||
attachment, err = broker.CreateAttachment(attachment)
|
||||
if err != nil {
|
||||
logrus.Errorf("service.CreateAttachment err: %v", err)
|
||||
response.ToErrorResponse(errcode.FileUploadFailed)
|
||||
}
|
||||
|
||||
response.ToResponse(attachment)
|
||||
}
|
||||
|
||||
func DownloadAttachmentPrecheck(c *gin.Context) {
|
||||
response := app.NewResponse(c)
|
||||
|
||||
contentID := convert.StrTo(c.Query("id")).MustInt64()
|
||||
// 加载content
|
||||
content, err := broker.GetPostContentByID(contentID)
|
||||
if err != nil {
|
||||
logrus.Errorf("service.GetPostContentByID err: %v", err)
|
||||
response.ToErrorResponse(errcode.InvalidDownloadReq)
|
||||
}
|
||||
user, _ := c.Get("USER")
|
||||
if content.Type == core.ContentTypeChargeAttachment {
|
||||
// 加载post
|
||||
post, err := broker.GetPost(content.PostID)
|
||||
if err != nil {
|
||||
logrus.Errorf("service.GetPost err: %v", err)
|
||||
response.ToResponse(gin.H{
|
||||
"paid": false,
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// 发布者或管理员免费下载
|
||||
if post.UserID == user.(*core.User).ID || user.(*core.User).IsAdmin {
|
||||
response.ToResponse(gin.H{
|
||||
"paid": true,
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// 检测是否有购买记录
|
||||
response.ToResponse(gin.H{
|
||||
"paid": broker.CheckPostAttachmentIsPaid(post.ID, user.(*core.User).ID),
|
||||
})
|
||||
return
|
||||
}
|
||||
response.ToResponse(gin.H{
|
||||
"paid": false,
|
||||
})
|
||||
}
|
||||
|
||||
func DownloadAttachment(c *gin.Context) {
|
||||
response := app.NewResponse(c)
|
||||
|
||||
contentID := convert.StrTo(c.Query("id")).MustInt64()
|
||||
|
||||
// 加载content
|
||||
content, err := broker.GetPostContentByID(contentID)
|
||||
if err != nil {
|
||||
logrus.Errorf("service.GetPostContentByID err: %v", err)
|
||||
response.ToErrorResponse(errcode.InvalidDownloadReq)
|
||||
}
|
||||
|
||||
// 收费附件
|
||||
if content.Type == core.ContentTypeChargeAttachment {
|
||||
user, _ := c.Get("USER")
|
||||
|
||||
// 加载post
|
||||
post, err := broker.GetPost(content.PostID)
|
||||
if err != nil {
|
||||
logrus.Errorf("service.GetPost err: %v", err)
|
||||
response.ToResponse(gin.H{
|
||||
"paid": false,
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
paidFlag := false
|
||||
|
||||
// 发布者或管理员免费下载
|
||||
if post.UserID == user.(*core.User).ID || user.(*core.User).IsAdmin {
|
||||
paidFlag = true
|
||||
}
|
||||
|
||||
// 检测是否有购买记录
|
||||
if broker.CheckPostAttachmentIsPaid(post.ID, user.(*core.User).ID) {
|
||||
paidFlag = true
|
||||
}
|
||||
|
||||
if !paidFlag {
|
||||
// 未购买,则尝试购买
|
||||
err := broker.BuyPostAttachment(&core.Post{
|
||||
Model: &core.Model{
|
||||
ID: post.ID,
|
||||
},
|
||||
UserID: post.UserID,
|
||||
AttachmentPrice: post.AttachmentPrice,
|
||||
}, user.(*core.User))
|
||||
if err != nil {
|
||||
logrus.Errorf("service.BuyPostAttachment err: %v", err)
|
||||
if err == errcode.InsuffientDownloadMoney {
|
||||
|
||||
response.ToErrorResponse(errcode.InsuffientDownloadMoney)
|
||||
} else {
|
||||
|
||||
response.ToErrorResponse(errcode.DownloadExecFail)
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
objectKey := objectStorage.ObjectKey(content.Content)
|
||||
signedURL, err := objectStorage.SignURL(objectKey, 60)
|
||||
if err != nil {
|
||||
logrus.Errorf("client.SignURL err: %v", err)
|
||||
response.ToErrorResponse(errcode.DownloadReqError)
|
||||
return
|
||||
}
|
||||
response.ToResponse(gin.H{
|
||||
"signed_url": signedURL,
|
||||
})
|
||||
}
|
Loading…
Reference in new issue