This commit is contained in:
邹宗楠
2022-09-21 10:03:21 +08:00
parent 9915fa1eb2
commit e2b41bf9db
33 changed files with 2919 additions and 3032 deletions

View File

@@ -137,6 +137,7 @@ func (c *BaseScheduler) SelfDeliverDelivering(order *model.GoodsOrder, userName
partner.CurOrderManager.OnOrderMsg(order, "美团外卖转自送成功.", "")
} else if strings.Contains(err.Error(), "包裹不存在") || strings.Contains(err.Error(), "运单不存在") || strings.Contains(err.Error(), "1071") || strings.Contains(err.Error(), "1014") || strings.Contains(err.Error(), "invalid character 'o' looking for beginning of value") {
partner.CurOrderManager.OnOrderMsg(order, "美团外卖转自送可能成功,异常:", err.Error())
err = nil
} else {
bill, _ := partner.CurOrderManager.LoadWaybill(order.VendorWaybillID, order.WaybillVendorID)
c.CancelWaybill(bill, partner.CancelWaybillReasonOther, partner.CancelWaybillReasonStrActive)

View File

@@ -105,7 +105,6 @@ var (
VendorIDQiNiuCloud: "Qiniu",
VendorIDJDWL: "Jdwl",
VendorGoMei: "GoMei",
}
VendorTypeName = map[int]string{

View File

@@ -35,8 +35,7 @@ const (
BrandOpenSMS = 8 //短信
BrandOpenVoice = 16 //语音
BrandBalanceLimit = 1000
GoMeiMaxCountNumber = 50 // 国美最大数据返回条数
BrandBalanceLimit = 1000
)
const (
@@ -87,13 +86,11 @@ const (
)
const (
ExdStoreName = "饿鲜达"
MatterStoreID = 666666
JdShopMainVendorStoreID = "9999999" // 三方平台总商户id
GoMeiShopMainVendorStoreID = "GMJ-MS-XOMRF-1J1" // 三方平台总商户id
ExdStoreName = "饿鲜达"
MatterStoreID = 666666
JdShopMainVendorStoreID = "9999999" // 三方平台总商户id
// JdShopMainVendorStoreID2 = "9999999"
JdShopMainStoreID = 100000 // 本地商户门店地
GoMeiShopMainStoreID = 200000 // 本店商户门店id
JdShopMainStoreID = 100000 // 本地商户门店地
// JdShopMainStoreID2 = 100000
VendorStoreTel = "18011597879"

View File

@@ -1,15 +0,0 @@
package gomei
import (
"git.rosy.net.cn/jx-callback/business/jxutils/jxcontext"
"git.rosy.net.cn/jx-callback/business/jxutils/tasksch"
"git.rosy.net.cn/jx-callback/business/model"
)
func (c *PurchaseHandler) SyncAct(ctx *jxcontext.Context, parentTask tasksch.ITask, act *model.Act2, actOrderRules []*model.ActOrderRule, actStoreSkuList []*model.ActStoreSku2) (err error) {
return err
}
func (c *PurchaseHandler) GetActAmple(ctx *jxcontext.Context, vendorStoreID, vendorOrgCode string) (ample int, err error) {
return ample, err
}

View File

@@ -1,502 +0,0 @@
package gomei
//
//import (
// "bytes"
// "encoding/base64"
// "encoding/hex"
// "encoding/json"
// "fmt"
// "math"
// "strings"
// "time"
//
// "git.rosy.net.cn/jx-callback/business/authz/autils"
// "git.rosy.net.cn/jx-callback/business/partner/delivery/dada"
//
// "git.rosy.net.cn/jx-callback/business/jxutils/jxcontext"
// beego "github.com/astaxie/beego/server/web"
//
// "git.rosy.net.cn/baseapi/platformapi/dadaapi"
// "git.rosy.net.cn/baseapi/platformapi/dingdingapi"
// "git.rosy.net.cn/baseapi/platformapi/jcqapi"
// "git.rosy.net.cn/baseapi/platformapi/jdshopapi"
// "git.rosy.net.cn/baseapi/utils"
// "git.rosy.net.cn/jx-callback/business/jxutils"
// "git.rosy.net.cn/jx-callback/business/jxutils/ddmsg"
// "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"
// "git.rosy.net.cn/jx-callback/globals/api2"
//)
//
////TODO 以下是京东商城云顶推送消息使用的代码,现在都是以网页爬取的形式拿订单了,下面的都不用了
////TODO 位置在 orderman/order.go 的 SaveJdsOrders
//func OnCallbackMsg(msg *jdshopapi.CallBackResult) (err error) {
// msgType := msg.MsgType
// switch msgType {
// case jcqapi.TopicOrderPay:
// utils.CallFuncAsync(func() {
// SaveJdsOrders(msg)
// })
// case jcqapi.TopicOrderCancel:
// utils.CallFuncAsync(func() {
// order := getRealOrderID(msg.OrderID)
// if order != nil {
// if order.Status != model.OrderStatusCanceled {
// CurPurchaseHandler.CancelOrder(jxcontext.AdminCtx, order, "系统取消")
// }
// }
// })
// case jcqapi.TopicOrderOut:
// utils.CallFuncAsync(func() {
// globals.SugarLogger.Debugf("jdsOrderOut", utils.Format4Output(msg, false))
// orders := getAllRealOrderID(msg.OrderID)
// if len(orders) > 0 {
// for _, order := range orders {
// if order.ActualPayPrice == 0 {
// if jxutils.StandardPrice2Int(utils.Str2Float64(msg.OrderPayment)) == 0 {
// order.ActualPayPrice = jxutils.StandardPrice2Int(utils.Str2Float64(msg.OrderTotalPrice) + utils.Str2Float64(msg.FreightPrice) - utils.Str2Float64(msg.SellerDiscount))
// } else {
// order.ActualPayPrice = jxutils.StandardPrice2Int(utils.Str2Float64(msg.OrderPayment))
// }
// order.TotalShopMoney = utils.Float64TwoInt64(float64(order.ActualPayPrice) * jdshopapi.JdsPayPercentage)
// partner.CurOrderManager.UpdateOrderFields(order, []string{"ActualPayPrice", "TotalShopMoney"})
// }
// }
// }
// })
// default:
// return fmt.Errorf("暂不支持的topic类型topic: %v", msgType)
// }
// return err
//}
//
//func SaveJdsOrders(msg *jdshopapi.CallBackResult) (err error) {
// if msg.OrderState == "TRADE_CANCELED" {
// return nil
// } //清洗脏数据 部分数据按照
// order, err := result2Orders(msg)
// if err != nil && order == nil {
// return err
// }
// globals.SugarLogger.Debugf("SaveJdsOrders : %v", utils.Format4Output(order, false))
// partner.CurOrderManager.OnOrderNew(order, model.Order2Status(order))
// noticeMsg := fmt.Sprintf("京东商城新订单,订单号:[%v] ,将要发到的门店id[%v] , 门店名:[%v]", order.VendorOrderID, order.StoreID, order.StoreName)
// if order.OrderType == model.OrderTypeAddressErr {
// noticeMsg += " 此订单地址有问题,需要矫正坐标!"
// }
// var role = autils.NewRole("jdshop", 0)
// userIDList, err := api2.RoleMan.GetRoleUserList(role)
// for _, v := range userIDList {
// ddmsg.SendUserMessage(dingdingapi.MsgTyeText, v, "京东商城来新订单了!", noticeMsg)
// }
// // ddmsg.SendUserMessage(dingdingapi.MsgTyeText, "1439B3E07D3911EA881A525400E86DC0", "京东商城来新订单了!", noticeMsg)
// return err
//}
//
//func result2Orders(msg *jdshopapi.CallBackResult) (order *model.GoodsOrder, err error) {
// var (
// db = dao.GetDB()
// )
// //有可能是库里已经有这个订单了
// orderE, err := partner.CurOrderManager.LoadOrder(msg.OrderID+"00000001", model.VendorIDJDShop)
// if orderE != nil {
// return order, fmt.Errorf("已经存在此订单!")
// }
// order = &model.GoodsOrder{
// VendorOrderID2: msg.OrderID,
// VendorOrderID: msg.OrderID + "00000001",
// VendorID: model.VendorIDJDShop,
// BaseFreightMoney: jxutils.StandardPrice2Int(utils.Str2Float64(msg.FreightPrice)),
// VendorStatus: msg.OrderState,
// VendorUserID: msg.Pin,
// BuyerComment: msg.OrderRemark,
// PickDeadline: utils.DefaultTimeValue,
// OriginalData: string(utils.MustMarshal(msg)),
// OrderCreatedAt: utils.Str2Time(msg.OrderStartTime),
// ConsigneeAddress: Decrypt(msg.ConsigneeInfo.FullAddress, msg.VendorOrgCode),
// ConsigneeName: Decrypt(msg.ConsigneeInfo.Fullname, msg.VendorOrgCode),
// // ConsigneeMobile: Decrypt(msg.ConsigneeInfo.Mobile),
// // ConsigneeMobile2: Decrypt(msg.ConsigneeInfo.Telephone),
// ActualPayPrice: jxutils.StandardPrice2Int(utils.Str2Float64(msg.OrderPayment)),
// Status: model.OrderStatusNew,
// TotalShopMoney: utils.Float64TwoInt64(math.Round(float64(jxutils.StandardPrice2Int(utils.Str2Float64(msg.OrderPayment))) * jdshopapi.JdsPayPercentage)),
// DeliveryType: model.OrderDeliveryTypeStoreSelf,
// StatusTime: utils.Str2Time(msg.OrderStartTime),
// OrderSeq: 0,
// VendorOrgCode: msg.VendorOrgCode,
// }
// if utils.Str2Float64(msg.BalanceUsed) != 0 {
// order.ActualPayPrice += jxutils.StandardPrice2Int(utils.Str2Float64(msg.BalanceUsed))
// order.TotalShopMoney += utils.Float64TwoInt64(math.Round(float64(jxutils.StandardPrice2Int(utils.Str2Float64(msg.BalanceUsed))) * jdshopapi.JdsPayPercentage))
// }
// if len(msg.ConsigneeInfo.Mobile) != 11 {
// order.ConsigneeMobile = Decrypt(msg.ConsigneeInfo.Mobile, msg.VendorOrgCode)
// } else {
// order.ConsigneeMobile = msg.ConsigneeInfo.Mobile
// }
// if len(msg.ConsigneeInfo.Telephone) != 11 {
// order.ConsigneeMobile2 = Decrypt(msg.ConsigneeInfo.Telephone, msg.VendorOrgCode)
// } else {
// order.ConsigneeMobile2 = msg.ConsigneeInfo.Telephone
// }
// if order.TotalShopMoney < 100 {
// order.TotalShopMoney = 100
// }
// if order.ConsigneeAddress != "" {
// var cityCode int
// place, err := dao.GetPlaceByJdsCode(db, utils.Str2Int(msg.ConsigneeInfo.CityID))
// if place == nil {
// cityCode = 510100
// } else {
// if place.Level == 3 {
// cityCode = place.ParentCode
// } else if place.Level == 2 {
// cityCode = place.Code
// }
// }
// lng, lat, err2 := api.AutonaviAPI.GetCoordinateFromAddressByPage(order.ConsigneeAddress, cityCode)
// if err = err2; err != nil {
// globals.SugarLogger.Infof("高德page err: %v", err)
// }
// lng2, lat2, _ := api.AutonaviAPI.GetCoordinateFromAddress(order.ConsigneeAddress, "")
// distance := jxutils.EarthDistance(lng, lat, lng2, lat2)
// if distance > 1 {
// order.OrderType = model.OrderTypeAddressErr
// }
// if err == nil && lng != 0 && lat != 0 {
// order.ConsigneeLng = jxutils.StandardCoordinate2Int(lng)
// order.ConsigneeLat = jxutils.StandardCoordinate2Int(lat)
// } else {
// order.ConsigneeLng = jxutils.StandardCoordinate2Int(lng2)
// order.ConsigneeLat = jxutils.StandardCoordinate2Int(lat2)
// }
// order.CoordinateType = model.CoordinateTypeMars
// }
// // storeList, err := common.GetStoreListByLocation(jxcontext.AdminCtx, jxutils.IntCoordinate2Standard(order.ConsigneeLng), jxutils.IntCoordinate2Standard(order.ConsigneeLat), 3000, false, true, 0)
// // if err != nil {
// // globals.SugarLogger.Debugf("jds GetStoreListByLocation error: %v", err.Error())
// // return order, err
// // }
// // if len(storeList) > 0 {
// // for _, store := range storeList {
// for _, v := range msg.ItemInfoList {
// sku := &model.OrderSku{
// VendorID: model.VendorIDJDShop,
// VendorOrderID: order.VendorOrderID,
// Count: utils.Str2Int(v.ItemTotal),
// VendorSkuID: v.SkuID,
// SkuName: v.SkuName,
// VendorPrice: jxutils.StandardPrice2Int(utils.Str2Float64(v.JdPrice)),
// SalePrice: jxutils.StandardPrice2Int(utils.Str2Float64(v.JdPrice)),
// // SkuID: utils.Str2Int(v.OuterSkuID),
// }
// if v.OuterSkuID != "" {
// sku.SkuID = utils.Str2Int(v.OuterSkuID)
// }
// _, _, _, specUnit, _, specQuality := jxutils.SplitSkuName(v.SkuName)
// sku.Weight = jxutils.FormatSkuWeight(specQuality, specUnit)
// order.Skus = append(order.Skus, sku)
// }
// if order.ActualPayPrice > 100000 {
// buildOrderTo102919(order)
// globals.SugarLogger.Debugf("resultjdsOrders return 8")
// }
// var store *dao.StoreDetail
// if msg.OrderExt != "" {
// orderExt := &jdshopapi.OrderExt{}
// if err = json.Unmarshal([]byte(msg.OrderExt), &orderExt); err == nil {
// order.VendorStoreID = orderExt.SiteID
// if store, err = dao.GetStoreDetailByVendorStoreID(db, order.VendorStoreID, model.VendorIDJDShop, ""); store != nil && err == nil {
// order.StoreID = store.ID
// order.JxStoreID = store.ID
// order.StoreName = store.Name
// globals.SugarLogger.Debugf("jds GetStoreListByLocation, orderID: %v storeID :%v", order.VendorOrderID, order.StoreID)
// //结算类型
// if store.PayPercentage < 50 {
// order.EarningType = model.EarningTypePoints
// } else {
// order.EarningType = model.EarningTypeQuote
// }
// var (
// shopPriceSum int
// // saleNormalSum int
// )
// for _, sku := range order.Skus {
// storeSkuList, _ := dao.GetStoresSkusInfo(db, []int{order.StoreID}, []int{sku.SkuID})
// if len(storeSkuList) > 0 {
// // if storeSkuList[0].Status == model.StoreSkuBindStatusNormal {
// // saleNormalSum += 1
// // }
// shopPriceSum += storeSkuList[0].Price * sku.Count
// sku.ShopPrice = int64(storeSkuList[0].Price)
// } else {
// shopPriceSum += int(sku.SalePrice) * 70 / 100
// }
// }
// //可售数小于一半就不行
// // if math.Mod(float64(len(order.Skus)), float64(2)) == 0 {
// // if saleNormalSum < len(order.Skus)/2 {
// // buildOrderTo102919(order)
// // globals.SugarLogger.Debugf("resultjdsOrders return 1")
// // } else {
// if order.EarningType == model.EarningTypeQuote && shopPriceSum+700 > int(order.TotalShopMoney) {
// buildOrderTo102919(order)
// globals.SugarLogger.Debugf("resultjdsOrders return 2")
// }
// // }
// // } else {
// // if saleNormalSum <= len(order.Skus)/2 {
// // buildOrderTo102919(order)
// // globals.SugarLogger.Debugf("resultjdsOrders return 3")
// // } else {
// // if order.EarningType == model.EarningTypeQuote && shopPriceSum+700 > int(order.TotalShopMoney) {
// // buildOrderTo102919(order)
// // globals.SugarLogger.Debugf("resultjdsOrders return 4")
// // }
// // }
// // }
// } else {
// buildOrderTo102919(order)
// globals.SugarLogger.Debugf("resultjdsOrders return 5")
// }
// } else {
// buildOrderTo102919(order)
// globals.SugarLogger.Debugf("resultjdsOrders return 6")
// }
// } else {
// buildOrderTo102919(order)
// globals.SugarLogger.Debugf("resultjdsOrders return 7")
// }
// // 如果是暂停表示是预订单g
// if msg.OrderState == jdshopapi.OrderStatusPause || msg.OrderState == jdshopapi.OrderStatusPopPause {
// order.BusinessType = model.BusinessTypeDingshida
// if time2, err := getAPI(msg.VendorOrgCode).GetOrderExtInfoByOrderId(order.VendorOrderID2); err == nil {
// if time2 == "" {
// order.ExpectedDeliveredTime = order.OrderCreatedAt.Add(time.Hour)
// } else {
// order.ExpectedDeliveredTime = utils.Str2Time(time2)
// }
// } else {
// order.ExpectedDeliveredTime = order.OrderCreatedAt.Add(time.Hour)
// err = nil
// }
// order.PickDeadline = order.ExpectedDeliveredTime.Add(-time.Hour)
// } else if msg.OrderState == jdshopapi.OrderStatusWait || msg.OrderState == "WAIT_GOODS_RECEIVE_CONFIRM" || msg.OrderState == "FINISHED_L" {
// order.ExpectedDeliveredTime = order.OrderCreatedAt.Add(time.Hour)
// order.BusinessType = model.BusinessTypeImmediate
// } else if msg.OrderState == "UN_KNOWN" {
// order.ExpectedDeliveredTime = order.OrderCreatedAt.Add(time.Hour)
// order.BusinessType = model.BusinessTypeImmediate
// } else {
// globals.SugarLogger.Debugf("暂不支持的京东商城订单类型type: %v", msg.OrderState)
// return nil, err
// }
//
// if msg.IDSopShipmenttype == jdshopapi.IdSopShipmenttypeTC {
// if msg.VendorOrgCode == "1" {
// if time2, err := getAPI(msg.VendorOrgCode).GetOrderExtInfoByOrderId(order.VendorOrderID2); err == nil {
// order.BusinessType = model.BusinessTypeDingshida
// if time2 == "" {
// order.ExpectedDeliveredTime = order.OrderCreatedAt.Add(time.Hour)
// } else {
// order.ExpectedDeliveredTime = utils.Str2Time(time2)
// }
// }
// } else {
// order.BusinessType = model.BusinessTypeImmediate
// if time2, err := getAPI(msg.VendorOrgCode).GetOrderExtInfoByOrderId(order.VendorOrderID2); err == nil {
// if time2 == "" {
// order.ExpectedDeliveredTime = order.OrderCreatedAt.Add(time.Hour)
// } else {
// order.ExpectedDeliveredTime = utils.Str2Time(time2)
// }
// } else {
// order.ExpectedDeliveredTime = order.OrderCreatedAt.Add(time.Hour)
// }
// }
// }
// setJdsOrderSeq(order)
// if order.OrderType == model.OrderTypeAddressErr {
// buildOrderTo102919(order)
// globals.SugarLogger.Debugf("resultjdsOrders return 9")
// }
// // billParams, _ := GetDaDaBillParams(db, order)
// // if result, err := api.DadaAPI.QueryDeliverFee(billParams); err == nil {
// // if result.Fee > 10 {
// // buildOrderTo102919(order)
// // globals.SugarLogger.Debugf("resultjdsOrders return 10")
// // }
// // }
// if store != nil {
// distance := jxutils.EarthDistance(jxutils.IntCoordinate2Standard(order.ConsigneeLng), jxutils.IntCoordinate2Standard(order.ConsigneeLat), jxutils.IntCoordinate2Standard(store.Lng), jxutils.IntCoordinate2Standard(store.Lat))
// if distance > 4 {
// buildOrderTo102919(order)
// globals.SugarLogger.Debugf("resultjdsOrders return 4")
// }
// }
// if order.ExpectedDeliveredTime.Sub(order.OrderCreatedAt) <= time.Hour+time.Minute {
// order.BusinessType = model.BusinessTypeImmediate
// }
// // buildOrderTo102919(order)
// return order, err
//}
//
//func buildOrderTo102919(order *model.GoodsOrder) {
// // if order.VendorOrgCode == "1" {
// // order.StoreID = 102919
// // order.JxStoreID = 102919
// // order.StoreName = "商城模板(成都发货)"
// // order.VendorStoreID = model.JdShopMainVendorStoreID
// // } else {
// order.StoreID = model.JdShopMainStoreID
// order.JxStoreID = model.JdShopMainStoreID
// order.StoreName = "商城模板店2"
// order.VendorStoreID = model.JdShopMainVendorStoreID
// // }
// order.DeliveryFlag = model.OrderDeliveryFlagMaskScheduleDisabled
//}
//
//func setJdsOrderSeq(order *model.GoodsOrder) (err error) {
// type tCount struct {
// Count int `json:"count"`
// }
// var count = &tCount{}
// sql := `
// SELECT count(*) count FROM goods_order WHERE store_id = ? AND order_create_at >= ? AND order_create_at <= ? AND vendor_id = ?
// `
// sqlParams := []interface{}{
// order.StoreID, utils.Time2Date(time.Now()), utils.Time2Date(time.Now().AddDate(0, 0, 1)), order.VendorID,
// }
// err = dao.GetRow(dao.GetDB(), &count, sql, sqlParams)
// order.OrderSeq = count.Count + 1
// return err
//}
//
//func Decrypt(p, vendorOrgCode string) (result string) {
// if p == "" {
// return ""
// }
// data, _ := base64.StdEncoding.DecodeString(strings.ReplaceAll(p, " ", "+"))
// key := GetKey(hex.EncodeToString(data)[4:36], vendorOrgCode)
// globals.SugarLogger.Debugf("Decrypt keys : %v", key)
// data2, _ := base64.StdEncoding.DecodeString(key)
// b := bytes.NewBuffer(data)
// b.Next(18)
// iv := make([]byte, 16)
// b.Read(iv)
// main := make([]byte, len(data)-18-16)
// b.Read(main)
// decryptedData, _ := utils.AESCBCDecpryt(main, data2[:16], iv)
// return string(decryptedData)
//}
//
//func getRealOrderID(orderID string) (order *model.GoodsOrder) {
// var (
// db = dao.GetDB()
// )
// sql := `
// SELECT * FROM goods_order WHERE vendor_order_id2 = ? ORDER BY vendor_order_id DESC LIMIT 1
// `
// sqlParams := []interface{}{
// orderID,
// }
// dao.GetRow(db, &order, sql, sqlParams)
// return order
//}
//
//func getAllRealOrderID(orderID string) (orders []*model.GoodsOrder) {
// var (
// db = dao.GetDB()
// )
// sql := `
// SELECT * FROM goods_order WHERE vendor_order_id2 = ?
// `
// sqlParams := []interface{}{
// orderID,
// }
// dao.GetRows(db, &orders, sql, sqlParams)
// return orders
//}
//
//func GetDaDaBillParams(db *dao.DaoDB, order *model.GoodsOrder) (billParams *dadaapi.OperateOrderParams, err error) {
// billParams = &dadaapi.OperateOrderParams{
// OriginID: jxutils.ComposeUniversalOrderID(order.VendorOrderID, order.VendorID),
// CargoPrice: jxutils.IntPrice2Standard(limitOrderPrice(order.ActualPayPrice)),
// IsPrepay: 0,
// ReceiverName: utils.FilterMb4(order.ConsigneeName),
// ReceiverAddress: utils.FilterMb4(order.ConsigneeAddress),
// ReceiverPhone: order.ConsigneeMobile,
// }
// if billParams.ShopNo, err = getDadaShopID(order, db); err == nil {
// if billParams.CityCode, err = getDataCityCodeFromOrder(order, db); err == nil {
// // storeTel := ""
// // storeID := jxutils.GetSaleStoreIDFromOrder(order)
// // storeDeatail, _ := dao.GetStoreDetail(db, storeID, order.VendorID)
// // if storeDeatail.Tel2 != "" {
// // storeTel = ",门店电话:" + storeDeatail.Tel2
// // }
// billParams.ReceiverLng, billParams.ReceiverLat, _ = jxutils.IntCoordinate2MarsStandard(order.ConsigneeLng, order.ConsigneeLat, order.CoordinateType)
// billParams.Info = fmt.Sprintf("%s第%d号订单, %s", model.VendorChineseNames[order.VendorID], order.OrderSeq, utils.FilterMb4("客户电话:"+order.ConsigneeMobile+","+order.BuyerComment+"取货失败或配送遇到问题请联系18048531223禁止未配送直接完成定单"))
// billParams.CargoType = dadaapi.CargoTypeFresh
// billParams.CargoWeight = float64(jxutils.IntWeight2Float(limitOrderWeight(order.Weight)))
// billParams.CargoNum = order.GoodsCount
// }
// }
// return billParams, err
//}
//
//func limitOrderPrice(price int64) int64 {
// var maxOrderPrice int64 = 6399
// if price > maxOrderPrice {
// return maxOrderPrice
// }
// return price
//}
//
//func limitOrderWeight(weight int) int {
// maxOrderWeight := 5000 // 5公斤
// if weight > maxOrderWeight {
// return maxOrderWeight
// }
// return weight
//}
//
//func getDadaShopID(order *model.GoodsOrder, db *dao.DaoDB) (retVal string, err error) {
// saleStoreID := jxutils.GetSaleStoreIDFromOrder(order)
// storeCourierList, err2 := dao.GetOpenedStoreCouriersByStoreID(db, saleStoreID, model.VendorIDDada)
// if err = err2; err != nil && !dao.IsNoRowsError(err) {
// return "", err
// }
// if len(storeCourierList) == 0 {
// return "", partner.ErrStoreHaveNoCourier
// }
// retVal = storeCourierList[0].VendorStoreID
// if beego.BConfig.RunMode == "dev" {
// retVal = "test_0001"
// }
// return retVal, nil
//}
//
//func getDataCityCodeFromOrder(order *model.GoodsOrder, db *dao.DaoDB) (retVal string, err error) {
// jxStoreID := jxutils.GetSaleStoreIDFromOrder(order)
// sql := `
// SELECT t2.tel_code
// FROM store t1
// JOIN place t2 on t1.city_code = t2.code
// WHERE t1.id = ?
// `
// codeInfo := &struct {
// TelCode string
// }{}
// if err = dao.GetRow(db, codeInfo, sql, jxStoreID); err != nil {
// globals.SugarLogger.Errorf("GetDataCityCodeFromOrder can not find store info for vendorID:%d, store:%s, error:%v", order.VendorID, order.VendorStoreID, err)
// if err == nil {
// err = dada.ErrCanNotFindDadaCityCode
// }
// return "", err
// }
// return codeInfo.TelCode, nil
//}

View File

@@ -1,34 +0,0 @@
package gomei
//
//import (
// "fmt"
// "git.rosy.net.cn/baseapi/platformapi/jdshopapi"
// "testing"
//)
//
//func TestSaveJdsOrders(t *testing.T) {
// type args struct {
// msg *jdshopapi.CallBackResult
// }
// tests := []struct {
// name string
// args args
// wantErr bool
// }{
// // TODO: Add test cases.
// }
// fmt.Println("测试1")
// for _, tt := range tests {
// t.Run(tt.name, func(t *testing.T) {
// if err := SaveJdsOrders(tt.args.msg); (err != nil) != tt.wantErr {
// t.Errorf("SaveJdsOrders() error = %v, wantErr %v", err, tt.wantErr)
// }
// })
// }
// fmt.Println("测试2")
//}
//
//func TestDecrypt(t *testing.T) {
// InitKey()
// fmt.Println(Decrypt("dGeoMeGNcXeT8iCHn3hTrCFYY8qfMnOptNcMFzAJA2/Dx/CPiZ526ec0NN0kWKs4+HwEGCLu9hAB9D0MIf8UB6q4G8IVgD3oXlOb89CFgGe0yO1HA9j51ESPFXh8=", "1"))
//}

View File

@@ -1,120 +0,0 @@
package gomei
import (
"encoding/base64"
gomei "git.rosy.net.cn/baseapi/platformapi/gome_live_show"
"git.rosy.net.cn/baseapi/platformapi/jdshopapi"
"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/business/partner"
"git.rosy.net.cn/jx-callback/business/partner/putils"
"git.rosy.net.cn/jx-callback/globals"
"git.rosy.net.cn/jx-callback/globals/api"
)
var (
CurPurchaseHandler *PurchaseHandler
)
type PurchaseHandler struct {
partner.BasePurchasePlatform
putils.DefSingleStorePlatform
}
func init() {
if api.GuoMeiApi != nil {
CurPurchaseHandler = New()
partner.RegisterPurchasePlatform(CurPurchaseHandler)
}
}
func New() (obj *PurchaseHandler) {
obj = new(PurchaseHandler)
obj.ISingleStoreStoreSkuHandler = obj
return obj
}
func getAPI(appOrgCode string) (apiObj *gomei.API) {
if appOrgCode == "" {
globals.SugarLogger.Warnf("getAPI appOrgCode is empty")
}
return partner.CurAPIManager.GetAPI(model.VendorGoMei, appOrgCode).(*gomei.API)
}
func GetAPI(appOrgCode string) (apiObj *jdshopapi.API) {
apiObj = partner.CurAPIManager.GetAPI(model.VendorGoMei, appOrgCode).(*jdshopapi.API)
if configs, err := dao.QueryConfigs(dao.GetDB(), "jdsCookie2", model.ConfigTypeCookie, ""); err == nil {
apiObj.SetCookieWithStr(configs[0].Value)
}
return apiObj
}
func (p *PurchaseHandler) GetVendorID() int {
return model.VendorGoMei
}
func (p *PurchaseHandler) UploadImg(ctx *jxcontext.Context, vendorOrgCode, imgURL string, imgData []byte, imgName string, imgType int) (imgHint string, err error) {
if globals.EnableJdShopWrite {
if imgType > model.ImgTypeLocal {
result, err := getAPI(vendorOrgCode).UploadPicture(base64.StdEncoding.EncodeToString(imgData), 0, imgName)
if err == nil {
imgHint = result.Data.Url
}
}
} else {
imgHint = utils.GetUpperUUID()
}
return imgHint, err
}
// 获取国美商户的分类标签,官方未提供接口.->查询所有门店分类,去重复!目前国美分类只有一级
func (p *PurchaseHandler) GetVendorCategories(ctx *jxcontext.Context) (vendorCats []*model.SkuVendorCategory, err error) {
storeList, err := getAPI(string(model.VendorGoMei)).QueryStoreList(&gomei.GetStoreListReq{
Page: gomei.Page{
PageSize: model.BrandBalanceLimit,
PageNumber: 1,
},
})
if err != nil {
return nil, err
}
if storeList.Data.Total == 0 {
return nil, nil
}
result := make(map[string]*model.SkuVendorCategory, 0)
for _, v := range storeList.Data.Records {
storeCategoryList, err := GetAllStoreCategories(string(model.VendorGoMei), v.StoreCode)
//storeCategoryList, err := api.GuoMeiApi.QueryStoreCategoryList(&gomei.QueryStoreGoodsCategoryListReq{
// Page: gomei.Page{PageNumber: 1, PageSize: model.BrandBalanceLimit},
// StoreCode: v.StoreCode,
//})
if err != nil || len(storeCategoryList) <= 0 {
continue
}
for _, c := range storeCategoryList {
cat := &model.SkuVendorCategory{
VendorID: model.VendorGoMei,
Name: c.CategoryName,
Level: 1,
VendorCategoryID: c.CategoryCode,
ParentID: "",
IsLeaf: 0,
}
result[cat.Name] = cat
}
}
for _, v := range result {
vendorCats = append(vendorCats, v)
}
return vendorCats, err
}
func (p *PurchaseHandler) GetOrderRider(vendorOrgCode, vendorStoreID string, param map[string]interface{}) (err error) {
return nil
}

View File

@@ -1,78 +0,0 @@
package gomei
import (
"encoding/base64"
"encoding/hex"
"encoding/json"
"git.rosy.net.cn/baseapi/platformapi/jdshopapi"
"git.rosy.net.cn/jx-callback/globals"
)
var (
KeyList []*Key
KeyList2 []*Key
)
type Key struct {
ID string `json:"id"`
KeyExp int64 `json:"key_exp"`
KeyStatus int `json:"key_status"`
KeyDigest string `json:"key_digest"`
KeyType string `json:"key_type"`
KeyString string `json:"key_string"`
KeyEffective int64 `json:"key_effective"`
Version int `json:"version"`
}
func InitKey() {
newapi := jdshopapi.New("37d36b62c0d14bd4b872f948b335c95czinj", "E1D746D42474D5F1F1A10CECE75D99F6", "efa7e1d1a22640fa990e6cf164b28608")
keyResult, err := newapi.KeyGet()
if err != nil {
return
}
for _, v := range keyResult.Response.ServiceKeyList[0].Keys {
data, _ := json.Marshal(v)
vv := &Key{}
err = json.Unmarshal(data, &vv)
KeyList = append(KeyList, vv)
}
keyResult2, err := jdshopapi.New("f9c5ce9a5ce24218936924f7c4864cc9owe1", "E1D746D42474D5F1F1A10CECE75D99F6", "efa7e1d1a22640fa990e6cf164b28608").KeyGet()
if err != nil {
return
}
for _, v := range keyResult2.Response.ServiceKeyList[0].Keys {
data, _ := json.Marshal(v)
vv := &Key{}
err = json.Unmarshal(data, &vv)
KeyList2 = append(KeyList2, vv)
}
globals.SugarLogger.Debugf("jdshop key refreshed..")
}
func GetKey(keySign, vendorOrgCode string) (key string) {
if vendorOrgCode == "1" {
for _, v := range KeyList {
data, _ := base64.StdEncoding.DecodeString(v.ID)
if keySign == hex.EncodeToString(data) {
return v.KeyString
}
}
} else {
for _, v := range KeyList2 {
//data, _ := base64.StdEncoding.DecodeString(v.ID)
//if keySign == hex.EncodeToString(data) {
return v.KeyString
}
}
// } else {
// for _, v := range KeyList2 {
// data, _ := base64.StdEncoding.DecodeString(v.ID)
// if keySign == hex.EncodeToString(data) {
// return v.KeyString
// }
// }
// }
globals.SugarLogger.Debugf("no key can equal..")
return key
}

View File

@@ -1,334 +0,0 @@
package gomei
import (
"fmt"
"git.rosy.net.cn/jx-callback/globals"
"net/http"
"strings"
"time"
"git.rosy.net.cn/jx-callback/business/model/dao"
"git.rosy.net.cn/baseapi"
"git.rosy.net.cn/baseapi/platformapi"
"git.rosy.net.cn/baseapi/platformapi/jdshopapi"
"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/jxutils/tasksch"
"git.rosy.net.cn/jx-callback/business/model"
"git.rosy.net.cn/jx-callback/business/partner"
"git.rosy.net.cn/jx-callback/globals/api"
)
func (p *PurchaseHandler) AcceptOrRefuseFailedGetOrder(ctx *jxcontext.Context, order *model.GoodsOrder, isAcceptIt bool) (err error) {
return err
}
func (p *PurchaseHandler) Map2Order(orderData map[string]interface{}) (order *model.GoodsOrder) {
result := &jdshopapi.AllOrdersResult{}
if err := utils.Map2StructByJson(orderData, &result, false); err != nil {
return nil
}
jdsOrder := result.OrderList[0]
order = &model.GoodsOrder{
VendorOrderID: utils.Int64ToStr(jdsOrder.OrderID),
VendorID: model.VendorIDJDShop,
BaseFreightMoney: jxutils.StandardPrice2Int(jdsOrder.Freight),
VendorStatus: utils.Int2Str(jdsOrder.OrderStatus),
VendorUserID: jdsOrder.UserPin,
BuyerComment: jdsOrder.UserRemark,
PickDeadline: utils.DefaultTimeValue,
OriginalData: string(utils.MustMarshal(jdsOrder)),
Status: status2Jxstatus(jdsOrder.OrderStatus),
}
return order
}
func (p *PurchaseHandler) GetOrder(vendorOrgCode, vendorOrderID, vendorStoreID string) (order *model.GoodsOrder, err error) {
resultOrders, err := api.JdShopAPI.AllOrders(&jdshopapi.AllOrdersParam{
OrderID: vendorOrderID,
Current: 1,
PageSize: 10,
})
if err != nil {
return nil, err
}
return p.Map2Order(utils.Struct2FlatMap(resultOrders)), err
}
func (p *PurchaseHandler) GetOrderStatus(vendorOrgCode, vendorOrderID string) (status int, err error) {
//jdsOrder, err := GetJdsOrder(vendorOrderID, vendorOrgCode)
//jdsOrder, err := GetJdsOrder2(vendorOrderID, vendorOrgCode)
//r := regexp.MustCompile(`"orderState":"(.*)","orderType`)
//if len(r.FindStringSubmatch(jdsOrder)) > 0 {
// return status2Jxstatus(r.FindStringSubmatch(jdsOrder)[1]), err
//}
if order, err := p.GetOrder(vendorOrgCode, vendorOrderID, ""); err == nil && order != nil {
return order.Status, err
}
return 0, err
}
func (p *PurchaseHandler) AcceptOrRefuseOrder(order *model.GoodsOrder, isAcceptIt bool, userName string) (err error) {
//var (
// status int
// remark string
//)
//if isAcceptIt {
// status = model.OrderStatusAccepted
// //京东商城第二个号要自动接单
// if order.VendorOrgCode == "2" {
// err = getAPI(order.VendorOrgCode).SetOrderStateToWait(utils.Str2Int64(order.VendorOrderID2))
// }
//} else {
// status = model.OrderStatusCanceled
//}
//return ChangeOrderStatus(order.VendorOrderID, status, remark)
return err
}
func (p *PurchaseHandler) PickupGoods(order *model.GoodsOrder, isSelfDelivery bool, userName string) (err error) {
status, err := p.GetOrderStatus(order.VendorOrgCode, order.VendorOrderID2)
if err != nil {
globals.SugarLogger.Debug("jdShop GetOrders err := ", err)
return err
}
//说明此时该订单在平台上已经取消了
if status == model.OrderStatusCanceled {
err = ChangeOrderStatus(order.VendorOrderID, model.OrderStatusCanceled, "订单在京东商城已被取消!")
} else {
if jxutils.GetSaleStoreIDFromOrder(order) != model.JdShopMainStoreID {
//可能还没接单?
if status == model.OrderStatusNew {
p.AcceptOrRefuseOrder(order, true, "")
}
err = ChangeOrderStatus(order.VendorOrderID, model.OrderStatusFinishedPickup, "自动拣货完成")
//if status == model.OrderStatusAccepted {
err = p.OrderExport(jxcontext.AdminCtx, order.VendorOrderID, order.VendorOrderID, true)
//}
}
}
return err
}
func (p *PurchaseHandler) CallCourier(ctx *jxcontext.Context, order *model.GoodsOrder) (err error) {
return err
} // 取货失败后再次招唤平台配送
func (p *PurchaseHandler) ConfirmReceiveGoods(ctx *jxcontext.Context, order *model.GoodsOrder) (err error) {
return err
} // 投递失败后确认收到退货
func (p *PurchaseHandler) CanSwitch2SelfDeliver(order *model.GoodsOrder) (isCan bool, err error) {
return isCan, err
}
func (p *PurchaseHandler) Swtich2SelfDeliver(order *model.GoodsOrder, userName string) (err error) {
return err
}
func (p *PurchaseHandler) Swtich2SelfDelivered(order *model.GoodsOrder, userName string) (err error) {
return err
}
func (p *PurchaseHandler) SelfDeliverDelivering(order *model.GoodsOrder, userName string) (err error) {
ChangeOrderStatus(order.VendorOrderID, model.OrderStatusDelivering, "")
return err
}
func (p *PurchaseHandler) SelfDeliverDelivered(order *model.GoodsOrder, userName string) (err error) {
//ChangeOrderStatus(order.VendorOrderID, model.OrderStatusFinished, "")
//if order.VendorOrgCode == "2" {
// getAPI(order.VendorOrgCode).SetOrderStateToFinish(utils.Str2Int64(order.VendorOrderID2))
//}
return err
}
func (p *PurchaseHandler) GetOrderRealMobile(ctx *jxcontext.Context, order *model.GoodsOrder) (mobile string, err error) {
return mobile, err
}
func (p *PurchaseHandler) ReplyOrderComment(ctx *jxcontext.Context, vendorOrgCode string, orderComment *model.OrderComment, replyComment string) (err error) {
return err
}
func (p *PurchaseHandler) AgreeOrRefuseCancel(ctx *jxcontext.Context, order *model.GoodsOrder, isAgree bool, reason string) (err error) {
return err
}
func (p *PurchaseHandler) CancelOrder(ctx *jxcontext.Context, order *model.GoodsOrder, reason string) (err error) {
ChangeOrderStatus(order.VendorOrderID, model.OrderStatusCanceled, reason)
if order.EclpOutID != "" {
_, err = api.JdEclpAPI.CancelOrder(order.EclpOutID)
}
return err
}
func (p *PurchaseHandler) AdjustOrder(ctx *jxcontext.Context, order *model.GoodsOrder, removedSkuList []*model.OrderSku, reason string) (err error) {
var (
db = dao.GetDB()
diffShopPrice int64
diffSalePrice int64
)
if order.Status >= model.OrderStatusDelivering {
return fmt.Errorf("配送中以后的订单无法进行售前退款!")
}
//1、删除原order_sku 中售前调整的商品
for _, sku := range removedSkuList {
sql := `DELETE FROM order_sku WHERE vendor_order_id = ? AND vendor_id = ? AND sku_id = ?`
sqlParams := []interface{}{order.VendorOrderID, order.VendorID, sku.SkuID}
dao.ExecuteSQL(db, sql, sqlParams)
diffShopPrice += sku.ShopPrice
diffSalePrice += sku.SalePrice
}
//2、修改goods_order 中的shopprice,若是扣点的订单还要改new_earning_price和total_shop_money
order.AdjustCount += 1
order.ShopPrice = order.ShopPrice - diffShopPrice
if order.EarningType == model.EarningTypePoints {
order.TotalShopMoney = utils.Float64TwoInt64(float64(float64(order.TotalShopMoney)/jdshopapi.JdsPayPercentage-float64(diffSalePrice)) * jdshopapi.JdsPayPercentage)
jxutils.RefreshOrderEarningPrice2(order, order.OrderPayPercentage)
partner.CurOrderManager.UpdateOrderFields(order, []string{"TotalShopMoney", "NewEarningPrice"})
}
partner.CurOrderManager.UpdateOrderFields(order, []string{"AdjustCount", "ShopPrice"})
return err
}
func (p *PurchaseHandler) GetJdsOrders(ctx *jxcontext.Context, orderCreatedStart, orderCreatedEnd string, current, pageSize int) (orderResult *jdshopapi.AllOrdersResult, err error) {
//jdsapi := getAPI("2")
//globals.SugarLogger.Debugf("此时的cookie , %d", jdsapi.GetCookieCount())
//orderResult, err = jdsapi.AllOrders(&jdshopapi.AllOrdersParam{
// Current: current,
// PageSize: pageSize,
// OrderCreateDateRange: []string{orderCreatedStart, orderCreatedEnd},
//})
return orderResult, err
}
func ChangeOrderStatus(vendorOrderID string, status int, remark string) (err error) {
orderStatus := &model.OrderStatus{
VendorOrderID: vendorOrderID,
VendorID: model.VendorIDJDShop,
OrderType: model.OrderTypeOrder,
RefVendorOrderID: vendorOrderID,
RefVendorID: model.VendorIDJDShop,
VendorStatus: utils.Int2Str(status),
Status: status,
StatusTime: time.Now(),
Remark: remark,
}
jxutils.CallMsgHandlerAsync(func() {
err = partner.CurOrderManager.OnOrderStatusChanged("", orderStatus)
}, jxutils.ComposeUniversalOrderID(vendorOrderID, model.VendorIDJDShop))
return err
}
func (p *PurchaseHandler) OrderExport(ctx *jxcontext.Context, vendorOrderID, vendorWaybillID string, isAuto bool) (err error) {
//companyID := jdshopapi.JdsDeliveryCompany3rd
////表示是门店手动发京东
//if !isAuto {
// companyID = jdshopapi.JdsDeliveryCompanyJD
//}
//if order, _ := partner.CurOrderManager.LoadOrder(vendorOrderID, model.VendorIDJDShop); order != nil {
// err = getAPI(order.VendorOrgCode).OrderShipment(utils.Str2Int64(order.VendorOrderID2), companyID, vendorWaybillID)
//}
return err
}
func (p *PurchaseHandler) OrderTransfer(ctx *jxcontext.Context, vendorOrderID, vendorWaybillID string, isAuto bool) (err error) {
companyID := jdshopapi.JdsDeliveryCompany3rd
//表示是门店手动发京东
if !isAuto {
companyID = jdshopapi.JdsDeliveryCompanyJD
}
err = api.JdShopAPI.UpdateWaybill(vendorOrderID[:12], companyID, vendorOrderID)
return err
}
func status2Jxstatus(status int) (statusJx int) {
//if status == jdshopapi.OrderStatusPopPause || status == jdshopapi.OrderStatusPause {
// statusJx = model.OrderStatusNew
//} else if status == jdshopapi.OrderStatusWait {
// statusJx = model.OrderStatusAccepted
//} else if status == jdshopapi.OrderStatusCancel {
// statusJx = model.OrderStatusCanceled
//}
if status == jdshopapi.OrderStatusFinishedPickup {
statusJx = model.OrderStatusAccepted
} else if status == jdshopapi.OrderStatusNew {
statusJx = model.OrderStatusNew
} else if status == jdshopapi.OrderStatusCancelm2 {
statusJx = model.OrderStatusCanceled
}
return statusJx
}
const (
ProdURL = "http://116.196.82.188:8080/v2/"
)
func apiToYd(url string, params map[string]interface{}) (retVal map[string]interface{}, err error) {
cl := &http.Client{}
err = platformapi.AccessPlatformAPIWithRetry(cl,
func() *http.Request {
request, _ := http.NewRequest(http.MethodPost, ProdURL+url, strings.NewReader(utils.Map2URLValues(params).Encode()))
request.Header.Set("Content-Type", "application/x-www-form-urlencoded")
return request
},
nil,
func(response *http.Response, bodyStr string, jsonResult1 map[string]interface{}) (errLevel string, err error) {
if jsonResult1 == nil {
return platformapi.ErrLevelRecoverableErr, fmt.Errorf("mapData is nil")
}
if err == nil {
if jsonResult1["code"] != nil {
if utils.Interface2Int64WithDefault(jsonResult1["code"], 0) != 0 {
errLevel = platformapi.ErrLevelGeneralFail
err = utils.NewErrorCode(jsonResult1["desc"].(string), jsonResult1["code"].(string))
baseapi.SugarLogger.Debugf("yd AccessAPI failed, jsonResult1:%s", utils.Format4Output(jsonResult1, true))
}
}
retVal = jsonResult1
}
return errLevel, err
})
return retVal, err
}
func GetJdsOrder(vendorOrderID, vendorOrgCode string) (jdsOrder *jdshopapi.GetEnOrderResult, err error) {
jdmcshopapi := jdshopapi.New("f9c5ce9a5ce24218936924f7c4864cc9owe1", "E1D746D42474D5F1F1A10CECE75D99F6", "efa7e1d1a22640fa990e6cf164b28608")
result, err := jdmcshopapi.GetOrderById(utils.Str2Int64(vendorOrderID[0:12]), false)
if err != nil {
return nil, err
}
return result, err
}
func GetJdsOrder2(vendorOrderID, vendorOrgCode string) (jdsOrder string, err error) {
params := make(map[string]interface{})
params["orderID"] = vendorOrderID
params["token"] = jdshopapi.JdsYdToken
params["vendorOrgCode"] = vendorOrgCode
result, err := apiToYd("order/GetJdsOrder", params)
//jdsOrder2 := &jdshopapi.GetOrderResult{}
return strings.ReplaceAll(result["data"].(string), "\\", ""), err
}
func (c *PurchaseHandler) GetSelfTakeCode(ctx *jxcontext.Context, order *model.GoodsOrder) (selfTakeCode string, err error) {
return selfTakeCode, err
}
func (c *PurchaseHandler) ConfirmSelfTake(ctx *jxcontext.Context, order *model.GoodsOrder, selfTakeCode string) (err error) {
return err
}
func (c *PurchaseHandler) ListOrders(ctx *jxcontext.Context, vendorOrgCode string, parentTask tasksch.ITask, queryDate time.Time, vendorStoreID string) (vendorOrderIDs []string, err error) {
return vendorOrderIDs, err
}
func (c *PurchaseHandler) ComplaintRider(vendorOrderId string, resonID int, resonContent string) (err error) {
return err
}
// 转自配送时取消非专送混合送门店取消理由
func (c *PurchaseHandler) GetCancelDeliveryReason(order *model.GoodsOrder) (string, error) {
return "", nil
}
// 取消美团外卖理由转使用三方配送
func (c *PurchaseHandler) CancelLogisticsByWmOrderId(order *model.GoodsOrder, reasonCode, detailContent, appPoiCode, orderId string) error {
return nil
}
// 获取订单配送状态
func (c *PurchaseHandler) OrderLogisticsStatus(orderId int64) (int64, error) {
return 0, nil
}

View File

@@ -1,138 +0,0 @@
package gomei
import (
"crypto/md5"
"fmt"
"math"
"time"
"git.rosy.net.cn/jx-callback/business/model/dao"
"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/partner"
"git.rosy.net.cn/jx-callback/globals"
)
func (c *PurchaseHandler) AgreeOrRefuseRefund(ctx *jxcontext.Context, afsOrder *model.AfsOrder, approveType int, reason string) (err error) {
var status int
if approveType == partner.AfsApproveTypeRefused {
status = model.AfsOrderStatusFailed
} else {
status = model.AfsOrderStatusFinished
}
orderStatus := &model.OrderStatus{
VendorOrderID: afsOrder.AfsOrderID, // 是售后单ID不是订单ID订单ID在RefVendorOrderID中
VendorID: afsOrder.VendorID,
OrderType: model.OrderTypeAfsOrder,
RefVendorOrderID: afsOrder.VendorOrderID,
RefVendorID: afsOrder.VendorID,
VendorStatus: utils.Int2Str(status),
Status: status,
StatusTime: time.Now(),
Remark: reason,
}
partner.CurOrderManager.OnAfsOrderStatusChanged(orderStatus)
return err
}
// 确认收到退货
func (c *PurchaseHandler) ConfirmReceivedReturnGoods(ctx *jxcontext.Context, order *model.AfsOrder) (err error) {
err = fmt.Errorf("京东商城当前不支持ConfirmReceivedReturnGoods")
return err
}
// 发起全款退款
func (c *PurchaseHandler) RefundOrder(ctx *jxcontext.Context, order *model.GoodsOrder, reason string) (err error) {
err = c.PartRefundOrder(ctx, order, order.Skus, reason)
return err
}
// 发起部分退款
func (c *PurchaseHandler) PartRefundOrder(ctx *jxcontext.Context, order *model.GoodsOrder, refundSkuList []*model.OrderSku, reason string) (err error) {
globals.SugarLogger.Debugf("PartRefundOrder jdshop, order :%v", utils.Format4Output(order, true))
var (
skuMap = make(map[int]*model.OrderSku)
salePrice int64
db = dao.GetDB()
)
for _, sku := range order.Skus {
skuMap[sku.SkuID] = sku
}
orderStatus := buildOrderStatus(ctx, order, reason)
afsOrder := &model.AfsOrder{
VendorID: order.VendorID,
AfsOrderID: orderStatus.VendorOrderID,
VendorOrderID: orderStatus.RefVendorOrderID,
// VendorStoreID: order.VendorStoreID,
// StoreID: jxutils.GetSaleStoreIDFromOrder(order),
AfsCreatedAt: time.Now(),
VendorAppealType: "",
AppealType: model.AfsAppealTypeRefund,
VendorReasonType: utils.Int2Str(model.AfsReasonNotOthers),
ReasonType: model.AfsReasonNotOthers,
ReasonDesc: utils.LimitUTF8StringLen(reason, 1024),
ReasonImgList: "",
RefundType: model.AfsTypePartRefund,
VendorOrgCode: "",
}
for _, sku := range refundSkuList {
orderSku := &model.OrderSkuFinancial{
Count: sku.Count,
VendorSkuID: utils.Int2Str(sku.SkuID),
SkuID: sku.SkuID,
}
storeSkus, _ := dao.GetStoresSkusInfo(db, []int{model.JdShopMainStoreID}, []int{sku.SkuID})
if len(storeSkus) > 0 {
orderSku.VendorSkuID = utils.Int64ToStr(storeSkus[0].JdsID)
}
if skuMap[sku.SkuID] != nil {
orderSku.Name = skuMap[sku.SkuID].SkuName
orderSku.UserMoney = skuMap[sku.SkuID].SalePrice * int64(sku.Count)
salePrice += skuMap[sku.SkuID].SalePrice * int64(sku.Count)
}
afsOrder.SkuUserMoney += orderSku.UserMoney
afsOrder.Skus = append(afsOrder.Skus, orderSku)
}
err = partner.CurOrderManager.OnAfsOrderNew(afsOrder, orderStatus)
return err
}
func buildOrderStatus(ctx *jxcontext.Context, order *model.GoodsOrder, reason string) (orderStatus *model.OrderStatus) {
orderStatus = &model.OrderStatus{
VendorOrderID: utils.Int64ToStr(GenAfsOrderNo(ctx)), // 是售后单ID不是订单ID订单ID在RefVendorOrderID中
VendorID: order.VendorID,
OrderType: model.OrderTypeAfsOrder,
RefVendorOrderID: order.VendorOrderID,
RefVendorID: order.VendorID,
VendorStatus: utils.Int2Str(model.AfsOrderStatusWait4Approve),
Status: model.AfsOrderStatusWait4Approve,
StatusTime: time.Now(),
Remark: reason,
}
orderStatus.Status = model.AfsOrderStatusWait4Approve
return orderStatus
}
func GenAfsOrderNo(ctx *jxcontext.Context) (orderNo int64) {
const prefix = 70
const randPartNum = 100
orderNoBeginTimestamp := utils.Str2Time("2010-01-01 00:00:00").Unix()
orderNo = time.Now().Unix() - orderNoBeginTimestamp
orderNo = orderNo * randPartNum
md5Bytes := md5.Sum([]byte(utils.GetUUID()))
randPart := 0
for k, v := range md5Bytes {
randPart += int(v) << ((k % 3) * 8)
}
orderNo += int64(randPart % randPartNum)
orderNo += int64(math.Pow10(int(math.Log10(float64(orderNo)))+1)) * prefix
return orderNo
}
func (c *PurchaseHandler) GetOrderAfsInfo(ctx *jxcontext.Context, vendorOrderID, afsOrderID string) (orderAfsInfo *partner.OrderAfsInfo, err error) {
return &partner.OrderAfsInfo{}, err
}

View File

@@ -1,5 +0,0 @@
package gomei
func (c *PurchaseHandler) StartRefreshComment() {
}

View File

@@ -1,87 +0,0 @@
package gomei
import (
"fmt"
gomei "git.rosy.net.cn/baseapi/platformapi/gome_live_show"
"git.rosy.net.cn/baseapi/platformapi/jdshopapi"
"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/jxutils/tasksch"
"git.rosy.net.cn/jx-callback/business/model"
"git.rosy.net.cn/jx-callback/business/model/dao"
"git.rosy.net.cn/jx-callback/globals/api"
)
func (p *PurchaseHandler) ReadStore(ctx *jxcontext.Context, vendorOrgCode, vendorStoreID, vendorStoreName string) (storeDetail *dao.StoreDetail, err error) {
if vendorStoreName != "" {
result2, _ := api.GuoMeiApi.QueryStoreList(&gomei.GetStoreListReq{
StoreName: vendorStoreName,
})
if len(result2.Data.Records) != model.YES {
return storeDetail, fmt.Errorf("国美未查询到该平台门店平台门店ID[%v]", vendorStoreID)
}
storeDetail = &dao.StoreDetail{}
storeDetail.Name = result2.Data.Records[0].StoreName
storeDetail.Lat = jxutils.StandardCoordinate2Int(utils.Str2Float64("0.000"))
storeDetail.Lng = jxutils.StandardCoordinate2Int(utils.Str2Float64("0.000"))
}
return storeDetail, err
}
// stoerIDs为nil表示所有
func (p *PurchaseHandler) UpdateStore(db *dao.DaoDB, storeID int, userName string) (err error) {
return nil
}
func (p *PurchaseHandler) CreateStore2(db *dao.DaoDB, storeID int, userName string, params map[string]interface{}, storeDetail *dao.StoreDetail) (vendorStoreID string, err error) {
return "", err
}
func (p *PurchaseHandler) DeleteStore(db *dao.DaoDB, storeID int, userName string) (err error) {
return err
}
func (p *PurchaseHandler) RefreshAllStoresID(ctx *jxcontext.Context, parentTask tasksch.ITask, isAsync bool) (hint string, err error) {
return hint, err
}
func (p *PurchaseHandler) GetStoreStatus(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string) (storeStatus int, err error) {
return storeStatus, err
}
func (p *PurchaseHandler) EnableAutoAcceptOrder(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, isSetEnable bool) (err error) {
return err
}
func (c *PurchaseHandler) UpdateStoreStatus(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, status int) (err error) {
err = api.JdShopAPI.UpdateStatus(utils.Str2Int(vendorStoreID), jxStatus2JdsStatus(status))
return err
}
func (c *PurchaseHandler) UpdateStoreOpTime(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, opTimeList []int16) (err error) {
return err
}
func (c *PurchaseHandler) GetAllStoresVendorID(ctx *jxcontext.Context, vendorOrgCode string) (vendorStoreIDs []string, err error) {
return vendorStoreIDs, err
}
func (c *PurchaseHandler) UpdateStoreCustomID(ctx *jxcontext.Context, vendorOrgCode, vendorStoreID string, storeID int64) (err error) {
return err
}
func jxStatus2JdsStatus(status int) (result int) {
if status == model.StoreStatusOpened {
result = jdshopapi.JdsStoreStatusOnline
} else if status == model.StoreStatusHaveRest || status == model.StoreStatusClosed {
result = jdshopapi.JdsStoreStatusRest
} else {
result = jdshopapi.JdsStoreStatusDisable
}
return result
}
func (c *PurchaseHandler) UpdateStoreLineStatus(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, lineStatus int) (err error) {
return err
}

View File

@@ -1,911 +0,0 @@
package gomei
import "regexp"
//
//import (
// "fmt"
// gomei "git.rosy.net.cn/baseapi/platformapi/gome_live_show"
// "regexp"
// "strings"
// "time"
//
// "git.rosy.net.cn/baseapi/platformapi/jdshopapi"
//
// "git.rosy.net.cn/jx-callback/globals/api"
//
// "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/business/partner/putils"
// "git.rosy.net.cn/jx-callback/globals"
//)
//
const (
deleteErr1 = "已经删除的不能直接下架"
deleteErr2 = "SKU"
deleteErr3 = "已删除"
)
var (
sensitiveWordRegexp = regexp.MustCompile(`商品名称中含有敏感词(\[.*\])`)
)
//func (p *PurchaseHandler) CreateStoreSkus(ctx *jxcontext.Context, storeID int, vendorStoreID string, storeSkuList []*dao.StoreSkuSyncInfo) (failedList []*partner.StoreSkuInfoWithErr, err error) {
// if globals.EnableJdShopWrite {
// if vendorStoreID == model.GoMeiShopMainVendorStoreID {
// for _, v := range storeSkuList {
// //判断京东商城上是否有这个商品了,如果有就是添加规格而不是创建商品
// //如果是京东商城2是下架的商品弄上架 ,先改为有下架的不管,重新建
// name := filterSensitiveWord(v.Name)
// flag := false
// result, err := getAPI(v.VendorOrgCode).SearchWare4Valid(name, 1, 100)
// if err != nil {
// failedList = putils.GetErrMsg2FailedSingleList(storeSkuList, err, storeID, model.VendorChineseNames[model.VendorIDJDShop], "创建商品")
// return failedList, err
// }
// for _, v := range result.Data {
// if v.Title == name {
// flag = true
// //下架
// if v.WareStatus == 2 || v.WareStatus == 1028 {
// flag = false
// //wareStatusUpdateWareID = utils.Int64ToStr(v.WareID)
// }
// break
// }
// }
// if flag {
// wareSaveParam := &jdshopapi.WareSaveParam{
// WareID: result.Data[0].WareID,
// Title: v.Name,
// CategoryID: int(v.VendorVendorCatID),
// VenderID: jdshopapi.VendorID2,
// Length: 200,
// Wide: 100,
// Height: 100,
// Weight: "1",
// BrandID: jdshopapi.BrandIdNO,
// ShopCategorys: []int{utils.Str2Int(v.VendorCatID)},
// PromiseID: -1,
// MultiCateProps: []interface{}{},
// PropsSet: []interface{}{},
// SaleAttrs: []interface{}{},
// WareStatus: 8,
// }
// var wareSaveSkus []*jdshopapi.WareSaveSkus
// //先把已有的规格放进去
// wareResult, _ := getAPI(v.VendorOrgCode).FindWareById(wareSaveParam.WareID)
// if wareResult != nil {
// for _, v := range wareResult.Images {
// wareSaveParam.ImageMap.Num0000000000 = append(wareSaveParam.ImageMap.Num0000000000, &jdshopapi.CreateSkuParamImages{
// ColorID: v.ColorID,
// ImgURL: v.ImgURL,
// ImgIndex: v.ImgIndex,
// })
// }
// }
// skus, _, _ := getAPI(v.VendorOrgCode).SearchSkuList2([]int{int(wareSaveParam.WareID)})
// if len(skus) > 0 {
// for _, vv := range skus {
// sku := &jdshopapi.WareSaveSkus{
// SkuID: vv.SkuID,
// JdPrice: utils.Float64ToStr(vv.JdPrice),
// StockNum: vv.StockNum,
// Props: []*jdshopapi.WareSaveSkusProp{
// &jdshopapi.WareSaveSkusProp{
// AttrID: utils.Str2Int(vv.SaleAttrs[0].AttrID),
// AttrValues: utils.Str2Int64(vv.SaleAttrs[0].AttrValues[0]),
// AttrValueAlias: vv.SaleAttrs[0].AttrValueAlias[0],
// },
// },
// OuterID: vv.OuterID,
// }
// wareSaveSkus = append(wareSaveSkus, sku)
// }
// }
// // }
// for _, vv := range v.StoreSkuSyncInfoJds {
// v.JdsWareID = result.Data[0].WareID
// vv.JdsWareID = result.Data[0].WareID
// _, wareSaveSku, err := buildUpdateSkusParam(v, vv, true)
// wareSaveSkus = append(wareSaveSkus, wareSaveSku)
// if err != nil {
// failedList = putils.GetErrMsg2FailedSingleList(storeSkuList, err, storeID, model.VendorChineseNames[model.VendorIDJDShop], "创建商品")
// return failedList, err
// }
//
// wareSaveParam.Skus = wareSaveSkus
// if wareResult, err2 := getAPI(v.VendorOrgCode).WareSave(wareSaveParam); err2 == nil {
// for _, vvv := range wareResult {
// if vvv.OuterID == wareSaveSku.OuterID {
// vv.VendorSkuID = utils.Int64ToStr(vvv.SkuID)
// break
// }
// }
// //创建商品后要上架,改价,库存,门店关注商品等
// if err = getAPI(v.VendorOrgCode).WareDoUpdate("up", utils.Int64ToStr(wareSaveParam.WareID)); err == nil {
// err = getAPI(v.VendorOrgCode).StoreSkuBindStore(true, []string{vv.VendorSkuID}, nil)
// }
// }
// // }
// }
// } else {
// // 商品不存在,直接添加商品,添加分类,添加规格,门店关注上线
// otherImg := make([]string, 0, 0)
// if v.Img2 != "" {
// otherImg = append(otherImg, v.Img2)
// }
// if v.Img3 != "" {
// otherImg = append(otherImg, v.Img3)
// }
// if v.Img4 != "" {
// otherImg = append(otherImg, v.Img4)
// }
// if v.Img5 != "" {
// otherImg = append(otherImg, v.Img5)
// }
//
// // 规格集合
// spec := &gomei.SpecProperty{
// SpecCode: v.VendorNameID,
// SpecName: v.Unit,
// SpecValues: nil,
// }
// specValuesList := make([]*gomei.SpecValues, 0, 0)
// for _, c := range v.StoreSkuSyncInfoJds {
// specValues := &gomei.SpecValues{
// SpecValueCode: c.JdsStockSwitch,
// SpecValueName: fmt.Sprintf("%f", c.SpecQuality) + c.SpecUnit,
// }
// specValuesList = append(specValuesList, specValues)
// }
// spec.SpecValues = append(spec.SpecValues, specValuesList...)
// specProperty := append(make([]*gomei.SpecProperty, 0, 0), spec)
//
// api.GuoMeiApi.CreateMerchantGoodsOnStore(&gomei.CreateGoodsListToStore{
// GoodsName: v.SkuName,
// MainPictureURL: v.Img,
// Detail: v.Name,
// Cat3Code: v.VendorCatID,
// SpecProperty: specProperty, // 规格集合
// SkuSaleList: nil, // 售卖组
// GoodsType: v.SkuVendorCatID,
// OtherPictureURL: otherImg,
// VideoURL: "",
// SpecCode: "",
// SpecName: "",
// SpecValues: "",
// SpecValueCode: "",
// SpecValueName: "",
// Specification: "", // 规格集合
// MarketPrice: utils.Int64ToFloat64(v.Price),
// ThirdSkuCode: string(v.SkuID),
// })
// _, _, wareSaveParam, err := buildCreateWareParam(v)
// if err != nil {
// failedList = putils.GetErrMsg2FailedSingleList(storeSkuList, err, storeID, model.VendorChineseNames[model.VendorIDJDShop], "创建商品")
// return failedList, err
// }
// var (
// wareID int64
// resultAttrs = make(map[string]int64)
// )
// var createSkuResult []*jdshopapi.WareSaveResult
// createSkuResult, err = getAPI(v.VendorOrgCode).WareSave(wareSaveParam)
// wareID = createSkuResult[0].WareID
//
// var paramAttrs = make(map[string]*jdshopapi.WareSaveSkus)
// for _, vv := range wareSaveParam.Skus {
// for _, vvv := range vv.Props {
// paramAttrs[vvv.AttrValueAlias] = vv
// }
// }
// for _, vv1 := range createSkuResult {
// for _, vvv1 := range vv1.Props {
// if paramAttrs[vvv1.AttrValueAlias] != nil {
// resultAttrs[paramAttrs[vvv1.AttrValueAlias].OuterID] = vv1.SkuID
// }
// }
// }
// for _, vv2 := range v.StoreSkuSyncInfoJds {
// vv2.JdsWareID = createSkuResult[0].WareID
// if resultAttrs[utils.Int2Str(vv2.SkuID)] != 0 {
// vv2.VendorSkuID = utils.Int64ToStr(resultAttrs[utils.Int2Str(vv2.SkuID)])
// }
// }
// //创建商品后要上架,改价,库存,门店关注商品等
// if err = getAPI(v.VendorOrgCode).WareDoUpdate("up", utils.Int64ToStr(wareID)); err == nil {
// for _, vv2 := range v.StoreSkuSyncInfoJds {
// if resultAttrs[utils.Int2Str(vv2.SkuID)] != 0 {
// err = getAPI(v.VendorOrgCode).StoreSkuBindStore(true, []string{utils.Int64ToStr(resultAttrs[utils.Int2Str(vv2.SkuID)])}, nil)
// }
// }
// }
// // }
// if err != nil {
// failedList = putils.GetErrMsg2FailedSingleList(storeSkuList, err, storeID, model.VendorChineseNames[model.VendorIDJDShop], "创建商品")
// return failedList, err
// } else {
// //追加商品透图
// imageURL := ""
// img := v.Img
// if img != "" {
// suffix := img[strings.LastIndex(img, "."):]
// if suffix != ".png" {
// if resBinary, _, _ := jxutils.DownloadFileByURL(img + model.SkuNameImgToPng); err == nil {
// downloadURL, _ := jxutils.UploadExportContent(resBinary, utils.Int64ToStr(time.Now().Unix()))
// imageURL, _ = uploadImg(downloadURL, name, "tou", v.VendorOrgCode)
// }
// } else {
// imageURL, _ = uploadImg(img, name, "tou", v.VendorOrgCode)
// }
// }
// if v.VendorOrgCode == "1" {
// api.JdShopAPI.TransparentImageAdd(wareID, imageURL)
// }
// }
// }
// if err != nil {
// failedList = putils.GetErrMsg2FailedSingleList(storeSkuList, err, storeID, model.VendorChineseNames[model.VendorIDJDShop], "创建商品")
// return failedList, err
// }
//
// }
// } else {
// //如果是普通店关注商品
// for _, v := range storeSkuList {
// for _, vv := range v.StoreSkuSyncInfoJds {
// storeSkus, _ := dao.GetStoresSkusInfo(dao.GetDB(), []int{model.GoMeiShopMainStoreID}, []int{vv.SkuID})
// if len(storeSkus) > 0 {
// for _, storeSku := range storeSkus {
// if storeSku.JdsID != 0 {
// status := vv.Status
// stock := vv.Stock
// price := vv.VendorPrice
// // 商品上架
// if status == model.StoreSkuBindStatusNormal {
// _, err = getAPI(vv.VendorOrgCode).OnOffLineGoodsOnStore(&gomei.ShelfGoodsForStoreReq{
// StoreCode: vendorStoreID,
// SkuCode: []string{storeSku.GmID},
// ShelveStatus: gomei.PutOnTheShelf,
// })
// if err != nil {
// failedList = putils.GetErrMsg2FailedSingleList(storeSkuList, err, storeID, model.VendorChineseNames[model.VendorGoMei], "国美商品已经存在,关注商品")
// return failedList, err
// }
// }
// // 修改库存
// if stock != 0 {
// _, err = getAPI(vv.VendorOrgCode).UpdateStockForStore(&gomei.StoreGoodsStockUpdateReq{
// StoreCode: vendorStoreID,
// ItemStocks: []*gomei.StoreSkuNum{{SkuCode: storeSku.GmID, StockNum: gomei.GoMeiMaxStock}},
// })
// if err != nil {
// failedList = putils.GetErrMsg2FailedSingleList(storeSkuList, err, storeID, model.VendorChineseNames[model.VendorIDJDShop], "国美修改商品库存")
// return failedList, err
// }
// }
// // 同步价格
// _, err = getAPI(v.VendorOrgCode).UpdateOnGoodsPriceForStore(&gomei.StoreGoodsPriceUpdateReq{
// StoreCode: vendorStoreID,
// SkuCode: storeSku.GmID,
// SalePrice: utils.Int64ToFloat64(price),
// })
// if err != nil {
// failedList = putils.GetErrMsg2FailedSingleList(storeSkuList, err, storeID, model.VendorChineseNames[model.VendorIDJDShop], "国美关注商品价格同步")
// return failedList, err
// }
// }
// }
// }
// }
// }
// }
// }
// return failedList, err
//}
//
//func (p *PurchaseHandler) UpdateStoreSkus(ctx *jxcontext.Context, storeID int, vendorStoreID string, storeSkuList []*dao.StoreSkuSyncInfo) (failedList []*partner.StoreSkuInfoWithErr, err error) {
// if globals.EnableJdShopWrite && vendorStoreID == model.JdShopMainVendorStoreID {
// if vendorStoreID == model.JdShopMainVendorStoreID {
// for _, v := range storeSkuList {
// name := filterSensitiveWord(v.Name)
// updateWareParam := &jdshopapi.UpdateWareParam{
// WareID: v.JdsWareID,
// Title: name,
// VenderID: jdshopapi.VenderID,
// // PromiseID: jdshopapi.JdsPromiseID,
// ShopCategorys: []int{utils.Str2Int(v.VendorCatID)},
// JdPrice: jxutils.IntPrice2Standard(v.UnitPrice),
// }
// if v.VendorVendorCatID != jdshopapi.JdsOtherMeatCatID {
// updateWareParam.PromiseID = jdshopapi.JdsPromiseID
// }
// var desc string
// if v.DescImg != "" {
// pic3, err2 := uploadImg2(v.DescImg, name, "desc", v.VendorOrgCode)
// err = err2
// desc = `<p><img src="` + jdshopapi.JdsImgURL + pic3 + `" style="width: auto; height: auto; max-width: 100%;"><br></p><p><br></p>`
// } else {
// desc = `<p><br></p><p><br></p>`
// }
// updateWareParam.Introduction = desc
// updateWareParam.MobileDesc = desc
// img := ""
// if v.ImgMix != "" {
// img = v.ImgMix
// } else {
// img = v.Img
// }
// if img != "" {
// pic1, err2 := uploadImg2(img, name, "1", v.VendorOrgCode)
// err = err2
// err = getAPI(v.VendorOrgCode).ImageUpdate(v.JdsWareID, 1, pic1)
// if v.Img2 != "" {
// pic2, err2 := uploadImg2(v.Img2, name, "2", v.VendorOrgCode)
// err = err2
// err = getAPI(v.VendorOrgCode).ImageUpdate(v.JdsWareID, 2, pic2)
// } else {
// err = getAPI(v.VendorOrgCode).ImageUpdate(v.JdsWareID, 2, pic1)
// }
// err = getAPI(v.VendorOrgCode).ImageUpdate(v.JdsWareID, 3, pic1)
// }
// var features = []*jdshopapi.CreateSkuParamFeatures{
// &jdshopapi.CreateSkuParamFeatures{
// Key: "is7ToReturn", //不支持7天无理由退货
// Value: "0",
// },
// &jdshopapi.CreateSkuParamFeatures{
// Key: "tssp", //支持自提
// Value: "",
// },
// // &jdshopapi.CreateSkuParamFeatures{
// // Key: "fdms", //分单?
// // Value: "1",
// // },
// }
// updateWareParam.Features = features
// err = getAPI(v.VendorOrgCode).UpdateWare(updateWareParam)
// if err == nil {
// //追加商品透图
// imageURL := ""
// img := v.Img
// if img != "" {
// suffix := img[strings.LastIndex(img, "."):]
// if suffix != ".png" {
// if resBinary, _, err := jxutils.DownloadFileByURL(img + model.SkuNameImgToPng); err == nil {
// downloadURL, err2 := jxutils.UploadExportContent(resBinary, utils.Int64ToStr(time.Now().Unix()))
// err = err2
// imageURL, err = uploadImg(downloadURL, name, "tou", v.VendorOrgCode)
// }
// } else {
// imageURL, err = uploadImg(img, name, "tou", v.VendorOrgCode)
// }
// }
// if v.VendorOrgCode == "1" {
// api.JdShopAPI.TransparentImageAdd(v.JdsWareID, imageURL)
// }
// }
// for _, vv := range v.StoreSkuSyncInfoJds {
// updateSkusParam, _, err := buildUpdateSkusParam(v, vv, false)
// if err != nil {
// failedList = putils.GetErrMsg2FailedSingleList(storeSkuList, err, storeID, model.VendorChineseNames[model.VendorIDJDShop], "更新商品基础信息")
// return failedList, err
// }
// _, err = getAPI(v.VendorOrgCode).UpdateSkus(updateSkusParam)
// }
// }
// } else {
// for _, v := range storeSkuList {
// var wareSaveSkus []*jdshopapi.WareSaveSkus
// name := filterSensitiveWord(v.Name)
// //jds2
// wareSaveParam := &jdshopapi.WareSaveParam{
// WareID: v.JdsWareID,
// Title: name,
// CategoryID: int(v.VendorVendorCatID),
// VenderID: jdshopapi.VendorID2,
// Length: 100,
// Wide: 100,
// Height: 100,
// Weight: utils.Int2Str(v.Weight),
// BrandID: jdshopapi.BrandIdNO,
// ShopCategorys: []int{utils.Str2Int(v.VendorCatID)},
// PromiseID: -1,
// MultiCateProps: []interface{}{},
// PropsSet: []interface{}{},
// SaleAttrs: []interface{}{},
// }
// var desc string
// if v.DescImg != "" {
// pic3, err2 := uploadImg2(v.DescImg, name, "desc", v.VendorOrgCode)
// err = err2
// desc = `<p><img src="` + jdshopapi.JdsImgURL + pic3 + `" style="width: auto; height: auto; max-width: 100%;"><br></p><p><br></p>`
// } else {
// desc = `<p><br></p><p><br></p>`
// }
// wareSaveParam.Notes = desc
// //上传京东图片
// //规则,有两张就传两张,没有就重复传一张
// pic1, _ := uploadImg(v.Img, name, "1", v.VendorOrgCode)
// img1 := &jdshopapi.CreateSkuParamImages{
// ColorID: "0000000000",
// ImgIndex: 1,
// ImgURL: pic1,
// }
// img2 := &jdshopapi.CreateSkuParamImages{
// ColorID: "0000000000",
// ImgIndex: 2,
// }
// if v.Img2 == "" {
// img2.ImgURL = pic1
// } else {
// pic2, err2 := uploadImg(v.Img, name, "2", v.VendorOrgCode)
// err = err2
// img2.ImgURL = pic2
// }
// img3 := &jdshopapi.CreateSkuParamImages{
// ColorID: "0000000000",
// ImgIndex: 3,
// ImgURL: pic1,
// }
// //jds2图片
// wareSaveParam.ImageMap.Num0000000000 = append(wareSaveParam.ImageMap.Num0000000000, img1, img2, img3)
// for _, vv := range v.StoreSkuSyncInfoJds {
// _, wareSaveSku, err2 := buildUpdateSkusParam(v, vv, true)
// err = err2
// wareSaveSku.SkuID = utils.Str2Int64(vv.VendorSkuID)
// wareSaveSkus = append(wareSaveSkus, wareSaveSku)
// }
// getAPI("2").WareSave(wareSaveParam)
// }
// }
// if err != nil {
// failedList = putils.GetErrMsg2FailedSingleList(storeSkuList, err, storeID, model.VendorChineseNames[model.VendorIDJDShop], "更新商品基础信息")
// }
// }
// return failedList, err
//}
//
//func buildUpdateSkusParam(storeSku *dao.StoreSkuSyncInfo, v *dao.StoreSkuSyncInfo, vendorStoreId string, isCreate bool) (updateSkusParam *jdshopapi.UpdateSkusParam, wareSku *jdshopapi.WareSaveSkus, err error) {
// // 判断分类是否存在
// storeCategoriesList, err := GetAllStoreCategories(string(model.VendorGoMei), vendorStoreId)
// if err != nil {
// return nil, nil, err
// }
// isHaveCategory := false
// for _, sc := range storeCategoriesList {
// if sc.CategoryCode == string(storeSku.VendorVendorCatID) {
// isHaveCategory = true
// break
// }
// }
// // 分类不存在则,创建分类
// if !isHaveCategory {
// if _, err := api.GuoMeiApi.AddStoreCategory(&gomei.StoreAddGoodsCategory{
// StoreCode: vendorStoreId,
// CategoryName: storeSku.CategoryName,
// Rank: 0,
// }); err != nil {
// return nil, nil, err
// }
// }
//
// // 规格组,规格设置(获取分类下的所有规格),线上规格
// attrsList, err := GetAllSpecSizeList(&gomei.QueryGoodsSpecSizeReq{
// Cat3Code: string(storeSku.VendorVendorCatID),
// SpecName: "",
// Page: gomei.Page{
// PageNumber: gomei.PageNumber,
// PageSize: gomei.PageSize,
// },
// })
// if err != nil {
// return nil, nil, err
// }
// // 本地规格
// var ggValueID string //规格的属性id
// var ggValueName string //规格名
// // 判断本地规格和在线上是否存在
// for _, goMeiSize := range attrsList {
// if goMeiSize.SpecName == v.Unit {
// ggValueID = goMeiSize.SpecCode
// ggValueName = goMeiSize.SpecName
// break
// }
// }
// if ggValueID == "" {
// // 规格不存在,创建规格,规格只有一个,规格属性有多个!
// specList := make([]*gomei.SpecValueName, 0, 0)
// for _, sl := range storeSku.StoreSkuSyncInfoJds {
// data1 := &gomei.SpecValueName{SpecValueName: utils.Float64ToStr(float64(sl.SpecQuality)) + sl.Unit}
// specList = append(specList, data1)
// }
// _, err = api.GuoMeiApi.CreateGoodsSpceList(&gomei.CreateSpecDetailParam{
// SpecName: ggValueName,
// SpecValues: specList, // 多个规格属性
// Cat3Code: string(storeSku.VendorVendorCatID),
// Remark: "",
// })
// if err != nil {
// return nil, nil, err
// }
// } else {
// // 存在规格,判断里面,规格属性是否充足
//
// }
//
//}
//
//func buildCreateWareParam(storeSku *dao.StoreSkuSyncInfo) (createSkuParamWare *jdshopapi.CreateSkuParamWare, createSkuParamSkus []*jdshopapi.CreateSkuParamSkus, wareSaveParam *jdshopapi.WareSaveParam, err error) {
// var (
// images []*jdshopapi.CreateSkuParamImages
// vendorCatID int
// )
// if storeSku.VendorCatID == "0" {
// resultCat, _ := getAPI(storeSku.VendorOrgCode).FindShopCategories() // 查询商家所有店内分类
// for _, v := range resultCat {
// if v.Name == storeSku.CategoryName {
// vendorCatID = int(v.CID)
// break
// }
// }
// } else {
// vendorCatID = utils.Str2Int(storeSku.VendorCatID)
// }
//
// name := filterSensitiveWord(storeSku.Name)
// wareSaveParam = &jdshopapi.WareSaveParam{
// WareID: 0,
// Title: name,
// CategoryID: int(storeSku.VendorVendorCatID),
// LastCategoryID: int(storeSku.VendorVendorCatID),
// VenderID: jdshopapi.VendorID2,
// Length: 200,
// Wide: 100,
// Height: 100,
// Weight: "1",
// BrandID: jdshopapi.BrandIdNO,
// WareStatus: 8, //上架待审核,没用,建好了都要再上架一次
// ShopCategorys: []int{vendorCatID},
// PromiseID: 0,
// MultiCateProps: []interface{}{},
// PropsSet: []interface{}{},
// SaleAttrs: []interface{}{},
// TransparentImageAudit: []interface{}{},
// OptionType: 1,
// AvailableFeatures: []interface{}{},
// CharacteristicService: []interface{}{},
// ExtendFeatures: []interface{}{},
// TempID: "10569615110055200", //必须要这个东西,不知道是啥
// }
// createSkuParamWare = &jdshopapi.CreateSkuParamWare{
// Title: name,
// ShopCategorys: []int{vendorCatID},
// CategoryID: int(storeSku.VendorVendorCatID),
// BrandID: jdshopapi.JxBrandId,
// // TransportID: jdshopapi.TransportID,
// WareStatus: 8, //上架待审核
// OuterID: utils.Int2Str(storeSku.NameID),
// // VenderID: jdshopapi.VenderID,
// Length: 100,
// Width: 100,
// Height: 100,
// Weight: 0.5,
// JdPrice: jxutils.IntPrice2Standard(storeSku.UnitPrice),
// // MarketPrice: jxutils.IntPrice2Standard(storeSku.UnitPrice),
// // PromiseID: jdshopapi.JdsPromiseID,
// }
//
// if storeSku.VendorOrgCode == "1" {
// createSkuParamWare.VenderID = jdshopapi.VenderID
// }
//
// if storeSku.VendorVendorCatID != jdshopapi.JdsOtherMeatCatID {
// createSkuParamWare.PromiseID = jdshopapi.JdsPromiseID
// }
//
// if storeSku.VendorVendorCatID == jdshopapi.JdsBeefCatID {
// createSkuParamWare.MultiCategoryID = jdshopapi.JdsBeefLastCatID
// }
//
// //上传京东图片
// //规则,有两张就传两张,没有就重复传一张
// pic1, err := uploadImg(storeSku.Img, name, "1", storeSku.VendorOrgCode)
// img1 := &jdshopapi.CreateSkuParamImages{
// ColorID: "0000000000",
// ImgIndex: 1,
// ImgURL: pic1,
// }
// img2 := &jdshopapi.CreateSkuParamImages{
// ColorID: "0000000000",
// ImgIndex: 2,
// }
// if storeSku.Img2 == "" {
// img2.ImgURL = pic1
// } else {
// pic2, err2 := uploadImg(storeSku.Img, name, "2", storeSku.VendorOrgCode)
// err = err2
// img2.ImgURL = pic2
// }
// img3 := &jdshopapi.CreateSkuParamImages{
// ColorID: "0000000000",
// ImgIndex: 3,
// ImgURL: pic1,
// }
// images = append(images, img1)
// images = append(images, img2)
// images = append(images, img3)
// createSkuParamWare.Images = images
// //jds2图片
// // img4 := img1
// // img4.ImgZoneID = "0000000000"
// // img5 := img2
// // img5.ImgZoneID = "0000000000"
// // img6 := img3
// // img6.ImgZoneID = "0000000000"
// wareSaveParam.ImageMap.Num0000000000 = append(wareSaveParam.ImageMap.Num0000000000, img1, img2, img3)
//
// //商品详情拼接
// var desc string
// if storeSku.DescImg != "" {
// pic3, err2 := uploadImg(storeSku.DescImg, name, "desc", storeSku.VendorOrgCode)
// err = err2
// desc = `<p><img src="` + jdshopapi.JdsImgURL + pic3 + `" style="width: auto; height: auto; max-width: 100%;"><br></p><p><br></p>`
// } else {
// desc = `<p><br></p><p><br></p>`
// }
// createSkuParamWare.MobileDesc = desc
// createSkuParamWare.Introduction = desc
// wareSaveParam.Notes = desc
//
// //设置商品属性值
// var (
// attrIDs = make(map[string]int) //贮存方式,净含量,保质期IDs
// zctjValueID int64 //贮存条件冷藏0-4的id
// gcjkValueID int64 //国产进口的id
// lbValueID int64 //类别的ID
// bcztValueID int64 //保存状态ID
// rmsjValueID int64 //热卖时间ID
// attrsProp []*jdshopapi.CreateSkuParamAttrs
// )
// attrs, err := getAPI(storeSku.VendorOrgCode).FindAttrs(int(storeSku.VendorVendorCatID))
// for _, v := range attrs {
// if v.Name == "保质期" {
// attrIDs[v.Name] = v.ID
// } else if v.Name == "贮存条件" {
// attrIDs[v.Name] = v.ID
// } else if v.Name == "净含量" {
// attrIDs[v.Name] = v.ID
// } else if v.Name == "规格" {
// attrIDs[v.Name] = v.ID
// } else if v.Name == "国产/进口" {
// attrIDs[v.Name] = v.ID
// } else if v.Name == "类别" {
// attrIDs[v.Name] = v.ID
// } else if v.Name == "保存状态" {
// attrIDs[v.Name] = v.ID
// } else if v.Name == "热卖时间" {
// attrIDs[v.Name] = v.ID
// }
// }
// values, _, err := getAPI(storeSku.VendorOrgCode).FindValuesByAttrId(attrIDs["贮存条件"])
// for _, v := range values {
// if v.Name == "冷藏 0-4℃" {
// zctjValueID = v.ID
// }
// }
// if attrIDs["国产/进口"] != 0 {
// values2, _, err2 := getAPI(storeSku.VendorOrgCode).FindValuesByAttrId(attrIDs["国产/进口"])
// err = err2
// for _, v := range values2 {
// if v.Name == "国产" {
// gcjkValueID = v.ID
// }
// }
// attrgcjk := &jdshopapi.CreateSkuParamAttrs{
// AttrID: utils.Int2Str(attrIDs["国产/进口"]),
// AttrValues: []string{utils.Int64ToStr(gcjkValueID)},
// }
// attrsProp = append(attrsProp, attrgcjk)
// }
// if attrIDs["保存状态"] != 0 {
// values2, _, err2 := getAPI(storeSku.VendorOrgCode).FindValuesByAttrId(attrIDs["保存状态"])
// err = err2
// for _, v := range values2 {
// if v.Name == "冷藏" || v.Name == "活鲜" {
// bcztValueID = v.ID
// }
// }
// attrbczt := &jdshopapi.CreateSkuParamAttrs{
// AttrID: utils.Int2Str(attrIDs["保存状态"]),
// AttrValues: []string{utils.Int64ToStr(bcztValueID)},
// }
// attrsProp = append(attrsProp, attrbczt)
// }
// if attrIDs["热卖时间"] != 0 {
// values2, _, err2 := getAPI(storeSku.VendorOrgCode).FindValuesByAttrId(attrIDs["热卖时间"])
// err = err2
// for _, v := range values2 {
// if v.Name == "12月" {
// rmsjValueID = v.ID
// }
// }
// attrrmsj := &jdshopapi.CreateSkuParamAttrs{
// AttrID: utils.Int2Str(attrIDs["热卖时间"]),
// AttrValues: []string{utils.Int64ToStr(rmsjValueID)},
// }
// attrsProp = append(attrsProp, attrrmsj)
// }
// //牛肉创建不一样
// if storeSku.VendorVendorCatID == jdshopapi.JdsBeefCatID {
// var exValueID int64
// values2, _, err2 := getAPI(storeSku.VendorOrgCode).FindValuesByAttrId(150390)
// err = err2
// for _, v := range values2 {
// if v.Name == "其它" {
// exValueID = v.ID
// }
// }
// attrex := &jdshopapi.CreateSkuParamAttrs{
// AttrID: utils.Int2Str(150390),
// AttrValues: []string{utils.Int64ToStr(exValueID)},
// }
// attrsProp = append(attrsProp, attrex)
// wareSaveParam.LastCategoryID = 17902
// }
// attrZctj := &jdshopapi.CreateSkuParamAttrs{
// AttrID: utils.Int2Str(attrIDs["贮存条件"]),
// AttrValues: []string{utils.Int64ToStr(zctjValueID)},
// }
// attrJhl := &jdshopapi.CreateSkuParamAttrs{
// AttrID: utils.Int2Str(attrIDs["净含量"]),
// AttrValues: []string{"0.5"},
// }
// attrBzq := &jdshopapi.CreateSkuParamAttrs{
// AttrID: utils.Int2Str(attrIDs["保质期"]),
// AttrValues: []string{"5"},
// }
// attrsProp = append(attrsProp, attrZctj)
// attrsProp = append(attrsProp, attrJhl)
// attrsProp = append(attrsProp, attrBzq)
// createSkuParamWare.MultiCateProps = attrsProp
// var features = []*jdshopapi.CreateSkuParamFeatures{
// &jdshopapi.CreateSkuParamFeatures{
// Key: "is7ToReturn", //不支持7天无理由退货
// Value: "0",
// },
// // &jdshopapi.CreateSkuParamFeatures{
// // Key: "tssp", //支持自提
// // Value: "",
// // },
// // &jdshopapi.CreateSkuParamFeatures{
// // Key: "fdms", //分单?
// // Value: "1",
// // },
// }
// createSkuParamWare.Features = features
// //组合sku
// var (
// vendorPrice int64 = 0
// wareSaveSkus []*jdshopapi.WareSaveSkus
// )
//
// for _, v := range storeSku.StoreSkuSyncInfoJds {
// var (
// ggValueID int64 //规格的属性id
// ggValueName string //规格的属性名
// attrsPropSku []*jdshopapi.CreateSkuParamAttrs
// attrsPropSku2 []*jdshopapi.WareSaveSkusProp //jds2
// multiPropSku []*jdshopapi.CreateSkuParamAttrs
// specQuality string
// )
// valuesSku, maxNo, _ := getAPI(storeSku.VendorOrgCode).FindValuesByAttrId(attrIDs["规格"])
// if v.SpecUnit == model.SpecUnitNames[1] || v.SpecUnit == model.SpecUnitNames[2] {
// specQuality = strings.TrimRight(fmt.Sprintf("%.2f", float64(v.SpecQuality)), "0.") + v.SpecUnit
// } else {
// specQuality = utils.Float64ToStr(float64(v.SpecQuality)) + v.SpecUnit
// }
// if v.Comment != "" {
// specQuality = v.Comment
// }
// for _, v := range valuesSku {
// if v.Name == specQuality {
// ggValueID = v.ID
// ggValueName = v.Name
// }
// }
// if ggValueID == 0 { //说明没有建这个规格,要建上
// catID, _ := getAPI(storeSku.VendorOrgCode).SaveVenderAttrValue(specQuality, attrIDs["规格"], int(storeSku.VendorVendorCatID), maxNo+1)
// ggValueID = catID
// ggValueName = specQuality
// }
// //jds1
// attrSku := &jdshopapi.CreateSkuParamAttrs{
// AttrID: utils.Int2Str(attrIDs["规格"]),
// AttrValues: []string{utils.Int64ToStr(ggValueID)},
// }
// attrsPropSku = append(attrsPropSku, attrSku)
// //jds2
// attrSku2 := &jdshopapi.WareSaveSkusProp{
// AttrID: attrIDs["规格"],
// AttrValues: ggValueID,
// AttrValueAlias: ggValueName,
// }
// attrsPropSku2 = append(attrsPropSku2, attrSku2)
//
// //jds1
// sku := &jdshopapi.CreateSkuParamSkus{
// JdPrice: jxutils.IntPrice2Standard(v.VendorPrice),
// // StockNum: 9999,
// Type: "com.jd.pop.ware.ic.api.domain.sku",
// Type2: "com.jd.pop.ware.ic.api.domain.Sku",
// OuterID: utils.Int2Str(v.SkuID),
// }
// sku.SaleAttrs = attrsPropSku
// //jds2
// sku2 := &jdshopapi.WareSaveSkus{
// JdPrice: utils.Float64ToStr(jxutils.IntPrice2Standard(v.VendorPrice)),
// OuterID: utils.Int2Str(v.SkuID),
// }
// sku2.Props = attrsPropSku2
//
// if attrIDs["类别"] != 0 {
// values2, _, err2 := getAPI(storeSku.VendorOrgCode).FindValuesByAttrId(attrIDs["类别"])
// err = err2
// lbValueID = values2[len(values2)-1].ID
// attrlb := &jdshopapi.CreateSkuParamAttrs{
// AttrID: utils.Int2Str(attrIDs["类别"]),
// AttrValues: []string{utils.Int64ToStr(lbValueID)},
// }
// multiPropSku = append(multiPropSku, attrlb)
// }
// sku.MultiCateProps = multiPropSku
// createSkuParamSkus = append(createSkuParamSkus, sku)
//
// if v.VendorPrice > vendorPrice {
// vendorPrice = v.VendorPrice
// }
// if v.Status == model.SkuStatusNormal {
// sku.StockNum = 9999
// sku2.StockNum = 9999
// } else {
// sku.StockNum = 0
// sku2.StockNum = 0
// }
// wareSaveSkus = append(wareSaveSkus, sku2)
// }
// //市场价固定500
// createSkuParamWare.MarketPrice = 500
// wareSaveParam.Skus = wareSaveSkus
// return createSkuParamWare, createSkuParamSkus, wareSaveParam, err
//}
//
//// 国美获取线上所有规格列表
//func GetAllSpecSizeList(param *gomei.QueryGoodsSpecSizeReq) ([]*gomei.QueryGoodsSpecSizeRecords, error) {
// attrs, err := api.GuoMeiApi.QueryGoodsSizeList(param)
// if err != nil {
// return nil, err
// }
//
// goMeiSizeList := make([]*gomei.QueryGoodsSpecSizeRecords, 0, 0)
// for i := 1; i <= attrs.Data.PageTotal; i++ {
// attrs, err := api.GuoMeiApi.QueryGoodsSizeList(&gomei.QueryGoodsSpecSizeReq{
// Cat3Code: param.Cat3Code,
// SpecName: "",
// Page: gomei.Page{
// PageNumber: i,
// PageSize: gomei.PageSize,
// },
// })
// if err != nil {
// return nil, err
// }
// goMeiSizeList = append(goMeiSizeList, attrs.Data.Records...)
// }
// return goMeiSizeList, nil
//}

View File

@@ -1,393 +0,0 @@
package gomei
import (
"encoding/base64"
"fmt"
gomei "git.rosy.net.cn/baseapi/platformapi/gome_live_show"
"git.rosy.net.cn/baseapi/platformapi/jdshopapi"
"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/jxutils/tasksch"
"git.rosy.net.cn/jx-callback/business/model"
"git.rosy.net.cn/jx-callback/business/model/dao"
"git.rosy.net.cn/jx-callback/business/partner"
"git.rosy.net.cn/jx-callback/business/partner/putils"
"git.rosy.net.cn/jx-callback/globals"
"regexp"
"strings"
"time"
)
// 删除不在使用商品(下架之后在删除) ok
func (p *PurchaseHandler) DeleteStoreSkus(ctx *jxcontext.Context, storeID int, vendorStoreID string, storeSkuList []*partner.StoreSkuInfo) (failedList []*partner.StoreSkuInfoWithErr, err error) {
if globals.EnableJdShopWrite && vendorStoreID == model.GoMeiShopMainVendorStoreID {
for _, v := range storeSkuList {
if v.IsDeletedBySku && storeID != 0 { // 如果门店id存在,则将该门店商品下架,所有门店该商品处于下架才可以删除!
_, err = getAPI(v.VendorOrgCode).OnOffLineGoodsOnStore(&gomei.ShelfGoodsForStoreReq{
StoreCode: vendorStoreID,
SkuCode: []string{v.VendorSkuID},
ShelveStatus: gomei.DownOnTheShelf,
})
}
if err == nil {
_, err = getAPI(v.VendorOrgCode).DeleteGoodsOnStore(v.VendorSkuID)
}
if err != nil {
failedList = append(failedList, putils.GetErrMsg2FailedSingleList(storeSkuList, err, storeID, model.VendorChineseNames[model.VendorGoMei], "删除商品")...)
}
}
}
return failedList, err
}
// 获取门店商品列表
func (p *PurchaseHandler) GetStoreSkusFullInfo(ctx *jxcontext.Context, parentTask tasksch.ITask, storeID int, vendorStoreID string, storeSkuList []*partner.StoreSkuInfo) (skuNameList []*partner.SkuNameInfo, err error) {
var (
pageNo = 1
pageSize = 50
)
result, err := getAPI(string(model.VendorGoMei)).QueryGoodsListById(&gomei.QueryGoodsListForStoreReq{
Page: gomei.Page{
PageNumber: pageNo,
PageSize: pageSize,
},
})
if err != nil {
return nil, err
}
for ; pageNo <= result.Data.Total/pageSize+1; pageNo++ {
result2, err := getAPI(string(model.VendorGoMei)).QueryGoodsListById(&gomei.QueryGoodsListForStoreReq{
Page: gomei.Page{
PageNumber: pageNo,
PageSize: pageSize,
},
})
if err != nil {
return nil, err
}
for _, v := range result2.Data.Records {
if skuName := vendorSku2Jx2(v); skuName != nil {
skuNameList = append(skuNameList, skuName)
}
}
}
return skuNameList, err
}
// 修改门店商品状态
func (p *PurchaseHandler) UpdateStoreSkusStatus(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, storeSkuList []*partner.StoreSkuInfo, status int) (failedList []*partner.StoreSkuInfoWithErr, err error) {
if globals.EnableJdShopWrite {
for _, v := range storeSkuList {
if vendorSkuID, err := getMainStoreVendorSkuID(model.GoMeiShopMainStoreID, v.SkuID); err == nil && vendorSkuID != "" {
storeSku := &gomei.ShelfGoodsForStoreReq{
StoreCode: vendorStoreID,
SkuCode: []string{vendorSkuID},
}
if status == 0 {
storeSku.ShelveStatus = gomei.PutOnTheShelf
} else {
storeSku.ShelveStatus = gomei.DownOnTheShelf
}
_, err = getAPI(v.VendorOrgCode).OnOffLineGoodsOnStore(storeSku)
}
}
if err != nil {
failedList = putils.GetErrMsg2FailedSingleList(storeSkuList, err, storeID, model.VendorChineseNames[model.VendorGoMei], "修改商品库存")
}
}
return failedList, err
}
// 修改门店商品价格维护
func (p *PurchaseHandler) UpdateStoreSkusPrice(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, storeSkuList []*partner.StoreSkuInfo) (failedList []*partner.StoreSkuInfoWithErr, err error) {
if globals.EnableJdShopWrite {
for _, v := range storeSkuList {
if vendorSkuID, err := getMainStoreVendorSkuID(model.GoMeiShopMainStoreID, v.SkuID); err == nil && vendorSkuID != "" {
_, err = getAPI(v.VendorOrgCode).UpdateOnGoodsPriceForStore(&gomei.StoreGoodsPriceUpdateReq{
StoreCode: vendorStoreID,
SkuCode: vendorSkuID,
SalePrice: utils.Int64ToFloat64(v.VendorPrice),
})
}
if err != nil {
failedList = append(failedList, putils.GetErrMsg2FailedSingleList(storeSkuList, err, storeID, model.VendorChineseNames[model.VendorIDJDShop], "修改商品价格")...)
}
}
}
return failedList, err
}
// 门店商品库存维护
func (p *PurchaseHandler) UpdateStoreSkusStock(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, storeSkuList []*partner.StoreSkuInfo) (failedList []*partner.StoreSkuInfoWithErr, err error) {
if globals.EnableJdShopWrite {
for _, v := range storeSkuList {
if vendorSkuID, err := getMainStoreVendorSkuID(model.GoMeiShopMainStoreID, v.SkuID); err == nil && vendorSkuID != "" {
_, err = getAPI(v.VendorOrgCode).UpdateStockForStore(&gomei.StoreGoodsStockUpdateReq{
StoreCode: vendorStoreID,
ItemStocks: []*gomei.StoreSkuNum{
{SkuCode: vendorSkuID, StockNum: int64(v.Stock)},
},
})
}
}
if err != nil {
failedList = append(failedList, putils.GetErrMsg2FailedSingleList(storeSkuList, err, storeID, model.VendorChineseNames[model.VendorIDJDShop], "修改商品库存")...)
}
}
return failedList, err
}
// 获取门店所有的分类
func (p *PurchaseHandler) GetStoreAllCategories(ctx *jxcontext.Context, storeID int, vendorStoreID string) (cats []*partner.BareCategoryInfo, err error) {
var (
pageNo = 1
pageSize = 50
)
result, err := getAPI(string(model.VendorGoMei)).QueryStoreCategoryList(&gomei.QueryStoreGoodsCategoryListReq{
Page: gomei.Page{
PageNumber: pageNo,
PageSize: pageSize,
},
StoreCode: vendorStoreID,
})
for ; pageNo <= result.Data.Total/pageSize+1; pageNo++ {
result2, err := getAPI(string(model.VendorGoMei)).QueryStoreCategoryList(&gomei.QueryStoreGoodsCategoryListReq{
Page: gomei.Page{
PageNumber: pageNo,
PageSize: pageSize,
},
StoreCode: vendorStoreID,
})
if err != nil {
return nil, err
}
for _, v := range result2.Data.Records {
var cat = &partner.BareCategoryInfo{
VendorCatID: v.CategoryCode,
Name: v.CategoryName,
}
cat.Level = 1
cats = append(cats, cat)
}
}
return cats, err
}
// 修改或者更新门店分类信息
func (p *PurchaseHandler) UpdateStoreCategory(ctx *jxcontext.Context, storeID int, vendorStoreID string, storeCat *dao.SkuStoreCatInfo) (err error) {
if globals.EnableJdShopWrite {
_, status, err2 := updateOrCreateCategories(storeCat, vendorStoreID, false)
err = err2
if status == -1 {
return fmt.Errorf("京东商城店内分类更新失败!")
}
}
return err
}
func (p *PurchaseHandler) CreateStoreCategory(ctx *jxcontext.Context, storeID int, vendorStoreID string, storeCat *dao.SkuStoreCatInfo) (err error) {
if globals.EnableJdShopWrite {
allCategoryList, status, err2 := updateOrCreateCategories(storeCat, vendorStoreID, true)
err = err2
if status == -1 {
return fmt.Errorf("国美商城店内分类创建失败!")
}
if err != nil {
return err
}
time.Sleep(time.Second * 2)
for _, v := range allCategoryList {
if v.CategoryName == storeCat.Name {
storeCat.VendorCatID = v.CategoryCode
break
}
}
if storeCat.VendorCatID == "" {
return fmt.Errorf("国美商城店内分类创建可能失败了storeID: %v", storeID)
}
}
return err
}
func (p *PurchaseHandler) DeleteStoreCategory(ctx *jxcontext.Context, storeID int, vendorStoreID, vendorCatID string, level int) (err error) {
if globals.EnableJdShopWrite {
_, err = getAPI(string(model.VendorGoMei)).DeleteStoreGoodsCategory(vendorStoreID, vendorCatID)
}
return err
}
func (p *PurchaseHandler) IsErrSkuExist(err error) (isExist bool) {
return false
}
func (p *PurchaseHandler) IsErrCategoryExist(err error) (isExist bool) {
return false
}
func (p *PurchaseHandler) IsErrCategoryNotExist(err error) (isNotExist bool) {
return false
}
func (p *PurchaseHandler) GetStoreSkusBatchSize(funcID int) (batchSize int) {
return 1
}
func (p *PurchaseHandler) GetSensitiveWordRegexp() *regexp.Regexp {
return sensitiveWordRegexp
}
func (p *PurchaseHandler) IsErrSkuNotExist(err error) (isNotExist bool) {
if strings.Contains(err.Error(), deleteErr1) || (strings.Contains(err.Error(), deleteErr2) && strings.Contains(err.Error(), deleteErr3)) {
return true
}
return false
}
func GetAllStoreCategories(vendorOrgCode, vendorStoreId string) ([]*gomei.StoreGoodsCategoryListRecord, error) {
var (
pageNo = 1
pageSize = 50
)
result, err := getAPI(vendorOrgCode).QueryStoreCategoryList(&gomei.QueryStoreGoodsCategoryListReq{
Page: gomei.Page{
PageSize: pageSize,
PageNumber: pageNo,
},
StoreCode: vendorStoreId,
})
if err != nil {
return nil, err
}
createShopCategoryParams := make([]*gomei.StoreGoodsCategoryListRecord, 0, 0)
for ; pageNo <= result.Data.Total/pageSize+1; pageNo++ {
result2, err := getAPI(vendorOrgCode).QueryStoreCategoryList(&gomei.QueryStoreGoodsCategoryListReq{
Page: gomei.Page{
PageNumber: pageNo,
PageSize: pageSize,
},
StoreCode: vendorStoreId,
})
if err != nil {
return nil, err
}
for _, v := range result2.Data.Records {
createShopCategoryParams = append(createShopCategoryParams, &gomei.StoreGoodsCategoryListRecord{
CategoryCode: v.CategoryCode,
CategoryName: v.CategoryName,
Rank: v.Rank,
})
}
}
return createShopCategoryParams, nil
}
// 创建或者修改分类
func updateOrCreateCategories(storeCat *dao.SkuStoreCatInfo, vendorStoreId string, isCreate bool) (createShopCategoryParams []*gomei.StoreGoodsCategoryListRecord, status int64, err error) {
createShopCategoryParams, err = GetAllStoreCategories(storeCat.VendorOrgCode, vendorStoreId)
if err != nil {
return nil, -1, err
}
if isCreate { // 创建分类
_, err = getAPI(storeCat.VendorOrgCode).AddStoreCategory(&gomei.StoreAddGoodsCategory{
StoreCode: vendorStoreId,
CategoryName: storeCat.VendorCategoryName, // storeCat.StoreCatName
Rank: 0,
})
if err != nil {
return nil, -1, err
}
} else { // 修改分类,无法新增和修改排序,排序结构需要在国美系统上获取
// 查询当前分类
for _, v := range createShopCategoryParams {
if v.CategoryCode != storeCat.VendorCatID {
continue
}
_, err = getAPI(storeCat.VendorOrgCode).ModifyStoreGoodsCategory(&gomei.StoreModifyGoodsCategory{
StoreCode: vendorStoreId,
CategoryCode: storeCat.VendorCatID, // storeCat.StoreCatName
CategoryName: storeCat.VendorCategoryName, // storeCat.StoreCatName
Rank: v.Rank,
})
if err != nil {
return nil, -1, err
}
}
}
return
}
// 将平台商品信息转化为本地商品信息
func vendorSku2Jx2(result *gomei.QueryGoodsListForStoreRecordRes) (skuName *partner.SkuNameInfo) {
if result == nil {
globals.SugarLogger.Warnf("vendorSku2Jx, strange result:%s", utils.Format4Output(result, true))
return nil
}
skuName = &partner.SkuNameInfo{
Name: result.GoodsName,
SkuList: []*partner.SkuInfo{
&partner.SkuInfo{
StoreSkuInfo: partner.StoreSkuInfo{
VendorSkuID: result.SkuCode,
Stock: result.StockNum,
VendorPrice: jxutils.StandardPrice2Int(result.SalePrice),
},
},
},
}
if result.ShelveStatus == gomei.PutOnTheShelf {
skuName.Status = 1
} else {
skuName.Status = 0
}
return skuName
}
// 获取当前门店第三方商品id
func getMainStoreVendorSkuID(mainStoreID int, skuID int) (vendorSkuID string, err error) {
var (
db = dao.GetDB()
)
storeSkus, err := dao.GetStoresSkusInfo(db, []int{mainStoreID}, []int{skuID})
if len(storeSkus) > 0 {
//vendorSkuID = storeSkus[0].GmID
}
return vendorSkuID, err
}
// 国美上传图片,转bese64字符串在上传,图片要求长宽和大小
func uploadImg(img, name, index, vendorOrgCode string) (imgURL string, err error) {
data, _, err := jxutils.DownloadFileByURL(img)
if err != nil {
return "", err
}
// 获取图片地址
uploadResult, err := getAPI(vendorOrgCode).UploadPicture(base64.StdEncoding.EncodeToString(data), 1, name+string(time.Now().Unix()))
if err != nil {
return "", err
}
return uploadResult.Data.Url, err
}
func filterSensitiveWord(name string) (result string) {
for _, v := range jdshopapi.SensitiveWordMap {
if strings.Contains(name, v) {
return strings.ReplaceAll(name, v, "")
}
}
return name
}

View File

@@ -3,22 +3,24 @@ 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/baseapi/utils"
"git.rosy.net.cn/jx-callback/business/jxutils"
"git.rosy.net.cn/jx-callback/business/model"
)
// 美团回调接口
func OnCallbackMsg(msg *tiktokShop.CreateOrderCallback) (resp *mtwmapi.CallbackResponse) {
// OnCallbackMsg 抖音
func OnCallbackMsg(msg *tiktokShop.OrderCallback) (response *tiktokShop.CallbackResponse) {
if CurPurchaseHandler != nil {
switch msg.Tag {
case tiktokShop.CallbackMsgTagId:
if msg.Data != "" && len(msg.Body) > 0 {
jxutils.CallMsgHandler(func() {
response = CurPurchaseHandler.onOrderMsg(msg)
}, jxutils.ComposeUniversalOrderID(msg.MsgId, model.VendorIDDD))
}
}
return response
}
func GetOrderIDFromMsg(msg *tiktokShop.CreateOrderCallback) string {
return utils.Int64ToStr(msg.Data.PId)
func GetOrderIDFromMsg(msg *mtwmapi.CallbackMsg) string {
return msg.FormData.Get(mtwmapi.KeyOrderID)
}
func GetVendorStoreIDFromMsg(msg *mtwmapi.CallbackMsg) string {

View File

@@ -0,0 +1,54 @@
package tiktok_store
import (
"fmt"
"net/url"
"testing"
"time"
"git.rosy.net.cn/baseapi/platformapi/mtwmapi"
"git.rosy.net.cn/baseapi/utils"
"git.rosy.net.cn/jx-callback/business/partner"
)
func TestOnFinancialMsg(t *testing.T) {
msg := &mtwmapi.CallbackMsg{
Cmd: "orderRefund",
FormData: url.Values{},
}
msg.FormData.Set("timestamp", utils.Int64ToStr(time.Now().Unix()))
msg.FormData.Set("order_id", "33762863167364867")
msg.FormData.Set("notify_type", "agree")
msg.FormData.Set("money", "23.56")
food := []map[string]interface{}{
map[string]interface{}{
"app_food_code": "123",
"food_name": "商品1",
"sku_id": "123",
"refund_price": 3.14,
"count": 2,
"box_num": 1,
"box_price": 1,
},
map[string]interface{}{
"app_food_code": "124",
"food_name": "商品2",
"sku_id": "124",
"refund_price": 3.15,
"count": 2,
"box_num": 1,
"box_price": 1,
},
}
msg.FormData.Set("food", string(utils.MustMarshal(food)))
res := CurPurchaseHandler.onAfsOrderMsg(msg)
fmt.Println(res)
}
func TestOnOrderDetail(t *testing.T) {
result := map[string]interface{}{
"app_order_code": "", "app_poi_code": "2828472", "avg_send_time": 2410, "backup_recipient_phone": "[\"13164714130_7645\"]", "caution": " 【如遇缺货】: 缺货时电话与我沟通 收餐人隐私号 13049813276_5307手机号 139****5027", "city_id": 440300, "ctime": 1555036346, "day_seq": 1, "delivery_time": 0, "detail": "[{\"app_food_code\":\"27262\",\"box_num\":0,\"box_price\":0,\"cart_id\":0,\"food_discount\":1,\"food_name\":\"红管鱿鱼约250g/份\",\"food_property\":\"\",\"price\":23.54,\"quantity\":1,\"sku_id\":\"27262\",\"spec\":\"250g\",\"unit\":\"份\"},{\"app_food_code\":\"24987\",\"box_num\":0,\"box_price\":0,\"cart_id\":0,\"food_discount\":1,\"food_name\":\"带皮猪梅花肉约250g/份\",\"food_property\":\"\",\"price\":15.84,\"quantity\":1,\"sku_id\":\"24987\",\"spec\":\"250g\",\"unit\":\"份\"},{\"app_food_code\":\"27179\",\"box_num\":0,\"box_price\":0,\"cart_id\":0,\"food_discount\":1,\"food_name\":\"[畅销]龙骨约250g/份\",\"food_property\":\"\",\"price\":18.59,\"quantity\":1,\"sku_id\":\"27179\",\"spec\":\"250g\",\"unit\":\"份\"}]", "dinners_number": 0, "expect_deliver_time": 0, "extras": "[{\"act_detail_id\":664795195,\"mt_charge\":0,\"poi_charge\":5,\"reduce_fee\":5,\"remark\":\"满46.0元减5.0元\",\"type\":2},{\"act_detail_id\":665051798,\"mt_charge\":0,\"poi_charge\":4,\"reduce_fee\":4,\"remark\":\"减配送费4.0元\",\"type\":25},{\"act_detail_id\":274839715,\"mt_charge\":0.5,\"poi_charge\":0,\"reduce_fee\":0.5,\"remark\":\"用户使用了支付红包减0.5元\",\"type\":9},{\"mt_charge\":0,\"poi_charge\":0,\"reduce_fee\":0,\"remark\":\"送30元商家代金券\",\"type\":100},{}]", "has_invoiced": 0, "invoice_title": "", "is_favorites": false, "is_poi_first_order": true, "is_pre": 0, "is_third_shipping": 0, "latitude": 22.530194, "logistics_code": "1001", "longitude": 114.08372, "order_id": 28284722536001020, "order_send_time": 1555036356, "original_price": 63.97, "package_bag_money": 0, "pay_type": 2, "pick_type": 0, "poi_receive_detail": "{\"actOrderChargeByMt\":[{\"comment\":\"活动款\",\"feeTypeDesc\":\"活动款\",\"feeTypeId\":10019,\"moneyCent\":50}],\"actOrderChargeByPoi\":[{\"comment\":\"满46.0元减5.0元\",\"feeTypeDesc\":\"活动款\",\"feeTypeId\":10019,\"moneyCent\":500},{\"comment\":\"减配送费4.0元\",\"feeTypeDesc\":\"活动款\",\"feeTypeId\":10019,\"moneyCent\":400}],\"foodShareFeeChargeByPoi\":490,\"logisticsFee\":600,\"onlinePayment\":5447,\"wmPoiReceiveCent\":4406}", "recipient_address": "汇港名苑 (南2区1005)@#广东省深圳市福田区滨河大道滨河大道3119号汇港名苑", "recipient_name": "颜(女士)", "recipient_phone": "13049813276_5307", "remark": "", "result": "ok", "shipper_phone": "", "shipping_fee": 6, "shipping_type": 0, "source_id": 3, "status": 2, "taxpayer_id": "", "total": 54.47, "utime": 1555036346, "wm_order_id_view": 28284722536001020, "wm_poi_address": "深圳市福田区南园街道南华社区滨河路2037号下小庙南区70栋101号滨河街市场", "wm_poi_id": 2828472, "wm_poi_name": "京西菜市(华强南店)", "wm_poi_phone": "13724313878",
}
err := new(PurchaseHandler).OnOrderDetail(result, partner.CreatedPeration)
fmt.Println(err)
}

View File

@@ -1,267 +0,0 @@
package tiktok_store
import (
"git.rosy.net.cn/jx-callback/business/jxutils/jxcontext"
"git.rosy.net.cn/jx-callback/business/jxutils/tasksch"
"git.rosy.net.cn/jx-callback/business/model"
"git.rosy.net.cn/jx-callback/business/model/dao"
"git.rosy.net.cn/jx-callback/business/partner"
"regexp"
"time"
)
func (c *PurchaseHandler) GetStoreSkusBatchSize(funcID int) int { return 0 }
func (c *PurchaseHandler) ListOrders(ctx *jxcontext.Context, vendorOrgCode string, parentTask tasksch.ITask, queryDate time.Time, vendorStoreID string) (vendorOrderIDs []string, err error) {
return nil, err
}
// 此接口要求实现为不限制批处理大小的
func (c *PurchaseHandler) GetStoreSkusBareInfo(ctx *jxcontext.Context, vendorOrgCode string, parentTask tasksch.ITask, storeID int, vendorStoreID string, inStoreSkuList []*partner.StoreSkuInfo) (outStoreSkuList []*partner.StoreSkuInfo, err error) {
return nil, err
}
func (c *PurchaseHandler) UpdateStoreSkusStock(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, storeSkuList []*partner.StoreSkuInfo) (failedList []*partner.StoreSkuInfoWithErr, err error) {
return nil, err
}
func (c *PurchaseHandler) UpdateStoreSkusStatus(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, storeSkuList []*partner.StoreSkuInfo, status int) (failedList []*partner.StoreSkuInfoWithErr, err error) {
return nil, err
}
func (c *PurchaseHandler) UpdateStoreSkusPrice(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, storeSkuList []*partner.StoreSkuInfo) (failedList []*partner.StoreSkuInfoWithErr, err error) {
return nil, err
}
func (c *PurchaseHandler) CreateStoreSkusAct(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, storeSkuList []*partner.StoreSkuInfo) (failedList []*partner.StoreSkuInfoWithErr, err error) {
return nil, err
}
func (c *PurchaseHandler) CancelActs(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, storeSkuList []*partner.StoreSkuInfo) (failedList []*partner.StoreSkuInfoWithErr, err error) {
return nil, err
}
func (c *PurchaseHandler) UpdateStoreSkusSpecTag(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, storeSkuList []*partner.StoreSkuInfo) (err error) {
return err
}
func (c *PurchaseHandler) GetStoreSkusFullInfo(ctx *jxcontext.Context, parentTask tasksch.ITask, storeID int, vendorStoreID string, storeSkuList []*partner.StoreSkuInfo) (outSkuNameList []*partner.SkuNameInfo, err error) {
return nil, err
}
func (c *PurchaseHandler) CreateStoreSkus(ctx *jxcontext.Context, storeID int, vendorStoreID string, storeSkuList []*dao.StoreSkuSyncInfo) (failedList []*partner.StoreSkuInfoWithErr, err error) {
return nil, err
}
func (c *PurchaseHandler) UpdateStoreSkus(ctx *jxcontext.Context, storeID int, vendorStoreID string, storeSkuList []*dao.StoreSkuSyncInfo) (failedList []*partner.StoreSkuInfoWithErr, err error) {
return nil, err
}
func (c *PurchaseHandler) DeleteStoreSkus(ctx *jxcontext.Context, storeID int, vendorStoreID string, storeSkuList []*partner.StoreSkuInfo) (failedList []*partner.StoreSkuInfoWithErr, err error) {
return nil, err
}
func (c *PurchaseHandler) DeleteStoreAllSkus(ctx *jxcontext.Context, parentTask tasksch.ITask, storeID int, vendorStoreID string, isContinueWhenError bool) (err error) {
return err
}
func (c *PurchaseHandler) IsErrSkuExist(err error) (isExist bool) { return true }
func (c *PurchaseHandler) IsErrSkuNotExist(err error) (isNotExist bool) { return true }
func (c *PurchaseHandler) GetStoreAllCategories(ctx *jxcontext.Context, storeID int, vendorStoreID string) (cats []*partner.BareCategoryInfo, err error) {
return nil, err
}
func (c *PurchaseHandler) GetStoreCategory(ctx *jxcontext.Context, storeID int, vendorStoreID, catName string) (cat *partner.BareCategoryInfo, err error) {
return nil, err
}
func (c *PurchaseHandler) CreateStoreCategory(ctx *jxcontext.Context, storeID int, vendorStoreID string, storeCat *dao.SkuStoreCatInfo) (err error) {
return err
}
func (c *PurchaseHandler) UpdateStoreCategory(ctx *jxcontext.Context, storeID int, vendorStoreID string, storeCat *dao.SkuStoreCatInfo) (err error) {
return err
}
func (c *PurchaseHandler) DeleteStoreCategory(ctx *jxcontext.Context, storeID int, vendorStoreID, vendorCatID string, level int) (err error) {
return err
}
func (c *PurchaseHandler) DeleteStoreAllCategories(ctx *jxcontext.Context, parentTask tasksch.ITask, storeID int, vendorStoreID string, isContinueWhenError bool) (err error) {
return err
}
func (c *PurchaseHandler) IsErrCategoryExist(err error) (isExist bool) { return true }
func (c *PurchaseHandler) IsErrCategoryNotExist(err error) (isNotExist bool) { return true }
func (c *PurchaseHandler) GetSensitiveWordRegexp() *regexp.Regexp { return nil }
func (c *PurchaseHandler) Map2Order(orderData map[string]interface{}) (order *model.GoodsOrder) {
//TODO implement me
panic("implement me")
}
func (c *PurchaseHandler) GetOrder(vendorOrgCode, vendorOrderID, vendorStoreID string) (order *model.GoodsOrder, err error) {
//TODO implement me
panic("implement me")
}
func (c *PurchaseHandler) GetOrderStatus(vendorOrgCode, vendorOrderID string) (status int, err error) {
//TODO implement me
panic("implement me")
}
func (c *PurchaseHandler) AcceptOrRefuseOrder(order *model.GoodsOrder, isAcceptIt bool, userName string) (err error) {
//TODO implement me
panic("implement me")
}
func (c *PurchaseHandler) PickupGoods(order *model.GoodsOrder, isSelfDelivery bool, userName string) (err error) {
//TODO implement me
panic("implement me")
}
func (c *PurchaseHandler) AcceptOrRefuseFailedGetOrder(ctx *jxcontext.Context, order *model.GoodsOrder, isAcceptIt bool) (err error) {
//TODO implement me
panic("implement me")
}
func (c *PurchaseHandler) CallCourier(ctx *jxcontext.Context, order *model.GoodsOrder) (err error) {
//TODO implement me
panic("implement me")
}
func (c *PurchaseHandler) ConfirmReceiveGoods(ctx *jxcontext.Context, order *model.GoodsOrder) (err error) {
//TODO implement me
panic("implement me")
}
func (c *PurchaseHandler) Swtich2SelfDeliver(order *model.GoodsOrder, userName string) (err error) {
//TODO implement me
panic("implement me")
}
func (c *PurchaseHandler) Swtich2SelfDelivered(order *model.GoodsOrder, userName string) (err error) {
//TODO implement me
panic("implement me")
}
func (c *PurchaseHandler) SelfDeliverDelivering(order *model.GoodsOrder, userName string) (err error) {
//TODO implement me
panic("implement me")
}
func (c *PurchaseHandler) GetCancelDeliveryReason(order *model.GoodsOrder) (string, error) {
//TODO implement me
panic("implement me")
}
func (c *PurchaseHandler) CancelLogisticsByWmOrderId(order *model.GoodsOrder, reasonCode, detailContent, appPoiCode, orderId string) error {
//TODO implement me
panic("implement me")
}
func (c *PurchaseHandler) OrderLogisticsStatus(orderId int64) (int64, error) {
//TODO implement me
panic("implement me")
}
func (c *PurchaseHandler) SelfDeliverDelivered(order *model.GoodsOrder, userName string) (err error) {
//TODO implement me
panic("implement me")
}
func (c *PurchaseHandler) GetOrderRealMobile(ctx *jxcontext.Context, order *model.GoodsOrder) (mobile string, err error) {
//TODO implement me
panic("implement me")
}
func (c *PurchaseHandler) ReplyOrderComment(ctx *jxcontext.Context, vendorOrgCode string, orderComment *model.OrderComment, replyComment string) (err error) {
//TODO implement me
panic("implement me")
}
func (c *PurchaseHandler) AgreeOrRefuseCancel(ctx *jxcontext.Context, order *model.GoodsOrder, isAgree bool, reason string) (err error) {
//TODO implement me
panic("implement me")
}
func (c *PurchaseHandler) CancelOrder(ctx *jxcontext.Context, order *model.GoodsOrder, reason string) (err error) {
//TODO implement me
panic("implement me")
}
func (c *PurchaseHandler) AdjustOrder(ctx *jxcontext.Context, order *model.GoodsOrder, removedSkuList []*model.OrderSku, reason string) (err error) {
//TODO implement me
panic("implement me")
}
func (c *PurchaseHandler) RefundOrder(ctx *jxcontext.Context, order *model.GoodsOrder, reason string) (err error) {
//TODO implement me
panic("implement me")
}
func (c *PurchaseHandler) PartRefundOrder(ctx *jxcontext.Context, order *model.GoodsOrder, refundSkuList []*model.OrderSku, reason string) (err error) {
//TODO implement me
panic("implement me")
}
func (c *PurchaseHandler) AgreeOrRefuseRefund(ctx *jxcontext.Context, order *model.AfsOrder, approveType int, reason string) (err error) {
//TODO implement me
panic("implement me")
}
func (c *PurchaseHandler) ConfirmReceivedReturnGoods(ctx *jxcontext.Context, order *model.AfsOrder) (err error) {
//TODO implement me
panic("implement me")
}
func (c *PurchaseHandler) GetSelfTakeCode(ctx *jxcontext.Context, order *model.GoodsOrder) (code string, err error) {
//TODO implement me
panic("implement me")
}
func (c *PurchaseHandler) ConfirmSelfTake(ctx *jxcontext.Context, order *model.GoodsOrder, selfTakeCode string) (err error) {
//TODO implement me
panic("implement me")
}
func (c *PurchaseHandler) GetOrderAfsInfo(ctx *jxcontext.Context, vendorOrderID, afsOrderID string) (orderAfsInfo *partner.OrderAfsInfo, err error) {
//TODO implement me
panic("implement me")
}
func (c *PurchaseHandler) ComplaintRider(vendorOrderId string, resonID int, resonContent string) (err error) {
//TODO implement me
panic("implement me")
}
func (c *PurchaseHandler) GetOrderRider(vendorOrgCode, vendorStoreID string, param map[string]interface{}) (err error) {
//TODO implement me
panic("implement me")
}
func (c *PurchaseHandler) ReadStore(ctx *jxcontext.Context, vendorOrgCode, vendorStoreID, vendorStoreName string) (store *dao.StoreDetail, err error) {
//TODO implement me
panic("implement me")
}
func (c *PurchaseHandler) UpdateStore(db *dao.DaoDB, storeID int, userName string) (err error) {
//TODO implement me
panic("implement me")
}
func (c *PurchaseHandler) CreateStore2(db *dao.DaoDB, storeID int, userName string, params map[string]interface{}, storeDetail *dao.StoreDetail) (vendorStoreID string, err error) {
//TODO implement me
panic("implement me")
}
func (c *PurchaseHandler) DeleteStore(db *dao.DaoDB, storeID int, userName string) (err error) {
//TODO implement me
panic("implement me")
}
func (c *PurchaseHandler) GetStoreStatus(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string) (storeStatus int, err error) {
//TODO implement me
panic("implement me")
}
func (c *PurchaseHandler) UpdateStoreCustomID(ctx *jxcontext.Context, vendorOrgCode, vendorStoreID string, storeID int64) (err error) {
//TODO implement me
panic("implement me")
}
func (c *PurchaseHandler) RefreshAllStoresID(ctx *jxcontext.Context, parentTask tasksch.ITask, isAsync bool) (hint string, err error) {
//TODO implement me
panic("implement me")
}
func (c *PurchaseHandler) UpdateStoreLineStatus(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, lineStatus int) (err error) {
//TODO implement me
panic("implement me")
}

View File

@@ -44,7 +44,7 @@ func New() (obj *PurchaseHandler) {
}
func (c *PurchaseHandler) GetVendorID() int {
return model.VendorIDDD
return model.VendorIDMTWM
}
func (p *PurchaseHandler) GetVendorCategories(ctx *jxcontext.Context) (vendorCats []*model.SkuVendorCategory, err error) {

View File

@@ -0,0 +1,50 @@
package tiktok_store
//import (
// "git.rosy.net.cn/jx-callback/business/model"
// "git.rosy.net.cn/jx-callback/business/model/dao"
// "testing"
// "time"
//
// "git.rosy.net.cn/jx-callback/business/jxutils/jxcontext"
//
// "git.rosy.net.cn/baseapi/utils"
// _ "git.rosy.net.cn/jx-callback/business/jxcallback/orderman"
// "git.rosy.net.cn/jx-callback/globals/testinit"
//)
//
//const (
// testShopVendorID = "2523687"
// testShopID = 2
//)
//
//func init() {
// testinit.Init()
//}
//
//// 获取平台分类属性(三级分类标签)
//func TestGetVendorCategories(t *testing.T) {
// result, err := new(PurchaseHandler).GetVendorCategories(jxcontext.AdminCtx)
// if err != nil {
// t.Fatal(err)
// }
// for _, v := range result {
// data := model.SkuVendorCategory{
// ModelIDCUL: model.ModelIDCUL{
// CreatedAt: time.Now(),
// UpdatedAt: time.Now(),
// LastOperator: "刘磊",
// },
// VendorCategoryID: v.VendorCategoryID,
// VendorID: v.VendorID,
// Name: v.Name,
// IsLeaf: v.IsLeaf,
// Level: v.Level,
// ParentID: v.ParentID,
// }
// if err := dao.CreateEntity(dao.GetDB(), &data); err != nil {
// t.Log(utils.Format4Output(err, false))
// }
// }
// t.Log(utils.Format4Output(result, false))
//}

View File

@@ -1,87 +1,404 @@
package tiktok_store
import (
"git.rosy.net.cn/baseapi/platformapi/ebaiapi"
"git.rosy.net.cn/baseapi/platformapi/mtwmapi"
"errors"
"fmt"
tiktokShop "git.rosy.net.cn/baseapi/platformapi/tiktok_shop/tiktok_api"
"math"
"net/url"
"regexp"
"strings"
"time"
"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/jxutils/tasksch"
"git.rosy.net.cn/jx-callback/business/model"
"git.rosy.net.cn/jx-callback/business/model/dao"
"git.rosy.net.cn/jx-callback/business/partner"
"git.rosy.net.cn/jx-callback/globals"
)
func (c *PurchaseHandler) onOrderMsg(msg *tiktokShop.CreateOrderCallback) (response *mtwmapi.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
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"
)
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,
}
if msg.Cmd == mtwmapi.MsgTypeNewOrder { // 新订单
order, orderMap, err2 := c.getOrder(msg.AppID, GetOrderIDFromMsg(msg), GetVendorStoreIDFromMsg(msg))
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)
}
})
skuActTypeMap = map[int]int{
mtwmapi.ExtrasPromotionTypeTeJiaCai: 1,
mtwmapi.ExtrasPromotionTypeZheKouCai: 1,
mtwmapi.ExtrasPromotionTypeSecondHalfPrice: 1,
}
)
func (p *PurchaseHandler) getStatusFromVendorStatus(vendorStatus string) int {
if status, ok := VendorStatus2StatusMap[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)
}
return order, result, err
}
func (p *PurchaseHandler) getOrderRider(vendorOrgCode, vendorStoreID string, param map[string]interface{}) (err error) {
return getAPI(vendorOrgCode, 0, vendorStoreID).OrderStatusAndPsInfo(param)
}
func (p *PurchaseHandler) GetOrderRider(vendorOrgCode, vendorStoreID string, param map[string]interface{}) (err error) {
return p.getOrderRider(vendorOrgCode, vendorStoreID, param)
}
func (p *PurchaseHandler) GetOrder(vendorOrgCode, vendorOrderID, vendorStoreID string) (order *model.GoodsOrder, err error) {
order, _, err = p.getOrder(vendorOrgCode, vendorOrderID, vendorStoreID)
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) 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]),
}
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
}
}
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 {
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,
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)
}
}
return weight
}
func (c *PurchaseHandler) onOrderMsg(msg *tiktokShop.OrderCallback) (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 msg.Cmd == mtwmapi.MsgTypeNewOrder {
order, orderMap, err2 := c.getOrder(msg.AppID, GetOrderIDFromMsg(msg), GetVendorStoreIDFromMsg(msg))
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)
}
})
}
}
} 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)
}
})
}
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)
}
})
}
}
}
}
}
}
//}
return mtwmapi.Err2CallbackResponse(err, "")
}
func (c *PurchaseHandler) callbackMsg2Status(msg *tiktokShop.CreateOrderCallback) (orderStatus *model.OrderStatus) {
func (c *PurchaseHandler) callbackMsg2Status(msg *mtwmapi.CallbackMsg) (orderStatus *model.OrderStatus) {
orderID := GetOrderIDFromMsg(msg)
vendorStatus := msg.Cmd
remark := ""
@@ -148,52 +465,386 @@ func (c *PurchaseHandler) callbackMsg2Status(msg *tiktokShop.CreateOrderCallback
return orderStatus
}
func (c *PurchaseHandler) callbackMsg2Status(msg *tiktokShop.CreateOrderCallback) (orderStatus *model.OrderStatus) {
orderID := GetOrderIDFromMsg(msg)
orderStatus = &model.OrderStatus{
VendorOrderID: orderID,
VendorID: model.VendorIDDD,
OrderType: model.OrderTypeOrder,
RefVendorOrderID: orderID,
RefVendorID: model.VendorIDDD,
StatusTime: utils.Timestamp2Time(msg.Timestamp),
VendorStatus: msg.Cmd,
func (c *PurchaseHandler) postFakeMsg(vendorOrderID, cmd, vendorStatus string) {
msg := &mtwmapi.CallbackMsg{
Cmd: cmd,
FormData: make(url.Values),
}
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 msgType == ebaiapi.OrderUserCancelApply /* || msgType == ebaiapi.OrderUserCancelCSIntervene */ {
orderStatus.Status = model.OrderStatusApplyCancel
} else if msgType == ebaiapi.OrderUserCancelCSRefused ||
msgType == ebaiapi.OrderUserCancelMerchantRefused {
orderStatus.Status = model.OrderStatusVendorRejectCancel
} else if msgType == ebaiapi.OrderUserCancelInvalid {
orderStatus.Status = model.OrderStatusUndoApplyCancel
} else if msgType == ebaiapi.OrderUserCancelCSAgreed ||
msgType == ebaiapi.OrderUserCancelMerchantAgreed {
orderStatus.Status = model.OrderStatusVendorAgreeCancel
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)
utils.CallFuncAsync(func() {
c.onOrderMsg(msg)
})
}
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)
}
}
}
} else if msg.Cmd == ebaiapi.CmdOrderPartRefund {
msgType := int(utils.MustInterface2Int64(msg.Body["type"]))
status := int(utils.MustInterface2Int64(msg.Body["status"]))
orderStatus.Remark = buildFullReason(utils.Interface2String(msg.Body["reason"]), utils.Interface2String(msg.Body["addition_reason"]))
if msgType == ebaiapi.OrderPartRefuncTypeMerchant && status == ebaiapi.OrderPartRefundSuccess {
orderStatus.VendorStatus = fakeOrderAdjustFinished
// if err == nil {
// c.postFakeMsg(order.VendorOrderID, FakeMsgType, mtwmapi.OrderStatusReceived)
// }
} else {
if globals.EnableMtwmStoreWrite {
err = c.CancelOrder(jxcontext.AdminCtx, order, "bu")
}
} else if status, ok := msg.Body["status"]; ok {
if vendorStatus, ok := status.(string); ok {
orderStatus.VendorStatus = vendorStatus
} else {
orderStatus.VendorStatus = utils.Int64ToStr(utils.MustInterface2Int64(status))
}
orderStatus.Remark = utils.Interface2String(msg.Body["reason"])
}
if orderStatus.Status == 0 {
orderStatus.Status = c.getStatusFromVendorStatus(orderStatus.VendorStatus)
}
return orderStatus
return err
}
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
}
func (p *PurchaseHandler) AcceptOrRefuseFailedGetOrder(ctx *jxcontext.Context, order *model.GoodsOrder, isAcceptIt bool) (err error) {
return err
}
func (p *PurchaseHandler) CallCourier(ctx *jxcontext.Context, order *model.GoodsOrder) (err error) { // 拣货失败后再次招唤平台配送
return err
}
func (p *PurchaseHandler) ConfirmReceiveGoods(ctx *jxcontext.Context, order *model.GoodsOrder) (err error) { // 投递失败后确认收到退货
return err
}
// 美团预定单不能转商家自送
func (c *PurchaseHandler) CanSwitch2SelfDeliver(order *model.GoodsOrder) (isCan bool, err error) {
return order.BusinessType != model.BusinessTypeDingshida, nil
}
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))
}
return err
}
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":"只允许商家配送调用该接口"}}
// err = api.MtwmAPI.OrderArrived(utils.Str2Int64(order.VendorOrderID))
}
return err
}
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))
}
return err
}
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))
}
return err
}
func getTimeFromTimestamp(timeStamp int64) time.Time {
if timeStamp < 1538103149 { // 立即达订单给的是1而不是空01538103149不是特殊值只是一个任意之前的时间这样写可以处理
return utils.DefaultTimeValue
}
return utils.Timestamp2Time(timeStamp)
}
func (c *PurchaseHandler) GetOrderRealMobile(ctx *jxcontext.Context, order *model.GoodsOrder) (mobile string, err error) {
err = errors.New("美团外卖还未实现GetOrderRealMobile")
return mobile, err
}
func (c *PurchaseHandler) AgreeOrRefuseCancel(ctx *jxcontext.Context, order *model.GoodsOrder, isAgree bool, reason string) (err error) {
if globals.EnableMtwmStoreWrite {
if isAgree {
err = getAPI(order.VendorOrgCode, jxutils.GetSaleStoreIDFromOrder(order), "").OrderRefundAgree(utils.Str2Int64(order.VendorOrderID), reason)
} else {
err = getAPI(order.VendorOrgCode, jxutils.GetSaleStoreIDFromOrder(order), "").OrderRefundReject(utils.Str2Int64(order.VendorOrderID), reason)
}
}
return err
}
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)
}
}
return err
}
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 == 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)
}
}
return err
}
func (c *PurchaseHandler) ListOrders(ctx *jxcontext.Context, vendorOrgCode string, parentTask tasksch.ITask, queryDate time.Time, vendorStoreID string) (vendorOrderIDs []string, err error) {
if utils.IsTimeZero(queryDate) {
return nil, fmt.Errorf("queryDate必须指定")
}
queryDate = utils.Time2Date(queryDate)
var vendorStoreIDs []string
if vendorStoreID == "" {
vendorStoreIDs, err = c.GetAllStoresVendorID(ctx, vendorOrgCode)
if err != nil {
return nil, err
}
} else {
vendorStoreIDs = []string{vendorStoreID}
}
task := tasksch.NewParallelTask("mtwm 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++
}
retVal = orderIDs
return retVal, nil
}, vendorStoreIDs)
tasksch.HandleTask(task, parentTask, true).Run()
orderList, err := task.GetResult(0)
if err == nil && len(orderList) > 0 {
vendorOrderIDs = make([]string, len(orderList))
for k, v := range orderList {
vendorOrderIDs[k] = v.(string)
}
}
return vendorOrderIDs, err
}
// func (c *PurchaseHandler) UpdateWaybillTip(ctx *jxcontext.Context, order *model.GoodsOrder, tipFee int64) (err error) {
// if globals.EnableMtwmStoreWrite {
// err = api.MtwmAPI.OrderUpdateTip(utils.Str2Int64(order.VendorOrderID), jxutils.IntPrice2Standard(tipFee))
// }
// return err
// }
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
}
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
}
}
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()
return response
}
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
}
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))
}
return err
}
func (c *PurchaseHandler) GetSelfTakeCode(ctx *jxcontext.Context, order *model.GoodsOrder) (selfTakeCode string, err error) {
return selfTakeCode, err
}
func (c *PurchaseHandler) ConfirmSelfTake(ctx *jxcontext.Context, order *model.GoodsOrder, selfTakeCode string) (err error) {
return err
}
func (c *PurchaseHandler) ComplaintRider(vendorOrderId string, resonID int, resonContent string) (err error) {
return err
}
// 转自配送时取消非专送混合送门店取消理由
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
}
// 取消美团外卖理由转使用三方配送
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)
}
// 获取订单配送状态
func (c *PurchaseHandler) OrderLogisticsStatus(orderId int64) (int64, error) {
return 0, nil
}

