341 lines
12 KiB
Go
341 lines
12 KiB
Go
package ebai
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
|
|
"git.rosy.net.cn/baseapi/platformapi/autonavi"
|
|
"git.rosy.net.cn/baseapi/platformapi/ebaiapi"
|
|
"git.rosy.net.cn/baseapi/utils"
|
|
"git.rosy.net.cn/jx-callback/business/jxcallback/scheduler"
|
|
"git.rosy.net.cn/jx-callback/business/jxutils"
|
|
"git.rosy.net.cn/jx-callback/business/jxutils/jxcontext"
|
|
"git.rosy.net.cn/jx-callback/business/jxutils/tasksch"
|
|
"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"
|
|
)
|
|
|
|
const (
|
|
VendorStorePrefix = "好菜鲜生"
|
|
)
|
|
|
|
type tEbaiStoreInfo struct {
|
|
model.Store
|
|
VendorStoreID string `orm:"column(vendor_store_id)"`
|
|
RealLastOperator string
|
|
EbaiStoreStatus int
|
|
SyncStatus int
|
|
|
|
ProvinceID int `orm:"column(province_id)"`
|
|
CityID int `orm:"column(city_id)"`
|
|
DistrictID int `orm:"column(district_id)"`
|
|
}
|
|
|
|
func (p *PurchaseHandler) GetFieldIDName() string {
|
|
return model.FieldEbaiID
|
|
}
|
|
|
|
func (p *PurchaseHandler) GetFieldSyncStatusName() string {
|
|
return model.FieldEbaiSyncStatus
|
|
}
|
|
|
|
func (p *PurchaseHandler) CreateStore(db *dao.DaoDB, storeID int, userName string) (vendorStoreID string, err error) {
|
|
var store tEbaiStoreInfo
|
|
sql := `
|
|
SELECT t1.*, t2.status ebai_store_status, t2.vendor_store_id,
|
|
IF(t1.updated_at > t2.updated_at, t1.last_operator, t2.last_operator) real_last_operator, t2.sync_status,
|
|
province.ebai_code province_id, city.ebai_code city_id, district.ebai_code district_id
|
|
FROM store t1
|
|
LEFT JOIN store_map t2 ON t1.id = t2.store_id AND t2.vendor_id = ? AND t2.deleted_at = ?
|
|
JOIN place district ON t1.district_code = district.code
|
|
JOIN place city ON t1.city_code = city.code
|
|
JOIN place province ON city.parent_code = province.code
|
|
WHERE t1.id = ? AND t2.id IS NULL;
|
|
`
|
|
if err = dao.GetRow(db, &store, sql, model.VendorIDEBAI, utils.DefaultTimeValue, storeID); err == nil {
|
|
params := genStoreMapFromStore(&store)
|
|
params["shop_id"] = store.ID
|
|
params["business_form_id"] = "179"
|
|
params["service_phone"] = store.Tel1
|
|
params["invoice_support"] = 2
|
|
params["package_box_price"] = 0
|
|
params["encrypt"] = ""
|
|
|
|
params["category1"] = ""
|
|
params["category2"] = ""
|
|
params["category3"] = ""
|
|
intVendorStoreID, err2 := api.EbaiAPI.ShopCreate(params)
|
|
if err = err2; err == nil {
|
|
return utils.Int64ToStr(intVendorStoreID), err
|
|
}
|
|
}
|
|
return "", err
|
|
}
|
|
|
|
func (p *PurchaseHandler) ReadStore(vendorStoreID string) (*model.Store, error) {
|
|
baiduShopID := utils.Str2Int64(vendorStoreID)
|
|
result, err := api.EbaiAPI.ShopGet("", baiduShopID)
|
|
if err == nil {
|
|
// globals.SugarLogger.Debug(utils.Format4Output(result, false))
|
|
retVal := &model.Store{
|
|
Address: utils.Interface2String(result["address"]),
|
|
Tel1: utils.Interface2String(result["phone"]),
|
|
}
|
|
_, retVal.Name = jxutils.SplitStoreName(utils.Interface2String(result["name"]), partner.StoreNameSeparator, VendorStorePrefix)
|
|
retVal.DeliveryType = EbaiDeliveryType2Jx(utils.Interface2String(result["delivery_type"]))
|
|
|
|
businessTime := result["business_time"].([]interface{})
|
|
btime := businessTime[0].(map[string]interface{})
|
|
retVal.OpenTime1 = jxutils.StrTime2JxOperationTime(utils.Interface2String(btime["start"].(string)), 700)
|
|
retVal.CloseTime1 = jxutils.StrTime2JxOperationTime(utils.Interface2String(btime["end"].(string)), 2000)
|
|
if len(businessTime) > 1 {
|
|
btime = businessTime[1].(map[string]interface{})
|
|
retVal.OpenTime2 = jxutils.StrTime2JxOperationTime(utils.Interface2String(btime["start"].(string)), 700)
|
|
retVal.CloseTime2 = jxutils.StrTime2JxOperationTime(utils.Interface2String(btime["end"].(string)), 2000)
|
|
}
|
|
|
|
if ebaiStatus, err2 := api.EbaiAPI.ShopBusStatusGet("", baiduShopID, ebaiapi.PlatformFlagBaidu); err2 == nil {
|
|
retVal.Status = EbaiBusStatus2JxStatus(ebaiStatus)
|
|
}
|
|
|
|
tel2 := utils.Interface2String(result["ivr_phone"])
|
|
if tel2 != "" && tel2 != retVal.Tel1 {
|
|
retVal.Tel2 = tel2
|
|
}
|
|
|
|
db := dao.GetDB()
|
|
if city, err2 := dao.GetPlaceByName(db, utils.Interface2String(result["city"]), model.PlaceLevelCity, 0); err2 == nil {
|
|
retVal.CityCode = city.Code
|
|
if district, err2 := dao.GetPlaceByName(db, utils.Interface2String(result["county"]), model.PlaceLevelDistrict, city.Code); err2 == nil {
|
|
retVal.DistrictCode = district.Code
|
|
}
|
|
}
|
|
lng := utils.MustInterface2Float64(result["longitude"])
|
|
lat := utils.MustInterface2Float64(result["latitude"])
|
|
if utils.Interface2String(result["coord_type"]) == ebaiapi.CoordTypeBaidu {
|
|
var err2 error
|
|
if lng, lat, err2 = api.AutonaviAPI.CoordinateConvert(lng, lat, autonavi.CoordSysBaidu); err2 != nil {
|
|
return nil, err2
|
|
}
|
|
}
|
|
retVal.Lng = jxutils.StandardCoordinate2Int(lng)
|
|
retVal.Lat = jxutils.StandardCoordinate2Int(lat)
|
|
|
|
retVal.ID = int(utils.Str2Int64WithDefault(utils.Interface2String(result["shop_id"]), 0))
|
|
|
|
retVal.DeliveryRangeType = model.DeliveryRangeTypePolygon
|
|
retVal.DeliveryRange = EbaiDeliveryRegion2Jx(result["delivery_region"])
|
|
|
|
return retVal, nil
|
|
}
|
|
return nil, err
|
|
}
|
|
|
|
func (p *PurchaseHandler) UpdateStore(db *dao.DaoDB, storeID int, userName string) (err error) {
|
|
var stores []*tEbaiStoreInfo
|
|
sql := `
|
|
SELECT t1.*, t2.status ebai_store_status, t2.vendor_store_id,
|
|
IF(t1.updated_at > t2.updated_at, t1.last_operator, t2.last_operator) real_last_operator, t2.sync_status
|
|
FROM store t1
|
|
JOIN store_map t2 ON t1.id = t2.store_id AND t2.vendor_id = ? AND (t2.deleted_at = ? OR t2.sync_status <> 0)
|
|
WHERE t1.id = ?
|
|
ORDER BY t2.updated_at
|
|
`
|
|
if err = dao.GetRows(db, &stores, sql, model.VendorIDEBAI, utils.DefaultTimeValue, storeID); err == nil {
|
|
for _, store := range stores {
|
|
params := genStoreMapFromStore(store)
|
|
// globals.SugarLogger.Debug(utils.Format4Output(params, false))
|
|
if globals.EnableStoreWrite {
|
|
if err = api.EbaiAPI.ShopUpdate(params); err == nil {
|
|
shopID := 0
|
|
if store.SyncStatus&model.SyncFlagDeletedMask == 0 {
|
|
shopID = store.ID
|
|
}
|
|
store2, err2 := p.ReadStore(store.VendorStoreID)
|
|
if err = err2; err == nil {
|
|
if store2.ID == store.ID {
|
|
shopID = -1
|
|
}
|
|
}
|
|
if err == nil {
|
|
if shopID > 0 {
|
|
err = api.EbaiAPI.ShopIDBatchUpdate([]string{store.VendorStoreID}, []string{utils.Int2Str(shopID)})
|
|
} else if shopID == 0 {
|
|
// todo remove out shop id
|
|
}
|
|
}
|
|
if err == nil {
|
|
mergeStatus := jxutils.MergeStoreStatus(store.Status, store.EbaiStoreStatus)
|
|
if mergeStatus == model.StoreStatusOpened {
|
|
err = api.EbaiAPI.ShopOnline("", utils.Str2Int64(store.VendorStoreID))
|
|
} else if mergeStatus == model.StoreStatusClosed {
|
|
err = api.EbaiAPI.ShopOffline("", utils.Str2Int64(store.VendorStoreID))
|
|
} else if mergeStatus == model.StoreStatusClosed {
|
|
err = api.EbaiAPI.ShopClose("", utils.Str2Int64(store.VendorStoreID))
|
|
}
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return err
|
|
}
|
|
|
|
func (p *PurchaseHandler) RefreshAllStoresID(ctx *jxcontext.Context, parentTask tasksch.ITask, isAsync bool) (hint string, err error) {
|
|
globals.SugarLogger.Debugf("ebai RefreshAllStoresID")
|
|
const batchSize = 50
|
|
const stepCount = 3
|
|
var stores []*tEbaiStoreInfo
|
|
db := dao.GetDB()
|
|
rootTask := tasksch.NewSeqTask("ebai RefreshAllStoresID", ctx.GetUserName(), func(task *tasksch.SeqTask, step int, params ...interface{}) (result interface{}, err error) {
|
|
switch step {
|
|
case 0:
|
|
err = dao.GetRows(db, &stores, `
|
|
SELECT t1.*, t2.vendor_store_id
|
|
FROM store t1
|
|
JOIN store_map t2 ON t1.id = t2.store_id AND t2.deleted_at = ? AND t2.vendor_id = ?
|
|
WHERE t1.deleted_at = ?
|
|
`, utils.DefaultTimeValue, model.VendorIDEBAI, utils.DefaultTimeValue)
|
|
default:
|
|
taskName := "ebai RefreshAllStoresID update to custom id"
|
|
if step != stepCount-1 {
|
|
taskName = "ebai RefreshAllStoresID update to uuid"
|
|
}
|
|
task1 := tasksch.NewParallelTask(taskName, tasksch.NewParallelConfig().SetBatchSize(batchSize), ctx.GetUserName(), func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) {
|
|
baiduShopIDs := make([]string, len(batchItemList))
|
|
shopIDs := make([]string, len(batchItemList))
|
|
for k, v := range batchItemList {
|
|
store := v.(*tEbaiStoreInfo)
|
|
baiduShopIDs[k] = store.VendorStoreID
|
|
shopIDs[k] = utils.Int2Str(store.ID)
|
|
if step != stepCount-1 {
|
|
shopIDs[k] = utils.GetUUID()
|
|
}
|
|
}
|
|
if globals.EnableStoreWrite {
|
|
err = api.EbaiAPI.ShopIDBatchUpdate(baiduShopIDs, shopIDs)
|
|
}
|
|
return nil, err
|
|
}, stores)
|
|
task.AddChild(task1).Run()
|
|
_, err = task1.GetResult(0)
|
|
}
|
|
return nil, err
|
|
}, stepCount)
|
|
|
|
ctx.SetTaskOrAddChild(rootTask, parentTask)
|
|
rootTask.Run()
|
|
if !isAsync {
|
|
_, err = rootTask.GetResult(0)
|
|
}
|
|
return rootTask.ID, err
|
|
}
|
|
|
|
func EbaiDeliveryType2Jx(deliveryType string) int8 {
|
|
spIndex := strings.Index(deliveryType, "|")
|
|
baiduDeliveryType := utils.Str2Int64(deliveryType[spIndex+1:])
|
|
switch baiduDeliveryType {
|
|
case ebaiapi.DeliveryTypeBaiduLogistics:
|
|
return scheduler.StoreDeliveryTypeByPlatform
|
|
case ebaiapi.DeliveryTypeBaiduDeliveryBySelf:
|
|
return scheduler.StoreDeliveryTypeByStore
|
|
case ebaiapi.DeliveryTypeBaiduCrowdSourcing:
|
|
return scheduler.StoreDeliveryTypeCrowdSourcing
|
|
default:
|
|
return scheduler.StoreDeliveryTypeCrowdSourcing
|
|
}
|
|
}
|
|
|
|
func EbaiDeliveryRegion2Jx(deliveryRegion interface{}) string {
|
|
realDeliveryRegion := deliveryRegion.([]interface{})
|
|
if len(realDeliveryRegion) > 0 {
|
|
region := deliveryRegion.([]interface{})[0].(map[string]interface{})["region"].([]interface{})[0].([]interface{})
|
|
coords := make([]string, len(region))
|
|
for k, v := range region {
|
|
mapV := v.(map[string]interface{})
|
|
coords[k] = fmt.Sprintf("%.6f,%.6f", utils.MustInterface2Float64(mapV["longitude"]), utils.MustInterface2Float64(mapV["latitude"]))
|
|
}
|
|
return strings.Join(coords, ";")
|
|
}
|
|
return ""
|
|
}
|
|
|
|
func JxDeliveryRegion2Ebai(store *model.Store) interface{} {
|
|
rangeStr := store.DeliveryRange
|
|
if store.DeliveryRangeType == model.DeliveryRangeTypeRadius {
|
|
rangeStr = jxutils.GetPolygonFromCircleStr(jxutils.IntCoordinate2Standard(store.Lng), jxutils.IntCoordinate2Standard(store.Lat), utils.Str2Float64(store.DeliveryRange), 8)
|
|
}
|
|
pointPairs := strings.Split(rangeStr, ";")
|
|
region := make([]map[string]interface{}, len(pointPairs))
|
|
for k, v := range pointPairs {
|
|
pointPair := strings.Split(v, ",")
|
|
region[k] = map[string]interface{}{
|
|
"longitude": utils.Str2Float64(pointPair[0]),
|
|
"latitude": utils.Str2Float64(pointPair[1]),
|
|
}
|
|
}
|
|
deliveryRegion := []interface{}{
|
|
map[string]interface{}{
|
|
"name": "主要配送区",
|
|
"delivery_fee": 600,
|
|
"delivery_time": "60",
|
|
"min_buy_free": "0",
|
|
"min_order_price": "0",
|
|
"region": []interface{}{
|
|
region,
|
|
},
|
|
},
|
|
}
|
|
return deliveryRegion
|
|
}
|
|
|
|
func JxBusinessTime2Ebai(store *model.Store) interface{} {
|
|
bTime := make([]map[string]interface{}, 1)
|
|
bTime[0] = map[string]interface{}{
|
|
"start": jxutils.JxOperationTime2StrTime(store.OpenTime1),
|
|
"end": jxutils.JxOperationTime2StrTime(store.CloseTime1),
|
|
}
|
|
if store.OpenTime2 != 0 {
|
|
bTime = append(bTime, map[string]interface{}{
|
|
"start": jxutils.JxOperationTime2StrTime(store.OpenTime2),
|
|
"end": jxutils.JxOperationTime2StrTime(store.CloseTime2),
|
|
})
|
|
}
|
|
return bTime
|
|
}
|
|
|
|
func genStoreMapFromStore(store *tEbaiStoreInfo) map[string]interface{} {
|
|
params := map[string]interface{}{
|
|
"name": jxutils.ComposeStoreName(store.Name, partner.StoreNameSeparator, VendorStorePrefix),
|
|
"phone": store.Tel1,
|
|
"longitude": jxutils.IntCoordinate2Standard(store.Lng),
|
|
"latitude": jxutils.IntCoordinate2Standard(store.Lat),
|
|
"address": store.Address,
|
|
"coord_type": ebaiapi.CoordTypeAutonavi, // 一直用高德
|
|
"delivery_region": JxDeliveryRegion2Ebai(&store.Store),
|
|
"business_time": JxBusinessTime2Ebai(&store.Store),
|
|
}
|
|
if store.VendorStoreID != "" {
|
|
params["baidu_shop_id"] = store.VendorStoreID
|
|
}
|
|
if store.Tel2 != "" {
|
|
params["ivr_phone"] = store.Tel2
|
|
}
|
|
if store.ProvinceID != 0 {
|
|
params["province"] = store.ProvinceID
|
|
}
|
|
if store.CityID != 0 {
|
|
params["city"] = store.CityID
|
|
}
|
|
if store.DistrictID != 0 {
|
|
params["county"] = store.DistrictID
|
|
}
|
|
return params
|
|
}
|