package logic import ( "context" "encoding/json" "errors" "fusenapi/constants" "fusenapi/model/gmodel" "fusenapi/server/product/internal/svc" "fusenapi/server/product/internal/types" "fusenapi/utils/auth" "fusenapi/utils/basic" "fusenapi/utils/format" "fusenapi/utils/image" "github.com/zeromicro/go-zero/core/logx" "github.com/zeromicro/go-zero/core/stores/sqlc" "gorm.io/gorm" "math" "sort" "strings" ) type GetProductListLogic struct { logx.Logger ctx context.Context svcCtx *svc.ServiceContext } func NewGetProductListLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetProductListLogic { return &GetProductListLogic{ Logger: logx.WithContext(ctx), ctx: ctx, svcCtx: svcCtx, } } // 获取产品列表 func (l *GetProductListLogic) GetProductList(req *types.GetProductListReq, userinfo *auth.UserInfo) (resp *basic.Response) { //如果是demo if req.IsDemo == 1 { var demo types.GetProductListRsp if err := json.Unmarshal([]byte(constants.PRODUCT_LIST_DEMO), &demo); err != nil { logx.Error(err) return resp.SetStatusWithMessage(basic.CodeServiceErr, "demo data format err") } return resp.SetStatusWithMessage(basic.CodeOK, "success", demo) } if req.Page <= 0 && req.Page > 10000 { req.Page = constants.DEFAULT_PAGE } //获取合适尺寸 if req.Size > 0 { req.Size = image.GetCurrentSize(req.Size) } pageSize := constants.DEFAULT_PAGE_SIZE //查询用户信息(不用判断存在) userModel := gmodel.NewFsUserModel(l.svcCtx.MysqlConn) user, err := userModel.FindUserById(l.ctx, userinfo.UserId) if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) { logx.Error(err) return resp.SetStatusWithMessage(basic.CodeServiceErr, "get user info err") } //查询符合的产品列表 productModel := gmodel.NewFsProductModel(l.svcCtx.MysqlConn) productList, total, err := productModel.GetProductListByTypeIds(l.ctx, []int64{req.Cid}, int(req.Page), pageSize, "sort-desc") if err != nil { logx.Error(err) return resp.SetStatusWithMessage(basic.CodeServiceErr, "failed to get product list") } productLen := len(productList) if productLen == 0 { return resp.SetStatusWithMessage(basic.CodeOK, "success") } //提取产品ids productIds := make([]int64, 0, productLen) for _, v := range productList { productIds = append(productIds, v.Id) } productPriceModel := gmodel.NewFsProductPriceModel(l.svcCtx.MysqlConn) productPriceList, err := productPriceModel.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) 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]) } //获取模板 productTemplateModel := gmodel.NewFsProductTemplateV2Model(l.svcCtx.MysqlConn) productTemplatesV2, err := productTemplateModel.FindAllByProductIds(l.ctx, productIds) 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{}{} } //获取分类 tagsModel := gmodel.NewFsTagsModel(l.svcCtx.MysqlConn) tagInfo, err := tagsModel.FindOne(l.ctx, req.Cid) if err != nil && !errors.Is(err, sqlc.ErrNotFound) { if errors.Is(err, gorm.ErrRecordNotFound) { return resp.SetStatusWithMessage(basic.CodeServiceErr, "tag is not exists") } logx.Error(err) return resp.SetStatusWithMessage(basic.CodeServiceErr, "get tag err") } //获取产品尺寸数量 productSizeModel := gmodel.NewFsProductSizeModel(l.svcCtx.MysqlConn) productSizeCountList, err := productSizeModel.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 } //拼接返回 itemList := make([]types.Items, 0, productLen) for _, v := range productList { minPrice, ok := mapProductMinPrice[v.Id] _, tmpOk := mapProductTemplate[v.Id] //无最小价格则不显示 || 没有模板也不显示 if !ok || !tmpOk { continue } sizeNum := int64(0) if mapSizeNum, ok := mapProductSizeCount[v.Id]; ok { sizeNum = mapSizeNum } item := types.Items{ Id: v.Id, Sn: *v.Sn, Title: *v.Title, Intro: *v.Intro, IsEnv: *v.IsProtection, IsMicro: *v.IsMicrowave, SizeNum: uint32(sizeNum), MiniPrice: minPrice, } //千人千面处理 r := image.ThousandFaceImageFormatReq{ Size: int(req.Size), IsThousandFace: 0, Cover: *v.Cover, CoverImg: *v.CoverImg, CoverDefault: *v.CoverImg, ProductId: v.Id, UserId: user.Id, } if user.Id != 0 { r.IsThousandFace = int(*user.IsThousandFace) } image.ThousandFaceImageFormat(&r) item.Cover = r.Cover item.CoverImg = r.CoverImg item.CoverDefault = r.CoverDefault itemList = append(itemList, item) } return resp.SetStatusWithMessage(basic.CodeOK, "success", types.GetProductListRsp{ Ob: types.Ob{ Items: itemList, Meta: types.Meta{ TotalCount: total, PageCount: int64(math.Ceil(float64(total) / float64(pageSize))), CurrentPage: int(req.Page), PerPage: pageSize, }, }, TypeName: *tagInfo.Title, Description: *tagInfo.Description, }) }