165 lines
		
	
	
		
			4.9 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			165 lines
		
	
	
		
			4.9 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| 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 {
 | |
| 	//要求写死不影响前端展示
 | |
| 	return []types.StepRange{
 | |
| 		{
 | |
| 			Begin: 1000,
 | |
| 			End:   2999,
 | |
| 			Price: 0.23,
 | |
| 		},
 | |
| 		{
 | |
| 			Begin: 3000,
 | |
| 			End:   4999,
 | |
| 			Price: 0.2,
 | |
| 		},
 | |
| 		{
 | |
| 			Begin: 5000,
 | |
| 			End:   -1,
 | |
| 			Price: 0.1,
 | |
| 		},
 | |
| 	}
 | |
| 	//下面是正常的
 | |
| 	lenStepNum := len(stepNumSlice)
 | |
| 	lenStepPrice := len(stepPriceSlice)
 | |
| 	stepListRsp := make([]types.StepRange, 0, lenStepNum)
 | |
| 	//只有一个阶梯价格
 | |
| 	if lenStepPrice == 1 {
 | |
| 		stepListRsp = append(stepListRsp, types.StepRange{
 | |
| 			Begin: *priceInfo.MinBuyNum * (*priceInfo.EachBoxNum),
 | |
| 			End:   -1,
 | |
| 			Price: float64(stepPriceSlice[0]) / 100,
 | |
| 		})
 | |
| 		return stepListRsp
 | |
| 	}
 | |
| 	begin := int64(0)
 | |
| 	end := int64(0)
 | |
| 	for numKey, stepNum := range stepNumSlice {
 | |
| 		//先取最后一个
 | |
| 		tmpPrice := float64(stepPriceSlice[lenStepPrice-1]) / 100
 | |
| 		//如果同下标下面有价格
 | |
| 		if numKey < lenStepPrice {
 | |
| 			tmpPrice = float64(stepPriceSlice[numKey]) / 100
 | |
| 		}
 | |
| 		begin = int64(stepNum) * (*priceInfo.EachBoxNum)
 | |
| 		//不是最后一个
 | |
| 		if numKey < lenStepNum-1 {
 | |
| 			nextBegin := int64(stepNumSlice[numKey+1]) * (*priceInfo.EachBoxNum)
 | |
| 			end = nextBegin - 1
 | |
| 		} else {
 | |
| 			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)
 | |
| }
 |