diff --git a/platformapi/ebaiapi/order_test.go b/platformapi/ebaiapi/order_test.go index d473fd86..21171185 100644 --- a/platformapi/ebaiapi/order_test.go +++ b/platformapi/ebaiapi/order_test.go @@ -18,7 +18,7 @@ func TestCancelOrder(t *testing.T) { } func TestOrderGet(t *testing.T) { - result, err := api.OrderGet("4042556041071971860") + result, err := api.OrderGet("4073360274750788248") products := result["products"].([]interface{})[0].([]interface{}) for _, product2 := range products { product := product2.(map[string]interface{}) diff --git a/platformapi/ebaiapi/shop_sku_test.go b/platformapi/ebaiapi/shop_sku_test.go index 9992ac55..9f6e44e5 100644 --- a/platformapi/ebaiapi/shop_sku_test.go +++ b/platformapi/ebaiapi/shop_sku_test.go @@ -372,5 +372,5 @@ func TestDeleteSku(t *testing.T) { } func TestCategoryAttrValueList(t *testing.T) { - api.CategoryAttrValueList(201220238, "666667") + api.CategoryAttrValueList(201232923, "666667") } diff --git a/platformapi/jdapi/im.go b/platformapi/jdapi/im.go index c61d5009..c4b3b8a6 100644 --- a/platformapi/jdapi/im.go +++ b/platformapi/jdapi/im.go @@ -1,6 +1,106 @@ package jdapi -// ImStatusModify 开启全平台或者单门店im通知 -func (a *API) ImStatusModify(waiterPin, stationId string, typePattern int, status bool) { +import ( + "fmt" + "git.rosy.net.cn/baseapi/utils" + "io/ioutil" + "net/http" + "time" +) +const ( + ImCallbackRisMsg = "chatRiskMsg" // 风控消息 + ImCallbackUserMsg = "msChatMessage" // 用户消息 + ImCallbackReadMsg = "msgReadAck" // 消息已读 +) + +//#region im信息推送相关 + +// ImStatusModify 开启全平台或者单门店im通知 +func (a *API) ImStatusModify(waiterPin, stationId string, typePattern int, status bool) error { + parameter := map[string]interface{}{ + "stationId": stationId, + "type": typePattern, + "openStatus": status, + } + _, err := a.AccessAPINoPage("ImMultiChatRpc/imStatusModify", parameter, nil, nil, genNoPageResultParser("code", "msg", "result", "0")) + if err != nil { + return err + } + return nil } + +// ImWaiterStatusModify 门店客服状态控制 0:下线;1:在线 +func (a *API) ImWaiterStatusModify(clientType int, stationId string, presence int) error { + parameter := map[string]interface{}{ + "stationId": stationId, + "clientType": clientType, + "presence": presence, + } + _, err := a.AccessAPINoPage("ImMultiChatRpc/waiterStatusModify", parameter, nil, nil, genNoPageResultParser("code", "msg", "data", "成功")) + if err != nil { + return err + } + return nil +} + +// MessagePushService 给京东用户推送消息 https://scene-control-access-pro.pf.jd.com/#/flow-center(咚咚场景化消息接入平台) +func (a *API) MessagePushService(msg *ContextMsg) error { + parameter := utils.Struct2Map(msg, "", false) + systemParam := map[string]interface{}{ + "aspid": "P0000201", // 可在“咚咚场景化消息接入平台 - 产品线 - 基础信息”中查看 + "accessid": utils.GetUUID(), // 访问ID,可用于请求去重 + "timestamp": time.Now().UnixNano(), + "version": "3.0", + "accessToken": "af1aa6a267849b3f9f4caa19e1ad5564", // 咚咚场景化消息接入平台 - 产品线 - 基础信息 + } + + result, err := a.AccessAPINoPage("MessagePushService/push2", utils.MergeMaps(parameter, systemParam), nil, nil, genNoPageResultParser("code", "msg", "result", "0")) + if err != nil { + return err + } + fmt.Println(result) + return nil +} + +//#endregion + +//#region im回到信息相关 + +// ImChatRiskMsg IM(风控,用户消息,消息已读)消息推送 +func ImChatRiskMsg(request *http.Request) (back []byte, url string, err error) { + msgURL := getMsgURLFromRequest(request) + data, err := ioutil.ReadAll(request.Body) + if err != nil { + return nil, "", err + } + return data, msgURL, err +} + +func ImMsgChange(msg *ChatRisMsgCallback, msgURL string) (info *ChatRisInfo, user *UserChatMsg, read *UserMsgReadAck, err error) { + var msgContext *ChatRisInfo + var userMsg *UserChatMsg + var redMsg *UserMsgReadAck + + switch msgURL { + case ImCallbackRisMsg: // 风控消息 + if err = utils.UnmarshalUseNumber([]byte(msg.ExtendJsonData), &msgContext); err != nil { + return nil, nil, nil, err + } + return msgContext, nil, nil, err + case ImCallbackUserMsg: // 用户消息 + if err = utils.UnmarshalUseNumber([]byte(msg.ExtendJsonData), &userMsg); err != nil { + return nil, nil, nil, err + } + return nil, userMsg, nil, err + case ImCallbackReadMsg: //推送用户消息已读状态 + if err = utils.UnmarshalUseNumber([]byte(msg.ExtendJsonData), &redMsg); err != nil { + return nil, nil, nil, err + } + return nil, nil, redMsg, err + } + + return nil, nil, nil, fmt.Errorf("%s,暂无此类消息推送", msg) +} + +//#endregion diff --git a/platformapi/jdapi/im_model.go b/platformapi/jdapi/im_model.go new file mode 100644 index 00000000..e22b359e --- /dev/null +++ b/platformapi/jdapi/im_model.go @@ -0,0 +1,121 @@ +package jdapi + +type ContextFrom struct { + Pin string `json:"pin"` // 发送消息的账号,从接收消息MQ里面取 + App string `json:"app"` // im.waiter 固定值 + ClientType string `json:"clientType"` // gw 固定值 +} + +type ContextTo struct { + Pin string `json:"pin"` // 消息接收者的账号, 从接收消息MQ里面取 + App string `json:"app"` // im.customer 固定值 +} + +type ContextBody struct { + Type string `json:"type"` // 消息类型,根据需求场景 + Content string `json:"content"` // 字符型,必须。文本消息内容。 + Chatinfo ContextBodyChatInfo `json:"chatinfo"` + Template struct { + Source string `json:"source"` // dd_msg_产品线标识_消息标识“ 卡片类消息必传 + } `json:"template"` + Mt int `json:"mt"` +} +type ContextBodyChatInfo struct { + VenderId string `json:"venderId"` // 服务商id,从接收消息MQ里面取 + AskAllocateType string `json:"askAllocateType"` // multiChat 固定值 + Sid string `json:"sid"` // 从接收消息MQ里面取 + Source string `json:"source"` // dd_msg_产品线标识_消息标识“ 必传 +} + +// ContextMsg 消息发送接口 - 向用户发送在线消息 +type ContextMsg struct { + Id string `json:"id"` // uuid 随机生成字符串 + Lang string `json:"lang"` // 固定值 zh_CN + Type string `json:"type"` // 固定值 chat_message + From ContextFrom `json:"from"` + To ContextTo `json:"to"` + //Body ContextBody `json:"body"` + Body interface{} `json:"body"` + Timestamp int64 `json:"timestamp"` + ClientTime int64 `json:"clientTime"` +} + +type BaseInfo struct { + AppKey string `json:"app_key"` + Token string `json:"token"` + Timestamp string `json:"timestamp"` + Sign string `json:"sign"` + Format string `json:"format"` + V string `json:"v"` +} + +// ChatRisMsgCallback 风控消息 +type ChatRisMsgCallback struct { + BaseInfo + StationId string `json:"stationId"` // 秒送门店ID + VenderId string `json:"venderId"` // 秒送商家ID + ExtendJsonData string `json:"extendJsonData"` +} + +type ChatRisInfo struct { + RiskType int `json:"riskType"` // 风控类型:1: 风控平台, 2: 商家自己设置敏感词, 3: 开放平台 + RiskCode string `json:"riskCode"` // 风控文案 + From struct { + App string `json:"app"` + Art string `json:"art"` + ClientType string `json:"clientType"` + Pin string `json:"pin"` + } `json:"from"` // 发送方消息 + To struct { + App string `json:"app"` + Pin string `json:"pin"` + } `json:"to"` // 接收方消息 + Type string `json:"type"` // 消息类型 + Body interface{} `json:"body"` // 消息信息 + Timestamp int64 `json:"timestamp"` // 时间 + Sid string `json:"sid"` // 客服咨询业务的会话ID[与接收的消息体里面的sid关联,属于同一会话] + Id string `json:"id"` // 咚咚聊天消息唯一ID[即chat_message消息体内的id字段] +} + +// UserChatMsg 用户消息推送 +type UserChatMsg struct { + Id string `json:"id"` // 咚咚聊天消息唯一ID[即chat_message消息体内的id字段] + Lang string `json:"lang"` // 语言类型 + Type string `json:"type"` + From struct { + Pin string `json:"pin"` // 发送消息的账号 + App string `json:"app"` // 发送消息的app + ClientType string `json:"clientType"` // 发送消息终端 + } `json:"from"` + To struct { + Pin string `json:"pin"` // 消息接收者的账号 + App string `json:"app"` // 接收消息的app + ClientType string `json:"clientType"` // 接收消息的终端" + } `json:"to"` + Body interface{} `json:"body"` + Timestamp int64 `json:"timestamp"` + ClientTime int64 `json:"clientTime"` +} + +// UserMsgReadAck 已读消息推送 +type UserMsgReadAck struct { + Timestamp int64 `json:"timestamp"` + To struct { + App string `json:"app"` + Pin string `json:"pin"` + } `json:"to"` + Body interface{} `json:"body"` + From struct { + App string `json:"app"` + Pin string `json:"pin"` + } `json:"from"` + Datetime int64 `json:"datetime"` + Type string `json:"type"` +} + +// JxSendData 京西回复京东用户消息 +type JxSendData struct { + FromPin string `json:"from_pin"` + ToPin string `json:"to_pin"` + Content string `json:"content"` +} diff --git a/platformapi/jdapi/im_test.go b/platformapi/jdapi/im_test.go index f7c1c046..d20df24b 100644 --- a/platformapi/jdapi/im_test.go +++ b/platformapi/jdapi/im_test.go @@ -16,3 +16,13 @@ func Test12(t *testing.T) { } globals.SugarLogger.Debugf("--:%s", utils.Format4Output(data, false)) } + +// TestImStatusModify 开启关闭门店im +func TestImStatusModify(t *testing.T) { + api.ImStatusModify("", "19854102+320406", 0, true) +} + +// TestImWaiterStatusModify 设置门店im在想状态 +func TestImWaiterStatusModify(t *testing.T) { + api.ImWaiterStatusModify(1, "19854102", 1) +} diff --git a/platformapi/jdapi/jdapi.go b/platformapi/jdapi/jdapi.go index e9e4413d..315b40f6 100644 --- a/platformapi/jdapi/jdapi.go +++ b/platformapi/jdapi/jdapi.go @@ -195,7 +195,6 @@ func (a *API) AccessAPI2(apiStr string, jdParams map[string]interface{}, traceIn userGet = false } params["jd_param_json"] = jdParamStr - err = platformapi.AccessPlatformAPIWithRetry(a.client, func() *http.Request { params["timestamp"] = utils.GetCurTimeStr() diff --git a/platformapi/mtwmapi/retail_test.go b/platformapi/mtwmapi/retail_test.go index ee9812c2..aaefd94a 100644 --- a/platformapi/mtwmapi/retail_test.go +++ b/platformapi/mtwmapi/retail_test.go @@ -394,7 +394,7 @@ func TestRetailRecommendTag(t *testing.T) { // 删除商品 func TestRetailDelete(t *testing.T) { - poiCode := "30400128" + poiCode := "24667579" i := 0 count := 0 @@ -408,6 +408,9 @@ func TestRetailDelete(t *testing.T) { count += len(fromFoodList) for k, v := range fromFoodList { + if v.AppFoodCode == "" { + continue + } if err := api.RetailDelete(utils.Int2Str(k), poiCode, v.AppFoodCode); err != nil { fmt.Println(err) } @@ -424,18 +427,18 @@ func TestRetailDelete(t *testing.T) { // 测试删除门店分类列表 func TestDeleteCat(t *testing.T) { - result, err := api.RetailCatList("20849656") + result, err := api.RetailCatList("24667579") fmt.Println(result, err) for _, v := range result { if v.Children != nil { for _, v2 := range v.Children { - err = api.RetailCatDelete("20849656", "", v2.Name, 1) + err = api.RetailCatDelete("24667579", "", v2.Name, 1) if err != nil { t.Fatal(err) } } } else { - err = api.RetailCatDelete("29913311", "", v.Name, 1) + err = api.RetailCatDelete("24667579", "", v.Name, 1) if err != nil { t.Fatal(err) } diff --git a/platformapi/platformapi.go b/platformapi/platformapi.go index e56eebda..44b2752f 100644 --- a/platformapi/platformapi.go +++ b/platformapi/platformapi.go @@ -122,7 +122,7 @@ func AccessPlatformAPIWithRetry(client *http.Client, handleRequest func() *http. usedMilliSecond := time.Now().Sub(beginTime) / time.Millisecond if err != nil { err, ok := err.(net.Error) - baseapi.SugarLogger.Infof("err %s", err) + baseapi.SugarLogger.Infof("%d,config:%d: err %s", recoverableErrorRetryCount, config.MaxRecoverableRetryCount, err) recoverableErrorRetryCount++ if ok /*&& err.Timeout()*/ && recoverableErrorRetryCount <= config.MaxRecoverableRetryCount { // 只要是网络错误都重试 continue