diff --git a/constants/rabbitmq.go b/constants/rabbitmq.go index 85269033..e9e06ef5 100644 --- a/constants/rabbitmq.go +++ b/constants/rabbitmq.go @@ -8,4 +8,13 @@ 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" ) + +// 队列列表 +var MqQueueArr = []RABBIT_MQ{ + RABBIT_MQ_ASSEMBLE_RENDER_DATA, + RABBIT_MQ_RENDER_RESULT_DATA, + RABBIT_MQ_TO_UNITY, +} diff --git a/initalize/mysql.go b/initalize/mysql.go index b41fe319..7ac6eaae 100644 --- a/initalize/mysql.go +++ b/initalize/mysql.go @@ -32,10 +32,10 @@ func InitMysql(sourceMysql string) *gorm.DB { panic(err) } // SetMaxIdleConns 设置空闲连接池中连接的最大数量 - sqlDB.SetMaxIdleConns(10) + sqlDB.SetMaxIdleConns(4) // SetMaxOpenConns 设置打开数据库连接的最大数量。 - sqlDB.SetMaxOpenConns(50) + sqlDB.SetMaxOpenConns(25) // SetConnMaxLifetime 设置了连接可复用的最大时间。 sqlDB.SetConnMaxLifetime(time.Minute * 20) diff --git a/initalize/rabbitmq.go b/initalize/rabbitmq.go index da7f4e7f..58a26645 100644 --- a/initalize/rabbitmq.go +++ b/initalize/rabbitmq.go @@ -21,12 +21,6 @@ type queueItem struct { queue amqp.Queue } -// 队列列表 -var mqQueueArr = []constants.RABBIT_MQ{ - constants.RABBIT_MQ_ASSEMBLE_RENDER_DATA, - constants.RABBIT_MQ_RENDER_RESULT_DATA, -} - // 存储连接 var mapMq = make(map[constants.RABBIT_MQ]queueItem) @@ -44,7 +38,7 @@ func InitRabbitMq(url string, config *tls.Config) *RabbitMqHandle { log.Fatalf("Failed to open a channel: %v", err) } //声明队列 - for _, queueName := range mqQueueArr { + for _, queueName := range constants.MqQueueArr { q, err := ch.QueueDeclare( string(queueName), // 队列名 true, // 是否持久化 diff --git a/model/gmodel/fs_product_tag_prop_gen.go b/model/gmodel/fs_product_tag_prop_gen.go index 078d6b4b..96a00508 100644 --- a/model/gmodel/fs_product_tag_prop_gen.go +++ b/model/gmodel/fs_product_tag_prop_gen.go @@ -6,12 +6,12 @@ import ( // fs_product_tag_prop 产品标签相关属性表 type FsProductTagProp struct { - Id int64 `gorm:"primary_key;default:0;auto_increment;" json:"id"` // id - ProductId *int64 `gorm:"default:0;" json:"product_id"` // 产品id - TagId *int64 `gorm:"default:0;" json:"tag_id"` // 模板标签id - Cover *string `gorm:"default:'';" json:"cover"` // - Status *int64 `gorm:"default:1;" json:"status"` // 状态 - Ctime *int64 `gorm:"default:0;" json:"ctime"` // 创建时间 + Id int64 `gorm:"primary_key;default:0;auto_increment;" json:"id"` // id + ProductId *int64 `gorm:"default:0;" json:"product_id"` // 产品id + TemplateTagId *int64 `gorm:"default:0;" json:"template_tag_id"` // 模板标签id + Cover *string `gorm:"default:'';" json:"cover"` // + Status *int64 `gorm:"default:1;" json:"status"` // 状态 + Ctime *int64 `gorm:"default:0;" json:"ctime"` // 创建时间 } type FsProductTagPropModel struct { db *gorm.DB diff --git a/model/gmodel/fs_product_tag_prop_logic.go b/model/gmodel/fs_product_tag_prop_logic.go index e68225aa..6612e196 100644 --- a/model/gmodel/fs_product_tag_prop_logic.go +++ b/model/gmodel/fs_product_tag_prop_logic.go @@ -1,2 +1,21 @@ package gmodel -// TODO: 使用model的属性做你想做的 \ No newline at end of file + +import "context" + +// TODO: 使用model的属性做你想做的 +type GetTagPropByProductIdsWithProductTagRsp struct { + FsProductTagProp + Title string `json:"title"` +} + +func (p *FsProductTagPropModel) GetTagPropByProductIdsWithProductTag(ctx context.Context, productIds []int64) (resp []GetTagPropByProductIdsWithProductTagRsp, err error) { + if len(productIds) == 0 { + return + } + 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"). + 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_logic.go b/model/gmodel/fs_product_template_element_logic.go index 35237a04..783f5480 100644 --- a/model/gmodel/fs_product_template_element_logic.go +++ b/model/gmodel/fs_product_template_element_logic.go @@ -1,3 +1,13 @@ package gmodel +import "context" + // TODO: 使用model的属性做你想做的 + +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). + Take(&resp).Error + return resp, err +} diff --git a/model/gmodel/fs_product_template_v2_logic.go b/model/gmodel/fs_product_template_v2_logic.go index dc8a1b02..d760f398 100755 --- a/model/gmodel/fs_product_template_v2_logic.go +++ b/model/gmodel/fs_product_template_v2_logic.go @@ -57,6 +57,9 @@ func (t *FsProductTemplateV2Model) FindAllByModelIds(ctx context.Context, modelI return } db := t.db.WithContext(ctx).Model(&FsProductTemplateV2{}).Where("`model_id` in (?) and `is_del` = ? and `status` = ?", modelIds, 0, 1) + if len(fields) != 0 { + db = db.Select(fields[0]) + } switch orderBy { case "": db = db.Order("id DESC") @@ -119,3 +122,20 @@ func (t *FsProductTemplateV2Model) FindOneByProductIdTagIdWithSizeTable(ctx cont Take(&resp).Error return resp, err } +func (t *FsProductTemplateV2Model) FindAllByModelIdsTemplateTag(ctx context.Context, modelIds []int64, templateTag string, orderBy string, fields ...string) (resp []FsProductTemplateV2, err error) { + 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) + if len(fields) != 0 { + db = db.Select(fields[0]) + } + switch orderBy { + case "": + db = db.Order("id DESC") + default: + db = db.Order(orderBy) + } + err = db.Find(&resp).Error + return resp, err +} diff --git a/server/product/internal/logic/getsizebypidlogic.go b/server/product/internal/logic/getsizebypidlogic.go index 3db7c7f3..55a0471c 100644 --- a/server/product/internal/logic/getsizebypidlogic.go +++ b/server/product/internal/logic/getsizebypidlogic.go @@ -6,7 +6,9 @@ import ( "fusenapi/constants" "fusenapi/utils/auth" "fusenapi/utils/basic" + "fusenapi/utils/format" "gorm.io/gorm" + "sort" "strings" "context" @@ -52,8 +54,38 @@ func (l *GetSizeByPidLogic) GetSizeByPid(req *types.GetSizeByPidReq, userinfo *a return resp.SetStatusWithMessage(basic.CodeDbSqlErr, "failed to get size list") } sizeIds := make([]int64, 0, len(sizeList)) + productIds := make([]int64, 0, len(sizeList)) for _, v := range sizeList { sizeIds = append(sizeIds, v.Id) + productIds = append(productIds, *v.ProductId) + } + //获取产品价格列表 + productPriceList, err := l.svcCtx.AllModels.FsProductPrice.GetSimplePriceListByProductIds(l.ctx, productIds) + if err != nil { + logx.Error(err) + return resp.SetStatusWithMessage(basic.CodeServiceErr, "failed to get product min price list") + } + mapProductMinPrice := make(map[int64]int64) + //存储产品最小价格 + for _, v := range productPriceList { + priceStrSlic := strings.Split(v.Price, ",") + priceSlice, err := format.StrSlicToIntSlice(priceStrSlic) + if err != nil { + logx.Error(err) + return resp.SetStatusWithMessage(basic.CodeServiceErr, err.Error()) + } + if len(priceSlice) == 0 { + continue + } + //正序排序价格(注意排序后的阶梯价格不能用作阶梯数量价格计算) + sort.Ints(priceSlice) + if min, ok := mapProductMinPrice[v.ProductId]; ok { + if min > int64(priceSlice[0]) { + mapProductMinPrice[v.ProductId] = int64(priceSlice[0]) + } + } else { + mapProductMinPrice[v.ProductId] = int64(priceSlice[0]) + } } //获取对应模型数据 modelList, err := l.svcCtx.AllModels.FsProductModel3d.GetAllBySizeIdsTag(l.ctx, sizeIds, constants.TAG_MODEL, "id,size_id") @@ -75,6 +107,10 @@ func (l *GetSizeByPidLogic) GetSizeByPid(req *types.GetSizeByPidReq, userinfo *a } var title interface{} _ = json.Unmarshal([]byte(*sizeInfo.Title), &title) + minPrice := int64(0) + if price, ok := mapProductMinPrice[*sizeInfo.ProductId]; ok { + minPrice = price + } listRsp = append(listRsp, types.GetSizeByPidRsp{ Id: sizeInfo.Id, Title: title, @@ -83,6 +119,7 @@ func (l *GetSizeByPidLogic) GetSizeByPid(req *types.GetSizeByPidReq, userinfo *a PartsCanDeleted: *sizeInfo.PartsCanDeleted > 0, ModelId: modelList[modelIndex].Id, IsPopular: *sizeInfo.IsPopular > 0, + MinPrice: float64(minPrice) / 100, }) } return resp.SetStatusWithMessage(basic.CodeOK, "success", listRsp) diff --git a/server/product/internal/logic/gettagproductlistlogic.go b/server/product/internal/logic/gettagproductlistlogic.go index 948c9799..8c6f5a3c 100644 --- a/server/product/internal/logic/gettagproductlistlogic.go +++ b/server/product/internal/logic/gettagproductlistlogic.go @@ -34,16 +34,16 @@ func NewGetTagProductListLogic(ctx context.Context, svcCtx *svc.ServiceContext) } func (l *GetTagProductListLogic) GetTagProductList(req *types.GetTagProductListReq, userinfo *auth.UserInfo) (resp *basic.Response) { - //获取合适尺寸 - if req.Size > 0 { - req.Size = image.GetCurrentSize(req.Size) - } //查询用户信息(不用判断存在) user, err := l.svcCtx.AllModels.FsUser.FindUserById(l.ctx, userinfo.UserId) if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) { logx.Error(err) return resp.SetStatusWithMessage(basic.CodeServiceErr, "get user info err") } + //获取合适尺寸 + if req.Size > 0 { + req.Size = image.GetCurrentSize(req.Size) + } //查询分类列表 tStatus := int64(1) tReq := gmodel.GetAllTagByParamsReq{ @@ -81,7 +81,8 @@ func (l *GetTagProductListLogic) GetTagProductList(req *types.GetTagProductListR typeIds = append(typeIds, v.Id) } var ( - productList []gmodel.FsProduct //产品列表(select 字段需要看查询的地方) + productList []gmodel.FsProduct //产品列表(select 字段需要看查询的地方) + mapTagProp = make(map[int64][]types.CoverDefaultItem) productOptionalPartList []gmodel.GetGroupPartListByProductIdsRsp //产品配件列表 mapProductHaveOptionFitting = make(map[int64]struct{}) productPriceList []gmodel.GetPriceListByProductIdsRsp //产品价格列表(select 字段需要看查询的地方) @@ -129,6 +130,18 @@ func (l *GetTagProductListLogic) GetTagProductList(req *types.GetTagProductListR } mapProductHaveOptionFitting[partList.ProductId] = struct{}{} } + //获取产品标签相关属性 + productTagPropList, err := l.svcCtx.AllModels.FsProductTagProp.GetTagPropByProductIdsWithProductTag(l.ctx, productIds) + if err != nil { + logx.Error(err) + return resp.SetStatusWithMessage(basic.CodeDbSqlErr, "failed to get product tag property") + } + for _, v := range productTagPropList { + mapTagProp[*v.ProductId] = append(mapTagProp[*v.ProductId], types.CoverDefaultItem{ + Tag: v.Title, + Cover: *v.Cover, + }) + } //获取产品价格列表 productPriceList, err = l.svcCtx.AllModels.FsProductPrice.GetSimplePriceListByProductIds(l.ctx, productIds) if err != nil { @@ -183,6 +196,7 @@ func (l *GetTagProductListLogic) GetTagProductList(req *types.GetTagProductListR TagList: tagList, WithProduct: req.WithProduct, ProductList: productList, + MapTagProp: mapTagProp, MapProductMinPrice: mapProductMinPrice, MapProductTemplate: mapProductTemplate, MapProductSizeCount: mapProductSizeCount, @@ -206,6 +220,8 @@ type dealWithTagMenuDataReq struct { TagList []gmodel.FsTags WithProduct bool ProductList []gmodel.FsProduct + MapTagProp map[int64][]types.CoverDefaultItem + ProductTagPropList []gmodel.FsProductTagProp MapProductMinPrice map[int64]int64 MapProductTemplate map[int64]struct{} MapProductSizeCount map[int64]int64 @@ -238,6 +254,7 @@ func (l *GetTagProductListLogic) dealWithTagMenuData(req dealWithTagMenuDataReq) productListRsp := l.getTagProducts(getTagProductsReq{ TagId: tagInfo.Id, ProductList: req.ProductList, + MapTagProp: req.MapTagProp, MapProductMinPrice: req.MapProductMinPrice, MapProductTemplate: req.MapProductTemplate, MapProductSizeCount: req.MapProductSizeCount, @@ -308,6 +325,7 @@ func (l *GetTagProductListLogic) organizationLevelRelation(minLevel int, mapTagL type getTagProductsReq struct { TagId int64 ProductList []gmodel.FsProduct + MapTagProp map[int64][]types.CoverDefaultItem MapProductMinPrice map[int64]int64 MapProductTemplate map[int64]struct{} MapProductSizeCount map[int64]int64 @@ -344,17 +362,20 @@ func (l *GetTagProductListLogic) getTagProducts(req getTagProductsReq) (productL Sn: *productInfo.Sn, Title: *productInfo.Title, SizeNum: uint32(sizeNum), + CoverDefault: []types.CoverDefaultItem{}, MinPrice: minPrice, HaveOptionalFitting: haveOptionalFitting, Recommended: *productInfo.IsRecommend > 0, } + if _, ok = req.MapTagProp[productInfo.Id]; ok { + item.CoverDefault = req.MapTagProp[productInfo.Id] + } //千人千面处理 r := image.ThousandFaceImageFormatReq{ Size: int(req.Size), IsThousandFace: 0, Cover: *productInfo.Cover, CoverImg: *productInfo.CoverImg, - CoverDefault: *productInfo.CoverImg, ProductId: productInfo.Id, UserId: req.User.Id, } @@ -363,7 +384,6 @@ func (l *GetTagProductListLogic) getTagProducts(req getTagProductsReq) (productL } image.ThousandFaceImageFormat(&r) item.Cover = r.Cover - item.CoverDefault = nil //加入分类产品切片 productListRsp = append(productListRsp, item) } diff --git a/server/product/internal/logic/gettemplatebypidlogic.go b/server/product/internal/logic/gettemplatebypidlogic.go index 2841173f..18ccb887 100644 --- a/server/product/internal/logic/gettemplatebypidlogic.go +++ b/server/product/internal/logic/gettemplatebypidlogic.go @@ -42,6 +42,9 @@ func (l *GetTemplateByPidLogic) GetTemplateByPid(req *types.GetTemplateByPidReq, if req.Size > 0 { req.Size = image.GetCurrentSize(req.Size) } + if req.ProductTemplateTagId <= 0 { + return resp.SetStatusWithMessage(basic.CodeRequestParamsErr, "err param:product_template_tag_id") + } //获取产品信息(只是获取id) productInfo, err := l.svcCtx.AllModels.FsProduct.FindOneBySn(l.ctx, req.Pid, "id") if err != nil { @@ -51,7 +54,7 @@ func (l *GetTemplateByPidLogic) GetTemplateByPid(req *types.GetTemplateByPidReq, logx.Error(err) return resp.SetStatusWithMessage(basic.CodeDbSqlErr, "failed to get product info") } - //获取尺寸ids(只获取) + //获取尺寸ids(只获取id) sizeList, err := l.svcCtx.AllModels.FsProductSize.GetAllByProductIds(l.ctx, []int64{productInfo.Id}, "id") if err != nil { logx.Error(err) @@ -80,7 +83,7 @@ func (l *GetTemplateByPidLogic) GetTemplateByPid(req *types.GetTemplateByPidReq, mapModel[v.Id] = k } //获取模板数据 - productTemplateList, err := l.svcCtx.AllModels.FsProductTemplateV2.FindAllByModelIds(l.ctx, modelIds, "sort DESC") + productTemplateList, err := l.svcCtx.AllModels.FsProductTemplateV2.FindAllByModelIdsTemplateTag(l.ctx, modelIds, fmt.Sprintf("%d", req.ProductTemplateTagId), "sort DESC") if err != nil { logx.Error(err) return resp.SetStatusWithMessage(basic.CodeDbSqlErr, "failed to get product templates") diff --git a/server/product/internal/types/types.go b/server/product/internal/types/types.go index c1aaf641..cf94b40b 100644 --- a/server/product/internal/types/types.go +++ b/server/product/internal/types/types.go @@ -336,11 +336,13 @@ type GetSizeByPidRsp struct { PartsCanDeleted bool `json:"parts_can_deleted"` //用户可否删除配件 ModelId int64 `json:"model_id"` //产品主模型id IsPopular bool `json:"is_popular"` //是否受欢迎 + MinPrice float64 `json:"min_price"` //最小价格 } type GetTemplateByPidReq struct { - Pid string `form:"pid"` - Size uint32 `form:"size"` + Pid string `form:"pid"` + Size uint32 `form:"size"` + ProductTemplateTagId int64 `form:"product_template_tag_id"` } type GetFittingByPidReq struct { diff --git a/server/render/consumer/assemble_render_data.go b/server/render/consumer/assemble_render_data.go index 4a1c6f75..dd36cc7b 100644 --- a/server/render/consumer/assemble_render_data.go +++ b/server/render/consumer/assemble_render_data.go @@ -6,12 +6,15 @@ import ( "encoding/json" "errors" "fmt" + "fusenapi/constants" + "fusenapi/initalize" "fusenapi/model/gmodel" "fusenapi/utils/websocket_data" "github.com/zeromicro/go-zero/core/logx" "gorm.io/gorm" "io/ioutil" "net/http" + "strconv" "time" ) @@ -73,10 +76,11 @@ func (m *MqConsumerRenderAssemble) Run(ctx context.Context, data []byte) error { pyapiBeginTime := time.Now().UnixMilli() //这里curl post请求数据。获取处理好的贴图数据,用于贴model的贴图 pythonPostData := map[string]interface{}{ - "tids": templateInfo.Id, + "tids": []int64{templateInfo.Id}, "data": parseInfo.RenderData.Data, } pyPostBytes, _ := json.Marshal(pythonPostData) + //post 数据结构 `{"tids":[128,431],"data":[{"id":"9d35ac5a-81a0-3caf-3246-cdbea9f2ddfe","tag":"MainColor","title":"\u8d34\u56fe2","type":"color","text":"","fill":"#c028b9","fontSize":20,"fontFamily":"Aqum2SmallCaps3","ifBr":false,"ifShow":true,"ifGroup":false,"maxNum":50,"rotation":0,"align":"center","verticalAlign":"middle","material":"","width":1024,"height":1024,"x":0,"y":0,"opacity":1,"optionalColor":[{"color":"#000000","name":"Black","default":true}],"zIndex":2,"svgPath":"","follow":{"fill":"","ifShow":"","content":""},"group":[],"cameraStand":{"x":0,"y":0,"z":0},"proportion":60,"materialName":"","materialTime":""},{"id":"c9be653f-dfc1-5659-1eb8-7ab128abe3d5","tag":"Logo","title":"\u8d34\u56fe4","type":"image","text":"","fill":"#c028b9","fontSize":65,"fontFamily":"MontserratBold3","ifBr":true,"ifShow":true,"ifGroup":false,"maxNum":50,"rotation":0,"align":"center","verticalAlign":"middle","material":"","width":312,"height":144.8044172010362,"x":99,"y":406.49999999999875,"opacity":1,"optionalColor":[{"color":"#000000","name":"Black","default":false},{"color":"#FFFFFF","name":"White","default":false},{"name":"MainColor","color":"#c028b9","default":true}],"zIndex":3,"svgPath":"","follow":{"fill":"","ifShow":"","content":""},"group":[],"cameraStand":{"x":0,"y":0,"z":0},"proportion":60,"materialTime":"","materialName":""},{"id":"e3269e77-b8c2-baec-bb9b-8399915a711c","tag":"Slogan","title":"\u8d34\u56fe5","type":"text","text":"","fill":"","fontSize":16,"fontFamily":"MontserratBold3","ifBr":false,"ifShow":true,"ifGroup":false,"maxNum":50,"rotation":0,"align":"center","verticalAlign":"middle","material":"","width":312,"height":18.999939381668568,"x":99,"y":605.0000538829611,"opacity":1,"optionalColor":[{"color":"#000000","name":"Black","default":true}],"zIndex":4,"svgPath":"","follow":{"fill":"bfc2b5a3-10af-c95b-fbf1-3016540fffad","ifShow":"","content":""},"group":[],"cameraStand":{"x":0,"y":0,"z":36},"proportion":60,"materialName":"","materialTime":""},{"id":"bfc2b5a3-10af-c95b-fbf1-3016540fffad","tag":"SecondaryColor","title":"\u8d34\u56fe9","type":"color","text":"","fill":"#FFFFFF","fontSize":20,"fontFamily":"Aqum2SmallCaps3","ifBr":false,"ifShow":true,"ifGroup":false,"maxNum":50,"rotation":0,"align":"center","verticalAlign":"middle","material":"","width":1024,"height":1024,"x":0,"y":0,"opacity":1,"optionalColor":[{"color":"#000000","name":"Black","default":true}],"zIndex":1,"svgPath":"","follow":{"fill":"","ifShow":"","content":""},"group":[],"cameraStand":{"x":0,"y":0,"z":0},"proportion":60}]}` url := "http://110.41.19.98:8867/imgRender" pyRsp, err := http.Post(url, "application/json;charset=UTF-8", bytes.NewReader(pyPostBytes)) if err != nil { @@ -102,6 +106,10 @@ func (m *MqConsumerRenderAssemble) Run(ctx context.Context, data []byte) error { logx.Error("python api 接口没有数据:") return err } + mapImageData := make(map[int64]int) + for k, v := range rspInfo.Data { + mapImageData[v.Tid] = k + } //云渲染日志 title = "2-请求->接收python合成刀版图接口" now = time.Now().Unix() @@ -140,99 +148,107 @@ func (m *MqConsumerRenderAssemble) Run(ctx context.Context, data []byte) error { if err != nil { logx.Error(err) } + timePinjieBegin := time.Now().UnixMilli() //获取渲染设置信息 - //element, err := allmodels.FsProductTemplateElement - /* - - $element = ProductTemplateElement::find() - ->andFilterWhere(['in', 'product_template_id', $mids]) - ->asArray() - ->all(); - - $element = array_column($element, null, 'product_template_id'); - $elementTitles = array_column($element, 'title'); - - $result = []; - - $time_pinjie_begin = $render->getMillisecond(); - foreach ($templates as $key => $val) { - if(!isset($element[$val['model_id']]) || !isset($imageData[$val['id']])){ - continue; - } - //数据拼装 - $item = []; - - $item['light'] = $element[$val['model_id']]['light']; - $item['refletion'] = $element[$val['model_id']]['refletion'] == '' ? -1 : (int)$element[$val['model_id']]['refletion']; - $item['scale'] = $element[$val['model_id']]['scale']; - $item['sku_id'] = $val['product_id']; - $item['tid'] = $element[$val['model_id']]['title']; - $item['rotation'] = $element[$val['model_id']]['rotation']; - $item['filePath'] = '';//todo 文件路径,针对千人千面 - - //组装data数据 - $tempData = []; - //获取材质模式对应关系 - $mode = $element[$val['model_id']]['mode'] ? json_decode($element[$val['model_id']]['mode'], true) : []; - // $base_img = (new ImageService())->base64EncodeImageNoHeader(\Yii::$app->params['baseurl'].$imageData[$val['id']]['imgurl']); - $base_img = \Yii::$app->params['h5Url'].'/storage'.$imageData[$val['id']]['imgurl']; - //判断是否包含base数据 即对应建模那边的model - if($element[$val['model_id']]['base']){ - $tempData[] = [ - 'name' => 'model', - 'data' => '0,'.$base_img.','.$element[$val['model_id']]['base'], - 'type' => 'other', - 'layer' => '0', - 'is_update' => 1, - 'mode' => $mode['model'], - ]; - } - if($element[$val['model_id']]['shadow']){ - $tempData[] = [ - 'name' => 'shadow', - 'data' => $element[$val['model_id']]['shadow'], - 'type' => 'other', - 'layer' => '0', - 'is_update' => 0, - 'mode' => $mode['shadow'], - ]; - } - if($element[$val['model_id']]['model_p']){ - $tempData[] = [ - 'name' => 'model_P', - 'data' => '0,'.$element[$val['model_id']]['model_p'], - 'type' => 'other', - 'layer' => '0', - 'is_update' => 0, - 'mode' => $mode['model_P'], - ]; - } - $item['data'] = $tempData; - $result[] = $item; - - } - $log = new CloudRenderLog(); - $log->title = '接收到python刀版图 -> 3-组装MQ渲染任务队列'; - $log->time = $render->getMillisecond() - $time_pinjie_begin; - $log->user_id = $user_id; - $log->post_data = ''; - $log->post_url = ''; - $log->result = $res; - $log->tag = $inputData['id']; - $log->ctime = time(); - $log->save(false); - } - - $sendData = [ - 'id' => $inputData['id'], - 'order_id' => 0, - 'user_id' => \Yii::$app->user->id, - 'sku_ids' => $inputData['sku_ids'], - 'tids' => $elementTitles, - 'data' => $result, - 'is_thousand_face' => 0, - 'folder' => '',//todo 千人千面需要使用 - ]; - return $sendData;*/ + element, err := allmodels.FsProductTemplateElement.FindOneByModelId(ctx, *templateInfo.ModelId) + if err != nil { + if errors.Is(err, gorm.ErrRecordNotFound) { + logx.Error("element info is not found,model_id = ?", *templateInfo.ModelId) + return nil + } + 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 + } + } + baseImage := "" + if index, ok := mapImageData[templateInfo.Id]; ok { + baseImage = constants.H5_URL + "/storage" + rspInfo.Data[index].Imgurl + } + tempData := make([]map[string]interface{}, 0, 3) + if element.Base != nil && *element.Base != "" { + tempData = append(tempData, map[string]interface{}{ + "name": "model", + "data": "0," + baseImage + "," + *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": *templateInfo.ProductId, + "tid": *element.Title, + "rotation": *element.Rotation, + "filePath": "", //todo 文件路径,针对千人千面 + "data": tempData, + }, + } + timePinjie := time.Now().UnixMilli() - timePinjieBegin + //云渲染日志 + title = "接收到python刀版图 -> 3-组装MQ渲染任务队列" + now = time.Now().Unix() + err = allmodels.FsCloudRenderLog.Create(ctx, &gmodel.FsCloudRenderLog{ + UserId: &parseInfo.RenderData.UserId, + Title: &title, + Time: &timePinjie, + Tag: &parseInfo.RenderId, + Ctime: &now, + }) + if err != nil { + logx.Error(err) + } + sendData := map[string]interface{}{ + "id": parseInfo.RenderId, + "order_id": 0, + "user_id": parseInfo.RenderData.UserId, + "sku_ids": []int64{parseInfo.RenderData.ProductId}, + "tids": []string{*element.Title}, + "data": result, + "is_thousand_face": 0, + "folder": "", //todo 千人千面需要使用 + } + b, _ := json.Marshal(sendData) + rabbitmq := initalize.RabbitMqHandle{} + if err = rabbitmq.SendMsg(constants.RABBIT_MQ_TO_UNITY, b); err != nil { + logx.Error("发送渲染组装数据到rabbitmq失败:", err) + return err + } + logx.Info("发送渲染组装数据到rabbitmq 成功") return nil } diff --git a/server/websocket/internal/logic/datatransferlogic.go b/server/websocket/internal/logic/datatransferlogic.go index d2926142..79ba3855 100644 --- a/server/websocket/internal/logic/datatransferlogic.go +++ b/server/websocket/internal/logic/datatransferlogic.go @@ -86,7 +86,7 @@ func (l *DataTransferLogic) DataTransfer(svcCtx *svc.ServiceContext, w http.Resp } defer conn.Close() //鉴权不成功10秒后断开 - var ( + /*var ( userInfo *auth.UserInfo isAuth bool ) @@ -103,7 +103,10 @@ func (l *DataTransferLogic) DataTransfer(svcCtx *svc.ServiceContext, w http.Resp //发送关闭信息 _ = conn.WriteMessage(websocket.CloseMessage, nil) return - } + }*/ + //测试的目前写死 39 + var userInfo auth.UserInfo + userInfo.UserId = 39 //生成连接唯一标识 uniqueId := websocketIdGenerator.Get() ws := wsConnectItem{ diff --git a/server/websocket/internal/logic/ws_render_image_logic.go b/server/websocket/internal/logic/ws_render_image_logic.go index dbe14335..fc887a0e 100644 --- a/server/websocket/internal/logic/ws_render_image_logic.go +++ b/server/websocket/internal/logic/ws_render_image_logic.go @@ -24,7 +24,7 @@ type renderImageControlChanItem struct { // 渲染发送到组装数据组装数据 func (w *wsConnectItem) renderImage(data []byte) { - var renderImageData websocket_data.RenderImageReqMsg + var renderImageData websocket_data.AssembleRenderData if err := json.Unmarshal(data, &renderImageData); err != nil { w.outChan <- w.respondDataFormat(constants.WEBSOCKET_ERR_DATA_FORMAT, "invalid format of websocket render image message:"+string(data)) logx.Error("invalid format of websocket render image message", err) diff --git a/server_api/product.api b/server_api/product.api index 711ce0d4..b4aca200 100644 --- a/server_api/product.api +++ b/server_api/product.api @@ -381,11 +381,13 @@ type GetSizeByPidRsp { PartsCanDeleted bool `json:"parts_can_deleted"` //用户可否删除配件 ModelId int64 `json:"model_id"` //产品主模型id IsPopular bool `json:"is_popular"` //是否受欢迎 + MinPrice float64 `json:"min_price"` //最小价格 } //获取产品模板列表 type GetTemplateByPidReq { - Pid string `form:"pid"` - Size uint32 `form:"size"` + Pid string `form:"pid"` + Size uint32 `form:"size"` + ProductTemplateTagId int64 `form:"product_template_tag_id"` } //获取产品配件数据 type GetFittingByPidReq {