Merge remote-tracking branch 'origin/mark' into don

This commit is contained in:
Rosy-zhudan
2019-09-11 17:38:54 +08:00
40 changed files with 754 additions and 289 deletions

View File

@@ -80,6 +80,7 @@ var (
CurStoreManager IStoreManager
PurchasePlatformHandlers map[int]IPurchasePlatformHandler
PurchaseOrderHandlers map[int]IPurchasePlatformOrderHandler
)
type IOrderManager interface {
@@ -194,6 +195,7 @@ func (p *BasePurchasePlatform) GetStatusActionTimeout(order *model.GoodsOrder, s
func init() {
PurchasePlatformHandlers = make(map[int]IPurchasePlatformHandler)
PurchaseOrderHandlers = make(map[int]IPurchasePlatformOrderHandler)
DeliveryPlatformHandlers = make(map[int]*DeliveryPlatformHandlerInfo)
}
@@ -221,10 +223,22 @@ func RegisterPurchasePlatform(handler IPurchasePlatformHandler) {
PurchasePlatformHandlers[vendorID] = handler
}
func RegisterPurchaseOrderHandler(vendorID int, handler IPurchasePlatformOrderHandler) {
PurchaseOrderHandlers[vendorID] = handler
}
func GetPurchasePlatformFromVendorID(vendorID int) IPurchasePlatformHandler {
return PurchasePlatformHandlers[vendorID]
}
func GetPurchaseOrderHandlerFromVendorID(vendorID int) (handler IPurchasePlatformOrderHandler) {
handler = PurchasePlatformHandlers[vendorID]
if handler == nil {
handler = PurchaseOrderHandlers[vendorID]
}
return handler
}
func GetPurchasePlatformVendorIDs() (vendorIDs []int) {
for k := range PurchasePlatformHandlers {
vendorIDs = append(vendorIDs, k)

View File

@@ -8,7 +8,7 @@ import (
type IPurchasePlatformNetSpiderHandler interface {
GetStoreIDListByCoordinates(ctx *jxcontext.Context, coord *ditu.Coordinate) (storeIDList []string, err error)
GetStorePageInfo(ctx *jxcontext.Context, cityInfo, storeID string) (storePageInfo *model.PageShop, err error)
GetStorePageInfo(ctx *jxcontext.Context, storeID string) (storePageInfo *model.PageShop, err error)
// GetStoreListByCoordinates(ctx *jxcontext.Context, parentTask tasksch.ITask, cityInfo string, coordList []*ditu.Coordinate) (storeList []*model.PageShop, err error)
}

View File

@@ -1,6 +1,7 @@
package ebai
import (
"git.rosy.net.cn/baseapi/platformapi/ebaiapi"
"git.rosy.net.cn/baseapi/utils"
"git.rosy.net.cn/jx-callback/business/jxutils/ditu"
"git.rosy.net.cn/jx-callback/business/jxutils/jxcontext"
@@ -21,12 +22,12 @@ func (c *PurchaseHandler) GetStoreIDListByCoordinates(ctx *jxcontext.Context, co
return storeIDList, nil
}
func (c *PurchaseHandler) GetStorePageInfo(ctx *jxcontext.Context, cityInfo, storeID string) (storePageInfo *model.PageShop, err error) {
func (c *PurchaseHandler) GetStorePageInfo(ctx *jxcontext.Context, storeID string) (storePageInfo *model.PageShop, err error) {
shopInfo, err2 := api.EbaiAPI.GetStoreInfo2(storeID)
if err = err2; err == nil && shopInfo != nil {
districtCode := 0
// districtCode := api.AutonaviAPI.GetCoordinateDistrictCode(shopInfo.Longitude, shopInfo.Latitude)
return &model.PageShop{
// 饿百扒下来的坐标是加了密的,不能用
// lng, lat, _ := api.AutonaviAPI.CoordinateConvert(shopInfo.Longitude/100000, shopInfo.Latitude/100000, autonavi.CoordSysBaidu)
storePageInfo = &model.PageShop{
Name: shopInfo.Name,
VendorID: model.VendorIDEBAI,
VendorStoreID: storeID,
@@ -34,9 +35,9 @@ func (c *PurchaseHandler) GetStorePageInfo(ctx *jxcontext.Context, cityInfo, sto
VendorStatus: utils.Int2Str(shopInfo.BusinessStatus),
Address: shopInfo.Address,
Lng: shopInfo.Longitude / 100000,
Lat: shopInfo.Latitude / 100000,
DistrictCode: districtCode,
Lng: 0,
Lat: 0,
DistrictCode: 0,
Tel1: shopInfo.Phone,
@@ -44,7 +45,21 @@ func (c *PurchaseHandler) GetStorePageInfo(ctx *jxcontext.Context, cityInfo, sto
SkuCount: shopInfo.SkuCount,
BusinessType: shopInfo.Category,
ShopScore: float64(shopInfo.ShopScore),
}, nil
}
storePageInfo.LicenceCode, storePageInfo.LicenceImg = getLicenceInfoFromShopInfo(shopInfo)
}
return nil, err
return storePageInfo, err
}
func getLicenceInfoFromShopInfo(storeInfo *ebaiapi.PageShopInfo) (licenceCode, licenceImg string) {
for _, v := range storeInfo.MedicineQualification {
if v.AptitudeType == "101" { // 营业执照
licenceCode = v.LicenseNumber
if len(v.AptitudePhoto) > 0 {
licenceImg = v.AptitudePhoto[0]
}
break
}
}
return licenceCode, licenceImg
}

View File

@@ -212,7 +212,7 @@ func (p *PurchaseHandler) Map2Order(orderData map[string]interface{}) (order *mo
}
}
deliveryGeo := userMap["coord"].(map[string]interface{})
deliveryGeo := userMap["coord_amap"].(map[string]interface{})
originalLng := utils.Interface2Float64WithDefault(deliveryGeo["longitude"], 0.0) // 饿百的订单在过一段时间后,经纬度信息会变成字符串"**"
originalLat := utils.Interface2Float64WithDefault(deliveryGeo["latitude"], 0.0)
lng, lat, err2 := api.AutonaviAPI.CoordinateConvert(originalLng, originalLat, autonavi.CoordSysBaidu)

View File

@@ -387,6 +387,7 @@ func genStoreMapFromStore(store *tEbaiStoreInfo) map[string]interface{} {
params["address"] = store.Address
// todo 饿百 开店审核通过后不允许修改商户信息
if store.SyncStatus&(model.SyncFlagNewMask /*|model.SyncFlagStoreAddress*/) != 0 {
// todo 这里应该要做坐标转换吧
params["longitude"] = jxutils.IntCoordinate2Standard(store.Lng)
params["latitude"] = jxutils.IntCoordinate2Standard(store.Lat)
params["coord_type"] = ebaiapi.CoordTypeAutonavi

View File

@@ -27,13 +27,9 @@ func (c *PurchaseHandler) GetStoreIDListByCoordinates(ctx *jxcontext.Context, co
return storeIDList, nil
}
func (c *PurchaseHandler) GetStorePageInfo(ctx *jxcontext.Context, cityInfo, storeID string) (storePageInfo *model.PageShop, err error) {
func (c *PurchaseHandler) GetStorePageInfo(ctx *jxcontext.Context, storeID string) (storePageInfo *model.PageShop, err error) {
shopInfo, err2 := api.JdPageAPI.GetStoreInfo2(storeID)
if err = err2; err == nil && shopInfo != nil {
var lng, lat float64
districtCode := 0
// 由于高德API免费有调用次数限制暂时不取坐标信息
// lng, lat, districtCode := api.AutonaviAPI.GetCoordinateFromAddress(shopInfo.StoreInfo.StoreAddress, cityInfo)
return &model.PageShop{
Name: shopInfo.StoreInfo.StoreName,
VendorID: model.VendorIDJD,
@@ -42,9 +38,9 @@ func (c *PurchaseHandler) GetStorePageInfo(ctx *jxcontext.Context, cityInfo, sto
VendorStatus: utils.Int2Str(shopInfo.StoreInfo.StationStatus),
Address: shopInfo.StoreInfo.StoreAddress,
Lng: lng,
Lat: lat,
DistrictCode: districtCode,
Lng: 0,
Lat: 0,
DistrictCode: 0,
Tel1: shopInfo.StoreInfo.StoreTel,

View File

@@ -1,15 +1,16 @@
package jx
import "fmt"
import (
"fmt"
"time"
"git.rosy.net.cn/baseapi/utils"
)
const (
appKey = "4A86853D-E4B6-454E-940A-B68ECDA2B73E"
MsgTypeOrder = "order"
SubMsgTypeOrderNew = "newOrder"
SubMsgTypeOrderAdjust = "adjustOrder"
SubMsgTypeOrderApplyCancel = "applyCancel"
// SubMsgTypeOrderApplayRefund = "applyRefund"
MsgTypeOrder = "order"
)
type CallbackResponse struct {
@@ -23,6 +24,7 @@ type CallbackMsg struct {
SubMsgType string `json:"subMsgType"`
ThingID string `json:"thingID"`
Data string `json:"data"`
Timestamp int64 `json:"timestamp"`
}
func OnCallbackMsg(msg *CallbackMsg) (retVal, errCode string, err error) {
@@ -34,3 +36,16 @@ func OnCallbackMsg(msg *CallbackMsg) (retVal, errCode string, err error) {
}
return retVal, errCode, err
}
func (p *PurchaseHandler) postFakeMsg(orderNo string, status int) {
msg := &CallbackMsg{
AppKey: appKey,
MsgType: MsgTypeOrder,
SubMsgType: utils.Int2Str(status),
ThingID: orderNo,
Timestamp: time.Now().Unix(),
}
utils.CallFuncAsync(func() {
OnCallbackMsg(msg)
})
}

View File

@@ -21,6 +21,7 @@ func init() {
CurPurchaseHandler = new(PurchaseHandler)
// 不能注册京西
// partner.RegisterPurchasePlatform(CurPurchaseHandler)
partner.RegisterPurchaseOrderHandler(CurPurchaseHandler.GetVendorID(), CurPurchaseHandler)
}
}

View File

@@ -0,0 +1,99 @@
package jx
import (
"fmt"
"net/http"
"strings"
"git.rosy.net.cn/baseapi"
"git.rosy.net.cn/baseapi/platformapi"
"git.rosy.net.cn/baseapi/utils"
)
type API struct {
token string
appKey string
appSecret string
client *http.Client
config *platformapi.APIConfig
}
const (
ResponseCodeSuccess = 200
)
const (
prodURL = "https://www.jingxicaishi.com/index.php/Weimendian/index"
)
var (
exceedLimitCodes = map[int]int{}
canRetryCodes = map[int]int{}
)
var (
jxAPI *API
)
func NewAPI(token, appKey, appSecret string, config ...*platformapi.APIConfig) *API {
curConfig := platformapi.DefAPIConfig
if len(config) > 0 {
curConfig = *config[0]
}
return &API{
token: token,
appKey: appKey,
appSecret: appSecret,
client: &http.Client{Timeout: curConfig.ClientTimeout},
config: &curConfig,
}
}
func init() {
jxAPI = NewAPI("", "", "")
}
func (a *API) AccessAPI(apiStr string, jxParams map[string]interface{}, traceInfo string) (retVal map[string]interface{}, err error) {
err = platformapi.AccessPlatformAPIWithRetry(a.client,
func() *http.Request {
params := utils.MergeMaps(jxParams, map[string]interface{}{
"timestamp": utils.GetCurTimeStr(),
})
var request *http.Request
if false {
} else {
fullURL := prodURL + "/" + apiStr
// baseapi.SugarLogger.Debug(utils.Map2URLValues(params).Encode())
request, _ = http.NewRequest(http.MethodPost, fullURL, strings.NewReader(utils.Map2URLValues(params).Encode()))
request.Header.Set("charset", "UTF-8")
request.Header.Set("Content-Type", "application/x-www-form-urlencoded")
}
if traceInfo != "" {
request.Header.Set(platformapi.KeyTrackInfo, traceInfo)
}
// request.Close = true //todo 为了性能考虑还是不要关闭
return request
},
a.config,
func(response *http.Response, bodyStr string, jsonResult1 map[string]interface{}) (errLevel string, err error) {
if jsonResult1 == nil {
return platformapi.ErrLevelRecoverableErr, fmt.Errorf("mapData is nil")
}
code := int(utils.Interface2Int64WithDefault(jsonResult1["code"], 0))
if code == ResponseCodeSuccess {
retVal = jsonResult1
return platformapi.ErrLevelSuccess, nil
}
newErr := utils.NewErrorIntCode(jsonResult1["msg"].(string), code)
if _, ok := exceedLimitCodes[code]; ok {
return platformapi.ErrLevelExceedLimit, newErr
} else if _, ok := canRetryCodes[code]; ok {
return platformapi.ErrLevelRecoverableErr, newErr
} else {
baseapi.SugarLogger.Debugf("jx AccessAPI failed, jsonResult1:%s", utils.Format4Output(jsonResult1, true))
return platformapi.ErrLevelCodeIsNotOK, newErr
}
})
return retVal, err
}

View File

@@ -0,0 +1,31 @@
package jx
import (
"git.rosy.net.cn/jx-callback/business/model"
)
var (
orderStatusMap = map[int]int{
model.OrderStatusFinishedPickup: 7,
model.OrderStatusDelivering: 8,
// 4,
model.OrderStatusFinished: 3,
model.OrderStatusCanceled: 3,
}
)
func translateOrderStatus(status int) (outStatus int) {
return status //orderStatusMap[status]
}
func (a *API) NotifyOrderStatusChanged(order *model.GoodsOrder) (err error) {
status := translateOrderStatus(order.Status)
if status > 0 {
_, err = a.AccessAPI("orderChangeStatus", map[string]interface{}{
"orderid": order.VendorOrderID,
"status": status,
"data": "", //string(utils.MustMarshal(order)),
}, "")
}
return err
}

View File

@@ -0,0 +1,21 @@
package jx
import (
"testing"
_ "git.rosy.net.cn/jx-callback/business/jxcallback/orderman"
"git.rosy.net.cn/jx-callback/business/model"
"git.rosy.net.cn/jx-callback/business/partner"
)
func TestNotifyOrderStatusChanged(t *testing.T) {
order, err := partner.CurOrderManager.LoadOrder("920931913000041", model.VendorIDJX)
if err != nil {
t.Fatal(err)
}
err = jxAPI.NotifyOrderStatusChanged(order)
if err != nil {
t.Fatal(err)
}
}

View File

@@ -25,22 +25,47 @@ func (c *PurchaseHandler) OnOrderMsg(msg *CallbackMsg) (retVal, errCode string,
}
func (c *PurchaseHandler) onOrderMsg(msg *CallbackMsg) (retVal, errCode string, err error) {
if msg.SubMsgType == SubMsgTypeOrderNew || msg.SubMsgType == SubMsgTypeOrderAdjust {
subMsgType := int(utils.Str2Int64WithDefault(msg.SubMsgType, 0))
if subMsgType == model.OrderStatusNew || subMsgType == model.OrderStatusAdjust {
var order *Data4Neworder
if err = utils.UnmarshalUseNumber([]byte(msg.Data), &order); err == nil {
retVal, errCode, err = c.onOrderNew(msg, order)
retVal, errCode, err = c.onOrderNew(msg, subMsgType, order)
}
} else {
status := c.callbackMsg2Status(msg)
err = partner.CurOrderManager.OnOrderStatusChanged(status)
}
return retVal, errCode, err
}
func (c *PurchaseHandler) onOrderNew(msg *CallbackMsg, order *Data4Neworder) (retVal, errCode string, err error) {
func (c *PurchaseHandler) callbackMsg2Status(msg *CallbackMsg) *model.OrderStatus {
orderStatus := &model.OrderStatus{
VendorOrderID: msg.ThingID,
VendorID: model.VendorIDJX,
OrderType: model.OrderTypeOrder,
RefVendorOrderID: msg.ThingID,
RefVendorID: model.VendorIDJX,
VendorStatus: msg.SubMsgType,
Status: int(utils.Str2Int64WithDefault(msg.SubMsgType, 0)),
StatusTime: utils.Timestamp2Time(msg.Timestamp),
Remark: "",
}
return orderStatus
}
func (c *PurchaseHandler) onOrderNew(msg *CallbackMsg, subMsgType int, order *Data4Neworder) (retVal, errCode string, err error) {
globals.SugarLogger.Debugf("onOrderNew orderID:%s", msg.ThingID)
order.StoreID = int(utils.Str2Int64WithDefault(order.VendorStoreID, 0))
order.GoodsOrder.Skus = order.Skus
order.VendorID = model.VendorIDJX
for _, v := range order.GoodsOrder.Skus {
v.SkuID = int(utils.Str2Int64WithDefault(v.VendorSkuID, 0))
}
jxutils.RefreshOrderSkuRelated(&order.GoodsOrder)
orderStatus := model.Order2Status(&order.GoodsOrder)
if msg.SubMsgType == SubMsgTypeOrderNew {
if subMsgType == model.OrderStatusNew {
err = partner.CurOrderManager.OnOrderNew(&order.GoodsOrder, orderStatus)
} else {
} else if subMsgType == model.OrderStatusAdjust {
err = partner.CurOrderManager.OnOrderAdjust(&order.GoodsOrder, orderStatus)
}
return retVal, errCode, err
@@ -55,10 +80,20 @@ func (c *PurchaseHandler) GetOrder(orderID string) (order *model.GoodsOrder, err
}
func (c *PurchaseHandler) AcceptOrRefuseOrder(order *model.GoodsOrder, isAcceptIt bool, userName string) (err error) {
if isAcceptIt {
order.Status = model.OrderStatusAccepted
} else {
order.Status = model.OrderStatusCanceled
}
c.postFakeMsg(order.VendorOrderID, order.Status)
jxAPI.NotifyOrderStatusChanged(order)
return err
}
func (c *PurchaseHandler) PickupGoods(order *model.GoodsOrder, isSelfDelivery bool, userName string) (err error) {
order.Status = model.OrderStatusFinishedPickup
c.postFakeMsg(order.VendorOrderID, order.Status)
jxAPI.NotifyOrderStatusChanged(order)
return err
}
@@ -83,11 +118,17 @@ func (c *PurchaseHandler) Swtich2SelfDelivered(order *model.GoodsOrder, userName
}
func (c *PurchaseHandler) SelfDeliverDelivering(order *model.GoodsOrder, userName string) (err error) {
order.Status = model.OrderStatusDelivering
c.postFakeMsg(order.VendorOrderID, order.Status)
jxAPI.NotifyOrderStatusChanged(order)
return err
}
// 京东送达接口都是一样的
func (c *PurchaseHandler) SelfDeliverDelivered(order *model.GoodsOrder, userName string) (err error) {
order.Status = model.OrderStatusFinished
c.postFakeMsg(order.VendorOrderID, order.Status)
jxAPI.NotifyOrderStatusChanged(order)
return err
}
@@ -118,3 +159,13 @@ func (c *PurchaseHandler) GetWaybillTip(ctx *jxcontext.Context, order *model.Goo
func (c *PurchaseHandler) AddWaybillTip(ctx *jxcontext.Context, order *model.GoodsOrder, tipFee2Add int64) (err error) {
return err
}
func (c *PurchaseHandler) ConfirmSelfTake(ctx *jxcontext.Context, vendorOrderID, selfTakeCode string) (err error) {
order, err := partner.CurOrderManager.LoadOrder(vendorOrderID, model.VendorIDJX)
if err == nil {
order.Status = model.OrderStatusFinished
c.postFakeMsg(order.VendorOrderID, order.Status)
jxAPI.NotifyOrderStatusChanged(order)
}
return err
}

View File

@@ -122,6 +122,17 @@ func (p *PurchaseHandler) Map2Order(orderData map[string]interface{}) (order *mo
OriginalData: string(utils.MustMarshal(result)),
ActualPayPrice: jxutils.StandardPrice2Int(utils.MustInterface2Float64(result["total"])),
}
pickType := int(utils.Interface2Int64WithDefault(result["pick_type"], 0))
if pickType == mtwmapi.OrderPickTypeSelf {
order.DeliveryType = model.OrderDeliveryTypeSelfTake
} else {
logisticsCode := utils.Interface2String(result["logistics_code"])
if logisticsCode == mtwmapi.PeiSongTypeSelf {
order.DeliveryType = model.OrderDeliveryTypeStoreSelf
} else {
order.DeliveryType = model.OrderDeliveryTypePlatform
}
}
openUID := utils.Interface2Int64WithDefault(result["openUid"], 0)
if openUID > 0 {
order.VendorUserID = utils.Int64ToStr(openUID)