package jxutils import ( "fmt" "math" "math/rand" "strings" "sync" "time" "git.rosy.net.cn/baseapi/platformapi/autonavi" "git.rosy.net.cn/baseapi/utils" "git.rosy.net.cn/baseapi/utils/routinepool" "git.rosy.net.cn/jx-callback/business/model" "git.rosy.net.cn/jx-callback/globals/api" ) const ( DefaultOrderCacheTimeout = 24 * time.Hour ) var ( routinePool *routinepool.Pool ) type SyncMapWithTimeout struct { sync.Map } func init() { rand.Seed(time.Now().Unix()) routinePool = routinepool.New(1000, 1000) } 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 GetJxStoreIDFromOrder(order *model.GoodsOrder) (retVal int) { if order.JxStoreID != 0 { return order.JxStoreID } return order.StoreID } 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) panic(fmt.Sprintf("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 GetUniversalOrderIDFromWaybill(bill *model.Waybill) string { return ComposeUniversalOrderID(bill.VendorOrderID, bill.OrderVendorID) } func GetUniversalOrderIDFromOrder(order *model.GoodsOrder) string { return ComposeUniversalOrderID(order.VendorOrderID, order.VendorID) } func GetUniversalOrderIDFromOrderStatus(status *model.OrderStatus) string { return ComposeUniversalOrderID(status.VendorOrderID, status.VendorID) } func GetRealTimeout(beginTime time.Time, timeout time.Duration, minTimeout time.Duration) time.Duration { retVal := beginTime.Add(timeout).Sub(time.Now()) if retVal < minTimeout { retVal = minTimeout + time.Duration(rand.Int31n(5*1000))*time.Millisecond // 随机分布在5秒内这样写的原因是避免启动时加载订单,TIMER同一瞬间启动 } return retVal } func EarthDistance(lat1, lng1, lat2, lng2 float64) float64 { radius := 6378.137 rad := math.Pi / 180.0 lat1 = lat1 * rad lng1 = lng1 * rad lat2 = lat2 * rad lng2 = lng2 * rad theta := lng2 - lng1 dist := math.Acos(math.Sin(lat1)*math.Sin(lat2) + math.Cos(lat1)*math.Cos(lat2)*math.Cos(theta)) return dist * radius } 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: panic(fmt.Sprintf("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 IntPrice2StandardString(value int64) string { return fmt.Sprintf("%.2f", IntPrice2Standard(value)) } func CallMsgHandler(handler func(), primaryID string) { routinePool.CallFun(func() { handler() }, primaryID) } func CallMsgHandlerAsync(handler func(), primaryID string) { routinePool.CallFunAsync(func() { handler() }, primaryID) } func SplitSkuName(fullName string) (name string, unit string) { index := strings.Index(fullName, "/") if index >= 0 { return fullName[:index], fullName[index+1:] } return fullName, "份" }