From 97c092cd2620fe8892190e929cf459948863889f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=82=B9=E5=AE=97=E6=A5=A0?= Date: Fri, 30 Sep 2022 17:16:22 +0800 Subject: [PATCH] dingdan --- business/jxstore/cms/store.go | 24 + business/jxstore/cms/sync_store_sku.go | 4 +- business/jxstore/misc/misc.go | 4 + business/jxutils/jxutils.go | 2 - business/jxutils/tasks/configrefresh.go | 90 +- business/model/api_config.go | 1 + business/model/const.go | 42 +- business/model/dao/dao_order.go | 18 + business/model/dao/store.go | 2 +- business/model/order_financial.go | 4 +- business/model/store.go | 2 +- business/partner/partner_store_sku.go | 40 +- business/partner/purchase/ebai/order.go | 4 +- business/partner/purchase/jd/order.go | 20 +- business/partner/purchase/jd/order_afs.go | 30 +- business/partner/purchase/mtwm/order.go | 6 +- business/partner/purchase/tiktok_store/act.go | 20 +- .../partner/purchase/tiktok_store/callback.go | 23 +- .../purchase/tiktok_store/financial.go | 134 +- .../partner/purchase/tiktok_store/mtwm.go | 47 +- .../partner/purchase/tiktok_store/order.go | 1157 ++++++++--------- .../purchase/tiktok_store/order_afs.go | 309 +---- .../purchase/tiktok_store/order_afs_utils.go | 294 +++++ .../purchase/tiktok_store/order_comment.go | 124 +- .../purchase/tiktok_store/store_sku2.go | 799 ++++++------ .../purchase/tiktok_store/store_sku2_test.go | 64 - .../purchase/tiktok_store/store_sku2_utils.go | 143 ++ .../purchase/tiktok_store/store_sku_test.go | 46 - .../purchase/tiktok_store/store_test.go | 43 - .../partner/purchase/tiktok_store/waybill.go | 108 +- conf/app.conf | 6 + controllers/tiktok_store.go | 14 +- globals/api/api.go | 10 +- globals/api/apimanager/apimanager.go | 2 + globals/globals.go | 4 + main.go | 8 +- 36 files changed, 1753 insertions(+), 1895 deletions(-) create mode 100644 business/partner/purchase/tiktok_store/order_afs_utils.go delete mode 100644 business/partner/purchase/tiktok_store/store_sku2_test.go create mode 100644 business/partner/purchase/tiktok_store/store_sku2_utils.go delete mode 100644 business/partner/purchase/tiktok_store/store_sku_test.go delete mode 100644 business/partner/purchase/tiktok_store/store_test.go diff --git a/business/jxstore/cms/store.go b/business/jxstore/cms/store.go index a45fd31d8..b955ee37c 100644 --- a/business/jxstore/cms/store.go +++ b/business/jxstore/cms/store.go @@ -4388,6 +4388,7 @@ func GetBrandStore(ctx *jxcontext.Context, name string) (brands []*model.BrandSt return brands, err } +// RefreshMTWMToken 刷新美团外卖门token func RefreshMTWMToken(ctx *jxcontext.Context) (err error) { var ( db = dao.GetDB() @@ -4409,6 +4410,29 @@ func RefreshMTWMToken(ctx *jxcontext.Context) (err error) { return err } +// RefreshTiktokShopToken 属性抖店门店tokne +func RefreshTiktokShopToken(ctx *jxcontext.Context) (err error) { + var ( + db = dao.GetDB() + ) + if time.Now().YearDay()%2 != 0 { + return + } + //token是三天,两天刷新一次token + storeMaps, _ := dao.GetStoresMapList(db, []int{model.VendorIDDD}, nil, nil, model.StoreStatusAll, model.StoreIsSyncAll, "", "", globals.Mtwm2Code) + for _, v := range storeMaps { + if v.MtwmRefreshToken != "" { + api.TiktokStore.SetRefreshToken(v.MtwmRefreshToken) + if result, err := api.TiktokStore.RefreshToken(); err == nil { + v.MtwmToken = result.AccessToken + v.MtwmRefreshToken = result.RefreshToken + dao.UpdateEntity(db, v, "MtwmToken", "MtwmRefreshToken") + } + } + } + return err +} + func StoreConfirmAct(ctx *jxcontext.Context, status, msgStatusID int) (err error) { msgStatus := &model.MessageStatus{} msgStatus.ID = msgStatusID diff --git a/business/jxstore/cms/sync_store_sku.go b/business/jxstore/cms/sync_store_sku.go index 1aef9c210..e6b5c182d 100644 --- a/business/jxstore/cms/sync_store_sku.go +++ b/business/jxstore/cms/sync_store_sku.go @@ -262,6 +262,8 @@ func storeSkuSyncInfo2Bare(inSku *dao.StoreSkuSyncInfo) (outSku *partner.StoreSk IsDeletedBySku: inSku.IsDeletedBySku, Stock: inSku.Stock, VendorOrgCode: inSku.VendorOrgCode, + SpecUnit: inSku.SpecUnit, + SpecQuality: inSku.SpecQuality, } if !isStoreSkuSyncNeedDelete(inSku) { outSku.Stock = model.MaxStoreSkuStockQty @@ -731,7 +733,7 @@ func syncStoreSkuNew(ctx *jxcontext.Context, parentTask tasksch.ITask, causeFlag updateStoreSku(dao.GetDB(), vendorID, successList, model.SyncFlagNewMask) } return nil, len(successList), err - }, ctx, task, createList, 1 /*singleStoreHandler.GetStoreSkusBatchSize(partner.FuncCreateStoreSkus)*/, isContinueWhenError2) + }, ctx, task, createList, 1, isContinueWhenError2) if err != nil { globals.SugarLogger.Debug("create sku wrong on :", err) } diff --git a/business/jxstore/misc/misc.go b/business/jxstore/misc/misc.go index f91123388..e44e6bc8b 100644 --- a/business/jxstore/misc/misc.go +++ b/business/jxstore/misc/misc.go @@ -292,6 +292,10 @@ func Init() { ScheduleTimerFunc("RefreshMTWMToken", func() { cms.RefreshMTWMToken(jxcontext.AdminCtx) }, updateActStatusTimeList) + //刷新抖音门店token + ScheduleTimerFunc("RefreshTiktokShopToken", func() { + cms.RefreshTiktokShopToken(jxcontext.AdminCtx) + }, updateActStatusTimeList) //获取最新平台流量活动 ScheduleTimerFunc("GetNewVendorPopActs", func() { act.GetNewVendorPopActs(jxcontext.AdminCtx) diff --git a/business/jxutils/jxutils.go b/business/jxutils/jxutils.go index 6abc83bc3..f8e639347 100644 --- a/business/jxutils/jxutils.go +++ b/business/jxutils/jxutils.go @@ -220,9 +220,7 @@ func GetPossibleVendorIDFromAfsOrderID(afsOrderID string) (vendorID int) { } func ComposeUniversalOrderID(orderID string, vendorID int) string { - // return fmt.Sprintf("%s|%d", orderID, vendorID) return orderID // 当前用长度就能区分,先不加上vendorID - // return orderID + utils.Int64ToStr(time.Now().Unix()) } func GetUniversalOrderIDFromWaybill(bill *model.Waybill) string { diff --git a/business/jxutils/tasks/configrefresh.go b/business/jxutils/tasks/configrefresh.go index 580452ce9..59d6472e1 100644 --- a/business/jxutils/tasks/configrefresh.go +++ b/business/jxutils/tasks/configrefresh.go @@ -473,48 +473,48 @@ func getWeimobTokenFromRemote(oldToken string) (tokenInfo *syseventhub.TokenInfo } // RefreshTiktokToken 刷新抖店token -func RefreshTiktokToken() (err error) { - if api.TiktokStore != nil { - err = RefreshConfig("tiktok", tiktokTokenExpires, func() (token string, expireTimeStr string, refreshToken string) { - curConfig := &legacymodel.Config{ - Thirdparty: "tiktok", - } - if err := orm.NewOrm().Read(curConfig, "Thirdparty"); err != nil { - globals.SugarLogger.Errorf("RefreshTiktokToken RefreshToken failed with error:%v", err) - } - if curConfig.RefreshToken == "" { - if tokenInfo, err := api.TiktokStore.CreateToken(curConfig.Token); err != nil { - globals.SugarLogger.Errorf("tiktok store get token err:%v", err) - } else { - token = tokenInfo.AccessToken - refreshToken = tokenInfo.RefreshToken - expireTimeStr = time.Unix(tokenInfo.ExpiresIn, 0).Format("2006-01-02 15:04:05") - } - } else { - expireIn, _ := time.Parse("2006-01-02 15:04:05", curConfig.Date) - if expireIn.Unix() < time.Now().Unix() { - api.TiktokStore.SetToken(curConfig.Token) - api.TiktokStore.SetRefreshToken(curConfig.RefreshToken) - if tokenInfo, err := api.TiktokStore.RefreshToken(); err == nil { - token = tokenInfo.AccessToken - refreshToken = tokenInfo.RefreshToken - expireTimeStr = time.Unix(tokenInfo.ExpiresIn, 0).Format("2006-01-02 15:04:05") - } else { - globals.SugarLogger.Errorf("RefreshTiktokToken RefreshToken failed with error:%v", err) - } - } - } - - sql := `UPDATE config SET token = ?,refresh_token = ?,data = ? WHERE thirdparty = ?` - dao.ExecuteSQL(dao.GetDB(), sql, []interface{}{ - token, refreshToken, expireTimeStr, "tiktok", - }) - return token, expireTimeStr, refreshToken - }, func(value, v2 string) { - globals.SugarLogger.Debugf("RefreshFnToken setter value:[%s],[%s]", value, v2) - api.TiktokStore.SetToken(value) - api.TiktokStore.SetRefreshToken(v2) - }) - } - return err -} +//func RefreshTiktokToken() (err error) { +// if api.TiktokStore != nil { +// err = RefreshConfig("tiktok", tiktokTokenExpires, func() (token string, expireTimeStr string, refreshToken string) { +// curConfig := &legacymodel.Config{ +// Thirdparty: "tiktok", +// } +// if err := orm.NewOrm().Read(curConfig, "Thirdparty"); err != nil { +// globals.SugarLogger.Errorf("RefreshTiktokToken RefreshToken failed with error:%v", err) +// } +// if curConfig.RefreshToken == "" { +// if tokenInfo, err := api.TiktokStore.CreateToken(curConfig.Token); err != nil { +// globals.SugarLogger.Errorf("tiktok store get token err:%v", err) +// } else { +// token = tokenInfo.AccessToken +// refreshToken = tokenInfo.RefreshToken +// expireTimeStr = time.Unix(tokenInfo.ExpiresIn, 0).Format("2006-01-02 15:04:05") +// } +// } else { +// expireIn, _ := time.Parse("2006-01-02 15:04:05", curConfig.Date) +// if expireIn.Unix() < time.Now().Unix() { +// api.TiktokStore.SetToken(curConfig.Token) +// api.TiktokStore.SetRefreshToken(curConfig.RefreshToken) +// if tokenInfo, err := api.TiktokStore.RefreshToken(); err == nil { +// token = tokenInfo.AccessToken +// refreshToken = tokenInfo.RefreshToken +// expireTimeStr = time.Unix(tokenInfo.ExpiresIn, 0).Format("2006-01-02 15:04:05") +// } else { +// globals.SugarLogger.Errorf("RefreshTiktokToken RefreshToken failed with error:%v", err) +// } +// } +// } +// +// sql := `UPDATE config SET token = ?,refresh_token = ?,data = ? WHERE thirdparty = ?` +// dao.ExecuteSQL(dao.GetDB(), sql, []interface{}{ +// token, refreshToken, expireTimeStr, "tiktok", +// }) +// return token, expireTimeStr, refreshToken +// }, func(value, v2 string) { +// globals.SugarLogger.Debugf("RefreshFnToken setter value:[%s],[%s]", value, v2) +// api.TiktokStore.SetToken(value) +// api.TiktokStore.SetRefreshToken(v2) +// }) +// } +// return err +//} diff --git a/business/model/api_config.go b/business/model/api_config.go index 09ab1fbc9..673251492 100644 --- a/business/model/api_config.go +++ b/business/model/api_config.go @@ -146,6 +146,7 @@ var ( VendorIDQiNiuCloud: "七牛云", VendorIDShowAPI: "万维易源", VendorGoMei: "国美", + VendorIDDD: "抖店平台", } VendorInfoMap = map[int]*VendorInfo{ diff --git a/business/model/const.go b/business/model/const.go index e4d0230d4..500d4e0e5 100644 --- a/business/model/const.go +++ b/business/model/const.go @@ -214,9 +214,9 @@ var ( ) const ( - OrderTypeOrder = 1 - OrderTypeWaybill = 2 - OrderTypeAfsOrder = 3 + OrderTypeOrder = 1 // 新订单 + OrderTypeWaybill = 2 // 运单 + OrderTypeAfsOrder = 3 // 售后单 ) // https://blog.csdn.net/a13570320979/article/details/51366355 @@ -245,19 +245,23 @@ const ( OrderStatusAdjust = -65 // 原值-35 订单调整完成 OrderStatusApplyUrgeOrder = -55 // 原值-15 - OrderStatusUnlocked = -25 - OrderStatusLocked = -20 - OrderStatusUndoApplyCancel = -10 - OrderStatusVendorRejectCancel = -7 - OrderStatusVendorAgreeCancel = -6 - OrderStatusApplyCancel = -5 + OrderStatusUnlocked = -25 + OrderStatusLocked = -20 + OrderStatusUndoApplyCancel = -10 + OrderStatusVendorRejectCancel = -7 + OrderStatusVendorAgreeCancel = -6 + OrderStatusApplyCancel = -5 // 发货前退款(取消) + OrderStatusAfterShipmentCancel = -4 // 发货后退款(取消) + OrderStatusAfterReceivingCancel = -3 // 收货后退款(取消) - OrderStatusUnknown = 0 - OrderStatusWait4Pay = 2 // 原值-60 下单待支付 - OrderStatusWaitAccepted = 3 // 待接单,目前饿百用 - OrderStatusNew = 5 // 新订单,实际是已经支付 - OrderStatusAccepted = 10 // 已经接单,也即待出库,待拣货 - OrderStatusFinishedPickup = 15 // 拣货完成 + OrderStatusUnknown = 0 + OrderStatusWait4Pay = 2 // 原值-60 下单待支付 + OrderStatusWaitAccepted = 3 // 待接单,目前饿百用 + OrderStatusNew = 5 // 新订单,实际是已经支付 + OrderStatusPartDeliverGoods = 6 // 部分发货 + OrderStatusPartPay = 7 // 部分支付 + OrderStatusAccepted = 10 // 已经接单,也即待出库,待拣货 + OrderStatusFinishedPickup = 15 // 拣货完成 OrderStatusApplyFailedGetGoods = 17 // 取货失败待审核 OrderStatusAgreeFailedGetGoods = 18 // 取货失败 @@ -402,6 +406,14 @@ const ( AfsAppealTypeRefund = 1 // 仅退款 AfsAppealTypeReturnAndRefund = 2 // 退货退款 AfsAppealTypeNewGoods = 3 // 重发新商品(即京东到家的直赔) + // 新补 + AfsAppealTypeSendPkgOnlyReturnMoney = 4 // 已发货仅退款 + AfsAppealTypeReturnMoney = 5 // 未发货仅退款 + AfsAppealTypeChangePkg = 6 // 换货 + AfsAppealTypeSystemCancel = 7 // 系统取消 + AfsAppealTypeUserCancel = 8 // 用户取消 + AfsAppealTypeInsuredPrice = 9 // 价保 + AfsAppealTypeReissue = 10 // 补寄 ) const ( diff --git a/business/model/dao/dao_order.go b/business/model/dao/dao_order.go index 0b943cc25..5a3dae209 100644 --- a/business/model/dao/dao_order.go +++ b/business/model/dao/dao_order.go @@ -1343,6 +1343,24 @@ func GetJxOrderCount(db *DaoDB, storeID int, orderID string, date time.Time) (co return count, err } +// GetVendorOrderNumber 查询当前平台当然订单数(抖音没有订单seq) +func GetVendorOrderNumber(db *DaoDB, vendorId int64, vendorStoreId string) (count int, err error) { + date := time.Now() + sql := ` + SELECT COUNT(*) ct + FROM goods_order t1 + WHERE t1.vendor_store_id = ? AND t1.vendor_id = ? AND t1.order_created_at >= ? AND t1.order_created_at < ? + ` + sqlParams := []interface{}{ + vendorStoreId, + vendorId, + utils.Time2Date(date), + utils.Time2Date(date).Add(24 * time.Hour), + } + + return count, GetRow(db, &count, sql, sqlParams...) +} + func GetOrdersForJxPay(db *DaoDB, finishTimeBegin, finishTimeEnd time.Time) (goods []*GoodsOrderPay, err error) { sql := ` SELECT a.*,b.transaction_id diff --git a/business/model/dao/store.go b/business/model/dao/store.go index 449b41b02..8f13399e6 100644 --- a/business/model/dao/store.go +++ b/business/model/dao/store.go @@ -60,7 +60,7 @@ type StoreDetail struct { YbAppKey string `json:"ybAppKey"` YbStorePrefix string `json:"ybStorePrefix"` - MtwmToken string `json:"mtwmToken"` + MtwmToken string `json:"mtwmToken"` // 当vendor为美团时存储美团token,为抖店时存储抖店token EbaiSupplierID string `json:"ebaiSupplierID"` BrandName string `json:"brandName"` //品牌信息 diff --git a/business/model/order_financial.go b/business/model/order_financial.go index 9dea95274..855c10c2e 100644 --- a/business/model/order_financial.go +++ b/business/model/order_financial.go @@ -87,8 +87,8 @@ type AfsOrder struct { VendorReasonType string `orm:"size(255)" json:"vendorReasonType"` // 原始售后原因 ReasonDesc string `orm:"size(1024)" json:"reasonDesc"` // 售后原因描述 ReasonImgList string `orm:"size(1024)" json:"reasonImgList"` // 售后描述图片 - AppealType int8 `json:"appealType"` // 售后方式 - VendorAppealType string `orm:"size(255)" json:"vendorAppealType"` // 原始售后方式 + AppealType int8 `json:"appealType"` // 售后方式(本地) + VendorAppealType string `orm:"size(255)" json:"vendorAppealType"` // 原始售后方式(第三方平台) Flag int `json:"flag"` RefundType int8 `json:"refundType"` RefuseReason string `orm:"size(1024)" json:"refuseReason"` diff --git a/business/model/store.go b/business/model/store.go index 544e0f5ad..d74c7eaa0 100644 --- a/business/model/store.go +++ b/business/model/store.go @@ -489,7 +489,7 @@ type StoreMap struct { YbAppKey string `orm:"size(255)" json:"ybAppKey"` YbStorePrefix string `orm:"size(255)" json:"ybStorePrefix"` - MtwmToken string `orm:"size(255)" json:"mtwmToken"` //美团外卖商超token,有效期30天,每20天刷一次 + MtwmToken string `orm:"size(512)" json:"mtwmToken"` //美团外卖商超token,有效期30天,每20天刷一次 MtwmRefreshToken string `orm:"size(255)" json:"mtwmRefreshToken"` //美团外卖商超refreshToken EbaiSupplierID string `orm:"column(ebai_supplier_id)" json:"ebaiSupplierID"` //饿百供应商ID diff --git a/business/partner/partner_store_sku.go b/business/partner/partner_store_sku.go index 62f3ab56e..86ba0a06f 100644 --- a/business/partner/partner_store_sku.go +++ b/business/partner/partner_store_sku.go @@ -14,17 +14,15 @@ import ( const ( // FuncGetStoreSkusBareInfo = 1 // 此接口要求实现为不限制批处理大小的 - FuncUpdateStoreSkusStock = 2 - FuncUpdateStoreSkusStatus = 3 - FuncUpdateStoreSkusPrice = 4 - - FuncGetStoreSkusFullInfo = 6 - FuncCreateStoreSkus = 7 - FuncUpdateStoreSkus = 8 - FuncDeleteStoreSkus = 9 - - FuncCreateActs = 10 - FuncCancelActs = 11 + FuncUpdateStoreSkusStock = 2 // 更新门店库存 + FuncUpdateStoreSkusStatus = 3 // 更新门店状态 + FuncUpdateStoreSkusPrice = 4 // 更新门店价格 + FuncGetStoreSkusFullInfo = 6 // 获取门店商品完整信息 + FuncCreateStoreSkus = 7 // 创建门店商品 + FuncUpdateStoreSkus = 8 // 修改门店商品 + FuncDeleteStoreSkus = 9 // 删除门店商品 + FuncCreateActs = 10 // 创建活动 + FuncCancelActs = 11 // 取消活动 ) const ( @@ -46,15 +44,17 @@ type StoreSkuInfo struct { Seq int `json:"seq,omitempty"` - ActPrice int64 `json:"actPrice,omitempty"` - VendorActID string `json:"vendorActID,omitempty"` - IsSpecialty int `json:"isSpecialty,omitempty"` - JxPrice int64 `json:"jxPrice,omitempty"` - JxUnitPrice int64 `json:"jxUnitPrice,omitempty"` - VendorSkuID2 string `json:"vendorSkuID2,omitempty"` - JdsStockSwitch int `json:"jdsStockSwitch"` - IsDeletedBySku bool `json:"isDeletedBySku"` - VendorOrgCode string `json:"vendorOrgCode"` + ActPrice int64 `json:"actPrice,omitempty"` + VendorActID string `json:"vendorActID,omitempty"` + IsSpecialty int `json:"isSpecialty,omitempty"` + JxPrice int64 `json:"jxPrice,omitempty"` + JxUnitPrice int64 `json:"jxUnitPrice,omitempty"` + VendorSkuID2 string `json:"vendorSkuID2,omitempty"` + JdsStockSwitch int `json:"jdsStockSwitch"` + IsDeletedBySku bool `json:"isDeletedBySku"` + VendorOrgCode string `json:"vendorOrgCode"` + SpecUnit string `json:"specUnit"` + SpecQuality float32 `json:"specQuality"` } type StoreSkuInfoWithErr struct { diff --git a/business/partner/purchase/ebai/order.go b/business/partner/purchase/ebai/order.go index d6a3f3222..da2e5311e 100644 --- a/business/partner/purchase/ebai/order.go +++ b/business/partner/purchase/ebai/order.go @@ -527,12 +527,12 @@ func (c *PurchaseHandler) callbackMsg2Status(msg *ebaiapi.CallbackMsg) (orderSta StatusTime: utils.Timestamp2Time(msg.Timestamp), VendorStatus: msg.Cmd, } - if msg.Cmd == ebaiapi.CmdOrderUserCancel { + if msg.Cmd == ebaiapi.CmdOrderUserCancel { // 用户取消订单 msgType := int(utils.MustInterface2Int64(msg.Body["type"])) cancelType := int(utils.MustInterface2Int64(msg.Body["cancel_type"])) orderStatus.Remark = buildFullReason(utils.Interface2String(msg.Body["cancel_reason"]), utils.Interface2String(msg.Body["addition_reason"])) orderStatus.VendorStatus = msg.Cmd + "-" + utils.Int2Str(msgType) - if cancelType == ebaiapi.OrderUserCancelTypeBeforeSale { + if cancelType == ebaiapi.OrderUserCancelTypeBeforeSale { // 完成前取消 if msgType == ebaiapi.OrderUserCancelApply /* || msgType == ebaiapi.OrderUserCancelCSIntervene */ { orderStatus.Status = model.OrderStatusApplyCancel } else if msgType == ebaiapi.OrderUserCancelCSRefused || diff --git a/business/partner/purchase/jd/order.go b/business/partner/purchase/jd/order.go index 4542810b7..4bac96ded 100644 --- a/business/partner/purchase/jd/order.go +++ b/business/partner/purchase/jd/order.go @@ -25,23 +25,23 @@ import ( var ( VendorStatus2StatusMap = map[string]int{ - jdapi.OrderStatusPurchased: model.OrderStatusNew, - jdapi.OrderStatusWaitOutStore: model.OrderStatusAccepted, - jdapi.StatusIDWaitOutStore: model.OrderStatusAccepted, - jdapi.OrderStatusFinishedPickup: model.OrderStatusFinishedPickup, + jdapi.OrderStatusPurchased: model.OrderStatusNew, // 新订单 + jdapi.OrderStatusWaitOutStore: model.OrderStatusAccepted, // 已接单 + jdapi.StatusIDWaitOutStore: model.OrderStatusAccepted, // 已接单 + jdapi.OrderStatusFinishedPickup: model.OrderStatusFinishedPickup, // 拣货完成 jdapi.OrderStatusDelivering: model.OrderStatusDelivering, - jdapi.OrderStatusDelivered: model.OrderStatusFinished, + jdapi.OrderStatusDelivered: model.OrderStatusFinished, // 订单完成 jdapi.OrderStatusFinished: model.OrderStatusFinished, // todo 这个状态不是真正都完成的意思? - jdapi.OrderStatusCanceled: model.OrderStatusCanceled, + jdapi.OrderStatusCanceled: model.OrderStatusCanceled, // 订单已经取消 - jdapi.OrderStatusAdjust: model.OrderStatusAdjust, + jdapi.OrderStatusAdjust: model.OrderStatusAdjust, // 订单调整 jdapi.OrderStatusUserApplyCancel: model.OrderStatusApplyCancel, jdapi.OrderStatusLocked: model.OrderStatusLocked, jdapi.OrderStatusUnlocked: model.OrderStatusUnlocked, - jdapi.OrderStatusVenderAgreeCancel: model.OrderStatusVendorAgreeCancel, - jdapi.OrderStatusVenderRejectCancel: model.OrderStatusVendorRejectCancel, - jdapi.CallbackMsgOrderAddTips: model.OrderStatusWaybillTipChanged, + jdapi.OrderStatusVenderAgreeCancel: model.OrderStatusVendorAgreeCancel, // 同意取消 + jdapi.OrderStatusVenderRejectCancel: model.OrderStatusVendorRejectCancel, // 拒绝取消 + jdapi.CallbackMsgOrderAddTips: model.OrderStatusWaybillTipChanged, // 小飞 } deliveryTypeMap = map[int]string{ jdapi.CarrierNoCrowdSourcing: model.OrderDeliveryTypePlatform, diff --git a/business/partner/purchase/jd/order_afs.go b/business/partner/purchase/jd/order_afs.go index b32a56aba..58f003fda 100644 --- a/business/partner/purchase/jd/order_afs.go +++ b/business/partner/purchase/jd/order_afs.go @@ -123,26 +123,26 @@ func (c *PurchaseHandler) convertAfsAppealType(vendorAppealType string) int8 { func (c *PurchaseHandler) buildAfsOrder(afsInfo *jdapi.AfsServiceResponse) (afsOrder *model.AfsOrder) { afsOrder = &model.AfsOrder{ - VendorID: model.VendorIDJD, - AfsOrderID: afsInfo.AfsServiceOrder, - VendorOrderID: afsInfo.OrderID, - VendorStoreID: afsInfo.StationID, - StoreID: int(utils.Str2Int64WithDefault(afsInfo.StationNumOutSystem, 0)), - AfsCreatedAt: afsInfo.CreateTime.GoTime(), + VendorID: model.VendorIDJD, + AfsOrderID: afsInfo.AfsServiceOrder, + VendorOrderID: afsInfo.OrderID, + VendorStoreID: afsInfo.StationID, + StoreID: int(utils.Str2Int64WithDefault(afsInfo.StationNumOutSystem, 0)), + AfsCreatedAt: afsInfo.CreateTime.GoTime(), + VendorAppealType: afsInfo.ApplyDeal, + AppealType: c.convertAfsAppealType(afsInfo.ApplyDeal), + VendorReasonType: utils.Int2Str(afsInfo.QuestionTypeCid), + ReasonType: c.convertAfsReasonType(afsInfo.QuestionTypeCid), + ReasonDesc: utils.LimitUTF8StringLen(afsInfo.QuestionDesc, 1024), + ReasonImgList: utils.LimitUTF8StringLen(jdapi.ProcessQuestionPic(afsInfo.QuestionPic), 1024), + VendorOrgCode: afsInfo.VenderID, + FreightUserMoney: afsInfo.OrderFreightMoney, AfsFreightMoney: afsInfo.AfsFreight, BoxMoney: afsInfo.PackagingMoney, TongchengFreightMoney: afsInfo.TongchengFreightMoney, SkuBoxMoney: afsInfo.MealBoxMoney, - - VendorStatus: utils.Int2Str(afsInfo.AfsServiceState), - VendorReasonType: utils.Int2Str(afsInfo.QuestionTypeCid), - ReasonType: c.convertAfsReasonType(afsInfo.QuestionTypeCid), - ReasonDesc: utils.LimitUTF8StringLen(afsInfo.QuestionDesc, 1024), - ReasonImgList: utils.LimitUTF8StringLen(jdapi.ProcessQuestionPic(afsInfo.QuestionPic), 1024), - VendorAppealType: afsInfo.ApplyDeal, - AppealType: c.convertAfsAppealType(afsInfo.ApplyDeal), - VendorOrgCode: afsInfo.VenderID, + VendorStatus: utils.Int2Str(afsInfo.AfsServiceState), } afsOrder.Status = c.GetAfsStatusFromVendorStatus(afsOrder.VendorStatus) diff --git a/business/partner/purchase/mtwm/order.go b/business/partner/purchase/mtwm/order.go index 5b4d1d542..4cff87fb9 100644 --- a/business/partner/purchase/mtwm/order.go +++ b/business/partner/purchase/mtwm/order.go @@ -415,12 +415,12 @@ func (c *PurchaseHandler) callbackMsg2Status(msg *mtwmapi.CallbackMsg) (orderSta case FakeMsgType, mtwmapi.MsgTypeNewOrder, mtwmapi.MsgTypeOrderAccepted, mtwmapi.MsgTypeOrderFinished: vendorStatus = msg.FormData.Get("status") statusTime = utils.Str2Int64(msg.FormData.Get("utime")) - case mtwmapi.MsgTypeOrderRefund, mtwmapi.MsgTypeOrderPartialRefund: + case mtwmapi.MsgTypeOrderRefund, mtwmapi.MsgTypeOrderPartialRefund: // 订单退款,部分退款 notifyType := msg.FormData.Get("notify_type") vendorStatus = msg.Cmd + "-" + notifyType if true { // 已经提前判断了,到这里的都是售中 remark = msg.FormData.Get("reason") - if msg.Cmd == mtwmapi.MsgTypeOrderPartialRefund { + if msg.Cmd == mtwmapi.MsgTypeOrderPartialRefund { // 部分退款 if notifyType == mtwmapi.NotifyTypePartyApply { if globals.EnableMtwmStoreWrite { //if order, _ := partner.CurOrderManager.LoadOrder(orderID, model.VendorIDMTWM); order != nil { @@ -833,7 +833,7 @@ func (c *PurchaseHandler) ComplaintRider(vendorOrderId string, resonID int, reso return err } -// 转自配送时取消非专送混合送门店取消理由 +// GetCancelDeliveryReason 转自配送时取消非专送混合送门店取消理由 func (c *PurchaseHandler) GetCancelDeliveryReason(order *model.GoodsOrder) (string, error) { reason, err := getAPI(order.VendorOrgCode, jxutils.GetSaleStoreIDFromOrder(order), "").GetCancelDeliveryReason(utils.Str2Int64(order.VendorOrderID), order.VendorStoreID) if err != nil { diff --git a/business/partner/purchase/tiktok_store/act.go b/business/partner/purchase/tiktok_store/act.go index 438cc880c..43650aa26 100644 --- a/business/partner/purchase/tiktok_store/act.go +++ b/business/partner/purchase/tiktok_store/act.go @@ -87,11 +87,6 @@ func createOneShopAct(act *model.Act2, vendorStoreID string, actStoreSku []*mode if globals.EnableMtwmStoreWrite { actResult, faileInfoList, err2 := api.MtwmAPI.RetailDiscountBatchSave2(vendorStoreID, jxActType2Mtwm(act.Type), actData) err = err2 - // 忽略错误,都放在failedList里 - // if err != nil { - // return nil, err - // } - // globals.SugarLogger.Debugf("mtwm createOneShopAct actResult:%s, faileInfoList:%s err2:%v", utils.Format4Output(actResult, true), utils.Format4Output(faileInfoList, true), err2) actStoreSkuMap := make(map[int]*model.ActStoreSku2) for _, v := range actStoreSku { actStoreSkuMap[v.SkuID] = v @@ -260,11 +255,12 @@ func (c *PurchaseHandler) SyncAct(ctx *jxcontext.Context, parentTask tasksch.ITa } func (c *PurchaseHandler) GetActAmple(ctx *jxcontext.Context, vendorStoreID, vendorOrgCode string) (ample int, err error) { - for _, v := range mtwmapi.ActTypeList { - //1表示进行中 - if actList, err := getAPI(vendorOrgCode, 0, vendorStoreID).GetByAppPoiCodeAndType(vendorOrgCode, 1, v); err == nil { - ample += len(actList) - } - } - return ample, err + return 0, err + //for _, v := range mtwmapi.ActTypeList { + // //1表示进行中 + // if actList, err := getAPI(vendorOrgCode, 0, vendorStoreID).GetByAppPoiCodeAndType(vendorOrgCode, 1, v); err == nil { + // ample += len(actList) + // } + //} + //return ample, err } diff --git a/business/partner/purchase/tiktok_store/callback.go b/business/partner/purchase/tiktok_store/callback.go index b7458f509..e6f48308c 100644 --- a/business/partner/purchase/tiktok_store/callback.go +++ b/business/partner/purchase/tiktok_store/callback.go @@ -1,28 +1,19 @@ package tiktok_store import ( - "git.rosy.net.cn/baseapi/platformapi/mtwmapi" tiktokShop "git.rosy.net.cn/baseapi/platformapi/tiktok_shop/tiktok_api" "git.rosy.net.cn/jx-callback/business/jxutils" "git.rosy.net.cn/jx-callback/business/model" + "git.rosy.net.cn/jx-callback/globals/api" ) -// OnCallbackMsg 抖音 -func OnCallbackMsg(msg *tiktokShop.OrderCallback) (response *tiktokShop.CallbackResponse) { +// OnOrderMsg 抖音 +func OnOrderMsg(msgId string, msg interface{}) (response *tiktokShop.CallbackResponse) { if CurPurchaseHandler != nil { - if msg.Data != "" && len(msg.Body) > 0 { - jxutils.CallMsgHandler(func() { - response = CurPurchaseHandler.onOrderMsg(msg) - }, jxutils.ComposeUniversalOrderID(msg.MsgId, model.VendorIDDD)) - } + orderId, _ := api.TiktokStore.GetCallbackOrderId(msgId, msg) + jxutils.CallMsgHandler(func() { + response = CurPurchaseHandler.onOrderMsg(msgId, orderId, msg) + }, jxutils.ComposeUniversalOrderID(orderId, model.VendorIDDD)) } return response } - -func GetOrderIDFromMsg(msg *mtwmapi.CallbackMsg) string { - return msg.FormData.Get(mtwmapi.KeyOrderID) -} - -func GetVendorStoreIDFromMsg(msg *mtwmapi.CallbackMsg) string { - return msg.FormData.Get(mtwmapi.KeyAppPoiCode) -} diff --git a/business/partner/purchase/tiktok_store/financial.go b/business/partner/purchase/tiktok_store/financial.go index b5c597fc2..ef899b350 100644 --- a/business/partner/purchase/tiktok_store/financial.go +++ b/business/partner/purchase/tiktok_store/financial.go @@ -1,6 +1,7 @@ package tiktok_store import ( + order_orderDetail_response "git.rosy.net.cn/baseapi/platformapi/tiktok_shop/sdk-golang/api/order_orderDetail/response" "net/url" "git.rosy.net.cn/baseapi/platformapi/mtwmapi" @@ -135,18 +136,15 @@ func (p *PurchaseHandler) AfsOrderDetail2Financial(orderData url.Values) (afsOrd } // 存储美团正向订单结账信息 -func (p *PurchaseHandler) OnOrderDetail(result map[string]interface{}, operation string) (err error) { - globals.SugarLogger.Debug(utils.Int64ToStr(utils.MustInterface2Int64(result["order_id"]))) - err = partner.CurOrderManager.SaveOrderFinancialInfo(p.OrderDetail2Financial(result), operation) - return err +func (p *PurchaseHandler) OnOrderDetail(result *order_orderDetail_response.ShopOrderDetail, operation string) (err error) { + return partner.CurOrderManager.SaveOrderFinancialInfo(p.OrderDetail2Financial(result), operation) } -func (p *PurchaseHandler) OrderDetail2Financial(result map[string]interface{}) (orderFinancial *model.OrderFinancial) { +func (p *PurchaseHandler) OrderDetail2Financial(result *order_orderDetail_response.ShopOrderDetail) (orderFinancial *model.OrderFinancial) { orderFinancial = &model.OrderFinancial{ - VendorID: model.VendorIDMTWM, - VendorOrderID: utils.Int64ToStr(utils.MustInterface2Int64(result["order_id"])), + VendorID: model.VendorIDDD, + VendorOrderID: result.OrderId, } - // orderFinancial.DeliveryConfirmTime = utils.Str2TimeWithDefault(utils.Interface2String(result["order_completed_time"]), utils.DefaultTimeValue) order, err := partner.CurOrderManager.LoadOrder(orderFinancial.VendorOrderID, orderFinancial.VendorID) jxStoreID := 0 if err == nil { @@ -157,96 +155,50 @@ func (p *PurchaseHandler) OrderDetail2Financial(result map[string]interface{}) ( } } } else { - //globals.SugarLogger.Warnf("mtwm OrderDetail2Financial, orderID:%s is not found from partner.CurOrderManager.LoadOrder", orderFinancial.VendorOrderID) err = nil } - if result["package_bag_money"] != nil { - orderFinancial.BoxMoney = utils.MustInterface2Int64(result["package_bag_money"]) + + // 订单 + for _, x := range result.SkuOrderList { + orderSkuFinancial := &model.OrderSkuFinancial{ + VendorID: orderFinancial.VendorID, + VendorOrderID: orderFinancial.VendorOrderID, + VendorStoreID: x.StoreInfo.StoreId, + StoreID: 0, + JxStoreID: jxStoreID, + VendorSkuID: utils.Interface2String(x.SkuId), + SkuID: int(utils.Str2Int64WithDefault(x.OutSkuId, 0)), + Name: utils.Interface2String(x.ProductName), + SalePrice: x.OrderAmount / x.ItemNum, + Count: int(x.ItemNum), + SkuBoxMoney: 0, + IsAfsOrder: 0, + } + orderFinancial.Skus = append(orderFinancial.Skus, orderSkuFinancial) + orderFinancial.SalePriceMoney += orderSkuFinancial.SalePrice * int64(orderSkuFinancial.Count) + orderFinancial.SkuBoxMoney += orderSkuFinancial.SkuBoxMoney } - detail := result["detail"] - if detail != nil { - var data []map[string]interface{} - utils.UnmarshalUseNumber([]byte(utils.Interface2String(detail)), &data) - for _, x := range data { - orderSkuFinancial := &model.OrderSkuFinancial{ + + // 活动 + for _, x := range result.SkuOrderList { + for _, v := range x.CampaignInfo { + activity := &model.OrderDiscountFinancial{ VendorID: orderFinancial.VendorID, VendorOrderID: orderFinancial.VendorOrderID, - // OrderFinancialID: orderFinancial.VendorOrderID, - // ConfirmTime: utils.Str2TimeWithDefault(utils.Interface2String(result["ctime"]), utils.DefaultTimeValue), - VendorStoreID: result["app_poi_code"].(string), - StoreID: 0, - JxStoreID: jxStoreID, - VendorSkuID: utils.Interface2String(x["sku_id"]), - SkuID: int(utils.Str2Int64WithDefault(utils.Interface2String(x["sku_id"]), 0)), - Name: utils.Interface2String(x["food_name"]), - SalePrice: jxutils.StandardPrice2Int(utils.MustInterface2Float64(x["price"])), - Count: int(utils.MustInterface2Int64(x["quantity"])), - SkuBoxMoney: jxutils.StandardPrice2Int(utils.MustInterface2Float64(x["box_price"])) * jxutils.StandardPrice2Int(utils.MustInterface2Float64(x["box_num"])), - IsAfsOrder: 0, - } - orderFinancial.Skus = append(orderFinancial.Skus, orderSkuFinancial) - orderFinancial.SalePriceMoney += orderSkuFinancial.SalePrice * int64(orderSkuFinancial.Count) - orderFinancial.SkuBoxMoney += orderSkuFinancial.SkuBoxMoney - } - } else { - globals.SugarLogger.Warnf("mtwm OrderDetail2Financial, orderID:%s have no detail", orderFinancial.VendorOrderID) - } - extras := result["extras"] - if extras != nil { - var data []map[string]interface{} - utils.UnmarshalUseNumber([]byte(utils.Interface2String(extras)), &data) - for _, x := range data { - if x["rider_fee"] == nil { - activity := &model.OrderDiscountFinancial{ - VendorID: orderFinancial.VendorID, - VendorOrderID: orderFinancial.VendorOrderID, - // ActivityName: utils.Interface2String(x["remark"]), - // ActivityMoney: jxutils.StandardPrice2Int(utils.MustInterface2Float64(x["reduce_fee"])), - // VendorActivityID: utils.Int64ToStr(utils.MustInterface2Int64(x["act_detail_id"])), - } - if x["act_detail_id"] != nil { // 容错处理 - activity.VendorActivityID = utils.Int64ToStr(utils.MustInterface2Int64(x["act_detail_id"])) - orderFinancial.Discounts = append(orderFinancial.Discounts, activity) - } - // 通过活动Id去取,京西活动补贴 - // orderFinancial.JxSubsidyMoney += } + activity.VendorActivityID = utils.Int64ToStr(v.CampaignId) + orderFinancial.Discounts = append(orderFinancial.Discounts, activity) } } - poiReceiveDetail := result["poi_receive_detail"] - if poiReceiveDetail != nil { - var data map[string]interface{} - utils.UnmarshalUseNumber([]byte(utils.Interface2String(poiReceiveDetail)), &data) - orderFinancial.ReceivableFreight = utils.MustInterface2Int64(data["logisticsFee"]) - orderFinancial.FreightMoney = utils.MustInterface2Int64(data["logisticsFee"]) - orderFinancial.ActualPayMoney = utils.MustInterface2Int64(data["onlinePayment"]) - orderFinancial.PmMoney = utils.MustInterface2Int64(data["foodShareFeeChargeByPoi"]) - orderFinancial.ShopMoney = utils.MustInterface2Int64(data["wmPoiReceiveCent"]) - for _, x := range data["actOrderChargeByMt"].([]interface{}) { - orderFinancial.TotalDiscountMoney += utils.MustInterface2Int64(x.(map[string]interface{})["moneyCent"]) - orderFinancial.PmSubsidyMoney += utils.MustInterface2Int64(x.(map[string]interface{})["moneyCent"]) - } - for _, x := range data["actOrderChargeByPoi"].([]interface{}) { - orderFinancial.TotalDiscountMoney += utils.MustInterface2Int64(x.(map[string]interface{})["moneyCent"]) - } - } else { - globals.SugarLogger.Warnf("mtwm OrderDetail2Financial, orderID:%s have no poi_receive_detail", orderFinancial.VendorOrderID) - } - if utils.MustInterface2Int64(result["is_third_shipping"]) == SelfDeliveryCarrierNo { // is_third_shipping int 是否是第三方配送平台配送,0表否,1表是) - orderFinancial.SelfDeliveryDiscountMoney = orderFinancial.ReceivableFreight - orderFinancial.DistanceFreightMoney = 0 - // 通过本地数据库去取是否转美团/达达,并计算运费 - // wayBill, err := partner.CurOrderManager.LoadWaybill(orderFinancial.VendorOrderID, orderFinancial.VendorID) - // if err == nil { - // orderFinancial.JxFreightMoney = wayBill.DesiredFee - // } - } - // // 美团订单单独处理部分,美团正向订单接口推送时总结算金额没有计算公益捐款一分钱,是否在这里直接提前扣除? - // // 3/18之后的订单一直都不显示公益捐款金额,而且结算现在结算到了3/18之后的订单,没有的已经不计算了,先注释 - // // 2019-04-03 10.52 询问赵mf, 此计划是必须参加的,而且是长期的,每单固定扣除一分钱 - orderFinancial.DonationMoney = PublicWelfareDonation - // 不应该对第三方结账金额做更改,就算有异常,也要保留异常,知道问题出在哪里 - // orderFinancial.ShopMoney -= PublicWelfareDonation - globals.SugarLogger.Debug(orderFinancial.VendorOrderID) + + orderFinancial.ReceivableFreight = result.PostAmount + orderFinancial.FreightMoney = 0 + orderFinancial.ActualPayMoney = result.PayAmount + orderFinancial.PmMoney = 0 // 平台费 + orderFinancial.ShopMoney = 0 // 应结金额 + orderFinancial.TotalDiscountMoney = result.PromotionAmount // 订单优惠总金额 + orderFinancial.PmSubsidyMoney = result.PromotionPlatformAmount // 平台活动补贴(订单主体活动补贴+订单单条sku补贴)1+ + orderFinancial.SelfDeliveryDiscountMoney = 0 // 平台承担运费补贴(商家自送)+ + orderFinancial.DistanceFreightMoney = 0 return orderFinancial } diff --git a/business/partner/purchase/tiktok_store/mtwm.go b/business/partner/purchase/tiktok_store/mtwm.go index 08eefc605..ae73504b4 100644 --- a/business/partner/purchase/tiktok_store/mtwm.go +++ b/business/partner/purchase/tiktok_store/mtwm.go @@ -2,6 +2,7 @@ package tiktok_store import ( "fmt" + "git.rosy.net.cn/baseapi/platformapi/tiktok_shop/tiktok_api" "strings" "sync" @@ -30,6 +31,11 @@ type PurchaseHandler struct { locker sync.RWMutex } +func (c *PurchaseHandler) GetOrderStatus(vendorOrgCode, vendorOrderID string) (status int, err error) { + //TODO implement me + panic("implement me") +} + func init() { if api.MtwmAPI != nil || api.Mtwm2API != nil { CurPurchaseHandler = New() @@ -163,7 +169,7 @@ func bizStatusJX2Mtwm(status int) (openLevel, online int) { return mtwmapi.PoiOpenLevelNormal, mtwmapi.PoiStatusOnline } -func skuStatusJX2Mtwm(status int) int { +func skuStatusJX2Tiktok(status int) int { if status == model.SkuStatusNormal { return mtwmapi.SellStatusOnline } @@ -226,17 +232,14 @@ func (p *PurchaseHandler) getUploadImgPoiCode() (poiCode string) { return poiCode } -func GetAPI(appOrgCode string, storeID int, vendorStoreID string) (apiObj *mtwmapi.API) { - if appOrgCode == "" { - globals.SugarLogger.Debugf("getAPI appOrgCode is empty") - } - apiObj = partner.CurAPIManager.GetAPI(model.VendorIDMTWM, appOrgCode).(*mtwmapi.API) - if appOrgCode == globals.Mtwm2Code { +func getAPI(appOrgCode string, storeID int, vendorStoreID string) (apiObj *tiktok_api.API) { + apiObj = partner.CurAPIManager.GetAPI(model.VendorIDDD, appOrgCode).(*tiktok_api.API) + if appOrgCode == globals.TiktokShopCode { var storeDetail *dao.StoreDetail if storeID != 0 { - storeDetail, _ = dao.GetStoreDetail(dao.GetDB(), storeID, model.VendorIDMTWM, appOrgCode) + storeDetail, _ = dao.GetStoreDetail(dao.GetDB(), storeID, model.VendorIDDD, appOrgCode) } else if vendorStoreID != "" { - storeDetail, _ = dao.GetStoreDetailByVendorStoreID(dao.GetDB(), vendorStoreID, model.VendorIDMTWM, appOrgCode) + storeDetail, _ = dao.GetStoreDetailByVendorStoreID(dao.GetDB(), vendorStoreID, model.VendorIDDD, appOrgCode) } if storeDetail != nil { apiObj.SetToken(storeDetail.MtwmToken) @@ -245,28 +248,6 @@ func GetAPI(appOrgCode string, storeID int, vendorStoreID string) (apiObj *mtwma return apiObj } -func getAPI(appOrgCode string, storeID int, vendorStoreID string) (apiObj *mtwmapi.API) { - if appOrgCode == "" { - globals.SugarLogger.Debugf("getAPI appOrgCode is empty") - } - apiObj = partner.CurAPIManager.GetAPI(model.VendorIDMTWM, appOrgCode).(*mtwmapi.API) - if appOrgCode == globals.Mtwm2Code { - var storeDetail *dao.StoreDetail - if storeID != 0 { - storeDetail, _ = dao.GetStoreDetail(dao.GetDB(), storeID, model.VendorIDMTWM, appOrgCode) - } else if vendorStoreID != "" { - storeDetail, _ = dao.GetStoreDetailByVendorStoreID(dao.GetDB(), vendorStoreID, model.VendorIDMTWM, appOrgCode) - } - if storeDetail != nil { - apiObj.SetToken(storeDetail.MtwmToken) - } - } - return apiObj -} - -func getAPIWithoutToken(appOrgCode string) (apiObj *mtwmapi.API) { - if appOrgCode == "" { - globals.SugarLogger.Warnf("getAPI appOrgCode is empty") - } - return partner.CurAPIManager.GetAPI(model.VendorIDMTWM, appOrgCode).(*mtwmapi.API) +func getAPIWithoutToken(appOrgCode string) (apiObj *tiktok_api.API) { + return partner.CurAPIManager.GetAPI(model.VendorIDDD, appOrgCode).(*tiktok_api.API) } diff --git a/business/partner/purchase/tiktok_store/order.go b/business/partner/purchase/tiktok_store/order.go index 134264d95..1cd44fb75 100644 --- a/business/partner/purchase/tiktok_store/order.go +++ b/business/partner/purchase/tiktok_store/order.go @@ -3,9 +3,9 @@ package tiktok_store import ( "errors" "fmt" + order_orderDetail_response "git.rosy.net.cn/baseapi/platformapi/tiktok_shop/sdk-golang/api/order_orderDetail/response" tiktokShop "git.rosy.net.cn/baseapi/platformapi/tiktok_shop/tiktok_api" - "math" - "net/url" + "git.rosy.net.cn/jx-callback/globals/api" "regexp" "strings" "time" @@ -24,47 +24,35 @@ import ( const ( FakeMsgType = "fakeMsgType" - fakeFinishedPickup = "fake_finished_pickup" - fakeUserApplyCancel = "fake_user_apply_cancel" - fakeMerchantAgreeApplyCancel = "fake_merchant_agree_apply_cancel" - fakeRefuseUserApplyCancel = "fake_refuse_user_apply_cancel" - fakeUserUndoApplyCancel = "fake_user_undo_apply_cancel" - fakeOrderAdjustFinished = "fake_order_adjust_finished" - - keyVendorOrgCode = "vendorOrgCode" + fakeFinishedPickup = "fake_finished_pickup" // 假的拣货完成 + fakeAcceptOrder = "fake_accept_order" + fakeOrderAdjustFinished = "fake_order_adjust_finished" // 表示商户/客服/客户发起的部分退款 + fakeOrderCanceled = "fake_order_canceled" // ) const ( SelfDeliveryCarrierNo = 1 // 美团配送方式:0-美团专送,1-商家自送 ) -const ( -// pickupOrderDelay = 260 * time.Second -// pickupOrderDelay = 1 * time.Second - -// callDeliveryDelay = 10 * time.Minute -// callDeliveryDelayGap = 30 -) - var ( specPat = regexp.MustCompile(`(\d+)(.+)`) ) var ( VendorStatus2StatusMap = map[string]int{ - mtwmapi.OrderStatusUserCommitted: model.OrderStatusUnknown, - mtwmapi.OrderStatusNew: model.OrderStatusNew, - mtwmapi.OrderStatusAccepted: model.OrderStatusAccepted, - mtwmapi.OrderStatusDelivering: model.OrderStatusDelivering, - mtwmapi.OrderStatusDelivered: model.OrderStatusUnknown, // 以mtwmapi.OrderStatusFinished为结束状态,这个当成一个中间状态(且很少看到这个状态) - mtwmapi.OrderStatusFinished: model.OrderStatusFinished, - mtwmapi.OrderStatusCanceled: model.OrderStatusCanceled, - fakeFinishedPickup: model.OrderStatusFinishedPickup, - fakeOrderAdjustFinished: model.OrderStatusAdjust, - fakeRefuseUserApplyCancel: model.OrderStatusVendorRejectCancel, - fakeUserApplyCancel: model.OrderStatusApplyCancel, - fakeUserUndoApplyCancel: model.OrderStatusUndoApplyCancel, - fakeMerchantAgreeApplyCancel: model.OrderStatusCanceled, + utils.Int2Str(tiktokShop.CreateOrderStatusWaitPay): model.OrderStatusWait4Pay, // 1待支付 + utils.Int2Str(tiktokShop.CreateOrderStatusStockUp): model.OrderStatusAccepted, // 2备货中 + utils.Int2Str(tiktokShop.CreateOrderStatusDelivery): model.OrderStatusDelivering, // 3发货 + utils.Int2Str(tiktokShop.CreateOrderStatusCancel): model.OrderStatusCanceled, // 4取消 + utils.Int2Str(tiktokShop.CreateOrderStatusOver): model.OrderStatusFinished, // 5完成 + utils.Int2Str(tiktokShop.CreateOrderStatusBeginRefund): model.OrderStatusApplyCancel, // 21发货前退款完成 + utils.Int2Str(tiktokShop.CreateOrderStatusEndRefund): model.OrderStatusAfterShipmentCancel, // 22发货后退款 + utils.Int2Str(tiktokShop.CreateOrderStatusReceiptRefund): model.OrderStatusAfterReceivingCancel, // 39收货后退款 + utils.Int2Str(tiktokShop.CreateOrderStatusPartialDelivery): model.OrderStatusPartDeliverGoods, // 101部分发货 + utils.Int2Str(tiktokShop.CreateOrderStatusSomePay): model.OrderStatusPartPay, // 103部分支付 + utils.Int2Str(tiktokShop.CreateOrderStatusAllPay): model.OrderStatusNew, // 105已支付 + fakeAcceptOrder: model.OrderStatusAccepted, + fakeOrderAdjustFinished: model.OrderStatusAdjust, } skuActTypeMap = map[int]int{ @@ -74,28 +62,131 @@ var ( } ) -func (p *PurchaseHandler) getStatusFromVendorStatus(vendorStatus string) int { - if status, ok := VendorStatus2StatusMap[vendorStatus]; ok { +func (p *PurchaseHandler) getStatusFromVendorStatus(vendorStatus int64) int { + if status, ok := VendorStatus2StatusMap[utils.Int64ToStr(vendorStatus)]; ok { return status } return model.OrderStatusUnknown } -func (p *PurchaseHandler) getOrder(vendorOrgCode, vendorOrderID, vendorStoreID string) (order *model.GoodsOrder, orderMap map[string]interface{}, err error) { - result, err := getAPI(vendorOrgCode, 0, vendorStoreID).OrderGetOrderDetail(utils.Str2Int64(vendorOrderID), true) - if err == nil { - result[keyVendorOrgCode] = vendorOrgCode - order = p.Map2Order(result) +func (c *PurchaseHandler) Map2Order(orderData map[string]interface{}) (order *model.GoodsOrder) { + order, _, _ = c.getOrder("", orderData["vendorOrderID"].(string), "") + return order +} + +func (p *PurchaseHandler) getOrder(vendorOrgCode, vendorOrderID, vendorStoreID string) (order *model.GoodsOrder, orderMap *order_orderDetail_response.ShopOrderDetail, err error) { + // 平台获取订单详情 + result, err := api.TiktokStore.GetTiktokOrderDetail(vendorOrderID) + if err != nil { + return nil, nil, err } - return order, result, err -} - -func (p *PurchaseHandler) getOrderRider(vendorOrgCode, vendorStoreID string, param map[string]interface{}) (err error) { - return getAPI(vendorOrgCode, 0, vendorStoreID).OrderStatusAndPsInfo(param) + orderMap = result + order = &model.GoodsOrder{ + VendorOrderID: result.OrderId, + VendorID: model.VendorIDDD, + VendorStoreID: utils.Int64ToStr(result.ShopId), + StoreID: 0, + StoreName: result.ShopName, + ConsigneeName: result.MaskPostReceiver, + ConsigneeMobile: result.MaskPostTel, + ConsigneeAddress: result.MaskPostAddr.Detail, + + CoordinateType: model.CoordinateTypeMars, + BuyerComment: result.BuyerWords, + ExpectedDeliveredTime: getTimeFromTimestamp(utils.Interface2Int64WithDefault(result.TargetArrivalTime, 0)), + PickDeadline: utils.DefaultTimeValue, + VendorStatus: utils.Int64ToStr(result.OrderStatus), //1待支付/103部分支付/105已支付/2备货中/101部分发货/3已发货/4取消/完成/21发货前退款完成/22发货后退款/39收货后退款 + OrderSeq: 0, + StatusTime: getTimeFromTimestamp(result.CreateTime), + OrderCreatedAt: getTimeFromTimestamp(result.CreateTime), + OriginalData: string(utils.MustMarshal(result)), + ActualPayPrice: jxutils.StandardPrice2Int(utils.MustInterface2Float64(result.PayAmount)), + BaseFreightMoney: result.PostAmount, + InvoiceTitle: "", + InvoiceTaxerID: "", + InvoiceEmail: "", + VendorOrgCode: "", + } + // 本地获取订单记录 + orderSeq, _ := dao.GetVendorOrderNumber(dao.GetDB(), model.VendorIDDD, order.VendorStoreID) + order.OrderSeq = orderSeq + 1 + + if result.FinishTime != 0 { + order.OrderFinishedAt = getTimeFromTimestamp(result.FinishTime) + } else { + order.OrderFinishedAt = utils.DefaultTimeValue + } + order.DeliveryType = model.OrderDeliveryTypeStoreSelf + order.Status = p.getStatusFromVendorStatus(result.OrderStatus) + if utils.IsTimeZero(order.ExpectedDeliveredTime) { + order.BusinessType = model.BusinessTypeImmediate + } else { + order.BusinessType = model.BusinessTypeDingshida + } + + order.VendorUserID = result.UserIdInfo.IdCardNo + originalLng := utils.MustInterface2Float64(result.UserCoordinate.UserCoordinateLongitude) + originalLat := utils.MustInterface2Float64(result.UserCoordinate.UserCoordinateLatitude) + order.ConsigneeLng = jxutils.StandardCoordinate2Int(originalLng) + order.ConsigneeLat = jxutils.StandardCoordinate2Int(originalLat) + + order.DiscountMoney = result.PromotionAmount + // 添加需要赠送的东西(暂时没有赠品套餐直接商品) + multiSkuMap := make(map[int]int) + if len(result.SkuOrderList) > 0 { + for _, extra := range result.SkuOrderList { + sku := &model.OrderSku{ + VendorOrderID: extra.ParentOrderId, + VendorID: model.VendorIDDD, + StoreSubID: 0, + StoreSubName: "", + Count: int(extra.ItemNum), + VendorSkuID: utils.Int64ToStr(extra.SkuId), + SkuID: utils.Str2Int(extra.OutSkuId), + JxSkuID: utils.Str2Int(extra.OutSkuId), + SkuName: extra.ProductName, + ShopPrice: 0, + VendorPrice: extra.OrderAmount / extra.ItemNum, + SalePrice: extra.OriginAmount, + EarningPrice: 0, + Weight: getSkuWeight(map[string]interface{}{"skuName": extra.ProductName}), + SkuType: 0, + PromotionType: 0, + OrderCreatedAt: utils.Timestamp2Time(extra.CreateTime), + IsVendorAct: 0, + Upc: extra.Code, + } + + activityId := make([]int64, 0) + activityName := make([]string, 0) + for _, v := range extra.CampaignInfo { + activityId = append(activityId, v.CampaignId) + activityName = append(activityName, utils.Int64ToStr(v.CampaignId)+":"+v.CampaignName) + } + if len(activityId) > 0 { + sku.StoreSubID = int(activityId[0]) + sku.StoreSubName = strings.Join(activityName, ",") + } + if sku.Weight == 0 { + sku.Weight = 222 // 如果名字里找不到缺省给半斤左右的一个特别值 + } + multiSkuMap[sku.SkuID]++ + order.Skus = append(order.Skus, sku) + } + } + order.PmSubsidyMoney = result.PromotionAmount // 美团记录订单优惠总金额 + for _, v := range order.Skus { + if multiSkuMap[v.SkuID] > 1 && v.SalePrice == v.VendorPrice { + v.IsVendorAct = model.YES + } + } + jxutils.RefreshOrderSkuRelated(order) + return order, orderMap, nil } +// GetOrderRider 商家自配送同步配送信息 func (p *PurchaseHandler) GetOrderRider(vendorOrgCode, vendorStoreID string, param map[string]interface{}) (err error) { - return p.getOrderRider(vendorOrgCode, vendorStoreID, param) + return nil } func (p *PurchaseHandler) GetOrder(vendorOrgCode, vendorOrderID, vendorStoreID string) (order *model.GoodsOrder, err error) { @@ -103,422 +194,283 @@ func (p *PurchaseHandler) GetOrder(vendorOrgCode, vendorOrderID, vendorStoreID s return order, err } -func (p *PurchaseHandler) GetOrderStatus(vendorOrgCode, vendorOrderID string) (status int, err error) { - if order, _ := partner.CurOrderManager.LoadOrder(vendorOrderID, model.VendorIDMTWM); order != nil { - status, err = getAPI(vendorOrgCode, jxutils.GetSaleStoreIDFromOrder(order), "").OrderViewStatus(utils.Str2Int64(vendorOrderID)) - } - if err == nil { - status = p.getStatusFromVendorStatus(utils.Int2Str(status)) - } - return status, err +func (p *PurchaseHandler) getOrderMap(vendorOrgCode, vendorOrderID, vendorStoreID string) (orderMap *order_orderDetail_response.ShopOrderDetail, err error) { + _, orderMap, err = p.getOrder(vendorOrgCode, vendorOrderID, vendorStoreID) + return orderMap, err } -func (p *PurchaseHandler) Map2Order(orderData map[string]interface{}) (order *model.GoodsOrder) { - result := orderData - vendorOrderID := utils.Int64ToStr(utils.MustInterface2Int64(result["order_id"])) - // 因为美团外卖不能自动设置商家门店号,且只能通过商家门店号来访问门店, - // 为了在后台设置简单一致,把app_poi_code直接当成平台门店号使用(即在后台设置时,平台门店号与商家门店号一样) - // 订单中wm_poi_id实际来平台门店号,app_poi_code为商家门店号,这样一来,这两个就相同了 - order = &model.GoodsOrder{ - VendorOrderID: vendorOrderID, - // VendorOrderID2: utils.Int64ToStr(utils.MustInterface2Int64(result["wm_order_id_view"])), - VendorID: model.VendorIDMTWM, - VendorStoreID: result["app_poi_code"].(string), - StoreID: 0, - // VendorStoreID: utils.Int64ToStr(utils.MustInterface2Int64(result["wm_poi_id"])), - // StoreID: int(utils.Str2Int64WithDefault(utils.Interface2String(result["app_poi_code"]), 0)), - StoreName: result["wm_poi_name"].(string), - ConsigneeName: result["recipient_name"].(string), - ConsigneeMobile: jxutils.FormalizeMobile(result["recipient_phone"].(string)), - ConsigneeAddress: result["recipient_address"].(string), - CoordinateType: model.CoordinateTypeMars, - BuyerComment: utils.TrimBlankChar(utils.Interface2String(result["caution"])), - ExpectedDeliveredTime: getTimeFromTimestamp(utils.Interface2Int64WithDefault(result["delivery_time"], 0)), - PickDeadline: utils.DefaultTimeValue, - VendorStatus: utils.Int64ToStr(utils.MustInterface2Int64(result["status"])), - OrderSeq: int(utils.MustInterface2Int64(result["day_seq"])), - StatusTime: getTimeFromTimestamp(utils.MustInterface2Int64(result["ctime"])), - OrderCreatedAt: getTimeFromTimestamp(utils.MustInterface2Int64(result["ctime"])), - // OrderFinishedAt: getTimeFromTimestamp(utils.MustInterface2Int64(result["order_completed_time"])), - OriginalData: string(utils.MustMarshal(result)), - ActualPayPrice: jxutils.StandardPrice2Int(utils.MustInterface2Float64(result["total"])), - BaseFreightMoney: jxutils.StandardPrice2Int(utils.Interface2Float64WithDefault(result["shipping_fee"], 0)), - - InvoiceTitle: utils.Interface2String(result["invoice_title"]), - InvoiceTaxerID: utils.Interface2String(result["taxpayer_id"]), - InvoiceEmail: jxutils.GetOneEmailFromStr(utils.Interface2String(result["caution"])), - - VendorOrgCode: utils.Interface2String(result[keyVendorOrgCode]), +// 获取部分商家退款的物品(缺货缺重) +func getRefundSkuDetailList(order *model.GoodsOrder) (skuList []order_orderDetail_response.SkuOrderListItem, err error) { + refundOrderDetailList, err := getAPI(order.VendorOrgCode, jxutils.GetSaleStoreIDFromOrder(order), "").GetTiktokOrderDetail(order.VendorOrderID) + if err != nil { + return nil, err } - if result["order_completed_time"] != nil { - order.OrderFinishedAt = getTimeFromTimestamp(utils.MustInterface2Int64(result["order_completed_time"])) - } else { - order.OrderFinishedAt = utils.DefaultTimeValue - } - 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 || logisticsCode == mtwmapi.PeiSongTypeMTZSPT { - order.DeliveryType = model.OrderDeliveryTypeStoreSelf - } else { - order.DeliveryType = model.OrderDeliveryTypePlatform + for _, v := range refundOrderDetailList.SkuOrderList { + if v.OrderStatus == tiktokShop.CreateOrderStatusCancel { + skuList = append(skuList, v) } } - openUID := utils.Interface2Int64WithDefault(result["openUid"], 0) - if openUID > 0 { - order.VendorUserID = utils.Int64ToStr(openUID) - } - // 不设置最晚拣货时间,以缺省值为准 - // if utils.IsTimeZero(order.PickDeadline) && !utils.IsTimeZero(order.StatusTime) { - // order.PickDeadline = order.StatusTime.Add(pickupOrderDelay) // 美团外卖要求在5分钟内拣货,不然订单会被取消 - // } - order.Status = p.getStatusFromVendorStatus(order.VendorStatus) - if utils.IsTimeZero(order.ExpectedDeliveredTime) { - order.BusinessType = model.BusinessTypeImmediate - } else { - order.BusinessType = model.BusinessTypeDingshida - } - - originalLng := utils.MustInterface2Float64(result["longitude"]) - originalLat := utils.MustInterface2Float64(result["latitude"]) - order.ConsigneeLng = jxutils.StandardCoordinate2Int(originalLng) - order.ConsigneeLat = jxutils.StandardCoordinate2Int(originalLat) - - var detail []map[string]interface{} - if err := utils.UnmarshalUseNumber([]byte(result["detail"].(string)), &detail); err != nil { - panic(fmt.Sprintf("mtwm Map2Order vendorID:%s failed with error:%v", vendorOrderID, err)) - } - - // 添加需要赠送的东西 - if result["extras"] != nil { - var extraList []*mtwmapi.OrderExtraInfo - if err := utils.UnmarshalUseNumber([]byte(result["extras"].(string)), &extraList); err != nil { - panic(fmt.Sprintf("mtwm Map2Order vendorID:%s failed with error:%v", vendorOrderID, err)) - } - for _, extra := range extraList { - order.DiscountMoney += jxutils.StandardPrice2Int(extra.ReduceFee) - if extra.Type == mtwmapi.ExtrasPromotionTypeTaoCanZeng || extra.Type == mtwmapi.ExtrasPromotionTypeManZeng { - sku := &model.OrderSku{ - VendorOrderID: order.VendorOrderID, - VendorID: model.VendorIDMTWM, - Count: 1, - SkuID: 0, - VendorSkuID: "", - SkuName: extra.Remark, - Weight: 0, - SalePrice: 0, - StoreSubName: utils.Int2Str(extra.Type), - } - order.Skus = append(order.Skus, sku) - } - } - } - - if poiReceiveDetailStr := utils.Interface2String(result["poi_receive_detail"]); poiReceiveDetailStr != "" { - var poiReceiveDetail *mtwmapi.PoiReceiveDetailInfo - utils.UnmarshalUseNumber([]byte(poiReceiveDetailStr), &poiReceiveDetail) - if poiReceiveDetail != nil { - order.TotalShopMoney = poiReceiveDetail.WmPoiReceiveCent - for _, v := range poiReceiveDetail.ActOrderChargeByMt { - order.PmSubsidyMoney += v.MoneyCent - } - } - } - - var skuBenefitDetailMap map[string]*mtwmapi.SkuBenefitDetailInfo - if skuBenefitDetai := utils.Interface2String(result["sku_benefit_detail"]); skuBenefitDetai != "" { - skuBenefitDetailMap = make(map[string]*mtwmapi.SkuBenefitDetailInfo) - var skuBenefitDetailList []*mtwmapi.SkuBenefitDetailInfo - utils.UnmarshalUseNumber([]byte(skuBenefitDetai), &skuBenefitDetailList) - for _, v := range skuBenefitDetailList { - skuBenefitDetailMap[v.SkuID] = v - } - } - ignoreSkuMap := make(map[int]int) - // detail := result["detail"].([]interface{}) - multiSkuMap := make(map[int]int) - for _, product := range detail { - // product := product2.(map[string]interface{}) - skuName := product["food_name"].(string) - skuID := utils.Interface2String(product["sku_id"]) - sku := &model.OrderSku{ - VendorOrderID: order.VendorOrderID, - VendorID: model.VendorIDMTWM, - Count: int(utils.MustInterface2Float64(product["quantity"])), - SkuID: int(utils.Str2Int64WithDefault(skuID, 0)), - VendorSkuID: skuID, - SkuName: skuName, - Weight: getSkuWeight(product), - VendorPrice: jxutils.StandardPrice2Int(utils.MustInterface2Float64(product["price"])), - SalePrice: jxutils.StandardPrice2Int(utils.MustInterface2Float64(product["price"])), - } - if product["upc"] != nil && product["upc"].(string) != "" { - sku.Upc = product["upc"].(string) - } - if sku.VendorSkuID == "" { - if !strings.Contains(product["app_food_code"].(string), "mtcode") { - sku.VendorSkuID = product["app_food_code"].(string) - } else { - sku.VendorSkuID = utils.Int64ToStr(utils.Interface2Int64WithDefault(product["mt_sku_id"], 0)) - } - } - if sku.Weight == 0 { - sku.Weight = 222 // 如果名字里找不到缺省给半斤左右的一个特别值 - } - if skuBenefitDetailMap != nil && skuBenefitDetailMap[sku.VendorSkuID] != nil && ignoreSkuMap[sku.SkuID] == 0 /* && sku.Count == 1 */ { - for _, v := range skuBenefitDetailMap[sku.VendorSkuID].WmAppOrderActDetails { - if /*skuActTypeMap[v.Type] == 1 && */ strings.Index(v.Remark, skuName) >= 0 && sku.Count == v.Count { - if sku.SalePrice-jxutils.StandardPrice2Int(v.MtCharge+v.PoiCharge) < 0 { - continue - } else { - ignoreSkuMap[sku.SkuID] = 1 - sku.SalePrice -= jxutils.StandardPrice2Int(v.MtCharge + v.PoiCharge) - } - sku.StoreSubName = utils.Int2Str(v.Type) - } - } - } - if sku.SalePrice < 0 { - sku.SalePrice = jxutils.StandardPrice2Int(utils.MustInterface2Float64(product["price"])) - } - // if product["isGift"].(bool) { - // sku.SkuType = 1 - // } - order.Skus = append(order.Skus, sku) - multiSkuMap[sku.SkuID]++ - } - for _, v := range order.Skus { - if multiSkuMap[v.SkuID] > 1 && v.SalePrice == v.VendorPrice { - v.IsVendorAct = model.YES - } - } - - jxutils.RefreshOrderSkuRelated(order) - return order -} - -func getRefundSkuDetailList(msg *mtwmapi.CallbackMsg, order *model.GoodsOrder) (skuList []*mtwmapi.RefundSkuDetail, err error) { - if false { - skuList = getAPI(order.VendorOrgCode, jxutils.GetSaleStoreIDFromOrder(order), "").GetRefundSkuDetailFromMsg(msg) - } else { - refundOrderDetailList, err2 := getAPI(order.VendorOrgCode, jxutils.GetSaleStoreIDFromOrder(order), "").GetOrderRefundDetail(utils.Str2Int64(GetOrderIDFromMsg(msg)), mtwmapi.RefundTypePart) - if err = err2; err == nil { - for _, v := range refundOrderDetailList { - skuList = append(skuList, v.WmAppRetailForOrderPartRefundList...) - } - } - } - globals.SugarLogger.Debugf("getRefundSkuDetailList orderID:%s skuList:%s", GetOrderIDFromMsg(msg), utils.Format4Output(skuList, true)) return skuList, err } func getSkuWeight(product map[string]interface{}) (weight int) { - if weight = int(utils.Interface2Int64WithDefault(product["weight"], 0)); weight == 0 { - searchResult := specPat.FindStringSubmatch(product["spec"].(string)) - if len(searchResult) == 3 { - weight = jxutils.FormatSkuWeight(float32(utils.Str2Float64WithDefault(searchResult[1], 0)), utils.TrimBlankChar(searchResult[2])) - } - if weight == 0 { - _, _, _, specUnit, _, specQuality := jxutils.SplitSkuName(product["food_name"].(string)) - weight = jxutils.FormatSkuWeight(specQuality, specUnit) - } - } + _, _, _, specUnit, _, specQuality := jxutils.SplitSkuName(product["skuName"].(string)) + weight = jxutils.FormatSkuWeight(specQuality, specUnit) return weight } -func (c *PurchaseHandler) onOrderMsg(msg *tiktokShop.OrderCallback) (response *tiktokShop.CallbackResponse) { +func (c *PurchaseHandler) onOrderMsg(msgId, orderId string, msg interface{}) (response *tiktokShop.CallbackResponse) { var err error - if c.isAfsMsg(msg) { - response = c.OnAfsOrderMsg(msg) - } else { - status := c.callbackMsg2Status(msg) - if partner.CurOrderManager.GetStatusDuplicatedCount(status) > 0 { - return nil + // 处理售后单 + if c.isAfsMsg(msgId) { + return c.OnAfsOrderMsg(msgId, orderId, msg) + } + + // 待支付订单将不做处理/支付订单待处理(抖音风控) + if msgId == tiktokShop.CallbackCreatedOrderMsgTagId || msgId == tiktokShop.CallbackWaitOrderMsgTagId { + return tiktokShop.Err2CallbackResponse(nil, "") + } + + // 取消订单:可能未支付取消订单,不做处理 + if msgId == tiktokShop.CallbackCancelOrderMsgTagId { + if _, err := partner.CurOrderManager.LoadOrder(orderId, model.VendorIDDD); err != nil && strings.Contains(err.Error(), "找不到相应订单") { + return tiktokShop.Err2CallbackResponse(nil, "") + } else { + globals.SugarLogger.Debugf("Cancel Order Err : %s", err.Error()) + return tiktokShop.Err2CallbackResponse(err, "") } - if msg.Cmd == mtwmapi.MsgTypeNewOrder { - order, orderMap, err2 := c.getOrder(msg.AppID, GetOrderIDFromMsg(msg), GetVendorStoreIDFromMsg(msg)) + } + + // 组装订单状态变化 + status := c.callbackMsg2Status(msgId, orderId, msg) + // 校验重复消息 + if partner.CurOrderManager.GetStatusDuplicatedCount(status) > 0 { + return tiktokShop.Err2CallbackResponse(nil, "") + } + + // 已经支付的订单,当做新订单创建在平台内部 + if msgId == tiktokShop.CallbackPayOrderMsgTagId { + order, err := c.GetOrder("", orderId, "") // 获取平台订单详情,制作本地订单 + if err != nil { + return tiktokShop.Err2CallbackResponse(err, "") + } + + if err := partner.CurOrderManager.OnOrderNew(order, c.callbackMsg2Status(msgId, orderId, msg)); err != nil { + return tiktokShop.Err2CallbackResponse(err, "") + } + + orderMap, err := c.getOrderMap("", orderId, "") + utils.CallFuncAsync(func() { + switch msgId { + case tiktokShop.CallbackPayOrderMsgTagId: + c.OnOrderDetail(orderMap, partner.CreatedPeration) + case tiktokShop.CallbackChangeMoneyMsgTagId: + c.OnOrderDetail(orderMap, partner.UpdatedPeration) + } + }) + } else { + if status == nil { + return tiktokShop.Err2CallbackResponse(errors.New("order_status create err"), "") + } + var order *model.GoodsOrder + if order, err = partner.CurOrderManager.LoadOrder(orderId, model.VendorIDDD); err != nil { + return tiktokShop.Err2CallbackResponse(err, "") + } + + if status.Status == model.OrderStatusAdjust { // 部分退款商品调整(缺货) + skuList, err2 := getRefundSkuDetailList(order) if err = err2; err == nil { - err = partner.CurOrderManager.OnOrderNew(order, c.callbackMsg2Status(msg)) - if err == nil { - utils.CallFuncAsync(func() { - if msg.Cmd == mtwmapi.MsgTypeNewOrder { - c.OnOrderDetail(orderMap, partner.CreatedPeration) - } else { - c.OnOrderDetail(orderMap, partner.UpdatedPeration) - } + var removedSkuList []*model.OrderSku + for _, ttSku := range skuList { + order.ActualPayPrice -= ttSku.PayAmount + removedSkuList = append(removedSkuList, &model.OrderSku{ + SkuID: int(utils.Str2Int64WithDefault(ttSku.OutSkuId, 0)), + Count: int(ttSku.ItemNum), }) } + order = jxutils.RemoveSkuFromOrder(order, removedSkuList) + jxutils.RefreshOrderSkuRelated(order) + err = partner.CurOrderManager.OnOrderAdjust(order, status) } } else { - if status != nil { - var order *model.GoodsOrder - if order, err = partner.CurOrderManager.LoadOrder(GetOrderIDFromMsg(msg), model.VendorIDMTWM); err == nil { - // if order, err = c.GetOrder(msg.AppID, GetOrderIDFromMsg(msg)); err == nil { - if status.Status == model.OrderStatusAdjust { - skuList, err2 := getRefundSkuDetailList(msg, order) - if err = err2; err == nil { - var removedSkuList []*model.OrderSku - for _, mtwmSku := range skuList { - order.ActualPayPrice -= jxutils.StandardPrice2Int(mtwmSku.RefundPrice) * int64(mtwmSku.Count) - removedSkuList = append(removedSkuList, &model.OrderSku{ - SkuID: int(utils.Str2Int64WithDefault(mtwmSku.SkuID, 0)), - Count: mtwmSku.Count, - }) - } - order = jxutils.RemoveSkuFromOrder(order, removedSkuList) - jxutils.RefreshOrderSkuRelated(order) - err = partner.CurOrderManager.OnOrderAdjust(order, status) - } - } else { - if status.Status == model.OrderStatusDelivering { - // 美团订单即使时在配送状态时,如果之前没有调用过拣货完成,也会对门店指标生成影响,这里强制再调用拣货完成,且忽略错误 - utils.CallFuncAsync(func() { - if globals.EnableMtwmStoreWrite { - err = getAPI(order.VendorOrgCode, jxutils.GetSaleStoreIDFromOrder(order), "").PreparationMealComplete(utils.Str2Int64(status.VendorOrderID)) - } - }) - } - err = partner.CurOrderManager.OnOrderStatusChanged(msg.AppID, status) - if err == nil && msg.Cmd == mtwmapi.MsgTypeOrderFinished { - utils.CallFuncAsync(func() { - orderMap, err := getAPI(order.VendorOrgCode, jxutils.GetSaleStoreIDFromOrder(order), "").OrderGetOrderDetail(utils.Str2Int64(GetOrderIDFromMsg(msg)), true) - if err == nil && utils.MustInterface2Int64(orderMap["is_third_shipping"]) == SelfDeliveryCarrierNo { - c.OnOrderDetail(orderMap, partner.UpdatedPeration) - } - }) - } - - } - } + // 发货完成 + if msgId == tiktokShop.CallbackPartAllGoodsMsgTagId || msgId == tiktokShop.CallbackRefundOrderMsgTagId { // || msgId == tiktokShop.CallbackPartGoodsMsgTagId 部分发货 + utils.CallFuncAsync(func() { + orderMap, _ := getAPI(order.VendorOrgCode, jxutils.GetSaleStoreIDFromOrder(order), "").GetTiktokOrderDetail(orderId) + c.OnOrderDetail(orderMap, partner.UpdatedPeration) + }) } + if err := partner.CurOrderManager.OnOrderStatusChanged(globals.TiktokShopCode, status); err != nil { + return tiktokShop.Err2CallbackResponse(err, "") + } + } } - return mtwmapi.Err2CallbackResponse(err, "") + return tiktokShop.Err2CallbackResponse(err, "") } -func (c *PurchaseHandler) callbackMsg2Status(msg *mtwmapi.CallbackMsg) (orderStatus *model.OrderStatus) { - orderID := GetOrderIDFromMsg(msg) - vendorStatus := msg.Cmd - remark := "" - statusTime := utils.Str2Int64(msg.FormData.Get("timestamp")) - switch msg.Cmd { - case mtwmapi.MsgTypeUserUrgeOrder, mtwmapi.MsgTypeOrderModified, mtwmapi.MsgTypeOrderFinancial: - vendorStatus = msg.Cmd - case mtwmapi.MsgTypeOrderCanceled: - vendorStatus = mtwmapi.OrderStatusCanceled - remark = msg.FormData.Get("reason") - case FakeMsgType, mtwmapi.MsgTypeNewOrder, mtwmapi.MsgTypeOrderAccepted, mtwmapi.MsgTypeOrderFinished: - vendorStatus = msg.FormData.Get("status") - statusTime = utils.Str2Int64(msg.FormData.Get("utime")) - case mtwmapi.MsgTypeOrderRefund, mtwmapi.MsgTypeOrderPartialRefund: - notifyType := msg.FormData.Get("notify_type") - vendorStatus = msg.Cmd + "-" + notifyType - if true { // 已经提前判断了,到这里的都是售中 - remark = msg.FormData.Get("reason") - if msg.Cmd == mtwmapi.MsgTypeOrderPartialRefund { - if notifyType == mtwmapi.NotifyTypePartyApply { - if globals.EnableMtwmStoreWrite { - //if order, _ := partner.CurOrderManager.LoadOrder(orderID, model.VendorIDMTWM); order != nil { - // getAPI(order.VendorOrgCode, jxutils.GetSaleStoreIDFromOrder(order), "").OrderRefundAgree(utils.Str2Int64(orderID), "自动确认退款") - //} - // goods, err := dao.GetSimpleOrder(dao.GetDB(), orderID) - // if err == nil { - // if goods.Status < model.OrderStatusDelivering { - // } else { - // api.MtwmAPI.OrderRefundReject(utils.Str2Int64(orderID), "商品配送中,请联系门店。") // todo 京东与饿百都没有售前用户提出订单调整的,自动拒绝调整单 - // } - // } - } - } else if notifyType == mtwmapi.NotifyTypeSuccess { - vendorStatus = fakeOrderAdjustFinished - } - } else if msg.Cmd == mtwmapi.MsgTypeOrderRefund { - if notifyType == mtwmapi.NotifyTypeApply { - vendorStatus = fakeUserApplyCancel - } else if notifyType == mtwmapi.NotifyTypeCancelRefund || notifyType == mtwmapi.NotifyTypeCancelRefundComplaint { - vendorStatus = fakeUserUndoApplyCancel - } else if notifyType == mtwmapi.NotifyTypeReject { - vendorStatus = fakeRefuseUserApplyCancel - } else if notifyType == mtwmapi.NotifyTypeSuccess { - vendorStatus = fakeMerchantAgreeApplyCancel // todo 可能导致订单取消消息重复 - } - } - } +func (c *PurchaseHandler) callbackMsg2Status(msgId, orderId string, msg interface{}) *model.OrderStatus { + orderStatus := &model.OrderStatus{} + switch msgId { + case tiktokShop.CallbackCreatedOrderMsgTagId: + return nil // 抖音新创建订单,未支付时本地不做创建,可能取消 + //orderMsg := msg.(*tiktokShop.CreateOrderData) + //orderStatus.VendorOrderID = utils.Int64ToStr(orderMsg.PId) + //orderStatus.VendorStatus = utils.Int64ToStr(orderMsg.OrderStatus) + //orderStatus.StatusTime = utils.Timestamp2Time(orderMsg.CreateTime) + //orderStatus.Status = vendorStatusToLocalStatus(orderMsg.OrderStatus) + //orderStatus.Remark = "100-新订单回调" + case tiktokShop.CallbackPayOrderMsgTagId: + orderMsg := msg.(*tiktokShop.PayOrderData) + orderStatus.VendorOrderID = utils.Int64ToStr(orderMsg.PId) + orderStatus.VendorStatus = utils.Int64ToStr(orderMsg.OrderStatus) + orderStatus.StatusTime = utils.Timestamp2Time(orderMsg.PayTime) + orderStatus.Status = vendorStatusToLocalStatus(orderMsg.OrderStatus) + orderStatus.Remark = "101-支付回调" + case tiktokShop.CallbackWaitOrderMsgTagId: + return nil // 支付订单风控消息不处理 + //orderMsg := msg.(*tiktokShop.WaitOrderData) + //orderStatus.VendorOrderID = utils.Int64ToStr(orderMsg.PId) + //orderStatus.VendorStatus = utils.Int64ToStr(orderMsg.OrderStatus) + //orderStatus.StatusTime = utils.Timestamp2Time(orderMsg.PayTime) + //orderStatus.Status = vendorStatusToLocalStatus(orderMsg.OrderStatus) + //orderStatus.Remark = "110-订单支付待处理:风控" + case tiktokShop.CallbackPartGoodsMsgTagId: + orderMsg := msg.(*tiktokShop.SomeSendOrderData) + orderStatus.VendorOrderID = utils.Int64ToStr(orderMsg.PId) + orderStatus.VendorStatus = utils.Int64ToStr(orderMsg.OrderStatus) + orderStatus.StatusTime = utils.Timestamp2Time(orderMsg.UpdateTime) + orderStatus.Status = vendorStatusToLocalStatus(orderMsg.OrderStatus) + orderStatus.Remark = "108-卖家部分发货" + case tiktokShop.CallbackPartAllGoodsMsgTagId: + orderMsg := msg.(*tiktokShop.BusinessDeliveryData) + orderStatus.VendorOrderID = utils.Int64ToStr(orderMsg.PId) + orderStatus.VendorStatus = utils.Int64ToStr(orderMsg.OrderStatus) + orderStatus.StatusTime = utils.Timestamp2Time(orderMsg.UpdateTime) + orderStatus.Status = vendorStatusToLocalStatus(orderMsg.OrderStatus) + orderStatus.Remark = "102-卖家发货完成" + case tiktokShop.CallbackCancelOrderMsgTagId: + orderMsg := msg.(*tiktokShop.CancelOrderData) + orderStatus.VendorOrderID = utils.Int64ToStr(orderMsg.PId) + orderStatus.VendorStatus = utils.Int64ToStr(orderMsg.OrderStatus) + orderStatus.StatusTime = utils.Timestamp2Time(orderMsg.CancelTime) + orderStatus.Status = vendorStatusToLocalStatus(orderMsg.OrderStatus) + orderStatus.Remark = "106-取消订单" + case tiktokShop.CallbackSuccessOrderMsgTagId: + orderMsg := msg.(*tiktokShop.SuccessOrderData) + orderStatus.VendorOrderID = utils.Int64ToStr(orderMsg.PId) + orderStatus.VendorStatus = utils.Int64ToStr(orderMsg.OrderStatus) + orderStatus.StatusTime = utils.Timestamp2Time(orderMsg.CompleteTime) + orderStatus.Status = vendorStatusToLocalStatus(orderMsg.OrderStatus) + orderStatus.Remark = "103-确认收货" + case tiktokShop.CallbackWayBillChangeOrderMsgTagId: + orderMsg := msg.(*tiktokShop.WayBillChangeData) + orderStatus.VendorOrderID = utils.Int64ToStr(orderMsg.PId) + orderStatus.VendorStatus = utils.Int64ToStr(orderMsg.OrderStatus) + orderStatus.StatusTime = utils.Timestamp2Time(orderMsg.UpdateTime) + orderStatus.Status = vendorStatusToLocalStatus(orderMsg.OrderStatus) + orderStatus.Remark = "104-物流消息变更" + case tiktokShop.CallbackReceivingChangeOrderMsgTagId: + orderMsg := msg.(*tiktokShop.ReceivingAddressChangeData) + orderStatus.VendorOrderID = utils.Int64ToStr(orderMsg.PId) + orderStatus.VendorStatus = utils.Int64ToStr(orderMsg.OrderStatus) + orderStatus.StatusTime = utils.Timestamp2Time(orderMsg.UpdateTime) + orderStatus.Status = vendorStatusToLocalStatus(orderMsg.OrderStatus) + orderStatus.Remark = "105-收货地址变更" + case tiktokShop.CallbackChangeMoneyMsgTagId: + orderMsg := msg.(*tiktokShop.UpdateAmountChangeData) + orderStatus.VendorOrderID = utils.Int64ToStr(orderMsg.PId) + orderStatus.VendorStatus = utils.Int64ToStr(orderMsg.OrderStatus) + orderStatus.StatusTime = utils.Timestamp2Time(orderMsg.ModifyTime) + orderStatus.Status = vendorStatusToLocalStatus(orderMsg.OrderStatus) + orderStatus.Remark = "109-卖家修改订单/运单金额" + case tiktokShop.CallbackApplyUpdateAddressMsgTagId: + orderMsg := msg.(*tiktokShop.BuyerUpdateWayBillData) + orderStatus.VendorOrderID = utils.Int64ToStr(orderMsg.PId) + orderStatus.VendorStatus = utils.Int64ToStr(tiktokShop.CreateOrderStatusStockUp) + orderStatus.StatusTime = time.Now() + orderStatus.Status = model.OrderStatusUnknown + orderStatus.Remark = "111-买家收货消息变更" + case tiktokShop.CallbackBusinessRemarkMsgTagId: + orderMsg := msg.(*tiktokShop.BusinessUpdateRemakeData) + orderStatus.VendorOrderID = utils.Int64ToStr(orderMsg.PId) + orderStatus.VendorStatus = utils.Int64ToStr(tiktokShop.CreateOrderStatusStockUp) + orderStatus.StatusTime = utils.Timestamp2Time(orderMsg.UpdateTime) + orderStatus.Status = model.OrderStatusUnknown + orderStatus.Remark = "113-添加备注:" + orderMsg.Remark + case tiktokShop.CallbackSendOrderTimeChangeMsgTagId: + orderMsg := msg.(*tiktokShop.AppointmentChangeData) + orderStatus.VendorOrderID = orderMsg.PId + orderStatus.VendorStatus = utils.Int64ToStr(tiktokShop.CreateOrderStatusStockUp) + orderStatus.StatusTime = time.Now() + orderStatus.Status = model.OrderStatusUnknown + orderStatus.Remark = "126-预约发货:" + case fakeFinishedPickup: // 应为需要同步京东,美团拣货功能制作的假拣货,抖音不存在拣货 + orderMsg := msg.(*tiktokShop.FakePickUpGoodsData) + orderStatus.VendorOrderID = orderMsg.PId + orderStatus.VendorStatus = fakeFinishedPickup + orderStatus.StatusTime = time.Now() + orderStatus.Status = model.OrderStatusFinishedPickup + orderStatus.Remark = "15-抖音假拣货:" default: - globals.SugarLogger.Errorf("mtwm unkonw msg:%s", utils.Format4Output(msg, false)) - } - if vendorStatus != "" { - orderStatus = &model.OrderStatus{ - VendorOrderID: orderID, - VendorID: model.VendorIDMTWM, - OrderType: model.OrderTypeOrder, - RefVendorOrderID: orderID, - RefVendorID: model.VendorIDMTWM, - VendorStatus: vendorStatus, - Status: c.getStatusFromVendorStatus(vendorStatus), - StatusTime: getTimeFromTimestamp(statusTime), - Remark: remark, - } + return nil } + orderStatus.OrderType = model.OrderTypeOrder + orderStatus.RefVendorOrderID = orderStatus.VendorOrderID + orderStatus.VendorID = model.VendorIDDD + orderStatus.RefVendorID = model.VendorIDDD return orderStatus } -func (c *PurchaseHandler) postFakeMsg(vendorOrderID, cmd, vendorStatus string) { - msg := &mtwmapi.CallbackMsg{ - Cmd: cmd, - FormData: make(url.Values), +// 将抖音平台订单状态修改为本地通用状态(不好用) +func vendorStatusToLocalStatus(vendorStatus int64) int { + if status, ok := VendorStatus2StatusMap[utils.Int64ToStr(vendorStatus)]; ok { + return status } - timeStr := utils.Int64ToStr(time.Now().Unix()) - msg.FormData.Set(mtwmapi.KeyOrderID, vendorOrderID) - msg.FormData.Set("status", vendorStatus) - msg.FormData.Set("timestamp", timeStr) - msg.FormData.Set("utime", timeStr) + return model.OrderStatusUnknown +} + +func (c *PurchaseHandler) postFakeMsg(vendorOrderID, cmd, vendorStatus string) { + msg := &tiktokShop.FakePickUpGoodsData{PId: vendorOrderID, VendorStatus: vendorStatus} + utils.CallFuncAsync(func() { - c.onOrderMsg(msg) + c.onOrderMsg(cmd, vendorOrderID, msg) }) } +// AcceptOrRefuseOrder 接单或者拒单(isAcceptIt:接单/拒单) 抖店暂无拒单 func (c *PurchaseHandler) AcceptOrRefuseOrder(order *model.GoodsOrder, isAcceptIt bool, userName string) (err error) { - globals.SugarLogger.Debugf("mtwm AcceptOrRefuseOrder orderID:%s, isAcceptIt:%t", order.VendorOrderID, isAcceptIt) - if isAcceptIt { - if globals.EnableMtwmStoreWrite { - // err = api.MtwmAPI.OrderReceived(utils.Str2Int64(order.VendorOrderID)) - err = getAPI(order.VendorOrgCode, jxutils.GetSaleStoreIDFromOrder(order), "").OrderConfirm(utils.Str2Int64(order.VendorOrderID)) - if err != nil { - if utils.IsErrMatch(err, utils.Int2Str(mtwmapi.ErrCodeOpFailed), []string{ - "订单已经确认过了", - }) { - err = nil - } else { - globals.SugarLogger.Warnf("mtwm AcceptOrRefuseOrder orderID:%s failed with err:%v", order.VendorOrderID, err) - } - } - } - // if err == nil { - // c.postFakeMsg(order.VendorOrderID, FakeMsgType, mtwmapi.OrderStatusReceived) - // } - } else { - if globals.EnableMtwmStoreWrite { - err = c.CancelOrder(jxcontext.AdminCtx, order, "bu") - } - } + //if isAcceptIt { + // if globals.EnableMtwmStoreWrite { + // err = getAPI(order.VendorOrgCode, jxutils.GetSaleStoreIDFromOrder(order), "").OrderConfirm(utils.Str2Int64(order.VendorOrderID)) + // if err != nil { + // if utils.IsErrMatch(err, utils.Int2Str(mtwmapi.ErrCodeOpFailed), []string{ + // "订单已经确认过了", + // }) { + // err = nil + // } else { + // globals.SugarLogger.Warnf("mtwm AcceptOrRefuseOrder orderID:%s failed with err:%v", order.VendorOrderID, err) + // } + // } + // } + //} else { + // if globals.EnableMtwmStoreWrite { + // err = c.CancelOrder(jxcontext.AdminCtx, order, "bu") + // } + //} return err } +// PickupGoods 拣货完成 (抖音无拣货接口) func (c *PurchaseHandler) PickupGoods(order *model.GoodsOrder, isSelfDelivery bool, userName string) (err error) { - globals.SugarLogger.Debugf("mtwm PickupGoods orderID:%s, isSelfDelivery:%t", order.VendorOrderID, isSelfDelivery) - if !isSelfDelivery { - if globals.EnableMtwmStoreWrite { - // err = api.MtwmAPI.OrderConfirm(utils.Str2Int64(order.VendorOrderID)) - err = getAPI(order.VendorOrgCode, jxutils.GetSaleStoreIDFromOrder(order), "").PreparationMealComplete(utils.Str2Int64(order.VendorOrderID)) - } - } - if err == nil { - c.postFakeMsg(order.VendorOrderID, FakeMsgType, fakeFinishedPickup) - } - return err + // 通知平台拣货完成,抖店只需要本地拣货完成 + //if !isSelfDelivery { + // if globals.EnableMtwmStoreWrite { + // err = getAPI(order.VendorOrgCode, jxutils.GetSaleStoreIDFromOrder(order), "").PreparationMealComplete(utils.Str2Int64(order.VendorOrderID)) + // } + //} + c.postFakeMsg(order.VendorOrderID, FakeMsgType, fakeFinishedPickup) + return nil } func (p *PurchaseHandler) AcceptOrRefuseFailedGetOrder(ctx *jxcontext.Context, order *model.GoodsOrder, isAcceptIt bool) (err error) { @@ -533,21 +485,21 @@ func (p *PurchaseHandler) ConfirmReceiveGoods(ctx *jxcontext.Context, order *mod return err } -// 美团预定单不能转商家自送 +// CanSwitch2SelfDeliver 美团预定单不能转商家自送 func (c *PurchaseHandler) CanSwitch2SelfDeliver(order *model.GoodsOrder) (isCan bool, err error) { return order.BusinessType != model.BusinessTypeDingshida, nil } +// Swtich2SelfDeliver 暂无转自送 func (c *PurchaseHandler) Swtich2SelfDeliver(order *model.GoodsOrder, userName string) (err error) { - globals.SugarLogger.Debugf("mtwm Swtich2SelfDeliver orderID:%s", order.VendorOrderID) - if globals.EnableMtwmStoreWrite { - err = getAPI(order.VendorOrgCode, jxutils.GetSaleStoreIDFromOrder(order), "").OrderLogisticsChange2Self(utils.Str2Int64(order.VendorOrderID)) - } + //if globals.EnableMtwmStoreWrite { + // err = getAPI(order.VendorOrgCode, jxutils.GetSaleStoreIDFromOrder(order), "").OrderLogisticsChange2Self(utils.Str2Int64(order.VendorOrderID)) + //} return err } +// Swtich2SelfDelivered 暂无自送完成 func (c *PurchaseHandler) Swtich2SelfDelivered(order *model.GoodsOrder, userName string) (err error) { - globals.SugarLogger.Debugf("mtwm Swtich2SelfDelivered orderID:%s", order.VendorOrderID) if globals.EnableMtwmStoreWrite { // 您好,之前的答复已经更正为,调用变更配送状态的接口,会校验门店的配送类型。美团配送的门店即便转自配后因门店配送类型是美团配送所以无法调用接口变更配送状态。可提醒顾客点击确认收货。谢谢 // 非自配送门店订单调用OrderArrived好像会报错:{"data":"ng","error":{"code":1038,"msg":"只允许商家配送调用该接口"}} @@ -556,19 +508,20 @@ func (c *PurchaseHandler) Swtich2SelfDelivered(order *model.GoodsOrder, userName return err } +// SelfDeliverDelivering 暂无自配送中 func (c *PurchaseHandler) SelfDeliverDelivering(order *model.GoodsOrder, userName string) (err error) { - globals.SugarLogger.Debugf("mtwm SelfDeliverDelivering orderID:%s", order.VendorOrderID) - if globals.EnableMtwmStoreWrite { - err = getAPI(order.VendorOrgCode, jxutils.GetSaleStoreIDFromOrder(order), "").OrderDelivering(utils.Str2Int64(order.VendorOrderID)) - } + //if globals.EnableMtwmStoreWrite { + // err = getAPI(order.VendorOrgCode, jxutils.GetSaleStoreIDFromOrder(order), "").OrderDelivering(utils.Str2Int64(order.VendorOrderID)) + //} return err } +// SelfDeliverDelivered 自配搜完成(暂无) func (c *PurchaseHandler) SelfDeliverDelivered(order *model.GoodsOrder, userName string) (err error) { - globals.SugarLogger.Debugf("mtwm SelfDeliverDelivered orderID:%s", order.VendorOrderID) - if globals.EnableMtwmStoreWrite { - err = getAPI(order.VendorOrgCode, jxutils.GetSaleStoreIDFromOrder(order), "").OrderArrived(utils.Str2Int64(order.VendorOrderID)) - } + //globals.SugarLogger.Debugf("mtwm SelfDeliverDelivered orderID:%s", order.VendorOrderID) + //if globals.EnableMtwmStoreWrite { + // err = getAPI(order.VendorOrgCode, jxutils.GetSaleStoreIDFromOrder(order), "").OrderArrived(utils.Str2Int64(order.VendorOrderID)) + //} return err } @@ -579,50 +532,54 @@ func getTimeFromTimestamp(timeStamp int64) time.Time { return utils.Timestamp2Time(timeStamp) } +// GetOrderRealMobile 获取真实号 func (c *PurchaseHandler) GetOrderRealMobile(ctx *jxcontext.Context, order *model.GoodsOrder) (mobile string, err error) { - err = errors.New("美团外卖还未实现GetOrderRealMobile") - return mobile, err + + return "", err } +// AgreeOrRefuseCancel 同意或拒绝(退款) func (c *PurchaseHandler) AgreeOrRefuseCancel(ctx *jxcontext.Context, order *model.GoodsOrder, isAgree bool, reason string) (err error) { - if globals.EnableMtwmStoreWrite { + afsOrder, err := partner.CurOrderManager.LoadAfsOrder(order.VendorOrderID, order.VendorID) + if err != nil { + return err + } + if globals.EnableDdStoreWrite { if isAgree { - err = getAPI(order.VendorOrgCode, jxutils.GetSaleStoreIDFromOrder(order), "").OrderRefundAgree(utils.Str2Int64(order.VendorOrderID), reason) + // 同意仅退款 + err = getAPI(order.VendorOrgCode, jxutils.GetSaleStoreIDFromOrder(order), "").AfterSaleOperate(tiktokShop.AfterSaleEmuAgreeOnlyRefundApply, afsOrder.AfsOrderID, reason, utils.Str2Int64(order.VendorStoreID)) } else { - err = getAPI(order.VendorOrgCode, jxutils.GetSaleStoreIDFromOrder(order), "").OrderRefundReject(utils.Str2Int64(order.VendorOrderID), reason) + // 拒绝退款 + err = getAPI(order.VendorOrgCode, jxutils.GetSaleStoreIDFromOrder(order), "").AfterSaleOperate(tiktokShop.AfterSaleEmuRefuseOnlyRefundApply, afsOrder.AfsOrderID, reason, utils.Str2Int64(order.VendorStoreID)) } } return err } +// CancelOrder 取消订单 (抖音商家无法发起退单操作) func (c *PurchaseHandler) CancelOrder(ctx *jxcontext.Context, order *model.GoodsOrder, reason string) (err error) { - if globals.EnableMtwmStoreWrite { - if err = getAPI(order.VendorOrgCode, jxutils.GetSaleStoreIDFromOrder(order), "").OrderCancel(utils.Str2Int64(order.VendorOrderID), reason, mtwmapi.CancelReasonOther); err == nil { - // 调用开放平台接口取消订单,不推送取消订单消息和退款消息。 - c.postFakeMsg(order.VendorOrderID, mtwmapi.MsgTypeOrderCanceled, mtwmapi.OrderStatusCanceled) - } + if globals.EnableDdStoreWrite { + return errors.New("抖音商家无法发起退单操作") + //if err = getAPI(order.VendorOrgCode, jxutils.GetSaleStoreIDFromOrder(order), "").OrderCancel(utils.Str2Int64(order.VendorOrderID), reason, mtwmapi.CancelReasonOther); err == nil { + // // 调用开放平台接口取消订单,不推送取消订单消息和退款消息。 + // c.postFakeMsg(order.VendorOrderID, tiktokShop.CallbackCancelOrderMsgTagId, utils.Int2Str(tiktokShop.CreateOrderStatusCancel)) + //} } return err } +// AdjustOrder 发起部分退款 func (c *PurchaseHandler) AdjustOrder(ctx *jxcontext.Context, order *model.GoodsOrder, removedSkuList []*model.OrderSku, reason string) (err error) { - // 美团外卖必须要确认订单后才能调整单 + // 拣货完成之后,在部分退款(抖店为缺货/缺重) if order.Status < model.OrderStatusFinishedPickup { - err = c.PickupGoods(order, false, ctx.GetUserName()) + if err = c.PickupGoods(order, false, ctx.GetUserName()); err != nil { + return err + } } - if err == nil { - var skuList []*mtwmapi.RefundSku - for _, sku := range removedSkuList { - skuID := utils.Int2Str(jxutils.GetSkuIDFromOrderSku(sku)) - skuList = append(skuList, &mtwmapi.RefundSku{ - AppFoodCode: skuID, - SkuID: skuID, - Count: sku.Count, - }) - } - if globals.EnableMtwmStoreWrite { - err = getAPI(order.VendorOrgCode, jxutils.GetSaleStoreIDFromOrder(order), "").OrderApplyPartRefund(utils.Str2Int64(order.VendorOrderID), reason, skuList) - } + + for _, sku := range removedSkuList { + // todo 商家发起部分退单,传入参数为子订单id,子订单id需要存储,返回售后单id + _, err = getAPI(order.VendorOrgCode, jxutils.GetSaleStoreIDFromOrder(order), "").ApplyMarketAfterSale(utils.Str2Int64(sku.VendorOrderID), 2) } return err } @@ -635,41 +592,21 @@ func (c *PurchaseHandler) ListOrders(ctx *jxcontext.Context, vendorOrgCode strin var vendorStoreIDs []string if vendorStoreID == "" { - vendorStoreIDs, err = c.GetAllStoresVendorID(ctx, vendorOrgCode) - if err != nil { - return nil, err - } + return nil, fmt.Errorf("门店id需要填写") + //vendorStoreIDs, err = c.GetAllStoresVendorID(ctx, vendorOrgCode) + //if err != nil { + // return nil, err + //} } else { vendorStoreIDs = []string{vendorStoreID} } - task := tasksch.NewParallelTask("mtwm ListOrders", nil, ctx, + task := tasksch.NewParallelTask("tiktok shop ListOrders", nil, ctx, func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { vendorStoreID := batchItemList[0].(string) var orderIDs []string - seqStart := 1 - i := 0 - for { - batchSize := int(math.Min(math.Pow(2, float64(i*3)), float64(mtwmapi.MaxGap4GetOrderIdByDaySeq))) - seqEnd := seqStart + batchSize - 1 - var tmpOrderIDs []int64 - if seqStart == seqEnd { - if vendorOderID, err2 := getAPI(vendorOrgCode, 0, vendorStoreID).GetOrderIdByDaySeqSingle(vendorStoreID, queryDate, seqStart); err2 == nil { - tmpOrderIDs = []int64{vendorOderID} - } - } else { - tmpOrderIDs, err = getAPI(vendorOrgCode, 0, vendorStoreID).GetOrderIdByDaySeq(vendorStoreID, queryDate, seqStart, seqEnd) - } - if len(tmpOrderIDs) > 0 { - for _, v := range tmpOrderIDs { - orderIDs = append(orderIDs, utils.Int64ToStr(v)) - } - } - if err != nil || len(tmpOrderIDs) < batchSize { - err = nil - break - } - seqStart = seqEnd + 1 - i++ + // 获取当前门店当天的订单 + if vendorOderID, err2 := getAPI(vendorOrgCode, 0, vendorStoreID).GetStoreOrderList(queryDate, utils.Str2Int64(vendorStoreID)); err2 == nil { + orderIDs = vendorOderID } retVal = orderIDs return retVal, nil @@ -692,129 +629,135 @@ func (c *PurchaseHandler) ListOrders(ctx *jxcontext.Context, vendorOrgCode strin // return err // } +// GetOrderConsigneeNumber 获取用户真实订单号 func (p *PurchaseHandler) GetOrderConsigneeNumber(ctx *jxcontext.Context, storeID int, vendorStoreID string) (numberList []*partner.OrderPhoneNumberInfo, err error) { - offset := 0 - for { - store, _ := dao.GetStoreDetail(dao.GetDB(), storeID, model.VendorIDMTWM, "") - result, err2 := getAPI(store.VendorOrgCode, storeID, "").OrderBatchPullPhoneNumber(vendorStoreID, offset, mtwmapi.MaxBatchPullPhoneNumberLimit) - if err = err2; err == nil { - for _, v := range result { - v2 := &partner.OrderPhoneNumberInfo{ - VendorOrderID: utils.Int64ToStr(v.OrderID), - PhoneNumber: v.RealPhoneNumber, - } - if v2.PhoneNumber == "" { - v2.PhoneNumber = v.RealOrderPhoneNumber - } - numberList = append(numberList, v2) - } - if len(result) <= mtwmapi.MaxBatchPullPhoneNumberLimit { - break - } - offset += mtwmapi.MaxBatchPullPhoneNumberLimit - } else { - break - } - } - return numberList, err + //offset := 0 + //for { + // store, _ := dao.GetStoreDetail(dao.GetDB(), storeID, model.VendorIDMTWM, "") + // result, err2 := getAPI(store.VendorOrgCode, storeID, "").OrderBatchPullPhoneNumber(vendorStoreID, offset, mtwmapi.MaxBatchPullPhoneNumberLimit) + // if err = err2; err == nil { + // for _, v := range result { + // v2 := &partner.OrderPhoneNumberInfo{ + // VendorOrderID: utils.Int64ToStr(v.OrderID), + // PhoneNumber: v.RealPhoneNumber, + // } + // if v2.PhoneNumber == "" { + // v2.PhoneNumber = v.RealOrderPhoneNumber + // } + // numberList = append(numberList, v2) + // } + // if len(result) <= mtwmapi.MaxBatchPullPhoneNumberLimit { + // break + // } + // offset += mtwmapi.MaxBatchPullPhoneNumberLimit + // } else { + // break + // } + //} + //return numberList, err + return nil, nil } +// GetOrderCourierNumber 获取配送员电话号码 func (p *PurchaseHandler) GetOrderCourierNumber(ctx *jxcontext.Context, storeID int, vendorStoreID string) (numberList []*partner.OrderPhoneNumberInfo, err error) { - offset := 0 - for { - store, _ := dao.GetStoreDetail(dao.GetDB(), storeID, model.VendorIDMTWM, "") - result, err2 := getAPI(store.VendorOrgCode, 0, "").OrderGetRiderInfoPhoneNumber(vendorStoreID, offset, mtwmapi.MaxBatchPullPhoneNumberLimit) - if err = err2; err == nil { - for _, v := range result { - numberList = append(numberList, &partner.OrderPhoneNumberInfo{ - VendorOrderID: utils.Int64ToStr(v.OrderID), - PhoneNumber: v.RiderRealPhoneNumber, - }) - } - if len(result) <= mtwmapi.MaxBatchPullPhoneNumberLimit { - break - } - offset += mtwmapi.MaxBatchPullPhoneNumberLimit - } else { - break - } - } + //offset := 0 + //for { + // store, _ := dao.GetStoreDetail(dao.GetDB(), storeID, model.VendorIDMTWM, "") + // result, err2 := getAPI(store.VendorOrgCode, 0, "").OrderGetRiderInfoPhoneNumber(vendorStoreID, offset, mtwmapi.MaxBatchPullPhoneNumberLimit) + // if err = err2; err == nil { + // for _, v := range result { + // numberList = append(numberList, &partner.OrderPhoneNumberInfo{ + // VendorOrderID: utils.Int64ToStr(v.OrderID), + // PhoneNumber: v.RiderRealPhoneNumber, + // }) + // } + // if len(result) <= mtwmapi.MaxBatchPullPhoneNumberLimit { + // break + // } + // offset += mtwmapi.MaxBatchPullPhoneNumberLimit + // } else { + // break + // } + //} return numberList, err } func (p *PurchaseHandler) onNumberDowngrade(msg *mtwmapi.CallbackMsg) (response *mtwmapi.CallbackResponse) { - userNumberMap := make(map[string]*partner.OrderPhoneNumberInfo) - courierNumberMap := make(map[string]*partner.OrderPhoneNumberInfo) - orderMap := make(map[string]int) - ctx := jxcontext.AdminCtx - task := tasksch.NewParallelTask("美团外卖平台处理隐私号降级通知", tasksch.NewParallelConfig().SetParallelCount(1).SetIsContinueWhenError(true), ctx, - func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - step := batchItemList[0].(int) - switch step { - case 0: - userNumberList, err2 := p.GetOrderConsigneeNumber(ctx, 0, "") - if err = err2; err == nil { - for _, v := range userNumberList { - userNumberMap[v.VendorOrderID] = v - orderMap[v.VendorOrderID] = 1 - } - } - case 1: - courierNumberList, err2 := p.GetOrderCourierNumber(ctx, 0, "") - if err = err2; err == nil { - for _, v := range courierNumberList { - courierNumberMap[v.VendorOrderID] = v - orderMap[v.VendorOrderID] = 1 - } - } - case 2: - orderList := jxutils.StringMap2List(orderMap) - if len(orderList) > 0 { - updateTask := tasksch.NewParallelTask("美团外卖平台处理隐私号降级通知/处理订单", tasksch.NewParallelConfig().SetParallelCount(1).SetIsContinueWhenError(true), ctx, - func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - vendorOrderID := batchItemList[0].(string) - db := dao.GetDB() - if userNumberMap[vendorOrderID] != nil { - _, err = dao.UpdateEntityByKV(db, &model.GoodsOrder{}, map[string]interface{}{ - "ConsigneeMobile": userNumberMap[vendorOrderID].PhoneNumber, - "ConsigneeMobile2": userNumberMap[vendorOrderID].PhoneNumber, - }, map[string]interface{}{ - model.FieldVendorOrderID: vendorOrderID, - model.FieldVendorID: model.VendorIDMTWM, - }) - } - if courierNumberMap[vendorOrderID] != nil { - _, err = dao.UpdateEntityByKV(db, &model.Waybill{}, map[string]interface{}{ - "CourierMobile": courierNumberMap[vendorOrderID].PhoneNumber, - }, map[string]interface{}{ - "VendorWaybillID": vendorOrderID, - "WaybillVendorID": model.VendorIDMTWM, - }) - } - return retVal, err - }, orderList) - tasksch.HandleTask(updateTask, task, true).Run() - _, err = updateTask.GetResult(0) - } - } - return retVal, err - }, []int{0, 1, 2}) - tasksch.HandleTask(task, nil, true).Run() + //userNumberMap := make(map[string]*partner.OrderPhoneNumberInfo) + //courierNumberMap := make(map[string]*partner.OrderPhoneNumberInfo) + //orderMap := make(map[string]int) + //ctx := jxcontext.AdminCtx + //task := tasksch.NewParallelTask("美团外卖平台处理隐私号降级通知", tasksch.NewParallelConfig().SetParallelCount(1).SetIsContinueWhenError(true), ctx, + // func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { + // step := batchItemList[0].(int) + // switch step { + // case 0: + // userNumberList, err2 := p.GetOrderConsigneeNumber(ctx, 0, "") + // if err = err2; err == nil { + // for _, v := range userNumberList { + // userNumberMap[v.VendorOrderID] = v + // orderMap[v.VendorOrderID] = 1 + // } + // } + // case 1: + // courierNumberList, err2 := p.GetOrderCourierNumber(ctx, 0, "") + // if err = err2; err == nil { + // for _, v := range courierNumberList { + // courierNumberMap[v.VendorOrderID] = v + // orderMap[v.VendorOrderID] = 1 + // } + // } + // case 2: + // orderList := jxutils.StringMap2List(orderMap) + // if len(orderList) > 0 { + // updateTask := tasksch.NewParallelTask("美团外卖平台处理隐私号降级通知/处理订单", tasksch.NewParallelConfig().SetParallelCount(1).SetIsContinueWhenError(true), ctx, + // func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { + // vendorOrderID := batchItemList[0].(string) + // db := dao.GetDB() + // if userNumberMap[vendorOrderID] != nil { + // _, err = dao.UpdateEntityByKV(db, &model.GoodsOrder{}, map[string]interface{}{ + // "ConsigneeMobile": userNumberMap[vendorOrderID].PhoneNumber, + // "ConsigneeMobile2": userNumberMap[vendorOrderID].PhoneNumber, + // }, map[string]interface{}{ + // model.FieldVendorOrderID: vendorOrderID, + // model.FieldVendorID: model.VendorIDMTWM, + // }) + // } + // if courierNumberMap[vendorOrderID] != nil { + // _, err = dao.UpdateEntityByKV(db, &model.Waybill{}, map[string]interface{}{ + // "CourierMobile": courierNumberMap[vendorOrderID].PhoneNumber, + // }, map[string]interface{}{ + // "VendorWaybillID": vendorOrderID, + // "WaybillVendorID": model.VendorIDMTWM, + // }) + // } + // return retVal, err + // }, orderList) + // tasksch.HandleTask(updateTask, task, true).Run() + // _, err = updateTask.GetResult(0) + // } + // } + // return retVal, err + // }, []int{0, 1, 2}) + //tasksch.HandleTask(task, nil, true).Run() return response } +// GetWaybillTip 获取订单小费 func (c *PurchaseHandler) GetWaybillTip(ctx *jxcontext.Context, vendorOrgCode, vendorStoreID, vendorOrderID, vendorWaybillID, vendorWaybillID2 string) (tipFee int64, err error) { - orderInfo, err := getAPI(vendorOrgCode, 0, vendorStoreID).GetDistributeOrderDetail(vendorOrderID, vendorStoreID) - if err == nil { - tipFee = jxutils.StandardPrice2Int(orderInfo.TipAmount) - } - return tipFee, err + //orderInfo, err := getAPI(vendorOrgCode, 0, vendorStoreID).GetDistributeOrderDetail(vendorOrderID, vendorStoreID) + //if err == nil { + // tipFee = jxutils.StandardPrice2Int(orderInfo.TipAmount) + //} + //return tipFee, err + return 0, nil } +// UpdateWaybillTip 修改订单小费 func (c *PurchaseHandler) UpdateWaybillTip(ctx *jxcontext.Context, vendorOrgCode, vendorStoreID, vendorOrderID, vendorWaybillID, vendorWaybillID2, cityCode string, tipFee int64) (err error) { - if globals.EnableMtwmStoreWrite { - err = getAPI(vendorOrgCode, 0, vendorStoreID).OrderModityTips(vendorOrderID, vendorStoreID, jxutils.IntPrice2Standard(tipFee)) - } + //if globals.EnableMtwmStoreWrite { + // err = getAPI(vendorOrgCode, 0, vendorStoreID).OrderModityTips(vendorOrderID, vendorStoreID, jxutils.IntPrice2Standard(tipFee)) + //} return err } @@ -830,21 +773,23 @@ func (c *PurchaseHandler) ComplaintRider(vendorOrderId string, resonID int, reso return err } -// 转自配送时取消非专送混合送门店取消理由 +// GetCancelDeliveryReason 转自配送时取消非专送混合送门店取消理由 func (c *PurchaseHandler) GetCancelDeliveryReason(order *model.GoodsOrder) (string, error) { - reason, err := getAPI(order.VendorOrgCode, jxutils.GetSaleStoreIDFromOrder(order), "").GetCancelDeliveryReason(utils.Str2Int64(order.VendorOrderID), order.VendorStoreID) - if err != nil { - return "", err - } - return reason, nil + //reason, err := getAPI(order.VendorOrgCode, jxutils.GetSaleStoreIDFromOrder(order), "").GetCancelDeliveryReason(utils.Str2Int64(order.VendorOrderID), order.VendorStoreID) + //if err != nil { + // return "", err + //} + //return reason, nil + return "", nil } -// 取消美团外卖理由转使用三方配送 +// CancelLogisticsByWmOrderId 取消美团外卖理由转使用三方配送 func (c *PurchaseHandler) CancelLogisticsByWmOrderId(order *model.GoodsOrder, reasonCode, detailContent, appPoiCode, orderId string) error { - return getAPI(order.VendorOrgCode, jxutils.GetSaleStoreIDFromOrder(order), "").CancelLogisticsByWmOrderId(reasonCode, detailContent, appPoiCode, orderId) + //return getAPI(order.VendorOrgCode, jxutils.GetSaleStoreIDFromOrder(order), "").CancelLogisticsByWmOrderId(reasonCode, detailContent, appPoiCode, orderId) + return nil } -// 获取订单配送状态 +// OrderLogisticsStatus 获取订单配送状态 func (c *PurchaseHandler) OrderLogisticsStatus(orderId int64) (int64, error) { return 0, nil } diff --git a/business/partner/purchase/tiktok_store/order_afs.go b/business/partner/purchase/tiktok_store/order_afs.go index 6f4b64e54..abc938b80 100644 --- a/business/partner/purchase/tiktok_store/order_afs.go +++ b/business/partner/purchase/tiktok_store/order_afs.go @@ -3,18 +3,13 @@ package tiktok_store import ( "fmt" tiktokShop "git.rosy.net.cn/baseapi/platformapi/tiktok_shop/tiktok_api" - "git.rosy.net.cn/jx-callback/globals/api" - "net/url" - "strings" - - "git.rosy.net.cn/baseapi/platformapi/mtwmapi" "git.rosy.net.cn/baseapi/utils" "git.rosy.net.cn/jx-callback/business/jxutils" "git.rosy.net.cn/jx-callback/business/jxutils/jxcontext" "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" ) var ( @@ -116,301 +111,13 @@ var ( } ) -// 是否为售后消息 -func (c *PurchaseHandler) isAfsMsg(msg *tiktokShop.OrderCallback) bool { - _, ok := AfsTagIDMap[msg.MsgId] - return ok -} - -func (c *PurchaseHandler) OnAfsOrderMsg(msg *mtwmapi.CallbackMsg) (retVal *mtwmapi.CallbackResponse) { - jxutils.CallMsgHandlerAsync(func() { - retVal = c.onAfsOrderMsg(msg) - }, jxutils.ComposeUniversalOrderID(GetOrderIDFromMsg(msg), model.VendorIDEBAI)) - return retVal -} - -// todo 对于退款与部分退款,order.go与这个文件中对于状态的处理不一致 -func (c *PurchaseHandler) onAfsOrderMsg(msg *tiktokShop.OrderCallback) (retVal *tiktokShop.CallbackResponse) { - var err error - orderStatus := c.callbackAfsMsg2Status(msg) - for _, v := range orderStatus { - needCallNew := v.Status == model.AfsOrderStatusWait4Approve || v.Status == model.AfsOrderStatusNew - if !needCallNew { - if _, err := partner.CurOrderManager.LoadAfsOrder(v.VendorOrderID, v.VendorID); err != nil { - if dao.IsNoRowsError(err) { - needCallNew = true - } else { - return tiktokShop.Err2CallbackResponse(err, "") - } - } - } - - if needCallNew { - var afsOrder *model.AfsOrder - refundData := msg.Data.(*mtwmapi.CallbackRefundInfo) - if msg.Cmd == mtwmapi.MsgTypeOrderPartialRefund { - afsOrder = &model.AfsOrder{ - VendorID: model.VendorIDMTWM, - AfsOrderID: orderStatus.VendorOrderID, - VendorOrderID: orderStatus.RefVendorOrderID, - VendorStoreID: "", - StoreID: 0, - AfsCreatedAt: utils.Timestamp2Time(refundData.Timestamp), - VendorAppealType: "", - AppealType: model.AfsAppealTypeRefund, - VendorReasonType: "", - ReasonType: model.AfsReasonNotOthers, - ReasonDesc: utils.LimitUTF8StringLen(refundData.Reason, 1024), - ReasonImgList: utils.LimitUTF8StringLen(strings.Join(refundData.PictureList, ","), 1024), - RefundType: model.AfsTypePartRefund, - - VendorOrgCode: msg.AppID, - } - for _, sku := range refundData.FoodList { - orderSku := &model.OrderSkuFinancial{ - Count: sku.Count, - VendorSkuID: sku.SkuID, - SkuID: int(utils.Str2Int64WithDefault(sku.SkuID, 0)), - Name: sku.FoodName, - UserMoney: jxutils.StandardPrice2Int(sku.RefundPrice)*int64(sku.Count) + jxutils.StandardPrice2Int(sku.BoxPrice)*int64(sku.BoxNum), - } - afsOrder.SkuUserMoney += orderSku.UserMoney - afsOrder.Skus = append(afsOrder.Skus, orderSku) - } - } else { - if afsOrder = c.createAfsOrder(msg.FormData); afsOrder != nil { - afsOrder.AfsOrderID = orderStatus.VendorOrderID - afsOrder.RefundType = model.AfsTypeFullRefund - afsOrder.AppealType = model.AfsAppealTypeRefund - afsOrder.VendorReasonType = "" - afsOrder.ReasonType = model.AfsReasonNotOthers - afsOrder.ReasonDesc = utils.LimitUTF8StringLen(refundData.Reason, 1024) - afsOrder.ReasonImgList = utils.LimitUTF8StringLen(strings.Join(refundData.PictureList, ","), 1024) - } - } - if afsOrder != nil { - //直接就来一个新的售后单,并且还是售后完成的 - if orderStatus.Status == model.AfsOrderStatusFinished { - afsOrder.AfsFinishedAt = afsOrder.AfsCreatedAt - } - err = partner.CurOrderManager.OnAfsOrderNew(afsOrder, orderStatus) - } - } else { - err = partner.CurOrderManager.OnAfsOrderStatusChanged(orderStatus) - } - } - - return mtwmapi.Err2CallbackResponse(err, "") -} - -func (p *PurchaseHandler) createAfsOrder(orderData url.Values) (afsOrder *model.AfsOrder) { - afsOrder, err := partner.CurOrderManager.CreateAfsOrderFromOrder(orderData.Get("order_id"), model.VendorIDMTWM) - if err == nil { - afsOrder.AfsOrderID = orderData.Get("refund_id") - afsOrder.AfsCreatedAt = utils.Timestamp2Time(utils.Str2Int64(orderData.Get("timestamp"))) - if afsOrder.AfsOrderID == "" { - afsOrder.AfsOrderID = afsOrder.VendorOrderID - } - } else { - afsOrder = nil - } - return afsOrder -} - -func (c *PurchaseHandler) callbackAfsMsg2Status(msg *tiktokShop.OrderCallback) (orderStatus []*model.OrderStatus) { - switch msg.MsgId { - case tiktokShop.CallbackRefundOrderMsgTagId: // 买家发起售后申请消息 - for _, v := range msg.Body[tiktokShop.CallbackRefundOrderMsgTagId] { - refundOrder := v.(*tiktokShop.BuyerRefundCreatedData) - orderMsg := &model.OrderStatus{ - VendorID: model.VendorIDDD, - OrderType: model.OrderTypeAfsOrder, - RefVendorOrderID: utils.Int64ToStr(refundOrder.PId), - RefVendorID: model.VendorIDDD, - VendorStatus: fmt.Sprintf("%s:%s", "order", "create"), - Status: c.GetAfsStatusFromVendorStatus(refundOrder.AftersaleType, tiktokShop.CallbackRefundOrderMsgTagId), - StatusTime: utils.Timestamp2Time(int64(refundOrder.ApplyTime)), - } - if k, ok := ReasonCodeMap[refundOrder.ReasonCode]; ok { - orderMsg.Remark = k - } else { - orderMsg.Remark = "抖音reason_code对应reason不足,需要更新.code:" + string(refundOrder.ReasonCode) - } - - if refundOrder.AftersaleId > 0 { - orderMsg.VendorOrderID = utils.Int64ToStr(refundOrder.AftersaleId) - } else { - orderMsg.VendorOrderID = orderMsg.RefVendorOrderID - } - orderStatus = append(orderStatus, orderMsg) - } - case tiktokShop.CallbackUpdateRefundOrderMsgTagId: // 买家修改售后申请消息 - for _, v := range msg.Body[tiktokShop.CallbackUpdateRefundOrderMsgTagId] { - refundOrder := v.(*tiktokShop.BuyerRefundModifiedData) - orderMsg := &model.OrderStatus{ - VendorID: model.VendorIDDD, - OrderType: model.OrderTypeAfsOrder, - RefVendorOrderID: utils.Int64ToStr(refundOrder.PId), - RefVendorID: model.VendorIDDD, - VendorStatus: fmt.Sprintf("%s:%s", "order", "update"), - Status: c.GetAfsStatusFromVendorStatus(refundOrder.AftersaleType, tiktokShop.CallbackUpdateRefundOrderMsgTagId), - StatusTime: utils.Timestamp2Time(int64(refundOrder.ModifyTime)), - } - if k, ok := ReasonCodeMap[refundOrder.ReasonCode]; ok { - orderMsg.Remark = k - } else { - orderMsg.Remark = "抖音reason_code对应reason不足,需要更新.code:" + string(refundOrder.ReasonCode) - } - - if refundOrder.AftersaleId > 0 { - orderMsg.VendorOrderID = utils.Int64ToStr(refundOrder.AftersaleId) - } else { - orderMsg.VendorOrderID = orderMsg.RefVendorOrderID - } - orderStatus = append(orderStatus, orderMsg) - } - case tiktokShop.CallbackRefundOrderSuccessMsgTagId: // 退款成功消息 - for _, v := range msg.Body[tiktokShop.CallbackRefundOrderSuccessMsgTagId] { - refundOrder := v.(*tiktokShop.BusinessRefundSuccessData) - orderMsg := &model.OrderStatus{ - VendorID: model.VendorIDDD, - OrderType: model.OrderTypeAfsOrder, - RefVendorOrderID: utils.Int64ToStr(refundOrder.PId), - RefVendorID: model.VendorIDDD, - VendorStatus: fmt.Sprintf("%s:%s", "order", "refund_success"), - Status: c.GetAfsStatusFromVendorStatus(refundOrder.AftersaleType, tiktokShop.CallbackUpdateRefundOrderMsgTagId), - StatusTime: utils.Timestamp2Time(int64(refundOrder.SuccessTime)), - } - if k, ok := ReasonCodeMap[refundOrder.ReasonCode]; ok { - orderMsg.Remark = k - } else { - orderMsg.Remark = "抖音reason_code对应reason不足,需要更新.code:" + string(refundOrder.ReasonCode) - } - if refundOrder.AftersaleId > 0 { - orderMsg.VendorOrderID = utils.Int64ToStr(refundOrder.AftersaleId) - } else { - orderMsg.VendorOrderID = orderMsg.RefVendorOrderID - } - orderStatus = append(orderStatus, orderMsg) - } - case tiktokShop.CallbackRefundOrderRefuseMsgTagId: // 拒绝退款消息 - for _, v := range msg.Body[tiktokShop.CallbackRefundOrderSuccessMsgTagId] { - refundOrder := v.(*tiktokShop.BusinessRefundSuccessData) - orderMsg := &model.OrderStatus{ - VendorID: model.VendorIDDD, - OrderType: model.OrderTypeAfsOrder, - RefVendorOrderID: utils.Int64ToStr(refundOrder.PId), - RefVendorID: model.VendorIDDD, - VendorStatus: fmt.Sprintf("%s:%s", "order", "refund_money_fail"), - Status: c.GetAfsStatusFromVendorStatus(refundOrder.AftersaleType, tiktokShop.CallbackUpdateRefundOrderMsgTagId), - StatusTime: utils.Timestamp2Time(int64(refundOrder.SuccessTime)), - } - if k, ok := ReasonCodeMap[refundOrder.ReasonCode]; ok { - orderMsg.Remark = k - } else { - orderMsg.Remark = "抖音reason_code对应reason不足,需要更新.code:" + string(refundOrder.ReasonCode) - } - if refundOrder.AftersaleId > 0 { - orderMsg.VendorOrderID = utils.Int64ToStr(refundOrder.AftersaleId) - } else { - orderMsg.VendorOrderID = orderMsg.RefVendorOrderID - } - orderStatus = append(orderStatus, orderMsg) - } - case tiktokShop.CallbackRefundShopMsgTagId: // 拒绝退货申请消息 - for _, v := range msg.Body[tiktokShop.CallbackRefundShopMsgTagId] { - refundOrder := v.(*tiktokShop.BusinessNotReturnApplyRefusedData) - orderMsg := &model.OrderStatus{ - VendorID: model.VendorIDDD, - OrderType: model.OrderTypeAfsOrder, - RefVendorOrderID: utils.Int64ToStr(refundOrder.PId), - RefVendorID: model.VendorIDDD, - VendorStatus: fmt.Sprintf("%s:%s", "order", "refuse_shop_fail"), - Status: c.GetAfsStatusFromVendorStatus(refundOrder.AftersaleType, tiktokShop.CallbackRefundShopMsgTagId), - StatusTime: utils.Timestamp2Time(int64(refundOrder.RefuseTime)), - } - if k, ok := ReasonCodeMap[refundOrder.ReasonCode]; ok { - orderMsg.Remark = k - } else { - orderMsg.Remark = "抖音reason_code对应reason不足,需要更新.code:" + string(refundOrder.ReasonCode) - } - if refundOrder.AftersaleId > 0 { - orderMsg.VendorOrderID = utils.Int64ToStr(refundOrder.AftersaleId) - } else { - orderMsg.VendorOrderID = orderMsg.RefVendorOrderID - } - orderStatus = append(orderStatus, orderMsg) - } - case tiktokShop.CallbackReturnApplyAgreedMsgTagId: // 同意退货申请消息 - for _, v := range msg.Body[tiktokShop.CallbackReturnApplyAgreedMsgTagId] { - refundOrder := v.(*tiktokShop.BusinessRefundSuccessData) - orderMsg := &model.OrderStatus{ - VendorID: model.VendorIDDD, - OrderType: model.OrderTypeAfsOrder, - RefVendorOrderID: utils.Int64ToStr(refundOrder.PId), - RefVendorID: model.VendorIDDD, - VendorStatus: fmt.Sprintf("%s:%s", "order", "refund_shop_success"), - Status: c.GetAfsStatusFromVendorStatus(refundOrder.AftersaleType, tiktokShop.CallbackReturnApplyAgreedMsgTagId), - StatusTime: utils.Timestamp2Time(int64(refundOrder.SuccessTime)), - } - if k, ok := ReasonCodeMap[refundOrder.ReasonCode]; ok { - orderMsg.Remark = k - } else { - orderMsg.Remark = "抖音reason_code对应reason不足,需要更新.code:" + string(refundOrder.ReasonCode) - } - if refundOrder.AftersaleId > 0 { - orderMsg.VendorOrderID = utils.Int64ToStr(refundOrder.AftersaleId) - } else { - orderMsg.VendorOrderID = orderMsg.RefVendorOrderID - } - orderStatus = append(orderStatus, orderMsg) - } - case tiktokShop.CallbackReturnRefundAgreedMsgTagId: // 同意退款消息 - for _, v := range msg.Body[tiktokShop.CallbackReturnRefundAgreedMsgTagId] { - refundOrder := v.(*tiktokShop.BusinessRefundSuccessData) - orderMsg := &model.OrderStatus{ - VendorID: model.VendorIDDD, - OrderType: model.OrderTypeAfsOrder, - RefVendorOrderID: utils.Int64ToStr(refundOrder.PId), - RefVendorID: model.VendorIDDD, - VendorStatus: fmt.Sprintf("%s:%s", "order", "refund_money_success"), - Status: c.GetAfsStatusFromVendorStatus(refundOrder.AftersaleType, tiktokShop.CallbackReturnRefundAgreedMsgTagId), - StatusTime: utils.Timestamp2Time(int64(refundOrder.SuccessTime)), - } - if k, ok := ReasonCodeMap[refundOrder.ReasonCode]; ok { - orderMsg.Remark = k - } else { - orderMsg.Remark = "抖音reason_code对应reason不足,需要更新.code:" + string(refundOrder.ReasonCode) - } - if refundOrder.AftersaleId > 0 { - orderMsg.VendorOrderID = utils.Int64ToStr(refundOrder.AftersaleId) - } else { - orderMsg.VendorOrderID = orderMsg.RefVendorOrderID - } - orderStatus = append(orderStatus, orderMsg) - } - default: - return nil - } - - return orderStatus -} - -func (c *PurchaseHandler) GetAfsStatusFromVendorStatus(resType int, notifyType string) int { - status := AfsVendorStatus2StatusMap[notifyType] - if status == model.AfsOrderStatusWait4Approve && resType != mtwmapi.ResTypePending { - status = model.AfsOrderStatusNew - } - return status -} - -// 审核售后单申请 +// AgreeOrRefuseRefund todo 审核售后单申请 退货退款(同意退货,确认收货之后会自动退款) 审核售后有点问题 func (c *PurchaseHandler) AgreeOrRefuseRefund(ctx *jxcontext.Context, order *model.AfsOrder, approveType int, reason string) (err error) { - if globals.EnableMtwmStoreWrite { - if approveType == partner.AfsApproveTypeRefused { - err = getAPI(order.VendorOrgCode, jxutils.GetSaleStoreIDFromAfsOrder(order), order.VendorStoreID).OrderRefundReject(utils.Str2Int64(order.VendorOrderID), reason) + if globals.EnableDdStoreWrite { + if approveType == partner.AfsApproveTypeRefused { // 拒绝退货 + err = getAPI(order.VendorOrgCode, order.JxStoreID, "").ReturnGoodsToWareHouseSuccess(order.AfsOrderID) } else { - err = getAPI(order.VendorOrgCode, jxutils.GetSaleStoreIDFromAfsOrder(order), order.VendorStoreID).OrderRefundAgree(utils.Str2Int64(order.VendorOrderID), reason) + err = getAPI(order.VendorOrgCode, order.JxStoreID, "").ReturnGoodsToWareHouseSuccess(order.AfsOrderID) } } return err @@ -418,13 +125,13 @@ func (c *PurchaseHandler) AgreeOrRefuseRefund(ctx *jxcontext.Context, order *mod // 确认收到退货 func (c *PurchaseHandler) ConfirmReceivedReturnGoods(ctx *jxcontext.Context, order *model.AfsOrder) (err error) { - err = fmt.Errorf("内部错误,美团外卖平台不支持确认收到退货操作") + err = fmt.Errorf("暂不支持的API调用") return err } // 发起全款退款 func (c *PurchaseHandler) RefundOrder(ctx *jxcontext.Context, order *model.GoodsOrder, reason string) (err error) { - return fmt.Errorf("%s不支持售后全额退款,请让买家发起退款", model.VendorChineseNames[model.VendorIDMTWM]) + return fmt.Errorf("%s不支持售后全额退款,请让买家发起退款", model.VendorChineseNames[model.VendorIDDD]) } // 发起部分退款 diff --git a/business/partner/purchase/tiktok_store/order_afs_utils.go b/business/partner/purchase/tiktok_store/order_afs_utils.go new file mode 100644 index 000000000..25a03f081 --- /dev/null +++ b/business/partner/purchase/tiktok_store/order_afs_utils.go @@ -0,0 +1,294 @@ +package tiktok_store + +import ( + "fmt" + tiktokShop "git.rosy.net.cn/baseapi/platformapi/tiktok_shop/tiktok_api" + "git.rosy.net.cn/baseapi/utils" + "git.rosy.net.cn/jx-callback/business/jxutils" + "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" + "strings" +) + +var ( + afsAppealTypeMap = map[int64]int8{ + tiktokShop.AfterSaleTypeAll: model.AfsAppealTypeReturnAndRefund, + tiktokShop.AfterSaleTypeSendPkgOnlyReturnMoney: model.AfsAppealTypeRefund, + tiktokShop.AfterSaleTypeReturnMoney: model.AfsAppealTypeRefund, + tiktokShop.AfterSaleTypeChangePkg: model.AfsAppealTypeNewGoods, + tiktokShop.AfterSaleTypeSystemCancel: model.AfsAppealTypeSystemCancel, + tiktokShop.AfterSaleTypeUserCancel: model.AfsAppealTypeUserCancel, + tiktokShop.AfterSaleTypeInsuredPrice: model.AfsAppealTypeInsuredPrice, + tiktokShop.AfterSaleTypeReissue: model.AfsAppealTypeReissue, + } +) + +// convertAfsAppealType 抖音订单索赔状态转换为当前系统状态 +func (c *PurchaseHandler) convertAfsAppealType(vendorAppealType int64) int8 { + if status, ok := afsAppealTypeMap[vendorAppealType]; ok { + return status + } + return 0 +} + +// 是否为售后消息 +func (c *PurchaseHandler) isAfsMsg(msg string) bool { + _, ok := AfsTagIDMap[msg] + return ok +} + +func (c *PurchaseHandler) OnAfsOrderMsg(msgId, orderId string, msg interface{}) (retVal *tiktokShop.CallbackResponse) { + jxutils.CallMsgHandlerAsync(func() { + retVal = c.onAfsOrderMsg(msgId, msg) + }, jxutils.ComposeUniversalOrderID(orderId, model.VendorIDDD)) + return retVal +} + +// todo 对于退款与部分退款,order.go与这个文件中对于状态的处理不一致 +func (c *PurchaseHandler) onAfsOrderMsg(msgId string, msg interface{}) (retVal *tiktokShop.CallbackResponse) { + var err error + orderStatus := c.callbackAfsMsg2Status(msgId, msg) + if orderStatus == nil { + return tiktokShop.Err2CallbackResponse(nil, "") + } + needCallNew := orderStatus.Status == model.AfsOrderStatusWait4Approve || orderStatus.Status == model.AfsOrderStatusNew + if !needCallNew { + if _, err := partner.CurOrderManager.LoadAfsOrder(orderStatus.VendorOrderID, orderStatus.VendorID); err != nil { + if dao.IsNoRowsError(err) { + needCallNew = true + } else { + return tiktokShop.Err2CallbackResponse(err, "") + } + } + } + + if needCallNew { + var afsOrder *model.AfsOrder + // 查询售后订单详情 + tiktokAfsOrderDetail, err := api.TiktokStore.QueryAfsOrderDetail(orderStatus.VendorOrderID, false) + if err != nil { + globals.SugarLogger.Debug("tic-tok get AfsOrder err :", err) + return tiktokShop.Err2CallbackResponse(err, "") + } + + if msgId == tiktokShop.CallbackRefundOrderMsgTagId { // 不存在的新订单 + afsOrder = &model.AfsOrder{ + VendorID: model.VendorIDDD, + AfsOrderID: orderStatus.VendorOrderID, + VendorOrderID: orderStatus.RefVendorOrderID, + VendorStoreID: "", + StoreID: 0, + AfsCreatedAt: orderStatus.StatusTime, + + VendorAppealType: utils.Int64ToStr(tiktokAfsOrderDetail.Data.ProcessInfo.AfterSaleInfo.AfterSaleStatus), + AppealType: c.convertAfsAppealType(tiktokAfsOrderDetail.Data.ProcessInfo.AfterSaleInfo.AfterSaleType), + VendorReasonType: tiktokAfsOrderDetail.Data.ProcessInfo.AfterSaleInfo.Reason, + ReasonType: int8(tiktokAfsOrderDetail.Data.ProcessInfo.AfterSaleInfo.ReasonCode), + ReasonDesc: tiktokAfsOrderDetail.Data.ProcessInfo.AfterSaleInfo.ReasonRemark, + ReasonImgList: utils.LimitUTF8StringLen(strings.Join(tiktokAfsOrderDetail.Data.ProcessInfo.AfterSaleInfo.Evidence, ","), 1024), + RefundType: model.AfsTypeUnknown, + VendorOrgCode: api.TiktokStore.GetAppId(), + } + afsOrder.FreightUserMoney = tiktokAfsOrderDetail.Data.ProcessInfo.AfterSaleInfo.RefundPostAmount + afsOrder.AfsFreightMoney = 0 // 暂时未发现退货取件费用 + afsOrder.BoxMoney = 0 // 餐盒费 + afsOrder.TongchengFreightMoney = 0 // 同城配送费 + afsOrder.SkuBoxMoney = 0 // 商品包装费 + afsOrder.VendorStatus = orderStatus.VendorStatus // 退货状态 + for _, sku := range tiktokAfsOrderDetail.Data.OrderInfo.SkuOrderInfos { + orderSku := &model.OrderSkuFinancial{ + Count: int(sku.ItemQuantity), + VendorSkuID: utils.Int64ToStr(sku.SkuOrderId), + SkuID: utils.Str2Int(sku.ShopSkuCode), + Name: sku.ProductName, + UserMoney: sku.PayAmount, + PmSkuSubsidyMoney: sku.PromotionAmount, // 平台补贴商品 + } + + afsOrder.PmSkuSubsidyMoney += orderSku.PmSkuSubsidyMoney + afsOrder.SkuUserMoney += orderSku.UserMoney + afsOrder.Skus = append(afsOrder.Skus, orderSku) + } + } + if afsOrder != nil { + //直接就来一个新的售后单,并且还是售后完成的 + if orderStatus.Status == model.AfsOrderStatusFinished { + afsOrder.AfsFinishedAt = afsOrder.AfsCreatedAt + } + err = partner.CurOrderManager.OnAfsOrderNew(afsOrder, orderStatus) + } + } else { + err = partner.CurOrderManager.OnAfsOrderStatusChanged(orderStatus) + } + + return tiktokShop.Err2CallbackResponse(err, "") +} + +func (c *PurchaseHandler) callbackAfsMsg2Status(msgId string, msg interface{}) (orderStatus *model.OrderStatus) { + switch msgId { + case tiktokShop.CallbackRefundOrderMsgTagId: // 买家发起售后申请消息 + refundOrder := msg.(*tiktokShop.BuyerRefundCreatedData) + orderMsg := &model.OrderStatus{ + VendorID: model.VendorIDDD, + OrderType: model.OrderTypeAfsOrder, + RefVendorOrderID: utils.Int64ToStr(refundOrder.PId), + RefVendorID: model.VendorIDDD, + VendorStatus: fmt.Sprintf("%s:%s", "order", "create"), + Status: c.GetAfsStatusFromVendorStatus(refundOrder.AftersaleType, tiktokShop.CallbackRefundOrderMsgTagId), + StatusTime: utils.Timestamp2Time(int64(refundOrder.ApplyTime)), + } + if k, ok := ReasonCodeMap[refundOrder.ReasonCode]; ok { + orderMsg.Remark = k + } else { + orderMsg.Remark = "抖音reason_code对应reason不足,需要更新.code:" + string(refundOrder.ReasonCode) + } + + if refundOrder.AftersaleId > 0 { + orderMsg.VendorOrderID = utils.Int64ToStr(refundOrder.AftersaleId) + } else { + orderMsg.VendorOrderID = orderMsg.RefVendorOrderID + } + case tiktokShop.CallbackUpdateRefundOrderMsgTagId: // 买家修改售后申请消息 + refundOrder := msg.(*tiktokShop.BuyerRefundModifiedData) + orderMsg := &model.OrderStatus{ + VendorID: model.VendorIDDD, + OrderType: model.OrderTypeAfsOrder, + RefVendorOrderID: utils.Int64ToStr(refundOrder.PId), + RefVendorID: model.VendorIDDD, + VendorStatus: fmt.Sprintf("%s:%s", "order", "update"), + Status: c.GetAfsStatusFromVendorStatus(refundOrder.AftersaleType, tiktokShop.CallbackUpdateRefundOrderMsgTagId), + StatusTime: utils.Timestamp2Time(int64(refundOrder.ModifyTime)), + } + if k, ok := ReasonCodeMap[refundOrder.ReasonCode]; ok { + orderMsg.Remark = k + } else { + orderMsg.Remark = "抖音reason_code对应reason不足,需要更新.code:" + string(refundOrder.ReasonCode) + } + + if refundOrder.AftersaleId > 0 { + orderMsg.VendorOrderID = utils.Int64ToStr(refundOrder.AftersaleId) + } else { + orderMsg.VendorOrderID = orderMsg.RefVendorOrderID + } + case tiktokShop.CallbackRefundOrderSuccessMsgTagId: // 退款成功消息 + refundOrder := msg.(*tiktokShop.BusinessRefundSuccessData) + orderMsg := &model.OrderStatus{ + VendorID: model.VendorIDDD, + OrderType: model.OrderTypeAfsOrder, + RefVendorOrderID: utils.Int64ToStr(refundOrder.PId), + RefVendorID: model.VendorIDDD, + VendorStatus: fmt.Sprintf("%s:%s", "order", "refund_success"), + Status: c.GetAfsStatusFromVendorStatus(refundOrder.AftersaleType, tiktokShop.CallbackUpdateRefundOrderMsgTagId), + StatusTime: utils.Timestamp2Time(int64(refundOrder.SuccessTime)), + } + if k, ok := ReasonCodeMap[refundOrder.ReasonCode]; ok { + orderMsg.Remark = k + } else { + orderMsg.Remark = "抖音reason_code对应reason不足,需要更新.code:" + string(refundOrder.ReasonCode) + } + if refundOrder.AftersaleId > 0 { + orderMsg.VendorOrderID = utils.Int64ToStr(refundOrder.AftersaleId) + } else { + orderMsg.VendorOrderID = orderMsg.RefVendorOrderID + } + case tiktokShop.CallbackRefundOrderRefuseMsgTagId: // 拒绝退款消息 + refundOrder := msg.(*tiktokShop.BusinessRefundSuccessData) + orderMsg := &model.OrderStatus{ + VendorID: model.VendorIDDD, + OrderType: model.OrderTypeAfsOrder, + RefVendorOrderID: utils.Int64ToStr(refundOrder.PId), + RefVendorID: model.VendorIDDD, + VendorStatus: fmt.Sprintf("%s:%s", "order", "refund_money_fail"), + Status: c.GetAfsStatusFromVendorStatus(refundOrder.AftersaleType, tiktokShop.CallbackUpdateRefundOrderMsgTagId), + StatusTime: utils.Timestamp2Time(int64(refundOrder.SuccessTime)), + } + if k, ok := ReasonCodeMap[refundOrder.ReasonCode]; ok { + orderMsg.Remark = k + } else { + orderMsg.Remark = "抖音reason_code对应reason不足,需要更新.code:" + string(refundOrder.ReasonCode) + } + if refundOrder.AftersaleId > 0 { + orderMsg.VendorOrderID = utils.Int64ToStr(refundOrder.AftersaleId) + } else { + orderMsg.VendorOrderID = orderMsg.RefVendorOrderID + } + case tiktokShop.CallbackRefundShopMsgTagId: // 拒绝退货申请消息 + refundOrder := msg.(*tiktokShop.BusinessNotReturnApplyRefusedData) + orderMsg := &model.OrderStatus{ + VendorID: model.VendorIDDD, + OrderType: model.OrderTypeAfsOrder, + RefVendorOrderID: utils.Int64ToStr(refundOrder.PId), + RefVendorID: model.VendorIDDD, + VendorStatus: fmt.Sprintf("%s:%s", "order", "refuse_shop_fail"), + Status: c.GetAfsStatusFromVendorStatus(refundOrder.AftersaleType, tiktokShop.CallbackRefundShopMsgTagId), + StatusTime: utils.Timestamp2Time(int64(refundOrder.RefuseTime)), + } + if k, ok := ReasonCodeMap[refundOrder.ReasonCode]; ok { + orderMsg.Remark = k + } else { + orderMsg.Remark = "抖音reason_code对应reason不足,需要更新.code:" + string(refundOrder.ReasonCode) + } + if refundOrder.AftersaleId > 0 { + orderMsg.VendorOrderID = utils.Int64ToStr(refundOrder.AftersaleId) + } else { + orderMsg.VendorOrderID = orderMsg.RefVendorOrderID + } + case tiktokShop.CallbackReturnApplyAgreedMsgTagId: // 同意退货申请消息 + refundOrder := msg.(*tiktokShop.BusinessRefundSuccessData) + orderMsg := &model.OrderStatus{ + VendorID: model.VendorIDDD, + OrderType: model.OrderTypeAfsOrder, + RefVendorOrderID: utils.Int64ToStr(refundOrder.PId), + RefVendorID: model.VendorIDDD, + VendorStatus: fmt.Sprintf("%s:%s", "order", "refund_shop_success"), + Status: c.GetAfsStatusFromVendorStatus(refundOrder.AftersaleType, tiktokShop.CallbackReturnApplyAgreedMsgTagId), + StatusTime: utils.Timestamp2Time(int64(refundOrder.SuccessTime)), + } + if k, ok := ReasonCodeMap[refundOrder.ReasonCode]; ok { + orderMsg.Remark = k + } else { + orderMsg.Remark = "抖音reason_code对应reason不足,需要更新.code:" + string(refundOrder.ReasonCode) + } + if refundOrder.AftersaleId > 0 { + orderMsg.VendorOrderID = utils.Int64ToStr(refundOrder.AftersaleId) + } else { + orderMsg.VendorOrderID = orderMsg.RefVendorOrderID + } + case tiktokShop.CallbackReturnRefundAgreedMsgTagId: // 同意退款消息 + refundOrder := msg.(*tiktokShop.BusinessRefundSuccessData) + orderMsg := &model.OrderStatus{ + VendorID: model.VendorIDDD, + OrderType: model.OrderTypeAfsOrder, + RefVendorOrderID: utils.Int64ToStr(refundOrder.PId), + RefVendorID: model.VendorIDDD, + VendorStatus: fmt.Sprintf("%s:%s", "order", "refund_money_success"), + Status: c.GetAfsStatusFromVendorStatus(refundOrder.AftersaleType, tiktokShop.CallbackReturnRefundAgreedMsgTagId), + StatusTime: utils.Timestamp2Time(int64(refundOrder.SuccessTime)), + } + if k, ok := ReasonCodeMap[refundOrder.ReasonCode]; ok { + orderMsg.Remark = k + } else { + orderMsg.Remark = "抖音reason_code对应reason不足,需要更新.code:" + string(refundOrder.ReasonCode) + } + if refundOrder.AftersaleId > 0 { + orderMsg.VendorOrderID = utils.Int64ToStr(refundOrder.AftersaleId) + } else { + orderMsg.VendorOrderID = orderMsg.RefVendorOrderID + } + default: + return nil + } + + return orderStatus +} + +func (c *PurchaseHandler) GetAfsStatusFromVendorStatus(resType int, notifyType string) int { + status := AfsVendorStatus2StatusMap[notifyType] + if status == model.AfsOrderStatusWait4Approve && resType == tiktokShop.AfterSaleStatusApply { + status = model.AfsOrderStatusNew + } + return status +} diff --git a/business/partner/purchase/tiktok_store/order_comment.go b/business/partner/purchase/tiktok_store/order_comment.go index 1a0d89eb9..26f1208f5 100644 --- a/business/partner/purchase/tiktok_store/order_comment.go +++ b/business/partner/purchase/tiktok_store/order_comment.go @@ -4,16 +4,9 @@ import ( "strings" "time" - "git.rosy.net.cn/baseapi/platformapi/mtwmapi" - - "git.rosy.net.cn/jx-callback/business/jxutils/tasksch" - "git.rosy.net.cn/jx-callback/business/partner" - "git.rosy.net.cn/baseapi/utils" "git.rosy.net.cn/jx-callback/business/jxutils/jxcontext" "git.rosy.net.cn/jx-callback/business/model" - "git.rosy.net.cn/jx-callback/business/model/dao" - "git.rosy.net.cn/jx-callback/globals" ) const ( @@ -42,72 +35,73 @@ func formalizeTagList(mtwmTagList string) (outTagList string) { return outTagList } +// RefreshComment 拉去用户评论 func (c *PurchaseHandler) RefreshComment(fromTime, toTime time.Time) (err error) { //storeMapList, err2 := dao.GetStoresMapList(dao.GetDB(), []int{model.VendorIDMTWM}, nil, nil, model.StoreStatusAll, model.StoreIsSyncYes, "", "", "") //if err = err2; err != nil { // return err //} - endDateStr := time.Now().Add(-24 * time.Hour).Format("20060102") - startDateStr := time.Now().Add(-RefreshCommentTime).Format("20060102") - storeIDs, _ := dao.GetOrderStoreIDs(dao.GetDB(), fromTime, toTime, model.VendorIDMTWM) - task := tasksch.NewParallelTask("mtwm RefreshComment", nil, jxcontext.AdminCtx, - func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - storeID := batchItemList[0].(int) - storeDetail, _ := dao.GetStoreDetail(dao.GetDB(), storeID, model.VendorIDMTWM, "") - commentList, err2 := getAPI(storeDetail.VendorOrgCode, storeID, storeDetail.VendorStoreID).CommentQuery(storeDetail.VendorStoreID, startDateStr, endDateStr, 0, 0, mtwmapi.CommentReplyStatusNotReplied) - var orderCommentList []*model.OrderComment - if err = err2; err != nil { - return nil, err - } - for _, mtwmComment := range commentList { - createdTime, err := utils.TryStr2Time(mtwmComment.CommentTime) - if err == nil { - orderComment := &model.OrderComment{ - VendorOrderID: utils.Int64ToStr(mtwmComment.CommentID), // 美团评价不能得到订单号,以评价ID代替 - VendorID: model.VendorIDMTWM, - UserCommentID: utils.Int64ToStr(mtwmComment.CommentID), - VendorStoreID: storeDetail.VendorStoreID, - TagList: formalizeTagList(mtwmComment.CommentLables), - Score: int8(mtwmComment.FoodCommentScore), - ModifyDuration: BAD_COMMENTS_MAX_MODIFY_TIME, - OriginalMsg: string(utils.MustMarshal(mtwmComment)), - IsReplied: int8(mtwmComment.ReplyStatus), - StoreID: storeDetail.ID, - } - if orderComment.IsReplied == 0 { - orderComment.Content = mtwmComment.CommentContent - orderComment.CommentCreatedAt = createdTime - } else { - orderComment.Content = mtwmComment.AddComment - if updatedTime, err := utils.TryStr2Time(mtwmComment.CommentTime); err == nil { - orderComment.CommentCreatedAt = updatedTime - } - } - orderCommentList = append(orderCommentList, orderComment) - } - } - return orderCommentList, nil - }, storeIDs) - task.Run() - resultList, err2 := task.GetResult(0) - if err = err2; err != nil { - return err - } - var orderCommentList []*model.OrderComment - for _, result := range resultList { - orderComment := result.(*model.OrderComment) - orderCommentList = append(orderCommentList, orderComment) - } - if len(orderCommentList) > 0 { - err = partner.CurOrderManager.OnOrderComments(orderCommentList) - } + //endDateStr := time.Now().Add(-24 * time.Hour).Format("20060102") + //startDateStr := time.Now().Add(-RefreshCommentTime).Format("20060102") + //storeIDs, _ := dao.GetOrderStoreIDs(dao.GetDB(), fromTime, toTime, model.VendorIDMTWM) + //task := tasksch.NewParallelTask("mtwm RefreshComment", nil, jxcontext.AdminCtx, + // func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { + // storeID := batchItemList[0].(int) + // storeDetail, _ := dao.GetStoreDetail(dao.GetDB(), storeID, model.VendorIDMTWM, "") + // commentList, err2 := getAPI(storeDetail.VendorOrgCode, storeID, storeDetail.VendorStoreID).CommentQuery(storeDetail.VendorStoreID, startDateStr, endDateStr, 0, 0, mtwmapi.CommentReplyStatusNotReplied) + // var orderCommentList []*model.OrderComment + // if err = err2; err != nil { + // return nil, err + // } + // for _, mtwmComment := range commentList { + // createdTime, err := utils.TryStr2Time(mtwmComment.CommentTime) + // if err == nil { + // orderComment := &model.OrderComment{ + // VendorOrderID: utils.Int64ToStr(mtwmComment.CommentID), // 美团评价不能得到订单号,以评价ID代替 + // VendorID: model.VendorIDMTWM, + // UserCommentID: utils.Int64ToStr(mtwmComment.CommentID), + // VendorStoreID: storeDetail.VendorStoreID, + // TagList: formalizeTagList(mtwmComment.CommentLables), + // Score: int8(mtwmComment.FoodCommentScore), + // ModifyDuration: BAD_COMMENTS_MAX_MODIFY_TIME, + // OriginalMsg: string(utils.MustMarshal(mtwmComment)), + // IsReplied: int8(mtwmComment.ReplyStatus), + // StoreID: storeDetail.ID, + // } + // if orderComment.IsReplied == 0 { + // orderComment.Content = mtwmComment.CommentContent + // orderComment.CommentCreatedAt = createdTime + // } else { + // orderComment.Content = mtwmComment.AddComment + // if updatedTime, err := utils.TryStr2Time(mtwmComment.CommentTime); err == nil { + // orderComment.CommentCreatedAt = updatedTime + // } + // } + // orderCommentList = append(orderCommentList, orderComment) + // } + // } + // return orderCommentList, nil + // }, storeIDs) + //task.Run() + //resultList, err2 := task.GetResult(0) + //if err = err2; err != nil { + // return err + //} + //var orderCommentList []*model.OrderComment + //for _, result := range resultList { + // orderComment := result.(*model.OrderComment) + // orderCommentList = append(orderCommentList, orderComment) + //} + //if len(orderCommentList) > 0 { + // err = partner.CurOrderManager.OnOrderComments(orderCommentList) + //} return err } +// ReplyOrderComment 订单评价恢复 func (c *PurchaseHandler) ReplyOrderComment(ctx *jxcontext.Context, vendorOrgCode string, orderComment *model.OrderComment, replyComment string) (err error) { - globals.SugarLogger.Debugf("mtwm ReplyOrderComment, orderComment:%s, replyComment:%s", utils.Format4Output(orderComment, true), replyComment) - if globals.EnableMtwmStoreWrite { - err = getAPI(vendorOrgCode, orderComment.StoreID, orderComment.VendorStoreID).CommentAddReply(orderComment.VendorStoreID, utils.Str2Int64(orderComment.UserCommentID), replyComment) - } + //if globals.EnableMtwmStoreWrite { + // err = getAPI(vendorOrgCode, orderComment.StoreID, orderComment.VendorStoreID).CommentAddReply(orderComment.VendorStoreID, utils.Str2Int64(orderComment.UserCommentID), replyComment) + //} return err } diff --git a/business/partner/purchase/tiktok_store/store_sku2.go b/business/partner/purchase/tiktok_store/store_sku2.go index c83b00999..707d4c03e 100644 --- a/business/partner/purchase/tiktok_store/store_sku2.go +++ b/business/partner/purchase/tiktok_store/store_sku2.go @@ -2,6 +2,11 @@ package tiktok_store import ( "encoding/json" + "fmt" + product_addV2_request "git.rosy.net.cn/baseapi/platformapi/tiktok_shop/sdk-golang/api/product_addV2/request" + product_detail_response "git.rosy.net.cn/baseapi/platformapi/tiktok_shop/sdk-golang/api/product_detail/response" + product_editV2_request "git.rosy.net.cn/baseapi/platformapi/tiktok_shop/sdk-golang/api/product_editV2/request" + tiktokShop "git.rosy.net.cn/baseapi/platformapi/tiktok_shop/tiktok_api" "regexp" "strings" @@ -34,12 +39,13 @@ var ( sensitiveWordRegexp = regexp.MustCompile(`包含敏感词:(\[.*\])`) ) +// GetStoreSkusBatchSize 当前任务最大更新条数 func (p *PurchaseHandler) GetStoreSkusBatchSize(funcID int) (batchSize int) { switch funcID { case partner.FuncUpdateStoreSkusStock, partner.FuncUpdateStoreSkusStatus, partner.FuncUpdateStoreSkusPrice: - batchSize = mtwmapi.MaxStoreSkuBatchSize + batchSize = tiktokShop.MaxStoreSkuBatchSize case partner.FuncDeleteStoreSkus: - batchSize = mtwmapi.MaxBatchDeleteSize + batchSize = tiktokShop.MaxBatchDeleteSize case partner.FuncCreateStoreSkus: batchSize = 1 // 可考虑用批量操作 case partner.FuncUpdateStoreSkus: @@ -47,36 +53,36 @@ func (p *PurchaseHandler) GetStoreSkusBatchSize(funcID int) (batchSize int) { case partner.FuncGetStoreSkusFullInfo: batchSize = 1 case partner.FuncCreateActs: - batchSize = mtwmapi.MaxRetailDiscountCreateBatchSize + batchSize = tiktokShop.MaxRetailDiscountCreateBatchSize case partner.FuncCancelActs: - batchSize = mtwmapi.MaxRetailDiscountDeleteBatchSize + batchSize = tiktokShop.MaxRetailDiscountDeleteBatchSize } return batchSize } func getStoreVendorOrgCode(storeID int) (vendorOrgCode string) { - if storeMap, _ := dao.GetStoreDetail(dao.GetDB(), storeID, model.VendorIDMTWM, ""); storeMap != nil { + if storeMap, _ := dao.GetStoreDetail(dao.GetDB(), storeID, model.VendorIDDD, ""); storeMap != nil { return storeMap.VendorOrgCode } return vendorOrgCode } -// 门店分类 +// GetStoreAllCategories 门店分类 func (p *PurchaseHandler) GetStoreAllCategories(ctx *jxcontext.Context, storeID int, vendorStoreID string) (cats []*partner.BareCategoryInfo, err error) { - remoteCats, err := getAPI(getStoreVendorOrgCode(storeID), storeID, vendorStoreID).RetailCatList(vendorStoreID) + remoteCats, err := getAPI(getStoreVendorOrgCode(storeID), storeID, vendorStoreID).GetShopCategory(0) if err == nil { cats = convertVendorCatList(remoteCats) } return cats, err } -func convertVendorCatList(remoteCats []*mtwmapi.RetailCategoryInfo) (cats []*partner.BareCategoryInfo) { +func convertVendorCatList(remoteCats []*tiktokShop.RetailCategoryInfo) (cats []*partner.BareCategoryInfo) { for _, rCat := range remoteCats { cat := &partner.BareCategoryInfo{ - VendorCatID: rCat.Code, + VendorCatID: utils.Int64ToStr(rCat.Id), Name: rCat.Name, - Level: rCat.Level, - Seq: rCat.Sequence, + Level: int(rCat.Level), + Seq: 0, Children: convertVendorCatList(rCat.Children), } if cat.VendorCatID == "" { @@ -113,63 +119,63 @@ func tryCatName2Code(originName string) (catCodeStr string) { } func (p *PurchaseHandler) CreateStoreCategory(ctx *jxcontext.Context, storeID int, vendorStoreID string, storeCat *dao.SkuStoreCatInfo) (err error) { - level := 1 - if storeCat.ParentCatName != "" { - level = 2 - } - originName := "" - catName := storeCat.Name - catCode := storeCat.ID - - subCatName := "" - subCatCode := 0 - if storeCat.CatSyncStatus&model.SyncFlagNewMask == 0 { - // 修改一级分类 - originName = storeCat.VendorCatID - } - if level == 2 { // 二级分类 - // 创建二级分类 - originName = storeCat.ParentVendorCatID - catName = storeCat.ParentCatName - catCode = storeCat.ParentID - subCatName = storeCat.Name - subCatCode = storeCat.ID - if storeCat.CatSyncStatus&model.SyncFlagNewMask == 0 { - // 修改二级分类 - originName = storeCat.VendorCatID - catName = storeCat.Name - catCode = storeCat.ID - subCatName = "" - subCatCode = 0 - } - } - if catName == "" { - panic("catName is empty") - } - catName = utils.FilterEmoji(catName) - subCatName = utils.FilterEmoji(subCatName) - globals.SugarLogger.Debugf("mtwm CreateStoreCategory vendorStoreID:%s, originName:%s, catCode:%d, catName:%s, subCatCode:%d, subCatName:%s, seq:%d", - vendorStoreID, originName, catCode, catName, subCatCode, subCatName, storeCat.Seq) - if globals.EnableMtwmStoreWrite { - // err = api.MtwmAPI.RetailCatUpdate2(vendorStoreID, tryCatName2Code(originName), originName, catCode2Str(catCode), catName, catCode2Str(subCatCode), subCatName, storeCat.Seq) - param4Update := &mtwmapi.Param4UpdateCat{ - CategoryCodeOrigin: tryCatName2Code(originName), - CategoryNameOrigin: originName, - CategoryCode: catCode2Str(catCode), - SecondaryCategoryCode: catCode2Str(subCatCode), - SecondaryCategoryName: subCatName, - Sequence: storeCat.Seq, - } - err = getAPI(storeCat.VendorOrgCode, storeID, vendorStoreID).RetailCatUpdate(vendorStoreID, catName, param4Update) - if storeCat.CatSyncStatus&model.SyncFlagNewMask == 0 && p.IsErrCategoryNotExist(err) && originName != "" { // 修改分类名,但分类不存在 - storeCat.CatSyncStatus |= model.SyncFlagNewMask - err = p.CreateStoreCategory(ctx, storeID, vendorStoreID, storeCat) - } - } - if err == nil { - // storeCat.VendorCatID = utils.FilterEmoji(storeCat.Name) - storeCat.VendorCatID = utils.Int2Str(storeCat.ID) - } + //level := 1 + //if storeCat.ParentCatName != "" { + // level = 2 + //} + //originName := "" + //catName := storeCat.Name + //catCode := storeCat.ID + // + //subCatName := "" + //subCatCode := 0 + //if storeCat.CatSyncStatus&model.SyncFlagNewMask == 0 { + // // 修改一级分类 + // originName = storeCat.VendorCatID + //} + //if level == 2 { // 二级分类 + // // 创建二级分类 + // originName = storeCat.ParentVendorCatID + // catName = storeCat.ParentCatName + // catCode = storeCat.ParentID + // subCatName = storeCat.Name + // subCatCode = storeCat.ID + // if storeCat.CatSyncStatus&model.SyncFlagNewMask == 0 { + // // 修改二级分类 + // originName = storeCat.VendorCatID + // catName = storeCat.Name + // catCode = storeCat.ID + // subCatName = "" + // subCatCode = 0 + // } + //} + //if catName == "" { + // panic("catName is empty") + //} + //catName = utils.FilterEmoji(catName) + //subCatName = utils.FilterEmoji(subCatName) + //globals.SugarLogger.Debugf("mtwm CreateStoreCategory vendorStoreID:%s, originName:%s, catCode:%d, catName:%s, subCatCode:%d, subCatName:%s, seq:%d", + // vendorStoreID, originName, catCode, catName, subCatCode, subCatName, storeCat.Seq) + //if globals.EnableMtwmStoreWrite { + // // err = api.MtwmAPI.RetailCatUpdate2(vendorStoreID, tryCatName2Code(originName), originName, catCode2Str(catCode), catName, catCode2Str(subCatCode), subCatName, storeCat.Seq) + // param4Update := &mtwmapi.Param4UpdateCat{ + // CategoryCodeOrigin: tryCatName2Code(originName), + // CategoryNameOrigin: originName, + // CategoryCode: catCode2Str(catCode), + // SecondaryCategoryCode: catCode2Str(subCatCode), + // SecondaryCategoryName: subCatName, + // Sequence: storeCat.Seq, + // } + // err = getAPI(storeCat.VendorOrgCode, storeID, vendorStoreID).RetailCatUpdate(vendorStoreID, catName, param4Update) + // if storeCat.CatSyncStatus&model.SyncFlagNewMask == 0 && p.IsErrCategoryNotExist(err) && originName != "" { // 修改分类名,但分类不存在 + // storeCat.CatSyncStatus |= model.SyncFlagNewMask + // err = p.CreateStoreCategory(ctx, storeID, vendorStoreID, storeCat) + // } + //} + //if err == nil { + // // storeCat.VendorCatID = utils.FilterEmoji(storeCat.Name) + // storeCat.VendorCatID = utils.Int2Str(storeCat.ID) + //} return err } @@ -178,23 +184,23 @@ func (p *PurchaseHandler) UpdateStoreCategory(ctx *jxcontext.Context, storeID in } func (p *PurchaseHandler) DeleteStoreCategory(ctx *jxcontext.Context, storeID int, vendorStoreID, vendorCatID string, level int) (err error) { - if false { - if globals.EnableMtwmStoreWrite { - err = getAPI(getStoreVendorOrgCode(storeID), storeID, vendorStoreID).RetailCatDelete(vendorStoreID, tryCatName2Code(vendorCatID), vendorCatID) - } - } else { - var catCodes []string - if catCode := tryCatName2Code(vendorCatID); catCode != "" { - catCodes = []string{catCode} - } - if globals.EnableMtwmStoreWrite { - if level == 1 { - err = getAPI(getStoreVendorOrgCode(storeID), storeID, vendorStoreID).RetailCatSkuBatchDelete2(ctx.GetTrackInfo(), vendorStoreID, catCodes, []string{vendorCatID}, nil, nil, nil) - } else { - err = getAPI(getStoreVendorOrgCode(storeID), storeID, vendorStoreID).RetailCatSkuBatchDelete2(ctx.GetTrackInfo(), vendorStoreID, nil, nil, catCodes, []string{vendorCatID}, nil) - } - } - } + //if false { + // if globals.EnableMtwmStoreWrite { + // err = getAPI(getStoreVendorOrgCode(storeID), storeID, vendorStoreID).RetailCatDelete(vendorStoreID, tryCatName2Code(vendorCatID), vendorCatID) + // } + //} else { + // var catCodes []string + // if catCode := tryCatName2Code(vendorCatID); catCode != "" { + // catCodes = []string{catCode} + // } + // if globals.EnableMtwmStoreWrite { + // if level == 1 { + // err = getAPI(getStoreVendorOrgCode(storeID), storeID, vendorStoreID).RetailCatSkuBatchDelete2(ctx.GetTrackInfo(), vendorStoreID, catCodes, []string{vendorCatID}, nil, nil, nil) + // } else { + // err = getAPI(getStoreVendorOrgCode(storeID), storeID, vendorStoreID).RetailCatSkuBatchDelete2(ctx.GetTrackInfo(), vendorStoreID, nil, nil, catCodes, []string{vendorCatID}, nil) + // } + // } + //} return err } @@ -231,167 +237,167 @@ func (p *PurchaseHandler) UpdateStoreSkus(ctx *jxcontext.Context, storeID int, v return failedList, err } +// CreateStoreSkus 门店创建商品 func (p *PurchaseHandler) CreateStoreSkus(ctx *jxcontext.Context, storeID int, vendorStoreID string, storeSkuList []*dao.StoreSkuSyncInfo) (failedList []*partner.StoreSkuInfoWithErr, err error) { failedList, err = p.createOrUpdateStoreSkus(ctx, storeID, vendorStoreID, storeSkuList, true) - // if err == nil && vendorStoreID == specialStoreID { - // for i := 0; i < 2; i++ { - // p.createOrUpdateStoreSkus(ctx, storeID, vendorStoreID, duplicateStoreSkuList(storeSkuList, i+1), true) - // } - // } + //if err == nil && vendorStoreID == specialStoreID { + // for i := 0; i < 2; i++ { + // p.createOrUpdateStoreSkus(ctx, storeID, vendorStoreID, duplicateStoreSkuList(storeSkuList, i+1), true) + // } + //} return failedList, err } // 对于多门店平台来说,storeSkuList中只有SkuID与VendorSkuID有意义 +// 抖店的商品只管创建,创建接口会返回成功,但是审核的时候不一定成功.当前系统无法判定此商品是否已经创建过了! func (p *PurchaseHandler) createOrUpdateStoreSkus(ctx *jxcontext.Context, storeID int, vendorStoreID string, storeSkuList []*dao.StoreSkuSyncInfo, isCreate bool) (failedList []*partner.StoreSkuInfoWithErr, err error) { var syncType string - foodDataList := make([]map[string]interface{}, len(storeSkuList)) + storeDetail, _ := dao.GetStoreDetail(dao.GetDB(), storeID, model.VendorIDDD, "") + api := getAPI(storeSkuList[0].VendorOrgCode, storeID, vendorStoreID) + freightId, err := api.GetStoreFreight(int64(storeID)) + if err != nil { + return nil, err + } if isCreate { syncType = "创建商品" + for _, storeSku := range storeSkuList { + // 创建商品 + param := &product_addV2_request.ProductAddV2Param{ + CategoryLeafId: utils.Str2Int64(storeSku.VendorCatID), + Name: storeSku.Name, + PayType: tiktokShop.TiktokPayType1, + ReduceType: tiktokShop.SkuReduceTypePayMakeOrder, + FreightId: freightId, + Weight: utils.Int2Float64(storeSku.Weight), + DeliveryDelayDay: tiktokShop.DeliveryDelayDayToDay, + PresellType: tiktokShop.SendGoodsTypeNow, + Supply7dayReturn: 0, + Mobile: storeDetail.Tel1, + Commit: true, + Specs: "净重|" + fmt.Sprintf("%f", storeSku.SpecQuality) + storeSku.SpecUnit, + NeedRechargeMode: false, + SellChannel: []int64{0}, + StartSaleType: 0, + PickupMethod: "0", + StoreId: int64(storeSku.StoreID), + MainProductId: int64(storeSku.NameID), + } + + // 获取上传图,商品轮播图 + img, err := GetTiktokImgList(utils.Int2Str(storeSku.StoreID), storeSku.ImgOrigin, storeSku.Img2, storeSku.Img3, storeSku.Img4, storeSku.Img5) + if err != nil { + return nil, err + } + param.Pic = img + // 商品详情图 + img2, err := GetTiktokImgList(utils.Int2Str(storeSku.StoreID), storeSku.DescImg) + if err != nil { + return nil, err + } + param.Description = img2 + + // weight_unit 目前抖音只支持g和kg两种 + switch storeSku.Unit { + case "g", "ml", "G", "ML": + param.WeightUnit = tiktokShop.WeightUint_G + case "kg", "l", "L", "KG": + param.WeightUnit = tiktokShop.WeightUint_G + } + + // spec_prices + param.SpecPrices = GetSpecPrices(param.Specs, storeSku) + // ProductFormatNew + productFormatNew, err := GetProductFormatNew(param.CategoryLeafId) + if err != nil { + return nil, err + } + param.ProductFormatNew = productFormatNew + + // 抖店创建商品 + tiktokResult, err := api.CreateStoreCommodity(param) + if err != nil { + failedList = putils.GetErrMsg2FailedSingleList(storeSkuList, err, storeID, model.VendorChineseNames[model.VendorIDDD], syncType) + storeSku.VendorSkuID = utils.Int2Str(storeSku.SkuID) + continue + } + storeSku.VendorSkuID = utils.Int64ToStr(tiktokResult.ProductId) + } } else { syncType = "更新商品" - } - for i, storeSku := range storeSkuList { - isNeedUpdatePrice := isCreate //storeSku.SkuSyncStatus&(model.SyncFlagPriceMask|model.SyncFlagNewMask) != 0 - foodData := make(map[string]interface{}) - foodDataList[i] = foodData - foodData[mtwmapi.KeyAppFoodCode] = utils.Int2Str(storeSku.SkuID) - skus := []map[string]interface{}{ - map[string]interface{}{ - "sku_id": foodData[mtwmapi.KeyAppFoodCode], - }, - } - foodData["skus"] = skus - foodData["name"] = utils.LimitUTF8StringLen(storeSku.SkuName, mtwmapi.MaxSkuNameCharCount) - foodData["description"] = storeSku.Comment - if isNeedUpdatePrice { - foodData["price"] = jxutils.IntPrice2Standard(storeSku.VendorPrice) - } - if storeSku.MinOrderCount != 0 { - foodData["min_order_count"] = storeSku.MinOrderCount - } else { - foodData["min_order_count"] = 1 - } - foodData["unit"] = storeSku.Unit - attr := switchAttr(storeSku.VendorVendorCatID) - if attr != "" { - foodData["common_attr_value"] = attr - } - catCode := tryCatName2Code(storeSku.VendorCatID) - if catCode != "" { - foodData["category_code"] = catCode - } else { - foodData["category_name"] = storeSku.VendorCatID - } - foodData["is_sold_out"] = skuStatusJX2Mtwm(storeSku.MergedStatus) - if true { // vendorStoreID == specialStoreID { - img2 := storeSku.Img2 - img3 := storeSku.Img3 - img4 := storeSku.Img4 - img5 := storeSku.Img5 - if img2 == "" { - img2 = storeSku.Img + for _, storeSku := range storeSkuList { + param := &product_editV2_request.ProductEditV2Param{ + ProductId: utils.Str2Int64(storeSku.VendorSkuID), + CategoryLeafId: utils.Str2Int64(storeSku.VendorCatID), + Name: storeSku.Name, + PayType: tiktokShop.TiktokPayType1, + ReduceType: tiktokShop.SkuReduceTypePayMakeOrder, + FreightId: freightId, + Weight: utils.Int2Float64(storeSku.Weight), + DeliveryDelayDay: tiktokShop.DeliveryDelayDayToDay, + PresellType: tiktokShop.SendGoodsTypeNow, + Supply7dayReturn: 0, + Mobile: storeDetail.Tel1, + Commit: true, + Specs: "净重|" + fmt.Sprintf("%f", storeSku.SpecQuality) + storeSku.SpecUnit, + NeedRechargeMode: false, + SellChannel: []int64{0}, + StartSaleType: 0, + PickupMethod: "0", + StoreId: int64(storeSku.StoreID), + MainProductId: int64(storeSku.NameID), } - if img3 == "" { - img3 = storeSku.Img - } - if img4 == "" { - img4 = storeSku.Img - } - if img5 == "" { - img5 = storeSku.Img - } - if storeSku.ImgMix != "" && ((storeSku.BrandID == storeSku.ExBrandID && storeSku.ExBrandID != 0) || storeSku.ExBrandID == 0) { - foodData["picture"] = strings.Join(jxutils.BatchString2Slice(storeSku.ImgMix, img2, img3, img4, img5), ",") - } else { - foodData["picture"] = strings.Join(jxutils.BatchString2Slice(storeSku.Img, img2, img3, img4, img5), ",") - } - } else { - foodData["picture"] = strings.Join(jxutils.BatchString2Slice(storeSku.Img, storeSku.Img2), ",") - } - if storeSku.DescImg != "" { - foodData["picture_contents"] = storeSku.DescImg - } - foodData["sequence"] = storeSku.GetSeq() - if storeSku.VendorVendorCatID != 0 { - foodData["tag_id"] = utils.Int64ToStr(storeSku.VendorVendorCatID) - } else { - // foodData["tag_id"] = utils.Int64ToStr(defVendorCatID) - } - skus[0]["spec"] = jxutils.ComposeSkuSpec(storeSku.SpecQuality, storeSku.SpecUnit) - if isNeedUpdatePrice { - skus[0]["price"] = foodData["price"] - } - skus[0]["stock"] = stockCount2Mtwm(model.MaxStoreSkuStockQty) - if storeSku.Upc != "" { - skus[0]["upc"] = storeSku.Upc - } - skus[0]["ladder_box_num"] = storeSku.LadderBoxNum - boxPirce := 0 - if storeSku.MtLadderBoxPrice != 0 { - boxPirce = storeSku.MtLadderBoxPrice - } else { - boxPirce = storeSku.LadderBoxPrice - } - skus[0]["ladder_box_price"] = jxutils.IntPrice2Standard(int64(boxPirce)) - if foodData["tag_id"] != nil { - skus[0]["weight"] = storeSku.Weight // weight字段仅限服饰鞋帽、美妆、日用品、母婴、生鲜果蔬、生活超市下的便利店/超市门店品类的商家使用 - } - } - if globals.EnableMtwmStoreWrite { - if len(foodDataList) == 1 { - foodDataList[0]["skus"] = string(utils.MustMarshal(foodDataList[0]["skus"])) - if err = getAPI(getStoreVendorOrgCode(storeID), storeID, vendorStoreID).RetailInitData(ctx.GetTrackInfo(), vendorStoreID, utils.Int2Str(storeSkuList[0].SkuID), foodDataList[0]); err != nil { - failedList = putils.GetErrMsg2FailedSingleList(storeSkuList, err, storeID, model.VendorChineseNames[model.VendorIDMTWM], syncType) + // 获取上传图,商品轮播图 + img, err := GetTiktokImgList(utils.Int2Str(storeSku.StoreID), storeSku.ImgOrigin, storeSku.Img2, storeSku.Img3, storeSku.Img4, storeSku.Img5) + if err != nil { + return nil, err } - } else if len(foodDataList) > 0 { - failedFoodList, err2 := getAPI(getStoreVendorOrgCode(storeID), storeID, vendorStoreID).RetailBatchInitData(ctx.GetTrackInfo(), vendorStoreID, foodDataList) - if err = err2; err == nil { - if err = putils.GenPartialFailedErr(failedFoodList, len(failedFoodList)); err != nil { - failedList = SelectStoreSkuListByFoodList(storeSkuList, failedFoodList, storeID, model.VendorChineseNames[model.VendorIDMTWM], syncType) - // successList = putils.UnselectStoreSkuSyncListByVendorSkuIDs(storeSkuList, getAppFoodCodeList(failedFoodList)) - } - } else if err2 != nil && len(failedFoodList) == 0 { - if errExt, ok := err2.(*utils.ErrorWithCode); ok { - err = utils.UnmarshalUseNumber([]byte(errExt.ErrMsg()), &failedFoodList) - failedList = SelectStoreSkuListByFoodList(storeSkuList, failedFoodList, storeID, model.VendorChineseNames[model.VendorIDMTWM], syncType) - } + param.Pic = img + // 商品详情图 + img2, err := GetTiktokImgList(utils.Int2Str(storeSku.StoreID), storeSku.DescImg) + if err != nil { + return nil, err + } + param.Description = img2 + + // weight_unit 目前抖音只支持g和kg两种 + switch storeSku.Unit { + case "g", "ml", "G", "ML": + param.WeightUnit = tiktokShop.WeightUint_G + case "kg", "l", "L", "KG": + param.WeightUnit = tiktokShop.WeightUint_G + } + + // spec_prices + param.SpecPrices = GetSpecPrices(param.Specs, storeSku) + // ProductFormatNew + productFormatNew, err := GetProductFormatNew(param.CategoryLeafId) + if err != nil { + return nil, err + } + param.ProductFormatNew = productFormatNew + + // 抖店更新商品 + if err := api.EditStoreCommodity(param); err != nil { + failedList = putils.GetErrMsg2FailedSingleList(storeSkuList, err, storeID, model.VendorChineseNames[model.VendorIDDD], syncType) + storeSku.VendorSkuID = utils.Int2Str(storeSku.SkuID) + continue } } + return } - for _, storeSku := range storeSkuList { - storeSku.VendorSkuID = utils.Int2Str(storeSku.SkuID) - } + if len(failedList) > 0 { err = nil } return failedList, err } -func getAppFoodCodeList(l []*mtwmapi.AppFoodResult) (vendorSkuIDs []string) { - if len(l) > 0 { - vendorSkuIDs = make([]string, len(l)) - for k, v := range l { - vendorSkuIDs[k] = v.AppFoodCode - } - } - return vendorSkuIDs -} - func (p *PurchaseHandler) DeleteStoreSkus(ctx *jxcontext.Context, storeID int, vendorStoreID string, storeSkuList []*partner.StoreSkuInfo) (failedList []*partner.StoreSkuInfoWithErr, err error) { - if globals.EnableMtwmStoreWrite { - if len(storeSkuList) == 1 { - err = getAPI(storeSkuList[0].VendorOrgCode, storeID, vendorStoreID).RetailDelete(ctx.GetTrackInfo(), vendorStoreID, storeSkuList[0].VendorSkuID) - failedList = putils.GetErrMsg2FailedSingleList(storeSkuList, err, storeID, model.VendorChineseNames[model.VendorIDMTWM], "删除商品") - } else { - // todo 部分失败 - err = getAPI(getStoreVendorOrgCode(storeID), storeID, vendorStoreID).RetailCatSkuBatchDelete2(ctx.GetTrackInfo(), vendorStoreID, nil, nil, nil, nil, partner.BareStoreSkuInfoList(storeSkuList).GetVendorSkuIDList()) - if err != nil { - if errExt, ok := err.(*utils.ErrorWithCode); ok { - myMap := make(map[string][]*mtwmapi.AppFoodResult) - json.Unmarshal([]byte(errExt.ErrMsg()), &myMap) - failedList = SelectStoreSkuListByFoodList(storeSkuList, myMap["retail_error_list"], storeID, model.VendorChineseNames[model.VendorIDMTWM], "批量删除商品") - } + if globals.EnableDdStoreWrite { + for _, v := range storeSkuList { + if err = getAPI(storeSkuList[0].VendorOrgCode, storeID, vendorStoreID).DeleteStoreCommodity(utils.Str2Int64(v.VendorSkuID)); err != nil { + failedList = append(failedList, putils.GetErrMsg2FailedSingleList(v, err, storeID, model.VendorChineseNames[model.VendorIDDD], "删除商品")...) } } } @@ -401,30 +407,6 @@ func (p *PurchaseHandler) DeleteStoreSkus(ctx *jxcontext.Context, storeID int, v return failedList, err } -func switchAttr(vendorCatID int64) (attrs string) { - switch vendorCatID { - case 200002727: - return mtwmapi.MtwmSkuAttr200002727 - case 200001555: - return mtwmapi.MtwmSkuAttr200001555 - case 200002728: - return mtwmapi.MtwmSkuAttr200002728 - case 200001519, 200000592: - return mtwmapi.MtwmSkuAttr200000592 - case 200002704, 200002731: - return mtwmapi.MtwmSkuAttr200002731 - case 200002716: - return mtwmapi.MtwmSkuAttr200002716 - case 200002667, 200002713, 200002670: - return mtwmapi.MtwmSkuAttr200002670 - case 200002680: - return mtwmapi.MtwmSkuAttr200002680 - default: - return "" - } - return attrs -} - func stockCount2Mtwm(stock int) (mtwmStock string) { return utils.Int2Str(stock) } @@ -451,44 +433,74 @@ func storeSku2Mtwm(storeSkuList []*partner.StoreSkuInfo, updateType int) (skuLis return skuList } +// UpdateStoreSkusStatus 批量更新商品上下架 func (p *PurchaseHandler) UpdateStoreSkusStatus(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, storeSkuList []*partner.StoreSkuInfo, status int) (failedList []*partner.StoreSkuInfoWithErr, err error) { - skuList := storeSku2Mtwm(storeSkuList, updateTypeStatus) - mtwmStatus := skuStatusJX2Mtwm(status) - if globals.EnableMtwmStoreWrite { - failedFoodList, err2 := getAPI(vendorOrgCode, storeID, vendorStoreID).RetailSellStatus(ctx.GetTrackInfo(), vendorStoreID, skuList, mtwmStatus) - if err = err2; err == nil { - if len(failedFoodList) > 0 { - failedList = SelectStoreSkuListByFoodList(storeSkuList, failedFoodList, storeID, model.VendorChineseNames[model.VendorIDMTWM], "更新商品状态") - // successList = putils.UnselectStoreSkuListByVendorSkuIDs(storeSkuList, getAppFoodCodeList(failedFoodList)) + api := getAPI(vendorOrgCode, storeID, vendorStoreID) + if status == model.SkuStatusNormal { // 上架 + for _, v := range storeSkuList { + if err := api.EditStoreCommodity(&product_editV2_request.ProductEditV2Param{ + ProductId: utils.Str2Int64(v.VendorSkuID), + Commit: true, + }); err != nil { + failedList = append(failedList, putils.GetErrMsg2FailedSingleList(v, err, storeID, model.VendorChineseNames[model.VendorIDDD], "上架商品正常")...) + } else { + failedList = append(failedList, putils.GetErrMsg2FailedSingleList(v, err, storeID, model.VendorChineseNames[model.VendorIDDD], "上架商品异常")...) } - } else if err2 != nil && len(failedFoodList) == 0 { - if errExt, ok := err2.(*utils.ErrorWithCode); ok { - err = utils.UnmarshalUseNumber([]byte(errExt.ErrMsg()), &failedFoodList) - failedList = SelectStoreSkuListByFoodList(storeSkuList, failedFoodList, storeID, model.VendorChineseNames[model.VendorIDMTWM], "更新商品状态") + } + } else { // 下架 + for _, v := range storeSkuList { + err := api.ProductSetOffline(utils.Str2Int64(v.VendorSkuID)) + if err == nil { + failedList = append(failedList, putils.GetErrMsg2FailedSingleList(v, err, storeID, model.VendorChineseNames[model.VendorIDDD], "下架商品正常")...) + } else { + failedList = append(failedList, putils.GetErrMsg2FailedSingleList(v, err, storeID, model.VendorChineseNames[model.VendorIDDD], "下架商品异常")...) } } } + if len(failedList) > 0 { err = nil } return failedList, err } +// UpdateStoreSkusPrice 更新商品价格 func (p *PurchaseHandler) UpdateStoreSkusPrice(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, storeSkuList []*partner.StoreSkuInfo) (failedList []*partner.StoreSkuInfoWithErr, err error) { - priceList := storeSku2Mtwm(storeSkuList, updateTypePrice) - if globals.EnableMtwmStoreWrite { - failedFoodList, err2 := getAPI(vendorOrgCode, storeID, vendorStoreID).RetailSkuPrice(ctx.GetTrackInfo(), vendorStoreID, priceList) - if err = err2; err == nil { - if len(failedFoodList) > 0 { - failedList = SelectStoreSkuListByFoodList(storeSkuList, failedFoodList, storeID, model.VendorChineseNames[model.VendorIDMTWM], "更新商品价格") - } - } else if err2 != nil && len(failedFoodList) == 0 { - if errExt, ok := err2.(*utils.ErrorWithCode); ok { - err = utils.UnmarshalUseNumber([]byte(errExt.ErrMsg()), &failedFoodList) - failedList = SelectStoreSkuListByFoodList(storeSkuList, failedFoodList, storeID, model.VendorChineseNames[model.VendorIDMTWM], "更新商品价格") + api := getAPI(vendorOrgCode, storeID, vendorStoreID) + for _, v := range storeSkuList { + param := &product_editV2_request.ProductEditV2Param{} + param.ProductId = utils.Str2Int64(v.VendorSkuID) + param.Specs = "净重|" + fmt.Sprintf("%f", v.SpecQuality) + v.SpecUnit + + skuSize := make([]*tiktokShop.SpecDetailList, 0, 0) + detail1 := strings.Split(param.Specs, "^") + name1 := strings.Split(strings.Split(detail1[0], "|")[1], ",") + for i := 0; i < len(name1); i++ { + sku := &tiktokShop.SpecDetailList{ + SpecDetailName1: name1[i], + StockNum: v.Stock, + Price: int(v.VendorPrice), + Code: utils.Int2Str(v.SkuID), + StepStockNum: 0, + SupplierID: "", + OuterSkuID: utils.Int2Str(v.NameID), + DeliveryInfos: []*tiktokShop.DeliveryInfos{ + {InfoType: "weight", InfoUnit: v.SpecUnit, InfoValue: fmt.Sprintf("%f", v.SpecQuality)}, + }, } + skuSize = append(skuSize, sku) + } + data, _ := json.Marshal(skuSize) + param.SpecPrices = string(data) + + err := api.EditStoreCommodity(param) + if err != nil { + failedList = append(failedList, putils.GetErrMsg2FailedSingleList(v, err, storeID, model.VendorChineseNames[model.VendorIDDD], "上架商品正常")...) + } else { + failedList = append(failedList, putils.GetErrMsg2FailedSingleList(v, err, storeID, model.VendorChineseNames[model.VendorIDDD], "上架商品异常")...) } } + if len(failedList) > 0 { err = nil } @@ -496,31 +508,14 @@ func (p *PurchaseHandler) UpdateStoreSkusPrice(ctx *jxcontext.Context, vendorOrg } func (p *PurchaseHandler) UpdateStoreSkusStock(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, storeSkuList []*partner.StoreSkuInfo) (failedList []*partner.StoreSkuInfoWithErr, err error) { - stockList := storeSku2Mtwm(storeSkuList, updateTypeStock) - if globals.EnableMtwmStoreWrite { - failedFoodList, err2 := getAPI(vendorOrgCode, storeID, vendorStoreID).RetailSkuStock(ctx.GetTrackInfo(), vendorStoreID, stockList) - if err = err2; err == nil { - if len(failedFoodList) > 0 { - failedList = SelectStoreSkuListByFoodList(storeSkuList, failedFoodList, storeID, model.VendorChineseNames[model.VendorIDMTWM], "更新商品库存") - } - //if err = putils.GenPartialFailedErr(failedFoodList, len(failedFoodList)); err != nil { - // successList = putils.UnselectStoreSkuListByVendorSkuIDs(storeSkuList, getAppFoodCodeList(failedFoodList)) - // } - } else if err2 != nil && len(failedFoodList) == 0 { - if errExt, ok := err2.(*utils.ErrorWithCode); ok { - err = utils.UnmarshalUseNumber([]byte(errExt.ErrMsg()), &failedFoodList) - failedList = SelectStoreSkuListByFoodList(storeSkuList, failedFoodList, storeID, model.VendorChineseNames[model.VendorIDMTWM], "更新商品库存") - } - } + if globals.EnableDdStoreWrite { + return p.UpdateStoreSkusPrice(ctx, vendorOrgCode, storeID, vendorStoreID, storeSkuList) } - if len(failedList) > 0 { - err = nil - } - return failedList, err + return nil, err } -func mtwmSkuStatus2Jx(mtwmSkuStatus int) (jxSkuStatus int) { - if mtwmSkuStatus == mtwmapi.SellStatusOnline { +func tiktokSkuStatus2Jx(skuStatus int64) (jxSkuStatus int) { + if skuStatus == mtwmapi.SellStatusOnline { jxSkuStatus = model.SkuStatusNormal } else { jxSkuStatus = model.SkuStatusDontSale @@ -529,188 +524,134 @@ func mtwmSkuStatus2Jx(mtwmSkuStatus int) (jxSkuStatus int) { } func (p *PurchaseHandler) GetStoreSkusFullInfo(ctx *jxcontext.Context, parentTask tasksch.ITask, storeID int, vendorStoreID string, storeSkuList []*partner.StoreSkuInfo) (skuNameList []*partner.SkuNameInfo, err error) { - if len(storeSkuList) == 1 { - skuInfo, err := getAPI(storeSkuList[0].VendorOrgCode, storeID, vendorStoreID).RetailGet(vendorStoreID, utils.Int2Str(storeSkuList[0].SkuID)) + // 查询单个门店商品 + tiktokApi := getAPI(storeSkuList[0].VendorOrgCode, storeID, vendorStoreID) + + for _, v := range storeSkuList { + skuInfo, err := tiktokApi.GetSkuDetail(v.VendorSkuID, utils.Int2Str(v.SkuID)) if err != nil { return nil, err } if skuName := vendorSku2Jx(skuInfo); skuName != nil { skuNameList = append(skuNameList, skuName) } - } else { - var storeSkuMap map[string]*partner.StoreSkuInfo - if storeSkuList != nil { - storeSkuMap = putils.StoreSkuList2MapByVendorSkuID(storeSkuList) - } - mtapi := getAPI(getStoreVendorOrgCode(storeID), storeID, vendorStoreID) - for { - // todo 待优化获取速度 - result, err := mtapi.RetailList(vendorStoreID, len(skuNameList), mtwmapi.GeneralMaxLimit) - if err != nil { - return nil, err - } - if storeSkuMap == nil { - skuNameList = append(skuNameList, vendorSkuList2Jx(result)...) - } else { - for _, v := range result { - if storeSkuMap[v.AppFoodCode] != nil { - if skuName := vendorSku2Jx(v); skuName != nil { - skuNameList = append(skuNameList, skuName) - } - } - } - } - if len(result) < mtwmapi.GeneralMaxLimit { - break - } - } } + //switch len(storeSkuList) { + //case 1: + // + //default: + // // 列表查询门店商品 + // //var storeSkuMap map[string]*partner.StoreSkuInfo + // //if storeSkuList != nil { + // // storeSkuMap = putils.StoreSkuList2MapByVendorSkuID(storeSkuList) + // //} + // //for { + // // result, err := mtapi.RetailList(vendorStoreID, len(skuNameList), mtwmapi.GeneralMaxLimit) + // // if err != nil { + // // return nil, err + // // } + // // if storeSkuMap == nil { + // // skuNameList = append(skuNameList, vendorSkuList2Jx(result)...) + // // } else { + // // for _, v := range result { + // // if storeSkuMap[v.AppFoodCode] != nil { + // // if skuName := vendorSku2Jx(v); skuName != nil { + // // skuNameList = append(skuNameList, skuName) + // // } + // // } + // // } + // // } + // // if len(result) < mtwmapi.GeneralMaxLimit { + // // break + // // } + // //} + //} return skuNameList, err } -func vendorSku2Jx(appFood *mtwmapi.AppFood) (skuName *partner.SkuNameInfo) { - if len(appFood.SkuList) == 0 { - globals.SugarLogger.Warnf("vendorSku2Jx, strange appFood:%s", utils.Format4Output(appFood, true)) +func vendorSku2Jx(tiktokSku *product_detail_response.ProductDetailData) (skuName *partner.SkuNameInfo) { + if len(tiktokSku.SpecPrices) == 0 { + globals.SugarLogger.Warnf("vendorSku2Jx, strange tiktokSku:%s", utils.Format4Output(tiktokSku, true)) return nil } - prefix, name, comment, specUnit, unit, specQuality := jxutils.SplitSkuName(appFood.Name) - vendorSku := appFood.SkuList[0] - weight := int(utils.Str2Int64WithDefault(vendorSku.Weight, 0)) - if weight <= 0 { - weight = jxutils.FormatSkuWeight(specQuality, specUnit) - } - skuID := int(utils.Str2Int64WithDefault(vendorSku.SkuID, 0)) + prefix, name, comment, specUnit, unit, specQuality := jxutils.SplitSkuName(tiktokSku.Name) + vendorSku := tiktokSku.SpecPrices[0] + weight := jxutils.FormatSkuWeight(specQuality, specUnit) + skuName = &partner.SkuNameInfo{ - NameID: int(utils.Str2Int64WithDefault(appFood.AppFoodCode, 0)), - VendorNameID: appFood.AppFoodCode, - UPC: appFood.SkuList[0].Upc, + NameID: utils.Str2Int(vendorSku.OuterSkuId), + VendorNameID: utils.Int64ToStr(tiktokSku.MainProductId), + UPC: tiktokSku.ProductIdStr, Prefix: prefix, Name: name, Unit: unit, - Status: mtwmSkuStatus2Jx(appFood.IsSoldOut), //此处为之前一个bug 如果吧状态放到切片内层 对于内层函数中映射无法关联 永远获取到的初始值为0 + Status: tiktokSkuStatus2Jx(tiktokSku.Status), //此处为之前一个bug 如果吧状态放到切片内层 对于内层函数中映射无法关联 永远获取到的初始值为0 SkuList: []*partner.SkuInfo{ &partner.SkuInfo{ StoreSkuInfo: partner.StoreSkuInfo{ - VendorSkuID: vendorSku.SkuID, - SkuID: skuID, - IsSpecialty: appFood.IsSpecialty, - Stock: int(utils.Str2Int64WithDefault(vendorSku.Stock, partner.UnlimitedStoreSkuStock)), - VendorPrice: jxutils.StandardPrice2Int(utils.Str2Float64WithDefault(vendorSku.Price, 0)), - Status: mtwmSkuStatus2Jx(appFood.IsSoldOut), + VendorSkuID: utils.Int64ToStr(vendorSku.SkuId), + SkuID: int(vendorSku.OutSkuId), + IsSpecialty: 0, + Stock: int(vendorSku.StockNum), + VendorPrice: vendorSku.Price, + Status: tiktokSkuStatus2Jx(tiktokSku.Status), }, - SkuName: appFood.Name, + SkuName: tiktokSku.Name, Comment: comment, SpecQuality: float64(specQuality), SpecUnit: specUnit, Weight: weight, }, }, - PictureList: appFood.PictureList, + PictureList: tiktokSku.Pic, } - if appFood.CategoryName != "" { + if tiktokSku.CategoryDetail != nil { // todo, 因为当前我们用的是分类名操作这种方式,所以要返回分类名(而不是分类code) - skuName.VendorCatIDList = []string{appFood.CategoryName} - if appFood.SecondaryCategoryName != "" { - skuName.VendorCatIDList = append(skuName.VendorCatIDList, appFood.SecondaryCategoryName) - } + skuName.VendorCatIDList = []string{tiktokSku.CategoryDetail.FirstCname, tiktokSku.CategoryDetail.SecondCname, tiktokSku.CategoryDetail.ThirdCname, tiktokSku.CategoryDetail.FourthCname} } return skuName } -func vendorSkuList2Jx(appFoodList []*mtwmapi.AppFood) (skuNameList []*partner.SkuNameInfo) { - for _, appFood := range appFoodList { - if skuName := vendorSku2Jx(appFood); skuName != nil { - skuNameList = append(skuNameList, skuName) - } - } - return skuNameList -} - func (p *PurchaseHandler) GetSensitiveWordRegexp() *regexp.Regexp { return sensitiveWordRegexp } -//美团api返回 -func SelectStoreSkuListByFoodList(storeSkuList interface{}, foodList []*mtwmapi.AppFoodResult, storeID int, vendorName, syncType string) (selectedStoreSkuList []*partner.StoreSkuInfoWithErr) { - foodMap := make(map[string]string) - if len(foodList) > 0 { - for _, v := range foodList { - foodMap[v.AppFoodCode] = v.ErrorMsg - } - if storeSkuLists, ok := storeSkuList.([]*partner.StoreSkuInfo); ok { - for _, v := range storeSkuLists { - if foodMap[v.VendorSkuID] != "" { - foodFailed := &partner.StoreSkuInfoWithErr{ - StoreSkuInfo: v, - ErrMsg: foodMap[v.VendorSkuID], - StoreID: storeID, - VendoreName: vendorName, - SyncType: syncType, - } - selectedStoreSkuList = append(selectedStoreSkuList, foodFailed) - } - } - } - if storeSkuLists, ok := storeSkuList.([]*dao.StoreSkuSyncInfo); ok { - for _, v := range storeSkuLists { - if foodMap[v.VendorSkuID] != "" { - storeSkuInfo := &partner.StoreSkuInfo{ - SkuID: v.SkuID, - VendorSkuID: v.VendorSkuID, - NameID: v.NameID, - VendorNameID: v.VendorNameID, - VendorPrice: v.VendorPrice, - Status: v.Status, - } - foodFailed := &partner.StoreSkuInfoWithErr{ - StoreSkuInfo: storeSkuInfo, - ErrMsg: foodMap[v.VendorSkuID], - StoreID: storeID, - VendoreName: vendorName, - SyncType: syncType, - } - selectedStoreSkuList = append(selectedStoreSkuList, foodFailed) - } - } - } - } - return selectedStoreSkuList -} - +// CreateStoreSkusAct 创建商品活动 func (p *PurchaseHandler) CreateStoreSkusAct(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, storeSkuList []*partner.StoreSkuInfo) (failedList []*partner.StoreSkuInfoWithErr, err error) { - actStoreSkuList := putils.StoreSku2ActStoreSku(model.SyncFlagNewMask, vendorStoreID, storeSkuList) - failedList, err = createOneShopAct(putils.GetFixDirectDownAct(vendorOrgCode, storeID, 0), vendorStoreID, actStoreSkuList) - storeSkuMap := putils.StoreSkuList2MapBySkuID(storeSkuList) - for _, v := range actStoreSkuList { - storeSkuMap[v.SkuID].VendorActID = v.VendorActID - } - if len(failedList) > 0 { - err = nil - } + //actStoreSkuList := putils.StoreSku2ActStoreSku(model.SyncFlagNewMask, vendorStoreID, storeSkuList) + //failedList, err = createOneShopAct(putils.GetFixDirectDownAct(vendorOrgCode, storeID, 0), vendorStoreID, actStoreSkuList) + //storeSkuMap := putils.StoreSkuList2MapBySkuID(storeSkuList) + //for _, v := range actStoreSkuList { + // storeSkuMap[v.SkuID].VendorActID = v.VendorActID + //} + //if len(failedList) > 0 { + // err = nil + //} return failedList, err } func (p *PurchaseHandler) CancelActs(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, storeSkuList []*partner.StoreSkuInfo) (failedList []*partner.StoreSkuInfoWithErr, err error) { - return cancelOneShopAct(putils.GetFixDirectDownAct(vendorOrgCode, storeID, 0), vendorStoreID, putils.StoreSku2ActStoreSku(model.SyncFlagDeletedMask, vendorStoreID, storeSkuList)) + return nil, err + // return cancelOneShopAct(putils.GetFixDirectDownAct(vendorOrgCode, storeID, 0), vendorStoreID, putils.StoreSku2ActStoreSku(model.SyncFlagDeletedMask, vendorStoreID, storeSkuList)) } func (p *PurchaseHandler) UpdateStoreSkusSpecTag(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, storeSkuList []*partner.StoreSkuInfo) (err error) { - var foodDataList = []map[string]interface{}{} - for _, v := range storeSkuList { - var foodData = make(map[string]interface{}) - if v.IsSpecialty != 0 && v.IsSpecialty == -1 { - v.IsSpecialty = 0 - } - foodData["is_specialty"] = v.IsSpecialty - foodData["app_food_code"] = v.SkuID - foodDataList = append(foodDataList, foodData) - } - if globals.EnableMtwmStoreWrite { - if len(foodDataList) == 1 { - err = getAPI(vendorOrgCode, storeID, vendorStoreID).RetailInitData(ctx.GetTrackInfo(), vendorStoreID, utils.Int2Str(storeSkuList[0].SkuID), foodDataList[0]) - } else if len(foodDataList) > 0 { - _, err = getAPI(vendorOrgCode, storeID, vendorStoreID).RetailBatchInitData(ctx.GetTrackInfo(), vendorStoreID, foodDataList) - } - } + //var foodDataList []map[string]interface{} + //for _, v := range storeSkuList { + // var foodData = make(map[string]interface{}) + // if v.IsSpecialty != 0 && v.IsSpecialty == -1 { + // v.IsSpecialty = 0 + // } + // foodData["is_specialty"] = v.IsSpecialty + // foodData["app_food_code"] = v.SkuID + // foodDataList = append(foodDataList, foodData) + //} + //if globals.EnableMtwmStoreWrite { + // if len(foodDataList) == 1 { + // err = getAPI(vendorOrgCode, storeID, vendorStoreID).RetailInitData(ctx.GetTrackInfo(), vendorStoreID, utils.Int2Str(storeSkuList[0].SkuID), foodDataList[0]) + // } else if len(foodDataList) > 0 { + // _, err = getAPI(vendorOrgCode, storeID, vendorStoreID).RetailBatchInitData(ctx.GetTrackInfo(), vendorStoreID, foodDataList) + // } + //} return err } diff --git a/business/partner/purchase/tiktok_store/store_sku2_test.go b/business/partner/purchase/tiktok_store/store_sku2_test.go deleted file mode 100644 index e4037c14f..000000000 --- a/business/partner/purchase/tiktok_store/store_sku2_test.go +++ /dev/null @@ -1,64 +0,0 @@ -package tiktok_store - -import ( - "testing" - - "git.rosy.net.cn/baseapi/utils" - "git.rosy.net.cn/jx-callback/business/jxutils/jxcontext" - "git.rosy.net.cn/jx-callback/business/partner" - // _ "git.rosy.net.cn/jx-callback/business/jxcallback/orderman" -) - -func TestGetStoreSkusFullInfo(t *testing.T) { - skuNameList, err := CurPurchaseHandler.GetStoreSkusFullInfo(jxcontext.AdminCtx, nil, 2, "8967897", nil) - if err != nil { - t.Fatal(err) - } - t.Log(utils.Format4Output(skuNameList, false)) - t.Log(len(skuNameList)) -} - -func TestGetStoreSkusBareInfo(t *testing.T) { - storeSkuList, err := CurPurchaseHandler.GetStoreSkusBareInfo(jxcontext.AdminCtx, "", nil, 2, "2523687", []*partner.StoreSkuInfo{ - &partner.StoreSkuInfo{ - SkuID: 16205, - }, - //&partner.StoreSkuInfo{ - // SkuID: 1306, - //}, - }) - if err != nil { - t.Fatal(err.Error()) - } - t.Log(utils.Format4Output(storeSkuList, false)) - t.Log(len(storeSkuList)) -} - -func TestDeleteStoreAllSkus(t *testing.T) { - err := CurPurchaseHandler.DeleteStoreAllSkus(jxcontext.AdminCtx, nil, 2, "2523687", true) - if err != nil { - t.Fatal(err) - } -} - -func TestDeleteStoreAllCategories(t *testing.T) { - err := CurPurchaseHandler.DeleteStoreAllCategories(jxcontext.AdminCtx, nil, 2, "2523687", true) - if err != nil { - t.Fatal(err) - } -} - -func TestGetStoreCategory(t *testing.T) { - _, err := CurPurchaseHandler.GetStoreCategory(jxcontext.AdminCtx, 2, "2523687", "不存在的分类") - if err == nil { - t.Fatal("应该找不到这个分类") - } - catName := "小月饼" - cat, err := CurPurchaseHandler.GetStoreCategory(jxcontext.AdminCtx, 2, "2523687", catName) - if err != nil { - t.Fatal(err) - } else if cat.Name != catName { - t.Fatal("没有找到正确的商家分类") - } - t.Log(utils.Format4Output(cat, false)) -} diff --git a/business/partner/purchase/tiktok_store/store_sku2_utils.go b/business/partner/purchase/tiktok_store/store_sku2_utils.go new file mode 100644 index 000000000..73ca4c9db --- /dev/null +++ b/business/partner/purchase/tiktok_store/store_sku2_utils.go @@ -0,0 +1,143 @@ +package tiktok_store + +import ( + "encoding/json" + "errors" + "fmt" + tiktokShop "git.rosy.net.cn/baseapi/platformapi/tiktok_shop/tiktok_api" + "git.rosy.net.cn/baseapi/utils" + "git.rosy.net.cn/jx-callback/business/model" + "git.rosy.net.cn/jx-callback/business/model/dao" + "git.rosy.net.cn/jx-callback/globals/api" + "strings" +) + +// GetProductFormatNew 获取物品属性 +func GetProductFormatNew(categoryLeftId int64) (string, error) { + category, err := api.TiktokStore.GetCatePropertyV2(categoryLeftId) + if err != nil { + return "", err + } + format := make(map[string][]*tiktokShop.ProductFormatNewList, 0) + for _, v := range category.Data.Data { + for _, d := range v.Options { + formateNew := &tiktokShop.ProductFormatNewList{ + Value: utils.Str2Int64(d.Value), + Name: d.Name, + DiyType: v.DiyType, + } + format[utils.Int64ToStr(v.CategoryId)] = append(format[utils.Int64ToStr(v.CategoryId)], formateNew) + } + } + productFormatNew, err := json.Marshal(format) + if err != nil { + return "", err + } + return string(productFormatNew), nil +} + +// GetTiktokImgList 获取抖音图片链接 +func GetTiktokImgList(storeId string, img ...string) (string, error) { + imgs := make([]tiktokShop.Imgs, 0, 0) + for _, v := range img { + if v != "" { + imgs = append(imgs, tiktokShop.Imgs{ + Name: storeId + "_" + v[21:54], + Url: v, + }) + } + } + tiktokImgList, err := api.TiktokStore.BatchUploadImages(imgs) + if err != nil { + return "", err + } + + var tiktokImg []string + for _, v := range tiktokImgList.SuccessMap { + tiktokImg = append(tiktokImg, v.ByteUrl) + } + if len(tiktokImg) <= model.NO { + for _, v := range tiktokImgList.FailedMap { + return "", errors.New(v.ErrMsg) + } + } + + return strings.Join(tiktokImg, "|"), nil +} + +// GetSpecPrices 解析属性和规格参数 +func GetSpecPrices(specs string, localSku *dao.StoreSkuSyncInfo) string { + skuSize := make([]*tiktokShop.SpecDetailList, 0, 0) + detail1 := strings.Split(specs, "^") + if len(detail1) > 3 { + detail1 = detail1[0:3] + } + switch len(detail1) { + case 1: + name1 := strings.Split(strings.Split(detail1[0], "|")[1], ",") + for i := 0; i < len(name1); i++ { + sku := &tiktokShop.SpecDetailList{ + SpecDetailName1: name1[i], + StockNum: localSku.Stock, + Price: int(localSku.VendorPrice), + Code: utils.Int2Str(localSku.SkuID), + StepStockNum: 0, + SupplierID: "", + OuterSkuID: utils.Int2Str(localSku.NameID), + DeliveryInfos: []*tiktokShop.DeliveryInfos{ + {InfoType: "weight", InfoUnit: localSku.SpecUnit, InfoValue: fmt.Sprintf("%f", localSku.SpecQuality)}, + }, + } + skuSize = append(skuSize, sku) + } + case 2: + name1 := strings.Split(strings.Split(detail1[0], "|")[1], ",") + name2 := strings.Split(strings.Split(detail1[1], "|")[1], ",") + for i := 0; i < len(name1); i++ { + for j := 0; j < len(name2); j++ { + sku := &tiktokShop.SpecDetailList{ + SpecDetailName1: name1[i], + SpecDetailName2: name2[j], + StockNum: localSku.Stock, + Price: int(localSku.UnitPrice), + Code: utils.Int2Str(localSku.SkuID), + StepStockNum: 0, + SupplierID: "", + OuterSkuID: utils.Int2Str(localSku.NameID), + DeliveryInfos: []*tiktokShop.DeliveryInfos{ + {InfoType: "weight", InfoUnit: localSku.SpecUnit, InfoValue: fmt.Sprintf("%f", localSku.SpecQuality)}, + }, + } + skuSize = append(skuSize, sku) + } + } + case 3: + name1 := strings.Split(strings.Split(detail1[0], "|")[1], ",") + name2 := strings.Split(strings.Split(detail1[1], "|")[1], ",") + name3 := strings.Split(strings.Split(detail1[2], "|")[1], ",") + for i := 0; i < len(name1); i++ { + for j := 0; j < len(name2); j++ { + for k := 0; k < len(name3); k++ { + sku := &tiktokShop.SpecDetailList{ + SpecDetailName1: name1[i], + SpecDetailName2: name2[j], + SpecDetailName3: name3[k], + StockNum: localSku.Stock, + Price: int(localSku.UnitPrice), + Code: utils.Int2Str(localSku.SkuID), + StepStockNum: 0, + SupplierID: "", + OuterSkuID: utils.Int2Str(localSku.NameID), + DeliveryInfos: []*tiktokShop.DeliveryInfos{ + {InfoType: "weight", InfoUnit: localSku.SpecUnit, InfoValue: fmt.Sprintf("%f", localSku.SpecQuality)}, + }, + } + skuSize = append(skuSize, sku) + } + } + } + } + + data, _ := json.Marshal(skuSize) + return string(data) +} diff --git a/business/partner/purchase/tiktok_store/store_sku_test.go b/business/partner/purchase/tiktok_store/store_sku_test.go deleted file mode 100644 index ead1b02f6..000000000 --- a/business/partner/purchase/tiktok_store/store_sku_test.go +++ /dev/null @@ -1,46 +0,0 @@ -package tiktok_store - -import ( - "testing" - - "git.rosy.net.cn/jx-callback/business/jxutils/jxcontext" - // _ "git.rosy.net.cn/jx-callback/business/jxcallback/orderman" -) - -// func TestSyncStoreCategory(t *testing.T) { -// hint, err := CurPurchaseHandler.SyncStoreCategory(jxcontext.AdminCtx, nil, testShopID, false) -// if err != nil { -// t.Fatal(err) -// } -// t.Log(hint) -// } - -// func TestSyncLocalStoreCategory(t *testing.T) { -// hint, err := CurPurchaseHandler.SyncLocalStoreCategory(jxcontext.AdminCtx, nil, testShopID, true, nil) -// if err != nil { -// t.Fatal(err) -// } -// t.Log(hint) -// } - -// func TestSyncStoreSkus(t *testing.T) { -// hint, err := CurPurchaseHandler.SyncStoreSkus(jxcontext.AdminCtx, nil, testShopID, nil, false, true) -// if err != nil { -// t.Fatal(err) -// } -// t.Log(hint) -// } - -func TestDeleteRemoteSkus(t *testing.T) { - err := CurPurchaseHandler.DeleteStoreAllSkus(jxcontext.AdminCtx, nil, testShopID, testShopVendorID, true) - if err != nil { - t.Fatal(err) - } -} - -func TestDeleteRemoteCategories(t *testing.T) { - err := CurPurchaseHandler.DeleteStoreAllCategories(jxcontext.AdminCtx, nil, testShopID, testShopVendorID, true) - if err != nil { - t.Fatal(err) - } -} diff --git a/business/partner/purchase/tiktok_store/store_test.go b/business/partner/purchase/tiktok_store/store_test.go deleted file mode 100644 index 68defac00..000000000 --- a/business/partner/purchase/tiktok_store/store_test.go +++ /dev/null @@ -1,43 +0,0 @@ -package tiktok_store - -import ( - "testing" - - "git.rosy.net.cn/baseapi/platformapi/mtwmapi" - "git.rosy.net.cn/baseapi/utils" - // _ "git.rosy.net.cn/jx-callback/business/jxcallback/orderman" -) - -//func TestReadStore(t *testing.T) { -// store, err := CurPurchaseHandler.ReadStore(jxcontext.AdminCtx, "", "4351018") -// if err != nil { -// t.Fatal(err) -// } -// t.Log(utils.Format4Output(store, false)) -//} - -func TestUpdateStore(t *testing.T) { - err := CurPurchaseHandler.UpdateStore(nil, 100002, "test") - if err != nil { - t.Fatal(err) - } -} - -func TestConstrainOpTimeList(t *testing.T) { - timeList := constrainOpTimeList([]int16{830, 1800}, []int16{ - 0, - 200, - 930, - 1700, - }) - t.Log(utils.Format4Output(timeList, false)) - if timeList[0] != 930 || timeList[1] != 1700 { - t.Fatal("constrainOpTimeList failed") - } -} - -func TestGetOpTimeListFromErr(t *testing.T) { - err := utils.NewErrorIntCode("当前配送营业时间为:07:00~24:00", mtwmapi.ErrCodeOpFailed) - list := getOpTimeListFromErr(err) - t.Log(list) -} diff --git a/business/partner/purchase/tiktok_store/waybill.go b/business/partner/purchase/tiktok_store/waybill.go index ac6a4cc98..ea5895486 100644 --- a/business/partner/purchase/tiktok_store/waybill.go +++ b/business/partner/purchase/tiktok_store/waybill.go @@ -1,59 +1,53 @@ package tiktok_store -import ( - "git.rosy.net.cn/baseapi/platformapi/mtwmapi" - "git.rosy.net.cn/baseapi/utils" - "git.rosy.net.cn/jx-callback/business/model" - "git.rosy.net.cn/jx-callback/business/partner" -) - -var ( - VendorWaybillStatus2StatusMap = map[string]int{ - mtwmapi.WaybillStatusWait4Delivery: model.WaybillStatusNew, - mtwmapi.WaybillStatusPending: model.WaybillStatusPending, - mtwmapi.WaybillStatusAccepted: model.WaybillStatusAccepted, - mtwmapi.WaybillStatusCourierArrived: model.WaybillStatusCourierArrived, - mtwmapi.WaybillStatusPickedup: model.WaybillStatusDelivering, - mtwmapi.WaybillStatusDelivered: model.WaybillStatusDelivered, - mtwmapi.WaybillStatusCanceled: model.WaybillStatusCanceled, - } -) - -func (p *PurchaseHandler) GetWaybillStatusFromVendorStatus(vendorStatus string) int { - if status, ok := VendorWaybillStatus2StatusMap[vendorStatus]; ok { - return status - } - return model.WaybillStatusUnknown -} - -func (c *PurchaseHandler) onWaybillMsg(msg *mtwmapi.CallbackMsg) (response *mtwmapi.CallbackResponse) { - waybill := c.callbackMsg2Waybill(msg) - err := partner.CurOrderManager.OnWaybillStatusChanged(waybill) - if err == nil && waybill.Status == model.WaybillStatusDelivering { - c.postFakeMsg(waybill.VendorOrderID, FakeMsgType, mtwmapi.OrderStatusDelivering) - } - return mtwmapi.Err2CallbackResponse(err, "") -} - -func (c *PurchaseHandler) callbackMsg2Waybill(msg *mtwmapi.CallbackMsg) (retVal *model.Waybill) { - orderID := GetOrderIDFromMsg(msg) - vendorStatus := msg.FormData.Get("logistics_status") - retVal = &model.Waybill{ - VendorOrderID: orderID, - OrderVendorID: model.VendorIDMTWM, - VendorWaybillID: orderID, - WaybillVendorID: model.VendorIDMTWM, - CourierName: msg.FormData.Get("dispatcher_name"), - CourierMobile: msg.FormData.Get("dispatcher_mobile"), - VendorStatus: vendorStatus, - Status: c.GetWaybillStatusFromVendorStatus(vendorStatus), - StatusTime: getTimeFromTimestamp(utils.Str2Int64(msg.FormData.Get("time"))), - Remark: "", - - VendorOrgCode: msg.AppID, - } - if retVal.StatusTime == utils.DefaultTimeValue { - retVal.StatusTime = getTimeFromTimestamp(utils.Str2Int64(msg.FormData.Get("timestamp"))) - } - return retVal -} +// +//var ( +// VendorWaybillStatus2StatusMap = map[string]int{ +// mtwmapi.WaybillStatusWait4Delivery: model.WaybillStatusNew, +// mtwmapi.WaybillStatusPending: model.WaybillStatusPending, +// mtwmapi.WaybillStatusAccepted: model.WaybillStatusAccepted, +// mtwmapi.WaybillStatusCourierArrived: model.WaybillStatusCourierArrived, +// mtwmapi.WaybillStatusPickedup: model.WaybillStatusDelivering, +// mtwmapi.WaybillStatusDelivered: model.WaybillStatusDelivered, +// mtwmapi.WaybillStatusCanceled: model.WaybillStatusCanceled, +// } +//) +// +//func (p *PurchaseHandler) GetWaybillStatusFromVendorStatus(vendorStatus string) int { +// if status, ok := VendorWaybillStatus2StatusMap[vendorStatus]; ok { +// return status +// } +// return model.WaybillStatusUnknown +//} +// +//func (c *PurchaseHandler) onWaybillMsg(msg *mtwmapi.CallbackMsg) (response *mtwmapi.CallbackResponse) { +// waybill := c.callbackMsg2Waybill(msg) +// err := partner.CurOrderManager.OnWaybillStatusChanged(waybill) +// if err == nil && waybill.Status == model.WaybillStatusDelivering { +// c.postFakeMsg(waybill.VendorOrderID, FakeMsgType, mtwmapi.OrderStatusDelivering) +// } +// return mtwmapi.Err2CallbackResponse(err, "") +//} +// +//func (c *PurchaseHandler) callbackMsg2Waybill(msg *mtwmapi.CallbackMsg) (retVal *model.Waybill) { +// orderID := GetOrderIDFromMsg(msg) +// vendorStatus := msg.FormData.Get("logistics_status") +// retVal = &model.Waybill{ +// VendorOrderID: orderID, +// OrderVendorID: model.VendorIDMTWM, +// VendorWaybillID: orderID, +// WaybillVendorID: model.VendorIDMTWM, +// CourierName: msg.FormData.Get("dispatcher_name"), +// CourierMobile: msg.FormData.Get("dispatcher_mobile"), +// VendorStatus: vendorStatus, +// Status: c.GetWaybillStatusFromVendorStatus(vendorStatus), +// StatusTime: getTimeFromTimestamp(utils.Str2Int64(msg.FormData.Get("time"))), +// Remark: "", +// +// VendorOrgCode: msg.AppID, +// } +// if retVal.StatusTime == utils.DefaultTimeValue { +// retVal.StatusTime = getTimeFromTimestamp(utils.Str2Int64(msg.FormData.Get("timestamp"))) +// } +// return retVal +//} diff --git a/conf/app.conf b/conf/app.conf index 44f31943f..6bfed0357 100644 --- a/conf/app.conf +++ b/conf/app.conf @@ -19,6 +19,7 @@ mtwmCallbackURL = "http://callback.jxc4.com" mtwmAppID2 = "5873" mtwmSecret2 = "41c479790a76f86326f89e8048964739" mtwmCallbackURL2 = "http://callback.jxc4.com" +tiktokShopAppId = "7136048270014416392" # mtwmCookieStr = "_lxsdk_cuid=16ddced5e9a95-0a65869c427a14-48714616-15f900-16ddced5e9b2b; _hc.v=cfebbfd1-79a7-9823-d8df-77e59646cb34.1571369610; _lxsdk=16ddced5e9a95-0a65869c427a14-48714616-15f900-16ddced5e9b2b; uuid_update=true; uuid=7b28e71504f5414e382b.1579155871.1.0.0; device_uuid=!64dedf83-b510-4910-8a31-b2b13d0bdd73; pushToken=00kRvxlerO15kB0dJFWDwYuctAoe04xGMNd0r3BqvLUA*; acctId=57396785; brandId=-1; wmPoiId=-1; isOfflineSelfOpen=0; city_id=0; isChain=1; existBrandPoi=true; ignore_set_router_proxy=true; region_id=; region_version=0; newCategory=false; bsid=OyqgRLyV54i9JKP0zRCI9jPyXc4UBU-6KReDAkPIwSlljhb97JPyFUIXfYQvhlJb6G1erzHQKbvtZ2pSWOYDxQ; cityId=510100; provinceId=510000; city_location_id=0; location_id=0; igateApp=shangouepc; wpush_server_url=wss://wpush.meituan.com; token=0MScAPaSa57iwRpgpCmGLf21tiA4yU4Uy-nDZlv8wNWs*; shopCategory=food; set_info=%7B%22wmPoiId%22%3A-1%2C%22ignoreSetRouterProxy%22%3Atrue%7D; JSESSIONID=105dgww27nsy6yfp68q7wmcni; LX_SC_CONSTANT=c_shangou_online_e_znrurnrc; _lxsdk_s=17041b590ac-3d-689-a8c%7C%7C15" @@ -35,6 +36,7 @@ enableJdStoreWrite = false enableEbaiStoreWrite = false enableElmStoreWrite = false enableMtwmStoreWrite = false +enableDdStoreWrite = false enableWscStoreWrite = false enableYbStoreWrite = false enableJdShopWrite = false @@ -301,6 +303,7 @@ enableStoreWrite = true enableJdStoreWrite = true enableEbaiStoreWrite = true enableMtwmStoreWrite = true +enableDdStoreWrite = true enableWscStoreWrite = true enableYbStoreWrite = true enableJdShopWrite = true @@ -363,6 +366,7 @@ enableStoreWrite = true enableJdStoreWrite = true enableEbaiStoreWrite = true enableMtwmStoreWrite = true +enableDdStoreWrite = true enableYbStoreWrite = true enableJdShopWrite = true @@ -504,6 +508,7 @@ enableStoreWrite = true enableJdStoreWrite = true enableEbaiStoreWrite = true enableMtwmStoreWrite = true +enableDdStoreWrite = true enableWscStoreWrite = false enableYbStoreWrite = false @@ -590,6 +595,7 @@ enableStoreWrite = true enableJdStoreWrite = true enableEbaiStoreWrite = true enableMtwmStoreWrite = true +enableDdStoreWrite = true enableWscStoreWrite = true enableYbStoreWrite = true enableJdShopWrite = true diff --git a/controllers/tiktok_store.go b/controllers/tiktok_store.go index 4eae45515..6a820036a 100644 --- a/controllers/tiktok_store.go +++ b/controllers/tiktok_store.go @@ -31,12 +31,14 @@ func (t *TiktokController) CallbackTiktokOrderMsg() { return } - for _, v := range orderStatus { - resp2 := tiktok_store.OnOrderMsg(v) - if resp2.Code != 0 { - t.Data["json"] = resp2 - t.ServeJSON() - return + for k, v := range orderStatus { + for _, callback := range v { + resp2 := tiktok_store.OnOrderMsg(k, callback) + if resp2.Code != 0 { + t.Data["json"] = resp2 + t.ServeJSON() + return + } } } diff --git a/globals/api/api.go b/globals/api/api.go index ab2c4c8e7..329690b5e 100644 --- a/globals/api/api.go +++ b/globals/api/api.go @@ -112,11 +112,11 @@ var ( Cacher cache.ICacher SMSClient *aliyunsmsclient.SmsClient - TiktokApi *tiktok.API // 抖音api - TiktokJXDJApi *tiktok.API //抖音京西到家api - TiktokApiID string //抖音商城ID - TiktokJXDJApiID string //抖音京西到家ID - TiktokStore *tiktokShop.API + TiktokApi *tiktok.API // 抖音api + TiktokJXDJApi *tiktok.API //抖音京西到家api + TiktokApiID string //抖音商城ID + TiktokJXDJApiID string //抖音京西到家ID + TiktokStore *tiktokShop.API // 抖店 EnterpriseChatHeadApi *enterprise.API // 企业微信api EnterpriseChatMin *enterprise.API // 企业微信小程序api ) diff --git a/globals/api/apimanager/apimanager.go b/globals/api/apimanager/apimanager.go index f10e89f07..461aab39d 100644 --- a/globals/api/apimanager/apimanager.go +++ b/globals/api/apimanager/apimanager.go @@ -64,6 +64,8 @@ func (a *APIManager) GetAPI(vendorID int, appOrgCode string) (pfAPI interface{}) pfAPI = api.JdShopAPI case model.VendorIDTT: pfAPI = api.TiktokApi + case model.VendorIDDD: + pfAPI = api.TiktokStore } return pfAPI } diff --git a/globals/globals.go b/globals/globals.go index c8da93ebf..b40e5c4dc 100644 --- a/globals/globals.go +++ b/globals/globals.go @@ -22,6 +22,7 @@ var ( EnableEbaiStoreWrite bool EnableElmStoreWrite bool EnableMtwmStoreWrite bool + EnableDdStoreWrite bool EnableWscStoreWrite bool EnablePendingChange bool EnableYbStoreWrite bool @@ -80,6 +81,7 @@ var ( IsAddEvent bool OutputDebugMsgLevel int + TiktokShopCode string ) func init() { @@ -108,6 +110,7 @@ func Init() { EnableJdStoreWrite = EnableStoreWrite && web.AppConfig.DefaultBool("enableJdStoreWrite", false) EnableEbaiStoreWrite = EnableStoreWrite && web.AppConfig.DefaultBool("enableEbaiStoreWrite", false) EnableElmStoreWrite = EnableStoreWrite && web.AppConfig.DefaultBool("enableElmStoreWrite", false) + EnableDdStoreWrite = EnableStoreWrite && web.AppConfig.DefaultBool("enableDdStoreWrite", false) EnableMtwmStoreWrite = EnableStoreWrite && web.AppConfig.DefaultBool("enableMtwmStoreWrite", false) EnableWscStoreWrite = EnableStoreWrite && web.AppConfig.DefaultBool("enableWscStoreWrite", false) // EnablePendingChange = web.AppConfig.DefaultBool("enablePendingChange", false) @@ -165,6 +168,7 @@ func Init() { MtwmCode = web.AppConfig.DefaultString("mtwmAppID", "") Mtwm2Code = web.AppConfig.DefaultString("mtwmAppID2", "") + TiktokShopCode = web.AppConfig.DefaultString("tiktokShopAppId", "7136048270014416392") } func IsCallbackAlwaysReturnSuccess() bool { diff --git a/main.go b/main.go index 57710d566..27c30da8f 100644 --- a/main.go +++ b/main.go @@ -162,10 +162,10 @@ func main() { globals.SugarLogger.Errorf("RefreshFnToken failed with error:%s", err) return } - if err := tasks.RefreshTiktokToken(); err != nil { - globals.SugarLogger.Errorf("RefreshTiktokToken failed with error:%s", err) - return - } + //if err := tasks.RefreshTiktokToken(); err != nil { + // globals.SugarLogger.Errorf("RefreshTiktokToken failed with error:%s", err) + // return + //} if err := tasks.RefreshQywxToken(); err != nil { globals.SugarLogger.Errorf("RefreshQywxToken failed with error:%s", err) return