提交 4bf303bb authored 作者: zhanglibo's avatar zhanglibo

京东

上级 92bdace8
/go.sum
/.idea
...@@ -5,6 +5,7 @@ go 1.16 ...@@ -5,6 +5,7 @@ go 1.16
require ( require (
github.com/gogf/gf v1.16.6 github.com/gogf/gf v1.16.6
github.com/kjk/betterguid v0.0.0-20170621091430-c442874ba63a github.com/kjk/betterguid v0.0.0-20170621091430-c442874ba63a
github.com/nsqio/go-nsq v1.1.0
github.com/olivere/elastic/v7 v7.0.30 github.com/olivere/elastic/v7 v7.0.30
) )
差异被折叠。
package logs package logs
import ( import (
"context"
"fmt" "fmt"
"github.com/gogf/gf/errors/gerror" "github.com/gogf/gf/errors/gerror"
"github.com/gogf/gf/frame/g" "github.com/gogf/gf/frame/g"
"github.com/gogf/gf/os/glog" "github.com/gogf/gf/os/glog"
) )
type RequestLogReq struct { type RequestLogReq struct {
Path string //存储路径 Path string //存储路径
RequestURI string //请求URI RequestURI string //请求URI
...@@ -20,13 +20,14 @@ type RequestLogReq struct { ...@@ -20,13 +20,14 @@ type RequestLogReq struct {
ResponseTime int64 //响应时间 毫秒级 ResponseTime int64 //响应时间 毫秒级
} }
const FormatErr = "参数【%v】错误【%v】响应时间【%v】"
const FormatSuc = "参数【%v】响应【%v】响应时间【%v】"
//统一请求日志 20211208 gk //统一请求日志 20211208 gk
func RequestLog(req RequestLogReq){ func RequestLog(req RequestLogReq) {
Info(req.Path, "请求ID:【%v】 服务名称: 【%v】 请求路径:【%v】 请求方法: 【%v】 请求参数: 【%v】 响应参数: 【%v】 响应时间:【%v ms】error:【%v】", Info(req.Path, "请求ID:【%v】 服务名称: 【%v】 请求路径:【%v】 请求方法: 【%v】 请求参数: 【%v】 响应参数: 【%v】 响应时间:【%v ms】error:【%v】",
req.RequestID, req.ServerName, req.RequestURI, req.Method, req.Params,req.Response, req.ResponseTime, nil) req.RequestID, req.ServerName, req.RequestURI, req.Method, req.Params, req.Response, req.ResponseTime, nil)
if req.Err != nil { if req.Err != nil {
Error("%+v", gerror.Wrap(req.Err, req.RequestID)) Error("%+v", gerror.Wrap(req.Err, req.RequestID))
...@@ -35,9 +36,9 @@ func RequestLog(req RequestLogReq){ ...@@ -35,9 +36,9 @@ func RequestLog(req RequestLogReq){
} }
//记录info日志 20211208 gk //记录info日志 20211208 gk
func Info(path string,format string, v ...interface{}) { func Info(path string, format string, v ...interface{}) {
newPath := g.Log().GetPath() + "/" + path newPath := g.Log().GetPath() + "/" + path
glog.Path(newPath).File( "info-{Ymd}.log").Println(fmt.Sprintf(format, v...)) glog.Path(newPath).File("info-{Ymd}.log").Println(fmt.Sprintf(format, v...))
} }
//记录error日志 20211208 gk //记录error日志 20211208 gk
...@@ -49,8 +50,16 @@ func Error(format string, v ...interface{}) { ...@@ -49,8 +50,16 @@ func Error(format string, v ...interface{}) {
//检查错误 20211208 gk //检查错误 20211208 gk
func CheckErr(err error, extra string) bool { func CheckErr(err error, extra string) bool {
if err != nil { if err != nil {
Error("%+v",gerror.Wrap(err, extra)) Error("%+v", gerror.Wrap(err, extra))
return true return true
} }
return false return false
} }
\ No newline at end of file
func Infof(ctx context.Context, path string, format string, v ...interface{}) {
g.Log().Ctx(ctx).Cat(path).Infof(format, v...)
}
func Errorf(ctx context.Context, format string, v ...interface{}) {
g.Log().Ctx(ctx).Cat("error").Infof(format, v...)
}
## stbz/library
胜天半子内部调用库
## 地址
https://gitlab.jxhh.com/stbz/library
## 限制
golang版本 >= 1.16
## 使用方法
```golang
package main
import (
"github.com/gogf/gf/net/ghttp"
"gitlab.jxhh.com/stbz/library.git/upstream/jingdong"
)
//初始化配置【可在boot使用】
var conf *jingdong.Config
_ = g.Cfg().GetStruct("jd", &conf
jingdong.New(conf)
//订单详情
InfoRes,err:=jingdong.Order.GetOrderInfo(ctx, "236317795961")
g.Dump(InfoRes)
g.Dump(err)
//地址解析
ParseRes, err := jingdong.Address.Parse(ctx, "四川省成都市武侯区天府四街保利星座5栋")
g.Dump(ParseRes)
g.Dump(err)
```
package jingdong
import (
"context"
"github.com/gogf/gf/crypto/gmd5"
"github.com/gogf/gf/encoding/gjson"
"github.com/gogf/gf/frame/g"
"github.com/gogf/gf/os/gtime"
"github.com/gogf/gf/util/gconv"
"gitlab.jxhh.com/stbz/library.git/logs"
"net/url"
"strings"
"time"
)
type Config struct {
ApiUrl string
BasePathUrl string
GetTokenUrl string
RefreshTokenUrl string
AppKey string
AppSecret string
UserName string
PassWord string
Mobile string
Email string
SubmitState string
CompanyName string
}
type CommonRes struct {
Success bool `json:"success"`
ResultCode string `json:"resultCode"`
ResultMessage string `json:"resultMessage"`
}
type client struct {
*Config
AccessToken string
}
var server *client
const CacheKey = "jingdong:token"
const pkgName = "jingdong"
func New(config *Config) {
_ = gconv.Scan(config, &server)
return
}
//post 请求
func (s *client) post(ctx context.Context, method string, params g.MapStrStr) (str string, err error) {
Start := gtime.TimestampMilli()
postValues := url.Values{}
for k, v := range params {
postValues.Add(k, v)
}
postString := postValues.Encode()
Request := g.Client()
Request.SetHeader("Content-Type", "application/x-www-form-urlencoded")
resp, err := Request.Timeout(time.Second*5).Post(method, postString)
defer func() {
_ = resp.Body.Close()
paramStr := gjson.New(params).MustToJsonString()
ctx = context.WithValue(ctx, "Method", "POST")
ctx = context.WithValue(ctx, "URI", method)
if err != nil {
logs.Errorf(ctx, logs.FormatErr, paramStr, err.Error(), gtime.TimestampMilli()-Start)
} else {
logs.Infof(ctx, pkgName, logs.FormatSuc, paramStr, str, gtime.TimestampMilli()-Start)
}
}()
if err != nil {
return
}
str = resp.ReadAllString()
return
}
//getSign 签名
func (s *client) getSign(timeStamp string) string {
var str = s.AppSecret + timeStamp + s.AppKey + s.UserName
return strings.ToUpper(gmd5.MustEncrypt(str + gmd5.MustEncrypt(s.PassWord) + "access_token" + s.AppSecret))
}
// requestApi 请求
func (s *client) requestApi(ctx context.Context, method string, businessParams g.MapStrStr) (str string, err error) {
params, err := s.createPostRequest(ctx, businessParams)
if err != nil {
return
}
urlMethod := s.ApiUrl + method
str, err = s.post(ctx, urlMethod, params)
return
}
func (s *client) createPostRequest(ctx context.Context, businessParams g.MapStrStr) (res g.MapStrStr, err error) {
err = s.getAccessToken(ctx)
if err != nil {
return
}
res = g.MapStrStr{
"token": s.AccessToken,
}
if businessParams != nil {
for k, v := range businessParams {
res[k] = v
}
}
return
}
package jingdong
import (
"context"
"github.com/gogf/gf/encoding/gjson"
"github.com/gogf/gf/util/gconv"
)
type addressJD struct {
}
var Address = addressJD{}
type ParseRes struct {
*CommonRes
Result struct {
NationId string `json:"nationId"` //国家ID
Nation string `json:"nation"` //国家名称
ProvinceId int `json:"provinceId"` //一级地址ID
Province string `json:"province"` //一级地址名称
CityId int `json:"cityId"` //二级地址ID
City string `json:"city"` //二级地址名称
CountyId int `json:"countyId"` //三级地址ID
County string `json:"county"` //三级地址名称
TownId int `json:"townId"` //四级地址ID
Town string `json:"town"` //四级地址名称
} `json:"result"`
}
type GetTownRes struct {
*CommonRes
Result map[string]int `json:"result"`
}
//Parse 地址详情转换京东地址编码
func (addressJD) Parse(ctx context.Context, address string) (res *ParseRes, err error) {
method := "area/getJDAddressFromAddress"
param := map[string]string{
"address": address,
}
result, err := server.requestApi(ctx, method, param)
if err != nil {
return
}
err = gjson.New(result).Scan(&res)
return
}
// CheckArea 验证地址有效性
func (addressJD) CheckArea(ctx context.Context, provinceId, cityId, countyId, townId interface{}) (res *CommonRes, err error) {
method := "area/checkArea"
param := map[string]string{
"provinceId": gconv.String(provinceId),
"cityId": gconv.String(cityId),
"countyId": gconv.String(countyId),
"townId": gconv.String(townId),
}
result, err := server.requestApi(ctx, method, param)
if err != nil {
return
}
err = gjson.New(result).Scan(&res)
return
}
// GetTown 查询四级地址
func (addressJD) GetTown(ctx context.Context, id interface{}) (res *GetTownRes, err error) {
method := "area/getTown"
param := map[string]string{
"id": gconv.String(id),
}
result, err := server.requestApi(ctx, method, param)
if err != nil {
return
}
err = gjson.New(result).Scan(&res)
return
}
package jingdong
import (
"context"
"github.com/gogf/gf/container/garray"
"github.com/gogf/gf/encoding/gjson"
"github.com/gogf/gf/util/gconv"
)
type goodsJD struct {
}
var Goods = goodsJD{}
type CheckSaleRes struct {
*CommonRes
Result []struct {
SkuId int `json:"skuid"` //商品编号
Name string `json:"name"` //销售名称
SaleState int `json:"saleState"` //是否可售 1:是,0:否
IsCanVAT int `json:"isCanVAT"` //是否可开增票,1:支持,0:不支持
Is7ToReturn int `json:"is7ToReturn"` //是否支持7天退货,1:是,0:不支持
} `json:"result"`
}
type CheckOnSaleRes struct {
*CommonRes
Result []struct {
Sku int `json:"sku"` //商品编号
State int `json:"state"` //1:上架,0:下架
} `json:"result"`
}
type GetStockRes struct {
*CommonRes
Result []struct {
SkuID int `json:"skuId"` //商品编号
AreaID string `json:"areaId"` //入参时传入的区域码area。因京东目前是3、4级地址均支持,存在areaId在传入的3级地址后填充4级地址“_0“后返回的情况。
StockStateID int `json:"stockStateId"` //存状态编号。 参考枚举值: 33,39,40,36,34,99
StockStateDesc string `json:"StockStateDesc"` //库存状态描述。以下为stockStateId不同时,此字段不同的返回值:
} `json:"result"`
}
type CheckAreaLimitRes struct {
*CommonRes
Result []struct {
SkuID int `json:"skuId"` //商品编码
IsAreaRestrict bool `json:"isAreaRestrict"` //true 代表区域受限 false 区域不受限
} `json:"result"`
}
type GetUnionBalanceRes struct {
*CommonRes
Result struct {
Balance struct {
Pin string `json:"pin"`
RemainLimit float64 `json:"remainLimit"`
} `json:"balance"`
}
}
type GetProductsPriceRes struct {
*CommonRes
Result []struct {
SkuID int `json:"skuId"`
Price float64 `json:"price"`
JdPrice float64 `json:"jdPrice"`
MarketPrice float64 `json:"marketPrice"`
} `json:"result"`
}
// CheckSale 商品可售验证接口
func (goodsJD) CheckSale(ctx context.Context, req *garray.Array) (res *CheckSaleRes, err error) {
method := "product/check"
param := map[string]string{
"skuIds": req.Join(","),
}
result, err := server.requestApi(ctx, method, param)
if err != nil {
return
}
err = gjson.New(result).Scan(&res)
return
}
// CheckOnSale 查询商品上下架状态
func (goodsJD) CheckOnSale(ctx context.Context, req *garray.Array) (res *CheckOnSaleRes, err error) {
method := "product/skuState"
param := map[string]string{
"sku": req.Join(","),
}
result, err := server.requestApi(ctx, method, param)
if err != nil {
return
}
err = gjson.New(result).Scan(&res)
return
}
//GetStock 查询商品库存
func (goodsJD) GetStock(ctx context.Context, req *garray.Array, area string) (res *GetStockRes, err error) {
method := "stock/getNewStockById"
param := map[string]string{
"skuNums": req.Join(","),
"area": area,
}
result, err := server.requestApi(ctx, method, param)
if err != nil {
return
}
err = gjson.New(result).Scan(&res)
return
}
// CheckAreaLimit 查询商品区域购买限制
func (goodsJD) CheckAreaLimit(ctx context.Context, skuIds *garray.Array, provinceID, cityID, countyID, townID interface{}) (res *CheckAreaLimitRes, err error) {
method := "product/checkAreaLimit"
param := map[string]string{
"skuIds": skuIds.Join(","),
"province": gconv.String(provinceID),
"city": gconv.String(cityID),
"county": gconv.String(countyID),
"town": gconv.String(townID),
}
result, err := server.requestApi(ctx, method, param)
if err != nil {
return
}
err = gjson.New(result).Scan(&res)
return
}
//GetProductsPrice 商品价格
func (goodsJD) GetProductsPrice(ctx context.Context, skus *garray.Array) (res *GetProductsPriceRes, err error) {
method := "price/getSellPrice"
param := map[string]string{
"sku": skus.Join(","),
"queryExts": "marketPrice",
}
result, err := server.requestApi(ctx, method, param)
if err != nil {
return
}
err = gjson.New(result).Scan(&res)
return
}
package jingdong
import (
"context"
"github.com/gogf/gf/container/garray"
"github.com/gogf/gf/encoding/gjson"
)
type msgJD struct {
}
var Msg = msgJD{}
type GetPushMessages struct {
*CommonRes
Result []struct {
Id int `json:"id"`
Type int `json:"type"`
Time string `json:"time"`
Result interface{} `json:"result"`
} `json:"result"`
}
type DelPushMessages struct {
*CommonRes
Result bool `json:"result"`
}
func (msgJD) GetPushMessages(ctx context.Context, id *garray.Array) (res *GetPushMessages, err error) {
method := "message/get"
param := map[string]string{
"type": id.Join(","),
}
result, err := server.requestApi(ctx, method, param)
if err != nil {
return
}
err = gjson.New(result).Scan(&res)
return
}
func (msgJD) DeletePushMessage(ctx context.Context, id *garray.Array) (res *DelPushMessages, err error) {
method := "message/del"
param := map[string]string{
"id": id.Join(","),
}
result, err := server.requestApi(ctx, method, param)
if err != nil {
return
}
err = gjson.New(result).Scan(&res)
return
}
package jingdong
import (
"context"
"github.com/gogf/gf/encoding/gjson"
"github.com/gogf/gf/frame/g"
)
type orderJD struct {
}
//Order 订单
var Order = orderJD{}
//GetDeliveryRes 物流轨迹
type GetDeliveryRes struct {
*CommonRes
Result struct {
OrderTrack []struct {
Content string `json:"content"`
MsgTime string `json:"msgTime"`
Operator string `json:"operator"`
} `json:"orderTrack"`
WaybillCode []struct {
OrderID string `json:"orderId"`
ParentID string `json:"parentId"`
Carrier string `json:"carrier"`
DeliveryOrderID string `json:"deliveryOrderId"`
} `json:"waybillCode"`
JdOrderID int `json:"jdOrderId"`
} `json:"result"`
}
//PriceSnap 商品价格
type PriceSnap struct {
SkuID int `json:"skuId"`
Price int `json:"price"`
}
//PlaceOrderReq 下单
type PlaceOrderReq struct {
OrderSn string
SkuNums []*SkuNums
Consignee string
Phone string
Address *PlaceOrderAddress
PriceSnap []*PriceSnap
}
//PlaceOrderAddress 下单地址
type PlaceOrderAddress struct {
Province string
City string
County string
Town string
Desc string
}
//PlaceOrderRes 下单
type PlaceOrderRes struct {
*CommonRes
Result struct {
JdOrderID int64 `json:"jdOrderId"`
OrderPrice float64 `json:"orderPrice"`
OrderNakedPrice float64 `json:"orderNakedPrice"`
OrderTaxPrice float64 `json:"orderTaxPrice"`
Sku []*OrderSkuItem `json:"sku"`
} `json:"result"`
}
//OrderSkuItem 订单商品
type OrderSkuItem struct {
SkuID int `json:"skuId"`
Num int `json:"num"`
Price float64 `json:"price"`
Name string `json:"name"`
NakedPrice float64 `json:"nakedPrice"`
}
//ReflectOrderRes 反查订单
type ReflectOrderRes struct {
*CommonRes
Result string `json:"result"`
}
//GetOrderRes 订单详情
type GetOrderRes struct {
*CommonRes
Result struct {
JdOrderID int64 `json:"jdOrderId"`
Type int `json:"type"`
Freight float64 `json:"freight"`
OrderPrice float64 `json:"orderPrice"`
OrderNakedPrice float64 `json:"orderNakedPrice"`
OrderTaxPrice float64 `json:"orderTaxPrice"`
Sku []*OrderSkuItem `json:"sku"`
OrderState int `json:"orderState"`
State int `json:"state"`
POrder struct {
JdOrderID int64 `json:"jdOrderId"`
Freight float64 `json:"freight"`
OrderPrice float64 `json:"orderPrice"`
OrderNakedPrice float64 `json:"orderNakedPrice"`
Sku []*OrderSkuItem `json:"sku"`
} `json:"pOrder"`
COrder []struct {
POrder string `json:"pOrder"`
JdOrderID int `json:"jdOrderId"`
Freight float64 `json:"freight"`
OrderPrice float64 `json:"orderPrice"`
OrderNakedPrice float64 `json:"orderNakedPrice"`
Sku []OrderSkuItem `json:"sku"`
} `json:"cOrder"`
} `json:"result"`
}
//GetFreightRes 运费
type GetFreightRes struct {
*CommonRes
Result struct {
Freight float64 `json:"freight"`
BaseFreight float64 `json:"baseFreight"`
RemoteRegionFreight float64 `json:"remoteRegionFreight"`
} `json:"result"`
}
//SkuNums 商品数量
type SkuNums struct {
SkuID int `json:"skuId"`
Num int `json:"num"`
}
// GetDelivery 物流信息
func (*orderJD) GetDelivery(ctx context.Context, OrderID string) (res *GetDeliveryRes, err error) {
method := "order/orderTrack"
param := g.MapStrStr{
"jdOrderId": OrderID,
"waybillCode": "1",
}
result, err := server.requestApi(ctx, method, param)
if err != nil {
return
}
err = gjson.New(result).Scan(&res)
return
}
// PlaceOrder 下单
func (orderJD) PlaceOrder(ctx context.Context, req *PlaceOrderReq) (res *PlaceOrderRes, err error) {
method := "order/submitOrder"
var param = g.MapStrStr{
"thirdOrder": req.OrderSn,
"sku": gjson.New(req.SkuNums).MustToJsonString(),
"orderPriceSnap": gjson.New(req.PriceSnap).MustToJsonString(),
"name": req.Consignee,
"mobile": req.Phone,
"province": req.Address.Province,
"city": req.Address.City,
"county": req.Address.County,
"town": req.Address.Town,
"address": req.Address.Desc,
"email": server.Email,
"companyName": server.CompanyName,
"submitState": server.SubmitState,
"invoicePhone": server.Mobile,
"invoiceState": "2",
"invoiceType": "4",
"selectedInvoiceTitle": "5",
"invoiceContent": "1",
"paymentType": "4",
"isUseBalance": "1",
"doOrderPriceMode": "1",
}
result, err := server.requestApi(ctx, method, param)
if err != nil {
return
}
err = gjson.New(result).Scan(&res)
return
}
// ReflectOrder 反查订单
func (orderJD) ReflectOrder(ctx context.Context, thirdOrder string) (res *ReflectOrderRes, err error) {
method := "order/selectJdOrderIdByThirdOrder"
param := g.MapStrStr{
"thirdOrder": thirdOrder,
}
result, err := server.requestApi(ctx, method, param)
if err != nil {
return
}
err = gjson.New(result).Scan(&res)
return
}
// GetOrderInfo 订单详情
func (orderJD) GetOrderInfo(ctx context.Context, OrderID string) (res *GetOrderRes, err error) {
method := "order/selectJdOrder"
param := g.MapStrStr{
"jdOrderId": OrderID,
}
result, err := server.requestApi(ctx, method, param)
if err != nil {
return
}
_ = gjson.New(result).Scan(&res)
return
}
// GetFreight 查询运费
func (orderJD) GetFreight(ctx context.Context, sku []*SkuNums, province, city, county, town string) (res *GetFreightRes, err error) {
method := "order/getFreight"
param := g.MapStrStr{
"sku": gjson.New(sku).MustToJsonString(),
"province": province,
"city": city,
"county": county,
"town": town,
"paymentType": "4",
}
result, err := server.requestApi(ctx, method, param)
if err != nil {
return
}
err = gjson.New(result).Scan(&res)
return
}
// ConfirmReceived 确认收货
func (orderJD) ConfirmReceived(ctx context.Context, OrderID string) (res *CommonRes, err error) {
method := "order/confirmReceived"
param := g.MapStrStr{
"jdOrderId": OrderID,
}
result, err := server.requestApi(ctx, method, param)
if err != nil {
return
}
err = gjson.New(result).Scan(&res)
return
}
package jingdong
import (
"context"
"github.com/gogf/gf/encoding/gjson"
"github.com/gogf/gf/frame/g"
"github.com/gogf/gf/util/gconv"
)
type refundJD struct {
}
var Refund = refundJD{}
type RefundCancelRes struct {
*CommonRes
Result bool `json:"result"`
}
type ApplyReq struct {
JdOrderId uint `json:"jdOrderId"`
CustomerExpect uint `json:"customerExpect"`
QuestionDesc string `json:"questionDesc"`
IsNeedDetectionReport bool `json:"isNeedDetectionReport"`
IsHasPackage bool `json:"isHasPackage"`
QuestionPic string `json:"questionPic"`
PackageDesc int `json:"packageDesc"`
UserInfoDto *AfterSaleCustomerDto `json:"asCustomerDto"`
PickDto *AfterSalePickwareDto `json:"asPickwareDto"`
ReturnDto *AfterSaleReturnwareDto `json:"asReturnwareDto"`
DetailDto *AfterSaleDetailDto `json:"asDetailDto"`
}
type AfterSaleCustomerDto struct {
Name string `json:"customerContactName"` //联系人,最多50字符,
Tel string `json:"customerTel"` //联系电话,最多50字符
Phone string `json:"customerMobilePhone"` //手机号,最多50字符
}
type AfterSalePickwareDto struct {
Type int `json:"pickwareType"` //取件方式:4上门取件; 7 客户送货;40客户发货
Province int `json:"pickwareProvince"` //取件省,必填
City int `json:"pickwareCity"` //取件市,必填
County int `json:"pickwareCounty"` //取件县,必填
Village int `json:"pickwareVillage"` //取件乡镇
Address string `json:"pickwareAddress"` //取件街道地址,取件方式为4(上门取件)时必填,最多500字符
}
type AfterSaleReturnwareDto struct {
Type int `json:"returnwareType"` //返件方式:自营配送(10),第三方配送(20);
Province int `json:"returnwareProvince"` //返件省
City int `json:"returnwareCity"` //返件市
County int `json:"returnwareCounty"` //返件县
Village int `json:"returnwareVillage"` //返件乡镇
Address string `json:"returnwareAddress"` //返件街道地址,最多500字符
}
type AfterSaleDetailDto struct {
Id int `json:"skuId"` //商品编号
Num uint `json:"skuNum"` //商品申请数量
}
type GetServiceListReq struct {
JdOrderID string `json:"jdOrderId"`
PageIndex int `json:"pageIndex"`
PageSize int `json:"pageSize"`
}
type GetServiceListRes struct {
*CommonRes
Result struct {
TotalNum int `json:"totalNum"`
PageSize int `json:"pageSize"`
PageNum int `json:"pageNum"`
PageIndex int `json:"pageIndex"`
ServiceInfoList []struct {
AfsServiceId int `json:"afsServiceId"`
WareId int `json:"wareId"`
Cancel int `json:"cancel"`
} `json:"serviceInfoList"`
} `json:"result"`
}
type GetServiceDetailRes struct {
*CommonRes
Result struct {
AfsServiceId int `json:"afsServiceId"`
CustomerExpect int `json:"customerExpect"`
AfsApplyTime string `json:"afsApplyTime"`
OrderId int `json:"orderId"`
ApproveNotes string `json:"approveNotes"`
ApprovedResult int `json:"approvedResult"`
AfsServiceStep int `json:"afsServiceStep"`
ProcessResult int `json:"processResult"`
ServiceAftersalesAddressInfoDTO struct {
Address string `json:"address"`
Tel string `json:"tel"`
LinkMan string `json:"linkMan"`
PostCode string `json:"postCode"`
} `json:"serviceAftersalesAddressInfoDto"`
ServiceFinanceDetailInfoDTOs []struct {
ServiceFinanceDetailInfoDTO
RefundPrice float64 `json:"refundPrice"`
} `json:"serviceFinanceDetailInfoDTOs"`
} `json:"result"`
}
type ServiceFinanceDetailInfoDTO struct {
RefundWay int `json:"refundWay"`
RefundWayName string `json:"refundWayName"`
Status int `json:"status"`
StatusName string `json:"statusName"`
WareName string `json:"wareName"`
WareId int `json:"wareId"`
}
type RefundCommonReq struct {
OrderID string `json:"jdOrderId"`
SkuID string `json:"skuId"`
}
type CheckIsSupportRes struct {
*CommonRes
Result int `json:"result"`
}
type GetSupportTypeRes struct {
*CommonRes
Result []*CodeItem `json:"result"`
}
type CodeItem struct {
Code string `json:"code"`
Name string `json:"name"`
}
type GetReturnTypeRes struct {
*CommonRes
Result []*CodeItem `json:"result"`
}
// UpdateSendSku 根据填写单号
func (refundJD) UpdateSendSku(ctx context.Context, postData string) (res *CommonRes, err error) {
method := "afterSale/updateSendSku"
param := g.MapStrStr{
"param": postData,
}
result, err := server.requestApi(ctx, method, param)
if err != nil {
return
}
_ = gjson.New(result).Scan(&res)
return
}
//AuditCancel 取消服务单
func (refundJD) AuditCancel(ctx context.Context, postData string) (res *CommonRes, err error) {
method := "afterSale/auditCancel"
param := g.MapStrStr{
"param": postData,
}
result, err := server.requestApi(ctx, method, param)
if err != nil {
return
}
_ = gjson.New(result).Scan(&res)
return
}
//RefundCancel 取消售后
func (refundJD) RefundCancel(ctx context.Context, id interface{}) (res *RefundCancelRes, err error) {
method := "afterSale/auditCancel"
req := g.Map{
"serviceIdList": gconv.Ints(id),
"approveNotes": "取消售后",
}
param := g.MapStrStr{
"param": gjson.New(req).MustToJsonString(),
}
result, err := server.requestApi(ctx, method, param)
if err != nil {
return
}
_ = gjson.New(result).Scan(&res)
return
}
// Apply 申请售后服务(退货、换货、维修)
func (refundJD) Apply(ctx context.Context, req *ApplyReq) (res *CommonRes, err error) {
method := "afterSale/createAfsApply"
param := g.MapStrStr{
"param": gjson.New(req).MustToJsonString(),
}
result, err := server.requestApi(ctx, method, param)
if err != nil {
return
}
_ = gjson.New(result).Scan(&res)
return
}
// GetServiceList 查询服务单根据客户账号和订单号分页查询服务单概要信息
func (refundJD) GetServiceList(ctx context.Context, req string) (res *GetServiceListRes, err error) {
method := "afterSale/getServiceListPage"
param := g.MapStrStr{
"param": gjson.New(&GetServiceListReq{
JdOrderID: req,
PageIndex: 1,
PageSize: 100,
}).MustToJsonString(),
}
result, err := server.requestApi(ctx, method, param)
if err != nil {
return
}
_ = gjson.New(result).Scan(&res)
return
}
// GetServiceDetail 根据服务单号查询服务单明细信息
func (refundJD) GetServiceDetail(ctx context.Context, req string) (res *GetServiceDetailRes, err error) {
method := "afterSale/getServiceDetailInfo"
param := g.MapStrStr{
"param": req,
}
result, err := server.requestApi(ctx, method, param)
if err != nil {
return
}
_ = gjson.New(result).Scan(&res)
return
}
// CheckIsSupport 查询订单商品是否允许售后
func (refundJD) CheckIsSupport(ctx context.Context, req *RefundCommonReq) (res *CheckIsSupportRes, err error) {
method := "afterSale/getAvailableNumberComp"
param := g.MapStrStr{
"param": gjson.New(req).MustToJsonString(),
}
result, err := server.requestApi(ctx, method, param)
if err != nil {
return
}
_ = gjson.New(result).Scan(&res)
return
}
// GetSupportType 查询订单商品售后类型
func (refundJD) GetSupportType(ctx context.Context, req *RefundCommonReq) (res *GetSupportTypeRes, err error) {
method := "afterSale/getCustomerExpectComp"
param := g.MapStrStr{
"param": gjson.New(req).MustToJsonString(),
}
result, err := server.requestApi(ctx, method, param)
if err != nil {
return
}
_ = gjson.New(result).Scan(&res)
return
}
// GetReturnType 查询支持的商品返回京东方式
func (refundJD) GetReturnType(ctx context.Context, req *RefundCommonReq) (res *GetReturnTypeRes, err error) {
method := "afterSale/getWareReturnJdComp"
param := g.MapStrStr{
"param": gjson.New(req).MustToJsonString(),
}
result, err := server.requestApi(ctx, method, param)
if err != nil {
return
}
_ = gjson.New(result).Scan(&res)
return
}
package jingdong
import (
"context"
"errors"
"github.com/gogf/gf/crypto/gmd5"
"github.com/gogf/gf/encoding/gjson"
"github.com/gogf/gf/frame/g"
"github.com/gogf/gf/os/gtime"
"github.com/gogf/gf/util/gconv"
"github.com/gogf/gf/util/gutil"
)
type getAccessTokenRes struct {
*CommonRes
Result *accessToken `json:"result"`
}
type refreshTokenRes struct {
*CommonRes
Result *accessToken `json:"result"`
}
type accessToken struct {
Uid string `json:"uid"`
AccessToken string `json:"access_token"`
RefreshToken string `json:"refresh_token"`
Time int64 `json:"time"`
ExpiresIn int64 `json:"expires_in"`
RefreshTokenExpires int64 `json:"refresh_token_expires"`
}
//getAccessToken 获取token
func (s *client) getAccessToken(ctx context.Context) (err error) {
var token *accessToken
cache, _ := g.Redis().DoVar("HGETALL", CacheKey)
if !cache.IsEmpty() {
_ = cache.Scan(&token)
if token.Time+token.ExpiresIn*1000 > gtime.TimestampMilli() {
s.AccessToken = token.AccessToken
return
}
return s.refreshToken(ctx, token)
}
timeStamp := gtime.Now().String()
sign := s.getSign(timeStamp)
var params = g.MapStrStr{
"grant_type": "access_token",
"client_id": s.AppKey,
"timestamp": timeStamp,
"username": server.UserName,
"password": gmd5.MustEncrypt(s.PassWord),
"sign": sign,
}
result, err := s.post(ctx, server.GetTokenUrl, params)
if err != nil {
return
}
var jdRes *getAccessTokenRes
_ = gjson.New(result).Scan(&jdRes)
if jdRes == nil {
err = errors.New("authorize failed,empty response")
return
}
if !jdRes.Success {
err = errors.New(jdRes.ResultMessage)
return
}
_, _ = g.Redis().Do("HMSET", append(g.Slice{CacheKey}, gutil.MapToSlice(gconv.Map(jdRes.Result))...)...)
s.AccessToken = jdRes.Result.AccessToken
return
}
//refreshToken 刷新token
func (s *client) refreshToken(ctx context.Context, req *accessToken) (err error) {
if req.RefreshTokenExpires < gtime.Timestamp() {
_, err = g.Redis().DoVar("DEL", CacheKey)
return s.getAccessToken(ctx)
}
var params = g.MapStrStr{
"refresh_token": req.RefreshToken,
"client_id": s.AppKey,
"client_secret": s.AppSecret,
}
result, err := s.post(ctx, s.RefreshTokenUrl, params)
if err != nil {
return
}
var jdRes *refreshTokenRes
err = gjson.New(result).Scan(&jdRes)
if err != nil {
return
}
if jdRes == nil {
return
}
if !jdRes.Success {
err = errors.New(jdRes.ResultMessage)
return
}
_, _ = g.Redis().Do("HMSET", append(g.Slice{CacheKey}, gutil.MapToSlice(gconv.Map(jdRes.Result))...)...)
s.AccessToken = jdRes.Result.AccessToken
return
}
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论