fusenapi/service/repositories/image_handle.go
2023-09-12 17:54:31 +08:00

520 lines
14 KiB
Go
Raw 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 repositories
import (
"context"
"encoding/json"
"errors"
"fusenapi/constants"
"fusenapi/model/gmodel"
"fusenapi/utils/curl"
"fusenapi/utils/file"
"fusenapi/utils/hash"
"time"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/zeromicro/go-zero/core/logc"
"github.com/zeromicro/go-zero/core/logx"
"gorm.io/gorm"
)
func NewImageHandle(gormDB *gorm.DB, bLMServiceUrl *string, awsSession *session.Session) ImageHandle {
return &defaultImageHandle{
MysqlConn: gormDB,
BLMServiceUrl: bLMServiceUrl,
AwsSession: awsSession,
}
}
type (
defaultImageHandle struct {
MysqlConn *gorm.DB
BLMServiceUrl *string
AwsSession *session.Session
}
ImageHandle = interface {
// 获取logo最新信息
LogoInfo(ctx context.Context, in *LogoInfoReq) (*LogoInfoRes, error)
// logo信息
LogoInfoSet(ctx context.Context, in *LogoInfoSetReq) (*LogoInfoSetRes, error)
// logo合图
LogoCombine(ctx context.Context, in *LogoCombineReq) (*LogoCombineRes, error)
// logo裁剪
LogoStandard(ctx context.Context, in *LogoStandardReq) (*LogoStandardRes, error)
}
)
/* 获取logo最新信息 */
type (
LogoInfoReq struct {
UserId int64 `json:"user_id"`
GuestId int64 `json:"guest_id"`
}
LogoInfoRes struct {
Metadata *string `json:"metadata"`
LogoUrl *string `json:"logo_url"`
}
)
func (l *defaultImageHandle) LogoInfo(ctx context.Context, in *LogoInfoReq) (*LogoInfoRes, error) {
var metadata *string
var logoUrl *string
// 更新用户信息
var module = "profile"
userInfoGorm := l.MysqlConn.Where("module = ?", module)
userInfo := gmodel.FsUserInfo{}
if in.UserId > 0 {
userInfoGorm.Where("user_id = ?", in.UserId)
userInfo.UserId = &in.UserId
} else {
userInfoGorm.Where("guest_id = ?", in.GuestId)
userInfo.GuestId = &in.GuestId
}
resFirst := userInfoGorm.First(&userInfo)
err := resFirst.Error
if err != nil {
if err != gorm.ErrRecordNotFound {
logc.Errorf(ctx, "FsUserInfo First err%+v", err)
return nil, err
}
}
var userMaterialInfo gmodel.FsUserMaterial
userMaterialModel := gmodel.NewFsUserMaterialModel(l.MysqlConn)
if userInfo.Id == 0 {
userMaterialInfo, err = userMaterialModel.FindLatestOne(ctx, in.UserId, in.GuestId)
if err != gorm.ErrRecordNotFound {
logc.Errorf(ctx, "FsUserMaterial FindLatestOne err%+v", err)
return nil, err
}
} else {
if userInfo.Metadata != nil {
var metadata map[string]interface{}
err = json.Unmarshal([]byte(*userInfo.Metadata), &metadata)
if err != nil {
logc.Errorf(ctx, "userInfo.Metadata Unmarshal err%+v", err)
return nil, err
}
logoSelectedId, isEx := metadata["logo_selected_id"]
if isEx {
var materialId int64 = int64(logoSelectedId.(float64))
userMaterialInfos, err := userMaterialModel.FindOneById(ctx, materialId)
if err != nil {
if err != gorm.ErrRecordNotFound {
logc.Errorf(ctx, "FsUserInfo First err%+v", err)
return nil, err
}
}
if userMaterialInfos.Id != 0 {
userMaterialInfo = *userMaterialInfos
}
}
}
}
if userMaterialInfo.Id == 0 {
userMaterialInfoDefault, err := userMaterialModel.FindOneById(ctx, 0)
if err != nil {
if err != gorm.ErrRecordNotFound {
logc.Errorf(ctx, "userMaterialModel FindOneById defaul err%+v", err)
return nil, err
}
}
metadataB := string(*userMaterialInfoDefault.Metadata)
metadata = &metadataB
logoUrl = userMaterialInfoDefault.ResourceUrl
} else {
metadataB := string(*userMaterialInfo.Metadata)
metadata = &metadataB
logoUrl = userMaterialInfo.ResourceUrl
}
return &LogoInfoRes{
Metadata: metadata,
LogoUrl: logoUrl,
}, nil
}
/* 获取logo最新信息 */
/* logo信息 */
type (
LogoInfoSetReq struct {
LogoUrl string `json:"logo_url"`
}
LogoInfoSetRes struct {
Res string `json:"res"`
}
)
func (l *defaultImageHandle) LogoInfoSet(ctx context.Context, in *LogoInfoSetReq) (*LogoInfoSetRes, error) {
var resultBLM constants.BLMServiceUrlResult
postMap := make(map[string]string, 1)
postMap["logo_url"] = in.LogoUrl
logc.Infof(ctx, "算法请求--LOGO基础信息--开始时间:%v", time.Now().UTC())
err := curl.NewClient(ctx, &curl.Config{
BaseUrl: *l.BLMServiceUrl,
Url: constants.BLMServiceUrlLogoFeatureExtraction,
}).PostJson(postMap, &resultBLM)
logc.Infof(ctx, "算法请求--LOGO基础信息--结束时间:%v", time.Now().UTC())
if err != nil {
logx.Error(err)
return nil, err
}
if resultBLM.Code != "200" {
err = errors.New(resultBLM.Msg)
logx.Error(err)
return nil, err
}
return &LogoInfoSetRes{
Res: resultBLM.Data.(string),
}, nil
}
/* logo信息 */
/* logo合图 */
type (
LogoCombineReq struct {
UserId int64 `json:"user_id"`
GuestId int64 `json:"guest_id"`
TemplateId int64 `json:"template_id"`
TemplateTag string `json:"template_tag"`
Website string `json:"website"` // 合图参数
Slogan string `json:"slogan"` // 合图参数
Address string `json:"address"` // 合图参数
Phone string `json:"phone"` // 合图参数
Qrcode string `json:"qrcode"` // 合图参数
LogoUrl string `json:"logo_url"` // 合图参数
}
LogoCombineRes struct {
ResourceId string
ResourceUrl *string
Metadata *string
DiffTimeLogoCombine int64
DiffTimeUploadFile int64
}
)
func (l *defaultImageHandle) LogoCombine(ctx context.Context, in *LogoCombineReq) (*LogoCombineRes, error) {
// 查询logo最新基础信息
resLogoInfo, err := l.LogoInfo(ctx, &LogoInfoReq{
UserId: in.UserId,
GuestId: in.GuestId,
})
if err != nil {
logx.Error(err)
return nil, err
}
// 根据hash 查询数据资源
var hashKeyData = *in
hashKeyData.GuestId = 0
hashKeyData.UserId = 0
hashKeyData.LogoUrl = *resLogoInfo.LogoUrl
var hashKeyDataMap map[string]interface{}
hashKeyDataB, _ := json.Marshal(hashKeyData)
json.Unmarshal(hashKeyDataB, &hashKeyDataMap)
var resourceId string = hash.JsonHashKey(hashKeyDataMap)
resourceModel := gmodel.NewFsResourceModel(l.MysqlConn)
resourceInfo, err := resourceModel.FindOneById(ctx, resourceId)
if err == nil && resourceInfo.ResourceId != "" {
return &LogoCombineRes{
ResourceId: resourceId,
ResourceUrl: resourceInfo.ResourceUrl,
}, nil
} else {
if err != nil {
if !errors.Is(err, gorm.ErrRecordNotFound) {
logx.Error(err)
return nil, err
}
}
}
// 没有查到先根据模版id 查询模版数据 请求算法数据
productTemplateV2Model := gmodel.NewFsProductTemplateV2Model(l.MysqlConn)
productTemplateV2Info, err := productTemplateV2Model.FindOne(ctx, in.TemplateId)
if err != nil {
logc.Errorf(ctx, "productTemplateV2Model.FindOne%v", err)
return nil, err
}
productTemplateTagInfo, err := gmodel.NewFsProductTemplateTagsModel(l.MysqlConn).FindOneByTagName(ctx, in.TemplateTag, "groups")
if err != nil {
logc.Errorf(ctx, "NewFsProductTemplateTagsModel.FindOneByTagName%v", err)
return nil, err
}
var groupOptions map[string]interface{}
var materialList []interface{}
if productTemplateV2Info.TemplateInfo != nil {
var templateInfo map[string]interface{}
err = json.Unmarshal([]byte(*productTemplateV2Info.TemplateInfo), &templateInfo)
if err != nil {
logx.Error(err)
return nil, err
}
mapMaterialList, existMaterialList := templateInfo["materialList"]
if !existMaterialList {
err = errors.New("materialList is null")
logc.Errorf(ctx, "materialList err%v", err)
return nil, err
}
materialList = mapMaterialList.([]interface{})
mapGroupOptions, existGroupOptions := templateInfo["groupOptions"]
if !existGroupOptions {
err = errors.New("groupOptions is null")
logc.Errorf(ctx, "groupOptions err%v", err)
return nil, err
}
groupOptions = mapGroupOptions.(map[string]interface{})
}
var moduleDataMap = make(map[string]interface{}, 4)
moduleDataMap["id"] = productTemplateV2Info.Id
moduleDataMap["material"] = productTemplateV2Info.MaterialImg
moduleDataMap["groupOptions"] = groupOptions
moduleDataMap["materialList"] = materialList
var tagDataMap []interface{}
err = json.Unmarshal([]byte(*productTemplateTagInfo.Groups), &tagDataMap)
if err != nil {
logc.Errorf(ctx, "Unmarshal tagDataMap%v", err)
return nil, err
}
var combineParam map[string]interface{}
json.Unmarshal([]byte(*resLogoInfo.Metadata), &combineParam)
combineParam["template_tagid"] = in.TemplateTag
combineParam["website"] = in.Website
combineParam["slogan"] = in.Slogan
combineParam["phone"] = in.Phone
combineParam["address"] = in.Address
combineParam["qrcode"] = in.Qrcode
var postMap = make(map[string]interface{}, 2)
postMap["module_data"] = moduleDataMap
postMap["tag_data"] = tagDataMap
postMap["param_data"] = combineParam
logc.Infof(ctx, "合图--算法请求--合图--开始时间:%v", time.Now().UTC())
var startTimeLogoCombine = time.Now().UnixMilli() //合图--处理--开始时间
var resultBLM constants.BLMServiceUrlResult
err = curl.NewClient(ctx, &curl.Config{
BaseUrl: *l.BLMServiceUrl,
Url: constants.BLMServiceUrlLogoCombine,
}).PostJson(postMap, &resultBLM)
logc.Infof(ctx, "合图--算法请求--合图--结束时间:%v", time.Now().UTC())
endTimeLogoCombine := time.Now().UnixMilli() //合图--处理--开始时间
diffTimeLogoCombine := endTimeLogoCombine - startTimeLogoCombine //合图--处理--中间差
logc.Infof(ctx, "合图--算法请求--合图--业务耗时:%d", diffTimeLogoCombine)
if err != nil {
logx.Error(err)
return nil, err
}
if resultBLM.Code != "200" {
err = errors.New(resultBLM.Msg)
logx.Error(err)
return nil, err
}
var resultStr string = resultBLM.Data.(string)
var resultData map[string]interface{}
err = json.Unmarshal([]byte(resultStr), &resultData)
if err != nil || resultData == nil {
logx.Error(err)
return nil, err
}
var fileBase = resultData["result"].(string)
// 上传文件
var upload = file.Upload{
Ctx: ctx,
MysqlConn: l.MysqlConn,
AwsSession: l.AwsSession,
}
logc.Infof(ctx, "合图--上传文件--开始时间:%v", time.Now().UTC())
var startTimeUploadFile = time.Now().UnixMilli() //合图--上传--开始时间
uploadRes, err := upload.UploadFileByBase64(&file.UploadBaseReq{
Source: "combine-image",
FileHash: resourceId,
FileData: fileBase,
UploadBucket: 1,
ApiType: 2,
UserId: in.UserId,
GuestId: in.GuestId,
})
logc.Infof(ctx, "合图--上传文件--结束时间:%v", time.Now().UTC())
endTimeUploadFile := time.Now().UnixMilli() //合图--处理--开始时间
diffTimeUploadFile := endTimeUploadFile - startTimeUploadFile //合图--处理--中间差
logc.Infof(ctx, "合图--上传文件--业务耗时:%d", diffTimeUploadFile)
if err != nil {
logx.Error(err)
return nil, err
}
return &LogoCombineRes{
ResourceId: uploadRes.ResourceId,
ResourceUrl: &uploadRes.ResourceUrl,
DiffTimeLogoCombine: diffTimeLogoCombine,
DiffTimeUploadFile: diffTimeUploadFile,
}, nil
}
/* logo合图 */
type (
LogoStandardReq struct {
IsRemoveBg string `json:"is_remove_bg"`
LogoFile string `json:"logo_file"`
Width string `json:"width"`
Height string `json:"height"`
Proportion string `json:"proportion"`
}
LogoStandardRes struct {
ResourceId string
ResourceUrl string
IsmaxProportion bool
ImgColor []string
}
LogoStandardMetaData struct {
Param LogoStandardReq `json:"param"`
Result LogoStandardRes `json:"result"`
}
)
/* 图片裁剪 */
func (l *defaultImageHandle) LogoStandard(ctx context.Context, in *LogoStandardReq) (*LogoStandardRes, error) {
var ismaxProportion bool
var imgColor []string
var logoStandardMetaData LogoStandardMetaData
var hashKeyDataMap map[string]interface{}
hashKeyDataB, _ := json.Marshal(in)
json.Unmarshal(hashKeyDataB, &hashKeyDataMap)
var resourceId string = hash.JsonHashKey(hashKeyDataMap)
resourceModel := gmodel.NewFsResourceModel(l.MysqlConn)
resourceInfo, err := resourceModel.FindOneById(ctx, resourceId)
if err == nil && resourceInfo.ResourceId != "" {
if resourceInfo.Metadata != nil {
json.Unmarshal([]byte(*resourceInfo.Metadata), &logoStandardMetaData)
}
// 取出参数
ismaxProportion = logoStandardMetaData.Result.IsmaxProportion
imgColor = logoStandardMetaData.Result.ImgColor
return &LogoStandardRes{
ResourceId: resourceInfo.ResourceId,
ResourceUrl: *resourceInfo.ResourceUrl,
IsmaxProportion: ismaxProportion,
ImgColor: imgColor,
}, nil
} else {
if err != nil {
if !errors.Is(err, gorm.ErrRecordNotFound) {
logx.Error(err)
return nil, err
}
}
}
var resultBLM constants.BLMServiceUrlResult
var postMap = make(map[string]interface{}, 5)
postMap["is_remove_bg"] = in.IsRemoveBg
postMap["logo_file"] = in.LogoFile
postMap["width"] = in.Width
postMap["height"] = in.Height
postMap["proportion"] = in.Proportion
logc.Infof(ctx, "算法请求--去背景--开始时间:%v", time.Now().UTC())
err = curl.NewClient(ctx, &curl.Config{
BaseUrl: *l.BLMServiceUrl,
Url: constants.BLMServiceUrlLogoRemovebg,
}).PostJson(postMap, &resultBLM)
logc.Infof(ctx, "算法请求--去背景--结束时间:%v", time.Now().UTC())
if err != nil {
logx.Error(err)
return nil, err
}
if resultBLM.Code != "200" {
err = errors.New(resultBLM.Msg)
logx.Error(err)
return nil, err
}
var resultStr string = resultBLM.Data.(string)
var resultData map[string]interface{}
err = json.Unmarshal([]byte(resultStr), &resultData)
if err != nil || resultData == nil {
logx.Error(err)
return nil, err
}
var fileBase = resultData["nobg_url"].(string)
ismaxProportion = resultData["ismax_proportion"].(bool)
for _, v := range resultData["img_color"].([]interface{}) {
imgColor = append(imgColor, v.(string))
}
var logoStandardRes LogoStandardRes
logoStandardRes.IsmaxProportion = ismaxProportion
logoStandardRes.ImgColor = imgColor
logoStandardMetaData.Param = *in
logoStandardMetaData.Result = logoStandardRes
metadataB, err := json.Marshal(logoStandardMetaData)
if err != nil {
logx.Error(err)
return nil, err
}
var metadata = string(metadataB)
// 上传文件
var upload = file.Upload{
Ctx: ctx,
MysqlConn: l.MysqlConn,
AwsSession: l.AwsSession,
}
uploadRes, err := upload.UploadFileByBase64(&file.UploadBaseReq{
Source: "combine-removebg",
FileHash: resourceId,
FileData: fileBase,
UploadBucket: 1,
ApiType: 2,
Metadata: metadata,
})
if err != nil {
logx.Error(err)
return nil, err
}
return &LogoStandardRes{
ResourceId: uploadRes.ResourceId,
ResourceUrl: uploadRes.ResourceUrl,
IsmaxProportion: ismaxProportion,
ImgColor: imgColor,
}, nil
}
/* 图片裁剪 */