add jt express

This commit is contained in:
Sinh 2023-09-13 17:42:06 +07:00
parent 94d6e0c606
commit b15d883542
6 changed files with 255 additions and 0 deletions

2
go.mod
View File

@ -14,6 +14,7 @@ require (
github.com/elastic/go-licenser v0.4.1 // indirect
github.com/elastic/go-sysinfo v1.1.1 // indirect
github.com/elastic/go-windows v1.0.1 // indirect
github.com/go-resty/resty/v2 v2.7.0 // indirect
github.com/golang/snappy v0.0.3 // indirect
github.com/jcchavezs/porto v0.4.0 // indirect
github.com/joeshaw/multierror v0.0.0-20140124173710-69b34d4ec901 // indirect
@ -34,6 +35,7 @@ require (
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d // indirect
golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 // indirect
golang.org/x/mod v0.5.1 // indirect
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2 // indirect
golang.org/x/sys v0.0.0-20211102192858-4dd72447c267 // indirect
golang.org/x/tools v0.1.7 // indirect
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect

4
go.sum
View File

@ -17,6 +17,8 @@ github.com/elastic/go-sysinfo v1.1.1/go.mod h1:i1ZYdU10oLNfRzq4vq62BEwD2fH8KaWh6
github.com/elastic/go-windows v1.0.0/go.mod h1:TsU0Nrp7/y3+VwE82FoZF8gC/XFg/Elz6CcloAxnPgU=
github.com/elastic/go-windows v1.0.1 h1:AlYZOldA+UJ0/2nBuqWdo90GFCgG9xuyw9SYzGUtJm0=
github.com/elastic/go-windows v1.0.1/go.mod h1:FoVvqWSun28vaDQPbj2Elfc0JahhPB7WQEGa3c814Ss=
github.com/go-resty/resty/v2 v2.7.0 h1:me+K9p3uhSmXtrBZ4k9jcEAfJmuC8IivWHwaLZwPrFY=
github.com/go-resty/resty/v2 v2.7.0/go.mod h1:9PWDzw47qPphMRFfhsyk0NnSgvluHcljSMVIq3w7q0I=
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
@ -142,6 +144,8 @@ golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLL
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20211029224645-99673261e6eb/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2 h1:CIJ76btIcR3eFI5EgSo6k1qKw9KJexJuRLI9G7Hp5wE=
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=

View File

@ -0,0 +1,20 @@
package jtexpress
const (
apiHostProd = ""
apiHostDev = "https://test.jtexpress.vn"
apiPathEstimateFee = "/yuenan-interface-web/jtpos/inquiry!freight.action"
apiPathCreateOrder = "/yuenan-interface-web/order/orderAction!createOrder.action"
apiPathCancelOrder = "/yuenan-interface-web/order/orderAction!createOrder.action"
apiPathTrackingOrder = ""
)
const (
statusSuccess = "true"
)
const (
msgTypeEstimateFee = "FREIGHTQUERY"
msgTypeCreateOrder = "ORDERCREATE"
)

View File

@ -0,0 +1,111 @@
package jtexpress
import (
"crypto/md5"
"fmt"
"io"
"github.com/go-resty/resty/v2"
"git.selly.red/Selly-Modules/3pl/util/pjson"
)
func New(degestKey, companyID string, isProd, debug bool) *Client {
host := apiHostDev
if isProd {
host = apiHostProd
}
c := &Client{
DigestKey: degestKey,
EccompanyID: companyID,
IsProduction: isProd,
Debug: debug,
host: host,
httpClient: resty.New().SetDebug(debug),
}
return c
}
type Client struct {
DigestKey string
EccompanyID string
IsProduction bool
Debug bool
host string
httpClient *resty.Client
}
func (c *Client) EstimateFee(req *EstimateFeeReq) (*EstimateFeeItemRes, error) {
path := c.host + apiPathEstimateFee
data := pjson.ToJSONString(req)
resp, err := c.httpClient.R().
SetFormData(map[string]string{
"logistics_interface": data,
"data_digest": c.getDigest(data),
"msg_type": msgTypeEstimateFee,
"eccompanyid": c.EccompanyID,
}).
SetResult(&EstimateFeeRes{}).
Post(path)
if err != nil {
return nil, fmt.Errorf("jtepxress: request %s, err %v", path, err)
}
res := resp.Result().(*EstimateFeeRes)
if len(res.ResponseItems) == 0 {
return nil, fmt.Errorf("jtepxress: estimate fee empty response")
}
return res.ResponseItems[0], nil
}
func (c *Client) CancelOrder(req *CancelOrderReq) (*CancelOrderRes, error) {
path := c.host + apiPathCancelOrder
data := pjson.ToJSONString(req)
resp, err := c.httpClient.R().
SetFormData(map[string]string{
"logistics_interface": data,
"data_digest": c.getDigest(data),
"msg_type": msgTypeEstimateFee,
"eccompanyid": c.EccompanyID,
}).
SetResult(&CancelOrderRes{}).
Post(path)
if err != nil {
return nil, fmt.Errorf("jtepxress: request %s, err %v", path, err)
}
res := resp.Result().(*CancelOrderRes)
if len(res.ResponseItems) == 0 {
return nil, fmt.Errorf("jtepxress: cancel order empty response")
}
// return res.ResponseItems[0], nil
return nil, err
}
func (c *Client) CreateOrder(req *CreateOrderReq) (*CreateOrderItemRes, error) {
path := c.host + apiPathCreateOrder
data := pjson.ToJSONString(req)
resp, err := c.httpClient.R().
SetFormData(map[string]string{
"logistics_interface": data,
"data_digest": c.getDigest(data),
"msg_type": msgTypeCreateOrder,
"eccompanyid": c.EccompanyID,
}).
SetResult(&CreateOrderRes{}).
Post(path)
if err != nil {
return nil, fmt.Errorf("jtepxress: request %s, err %v", path, err)
}
res := resp.Result().(*CreateOrderRes)
if len(res.ResponseItems) == 0 {
return nil, fmt.Errorf("jtepxress: create order empty response")
}
return res.ResponseItems[0], nil
}
func (c *Client) getDigest(data string) string {
s := data + c.DigestKey
h := md5.New()
io.WriteString(h, s)
return fmt.Sprintf("%x", h.Sum(nil))
}

View File

@ -0,0 +1,75 @@
package jtexpress
type EstimateFeeLocation struct {
Prov string `json:"prov"`
City string `json:"city"`
Area string `json:"area"`
}
type EstimateFeeReq struct {
SelfAddress int `json:"selfAddress"`
ProductType string `json:"producttype"`
CusName string `json:"cusname"`
GoodsValue string `json:"goodsvalue"`
ItemsValue string `json:"itemsvalue"`
Weight string `json:"weight"`
Sender EstimateFeeLocation `json:"sender"`
Receiver EstimateFeeLocation `json:"receiver"`
Decs string `json:"decs"`
FeeType string `json:"feetype"`
}
type CreateOrderReq struct {
Customerid string `json:"customerid"`
Txlogisticid string `json:"txlogisticid"`
Ordertype int `json:"ordertype"`
Servicetype int `json:"servicetype"`
SelfAddress int `json:"selfAddress"`
Special string `json:"special"`
Partsign string `json:"partsign"`
Sender CreateOrderLocation `json:"sender"`
Receiver CreateOrderLocation `json:"receiver"`
Createordertime string `json:"createordertime"`
Sendstarttime string `json:"sendstarttime"`
Sendendtime string `json:"sendendtime"`
Paytype string `json:"paytype"`
Itemsvalue string `json:"itemsvalue"`
Goodsvalue string `json:"goodsvalue"`
IsInsured string `json:"isInsured"`
Items []OrderItem `json:"items"`
Weight string `json:"weight"`
Volume string `json:"volume"`
Remark string `json:"remark"`
}
type CreateOrderLocation struct {
Name string `json:"name"`
Phone string `json:"phone"`
Mobile string `json:"mobile"`
Prov string `json:"prov"`
City string `json:"city"`
Area string `json:"area"`
Address string `json:"address"`
}
type OrderItem struct {
Itemname string `json:"itemname"`
EnglishName string `json:"englishName"`
Number string `json:"number"`
Itemvalue string `json:"itemvalue"`
Desc string `json:"desc"`
}
type CancelOrderReq struct {
Eccompanyid string `json:"eccompanyid"`
Customerid string `json:"customerid"`
Logisticproviderid string `json:"logisticproviderid"`
Fieldlist []CancelOrderFieldList `json:"fieldlist"`
}
type CancelOrderFieldList struct {
Txlogisticid string `json:"txlogisticid"`
Fieldname string `json:"fieldname"`
Fieldvalue string `json:"fieldvalue"`
Remark string `json:"remark"`
}

View File

@ -0,0 +1,43 @@
package jtexpress
type EstimateFeeItemRes struct {
ProductType string `json:"producttype"`
Price string `json:"price"`
CodFee string `json:"codfee"`
InsuranceFee string `json:"insurancefee"`
DiscountFee string `json:"discountFee"`
Success string `json:"success"`
Reason string `json:"reason"`
}
type EstimateFeeRes struct {
LogisticProviderID string `json:"logisticproviderid"`
ResponseItems []*EstimateFeeItemRes `json:"responseitems"`
}
type CreateOrderRes struct {
LogisticProviderID string `json:"logisticproviderid"`
ResponseItems []*CreateOrderItemRes `json:"responseitems"`
}
type CreateOrderItemRes struct {
Billcode string `json:"billcode"`
CodFee string `json:"codFee"`
Code string `json:"code"`
DiscountFee string `json:"discountFee"`
DispatchSite string `json:"dispatchSite"`
InquiryFee string `json:"inquiryFee"`
Insurancefee string `json:"insurancefee"`
Reason string `json:"reason"`
Reportnewurl string `json:"reportnewurl"`
Reporturl string `json:"reporturl"`
ReporturlJT string `json:"reporturlJT"`
Success string `json:"success"`
Transport string `json:"transport"`
Txlogisticid string `json:"txlogisticid"`
}
type CancelOrderRes struct {
LogisticProviderID string `json:"logisticproviderid"`
ResponseItems []*CreateOrderItemRes `json:"responseitems"`
}