From ea1335607a9c3e85407acf5938c2d7817e7ed4bb Mon Sep 17 00:00:00 2001 From: laodaming <11058467+laudamine@user.noreply.gitee.com> Date: Tue, 17 Oct 2023 15:33:46 +0800 Subject: [PATCH] =?UTF-8?q?=E6=95=B4=E5=90=88=E7=9B=AE=E5=89=8D=E6=96=B0?= =?UTF-8?q?=E7=9A=84=E8=AF=A6=E6=83=85=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- model/gmodel/fs_product_model3d_logic.go | 17 +- model/gmodel/fs_product_template_v2_logic.go | 19 +- .../handler/getproductdetailhandler.go | 35 ++ server/product/internal/handler/routes.go | 5 + .../internal/logic/getproductdetaillogic.go | 365 ++++++++++++++++++ .../logic/getrecommandproductlistlogic.go | 8 +- .../internal/logic/getsizebypidlogic.go | 17 +- .../internal/logic/gettagproductlistlogic.go | 8 +- .../homepagerecommendproductlistlogic.go | 8 +- server/product/internal/types/types.go | 64 +++ server_api/product.api | 86 +++-- 11 files changed, 568 insertions(+), 64 deletions(-) create mode 100644 server/product/internal/handler/getproductdetailhandler.go create mode 100644 server/product/internal/logic/getproductdetaillogic.go diff --git a/model/gmodel/fs_product_model3d_logic.go b/model/gmodel/fs_product_model3d_logic.go index 92a54a39..ced105c5 100755 --- a/model/gmodel/fs_product_model3d_logic.go +++ b/model/gmodel/fs_product_model3d_logic.go @@ -173,12 +173,7 @@ func (d *FsProductModel3dModel) GetAllByProductIdsTags(ctx context.Context, prod } // 获取每个产品最低价格 -func (d *FsProductModel3dModel) GetProductMinPrice(ctx context.Context, productIds []int64, mapProductMinPrice map[int64]int64) error { - //获取产品模型价格列表 - modelList, err := d.GetAllByProductIdsTags(ctx, productIds, []int{constants.TAG_MODEL, constants.TAG_PARTS}, "id,product_id,price,tag,part_id,step_price") - if err != nil { - return errors.New("failed to get model list") - } +func (d *FsProductModel3dModel) GetProductMinPrice(modelList []FsProductModel3d, mapProductMinPrice map[int64]int64) error { mapModelMinPrice := make(map[int64]int64) //每个模型/配件存储最小价格 for _, modelInfo := range modelList { @@ -189,7 +184,7 @@ func (d *FsProductModel3dModel) GetProductMinPrice(ctx context.Context, productI continue } var stepPrice StepPriceJsonStruct - if err = json.Unmarshal(*modelInfo.StepPrice, &stepPrice); err != nil { + if err := json.Unmarshal(*modelInfo.StepPrice, &stepPrice); err != nil { return errors.New(fmt.Sprintf("failed to parse model step price:%d", modelInfo.Id)) } lenRange := len(stepPrice.PriceRange) @@ -226,3 +221,11 @@ func (d *FsProductModel3dModel) GetProductMinPrice(ctx context.Context, productI } return nil } +func (d *FsProductModel3dModel) GetAllByProductIdTags(ctx context.Context, productId int64, tags []int64, fields ...string) (resp []FsProductModel3d, err error) { + db := d.db.WithContext(ctx).Model(&FsProductModel3d{}).Where("`product_id`= ? and `tag` in(?) and `status` = ?", productId, tags, 1) + if len(fields) != 0 { + db = db.Select(fields[0]) + } + err = db.Find(&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 1462d7b9..3bacf94b 100755 --- a/model/gmodel/fs_product_template_v2_logic.go +++ b/model/gmodel/fs_product_template_v2_logic.go @@ -18,15 +18,16 @@ func (t *FsProductTemplateV2Model) FindAllByProductIds(ctx context.Context, prod err = db.Find(&resp).Error return resp, err } -func (t *FsProductTemplateV2Model) FindAllByIds(ctx context.Context, ids []int64) (resp []FsProductTemplateV2, err error) { +func (t *FsProductTemplateV2Model) FindAllByIds(ctx context.Context, ids []int64, fields ...string) (resp []FsProductTemplateV2, err error) { if len(ids) == 0 { return } - err = t.db.WithContext(ctx).Model(&FsProductTemplateV2{}).Where("`id` in (?) and `is_del` = ? and `status` = ?", ids, 0, 1).Find(&resp).Error - if err != nil { - return nil, err + db := t.db.WithContext(ctx).Model(&FsProductTemplateV2{}).Where("`id` in (?) and `is_del` = ? and `status` = ?", ids, 0, 1) + if len(fields) != 0 { + db = db.Select(fields[0]) } - return + err = db.Find(&resp).Error + return resp, err } func (t *FsProductTemplateV2Model) FindAllByIdsWithoutStatus(ctx context.Context, ids []int64, fields ...string) (resp []FsProductTemplateV2, err error) { if len(ids) == 0 { @@ -179,3 +180,11 @@ func (t *FsProductTemplateV2Model) FindAllByProductIdsTemplateTag(ctx context.Co err = db.Find(&resp).Error return resp, err } +func (t *FsProductTemplateV2Model) FindAllByFittingIds(ctx context.Context, fittingIds []int64, fields ...string) (resp []FsProductTemplateV2, err error) { + db := t.db.WithContext(ctx).Model(&FsProductTemplateV2{}).Where("`model_id` in(?) and `status` = ? and `is_del` = ? ", fittingIds, 1, 0) + if len(fields) != 0 { + db = db.Select(fields[0]) + } + err = db.Find(&resp).Error + return resp, err +} diff --git a/server/product/internal/handler/getproductdetailhandler.go b/server/product/internal/handler/getproductdetailhandler.go new file mode 100644 index 00000000..ef0a1725 --- /dev/null +++ b/server/product/internal/handler/getproductdetailhandler.go @@ -0,0 +1,35 @@ +package handler + +import ( + "net/http" + "reflect" + + "fusenapi/utils/basic" + + "fusenapi/server/product/internal/logic" + "fusenapi/server/product/internal/svc" + "fusenapi/server/product/internal/types" +) + +func GetProductDetailHandler(svcCtx *svc.ServiceContext) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + + var req types.GetProductDetailReq + userinfo, err := basic.RequestParse(w, r, svcCtx, &req) + if err != nil { + return + } + + // 创建一个业务逻辑层实例 + l := logic.NewGetProductDetailLogic(r.Context(), svcCtx) + + rl := reflect.ValueOf(l) + basic.BeforeLogic(w, r, rl) + + resp := l.GetProductDetail(&req, userinfo) + + if !basic.AfterLogic(w, r, rl, resp) { + basic.NormalAfterLogic(w, r, resp) + } + } +} diff --git a/server/product/internal/handler/routes.go b/server/product/internal/handler/routes.go index 2d0b468c..589462eb 100644 --- a/server/product/internal/handler/routes.go +++ b/server/product/internal/handler/routes.go @@ -72,6 +72,11 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) { Path: "/api/product/home_page_recommend", Handler: HomePageRecommendProductListHandler(serverCtx), }, + { + Method: http.MethodGet, + Path: "/api/product/get_product_detail", + Handler: GetProductDetailHandler(serverCtx), + }, }, ) } diff --git a/server/product/internal/logic/getproductdetaillogic.go b/server/product/internal/logic/getproductdetaillogic.go new file mode 100644 index 00000000..9fde3ed2 --- /dev/null +++ b/server/product/internal/logic/getproductdetaillogic.go @@ -0,0 +1,365 @@ +package logic + +import ( + "encoding/json" + "errors" + "fusenapi/constants" + "fusenapi/model/gmodel" + "fusenapi/utils/auth" + "fusenapi/utils/basic" + "fusenapi/utils/color_list" + "fusenapi/utils/format" + "fusenapi/utils/s3url_to_s3id" + "fusenapi/utils/template_switch_info" + "gorm.io/gorm" + "strings" + + "context" + + "fusenapi/server/product/internal/svc" + "fusenapi/server/product/internal/types" + + "github.com/zeromicro/go-zero/core/logx" +) + +type GetProductDetailLogic struct { + logx.Logger + ctx context.Context + svcCtx *svc.ServiceContext +} + +func NewGetProductDetailLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetProductDetailLogic { + return &GetProductDetailLogic{ + Logger: logx.WithContext(ctx), + ctx: ctx, + svcCtx: svcCtx, + } +} + +// 处理进入前逻辑w,r +// func (l *GetProductDetailLogic) BeforeLogic(w http.ResponseWriter, r *http.Request) { +// } + +func (l *GetProductDetailLogic) GetProductDetail(req *types.GetProductDetailReq, userinfo *auth.UserInfo) (resp *basic.Response) { + if req.ProductId <= 0 { + return resp.SetStatusWithMessage(basic.CodeRequestParamsErr, "err param:product id is invalid") + } + req.TemplateTag = strings.Trim(req.TemplateTag, " ") + if req.TemplateTag == "" { + return resp.SetStatusWithMessage(basic.CodeRequestParamsErr, "err param:template tag is invalid") + } + //获取产品信息 + productInfo, err := l.svcCtx.AllModels.FsProduct.FindOne(l.ctx, req.ProductId) + if err != nil { + if errors.Is(err, gorm.ErrRecordNotFound) { + return resp.SetStatusWithMessage(basic.CodeDbRecordNotFoundErr, "the product is not exists") + } + logx.Error(err) + return resp.SetStatusWithMessage(basic.CodeDbSqlErr, "failed to get product info") + } + if *productInfo.Status != 1 { + return resp.SetStatusWithMessage(basic.CodeDbSqlErr, "the product status is unNormal") + } + if *productInfo.IsShelf != 1 { + return resp.SetStatusWithMessage(basic.CodeDbSqlErr, "the product status is off shelf") + } + if *productInfo.IsDel == 1 { + return resp.SetStatusWithMessage(basic.CodeDbSqlErr, "the product status is deleted") + } + //获取产品类型 + productTag, err := l.svcCtx.AllModels.FsTags.FindOne(l.ctx, *productInfo.Type) + if err != nil { + if errors.Is(err, gorm.ErrRecordNotFound) { + return resp.SetStatusWithMessage(basic.CodeDbRecordNotFoundErr, "the product`s tag is not exists") + } + logx.Error(err) + return resp.SetStatusWithMessage(basic.CodeDbSqlErr, "failed to get product tag info") + } + //获取模板标签颜色选择信息 + templateTagColorInfo, err := l.GetTemplateTagColor(req, userinfo) + if err != nil { + return resp.SetStatusWithMessage(basic.CodeServiceErr, err.Error()) + } + //获取产品尺寸列表 + sizeList, err := l.svcCtx.AllModels.FsProductSize.GetAllByProductIds(l.ctx, []int64{req.ProductId}, "is_hot DESC,sort ASC") + if err != nil { + logx.Error(err) + return resp.SetStatusWithMessage(basic.CodeDbSqlErr, "failed to get size list") + } + //获取模型+配件信息 + modelList, err := l.svcCtx.AllModels.FsProductModel3d.GetAllByProductIdTags(l.ctx, req.ProductId, []int64{constants.TAG_MODEL, constants.TAG_PARTS}) + if err != nil { + logx.Error(err) + return resp.SetStatusWithMessage(basic.CodeDbSqlErr, "failed to get model list") + } + mapSizeKeyModel := make(map[int64]int) //模型(不包含配件)sizeId为key + mapFitting := make(map[int64]int) //配件 + publicFittingOptionTemplateIds := make([]int64, 0, len(modelList)) //配件配置了公共模板的模板id + notPublicFittingOptionTemplateFittingIds := make([]int64, 0, len(modelList)) //配件没有配置公共模板的配件id + lightIds := make([]int64, 0, len(modelList)) + for k, v := range modelList { + switch *v.Tag { + case constants.TAG_MODEL: //模型的 + mapSizeKeyModel[*v.SizeId] = k + if *v.Light > 0 { + lightIds = append(lightIds, *v.Light) + } + case constants.TAG_PARTS: //配件的 + mapFitting[v.Id] = k + if *v.OptionTemplate > 0 { + publicFittingOptionTemplateIds = append(publicFittingOptionTemplateIds, *v.OptionTemplate) + } else { + notPublicFittingOptionTemplateFittingIds = append(notPublicFittingOptionTemplateFittingIds, v.Id) + } + } + } + //获取没有绑定公共模板的配件贴图 + notPublicFittingOptionTemplateList, err := l.svcCtx.AllModels.FsProductTemplateV2.FindAllByFittingIds(l.ctx, notPublicFittingOptionTemplateFittingIds, "id,model_id,material_img") + if err != nil { + logx.Error(err) + return resp.SetStatusWithMessage(basic.CodeDbSqlErr, "failed to get fitting material image list") + } + mapNotPublicFittingOptionTemplateMaterialImage := make(map[int64]string) //model_id为key + for _, v := range notPublicFittingOptionTemplateList { + mapNotPublicFittingOptionTemplateMaterialImage[*v.ModelId] = *v.MaterialImg + } + //获取配件绑定的公共模板列表 + publicFittingOptionTemplateList, err := l.svcCtx.AllModels.FsProductTemplateV2.FindAllByIds(l.ctx, publicFittingOptionTemplateIds, "id,model_id,material_img") + if err != nil { + logx.Error(err) + return resp.SetStatusWithMessage(basic.CodeDbSqlErr, "failed to get fitting optional template list") + } + mapPublicFittingOptionTemplate := make(map[int64]string) //模板id为key + for _, v := range publicFittingOptionTemplateList { + mapPublicFittingOptionTemplate[v.Id] = *v.MaterialImg + } + //获取灯光列表 + lightList, err := l.svcCtx.AllModels.FsProductModel3dLight.GetAllByIds(l.ctx, lightIds) + if err != nil { + logx.Error(err) + return resp.SetStatusWithMessage(basic.CodeDbSqlErr, "failed to get light list") + } + mapLight := make(map[int64]int) + for k, v := range lightList { + mapLight[v.Id] = k + } + //获取产品模板列表 + templateList, err := l.svcCtx.AllModels.FsProductTemplateV2.FindAllByProductIdsTemplateTag(l.ctx, []int64{req.ProductId}, req.TemplateTag, "") + if err != nil { + logx.Error(err) + return resp.SetStatusWithMessage(basic.CodeDbSqlErr, "failed to get template list") + } + mapModelIdKeyTemplate := make(map[int64]int) + for k, v := range templateList { + mapModelIdKeyTemplate[*v.ModelId] = k + } + //记录产品最低价 + mapProductMinPrice := make(map[int64]int64) + if err = l.svcCtx.AllModels.FsProductModel3d.GetProductMinPrice(modelList, mapProductMinPrice); err != nil { + logx.Error(err) + return resp.SetStatusWithMessage(basic.CodeServiceErr, "failed to get product min price") + } + //整理返回 + rspSizeList := make([]types.SizeInfo, 0, len(sizeList)) + for _, sizeInfo := range sizeList { + var sizeTitle interface{} + if err = json.Unmarshal([]byte(*sizeInfo.Title), &sizeTitle); err != nil { + logx.Error(err) + return resp.SetStatusWithMessage(basic.CodeJsonErr, "failed to parse size title") + } + //尺寸下最低价 + minPrice := "" + if price, ok := mapProductMinPrice[*sizeInfo.ProductId]; ok { + minPrice = format.CentitoDollar(price, 3) + } + var modelInfoRsp types.ModelInfo + var TemplateInfoRsp interface{} + var FittingListRsp = make([]types.FittingInfo, 0, 10) + if modelIndex, ok := mapSizeKeyModel[sizeInfo.Id]; ok { + modelInfo := modelList[modelIndex] + //模板信息 + if templateIndex, ok := mapModelIdKeyTemplate[modelInfo.Id]; ok { + templateInfo := templateList[templateIndex] + //获取开关信息 + TemplateInfoRsp = template_switch_info.GetTemplateSwitchInfo(templateInfo.Id, templateInfo.TemplateInfo, *templateInfo.MaterialImg) + } + //赋值id + modelInfoRsp.Id = modelInfo.Id + //模型设计信息 + var modelDesignInfo interface{} + if modelInfo.ModelInfo != nil && *modelInfo.ModelInfo != "" { + if err = json.Unmarshal([]byte(*modelInfo.ModelInfo), &modelDesignInfo); err != nil { + logx.Error(err) + return resp.SetStatusWithMessage(basic.CodeJsonErr, "failed to parse model design info") + } + //赋值 + modelInfoRsp.ModelDesignInfo = modelDesignInfo + } + //灯光信息 + if lightIndex, ok := mapLight[*modelInfo.Light]; ok { + lightInfo := lightList[lightIndex] + var lightDesignInfo interface{} + if lightInfo.Info != nil && *lightInfo.Info != "" { + if err = json.Unmarshal([]byte(*lightInfo.Info), &lightDesignInfo); err != nil { + logx.Error(err) + return resp.SetStatusWithMessage(basic.CodeJsonErr, "failed to parse light design info") + } + //赋值 + modelInfoRsp.LightInfo = types.LightInfo{ + Id: lightInfo.Id, + LightName: *lightInfo.Name, + LightDesignInfo: lightDesignInfo, + } + } + } + optionalFittingIdsStr := strings.Trim(*modelInfo.PartList, " ") + optionalFittingIdsStr = strings.Trim(optionalFittingIdsStr, ",") + //配件信息 + if optionalFittingIdsStr != "" { + optionalFittingIds, err := format.StrSlicToInt64Slice(strings.Split(optionalFittingIdsStr, ",")) + if err != nil { + logx.Error(err) + return resp.SetStatusWithMessage(basic.CodeServiceErr, "failed to split optional fitting list") + } + //可选配件 + for _, optionFittingId := range optionalFittingIds { + fittingIndex, ok := mapFitting[optionFittingId] + if !ok { + continue + } + fittingInfo := modelList[fittingIndex] + var fittingDesignInfo interface{} + if fittingInfo.ModelInfo == nil || *fittingInfo.ModelInfo == "" { + continue + } + if err = json.Unmarshal([]byte(*fittingInfo.ModelInfo), &fittingDesignInfo); err != nil { + logx.Error(err) + return resp.SetStatusWithMessage(basic.CodeJsonErr, "failed to parse fitting design info") + } + //是否默认显示配件 + isDefault := int64(0) + if optionFittingId == *modelInfo.PartId { + isDefault = 1 + } + //配件贴图 + FittingMaterialImg := "" + //贴图,如果绑定了公共模板,则获取公共模板的贴图数据(待优化) + if *fittingInfo.OptionTemplate > 0 { + if image, ok := mapPublicFittingOptionTemplate[*fittingInfo.OptionTemplate]; ok { + FittingMaterialImg = image + } + } else { //否则取该配件下的模板贴图 + if image, ok := mapNotPublicFittingOptionTemplateMaterialImage[fittingInfo.Id]; ok { + FittingMaterialImg = image + } + } + FittingListRsp = append(FittingListRsp, types.FittingInfo{ + Id: fittingInfo.Id, + IsHot: *fittingInfo.IsHot, + MaterialImage: FittingMaterialImg, + DesignInfo: fittingDesignInfo, + Price: format.CentitoDollar(*fittingInfo.Price, 3), + Name: *fittingInfo.Name, + IsDefault: isDefault, + }) + } + + } + } + rspSizeList = append(rspSizeList, types.SizeInfo{ + Id: sizeInfo.Id, + Title: sizeTitle, + Capacity: *sizeInfo.Capacity, + PartsCanDeleted: *sizeInfo.PartsCanDeleted, + IsHot: *sizeInfo.IsHot, + MinPrice: minPrice, + TemplateInfo: TemplateInfoRsp, + ModelInfo: modelInfoRsp, + FittingList: FittingListRsp, + }) + } + return resp.SetStatusWithMessage(basic.CodeOK, "success", types.GetProductDetailRsp{ + TemplateTagColorInfo: templateTagColorInfo, + ProductInfo: types.ProductInfo{ + Id: productInfo.Id, + ProductType: *productInfo.Type, + ProductTypeName: *productTag.Title, + Title: *productInfo.Title, + IsEnv: *productInfo.IsProtection, + IsMicro: *productInfo.IsMicrowave, + IsCustomization: *productInfo.IsCustomization, + }, + BaseColors: color_list.GetColor(), + SizeList: rspSizeList, + }) +} + +// 处理逻辑后 w,r 如:重定向, resp 必须重新处理 +// func (l *GetProductDetailLogic) AfterLogic(w http.ResponseWriter, r *http.Request, resp *basic.Response) { +// // httpx.OkJsonCtx(r.Context(), w, resp) +// } +func (l *GetProductDetailLogic) GetTemplateTagColor(req *types.GetProductDetailReq, userinfo *auth.UserInfo) (resp types.TemplateTagColorInfo, err error) { + if req.SelectColorIndex < 0 { + return types.TemplateTagColorInfo{}, errors.New("param selected_color_index is invalid") + } + //根据logo查询素材资源 + resourceId := s3url_to_s3id.GetS3ResourceIdFormUrl(req.Logo) + if resourceId == "" { + return types.TemplateTagColorInfo{}, errors.New("param logo is invalid") + } + var ( + userMaterial *gmodel.FsUserMaterial + templateTagInfo *gmodel.FsProductTemplateTags + ) + //获取模板标签信息 + templateTagInfo, err = l.svcCtx.AllModels.FsProductTemplateTags.FindOneByTagName(l.ctx, req.TemplateTag) + if err != nil { + if errors.Is(err, gorm.ErrRecordNotFound) { + return types.TemplateTagColorInfo{}, errors.New("the template tag is not exists") + } + logx.Error(err) + return types.TemplateTagColorInfo{}, errors.New("failed to get template tag info") + } + userMaterial, err = l.svcCtx.AllModels.FsUserMaterial.FindOneByLogoResourceId(l.ctx, resourceId) + if err != nil { + if errors.Is(err, gorm.ErrRecordNotFound) { + return types.TemplateTagColorInfo{}, errors.New("the logo is not found") + } + logx.Error(err) + return types.TemplateTagColorInfo{}, errors.New("failed to get user material") + } + if userMaterial.Metadata == nil || len(*userMaterial.Metadata) == 0 { + return types.TemplateTagColorInfo{}, errors.New("the user material is empty") + } + //解析用户素材元数据 + var metaData map[string]interface{} + if err = json.Unmarshal(*userMaterial.Metadata, &metaData); err != nil { + logx.Error(err) + return types.TemplateTagColorInfo{}, errors.New("failed to parse user metadata") + } + var mapMaterialTemplateTag map[string][][]string + b, _ := json.Marshal(metaData["template_tag"]) + if err = json.Unmarshal(b, &mapMaterialTemplateTag); err != nil { + logx.Error(err) + return types.TemplateTagColorInfo{}, errors.New("invalid format of metadata`s template_tag") + } + colors, ok := mapMaterialTemplateTag[req.TemplateTag] + if !ok { + return types.TemplateTagColorInfo{}, errors.New("the template tag is not found from this logo material`s metadata") + } + if req.SelectColorIndex >= len(colors) { + return types.TemplateTagColorInfo{}, errors.New("select color index is out of range !!") + } + var templateTagGroups interface{} + if templateTagInfo.Groups != nil && *templateTagInfo.Groups != "" { + if err = json.Unmarshal([]byte(*templateTagInfo.Groups), &templateTagGroups); err != nil { + logx.Error(err) + return types.TemplateTagColorInfo{}, errors.New("failed to parse template tag`s groups info") + } + } + return types.TemplateTagColorInfo{ + Colors: colors, + SelectedColorIndex: req.SelectColorIndex, + TemplateTagGroups: templateTagGroups, + }, nil +} diff --git a/server/product/internal/logic/getrecommandproductlistlogic.go b/server/product/internal/logic/getrecommandproductlistlogic.go index 2877ef95..0debe6e8 100644 --- a/server/product/internal/logic/getrecommandproductlistlogic.go +++ b/server/product/internal/logic/getrecommandproductlistlogic.go @@ -3,6 +3,7 @@ package logic import ( "encoding/json" "errors" + "fusenapi/constants" "fusenapi/model/gmodel" "fusenapi/utils/auth" "fusenapi/utils/basic" @@ -93,7 +94,12 @@ func (l *GetRecommandProductListLogic) GetRecommandProductList(req *types.GetRec } //获取产品最低价 mapProductMinPrice := make(map[int64]int64) - if err = l.svcCtx.AllModels.FsProductModel3d.GetProductMinPrice(l.ctx, productIds, mapProductMinPrice); err != nil { + modelList, err := l.svcCtx.AllModels.FsProductModel3d.GetAllByProductIdsTags(l.ctx, []int64{productInfo.Id}, []int{constants.TAG_MODEL, constants.TAG_PARTS}, "id,size_id,product_id,price,tag,part_id,step_price") + if err != nil { + logx.Error(err) + return resp.SetStatusWithMessage(basic.CodeDbSqlErr, "failed to get model list") + } + if err = l.svcCtx.AllModels.FsProductModel3d.GetProductMinPrice(modelList, mapProductMinPrice); err != nil { logx.Error(err) return resp.SetStatusWithMessage(basic.CodeDbSqlErr, "failed to get product min price") } diff --git a/server/product/internal/logic/getsizebypidlogic.go b/server/product/internal/logic/getsizebypidlogic.go index 46d81e4f..d83e4dd7 100644 --- a/server/product/internal/logic/getsizebypidlogic.go +++ b/server/product/internal/logic/getsizebypidlogic.go @@ -74,25 +74,26 @@ 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) } //获取产品价格列表 mapProductMinPrice := make(map[int64]int64) - if err = l.svcCtx.AllModels.FsProductModel3d.GetProductMinPrice(l.ctx, productIds, mapProductMinPrice); err != nil { - logx.Error(err) - return resp.SetStatusWithMessage(basic.CodeDbSqlErr, "failed to get product min price") - } - //获取对应模型数据 - modelList, err := l.svcCtx.AllModels.FsProductModel3d.GetAllBySizeIdsTag(l.ctx, sizeIds, constants.TAG_MODEL, "id,size_id") + //获取产品模型 + modelList, err := l.svcCtx.AllModels.FsProductModel3d.GetAllByProductIdsTags(l.ctx, []int64{productInfo.Id}, []int{constants.TAG_MODEL, constants.TAG_PARTS}, "id,size_id,product_id,price,tag,part_id,step_price") if err != nil { logx.Error(err) return resp.SetStatusWithMessage(basic.CodeDbSqlErr, "failed to get model list") } + if err = l.svcCtx.AllModels.FsProductModel3d.GetProductMinPrice(modelList, mapProductMinPrice); err != nil { + logx.Error(err) + return resp.SetStatusWithMessage(basic.CodeDbSqlErr, "failed to get product min price") + } mapSizeModel := make(map[int64]int) //size id为key for k, v := range modelList { + if *v.Tag != constants.TAG_MODEL { + continue + } mapSizeModel[*v.SizeId] = k } //处理 diff --git a/server/product/internal/logic/gettagproductlistlogic.go b/server/product/internal/logic/gettagproductlistlogic.go index eae2abfb..4ffae478 100644 --- a/server/product/internal/logic/gettagproductlistlogic.go +++ b/server/product/internal/logic/gettagproductlistlogic.go @@ -3,6 +3,7 @@ package logic import ( "encoding/json" "errors" + "fusenapi/constants" "fusenapi/model/gmodel" "fusenapi/utils/auth" "fusenapi/utils/basic" @@ -228,8 +229,13 @@ func (l *GetTagProductListLogic) getProductRelationInfo(req getProductRelationIn CoverMetadata: req.MapResourceMetadata[*v.Cover], }) } + modelList, err := l.svcCtx.AllModels.FsProductModel3d.GetAllByProductIdsTags(l.ctx, productIds, []int{constants.TAG_MODEL, constants.TAG_PARTS}, "id,size_id,product_id,price,tag,part_id,step_price") + if err != nil { + logx.Error(err) + return nil, errors.New("failed to get model list") + } //获取产品最低价格 - if err = l.svcCtx.AllModels.FsProductModel3d.GetProductMinPrice(l.ctx, productIds, req.MapProductMinPrice); err != nil { + if err = l.svcCtx.AllModels.FsProductModel3d.GetProductMinPrice(modelList, req.MapProductMinPrice); err != nil { logx.Error(err) return nil, errors.New("failed to get product min price") } diff --git a/server/product/internal/logic/homepagerecommendproductlistlogic.go b/server/product/internal/logic/homepagerecommendproductlistlogic.go index a4447811..f0bf6206 100644 --- a/server/product/internal/logic/homepagerecommendproductlistlogic.go +++ b/server/product/internal/logic/homepagerecommendproductlistlogic.go @@ -3,6 +3,7 @@ package logic import ( "encoding/json" "errors" + "fusenapi/constants" "fusenapi/model/gmodel" "fusenapi/utils/auth" "fusenapi/utils/basic" @@ -113,7 +114,12 @@ func (l *HomePageRecommendProductListLogic) HomePageRecommendProductList(req *ty } //获取产品最低价格 mapProductMinPrice := make(map[int64]int64) - if err = l.svcCtx.AllModels.FsProductModel3d.GetProductMinPrice(l.ctx, productIds, mapProductMinPrice); err != nil { + modelList, err := l.svcCtx.AllModels.FsProductModel3d.GetAllByProductIdsTags(l.ctx, productIds, []int{constants.TAG_MODEL, constants.TAG_PARTS}, "id,size_id,product_id,price,tag,part_id,step_price") + if err != nil { + logx.Error(err) + return resp.SetStatusWithMessage(basic.CodeServiceErr, "get product model list err") + } + if err = l.svcCtx.AllModels.FsProductModel3d.GetProductMinPrice(modelList, mapProductMinPrice); err != nil { logx.Error(err) return resp.SetStatusWithMessage(basic.CodeServiceErr, "failed to get product min price") } diff --git a/server/product/internal/types/types.go b/server/product/internal/types/types.go index 05455455..cfee8e8c 100644 --- a/server/product/internal/types/types.go +++ b/server/product/internal/types/types.go @@ -191,6 +191,70 @@ type HomePageRecommendProductListRsp struct { IsCustomization int64 `json:"is_customization"` } +type GetProductDetailReq struct { + ProductId int64 `form:"product_id"` //产品id + TemplateTag string `form:"template_tag"` //模板标签 + SelectColorIndex int `form:"select_color_index"` //模板标签颜色索引 + Logo string `form:"logo"` //logo地址 +} + +type GetProductDetailRsp struct { + TemplateTagColorInfo TemplateTagColorInfo `json:"template_tag_color_info"` //标签颜色信息 + ProductInfo ProductInfo `json:"product_info"` //产品基本信息 + BaseColors interface{} `json:"base_colors"` //一些返回写死的颜色 + SizeList []SizeInfo `json:"size_list"` //尺寸相关信息 +} + +type SizeInfo struct { + Id int64 `json:"id"` //尺寸id + Title interface{} `json:"title"` //尺寸标题信息 + Capacity string `json:"capacity"` //尺寸名称 + PartsCanDeleted int64 `json:"parts_can_deleted"` //配件是否可删除 + IsHot int64 `json:"is_hot"` //是否热门 + MinPrice string `json:"min_price"` //最低价 + TemplateInfo interface{} `json:"template_info"` //模板相关信息 + ModelInfo ModelInfo `json:"model_info"` //模型相关信息 + FittingList []FittingInfo `json:"fitting_List"` //配件相关信息 +} + +type FittingInfo struct { + Id int64 `json:"id"` //配件id + IsHot int64 `json:"is_hot"` //是否热门 + MaterialImage string `json:"material_image"` //配件材质图 + DesignInfo interface{} `json:"design_info"` //配件设计信息 + Price string `json:"price"` //配件价格 + Name string `json:"name"` //配件名 + IsDefault int64 `json:"is_default"` //是否默认的配件 +} + +type ModelInfo struct { + Id int64 `json:"id"` //模型id + ModelDesignInfo interface{} `json:"design_info"` //模型设计信息 + LightInfo LightInfo `json:"light_info"` //灯光信息 +} + +type LightInfo struct { + Id int64 `json:"id"` //灯光id + LightName string `json:"light_name"` //灯光组名称 + LightDesignInfo interface{} `json:"light_design_info"` //灯光设计信息 +} + +type ProductInfo struct { + Id int64 `json:"id"` //产品id + ProductType int64 `json:"product_type"` //产品类型id + ProductTypeName string `json:"product_type_name"` //产品类型名称 + Title string `json:"title"` //产品标题 + IsEnv int64 `json:"is_env"` //是否环保 + IsMicro int64 `json:"is_micro"` //是否可微波炉 + IsCustomization int64 `json:"is_customization"` //是否可定制产品 +} + +type TemplateTagColorInfo struct { + Colors [][]string `json:"colors"` //传入logo对应的算法颜色组 + SelectedColorIndex int `json:"selected_color_index"` //选择的模板标签的颜色索引值 + TemplateTagGroups interface{} `json:"template_tag_groups"` //模板标签分组信息 +} + type Request struct { } diff --git a/server_api/product.api b/server_api/product.api index 5f586731..b1bfb0b6 100644 --- a/server_api/product.api +++ b/server_api/product.api @@ -227,55 +227,59 @@ type HomePageRecommendProductListRsp { } //获取产品详情(重构版) -type GetProductDetailReq{ - ProductId int64 `form:"product_id"`//产品id - TemplateTag string `form:"template_tag"` //模板标签 - SelectColorIndex int `form:"select_color_index"` //模板标签颜色索引 +type GetProductDetailReq { + ProductId int64 `form:"product_id"` //产品id + TemplateTag string `form:"template_tag"` //模板标签 + SelectColorIndex int `form:"select_color_index"` //模板标签颜色索引 + Logo string `form:"logo"` //logo地址 } -type GetProductDetailRsp{ +type GetProductDetailRsp { TemplateTagColorInfo TemplateTagColorInfo `json:"template_tag_color_info"` //标签颜色信息 - ProductInfo ProductInfo `json:"product_info"` //产品基本信息 - BaseColors interface{} `json:"base_colors"` //一些返回写死的颜色 - SizeInfo SizeInfo `json:"size_info"` //尺寸相关信息 + ProductInfo ProductInfo `json:"product_info"` //产品基本信息 + BaseColors interface{} `json:"base_colors"` //一些返回写死的颜色 + SizeList []SizeInfo `json:"size_list"` //尺寸相关信息 } -type SizeInfo{ - SizeId int64 `json:"size_id"` - Title interface{} `json:"title"` - Capacity string `json:"capacity"` - PartsCanDeleted bool `json:"parts_can_deleted"` - ModelId int64 `json:"model_id"` - IsHot int64 `json:"is_hot"` - MinPrice string `json:"min_price"` - IsDefault bool `json:"is_default"` - TemplateInfo TemplateInfo `json:"template_info"` - ModelInfo ModelInfo `json:"model_info"` +type SizeInfo { + Id int64 `json:"id"` //尺寸id + Title interface{} `json:"title"` //尺寸标题信息 + Capacity string `json:"capacity"` //尺寸名称 + PartsCanDeleted int64 `json:"parts_can_deleted"` //配件是否可删除 + IsHot int64 `json:"is_hot"` //是否热门 + MinPrice string `json:"min_price"` //最低价 + TemplateInfo interface{} `json:"template_info"` //模板相关信息 + ModelInfo ModelInfo `json:"model_info"` //模型相关信息 + FittingList []FittingInfo `json:"fitting_List"` //配件相关信息 } -type ModelInfo{ - ModelId int64 `json:"model_id"` //模型id +type FittingInfo { + Id int64 `json:"id"` //配件id + IsHot int64 `json:"is_hot"` //是否热门 + MaterialImage string `json:"material_image"` //配件材质图 + DesignInfo interface{} `json:"design_info"` //配件设计信息 + Price string `json:"price"` //配件价格 + Name string `json:"name"` //配件名 + IsDefault int64 `json:"is_default"` //是否默认的配件 +} +type ModelInfo { + Id int64 `json:"id"` //模型id ModelDesignInfo interface{} `json:"design_info"` //模型设计信息 - LightInfo LightInfo `json:"light_info"` //灯光信息 + LightInfo LightInfo `json:"light_info"` //灯光信息 } -type LightInfo{ - LightId int64 `json:"light_id"` //灯光id - LightName string `json:"light_name"` //灯光组名称 +type LightInfo { + Id int64 `json:"id"` //灯光id + LightName string `json:"light_name"` //灯光组名称 LightDesignInfo interface{} `json:"light_design_info"` //灯光设计信息 } -type TemplateInfo { - TemplateSwitchInfo interface{} `json:"template_switch_info"` //对应模板标签下模板的开关信息,同列表页 - CombineIsVisible bool `json:"combine_is_visible"` //合图开关是否开启 - Material string `json:"material"` //默认素材 -} -type ProductInfo{ - ProductId int64 `json:"product_id"` //产品id - ProductType int64 `json:"product_type"` //产品类型id +type ProductInfo { + Id int64 `json:"id"` //产品id + ProductType int64 `json:"product_type"` //产品类型id ProductTypeName string `json:"product_type_name"` //产品类型名称 - Title string `json:"title"` //产品标题 - IsEnv int64 `json:"is_env"` //是否环保 - IsMicro int64 `json:"is_micro"` //是否可微波炉 - IsCustomization int64 `json:"is_customization"` //是否可定制产品 + Title string `json:"title"` //产品标题 + IsEnv int64 `json:"is_env"` //是否环保 + IsMicro int64 `json:"is_micro"` //是否可微波炉 + IsCustomization int64 `json:"is_customization"` //是否可定制产品 } -type TemplateTagColorInfo{ - Colors []string `json:"colors"` - SelectedColorIndex int `json:"selected_color_index"` - TemplateTagGroups interface{} `json:"template_tag_groups"` +type TemplateTagColorInfo { + Colors [][]string `json:"colors"` //传入logo对应的算法颜色组 + SelectedColorIndex int `json:"selected_color_index"` //选择的模板标签的颜色索引值 + TemplateTagGroups interface{} `json:"template_tag_groups"` //模板标签分组信息 } \ No newline at end of file