View File

@@ -0,0 +1,449 @@
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"
)
var (
AfsVendorStatus2StatusMap = map[string]int{
tiktokShop.CallbackRefundOrderMsgTagId: model.AfsOrderStatusWait4Approve, // 发起售后申请待审核
tiktokShop.CallbackUpdateRefundOrderMsgTagId: model.AfsOrderStatusWait4Approve, // 修改售后待审核
tiktokShop.CallbackRefundOrderSuccessMsgTagId: model.AfsOrderStatusFinished, // 退款成功
tiktokShop.CallbackRefundOrderRefuseMsgTagId: model.AfsOrderStatusFailed, // 拒绝退款
tiktokShop.CallbackRefundShopMsgTagId: model.AfsOrderStatusFailed, // 拒绝退货
tiktokShop.CallbackReturnApplyAgreedMsgTagId: model.AfsOrderStatusFinished, // 同意退货
tiktokShop.CallbackReturnRefundAgreedMsgTagId: model.AfsOrderStatusFinished, // 同意退款
}
AfsTagIDMap = map[string]string{
tiktokShop.CallbackRefundOrderMsgTagId: "1",
tiktokShop.CallbackUpdateRefundOrderMsgTagId: "1",
tiktokShop.CallbackRefundOrderSuccessMsgTagId: "1",
tiktokShop.CallbackRefundOrderRefuseMsgTagId: "1",
tiktokShop.CallbackRefundShopMsgTagId: "1",
tiktokShop.CallbackReturnApplyAgreedMsgTagId: "1",
tiktokShop.CallbackReturnRefundAgreedMsgTagId: "1",
tiktokShop.CallbackExchangeComfirmedMsgTagId: "1",
tiktokShop.CallbackArbitrateDiscussUploadMsgTagId: "1",
tiktokShop.CallbackArbitrateServiceInterveneMsgTagId: "1",
tiktokShop.CallbackArbitrateCancelledMsgTagId: "1",
tiktokShop.CallbackArbitrateAuditedMsgTagId: "1",
tiktokShop.CallbackArbitrateSubmitedMsgTagId: "1",
tiktokShop.CallbackArbitrateSubmitingMsgTagId: "1",
tiktokShop.CallbackArbitrateAppliedMsgTagId: "1",
tiktokShop.CallbackExpirationChangeMsgTagId: "1",
tiktokShop.CallbackRefundClosedMsgTagId: "1",
tiktokShop.CallbackBuyerReturnGoodsMsgTagId: "1",
tiktokShop.CallbackSpecialRefundMsgTagId: "1",
tiktokShop.CallbackSpecialRefundSuccessMsgTagId: "1",
tiktokShop.CallbackAuditAgreeResendMsgTagId: "1",
tiktokShop.CallbackResendFillLogisticsMsgTagId: "1",
}
// ReasonCodeMap 申请退货理由,可能会更新
ReasonCodeMap = map[int]string{
1: "商品已发出,如买家不再需要请拒收后申请仅退款或收到后申请退货退款",
2: "商品已经签收,如买家不再需要可以申请退货退款",
3: "买家误操作/取消申请",
4: "问题已解决,待用户收货",
5: "商品已发出,如买家不再需要请拒收后申请仅退款或收到后申请退货退款",
6: "买家误操作/取消申请",
7: "协商一致,用户取消退款",
8: "已与买家协商补偿,包括差价、赠品、额外补偿",
9: "已与买家协商补发商品",
10: "已与买家协商换货",
11: "买家上传的单号有误,商家尚未收到货,请核实正确物流单号后重新上传",
12: "退货与原订单不符(商品不符、退货地址不符)",
13: "退回商品影响二次销售",
14: "买家误操作/取消申请",
15: "协商一致,用户取消退款",
16: "买家误操作/取消申请",
17: "协商一致,用户取消退款",
18: "商品影响二次销售",
19: "定制商品不支持七天无理由退货,定制商品不接受质量问题以外的退货",
20: "定制商品不支持七天无理由退货,定制商品不接受质量问题以外的退货",
21: "买家申请的金额有误",
22: "运费未协商一致",
23: "商品没问题,买家未举证或凭证无效",
24: "已在约定时间发货",
25: "运费未协商一致",
26: "商品已经签收,如买家不再需要可以申请退货退款",
27: "商品没问题,买家未举证或举证无效",
28: "已在约定时间发货",
29: "买家申请的金额有误",
30: "发票没问题,买家未举证",
31: "发票已补寄",
32: "买家发票信息不完整",
33: "运费未协商一致",
34: "申请时间已超7天无理由退换货时间",
35: "不支持买家主观原因退换货",
36: "买家填错号码",
37: "已完成服务,买家未提供凭证或凭证无效",
38: "买家填错号码",
39: "已完成服务,买家未提供凭证或凭证无效",
40: "和达人达成一致,取消终止",
41: "其他",
42: "其他",
43: "未收到货/退货单号有误",
44: "退货与原订单不符(商品不符、退货地址不符)",
45: "商家已发货",
46: "商品已经签收,如买家不再需要可以申请退货退款",
47: "已与买家协商一致仅退款",
48: "问题已解决,待用户确认收货",
49: "已与买家协商一致延迟发货",
50: "未少发漏发",
51: "已与买家协商补偿,包括差价、赠品、额外补偿",
52: "已与买家协商一致延迟发货",
53: "其他",
54: "本单已购买【养死包赔】保险,请从保险理赔入口申请理赔",
55: "本单已购买【开箱无忧】保险,请从保险理赔入口申请理赔",
56: "商品没问题,买家未举证或举证无效",
57: "已完成服务,买家未举证或举证无效",
58: "本单已购买【食安保】保险,请从保险理赔入口申请理赔",
}
)
// 是否为售后消息
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
}
// 审核售后单申请
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)
} else {
err = getAPI(order.VendorOrgCode, jxutils.GetSaleStoreIDFromAfsOrder(order), order.VendorStoreID).OrderRefundAgree(utils.Str2Int64(order.VendorOrderID), reason)
}
}
return err
}
// 确认收到退货
func (c *PurchaseHandler) ConfirmReceivedReturnGoods(ctx *jxcontext.Context, order *model.AfsOrder) (err error) {
err = fmt.Errorf("内部错误,美团外卖平台不支持确认收到退货操作")
return err
}
// 发起全款退款
func (c *PurchaseHandler) RefundOrder(ctx *jxcontext.Context, order *model.GoodsOrder, reason string) (err error) {
return fmt.Errorf("%s不支持售后全额退款请让买家发起退款", model.VendorChineseNames[model.VendorIDMTWM])
}
// 发起部分退款
func (c *PurchaseHandler) PartRefundOrder(ctx *jxcontext.Context, order *model.GoodsOrder, refundSkuList []*model.OrderSku, reason string) (err error) {
return c.AdjustOrder(ctx, order, refundSkuList, reason)
}
func (c *PurchaseHandler) GetOrderAfsInfo(ctx *jxcontext.Context, vendorOrderID, afsOrderID string) (orderAfsInfo *partner.OrderAfsInfo, err error) {
orderAfsInfo = &partner.OrderAfsInfo{}
var afsTotalShopMoney int64
if list, err := api.MtwmAPI.GetOrderRefundDetail(utils.Str2Int64(vendorOrderID), 0); err == nil {
for _, v := range list {
if v.RefundPartialEstimateCharge.SettleAmount != "" {
afsTotalShopMoney += jxutils.StandardPrice2Int(utils.Str2Float64(v.RefundPartialEstimateCharge.SettleAmount))
}
}
}
if order, err := partner.CurOrderManager.LoadOrder(vendorOrderID, model.VendorIDMTWM); err == nil {
orderAfsInfo.AfsTotalShopMoney = order.TotalShopMoney + afsTotalShopMoney
}
return orderAfsInfo, err
}

