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) tmpMinBuyNum := *priceInfo.MinBuyNum for tmpMinBuyNum < (int64(stepNumSlice[lenStepNum-1]) + 5) { itemList = append(itemList, types.PriceItem{ Num: tmpMinBuyNum, TotalNum: tmpMinBuyNum * (*priceInfo.EachBoxNum), Price: step_price.GetCentStepPrice(int(tmpMinBuyNum), stepNumSlice, stepPriceSlice), }) tmpMinBuyNum++ } //组装阶梯数量范围价格 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) begin := int64(0) end := int64(0) if numKey == 0 { //第一个 begin = *priceInfo.MinBuyNum * (*priceInfo.EachBoxNum) end = num - 1 } else if numKey < lenStepNum-1 { //中间的 nextNum := int64(stepNumSlice[numKey+1]) * (*priceInfo.EachBoxNum) begin = num end = nextNum - 1 } else { //最后的 begin = num end = -1 } stepListRsp = append(stepListRsp, types.StepRange{ Begin: begin, End: end, Price: tmpPrice, }) } return stepListRsp } // 获取mapKey func (l *GetPriceByPidLogic) getSizePriceMapKey(sizeId int64) string { return fmt.Sprintf("_%d", sizeId) }