From 71e96a81b1ce02ab15ea3789da8e5e155f21938a Mon Sep 17 00:00:00 2001
From: gukai <89243742@qq.com>
Date: Mon, 27 Jun 2022 14:43:25 +0800
Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E7=9B=9B=E5=88=9B=E6=B1=87?=
 =?UTF-8?q?=E8=81=94=E6=B8=A0=E9=81=93sdk?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 upstream/schl/base.go   | 115 ++++++++++++++++++++++++++++++
 upstream/schl/define.go | 152 ++++++++++++++++++++++++++++++++++++++++
 upstream/schl/schl.go   | 136 +++++++++++++++++++++++++++++++++++
 3 files changed, 403 insertions(+)
 create mode 100644 upstream/schl/base.go
 create mode 100644 upstream/schl/define.go
 create mode 100644 upstream/schl/schl.go

diff --git a/upstream/schl/base.go b/upstream/schl/base.go
new file mode 100644
index 0000000..6e916ee
--- /dev/null
+++ b/upstream/schl/base.go
@@ -0,0 +1,115 @@
+package schl
+
+import (
+	"context"
+	"crypto/hmac"
+	"crypto/sha256"
+	"encoding/hex"
+	"github.com/gogf/gf/container/garray"
+	"github.com/gogf/gf/frame/g"
+	"github.com/gogf/gf/os/gtime"
+	"github.com/gogf/gf/util/gconv"
+	"github.com/gogf/gf/util/grand"
+	"sort"
+	"strings"
+)
+
+var server *Config
+
+type Config struct {
+	ApiUrl      string
+	AppKey      string
+	AppSecret   string
+}
+
+const pkgName = "schl"
+
+func New(config *Config) {
+	server = config
+	return
+}
+
+
+func (c *Config)Post(ctx context.Context, api string, bodyMap g.Map) (result string, err error) {
+
+	Start := gtime.TimestampMilli()
+	pubilcParams := new(PubilcParams)
+	pubilcParams.AppID = c.AppKey
+	pubilcParams.Timestamp = gtime.TimestampStr()
+	pubilcParams.Nonce = grand.S(16,false)
+	secret := c.AppSecret
+	sign := c.Sign(ctx,*pubilcParams, bodyMap, secret)
+
+	defer func() {
+		ctx = context.WithValue(ctx, "URI", api)
+		if err != nil {
+			g.Log().Ctx(ctx).Cat("error").Async(true).
+				Infof("参数【%v】错误【%v】响应时间:【%v ms】", bodyMap, err.Error(), gtime.TimestampMilli()-Start)
+		} else {
+			g.Log().Ctx(ctx).Cat(pkgName).Async(true).
+				Infof("参数【%v】响应【%v】响应时间:【%v ms】", bodyMap, result, gtime.TimestampMilli()-Start)
+		}
+	}()
+
+	pubilcParams.Signature = sign
+
+	pubilcParamsMap := gconv.Map(pubilcParams)
+	for k,v := range pubilcParamsMap{
+		bodyMap[k] = v
+	}
+	response, err := g.Client().Ctx(ctx).
+		Post(c.ApiUrl+api, bodyMap)
+	if nil != err {
+		return
+	}
+	result = response.ReadAllString()
+	return
+}
+
+
+func (c *Config)Sign(ctx context.Context,pubilcParams PubilcParams,params g.Map , secret string)(sign string){
+
+	allMaps := make(map[string]string)
+	var arr = garray.New().Append("appId", "timestamp", "nonce")
+	for k, v := range gconv.MapStrStr(pubilcParams) {
+		if arr.Contains(k) {
+			allMaps[k] = v
+		}
+	}
+	allMaps["secret"] = secret
+
+	for k,v := range params{
+		allMaps[k] = gconv.String(v)
+	}
+
+
+	keys := make([]string, 0)
+	for k := range allMaps {
+		keys = append(keys, k)
+	}
+	sort.Strings(keys)
+
+	paramsString := ""
+	for k, v := range keys {
+		if k > 0 {
+			paramsString += "&"
+		}
+		paramsString += v + "=" + allMaps[v]
+	}
+
+	paramsString += "&key="+secret
+
+	hmacSha256String := hmacSha256(paramsString,secret)
+
+	sign = strings.ToUpper(hmacSha256String)
+	return
+}
+
+
+
+
+func hmacSha256(data string, secret string) string {
+	h := hmac.New(sha256.New, []byte(secret))
+	h.Write([]byte(data))
+	return hex.EncodeToString(h.Sum(nil))
+}
\ No newline at end of file
diff --git a/upstream/schl/define.go b/upstream/schl/define.go
new file mode 100644
index 0000000..68b52e7
--- /dev/null
+++ b/upstream/schl/define.go
@@ -0,0 +1,152 @@
+package schl
+
+type CommonRes struct {
+	Code int    `json:"code"`
+	Msg  string `json:"msg"`
+}
+
+type PubilcParams struct {
+	AppID     string `json:"appId"`
+	Nonce     string `json:"nonce"`
+	Timestamp string `json:"timestamp"`
+	Signature string `json:"signature"`
+}
+
+type CategoryRes struct {
+	CommonRes
+	Result []CategoryItem `json:"result"`
+}
+type CategoryItem struct {
+	Id    int    `json:"id"`
+	Img   string `json:"img"`
+	Name  string `json:"name"`
+	SupId int    `json:"supId"`
+}
+
+type ListGoodsRes struct {
+	CommonRes
+	Result []ListGoodsItem `json:"result"`
+}
+
+type ListGoodsItem struct {
+	Code                 string   `json:"code"`
+	Name                 string   `json:"name"`
+	ItemMainImg          string   `json:"itemMainImg"`
+	Imgs                 []string `json:"imgs"`
+	DetailImgs           []string `json:"detailImgs"`
+	GoodsVideo           string   `json:"goodsVideo"`
+	ShareImg             string   `json:"shareImg"`
+	ShareVideo           string   `json:"shareVideo"`
+	MarketPrice          float64  `json:"marketPrice"`
+	MarketPriceTagImg    string   `json:"marketPriceTagImg"`
+	NormalPrice          float64  `json:"normalPrice"`
+	Vip1Price            float64  `json:"vip1Price"`
+	Vip2Price            float64  `json:"vip2Price"`
+	CurrVipPrice         float64  `json:"currVipPrice"`
+	MinBuyNum            int      `json:"minBuyNum"`
+	PlusStep             int      `json:"plusStep"`
+	Unit                 string   `json:"unit"`
+	Weight               float64  `json:"weight"`
+	Volume               float64  `json:"volume"`
+	Stock                int      `json:"stock"`
+	State                int      `json:"state"`
+	ForbidBuyArea        []string `json:"forbidBuyArea"`
+	SupplierFreightPayer int      `json:"supplierFreightPayer"`
+	CategoryGRList       []struct {
+		C1 int `json:"c1"`
+		C2 int `json:"c2"`
+	} `json:"categoryGRList"`
+}
+
+type ListGoodsByCodesReq struct {
+	CodeList []string `json:"codeList"` //["ZGRSH12","ZGYSH11","ZGJRJ10","ZGGTJ09","CWSKYTJ15","CWDYLG14"]
+}
+
+type OrderFreightPreviewReq struct {
+	Province        string `json:"province"`
+	City            string `json:"city"`
+	District        string `json:"district"`
+	AddressDetail   string `json:"addressDetail"`
+	GoodsParamsList string `json:"goodsParamsList"` //[{\"code\":\"goodsCode1\",\"goodsNum\":1}]
+}
+
+type OrderFreightPreviewRes struct {
+	CommonRes
+	Result OrderFreightPreviewItem `json:"result"`
+}
+
+type OrderFreightPreviewItem struct {
+	ExpName string  `json:"expName"` //运费总额
+	Freight float64 `json:"freight"` //快递编码
+	ExpCode string  `json:"expCode"` //快递名称
+}
+
+type CreateOrderReq struct {
+	PlatformOrderNo string `json:"platformOrderNo"` //商户单号,若创建多商品订单建议不传该参
+	CustName        string `json:"custName"`        //收货人
+	CustMobile      string `json:"custMobile"`      //收货人联系方式
+	Province        string `json:"province"`        //省
+	City            string `json:"city"`            //市
+	District        string `json:"district"`        //区
+	AddressDetail   string `json:"addressDetail"`
+	GoodsParamsList string `json:"goodsParamsList"` //[{\"code\":\"goodsCode1\",\"goodsNum\":1}]code需创建订单的商品编码 goodsNum 数量
+}
+
+type CreateOrderRes struct {
+	CommonRes
+	Result CreateOrderItem `json:"result"`
+}
+
+type CreateOrderItem struct {
+	UnionId          string `json:"unionId"`          //平台订单编号,用于后续操作平台订单
+	PayMoney         string `json:"payMoney"`         //支付总额
+	GoodsMoneyAmount string `json:"goodsMoneyAmount"` //商品总额
+	ExpFeeAmount     string `json:"expFeeAmount"`     //运费总额
+	ExpCode          string `json:"expCode"`          //快递编码
+	ExpName          string `json:"expName"`          //快递名称
+}
+
+type SyncOrderExpNoReq struct {
+	UnionIdList string `json:"unionIdList"` //平台订单编号数组,需转成String传入
+}
+
+type SyncOrderExpNoRes struct {
+	UnionId string `json:"unionId"` //平台订单编号
+	ExpNo   string `json:"expNo"`   //快递/物流单号
+
+}
+
+type QueryExpTrackReq struct {
+	UnionId    string   `json:"unionId"`    //平台订单编号,用于后续操作平台订单
+	ExpNos     []string `json:"expNos"`     //订单对应的快递单号数组
+	BusinessId string   `json:"businessId"` //业务订单编号(平台中所查看到的订单编号)
+}
+
+type QueryExpTrackRes struct {
+	CommonRes
+	Result QueryExpTrackItem `json:"result"`
+}
+
+
+type QueryExpTrackItem struct {
+	ExpInfo interface{} `json:"expInfo"` //json
+}
+
+type ExpInfoItem struct {
+	Number string `json:"number"`
+	Type   string `json:"type"`
+	List   []struct {
+		Time   string `json:"time"`
+		Status string `json:"status"`
+	} `json:"list"`
+	Deliverystatus string `json:"deliverystatus"`
+	Issign         string `json:"issign"`
+	ExpName        string `json:"expName"`
+	ExpSite        string `json:"expSite"`
+	ExpPhone       string `json:"expPhone"`
+	Logo           string `json:"logo"`
+	Courier        string `json:"courier"`
+	CourierPhone   string `json:"courierPhone"`
+	UpdateTime     string `json:"updateTime"`
+	TakeTime       string `json:"takeTime"`
+}
diff --git a/upstream/schl/schl.go b/upstream/schl/schl.go
new file mode 100644
index 0000000..2cd9042
--- /dev/null
+++ b/upstream/schl/schl.go
@@ -0,0 +1,136 @@
+package schl
+
+import (
+	"context"
+	"github.com/gogf/gf/encoding/gjson"
+	"github.com/gogf/gf/frame/g"
+	"github.com/gogf/gf/util/gconv"
+)
+
+type api struct {
+}
+
+var Api = api{}
+
+
+/*
+	获取分类
+*/
+func (api)Category(ctx context.Context) (res *CategoryRes, err error) {
+
+	result, err := server.Post(ctx, "vip/api/goods/listGoodsCategory", g.Map{})
+	err = gjson.New(result).Scan(&res)
+	if err != nil {
+		return
+	}
+	return
+}
+
+/*
+	获取商品
+*/
+func (api) GoodsList(ctx context.Context) (res *ListGoodsRes, err error) {
+
+	result, err := server.Post(ctx, "vip/api/goods/listGoods", g.Map{})
+
+	err = gjson.New(result).Scan(&res)
+	if err != nil {
+		return
+	}
+	return
+}
+
+/*
+	编码查询商品
+*/
+func (api) ListGoodsByCodes(ctx context.Context, codeList []string) (res *ListGoodsRes, err error) {
+
+	data := g.Map{
+		"codeList": gjson.New(codeList).MustToJsonString(),
+	}
+	result, err := server.Post(ctx, "vip/api/goods/listGoodsByCodes", data)
+	if err != nil {
+		return
+	}
+	err = gjson.New(result).Scan(&res)
+	if err != nil {
+		return
+	}
+	return
+}
+
+/*
+	订单运费预览
+*/
+func (api) OrderFreightPreview(ctx context.Context, req *OrderFreightPreviewReq) (res *OrderFreightPreviewRes, err error) {
+
+	data := gconv.Map(req)
+	result, err := server.Post(ctx, "vip/api/order/orderFreightPreview", data)
+	if err != nil {
+		return
+	}
+	err = gjson.New(result).Scan(&res)
+	if err != nil {
+		return
+	}
+	return
+}
+
+/*
+	同步订单快递单号
+*/
+func (api) SyncOrderExpNo(ctx context.Context, req *SyncOrderExpNoReq) (res *SyncOrderExpNoRes, err error) {
+
+	data := gconv.Map(req)
+
+	result, err := server.Post(ctx, "vip/api/order/syncOrderExpNo", data)
+	if err != nil {
+		return
+	}
+	err = gjson.New(result).Scan(&res)
+	if err != nil {
+		return
+	}
+	return
+}
+
+/*
+	订单创建
+*/
+func (api) CreateOrder(ctx context.Context, req *CreateOrderReq) (res *CreateOrderRes, err error) {
+
+	data := gconv.Map(req)
+
+	result, err := server.Post(ctx, "vip/api/order/createOrder", data)
+	if err != nil {
+		return
+	}
+
+	err = gjson.New(result).Scan(&res)
+	if err != nil {
+		return
+	}
+	if err != nil {
+		return
+	}
+	return
+}
+
+/*
+	查询订单快递/物流轨迹
+*/
+func (api)  QueryExpTrack(ctx context.Context, req *QueryExpTrackReq) (res *QueryExpTrackRes, err error) {
+
+	data := gconv.Map(req)
+
+	result, err := server.Post(ctx, "vip/api/order/queryExpTrack", data)
+	if err != nil {
+		return
+	}
+	err = gjson.New(result).Scan(&res)
+	if err != nil {
+		return
+	}
+
+	return
+}
-- 
2.18.1