View File

@@ -0,0 +1,113 @@
package tiktok_store
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 (
RefreshCommentTime = 7 * 24 * time.Hour // 此值必须大于24小时
RefreshCommentTimeInterval = 60 * time.Minute
BAD_COMMENTS_MAX_MODIFY_TIME = 24 * 6 // 小时
)
func (c *PurchaseHandler) StartRefreshComment() {
utils.AfterFuncWithRecover(5*time.Second, func() {
c.refreshCommentOnce()
})
}
func (c *PurchaseHandler) refreshCommentOnce() {
c.RefreshComment(time.Now().Add(-RefreshCommentTime), time.Now())
utils.AfterFuncWithRecover(RefreshCommentTimeInterval, func() {
c.refreshCommentOnce()
})
}
func formalizeTagList(mtwmTagList string) (outTagList string) {
if mtwmTagList != "" {
outTagList = string(utils.Format4Output(strings.Split(mtwmTagList, ","), true))
}
return outTagList
}
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)
}
return err
}
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)
}
return err
}

View File

@@ -0,0 +1,35 @@
package tiktok_store
import (
"testing"
"time"
"git.rosy.net.cn/jx-callback/business/jxutils/jxcontext"
"git.rosy.net.cn/baseapi/utils"
_ "git.rosy.net.cn/jx-callback/business/jxcallback/orderman"
)
func TestGetOrder(t *testing.T) {
// result, err := CurPurchaseHandler.GetOrder("", "33437032333978492")
// if err != nil {
// t.Fatal(err)
// }
//t.Log(utils.Format4Output(result, false))
}
func TestGetOrderStatus(t *testing.T) {
result, err := CurPurchaseHandler.GetOrderStatus("", "71884881906304496")
if err != nil {
t.Fatal(err)
}
t.Log(utils.Format4Output(result, false))
}
func TestListOrders(t *testing.T) {
result, err := CurPurchaseHandler.ListOrders(jxcontext.AdminCtx, "5873", nil, time.Now(), "14038247")
if err != nil {
t.Fatal(err)
}
t.Log(utils.Format4Output(result, false))
}

