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" "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) { if userinfo.GetIdType() != auth.IDTYPE_User { return resp.SetStatusWithMessage(basic.CodeUnAuth, "please login first") } //如果是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 = 1 } //获取合适尺寸 if req.Size > 0 { req.Size = image.GetCurrentSize(req.Size) } //查询用户信息 userModel := gmodel.NewFsUserModel(l.svcCtx.MysqlConn) userInfo, err := userModel.FindOne(l.ctx, userinfo.UserId) if err != nil { logx.Error(err) return resp.SetStatusWithMessage(basic.CodeServiceErr, "get user info err") } if userInfo.Id == 0 { return resp.SetStatusWithMessage(basic.CodeUnAuth, "user not exists") } //查询符合的产品列表 productModel := gmodel.NewFsProductModel(l.svcCtx.MysqlConn) productList, err := productModel.GetProductListByTypeIds(l.ctx, []int64{req.Cid}, "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) { logx.Error(err) return resp.SetStatusWithMessage(basic.CodeServiceErr, "get tag err") } if tagInfo.Id == 0 { return resp.SetStatusWithMessage(basic.CodeServiceErr, "tag is not exists") } //获取产品尺寸数量 productSizeModel := gmodel.NewFsProductSizeModel(l.svcCtx.MysqlConn) productSizeCount, err := productSizeModel.CountByStatus(l.ctx, 1) if err != nil { logx.Error(err) return resp.SetStatusWithMessage(basic.CodeServiceErr, "get product size count err") } //拼接返回 itemList := make([]types.Items, 0, productLen) for _, v := range productList { minPrice, ok := mapProductMinPrice[v.Id] _, tmpOk := mapProductTemplate[v.Id] //无最小价格则不显示 || 没有模板也不显示 if !ok || !tmpOk { continue } item := types.Items{ Id: v.Id, Sn: *v.Sn, Title: *v.Title, Intro: *v.Intro, IsEnv: *v.IsProtection, IsMicro: *v.IsMicrowave, SizeNum: uint32(productSizeCount), MiniPrice: format.CentoDollar(minPrice), } //千人千面处理 thousandFaceImageFormatReq := image.ThousandFaceImageFormatReq{ Size: int(req.Size), IsThousandFace: int(userInfo.IsThousandFace), Cover: *v.Cover, CoverImg: *v.CoverImg, CoverDefault: *v.CoverImg, ProductId: v.Id, UserInfo: userInfo, } image.ThousandFaceImageFormat(&thousandFaceImageFormatReq) item.Cover = thousandFaceImageFormatReq.Cover item.CoverImg = thousandFaceImageFormatReq.CoverImg item.CoverDefault = thousandFaceImageFormatReq.CoverDefault itemList = append(itemList, item) } return resp.SetStatusWithMessage(basic.CodeOK, "success", types.GetProductListRsp{ Ob: types.Ob{ Items: itemList, }, TypeName: *tagInfo.Title, Description: *tagInfo.Description, }) }