| 
									
										
										
										
											2023-07-11 17:08:19 +08:00
										 |  |  | package logic | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							|  |  |  | 	"errors" | 
					
						
							| 
									
										
										
										
											2023-08-08 14:31:40 +08:00
										 |  |  | 	"fusenapi/model/gmodel" | 
					
						
							| 
									
										
										
										
											2023-07-11 17:08:19 +08:00
										 |  |  | 	"fusenapi/utils/auth" | 
					
						
							|  |  |  | 	"fusenapi/utils/basic" | 
					
						
							| 
									
										
										
										
											2023-07-20 15:27:17 +08:00
										 |  |  | 	"fusenapi/utils/format" | 
					
						
							| 
									
										
										
										
											2023-07-11 17:08:19 +08:00
										 |  |  | 	"fusenapi/utils/image" | 
					
						
							|  |  |  | 	"gorm.io/gorm" | 
					
						
							| 
									
										
										
										
											2023-07-20 15:27:17 +08:00
										 |  |  | 	"sort" | 
					
						
							|  |  |  | 	"strings" | 
					
						
							| 
									
										
										
										
											2023-07-11 17:08:19 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	"context" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	"fusenapi/server/product/internal/svc" | 
					
						
							|  |  |  | 	"fusenapi/server/product/internal/types" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	"github.com/zeromicro/go-zero/core/logx" | 
					
						
							|  |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | type GetRecommandProductListLogic struct { | 
					
						
							|  |  |  | 	logx.Logger | 
					
						
							|  |  |  | 	ctx    context.Context | 
					
						
							|  |  |  | 	svcCtx *svc.ServiceContext | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func NewGetRecommandProductListLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetRecommandProductListLogic { | 
					
						
							|  |  |  | 	return &GetRecommandProductListLogic{ | 
					
						
							|  |  |  | 		Logger: logx.WithContext(ctx), | 
					
						
							|  |  |  | 		ctx:    ctx, | 
					
						
							|  |  |  | 		svcCtx: svcCtx, | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (l *GetRecommandProductListLogic) GetRecommandProductList(req *types.GetRecommandProductListReq, userinfo *auth.UserInfo) (resp *basic.Response) { | 
					
						
							| 
									
										
										
										
											2023-07-20 14:56:28 +08:00
										 |  |  | 	req.Num = 4 //写死4个 | 
					
						
							| 
									
										
										
										
											2023-07-11 17:08:19 +08:00
										 |  |  | 	if req.Size > 0 { | 
					
						
							| 
									
										
										
										
											2023-08-15 19:43:50 +08:00
										 |  |  | 		req.Size = int32(image.GetCurrentSize(uint32(req.Size))) | 
					
						
							| 
									
										
										
										
											2023-07-11 17:08:19 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2023-07-20 14:56:28 +08:00
										 |  |  | 	productInfo, err := l.svcCtx.AllModels.FsProduct.FindOneBySn(l.ctx, req.Sn) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		if errors.Is(err, gorm.ErrRecordNotFound) { | 
					
						
							|  |  |  | 			return resp.SetStatusWithMessage(basic.CodeDbRecordNotFoundErr, "detail`s product is not found") | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		logx.Error(err) | 
					
						
							|  |  |  | 		return resp.SetStatusWithMessage(basic.CodeDbSqlErr, "failed to get detail product info") | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2023-08-08 14:31:40 +08:00
										 |  |  | 	var ( | 
					
						
							|  |  |  | 		recommendProductList []gmodel.FsProduct | 
					
						
							|  |  |  | 	) | 
					
						
							|  |  |  | 	if productInfo.RecommendProduct != nil && *productInfo.RecommendProduct != "" { | 
					
						
							|  |  |  | 		recommendProductIds, err := format.StrSlicToInt64Slice(strings.Split(*productInfo.RecommendProduct, ",")) | 
					
						
							|  |  |  | 		if err != nil { | 
					
						
							|  |  |  | 			logx.Error(err) | 
					
						
							|  |  |  | 			return resp.SetStatusWithMessage(basic.CodeServiceErr, "failed to split recommend product ids") | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		recommendProductList, err = l.svcCtx.AllModels.FsProduct.GetProductListByIds(l.ctx, recommendProductIds, "") | 
					
						
							|  |  |  | 		if err != nil { | 
					
						
							|  |  |  | 			logx.Error(err) | 
					
						
							|  |  |  | 			return resp.SetStatusWithMessage(basic.CodeDbSqlErr, "failed to get recommend product list") | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2023-07-11 17:08:19 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2023-07-20 14:56:28 +08:00
										 |  |  | 	//需要填充时需要忽略的id | 
					
						
							| 
									
										
										
										
											2023-08-08 14:31:40 +08:00
										 |  |  | 	ignoreProductIds := make([]int64, 0, len(recommendProductList)) | 
					
						
							| 
									
										
										
										
											2023-07-20 18:04:50 +08:00
										 |  |  | 	productIds := make([]int64, 0, len(recommendProductList)) | 
					
						
							| 
									
										
										
										
											2023-07-20 14:56:28 +08:00
										 |  |  | 	//在合并之前记住推荐的产品 | 
					
						
							|  |  |  | 	mapRecommend := make(map[int64]struct{}) | 
					
						
							|  |  |  | 	for _, v := range recommendProductList { | 
					
						
							| 
									
										
										
										
											2023-07-20 18:06:48 +08:00
										 |  |  | 		ignoreProductIds = append(ignoreProductIds, v.Id) | 
					
						
							|  |  |  | 		productIds = append(productIds, v.Id) | 
					
						
							| 
									
										
										
										
											2023-07-20 14:56:28 +08:00
										 |  |  | 		mapRecommend[v.Id] = struct{}{} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2023-07-20 18:06:48 +08:00
										 |  |  | 	//小于请求的数量则需要从产品表中随机填补上(不包含上面的产品) | 
					
						
							| 
									
										
										
										
											2023-07-20 14:56:28 +08:00
										 |  |  | 	lenRecommendProduct := len(recommendProductList) | 
					
						
							|  |  |  | 	if lenRecommendProduct < int(req.Num) { | 
					
						
							|  |  |  | 		appendNum := int(req.Num) - lenRecommendProduct | 
					
						
							|  |  |  | 		productList, err := l.svcCtx.AllModels.FsProduct.GetIgnoreRandomProductList(l.ctx, appendNum, ignoreProductIds) | 
					
						
							|  |  |  | 		if err != nil { | 
					
						
							|  |  |  | 			logx.Error(err) | 
					
						
							|  |  |  | 			return resp.SetStatusWithMessage(basic.CodeDbSqlErr, "failed to get product list") | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		//合并列表 | 
					
						
							| 
									
										
										
										
											2023-07-20 15:27:17 +08:00
										 |  |  | 		for _, v := range productList { | 
					
						
							|  |  |  | 			productIds = append(productIds, v.Id) | 
					
						
							|  |  |  | 			recommendProductList = append(recommendProductList, v) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	//查询产品价格 | 
					
						
							|  |  |  | 	priceList, err := l.svcCtx.AllModels.FsProductPrice.GetPriceListByProductIds(l.ctx, productIds) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		logx.Error(err) | 
					
						
							|  |  |  | 		return resp.SetStatusWithMessage(basic.CodeDbSqlErr, "failed to get product price list") | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	mapProductMinPrice := make(map[int64]int64) | 
					
						
							|  |  |  | 	for _, v := range priceList { | 
					
						
							|  |  |  | 		if v.StepPrice == nil || *v.StepPrice == "" { | 
					
						
							|  |  |  | 			continue | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		stepPriceSlice, err := format.StrSlicToIntSlice(strings.Split(*v.StepPrice, ",")) | 
					
						
							|  |  |  | 		if err != nil { | 
					
						
							|  |  |  | 			logx.Error(err) | 
					
						
							|  |  |  | 			return resp.SetStatusWithMessage(basic.CodeServiceErr, "failed to parse step price") | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		//正序排序 | 
					
						
							|  |  |  | 		sort.Ints(stepPriceSlice) | 
					
						
							|  |  |  | 		if min, ok := mapProductMinPrice[*v.ProductId]; ok { | 
					
						
							|  |  |  | 			if min > int64(stepPriceSlice[0]) { | 
					
						
							|  |  |  | 				mapProductMinPrice[*v.ProductId] = int64(stepPriceSlice[0]) | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} else { | 
					
						
							|  |  |  | 			mapProductMinPrice[*v.ProductId] = int64(stepPriceSlice[0]) | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2023-07-11 17:08:19 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	//获取用户信息(不用判断存在) | 
					
						
							| 
									
										
										
										
											2023-08-14 12:30:14 +08:00
										 |  |  | 	/*user, err := l.svcCtx.AllModels.FsUser.FindUserById(l.ctx, userinfo.UserId) | 
					
						
							| 
									
										
										
										
											2023-07-11 17:08:19 +08:00
										 |  |  | 	if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) { | 
					
						
							|  |  |  | 		logx.Error(err) | 
					
						
							|  |  |  | 		return resp.SetStatusWithMessage(basic.CodeDbSqlErr, "failed to get user") | 
					
						
							| 
									
										
										
										
											2023-08-14 12:30:14 +08:00
										 |  |  | 	}*/ | 
					
						
							|  |  |  | 	//获取产品标签相关属性 | 
					
						
							|  |  |  | 	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") | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	mapTagProp := make(map[int64][]types.CoverDefaultItem) | 
					
						
							|  |  |  | 	for _, v := range productTagPropList { | 
					
						
							|  |  |  | 		mapTagProp[*v.ProductId] = append(mapTagProp[*v.ProductId], types.CoverDefaultItem{ | 
					
						
							| 
									
										
										
										
											2023-08-17 11:14:47 +08:00
										 |  |  | 			Tag:   v.TemplateTag, | 
					
						
							| 
									
										
										
										
											2023-08-14 12:30:14 +08:00
										 |  |  | 			Cover: *v.Cover, | 
					
						
							|  |  |  | 		}) | 
					
						
							| 
									
										
										
										
											2023-07-11 17:08:19 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2023-07-20 14:56:28 +08:00
										 |  |  | 	list := make([]types.GetRecommandProductListRsp, 0, len(recommendProductList)) | 
					
						
							|  |  |  | 	for _, v := range recommendProductList { | 
					
						
							| 
									
										
										
										
											2023-08-14 12:30:14 +08:00
										 |  |  | 		/*r := image.ThousandFaceImageFormatReq{ | 
					
						
							| 
									
										
										
										
											2023-07-11 17:08:19 +08:00
										 |  |  | 			Size:           int(req.Size), | 
					
						
							|  |  |  | 			IsThousandFace: 0, | 
					
						
							|  |  |  | 			Cover:          *v.Cover, | 
					
						
							|  |  |  | 			CoverImg:       *v.CoverImg, | 
					
						
							|  |  |  | 			CoverDefault:   *v.Cover, | 
					
						
							|  |  |  | 			ProductId:      v.Id, | 
					
						
							|  |  |  | 			UserId:         userinfo.UserId, | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		if user.Id != 0 { | 
					
						
							|  |  |  | 			r.IsThousandFace = int(*user.IsThousandFace) | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2023-07-20 14:56:28 +08:00
										 |  |  | 		//千人前面处理 | 
					
						
							| 
									
										
										
										
											2023-08-14 12:30:14 +08:00
										 |  |  | 		image.ThousandFaceImageFormat(&r)*/ | 
					
						
							| 
									
										
										
										
											2023-07-20 14:56:28 +08:00
										 |  |  | 		isRecommend := int64(0) | 
					
						
							|  |  |  | 		if _, ok := mapRecommend[v.Id]; ok { | 
					
						
							|  |  |  | 			isRecommend = 1 | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2023-07-20 15:27:17 +08:00
										 |  |  | 		minPrice := int64(0) | 
					
						
							|  |  |  | 		if minVal, ok := mapProductMinPrice[v.Id]; ok { | 
					
						
							|  |  |  | 			minPrice = minVal | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2023-08-14 12:30:14 +08:00
										 |  |  | 		item := types.GetRecommandProductListRsp{ | 
					
						
							| 
									
										
										
										
											2023-08-14 12:31:49 +08:00
										 |  |  | 			Id:           v.Id, | 
					
						
							|  |  |  | 			Sn:           *v.Sn, | 
					
						
							|  |  |  | 			Title:        *v.Title, | 
					
						
							|  |  |  | 			TitleCn:      *v.TitleCn, | 
					
						
							| 
									
										
										
										
											2023-08-22 12:21:31 +08:00
										 |  |  | 			Cover:        *v.Cover, | 
					
						
							|  |  |  | 			CoverImg:     *v.CoverImg, | 
					
						
							| 
									
										
										
										
											2023-08-14 12:31:49 +08:00
										 |  |  | 			CoverDefault: []types.CoverDefaultItem{}, | 
					
						
							|  |  |  | 			Intro:        *v.Intro, | 
					
						
							|  |  |  | 			IsRecommend:  isRecommend, | 
					
						
							|  |  |  | 			MinPrice:     minPrice, | 
					
						
							| 
									
										
										
										
											2023-08-14 12:30:14 +08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		if _, ok := mapTagProp[productInfo.Id]; ok { | 
					
						
							|  |  |  | 			item.CoverDefault = mapTagProp[productInfo.Id] | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		list = append(list, item) | 
					
						
							| 
									
										
										
										
											2023-07-11 17:08:19 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	return resp.SetStatusWithMessage(basic.CodeOK, "success", list) | 
					
						
							|  |  |  | } |