View File

@@ -0,0 +1,487 @@
package tiktok_store
import (
"encoding/json"
"errors"
"fmt"
"git.rosy.net.cn/baseapi/platformapi/mtwmapi"
"git.rosy.net.cn/baseapi/utils"
"git.rosy.net.cn/baseapi/utils/errlist"
"git.rosy.net.cn/jx-callback/business/jxcallback/scheduler"
"git.rosy.net.cn/jx-callback/business/jxstore/event"
"git.rosy.net.cn/jx-callback/business/jxutils"
"git.rosy.net.cn/jx-callback/business/jxutils/jxcontext"
"git.rosy.net.cn/jx-callback/business/jxutils/tasksch"
"git.rosy.net.cn/jx-callback/business/model"
"git.rosy.net.cn/jx-callback/business/model/dao"
"git.rosy.net.cn/jx-callback/business/partner"
"git.rosy.net.cn/jx-callback/globals"
"git.rosy.net.cn/jx-callback/globals/api"
"math"
"regexp"
"strings"
)
var (
opTimeErrReg = regexp.MustCompile(`当前配送营业时间为:([\d:~,]*)`)
storeVendorOrgCodeMap = map[string]map[string]string{
"589": map[string]string{
"firstTag": mtwmapi.MtwmC4Tag, //经营品类
"settlementID": "7030017", //结算ID
"poiCert": "1,2,5", //资质列表
},
"5873": map[string]string{
"firstTag": mtwmapi.MtwmSCTag,
"settlementID": "",
"poiCert": "1,2,5,6",
},
"4123": map[string]string{
"firstTag": mtwmapi.MtwmSGTag,
"settlementID": "6572945",
"poiCert": "1,5",
},
}
poiCertMap = map[string]string{
"1": "门脸图",
"2": "环境图",
"5": "营业执照",
"6": "食品经营许可证",
}
)
type tEbaiStoreInfo struct {
model.Store
VendorStoreID string `orm:"column(vendor_store_id)"`
RealLastOperator string
EbaiStoreStatus int
SyncStatus int
ProvinceID int `orm:"column(province_id)"`
CityID int `orm:"column(city_id)"`
DistrictID int `orm:"column(district_id)"`
}
func (p *PurchaseHandler) ReadStore(ctx *jxcontext.Context, vendorOrgCode, vendorStoreID, vendorStoreName string) (retVal *dao.StoreDetail, err error) {
result, err := getAPIWithoutToken(vendorOrgCode).PoiGet(vendorStoreID)
if err == nil {
// globals.SugarLogger.Debug(utils.Format4Output(result, false))
retVal = &dao.StoreDetail{
Store: model.Store{
Address: result.Address,
Tel1: result.Phone,
},
}
retVal.OriginalName = result.Name
_, retVal.Name = jxutils.SplitStoreName(retVal.OriginalName, partner.StoreNameSeparator, globals.StoreNameMtwm)
retVal.SetOpTime(openTimeMtwm2JX(result.ShippingTime))
retVal.Status = bizStatusMtwm2JX(result.OpenLevel, result.IsOnline)
tel2 := result.StandbyTel
if tel2 != "" && tel2 != retVal.Tel1 {
retVal.Tel2 = tel2
}
retVal.Lng = int(result.Longitude)
retVal.Lat = int(result.Latitude)
lng := jxutils.IntCoordinate2Standard(retVal.Lng)
lat := jxutils.IntCoordinate2Standard(retVal.Lat)
db := dao.GetDB()
retVal.DistrictCode = api.AutonaviAPI.GetCoordinateDistrictCode(lng, lat)
city, err := dao.GetPlaceByCode(db, result.CityID)
retVal.CityName = city.Name
retVal.CityCode = result.CityID
poiCode := result.AppPoiCode
retVal.VendorStoreID = vendorStoreID
retVal.ID = int(utils.Str2Int64WithDefault(poiCode, 0))
retVal.DeliveryRangeType = model.DeliveryRangeTypePolygon
var deliveryRangeInfo []map[string]interface{}
deliveryRangeInfo, err = getAPIWithoutToken(vendorOrgCode).ShippingFetch(poiCode)
if err != nil {
deliveryRangeInfo, err = getAPIWithoutToken(vendorOrgCode).ShippingList(poiCode)
}
if err == nil {
if len(deliveryRangeInfo) > 0 {
retVal.DeliveryRange = rangeMtwm2JX(deliveryRangeInfo[0]["area"].(string))
logisticsCode := utils.Interface2String(deliveryRangeInfo[0]["logistics_code"])
if logisticsCode == "" || logisticsCode == mtwmapi.PeiSongTypeSelf {
retVal.DeliveryType = scheduler.StoreDeliveryTypeByStore
} else {
retVal.DeliveryType = scheduler.StoreDeliveryTypeByPlatform
}
}
}
return retVal, nil
}
return nil, err
}
func (p *PurchaseHandler) CreateStore(db *dao.DaoDB, storeID int, userName string) (err error) {
return p.UpdateStore(db, storeID, userName)
}
func (p *PurchaseHandler) CreateStore2(db *dao.DaoDB, storeID int, userName string, params map[string]interface{}, storeDetail *dao.StoreDetail) (vendorStoreID string, err error) {
vendorOrgCode := params["vendorOrgCode"].(string)
if vendorOrgCode == "" {
return "", fmt.Errorf("平台账号必传!")
}
cityName := storeDetail.CityName
if strings.Contains(cityName, "市") {
cityName = strings.Replace(cityName, "市", "", strings.LastIndex(cityName, "市"))
}
shippingTime := ""
if storeDetail.OpenTime1 != 0 && storeDetail.CloseTime1 != 0 {
shippingTime += jxutils.JxOperationTime2StrTime(storeDetail.OpenTime1)
shippingTime += "-"
shippingTime += jxutils.JxOperationTime2StrTime(storeDetail.CloseTime1)
if storeDetail.OpenTime2 != 0 && storeDetail.CloseTime2 != 0 {
shippingTime += ","
shippingTime += jxutils.JxOperationTime2StrTime(storeDetail.OpenTime2)
shippingTime += "-"
shippingTime += jxutils.JxOperationTime2StrTime(storeDetail.CloseTime2)
}
}
vendorInfoMap := storeVendorOrgCodeMap[vendorOrgCode]
poiSettleSaveParam := &mtwmapi.PoiSettleSaveParam{
Type: 1, //创建
ApplyInfos: []*mtwmapi.ApplyInfo{
&mtwmapi.ApplyInfo{
AppPoiCode: utils.Int2Str(storeDetail.ID),
SettlementID: utils.Str2Int(vendorInfoMap["settlementID"]), //结算ID暂时还没得
MultiPoiBasicInfo: &mtwmapi.MultiPoiBasicInfo{
Name: params["vendorStoreName"].(string),
City: cityName,
Address: storeDetail.Address,
Longitude: utils.Float64ToStr(jxutils.IntCoordinate2Standard(storeDetail.Lng)),
Latitude: utils.Float64ToStr(jxutils.IntCoordinate2Standard(storeDetail.Lat)),
FirstTag: vendorInfoMap["firstTag"],
CallCenter: storeDetail.Tel1,
ContactPhone: storeDetail.Tel1,
ContactName: storeDetail.IDName,
EcommerceAccountPhone: "18048531223", //石总的手机
ShippingTime: shippingTime,
},
MultiPoiShippingInfo: &mtwmapi.MultiPoiShippingInfo{
ShippingType: 5, //1:商家自配 5:美团专送,101:美团快送
//美团专送不需要输下面这俩
// MinPrice: params["minPrice"].(float64),
// ShippingFee: params["shippingFee"].(float64),
},
//资质
},
},
}
switchCertType := func(certType string) (licensePic, licenseSocialCreditCode, licenseNumber, licenseLegalPerson, licenseAddress, licenseValidStartDate, licenseValidity string, isLongTime int) {
switch certType {
case "1":
licensePic = storeDetail.StoreFrontPic
case "2":
licensePic = storeDetail.StoreInPic
case "5":
licensePic = storeDetail.Licence
licenseSocialCreditCode = storeDetail.LicenceCode
licenseNumber = storeDetail.LicenceCode
licenseLegalPerson = storeDetail.LicenceOwnerName
licenseAddress = storeDetail.LicenceAddress
licenseValidStartDate = storeDetail.LicenceValid
if storeDetail.LicenceExpire == "" {
isLongTime = 1
} else {
licenseValidity = storeDetail.LicenceExpire
}
case "6":
licensePic = storeDetail.Licence2Image
licenseSocialCreditCode = storeDetail.Licence2Code
licenseNumber = storeDetail.Licence2Code
licenseLegalPerson = storeDetail.LicenceOwnerName
licenseAddress = storeDetail.LicenceAddress
licenseValidStartDate = storeDetail.Licence2Valid
if storeDetail.Licence2Expire == "" {
isLongTime = 1
} else {
licenseValidity = storeDetail.Licence2Expire
}
}
return licensePic, licenseSocialCreditCode, licenseNumber, licenseLegalPerson, licenseAddress, licenseValidStartDate, licenseValidity, isLongTime
}
var certs []*mtwmapi.MultiPoiCertInfo
for _, v := range strings.Split(vendorInfoMap["poiCert"], ",") {
cert := &mtwmapi.MultiPoiCertInfo{
Type: utils.Str2Int(v),
LicenseName: poiCertMap[v],
}
cert.LicensePic, cert.LicenseSocialCreditCode, cert.LicenseNumber, cert.LicenseLegalPerson, cert.LicenseAddress, cert.LicenseValidStartDate, cert.LicenseValidity, cert.IsLongTime = switchCertType(v)
certs = append(certs, cert)
}
poiSettleSaveParam.ApplyInfos[0].MultiPoiCertInfos = certs
mtapi := getAPIWithoutToken(vendorOrgCode)
if vendorStoreID, err = mtapi.PoiSettleSave(poiSettleSaveParam); err == nil {
err = mtapi.PoiSettleAuditSubmit([]string{vendorStoreID})
}
return vendorStoreID, err
}
func (p *PurchaseHandler) DeleteStore(db *dao.DaoDB, storeID int, userName string) (err error) {
return err
}
func (p *PurchaseHandler) UpdateStore(db *dao.DaoDB, storeID int, userName string) (err error) {
var name string
if db == nil {
db = dao.GetDB()
}
mtapi := getAPI(getStoreVendorOrgCode(storeID), storeID, "")
storeDetail, err := dao.GetStoreDetail(db, storeID, model.VendorIDMTWM, "")
if err != nil {
return err
}
errList := errlist.New()
remoteStoreInfo, err := mtapi.PoiGet(storeDetail.VendorStoreID)
if err != nil {
return err
}
mergedStoreStatus := jxutils.MergeStoreStatus(storeDetail.Status, storeDetail.VendorStatus)
name = remoteStoreInfo.Name
if storeDetail.SyncStatus&(model.SyncFlagNewMask|model.SyncFlagStoreName) != 0 {
if storeDetail.VendorStoreName != "" {
name = storeDetail.VendorStoreName
}
// else {
// name = jxutils.ComposeStoreName(storeDetail.Store.Name, model.VendorIDMTWM)
// }
}
store := fmt.Sprintf("门店id:%d,门店名称:%s,第三方门店状态:%d,本地修改前门店状态%d,本地门店修改后状态:%d,第三方平台Id(美团):%s", storeID, remoteStoreInfo.Name, remoteStoreInfo.IsOnline, storeDetail.Status, mergedStoreStatus, storeDetail.VendorOrgCode)
event.AddOperateEvent(jxcontext.AdminCtx, jxcontext.AdminCtx.GetTrackInfo(), store, "", "", 10, "UpdateStore")
// openLevel, isOnline := bizStatusJX2Mtwm(mergedStoreStatus)
//TODO 美团暂时不用那个电话
phone := storeDetail.Tel1
// if storeDetail.MarketManPhone != "" {
// phone = storeDetail.MarketManPhone
// } else {
// phone = model.VendorStoreTel
// }
params := map[string]interface{}{
"name": name, //jxutils.ComposeStoreName(storeDetail.Store.Name, model.VendorIDMTWM),
"address": storeDetail.Address, // 美团好像地址也不能改的?
"longitude": jxutils.IntCoordinate2Standard(int(remoteStoreInfo.Longitude)),
"latitude": jxutils.IntCoordinate2Standard(int(remoteStoreInfo.Latitude)),
"phone": phone,
"shipping_fee": remoteStoreInfo.ShippingFee,
"shipping_time": remoteStoreInfo.ShippingTime,
"open_level": remoteStoreInfo.OpenLevel,
"is_online": remoteStoreInfo.IsOnline,
"third_tag_name": remoteStoreInfo.ThirdTagName,
"promotion_info": storeDetail.PromoteInfo,
}
// globals.SugarLogger.Debug(utils.Format4Output(params, false))
if globals.EnableMtwmStoreWrite {
errList.AddErr(mtapi.PoiSave(storeDetail.VendorStoreID, params))
}
// PoiSave有时会报错商家已接入美团配送不可修改门店配送相关信息这里放弃信息修改
// if err != nil {
// if utils.IsErrMatch(err, utils.Int2Str(mtwmapi.ErrCodeCanNotModifyStoreDeliveryInfo), nil) {
// globals.SugarLogger.Infof("mtwm UpdateStore vendorStoreID:%s, params:%s failed with err:%v", storeDetail.VendorStoreID, utils.Format4Output(params, true), err)
// if storeDetail.SyncStatus&(model.SyncFlagNewMask|model.SyncFlagStoreStatus) != 0 {
// err = p.UpdateStoreStatus(jxcontext.AdminCtx, storeDetail.VendorOrgCode, storeID, storeDetail.VendorStoreID, mergedStoreStatus)
// } else {
// err = nil
// }
// }
// errList.AddErr(err)
// }
if storeDetail.SyncStatus&(model.SyncFlagNewMask|model.SyncFlagStoreStatus) != 0 {
errList.AddErr(p.UpdateStoreStatus(jxcontext.AdminCtx, storeDetail.VendorOrgCode, storeID, storeDetail.VendorStoreID, mergedStoreStatus))
}
errList.AddErr(p.UpdateStoreOpTime(jxcontext.AdminCtx, storeDetail.VendorOrgCode, storeID, storeDetail.VendorStoreID, storeDetail.GetOpTimeList()))
// errList.AddErr(p.UpdateStoreBoxFee(jxcontext.AdminCtx, storeDetail.VendorOrgCode, storeID, storeDetail.VendorStoreID))
return errList.GetErrListAsOne()
}
func (p *PurchaseHandler) RefreshAllStoresID(ctx *jxcontext.Context, parentTask tasksch.ITask, isAsync bool) (hint string, err error) {
return "", errors.New("美团外卖不支持此操作")
}
func (p *PurchaseHandler) onStoreStatusChanged(msg *mtwmapi.CallbackMsg) (response *mtwmapi.CallbackResponse) {
var err error
vendorStoreID := msg.FormData.Get("app_poi_code")
storeStatus := 0
if msg.Cmd == mtwmapi.MsgTypeStoreStatusChanged {
poiStatus := int(utils.Str2Int64(msg.FormData.Get("poi_status")))
if poiStatus == mtwmapi.MsgPoiStatusOpened {
storeStatus = model.StoreStatusOpened
} else if poiStatus == mtwmapi.MsgPoiStatusClosed {
storeStatus = model.StoreStatusClosed
} else if poiStatus == mtwmapi.MsgPoiStatusOffline {
storeStatus = model.StoreStatusDisabled
} else {
storeStatus, err = p.GetStoreStatus(jxcontext.AdminCtx, "", 0, vendorStoreID)
}
} else if msg.Cmd == mtwmapi.MsgTypeStoreAuditStatusChanged {
auditDetails := []map[string]interface{}{}
auditDetail := msg.FormData.Get("audit_detail")
openFlag := false
openCount := 0
closeFlag := false
if err = json.Unmarshal([]byte(auditDetail), &auditDetails); err == nil {
for _, v := range auditDetails {
if v["module_status"].(string) == "3" || v["module_status"].(string) == "5" || v["module_status"].(string) == "7" {
closeFlag = true
break
}
if v["module_status"].(string) == "6" {
openCount++
}
}
if openCount == len(auditDetails) {
openFlag = true
}
if closeFlag {
storeStatus = model.StoreStatusDisabled
} else if openFlag {
storeStatus = model.StoreStatusOpened
} else {
storeStatus = model.StoreStatusClosed
}
}
}
if err == nil {
err = partner.CurStoreManager.OnStoreStatusChanged(vendorStoreID, model.VendorIDMTWM, storeStatus)
}
response = mtwmapi.Err2CallbackResponse(err, "")
// 操作日志(美团外卖)
ctx := jxcontext.AdminCtx
store := fmt.Sprintf("美团外卖回调门店改变回调(营业状态/审核状态):门店id:%s,美团门店状态:%d.[121营业,120休息,18上线,19下线],本地修改后状态[%d]", vendorStoreID, int(utils.Str2Int64(msg.FormData.Get("poi_status"))), storeStatus)
event.AddOperateEvent(ctx, ctx.GetTrackInfo(), store, "", "", 10, "UpdateStore")
return response
}
func (p *PurchaseHandler) GetStoreStatus(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string) (storeStatus int, err error) {
result, err := getAPI(vendorOrgCode, storeID, "").PoiGet(vendorStoreID)
if err == nil {
return bizStatusMtwm2JX(result.OpenLevel, result.IsOnline), nil
}
return 0, err
}
func (p *PurchaseHandler) EnableAutoAcceptOrder(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, isSetEnable bool) (err error) {
return err
}
func (c *PurchaseHandler) UpdateStoreStatus(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, status int) (err error) {
openLevel, isOnline := bizStatusJX2Mtwm(status)
if globals.EnableMtwmStoreWrite {
if isOnline != mtwmapi.PoiStatusOnline {
err = getAPI(vendorOrgCode, storeID, vendorStoreID).PoiOffline(vendorStoreID)
} else {
if err = getAPI(vendorOrgCode, storeID, vendorStoreID).PoiOnline(vendorStoreID); err == nil { // 这个函数成功返回也并不表示上线成功。。。
remoteStoreInfo, err2 := getAPI(vendorOrgCode, storeID, vendorStoreID).PoiGet(vendorStoreID)
if err = err2; err != nil {
return err
}
if remoteStoreInfo.IsOnline == mtwmapi.PoiStatusOnline {
if openLevel == mtwmapi.PoiOpenLevelHaveRest {
err = getAPI(vendorOrgCode, storeID, vendorStoreID).PoiClose(vendorStoreID)
} else {
err = getAPI(vendorOrgCode, storeID, vendorStoreID).PoiOpen(vendorStoreID)
}
} else {
err = errors.New("门店还未上线,不能修改营业状态")
}
store := fmt.Sprintf("美团外卖回调门店改变回调(营业状态/审核状态):门店id:%s,美团门店状态:%d.[121营业,120休息,18上线,19下线],本地修改后状态[%d]", vendorStoreID, remoteStoreInfo.OpenLevel, openLevel)
event.AddOperateEvent(ctx, ctx.GetTrackInfo(), store, "", "", 10, "UpdateStore")
}
}
}
return err
}
func errOpStr2Int16(str string) []int16 {
list := strings.Split(str, "~")
if len(list) >= 2 {
return []int16{jxutils.StrTime2JxOperationTime(list[0]+":00", 0), jxutils.StrTime2JxOperationTime(list[1]+":00", 2359)}
}
return nil
}
func getOpTimeListFromErr(err error) (opTimeList []int16) {
if errExt, ok := err.(*utils.ErrorWithCode); ok && errExt.IntCode() == mtwmapi.ErrCodeOpFailed {
if result := opTimeErrReg.FindStringSubmatch(errExt.ErrMsg()); len(result) >= 2 {
timeStrList := strings.Split(result[1], ",")
for _, v := range timeStrList {
v = utils.TrimBlankChar(v)
if len(v) == len("00:00~02:00") {
opTimeList = append(opTimeList, errOpStr2Int16(v)...)
}
}
}
}
return opTimeList
}
// 此函数只是简单实现,不支持区间切分,只做单一区间限制
func constrainOpTimeList(opTimeList, validOpTimeList []int16) (newOpTimeList []int16) {
for k := 0; k < len(opTimeList); k += 2 {
beginTime := opTimeList[k]
endTime := opTimeList[k+1]
for k2 := 0; k2 < len(validOpTimeList); k2 += 2 {
beginTime2 := validOpTimeList[k2]
endTime2 := validOpTimeList[k2+1]
if beginTime >= beginTime2 && beginTime <= endTime2 {
newOpTimeList = append(newOpTimeList, beginTime)
newOpTimeList = append(newOpTimeList, int16(math.Min(float64(endTime), float64(endTime2))))
} else if beginTime2 >= beginTime && beginTime2 <= endTime {
newOpTimeList = append(newOpTimeList, beginTime2)
newOpTimeList = append(newOpTimeList, int16(math.Min(float64(endTime), float64(endTime2))))
}
}
}
return newOpTimeList
}
func (c *PurchaseHandler) UpdateStoreOpTime(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, opTimeList []int16) (err error) {
shippingTime := openTimeJX2Mtwm(opTimeList)
if globals.EnableMtwmStoreWrite {
err = getAPI(vendorOrgCode, storeID, vendorStoreID).PoiShipTimeUpdate(vendorStoreID, shippingTime)
if err != nil {
shippingTime = ""
if validOpTimeList := getOpTimeListFromErr(err); len(validOpTimeList) > 0 {
shippingTime = openTimeJX2Mtwm(constrainOpTimeList(opTimeList, validOpTimeList))
}
if shippingTime != "" {
err = getAPI(vendorOrgCode, storeID, vendorStoreID).PoiShipTimeUpdate(vendorStoreID, shippingTime)
}
}
}
return err
}
func (c *PurchaseHandler) GetAllStoresVendorID(ctx *jxcontext.Context, vendorOrgCode string) (vendorStoreIDs []string, err error) {
vendorStoreIDs, err = getAPIWithoutToken(vendorOrgCode).PoiGetIDs()
return vendorStoreIDs, err
}
func (c *PurchaseHandler) UpdateStoreCustomID(ctx *jxcontext.Context, vendorOrgCode, vendorStoreID string, storeID int64) (err error) {
return err
}
func (c *PurchaseHandler) UpdateStoreBoxFee(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string) (err error) {
boxFee, err := dao.GetSysConfigAsInt64(dao.GetDB(), model.ConfigSysMtwmBoxFee)
if err == nil {
if globals.EnableMtwmStoreWrite && globals.IsProductEnv() {
err = getAPI(vendorOrgCode, storeID, vendorStoreID).PackagePriceUpdate(vendorStoreID, 1, int(boxFee))
}
}
return err
}
func (c *PurchaseHandler) UpdateStoreLineStatus(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, lineStatus int) (err error) {
if lineStatus == model.StoreStatusOpened {
err = getAPI(vendorOrgCode, storeID, vendorStoreID).PoiOnline(vendorStoreID)
} else {
err = getAPI(vendorOrgCode, storeID, vendorStoreID).PoiOffline(vendorStoreID)
}
return err
}

