182 lines
4.8 KiB
Go
182 lines
4.8 KiB
Go
package controller
|
||
|
||
import (
|
||
"fmt"
|
||
"math"
|
||
"strings"
|
||
"sync"
|
||
"time"
|
||
|
||
"git.rosy.net.cn/baseapi/platformapi/autonavi"
|
||
|
||
"github.com/astaxie/beego/orm"
|
||
|
||
"git.rosy.net.cn/jx-callback/business/model"
|
||
|
||
"git.rosy.net.cn/baseapi/utils"
|
||
"git.rosy.net.cn/baseapi/utils/routinepool"
|
||
"git.rosy.net.cn/jx-callback/business/scheduler"
|
||
_ "git.rosy.net.cn/jx-callback/business/scheduler/defsch" // 导入缺省订单调度器
|
||
"git.rosy.net.cn/jx-callback/globals"
|
||
"git.rosy.net.cn/jx-callback/globals/api"
|
||
)
|
||
|
||
const (
|
||
DefaultOrderCacheTimeout = 24 * time.Hour
|
||
)
|
||
|
||
var (
|
||
OrderManager *OrderController
|
||
WaybillManager *WaybillController
|
||
|
||
routinePool *routinepool.Pool
|
||
)
|
||
|
||
type SyncMapWithTimeout struct {
|
||
sync.Map
|
||
}
|
||
|
||
func init() {
|
||
routinePool = routinepool.New(1000, 1000)
|
||
OrderManager = NewOrderManager()
|
||
WaybillManager = NewWaybillManager()
|
||
scheduler.CurrentScheduler.RegisterOrderManager(OrderManager)
|
||
}
|
||
|
||
func (m *SyncMapWithTimeout) StoreWithTimeout(key, value interface{}, timeout time.Duration) {
|
||
m.Map.Store(key, value)
|
||
time.AfterFunc(timeout, func() {
|
||
m.Delete(key)
|
||
})
|
||
}
|
||
|
||
func (m *SyncMapWithTimeout) Store(key, value interface{}) {
|
||
m.StoreWithTimeout(key, value, DefaultOrderCacheTimeout)
|
||
}
|
||
|
||
func SplitUniversalOrderID(universalOrderID string) (orderID string, vendorID int) {
|
||
index := strings.Index(universalOrderID, "|")
|
||
if index != -1 {
|
||
orderID = universalOrderID[:index]
|
||
vendorID = int(utils.Str2Int64(universalOrderID[index:]))
|
||
} else {
|
||
// 800402581000221 jd order
|
||
// 3022716176275221584 elm order
|
||
orderIDLen := len(universalOrderID)
|
||
if orderIDLen == len("800402581000221") {
|
||
vendorID = model.VendorIDJD
|
||
} else if orderIDLen == len("3022716176275221584") {
|
||
vendorID = model.VendorIDELM
|
||
} else {
|
||
globals.SugarLogger.Errorf("unkown order type:%v", universalOrderID)
|
||
vendorID = model.VendorIDUnknown
|
||
}
|
||
orderID = universalOrderID
|
||
}
|
||
return orderID, vendorID
|
||
}
|
||
|
||
func ComposeUniversalOrderID(orderID string, vendorID int) string {
|
||
// return fmt.Sprintf("%s|%d", orderID, vendorID)
|
||
return orderID // 当前用长度就能区分,先不加上vendorID
|
||
}
|
||
|
||
func StandardCoordinate2Int(value float64) int {
|
||
return int(math.Round(value * 1000000))
|
||
}
|
||
|
||
func IntCoordinate2Standard(value int) float64 {
|
||
return float64(value) / 1000000
|
||
}
|
||
|
||
func IntCoordinate2MarsStandard(gpsLng, gpsLat int, coordinateType int) (marsLng, marsLat float64, err error) {
|
||
marsLng = IntCoordinate2Standard(gpsLng)
|
||
marsLat = IntCoordinate2Standard(gpsLat)
|
||
coordSys := ""
|
||
switch coordinateType {
|
||
case model.CoordinateTypeGPS:
|
||
coordSys = autonavi.CoordSysGPS
|
||
case model.CoordinateTypeMars:
|
||
coordSys = autonavi.CoordSysAutonavi
|
||
case model.CoordinateTypeBaiDu:
|
||
coordSys = autonavi.CoordSysBaidu
|
||
case model.CoordinateTypeMapbar:
|
||
coordSys = autonavi.CoordSysMapbar
|
||
default:
|
||
globals.SugarLogger.Errorf("known coordinate type:%d", coordinateType)
|
||
}
|
||
return api.AutonaviAPI.CoordinateConvert(marsLng, marsLat, coordSys)
|
||
}
|
||
|
||
func IntPrice2Standard(value int64) float64 {
|
||
return float64(value) / 100
|
||
}
|
||
|
||
func StandardPrice2Int(value float64) int64 {
|
||
return int64(math.Round(value * 100))
|
||
}
|
||
|
||
func addOrderOrWaybillStatus(status *model.OrderStatus, db orm.Ormer) (isDuplicated bool, err error) {
|
||
status.ID = 0
|
||
created, _, err := db.ReadOrCreate(status, "VendorOrderID", "VendorID", "OrderType", "VendorStatus", "StatusTime")
|
||
if err == nil {
|
||
if !created {
|
||
isDuplicated = true
|
||
status.DuplicatedCount++
|
||
_, err = db.Update(status, "DuplicatedCount")
|
||
globals.SugarLogger.Infof("duplicated event:%v", status)
|
||
}
|
||
}
|
||
if err != nil {
|
||
// todo 这里居然会有主键重复错误,逻辑上是不应该的
|
||
globals.SugarLogger.Warnf("access db error:%v", err)
|
||
}
|
||
return isDuplicated, err
|
||
}
|
||
|
||
func CallMsgHandler(handler func(), primaryID string) {
|
||
// handler()
|
||
routinePool.CallFun(func() {
|
||
handler()
|
||
}, primaryID)
|
||
}
|
||
|
||
func GetDataCityCodeFromOrder(order *model.GoodsOrder) (retVal string, err error) {
|
||
var sql string
|
||
if order.VendorID == model.VendorIDJD {
|
||
sql = `
|
||
SELECT t2.tel_code
|
||
FROM jxstoremap t0
|
||
JOIN jxstore t1 ON t0.jxstoreid = t1.storeid
|
||
JOIN city t2 ON t1.area = t2.citycode
|
||
WHERE t0.jdstoreid = ?
|
||
`
|
||
} else if order.VendorID == model.VendorIDELM {
|
||
sql = `
|
||
SELECT t2.tel_code
|
||
FROM jx_to_elm_store_map t0
|
||
JOIN jxstore t1 ON t0.jx_store_id = t1.storeid
|
||
JOIN city t2 ON t1.area = t2.citycode
|
||
WHERE t0.elm_store_id = ?
|
||
`
|
||
} else {
|
||
panic(fmt.Sprintf("wrong vendorid:%d", order.VendorID))
|
||
}
|
||
db := orm.NewOrm()
|
||
var lists []orm.ParamsList
|
||
num, err := db.Raw(sql, utils.Str2Int64(order.VendorStoreID)).ValuesList(&lists)
|
||
if err != nil && num == 1 {
|
||
retVal = lists[0][0].(string)
|
||
} else {
|
||
globals.SugarLogger.Errorf("can not find store info for vendorID:%d, store:%s", order.VendorID, order.VendorStoreID)
|
||
}
|
||
return retVal, err
|
||
}
|
||
|
||
func GetJxStoreIDFromOrder(order *model.GoodsOrder) (retVal int) {
|
||
if order.JxStoreID != 0 {
|
||
return order.JxStoreID
|
||
}
|
||
return order.StoreID
|
||
}
|