264 lines
8.7 KiB
Go
264 lines
8.7 KiB
Go
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
|
||
// }
|