View File

@@ -0,0 +1,716 @@
package tiktok_store
import (
"encoding/json"
"regexp"
"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/jxutils/tasksch"
"git.rosy.net.cn/jx-callback/business/model"
"git.rosy.net.cn/jx-callback/business/model/dao"
"git.rosy.net.cn/jx-callback/business/partner"
"git.rosy.net.cn/jx-callback/business/partner/putils"
"git.rosy.net.cn/jx-callback/globals"
)
const (
updateTypeStock = iota
updateTypeStatus
updateTypePrice
)
const (
defVendorCatID = 200001903 // 生菜
specialStoreID = "8171010"
// specialStoreID = "2523687"
)
var (
sensitiveWordRegexp = regexp.MustCompile(`包含敏感词:(\[.*\])`)
)
func (p *PurchaseHandler) GetStoreSkusBatchSize(funcID int) (batchSize int) {
switch funcID {
case partner.FuncUpdateStoreSkusStock, partner.FuncUpdateStoreSkusStatus, partner.FuncUpdateStoreSkusPrice:
batchSize = mtwmapi.MaxStoreSkuBatchSize
case partner.FuncDeleteStoreSkus:
batchSize = mtwmapi.MaxBatchDeleteSize
case partner.FuncCreateStoreSkus:
batchSize = 1 // 可考虑用批量操作
case partner.FuncUpdateStoreSkus:
batchSize = 1 // mtwmapi.MaxStoreSkuBatchSize
case partner.FuncGetStoreSkusFullInfo:
batchSize = 1
case partner.FuncCreateActs:
batchSize = mtwmapi.MaxRetailDiscountCreateBatchSize
case partner.FuncCancelActs:
batchSize = mtwmapi.MaxRetailDiscountDeleteBatchSize
}
return batchSize
}
func getStoreVendorOrgCode(storeID int) (vendorOrgCode string) {
if storeMap, _ := dao.GetStoreDetail(dao.GetDB(), storeID, model.VendorIDMTWM, ""); storeMap != nil {
return storeMap.VendorOrgCode
}
return vendorOrgCode
}
// 门店分类
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)
if err == nil {
cats = convertVendorCatList(remoteCats)
}
return cats, err
}
func convertVendorCatList(remoteCats []*mtwmapi.RetailCategoryInfo) (cats []*partner.BareCategoryInfo) {
for _, rCat := range remoteCats {
cat := &partner.BareCategoryInfo{
VendorCatID: rCat.Code,
Name: rCat.Name,
Level: rCat.Level,
Seq: rCat.Sequence,
Children: convertVendorCatList(rCat.Children),
}
if cat.VendorCatID == "" {
cat.VendorCatID = rCat.Name
}
cats = append(cats, cat)
}
return cats
}
func (p *PurchaseHandler) IsErrCategoryExist(err error) (isExist bool) {
return mtwmapi.IsErrCategoryExist(err)
}
func (p *PurchaseHandler) IsErrCategoryNotExist(err error) (isNotExist bool) {
return mtwmapi.IsErrCategoryNotExist(err)
}
func catCode2Str(catCode int) (catCodeStr string) {
if catCode > 0 {
catCodeStr = utils.Int2Str(catCode)
}
return catCodeStr
}
func tryCatName2Code(originName string) (catCodeStr string) {
if intValue := utils.Str2Int64WithDefault(originName, 0); intValue > 0 {
catCodeStr = utils.Int64ToStr(intValue)
if catCodeStr != originName {
catCodeStr = ""
}
}
return catCodeStr
}
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)
}
return err
}
func (p *PurchaseHandler) UpdateStoreCategory(ctx *jxcontext.Context, storeID int, vendorStoreID string, storeCat *dao.SkuStoreCatInfo) (err error) {
return p.CreateStoreCategory(ctx, storeID, vendorStoreID, storeCat)
}
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)
}
}
}
return err
}
// 门店商品
// 多门店平台不需要实现这个接口
func (p *PurchaseHandler) IsErrSkuExist(err error) (isExist bool) {
return false
}
func (p *PurchaseHandler) IsErrSkuNotExist(err error) (isNotExist bool) {
return mtwmapi.IsErrSkuNotExist(err)
}
// func duplicateStoreSkuList(storeSkuList []*dao.StoreSkuSyncInfo, index int) (newStoreSkuList []*dao.StoreSkuSyncInfo) {
// newStoreSkuList = make([]*dao.StoreSkuSyncInfo, len(storeSkuList))
// for k, v := range storeSkuList {
// tmp := *v
// tmp.SkuName = fmt.Sprintf("%s.%d", tmp.SkuName, index)
// tmp.SkuID = index*1000000 + tmp.SkuID
// newStoreSkuList[k] = &tmp
// }
// return newStoreSkuList
// }
func (p *PurchaseHandler) UpdateStoreSkus(ctx *jxcontext.Context, storeID int, vendorStoreID string, storeSkuList []*dao.StoreSkuSyncInfo) (failedList []*partner.StoreSkuInfoWithErr, err error) {
failedList, err = p.createOrUpdateStoreSkus(ctx, storeID, vendorStoreID, storeSkuList, false)
// if err == nil && vendorStoreID == specialStoreID {
// for i := 0; i < 2; i++ {
// p.createOrUpdateStoreSkus(ctx, storeID, vendorStoreID, duplicateStoreSkuList(storeSkuList, i+1), true)
// }
// }
return failedList, err
}
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)
// }
// }
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))
if isCreate {
syncType = "创建商品"
} 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
}
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)
}
} 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)
}
}
}
}
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 len(failedList) > 0 {
err = nil
}
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)
}
func storeSku2Mtwm(storeSkuList []*partner.StoreSkuInfo, updateType int) (skuList []*mtwmapi.BareStoreFoodInfo) {
for _, storeSku := range storeSkuList {
skuInfo := &mtwmapi.BareStoreFoodInfo{
AppFoodCode: storeSku.VendorSkuID,
Skus: []*mtwmapi.BareStoreSkuInfo{
&mtwmapi.BareStoreSkuInfo{
SkuID: storeSku.VendorSkuID,
},
},
}
if updateType == updateTypeStock {
skuInfo.Skus[0].Stock = stockCount2Mtwm(storeSku.Stock)
} else if updateType == updateTypePrice {
skuInfo.Skus[0].Price = jxutils.IntPrice2StandardString(storeSku.VendorPrice)
} else {
skuInfo.Skus = nil
}
skuList = append(skuList, skuInfo)
}
return skuList
}
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))
}
} 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 len(failedList) > 0 {
err = nil
}
return failedList, err
}
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], "更新商品价格")
}
}
}
if len(failedList) > 0 {
err = nil
}
return failedList, err
}
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 len(failedList) > 0 {
err = nil
}
return failedList, err
}
func mtwmSkuStatus2Jx(mtwmSkuStatus int) (jxSkuStatus int) {
if mtwmSkuStatus == mtwmapi.SellStatusOnline {
jxSkuStatus = model.SkuStatusNormal
} else {
jxSkuStatus = model.SkuStatusDontSale
}
return jxSkuStatus
}
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))
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
}
}
}
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))
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))
skuName = &partner.SkuNameInfo{
NameID: int(utils.Str2Int64WithDefault(appFood.AppFoodCode, 0)),
VendorNameID: appFood.AppFoodCode,
UPC: appFood.SkuList[0].Upc,
Prefix: prefix,
Name: name,
Unit: unit,
Status: mtwmSkuStatus2Jx(appFood.IsSoldOut), //此处为之前一个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),
},
SkuName: appFood.Name,
Comment: comment,
SpecQuality: float64(specQuality),
SpecUnit: specUnit,
Weight: weight,
},
},
PictureList: appFood.PictureList,
}
if appFood.CategoryName != "" {
// todo, 因为当前我们用的是分类名操作这种方式所以要返回分类名而不是分类code
skuName.VendorCatIDList = []string{appFood.CategoryName}
if appFood.SecondaryCategoryName != "" {
skuName.VendorCatIDList = append(skuName.VendorCatIDList, appFood.SecondaryCategoryName)
}
}
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
}
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
}
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))
}
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)
}
}
return err
}

