fusenapi/server/shopping-cart-confirmation/internal/logic/createorderlogic.go
2023-08-28 14:21:06 +08:00

191 lines
6.0 KiB
Go

package logic
import (
"fmt"
"fusenapi/model/gmodel"
"fusenapi/utils/auth"
"fusenapi/utils/basic"
"fusenapi/utils/format"
"fusenapi/utils/id_generator"
"fusenapi/utils/step_price"
"math"
"strings"
"time"
"gorm.io/gorm"
"context"
"fusenapi/server/shopping-cart-confirmation/internal/svc"
"fusenapi/server/shopping-cart-confirmation/internal/types"
"github.com/zeromicro/go-zero/core/logx"
)
type CreateOrderLogic struct {
logx.Logger
ctx context.Context
svcCtx *svc.ServiceContext
}
func NewCreateOrderLogic(ctx context.Context, svcCtx *svc.ServiceContext) *CreateOrderLogic {
return &CreateOrderLogic{
Logger: logx.WithContext(ctx),
ctx: ctx,
svcCtx: svcCtx,
}
}
func (l *CreateOrderLogic) CreateOrder(req *types.CreateOrderReq, userinfo *auth.UserInfo) (resp *basic.Response) {
if userinfo.GetIdType() != auth.IDTYPE_User {
return resp.SetStatusWithMessage(basic.CodeUnAuth, "please login first")
}
if len(req.Form) == 0 {
return resp.SetStatusWithMessage(basic.CodeRequestParamsErr, "err param form:can`t be empty")
}
cartIds := make([]int64, 0, len(req.Form))
mapForm := make(map[int64]int)
for k, v := range req.Form {
cartIds = append(cartIds, v.Id)
mapForm[v.Id] = k
}
//获取购物车列表
cartList, err := l.svcCtx.AllModels.FsCart.GetUserCartsByIds(l.ctx, userinfo.UserId, cartIds)
if err != nil {
logx.Error(err)
return resp.SetStatusWithMessage(basic.CodeDbSqlErr, "failed to get cart list")
}
if len(cartList) != len(req.Form) {
return resp.SetStatusWithMessage(basic.CodeRequestParamsErr, "sorry,may be some one not belong to you")
}
priceIds := make([]int64, 0, len(cartList))
optionalIds := make([]int64, 0, len(cartList))
for _, v := range cartList {
priceIds = append(priceIds, *v.PriceId)
optionalIds = append(optionalIds, *v.OptionalId)
}
//获取价格
priceList, err := l.svcCtx.AllModels.FsProductPrice.GetAllByIdsWithoutStatus(l.ctx, priceIds)
if err != nil {
logx.Error(err)
return resp.SetStatusWithMessage(basic.CodeDbSqlErr, "failed to get product price list")
}
mapPrice := make(map[int64]int)
for k, v := range priceList {
mapPrice[v.Id] = k
}
//获取附加项
model3dList, err := l.svcCtx.AllModels.FsProductModel3d.GetAllByIdsWithoutStatus(l.ctx, optionalIds)
if err != nil {
logx.Error(err)
return resp.SetStatusWithMessage(basic.CodeDbSqlErr, "failed to get 3d model list")
}
mapModel3d := make(map[int64]int)
for k, v := range model3dList {
mapModel3d[v.Id] = k
}
var (
now = time.Now().UTC().Unix()
total int64 //总价
)
orderSn := id_generator.GenSnNum()
//开启事务
err = l.svcCtx.MysqlConn.Transaction(func(tx *gorm.DB) error {
orderDetailTemplateModel := gmodel.NewFsOrderDetailTemplateModel(tx)
orderDetailModel := gmodel.NewFsOrderDetailModel(tx)
orderModel := gmodel.NewFsOrderModel(tx)
//订单数据
deliveryMethod := int64(1)
orderCreateData := gmodel.FsOrder{
Sn: &orderSn,
UserId: &userinfo.UserId,
Ctime: &now,
Utime: &now,
DeliveryMethod: &deliveryMethod,
}
if err = orderModel.Create(l.ctx, &orderCreateData); err != nil {
return err
}
for _, cart := range cartList {
priceIndex, ok := mapPrice[*cart.PriceId]
if !ok {
return fmt.Errorf("price info is not exists,id = %d", *cart.PriceId)
}
//订单详情模板数据
orderDetailTemplateSn, err := id_generator.GenSnowFlakeId()
if err != nil {
return err
}
orderDetailTemplateCreateData := gmodel.FsOrderDetailTemplate{
Sn: &orderDetailTemplateSn,
ProductId: cart.ProductId,
ModelId: cart.OptionalId,
TemplateId: cart.TemplateId,
MaterialId: cart.MaterialId,
SizeId: cart.SizeId,
EachBoxNum: priceList[priceIndex].EachBoxNum,
EachBoxWeight: priceList[priceIndex].EachBoxWeight,
DesignId: cart.DesignId,
Ctime: &now,
}
if err = orderDetailTemplateModel.Create(l.ctx, &orderDetailTemplateCreateData); err != nil {
return err
}
//获取阶梯价格和数量
stepNumSlice, err := format.StrSlicToIntSlice(strings.Split(*priceList[priceIndex].StepNum, ","))
if err != nil {
return err
}
stepPriceSlice, err := format.StrSlicToIntSlice(strings.Split(*priceList[priceIndex].StepPrice, ","))
if err != nil {
return err
}
formIndex, _ := mapForm[cart.Id] //一定会有不用判断
//订单详情数据
orderDetailSn, err := id_generator.GenSnowFlakeId()
if err != nil {
return err
}
optionalPrice := int64(0)
optionalTitle := ""
if model3dIndex, ok := mapModel3d[*cart.OptionalId]; ok {
optionalPrice = *model3dList[model3dIndex].Price
optionalTitle = *model3dList[model3dIndex].Title
}
fn := int(math.Ceil(float64(req.Form[formIndex].Num) / float64(*priceList[priceIndex].EachBoxNum)))
amount := step_price.GetCentStepPrice(fn, stepNumSlice, stepPriceSlice)
orderDetailCreateData := gmodel.FsOrderDetail{
OrderId: &orderCreateData.Id,
Sn: &orderDetailSn,
UserId: &userinfo.UserId,
OrderDetailTemplateId: &orderDetailTemplateCreateData.Id,
ProductId: cart.ProductId,
BuyNum: &req.Form[formIndex].Num, //以提交数量为准
Amount: &amount,
Cover: cart.Cover,
Ctime: &now,
OptionalId: cart.OptionalId,
OptionalTitle: &optionalTitle,
OptionPrice: &optionalPrice,
CartId: &cart.Id,
}
if err = orderDetailModel.Create(l.ctx, &orderDetailCreateData); err != nil {
return err
}
total += amount * (*orderDetailCreateData.BuyNum)
}
//更新订单总价
return orderModel.Update(l.ctx, &gmodel.FsOrder{
Id: orderCreateData.Id,
TotalAmount: &total,
})
})
if err != nil {
logx.Error(err)
return resp.SetStatusWithMessage(basic.CodeServiceErr, "failed to create order")
}
return resp.SetStatusWithMessage(basic.CodeOK, "success", types.CreateOrderRsp{
Sn: orderSn,
})
}