master #14
			
				
			
		
		
		
	
							
								
								
									
										2
									
								
								go.mod
								
								
								
								
							
							
						
						
									
										2
									
								
								go.mod
								
								
								
								
							|  | @ -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
								
								
								
								
							
							
						
						
									
										4
									
								
								go.sum
								
								
								
								
							|  | @ -21,6 +21,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= | ||||
|  | @ -146,6 +148,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= | ||||
|  |  | |||
|  | @ -0,0 +1,21 @@ | |||
| package jtexpress | ||||
| 
 | ||||
| const ( | ||||
| 	apiHostProd = "https://ylstandard.jtexpress.vn" | ||||
| 	apiHostDev  = "https://demo-ylstandard.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" | ||||
| 	msgTypeCancelOrder = "UPDATE" | ||||
| ) | ||||
|  | @ -0,0 +1,120 @@ | |||
| package jtexpress | ||||
| 
 | ||||
| import ( | ||||
| 	"crypto/md5" | ||||
| 	"fmt" | ||||
| 	"io" | ||||
| 
 | ||||
| 	"github.com/go-resty/resty/v2" | ||||
| 
 | ||||
| 	"git.selly.red/Selly-Modules/3pl/util/base64" | ||||
| 	"git.selly.red/Selly-Modules/3pl/util/pjson" | ||||
| ) | ||||
| 
 | ||||
| func New(digestKey, companyID string, isProd, debug bool) *Client { | ||||
| 	host := apiHostDev | ||||
| 	if isProd { | ||||
| 		host = apiHostProd | ||||
| 	} | ||||
| 	c := &Client{ | ||||
| 		DigestKey:    digestKey, | ||||
| 		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) (r Response) { | ||||
| 	path := c.host + apiPathEstimateFee | ||||
| 	data := pjson.ToJSONString(req) | ||||
| 	body := map[string]string{ | ||||
| 		"logistics_interface": data, | ||||
| 		"data_digest":         c.getDigest(data), | ||||
| 		"msg_type":            msgTypeEstimateFee, | ||||
| 		"eccompanyid":         c.EccompanyID, | ||||
| 	} | ||||
| 	r.Request.Body = pjson.ToBytes(body) | ||||
| 	r.Request.URL = path | ||||
| 	resp, err := c.httpClient.R(). | ||||
| 		SetMultipartFormData(body). | ||||
| 		Post(path) | ||||
| 	if err != nil { | ||||
| 		r.Error = fmt.Errorf("jtepxress: request %s, err %v", path, err) | ||||
| 		return r | ||||
| 	} | ||||
| 	r.Response.StatusCode = resp.StatusCode() | ||||
| 	r.Response.Body = resp.Body() | ||||
| 
 | ||||
| 	return r | ||||
| } | ||||
| 
 | ||||
| func (c *Client) CancelOrder(req *CancelOrderReq) (r Response) { | ||||
| 	path := c.host + apiPathCancelOrder | ||||
| 	data := pjson.ToJSONString(req) | ||||
| 	body := map[string]string{ | ||||
| 		"logistics_interface": data, | ||||
| 		"data_digest":         c.getDigest(data), | ||||
| 		"msg_type":            msgTypeCancelOrder, | ||||
| 		"eccompanyid":         c.EccompanyID, | ||||
| 	} | ||||
| 	r.Request.Body = pjson.ToBytes(body) | ||||
| 	r.Request.URL = path | ||||
| 	resp, err := c.httpClient.R(). | ||||
| 		SetMultipartFormData(body). | ||||
| 		Post(path) | ||||
| 	if err != nil { | ||||
| 		r.Error = fmt.Errorf("jtepxress: request %s, err %v", path, err) | ||||
| 		return r | ||||
| 	} | ||||
| 
 | ||||
| 	r.Response.StatusCode = resp.StatusCode() | ||||
| 	r.Response.Body = resp.Body() | ||||
| 
 | ||||
| 	return r | ||||
| } | ||||
| 
 | ||||
| func (c *Client) CreateOrder(req *CreateOrderReq) (r Response) { | ||||
| 	path := c.host + apiPathCreateOrder | ||||
| 	data := pjson.ToJSONString(req) | ||||
| 	body := map[string]string{ | ||||
| 		"logistics_interface": data, | ||||
| 		"data_digest":         c.getDigest(data), | ||||
| 		"msg_type":            msgTypeCreateOrder, | ||||
| 		"eccompanyid":         c.EccompanyID, | ||||
| 	} | ||||
| 	r.Request.Body = pjson.ToBytes(body) | ||||
| 	r.Request.URL = path | ||||
| 
 | ||||
| 	resp, err := c.httpClient.R(). | ||||
| 		SetMultipartFormData(body). | ||||
| 		Post(path) | ||||
| 	if err != nil { | ||||
| 		r.Error = fmt.Errorf("jtepxress: request %s, err %v", path, err) | ||||
| 		return r | ||||
| 	} | ||||
| 
 | ||||
| 	r.Response.StatusCode = resp.StatusCode() | ||||
| 	r.Response.Body = resp.Body() | ||||
| 
 | ||||
| 	return r | ||||
| } | ||||
| 
 | ||||
| func (c *Client) getDigest(data string) string { | ||||
| 	s := data + c.DigestKey | ||||
| 	h := md5.New() | ||||
| 
 | ||||
| 	io.WriteString(h, s) | ||||
| 	return base64.Encode([]byte(fmt.Sprintf("%x", h.Sum(nil)))) | ||||
| } | ||||
|  | @ -0,0 +1,76 @@ | |||
| package jtexpress | ||||
| 
 | ||||
| type EstimateFeeLocation struct { | ||||
| 	Prov string `json:"prov"` | ||||
| 	City string `json:"city"` | ||||
| 	Area string `json:"area"` | ||||
| } | ||||
| 
 | ||||
| type EstimateFeeReq struct { | ||||
| 	Cusname     string              `json:"cusname"` // = customerid
 | ||||
| 	SelfAddress int                 `json:"selfAddress"` | ||||
| 	ProductType string              `json:"producttype"` | ||||
| 	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 { | ||||
| 	Eccompanyid     string              `json:"eccompanyid"` | ||||
| 	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"` | ||||
| } | ||||
|  | @ -0,0 +1,61 @@ | |||
| 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"` | ||||
| } | ||||
| 
 | ||||
| type Response struct { | ||||
| 	Request  RequestInfo | ||||
| 	Response ResponseInfo | ||||
| 	Error    error | ||||
| } | ||||
| 
 | ||||
| type ResponseInfo struct { | ||||
| 	StatusCode int | ||||
| 	Body       []byte | ||||
| } | ||||
| 
 | ||||
| type RequestInfo struct { | ||||
| 	Method  string | ||||
| 	URL     string | ||||
| 	Headers map[string]string | ||||
| 	Body    []byte | ||||
| } | ||||
		Loading…
	
		Reference in New Issue