243 lines
8.2 KiB
Go
243 lines
8.2 KiB
Go
package ebaiapi
|
||
|
||
import (
|
||
"errors"
|
||
"fmt"
|
||
"git.rosy.net.cn/baseapi"
|
||
"git.rosy.net.cn/baseapi/utils"
|
||
"net/http"
|
||
"net/url"
|
||
)
|
||
|
||
const (
|
||
CmdOrderCreate = "order.create"
|
||
CmdOrderDeliveryStatus = "order.deliveryStatus.push"
|
||
CmdOrderPartRefund = "order.partrefund.push" // 售前只能是商户发起 售后是用户, 你看是由谁发起的就可以知道,来自惠焕
|
||
CmdOrderStatus = "order.status.push"
|
||
CmdOrderUserCancel = "order.user.cancel"
|
||
|
||
CmdShopMsgPush = "shop.msg.push"
|
||
CmdShopBindMsg = "shop.bind.msg"
|
||
CmdShopUnbindMsg = "shop.unbind.msg"
|
||
|
||
//IM消息回调通知
|
||
CmdImMessageSendEvent = "im.message.send.event" //用户/骑手消息通知
|
||
CmdImMessageReadEvent = "im.message.read.event" //用户/骑手已读通知
|
||
|
||
)
|
||
|
||
type CallbackResponse struct {
|
||
Cmd string `json:"cmd"`
|
||
Sign string `json:"sign"`
|
||
Source string `json:"source"`
|
||
Ticket string `json:"ticket"`
|
||
Encrypt string `json:"encrypt"`
|
||
Timestamp int64 `json:"timestamp"`
|
||
Version int `json:"version"`
|
||
Body *ResponseResult `json:"body"`
|
||
}
|
||
|
||
type CallbackMsg struct {
|
||
Cmd string `json:"cmd"`
|
||
Version string `json:"version"`
|
||
Timestamp int64 `json:"timestamp"`
|
||
Ticket string `json:"ticket"`
|
||
Source string `json:"source"`
|
||
Sign string `json:"sign"`
|
||
Encrypt string `json:"encrypt"`
|
||
|
||
Body map[string]interface{} `json:"body"`
|
||
Data interface{} `json:"data"`
|
||
}
|
||
|
||
type EBaiShopList struct {
|
||
BaiduShopID string `json:"baidu_shop_id"`
|
||
ShopID string `json:"shop_id"`
|
||
Name string `json:"name"`
|
||
Source string `json:"source"`
|
||
SupplierID string `json:"supplier_id"`
|
||
}
|
||
|
||
type CBPartRefundInfo struct {
|
||
OrderID int64 `json:"order_id"`
|
||
RefundID string `json:"refund_id"`
|
||
Type int `json:"type"`
|
||
Status int `json:"status"`
|
||
AdditionReason string `json:"addition_reason"`
|
||
Photos []string `json:"photos"`
|
||
ReasonType string `json:"reason_type"`
|
||
Reason string `json:"reason"`
|
||
RefundProducts []*struct {
|
||
SkuID string `json:"sku_id"`
|
||
Upc string `json:"upc"`
|
||
CustomSkuID string `json:"custom_sku_id"`
|
||
Name string `json:"name"`
|
||
Number int `json:"number"`
|
||
TotalRefund int64 `json:"total_refund"`
|
||
ShopEleRefund int64 `json:"shop_ele_refund"`
|
||
} `json:"refund_products"`
|
||
RefundPrice int64 `json:"refund_price"`
|
||
}
|
||
|
||
type CBUserCancelInfo struct {
|
||
OrderID int64 `json:"order_id"`
|
||
CancelReason string `json:"cancel_reason"`
|
||
AdditionReason string `json:"addition_reason"`
|
||
RefuseReason string `json:"refuse_reason"`
|
||
Pictures []string `json:"pictures"`
|
||
Type int `json:"type"`
|
||
CancelType int `json:"cancel_type"`
|
||
}
|
||
|
||
//temp IM 用户/骑手消息通知
|
||
type TempSent struct {
|
||
SubBizType string `json:"subBizType"` //业务子类型,枚举值:SEND_MESSAGE-发送消息
|
||
BizType string `json:"bizType"` //业务类型,枚举值:IM-消息
|
||
PayLoad struct {
|
||
SenderID string `json:"senderId"` //角色+随机数字串;角色:10(用户)、20(骑手)、30(商家)、32(连锁账号登录)
|
||
ReceiverIDs []string `json:"receiverIds"` //角色+随机数字串;角色:10(用户)、20(骑手)、30(商家)、32(连锁账号登录)
|
||
CreateTime int64 `json:"createTime"` //时间戳
|
||
GroupID string `json:"groupId"` //会话id
|
||
MsgID string `json:"msgId"` //消息ID
|
||
ContentType int `json:"contentType"` //消息类型,枚举值:1-普通文本
|
||
} `json:"payload"`
|
||
PlatformShopID string `json:"platformShopId"` //平台门店ID
|
||
}
|
||
|
||
//IM 用户/骑手消息通知
|
||
type ImMessageSend struct {
|
||
SubBizType string `json:"subBizType"` //业务子类型,枚举值:SEND_MESSAGE-发送消息
|
||
BizType string `json:"bizType"` //业务类型,枚举值:IM-消息
|
||
PayLoad PayLoad `json:"payLoad"`
|
||
PlatformShopID string `json:"platformShopId"` //平台门店ID
|
||
}
|
||
type PayLoad struct {
|
||
SenderID string `json:"senderId"` //角色+随机数字串;角色:10(用户)、20(骑手)、30(商家)、32(连锁账号登录)
|
||
ReceiverIDs []string `json:"receiverIds"` //角色+随机数字串;角色:10(用户)、20(骑手)、30(商家)、32(连锁账号登录)
|
||
CreateTime int64 `json:"createTime"` //时间戳
|
||
GroupID string `json:"groupId"` //会话id
|
||
MsgID string `json:"msgId"` //消息ID
|
||
ContentType int `json:"contentType"` //消息类型,枚举值:1-普通文本
|
||
Content string `json:"content"`
|
||
}
|
||
|
||
//ContentType =1-普通文本,8-@消息
|
||
type Content struct {
|
||
Text string `json:"text"`
|
||
}
|
||
|
||
//IM 用户/骑手已读通知
|
||
type ImMessageRead struct {
|
||
PlatformShopID string `json:"platformShopId"` //平台门店ID
|
||
BizType string `json:"bizType"` //业务类型,枚举值:IM-消息
|
||
SubBizType string `json:"subBizType"` //业务子类型,枚举值:READ_MESSAGE-读取消息
|
||
PayLoad struct {
|
||
MsgIDs string `json:"msgIds"` //消息ID 列表
|
||
CID string `json:"cid"` //会话id
|
||
UID string `json:"uid"` //已读操作人
|
||
} `json:"payLoad"`
|
||
}
|
||
|
||
func (a *API) Err2CallbackResponse(cmd string, err error, data interface{}) *CallbackResponse {
|
||
response := &CallbackResponse{
|
||
Cmd: "resp." + cmd,
|
||
Source: a.source,
|
||
Ticket: utils.GetUpperUUID(),
|
||
Timestamp: utils.GetCurTimestamp(),
|
||
Version: 3,
|
||
}
|
||
if err == nil {
|
||
response.Body = &ResponseResult{
|
||
Error: "success",
|
||
ErrNo: 0,
|
||
Data: data,
|
||
}
|
||
} else {
|
||
response.Body = &ResponseResult{
|
||
Error: fmt.Sprintf("error:%v, data:%v", err, data),
|
||
ErrNo: -1,
|
||
Data: data,
|
||
}
|
||
}
|
||
params := url.Values{
|
||
"cmd": []string{response.Cmd},
|
||
"version": []string{utils.Int2Str(response.Version)},
|
||
"timestamp": []string{utils.Int64ToStr(response.Timestamp)},
|
||
"ticket": []string{response.Ticket},
|
||
"source": []string{response.Source},
|
||
"body": []string{string(utils.MustMarshal(response.Body))},
|
||
"encrypt": []string{""},
|
||
}
|
||
response.Sign = a.signParams(params)
|
||
return response
|
||
}
|
||
|
||
func (a *API) unmarshalData(cmd string, data []byte, msg interface{}) (callbackResponse *CallbackResponse) {
|
||
err := utils.UnmarshalUseNumber(data, msg)
|
||
if err != nil {
|
||
return a.Err2CallbackResponse(cmd, err, nil)
|
||
}
|
||
return nil
|
||
}
|
||
|
||
func (a *API) CheckCallbackValidation(cmd string, params url.Values) (callbackResponse *CallbackResponse) {
|
||
sign := a.signParams(params)
|
||
if sign != params.Get(signKey) {
|
||
msg := fmt.Sprintf("Signature is not ok, mine:%v, get:%v", sign, params.Get(signKey))
|
||
baseapi.SugarLogger.Info(msg)
|
||
return a.Err2CallbackResponse(cmd, errors.New(msg), nil)
|
||
}
|
||
return nil
|
||
}
|
||
|
||
func (a *API) GetCallbackMsg(request *http.Request) (msg *CallbackMsg, callbackResponse *CallbackResponse) {
|
||
err := request.ParseForm()
|
||
if err == nil {
|
||
params := make(url.Values)
|
||
for k := range request.PostForm {
|
||
decodedValue, _ := url.QueryUnescape(request.PostFormValue(k))
|
||
params.Set(k, decodedValue)
|
||
}
|
||
msg = new(CallbackMsg)
|
||
msg.Cmd = GetCmd(request)
|
||
if callbackResponse = a.CheckCallbackValidation(msg.Cmd, params); callbackResponse != nil {
|
||
return nil, callbackResponse
|
||
}
|
||
if callbackResponse = a.unmarshalData(msg.Cmd, []byte(params.Get("body")), &msg.Body); callbackResponse != nil {
|
||
return nil, callbackResponse
|
||
}
|
||
msg.Timestamp = utils.Str2Int64(params.Get("timestamp"))
|
||
msg.Version = params.Get("version")
|
||
msg.Ticket = params.Get("ticket")
|
||
msg.Source = params.Get("source")
|
||
msg.Sign = params.Get("sign")
|
||
msg.Encrypt = params.Get("encrypt")
|
||
|
||
var tmpObj interface{}
|
||
switch msg.Cmd {
|
||
case CmdOrderPartRefund:
|
||
var partRefundData CBPartRefundInfo
|
||
tmpObj = &partRefundData
|
||
case CmdOrderUserCancel:
|
||
var userCancelData CBUserCancelInfo
|
||
tmpObj = &userCancelData
|
||
case CmdImMessageSendEvent:
|
||
tmpObj = &ImMessageSend{}
|
||
case CmdImMessageReadEvent:
|
||
tmpObj = &ImMessageRead{}
|
||
}
|
||
if tmpObj != nil {
|
||
if utils.Map2StructByJson(msg.Body, tmpObj, true) == nil {
|
||
msg.Data = tmpObj
|
||
}
|
||
}
|
||
return msg, nil
|
||
}
|
||
return nil, a.Err2CallbackResponse("", err, nil)
|
||
}
|
||
|
||
func GetCmd(request *http.Request) (cmd string) {
|
||
cmd, _ = url.QueryUnescape(request.FormValue("cmd"))
|
||
return cmd
|
||
}
|