package logic import ( "context" "errors" "fmt" "fusenapi/constants" "fusenapi/model/gmodel" "fusenapi/utils/auth" "fusenapi/utils/basic" "fusenapi/utils/format" "fusenapi/utils/step_price" "strings" "fusenapi/server/product/internal/svc" "fusenapi/server/product/internal/types" "github.com/zeromicro/go-zero/core/logx" ) type GetSizeByProductLogic struct { logx.Logger ctx context.Context svcCtx *svc.ServiceContext } func NewGetSizeByProductLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetSizeByProductLogic { return &GetSizeByProductLogic{ Logger: logx.WithContext(ctx), ctx: ctx, svcCtx: svcCtx, } } // 获取分类下的产品以及尺寸 func (l *GetSizeByProductLogic) GetSizeByProduct(req *types.Request, userinfo *auth.UserInfo) (resp *basic.Response) { if userinfo.GetIdType() != auth.IDTYPE_User { return resp.SetStatusWithMessage(basic.CodeUnAuth, "please sign in first") } //获取所有网站目录 tagsModel := gmodel.NewFsTagsModel(l.svcCtx.MysqlConn) tagsList, err := tagsModel.GetAllByLevel(l.ctx, constants.TYPE_WEBSITE) if err != nil { logx.Error(err) return resp.SetStatusWithMessage(basic.CodeServiceErr, "failed to get website tags") } if len(tagsList) == 0 { return resp.SetStatusWithMessage(basic.CodeOK, "tag list is null") } tagIds := make([]int64, 0, len(tagsList)) for _, v := range tagsList { tagIds = append(tagIds, v.Id) } //获取这些类型的产品 productModel := gmodel.NewFsProductModel(l.svcCtx.MysqlConn) productList, err := productModel.GetProductListByIds(l.ctx, tagIds, "sort-desc") if err != nil { logx.Error(err) return resp.SetStatusWithMessage(basic.CodeServiceErr, "failed to get tag product list") } productIds := make([]int64, 0, len(productList)) for _, v := range productList { productIds = append(productIds, v.Id) } productSizeModel := gmodel.NewFsProductSizeModel(l.svcCtx.MysqlConn) productSizeList, err := productSizeModel.GetAllByProductIds(l.ctx, productIds, "sort DESC") if err != nil { logx.Error(err) return resp.SetStatusWithMessage(basic.CodeServiceErr, "failed to get product size list") } sizeIds := make([]int64, 0, len(productSizeList)) for _, v := range productSizeList { sizeIds = append(sizeIds, v.Id) } //获取价格列表 productPriceModel := gmodel.NewFsProductPriceModel(l.svcCtx.MysqlConn) productPriceList, err := productPriceModel.GetPriceListBySizeIds(l.ctx, sizeIds) if err != nil { logx.Error(err) return resp.SetStatusWithMessage(basic.CodeServiceErr, "failed to get product proce list") } mapProductPrice := make(map[int64]gmodel.FsProductPrice) for _, v := range productPriceList { mapProductPrice[*v.SizeId] = v } //组装返回 list := make([]types.GetSizeByProductRsp, 0, len(tagsList)) for _, tag := range tagsList { //获取第一层子类 firstChildrenList, err := l.GetFirstChildrenList(tag, productList, productSizeList, mapProductPrice) if err != nil { logx.Error(err) return resp.SetStatusWithMessage(basic.CodeServiceErr, "failed to get first level children list") } data := types.GetSizeByProductRsp{ Id: tag.Id, Name: *tag.Title, Children: firstChildrenList, } list = append(list, data) } return resp.SetStatusWithMessage(basic.CodeOK, "success", list) } // 第一层子层 func (l *GetSizeByProductLogic) GetFirstChildrenList(tag gmodel.FsTags, productList []gmodel.FsProduct, productSizeList []gmodel.FsProductSize, mapProductPrice map[int64]gmodel.FsProductPrice) (childrenList []types.Children, err error) { childrenList = make([]types.Children, 0, len(productList)) for _, product := range productList { if *product.Type != tag.Id { continue } childrenObjList, err := l.GetSecondChildrenList(product, productSizeList, mapProductPrice) if err != nil { return nil, err } //获取第二层子类 data := types.Children{ Id: product.Id, Name: *product.Title, Cycle: int(*product.DeliveryDays + *product.ProduceDays), ChildrenList: childrenObjList, } childrenList = append(childrenList, data) } return } // 第2层子层 func (l *GetSizeByProductLogic) GetSecondChildrenList(product gmodel.FsProduct, productSizeList []gmodel.FsProductSize, mapProductPrice map[int64]gmodel.FsProductPrice) (childrenObjList []types.ChildrenObj, err error) { childrenObjList = make([]types.ChildrenObj, 0, len(productSizeList)) for _, productSize := range productSizeList { if product.Id != *productSize.ProductId { continue } priceList := make([]types.PriceObj, 0, len(productSizeList)) price, ok := mapProductPrice[productSize.Id] //无对应尺寸价格 if !ok { priceList = []types.PriceObj{ {Num: 1, Price: 0}, {Num: 1, Price: 0}, {Num: 1, Price: 0}, } childrenObjList = append(childrenObjList, types.ChildrenObj{ Id: productSize.Id, Name: *productSize.Capacity, PriceList: priceList, }) continue } if price.StepNum == nil || price.StepPrice == nil { continue } *price.StepNum = strings.Trim(*price.StepNum, " ") *price.StepPrice = strings.Trim(*price.StepPrice, " ") //阶梯数量切片 stepNum, err := format.StrSlicToIntSlice(strings.Split(*price.StepNum, ",")) if err != nil { return nil, err } //阶梯价格切片 stepPrice, err := format.StrSlicToIntSlice(strings.Split(*price.StepPrice, ",")) if err != nil { return nil, err } if len(stepNum) == 0 || len(stepPrice) == 0 { return nil, errors.New(fmt.Sprintf("stepNum count or stepPrice count is empty: product size id :%d ,product price id :%d", productSize.Id, price.Id)) } index := 0 // 最小购买数量小于 最大阶梯数量+5 for int(*price.MinBuyNum) < (stepNum[len(stepNum)-1]+5) && index < 3 { priceList = append(priceList, types.PriceObj{ Num: int(*price.MinBuyNum * *price.EachBoxNum), Price: step_price.GetStepPrice(int(*price.MinBuyNum), stepNum, stepPrice), }) *price.MinBuyNum++ index++ } data := types.ChildrenObj{ Id: productSize.Id, Name: *productSize.Capacity, PriceList: priceList, } childrenObjList = append(childrenObjList, data) } return }