package controllers import ( "encoding/json" "fmt" "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/purchase/tiktok_store" "github.com/astaxie/beego/server/web" "io/ioutil" "time" ) type LogisticsController struct { web.Controller } //#region 美团物流注册(发货完成时注册) // LogisticsRegisterReq 注册接口请求参数 type LogisticsRegisterReq struct { TrackNo string `json:"track_no"` // 运单号 CallbackUrl string `json:"callback_url"` // 回调地址 Company string `json:"company"` //物流公司编码 } // LogisticsRegisterResp 响应接口 type LogisticsRegisterResp struct { Result bool `json:"result"` ReturnCode string `json:"return_code"` Message string `json:"message"` } // LogisticsRegister 即时配轨迹订阅接口 func (c *LogisticsController) LogisticsRegister() { body, _ := ioutil.ReadAll(c.Ctx.Request.Body) register := &LogisticsRegisterReq{} if err := json.Unmarshal(body, register); err != nil { c.Data["json"] = LogisticsRegisterResp{ Result: false, ReturnCode: "1007", Message: err.Error(), } c.ServeJSON() return } if register.TrackNo == "" { c.Data["json"] = LogisticsRegisterResp{ Result: false, ReturnCode: "1002", Message: "单号不存在", } c.ServeJSON() return } // 查询订单的运单是否存在 data, err := dao.GetWayBillsByWayBillId(dao.GetDB(), register.TrackNo) // 此订单可能是果园订单 if web.BConfig.RunMode != "jxgy" && (len(data) == 0 || err != nil) { resp, err := tiktok_store.HttpToGuoYuan(utils.Struct2Map(register, "", true), tiktok_store.CaiShiPushGyTagDeliveryRegister) if err != nil { c.Data["json"] = LogisticsRegisterResp{ Result: false, ReturnCode: "1002", Message: "单号不存在", } c.ServeJSON() return } gyData := &LogisticsRegisterResp{} gyBody, _ := ioutil.ReadAll(resp.Body) if err := json.Unmarshal(gyBody, gyData); err != nil { c.Data["json"] = LogisticsRegisterResp{ Result: false, ReturnCode: "1002", Message: "单号不存在", } c.ServeJSON() return } c.Data["json"] = gyData c.ServeJSON() } if len(data) == 0 || err != nil { c.Data["json"] = LogisticsRegisterResp{ Result: false, ReturnCode: "1002", Message: "单号不存在", } c.ServeJSON() return } c.Data["json"] = LogisticsRegisterResp{ Result: true, ReturnCode: "200", Message: "", } c.ServeJSON() return } //#endregion //#region 保底物流信息更新 // LogisticsQueryReq 请求参数 type LogisticsQueryReq struct { TrackNo string `json:"track_no"` // 运单号 Company string `json:"company"` // 物流商编码 PhoneLastFour string `json:"phone_last_four"` // 手机号后4位 } // LogisticsQueryRest 响应参数 type LogisticsQueryRest struct { Result bool `json:"result"` // 结果 ReturnCode string `json:"return_code"` // 错误码 Message string `json:"message"` // 错误消息 Data LogisticsQueryData `json:"data"` // 轨迹数据 } type LogisticsQueryData struct { Timestamp string `json:"timestamp"` // 运单状态时间 TrackNo string `json:"track_no"` // 运单号 Traces []TracesList `json:"traces"` // 轨迹列表 } type TracesList struct { Timestamp string `json:"timestamp"` // 当前系统时间 // 事件编码 Opcode string `json:"opcode"` // 文案 Content string `json:"content"` // 骑手信息 Rider RiderInfo `json:"rider"` // 三方运力公司,顺丰同城 sftc 闪送 shansong 达达 dada UU uupt 美团 meituan 蜂鸟 fengniao ThirdPartyCompany string `json:"third_party_company"` // 异常编码 ExceptionCode string `json:"exception_code"` // 异常原因 ExceptionDesc string `json:"exception_desc"` // 取消编码 CancelCode string `json:"cancel_code"` // 取消原因 CancelDesc string `json:"cancel_desc"` } type RiderInfo struct { Name string `json:"name"` // 骑手姓名 Mobile string `json:"mobile"` // 骑手电话号码 } // LogisticsQuery 即时配保底查询接口 func (c *LogisticsController) LogisticsQuery() { body, _ := ioutil.ReadAll(c.Ctx.Request.Body) param := &LogisticsQueryReq{} if err := json.Unmarshal(body, param); err != nil { c.Data["json"] = LogisticsQueryRest{ Result: false, ReturnCode: "1005", Message: "数据解析错误", } c.ServeJSON() return } if param.TrackNo == "" { c.Data["json"] = LogisticsQueryRest{ Result: false, ReturnCode: "1002", Message: "运单账号不存在", } c.ServeJSON() return } // 查询订单的运单是否存在 data, err := dao.GetWayBillsByWayBillId(dao.GetDB(), param.TrackNo) if (err != nil || len(data) == 0) && web.BConfig.RunMode != "jxgy" { resp, err := tiktok_store.HttpToGuoYuan(utils.Struct2Map(param, "", true), tiktok_store.CaiShiPushGyTagDeliveryDetail) if err != nil { c.Data["json"] = LogisticsQueryRest{ Result: false, ReturnCode: "1002", Message: "运单账号不存在", } c.ServeJSON() return } wayBillDetail := &LogisticsQueryRest{} gyBody, _ := ioutil.ReadAll(resp.Body) if err := json.Unmarshal(gyBody, wayBillDetail); err != nil { c.Data["json"] = LogisticsQueryRest{ Result: false, ReturnCode: "1002", Message: "json unmarshal", } c.ServeJSON() return } c.Data["json"] = wayBillDetail c.ServeJSON() } returnParam := &LogisticsQueryRest{ Result: true, ReturnCode: "200", Message: "正常", Data: LogisticsQueryData{ Timestamp: utils.Time2Str(data[0].StatusTime), TrackNo: param.TrackNo, Traces: []TracesList{{ Timestamp: utils.Time2Str(time.Now()), Content: "", ThirdPartyCompany: tiktok_api.TiktokExpressCode, ExceptionCode: "", ExceptionDesc: "", CancelCode: "", CancelDesc: "", Rider: RiderInfo{Name: data[0].CourierName, Mobile: data[0].CourierMobile}, }}, }, } switch data[0].Status { case 5: // 呼叫骑手 returnParam.Data.Traces[0].Opcode = tiktok_api.TiktokLogisticsStatusCALLRIDER returnParam.Data.Traces[0].Content = "呼叫骑手,新建运单" case 10, 12: // 骑手接单 returnParam.Data.Traces[0].Opcode = tiktok_api.TiktokLogisticsORDERRECEIVED returnParam.Data.Traces[0].Content = model.RiderWaitGetGoods case 15: // 到店 returnParam.Data.Traces[0].Opcode = tiktok_api.TiktokLogisticsRIDERARRIVED returnParam.Data.Traces[0].Content = model.RiderToStore case 20: //配送中 returnParam.Data.Traces[0].Opcode = tiktok_api.TiktokLogisticsRIDERPICKUP returnParam.Data.Traces[0].Content = model.RiderGetOrderDelivering case 105, 120: // 完成 returnParam.Data.Traces[0].Opcode = tiktok_api.TiktokLogisticsDELIVERED returnParam.Data.Traces[0].Content = model.RiderGetOrderDelivered case 8, 115: // 取消 returnParam.Data.Traces[0].Opcode = tiktok_api.TiktokLogisticsCANCELDELIVERY returnParam.Data.Traces[0].CancelCode = "3000" // 骑手原因取消 returnParam.Data.Traces[0].CancelDesc = "繁忙" // 骑手原因取消 returnParam.Data.Traces[0].Content = "取消" case 22: //配送异常 returnParam.Data.Traces[0].Opcode = tiktok_api.TiktokLogisticsINDDELIVERYEXCEPTION returnParam.Data.Traces[0].ExceptionCode = "5001" // 服务商系统异常 returnParam.Data.Traces[0].ExceptionDesc = "服务商系统异常" // 服务商系统异常 returnParam.Data.Traces[0].Content = "异常订单/配送" } if returnParam.Data.Traces[0].Rider.Name == "" { returnParam.Data.Traces[0].Rider.Name = " 暂无骑手 " } if returnParam.Data.Traces[0].Rider.Mobile == "" { returnParam.Data.Traces[0].Rider.Mobile = " 暂无电话 " } switch data[0].Status { case 5, 10, 12, 15, 20, 105, 120: returnParam.Data.Traces[0].Content = fmt.Sprintf(returnParam.Data.Traces[0].Content, returnParam.Data.Traces[0].Rider.Name, returnParam.Data.Traces[0].Rider.Mobile) } c.Data["json"] = returnParam c.ServeJSON() } //#endregion