Files
jx-callback/business/partner/purchase/jdshop/callback.go
邹宗楠 82d3eb2289 1
2022-10-27 14:13:26 +08:00

485 lines
17 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package jdshop
import (
"bytes"
"encoding/base64"
"encoding/hex"
"encoding/json"
"fmt"
"math"
"strings"
"time"
"git.rosy.net.cn/jx-callback/business/authz/autils"
"git.rosy.net.cn/jx-callback/business/partner/delivery/dada"
"git.rosy.net.cn/jx-callback/business/jxutils/jxcontext"
beego "github.com/astaxie/beego/server/web"
"git.rosy.net.cn/baseapi/platformapi/dadaapi"
"git.rosy.net.cn/baseapi/platformapi/dingdingapi"
"git.rosy.net.cn/baseapi/platformapi/jcqapi"
"git.rosy.net.cn/baseapi/platformapi/jdshopapi"
"git.rosy.net.cn/baseapi/utils"
"git.rosy.net.cn/jx-callback/business/jxutils"
"git.rosy.net.cn/jx-callback/business/jxutils/ddmsg"
"git.rosy.net.cn/jx-callback/business/model"
"git.rosy.net.cn/jx-callback/business/model/dao"
"git.rosy.net.cn/jx-callback/business/partner"
"git.rosy.net.cn/jx-callback/globals"
"git.rosy.net.cn/jx-callback/globals/api"
"git.rosy.net.cn/jx-callback/globals/api2"
)
//TODO 以下是京东商城云顶推送消息使用的代码,现在都是以网页爬取的形式拿订单了,下面的都不用了
//TODO 位置在 orderman/order.go 的 SaveJdsOrders
func OnCallbackMsg(msg *jdshopapi.CallBackResult) (err error) {
msgType := msg.MsgType
switch msgType {
case jcqapi.TopicOrderPay:
utils.CallFuncAsync(func() {
SaveJdsOrders(msg)
})
case jcqapi.TopicOrderCancel:
utils.CallFuncAsync(func() {
order := getRealOrderID(msg.OrderID)
if order != nil {
if order.Status != model.OrderStatusCanceled {
CurPurchaseHandler.CancelOrder(jxcontext.AdminCtx, order, "系统取消")
}
}
})
case jcqapi.TopicOrderOut:
utils.CallFuncAsync(func() {
orders := getAllRealOrderID(msg.OrderID)
if len(orders) > 0 {
for _, order := range orders {
if order.ActualPayPrice == 0 {
if jxutils.StandardPrice2Int(utils.Str2Float64(msg.OrderPayment)) == 0 {
order.ActualPayPrice = jxutils.StandardPrice2Int(utils.Str2Float64(msg.OrderTotalPrice) + utils.Str2Float64(msg.FreightPrice) - utils.Str2Float64(msg.SellerDiscount))
} else {
order.ActualPayPrice = jxutils.StandardPrice2Int(utils.Str2Float64(msg.OrderPayment))
}
order.TotalShopMoney = utils.Float64TwoInt64(float64(order.ActualPayPrice) * jdshopapi.JdsPayPercentage)
partner.CurOrderManager.UpdateOrderFields(order, []string{"ActualPayPrice", "TotalShopMoney"})
}
}
}
})
default:
return fmt.Errorf("暂不支持的topic类型topic: %v", msgType)
}
return err
}
func SaveJdsOrders(msg *jdshopapi.CallBackResult) (err error) {
if msg.OrderState == "TRADE_CANCELED" {
return nil
} //清洗脏数据 部分数据按照
order, err := result2Orders(msg)
if err != nil && order == nil {
return err
}
partner.CurOrderManager.OnOrderNew(order, model.Order2Status(order))
noticeMsg := fmt.Sprintf("京东商城新订单,订单号:[%v] ,将要发到的门店id[%v] , 门店名:[%v]", order.VendorOrderID, order.StoreID, order.StoreName)
if order.OrderType == model.OrderTypeAddressErr {
noticeMsg += " 此订单地址有问题,需要矫正坐标!"
}
var role = autils.NewRole("jdshop", 0)
userIDList, err := api2.RoleMan.GetRoleUserList(role)
for _, v := range userIDList {
ddmsg.SendUserMessage(dingdingapi.MsgTyeText, v, "京东商城来新订单了!", noticeMsg)
}
// ddmsg.SendUserMessage(dingdingapi.MsgTyeText, "1439B3E07D3911EA881A525400E86DC0", "京东商城来新订单了!", noticeMsg)
return err
}
func result2Orders(msg *jdshopapi.CallBackResult) (order *model.GoodsOrder, err error) {
var (
db = dao.GetDB()
)
//有可能是库里已经有这个订单了
orderE, err := partner.CurOrderManager.LoadOrder(msg.OrderID+"00000001", model.VendorIDJDShop)
if orderE != nil {
return order, fmt.Errorf("已经存在此订单!")
}
order = &model.GoodsOrder{
VendorOrderID2: msg.OrderID,
VendorOrderID: msg.OrderID + "00000001",
VendorID: model.VendorIDJDShop,
BaseFreightMoney: jxutils.StandardPrice2Int(utils.Str2Float64(msg.FreightPrice)),
VendorStatus: msg.OrderState,
VendorUserID: msg.Pin,
BuyerComment: msg.OrderRemark,
PickDeadline: utils.DefaultTimeValue,
OriginalData: string(utils.MustMarshal(msg)),
OrderCreatedAt: utils.Str2Time(msg.OrderStartTime),
ConsigneeAddress: Decrypt(msg.ConsigneeInfo.FullAddress, msg.VendorOrgCode),
ConsigneeName: Decrypt(msg.ConsigneeInfo.Fullname, msg.VendorOrgCode),
// ConsigneeMobile: Decrypt(msg.ConsigneeInfo.Mobile),
// ConsigneeMobile2: Decrypt(msg.ConsigneeInfo.Telephone),
ActualPayPrice: jxutils.StandardPrice2Int(utils.Str2Float64(msg.OrderPayment)),
Status: model.OrderStatusNew,
TotalShopMoney: utils.Float64TwoInt64(math.Round(float64(jxutils.StandardPrice2Int(utils.Str2Float64(msg.OrderPayment))) * jdshopapi.JdsPayPercentage)),
DeliveryType: model.OrderDeliveryTypeStoreSelf,
StatusTime: utils.Str2Time(msg.OrderStartTime),
OrderSeq: 0,
VendorOrgCode: msg.VendorOrgCode,
}
if utils.Str2Float64(msg.BalanceUsed) != 0 {
order.ActualPayPrice += jxutils.StandardPrice2Int(utils.Str2Float64(msg.BalanceUsed))
order.TotalShopMoney += utils.Float64TwoInt64(math.Round(float64(jxutils.StandardPrice2Int(utils.Str2Float64(msg.BalanceUsed))) * jdshopapi.JdsPayPercentage))
}
if len(msg.ConsigneeInfo.Mobile) != 11 {
order.ConsigneeMobile = Decrypt(msg.ConsigneeInfo.Mobile, msg.VendorOrgCode)
} else {
order.ConsigneeMobile = msg.ConsigneeInfo.Mobile
}
if len(msg.ConsigneeInfo.Telephone) != 11 {
order.ConsigneeMobile2 = Decrypt(msg.ConsigneeInfo.Telephone, msg.VendorOrgCode)
} else {
order.ConsigneeMobile2 = msg.ConsigneeInfo.Telephone
}
if order.TotalShopMoney < 100 {
order.TotalShopMoney = 100
}
if order.ConsigneeAddress != "" {
var cityCode int
place, err := dao.GetPlaceByJdsCode(db, utils.Str2Int(msg.ConsigneeInfo.CityID))
if place == nil {
cityCode = 510100
} else {
if place.Level == 3 {
cityCode = place.ParentCode
} else if place.Level == 2 {
cityCode = place.Code
}
}
lng, lat, err2 := api.AutonaviAPI.GetCoordinateFromAddressByPage(order.ConsigneeAddress, cityCode)
if err = err2; err != nil {
globals.SugarLogger.Infof("高德page err: %v", err)
}
lng2, lat2, _ := api.AutonaviAPI.GetCoordinateFromAddress(order.ConsigneeAddress, "")
distance := jxutils.EarthDistance(lng, lat, lng2, lat2)
if distance > 1 {
order.OrderType = model.OrderTypeAddressErr
}
if err == nil && lng != 0 && lat != 0 {
order.ConsigneeLng = jxutils.StandardCoordinate2Int(lng)
order.ConsigneeLat = jxutils.StandardCoordinate2Int(lat)
} else {
order.ConsigneeLng = jxutils.StandardCoordinate2Int(lng2)
order.ConsigneeLat = jxutils.StandardCoordinate2Int(lat2)
}
order.CoordinateType = model.CoordinateTypeMars
}
// storeList, err := common.GetStoreListByLocation(jxcontext.AdminCtx, jxutils.IntCoordinate2Standard(order.ConsigneeLng), jxutils.IntCoordinate2Standard(order.ConsigneeLat), 3000, false, true, 0)
// if err != nil {
// return order, err
// }
// if len(storeList) > 0 {
// for _, store := range storeList {
for _, v := range msg.ItemInfoList {
sku := &model.OrderSku{
VendorID: model.VendorIDJDShop,
VendorOrderID: order.VendorOrderID,
Count: utils.Str2Int(v.ItemTotal),
VendorSkuID: v.SkuID,
SkuName: v.SkuName,
VendorPrice: jxutils.StandardPrice2Int(utils.Str2Float64(v.JdPrice)),
SalePrice: jxutils.StandardPrice2Int(utils.Str2Float64(v.JdPrice)),
// SkuID: utils.Str2Int(v.OuterSkuID),
}
if v.OuterSkuID != "" {
sku.SkuID = utils.Str2Int(v.OuterSkuID)
}
_, _, _, specUnit, _, specQuality := jxutils.SplitSkuName(v.SkuName)
sku.Weight = jxutils.FormatSkuWeight(specQuality, specUnit)
order.Skus = append(order.Skus, sku)
}
if order.ActualPayPrice > 100000 {
buildOrderTo102919(order)
}
var store *dao.StoreDetail
if msg.OrderExt != "" {
orderExt := &jdshopapi.OrderExt{}
if err = json.Unmarshal([]byte(msg.OrderExt), &orderExt); err == nil {
order.VendorStoreID = orderExt.SiteID
if store, err = dao.GetStoreDetailByVendorStoreID(db, order.VendorStoreID, model.VendorIDJDShop, ""); store != nil && err == nil {
order.StoreID = store.ID
order.JxStoreID = store.ID
order.StoreName = store.Name
//结算类型
if store.PayPercentage < 50 {
order.EarningType = model.EarningTypePoints
} else {
order.EarningType = model.EarningTypeQuote
}
var (
shopPriceSum int
// saleNormalSum int
)
for _, sku := range order.Skus {
storeSkuList, _ := dao.GetStoresSkusInfo(db, []int{order.StoreID}, []int{sku.SkuID})
if len(storeSkuList) > 0 {
// if storeSkuList[0].Status == model.StoreSkuBindStatusNormal {
// saleNormalSum += 1
// }
shopPriceSum += storeSkuList[0].Price * sku.Count
sku.ShopPrice = int64(storeSkuList[0].Price)
} else {
shopPriceSum += int(sku.SalePrice) * 70 / 100
}
}
//可售数小于一半就不行
// if math.Mod(float64(len(order.Skus)), float64(2)) == 0 {
// if saleNormalSum < len(order.Skus)/2 {
// buildOrderTo102919(order)
// } else {
if order.EarningType == model.EarningTypeQuote && shopPriceSum+700 > int(order.TotalShopMoney) {
buildOrderTo102919(order)
}
// }
// } else {
// if saleNormalSum <= len(order.Skus)/2 {
// buildOrderTo102919(order)
// } else {
// if order.EarningType == model.EarningTypeQuote && shopPriceSum+700 > int(order.TotalShopMoney) {
// buildOrderTo102919(order)
// }
// }
// }
} else {
buildOrderTo102919(order)
}
} else {
buildOrderTo102919(order)
}
} else {
buildOrderTo102919(order)
}
// 如果是暂停表示是预订单g
if msg.OrderState == jdshopapi.OrderStatusPause || msg.OrderState == jdshopapi.OrderStatusPopPause {
order.BusinessType = model.BusinessTypeDingshida
if time2, err := getAPI(msg.VendorOrgCode).GetOrderExtInfoByOrderId(order.VendorOrderID2); err == nil {
if time2 == "" {
order.ExpectedDeliveredTime = order.OrderCreatedAt.Add(time.Hour)
} else {
order.ExpectedDeliveredTime = utils.Str2Time(time2)
}
} else {
order.ExpectedDeliveredTime = order.OrderCreatedAt.Add(time.Hour)
err = nil
}
order.PickDeadline = order.ExpectedDeliveredTime.Add(-time.Hour)
} else if msg.OrderState == jdshopapi.OrderStatusWait || msg.OrderState == "WAIT_GOODS_RECEIVE_CONFIRM" || msg.OrderState == "FINISHED_L" {
order.ExpectedDeliveredTime = order.OrderCreatedAt.Add(time.Hour)
order.BusinessType = model.BusinessTypeImmediate
} else if msg.OrderState == "UN_KNOWN" {
order.ExpectedDeliveredTime = order.OrderCreatedAt.Add(time.Hour)
order.BusinessType = model.BusinessTypeImmediate
} else {
return nil, err
}
if msg.IDSopShipmenttype == jdshopapi.IdSopShipmenttypeTC {
if msg.VendorOrgCode == "1" {
if time2, err := getAPI(msg.VendorOrgCode).GetOrderExtInfoByOrderId(order.VendorOrderID2); err == nil {
order.BusinessType = model.BusinessTypeDingshida
if time2 == "" {
order.ExpectedDeliveredTime = order.OrderCreatedAt.Add(time.Hour)
} else {
order.ExpectedDeliveredTime = utils.Str2Time(time2)
}
}
} else {
order.BusinessType = model.BusinessTypeImmediate
if time2, err := getAPI(msg.VendorOrgCode).GetOrderExtInfoByOrderId(order.VendorOrderID2); err == nil {
if time2 == "" {
order.ExpectedDeliveredTime = order.OrderCreatedAt.Add(time.Hour)
} else {
order.ExpectedDeliveredTime = utils.Str2Time(time2)
}
} else {
order.ExpectedDeliveredTime = order.OrderCreatedAt.Add(time.Hour)
}
}
}
setJdsOrderSeq(order)
if order.OrderType == model.OrderTypeAddressErr {
buildOrderTo102919(order)
}
// billParams, _ := GetDaDaBillParams(db, order)
// if result, err := api.DadaAPI.QueryDeliverFee(billParams); err == nil {
// if result.Fee > 10 {
// buildOrderTo102919(order)
// }
// }
if store != nil {
distance := jxutils.EarthDistance(jxutils.IntCoordinate2Standard(order.ConsigneeLng), jxutils.IntCoordinate2Standard(order.ConsigneeLat), jxutils.IntCoordinate2Standard(store.Lng), jxutils.IntCoordinate2Standard(store.Lat))
if distance > 4 {
buildOrderTo102919(order)
}
}
if order.ExpectedDeliveredTime.Sub(order.OrderCreatedAt) <= time.Hour+time.Minute {
order.BusinessType = model.BusinessTypeImmediate
}
// buildOrderTo102919(order)
return order, err
}
func buildOrderTo102919(order *model.GoodsOrder) {
// if order.VendorOrgCode == "1" {
// order.StoreID = 102919
// order.JxStoreID = 102919
// order.StoreName = "商城模板(成都发货)"
// order.VendorStoreID = model.JdShopMainVendorStoreID
// } else {
order.StoreID = model.JdShopMainStoreID
order.JxStoreID = model.JdShopMainStoreID
order.StoreName = "商城模板店2"
order.VendorStoreID = model.JdShopMainVendorStoreID
// }
order.DeliveryFlag = model.OrderDeliveryFlagMaskScheduleDisabled
}
func setJdsOrderSeq(order *model.GoodsOrder) (err error) {
type tCount struct {
Count int `json:"count"`
}
var count = &tCount{}
sql := `
SELECT count(*) count FROM goods_order WHERE store_id = ? AND order_create_at >= ? AND order_create_at <= ? AND vendor_id = ?
`
sqlParams := []interface{}{
order.StoreID, utils.Time2Date(time.Now()), utils.Time2Date(time.Now().AddDate(0, 0, 1)), order.VendorID,
}
err = dao.GetRow(dao.GetDB(), &count, sql, sqlParams)
order.OrderSeq = count.Count + 1
return err
}
func Decrypt(p, vendorOrgCode string) (result string) {
if p == "" {
return ""
}
data, _ := base64.StdEncoding.DecodeString(strings.ReplaceAll(p, " ", "+"))
key := GetKey(hex.EncodeToString(data)[4:36], vendorOrgCode)
data2, _ := base64.StdEncoding.DecodeString(key)
b := bytes.NewBuffer(data)
b.Next(18)
iv := make([]byte, 16)
b.Read(iv)
main := make([]byte, len(data)-18-16)
b.Read(main)
decryptedData, _ := utils.AESCBCDecpryt(main, data2[:16], iv)
return string(decryptedData)
}
func getRealOrderID(orderID string) (order *model.GoodsOrder) {
var (
db = dao.GetDB()
)
sql := `
SELECT * FROM goods_order WHERE vendor_order_id2 = ? ORDER BY vendor_order_id DESC LIMIT 1
`
sqlParams := []interface{}{
orderID,
}
dao.GetRow(db, &order, sql, sqlParams)
return order
}
func getAllRealOrderID(orderID string) (orders []*model.GoodsOrder) {
var (
db = dao.GetDB()
)
sql := `
SELECT * FROM goods_order WHERE vendor_order_id2 = ?
`
sqlParams := []interface{}{
orderID,
}
dao.GetRows(db, &orders, sql, sqlParams)
return orders
}
func GetDaDaBillParams(db *dao.DaoDB, order *model.GoodsOrder) (billParams *dadaapi.OperateOrderParams, err error) {
billParams = &dadaapi.OperateOrderParams{
OriginID: jxutils.ComposeUniversalOrderID(order.VendorOrderID, order.VendorID),
CargoPrice: jxutils.IntPrice2Standard(limitOrderPrice(order.ActualPayPrice)),
IsPrepay: 0,
ReceiverName: utils.FilterMb4(order.ConsigneeName),
ReceiverAddress: utils.FilterMb4(order.ConsigneeAddress),
ReceiverPhone: order.ConsigneeMobile,
}
if billParams.ShopNo, err = getDadaShopID(order, db); err == nil {
if billParams.CityCode, err = getDataCityCodeFromOrder(order, db); err == nil {
// storeTel := ""
// storeID := jxutils.GetSaleStoreIDFromOrder(order)
// storeDeatail, _ := dao.GetStoreDetail(db, storeID, order.VendorID)
// if storeDeatail.Tel2 != "" {
// storeTel = ",门店电话:" + storeDeatail.Tel2
// }
billParams.ReceiverLng, billParams.ReceiverLat, _ = jxutils.IntCoordinate2MarsStandard(order.ConsigneeLng, order.ConsigneeLat, order.CoordinateType)
billParams.Info = fmt.Sprintf("%s第%d号订单, %s", model.VendorChineseNames[order.VendorID], order.OrderSeq, utils.FilterMb4("客户电话:"+order.ConsigneeMobile+","+order.BuyerComment+"配送遇到问题可联系18048531223取消配送单禁止未配送直接完成定单"))
billParams.CargoType = dadaapi.CargoTypeFresh
billParams.CargoWeight = float64(jxutils.IntWeight2Float(limitOrderWeight(order.Weight)))
billParams.CargoNum = order.GoodsCount
}
}
return billParams, err
}
func limitOrderPrice(price int64) int64 {
var maxOrderPrice int64 = 6399
if price > maxOrderPrice {
return maxOrderPrice
}
return price
}
func limitOrderWeight(weight int) int {
maxOrderWeight := 5000 // 5公斤
if weight > maxOrderWeight {
return maxOrderWeight
}
return weight
}
func getDadaShopID(order *model.GoodsOrder, db *dao.DaoDB) (retVal string, err error) {
saleStoreID := jxutils.GetSaleStoreIDFromOrder(order)
storeCourierList, err2 := dao.GetOpenedStoreCouriersByStoreID(db, saleStoreID, model.VendorIDDada)
if err = err2; err != nil && !dao.IsNoRowsError(err) {
return "", err
}
if len(storeCourierList) == 0 {
return "", partner.ErrStoreHaveNoCourier
}
retVal = storeCourierList[0].VendorStoreID
if beego.BConfig.RunMode == "dev" {
retVal = "test_0001"
}
return retVal, nil
}
func getDataCityCodeFromOrder(order *model.GoodsOrder, db *dao.DaoDB) (retVal string, err error) {
jxStoreID := jxutils.GetSaleStoreIDFromOrder(order)
sql := `
SELECT t2.tel_code
FROM store t1
JOIN place t2 on t1.city_code = t2.code
WHERE t1.id = ?
`
codeInfo := &struct {
TelCode string
}{}
if err = dao.GetRow(db, codeInfo, sql, jxStoreID); err != nil {
if err == nil {
err = dada.ErrCanNotFindDadaCityCode
}
return "", err
}
return codeInfo.TelCode, nil
}