diff --git a/model/gmodel/fs_product_logic.go b/model/gmodel/fs_product_logic.go index 16081b58..009181db 100755 --- a/model/gmodel/fs_product_logic.go +++ b/model/gmodel/fs_product_logic.go @@ -73,7 +73,7 @@ func (p *FsProductModel) GetRandomProductList(ctx context.Context, limit int) (r return resp, err } -func (p *FsProductModel) FindAllOnlyByIds(ctx context.Context, ids []int64) (resp []*FsProduct, err error) { +func (p *FsProductModel) FindAllOnlyByIds(ctx context.Context, ids []int64) (resp []FsProduct, err error) { err = p.db.WithContext(ctx).Model(&FsProduct{}).Where("`id` IN (?)", ids).Find(&resp).Error return resp, err } diff --git a/server/product/internal/logic/gettagproductlistlogic.go b/server/product/internal/logic/gettagproductlistlogic.go index fd89b6eb..3cb7ba9f 100644 --- a/server/product/internal/logic/gettagproductlistlogic.go +++ b/server/product/internal/logic/gettagproductlistlogic.go @@ -2,6 +2,7 @@ package logic import ( "errors" + "fmt" "fusenapi/model/gmodel" "fusenapi/utils/auth" "fusenapi/utils/basic" @@ -74,67 +75,107 @@ func (l *GetTagProductListLogic) GetTagProductList(req *types.GetTagProductListR for _, v := range tagList { typeIds = append(typeIds, v.Id) } - //查询符合的产品列表 - pIsDel := int64(0) - pStatus := int64(1) - pIsShelf := int64(1) - pReq := gmodel.GetProductListByParamsReq{ - Type: typeIds, - IsDel: &pIsDel, - IsShelf: &pIsShelf, - Status: &pStatus, - OrderBy: "`sort` DESC", - } - //获取产品列表 - productList, err := l.svcCtx.AllModels.FsProduct.GetProductListByParams(l.ctx, pReq) - if err != nil { - logx.Error(err) - return resp.SetStatusWithMessage(basic.CodeServiceErr, "failed to get product list") - } - //提取产品ids - productIds := make([]int64, 0, len(productList)) - for _, v := range productList { - productIds = append(productIds, v.Id) - } - 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) + var ( + productList []gmodel.FsProduct //产品列表(select 字段需要看查询的地方) + recommendProductList []gmodel.FsProduct //tag推荐产品列表(select 字段需要看查询的地方) + mapProduct = make(map[int64]int) //产品map + productPriceList []gmodel.GetPriceListByProductIdsRsp //产品价格列表(select 字段需要看查询的地方) + mapProductMinPrice = make(map[int64]int64) //产品最小价格map + productTemplatesV2 []gmodel.FsProductTemplateV2 //产品模板列表(select 字段需要看查询的地方) + productSizeCountList []gmodel.CountProductSizeByStatusRsp //产品尺寸数量列表(select 字段需要看查询的地方) + mapProductSizeCount = make(map[int64]int64) //产品尺寸数量map + mapProductTemplate = make(map[int64]struct{}) //产品模板map + ) + //携带产品 + if req.WithProduct { + //查询符合的产品列表 + pIsDel := int64(0) + pStatus := int64(1) + pIsShelf := int64(1) + pReq := gmodel.GetProductListByParamsReq{ + Type: typeIds, + IsDel: &pIsDel, + IsShelf: &pIsShelf, + Status: &pStatus, + OrderBy: "`sort` DESC", + } + //获取产品列表 + productList, err = l.svcCtx.AllModels.FsProduct.GetProductListByParams(l.ctx, pReq) if err != nil { logx.Error(err) - return resp.SetStatusWithMessage(basic.CodeServiceErr, err.Error()) + return resp.SetStatusWithMessage(basic.CodeServiceErr, "failed to get product list") } - if len(priceSlice) == 0 { - continue + //提取tag推荐产品 + allTagRecommendProductIds := make([]int64, 0, len(tagList)*5) + for _, v := range tagList { + if v.RecommendProduct == nil || *v.RecommendProduct == "" { + continue + } + sl, err := format.StrSlicToInt64Slice(strings.Split(*v.RecommendProductSort, ",")) + if err != nil { + logx.Error(err) + return resp.SetStatusWithMessage(basic.CodeServiceErr, fmt.Sprintf("failed to parse recommend product ids,id=%d", v.Id)) + } + allTagRecommendProductIds = append(allTagRecommendProductIds, sl...) + } + //获取推荐的产品列表 + recommendProductList, err = l.svcCtx.AllModels.FsProduct.FindAllOnlyByIds(l.ctx, allTagRecommendProductIds) + if err != nil { + logx.Error(err) + return resp.SetStatusWithMessage(basic.CodeDbSqlErr, "failed to get tag recommend products") + } + //提取产品ids + productIds := make([]int64, 0, len(productList)) + for k, v := range productList { + productIds = append(productIds, v.Id) + mapProduct[v.Id] = k + } + //合并产品列表 + for _, v := range recommendProductList { + //存在则不并入 + if _, ok := mapProduct[v.Id]; ok { + continue + } + productList = append(productList, v) + mapProduct[v.Id] = len(productList) - 1 + } + 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") + } + //存储产品最小价格 + 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) + mapProductMinPrice[v.ProductId] = int64(priceSlice[0]) + } + //获取模板(只是获取产品product_id) + productTemplatesV2, err = l.svcCtx.AllModels.FsProductTemplateV2.FindAllByProductIds(l.ctx, productIds, "product_id") + if err != nil { + logx.Error(err) + return resp.SetStatusWithMessage(basic.CodeServiceErr, "get product template_v2 err") + } + for _, v := range productTemplatesV2 { + mapProductTemplate[*v.ProductId] = struct{}{} + } + //获取产品尺寸数量 + productSizeCountList, err = l.svcCtx.AllModels.FsProductSize.GetGroupProductSizeByStatus(l.ctx, productIds, 1) + if err != nil { + logx.Error(err) + return resp.SetStatusWithMessage(basic.CodeServiceErr, "get product size count err") + } + for _, v := range productSizeCountList { + mapProductSizeCount[v.ProductId] = v.Num } - sort.Ints(priceSlice) - mapProductMinPrice[v.ProductId] = int64(priceSlice[0]) - } - //获取模板(只是获取产品product_id) - productTemplatesV2, err := l.svcCtx.AllModels.FsProductTemplateV2.FindAllByProductIds(l.ctx, productIds, "product_id") - if err != nil { - logx.Error(err) - return resp.SetStatusWithMessage(basic.CodeServiceErr, "get product template_v2 err") - } - mapProductTemplate := make(map[int64]struct{}) - for _, v := range productTemplatesV2 { - mapProductTemplate[*v.ProductId] = struct{}{} - } - //获取产品尺寸数量 - productSizeCountList, err := l.svcCtx.AllModels.FsProductSize.GetGroupProductSizeByStatus(l.ctx, productIds, 1) - if err != nil { - logx.Error(err) - return resp.SetStatusWithMessage(basic.CodeServiceErr, "get product size count err") - } - mapProductSizeCount := make(map[int64]int64) - for _, v := range productSizeCountList { - mapProductSizeCount[v.ProductId] = v.Num } mapTagLevel := make(map[string]*types.TagItem) minLevel := int64(0) //记录最小等级数字 @@ -145,6 +186,24 @@ func (l *GetTagProductListLogic) GetTagProductList(req *types.GetTagProductListR if minLevel > *tagInfo.Level { minLevel = *tagInfo.Level } + tagTem := types.TagItem{ + TagProductList: nil, + TagRecommendProductList: nil, + TypeName: *tagInfo.Title, + TypeId: tagInfo.Id, + Level: *tagInfo.Level, + LevelPrefix: *tagInfo.LevelPrefix, + Icon: *tagInfo.Icon, + Sort: *tagInfo.Sort, + Description: *tagInfo.Description, + ChildTagList: make([]*types.TagItem, 0, 100), + } + //不携带产品 + if !req.WithProduct { + //加入分类 + mapTagLevel[*tagInfo.LevelPrefix] = &tagTem + continue + } //获取分类产品列表 productListRsp := l.getTagProducts(getTagProductsReq{ TagId: tagInfo.Id, @@ -155,19 +214,12 @@ func (l *GetTagProductListLogic) GetTagProductList(req *types.GetTagProductListR Size: req.Size, User: user, }) - //加入分类 - tagTem := types.TagItem{ - TagProductList: productListRsp, - TypeName: *tagInfo.Title, - TypeId: tagInfo.Id, - Level: *tagInfo.Level, - LevelPrefix: *tagInfo.LevelPrefix, - Icon: *tagInfo.Icon, - Sort: *tagInfo.Sort, - Description: *tagInfo.Description, - ChildTagList: make([]*types.TagItem, 0, 100), + tagTem.TagProductList = productListRsp + //获取推荐产品列表 + if tagInfo.RecommendProduct != nil && *tagInfo.RecommendProduct != "" { + } - //当前tag保存入map + //加入分类 mapTagLevel[*tagInfo.LevelPrefix] = &tagTem } //组装等级从属关系 diff --git a/server/product/internal/types/types.go b/server/product/internal/types/types.go index 926bc0e5..096a3626 100644 --- a/server/product/internal/types/types.go +++ b/server/product/internal/types/types.go @@ -245,8 +245,9 @@ type GetRecommandProductListRsp struct { } type GetTagProductListReq struct { - Cid int64 `form:"cid,optional"` //分类id - Size uint32 `form:"size,optional"` //尺寸 + Cid int64 `form:"cid,optional"` //分类id + Size uint32 `form:"size,optional"` //尺寸 + WithProduct bool `form:"with_product,optional"` //不携带产品只返回菜单 } type GetTagProductListRsp struct { @@ -255,15 +256,16 @@ type GetTagProductListRsp struct { } type TagItem struct { - TypeName string `json:"type_name"` - TypeId int64 `json:"type_id"` - Description string `json:"description"` - Level int64 `json:"level"` - LevelPrefix string `json:"level_prefix"` - Icon string `json:"icon"` - Sort int64 `json:"sort"` - TagProductList []TagProduct `json:"tag_product_list"` - ChildTagList []*TagItem `json:"child_tag_list"` + TypeName string `json:"type_name"` + TypeId int64 `json:"type_id"` + Description string `json:"description"` + Level int64 `json:"level"` + LevelPrefix string `json:"level_prefix"` + Icon string `json:"icon"` + Sort int64 `json:"sort"` + TagProductList []TagProduct `json:"tag_product_list"` //分类下的产品 + TagRecommendProductList [][]TagProduct `json:"tag_recommend_product_list"` //分类推荐产品 + ChildTagList []*TagItem `json:"child_tag_list"` } type TagProduct struct { diff --git a/server_api/product.api b/server_api/product.api index 96b2b5d7..12037107 100644 --- a/server_api/product.api +++ b/server_api/product.api @@ -291,23 +291,25 @@ type GetRecommandProductListRsp { } //获取分类产品列表 type GetTagProductListReq { - Cid int64 `form:"cid,optional"` //分类id - Size uint32 `form:"size,optional"` //尺寸 + Cid int64 `form:"cid,optional"` //分类id + Size uint32 `form:"size,optional"` //尺寸 + WithProduct bool `form:"with_product,optional"` //不携带产品只返回菜单 } type GetTagProductListRsp { TotalCategory int `json:"total_category"` TagList []TagItem `json:"tag_list"` } type TagItem { - TypeName string `json:"type_name"` - TypeId int64 `json:"type_id"` - Description string `json:"description"` - Level int64 `json:"level"` - LevelPrefix string `json:"level_prefix"` - Icon string `json:"icon"` - Sort int64 `json:"sort"` - TagProductList []TagProduct `json:"tag_product_list"` - ChildTagList []*TagItem `json:"child_tag_list"` + TypeName string `json:"type_name"` + TypeId int64 `json:"type_id"` + Description string `json:"description"` + Level int64 `json:"level"` + LevelPrefix string `json:"level_prefix"` + Icon string `json:"icon"` + Sort int64 `json:"sort"` + TagProductList []TagProduct `json:"tag_product_list"` //分类下的产品 + TagRecommendProductList [][]TagProduct `json:"tag_recommend_product_list"` //分类推荐产品 + ChildTagList []*TagItem `json:"child_tag_list"` } type TagProduct { ProductId int64 `json:"product_id"`