@@ -2,7 +2,6 @@ package logic
import (
"errors"
"fmt"
"fusenapi/model/gmodel"
"fusenapi/utils/auth"
"fusenapi/utils/basic"
@@ -60,6 +59,8 @@ func (l *GetTagProductListLogic) GetTagProductList(req *types.GetTagProductListR
if errors . Is ( err , gorm . ErrRecordNotFound ) {
return resp . SetStatusWithMessage ( basic . CodeDbRecordNotFoundErr , "param cid is invalid:record not found" )
}
logx . Error ( err )
return resp . SetStatusWithMessage ( basic . CodeDbSqlErr , "failed to get tag info" )
}
tReq . LevelPrefixLeftLike = * tagData . LevelPrefix
}
@@ -77,8 +78,6 @@ func (l *GetTagProductListLogic) GetTagProductList(req *types.GetTagProductListR
}
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 字段需要看查询的地方)
@@ -86,64 +85,28 @@ func (l *GetTagProductListLogic) GetTagProductList(req *types.GetTagProductListR
mapProductSizeCount = make ( map [ int64 ] int64 ) //产品尺寸数量map
mapProductTemplate = make ( map [ int64 ] struct { } ) //产品模板map
)
//携带推荐产品
if req . WithRecommendProduct {
//提取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" )
}
}
//携带产品
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 )
productList , err = l . svcCtx . AllModels . FsProduct . GetProductListByParams ( l . ctx ,
gmodel . GetProductListByParamsReq {
Type : typeIds ,
IsDel : & pIsDel ,
IsShelf : & pIsShelf ,
Status : & pStatus ,
OrderBy : "`sort` DESC" ,
} )
if err != nil {
logx . Error ( err )
return resp . SetStatusWithMessage ( basic . CodeServiceErr , "failed to get product list" )
}
}
//任意一个不为空
if len ( productList ) ! = 0 || l en( recommendProductList ) != 0 {
//提取产品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
productIds := make ( [ ] int64 , 0 , len ( productList ) )
for _ , product := range productList {
productIds = app end ( productIds , product . Id )
}
//获取产品价格列表
productPriceList , err = l . svcCtx . AllModels . FsProductPrice . GetSimplePriceListByProductIds ( l . ctx , productIds )
@@ -186,10 +149,50 @@ func (l *GetTagProductListLogic) GetTagProductList(req *types.GetTagProductListR
}
//map tag菜单
mapTagLevel := make ( map [ string ] * types . TagItem )
for _ , tagInfo := range tagList {
//处理tags数据
if err = l . dealWithTagMenuData ( dealWithTagMenuDataReq {
TagList : tagList ,
WithProduct : req . WithProduct ,
ProductList : productList ,
MapProductMinPrice : mapProductMinPrice ,
MapProductTemplate : mapProductTemplate ,
MapProductSizeCount : mapProductSizeCount ,
MapTagLevel : mapTagLevel ,
Size : req . Size ,
user : user ,
} ) ; err != nil {
logx . Error ( err )
return resp . SetStatusAddMessage ( basic . CodeServiceErr , "failed to deal with tag data" )
}
return resp . SetStatusWithMessage ( basic . CodeOK , "success" , types . GetTagProductListRsp {
TotalCategoryProduct : len ( productList ) ,
TagList : l . organizationLevelRelation ( mapTagLevel ) , //组装等级从属关系
} )
}
// 排序推荐产品结构体
type sortRecommendProduct struct {
ProductId int64
Sort int64
}
// 处理tag菜单数据
type dealWithTagMenuDataReq struct {
TagList [ ] gmodel . FsTags
WithProduct bool
ProductList [ ] gmodel . FsProduct
MapProductMinPrice map [ int64 ] int64
MapProductTemplate map [ int64 ] struct { }
MapProductSizeCount map [ int64 ] int64
MapTagLevel map [ string ] * types . TagItem
Size uint32
user gmodel . FsUser
}
func ( l * GetTagProductListLogic ) dealWithTagMenuData ( req dealWithTagMenuDataReq ) error {
for _ , tagInfo := range req . TagList {
tagTem := types . TagItem {
TagProductList : nil ,
TagRecommendProductList : nil ,
TypeName : * tagInfo . Title ,
TypeId : tagInfo . Id ,
Level : * tagInfo . Level ,
@@ -197,66 +200,31 @@ func (l *GetTagProductListLogic) GetTagProductList(req *types.GetTagProductListR
Icon : * tagInfo . Icon ,
Sort : * tagInfo . Sort ,
Description : * tagInfo . Description ,
ChildTagList : make ( [ ] * types . TagItem , 0 , 10 0) ,
ChildTagList : make ( [ ] * types . TagItem , 0 , 5 0) ,
}
//携带产品
if req . WithProduct {
if req . WithProduct {
//获取分类产品列表
productListRsp := l . getTagProducts ( getTagProductsReq {
TagId : tagInfo . Id ,
ProductList : p roductList,
MapProductMinPrice : m apProductMinPrice,
MapProductTemplate : m apProductTemplate,
MapProductSizeCount : m apProductSizeCount,
ProductList : req . P roductList,
MapProductMinPrice : req . M apProductMinPrice,
MapProductTemplate : req . M apProductTemplate,
MapProductSizeCount : req . M apProductSizeCount,
Size : req . Size ,
User : user ,
User : req . user,
} )
//赋值
tagTem . TagProductList = productListRsp
}
//获取推荐产品列表
if req . WithRecommendProduct && tagInfo . RecommendProduct != nil && * tagInfo . RecommendProduct != "" {
//上面解析过,这里就无需判断错误
recommendProductIds , _ := format . StrSlicToInt64Slice ( strings . Split ( * tagInfo . RecommendProduct , "," ) )
//推荐产品的排序
recommendProductIdsSort , err := format . StrSlicToInt64Slice ( strings . Split ( * tagInfo . RecommendProductSort , "," ) )
if err != nil {
logx . Error ( err )
return nil
}
if len ( recommendProductIds ) != len ( recommendProductIdsSort ) {
return resp . SetStatusWithMessage ( basic . CodeServiceErr , fmt . Sprintf ( "length of recommend product id is neq length of recommend sort,id= %d" , tagInfo . Id ) )
}
recommendProductListRsp := l . getTagRecommendProducts ( getTagRecommendProductsReq {
TagInfo : tagInfo ,
ProductList : productList ,
MapProduct : mapProduct ,
MapProductMinPrice : mapProductMinPrice ,
MapProductTemplate : mapProductTemplate ,
MapProductSizeCount : mapProductSizeCount ,
RecommendProductIds : recommendProductIds ,
RecommendProductIdsSort : recommendProductIdsSort ,
Size : req . Size ,
User : user ,
} )
//赋值
tagTem . TagRecommendProductList = recommendProductListRsp
}
//加入分类
m apTagLevel[ * tagInfo . LevelPrefix ] = & tagTem
req . M apTagLevel[ * tagInfo . LevelPrefix ] = & tagTem
}
return resp . SetStatusWithMessage ( basic . CodeOK , "success" , types . GetTagProductListRsp {
TotalCategory : len ( mapTagLevel ) ,
TagList : l . organizationLevelRelation ( mapTagLevel ) , //组装等级从属关系
} )
return nil
}
//排序推荐产品结构体
type sortRecommendProduct struct {
ProductId int64
Sort int64
}
//组织等级从属关系
func ( l * GetTagProductListLogic ) organizationLevelRelation ( mapTagLevel map [ string ] * types . TagItem ) [ ] types . TagItem {
// 组织等级从属关系
func ( l * GetTagProductListLogic ) organizationLevelRelation ( mapTagLevel map [ string ] * types . TagItem ) [ ] types . TagItem {
mapTop := make ( map [ string ] struct { } )
for prefix , tagItem := range mapTagLevel {
//最上级没有父级
@@ -267,19 +235,21 @@ func (l *GetTagProductListLogic)organizationLevelRelation(mapTagLevel map[string
prefixSlice := strings . Split ( prefix , "/" )
//有父级
parentPrefix := strings . Join ( prefixSlice [ : len ( prefixSlice ) - 1 ] , "/" )
if parent , ok := mapTagLevel [ parentPrefix ] ; ok {
parent . ChildTagList = append ( parent . ChildTagList , tagItem )
//排序
sort . SliceStable ( parent . ChildTagList , func ( i , j int ) bool {
return parent . ChildTagList [ i ] . Sort < parent . ChildTagList [ j ] . Sort
} )
mapTagLevel [ parentPrefix ] = parent
parent , ok := mapTagLevel [ parentPrefix ]
if ! ok {
continue
}
parent . ChildTagList = append ( parent . ChildTagList , tagItem )
//排序
sort . SliceStable ( parent . ChildTagList , func ( i , j int ) bool {
return parent . ChildTagList [ i ] . Sort < parent . ChildTagList [ j ] . Sort
} )
mapTagLevel [ parentPrefix ] = parent
}
//最终值提取最高级别那一层出来
rspList := make ( [ ] types . TagItem , 0 , len ( mapTagLevel ) )
for prefix , _ := range mapTop {
rspList = append ( rspList , * mapTagLevel [ prefix ] )
rspList = append ( rspList , * mapTagLevel [ prefix ] )
}
//排序
sort . SliceStable ( rspList , func ( i , j int ) bool {
@@ -287,81 +257,6 @@ func (l *GetTagProductListLogic)organizationLevelRelation(mapTagLevel map[string
} )
return rspList
}
//获取tag推荐产品列表
type getTagRecommendProductsReq struct {
TagInfo gmodel . FsTags
ProductList [ ] gmodel . FsProduct
MapProduct map [ int64 ] int
MapProductMinPrice map [ int64 ] int64
MapProductTemplate map [ int64 ] struct { }
MapProductSizeCount map [ int64 ] int64
RecommendProductIds [ ] int64
RecommendProductIdsSort [ ] int64
Size uint32
User gmodel . FsUser
}
func ( l * GetTagProductListLogic ) getTagRecommendProducts ( req getTagRecommendProductsReq ) ( productListRsp [ ] types . TagProduct ) {
//排序
sortList := make ( [ ] sortRecommendProduct , 0 , len ( req . RecommendProductIds ) )
for sortIndex , pid := range req . RecommendProductIds {
sortList = append ( sortList , sortRecommendProduct {
ProductId : pid ,
Sort : req . RecommendProductIdsSort [ sortIndex ] ,
} )
}
sort . SliceStable ( sortList , func ( i , j int ) bool {
return sortList [ i ] . Sort < sortList [ j ] . Sort
} )
productListRsp = make ( [ ] types . TagProduct , 0 , len ( sortList ) )
for _ , sortVal := range sortList {
productIndex , ok := req . MapProduct [ sortVal . ProductId ]
if ! ok {
continue
}
productInfo := req . ProductList [ productIndex ]
minPrice , ok := req . MapProductMinPrice [ productInfo . Id ]
_ , tmpOk := req . MapProductTemplate [ productInfo . Id ]
//无最小价格则不显示 || 没有模板也不显示
if ! ok || ! tmpOk {
continue
}
sizeNum := int64 ( 0 )
if mapSizeNum , ok := req . MapProductSizeCount [ productInfo . Id ] ; ok {
sizeNum = mapSizeNum
}
item := types . TagProduct {
ProductId : productInfo . Id ,
Sn : * productInfo . Sn ,
Title : * productInfo . Title ,
Intro : * productInfo . Intro ,
IsEnv : * productInfo . IsProtection ,
IsMicro : * productInfo . IsMicrowave ,
SizeNum : uint32 ( sizeNum ) ,
MiniPrice : minPrice ,
}
//千人千面处理
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 ,
}
if req . User . Id != 0 {
r . IsThousandFace = int ( * req . User . IsThousandFace )
}
image . ThousandFaceImageFormat ( & r )
item . Cover = r . Cover
item . CoverImg = r . CoverImg
item . CoverDefault = r . CoverDefault
//加入切片
productListRsp = append ( productListRsp , item )
}
return productListRsp
}
// 获取对应tag的产品列表
type getTagProductsReq struct {
TagId int64