191 lines
6.0 KiB
Go
191 lines
6.0 KiB
Go
package logic
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"fusenapi/model/gmodel"
|
|
"fusenapi/utils/auth"
|
|
"fusenapi/utils/basic"
|
|
"fusenapi/utils/format"
|
|
"fusenapi/utils/id_generator"
|
|
"fusenapi/utils/step_price"
|
|
"gorm.io/gorm"
|
|
"math"
|
|
"strings"
|
|
"time"
|
|
|
|
"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().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 errors.New(fmt.Sprintf("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,
|
|
})
|
|
}
|