package tiktok_store import ( "errors" "fmt" "git.rosy.net.cn/baseapi/platformapi/mtpsapi" shop_getStoreDetail_request "git.rosy.net.cn/baseapi/platformapi/tiktok_shop/sdk-golang/api/shop_getStoreDetail/request" superm_createVirtualMobile_response "git.rosy.net.cn/baseapi/platformapi/tiktok_shop/sdk-golang/api/superm_createVirtualMobile/response" "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/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/delivery" "git.rosy.net.cn/jx-callback/globals" "git.rosy.net.cn/jx-callback/globals/api" "time" ) var ( curDeliveryHandler *DeliveryHandler ) type DeliveryHandler struct { } func init() { if api.TiktokStore != nil { curDeliveryHandler = new(DeliveryHandler) partner.RegisterDeliveryPlatform(curDeliveryHandler, true) } } func (c *DeliveryHandler) GetVendorID() int { return model.VendorIDDYPS } func (c *DeliveryHandler) CreateStore(ctx *jxcontext.Context, storeDetail *dao.StoreDetail2) (vendorStoreID string, status int, err error) { return "", 0, errors.New("抖店暂不支持此操作") } func (c *DeliveryHandler) GetStore(ctx *jxcontext.Context, storeID int, vendorStoreID string) (storeDetail *dao.StoreDetail2, err error) { relInfo, err := dao.GetStoreDetailForDD(dao.GetDB(), storeID, model.VendorIDDD, vendorStoreID, "") if err != nil { return nil, errors.New("获取抖音平台账号信息失败,请重试") } apiObj := getAPI(relInfo.VendorOrgCode) if storeInfo, err := apiObj.GetStoreDetail(&shop_getStoreDetail_request.ShopGetStoreDetailParam{ StoreId: vendorStoreID, }); err == nil { storeDetail = &dao.StoreDetail2{ Store: model.Store{ Name: storeInfo.StoreDetail.Store.Name, Tel1: storeInfo.StoreDetail.Store.Contact, Address: storeInfo.StoreDetail.Store.Address, Lng: jxutils.StandardCoordinate2Int(utils.Str2Float64(storeInfo.StoreDetail.Store.Longitude)), Lat: jxutils.StandardCoordinate2Int(utils.Str2Float64(storeInfo.StoreDetail.Store.Latitude)), }, VendorID: model.VendorIDDYPS, VendorStoreID: utils.Int64ToStr(storeInfo.StoreDetail.Store.StoreId), CourierStatus: int(storeInfo.StoreDetail.Store.State), } globals.SugarLogger.Debugf("storeDetail.Store.Lng====%d,storeDetail.Store.Lat==========%d", storeDetail.Store.Lng, storeDetail.Store.Lat) } else { globals.SugarLogger.Debugf("GetStoreDetail err=========%s", err) } globals.SugarLogger.Debugf("DYPS GetStore storeDetail====%s", utils.Format4Output(storeDetail, false)) return storeDetail, err } func (c *DeliveryHandler) IsErrStoreNotExist(err error) bool { return false } func (c *DeliveryHandler) IsErrStoreExist(err error) bool { return false } // 呼叫运力并发货 func (c *DeliveryHandler) CreateWaybill(order *model.GoodsOrder, maxDeliveryFee int64) (bill *model.Waybill, err error) { relInfo, err := dao.GetStoreDetail(dao.GetDB(), order.JxStoreID, model.VendorIDDD, "") if err != nil { return nil, errors.New("获取抖音平台账号信息失败,请重试") } apiObj := getAPI(relInfo.VendorOrgCode) if order.VendorID != model.VendorIDDD { return nil, errors.New("非抖音平台店铺不可发抖音配送") } bill = &model.Waybill{ VendorOrderID: order.VendorOrderID, OrderVendorID: order.VendorID, VendorWaybillID: order.VendorOrderID, //抖音配送订单号即运单号 WaybillVendorID: model.VendorIDDYPS, } if dispatcherFee, err := apiObj.GetDispatcherInfo(int64(order.StoreID), order.VendorOrderID, tiktok_api.DispatcherFeeTypeCall); err == nil { bill.DesiredFee = dispatcherFee } if err := apiObj.ShopOrderDispatcher(utils.Str2Int64(order.VendorStoreID), order.VendorOrderID, tiktok_api.DispatcherFeeTypeCall); err != nil { return nil, err } delivery.OnWaybillCreated(bill) globals.SugarLogger.Debugf("DYPS CreateWaybill bill======%s", utils.Format4Output(bill, false)) return bill, nil } func (c *DeliveryHandler) CancelWaybill(bill *model.Waybill, cancelReasonID int, cancelReason string) (err error) { globals.SugarLogger.Debugf("进入DYPS CancelWaybill") if localOrder, _, err := dao.GetOrders(dao.GetDB(), []int64{utils.Str2Int64(bill.VendorOrderID)}, false, false, "", "", false, []int{0}, false, "", nil, 0, 0); err != nil { return errors.New("取消运单时,获取平台门店ID失败,请重试") } else { globals.SugarLogger.Debugf("localOrder=%s", utils.Format4Output(localOrder, false)) if err = getAPI(bill.VendorOrgCode).ShopOrderDispatcher(utils.Str2Int64(localOrder[0].VendorStoreID), bill.VendorOrderID, tiktok_api.DispatcherFeeTypeCancel); err != nil { globals.SugarLogger.Debugf("抖音配送取消运力失败:%v", err) return fmt.Errorf("抖音配送取消运力失败:%v", err) } bill.Status = model.WaybillStatusCanceled bill.Remark = cancelReason partner.CurOrderManager.OnWaybillStatusChanged(bill) } globals.SugarLogger.Debugf("DYPS CancelWaybill bill.Status=%d err=%v", bill.Status, err) return err } func (c *DeliveryHandler) GetWaybillFee(order *model.GoodsOrder) (deliveryFeeInfo *partner.WaybillFeeInfo, err error) { relInfo, err := dao.GetStoreDetail(dao.GetDB(), order.JxStoreID, model.VendorIDDD, "") if err != nil { return nil, errors.New("获取抖音平台账号信息失败,请重试") } globals.SugarLogger.Debugf("relInfo.VendorStoreID======%s,order.VendorOrderID======%s", relInfo.VendorStoreID, order.VendorOrderID) if dispatcherFee, err := getAPI(relInfo.VendorOrgCode).GetDispatcherInfo(utils.Str2Int64(relInfo.VendorStoreID), order.VendorOrderID, tiktok_api.DispatcherFeeTypeCall); err == nil { deliveryFeeInfo = &partner.WaybillFeeInfo{} deliveryFeeInfo.DeliveryFee = dispatcherFee } globals.SugarLogger.Debugf("DYPS GetWaybillFee deliveryFeeInfo======%s", utils.Format4Output(deliveryFeeInfo, false)) return deliveryFeeInfo, err } func getDispatcherFee(storeID int64, vendorOrderID string, dispatcherType int32) int64 { if relInfo, err := dao.GetStoreDetailForDD(dao.GetDB(), 0, model.VendorIDDD, utils.Int64ToStr(storeID), ""); err != nil { return 0 } else { if dispatcherFee, err := getAPI(relInfo.VendorOrgCode).GetDispatcherInfo(storeID, vendorOrderID, dispatcherType); err == nil { return 0 } else { return dispatcherFee } } } func (c *DeliveryHandler) ComplaintRider(bill *model.Waybill, resonID int, resonContent string) (err error) { return errors.New("抖店配送暂不支持此操作") } func (c *DeliveryHandler) GetRiderInfo(orderId string, deliveryId int64, mtPeisongId string) (rider *mtpsapi.RiderInfo, err error) { orderInfo, _, err := dao.GetOrders(dao.GetDB(), []int64{utils.Str2Int64(orderId)}, false, false, "", "", false, []int{0}, false, "", nil, 0, 0) if err != nil { return nil, errors.New("获取本地门店账号信息失败,请重试") } if waybill, err := getAPI(orderInfo[0].VendorOrgCode).GetShipmentInfo(utils.Str2Int64(orderId), deliveryId, tiktok_api.ShipmentTypeInvoice); err != nil { return nil, err } else { rider = &mtpsapi.RiderInfo{ OrderId: orderId, ThirdCarrierOrderId: mtPeisongId, CourierName: waybill.RiderName, CourierPhone: waybill.RiderPhone, LogisticsProviderCode: mtpsapi.DYPsCode, LogisticsStatus: int(waybill.ShipmentStatus), LogisticsContext: tiktok_api.ShipmentStatus[waybill.ShipmentStatus], Latitude: waybill.RiderLatitude, Longitude: waybill.RiderLongitude, } } globals.SugarLogger.Debugf("DYPS GetRiderInfo rider======%s", utils.Format4Output(rider, false)) return rider, nil } func CreateVirtualMobile(shopOrderID int64) (*superm_createVirtualMobile_response.SupermCreateVirtualMobileData, error) { if orderInfo, _, err := dao.GetOrders(dao.GetDB(), []int64{shopOrderID}, false, false, "", "", false, []int{0}, false, "", nil, 0, 0); err != nil { return nil, errors.New("获取本地门店账号信息失败,请重试") } else { if visMobile, err := getAPI(orderInfo[0].VendorOrgCode).CreateVirtualMobile(shopOrderID); err != nil { return nil, err } else { return visMobile, nil } } } //订单状态回调 func OnWaybillMsg(tag, orderId string, data interface{}) (response *tiktok_api.CallbackResponse) { req := data.(tiktok_api.ShipmentInfoData) globals.SugarLogger.Debugf("DYPS OnWaybillMsg req============%s", utils.Format4Output(req, false)) param := &model.Waybill{ VendorOrderID: utils.Int64ToStr(req.ShopOrderID), VendorWaybillID: req.TrackNo, VendorWaybillID2: utils.Int64ToStr(req.AfterSaleID), WaybillVendorID: model.VendorIDDYPS, OrderVendorID: model.VendorIDDD, CourierName: req.RiderName, CourierMobile: req.RiderPhone, VendorStatus: utils.Int64ToStr(req.ShipmentStatus), StatusTime: utils.Str2Time(req.OccurredTime), Remark: "", } if req.OccurredTime == "" { param.StatusTime = time.Now() } dispatcherFee := getDispatcherFee(req.ShopID, utils.Int64ToStr(req.ShopOrderID), tiktok_api.DispatcherFeeTypeCall) globals.SugarLogger.Debugf("DYPS OnWaybillMsg dispatcherFee=%d req.ShipmentStatus=%d", dispatcherFee, req.ShipmentStatus) switch req.ShipmentStatus { case tiktok_api.ShipmentStatusCalling: //1 骑手呼叫中 param.DesiredFee = dispatcherFee param.Status = model.WaybillStatusNew //5 待调度 case tiktok_api.ShipmentStatusReceived: //2 骑手已接单 param.DesiredFee = dispatcherFee param.Status = model.WaybillStatusCourierAssigned param.Remark = req.RiderName + "," + req.RiderPhone case tiktok_api.ShipmentStatusArrived: //3 骑手已到达取货点 param.DesiredFee = dispatcherFee param.Status = model.WaybillStatusCourierArrived //80 到店 param.Remark = tiktok_api.ShipmentStatus[req.ShipmentStatus] case tiktok_api.ShipmentStatusDelivering: //4 配送中 param.Status = model.WaybillStatusDelivering param.Remark = tiktok_api.ShipmentStatus[req.ShipmentStatus] case tiktok_api.ShipmentStatusRejected, tiktok_api.ShipmentStatusReturning, tiktok_api.ShipmentStatusReturned: //5 收货人已拒收,6 返回中,7 返回完成 param.Status = model.WaybillStatusDeliverFailed param.Remark = tiktok_api.ShipmentStatus[req.ShipmentStatus] case tiktok_api.ShipmentStatusDelivered: // 8 订单妥投 param.Status = model.WaybillStatusDelivered param.Remark = tiktok_api.ShipmentStatus[req.ShipmentStatus] case tiktok_api.ShipmentStatusCanceled: //9 订单取消 param.Status = model.WaybillStatusCanceled param.Remark = tiktok_api.ShipmentStatus[req.ShipmentStatus] default: globals.SugarLogger.Warnf("onWaybillMsg unknown shipmentStatus:%v", req.ShipmentStatus) } globals.SugarLogger.Debugf("DYPS onWaybillMsg param=====%s", utils.Format4Output(param, false)) if err := partner.CurOrderManager.OnWaybillStatusChanged(param); err != nil { return tiktok_api.CallbackResponseErr(false) } return tiktok_api.CallbackResponseErr(true) } //以下为辅助函数 func getAPI(appOrgCode string) (apiObj *tiktok_api.API) { apiObj = partner.CurAPIManager.GetAPI(model.VendorIDDD, appOrgCode).(*tiktok_api.API) return apiObj }