2023-09-15 10:19:01 +00:00
package logic
import (
"context"
"fmt"
2023-09-18 04:31:51 +00:00
"fusenapi/constants"
2023-09-15 10:19:01 +00:00
"fusenapi/model/gmodel"
"fusenapi/utils/auth"
"fusenapi/utils/basic"
2023-09-18 04:31:51 +00:00
"fusenapi/utils/format"
"fusenapi/utils/step_price"
"math"
"strings"
2023-09-15 10:19:01 +00:00
"fusenapi/server/shopping-cart/internal/svc"
"fusenapi/server/shopping-cart/internal/types"
"github.com/zeromicro/go-zero/core/logx"
)
type CalculateCartPriceLogic struct {
logx . Logger
ctx context . Context
svcCtx * svc . ServiceContext
}
func NewCalculateCartPriceLogic ( ctx context . Context , svcCtx * svc . ServiceContext ) * CalculateCartPriceLogic {
return & CalculateCartPriceLogic {
Logger : logx . WithContext ( ctx ) ,
ctx : ctx ,
svcCtx : svcCtx ,
}
}
// 处理进入前逻辑w,r
// func (l *CalculateCartPriceLogic) BeforeLogic(w http.ResponseWriter, r *http.Request) {
// }
func ( l * CalculateCartPriceLogic ) CalculateCartPrice ( req * types . CalculateCartPriceReq , userinfo * auth . UserInfo ) ( resp * basic . Response ) {
if ! userinfo . IsUser ( ) {
return resp . SetStatusWithMessage ( basic . CodeUnAuth , "please sign in" )
}
if len ( req . CalculateList ) == 0 {
return resp . SetStatusWithMessage ( basic . CodeOK , "success" , types . CalculateCartPriceRsp { CalculateResultList : [ ] types . CalculateResultItem { } } )
}
cartIds := make ( [ ] int64 , 0 , len ( req . CalculateList ) )
2023-09-18 04:31:51 +00:00
mapCalculateQuantity := make ( map [ int64 ] int64 )
2023-09-15 10:19:01 +00:00
for _ , v := range req . CalculateList {
cartIds = append ( cartIds , v . CartId )
2023-09-18 04:31:51 +00:00
if v . PurchaseQuantity <= 0 {
return resp . SetStatusWithMessage ( basic . CodeRequestParamsErr , "purchase quantity must grater than 0" )
}
mapCalculateQuantity [ v . CartId ] = v . PurchaseQuantity
2023-09-15 10:19:01 +00:00
}
//获取购物车列表
carts , _ , err := l . svcCtx . AllModels . FsShoppingCart . GetAllCartsByParam ( l . ctx , gmodel . GetAllCartsByParamReq {
Ids : cartIds ,
2023-09-18 04:31:51 +00:00
Fields : "id,size_id,product_id,fitting_id" ,
2023-09-15 10:19:01 +00:00
UserId : userinfo . UserId ,
Page : 1 ,
Limit : len ( cartIds ) ,
} )
if err != nil {
logx . Error ( err )
return resp . SetStatusWithMessage ( basic . CodeDbSqlErr , "failed to get cart list" )
}
2023-09-18 04:31:51 +00:00
if len ( carts ) < len ( req . CalculateList ) {
return resp . SetStatusWithMessage ( basic . CodeRequestParamsErr , "please refresh page for the shopping cart has changed!!" )
}
2023-09-15 10:19:01 +00:00
sizeIds := make ( [ ] int64 , 0 , len ( carts ) )
productIds := make ( [ ] int64 , 0 , len ( carts ) )
fittingIds := make ( [ ] int64 , 0 , len ( carts ) )
for _ , v := range carts {
sizeIds = append ( sizeIds , * v . SizeId )
productIds = append ( productIds , * v . ProductId )
if * v . FittingId > 0 {
fittingIds = append ( fittingIds , * v . FittingId )
}
}
//根据sizeid获取价格列表
priceList , err := l . svcCtx . AllModels . FsProductPrice . GetPriceListByProductIdsSizeIds ( l . ctx , productIds , sizeIds )
if err != nil {
logx . Error ( err )
return resp . SetStatusWithMessage ( basic . CodeDbSqlErr , "failed to get price list" )
}
2023-09-18 04:31:51 +00:00
mapPrice := make ( map [ string ] gmodel . FsProductPrice )
for _ , v := range priceList {
mapPrice [ fmt . Sprintf ( "%d_%d" , * v . ProductId , * v . SizeId ) ] = v
2023-09-15 10:19:01 +00:00
}
2023-09-18 04:31:51 +00:00
//获取配件列表(只有id跟价格)
fittingList , err := l . svcCtx . AllModels . FsProductModel3d . GetAllByIdsTag ( l . ctx , fittingIds , constants . TAG_PARTS , "id,price" )
if err != nil {
logx . Error ( err )
return resp . SetStatusWithMessage ( basic . CodeDbSqlErr , "failed to get fitting list" )
}
mapFitting := make ( map [ int64 ] int64 )
for _ , v := range fittingList {
mapFitting [ v . Id ] = * v . Price
}
//开始计算价格
calculateResultList := make ( [ ] types . CalculateResultItem , 0 , len ( req . CalculateList ) )
2023-09-18 07:18:55 +00:00
subTotalPrice := int64 ( 0 )
2023-09-18 04:31:51 +00:00
for _ , cart := range carts {
sizePrice , ok := mapPrice [ fmt . Sprintf ( "%d_%d" , * cart . ProductId , * cart . SizeId ) ]
if ! ok {
return resp . SetStatusWithMessage ( basic . CodeRequestParamsErr , fmt . Sprintf ( "there carts contain some one which have no price info:%d_%d" , * cart . ProductId , * cart . SizeId ) )
}
//阶梯数量切片
stepNum , err := format . StrSlicToIntSlice ( strings . Split ( * sizePrice . StepNum , "," ) )
if err != nil {
logx . Error ( err )
return resp . SetStatusWithMessage ( basic . CodeServiceErr , fmt . Sprintf ( "failed to parse step number:%d_%d" , * cart . ProductId , * cart . SizeId ) )
}
lenStepNum := len ( stepNum )
//阶梯价格切片
stepPrice , err := format . StrSlicToIntSlice ( strings . Split ( * sizePrice . StepPrice , "," ) )
if err != nil {
logx . Error ( err )
return resp . SetStatusWithMessage ( basic . CodeServiceErr , fmt . Sprintf ( "failed to parse step price:%d_%d" , * cart . ProductId , * cart . SizeId ) )
}
lenStepPrice := len ( stepPrice )
if lenStepPrice == 0 || lenStepNum == 0 {
return resp . SetStatusWithMessage ( basic . CodeServiceErr , fmt . Sprintf ( "step price or step number is not set:%d_%d" , * cart . ProductId , * cart . SizeId ) )
}
//购买箱数
boxQuantity := int ( math . Ceil ( float64 ( mapCalculateQuantity [ cart . Id ] ) / float64 ( * sizePrice . EachBoxNum ) ) )
//根据数量获取阶梯价格中对应的价格
itemPrice := step_price . GetCentStepPrice ( boxQuantity , stepNum , stepPrice )
//如果有配件,单价也要加入配件价格
if * cart . FittingId > 0 {
if fittingPrice , ok := mapFitting [ * cart . FittingId ] ; ok {
itemPrice += fittingPrice
2023-09-18 06:53:15 +00:00
} else {
return resp . SetStatusWithMessage ( basic . CodeRequestParamsErr , "cart contain some one witch lose fitting:%d" , * cart . FittingId )
2023-09-18 04:31:51 +00:00
}
}
//单个购物车总价
totalPrice := itemPrice * mapCalculateQuantity [ cart . Id ]
calculateResultList = append ( calculateResultList , types . CalculateResultItem {
CartId : cart . Id ,
ItemPrice : fmt . Sprintf ( "%.3f" , format . CentitoDollar ( itemPrice ) ) ,
TotalPrice : fmt . Sprintf ( "%.3f" , format . CentitoDollar ( totalPrice ) ) ,
} )
2023-09-18 07:18:55 +00:00
subTotalPrice += totalPrice
2023-09-18 04:31:51 +00:00
}
return resp . SetStatusWithMessage ( basic . CodeOK , "success" , types . CalculateCartPriceRsp {
2023-09-18 07:18:55 +00:00
SubTotalPrice : fmt . Sprintf ( "%.3f" , format . CentitoDollar ( subTotalPrice ) ) ,
2023-09-18 04:31:51 +00:00
CalculateResultList : calculateResultList ,
} )
2023-09-15 10:19:01 +00:00
}
// 处理逻辑后 w,r 如:重定向, resp 必须重新处理
// func (l *CalculateCartPriceLogic) AfterLogic(w http.ResponseWriter, r *http.Request, resp *basic.Response) {
// // httpx.OkJsonCtx(r.Context(), w, resp)
// }