diff --git a/model/gmodel/fs_product_logic.go b/model/gmodel/fs_product_logic.go index 009181db..95c301ce 100755 --- a/model/gmodel/fs_product_logic.go +++ b/model/gmodel/fs_product_logic.go @@ -72,7 +72,11 @@ func (p *FsProductModel) GetRandomProductList(ctx context.Context, limit int) (r Where("`is_del` =? and `is_shelf` = ?", 0, 1).Order("RAND()").Limit(limit).Find(&resp).Error return resp, err } - +func (p *FsProductModel) GetIgnoreRandomProductList(ctx context.Context, limit int, notInProductIds []int64) (resp []FsProduct, err error) { + err = p.db.WithContext(ctx).Model(&FsProduct{}). + Where("`is_del` =? and `is_shelf` = ? and `id` not in(?)", 0, 1, notInProductIds).Order("RAND()").Limit(limit).Find(&resp).Error + return resp, err +} 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/model/gmodel/fs_product_recommend_gen.go b/model/gmodel/fs_product_recommend_gen.go new file mode 100644 index 00000000..b70ba056 --- /dev/null +++ b/model/gmodel/fs_product_recommend_gen.go @@ -0,0 +1,21 @@ +package gmodel + +import ( + "gorm.io/gorm" +) + +// fs_product_recommend 推荐商品表 +type FsProductRecommend struct { + Id int64 `gorm:"primary_key;default:0;auto_increment;" json:"id"` // + ProductId *int64 `gorm:"unique_key;default:0;" json:"product_id"` // 产品ID + Status *int64 `gorm:"default:1;" json:"status"` // 状态 1正常 0不正常 + Ctime *int64 `gorm:"default:0;" json:"ctime"` // 添加时间 +} +type FsProductRecommendModel struct { + db *gorm.DB + name string +} + +func NewFsProductRecommendModel(db *gorm.DB) *FsProductRecommendModel { + return &FsProductRecommendModel{db: db, name: "fs_product_recommend"} +} diff --git a/model/gmodel/fs_product_recommend_logic.go b/model/gmodel/fs_product_recommend_logic.go new file mode 100644 index 00000000..3de52d5c --- /dev/null +++ b/model/gmodel/fs_product_recommend_logic.go @@ -0,0 +1,46 @@ +package gmodel + +import ( + "context" + "errors" + "gorm.io/gorm" +) + +type GetRecommendProductListReq struct { + Ctx context.Context + Page int + Limit int + OrderBy string + Status *int64 +} + +func (r *FsProductRecommendModel) GetRecommendProductList(req GetRecommendProductListReq) (resp []FsProductRecommend, total int64, err error) { + db := r.db.WithContext(req.Ctx).Model(&FsProductRecommend{}) + if req.Status != nil { + db = db.Where("`status` = ?", *req.Status) + } + if req.OrderBy != "" { + db = db.Order(req.OrderBy) + } + if err = db.Limit(1).Count(&total).Error; err != nil { + return nil, 0, err + } + offset := (req.Page - 1) * req.Limit + err = db.Offset(offset).Limit(req.Limit).Find(&resp).Error + return resp, total, err +} +func (r *FsProductRecommendModel) GetIgnoreRandomRecommendProductList(ctx context.Context, limit int, idNotInt []int64) (resp []FsProductRecommend, err error) { + err = r.db.WithContext(ctx).Model(&FsProductRecommend{}).Where("`product_id` not in(?)", idNotInt).Order("RAND()").Limit(limit).Find(&resp).Error + return resp, err +} +func (r *FsProductRecommendModel) CreateOrUpdate(ctx context.Context, productId int64, data *FsProductRecommend) error { + var info FsProductRecommend + err := r.db.WithContext(ctx).Model(&FsProductRecommend{}).Where("`product_id` = ?", productId).Take(&info).Error + if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) { + return err + } + if info.Id == 0 { + return r.db.WithContext(ctx).Model(&FsProductRecommend{}).Create(data).Error + } + return r.db.WithContext(ctx).Model(&FsProductRecommend{}).Where("`product_id` = ?", productId).Updates(data).Error +} diff --git a/server/product/internal/handler/routes.go b/server/product/internal/handler/routes.go index dd11f8fe..669d7cef 100644 --- a/server/product/internal/handler/routes.go +++ b/server/product/internal/handler/routes.go @@ -107,11 +107,6 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) { Path: "/api/product/get_last_product_design", Handler: GetLastProductDesignHandler(serverCtx), }, - { - Method: http.MethodPost, - Path: "/api/product/save_recommend_product", - Handler: SaveRecommendProductHandler(serverCtx), - }, }, ) } diff --git a/server/product/internal/logic/getrecommandproductlistlogic.go b/server/product/internal/logic/getrecommandproductlistlogic.go index 80176d90..68f4cb29 100644 --- a/server/product/internal/logic/getrecommandproductlistlogic.go +++ b/server/product/internal/logic/getrecommandproductlistlogic.go @@ -30,18 +30,54 @@ func NewGetRecommandProductListLogic(ctx context.Context, svcCtx *svc.ServiceCon } func (l *GetRecommandProductListLogic) GetRecommandProductList(req *types.GetRecommandProductListReq, userinfo *auth.UserInfo) (resp *basic.Response) { - req.Num = 8 //目前写死 + req.Num = 4 //写死4个 if req.Size > 0 { req.Size = image.GetCurrentSize(req.Size) } - //随机取产品列表 - productList, err := l.svcCtx.AllModels.FsProduct.GetRandomProductList(l.ctx, int(req.Num)) + 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") + } + //随机取产品列表(不包含详情产品) + recommendList, err := l.svcCtx.AllModels.FsProductRecommend.GetIgnoreRandomRecommendProductList(l.ctx, int(req.Num), []int64{productInfo.Id}) if err != nil { logx.Error(err) - return resp.SetStatusWithMessage(basic.CodeDbSqlErr, "failed to get random recommend product list") + return resp.SetStatusWithMessage(basic.CodeDbSqlErr, "failed to get random recommend list") } - if len(productList) == 0 { - return resp.SetStatusWithMessage(basic.CodeOK, "success") + //需要填充时需要忽略的id + ignoreProductIds := make([]int64, 0, len(recommendList)+1) + ignoreProductIds = append(ignoreProductIds, productInfo.Id) + recommendProductIds := make([]int64, 0, len(recommendList)) + for _, v := range recommendList { + ignoreProductIds = append(ignoreProductIds, *v.ProductId) + recommendProductIds = append(recommendProductIds, *v.ProductId) + } + //获取推荐产品列表 + recommendProductList, err := l.svcCtx.AllModels.FsProduct.GetProductListByIds(l.ctx, recommendProductIds, "") + if err != nil { + logx.Error(err) + return resp.SetStatus(basic.CodeDbSqlErr, "failed to get recommend product list") + } + //在合并之前记住推荐的产品 + mapRecommend := make(map[int64]struct{}) + for _, v := range recommendProductList { + mapRecommend[v.Id] = struct{}{} + } + //小于请求的数量则需要从产品表中随机填补上 + 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") + } + //合并列表 + recommendProductList = append(recommendProductList, productList...) } //获取用户信息(不用判断存在) user, err := l.svcCtx.AllModels.FsUser.FindUserById(l.ctx, userinfo.UserId) @@ -49,8 +85,8 @@ func (l *GetRecommandProductListLogic) GetRecommandProductList(req *types.GetRec logx.Error(err) return resp.SetStatusWithMessage(basic.CodeDbSqlErr, "failed to get user") } - list := make([]types.GetRecommandProductListRsp, 0, len(productList)) - for _, v := range productList { + list := make([]types.GetRecommandProductListRsp, 0, len(recommendProductList)) + for _, v := range recommendProductList { r := image.ThousandFaceImageFormatReq{ Size: int(req.Size), IsThousandFace: 0, @@ -63,7 +99,12 @@ func (l *GetRecommandProductListLogic) GetRecommandProductList(req *types.GetRec if user.Id != 0 { r.IsThousandFace = int(*user.IsThousandFace) } + //千人前面处理 image.ThousandFaceImageFormat(&r) + isRecommend := int64(0) + if _, ok := mapRecommend[v.Id]; ok { + isRecommend = 1 + } list = append(list, types.GetRecommandProductListRsp{ Id: v.Id, Sn: *v.Sn, @@ -73,6 +114,7 @@ func (l *GetRecommandProductListLogic) GetRecommandProductList(req *types.GetRec CoverImg: r.CoverImg, CoverDefault: r.CoverDefault, Intro: *v.Intro, + IsRecommend: isRecommend, }) } return resp.SetStatusWithMessage(basic.CodeOK, "success", list) diff --git a/server/product/internal/types/types.go b/server/product/internal/types/types.go index f10feab7..3b611579 100644 --- a/server/product/internal/types/types.go +++ b/server/product/internal/types/types.go @@ -242,6 +242,7 @@ type GetRecommandProductListRsp struct { CoverImg string `json:"cover_img"` CoverDefault string `json:"cover_default"` Intro string `json:"intro"` + IsRecommend int64 `json:"is_recommend"` } type GetTagProductListReq struct { @@ -376,16 +377,6 @@ type GetLastProductDesignRsp struct { Info interface{} `json:"info"` } -type SaveRecommendProductReq struct { - ProductList []RecommendProductItem `json:"product_list"` -} - -type RecommendProductItem struct { - ProductId int64 `json:"product_id"` - Sort int64 `json:"sort"` - Status int64 `json:"status,options=0|1"` -} - type Request struct { } diff --git a/server_api/product.api b/server_api/product.api index a1db4ad2..9c214c82 100644 --- a/server_api/product.api +++ b/server_api/product.api @@ -70,7 +70,7 @@ service product { get /api/product/get_last_product_design(request) returns (response); //*********************产品详情分解接口结束*********************** //*********************推荐产品接口开始×××××××××××××××××××××××××× - + //*********************推荐产品接口结束×××××××××××××××××××××××××× } @@ -291,6 +291,7 @@ type GetRecommandProductListRsp { CoverImg string `json:"cover_img"` CoverDefault string `json:"cover_default"` Intro string `json:"intro"` + IsRecommend int64 `json:"is_recommend"` } //获取分类产品列表 type GetTagProductListReq { @@ -415,4 +416,4 @@ type GetLastProductDesignRsp { SizeId int64 `json:"size_id"` LogoColor interface{} `json:"logo_color"` Info interface{} `json:"info"` -} +} \ No newline at end of file