View File

@@ -0,0 +1,64 @@
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))
}

View File

@@ -0,0 +1,46 @@
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)
}
}

View File

@@ -0,0 +1,43 @@
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)
}

View File

@@ -0,0 +1,59 @@
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
}

View File

@@ -213,9 +213,6 @@ tiktokAppSecret = "5c08a0465cf0f996af254a03b6c2548defef87ad"
tiktokJXDJKey="ttaceeda5333d7a7ab01" #京西到家抖音小程序
TiktokJXDJApiID="ttaceeda5333d7a7ab01"
tiktokJXDJSecret="5c8492ec2744fb72bb6cc356983f3cfc317f85d4"
#国美
gomeiAppKey = "N0R033L2QQFR53"
gomeiAppSecret = "686ffc3e31c24594838baed045563790"
[prod]
EnableDocs = false
@@ -339,9 +336,6 @@ tiktokAppSecret = "5c08a0465cf0f996af254a03b6c2548defef87ad"
tiktokJXDJKey="ttaceeda5333d7a7ab01" #京西到家抖音小程序
TiktokJXDJApiID="ttaceeda5333d7a7ab01"
tiktokJXDJSecret="5c8492ec2744fb72bb6cc356983f3cfc317f85d4"
#国美
gomeiAppKey = "N0R033L2QQFR53"
gomeiAppSecret = "686ffc3e31c24594838baed045563790"
[jxgy]
httpport = 8088
EnableDocs = false
@@ -445,9 +439,6 @@ tiktokAppSecret = "5c08a0465cf0f996af254a03b6c2548defef87ad"
tiktokJXDJKey="ttaceeda5333d7a7ab01" #京西到家抖音小程序
TiktokJXDJApiID="ttaceeda5333d7a7ab01"
tiktokJXDJSecret="5c8492ec2744fb72bb6cc356983f3cfc317f85d4"
#国美
gomeiAppKey = "N0R033L2QQFR53"
gomeiAppSecret = "686ffc3e31c24594838baed045563790"
[test]
jdOrgCode = "82029"
jdToken = "594ab45a-9a73-4a43-82b0-a64cbd55d883"
@@ -634,6 +625,3 @@ tiktokAppSecret = "5c08a0465cf0f996af254a03b6c2548defef87ad"
tiktokJXDJKey="ttaceeda5333d7a7ab01" #京西到家抖音小程序
TiktokJXDJApiID="ttaceeda5333d7a7ab01"
tiktokJXDJSecret="5c8492ec2744fb72bb6cc356983f3cfc317f85d4"
#国美
gomeiAppKey = "N0R033L2QQFR53"
gomeiAppSecret = "686ffc3e31c24594838baed045563790"

