京西商城订单
This commit is contained in:
@@ -1,6 +1,7 @@
|
|||||||
package localjx
|
package localjx
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"crypto/md5"
|
||||||
"fmt"
|
"fmt"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@@ -9,6 +10,7 @@ import (
|
|||||||
"git.rosy.net.cn/jx-callback/business/jxutils/jxcontext"
|
"git.rosy.net.cn/jx-callback/business/jxutils/jxcontext"
|
||||||
"git.rosy.net.cn/jx-callback/business/model"
|
"git.rosy.net.cn/jx-callback/business/model"
|
||||||
"git.rosy.net.cn/jx-callback/business/model/dao"
|
"git.rosy.net.cn/jx-callback/business/model/dao"
|
||||||
|
"git.rosy.net.cn/jx-callback/business/partner"
|
||||||
)
|
)
|
||||||
|
|
||||||
type JxSkuInfo struct {
|
type JxSkuInfo struct {
|
||||||
@@ -17,9 +19,13 @@ type JxSkuInfo struct {
|
|||||||
|
|
||||||
Price int64 `json:"price,omitempty"` // 原价
|
Price int64 `json:"price,omitempty"` // 原价
|
||||||
SalePrice int64 `json:"salePrice,omitempty"` // 售卖价
|
SalePrice int64 `json:"salePrice,omitempty"` // 售卖价
|
||||||
|
|
||||||
|
Name string `json:"name"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type JxOrderInfo struct {
|
type JxOrderInfo struct {
|
||||||
|
BuyerComment string
|
||||||
|
StoreID int `json:"storeID"`
|
||||||
Skus []*JxSkuInfo `json:"skus"`
|
Skus []*JxSkuInfo `json:"skus"`
|
||||||
|
|
||||||
ExpectedDeliveredTime *time.Time `orm:"type(datetime)" json:"expectedDeliveredTime"` // 预期送达时间
|
ExpectedDeliveredTime *time.Time `orm:"type(datetime)" json:"expectedDeliveredTime"` // 预期送达时间
|
||||||
@@ -28,12 +34,40 @@ type JxOrderInfo struct {
|
|||||||
FreightPrice int64 `json:"freightPrice"` // 单位为分 订单配送费
|
FreightPrice int64 `json:"freightPrice"` // 单位为分 订单配送费
|
||||||
OrderPrice int64 `json:"orderPrice"` // 单位为分 订单商品价格
|
OrderPrice int64 `json:"orderPrice"` // 单位为分 订单商品价格
|
||||||
ActualPayPrice int64 `json:"actualPayPrice"` // 单位为分 顾客实际支付
|
ActualPayPrice int64 `json:"actualPayPrice"` // 单位为分 顾客实际支付
|
||||||
|
|
||||||
|
OrderID int64 `json:"orderID"`
|
||||||
|
StoreName string `json:"storeName"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func PreCreateOrder(ctx *jxcontext.Context, jxOrder *JxOrderInfo, addressID int64, ExpectedDeliveredTime *time.Time) (outJxOrder *JxOrderInfo, err error) {
|
func PreCreateOrder(ctx *jxcontext.Context, jxOrder *JxOrderInfo, addressID int64) (outJxOrder *JxOrderInfo, err error) {
|
||||||
|
outJxOrder, _, err = generateOrder(ctx, jxOrder, addressID)
|
||||||
return outJxOrder, err
|
return outJxOrder, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func CreateOrder(ctx *jxcontext.Context, jxOrder *JxOrderInfo, addressID int64) (outJxOrder *JxOrderInfo, err error) {
|
||||||
|
outJxOrder, deliveryAddress, err := generateOrder(ctx, jxOrder, addressID)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if outJxOrder.TotalPrice != jxOrder.TotalPrice {
|
||||||
|
return nil, fmt.Errorf("商品或配送信息发生改变,请重新下单")
|
||||||
|
}
|
||||||
|
outJxOrder.OrderID = GenOrderNo()
|
||||||
|
order, err := jxOrder2GoodsOrder(ctx, jxOrder, deliveryAddress)
|
||||||
|
partner.CurOrderManager.OnOrderNew(order, model.Order2Status(order))
|
||||||
|
return outJxOrder, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func GenOrderNo() (orderNo int64) {
|
||||||
|
orderNo = time.Now().Unix()*100000 + 88000000000000000
|
||||||
|
md5Bytes := md5.Sum([]byte(utils.GetUUID()))
|
||||||
|
randPart := 0
|
||||||
|
for k, v := range md5Bytes {
|
||||||
|
randPart += int(v) << ((k % 3) * 8)
|
||||||
|
}
|
||||||
|
return orderNo + int64(randPart%10000)
|
||||||
|
}
|
||||||
|
|
||||||
func formalizeSkus(skus []*JxSkuInfo) (outSkus []*JxSkuInfo) {
|
func formalizeSkus(skus []*JxSkuInfo) (outSkus []*JxSkuInfo) {
|
||||||
skuMap := make(map[int]int)
|
skuMap := make(map[int]int)
|
||||||
for _, v := range skus {
|
for _, v := range skus {
|
||||||
@@ -68,66 +102,134 @@ func isTimeInOpTime(openTime1, closeTime1, openTime2, closeTime2 int16, time2Che
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func generateOrder(ctx *jxcontext.Context, jxOrder *JxOrderInfo, storeID int, addressID int64, ExpectedDeliveredTime *time.Time) (outJxOrder *JxOrderInfo, err error) {
|
func generateOrder(ctx *jxcontext.Context, jxOrder *JxOrderInfo, addressID int64) (outJxOrder *JxOrderInfo, deliveryAddress *dao.UserDeliveryAddressEx, err error) {
|
||||||
db := dao.GetDB()
|
db := dao.GetDB()
|
||||||
|
|
||||||
// 配送范围检查
|
// 配送范围检查
|
||||||
storeDetail, err := dao.GetStoreDetail(db, storeID, model.VendorIDJX)
|
storeDetail, err := dao.GetStoreDetail(db, jxOrder.StoreID, model.VendorIDJX)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
addressList, _, err := dao.QueryUserDeliveryAddress(db, addressID, []string{ctx.GetUserID()}, 0, 0)
|
addressList, _, err := dao.QueryUserDeliveryAddress(db, addressID, []string{ctx.GetUserID()}, 0, 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
if len(addressList) == 0 {
|
if len(addressList) == 0 {
|
||||||
return nil, fmt.Errorf("地址ID不正确")
|
return nil, nil, fmt.Errorf("地址ID不正确")
|
||||||
}
|
}
|
||||||
deliveryAddress := addressList[0]
|
deliveryAddress = addressList[0]
|
||||||
if distance := jxutils.Point2StoreDistance(deliveryAddress.Lng, deliveryAddress.Lat, storeDetail.Lng, storeDetail.Lat, storeDetail.DeliveryRangeType, storeDetail.DeliveryRange); distance == 0 {
|
if distance := jxutils.Point2StoreDistance(deliveryAddress.Lng, deliveryAddress.Lat, storeDetail.Lng, storeDetail.Lat, storeDetail.DeliveryRangeType, storeDetail.DeliveryRange); distance == 0 {
|
||||||
return nil, fmt.Errorf("送货地址:%s不在门店%s的配送范围", deliveryAddress.DetailAddress, storeDetail.Name)
|
return nil, nil, fmt.Errorf("送货地址:%s不在门店%s的配送范围", deliveryAddress.DetailAddress, storeDetail.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 营业状态及时间检查
|
// 营业状态及时间检查
|
||||||
if storeDetail.Status == model.StoreStatusDisabled {
|
if storeDetail.Status == model.StoreStatusDisabled {
|
||||||
return nil, fmt.Errorf("门店:%s状态是:%s", storeDetail.Name, model.StoreStatusName[storeDetail.Status])
|
return nil, nil, fmt.Errorf("门店:%s状态是:%s", storeDetail.Name, model.StoreStatusName[storeDetail.Status])
|
||||||
}
|
}
|
||||||
checkTime := time.Now()
|
checkTime := time.Now()
|
||||||
if ExpectedDeliveredTime == nil {
|
if jxOrder.ExpectedDeliveredTime == nil {
|
||||||
if storeDetail.Status != model.StoreStatusOpened {
|
if storeDetail.Status != model.StoreStatusOpened {
|
||||||
return nil, fmt.Errorf("门店:%s不是营业状态,状态是:%s", storeDetail.Name, model.StoreStatusName[storeDetail.Status])
|
return nil, nil, fmt.Errorf("门店:%s不是营业状态,状态是:%s", storeDetail.Name, model.StoreStatusName[storeDetail.Status])
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
checkTime = *ExpectedDeliveredTime
|
checkTime = *jxOrder.ExpectedDeliveredTime
|
||||||
}
|
}
|
||||||
if !isTimeInOpTime(storeDetail.OpenTime1, storeDetail.CloseTime1, storeDetail.OpenTime2, storeDetail.CloseTime2, checkTime) {
|
if !isTimeInOpTime(storeDetail.OpenTime1, storeDetail.CloseTime1, storeDetail.OpenTime2, storeDetail.CloseTime2, checkTime) {
|
||||||
return nil, fmt.Errorf("门店:%s不在营业时间范围", storeDetail.Name)
|
return nil, nil, fmt.Errorf("门店:%s不在营业时间范围", storeDetail.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
skus := formalizeSkus(jxOrder.Skus)
|
skus := formalizeSkus(jxOrder.Skus)
|
||||||
|
if len(skus) == 0 {
|
||||||
|
return nil, nil, fmt.Errorf("商品列表为空")
|
||||||
|
}
|
||||||
var skuIDs []int
|
var skuIDs []int
|
||||||
for _, v := range skus {
|
for _, v := range skus {
|
||||||
skuIDs = append(skuIDs, v.SkuID)
|
skuIDs = append(skuIDs, v.SkuID)
|
||||||
}
|
}
|
||||||
storeSkuList, err := dao.GetStoresSkusInfo(db, []int{storeID}, skuIDs)
|
storeSkuList, err := dao.GetStoresSkusInfo(db, []int{jxOrder.StoreID}, skuIDs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
storeSkuMap := make(map[int]*model.StoreSkuBind)
|
storeSkuMap := make(map[int]*model.StoreSkuBind)
|
||||||
for _, v := range storeSkuList {
|
for _, v := range storeSkuList {
|
||||||
storeSkuMap[v.SkuID] = v
|
storeSkuMap[v.SkuID] = v
|
||||||
}
|
}
|
||||||
|
|
||||||
outJxOrder = &JxOrderInfo{}
|
skuList, err := dao.GetSkus(db, skuIDs, nil, nil, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
skuMap := make(map[int]*model.SkuAndName)
|
||||||
|
for _, v := range skuList {
|
||||||
|
skuMap[v.ID] = v
|
||||||
|
}
|
||||||
|
|
||||||
|
outJxOrder = &JxOrderInfo{
|
||||||
|
StoreName: storeDetail.Name,
|
||||||
|
}
|
||||||
for _, v := range skus {
|
for _, v := range skus {
|
||||||
|
if storeSkuBind := storeSkuMap[v.SkuID]; storeSkuBind != nil {
|
||||||
|
if sku := skuMap[v.SkuID]; sku != nil {
|
||||||
outJxOrder.Skus = append(outJxOrder.Skus, &JxSkuInfo{
|
outJxOrder.Skus = append(outJxOrder.Skus, &JxSkuInfo{
|
||||||
SkuID: v.SkuID,
|
SkuID: v.SkuID,
|
||||||
Count: v.Count,
|
Count: v.Count,
|
||||||
Price: v.Price,
|
Price: int64(storeSkuBind.JxPrice),
|
||||||
SalePrice: v.SalePrice,
|
SalePrice: int64(storeSkuBind.JxPrice), // todo 考虑活动价
|
||||||
|
Name: jxutils.ComposeSkuName(sku.Prefix, sku.Name, sku.Comment, sku.Unit, sku.SpecQuality, sku.SpecUnit, 0),
|
||||||
})
|
})
|
||||||
outJxOrder.TotalPrice += int64(v.Count) * v.SalePrice
|
outJxOrder.TotalPrice += int64(v.Count) * v.SalePrice
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return outJxOrder, err
|
}
|
||||||
|
return outJxOrder, deliveryAddress, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func jxOrder2GoodsOrder(ctx *jxcontext.Context, jxOrder *JxOrderInfo, deliveryAddress *dao.UserDeliveryAddressEx) (order *model.GoodsOrder, err error) {
|
||||||
|
order = &model.GoodsOrder{
|
||||||
|
VendorOrderID: utils.Int64ToStr(jxOrder.OrderID),
|
||||||
|
VendorID: model.VendorIDJX,
|
||||||
|
VendorStoreID: utils.Int2Str(jxOrder.StoreID),
|
||||||
|
StoreID: jxOrder.StoreID,
|
||||||
|
StoreName: jxOrder.StoreName,
|
||||||
|
UserID: ctx.GetUserID(),
|
||||||
|
|
||||||
|
ConsigneeName: deliveryAddress.ConsigneeName,
|
||||||
|
ConsigneeMobile: deliveryAddress.ConsigneeMobile,
|
||||||
|
ConsigneeMobile2: deliveryAddress.ConsigneeMobile,
|
||||||
|
ConsigneeAddress: deliveryAddress.DetailAddress,
|
||||||
|
CoordinateType: model.CoordinateTypeMars,
|
||||||
|
ConsigneeLng: jxutils.StandardCoordinate2Int(deliveryAddress.Lng),
|
||||||
|
ConsigneeLat: jxutils.StandardCoordinate2Int(deliveryAddress.Lat),
|
||||||
|
|
||||||
|
Status: model.OrderStatusUnknown,
|
||||||
|
VendorStatus: "realnew",
|
||||||
|
OrderSeq: 0,
|
||||||
|
BuyerComment: jxOrder.BuyerComment,
|
||||||
|
|
||||||
|
DeliveryType: model.OrderDeliveryTypeStoreSelf,
|
||||||
|
StatusTime: time.Now(),
|
||||||
|
}
|
||||||
|
order.VendorUserID = order.UserID
|
||||||
|
if jxOrder.ExpectedDeliveredTime != nil {
|
||||||
|
order.ExpectedDeliveredTime = *jxOrder.ExpectedDeliveredTime
|
||||||
|
order.BusinessType = model.BusinessTypeDingshida
|
||||||
|
} else {
|
||||||
|
order.ExpectedDeliveredTime = utils.DefaultTimeValue
|
||||||
|
order.BusinessType = model.BusinessTypeImmediate
|
||||||
|
}
|
||||||
|
for _, sku := range jxOrder.Skus {
|
||||||
|
order.Skus = append(order.Skus, &model.OrderSku{
|
||||||
|
Count: sku.Count,
|
||||||
|
VendorSkuID: utils.Int2Str(sku.SkuID),
|
||||||
|
SkuID: sku.SkuID,
|
||||||
|
SkuName: sku.Name,
|
||||||
|
VendorPrice: sku.Price,
|
||||||
|
SalePrice: sku.SalePrice,
|
||||||
|
})
|
||||||
|
order.TotalShopMoney += int64(sku.Count) * sku.SalePrice
|
||||||
|
}
|
||||||
|
order.TotalShopMoney += jxOrder.FreightPrice
|
||||||
|
order.ActualPayPrice = order.TotalShopMoney
|
||||||
|
|
||||||
|
return order, err
|
||||||
}
|
}
|
||||||
|
|||||||
8
business/partner/purchase/jx/localjx/order_test.go
Normal file
8
business/partner/purchase/jx/localjx/order_test.go
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
package localjx
|
||||||
|
|
||||||
|
import "testing"
|
||||||
|
|
||||||
|
func TestSyncStoreSkus(t *testing.T) {
|
||||||
|
orderNo := GenOrderNo()
|
||||||
|
t.Log(orderNo)
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user