package repositories import ( "context" "encoding/json" "errors" "fmt" "fusenapi/constants" "fusenapi/model/gmodel" "fusenapi/utils/curl" "fusenapi/utils/file" "fusenapi/utils/hash" "fusenapi/utils/s3url_to_s3id" "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" ) var globalBLMServiceIndex int func NewImageHandle(gormDB *gorm.DB, bLMServiceUrls []string, awsSession *session.Session) ImageHandle { return &defaultImageHandle{ MysqlConn: gormDB, BLMServiceUrls: bLMServiceUrls, AwsSession: awsSession, } } type ( defaultImageHandle struct { MysqlConn *gorm.DB BLMServiceUrls []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"` UserInfoMetadata *string `json:"user_info_metadata"` } ) func (l *defaultImageHandle) LogoInfo(ctx context.Context, in *LogoInfoReq) (*LogoInfoRes, error) { var metadata *string var logoUrl *string var userInfoMetadata *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 } } if userInfo.Id != 0 { tmp := string(*userInfo.Metadata) userInfoMetadata = &tmp } var userMaterialInfo gmodel.FsUserMaterial userMaterialModel := gmodel.NewFsUserMaterialModel(l.MysqlConn) var metadataUserInfo struct { LogoSelected struct { TemplateTagSelected *struct { Color [][]string `json:"color"` TemplateTag string `json:"template_tag"` SelectedIndex int64 `json:"selected_index"` } `json:"template_tag_selected"` LogoSelectedId int64 `json:"logo_selected_id"` } `json:"logo_selected"` } userInfo.Id = 0 if userInfo.Id == 0 { userMaterialInfo, err = userMaterialModel.FindLatestOne(ctx, in.UserId, in.GuestId) if err != nil && err != gorm.ErrRecordNotFound { logc.Errorf(ctx, "FsUserMaterial FindLatestOne err:%+v", err) return nil, err } } else { if userInfo.Metadata != nil { err = json.Unmarshal([]byte(*userInfo.Metadata), &metadataUserInfo) if err != nil { logc.Errorf(ctx, "userInfo.Metadata Unmarshal err:%+v", err) return nil, err } if metadataUserInfo.LogoSelected.LogoSelectedId != 0 { userMaterialInfos, err := userMaterialModel.FindOneById(ctx, metadataUserInfo.LogoSelected.LogoSelectedId) if err != nil { if err != gorm.ErrRecordNotFound { logc.Errorf(ctx, "userMaterial findOneById 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, UserInfoMetadata: userInfoMetadata, }, nil } /* 获取logo最新信息 */ /* logo信息 */ type ( LogoInfoSetReq struct { LogoUrl string `json:"logo_url"` Version string `json:"version"` } LogoInfoSetRes struct { Res string `json:"res"` } ) func (l *defaultImageHandle) LogoInfoSet(ctx context.Context, in *LogoInfoSetReq) (*LogoInfoSetRes, error) { fmt.Println("算法请求轮训下标:", globalBLMServiceIndex) var bLMServicePort = l.BLMServiceUrls[globalBLMServiceIndex] if len(l.BLMServiceUrls) == (globalBLMServiceIndex + 1) { globalBLMServiceIndex = 0 } else { globalBLMServiceIndex = globalBLMServiceIndex + 1 } var resultBLM constants.BLMServiceUrlResult postMap := make(map[string]string, 2) postMap["logo_url"] = in.LogoUrl postMap["version"] = in.Version logc.Infof(ctx, "算法请求--LOGO基础信息--开始时间:%v", time.Now().UTC()) err := curl.NewClient(ctx, &curl.Config{ BaseUrl: bLMServicePort, 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"` ProductTemplateV2Info *gmodel.FsProductTemplateV2 `json:"product_template_v2_info"` ProductTemplateTagGroups interface{} `json:"product_template_tag_groups"` 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"` // 合图参数 Resolution string `json:"resolution"` // 合图参数 TemplateTagColor TemplateTagColor `json:"template_tag_color"` //合图颜色 } LogoCombineRes struct { ResourceId string ResourceUrl *string Metadata *string DiffTimeLogoCombine int64 DiffTimeUploadFile int64 } ) type TemplateTagColor struct { Color [][]string `json:"color"` Index int `json:"index"` } func (l *defaultImageHandle) LogoCombine(ctx context.Context, in *LogoCombineReq) (*LogoCombineRes, error) { logoResourceId := s3url_to_s3id.GetS3ResourceIdFormUrl(in.LogoUrl) if logoResourceId == "" { return nil, errors.New("invalid logo url") } userMaterialModel := gmodel.NewFsUserMaterialModel(l.MysqlConn) resLogoInfo, err := userMaterialModel.FindOneByLogoResourceId(ctx, logoResourceId) if err != nil { logx.Error(err) return nil, err } // 根据hash 查询数据资源 var hashKeyData = *in hashKeyData.GuestId = 0 hashKeyData.UserId = 0 hashKeyData.LogoUrl = in.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 } } } var groupOptions map[string]interface{} var materialList []interface{} if in.ProductTemplateV2Info.TemplateInfo != nil { var templateInfo map[string]interface{} err = json.Unmarshal([]byte(*in.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"] = in.ProductTemplateV2Info.Id moduleDataMap["material"] = in.ProductTemplateV2Info.MaterialImg moduleDataMap["groupOptions"] = groupOptions moduleDataMap["materialList"] = materialList var combineParam map[string]interface{} json.Unmarshal([]byte(*resLogoInfo.Metadata), &combineParam) combineParam["resolution"] = in.Resolution 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 combineParam["template_tag_selected"] = map[string]interface{}{ "template_tag": in.TemplateTag, "color": in.TemplateTagColor.Color, "index": in.TemplateTagColor.Index, } var postMap = make(map[string]interface{}, 3) postMap["module_data"] = moduleDataMap postMap["tag_data"] = in.ProductTemplateTagGroups postMap["param_data"] = combineParam fmt.Println("算法请求轮训下标:", globalBLMServiceIndex) var bLMServicePort = l.BLMServiceUrls[globalBLMServiceIndex] if len(l.BLMServiceUrls) == (globalBLMServiceIndex + 1) { globalBLMServiceIndex = 0 } else { globalBLMServiceIndex = globalBLMServiceIndex + 1 } logc.Infof(ctx, "合图--算法请求--合图--开始时间:%v", time.Now().UTC()) var startTimeLogoCombine = time.Now().UnixMilli() //合图--处理--开始时间 var resultBLM constants.BLMServiceUrlResult err = curl.NewClient(ctx, &curl.Config{ BaseUrl: bLMServicePort, Url: constants.BLMServiceUrlLogoCombine, RequireTimeout: time.Second * 15, }).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 fmt.Println("算法请求轮训下标:", globalBLMServiceIndex) var bLMServicePort = l.BLMServiceUrls[globalBLMServiceIndex] if len(l.BLMServiceUrls) == (globalBLMServiceIndex + 1) { globalBLMServiceIndex = 0 } else { globalBLMServiceIndex = globalBLMServiceIndex + 1 } logc.Infof(ctx, "算法请求--去背景--开始时间:%v", time.Now().UTC()) err = curl.NewClient(ctx, &curl.Config{ BaseUrl: bLMServicePort, 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 } /* 图片裁剪 */