package logic import ( "errors" "fmt" "fusenapi/model/gmodel" "fusenapi/utils/auth" "fusenapi/utils/basic" "fusenapi/utils/format" "fusenapi/utils/step_price" "gorm.io/gorm" "sort" "strings" "context" "fusenapi/server/product/internal/svc" "fusenapi/server/product/internal/types" "github.com/zeromicro/go-zero/core/logx" ) type GetPriceByPidLogic struct { logx.Logger ctx context.Context svcCtx *svc.ServiceContext } func NewGetPriceByPidLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetPriceByPidLogic { return &GetPriceByPidLogic{ Logger: logx.WithContext(ctx), ctx: ctx, svcCtx: svcCtx, } } func (l *GetPriceByPidLogic) GetPriceByPid(req *types.GetPriceByPidReq, userinfo *auth.UserInfo) (resp *basic.Response) { req.Pid = strings.Trim(req.Pid, " ") if req.Pid == "" { return resp.SetStatusWithMessage(basic.CodeRequestParamsErr, "err param:pid is empty") } //获取产品信息(只是获取id) productInfo, err := l.svcCtx.AllModels.FsProduct.FindOneBySn(l.ctx, req.Pid, "id") if err != nil { if errors.Is(err, gorm.ErrRecordNotFound) { return resp.SetStatusWithMessage(basic.CodeDbRecordNotFoundErr, "the product is not exists") } logx.Error(err) return resp.SetStatusWithMessage(basic.CodeDbSqlErr, "failed to get product info") } //查询产品价格 priceList, err := l.svcCtx.AllModels.FsProductPrice.GetPriceListByProductIds(l.ctx, []int64{productInfo.Id}) if err != nil { logx.Error(err) return resp.SetStatusWithMessage(basic.CodeDbSqlErr, "failed to get price list") } if len(priceList) == 0 { return resp.SetStatusWithMessage(basic.CodeOK, "success:price list is empty") } //处理价格信息 mapRsp := make(map[string]*types.GetPriceByPidRsp) for _, priceInfo := range priceList { stepNumSlice, err := format.StrSlicToIntSlice(strings.Split(*priceInfo.StepNum, ",")) if err != nil { return resp.SetStatusWithMessage(basic.CodeServiceErr, fmt.Sprintf("failed to parse step num,price_id=%d", priceInfo.Id)) } stepPriceSlice, err := format.StrSlicToIntSlice(strings.Split(*priceInfo.StepPrice, ",")) if err != nil { return resp.SetStatusWithMessage(basic.CodeServiceErr, fmt.Sprintf("failed to parse step price,id = %d", priceInfo.Id)) } if len(stepPriceSlice) == 0 || len(stepNumSlice) == 0 { return resp.SetStatusWithMessage(basic.CodeServiceErr, "number of step num or step price is zero") } lenStepNum := len(stepNumSlice) itemList := make([]types.PriceItem, 0, 10) for *priceInfo.MinBuyNum < (int64(stepNumSlice[lenStepNum-1]) + 5) { itemList = append(itemList, types.PriceItem{ Num: *priceInfo.MinBuyNum, TotalNum: (*priceInfo.MinBuyNum) * (*priceInfo.EachBoxNum), Price: step_price.GetCentStepPrice(int(*priceInfo.MinBuyNum), stepNumSlice, stepPriceSlice), }) *priceInfo.MinBuyNum++ } //组装阶梯数量范围价格 stepRange := l.dealWithStepRange(stepNumSlice, stepPriceSlice, priceInfo) //排序(必须放在其他逻辑之后) sort.Ints(stepPriceSlice) minPrice := float64(stepPriceSlice[0]) / 100 maxPrice := float64(stepPriceSlice[len(stepPriceSlice)-1]) / 100 mapKey := l.getSizePriceMapKey(*priceInfo.SizeId) mapRsp[mapKey] = &types.GetPriceByPidRsp{ Items: itemList, MinPrice: minPrice, MaxPrice: maxPrice, StepRange: stepRange, } } return resp.SetStatusWithMessage(basic.CodeOK, "success", mapRsp) } // 组装阶梯价格范围 func (l *GetPriceByPidLogic) dealWithStepRange(stepNumSlice, stepPriceSlice []int, priceInfo gmodel.FsProductPrice) []types.StepRange { lenStepNum := len(stepNumSlice) lenStepPrice := len(stepPriceSlice) stepListRsp := make([]types.StepRange, 0, lenStepNum) for numKey, stepNum := range stepNumSlice { //先取最后一个 tmpPrice := float64(stepPriceSlice[lenStepPrice-1]) / 100 //如果同下标下面有价格 if numKey < lenStepPrice { tmpPrice = float64(stepPriceSlice[numKey]) / 100 } num := int64(stepNum) * (*priceInfo.EachBoxNum) rangeNum := types.RangeNum{} if numKey < lenStepNum-1 { //前面的 nextNum := int64(stepNumSlice[numKey+1]) * (*priceInfo.EachBoxNum) rangeNum.Begin = num rangeNum.End = nextNum - 1 } else { //最后一个 rangeNum.Begin = num rangeNum.End = -1 } stepListRsp = append(stepListRsp, types.StepRange{ RangeNum: rangeNum, Price: tmpPrice, }) } return stepListRsp } // 获取mapKey func (l *GetPriceByPidLogic) getSizePriceMapKey(sizeId int64) string { return fmt.Sprintf("_%d", sizeId) }