View File

@@ -1,7 +1,9 @@
package controllers
import (
"git.rosy.net.cn/baseapi/platformapi/tiktok_shop/tiktok_api"
"git.rosy.net.cn/jx-callback/business/partner/purchase/tiktok_store"
"git.rosy.net.cn/jx-callback/globals"
"git.rosy.net.cn/jx-callback/globals/api"
"github.com/astaxie/beego/server/web"
)
@@ -10,13 +12,35 @@ type TiktokController struct {
web.Controller
}
// CallbackTiktok 抖店用户下单订单推送 (tiktokStore)
func (t *TiktokController) CallbackTiktok() {
data, resp := api.TiktokStore.CreateOrderCallback(t.Ctx.Request)
if resp.Code == 200 {
// 业务处理
tiktok_store.OnCallbackMsg(data)
// CallbackTiktokOrderMsg 抖店用户下单订单推送 (tiktokStore)
func (t *TiktokController) CallbackTiktokOrderMsg() {
// 1.防伪校验
resp := api.TiktokStore.EventSignChange(t.Ctx.Request)
if resp.Code != 0 {
t.Data["json"] = resp
t.ServeJSON()
return
}
t.Data["json"] = resp
// 2.参数解析
orderStatus, resp := api.TiktokStore.CreateOrderCallback(t.Ctx.Request)
globals.SugarLogger.Debug("美团订单回调数据打印测试===========", orderStatus)
if resp.Code != 0 {
t.Data["json"] = resp
t.ServeJSON()
return
}
for _, v := range orderStatus {
resp2 := tiktok_store.OnOrderMsg(v)
if resp2.Code != 0 {
t.Data["json"] = resp2
t.ServeJSON()
return
}
}
t.Data["json"] = tiktok_api.CallbackResponse{Code: tiktok_api.CallbackSuccessCode, Msg: tiktok_api.CallbackSuccess}
t.ServeJSON()
}

View File

@@ -2,7 +2,6 @@ package api
import (
enterprise "git.rosy.net.cn/baseapi/platformapi/enterprise_wechat"
gomei "git.rosy.net.cn/baseapi/platformapi/gome_live_show"
"git.rosy.net.cn/baseapi/platformapi/jxprintapi"
"git.rosy.net.cn/baseapi/platformapi/qywxapi"
"git.rosy.net.cn/baseapi/platformapi/tiktok"
@@ -117,8 +116,7 @@ var (
TiktokJXDJApi *tiktok.API //抖音京西到家api
TiktokApiID string //抖音商城ID
TiktokJXDJApiID string //抖音京西到家ID
GuoMeiApi *gomei.API // 国美api
TiktokStore *tiktokShop.Api
TiktokStore *tiktokShop.API
EnterpriseChatHeadApi *enterprise.API // 企业微信api
EnterpriseChatMin *enterprise.API // 企业微信小程序api
)
@@ -309,9 +307,8 @@ func Init() {
if TiktokJXDJApiID = beego.AppConfig.DefaultString("TiktokJXDJApiID", ""); TiktokJXDJApiID != "" {
TiktokJXDJApi = tiktok.New(beego.AppConfig.DefaultString("tiktokJXDJSecret", ""), beego.AppConfig.DefaultString("TiktokJXDJApiID", ""))
}
// 抖店
TiktokStore = tiktokShop.New(beego.AppConfig.DefaultString("key", ""), beego.AppConfig.DefaultString("sercret", ""), "")
// 国美aip
GuoMeiApi = gomei.New(beego.AppConfig.DefaultString("gomeiAppKey", ""), beego.AppConfig.DefaultString("gomeiAppSecret", ""), "")
EnterpriseChatHeadApi = enterprise.New("ww9a156bfa070e1857", "0jBdCjSmoFiOoHIXyeCK9VbGQ82fVNJZ8uMl6JNN7X4") // 通讯录
EnterpriseChatMin = enterprise.NewMin("ww9a156bfa070e1857", "JQsEmSTltHhNgdPIT320YJFphiYmRs-YZa-rCBwplss") // 小程序
}

View File

@@ -62,8 +62,6 @@ func (a *APIManager) GetAPI(vendorID int, appOrgCode string) (pfAPI interface{})
pfAPI = api.EbaiAPI
case model.VendorIDJDShop:
pfAPI = api.JdShopAPI
case model.VendorGoMei:
pfAPI = api.GuoMeiApi
case model.VendorIDTT:
pfAPI = api.TiktokApi
}
@@ -84,8 +82,6 @@ func (a *APIManager) GetAppOrgCodeList(vendorID int) (appOrgCodeList []string) {
appOrgCodeList = []string{api.EbaiAPI.GetSource()}
case model.VendorIDJDShop:
appOrgCodeList = []string{"2"}
case model.VendorGoMei:
appOrgCodeList = []string{api.GuoMeiApi.GetAppKey()}
}
return appOrgCodeList
}