From 930d551962a4f89eca6de96a3373b3fc2e0ee578 Mon Sep 17 00:00:00 2001 From: howell <2827207845@qq.com> Date: Thu, 8 Jul 2021 14:14:03 +0800 Subject: [PATCH] init --- .gitignore | 3 + README.md | 1 + api/auth/refresh.go | 47 ++++++++++ api/mq/base.go | 100 ++++++++++++++++++++++ api/mq/sku.go | 16 ++++ api/mq/test.go | 16 ++++ api/rest/address.go | 41 +++++++++ api/rest/afs/afsAddress.go | 43 ++++++++++ api/rest/afs/afsCanQuery.go | 91 ++++++++++++++++++++ api/rest/afs/afsCancel.go | 57 +++++++++++++ api/rest/afs/afsCreate.go | 53 ++++++++++++ api/rest/afs/afsDetail.go | 73 ++++++++++++++++ api/rest/afs/afsLogisticsPush.go | 44 ++++++++++ api/rest/afs/afsReason.go | 43 ++++++++++ api/rest/base.go | 127 +++++++++++++++++++++++++++ api/rest/logisitics/fee.go | 52 +++++++++++ api/rest/logisitics/logistics.go | 47 ++++++++++ api/rest/logisitics/method.go | 90 ++++++++++++++++++++ api/rest/order/Inventory.go | 69 +++++++++++++++ api/rest/order/Invoice.go | 64 ++++++++++++++ api/rest/order/cancel.go | 59 +++++++++++++ api/rest/order/confirm.go | 32 +++++++ api/rest/order/order.go | 140 ++++++++++++++++++++++++++++++ api/rest/order/pay.go | 54 ++++++++++++ api/rest/order/push.go | 30 +++++++ api/rest/order/query.go | 39 +++++++++ api/rest/order/submit.go | 106 +++++++++++++++++++++++ api/rest/sku/skuDetail.go | 142 +++++++++++++++++++++++++++++++ api/rest/sku/skuList.go | 59 +++++++++++++ api/rest/sku/skuPrice.go | 46 ++++++++++ go.mod | 8 ++ go.sum | 13 +++ util/http/http.go | 66 ++++++++++++++ util/security/md5.go | 31 +++++++ util/security/sha1.go | 37 ++++++++ 35 files changed, 1939 insertions(+) create mode 100644 .gitignore create mode 100644 README.md create mode 100644 api/auth/refresh.go create mode 100644 api/mq/base.go create mode 100644 api/mq/sku.go create mode 100644 api/mq/test.go create mode 100644 api/rest/address.go create mode 100644 api/rest/afs/afsAddress.go create mode 100644 api/rest/afs/afsCanQuery.go create mode 100644 api/rest/afs/afsCancel.go create mode 100644 api/rest/afs/afsCreate.go create mode 100644 api/rest/afs/afsDetail.go create mode 100644 api/rest/afs/afsLogisticsPush.go create mode 100644 api/rest/afs/afsReason.go create mode 100644 api/rest/base.go create mode 100644 api/rest/logisitics/fee.go create mode 100644 api/rest/logisitics/logistics.go create mode 100644 api/rest/logisitics/method.go create mode 100644 api/rest/order/Inventory.go create mode 100644 api/rest/order/Invoice.go create mode 100644 api/rest/order/cancel.go create mode 100644 api/rest/order/confirm.go create mode 100644 api/rest/order/order.go create mode 100644 api/rest/order/pay.go create mode 100644 api/rest/order/push.go create mode 100644 api/rest/order/query.go create mode 100644 api/rest/order/submit.go create mode 100644 api/rest/sku/skuDetail.go create mode 100644 api/rest/sku/skuList.go create mode 100644 api/rest/sku/skuPrice.go create mode 100644 go.mod create mode 100644 go.sum create mode 100644 util/http/http.go create mode 100644 util/security/md5.go create mode 100644 util/security/sha1.go diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..3c27099 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +.idea +test +*_test.go \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..af5dfed --- /dev/null +++ b/README.md @@ -0,0 +1 @@ +``jcook-sdk对接开普勒云相关的接口`` \ No newline at end of file diff --git a/api/auth/refresh.go b/api/auth/refresh.go new file mode 100644 index 0000000..e9733ae --- /dev/null +++ b/api/auth/refresh.go @@ -0,0 +1,47 @@ +package auth + +import ( + "encoding/json" + "fmt" + "git.oa00.com/go/jcook-sdk/util/http" + + "net/url" +) + +const ( + PAppKey = "app_key" + PAppSecret = "app_secret" + PRefreshToken = "refresh_token" + Url = "https://open-oauth.jd.com/oauth2/refresh_token" + PGrantType = "grant_type" +) + +type Bearer struct { + AccessToken string `json:"access_token"` + ExpiresIn uint `json:"expires_in"` + RefreshToken string `json:"refresh_token"` + Scope string `json:"scope"` + UID string `json:"uid"` + Time int64 `json:"time"` + TokenType string `json:"token_type"` + Code uint `json:"code"` + Xid string `json:"xid"` +} + +func RefreshToken(appKey string, appSecret string, token string) (*Bearer, error) { + value := url.Values{} + value.Set(PAppKey, appKey) + value.Set(PAppSecret, appSecret) + value.Set(PRefreshToken, token) + value.Set(PGrantType, "refresh_token") + data, err := http.JGet(Url, value, nil) + if err != nil { + fmt.Println(err.Error()) + return nil, err + } + var b Bearer + if err = json.Unmarshal(data, &b); err != nil { + return nil, err + } + return &b, nil +} diff --git a/api/mq/base.go b/api/mq/base.go new file mode 100644 index 0000000..63759ec --- /dev/null +++ b/api/mq/base.go @@ -0,0 +1,100 @@ +package mq + +import ( + "encoding/json" + "fmt" + "git.oa00.com/go/jcook-sdk/util/http" + "git.oa00.com/go/jcook-sdk/util/security" + "net/url" + "time" +) + +const maxSize = "32" +const autoAck = "false" + +const ( + PTopic = "topic" + PConsumerGroupID = "consumerGroupId" + PSize = "size" + PAck = "ack" + PAccessKey = "accessKey" + PDateTime = "dateTime" + PSignature = "signature" + PToken = "token" + PAckAction = "ackAction" + PAckIndex = "ackIndex" +) + +type Client struct { + AccessKey string + SecretKey string +} + +func NewClient(ak string, sk string) *Client { + return &Client{ + AccessKey: ak, + SecretKey: sk, + } +} + +type UrlBase interface { + GetTopicName() string + GetConsumerGroupID() string + GetEndPoint() string +} + +func getUTCStr() string { + return time.Now().UTC().Format("2006-01-02T15:04:05Z") +} + +func (c *Client) Pull(r UrlBase) ([]byte, error) { + mq := fmt.Sprintf("%s/%s/messages", http.FormatUrl(r.GetEndPoint(), false), "v2") + value := url.Values{} + data := map[string]string{ + PTopic: r.GetTopicName(), + PConsumerGroupID: r.GetConsumerGroupID(), + PSize: maxSize, + PAck: autoAck, + } + + for k, v := range data { + value.Set(k, v) + } + t := getUTCStr() + data[PAccessKey] = c.AccessKey + data[PDateTime] = t + + sign := security.Sha1OrderlyWithBase64(c.SecretKey, data) + + header := map[string]string{ + PAccessKey: c.AccessKey, + PDateTime: t, + PSignature: sign, + } + + return http.JGet(mq, value, header) +} + +func (c *Client) Ack(r UrlBase, index string, action string) ([]byte, error) { + ack := fmt.Sprintf("%s/%s/ack", http.FormatUrl(r.GetEndPoint(), false), "v2") + t := getUTCStr() + data := map[string]string{ + PTopic: r.GetTopicName(), + PAccessKey: c.AccessKey, + PAckAction: action, + PAckIndex: index, + PConsumerGroupID: r.GetConsumerGroupID(), + PDateTime: t, + } + sign := security.Sha1OrderlyWithBase64(c.SecretKey, data) + + header := map[string]string{ + PAccessKey: c.AccessKey, + PDateTime: t, + PSignature: sign, + } + + jsonStr, _ := json.Marshal(&data) + + return http.JPostJson(ack, jsonStr, header) +} diff --git a/api/mq/sku.go b/api/mq/sku.go new file mode 100644 index 0000000..26f853d --- /dev/null +++ b/api/mq/sku.go @@ -0,0 +1,16 @@ +package mq + +type CtSkuChangeChannel struct { +} + +func (t CtSkuChangeChannel) GetTopicName() string { + return "open_message_ct_sku_change_7cf1b0ca92a1d3a2ccdbc07ce014a2c7" +} + +func (t CtSkuChangeChannel) GetConsumerGroupID() string { + return "open_message_408486475484" +} + +func (t CtSkuChangeChannel) GetEndPoint() string { + return "jcq-shared-004-httpsrv-nlb-FI.jvessel-open-hb.jdcloud.com:8080" +} diff --git a/api/mq/test.go b/api/mq/test.go new file mode 100644 index 0000000..df6719c --- /dev/null +++ b/api/mq/test.go @@ -0,0 +1,16 @@ +package mq + +type TestChannel struct { +} + +func (t TestChannel) GetTopicName() string { + return "open_message_internet_test" +} + +func (t TestChannel) GetConsumerGroupID() string { + return "open_message_20210625" +} + +func (t TestChannel) GetEndPoint() string { + return "jcq-internet-001-httpsrv-nlb-FI.jvessel-open-hb.jdcloud.com:8080" +} diff --git a/api/rest/address.go b/api/rest/address.go new file mode 100644 index 0000000..185101b --- /dev/null +++ b/api/rest/address.go @@ -0,0 +1,41 @@ +package rest + +// GetAddressRequest 地址转换请求 +type GetAddressRequest struct { + Uname string `json:"uname"` + Province string `json:"province"` + City string `json:"city"` + Street string `json:"street"` + Town string `json:"town"` + Address string `json:"address"` +} + +func (o GetAddressRequest) GetApiName() string { + return "jingdong.jingdong.ks.getJDAddress" +} + +func (o GetAddressRequest) GetRespName() string { + return "jingdong_jingdong_ks_getJDAddress_responce" +} + +func (o GetAddressRequest) GetRespObj() interface{} { + return GetAddressResponse{} +} + +// GetAddressResponse 返回参数. +type GetAddressResponse struct { + Response struct { + Message string `json:"message"` + Result GetAddressParams `json:"result"` + Code string `json:"code"` + } + Code string `json:"code"` +} + +type GetAddressParams struct { + Address string `json:"address"` + TownID uint `json:"townid"` + ProvinceID uint `json:"provinceid"` + CityID uint `json:"cityid"` + StreetID uint `json:"streetid"` +} diff --git a/api/rest/afs/afsAddress.go b/api/rest/afs/afsAddress.go new file mode 100644 index 0000000..42cad4f --- /dev/null +++ b/api/rest/afs/afsAddress.go @@ -0,0 +1,43 @@ +package afs + +import "git.oa00.com/go/jcook-sdk/api/rest" + +// GetAfsAddressRequest 获取售后回寄地址. +type GetAfsAddressRequest struct { + CtpProtocol rest.CtpProtocol `json:"ctpProtocol"` + LogisticsAddressParam LogisticsAddressParam `json:"logisticsAddressParam"` +} + +type LogisticsAddressParam struct { + AfsServiceID uint `json:"afsServiceId"` + Pin string `json:"pin"` +} + +func (o GetAfsAddressRequest) GetApiName() string { + return "jingdong.ctp.afs.logistics.getLogisticsAddress" +} + +func (o GetAfsAddressRequest) GetRespName() string { + return "jingdong_ctp_afs_logistics_getLogisticsAddress_responce" +} + +func (o GetAfsAddressRequest) GetRespObj() interface{} { + return AddressResponse{} +} + +// AddressResponse 返回参数. +type AddressResponse struct { + Result struct { + Data AddressParams `json:"data"` + ErrCode uint `json:"errCode"` + ErrMsg string `json:"errMsg"` + Success bool `json:"success"` + } `json:"result"` +} + +type AddressParams struct { + Address string `json:"address"` + ContactsZipCode string `json:"contactsZipCode"` + ContactsName string `json:"ContactsName"` + ContactsMobile string `json:"ContactsMobile"` +} diff --git a/api/rest/afs/afsCanQuery.go b/api/rest/afs/afsCanQuery.go new file mode 100644 index 0000000..fe024e9 --- /dev/null +++ b/api/rest/afs/afsCanQuery.go @@ -0,0 +1,91 @@ +package afs + +import "git.oa00.com/go/jcook-sdk/api/rest" + +// QueryCanAfterSaleRequest 是否可以有售后. +type QueryCanAfterSaleRequest struct { + CtpProtocol rest.CtpProtocol `json:"ctpProtocol"` + CanApplyInfoParam CanApplyInfoParam `json:"canApplyInfoParam"` +} + +type CanApplyInfoParam struct { + Pin string `json:"pin"` + SkuID uint `json:"skuId"` + OrderID uint `json:"orderId"` +} + +type canApplyType uint + +const ( + CannotApply canApplyType = iota + CanApply +) + +var canApplyTypeMap = map[canApplyType]string{ + CannotApply: "不可申请", + CanApply: "可申请", +} + +func (o canApplyType) String() string { + if value, ok := canApplyTypeMap[o]; !ok { + return rest.UnKnow + } else { + return value + } +} + +type returnType uint + +const ( + Return returnType = 10 + Exchange returnType = 20 +) + +var returnTypeMap = map[returnType]string{ + Return: "退货", + Exchange: "换货", +} + +func (o returnType) String() string { + if value, ok := returnTypeMap[o]; !ok { + return rest.UnKnow + } else { + return value + } +} + +func (o QueryCanAfterSaleRequest) GetApiName() string { + return "jingdong.ctp.afs.operate.apply.getIsCanApplyInfo" +} + +func (o QueryCanAfterSaleRequest) GetRespName() string { + return "jingdong_ctp_afs_operate_apply_getIsCanApplyInfo_responce" +} + +func (o QueryCanAfterSaleRequest) GetRespObj() interface{} { + return CanAfterSaleResponse{} +} + +//CanAfterSaleResponse 返回参数. +type CanAfterSaleResponse struct { + Result struct { + Data CanAfterSaleParams `json:"data"` + ErrCode uint `json:"errCode"` + ErrMsg string `json:"errMsg"` + Success bool `json:"success"` + } `json:"result"` +} + +type CanAfterSaleParams struct { + CanApply canApplyType `json:"canApply"` + SkuID uint `json:"skuId"` + AppliedNum uint `json:"appliedNum"` + CannotApplyTip string `json:"cannotApplyTip"` + OrderID uint `json:"orderId"` + AfsSupportedTypes []SupportParams `json:"afsSupportedTypes"` +} + +type SupportParams struct { + AfsTypeName string `json:"afsTypeName"` + AfsType returnType `json:"afsType"` +} diff --git a/api/rest/afs/afsCancel.go b/api/rest/afs/afsCancel.go new file mode 100644 index 0000000..3b1bd21 --- /dev/null +++ b/api/rest/afs/afsCancel.go @@ -0,0 +1,57 @@ +package afs + +import "git.oa00.com/go/jcook-sdk/api/rest" + +// CancelAfsServiceDetailRequest 售后服务单取消. +type CancelAfsServiceDetailRequest struct { + CtpProtocol rest.CtpProtocol `json:"ctpProtocol"` + CancelAfsServiceParam ServiceDetailParam `json:"cancelAfsServiceParam"` +} + +func (o CancelAfsServiceDetailRequest) GetApiName() string { + return "jingdong.ctp.afs.servicenbill.cancelAfsService" +} + +func (o CancelAfsServiceDetailRequest) GetRespName() string { + return "jingdong_ctp_afs_servicenbill_cancelAfsService_responce" +} + +func (o CancelAfsServiceDetailRequest) GetRespObj() interface{} { + return CancelAfsResponse{} +} + +// CancelAfsResponse 售后单创建返回. +type CancelAfsResponse struct { + Result struct { + Data CancelAfsParams `json:"data"` + ErrCode uint `json:"errCode"` + ErrMsg string `json:"errMsg"` + Success bool `json:"success"` + } `json:"result"` +} + +type cancelState uint + +const ( + CancelStateNot cancelState = iota + 1 + CancelStateSuccess + CancelStateFail +) + +var cancelStateMap = map[cancelState]string{ + CancelStateNot: "不可取消", + CancelStateSuccess: "取消成功", + CancelStateFail: "取消失败", +} + +func (o cancelState) String() string { + if value, ok := cancelStateMap[o]; !ok { + return rest.UnKnow + } else { + return value + } +} + +type CancelAfsParams struct { + CancelState cancelState `json:"cancelState"` +} diff --git a/api/rest/afs/afsCreate.go b/api/rest/afs/afsCreate.go new file mode 100644 index 0000000..6e1c128 --- /dev/null +++ b/api/rest/afs/afsCreate.go @@ -0,0 +1,53 @@ +package afs + +import "git.oa00.com/go/jcook-sdk/api/rest" + +// CreateAfsRequest 售后单申请. +type CreateAfsRequest struct { + CtpProtocol rest.CtpProtocol `json:"ctpProtocol"` + AfsApplyParam ApplyParam `json:"afsApplyParam"` +} + +type SkuQuantityParam struct { + SkuID uint `json:"skuId"` + SkuName string `json:"skuName"` + Quantity uint `json:"quantity"` +} + +type ApplyParam struct { + ApplyReasonName string `json:"applyReasonName"` + ApplyReasonID uint `json:"applyReasonId"` + Pin string `json:"pin"` + ChannelAfsApplyID string `json:"channelAfsApplyId"` + AfsType returnType `json:"afsType"` + QuestionPic string `json:"questionPic"` + OrderID uint `json:"orderId"` + SkuQuantity SkuQuantityParam `json:"skuQuantity"` +} + +func (o CreateAfsRequest) GetApiName() string { + return "jingdong.ctp.afs.operate.apply.createAfsApply" +} + +func (o CreateAfsRequest) GetRespName() string { + return "jingdong_ctp_afs_operate_apply_createAfsApply_responce" +} + +func (o CreateAfsRequest) GetRespObj() interface{} { + return CreateAfsResponse{} +} + +// CreateAfsResponse 售后单创建返回. +type CreateAfsResponse struct { + Result struct { + Data CreateAfsParams `json:"data"` + ErrCode uint `json:"errCode"` + ErrMsg string `json:"errMsg"` + Success bool `json:"success"` + } `json:"result"` +} + +type CreateAfsParams struct { + AfsApplyID uint `json:"afsApplyId"` + ChannelAfsApplyID string `json:"channelAfsApplyId"` +} diff --git a/api/rest/afs/afsDetail.go b/api/rest/afs/afsDetail.go new file mode 100644 index 0000000..7af5e22 --- /dev/null +++ b/api/rest/afs/afsDetail.go @@ -0,0 +1,73 @@ +package afs + +import "git.oa00.com/go/jcook-sdk/api/rest" + +// GetAfsServiceDetailRequest 获取售后详情. +type GetAfsServiceDetailRequest struct { + CtpProtocol rest.CtpProtocol `json:"ctpProtocol"` + AfsServiceDetailParam ServiceDetailParam `json:"afsServiceDetailParam"` +} + +type ServiceDetailParam struct { + Pin string `json:"pin"` + AfsServiceID uint `json:"afsServiceId"` +} + +func (o GetAfsServiceDetailRequest) GetApiName() string { + return "jingdong.ctp.afs.servicenbill.getAfsServiceDetail" +} + +func (o GetAfsServiceDetailRequest) GetRespName() string { + return "jingdong_ctp_afs_servicenbill_getAfsServiceDetail_responce" +} + +func (o GetAfsServiceDetailRequest) GetRespObj() interface{} { + return GetAfsResponse{} +} + +// GetAfsResponse 售后单查询返回. +type GetAfsResponse struct { + Result struct { + Data GetAfsParams `json:"data"` + ErrCode uint `json:"errCode"` + ErrMsg string `json:"errMsg"` + Success bool `json:"success"` + } `json:"result"` +} + +type GetAfsParams struct { + ProcessResult uint `json:"processResult"` + CustomerName string `json:"customerName"` + ApplyReasonID uint `json:"applyReasonId"` + ApplyReasonName string `json:"applyReasonName"` + ApproveResult uint `json:"approveResult"` + AfsApplyTime string `json:"afsApplyTime"` + ApproveResultName string `json:"approveResultName"` + ProcessResultName string `json:"processResultName"` + AfsType returnType `json:"afsType"` + ReturnWareType uint `json:"returnWareType"` + CustomerMobile string `json:"customerMobile"` + QuestionPic string `json:"questionPic"` + ApproveNotes string `json:"approveNotes"` + ApprovedDate string `json:"approvedDate"` + CustomerEmail string `json:"customerEmail"` + ProcessedDate string `json:"processedDate"` + AfsApplyID uint `json:"afsApplyId"` + AfsTypeName string `json:"afsTypeName"` + Pin string `json:"pin"` + AfsServiceState uint `json:"afsServiceState"` + AfsServiceID uint `json:"afsServiceId"` + NewOrderID uint `json:"newOrderId"` + AfsServiceStep uint `json:"afsServiceStep"` + AfsServiceStateName string `json:"afsServiceStateName"` + ProcessNotes string `json:"processNotes"` + AfsServiceStepName string `json:"afsServiceStepName"` + OrderID uint `json:"orderId"` + SkuQuantity SkuQuantity `json:"skuQuantity"` +} + +type SkuQuantity struct { + SkuID uint `json:"skuId"` + SkuName string `json:"skuName"` + Quantity uint `json:"quantity"` +} diff --git a/api/rest/afs/afsLogisticsPush.go b/api/rest/afs/afsLogisticsPush.go new file mode 100644 index 0000000..582f032 --- /dev/null +++ b/api/rest/afs/afsLogisticsPush.go @@ -0,0 +1,44 @@ +package afs + +import "git.oa00.com/go/jcook-sdk/api/rest" + +// PostBackLogisticsBillRequest 上传物流. +type PostBackLogisticsBillRequest struct { + CtpProtocol rest.CtpProtocol `json:"ctpProtocol"` + LogisticsBillParam LogisticsBillParam `json:"logisticsBillParam"` +} + +type LogisticsBillParam struct { + Pin string `json:"pin"` + AfsServiceID uint `json:"afsServiceId"` + LogisticsCompany string `json:"logisticsCompany"` + WaybillCode string `json:"waybillCode"` + SendGoodsDate string `json:"sendGoodsDate"` +} + +func (o PostBackLogisticsBillRequest) GetApiName() string { + return "jingdong.ctp.afs.logistics.postBackLogisticsBillParam" +} + +func (o PostBackLogisticsBillRequest) GetRespName() string { + return "jingdong_ctp_afs_logistics_postBackLogisticsBillParam_responce" +} + +func (o PostBackLogisticsBillRequest) GetRespObj() interface{} { + return PostBackLogisticsBillResponse{} +} + +// PostBackLogisticsBillResponse 售后单创建返回. +type PostBackLogisticsBillResponse struct { + Result struct { + Data PostBackLogisticsBillParams `json:"data"` + ErrCode uint `json:"errCode"` + ErrMsg string `json:"errMsg"` + Success bool `json:"success"` + } `json:"result"` +} + +type PostBackLogisticsBillParams struct { + PostBackResult bool `json:"postBackResult"` + Message string `json:"message"` +} diff --git a/api/rest/afs/afsReason.go b/api/rest/afs/afsReason.go new file mode 100644 index 0000000..e4b0378 --- /dev/null +++ b/api/rest/afs/afsReason.go @@ -0,0 +1,43 @@ +package afs + +import "git.oa00.com/go/jcook-sdk/api/rest" + +type ApplyReasonParam struct { + Pin string `json:"pin"` + SkuID uint `json:"skuId"` + OrderID uint `json:"orderId"` + AfsType returnType `json:"afsType"` +} + +// QueryAfterSaleReasonRequest 查询售后原因. +type QueryAfterSaleReasonRequest struct { + CtpProtocol rest.CtpProtocol `json:"ctpProtocol"` + ApplyReasonParam ApplyReasonParam `json:"applyReasonParam"` +} + +func (o QueryAfterSaleReasonRequest) GetApiName() string { + return "jingdong.ctp.afs.operate.apply.getApplyReason" +} + +func (o QueryAfterSaleReasonRequest) GetRespName() string { + return "jingdong_ctp_afs_operate_apply_getApplyReason_responce" +} + +func (o QueryAfterSaleReasonRequest) GetRespObj() interface{} { + return ReasonResponse{} +} + +type ReasonResponse struct { + Result struct { + Data []ReasonParams `json:"data"` + ErrCode uint `json:"errCode"` + ErrMsg string `json:"errMsg"` + Success bool `json:"success"` + } `json:"result"` +} + +type ReasonParams struct { + ApplyReasonName string `json:"applyReasonName"` + ApplyReasonID uint `json:"applyReasonId"` + NeedUploadPic bool `json:"needUploadPic"` +} diff --git a/api/rest/base.go b/api/rest/base.go new file mode 100644 index 0000000..1445334 --- /dev/null +++ b/api/rest/base.go @@ -0,0 +1,127 @@ +package rest + +import ( + "encoding/json" + "fmt" + "git.oa00.com/go/jcook-sdk/util/http" + "git.oa00.com/go/jcook-sdk/util/security" + "github.com/mitchellh/mapstructure" + + "net/url" + "strings" + "time" +) + +type Requester interface { + GetApiName() string + GetRespObj() interface{} + GetRespName() string +} + +const UnKnow = "UnKnow" + +type Address struct { + CityID uint `json:"cityId"` + CountyID uint `json:"countyId"` + ProvinceID uint `json:"provinceId"` + TownID uint `json:"townId"` + FullAddress string `json:"fullAddress"` + AddressDetail string `json:"addressDetail"` +} + +type CtpProtocol struct { + AppKey string `json:"appKey"` + ChannelID uint `json:"channelId"` + CustomerID uint `json:"customerId"` + TraceID string `json:"traceId"` + OpName string `json:"opName"` +} + +type Response struct { + Result struct { + ErrCode uint `json:"errCode"` + ErrMsg string `json:"errMsg"` + Success bool `json:"success"` + Data interface{} `json:"data"` + } `json:"result"` +} + +const ( + PAppKey = "app_key" + PApi = "method" + PAccessToken = "access_token" + PVersion = "v" + PFormat = "format" + PTimestamp = "timestamp" + PSign = "sign" + PJsonParamKey = "360buy_param_json" + PCode = "code" + PSubCode = "sub_code" + PMsg = "msg" + PSubMsg = "sub_msg" + Rest = "https://api.jd.com/routerjson" + Version = "2.0" + Format = "json" + ResponseSuffix = "_responce" +) + +type Client struct { + AppKey string + AppSecret string + AccessKey string + OpName string +} + +func NewClient(appKey string, AppSecret string, AccessKey string, OpName string) *Client { + return &Client{ + AppKey: appKey, + AppSecret: AppSecret, + AccessKey: AccessKey, + OpName: OpName, + } +} + +func (c *Client) Exec(r Requester) (interface{}, error) { + j, _ := json.Marshal(&r) + jsonParams := string(j) + t := time.Now().Format("2006-01-02 15:04:05") + data := map[string]string{ + PAppKey: c.AppKey, + PApi: r.GetApiName(), + PAccessToken: c.AccessKey, + PVersion: Version, + PFormat: Format, + PTimestamp: t, + PJsonParamKey: jsonParams, + } + + sign := security.Md5OrderlyWithSecret(c.AppSecret, data) + data[PSign] = sign + + params := url.Values{} + + for key, value := range data { + params.Add(key, value) + } + + resp, err := http.JGet(Rest, params, nil) + if err != nil { + return nil, err + } + if !strings.Contains(string(resp), r.GetRespName()) { + return nil, fmt.Errorf("system err: %s", string(resp)) + } + + var temp map[string]interface{} + err = json.Unmarshal(resp, &temp) + if err != nil { + return nil, err + } + fmt.Println(temp) + result := temp[r.GetRespName()] + response := r.GetRespObj() + if err = mapstructure.Decode(result, &response); err != nil { + return nil, err + } + return response, err +} diff --git a/api/rest/logisitics/fee.go b/api/rest/logisitics/fee.go new file mode 100644 index 0000000..5b6623e --- /dev/null +++ b/api/rest/logisitics/fee.go @@ -0,0 +1,52 @@ +package logisitics + +import ( + "git.oa00.com/go/jcook-sdk/api/rest" +) + +// GetFeeRequest 获取物流费用请求. +type GetFeeRequest struct { + CtpProtocol rest.CtpProtocol `json:"protocol"` + ApiFreightFeeParam ApiFreightFeeParam `json:"apiFreightFeeParam"` +} + +type SkuInfo struct { + SkuPrice float64 `json:"skuPrice"` + SkuID string `json:"skuId"` + SkuName string `json:"skuName"` + Quantity uint `json:"quantity"` +} + +type ApiFreightFeeParam struct { + Address rest.Address `json:"address"` + Pin string `json:"pin"` + PaymentType uint `json:"paymentType"` + OrderFee float64 `json:"orderFee"` + SkuList []SkuInfo `json:"skuList"` +} + +func (o GetFeeRequest) GetApiName() string { + return "jingdong.ctp.order.getFreightFee" +} + +func (o GetFeeRequest) GetRespName() string { + return "jingdong_ctp_order_getFreightFee_responce" +} + +func (o GetFeeRequest) GetRespObj() interface{} { + return GetFeeResponse{} +} + +// GetFeeResponse 获取物流费用 +type GetFeeResponse struct { + Result struct { + Data GetFeeParams `json:"data"` + ErrCode uint `json:"errCode"` + ErrMsg string `json:"errMsg"` + Success bool `json:"success"` + } `json:"result"` +} + +type GetFeeParams struct { + FreightFee float64 `json:"freightFee"` +} diff --git a/api/rest/logisitics/logistics.go b/api/rest/logisitics/logistics.go new file mode 100644 index 0000000..c20ae18 --- /dev/null +++ b/api/rest/logisitics/logistics.go @@ -0,0 +1,47 @@ +package logisitics + +// GetLogisticsRequest 获取物流轨迹. +type GetLogisticsRequest struct { + CustomerID uint `json:"customerId"` + ChannelID uint `json:"channelId"` + AppKey string `json:"appKey"` + OrderID uint `json:"orderId"` + Pin string `json:"pin"` +} + +func (o GetLogisticsRequest) GetApiName() string { + return "jingdong.ctp.order.getLogistics" +} + +func (o GetLogisticsRequest) GetRespName() string { + return "jingdong_ctp_order_getLogistics_responce" +} + +func (o GetLogisticsRequest) GetRespObj() interface{} { + return GetLogisticsResponse{} +} + +// GetLogisticsResponse 获取物流轨迹返回. +type GetLogisticsResponse struct { + Result struct { + Data []GetLogisticsParams `json:"data"` + ErrCode uint `json:"errCode"` + ErrMsg string `json:"errMsg"` + Success bool `json:"success"` + } `json:"result"` +} + +type GetLogisticsParams struct { + LogisticsName string `json:"logisticsName"` + WaybillCode string `json:"waybillCode"` + OperatorNodeList []OperatorNode `json:"operatorNodeList"` +} + +type OperatorNode struct { + Content string `json:"content"` + GroupState string `json:"groupState"` + ScanState string `json:"scanState"` + MsgTime string `json:"msgTime"` + SystemOperator string `json:"systemOperator"` + OrderID uint `json:"orderId"` +} diff --git a/api/rest/logisitics/method.go b/api/rest/logisitics/method.go new file mode 100644 index 0000000..3496095 --- /dev/null +++ b/api/rest/logisitics/method.go @@ -0,0 +1,90 @@ +package logisitics + +import "git.oa00.com/go/jcook-sdk/api/rest" + +// GetMethodRequest 获取物流方法. +type GetMethodRequest struct { + CtpProtocol rest.CtpProtocol `json:"protocol"` + ApiShipmentTypeParam ApiShipmentTypeParam `json:"apiShipmentTypeParam"` +} + +type ApiShipmentTypeParam struct { + Address rest.Address `json:"address"` + Pin string `json:"pin"` + PaymentType uint `json:"paymentType"` + SkuList []SkuInfo `json:"skuList"` +} + +func (o GetMethodRequest) GetApiName() string { + return "jingdong.ctp.order.getShipmentType" +} + +func (o GetMethodRequest) GetRespName() string { + return "jingdong_ctp_order_getShipmentType_responce" +} + +func (o GetMethodRequest) GetRespObj() interface{} { + return GetMethodResponse{} +} + +// GetMethodResponse 获取物流轨迹返回. +type GetMethodResponse struct { + Result struct { + Data GetMethodParams `json:"data"` + ErrCode uint `json:"errCode"` + ErrMsg string `json:"errMsg"` + Success bool `json:"success"` + } `json:"result"` +} + +type shipmentType uint + +const ( + JdSelf shipmentType = iota + 1 + JdOther + Third + Normal + NotSupport = 9 +) + +var shipmentTypeMap = map[shipmentType]string{ + JdSelf: "京东配送", + JdOther: "京配转三方配送", + Third: "第三方配送", + Normal: "普通快递配送", + NotSupport: "不支持配送", +} + +func (o shipmentType) String() string { + if value, ok := shipmentTypeMap[o]; !ok { + return rest.UnKnow + } else { + return value + } +} + +type GetMethodParams struct { + ShipmentType shipmentType `json:"shipmentType"` + ShipmentInfoList []ShipmentInfoParams `json:"shipmentInfoList"` +} + +type ShipmentInfoParams struct { + SkuID string `json:"skuId"` + ShipmentDetail ShipmentDetailParams `json:"shipmentDetail"` +} + +type ShipmentDetailParams struct { + ShipmentType shipmentType `json:"shipmentType"` + AttachmentList []Attachment `json:"attachmentList"` + GiftList []Gift `json:"giftList"` +} + +type Attachment struct { + SkuID string `json:"skuId"` + ShipmentType shipmentType `json:"shipmentType"` +} + +type Gift struct { + SkuID string `json:"skuId"` + ShipmentType shipmentType `json:"shipmentType"` +} diff --git a/api/rest/order/Inventory.go b/api/rest/order/Inventory.go new file mode 100644 index 0000000..1d438e4 --- /dev/null +++ b/api/rest/order/Inventory.go @@ -0,0 +1,69 @@ +package order + +import "git.oa00.com/go/jcook-sdk/api/rest" + +// GetSkuStockRequest 获取库存状态. +type GetSkuStockRequest struct { + CtpProtocol rest.CtpProtocol `json:"ctpProtocol"` + StockStateParam StockStateParam `json:"stockStateParam"` +} + +type SkuQuantity struct { + Quantity uint `json:"quantity"` + SkuID uint `json:"skuId"` +} + +type StockStateParam struct { + Address rest.Address `json:"address"` + SkuQuantityList []SkuQuantity `json:"skuQuantityList"` +} + +func (o GetSkuStockRequest) GetApiName() string { + return "jingdong.ctp.ware.stock.queryAreaStockState" +} + +func (o GetSkuStockRequest) GetRespName() string { + return "jingdong_ctp_ware_stock_queryAreaStockState_responce" +} + +func (o GetSkuStockRequest) GetRespObj() interface{} { + return GetSkuStockResponse{} +} + +// GetSkuStockResponse 库存状态返回. +type GetSkuStockResponse struct { + Result struct { + ErrCode uint `json:"errCode"` + ErrMsg string `json:"errMsg"` + Success bool `json:"success"` + StockStateList []StockState `json:"stockStateList"` + } `json:"result"` +} + +type areaStockState uint + +const ( + SoldOut areaStockState = iota + SoldIn + StockIng +) + +var areaStockStateMap = map[areaStockState]string{ + SoldOut: "无库存", + SoldIn: "有库存", + StockIng: "采购中", +} + +func (o areaStockState) String() string { + if value, ok := areaStockStateMap[o]; !ok { + return rest.UnKnow + } else { + return value + } +} + +type StockState struct { + AreaStockState areaStockState `json:"areaStockState"` + LeadTime string `json:"leadTime"` + SkuQuantity SkuQuantity `json:"skuQuantity"` +} diff --git a/api/rest/order/Invoice.go b/api/rest/order/Invoice.go new file mode 100644 index 0000000..a0a61c1 --- /dev/null +++ b/api/rest/order/Invoice.go @@ -0,0 +1,64 @@ +package order + +// QueryInvoiceInfoRequest 查询发票详情. +type QueryInvoiceInfoRequest struct { + CustomerID uint `json:"customerId"` + ChannelID uint `json:"channelId"` + AppKey string `json:"appKey"` + OrderID uint `json:"orderId"` +} + +func (o QueryInvoiceInfoRequest) GetApiName() string { + return "jingdong.ctp.finance.getInvoiceDetail" +} + +func (o QueryInvoiceInfoRequest) GetRespName() string { + return "jingdong_ctp_finance_getInvoiceDetail_responce" +} + +func (o QueryInvoiceInfoRequest) GetRespObj() interface{} { + return QueryInvoiceInfoResponse{} +} + +// QueryInvoiceInfoResponse 查询发票详情. +type QueryInvoiceInfoResponse struct { + Result struct { + ErrCode uint `json:"errCode"` + ErrMsg string `json:"errMsg"` + Success bool `json:"success"` + Data []InvoiceDetail `json:"data"` + } `json:"result"` +} + +type InvoiceDetail struct { + Valid string `json:"valid"` + TaxRate float64 `json:"taxRate"` + UpdateTime string `json:"updateTime"` + Remark string `json:"remark"` + IvcCode string `json:"ivcCode"` + IvcContentType uint `json:"ivcContentType"` + IvcTitle string `json:"ivcTitle"` + IvcContentName string `json:"ivcContentName"` + FileUrl string `json:"fileUrl"` + ExpandColumn string `json:"expandColumn"` + IvcTime string `json:"ivcTime"` + IvcNo string `json:"ivcNo"` + IvcType uint `json:"ivcType"` + TotalTaxPrice float64 `json:"totalTaxPrice"` + OrderID uint `json:"orderId"` + TotalPrice float64 `json:"totalPrice"` + InvoiceSkuDetailList []InvoiceSkuDetail `json:"invoiceSkuDetailList"` +} + +type InvoiceSkuDetail struct { + IvcSkuName string `json:"ivcSkuName"` + Unit string `json:"unit"` + Num uint `json:"num"` + Price float64 `json:"price"` + TaxRate float64 `json:"taxRate"` + IvcPrice float64 `json:"ivcPrice"` + Isn string `json:"isn"` + IvcNum uint `json:"ivcNum"` + SkuId string `json:"skuId"` + SkuName string `json:"skuName"` +} diff --git a/api/rest/order/cancel.go b/api/rest/order/cancel.go new file mode 100644 index 0000000..1fe417e --- /dev/null +++ b/api/rest/order/cancel.go @@ -0,0 +1,59 @@ +package order + +import "git.oa00.com/go/jcook-sdk/api/rest" + +// CancelOrderRequest 取消订单. +type CancelOrderRequest struct { + CustomerID uint `json:"customerId"` + AppKey string `json:"appKey"` + ChannelID uint `json:"channelId"` + OrderID uint `json:"orderId"` + Pin string `json:"pin"` + CancelReasonCode uint `json:"cancelReasonCode"` +} + +func (o CancelOrderRequest) GetApiName() string { + return "jingdong.ctp.order.cancelOrder" +} + +func (o CancelOrderRequest) GetRespName() string { + return "jingdong_ctp_order_cancelOrder_responce" +} + +func (o CancelOrderRequest) GetRespObj() interface{} { + return CancelOrderResponse{} +} + +// CancelOrderResponse 取消订单返回. +type CancelOrderResponse struct { + Result struct { + ErrCode uint `json:"errCode"` + ErrMsg string `json:"errMsg"` + Success bool `json:"success"` + Data CancelParam `json:"data"` + } `json:"result"` +} + +type cancelStatus uint + +const ( + CancelFail cancelStatus = 1 + CancelSuccess cancelStatus = 3 +) + +var cancelStatusMap = map[cancelStatus]string{ + CancelFail: "取消失败", + CancelSuccess: "取消成功", +} + +func (o cancelStatus) String() string { + if value, ok := cancelStatusMap[o]; !ok { + return rest.UnKnow + } else { + return value + } +} + +type CancelParam struct { + CancelStatus cancelStatus `json:"cancelStatus"` +} diff --git a/api/rest/order/confirm.go b/api/rest/order/confirm.go new file mode 100644 index 0000000..eb1926b --- /dev/null +++ b/api/rest/order/confirm.go @@ -0,0 +1,32 @@ +package order + +// ConfirmOrderRequest 确认收货请求. +type ConfirmOrderRequest struct { + CustomerID uint `json:"customerId"` + ClientPort string `json:"clientPort"` + ChannelID uint `json:"channelId"` + ClientIp string `json:"clientIp"` + AppKey string `json:"appKey"` + OrderID uint `json:"orderId"` +} + +func (o ConfirmOrderRequest) GetApiName() string { + return "jingdong.ctp.order.confirmDelivery" +} + +func (o ConfirmOrderRequest) GetRespName() string { + return "jingdong_ctp_order_confirmDelivery_responce" +} + +func (o ConfirmOrderRequest) GetRespObj() interface{} { + return ConfirmOrderResponse{} +} + +// ConfirmOrderResponse 确认收货返回. +type ConfirmOrderResponse struct { + Result struct { + ErrCode uint `json:"errCode"` + ErrMsg string `json:"errMsg"` + Success bool `json:"success"` + } `json:"result"` +} diff --git a/api/rest/order/order.go b/api/rest/order/order.go new file mode 100644 index 0000000..ec85380 --- /dev/null +++ b/api/rest/order/order.go @@ -0,0 +1,140 @@ +package order + +import "git.oa00.com/go/jcook-sdk/api/rest" + +// QueryOrderDetailRequest 订单详细. +type QueryOrderDetailRequest struct { + CustomerID uint `json:"customerId"` + ChannelID uint `json:"channelId"` + TraceID string `json:"traceId"` + AppKey string `json:"appKey"` + OrderID uint `json:"orderId"` + Pin string `json:"pin"` + ClientIp string `json:"clientIp"` + ClientPort string `json:"clientPort"` +} + +func (o QueryOrderDetailRequest) GetApiName() string { + return "jingdong.ctp.order.getOrderDetail" +} + +func (o QueryOrderDetailRequest) GetRespName() string { + return "jingdong_ctp_order_getOrderDetail_responce" +} + +func (o QueryOrderDetailRequest) GetRespObj() interface{} { + return QueryOrderDetailResponse{} +} + +// QueryOrderDetailResponse 订单详情. +type QueryOrderDetailResponse struct { + Result struct { + ErrCode uint `json:"errCode"` + ErrMsg string `json:"errMsg"` + Success bool `json:"success"` + Data Detail `json:"data"` + } `json:"result"` +} + +type Detail struct { + SkuList []SkuDetailParam `json:"skuList"` + OrderID uint `json:"orderId"` + BaseOrderInfo BaseOrder `json:"baseOrderInfo"` + OrderRelationFee RelateFee `json:"orderRelationFee"` + Shipment ShipmentParam `json:"shipment"` +} + +type ShipmentParam struct { + ShipmentType uint `json:"shipmentType"` +} + +type RelateFee struct { + ShouldPaymentFee float64 `json:"shouldPaymentFee"` + FreightFee float64 `json:"freightFee"` +} + +type SkuDetailParam struct { + ImgUrl string `json:"imgUrl"` + Weight float64 `json:"weight"` + Color string `json:"color"` + CategoryID uint `json:"categoryId"` + SkuID uint `json:"skuId"` + SkuName string `json:"skuName"` + ShouldPrice float64 `json:"shouldPrice"` + Quantity uint `json:"Quantity"` + Bulk float64 `json:"bulk"` + SkuGiftType uint `json:"skuGiftType"` + MainSkuID uint `json:"mainSkuId"` +} + +type status int + +const ( + Submit status = 0 + WaitPay = 1 + IsPay = 4 + WaitPrint = 6 + Pick = 7 + OutOfStock = 8 + WaitConfirm = 15 + UserReject = 16 + Lock = 20 + Cancel = -100 +) + +var statusMap = map[status]string{ + Submit: "提单成功", + WaitPay: "等待付款", + IsPay: "已支付", + WaitPrint: "待打印", + Pick: "拣货完成", + OutOfStock: "出库完成", + WaitConfirm: "待用户确认收货", + UserReject: "用户拒收", + Lock: "订单锁定", + Cancel: "已取消", +} + +func (o status) String() string { + if value, ok := statusMap[o]; !ok { + return rest.UnKnow + } else { + return value + } +} + +type typeState int8 + +const ( + Self typeState = iota + Shop + Factory + Other = 99 +) + +var typeMap = map[typeState]string{ + Self: "京东自营订单或混单", + Shop: "商家自发货订单", + Factory: "厂直订单", + Other: "其他订单", +} + +func (o typeState) String() string { + if value, ok := typeMap[o]; !ok { + return rest.UnKnow + } else { + return value + } +} + +type BaseOrder struct { + RootOrderID uint `json:"rootOrderId"` + OrderStatus status `json:"orderStatus"` + SubmitTime int64 `json:"submitTime"` + CompleteTime string `json:"completeTime"` + PayTime int64 `json:"payTime"` + OutWarehouseTime string `json:"outWarehouseTime"` + PaymentType uint `json:"PaymentType"` + Remark string `json:"remark"` + OrderType typeState `json:"orderType"` +} diff --git a/api/rest/order/pay.go b/api/rest/order/pay.go new file mode 100644 index 0000000..878ac51 --- /dev/null +++ b/api/rest/order/pay.go @@ -0,0 +1,54 @@ +package order + +// QueryPayInfoRequest 查看支付详情. +type QueryPayInfoRequest struct { + CustomerID uint `json:"customerId"` + ChannelID uint `json:"channelId"` + AppKey string `json:"appKey"` + OrderID uint `json:"orderId"` +} + +func (o QueryPayInfoRequest) GetApiName() string { + return "jingdong.ctp.order.getOrderPayInfo" +} + +func (o QueryPayInfoRequest) GetRespName() string { + return "jingdong_ctp_order_getOrderPayInfo_responce" +} + +func (o QueryPayInfoRequest) GetRespObj() interface{} { + return QueryPayInfoResponse{} +} + +// QueryPayInfoResponse 查看支付返回. +type QueryPayInfoResponse struct { + Result struct { + ErrCode uint `json:"errCode"` + ErrMsg string `json:"errMsg"` + Success bool `json:"success"` + Data PayInfoParam `json:"data"` + } `json:"result"` +} + +type PayInfoParam struct { + RefundDetailList []RefundDetail `json:"refundDetailList"` + RefundTotalFee float64 `json:"refundTotalFee"` + RootOrderID uint `json:"rootOrderId"` + PaidInDetailList []PaidDetail `json:"paidInDetailList"` + ChannelOrderID string `json:"channelOrderId"` + FreightFee float64 `json:"freightFee"` + PaidInTotalFee float64 `json:"paidInTotalFee"` + OrderFee float64 `json:"orderFee"` +} + +type RefundDetail struct { + RefundFee float64 `json:"refundFee"` + RefundType uint `json:"refundType"` + RefundTime string `json:"refundTime"` +} + +type PaidDetail struct { + PaidInType uint `json:"paidInType"` + PaidInTime string `json:"paidInTime"` + PaidInFee float64 `json:"paidInFee"` +} diff --git a/api/rest/order/push.go b/api/rest/order/push.go new file mode 100644 index 0000000..9aedcad --- /dev/null +++ b/api/rest/order/push.go @@ -0,0 +1,30 @@ +package order + +// PushOrderRequest 推送订单. +type PushOrderRequest struct { + CustomerID uint `json:"customerId"` + ChannelID uint `json:"channelId"` + AppKey string `json:"appKey"` + OrderID uint `json:"orderId"` +} + +func (o PushOrderRequest) GetApiName() string { + return "jingdong.ctp.order.pushOrder" +} + +func (o PushOrderRequest) GetRespName() string { + return "jingdong_ctp_order_pushOrder_responce" +} + +func (o PushOrderRequest) GetRespObj() interface{} { + return PushOrderResponse{} +} + +// PushOrderResponse 推送订单返回. +type PushOrderResponse struct { + Result struct { + ErrCode uint `json:"errCode"` + ErrMsg string `json:"errMsg"` + Success bool `json:"success"` + } `json:"result"` +} diff --git a/api/rest/order/query.go b/api/rest/order/query.go new file mode 100644 index 0000000..a50c5de --- /dev/null +++ b/api/rest/order/query.go @@ -0,0 +1,39 @@ +package order + +// QueryOrderIDRequest 反查询orderId. +type QueryOrderIDRequest struct { + CustomerID uint `json:"customerId"` + ChannelID uint `json:"channelId"` + TraceID string `json:"traceId"` + AppKey string `json:"appKey"` + ChannelOrderID string `json:"channelOrderId"` + Pin string `json:"pin"` +} + +func (o QueryOrderIDRequest) GetApiName() string { + return "jingdong.ctp.order.querySubmitOrder" +} + +func (o QueryOrderIDRequest) GetRespName() string { + return "jingdong_ctp_order_querySubmitOrder_responce" +} + +func (o QueryOrderIDRequest) GetRespObj() interface{} { + return QueryOrderIDResponse{} +} + +// QueryOrderIDResponse 反查询orderId. +type QueryOrderIDResponse struct { + Result struct { + ErrCode uint `json:"errCode"` + ErrMsg string `json:"errMsg"` + Success bool `json:"success"` + Data QueryOrderIDParam `json:"data"` + } `json:"result"` +} + +type QueryOrderIDParam struct { + ChannelID uint `json:"channelId"` + ChannelOrderID string `json:"channelOrderId"` + OrderID uint `json:"orderId"` +} diff --git a/api/rest/order/submit.go b/api/rest/order/submit.go new file mode 100644 index 0000000..3c00633 --- /dev/null +++ b/api/rest/order/submit.go @@ -0,0 +1,106 @@ +package order + +import ( + "git.oa00.com/go/jcook-sdk/api/rest" +) + +// SubmitOrderRequest 提交order. +type SubmitOrderRequest struct { + CtpProtocol rest.CtpProtocol `json:"protocol"` + OrderParam Param `json:"param"` +} + +type Param struct { + ChannelOrderID string `json:"channelOrderId"` + Pin string `json:"pin"` + ProductList []ProductParam `json:"productList"` + OrderFee float64 `json:"orderFee"` + FreightFee float64 `json:"freightFee"` + Address rest.Address `json:"address"` + Receiver ReceiverParam `json:"receiver"` + PaymentType uint `json:"paymentType"` + ShipmentType uint `json:"shipmentType"` + ChannelOrderSource string `json:"channelOrderSource"` + SendGoods uint `json:"sendGoods"` + UserIp string `json:"userIp"` +} + +type ProductParam struct { + MainSku SkuParam `json:"mainSku"` +} + +type SkuParam struct { + SkuID string `json:"skuId"` + SkuPrice float64 `json:"skuPrice"` + Quantity uint `json:"quantity"` + SkuName string `json:"skuName"` +} + +type ReceiverParam struct { + ReceiverName string `json:"receiverName"` + ReceiverMobile string `json:"receiverMobile"` + ReceiverEmail string `json:"receiverEmail"` + ZipCode string `json:"zipCode"` +} + +type VatAddressParam struct { + VatProvinceID uint `json:"vatProvinceId"` + VatCityID uint `json:"vatCityId"` + VatCountyID uint `json:"vatCountyId"` + VatTownID uint `json:"vatTownId"` + VatFullAddress string `json:"vatFullAddress"` +} + +type VatInvoiceParam struct { + CompanyName string `json:"companyName"` + Code string `json:"code"` + RegAddr string `json:"regAddr"` + RegPhone string `json:"regPhone"` + RegBank string `json:"regBank"` + RegBankAccount string `json:"regBankAccount"` + ConsigneeName string `json:"consigneeName"` + ConsigneeMobile string `json:"consigneeMobile"` + VatAddress VatAddressParam `json:"vatAddress"` +} + +type ElectronicInvoiceParam struct { + SelectedInvoiceTitle string `json:"selectedInvoiceTitle"` + ElectCompanyName string `json:"electCompanyName"` + ElectCode string `json:"electCode"` + InvoiceConsigneeEmail string `json:"invoiceConsigneeEmail"` + InvoiceConsigneePhone string `json:"invoiceConsigneePhone"` +} + +type InvoiceParam struct { + InvoiceType uint `json:"invoiceType"` + VatInvoice VatInvoiceParam `json:"vatInvoice"` + ElectronicInvoice ElectronicInvoiceParam `json:"electronicInvoice"` +} + +func (o SubmitOrderRequest) GetApiName() string { + return "jingdong.ctp.order.submitOrder" +} + +func (o SubmitOrderRequest) GetRespName() string { + return "jingdong_ctp_order_submitOrder_responce" +} + +func (o SubmitOrderRequest) GetRespObj() interface{} { + return SubmitOrderResponse{} +} + +//SubmitOrderResponse 提交订单返回. +type SubmitOrderResponse struct { + Result struct { + ErrCode uint `json:"errCode"` + ErrMsg string `json:"errMsg"` + Success bool `json:"success"` + Data SubmitOrderParam `json:"data"` + } `json:"result"` +} + +type SubmitOrderParam struct { + ChannelID uint `json:"channelId"` + ChannelOrderID string `json:"channelOrderId"` + OrderID uint `json:"orderId"` +} diff --git a/api/rest/sku/skuDetail.go b/api/rest/sku/skuDetail.go new file mode 100644 index 0000000..42bca02 --- /dev/null +++ b/api/rest/sku/skuDetail.go @@ -0,0 +1,142 @@ +package sku + +import "git.oa00.com/go/jcook-sdk/api/rest" + +// GetSkuDetailRequest 获取sku详情. +type GetSkuDetailRequest struct { + CtpProtocol rest.CtpProtocol `json:"ctpProtocol"` + SkuDetailParam DetailParam `json:"skuDetailParam"` +} +type DetailParam struct { + DetailAssemblyType uint `json:"detailAssemblyType"` + SkuIDSet []uint `json:"skuIdSet"` +} + +func (o GetSkuDetailRequest) GetApiName() string { + return "jingdong.ctp.ware.sku.getSkuDetail" +} + +func (o GetSkuDetailRequest) GetRespName() string { + return "jingdong_ctp_ware_sku_getSkuDetail_responce" +} + +func (o GetSkuDetailRequest) GetRespObj() interface{} { + return GetSkuDetailResponse{} +} + +// GetSkuDetailResponse 获取物流轨迹返回. +type GetSkuDetailResponse struct { + Result struct { + Data []GetSkuDetailParams `json:"data"` + ErrCode uint `json:"errCode"` + ErrMsg string `json:"errMsg"` + Success bool `json:"success"` + } `json:"result"` +} + +type GetSkuDetailParams struct { + ImageInfos []ImageBase `json:"imageInfos"` + WReadMe string `json:"wReadMe"` + SkuID uint `json:"skuId"` + Specifications []Specification `json:"specifications"` + ExtAtts []Attr `json:"extAtts"` + SkuBaseInfo Base `json:"skuBaseInfo"` + SkuBigFieldInfo BigFieldInfo `json:"skuBigFieldInfo"` +} + +type BigFieldInfo struct { + PcWDis string `json:"pcWdis"` + PcHtmlContent string `json:"pcHtmlContent"` + PcJsContent string `json:"pcJsContent"` + PcCssContent string `json:"pcCssContent"` +} + +type Specification struct { + GroupName string `json:"groupName"` + Attributes []Attr `json:"attributes"` +} + +type Attr struct { + AttName string `json:"attName"` + ValNames []string `json:"valNames"` +} + +type ImageBase struct { + Path string `json:"path"` + Features string `json:"features"` + OrderSort uint `json:"orderSort"` + IsPrimary uint `json:"isPrimary"` + Position string `json:"position"` + Type uint `json:"type"` +} + +type Base struct { + SkuName string `json:"skuName"` + VenderName string `json:"venderName"` + ShopName string `json:"shopName"` + CategoryID1 uint `json:"categoryId1"` + CategoryID2 uint `json:"categoryId2"` + CategoryID uint `json:"categoryId"` + Length float64 `json:"length"` + Width float64 `json:"Width"` + Height float64 `json:"Height"` + PackageType string `json:"packageType"` + Model string `json:"model"` + Color string `json:"color"` + ColorSequence string `json:"colorSequence"` + UpcCode string `json:"upcCode"` + Size string `json:"size"` + SizeSequence string `json:"sizeSequence"` + Unit string `json:"unit"` + Warranty string `json:"warranty"` + ShelfLife string `json:"shelfLife"` + Delivery string `json:"delivery"` + PlaceOfProduction string `json:"placeOfProduction"` + Tax string `json:"tax"` + ProductID uint `json:"productId"` + SkuStatus uint `json:"skuStatus"` + Yn uint `json:"yn"` + Fare uint `json:"fare"` + CategoryName1 string `json:"categoryName1"` + CategoryName2 string `json:"categoryName2"` + CategoryName string `json:"categoryName"` + SkuInfoType uint `json:"skuInfoType"` + BookSkuBaseInfo BookSkuBase `json:"bookSkuBaseInfo"` +} + +type BookSkuBase struct { + SizeAndHeight string `json:"sizeAndHeight"` + MarketPrice string `json:"marketPrice"` + PackNum string `json:"packNum"` + Language string `json:"language"` + Remarker string `json:"remarker"` + AttachmentNum string `json:"attachmentNum"` + ChinaCatalog string `json:"chinaCatalog"` + ForeignBookName string `json:"foreignBookName"` + Pages string `json:"pages"` + ISBN string `json:"ISBN"` + Attachment string `json:"attachment"` + Compile string `json:"compile"` + Proofreader string `json:"proofreader"` + Publishers string `json:"publishers"` + Id string `json:"id"` + Brand string `json:"brand"` + Letters string `json:"letters"` + PublishTime string `json:"publishTime"` + BatchNo string `json:"batchNo"` + Author string `json:"author"` + ISSN string `json:"ISSN"` + Format string `json:"format"` + Drawer string `json:"drawer"` + BookName string `json:"bookName"` + BarCode string `json:"barCode"` + PicNo string `json:"picNo"` + Transfer string `json:"transfer"` + PrintNo string `json:"printNo"` + PackageStr string `json:"packageStr"` + PublishNo string `json:"publishNo"` + Series string `json:"series"` + Editer string `json:"editer"` + PrintTime string `json:"printTime"` + Photography string `json:"photography"` +} diff --git a/api/rest/sku/skuList.go b/api/rest/sku/skuList.go new file mode 100644 index 0000000..1b84b6c --- /dev/null +++ b/api/rest/sku/skuList.go @@ -0,0 +1,59 @@ +package sku + +import "git.oa00.com/go/jcook-sdk/api/rest" + +type ApiSkuListParam struct { + ScrollID string `json:"scrollId"` + SkuStatus uint `json:"skuStatus"` + PageSize uint `json:"pageSize"` +} +type GetSkuRequest struct { + CtpProtocol rest.CtpProtocol `json:"ctpProtocol"` + ApiSkuListParam ApiSkuListParam `json:"apiSkuListParam"` +} + +func (o GetSkuRequest) GetApiName() string { + return "jingdong.ctp.ware.sku.getSkuList" +} + +func (o GetSkuRequest) GetRespName() string { + return "jingdong_ctp_ware_sku_getSkuList_responce" +} + +func (o GetSkuRequest) GetRespObj() interface{} { + return ListResponse{} +} + +type EntryParams struct { + CategoryName2 string `json:"categoryName2"` + CategoryName1 string `json:"categoryName1"` + CategoryID uint `json:"categoryId"` + SkuName string `json:"skuName"` + BrandID uint `json:"brandId"` + BrandName string `json:"brandName"` + Modified int64 `json:"modified"` + ImgUrl string `json:"imgUrl"` + CategoryName string `json:"categoryName"` + CategoryId1 uint `json:"categoryId1"` + CategoryId2 uint `json:"categoryId2"` + Created int64 `json:"created"` + SkuStatus uint `json:"skuStatus"` + SkuID uint `json:"skuId"` + EnBrandName string `json:"enBrandName"` +} + +type ListParams struct { + ScrollID string `json:"scrollId"` + Total uint `json:"total"` + Entries []EntryParams `json:"entries"` +} + +type ListResponse struct { + Code string `json:"code"` + Result struct { + Data ListParams `json:"data"` + ErrCode uint `json:"errCode"` + ErrMsg string `json:"errMsg"` + Success bool `json:"success"` + } `json:"result"` +} diff --git a/api/rest/sku/skuPrice.go b/api/rest/sku/skuPrice.go new file mode 100644 index 0000000..c6b9485 --- /dev/null +++ b/api/rest/sku/skuPrice.go @@ -0,0 +1,46 @@ +package sku + +import "git.oa00.com/go/jcook-sdk/api/rest" + +// GetSkuPriceRequest 请求sku价格. +type GetSkuPriceRequest struct { + CtpProtocol rest.CtpProtocol `json:"ctpProtocol"` + SkuPriceInfoParam PriceParam `json:"skuPriceInfoParam"` +} +type PriceParam struct { + SkuIDSet []uint `json:"skuIdSet"` +} + +func (o GetSkuPriceRequest) GetApiName() string { + return "jingdong.ctp.ware.price.getSkuPriceInfoList" +} + +func (o GetSkuPriceRequest) GetRespName() string { + return "jingdong_ctp_ware_price_getSkuPriceInfoList_responce" +} + +func (o GetSkuPriceRequest) GetRespObj() interface{} { + return GetSkuPriceResponse{} +} + +// GetSkuPriceResponse 请求sku价格返回 +type GetSkuPriceResponse struct { + Result struct { + ErrCode uint `json:"errCode"` + ErrMsg string `json:"errMsg"` + Success bool `json:"success"` + Data PriceDetail `json:"data"` + } `json:"result"` +} +type PriceDetail struct { + SkuPriceList []Price `json:"skuPriceList"` + CustomerId uint `json:"customerId"` + ChannelId uint `json:"channelId"` +} + +type Price struct { + ErrorMessage string `json:"errorMessage"` + SkuPrice float64 `json:"skuPrice"` + SkuId uint `json:"skuId"` + IsSuccess bool `json:"isSuccess"` +} diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..18a7836 --- /dev/null +++ b/go.mod @@ -0,0 +1,8 @@ +module git.oa00.com/go/jcook-sdk + +go 1.16 + +require ( + github.com/mitchellh/mapstructure v1.4.1 + github.com/stretchr/testify v1.7.0 +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..4cea766 --- /dev/null +++ b/go.sum @@ -0,0 +1,13 @@ +github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/mitchellh/mapstructure v1.4.1 h1:CpVNEelQCZBooIPDn+AR3NpivK/TIKU8bDxdASFVQag= +github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/util/http/http.go b/util/http/http.go new file mode 100644 index 0000000..7da566f --- /dev/null +++ b/util/http/http.go @@ -0,0 +1,66 @@ +package http + +import ( + "bytes" + "fmt" + "io" + "net/http" + "net/url" +) + +var ( + client = &http.Client{} +) + +func init() { + +} + +func FormatUrl(endPoint string, isHttps bool) string { + if isHttps { + return fmt.Sprintf("https://%s", endPoint) + } else { + return fmt.Sprintf("http://%s", endPoint) + } +} + +func JGet(url string, params url.Values, header map[string]string) ([]byte, error) { + req, _ := http.NewRequest("GET", url, nil) + for k, v := range header { + req.Header.Add(k, v) + } + req.URL.RawQuery = params.Encode() + resp, err := client.Do(req) + if err != nil { + return []byte(""), err + } + defer func(Body io.ReadCloser) { + err = Body.Close() + if err != nil { + fmt.Println(err.Error()) + } + }(resp.Body) + + return io.ReadAll(resp.Body) +} + +func JPostJson(url string, jsonStr []byte, header map[string]string) ([]byte, error) { + req, _ := http.NewRequest("POST", url, bytes.NewBuffer(jsonStr)) + req.Header.Set("Content-Type", "application/json") + for k, v := range header { + req.Header.Add(k, v) + } + resp, err := client.Do(req) + if err != nil { + return []byte(""), err + } + + defer func(Body io.ReadCloser) { + err = Body.Close() + if err != nil { + fmt.Println(err.Error()) + } + }(resp.Body) + + return io.ReadAll(resp.Body) +} diff --git a/util/security/md5.go b/util/security/md5.go new file mode 100644 index 0000000..41b57ba --- /dev/null +++ b/util/security/md5.go @@ -0,0 +1,31 @@ +package security + +import ( + "crypto/md5" + "encoding/hex" + "fmt" + "sort" + "strings" +) + +func Md5OrderlyWithSecret(secret string, data map[string]string) string { + h := md5.New() + + var order []string + + for key, _ := range data{ + order = append(order, key) + } + + sort.Strings(order) + + h.Write([]byte(secret)) + + for _, value := range order{ + h.Write([]byte(fmt.Sprintf("%s%s", value, data[value]))) + } + + h.Write([]byte(secret)) + + return strings.ToUpper(hex.EncodeToString(h.Sum(nil))) +} diff --git a/util/security/sha1.go b/util/security/sha1.go new file mode 100644 index 0000000..967427d --- /dev/null +++ b/util/security/sha1.go @@ -0,0 +1,37 @@ +package security + +import ( + "crypto/hmac" + "crypto/sha1" + "encoding/base64" + "fmt" + "sort" + "strings" +) + +func map2str(data map[string]string, sep string) string { + var temp []string + + for key, _ := range data { + temp = append(temp, key) + } + + sort.Strings(temp) + + var tt []string + for _, v := range temp { + tt = append(tt, fmt.Sprintf("%s=%s", v, data[v])) + } + + return strings.Join(tt, sep) +} + +func Sha1OrderlyWithBase64(secret string, data map[string]string) string { + h := hmac.New(sha1.New, []byte(secret)) + + str := map2str(data, "&") + + h.Write([]byte(str)) + + return base64.StdEncoding.EncodeToString(h.Sum(nil)) +}