fusenapi/server/product/internal/logic/calculateproductpricelogic.go
laodaming 9bdaa75514 fix
2023-10-27 15:31:23 +08:00

126 lines
4.7 KiB
Go

package logic
import (
"encoding/json"
"errors"
"fmt"
"fusenapi/constants"
"fusenapi/model/gmodel"
"fusenapi/utils/auth"
"fusenapi/utils/basic"
"fusenapi/utils/format"
"gorm.io/gorm"
"context"
"fusenapi/server/product/internal/svc"
"fusenapi/server/product/internal/types"
"github.com/zeromicro/go-zero/core/logx"
)
type CalculateProductPriceLogic struct {
logx.Logger
ctx context.Context
svcCtx *svc.ServiceContext
}
func NewCalculateProductPriceLogic(ctx context.Context, svcCtx *svc.ServiceContext) *CalculateProductPriceLogic {
return &CalculateProductPriceLogic{
Logger: logx.WithContext(ctx),
ctx: ctx,
svcCtx: svcCtx,
}
}
// 处理进入前逻辑w,r
// func (l *CalculateProductPriceLogic) BeforeLogic(w http.ResponseWriter, r *http.Request) {
// }
func (l *CalculateProductPriceLogic) CalculateProductPrice(req *types.CalculateProductPriceReq, userinfo *auth.UserInfo) (resp *basic.Response) {
if req.ProductId <= 0 {
return resp.SetStatusWithMessage(basic.CodeRequestParamsErr, "err param:product id")
}
if req.SizeId <= 0 {
return resp.SetStatusWithMessage(basic.CodeRequestParamsErr, "err param:size id")
}
if req.PurchaseQuantity <= 0 {
return resp.SetStatusWithMessage(basic.CodeRequestParamsErr, "err param:purchase quantity")
}
//获取产品信息(只是获取id)
_, err := l.svcCtx.AllModels.FsProduct.FindOne(l.ctx, req.ProductId, "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")
}
//根据产品跟尺寸获取模型价格信息
modelInfo, err := l.svcCtx.AllModels.FsProductModel3d.FindOneByProductIdSizeIdTag(l.ctx, req.ProductId, req.SizeId, constants.TAG_MODEL, "id,step_price")
if err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return resp.SetStatusWithMessage(basic.CodeDbRecordNotFoundErr, "model info is not exists")
}
return resp.SetStatusWithMessage(basic.CodeDbSqlErr, "failed to get model info")
}
var stepPrice gmodel.StepPriceJsonStruct
if modelInfo.StepPrice != nil && len(*modelInfo.StepPrice) != 0 {
if err = json.Unmarshal(*modelInfo.StepPrice, &stepPrice); err != nil {
logx.Error(err)
return resp.SetStatusWithMessage(basic.CodeJsonErr, "failed to parse step price")
}
}
//配件
fittingPrice := int64(0)
if req.FittingId > 0 {
fittingInfo, err := l.svcCtx.AllModels.FsProductModel3d.FindOne(l.ctx, req.FittingId, "id,price")
if err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return resp.SetStatusWithMessage(basic.CodeDbRecordNotFoundErr, "fitting info is not exists")
}
logx.Error(err)
return resp.SetStatusWithMessage(basic.CodeDbSqlErr, "failed to get fitting info")
}
fittingPrice = *fittingInfo.Price
}
rangeLen := len(stepPrice.PriceRange)
stepRange := make([]interface{}, 0, rangeLen)
for rIndex, rangeInfo := range stepPrice.PriceRange {
//最后一个
if rIndex+1 == rangeLen {
begin := format.NumToStringWithThousandthPercentile(fmt.Sprintf("%d", rangeInfo.StartQuantity))
stepRange = append(stepRange, map[string]interface{}{
"start": rangeInfo.StartQuantity,
"end": rangeInfo.EndQuantity,
"range_description": fmt.Sprintf(">=%s Units", begin),
"item_price": format.CentitoDollar(rangeInfo.Price+fittingPrice, 3),
})
break
}
begin := format.NumToStringWithThousandthPercentile(fmt.Sprintf("%d", rangeInfo.StartQuantity))
end := format.NumToStringWithThousandthPercentile(fmt.Sprintf("%d", rangeInfo.EndQuantity))
stepRange = append(stepRange, map[string]interface{}{
"start": rangeInfo.StartQuantity,
"end": rangeInfo.EndQuantity,
"range_description": fmt.Sprintf("%s-%s Units", begin, end),
"item_price": format.CentitoDollar(rangeInfo.Price+fittingPrice, 3),
})
}
totalPrice, itemPrice, err := l.svcCtx.Repositories.NewShoppingCart.CaculateStepPrice(req.PurchaseQuantity, stepPrice, fittingPrice)
if err != nil {
logx.Error(err)
return resp.SetStatusWithMessage(basic.CodeServiceErr, "failed to calculate product price ")
}
return resp.SetStatusWithMessage(basic.CodeOK, "success", types.CalculateProductPriceRsp{
ItemPrice: format.NumToStringWithThousandthPercentile(format.CentitoDollar(itemPrice, 3)),
TotalPrice: format.NumToStringWithThousandthPercentile(format.CentitoDollarWithNoHalfAdjust(totalPrice, 2)),
StepRange: stepRange,
})
}
// 处理逻辑后 w,r 如:重定向, resp 必须重新处理
// func (l *CalculateProductPriceLogic) AfterLogic(w http.ResponseWriter, r *http.Request, resp *basic.Response) {
// // httpx.OkJsonCtx(r.Context(), w, resp)
// }