package delivery import ( "crypto/rand" "fmt" "git.rosy.net.cn/baseapi/platformapi/dingdingapi" "git.rosy.net.cn/jx-callback/business/jxcallback/scheduler/defsch" "git.rosy.net.cn/jx-callback/business/jxstore/cms" "git.rosy.net.cn/jx-callback/business/jxutils/ddmsg" "git.rosy.net.cn/jx-callback/business/partner/purchase/jd" "math/big" "strings" "time" "git.rosy.net.cn/baseapi/platformapi/tao_vegetable" "git.rosy.net.cn/jx-callback/business/jxutils" "git.rosy.net.cn/jx-callback/globals/api" "git.rosy.net.cn/baseapi" "git.rosy.net.cn/baseapi/platformapi/mtwmapi" "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/partner/purchase/ebai" "git.rosy.net.cn/jx-callback/business/partner/purchase/mtwm" "git.rosy.net.cn/baseapi/platformapi/tiktok_shop/tiktok_api" "git.rosy.net.cn/baseapi/utils" "git.rosy.net.cn/jx-callback/business/model" "git.rosy.net.cn/jx-callback/business/model/dao" "git.rosy.net.cn/jx-callback/business/partner" utilsTao "git.rosy.net.cn/jx-callback/business/partner/purchase/tao_vegetable" "git.rosy.net.cn/jx-callback/globals" ) var ( // 换成京西结算账号 jxSettleIdMap = map[int64]bool{ // 菜市 7030017: true, 7974502: true, 100639968: true, 100715370: true, 100822700: true, 101093797: true, 102715080: true, 102114997: true, 102641826: true, 102651220: true, // 果园啊 6572945: true, 6772759: true, 101968432: true, 102101411: true, 102176700: true, 102369597: true, 102416681: true, 102924441: true, 103376926: true, } ) // 订单骑手信息推送:将获取到的三方配送订单,且订单状态为配送中的订单,将配送人员的信息返回给订单方 // 该方法为定时任务,没五分钟推送一次订单消息,订单状态发生变化时 //配送状态code,如下提供配送状态枚举值, //以及各配送状态对应在C端(用户端)和B端(商家PC端)后台展示的配送状态信息。 //未同步配送状态时(C端:商家已接单;B端:待发配送) //0-配送单发往配送(C端:商家已接单;B端:待骑手接单) //1-已创建配送包裹(C端:商家已接单;B端:待骑手接单) //5-已分配骑手(C端:商家已接单;B端:已分配骑手) //10-骑手已接单(C端:骑手正在赶往商家;B端:待骑手取货) //15-骑手已到店(C端:骑手到店取货中;B端:骑手已到店) //20-骑手已取货(C端:商品配送中/骑手正在送货;B端:骑手已取货) //40-骑手已送达(C端:商品已送达;B端:骑手已送达) //100-配送单已取消(C端:商家已接单;B端:配送已取消) //注:若同步配送状态为“配送单已取消”,接口仍支持继续同步配送状态。 说明:商家如未上传此信息,则平台默认值为20(现已要求必传)。 func GetOrderRiderInfoToPlatform(orderId string, wayBillStatus int) { var db = dao.GetDB() params := make(map[string]interface{}, 0) params["isDateFinish"] = false params["isIncludeFake"] = true params["mustInvoice"] = false params["adjustCount"] = 0 //params["waybillVendorIDs"] = `[101,102,103,105]` if orderId != "" { // 订单id会忽略其他参数 params["keyword"] = orderId } else { params["statuss"] = "[20]" } // 每五分钟查询当前订单信息,待配送状态订单1 orders, _, err := dao.GetOrders(db, nil, false, true, time.Now().Add(-24*time.Hour).Format("2006-01-02"), time.Now().Format("2006-01-02"), false, nil, false, "", params, 0, 10000) if err != nil { return } //1.此接口用于同步自配送商家自配订单(除在B2C清单中的商家)的配送信息,包括物流平台、骑手名称、骑手电话,且此配送信息会同步展示在用户端订单详情的“配送信息”中。 //(注:美团跑腿订单的配送信息,平台会自动回流,无需商家再同步。自配的配送信息目前只能在用户端查询,不支持在商家端查询 //2.从订单状态为“商家已确认”(status=4)到“订单已完成”(status=8)后的24小时之内,均可使用此接口创建和更新配送信息。 //3.当同一个订单已经上传了一次配送信息,如再次同步会更新配送信息,以最新的一次为准。 //4.如订单已完成、已取消等状态发货将失败。 for _, v := range orders { if v.Status >= model.OrderStatusEndBegin { continue } riderInfo := &utils.RiderInfo{} if handlerInfo := partner.GetDeliveryPlatformFromVendorID(v.WaybillVendorID); handlerInfo != nil { if v.WaybillVendorID == model.VendorIDDada || v.WaybillVendorID == model.VendorIDFengNiao || v.WaybillVendorID == model.VendorIDUUPT || v.WaybillVendorID == model.VendorIDSFPS { riderInfo, err = handlerInfo.Handler.GetRiderInfo(v.VendorOrderID, 0, v.VendorWaybillID) if err != nil { globals.SugarLogger.Debug("Get Order waybill rider info err FN/DADA/SFPS :%v", err) continue } if riderInfo.CourierPhone != "" && riderInfo.CourierName != "" && strings.Contains(riderInfo.LogisticsContext, "%s") { riderInfo.LogisticsContext = fmt.Sprintf(riderInfo.LogisticsContext, riderInfo.CourierPhone, riderInfo.CourierName) } } else if v.WaybillVendorID == model.VendorIDMTPS { if v.VendorWaybillID != "" { riderInfo, err = handlerInfo.Handler.GetRiderInfo(v.VendorOrderID, v.ID+1000000, v.VendorWaybillID) if err != nil { globals.SugarLogger.Debug("Get Order waybill rider info err MT:%v", err) continue } } } } else { continue //fakeWayBill, err := dao.GetWaybills(db, v.VendorOrderID, []int64{model.VendorJXFakeWL}) //if err != nil || len(fakeWayBill) == model.NO { // continue //} // //riderInfo = &utils.RiderInfo{ // OrderId: fakeWayBill[0].VendorOrderID, // ThirdCarrierOrderId: fakeWayBill[0].VendorWaybillID, // //CourierName: fakeWayBill[0].CourierName, // //CourierPhone: fakeWayBill[0].CourierMobile, // LogisticsProviderCode: "10002", // LogisticsStatus: fakeWayBill[0].Status, //} //makeRiderInfo(fakeWayBill[0], riderInfo) } taoDeliveryStatus := "" switch v.Status { case 5: // 呼叫骑手 riderInfo.LogisticsStatus = 0 riderInfo.OpCode = tiktok_api.TiktokLogisticsStatusCALLRIDER case 12: // 骑手接单 riderInfo.LogisticsStatus = 10 riderInfo.OpCode = tiktok_api.TiktokLogisticsORDERRECEIVED case 15: // 到店 riderInfo.LogisticsStatus = 15 riderInfo.OpCode = tiktok_api.TiktokLogisticsRIDERARRIVED case 20: //配送中 riderInfo.LogisticsStatus = 20 riderInfo.OpCode = tiktok_api.TiktokLogisticsRIDERPICKUP taoDeliveryStatus = tao_vegetable.OrderStatusDelivery // 配送中 case 110: // 完成 riderInfo.LogisticsStatus = 40 riderInfo.OpCode = tiktok_api.TiktokLogisticsDELIVERED taoDeliveryStatus = tao_vegetable.OrderStatusDeliveryOver // 完成 case 105: // 完成 riderInfo.LogisticsStatus = 40 riderInfo.OpCode = tiktok_api.TiktokLogisticsDELIVERED taoDeliveryStatus = tao_vegetable.OrderStatusDeliveryOver // 完成 case 115: // 取消 riderInfo.CourierName = "" riderInfo.CourierPhone = "" riderInfo.LogisticsStatus = 100 riderInfo.OpCode = tiktok_api.TiktokLogisticsCANCELDELIVERY case 22, 0, 120: // 异常配送 riderInfo.LogisticsStatus = 22 riderInfo.OpCode = tiktok_api.TiktokLogisticsINDDELIVERYEXCEPTION taoDeliveryStatus = tao_vegetable.OrderStatusUserRejection // 完成 default: continue } // 有时候运单状态改变之后但是上面的订单状态还没来得及改变,这里覆盖一下(riderInfo.LogisticsStatus 美团状态为准) if wayBillStatus != model.NO { switch wayBillStatus { case 5: // 呼叫骑手 riderInfo.LogisticsStatus = 0 case 12: // 骑手接单 riderInfo.LogisticsStatus = 10 case 15: // 到店 riderInfo.LogisticsStatus = 15 case 20: //配送中 riderInfo.LogisticsStatus = 20 case 110: // 完成 riderInfo.LogisticsStatus = 40 case 105: // 完成 riderInfo.LogisticsStatus = 40 case 115: // 取消 riderInfo.LogisticsStatus = 100 case 22, 0, 120: // 异常配送 riderInfo.LogisticsStatus = 22 default: continue } } storeDetail, err := dao.GetStoreDetail(db, v.JxStoreID, 0, "") if riderInfo.CourierPhone == "" { if err == nil { riderInfo.CourierPhone = storeDetail.Tel1 } riderInfo.CourierName = "老板3" } if riderInfo.Longitude == "" && riderInfo.LogisticsStatus != 105 { riderInfo.Longitude = utils.Float64ToStr(jxutils.IntCoordinate2Standard(storeDetail.Lng)) riderInfo.Latitude = utils.Float64ToStr(jxutils.IntCoordinate2Standard(storeDetail.Lat)) } if riderInfo.Longitude == "" && riderInfo.LogisticsStatus == 105 { riderInfo.Longitude = utils.Float64ToStr(jxutils.IntCoordinate2Standard(v.ConsigneeLng)) riderInfo.Latitude = utils.Float64ToStr(jxutils.IntCoordinate2Standard(v.ConsigneeLat)) } if riderInfo.OrderId == "" { riderInfo.OrderId = v.VendorOrderID // 10001-顺丰, 10002-达达, 10003-闪送, 10004-蜂鸟, 10005 UU跑腿,10006 快跑者, 10007 极客快送,10008-点我达,10009 同达, 10010-生活半径,10011 邻趣,10012 趣送, 10013 快服务 10014 菜鸟新配盟 10015 商家自建配送 10016 风先生,10017-其他,10032-美团跑腿。 riderInfo.LogisticsProviderCode = "10017" } if riderInfo.ThirdCarrierOrderId == "" { riderInfo.ThirdCarrierOrderId = riderInfo.OrderId } switch v.VendorID { case model.VendorIDMTWM: // 美团订单 if handler := partner.GetPurchaseOrderHandlerFromVendorID(v.VendorID); handler != nil { if err := handler.GetOrderRider(v.VendorOrgCode, v.VendorStoreID, utils.Struct2Map(riderInfo, "", true)); err != nil { globals.SugarLogger.Debugf("Error pushing meituan rider information :%s--%s--%v", v.VendorOrderID, utils.Format4Output(riderInfo, false), err) } } case model.VendorIDELM: // 饿了么 continue case model.VendorIDEBAI: // 饿百发单 if orderId == "" { if handler := partner.GetPurchaseOrderHandlerFromVendorID(v.VendorID); handler != nil { if err := handler.GetOrderRider(v.VendorOrgCode, v.VendorStoreID, utils.Struct2Map(riderInfo, "", true)); err != nil { globals.SugarLogger.Debugf("Error pushing ebai rider information :%s--%s--%v", v.VendorOrderID, utils.Format4Output(riderInfo, false), err) } } } else { if err := ebai.OrderDeliveryCoordinate(utils.Struct2Map(riderInfo, "", true)); err != nil { globals.SugarLogger.Debugf("Error pushing ebai OrderStatussync information :%s--%s--%v", v.VendorOrderID, utils.Format4Output(riderInfo, false), err) } } case model.VendorIDJD: // 京东发单 if orderId == "" { // 定时同步骑手坐标 if err = jd.OrderDeliveryCoordinate(v.VendorOrderID, utils.Struct2Map(riderInfo, "", true)); err != nil { globals.SugarLogger.Debugf("Error pushing jd OrderStatussync information :%s--%s--%v", v.VendorOrderID, utils.Format4Output(riderInfo, false), err) } } else { // 同步订单骑手状态 if handler := partner.GetPurchaseOrderHandlerFromVendorID(v.VendorID); handler != nil { if err := handler.GetOrderRider(v.VendorOrgCode, v.VendorStoreID, utils.Struct2Map(riderInfo, "", true)); err != nil { globals.SugarLogger.Debugf("Error pushing jd rider information :%s--%s--%v", v.VendorOrderID, utils.Format4Output(riderInfo, false), err) } } } case model.VendorIDJDShop: // 京东商城 continue case model.VendorIDDD: // 抖店小时达 riderInfo.LogisticsProviderCode = tiktok_api.JxVendorId2TiktokCode(v.WaybillVendorID) if handler := partner.GetPurchaseOrderHandlerFromVendorID(v.VendorID); handler != nil { if err := handler.GetOrderRider(v.VendorOrgCode, v.VendorStoreID, utils.Struct2Map(riderInfo, "", true)); err != nil { globals.SugarLogger.Debugf("Error pushing tiktok rider information :%s--%s--%v", v.VendorOrderID, utils.Format4Output(riderInfo, false), err) } } case model.VendorIDTaoVegetable: // 淘鲜达 // 定时任务刷新骑手坐标 if orderId == "" { if handler := partner.GetPurchaseOrderHandlerFromVendorID(v.VendorID); handler != nil { if err := handler.GetOrderRider(v.VendorOrgCode, v.VendorStoreID, utils.Struct2Map(riderInfo, "", true)); err != nil { globals.SugarLogger.Debugf("Error pushing meituan rider information :%s--%s--%v", v.VendorOrderID, utils.Format4Output(riderInfo, false), err) } } } else { // 订单状态改变 [配送中/用户签收/用户拒收] param := utilsTao.OrderStatusChangeDelivery(&v.GoodsOrder, taoDeliveryStatus) if err := api.TaoVegetableApi.DeliveryFinish(param); err != nil { globals.SugarLogger.Debugf("淘鲜达运单状态推送错误运单状态[%s],错误:%s", taoDeliveryStatus, err.Error()) } } default: globals.SugarLogger.Debugf("Order source error, non system order: %s", v.VendorOrderID) continue } } return } func PullTiktokRiderInfo(riderInfo *utils.RiderInfo, vendorOrgCode string) { switch riderInfo.LogisticsStatus { case 5: // 呼叫骑手 riderInfo.LogisticsStatus = 0 riderInfo.OpCode = tiktok_api.TiktokLogisticsStatusCALLRIDER case 12: // 骑手接单 riderInfo.LogisticsStatus = 12 riderInfo.OpCode = tiktok_api.TiktokLogisticsORDERRECEIVED case 15: // 到店 riderInfo.LogisticsStatus = 15 riderInfo.OpCode = tiktok_api.TiktokLogisticsRIDERARRIVED case 20: //配送中 riderInfo.LogisticsStatus = 20 riderInfo.OpCode = tiktok_api.TiktokLogisticsRIDERPICKUP case 110: // 完成 riderInfo.LogisticsStatus = 40 riderInfo.OpCode = tiktok_api.TiktokLogisticsDELIVERED case 105: // 完成 riderInfo.LogisticsStatus = 40 riderInfo.OpCode = tiktok_api.TiktokLogisticsDELIVERED case 115: // 取消 riderInfo.LogisticsStatus = 100 riderInfo.OpCode = tiktok_api.TiktokLogisticsCANCELDELIVERY case 22, 0, 120: // 异常配送 riderInfo.LogisticsStatus = 22 riderInfo.OpCode = tiktok_api.TiktokLogisticsINDDELIVERYEXCEPTION } if riderInfo.CourierPhone == "" { riderInfo.CourierPhone = " 暂无电话 " } if riderInfo.CourierName == "" { riderInfo.CourierName = " 暂无骑手 " } if riderInfo.LogisticsStatus != 22 && riderInfo.LogisticsStatus != 120 && riderInfo.LogisticsStatus != 0 { riderInfo.LogisticsContext = fmt.Sprintf(riderInfo.LogisticsContext, riderInfo.CourierName, riderInfo.CourierPhone) } // 呼叫骑手的时候推送发货 // 抖店由于发配送时运单id已经固定了,我们系统在重新发货,或者运单号发生改变时去推送信息时.抖店只识别第一个运单号所以在这儿修改成发单时的第一个运单号! paramsMap := utils.Struct2Map(riderInfo, "", true) if handler := partner.GetPurchaseOrderHandlerFromVendorID(model.VendorIDDD); handler != nil { if err := handler.GetOrderRider(vendorOrgCode, "", paramsMap); err != nil { globals.SugarLogger.Errorf("PullTiktokRiderInfo Err %s", err.Error()) } } } // UpdateOrder2Complete 将以过期订单状态为配送中的订单修改为完成状态 func UpdateOrder2Complete() { var ( db = dao.GetDB() orders = make([]*model.GoodsOrder, 0, 0) ) sql := `SELECT * FROM goods_order g WHERE g.order_created_at > ? AND g.order_created_at <= ? AND g.status = 20 AND g.waybill_vendor_id = -1 ` sqlParams := []interface{}{ time.Now().AddDate(0, 0, -30), time.Now().AddDate(0, 0, -2), } if err := dao.GetRows(db, &orders, sql, sqlParams...); err != nil { return } for _, v := range orders { if err := defsch.FixedScheduler.SelfDeliveredAndUpdateStatus(jxcontext.AdminCtx, v.VendorOrderID, v.VendorID, jxcontext.AdminCtx.GetUserName()); err == nil { v.Status = model.OrderStatusFinished v.StatusTime = time.Now() dao.UpdateEntity(db, v, "Status", "StatusTime") } } return } func makeRiderInfo(fakeWayBill *model.Waybill, riderInfo *utils.RiderInfo) error { order, _ := partner.CurOrderManager.LoadOrder(fakeWayBill.VendorOrderID, fakeWayBill.OrderVendorID) if order.Status == model.OrderStatusCanceled { return fmt.Errorf(utils.Int2Str(model.OrderStatusCanceled)) } storeId := jxutils.GetSaleStoreIDFromOrder(order) storeDetail, err := dao.GetStoreDetail(dao.GetDB(), storeId, order.VendorID, order.VendorOrgCode) if err != nil || storeDetail == nil { globals.SugarLogger.Debugf("根据订单信息获取门店详情错误:%d %d", storeId, order.VendorID) return fmt.Errorf(utils.Int2Str(model.OrderStatusCanceled)) } waybill2, err := cms.GetSToURidingDistance2(jxutils.IntCoordinate2Standard(storeDetail.Lng), jxutils.IntCoordinate2Standard(storeDetail.Lat), jxutils.IntCoordinate2Standard(order.ConsigneeLng), jxutils.IntCoordinate2Standard(order.ConsigneeLat), fakeWayBill.VendorOrderID, []int64{int64(fakeWayBill.WaybillVendorID)}) if err != nil { ddmsg.SendUserMessage(dingdingapi.MsgTyeText, "2452A93EEB9111EC9B06525400E86DC0", "百度地图骑行方案获取错误:", utils.Format4Output(err.Error(), false)) } courierCoordinate := strings.Split(waybill2.CourierCoordinate, ",") if waybill2.CourierCoordinate == "" && fakeWayBill.Status < model.WaybillStatusDelivered { courierCoordinate = append(courierCoordinate, utils.Float64ToStr(jxutils.IntCoordinate2Standard(storeDetail.Lng)), utils.Float64ToStr(jxutils.IntCoordinate2Standard(storeDetail.Lat))) } if waybill2.CourierCoordinate == "" && fakeWayBill.Status >= model.WaybillStatusDelivered { courierCoordinate = append(courierCoordinate, utils.Float64ToStr(jxutils.IntCoordinate2Standard(order.ConsigneeLng)), utils.Float64ToStr(jxutils.IntCoordinate2Standard(order.ConsigneeLat))) } switch fakeWayBill.Status { case 5: // 呼叫骑手 riderInfo.LogisticsContext = "呼叫骑手,新建运单 %s (%s)" riderInfo.LogisticsStatus = 0 riderInfo.CourierName = "" riderInfo.CourierPhone = "" riderInfo.OpCode = tiktok_api.TiktokLogisticsStatusCALLRIDER riderInfo.Latitude = utils.Float64ToStr(jxutils.IntCoordinate2Standard(storeDetail.Lat)) riderInfo.Longitude = utils.Float64ToStr(jxutils.IntCoordinate2Standard(storeDetail.Lng)) // 下一状态以及推送时间 fakeWayBill.Status = model.WaybillStatusCourierAssigned fakeWayBill.VendorStatus = utils.Int64ToStr(model.WaybillStatusCourierAssigned) case 12: // 骑手接单 riderInfo.LogisticsContext = model.RiderWaitGetGoods riderInfo.LogisticsStatus = 10 riderInfo.OpCode = tiktok_api.TiktokLogisticsORDERRECEIVED riderInfo.Latitude = courierCoordinate[1] riderInfo.Longitude = courierCoordinate[0] // 下一状态以及推送时间 fakeWayBill.Status = model.WaybillStatusCourierArrived fakeWayBill.VendorStatus = utils.Int64ToStr(model.WaybillStatusCourierArrived) case 15: // 到店 riderInfo.LogisticsContext = model.RiderToStore riderInfo.LogisticsStatus = 15 riderInfo.OpCode = tiktok_api.TiktokLogisticsRIDERARRIVED riderInfo.Latitude = courierCoordinate[1] riderInfo.Longitude = courierCoordinate[0] // 下一状态以及推送时间 fakeWayBill.Status = model.WaybillStatusDelivering fakeWayBill.VendorStatus = utils.Int64ToStr(model.WaybillStatusDelivering) case 20: //配送中 riderInfo.LogisticsContext = model.RiderGetOrderDelivering riderInfo.LogisticsStatus = 20 riderInfo.OpCode = tiktok_api.TiktokLogisticsRIDERPICKUP riderInfo.Latitude = courierCoordinate[1] riderInfo.Longitude = courierCoordinate[0] // 下一状态以及推送时间 fakeWayBill.Status = model.WaybillStatusDelivered fakeWayBill.VendorStatus = utils.Int64ToStr(model.WaybillStatusDelivered) case 105: // 完成 riderInfo.LogisticsContext = model.RiderGetOrderDelivered riderInfo.LogisticsStatus = 40 riderInfo.OpCode = tiktok_api.TiktokLogisticsDELIVERED riderInfo.Latitude = courierCoordinate[1] riderInfo.Longitude = courierCoordinate[0] // 下一状态以及推送时间 fakeWayBill.Status = model.WaybillStatusFailed fakeWayBill.VendorStatus = utils.Int64ToStr(model.WaybillStatusFailed) default: return nil } return nil } // UpdateFakeWayBillToTiktok 轮询更新假订单到抖音(抖音/美团/饿百) func UpdateFakeWayBillToTiktok() { fakeWayBill, err := dao.GetWayBillFakeOrder() if err != nil { globals.SugarLogger.Debugf("Get Fake Order Err : %s", err.Error()) return } if len(fakeWayBill) == 0 { return } for i := 0; i < len(fakeWayBill); i++ { // 判断当前订单是否可以推送,UpdatedAt > 当前时间 就跳过 //if fakeWayBill[i].StatusTime.After(time.Now()) { // continue //} riderInfo := &utils.RiderInfo{ OrderId: fakeWayBill[i].VendorOrderID, ThirdCarrierOrderId: fakeWayBill[i].VendorWaybillID, CourierName: fakeWayBill[i].CourierName, CourierPhone: fakeWayBill[i].CourierMobile, LogisticsProviderCode: "10002", LogisticsStatus: fakeWayBill[i].Status, } // 设置骑手和下一状态时间 if err = makeRiderInfo(fakeWayBill[i], riderInfo); err != nil && err.Error() == utils.Int2Str(model.OrderStatusCanceled) { fakeWayBill[i].Status = model.OrderStatusCanceled dao.UpdateEntity(dao.GetDB(), fakeWayBill[i], "Status") continue } if riderInfo.CourierName == "" && fakeWayBill[i].CourierName != "" { riderInfo.CourierName = fakeWayBill[i].CourierName riderInfo.CourierPhone = fakeWayBill[i].CourierMobile } //if riderInfo.CourierName == "" && fakeWayBill[i].CourierName == "" { // riderInfo.CourierName = model.DefaultName // riderInfo.CourierPhone = model.DefaultPhone //} if riderInfo.LogisticsContext != model.RiderGetOrderDeliverFailed && riderInfo.LogisticsContext != model.RiderGetOrderDeliverOther && riderInfo.LogisticsContext != model.RiderWaitRider { riderInfo.LogisticsContext = fmt.Sprintf(riderInfo.LogisticsContext, riderInfo.CourierName, riderInfo.CourierPhone) } if fakeWayBill[i].OrderVendorID == model.VendorIDDD { riderInfo.LogisticsProviderCode = tiktok_api.JxVendorId2TiktokCode(fakeWayBill[i].WaybillVendorID) } order, _ := partner.CurOrderManager.LoadOrder(fakeWayBill[i].VendorOrderID, fakeWayBill[i].OrderVendorID) if riderInfo.Longitude == "" && riderInfo.LogisticsStatus < 40 { storeDetail, _ := dao.GetStoreDetail(dao.GetDB(), order.JxStoreID, order.VendorID, order.VendorOrgCode) riderInfo.Longitude = utils.Float64ToStr(jxutils.IntCoordinate2Standard(storeDetail.Lng)) riderInfo.Latitude = utils.Float64ToStr(jxutils.IntCoordinate2Standard(storeDetail.Lat)) } if riderInfo.Longitude == "" && riderInfo.LogisticsStatus >= 40 { riderInfo.Longitude = utils.Float64ToStr(jxutils.IntCoordinate2Standard(order.ConsigneeLng)) riderInfo.Latitude = utils.Float64ToStr(jxutils.IntCoordinate2Standard(order.ConsigneeLat)) } // 推送骑手信息 paramsMap := utils.Struct2Map(riderInfo, "", true) handler := partner.GetPurchaseOrderHandlerFromVendorID(fakeWayBill[i].OrderVendorID) if handler != nil { if err := handler.GetOrderRider(order.VendorOrgCode, order.VendorStoreID, paramsMap); err != nil { partner.CurOrderManager.OnOrderMsg(order, tao_vegetable.OrderStatusDelivery, fmt.Sprintf("Fake Pull Rider Info Err :%s--%s--%v", riderInfo.OrderId, riderInfo.ThirdCarrierOrderId, err)) } else { partner.CurOrderManager.OnOrderMsg(order, tao_vegetable.OrderStatusDelivery, "订单配送中") } if order.VendorID == model.VendorIDEBAI { ebai.OrderDeliveryCoordinate(utils.Struct2Map(riderInfo, "", true)) } else if order.VendorID == model.VendorIDJD { jd.OrderDeliveryCoordinate(order.VendorOrgCode, utils.Struct2Map(riderInfo, "", true)) } } // 还没到下一状态时间 if fakeWayBill[i].StatusTime.After(time.Now()) { continue } // //allTime := order.ExpectedDeliveredTime.Unix() - order.OrderCreatedAt.Unix() //nowTime := time.Now().Unix() - order.OrderCreatedAt.Unix() //float64(nowTime)/float64(allTime) randNumber, _ := rand.Int(rand.Reader, big.NewInt(800)) randTime := randNumber.Int64() if randTime < 300 { randTime += 300 } if fakeWayBill[i].Status < model.WaybillStatusDelivering { randTime = 120 } if fakeWayBill[i].Status == model.WaybillStatusDelivered && order.ExpectedDeliveredTime.Unix()-time.Now().Unix() <= 120 { fakeWayBill[i].StatusTime = time.Now() } else { fakeWayBill[i].StatusTime = time.Now().Add(time.Duration(randTime) * time.Second).Local() } fakeWayBill[i].WaybillFinishedAt = time.Now() // 更新假运单 if _, err := dao.UpdateEntity(dao.GetDB(), fakeWayBill[i], "Status", "VendorStatus", "StatusTime", "WaybillFinishedAt"); err != nil { globals.SugarLogger.Errorf("Update Fake Way Bill Err:%s--%s--%v", riderInfo.OrderId, riderInfo.ThirdCarrierOrderId, err) } // 更新运单为完成状态 if fakeWayBill[i].Status == model.WaybillStatusDelivered { sql := `UPDATE goods_order g SET g.status = ?,g.vendor_status = ?,g.order_finished_at = ? WHERE g.vendor_order_id = ? ` _, err = dao.ExecuteSQL(dao.GetDB(), sql, []interface{}{model.OrderStatusFinished, model.OrderStatusFinished, time.Now(), fakeWayBill[i].VendorOrderID}...) if err != nil { globals.SugarLogger.Debugf("UPDATA goods_order Err :%s", err.Error()) } order, _ := partner.CurOrderManager.LoadOrder(fakeWayBill[i].VendorOrderID, fakeWayBill[i].OrderVendorID) if order.Status == model.OrderStatusCanceled { continue } // 饿百订单推送订单送达 if fakeWayBill[i].OrderVendorID == model.VendorIDEBAI || fakeWayBill[i].OrderVendorID == model.VendorIDJD || fakeWayBill[i].OrderVendorID == model.VendorIDTaoVegetable || fakeWayBill[i].OrderVendorID == model.VendorIDMTWM { if err := handler.Swtich2SelfDelivered(order, "JingXiAdmin"); err != nil { partner.CurOrderManager.OnOrderMsg(order, tao_vegetable.OrderStatusDeliveryOver, fmt.Sprintf("%v", err)) } else { partner.CurOrderManager.OnOrderMsg(order, tao_vegetable.OrderStatusDeliveryOver, "订单送达") } } } } } // LoadingStoreOrderSettleAmount 获取平台门店的结算信息(订单的配送费和准时保险费/运费) func LoadingStoreOrderSettleAmount(startTime, endTime int64, jxStoreId []int) error { var ( db = dao.GetDB() now = time.Now() from = time.Date(now.Year(), now.Month(), now.Day()-4, 0, 0, 0, 0, time.Local).Unix() to = time.Date(now.Year(), now.Month(), now.Day()-1, 23, 59, 59, 59, time.Local).Unix() ) if startTime != 0 && endTime != 0 { from = startTime to = endTime } storeMapList, err := dao.GetStoresMapList(db, []int{model.VendorIDMTWM}, jxStoreId, []int{model.StoreStatusClosed, model.StoreStatusHaveRest, model.StoreStatusOpened}, model.StoreStatusAll, model.StoreIsSyncAll, "", "", "") if err != nil || len(storeMapList) == model.NO { globals.SugarLogger.Errorf("获取美团门店列表异常: %v", err) return err } taskFunc := func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { storeListValue := batchItemList[0].(*model.StoreMap) billListParam := &mtwmapi.Bill{ AppPoiCode: storeListValue.VendorStoreID, StartDate: from, EndDate: to, Offset: 0, Limit: 200, } storeOrder, settleId, err := mtwm.GetAPI(storeListValue.VendorOrgCode, storeListValue.StoreID, storeListValue.VendorStoreID).GetStoreBillList(billListParam) if err != nil { globals.SugarLogger.Debugf("GetStoreBillList err : %v", err) return nil, err } // 如果收款账户为京西的收款账户,则此门店不是服务商(否则是服务商,使用门店发单[需要自己的账户充值金额才行]!) if settleId != 0 { if settleId != model.NO && jxSettleIdMap[settleId] { brandSql := `UPDATE store_map s SET s.create_delivery_type = ?,s.is_service = ? WHERE s.vendor_store_id = ? AND s.deleted_at = ?` if _, err := dao.ExecuteSQL(db, brandSql, []interface{}{model.NO, model.NO, storeListValue.VendorStoreID, utils.DefaultTimeValue}...); err != nil { globals.SugarLogger.Debugf("将门店修改为非服务商和系统发单: %v", err) } } else { brandSql := `UPDATE store_map s SET s.create_delivery_type = ?,s.is_service = ? WHERE s.vendor_store_id = ? AND s.deleted_at = ?` if _, err := dao.ExecuteSQL(db, brandSql, []interface{}{model.YES, model.YES, storeListValue.VendorStoreID, utils.DefaultTimeValue}...); err != nil { globals.SugarLogger.Debugf("将门店修改为服务商和门店发单: %v", err) } } } for _, so := range storeOrder { goodsOrder, _ := partner.CurOrderManager.LoadOrder(so.OrderId, model.VendorIDMTWM) // 更新订单的结算信息 if so.PlatformSettlement > 0 && goodsOrder != nil { dao.UpdateEntity(db, goodsOrder, "TotalShopMoney") //goodsOrderSql := `UPDATE goods_order g SET g.total_shop_money = ? WHERE g.vendor_order_id = ? ` //if _, err := dao.ExecuteSQL(db, goodsOrderSql, []interface{}{so.PlatformSettlement, so.OrderId}...); err != nil { // globals.SugarLogger.Debugf("更新订单结算信息错误: %v", err) //} } // 更新订单的配送信息 //if goodsOrder.JxStoreID == 804947 { // if so.TimingFee != 0 || so.DeliveryFee != 0 { // if so.TimingFee < 0 { // so.TimingFee = so.TimingFee * -1 // } // if so.DeliveryFee < 0 { // so.DeliveryFee = so.DeliveryFee * -1 // } // wayBillSql := `UPDATE waybill w SET w.desired_fee = ?,w.punctual_fee = ? WHERE w.vendor_order_id = ? AND w.vendor_waybill_id = ? ` // if _, err := dao.ExecuteSQL(db, wayBillSql, []interface{}{so.DeliveryFee, so.TimingFee, so.OrderId, so.OrderId}...); err != nil { // globals.SugarLogger.Debugf("更新订单物流结算信息错误: %v", err) // } // } //} } return retVal, err } task := tasksch.NewParallelTask("更新美团订单配送费/保险费/结算信息", tasksch.NewParallelConfig().SetParallelCount(4), jxcontext.AdminCtx, taskFunc, storeMapList) tasksch.HandleTask(task, nil, true).Run() if _, err = task.GetResult(0); err != nil { baseapi.SugarLogger.Debugf("LoadingStoreOrderSettleAmount :%v", err) return err } return nil } func GetVendorRiderInfo(wayBillVendorId, vendorId int, vendorOrderId, vendorWaybillId string) (riderInfo *utils.RiderInfo, err error) { riderInfo = &utils.RiderInfo{} if handlerInfo := partner.GetDeliveryPlatformFromVendorID(wayBillVendorId); handlerInfo != nil { if wayBillVendorId == model.VendorIDDada || wayBillVendorId == model.VendorIDFengNiao || wayBillVendorId == model.VendorIDUUPT { riderInfo, err = handlerInfo.Handler.GetRiderInfo(vendorOrderId, 0, vendorWaybillId) if err != nil { return nil, err } } else if wayBillVendorId == model.VendorIDMTPS { riderInfo, err = handlerInfo.Handler.GetRiderInfo(vendorOrderId, time.Now().Unix()+1000000, vendorWaybillId) if err != nil { return nil, err } } } if riderInfo.Longitude == "" || riderInfo.Latitude == "" { order, err := partner.CurOrderManager.LoadOrder(vendorOrderId, vendorId) if err != nil { return nil, err } if order.Status >= model.OrderStatusEndBegin { riderInfo.Longitude = utils.Float64ToStr(jxutils.IntCoordinate2Standard(order.ConsigneeLng)) riderInfo.Latitude = utils.Float64ToStr(jxutils.IntCoordinate2Standard(order.ConsigneeLat)) } else { store, err := dao.GetStoreDetail(dao.GetDB(), order.JxStoreID, order.VendorID, order.VendorOrgCode) if err != nil { return nil, err } riderInfo.Longitude = utils.Float64ToStr(jxutils.IntCoordinate2Standard(store.Lng)) riderInfo.Latitude = utils.Float64ToStr(jxutils.IntCoordinate2Standard(store.Lat)) } } if riderInfo.CourierName != "" && riderInfo.CourierPhone != "" { riderInfo.LogisticsContext = fmt.Sprintf(riderInfo.LogisticsContext, riderInfo.CourierName, riderInfo.CourierPhone) } else { riderInfo.LogisticsContext = fmt.Sprintf(riderInfo.LogisticsContext, "暂无", "暂无") } return }