diff --git a/constants/rabbitmq.go b/constants/rabbitmq.go index e9e06ef5..b8e374b3 100644 --- a/constants/rabbitmq.go +++ b/constants/rabbitmq.go @@ -4,17 +4,16 @@ type RABBIT_MQ string // 消息队列队列名 const ( - //组装渲染数据队列 - RABBIT_MQ_ASSEMBLE_RENDER_DATA RABBIT_MQ = "RABBIT_MQ_ASSEMBLE_RENDER_DATA" - //渲染结果数据队列 - RABBIT_MQ_RENDER_RESULT_DATA RABBIT_MQ = "RABBIT_MQ_RENDER_RESULT_DATA" - //原来发送到unity渲染的队列 - RABBIT_MQ_TO_UNITY RABBIT_MQ = "newTaskQueue" +//组装渲染数据队列 +/*RABBIT_MQ_ASSEMBLE_RENDER_DATA RABBIT_MQ = "RABBIT_MQ_ASSEMBLE_RENDER_DATA" +//渲染结果数据队列 +RABBIT_MQ_RENDER_RESULT_DATA RABBIT_MQ = "RABBIT_MQ_RENDER_RESULT_DATA"*/ ) // 队列列表 var MqQueueArr = []RABBIT_MQ{ - RABBIT_MQ_ASSEMBLE_RENDER_DATA, - RABBIT_MQ_RENDER_RESULT_DATA, - RABBIT_MQ_TO_UNITY, + /* + RABBIT_MQ_ASSEMBLE_RENDER_DATA, + RABBIT_MQ_RENDER_RESULT_DATA, + */ } diff --git a/model/gmodel/fs_product_tag_prop_logic.go b/model/gmodel/fs_product_tag_prop_logic.go index 6612e196..338a61d1 100644 --- a/model/gmodel/fs_product_tag_prop_logic.go +++ b/model/gmodel/fs_product_tag_prop_logic.go @@ -5,7 +5,7 @@ import "context" // TODO: 使用model的属性做你想做的 type GetTagPropByProductIdsWithProductTagRsp struct { FsProductTagProp - Title string `json:"title"` + TemplateTag string `json:"template_tag"` } func (p *FsProductTagPropModel) GetTagPropByProductIdsWithProductTag(ctx context.Context, productIds []int64) (resp []GetTagPropByProductIdsWithProductTagRsp, err error) { @@ -14,7 +14,7 @@ func (p *FsProductTagPropModel) GetTagPropByProductIdsWithProductTag(ctx context } err = p.db.WithContext(ctx).Table(p.name+" as p "). Joins("left join fs_product_template_tags as t on p.template_tag_id = t.id"). - Select("p.*,t.title as title"). + Select("p.*,t.template_tag as template_tag"). Where("p.product_id in (?) and p.status = ? and t.status = ?", productIds, 1, 1). Find(&resp).Error return resp, err diff --git a/model/gmodel/fs_product_template_element_gen.go b/model/gmodel/fs_product_template_element_gen.go index 7dd21864..44f32f14 100644 --- a/model/gmodel/fs_product_template_element_gen.go +++ b/model/gmodel/fs_product_template_element_gen.go @@ -6,26 +6,26 @@ import ( // fs_product_template_element 云渲染配置表 type FsProductTemplateElement struct { - Id int64 `gorm:"primary_key;default:0;auto_increment;" json:"id"` // id - Title *string `gorm:"default:'';" json:"title"` // 产品模板名称 - ProductTemplateId *int64 `gorm:"index;default:0;" json:"product_template_id"` // 产品模板id - Main *string `gorm:"default:'';" json:"main"` // - Second *string `gorm:"default:'';" json:"second"` // - Base *string `gorm:"default:'';" json:"base"` // - Paper *string `gorm:"default:'';" json:"paper"` // - Spoon *string `gorm:"default:'';" json:"spoon"` // - Fork *string `gorm:"default:'';" json:"fork"` // - Toothpick *string `gorm:"default:'';" json:"toothpick"` // - Chopsticks *string `gorm:"default:'';" json:"chopsticks"` // - Shadow *string `gorm:"default:'';" json:"shadow"` // - Cover *string `gorm:"default:'';" json:"cover"` // - Cover1 *string `gorm:"default:'';" json:"cover1"` // - Mode *string `gorm:"default:'';" json:"mode"` // - Light *int64 `gorm:"default:0;" json:"light"` // - Rotation *string `gorm:"default:'';" json:"rotation"` // - Scale *string `gorm:"default:'';" json:"scale"` // - ModelP *string `gorm:"default:'';" json:"model_p"` // 配件对应的云渲染贴图数据 - Refletion *string `gorm:"default:'';" json:"refletion"` // 反射探头组 + Id int64 `gorm:"primary_key;default:0;auto_increment;" json:"id"` // id + Title *string `gorm:"default:'';" json:"title"` // 产品模板名称 + ModelId *int64 `gorm:"index;default:0;" json:"model_id"` // 模型id + Main *string `gorm:"default:'';" json:"main"` // + Second *string `gorm:"default:'';" json:"second"` // + Base *string `gorm:"default:'';" json:"base"` // + Paper *string `gorm:"default:'';" json:"paper"` // + Spoon *string `gorm:"default:'';" json:"spoon"` // + Fork *string `gorm:"default:'';" json:"fork"` // + Toothpick *string `gorm:"default:'';" json:"toothpick"` // + Chopsticks *string `gorm:"default:'';" json:"chopsticks"` // + Shadow *string `gorm:"default:'';" json:"shadow"` // + Cover *string `gorm:"default:'';" json:"cover"` // + Cover1 *string `gorm:"default:'';" json:"cover1"` // + Mode *string `gorm:"default:'';" json:"mode"` // + Light *int64 `gorm:"default:0;" json:"light"` // + Rotation *string `gorm:"default:'';" json:"rotation"` // + Scale *string `gorm:"default:'';" json:"scale"` // + ModelP *string `gorm:"default:'';" json:"model_p"` // 配件对应的云渲染贴图数据 + Refletion *string `gorm:"default:'';" json:"refletion"` // 反射探头组 } type FsProductTemplateElementModel struct { db *gorm.DB diff --git a/model/gmodel/fs_product_template_element_logic.go b/model/gmodel/fs_product_template_element_logic.go index 783f5480..5ace306f 100644 --- a/model/gmodel/fs_product_template_element_logic.go +++ b/model/gmodel/fs_product_template_element_logic.go @@ -7,7 +7,7 @@ import "context" func (e *FsProductTemplateElementModel) FindOneByModelId(ctx context.Context, modelId int64) (resp *FsProductTemplateElement, err error) { err = e.db.WithContext(ctx).Model(&FsProductTemplateElement{}). //以前的神仙员工把表model_id变成product_template_id - Where("`product_template_id` = ?", modelId). + Where("`model_id` = ?", modelId). Take(&resp).Error return resp, err } diff --git a/model/gmodel/fs_product_template_tags_gen.go b/model/gmodel/fs_product_template_tags_gen.go index a5505bbb..a940bced 100644 --- a/model/gmodel/fs_product_template_tags_gen.go +++ b/model/gmodel/fs_product_template_tags_gen.go @@ -6,12 +6,12 @@ import ( // fs_product_template_tags 模板标签表 type FsProductTemplateTags struct { - Id int64 `gorm:"primary_key;default:0;auto_increment;" json:"id"` // ID - Title *string `gorm:"unique_key;default:'';" json:"title"` // 标题 - Cover *string `gorm:"default:'';" json:"cover"` // 封面图 - Status *int64 `gorm:"default:0;" json:"status"` // 状态 1:可用 - CreateAt *int64 `gorm:"default:0;" json:"create_at"` // 创建时间 - Groups *string `gorm:"default:'';" json:"groups"` // 分组信息 + Id int64 `gorm:"primary_key;default:0;auto_increment;" json:"id"` // ID + TemplateTag *string `gorm:"unique_key;default:'';" json:"template_tag"` // 标题 + Cover *string `gorm:"default:'';" json:"cover"` // 封面图 + Status *int64 `gorm:"default:0;" json:"status"` // 状态 1:可用 + CreateAt *int64 `gorm:"default:0;" json:"create_at"` // 创建时间 + Groups *string `gorm:"default:'';" json:"groups"` // 分组信息 } type FsProductTemplateTagsModel struct { db *gorm.DB diff --git a/model/gmodel/fs_product_template_tags_logic.go b/model/gmodel/fs_product_template_tags_logic.go index 96d4cca2..53e76130 100755 --- a/model/gmodel/fs_product_template_tags_logic.go +++ b/model/gmodel/fs_product_template_tags_logic.go @@ -36,14 +36,18 @@ func (pt *FsProductTemplateTagsModel) GetListByTagNames(ctx context.Context, tag if len(tagNames) == 0 { return nil, nil } - db := pt.db.WithContext(ctx).Model(&FsProductTemplateTags{}).Where("`title` in (?) and `status` = ?", tagNames, 1) + db := pt.db.WithContext(ctx).Model(&FsProductTemplateTags{}).Where("`template_tag` in (?) and `status` = ?", tagNames, 1) if orderBy != "" { db = db.Order(orderBy) } err = db.Limit(limit).Find(&resp).Error return resp, err } -func (pt *FsProductTemplateTagsModel) FindOneByTagName(ctx context.Context, tagName string) (resp *FsProductTemplateTags, err error) { - err = pt.db.WithContext(ctx).Model(&FsProductTemplateTags{}).Where("`title` = ? and `status` = ?", tagName, 1).Take(&resp).Error +func (pt *FsProductTemplateTagsModel) FindOneByTagName(ctx context.Context, tagName string, fields ...string) (resp *FsProductTemplateTags, err error) { + db := pt.db.WithContext(ctx).Model(&FsProductTemplateTags{}).Where("`template_tag` = ? and `status` = ?", tagName, 1) + if len(fields) != 0 { + db = db.Select(fields[0]) + } + err = db.Take(&resp).Error return resp, err } diff --git a/model/gmodel/fs_product_template_v2_gen.go b/model/gmodel/fs_product_template_v2_gen.go index 68c91ed5..cd6a5f51 100644 --- a/model/gmodel/fs_product_template_v2_gen.go +++ b/model/gmodel/fs_product_template_v2_gen.go @@ -20,10 +20,9 @@ type FsProductTemplateV2 struct { IsPublic *int64 `gorm:"default:0;" json:"is_public"` // 是否可公用(1:可以,0:不可以) Status *int64 `gorm:"default:0;" json:"status"` // 状态1正常 2异常 Ctime *int64 `gorm:"default:0;" json:"ctime"` // 添加时间 - Tag *string `gorm:"default:'';" json:"tag"` // + TemplateTag *string `gorm:"default:'';" json:"template_tag"` // IsDel *int64 `gorm:"default:0;" json:"is_del"` // 是否删除 1删除 SwitchInfo *string `gorm:"default:'';" json:"switch_info"` // - GroupOptions *string `gorm:"default:'';" json:"group_options"` // Version *int64 `gorm:"index;default:0;" json:"version"` // 默认1 } type FsProductTemplateV2Model struct { diff --git a/model/gmodel/fs_product_template_v2_logic.go b/model/gmodel/fs_product_template_v2_logic.go index a4945096..94c99826 100755 --- a/model/gmodel/fs_product_template_v2_logic.go +++ b/model/gmodel/fs_product_template_v2_logic.go @@ -113,9 +113,9 @@ func (t *FsProductTemplateV2Model) GetProductTemplateListByParams(ctx context.Co // 获取第一个尺寸下的模板 func (t *FsProductTemplateV2Model) FindOneByProductIdTagIdWithSizeTable(ctx context.Context, productId int64, templateTag string) (resp *FsProductTemplateV2, err error) { err = t.db.WithContext(ctx).Table(t.name+" as t"). - Joins("left join fs_product_size as s on t.product_id = s.product_id"). + Joins("inner join fs_product_size as s on t.product_id = s.product_id"). Select("t.*"). - Where("t.product_id = ? and t.tag = ? ", productId, templateTag). + Where("t.product_id = ? and t.template_tag = ? ", productId, templateTag). Where("t.status = ? and t.is_del = ?", 1, 0). Where("s.status = ?", 1). Order("s.sort ASC"). @@ -126,7 +126,7 @@ func (t *FsProductTemplateV2Model) FindAllByModelIdsTemplateTag(ctx context.Cont if len(modelIds) == 0 { return } - db := t.db.WithContext(ctx).Model(&FsProductTemplateV2{}).Where("`model_id` in (?) and `tag` = ? and `is_del` = ? and `status` = ?", modelIds, templateTag, 0, 1) + db := t.db.WithContext(ctx).Model(&FsProductTemplateV2{}).Where("`model_id` in (?) and `template_tag` = ? and `is_del` = ? and `status` = ?", modelIds, templateTag, 0, 1) if len(fields) != 0 { db = db.Select(fields[0]) } @@ -143,7 +143,7 @@ func (t *FsProductTemplateV2Model) FindAllByModelIdsTemplateTag(ctx context.Cont // 获取产品在指定模板标签下的所有模板 func (t *FsProductTemplateV2Model) GetListByProductAndTemplateTag(ctx context.Context, templateTagId string, productId int64, fields ...string) (resp []FsProductTemplateV2, err error) { db := t.db.WithContext(ctx).Model(&FsProductTemplateV2{}). - Where("tag = ? and product_id = ? and status = ? and is_del = ?", templateTagId, productId, 1, 0) + Where("template_tag = ? and product_id = ? and status = ? and is_del = ?", templateTagId, productId, 1, 0) if len(fields) > 0 { db = db.Select(fields[0]) } diff --git a/model/gmodel/fs_resource_gen.go b/model/gmodel/fs_resource_gen.go index 400dd9e4..0f308faf 100644 --- a/model/gmodel/fs_resource_gen.go +++ b/model/gmodel/fs_resource_gen.go @@ -18,6 +18,7 @@ type FsResource struct { MetaKey1 *string `gorm:"index;default:'';" json:"meta_key1"` // 需要关键信息查询的自定义属性1,可以动态增加 ApiType *int64 `gorm:"default:1;" json:"api_type"` // 调用类型:1=对外,2=对内 BucketName *string `gorm:"default:'';" json:"bucket_name"` // 存储桶名: 1=持久 2=缓存 + Source *string `gorm:"default:'';" json:"source"` // 来源 } type FsResourceModel struct { db *gorm.DB diff --git a/model/gmodel/fs_tags_gen.go b/model/gmodel/fs_tags_gen.go index 5f27544b..1a7d89c9 100644 --- a/model/gmodel/fs_tags_gen.go +++ b/model/gmodel/fs_tags_gen.go @@ -16,8 +16,8 @@ type FsTags struct { Icon *string `gorm:"default:'';" json:"icon"` // 标签图标 Status *int64 `gorm:"default:1;" json:"status"` // 状态 1:可用 Description *string `gorm:"default:'';" json:"description"` // 介绍 Seo - RecommendProduct *string `gorm:"default:'';" json:"recommend_product"` // - RecommendProductSort *string `gorm:"default:'';" json:"recommend_product_sort"` // + RecommendProduct *string `gorm:"default:'';" json:"recommend_product"` // 推荐产品id例如: 1,3,4,5 + RecommendProductSort *string `gorm:"default:'';" json:"recommend_product_sort"` // 推荐排序例如:1324 Category *int64 `gorm:"default:1;" json:"category"` // 分类:1前台用的 2后台用的 } type FsTagsModel struct { diff --git a/server/map-library/internal/logic/getmaplibrarylistlogic.go b/server/map-library/internal/logic/getmaplibrarylistlogic.go index aa7ec7a8..1ecf5167 100644 --- a/server/map-library/internal/logic/getmaplibrarylistlogic.go +++ b/server/map-library/internal/logic/getmaplibrarylistlogic.go @@ -66,7 +66,7 @@ func (l *GetMapLibraryListLogic) GetMapLibraryList(req *types.Request, userinfo if tagIndex, ok := mapTag[*v.TagId]; ok { data.Tag = &types.MapLibraryListTag{ Id: templateTagList[tagIndex].Id, - Title: *templateTagList[tagIndex].Title, + Title: *templateTagList[tagIndex].TemplateTag, } } //解析info diff --git a/server/product-template-tag/internal/logic/getproducttemplatetagslogic.go b/server/product-template-tag/internal/logic/getproducttemplatetagslogic.go index d0c8377f..cf89a9b4 100644 --- a/server/product-template-tag/internal/logic/getproducttemplatetagslogic.go +++ b/server/product-template-tag/internal/logic/getproducttemplatetagslogic.go @@ -83,7 +83,7 @@ func (l *GetProductTemplateTagsLogic) GetProductTemplateTags(req *types.GetProdu for _, v := range productTemplateTags { list = append(list, types.GetProductTemplateTagsRsp{ Id: v.Id, - TemplateTag: *v.Title, + TemplateTag: *v.TemplateTag, Cover: *v.Cover, }) } diff --git a/server/product-template/internal/logic/gettemplatevdetaillogic.go b/server/product-template/internal/logic/gettemplatevdetaillogic.go index 12324f50..7ef73a14 100644 --- a/server/product-template/internal/logic/gettemplatevdetaillogic.go +++ b/server/product-template/internal/logic/gettemplatevdetaillogic.go @@ -8,7 +8,6 @@ import ( "fusenapi/utils/basic" "fusenapi/utils/format" "gorm.io/gorm" - "strconv" "strings" "context" @@ -62,13 +61,7 @@ func (l *GetTemplatevDetailLogic) GetTemplatevDetail(req *types.GetTemplatevDeta return resp.SetStatusWithMessage(basic.CodeDbSqlErr, "failed to get product template info") } //获取模板标签 - templateTagModel := gmodel.NewFsProductTemplateTagsModel(l.svcCtx.MysqlConn) - tagId, err := strconv.ParseInt(*templatev2Info.Tag, 10, 64) - if err != nil { - logx.Error(err) - return resp.SetStatusWithMessage(basic.CodeServiceErr, "parse int tag id err") - } - templateTagInfo, err := templateTagModel.FindOne(l.ctx, tagId, "id,title") + templateTagInfo, err := l.svcCtx.AllModels.FsProductTemplateTags.FindOneByTagName(l.ctx, *templatev2Info.TemplateTag, "id,title") if err != nil { if errors.Is(err, gorm.ErrRecordNotFound) { return resp.SetStatusWithMessage(basic.CodeDbRecordNotFoundErr, "template tag info is not exists") @@ -125,7 +118,7 @@ func (l *GetTemplatevDetailLogic) GetTemplatevDetail(req *types.GetTemplatevDeta } templateInfoRsp["tag"] = map[string]interface{}{ "id": templateTagInfo.Id, - "title": *templateTagInfo.Title, + "title": *templateTagInfo.TemplateTag, } response := types.GetTemplatevDetailRsp{ ProductModelInfo: productModelInfoRsp, diff --git a/server/product/internal/logic/getproductinfologic.go b/server/product/internal/logic/getproductinfologic.go index 8047752a..1a768d3c 100644 --- a/server/product/internal/logic/getproductinfologic.go +++ b/server/product/internal/logic/getproductinfologic.go @@ -109,8 +109,8 @@ func (l *GetProductInfoLogic) GetProductInfo(req *types.GetProductInfoReq, useri tagIds := make([]int64, 0, len(productTemplateList)) for _, v := range productTemplateList { mapTemplateModelId[*v.ModelId] = struct{}{} - if v.Tag != nil && *v.Tag != "" { - tagId, err := strconv.ParseInt(*v.Tag, 10, 64) + if v.TemplateTag != nil && *v.TemplateTag != "" { + tagId, err := strconv.ParseInt(*v.TemplateTag, 10, 64) if err != nil { logx.Error(err) return resp.SetStatusWithMessage(basic.CodeServiceErr, "tag is not a number") @@ -296,7 +296,7 @@ func (l *GetProductInfoLogic) GetProductInfo(req *types.GetProductInfoReq, useri partListRsp = append(partListRsp, thisInfo) } tagName := "" - if tagData, ok := mapTag[*tmp.Tag]; ok { + if tagData, ok := mapTag[*tmp.TemplateTag]; ok { tagName = *tagData.Title } //按照材质和尺寸来存放模板信息 diff --git a/server/product/internal/logic/getrecommandproductlistlogic.go b/server/product/internal/logic/getrecommandproductlistlogic.go index d73206c7..7f082fef 100644 --- a/server/product/internal/logic/getrecommandproductlistlogic.go +++ b/server/product/internal/logic/getrecommandproductlistlogic.go @@ -127,7 +127,7 @@ func (l *GetRecommandProductListLogic) GetRecommandProductList(req *types.GetRec mapTagProp := make(map[int64][]types.CoverDefaultItem) for _, v := range productTagPropList { mapTagProp[*v.ProductId] = append(mapTagProp[*v.ProductId], types.CoverDefaultItem{ - Tag: v.Title, + Tag: v.TemplateTag, Cover: *v.Cover, }) } diff --git a/server/product/internal/logic/gettagproductlistlogic.go b/server/product/internal/logic/gettagproductlistlogic.go index 480e2bc1..0ebb5196 100644 --- a/server/product/internal/logic/gettagproductlistlogic.go +++ b/server/product/internal/logic/gettagproductlistlogic.go @@ -138,7 +138,7 @@ func (l *GetTagProductListLogic) GetTagProductList(req *types.GetTagProductListR } for _, v := range productTagPropList { mapTagProp[*v.ProductId] = append(mapTagProp[*v.ProductId], types.CoverDefaultItem{ - Tag: v.Title, + Tag: v.TemplateTag, Cover: *v.Cover, }) } @@ -312,6 +312,10 @@ func (l *GetTagProductListLogic) organizationLevelRelation(minLevel int, mapTagL //最终值提取最高级别那一层出来 rspList := make([]types.TagItem, 0, len(mapTagLevel)) for prefix, _ := range mapTop { + //大类下没有任何产品则不显示 + if len(mapTagLevel[prefix].TagProductList) == 0 { + continue + } rspList = append(rspList, *mapTagLevel[prefix]) } //排序 diff --git a/server/product/internal/logic/gettemplatebypidlogic.go b/server/product/internal/logic/gettemplatebypidlogic.go index 9e1b66d1..7612c61c 100644 --- a/server/product/internal/logic/gettemplatebypidlogic.go +++ b/server/product/internal/logic/gettemplatebypidlogic.go @@ -67,6 +67,15 @@ func (l *GetTemplateByPidLogic) GetTemplateByPid(req *types.GetTemplateByPidReq, } else { //指定物料 sizeIds = append(sizeIds, req.ProductSizeId) } + //获取templatetag信息 + templateTagInfo, err := l.svcCtx.AllModels.FsProductTemplateTags.FindOne(l.ctx, req.ProductTemplateTagId) + if err != nil { + if errors.Is(err, gorm.ErrRecordNotFound) { + return resp.SetStatusWithMessage(basic.CodeDbRecordNotFoundErr, "template tag is not exists") + } + logx.Error(err) + return resp.SetStatusWithMessage(basic.CodeDbRecordNotFoundErr, "failed to get template tag") + } //根据尺寸id获取模型 modelList, err := l.svcCtx.AllModels.FsProductModel3d.GetAllBySizeIdsTag(l.ctx, sizeIds, constants.TAG_MODEL) if err != nil { @@ -83,7 +92,7 @@ func (l *GetTemplateByPidLogic) GetTemplateByPid(req *types.GetTemplateByPidReq, mapModel[v.Id] = k } //查询模型ids下对应tag标签的模板 - templateList, err := l.svcCtx.AllModels.FsProductTemplateV2.FindAllByModelIdsTemplateTag(l.ctx, modelIds, fmt.Sprintf("%d", req.ProductTemplateTagId), "") + templateList, err := l.svcCtx.AllModels.FsProductTemplateV2.FindAllByModelIdsTemplateTag(l.ctx, modelIds, *templateTagInfo.TemplateTag, "") if err != nil { logx.Error(err) return resp.SetStatusWithMessage(basic.CodeDbSqlErr, "failed to get template list") diff --git a/server/product/internal/logic/homepagerecommendproductlistlogic.go b/server/product/internal/logic/homepagerecommendproductlistlogic.go index a8bd03df..6d449757 100644 --- a/server/product/internal/logic/homepagerecommendproductlistlogic.go +++ b/server/product/internal/logic/homepagerecommendproductlistlogic.go @@ -156,7 +156,7 @@ func (l *HomePageRecommendProductListLogic) HomePageRecommendProductList(req *ty mapTagProp := make(map[int64][]types.CoverDefaultItem) for _, v := range productTagPropList { mapTagProp[*v.ProductId] = append(mapTagProp[*v.ProductId], types.CoverDefaultItem{ - Tag: v.Title, + Tag: v.TemplateTag, Cover: *v.Cover, }) } diff --git a/server/render/consumer/assemble_render_data.go b/server/render/consumer/assemble_render_data.go deleted file mode 100644 index 96e6a38f..00000000 --- a/server/render/consumer/assemble_render_data.go +++ /dev/null @@ -1,179 +0,0 @@ -package consumer - -import ( - "context" - "encoding/json" - "errors" - "fmt" - "fusenapi/constants" - "fusenapi/initalize" - "fusenapi/server/render/internal/svc" - "fusenapi/service/repositories" - "fusenapi/utils/websocket_data" - "github.com/zeromicro/go-zero/core/logx" - "gorm.io/gorm" - "strconv" -) - -// 这里请求的py接口返回数据 -type pythonApiRsp struct { - Id string `json:"id"` //物料模板的id - LogoUrl string `json:"logo_url"` //logo地址 - Result string `json:"result"` //图片base64 -} - -// 消费渲染需要组装的数据 -type MqConsumerRenderAssemble struct { -} - -func (m *MqConsumerRenderAssemble) Run(ctx context.Context, data []byte) error { - defer func() { - if err := recover(); err != nil { - logx.Error("MqConsumerRenderAssemble panic:", err) - } - }() - logx.Info("收到需要组装的消息:", string(data)) - var parseInfo websocket_data.AssembleRenderData - if err := json.Unmarshal(data, &parseInfo); err != nil { - logx.Error("MqConsumerRenderAssemble数据格式错误:", err) - return nil //不返回错误就删除消息 - } - val := ctx.Value("svcctx") - if val == nil { - logx.Error("svcctx is nil") - return nil //不返回错误就删除消息 - } - svcCtx, ok := val.(*svc.ServiceContext) - if !ok { - logx.Error("svcctx is nil!!") - return nil //不返回错误就删除消息 - } - rabbitmq := initalize.RabbitMqHandle{} - //根据templateTag获取templateTagId(后续模板表的tag改成template_tag后可能就不需要这个步骤了) - templateTag, err := svcCtx.AllModels.FsProductTemplateTags.FindOneByTagName(ctx, parseInfo.RenderData.TemplateTag) - if err != nil { - if errors.Is(err, gorm.ErrRecordNotFound) { - logx.Error("can`t find template tag info by template tag:", parseInfo.RenderData.TemplateTag) - return nil - } - logx.Error("failed to get template tag info") - return nil - } - //获取模板(模板标签下的对一个物料的的模板) - productTemplate, err := svcCtx.AllModels.FsProductTemplateV2.FindOneByProductIdTagIdWithSizeTable(ctx, parseInfo.RenderData.ProductId, fmt.Sprintf("%d", templateTag.Id)) - if err != nil { - if errors.Is(err, gorm.ErrRecordNotFound) { - logx.Error("template info is not found") - return nil //不返回错误就删除消息 - } - logx.Error("failed to get template info:", err) - return nil //不返回错误就删除消息 - } - //获取刀版图 - res, err := svcCtx.Repositories.ImageHandle.LogoCombine(ctx, &repositories.LogoCombineReq{ - UserId: parseInfo.RenderData.UserId, - GuestId: parseInfo.RenderData.GuestId, - TemplateId: productTemplate.Id, - TemplateTag: parseInfo.RenderData.TemplateTag, - Website: parseInfo.RenderData.Website, - Slogan: parseInfo.RenderData.Slogan, - Address: parseInfo.RenderData.Address, - Phone: parseInfo.RenderData.Phone, - }) - if err != nil { - logx.Error("合成刀版图失败:", err) - return nil - } - combineImage := "" //刀版图 - if res != nil && res.ResourceUrl != nil { - combineImage = *res.ResourceUrl - } else { - logx.Error("合成刀版图失败,合成的刀版图是空指针:", err) - return nil - } - logx.Info("合成刀版图成功:", *res.ResourceUrl) - //获取渲染设置信息 - element, err := svcCtx.AllModels.FsProductTemplateElement.FindOneByModelId(ctx, *productTemplate.ModelId) - if err != nil { - if errors.Is(err, gorm.ErrRecordNotFound) { - logx.Error("element info is not found,model_id = ?", *productTemplate.ModelId) - return nil //不返回错误就删除消息 - } - logx.Error("failed to get element list,", err) - return nil //不返回错误就删除消息 - } - //组装数据 - refletion := -1 - if element.Refletion != nil && *element.Refletion != "" { - refletion, err = strconv.Atoi(*element.Refletion) - } - //组装data数据 - var mode map[string]interface{} - if element.Mode != nil && *element.Mode != "" { - if err = json.Unmarshal([]byte(*element.Mode), &mode); err != nil { - logx.Error("faile to parse element mode json:", err) - return nil //不返回错误就删除消息 - } - } - tempData := make([]map[string]interface{}, 0, 3) - if element.Base != nil && *element.Base != "" { - tempData = append(tempData, map[string]interface{}{ - "name": "model", - "data": "0," + combineImage + "," + *element.Base, - "type": "other", - "layer": "0", - "is_update": 1, - "mode": mode["model"], - }) - } - if element.Shadow != nil && *element.Shadow != "" { - tempData = append(tempData, map[string]interface{}{ - "name": "shadow", - "data": *element.Shadow, - "type": "other", - "layer": "0", - "is_update": 0, - "mode": mode["shadow"], - }) - } - if element.ModelP != nil && *element.ModelP != "" { - tempData = append(tempData, map[string]interface{}{ - "name": "model_P", - "data": "0," + *element.ModelP, - "type": "other", - "layer": "0", - "is_update": 0, - "mode": mode["model_P"], - }) - } - result := []interface{}{ - map[string]interface{}{ - "light": *element.Light, - "refletion": refletion, - "scale": *element.Scale, - "sku_id": parseInfo.RenderData.ProductId, - "tid": *element.Title, - "rotation": *element.Rotation, - "filePath": "", //todo 文件路径,针对千人千面 - "data": tempData, - }, - } - sendData := map[string]interface{}{ - "id": parseInfo.TaskId, - "order_id": 0, - "user_id": parseInfo.RenderData.UserId, - "guest_id": parseInfo.RenderData.GuestId, - "sku_ids": []int64{parseInfo.RenderData.ProductId}, - "tids": []string{*element.Title}, - "data": result, - "is_thousand_face": 0, - "folder": "", //todo 千人千面需要使用 - } - b, _ := json.Marshal(sendData) - if err = rabbitmq.SendMsg(constants.RABBIT_MQ_TO_UNITY, b); err != nil { - logx.Error("发送渲染组装数据到rabbitmq失败:", err) - return nil //不返回错误就删除消息 - } - logx.Info("发送渲染组装数据到unity成功") - return nil -} diff --git a/server/render/internal/handler/routes.go b/server/render/internal/handler/routes.go index 26ad8b15..03e1cab2 100644 --- a/server/render/internal/handler/routes.go +++ b/server/render/internal/handler/routes.go @@ -12,11 +12,6 @@ import ( func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) { server.AddRoutes( []rest.Route{ - { - Method: http.MethodPost, - Path: "/api/render/render_notify", - Handler: RenderNotifyHandler(serverCtx), - }, { Method: http.MethodPost, Path: "/api/render/get_face_slice", diff --git a/server/render/internal/types/types.go b/server/render/internal/types/types.go index ef9aad74..70ec268a 100644 --- a/server/render/internal/types/types.go +++ b/server/render/internal/types/types.go @@ -5,19 +5,6 @@ import ( "fusenapi/utils/basic" ) -type RequestToUnity struct { -} - -type RequestReadImages struct { -} - -type RenderNotifyReq struct { - TaskId string `json:"task_id"` //任务id - UserId int64 `json:"user_id"` - GuestId int64 `json:"guest_id"` - Image string `json:"image"` -} - type Request struct { } diff --git a/server/render/render.go b/server/render/render.go index 56fc25ee..9790b18a 100644 --- a/server/render/render.go +++ b/server/render/render.go @@ -1,11 +1,8 @@ package main import ( - "context" "flag" "fmt" - "fusenapi/constants" - "fusenapi/server/render/consumer" "net/http" "fusenapi/utils/auth" @@ -30,12 +27,6 @@ func main() { defer server.Stop() ctx := svc.NewServiceContext(c) - //消费渲染前组装数据队列 - ctx1 := context.Background() - ctx2, cancel := context.WithCancel(ctx1) - ctx2 = context.WithValue(ctx2, "svcctx", ctx) - defer cancel() - go ctx.RabbitMq.Consume(ctx2, constants.RABBIT_MQ_ASSEMBLE_RENDER_DATA, &consumer.MqConsumerRenderAssemble{}) handler.RegisterHandlers(server, ctx) fmt.Printf("Starting server at %s:%d...\n", c.Host, c.Port) server.Start() diff --git a/server/resource/internal/logic/logocombinelogic.go b/server/resource/internal/logic/logocombinelogic.go index 661228e3..53b02768 100644 --- a/server/resource/internal/logic/logocombinelogic.go +++ b/server/resource/internal/logic/logocombinelogic.go @@ -65,7 +65,8 @@ func (l *LogoCombineLogic) LogoCombine(req *types.LogoCombineReq, userinfo *auth Slogan: req.Slogan, Phone: req.Phone, Address: req.Address, - Qrcode: req.Qrcode, + + Qrcode: req.Qrcode, }) if err != nil { diff --git a/server/resource/resource_test.go b/server/resource/resource_test.go index d035c13a..80820ef2 100644 --- a/server/resource/resource_test.go +++ b/server/resource/resource_test.go @@ -4,9 +4,6 @@ import ( "testing" ) -// var configFile = flag.String("f", "etc/home-user-auth.yaml", "the config file") - func TestMain(t *testing.T) { - // log.Println(model.RawFieldNames[FsCanteenType]()) main() } diff --git a/server/upload/internal/logic/uploadcallbacklogic.go b/server/upload/internal/logic/uploadcallbacklogic.go index 615052fd..796016ba 100644 --- a/server/upload/internal/logic/uploadcallbacklogic.go +++ b/server/upload/internal/logic/uploadcallbacklogic.go @@ -83,8 +83,10 @@ func (l *UploadCallbackLogic) UploadCallback(req *types.UploadCallbackReq, useri fsResource.ResourceUrl = &req.ResourceUrl fsResource.Metadata = &req.Metadata fsResource.ApiType = &req.ApiType + fsResource.Source = &req.Source fsResource.BucketName = bucketName fsResource.Version = &version + if resourceInfo.ResourceId == "" { _, err = resourceModelTS.BuilderCreate(ctx, transBuilder, fsResource) } else { diff --git a/server/upload/internal/logic/uploadfilebackendlogic.go b/server/upload/internal/logic/uploadfilebackendlogic.go index 3864c3a4..8e817639 100644 --- a/server/upload/internal/logic/uploadfilebackendlogic.go +++ b/server/upload/internal/logic/uploadfilebackendlogic.go @@ -90,6 +90,7 @@ func (l *UploadFileBackendLogic) UploadFileBackend(req *types.UploadFileBackendR ApiType: req.ApiType, UserId: userId, GuestId: guestId, + Source: req.Source, }) if err != nil { diff --git a/server/upload/internal/logic/uploadfilebaselogic.go b/server/upload/internal/logic/uploadfilebaselogic.go index 0e079884..55326ac1 100644 --- a/server/upload/internal/logic/uploadfilebaselogic.go +++ b/server/upload/internal/logic/uploadfilebaselogic.go @@ -77,6 +77,7 @@ func (l *UploadFileBaseLogic) UploadFileBase(req *types.UploadFileBaseReq, useri ApiType: req.ApiType, UserId: userId, GuestId: guestId, + Source: req.Source, }) if err != nil { diff --git a/server/upload/internal/logic/uploadfilesbackendlogic.go b/server/upload/internal/logic/uploadfilesbackendlogic.go index 6995b0c7..cedbb8de 100644 --- a/server/upload/internal/logic/uploadfilesbackendlogic.go +++ b/server/upload/internal/logic/uploadfilesbackendlogic.go @@ -123,6 +123,7 @@ func (l *UploadFilesBackendLogic) UploadFilesBackend(req *types.UploadFilesReq, ApiType: req.ApiType, Bucket: bucketName, HashKey: hashKey, + Source: req.Source, } } }, func(item interface{}, writer mr.Writer[interface{}], cancel func(error)) { @@ -148,6 +149,7 @@ func (l *UploadFilesBackendLogic) UploadFilesBackend(req *types.UploadFilesReq, ApiType: req.ApiType, UserId: userId, GuestId: guestId, + Source: uploadDataInfo.Source, }) if err == nil { uploadUrl.Status = 1 @@ -201,6 +203,7 @@ type UploadData struct { Bucket *string `json:"bucket"` HashKey string `json:"hash_key"` FileData []byte `fsfile:"data"` + Source string `json:"source"` } type UploadUrl struct { diff --git a/server/upload/internal/logic/uploadlogologic.go b/server/upload/internal/logic/uploadlogologic.go index 1c51eb22..0019177a 100644 --- a/server/upload/internal/logic/uploadlogologic.go +++ b/server/upload/internal/logic/uploadlogologic.go @@ -88,6 +88,7 @@ func (l *UploadLogoLogic) UploadLogo(req *types.UploadLogoReq, userinfo *auth.Us imageTypes["image/tiff"] = struct{}{} imageTypes["image/webp"] = struct{}{} imageTypes["image/svg+xml"] = struct{}{} + // 判断文件类型是否为图片 _, ok := imageTypes[fileType] if !ok { @@ -115,6 +116,7 @@ func (l *UploadLogoLogic) UploadLogo(req *types.UploadLogoReq, userinfo *auth.Us ApiType: 2, UserId: userId, GuestId: guestId, + Source: "upload-logo", }) if err != nil { diff --git a/server/upload/internal/types/types.go b/server/upload/internal/types/types.go index 6ac757ae..4a946586 100644 --- a/server/upload/internal/types/types.go +++ b/server/upload/internal/types/types.go @@ -13,6 +13,7 @@ type UploadFileBaseReq struct { UserId int64 `form:"user_id,optional"` // 上传文件额外信息 GuestId int64 `form:"guest_id,optional"` // 上传文件额外信息 UploadBucket int64 `form:"upload_bucket,options=[1,2],default=1"` // 上传桶名:1=缓存,2=持久 + Source string `form:"source"` // 上传来源 } type UploadLogoReq struct { @@ -28,12 +29,14 @@ type UploadFileBackendReq struct { FileKey string `form:"file_key"` // 上传唯一标识信息 FileSize int64 `form:"file_size,optional"` // 上传唯一标识信息 Metadata string `form:"meta_data,optional"` // 上传文件额外信息 + Source string `form:"source"` // 上传来源 } type UploadFilesReq struct { ApiType int64 `form:"api_type,options=[1,2],default=1"` // 调用类型:1=对外,2=对内 UploadBucket int64 `form:"upload_bucket,options=[1,2],default=1"` // 上传桶名:1=缓存,2=持久 UploadInfo string `form:"upload_info"` // 上传信息 json + Source string `form:"source"` // 上传来源 } type UploadCallbackReq struct { @@ -43,6 +46,7 @@ type UploadCallbackReq struct { ResourceUrl string `form:"resource_url"` // 资源URL Metadata string `form:"metadata,optional"` // 元数据,json格式,存储图像分率 ApiType int64 `form:"api_type,options=[1,2],default=1"` // 调用类型:1=对外,2=对内 + Source string `form:"source"` // 上传来源 } type RequestUpFile struct { diff --git a/server/websocket/etc/websocket.yaml b/server/websocket/etc/websocket.yaml index 58116e52..368f1ca8 100644 --- a/server/websocket/etc/websocket.yaml +++ b/server/websocket/etc/websocket.yaml @@ -8,4 +8,17 @@ Auth: AccessSecret: fusen2023 AccessExpire: 2592000 RefreshAfter: 1592000 -SourceRabbitMq: amqp://rabbit001:rabbit001129@110.41.19.98:5672 \ No newline at end of file +SourceRabbitMq: amqp://rabbit001:rabbit001129@110.41.19.98:5672 +AWS: + S3: + Credentials: + AccessKeyID: AKIAZB2JKUXDPNRP4YT2 + Secret: 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 + Token: +BLMService: + Url: "http://18.119.109.254:8999" + LogoCombine: + #Url: "http://192.168.1.7:8999/LogoCombine" + Url: "http://18.119.109.254:8999/LogoCombine" +Unity: + Host: http://api.fusen.3718.cn:4050 \ No newline at end of file diff --git a/server/websocket/internal/config/config.go b/server/websocket/internal/config/config.go index 8315787e..adf53be1 100644 --- a/server/websocket/internal/config/config.go +++ b/server/websocket/internal/config/config.go @@ -12,4 +12,22 @@ type Config struct { Auth types.Auth ReplicaId uint64 SourceRabbitMq string + AWS struct { + S3 struct { + Credentials struct { + AccessKeyID string + Secret string + Token string + } + } + } + BLMService struct { + Url string + LogoCombine struct { + Url string + } + } + Unity struct { + Host string + } } diff --git a/server/websocket/internal/handler/datatransferhandler.go b/server/websocket/internal/handler/datatransferhandler.go index 8ef09842..c167b31c 100644 --- a/server/websocket/internal/handler/datatransferhandler.go +++ b/server/websocket/internal/handler/datatransferhandler.go @@ -10,6 +10,6 @@ func DataTransferHandler(svcCtx *svc.ServiceContext) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { // 创建一个业务逻辑层实例 l := logic.NewDataTransferLogic(r.Context(), svcCtx) - l.DataTransfer(svcCtx, w, r) + l.DataTransfer(w, r) } } diff --git a/server/render/internal/handler/rendernotifyhandler.go b/server/websocket/internal/handler/rendernotifyhandler.go similarity index 82% rename from server/render/internal/handler/rendernotifyhandler.go rename to server/websocket/internal/handler/rendernotifyhandler.go index a8d01c9c..63a84e1f 100644 --- a/server/render/internal/handler/rendernotifyhandler.go +++ b/server/websocket/internal/handler/rendernotifyhandler.go @@ -6,9 +6,9 @@ import ( "fusenapi/utils/basic" - "fusenapi/server/render/internal/logic" - "fusenapi/server/render/internal/svc" - "fusenapi/server/render/internal/types" + "fusenapi/server/websocket/internal/logic" + "fusenapi/server/websocket/internal/svc" + "fusenapi/server/websocket/internal/types" ) func RenderNotifyHandler(svcCtx *svc.ServiceContext) http.HandlerFunc { diff --git a/server/websocket/internal/handler/routes.go b/server/websocket/internal/handler/routes.go index fd3200e4..859ecc5b 100644 --- a/server/websocket/internal/handler/routes.go +++ b/server/websocket/internal/handler/routes.go @@ -17,6 +17,11 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) { Path: "/api/websocket/data_transfer", Handler: DataTransferHandler(serverCtx), }, + { + Method: http.MethodPost, + Path: "/api/websocket/render_notify", + Handler: RenderNotifyHandler(serverCtx), + }, }, ) } diff --git a/server/websocket/internal/logic/datatransferlogic.go b/server/websocket/internal/logic/datatransferlogic.go index 0511a44c..88602b7c 100644 --- a/server/websocket/internal/logic/datatransferlogic.go +++ b/server/websocket/internal/logic/datatransferlogic.go @@ -5,8 +5,6 @@ import ( "encoding/json" "fmt" "fusenapi/constants" - "fusenapi/initalize" - "fusenapi/model/gmodel" "fusenapi/utils/auth" "fusenapi/utils/id_generator" "fusenapi/utils/websocket_data" @@ -70,22 +68,20 @@ var ( // 每个连接的连接基本属性 type wsConnectItem struct { - conn *websocket.Conn //websocket的连接 - ctx context.Context - rabbitMq *initalize.RabbitMqHandle - allModels *gmodel.AllModelsGen - closeChan chan struct{} //ws连接关闭chan - isClose bool //是否已经关闭 - uniqueId string //ws连接唯一标识 - inChan chan []byte //接受消息缓冲通道 - outChan chan []byte //发送回客户端的消息 - mutex sync.Mutex //互斥锁 - userId int64 //用户id - guestId int64 //游客id - renderProperty renderProperty //扩展云渲染属性 + conn *websocket.Conn //websocket的连接 + logic *DataTransferLogic //logic + closeChan chan struct{} //ws连接关闭chan + isClose bool //是否已经关闭 + uniqueId string //ws连接唯一标识 + inChan chan []byte //接受消息缓冲通道 + outChan chan []byte //发送回客户端的消息 + mutex sync.Mutex //互斥锁 + userId int64 //用户id + guestId int64 //游客id + renderProperty renderProperty //扩展云渲染属性 } -func (l *DataTransferLogic) DataTransfer(svcCtx *svc.ServiceContext, w http.ResponseWriter, r *http.Request) { +func (l *DataTransferLogic) DataTransfer(w http.ResponseWriter, r *http.Request) { //升级websocket conn, err := upgrade.Upgrade(w, r, nil) if err != nil { @@ -98,7 +94,7 @@ func (l *DataTransferLogic) DataTransfer(svcCtx *svc.ServiceContext, w http.Resp userInfo *auth.UserInfo isAuth bool ) - isAuth, userInfo = l.checkAuth(svcCtx, r) + isAuth, userInfo = l.checkAuth(r) if !isAuth { time.Sleep(time.Second * 1) //兼容下火狐 rsp := websocket_data.DataTransferData{ @@ -126,6 +122,8 @@ func (l *DataTransferLogic) DataTransfer(svcCtx *svc.ServiceContext, w http.Resp go ws.sendLoop() //操作连接中渲染任务的增加/删除 go ws.operationRenderTask() + //消费渲染缓冲队列 + go ws.renderImage() //心跳 ws.heartbeat() } @@ -138,18 +136,17 @@ func (l *DataTransferLogic) setConnPool(conn *websocket.Conn, userInfo auth.User uniqueId := l.getUniqueId(userInfo) ws := wsConnectItem{ conn: conn, - ctx: l.ctx, - rabbitMq: l.svcCtx.RabbitMq, - allModels: l.svcCtx.AllModels, + logic: l, uniqueId: uniqueId, closeChan: make(chan struct{}, 1), - inChan: make(chan []byte, 1000), - outChan: make(chan []byte, 1000), + inChan: make(chan []byte, 100), + outChan: make(chan []byte, 100), userId: userInfo.UserId, guestId: userInfo.GuestId, renderProperty: renderProperty{ renderImageTask: make(map[string]string), renderImageTaskCtlChan: make(chan renderImageControlChanItem, 100), + renderChan: make(chan []byte, 100), }, } //保存连接 @@ -178,9 +175,9 @@ func getUserPart(userId, guestId int64) string { } // 鉴权 -func (l *DataTransferLogic) checkAuth(svcCtx *svc.ServiceContext, r *http.Request) (isAuth bool, userInfo *auth.UserInfo) { +func (l *DataTransferLogic) checkAuth(r *http.Request) (isAuth bool, userInfo *auth.UserInfo) { // 解析JWT token,并对空用户进行判断 - claims, err := svcCtx.ParseJwtToken(r) + claims, err := l.svcCtx.ParseJwtToken(r) // 如果解析JWT token出错,则返回未授权的JSON响应并记录错误消息 if err != nil { return false, nil @@ -321,7 +318,7 @@ func (w *wsConnectItem) dealwithReciveData(data []byte) { switch parseInfo.T { //图片渲染 case constants.WEBSOCKET_RENDER_IMAGE: - w.renderImage(d) + w.sendToRenderChan(d) //刷新重连请求恢复上次连接的标识 case constants.WEBSOCKET_REQUEST_REUSE_LAST_CONNECT: w.reuseLastConnect(d) diff --git a/server/websocket/internal/logic/mq_consumer.go b/server/websocket/internal/logic/mq_consumer.go deleted file mode 100644 index 16bd0eec..00000000 --- a/server/websocket/internal/logic/mq_consumer.go +++ /dev/null @@ -1,59 +0,0 @@ -package logic - -import ( - "context" - "encoding/json" - "fusenapi/constants" - "fusenapi/utils/websocket_data" - - "github.com/zeromicro/go-zero/core/logx" -) - -// 消费渲染结果数据 -type MqConsumerRenderResult struct { -} - -func (m *MqConsumerRenderResult) Run(ctx context.Context, data []byte) error { - defer func() { - if err := recover(); err != nil { - logx.Error("MqConsumerRenderResult panic:", err) - } - }() - logx.Info("接收到MqConsumerRenderResult数据:", string(data)) - var parseInfo websocket_data.RenderImageNotify - if err := json.Unmarshal(data, &parseInfo); err != nil { - logx.Error("MqConsumerRenderResult data format err:", err) - return nil //不返回错误则就删掉该消息 - } - //遍历websocket链接把数据传进去 - mapConnPool.Range(func(key, value any) bool { - //断言连接 - ws, ok := value.(wsConnectItem) - if !ok { - return true - } - //关闭标识 - if ws.isClose { - return true - } - //查询有无该渲染任务 - renderId, ok := ws.renderProperty.renderImageTask[parseInfo.TaskId] - if !ok { - return true - } - b := ws.respondDataFormat(constants.WEBSOCKET_RENDER_IMAGE, websocket_data.RenderImageRspMsg{ - RenderId: renderId, - Image: parseInfo.Image, - }) - //删除对应的需要渲染的图片map - ws.renderProperty.renderImageTaskCtlChan <- renderImageControlChanItem{ - Option: 0, //0删除 1添加 - TaskId: parseInfo.TaskId, - RenderId: renderId, - } - //发送数据到out chan - ws.sendToOutChan(b) - return true - }) - return nil -} diff --git a/server/render/internal/logic/rendernotifylogic.go b/server/websocket/internal/logic/rendernotifylogic.go similarity index 61% rename from server/render/internal/logic/rendernotifylogic.go rename to server/websocket/internal/logic/rendernotifylogic.go index c49da008..58b9ffeb 100644 --- a/server/render/internal/logic/rendernotifylogic.go +++ b/server/websocket/internal/logic/rendernotifylogic.go @@ -1,16 +1,17 @@ package logic import ( - "context" - "encoding/json" "fusenapi/constants" "fusenapi/utils/auth" "fusenapi/utils/basic" "fusenapi/utils/file" "fusenapi/utils/websocket_data" + "time" - "fusenapi/server/render/internal/svc" - "fusenapi/server/render/internal/types" + "context" + + "fusenapi/server/websocket/internal/svc" + "fusenapi/server/websocket/internal/types" "github.com/zeromicro/go-zero/core/logx" ) @@ -55,26 +56,56 @@ func (l *RenderNotifyLogic) RenderNotify(req *types.RenderNotifyReq, userinfo *a AwsSession: l.svcCtx.AwsSession, } uploadRes, err := upload.UploadFileByBase64(&file.UploadBaseReq{ + Source: "unity cloud render", FileHash: req.TaskId, FileData: req.Image, + Metadata: "", UploadBucket: 1, ApiType: 2, UserId: req.UserId, GuestId: req.GuestId, + FileByte: nil, }) if err != nil { logx.Error(err) return resp.SetStatusWithMessage(basic.CodeFileUploadErr, "failed to upload render resource image") } - //发送消息到对应的rabbitmq - data := websocket_data.RenderImageNotify{ - TaskId: req.TaskId, - Image: uploadRes.ResourceUrl, - } - d, _ := json.Marshal(data) - if err = l.svcCtx.RabbitMq.SendMsg(constants.RABBIT_MQ_RENDER_RESULT_DATA, d); err != nil { - logx.Error(err) - return resp.SetStatusWithMessage(basic.CodeServiceErr, "failed to send data") - } + //遍历websocket链接把数据传进去 + mapConnPool.Range(func(key, value any) bool { + //断言连接 + ws, ok := value.(wsConnectItem) + if !ok { + return true + } + //关闭标识 + if ws.isClose { + return true + } + //查询有无该渲染任务 + renderId, ok := ws.renderProperty.renderImageTask[req.TaskId] + if !ok { + return true + } + b := ws.respondDataFormat(constants.WEBSOCKET_RENDER_IMAGE, websocket_data.RenderImageRspMsg{ + RenderId: renderId, + Image: uploadRes.ResourceUrl, + }) + deleteTask := renderImageControlChanItem{ + Option: 0, //0删除 1添加 + TaskId: req.TaskId, + RenderId: renderId, + } + select { + case <-ws.closeChan: //关闭了 + return true + case ws.renderProperty.renderImageTaskCtlChan <- deleteTask: //删除对应的需要渲染的图片map + //发送数据到out chan + ws.sendToOutChan(b) + case <-time.After(time.Second * 3): //超时丢弃 + return true + } + return true + }) + logx.Info("渲染回调成功######################") return resp.SetStatusWithMessage(basic.CodeOK, "success") } diff --git a/server/websocket/internal/logic/ws_render_image_logic.go b/server/websocket/internal/logic/ws_render_image_logic.go index 45d5688f..ec133adb 100644 --- a/server/websocket/internal/logic/ws_render_image_logic.go +++ b/server/websocket/internal/logic/ws_render_image_logic.go @@ -1,20 +1,26 @@ package logic import ( + "bytes" "encoding/json" "errors" "fusenapi/constants" + "fusenapi/service/repositories" + "fusenapi/utils/curl" "fusenapi/utils/hash" "fusenapi/utils/websocket_data" "github.com/zeromicro/go-zero/core/logx" "gorm.io/gorm" + "strconv" + "time" ) // 云渲染属性 type renderProperty struct { renderImageTask map[string]string //需要渲染的图片任务 key是taskId val 是renderId renderImageTaskCtlChan chan renderImageControlChanItem //渲染任务新增移除的控制通道 + renderChan chan []byte //渲染的缓冲队列 } // 渲染任务新增移除的控制通道的数据 @@ -24,8 +30,39 @@ type renderImageControlChanItem struct { RenderId string // map的val } +// 发送到渲染缓冲池 +func (w *wsConnectItem) sendToRenderChan(data []byte) { + select { + case <-w.closeChan: //已经关闭 + return + case w.renderProperty.renderChan <- data: + return + case <-time.After(time.Second * 3): + return + } +} + // 渲染发送到组装数据组装数据 -func (w *wsConnectItem) renderImage(data []byte) { +func (w *wsConnectItem) renderImage() { + defer func() { + if err := recover(); err != nil { + logx.Error("renderImage panic:", err) + } + }() + for { + select { + case <-w.closeChan: //已关闭 + return + case data := <-w.renderProperty.renderChan: + w.consumeRenderCache(data) + } + } + +} + +// 消费渲染缓冲数据 +func (w *wsConnectItem) consumeRenderCache(data []byte) { + logx.Info("消费渲染数据:", string(data)) var renderImageData websocket_data.RenderImageReqMsg if err := json.Unmarshal(data, &renderImageData); err != nil { w.sendToOutChan(w.respondDataFormat(constants.WEBSOCKET_ERR_DATA_FORMAT, "invalid format of websocket render image message:"+string(data))) @@ -49,7 +86,7 @@ func (w *wsConnectItem) renderImage(data []byte) { return } //获取上传最近的logo - userMaterial, err := w.allModels.FsUserMaterial.FindLatestOne(w.ctx, w.userId, w.guestId) + userMaterial, err := w.logic.svcCtx.AllModels.FsUserMaterial.FindLatestOne(w.logic.ctx, w.userId, w.guestId) if err != nil { if !errors.Is(err, gorm.ErrRecordNotFound) { w.sendToOutChan(w.respondDataFormat(constants.WEBSOCKET_ERR_DATA_FORMAT, "failed to get user logo")) @@ -57,7 +94,7 @@ func (w *wsConnectItem) renderImage(data []byte) { return } //使用默认logo(id=0) - userMaterialDefault, err := w.allModels.FsUserMaterial.FindOneById(w.ctx, 0) + userMaterialDefault, err := w.logic.svcCtx.AllModels.FsUserMaterial.FindOneById(w.logic.ctx, 0) if err != nil { if errors.Is(err, gorm.ErrRecordNotFound) { w.sendToOutChan(w.respondDataFormat(constants.WEBSOCKET_ERR_DATA_FORMAT, "default logo is not exists")) @@ -75,10 +112,13 @@ func (w *wsConnectItem) renderImage(data []byte) { renderImageData.RenderData.UserId = w.userId renderImageData.RenderData.GuestId = w.guestId - //生成任务id - taskId := hash.JsonHashKey(renderImageData.RenderData) + //生成任务id(需要把user_id,guest_id设为0) + hashVal := renderImageData.RenderData + hashVal.UserId = 0 + hashVal.GuestId = 0 + taskId := hash.JsonHashKey(hashVal) //查询有没有缓存的资源,有就返回###################### - resource, err := w.allModels.FsResource.FindOneById(w.ctx, taskId) + resource, err := w.logic.svcCtx.AllModels.FsResource.FindOneById(w.logic.ctx, taskId) if err != nil { if !errors.Is(err, gorm.ErrRecordNotFound) { logx.Error("failed to find render resource:", err) @@ -101,18 +141,156 @@ func (w *wsConnectItem) renderImage(data []byte) { TaskId: taskId, RenderId: renderImageData.RenderId, } - tmpData := websocket_data.AssembleRenderData{ - TaskId: taskId, - RenderId: renderImageData.RenderId, - RenderData: renderImageData.RenderData, - } - d, _ := json.Marshal(tmpData) - //发送给对应的流水线组装数据 - if err = w.rabbitMq.SendMsg(constants.RABBIT_MQ_ASSEMBLE_RENDER_DATA, d); err != nil { - logx.Error("发送渲染任务数据到MQ失败:", string(d), "err:", err) + //组装数据 + if err = w.assembleRenderData(taskId, renderImageData); err != nil { + logx.Error("组装数据失败:", err) return } - logx.Info("发送渲染数据到rabbitmq成功:", string(d)) +} + +// 组装数据发送给unity +func (w *wsConnectItem) assembleRenderData(taskId string, info websocket_data.RenderImageReqMsg) error { + defer func() { + if err := recover(); err != nil { + logx.Error("assembleRenderData panic:", err) + } + }() + //获取模板 + productTemplate, err := w.logic.svcCtx.AllModels.FsProductTemplateV2.FindOneByProductIdTagIdWithSizeTable(w.logic.ctx, info.RenderData.ProductId, info.RenderData.TemplateTag) + if err != nil { + if errors.Is(err, gorm.ErrRecordNotFound) { + logx.Error("template info is not found") + return err + } + logx.Error("failed to get template info:", err) + return err + } + //获取刀版图 + res, err := w.logic.svcCtx.Repositories.ImageHandle.LogoCombine(w.logic.ctx, &repositories.LogoCombineReq{ + UserId: info.RenderData.UserId, + GuestId: info.RenderData.GuestId, + TemplateId: productTemplate.Id, + TemplateTag: info.RenderData.TemplateTag, + Website: info.RenderData.Website, + Slogan: info.RenderData.Slogan, + Address: info.RenderData.Address, + Phone: info.RenderData.Phone, + }) + if err != nil { + logx.Error("合成刀版图失败:", err) + return err + } + combineImage := "" //刀版图 + if res != nil && res.ResourceUrl != nil { + combineImage = *res.ResourceUrl + } else { + logx.Error("合成刀版图失败,合成的刀版图是空指针:", err) + return err + } + logx.Info("合成刀版图成功:", *res.ResourceUrl) + //获取渲染设置信息 + element, err := w.logic.svcCtx.AllModels.FsProductTemplateElement.FindOneByModelId(w.logic.ctx, *productTemplate.ModelId) + if err != nil { + if errors.Is(err, gorm.ErrRecordNotFound) { + // todo 没有图就给他返回一张默认(后面要删除) + defaultImg := w.respondDataFormat(constants.WEBSOCKET_RENDER_IMAGE, websocket_data.RenderImageRspMsg{ + RenderId: info.RenderId, + Image: "https://s3.us-west-1.amazonaws.com/storage.fusenpack.com/695463af6e9b93c003db39ddf728241f9523efc55b20dc37f30fe5d96ed54fb5", + }) + w.sendToOutChan(defaultImg) + logx.Error("element info is not found,model_id = ", *productTemplate.ModelId) + return err + } + logx.Error("failed to get element list,", err) + return err + } + //组装数据 + refletion := -1 + if element.Refletion != nil && *element.Refletion != "" { + refletion, err = strconv.Atoi(*element.Refletion) + } + //组装data数据 + var mode map[string]interface{} + if element.Mode != nil && *element.Mode != "" { + if err = json.Unmarshal([]byte(*element.Mode), &mode); err != nil { + logx.Error("faile to parse element mode json:", err) + return err + } + } + tempData := make([]map[string]interface{}, 0, 3) + if element.Base != nil && *element.Base != "" { + tempData = append(tempData, map[string]interface{}{ + "name": "model", + "data": "0," + combineImage + "," + *element.Base, + "type": "other", + "layer": "0", + "is_update": 1, + "mode": mode["model"], + }) + } + if element.Shadow != nil && *element.Shadow != "" { + tempData = append(tempData, map[string]interface{}{ + "name": "shadow", + "data": *element.Shadow, + "type": "other", + "layer": "0", + "is_update": 0, + "mode": mode["shadow"], + }) + } + if element.ModelP != nil && *element.ModelP != "" { + tempData = append(tempData, map[string]interface{}{ + "name": "model_P", + "data": "0," + *element.ModelP, + "type": "other", + "layer": "0", + "is_update": 0, + "mode": mode["model_P"], + }) + } + result := []interface{}{ + map[string]interface{}{ + "light": *element.Light, + "refletion": refletion, + "scale": *element.Scale, + "sku_id": info.RenderData.ProductId, + "tid": *element.Title, + "rotation": *element.Rotation, + "filePath": "", //todo 文件路径,针对千人千面 + "data": tempData, + }, + } + sendData := map[string]interface{}{ + "id": taskId, + "order_id": 0, + "user_id": info.RenderData.UserId, + "guest_id": info.RenderData.GuestId, + "sku_ids": []int64{info.RenderData.ProductId}, + "tids": []string{*element.Title}, + "data": result, + "is_thousand_face": 0, + "folder": "", //todo 千人千面需要使用 + } + //请求unity接口 + url := "http://api.fusen.3718.cn:4050/api/render/queue/push" + header := make(map[string]string) + header["content-type"] = "application/json" + t := time.Now().UTC() + postData := map[string]interface{}{ + "group": "unity3d", + "source": "home page", + "priority": 1, + "create_at": t, + "render_data": sendData, + } + p, _ := json.Marshal(postData) + _, err = curl.ApiCall(url, "POST", header, bytes.NewReader(p), time.Second*10) + if err != nil { + logx.Error("failed to send data to unity") + return err + } + logx.Info("发送到unity成功################") + return nil } // 操作连接中渲染任务的增加/删除 diff --git a/server/websocket/internal/svc/servicecontext.go b/server/websocket/internal/svc/servicecontext.go index 0b1c7759..d3834630 100644 --- a/server/websocket/internal/svc/servicecontext.go +++ b/server/websocket/internal/svc/servicecontext.go @@ -7,6 +7,10 @@ import ( "fusenapi/shared" "net/http" + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/credentials" + "github.com/aws/aws-sdk-go/aws/session" + "fusenapi/initalize" "fusenapi/model/gmodel" @@ -18,21 +22,29 @@ type ServiceContext struct { Config config.Config SharedState *shared.SharedState - MysqlConn *gorm.DB - AllModels *gmodel.AllModelsGen - RabbitMq *initalize.RabbitMqHandle + MysqlConn *gorm.DB + AllModels *gmodel.AllModelsGen + RabbitMq *initalize.RabbitMqHandle + AwsSession *session.Session + Repositories *initalize.Repositories } func NewServiceContext(c config.Config) *ServiceContext { conn := initalize.InitMysql(c.SourceMysql) - // StateServer := shared.StartNode(c.ReplicaId, autoconfig.AutoGetAllServerConfig(), conn) - + config := aws.Config{ + Credentials: credentials.NewStaticCredentials(c.AWS.S3.Credentials.AccessKeyID, c.AWS.S3.Credentials.Secret, c.AWS.S3.Credentials.Token), + } return &ServiceContext{ - Config: c, - SharedState: nil, - MysqlConn: conn, - AllModels: gmodel.NewAllModels(initalize.InitMysql(c.SourceMysql)), - RabbitMq: initalize.InitRabbitMq(c.SourceRabbitMq, nil), + Config: c, + MysqlConn: conn, + AllModels: gmodel.NewAllModels(conn), + RabbitMq: initalize.InitRabbitMq(c.SourceRabbitMq, nil), + AwsSession: session.Must(session.NewSession(&config)), + Repositories: initalize.NewAllRepositories(&initalize.NewAllRepositorieData{ + GormDB: conn, + BLMServiceUrl: &c.BLMService.Url, + AwsSession: session.Must(session.NewSession(&config)), + }), } } diff --git a/server/websocket/internal/types/types.go b/server/websocket/internal/types/types.go index 266a1bbf..087da9ba 100644 --- a/server/websocket/internal/types/types.go +++ b/server/websocket/internal/types/types.go @@ -5,21 +5,11 @@ import ( "fusenapi/utils/basic" ) -type RequestToUnity struct { -} - -type RequestReadImages struct { -} - type RenderNotifyReq struct { - Sign string `json:"sign"` - Time int64 `json:"time"` - Info NotifyInfo `json:"info"` -} - -type NotifyInfo struct { - TaskId string `json:"task_id"` //任务id - Image string `json:"image"` + TaskId string `json:"task_id"` //任务id + UserId int64 `json:"user_id"` + GuestId int64 `json:"guest_id"` + Image string `json:"image"` } type Request struct { diff --git a/server/websocket/websocket.go b/server/websocket/websocket.go index cfc775f7..b6c469b6 100644 --- a/server/websocket/websocket.go +++ b/server/websocket/websocket.go @@ -1,11 +1,8 @@ package main import ( - "context" "flag" "fmt" - "fusenapi/constants" - "fusenapi/server/websocket/internal/logic" "net/http" "fusenapi/utils/auth" @@ -30,12 +27,6 @@ func main() { defer server.Stop() ctx := svc.NewServiceContext(c) - //消费渲染结果队列 - ctx1 := context.Background() - ctx2, cancel := context.WithCancel(ctx1) - ctx2 = context.WithValue(ctx2, "allmodels", ctx.AllModels) - defer cancel() - go ctx.RabbitMq.Consume(ctx2, constants.RABBIT_MQ_RENDER_RESULT_DATA, &logic.MqConsumerRenderResult{}) handler.RegisterHandlers(server, ctx) fmt.Printf("Starting server at %s:%d...\n", c.Host, c.Port) server.Start() diff --git a/server_api/render.api b/server_api/render.api index 2a717984..c860476f 100644 --- a/server_api/render.api +++ b/server_api/render.api @@ -8,26 +8,8 @@ info ( ) import "basic.api" - -type RequestToUnity { -} - -type RequestReadImages { -} - service render { - //云渲染完了通知接口 - @handler RenderNotifyHandler - post /api/render/render_notify(RenderNotifyReq) returns (response); //获取面片信息 @handler GetFaceSliceHandler post /api/render/get_face_slice(request) returns (response); -} - -//渲染完了通知接口 -type RenderNotifyReq { - TaskId string `json:"task_id"` //任务id - UserId int64 `json:"user_id"` - GuestId int64 `json:"guest_id"` - Image string `json:"image"` } \ No newline at end of file diff --git a/server_api/upload.api b/server_api/upload.api index a3c7399f..85e85433 100644 --- a/server_api/upload.api +++ b/server_api/upload.api @@ -53,6 +53,7 @@ type ( UserId int64 `form:"user_id,optional"` // 上传文件额外信息 GuestId int64 `form:"guest_id,optional"` // 上传文件额外信息 UploadBucket int64 `form:"upload_bucket,options=[1,2],default=1"` // 上传桶名:1=缓存,2=持久 + Source string `form:"source"` // 上传来源 } ) @@ -72,12 +73,14 @@ type ( FileKey string `form:"file_key"` // 上传唯一标识信息 FileSize int64 `form:"file_size,optional"` // 上传唯一标识信息 Metadata string `form:"meta_data,optional"` // 上传文件额外信息 + Source string `form:"source"` // 上传来源 } UploadFilesReq { ApiType int64 `form:"api_type,options=[1,2],default=1"` // 调用类型:1=对外,2=对内 UploadBucket int64 `form:"upload_bucket,options=[1,2],default=1"` // 上传桶名:1=缓存,2=持久 UploadInfo string `form:"upload_info"` // 上传信息 json + Source string `form:"source"` // 上传来源 } UploadCallbackReq { UploadBucket int64 `form:"upload_bucket,options=[1,2],default=1"` // 上传桶名:1=缓存,2=持久 @@ -86,6 +89,7 @@ type ( ResourceUrl string `form:"resource_url"` // 资源URL Metadata string `form:"metadata,optional"` // 元数据,json格式,存储图像分率 ApiType int64 `form:"api_type,options=[1,2],default=1"` // 调用类型:1=对外,2=对内 + Source string `form:"source"` // 上传来源 } ) diff --git a/server_api/websocket.api b/server_api/websocket.api index ef24d79f..b5adb666 100644 --- a/server_api/websocket.api +++ b/server_api/websocket.api @@ -12,4 +12,15 @@ service websocket { //websocket数据交互 @handler DataTransferHandler get /api/websocket/data_transfer(request) returns (response); + //云渲染完了通知接口 + @handler RenderNotifyHandler + post /api/websocket/render_notify(RenderNotifyReq) returns (response); +} + +//渲染完了通知接口 +type RenderNotifyReq { + TaskId string `json:"task_id"` //任务id + UserId int64 `json:"user_id"` + GuestId int64 `json:"guest_id"` + Image string `json:"image"` } \ No newline at end of file diff --git a/service/repositories/image_handle.go b/service/repositories/image_handle.go index 861a9f1e..ffacf0d2 100644 --- a/service/repositories/image_handle.go +++ b/service/repositories/image_handle.go @@ -46,7 +46,7 @@ type ( UserId int64 `json:"user_id"` GuestId int64 `json:"guest_id"` TemplateId int64 `json:"template_id"` - TemplateTag string `json:"resource_key"` + TemplateTag string `json:"template_tag"` Website string `json:"website"` // 合图参数 Slogan string `json:"slogan"` // 合图参数 Address string `json:"address"` // 合图参数 @@ -62,7 +62,10 @@ type ( func (l *defaultImageHandle) LogoCombine(ctx context.Context, in *LogoCombineReq) (*LogoCombineRes, error) { // 根据hash 查询数据资源 - var resourceId string = hash.JsonHashKey(in) + var hashKeyData = *in + hashKeyData.GuestId = 0 + hashKeyData.UserId = 0 + var resourceId string = hash.JsonHashKey(hashKeyData) resourceModel := gmodel.NewFsResourceModel(l.MysqlConn) resourceInfo, err := resourceModel.FindOneById(ctx, resourceId) @@ -89,15 +92,6 @@ func (l *defaultImageHandle) LogoCombine(ctx context.Context, in *LogoCombineReq return nil, err } var groupOptions map[string]interface{} - if productTemplateV2Info.GroupOptions != nil { - err = json.Unmarshal([]byte(*productTemplateV2Info.GroupOptions), &groupOptions) - - if err != nil { - logx.Error(err) - return nil, err - } - } - var materialList []interface{} if productTemplateV2Info.TemplateInfo != nil { var templateInfo map[string]interface{} @@ -108,6 +102,7 @@ func (l *defaultImageHandle) LogoCombine(ctx context.Context, in *LogoCombineReq return nil, err } materialList = templateInfo["materialList"].([]interface{}) + groupOptions = templateInfo["groupOptions"].(map[string]interface{}) } var moduleDataMap = make(map[string]interface{}, 4) @@ -211,6 +206,7 @@ func (l *defaultImageHandle) LogoCombine(ctx context.Context, in *LogoCombineReq AwsSession: l.AwsSession, } uploadRes, err := upload.UploadFileByBase64(&file.UploadBaseReq{ + Source: "combine-image", FileHash: resourceId, FileData: fileBase.(string), UploadBucket: 1, diff --git a/utils/file/upload.go b/utils/file/upload.go index d19752e7..d561ae28 100644 --- a/utils/file/upload.go +++ b/utils/file/upload.go @@ -22,6 +22,7 @@ type Upload struct { } type UploadBaseReq struct { + Source string FileHash string FileData string Metadata string @@ -119,6 +120,7 @@ func (upload *Upload) UploadFileByBase64(req *UploadBaseReq) (*UploadBaseRes, er Metadata: &req.Metadata, ApiType: &apiType, BucketName: bucketName, + Source: &req.Source, }).Error if err != nil { logx.Errorf("err:%+v,desc:%+v", err, "fail.upload.resourceInfoAdd.mysql") @@ -212,6 +214,7 @@ func (upload *Upload) UploadFileByByte(req *UploadBaseReq) (*UploadBaseRes, erro Metadata: &req.Metadata, ApiType: &apiType, BucketName: bucketName, + Source: &req.Source, }).Error if err != nil { logx.Errorf("err:%+v,desc:%+v", err, "fail.upload.resourceInfoAdd.mysql") diff --git a/utils/websocket_data/render_data.go b/utils/websocket_data/render_data.go index bb4c82eb..0238bcfa 100644 --- a/utils/websocket_data/render_data.go +++ b/utils/websocket_data/render_data.go @@ -28,20 +28,7 @@ type RenderImageRspMsg struct { RenderId string `json:"render_id"` //渲染id Image string `json:"image"` //渲染结果图片 } - -// 渲染服务器回调数据 -type RenderImageNotify struct { - TaskId string `json:"task_id"` - Image string `json:"image"` -} type ThirdPartyLoginRspMsg struct { //websocket三方登录的通知数据 Token string `json:"token"` } - -// 发送到渲染组装的mq数据 -type AssembleRenderData struct { - TaskId string `json:"task_id"` - RenderId string `json:"render_id"` - RenderData RenderData `json:"render_data"` -}