Files
苏尹岚 0f96fb73d0 aa
2020-12-28 14:55:21 +08:00

264 lines
8.7 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package datares
import (
"bytes"
"fmt"
"image"
"image/gif"
"image/jpeg"
"image/png"
"net/http"
"git.rosy.net.cn/jx-callback/business/jxutils"
"git.rosy.net.cn/jx-callback/business/jxutils/jxcontext"
"git.rosy.net.cn/jx-callback/business/jxutils/tasksch"
"git.rosy.net.cn/jx-callback/business/model"
"git.rosy.net.cn/jx-callback/business/model/dao"
"git.rosy.net.cn/jx-callback/business/partner"
"git.rosy.net.cn/jx-callback/globals"
"git.rosy.net.cn/jx-callback/globals/api"
"github.com/qiniu/api.v7/storage"
)
const (
qiniuTokenExpires = 300 // 七牛TOKEN有效时间5分钟
MainImgWidth = 800
MainImgHeight = 800
MainImgWidth2 = 500
MainImgHeight2 = 500
)
type UploadResTokenInfo struct {
Token string `json:"token,omitempty"`
Expires uint64 `json:"expires,omitempty"`
FileName string `json:"fileName,omitempty"`
Hit bool `json:"hit,omitempty"`
Img string `json:"img,omitempty"`
}
func Binary2Image(binaryData []byte, mimeType string) (img image.Image, outMimeType string, err error) {
if mimeType == "" {
mimeType = http.DetectContentType(binaryData)
}
switch mimeType {
case model.MimeTypeJpeg:
img, err = jpeg.Decode(bytes.NewReader(binaryData))
case model.MimeTypePng:
img, err = png.Decode(bytes.NewReader(binaryData))
case model.MimeTypeGif:
img, err = gif.Decode(bytes.NewReader(binaryData))
}
return img, mimeType, err
}
func GetQiniuUploadToken(ctx *jxcontext.Context, suffix, hashCode string) (upTokenInfo *UploadResTokenInfo, err error) {
imgURL := ""
if hashCode != "" {
imgURL, _ = GetDataResource(ctx, hashCode)
}
putPolicy := storage.PutPolicy{
Scope: globals.QiniuBucket,
Expires: qiniuTokenExpires,
}
upTokenInfo = &UploadResTokenInfo{
Token: putPolicy.UploadToken(api.QiniuAPI),
Expires: putPolicy.Expires,
FileName: jxutils.GenPicFileName(suffix),
Hit: imgURL != "",
Img: imgURL,
}
return upTokenInfo, err
}
// 此函数要求resBinary不能空mimeType与hashCode必须是正确的
func RegisterDataResource(ctx *jxcontext.Context, name, resourceURL, mimeType, hashCode string, resBinary []byte, imgType int, isAsyncUpload2Vendor bool) (dataRes *model.DataResource, err error) {
globals.SugarLogger.Debugf("RegisterDataResource, name:%s, resourceURL:%s, mimeType:%s, hashCode:%s, imgType:%d, isAsyncUpload2Vendor;%t", name, resourceURL, mimeType, hashCode, imgType, isAsyncUpload2Vendor)
if model.ValidMimeTypes[mimeType] == 0 {
return nil, fmt.Errorf("MIME type:%s非法当前只支持:%s", mimeType, model.GetValidMimeTypeDesc())
}
img, _, err := Binary2Image(resBinary, mimeType)
if err != nil {
return nil, err
}
if imgType == model.ImgTypeMain {
if (img.Bounds().Dx() != MainImgWidth || img.Bounds().Dy() != MainImgHeight) && (img.Bounds().Dx() != MainImgWidth2 || img.Bounds().Dy() != MainImgHeight2) {
return nil, fmt.Errorf("图片大小:%dx%d非法要求必须:%dx%d", img.Bounds().Dx(), img.Bounds().Dy(), MainImgWidth, MainImgHeight)
}
}
dataRes = &model.DataResource{
Name: name,
HashCode: hashCode,
ResourceType: mimeType,
MainURL: resourceURL,
UseType: int8(imgType),
}
vendorID := jxutils.GuessDataResourceVendor(resourceURL)
switch vendorID {
case model.VendorIDQiNiuCloud:
dataRes.QiniuURL = resourceURL
case model.VendorIDEBAI:
dataRes.EbaiURL = resourceURL
}
dao.WrapAddIDCULEntity(dataRes, ctx.GetUserName())
if err = dao.CreateEntity(dao.GetDB(), dataRes); err != nil {
if dao.IsDuplicateError(err) {
dataRes, err = dao.GetDataResource(dao.GetDB(), dataRes.HashCode, dataRes.MainURL)
} else {
dataRes = nil
}
return dataRes, err
}
if imgType > 0 {
if globals.EnableStoreWrite {
// 忽略上传错误
UploadImage2Vendors(ctx, nil, dataRes, resBinary, isAsyncUpload2Vendor)
}
}
return dataRes, err
}
func TryRegisterDataResource(ctx *jxcontext.Context, name, resourceURL string, imgType int, isAsyncUpload2Vendor bool) (dataRes *model.DataResource, err error) {
globals.SugarLogger.Debugf("TryRegisterDataResource, name:%s, resourceURL:%s, imgType:%d, isAsyncUpload2Vendor;%t", name, resourceURL, imgType, isAsyncUpload2Vendor)
dataRes = &model.DataResource{
MainURL: resourceURL,
}
err = dao.GetEntity(dao.GetDB(), dataRes, "MainURL")
if err != nil {
if !dao.IsNoRowsError(err) {
return nil, err
}
} else {
return dataRes, nil
}
resBinary, hashCode, err := jxutils.DownloadFileByURL(resourceURL)
if err != nil {
return nil, err
}
return RegisterDataResource(ctx, name, resourceURL, http.DetectContentType(resBinary), hashCode, resBinary, imgType, isAsyncUpload2Vendor)
}
func GetDataResource(ctx *jxcontext.Context, hashCode string) (resourceURL string, err error) {
db := dao.GetDB()
dataRes, err := dao.GetDataResource(db, hashCode, "")
if err != nil {
if dao.IsNoRowsError(err) {
err = nil
}
} else {
resourceURL = dataRes.MainURL
}
return resourceURL, err
}
// 这个函数,可能部分平台成功,部分失败
func UploadImage2Vendors(ctx *jxcontext.Context, parentTask tasksch.ITask, dataRes *model.DataResource, imgData []byte, isAsync bool) (hint string, err error) {
var vendorIDs []int
if dataRes.EbaiURL == "" {
vendorIDs = append(vendorIDs, model.VendorIDEBAI)
}
if dataRes.MtwmURL == "" {
vendorIDs = append(vendorIDs, model.VendorIDMTWM)
}
// if dataRes.JdsURL == "" {
// vendorIDs = append(vendorIDs, model.VendorIDJDShop)
// }
if len(vendorIDs) > 0 {
imgName := jxutils.GetShortNameFromURL(dataRes.MainURL)
task := tasksch.NewSeqTask(fmt.Sprintf("上传图片至平台1:%s,%s", dataRes.Name, dataRes.MainURL), ctx,
func(task *tasksch.SeqTask, step int, params ...interface{}) (result interface{}, err error) {
switch step {
case 0:
if imgData == nil {
if imgData, _, err = jxutils.DownloadFileByURL(dataRes.MainURL); err != nil {
return nil, err
}
}
case 1:
uploadTask := tasksch.NewParallelTask(fmt.Sprintf("上传图片至平台2:%s,%s", dataRes.Name, imgName),
tasksch.NewParallelConfig().SetIsContinueWhenError(true), ctx,
func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) {
vendorID := batchItemList[0].(int)
if handler := partner.GetPurchasePlatformFromVendorID(vendorID); handler != nil {
// TODO vendorOrgCode
imgHint, err2 := handler.UploadImg(ctx, "", dataRes.MainURL, imgData, imgName, int(dataRes.UseType))
if err = err2; err == nil {
retVal = [][]interface{}{
[]interface{}{
vendorID,
imgHint,
},
}
}
}
return retVal, err
}, vendorIDs)
tasksch.HandleTask(uploadTask, task, false).Run()
resultList, err2 := uploadTask.GetResult(0)
err = err2
if len(resultList) > 0 {
db := dao.GetDB()
for _, v := range resultList {
result := v.([]interface{})
vendorID := result[0].(int)
imgHint := result[1].(string)
updateField := ""
if vendorID == model.VendorIDEBAI {
dataRes.EbaiURL = imgHint
updateField = "EbaiURL"
} else if vendorID == model.VendorIDMTWM {
dataRes.MtwmURL = imgHint
updateField = "MtwmURL"
}
// else if vendorID == model.VendorIDJDShop {
// dataRes.JdsURL = imgHint
// updateField = "JdsURL"
// }
dao.UpdateEntity(db, dataRes, updateField)
}
}
}
return result, err
}, 2)
tasksch.HandleTask(task, parentTask, false).Run()
if !isAsync {
if _, err = task.GetResult(0); err == nil {
hint = "1"
}
} else {
hint = task.GetID()
}
}
return hint, err
}
// func UploadImg2Platforms(ctx *jxcontext.Context, parentTask tasksch.ITask, imgURL string, imgData []byte, imgName string) (imgHintMap map[int]string, err error) {
// task := tasksch.NewParallelTask("UploadImg2Platforms", nil, ctx,
// func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) {
// vendorID := batchItemList[0].(int)
// if handler := partner.GetPurchasePlatformFromVendorID(vendorID); handler != nil {
// imgHint, err2 := handler.UploadImg(ctx, imgURL, imgData, imgName)
// if err = err2; err == nil {
// return [][]interface{}{
// []interface{}{
// vendorID,
// imgHint,
// },
// }, nil
// }
// }
// return nil, err
// }, []int{model.VendorIDEBAI})
// tasksch.HandleTask(task, parentTask, false).Run()
// resultList, err := task.GetResult(0)
// if err == nil {
// imgHintMap = make(map[int]string)
// for _, v := range resultList {
// vList := v.([]interface{})
// imgHintMap[vList[0].(int)] = vList[1].(string)
// }
// }
// return imgHintMap, err
// }