|
|
|
@ -2,28 +2,23 @@ package order
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"fmt"
|
|
|
|
|
"github.com/gin-gonic/gin"
|
|
|
|
|
"github.com/jinzhu/gorm"
|
|
|
|
|
"github.com/shopspring/decimal"
|
|
|
|
|
"log"
|
|
|
|
|
order_preview2 "recook/internal/api/mobile/order_preview"
|
|
|
|
|
"recook/internal/back"
|
|
|
|
|
"recook/internal/dbc"
|
|
|
|
|
"recook/internal/model/coupon"
|
|
|
|
|
"recook/internal/libs/snow"
|
|
|
|
|
"recook/internal/model/goods"
|
|
|
|
|
"recook/internal/model/order"
|
|
|
|
|
"recook/internal/model/order_preview"
|
|
|
|
|
"recook/internal/model/promotion"
|
|
|
|
|
"recook/internal/model/shopping_trolley"
|
|
|
|
|
"recook/internal/model/user"
|
|
|
|
|
"recook/internal/v2/controller/task"
|
|
|
|
|
"recook/internal/v2/lib/jcook"
|
|
|
|
|
goods3 "recook/internal/v2/model/recook/goods"
|
|
|
|
|
"recook/tools"
|
|
|
|
|
"strconv"
|
|
|
|
|
"sync"
|
|
|
|
|
"time"
|
|
|
|
|
|
|
|
|
|
"github.com/gin-gonic/gin"
|
|
|
|
|
"github.com/jinzhu/gorm"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
/*创建普通订单的参数*/
|
|
|
|
@ -32,20 +27,8 @@ type submitOrderParam struct {
|
|
|
|
|
PreviewOrderID uint `json:"previewOrderId"`
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var submitOrderSentinel sync.Mutex
|
|
|
|
|
//var submitOrderSentinel sync.Mutex
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
提交订单 用户在订单预览界面时,完全不提交,10分钟再提交。此时判断活动,地址 商品信息,库存等是否发生了变化,变化了则提交失败,需要重新购买
|
|
|
|
|
|
|
|
|
|
生成订单记录
|
|
|
|
|
删除预览订单信息
|
|
|
|
|
如果是购物车下单 删除购物车商品
|
|
|
|
|
|
|
|
|
|
减去库存/活动库存 销量增加
|
|
|
|
|
|
|
|
|
|
标记自己的优惠券状态为使用过
|
|
|
|
|
扣除瑞币
|
|
|
|
|
*/
|
|
|
|
|
func SubmitOrder(c *gin.Context) {
|
|
|
|
|
var p submitOrderParam
|
|
|
|
|
err := tools.ParseParams(&p, c)
|
|
|
|
@ -54,12 +37,6 @@ func SubmitOrder(c *gin.Context) {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
submitOrderSentinel.Lock()
|
|
|
|
|
defer submitOrderSentinel.Unlock()
|
|
|
|
|
|
|
|
|
|
// 验证库存 验证优惠券是否失效 验证活动 验证金额是否匹配
|
|
|
|
|
now := time.Now().Unix()
|
|
|
|
|
|
|
|
|
|
var previewOrderInfo order_preview.Information
|
|
|
|
|
if err = dbc.DB.First(&previewOrderInfo, "id = ?", p.PreviewOrderID).Error; err != nil {
|
|
|
|
|
back.Err(c, err.Error())
|
|
|
|
@ -83,47 +60,6 @@ func SubmitOrder(c *gin.Context) {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 钱包的瑞币是否足够支付
|
|
|
|
|
var wallet user.Wallet
|
|
|
|
|
{
|
|
|
|
|
if err = dbc.DB.First(&wallet, "user_id = ?", p.UserID).Error; err != nil {
|
|
|
|
|
back.Err(c, err.Error())
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
if wallet.Coin.LessThan(previewOrderInfo.CoinTotalAmount) {
|
|
|
|
|
back.Fail(c, "瑞币不足,请重新购买")
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 优惠券是否可用
|
|
|
|
|
var preOrderCouponList []order_preview.CouponDetail
|
|
|
|
|
if err = dbc.DB.Find(&preOrderCouponList, "order_id = ?", p.PreviewOrderID).Error; err != nil && false == gorm.IsRecordNotFoundError(err) {
|
|
|
|
|
back.Err(c, err.Error())
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
personalCouponMidList := make([]*coupon.ReceiverMid, 0, 0)
|
|
|
|
|
for _, v := range preOrderCouponList {
|
|
|
|
|
var couponMid coupon.ReceiverMid
|
|
|
|
|
if err = dbc.DB.First(&couponMid, "id = ?", v.PersonalCouponID).Error; err != nil {
|
|
|
|
|
back.Err(c, err.Error())
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if couponMid.Status == 1 {
|
|
|
|
|
back.Fail(c, "优惠券已在其他订单使用,请重新下单")
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if couponMid.EndTime.Time.Unix() < now {
|
|
|
|
|
back.Fail(c, "优惠券已过期,请重新下单")
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
personalCouponMidList = append(personalCouponMidList, &couponMid)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var preOrderGoodsList []order_preview.GoodsDetail
|
|
|
|
|
if err = dbc.DB.Find(&preOrderGoodsList, "order_id = ?", p.PreviewOrderID).Error; err != nil {
|
|
|
|
|
back.Err(c, err.Error())
|
|
|
|
@ -149,17 +85,6 @@ func SubmitOrder(c *gin.Context) {
|
|
|
|
|
back.Err(c, err.Error())
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
if goodsInfo.ThirdPartyType == goods3.RecookGoodsInfoThirdPartyTypeJingtong {
|
|
|
|
|
jingtong := &task.Jingtong{}
|
|
|
|
|
if err := jingtong.Update(goodsInfo.ThirdPartyId); err != nil {
|
|
|
|
|
back.Err(c, err.Error())
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
if err = dbc.DB.Select("hash, publish_status,third_party_id,third_party_type").First(&goodsInfo, "id = ?", v.GoodsID).Error; err != nil {
|
|
|
|
|
back.Err(c, err.Error())
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if goodsInfo.Hash != v.Hash {
|
|
|
|
|
back.Fail(c, "商品信息已经发生变化,请重新下单")
|
|
|
|
@ -217,31 +142,30 @@ func SubmitOrder(c *gin.Context) {
|
|
|
|
|
|
|
|
|
|
data := make(map[uint][]order_preview.GoodsDetail)
|
|
|
|
|
fData := make(map[uint]decimal.Decimal)
|
|
|
|
|
var lastId uint
|
|
|
|
|
virtualID := GetVirtualID()
|
|
|
|
|
tx := dbc.DB.Begin()
|
|
|
|
|
{
|
|
|
|
|
sql := `select max(id)+floor(1+rand()*50) from recook_order_info`
|
|
|
|
|
if err = tx.Raw(sql).Count(&lastId).Error; err != nil {
|
|
|
|
|
back.Err(c, err.Error())
|
|
|
|
|
tx.Rollback()
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for _, value := range preOrderGoodsList {
|
|
|
|
|
data[value.VendorID] = append(data[value.VendorID], value)
|
|
|
|
|
fData[value.VendorID] = fData[value.VendorID].Add(value.ExpressFee)
|
|
|
|
|
}
|
|
|
|
|
work := snow.GetOrderWorker()
|
|
|
|
|
orderID, err := work.NextID()
|
|
|
|
|
if err != nil {
|
|
|
|
|
back.Err(c, err.Error())
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
condition := len(data) == 1
|
|
|
|
|
orderInfo.ID = lastId
|
|
|
|
|
var count uint = 0
|
|
|
|
|
orderInfo.ID = uint(orderID)
|
|
|
|
|
for vendor, value := range data {
|
|
|
|
|
//if vendor == 1800 || vendor== 2000 {
|
|
|
|
|
// continue
|
|
|
|
|
//}
|
|
|
|
|
id1, err := work.NextID()
|
|
|
|
|
if err != nil {
|
|
|
|
|
back.Err(c, err.Error())
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
orderCopy := order.Information{
|
|
|
|
|
ID: lastId + count,
|
|
|
|
|
ID: uint(id1),
|
|
|
|
|
AncestorID: orderInfo.AncestorID,
|
|
|
|
|
ParentID: orderInfo.ParentID,
|
|
|
|
|
SharerID: orderInfo.SharerID,
|
|
|
|
@ -276,7 +200,7 @@ func SubmitOrder(c *gin.Context) {
|
|
|
|
|
}
|
|
|
|
|
kind := 0
|
|
|
|
|
if vendor == 1800 || vendor == 2000 {
|
|
|
|
|
channelOrderID := strconv.Itoa(int(lastId + count))
|
|
|
|
|
channelOrderID := strconv.Itoa(int(orderCopy.ID))
|
|
|
|
|
resp, err := JdOrderSubmit(tx, c.ClientIP(), data, vendor, previewOrderAddr, fData, channelOrderID)
|
|
|
|
|
if err != nil {
|
|
|
|
|
log.Println("订单生成失败:", err.Error())
|
|
|
|
@ -296,7 +220,6 @@ func SubmitOrder(c *gin.Context) {
|
|
|
|
|
if condition {
|
|
|
|
|
orderCopy.VirtualID = orderCopy.ID
|
|
|
|
|
}
|
|
|
|
|
count += 1
|
|
|
|
|
for _, v := range value {
|
|
|
|
|
orderCopy.BrandCouponTotalAmount = orderCopy.BrandCouponTotalAmount.Add(v.BrandCouponAmount)
|
|
|
|
|
orderCopy.UniverseCouponTotalAmount = orderCopy.UniverseCouponTotalAmount.Add(v.UniverseCouponAmount)
|
|
|
|
@ -319,39 +242,9 @@ func SubmitOrder(c *gin.Context) {
|
|
|
|
|
tx.Rollback()
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
//判断是否为秒杀商品
|
|
|
|
|
smp := make(map[uint]uint)
|
|
|
|
|
now1 := previewOrderInfo.CreatedAt.Time
|
|
|
|
|
for _, v := range preOrderGoodsList {
|
|
|
|
|
res, _ := order_preview2.IfSecKill(now1, v.SkuID)
|
|
|
|
|
if res.Id > 0 {
|
|
|
|
|
//秒杀中
|
|
|
|
|
num := res.RealStock.Sub(decimal.NewFromInt(int64(v.Quantity)))
|
|
|
|
|
if num.LessThan(decimal.Zero) {
|
|
|
|
|
back.Err(c, "库存不足")
|
|
|
|
|
tx.Rollback()
|
|
|
|
|
return
|
|
|
|
|
} else {
|
|
|
|
|
//库存更新
|
|
|
|
|
err = tx.Table(res.TableName()).Where("id=?", res.Id).Update("real_stock", num).Error
|
|
|
|
|
if err != nil {
|
|
|
|
|
back.Err(c, err.Error())
|
|
|
|
|
tx.Rollback()
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
smp[v.SkuID] = res.SecKillActivityId
|
|
|
|
|
} else {
|
|
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for _, v := range value {
|
|
|
|
|
goodsDetail := (&order.GoodsDetail{}).Reflect(&v, &orderCopy)
|
|
|
|
|
if _, ok := smp[v.SkuID]; ok {
|
|
|
|
|
goodsDetail.ActivityStatus = 1
|
|
|
|
|
goodsDetail.ActivityId = smp[v.SkuID]
|
|
|
|
|
}
|
|
|
|
|
if err = tx.Create(goodsDetail).Error; err != nil {
|
|
|
|
|
back.Err(c, err.Error())
|
|
|
|
|
tx.Rollback()
|
|
|
|
@ -371,45 +264,6 @@ func SubmitOrder(c *gin.Context) {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if orderCopy.CoinTotalAmount.GreaterThan(decimal.NewFromFloat(0.0)) {
|
|
|
|
|
// 标记瑞币, 即扣除了总额
|
|
|
|
|
if err = tx.Model(&wallet).Updates(map[string]interface{}{
|
|
|
|
|
"coin": wallet.Coin.Sub(orderCopy.CoinTotalAmount),
|
|
|
|
|
}).Error; err != nil {
|
|
|
|
|
back.Err(c, err.Error())
|
|
|
|
|
tx.Rollback()
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 加入流水记录, 直接加在coinHistory中
|
|
|
|
|
var uCoinHis user.CoinHistory
|
|
|
|
|
uCoinHis.UserID = p.UserID
|
|
|
|
|
uCoinHis.CoinNum = orderCopy.CoinTotalAmount.Neg()
|
|
|
|
|
uCoinHis.CoinType = user.PurchasedTypeForCoinHistory
|
|
|
|
|
uCoinHis.OrderId = orderCopy.ID
|
|
|
|
|
uCoinHis.CreatedAt = orderCopy.CreatedAt
|
|
|
|
|
uCoinHis.Remark = "订单扣除"
|
|
|
|
|
|
|
|
|
|
if err := dbc.DB.Create(&uCoinHis).Error; err != nil {
|
|
|
|
|
back.Err(c, err.Error())
|
|
|
|
|
tx.Rollback()
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
walletCoinDetail := user.WalletCoinList{
|
|
|
|
|
UserID: wallet.UserID,
|
|
|
|
|
Number: int64(orderCopy.CoinTotalAmount.IntPart()),
|
|
|
|
|
Title: orderCopy.Title,
|
|
|
|
|
Comment: "订单支付抵扣",
|
|
|
|
|
OrderID: orderCopy.ID,
|
|
|
|
|
}
|
|
|
|
|
if err = tx.Create(&walletCoinDetail).Error; err != nil {
|
|
|
|
|
back.Err(c, err.Error())
|
|
|
|
|
tx.Rollback()
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 如果是购物车下单 则要清除一下购物车
|
|
|
|
@ -468,14 +322,7 @@ func JdOrderSubmit(tx *gorm.DB, ip string, data map[uint][]order_preview.GoodsDe
|
|
|
|
|
return resp, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const initCount int64 = 20210624681
|
|
|
|
|
|
|
|
|
|
func GetVirtualID() uint {
|
|
|
|
|
result := dbc.Rds.Incr("order_count")
|
|
|
|
|
if r, err := result.Result(); err != nil {
|
|
|
|
|
log.Println(err.Error())
|
|
|
|
|
return uint(time.Now().Unix()) * 10
|
|
|
|
|
} else {
|
|
|
|
|
return uint(r + initCount)
|
|
|
|
|
}
|
|
|
|
|
id, _ := snow.GetOrderWorker().NextID()
|
|
|
|
|
return uint(id)
|
|
|
|
|
}
|
|
|
|
|