From 6f27df7342ad5836c6998bd2ed14facfb75bbe96 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E5=85=89=E6=98=A5?= Date: Thu, 26 May 2022 17:43:37 +0800 Subject: [PATCH] - init --- .drone.yml | 17 +++ .gitignore | 10 ++ app.go | 73 ++++++++++ cgi-bin.token.monitor.go | 20 +++ cgi-bin.token.rdb.go | 22 +++ cgi_bin.token.go | 38 ++++++ getcallbackip.go | 35 +++++ go.mod | 29 ++++ go.sum | 255 +++++++++++++++++++++++++++++++++++ order.go | 77 +++++++++++ params.go | 27 ++++ pgsql.go | 26 ++++ promoter.order.info.go | 73 ++++++++++ promoter.order.search.go | 70 ++++++++++ promoter.product.category.go | 40 ++++++ promoter.product.generate.go | 69 ++++++++++ promoter.product.list.go | 152 +++++++++++++++++++++ promoter.product.select.go | 153 +++++++++++++++++++++ promoter.promotion.add.go | 40 ++++++ promoter.promotion.del.go | 40 ++++++ promoter.promotion.list.go | 48 +++++++ promoter.promotion.upd.go | 38 ++++++ version.go | 3 + 23 files changed, 1355 insertions(+) create mode 100644 .drone.yml create mode 100644 .gitignore create mode 100644 app.go create mode 100644 cgi-bin.token.monitor.go create mode 100644 cgi-bin.token.rdb.go create mode 100644 cgi_bin.token.go create mode 100644 getcallbackip.go create mode 100644 go.mod create mode 100644 go.sum create mode 100644 order.go create mode 100644 params.go create mode 100644 pgsql.go create mode 100644 promoter.order.info.go create mode 100644 promoter.order.search.go create mode 100644 promoter.product.category.go create mode 100644 promoter.product.generate.go create mode 100644 promoter.product.list.go create mode 100644 promoter.product.select.go create mode 100644 promoter.promotion.add.go create mode 100644 promoter.promotion.del.go create mode 100644 promoter.promotion.list.go create mode 100644 promoter.promotion.upd.go create mode 100644 version.go diff --git a/.drone.yml b/.drone.yml new file mode 100644 index 0000000..c56c479 --- /dev/null +++ b/.drone.yml @@ -0,0 +1,17 @@ +kind: pipeline +type: docker +name: clone + +steps: + - name: Test + image: golang:1.18 + commands: + - go env -w GO111MODULE=on + - go env -w GOPROXY=https://goproxy.cn,direct + - go test -v ./... + - name: Benchmark + image: golang:1.18 + commands: + - go env -w GO111MODULE=on + - go env -w GOPROXY=https://goproxy.cn,direct + - go test -bench=. -benchmem \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..502d67a --- /dev/null +++ b/.gitignore @@ -0,0 +1,10 @@ +.env +.git +.svn +.idea +.vscode +*.log +goinit.sh +gomod.sh +/vendor/ +*_test.go \ No newline at end of file diff --git a/app.go b/app.go new file mode 100644 index 0000000..c753c47 --- /dev/null +++ b/app.go @@ -0,0 +1,73 @@ +package wechatunion + +import ( + "go.dtapp.net/golog" + "go.dtapp.net/goredis" + "go.dtapp.net/gorequest" + "gorm.io/gorm" +) + +const ( + UnionUrl = "https://api.weixin.qq.com/union" +) + +// App 微信小程序联盟 +type App struct { + appId string // 小程序唯一凭证,即 appId + appSecret string // 小程序唯一凭证密钥,即 appSecret + accessToken string // 接口调用凭证 + pid string // 推广位PID + Redis goredis.App // 缓存数据库服务 + pgsql *gorm.DB // pgsql数据库 + client *gorequest.App // 请求客户端 + log *golog.Api // 日志服务 + logTableName string // 日志表名 + logStatus bool // 日志状态 +} + +func NewApp(appId string, appSecret string, pid string, redis goredis.App, pgsql *gorm.DB) *App { + app := &App{appId: appId, appSecret: appSecret, pid: pid, Redis: redis} + app.client = gorequest.NewHttp() + if pgsql != nil { + app.pgsql = pgsql + app.logStatus = true + app.logTableName = "wechatunion" + app.log = golog.NewApi(&golog.ApiConfig{ + Db: pgsql, + TableName: app.logTableName, + }) + } + return app +} + +// 请求 +func (app *App) request(url string, params map[string]interface{}, method string) (resp gorequest.Response, err error) { + + // 创建请求 + client := app.client + + // 设置请求地址 + client.SetUri(url) + + // 设置请求方式 + client.SetMethod(method) + + // 设置FORM格式 + client.SetContentTypeForm() + + // 设置参数 + client.SetParams(params) + + // 发起请求 + request, err := client.Request() + if err != nil { + return gorequest.Response{}, err + } + + // 日志 + if app.logStatus == true { + go app.postgresqlLog(request) + } + + return request, err +} diff --git a/cgi-bin.token.monitor.go b/cgi-bin.token.monitor.go new file mode 100644 index 0000000..7a2c4a0 --- /dev/null +++ b/cgi-bin.token.monitor.go @@ -0,0 +1,20 @@ +package wechatunion + +import ( + "context" + "errors" + "time" +) + +func (app *App) GetAccessTokenMonitor() (string, error) { + if app.Redis.Db == nil { + return "", errors.New("驱动没有初始化") + } + result := app.GetCallBackIp() + if len(result.Result.IpList) <= 0 { + token := app.CgiBinToken() + app.Redis.Db.Set(context.Background(), app.getAccessTokenCacheKeyName(), token.Result.AccessToken, time.Second*7000) + return token.Result.AccessToken, nil + } + return app.accessToken, nil +} diff --git a/cgi-bin.token.rdb.go b/cgi-bin.token.rdb.go new file mode 100644 index 0000000..887232c --- /dev/null +++ b/cgi-bin.token.rdb.go @@ -0,0 +1,22 @@ +package wechatunion + +import ( + "fmt" + "time" +) + +func (app *App) GetAccessToken() string { + if app.Redis.Db == nil { + return app.accessToken + } + newCache := app.Redis.NewSimpleStringCache(app.Redis.NewStringOperation(), time.Second*7000) + newCache.DBGetter = func() string { + token := app.CgiBinToken() + return token.Result.AccessToken + } + return newCache.GetCache(app.getAccessTokenCacheKeyName()) +} + +func (app *App) getAccessTokenCacheKeyName() string { + return fmt.Sprintf("wechat_access_token:%v", app.appId) +} diff --git a/cgi_bin.token.go b/cgi_bin.token.go new file mode 100644 index 0000000..0ea0131 --- /dev/null +++ b/cgi_bin.token.go @@ -0,0 +1,38 @@ +package wechatunion + +import ( + "encoding/json" + "fmt" + "go.dtapp.net/gorequest" + "net/http" +) + +type CgiBinTokenResponse struct { + AccessToken string `json:"access_token"` // 获取到的凭证 + ExpiresIn int `json:"expires_in"` // 凭证有效时间,单位:秒。目前是7200秒之内的值 + Errcode int `json:"errcode"` // 错误码 + Errmsg string `json:"errmsg"` // 错误信息 +} + +type CgiBinTokenResult struct { + Result CgiBinTokenResponse // 结果 + Byte []byte // 内容 + Http gorequest.Response // 请求 + Err error // 错误 +} + +func NewCgiBinTokenResult(result CgiBinTokenResponse, byte []byte, http gorequest.Response, err error) *CgiBinTokenResult { + return &CgiBinTokenResult{Result: result, Byte: byte, Http: http, Err: err} +} + +// CgiBinToken +// 接口调用凭证 +// https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/access-token/auth.getAccessToken.html +func (app *App) CgiBinToken() *CgiBinTokenResult { + // 请求 + request, err := app.request(fmt.Sprintf("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s", app.appId, app.appSecret), map[string]interface{}{}, http.MethodGet) + // 定义 + var response CgiBinTokenResponse + err = json.Unmarshal(request.ResponseBody, &response) + return NewCgiBinTokenResult(response, request.ResponseBody, request, err) +} diff --git a/getcallbackip.go b/getcallbackip.go new file mode 100644 index 0000000..ecfee43 --- /dev/null +++ b/getcallbackip.go @@ -0,0 +1,35 @@ +package wechatunion + +import ( + "encoding/json" + "fmt" + "go.dtapp.net/gorequest" +) + +type GetCallBackIpResponse struct { + IpList []string `json:"ip_list"` +} + +type GetCallBackIpResult struct { + Result GetCallBackIpResponse // 结果 + Byte []byte // 内容 + Http gorequest.Response // 请求 + Err error // 错误 +} + +func NewGetCallBackIpResult(result GetCallBackIpResponse, byte []byte, http gorequest.Response, err error) *GetCallBackIpResult { + return &GetCallBackIpResult{Result: result, Byte: byte, Http: http, Err: err} +} + +// GetCallBackIp 获取微信callback IP地址 +// callback IP即微信调用开发者服务器所使用的出口IP。 +// https://developers.weixin.qq.com/doc/offiaccount/Basic_Information/Get_the_WeChat_server_IP_address.html#2.%20%E8%8E%B7%E5%8F%96%E5%BE%AE%E4%BF%A1callback%20IP%E5%9C%B0%E5%9D%80 +func (app *App) GetCallBackIp() *GetCallBackIpResult { + app.accessToken = app.GetAccessToken() + // 请求 + request, err := app.request(fmt.Sprintf("https://api.weixin.qq.com/cgi-bin/getcallbackip?access_token=%s", app.accessToken), map[string]interface{}{}, "GET") + // 定义 + var response GetCallBackIpResponse + err = json.Unmarshal(request.ResponseBody, &response) + return NewGetCallBackIpResult(response, request.ResponseBody, request, err) +} diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..f4b4348 --- /dev/null +++ b/go.mod @@ -0,0 +1,29 @@ +module go.dtapp.net/wechatunion + +go 1.18 + +require ( + go.dtapp.net/gojson v1.0.0 + go.dtapp.net/golog v1.0.13 + go.dtapp.net/goredis v1.0.0 + go.dtapp.net/gorequest v1.0.18 + go.dtapp.net/gotime v1.0.2 + gorm.io/datatypes v1.0.6 + gorm.io/gorm v1.23.5 +) + +require ( + github.com/cespare/xxhash/v2 v2.1.2 // indirect + github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect + github.com/go-redis/redis/v8 v8.11.5 // indirect + github.com/go-sql-driver/mysql v1.6.0 // indirect + github.com/jinzhu/inflection v1.0.0 // indirect + github.com/jinzhu/now v1.1.5 // indirect + github.com/saracen/go7z v0.0.0-20191010121135-9c09b6bd7fda // indirect + github.com/saracen/solidblock v0.0.0-20190426153529-45df20abab6f // indirect + github.com/ulikunitz/xz v0.5.10 // indirect + go.dtapp.net/goip v1.0.16 // indirect + go.dtapp.net/gostring v1.0.3 // indirect + golang.org/x/text v0.3.7 // indirect + gorm.io/driver/mysql v1.3.3 // indirect +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..e0e81c2 --- /dev/null +++ b/go.sum @@ -0,0 +1,255 @@ +github.com/Azure/azure-sdk-for-go/sdk/azcore v0.19.0/go.mod h1:h6H6c8enJmmocHUbLiiGY6sx7f9i+X3m1CHdd5c6Rdw= +github.com/Azure/azure-sdk-for-go/sdk/azidentity v0.11.0/go.mod h1:HcM1YX14R7CJcghJGOYCgdezslRSVzqwLf/q+4Y2r/0= +github.com/Azure/azure-sdk-for-go/sdk/internal v0.7.0/go.mod h1:yqy467j36fJxcRV2TzfVZ1pCb5vxm4BtZPUdYWe/Xo8= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs= +github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE= +github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ= +github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/denisenkom/go-mssqldb v0.12.0 h1:VtrkII767ttSPNRfFekePK3sctr+joXgO58stqQbtUA= +github.com/denisenkom/go-mssqldb v0.12.0/go.mod h1:iiK0YP1ZeepvmBQk/QpLEhhTNJgfzrpArPY/aFvc9yU= +github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78= +github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= +github.com/dnaeon/go-vcr v1.2.0/go.mod h1:R4UdLID7HZT3taECzJs4YgbbH6PIGXB6W/sc5OLb6RQ= +github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= +github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= +github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= +github.com/go-redis/redis/v8 v8.11.5 h1:AcZZR7igkdvfVmQTPnu9WE37LRrO/YrBH5zWyjDC0oI= +github.com/go-redis/redis/v8 v8.11.5/go.mod h1:gREzHqY1hg6oD9ngVRbLStwAWKhA0FEgq8Jd4h5lpwo= +github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE= +github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= +github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/gofrs/uuid v4.0.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= +github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0= +github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9 h1:au07oEsX2xN0ktxqI+Sida1w446QrXBRJ0nee3SNZlA= +github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0= +github.com/golang-sql/sqlexp v0.0.0-20170517235910-f1bb20e5a188 h1:+eHOFJl1BaXrQxKX+T06f78590z4qA2ZzBTqahsKSE4= +github.com/golang-sql/sqlexp v0.0.0-20170517235910-f1bb20e5a188/go.mod h1:vXjM/+wXQnTPR4KqTKDgJukSZ6amVRtWMPEjE6sQoK8= +github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= +github.com/jackc/chunkreader v1.0.0 h1:4s39bBR8ByfqH+DKm8rQA3E1LHZWB9XWcrz8fqaZbe0= +github.com/jackc/chunkreader v1.0.0/go.mod h1:RT6O25fNZIuasFJRyZ4R/Y2BbhasbmZXF9QQ7T3kePo= +github.com/jackc/chunkreader/v2 v2.0.0/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk= +github.com/jackc/chunkreader/v2 v2.0.1 h1:i+RDz65UE+mmpjTfyz0MoVTnzeYxroil2G82ki7MGG8= +github.com/jackc/chunkreader/v2 v2.0.1/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk= +github.com/jackc/pgconn v0.0.0-20190420214824-7e0022ef6ba3/go.mod h1:jkELnwuX+w9qN5YIfX0fl88Ehu4XC3keFuOJJk9pcnA= +github.com/jackc/pgconn v0.0.0-20190824142844-760dd75542eb/go.mod h1:lLjNuW/+OfW9/pnVKPazfWOgNfH2aPem8YQ7ilXGvJE= +github.com/jackc/pgconn v0.0.0-20190831204454-2fabfa3c18b7/go.mod h1:ZJKsE/KZfsUgOEh9hBm+xYTstcNHg7UPMVJqRfQxq4s= +github.com/jackc/pgconn v1.8.0/go.mod h1:1C2Pb36bGIP9QHGBYCjnyhqu7Rv3sGshaQUvmfGIB/o= +github.com/jackc/pgconn v1.9.0/go.mod h1:YctiPyvzfU11JFxoXokUOOKQXQmDMoJL9vJzHH8/2JY= +github.com/jackc/pgconn v1.9.1-0.20210724152538-d89c8390a530/go.mod h1:4z2w8XhRbP1hYxkpTuBjTS3ne3J48K83+u0zoyvg2pI= +github.com/jackc/pgconn v1.10.1/go.mod h1:4z2w8XhRbP1hYxkpTuBjTS3ne3J48K83+u0zoyvg2pI= +github.com/jackc/pgconn v1.11.0/go.mod h1:4z2w8XhRbP1hYxkpTuBjTS3ne3J48K83+u0zoyvg2pI= +github.com/jackc/pgconn v1.12.1 h1:rsDFzIpRk7xT4B8FufgpCCeyjdNpKyghZeSefViE5W8= +github.com/jackc/pgio v1.0.0 h1:g12B9UwVnzGhueNavwioyEEpAmqMe1E/BN9ES+8ovkE= +github.com/jackc/pgio v1.0.0/go.mod h1:oP+2QK2wFfUWgr+gxjoBH9KGBb31Eio69xUb0w5bYf8= +github.com/jackc/pgmock v0.0.0-20190831213851-13a1b77aafa2/go.mod h1:fGZlG77KXmcq05nJLRkk0+p82V8B8Dw8KN2/V9c/OAE= +github.com/jackc/pgmock v0.0.0-20201204152224-4fe30f7445fd/go.mod h1:hrBW0Enj2AZTNpt/7Y5rr2xe/9Mn757Wtb2xeBzPv2c= +github.com/jackc/pgmock v0.0.0-20210724152146-4ad1a8207f65/go.mod h1:5R2h2EEX+qri8jOWMbJCtaPWkrrNc7OHwsp2TCqp7ak= +github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM= +github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg= +github.com/jackc/pgproto3 v1.1.0 h1:FYYE4yRw+AgI8wXIinMlNjBbp/UitDJwfj5LqqewP1A= +github.com/jackc/pgproto3 v1.1.0/go.mod h1:eR5FA3leWg7p9aeAqi37XOTgTIbkABlvcPB3E5rlc78= +github.com/jackc/pgproto3/v2 v2.0.0-alpha1.0.20190420180111-c116219b62db/go.mod h1:bhq50y+xrl9n5mRYyCBFKkpRVTLYJVWeCc+mEAI3yXA= +github.com/jackc/pgproto3/v2 v2.0.0-alpha1.0.20190609003834-432c2951c711/go.mod h1:uH0AWtUmuShn0bcesswc4aBTWGvw0cAxIJp+6OB//Wg= +github.com/jackc/pgproto3/v2 v2.0.0-rc3/go.mod h1:ryONWYqW6dqSg1Lw6vXNMXoBJhpzvWKnT95C46ckYeM= +github.com/jackc/pgproto3/v2 v2.0.0-rc3.0.20190831210041-4c03ce451f29/go.mod h1:ryONWYqW6dqSg1Lw6vXNMXoBJhpzvWKnT95C46ckYeM= +github.com/jackc/pgproto3/v2 v2.0.6/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= +github.com/jackc/pgproto3/v2 v2.1.1/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= +github.com/jackc/pgproto3/v2 v2.2.0/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= +github.com/jackc/pgproto3/v2 v2.3.0 h1:brH0pCGBDkBW07HWlN/oSBXrmo3WB0UvZd1pIuDcL8Y= +github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b h1:C8S2+VttkHFdOOCXJe+YGfa4vHYwlt4Zx+IVXQ97jYg= +github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b/go.mod h1:vsD4gTJCa9TptPL8sPkXrLZ+hDuNrZCnj29CQpr4X1E= +github.com/jackc/pgtype v0.0.0-20190421001408-4ed0de4755e0/go.mod h1:hdSHsc1V01CGwFsrv11mJRHWJ6aifDLfdV3aVjFF0zg= +github.com/jackc/pgtype v0.0.0-20190824184912-ab885b375b90/go.mod h1:KcahbBH1nCMSo2DXpzsoWOAfFkdEtEJpPbVLq8eE+mc= +github.com/jackc/pgtype v0.0.0-20190828014616-a8802b16cc59/go.mod h1:MWlu30kVJrUS8lot6TQqcg7mtthZ9T0EoIBFiJcmcyw= +github.com/jackc/pgtype v1.8.1-0.20210724151600-32e20a603178/go.mod h1:C516IlIV9NKqfsMCXTdChteoXmwgUceqaLfjg2e3NlM= +github.com/jackc/pgtype v1.9.1/go.mod h1:LUMuVrfsFfdKGLw+AFFVv6KtHOFMwRgDDzBt76IqCA4= +github.com/jackc/pgtype v1.10.0/go.mod h1:LUMuVrfsFfdKGLw+AFFVv6KtHOFMwRgDDzBt76IqCA4= +github.com/jackc/pgtype v1.11.0 h1:u4uiGPz/1hryuXzyaBhSk6dnIyyG2683olG2OV+UUgs= +github.com/jackc/pgx/v4 v4.0.0-20190420224344-cc3461e65d96/go.mod h1:mdxmSJJuR08CZQyj1PVQBHy9XOp5p8/SHH6a0psbY9Y= +github.com/jackc/pgx/v4 v4.0.0-20190421002000-1b8f0016e912/go.mod h1:no/Y67Jkk/9WuGR0JG/JseM9irFbnEPbuWV2EELPNuM= +github.com/jackc/pgx/v4 v4.0.0-pre1.0.20190824185557-6972a5742186/go.mod h1:X+GQnOEnf1dqHGpw7JmHqHc1NxDoalibchSk9/RWuDc= +github.com/jackc/pgx/v4 v4.12.1-0.20210724153913-640aa07df17c/go.mod h1:1QD0+tgSXP7iUjYm9C1NxKhny7lq6ee99u/z+IHFcgs= +github.com/jackc/pgx/v4 v4.14.1/go.mod h1:RgDuE4Z34o7XE92RpLsvFiOEfrAUT0Xt2KxvX73W06M= +github.com/jackc/pgx/v4 v4.15.0/go.mod h1:D/zyOyXiaM1TmVWnOM18p0xdDtdakRBa0RsVGI3U3bw= +github.com/jackc/pgx/v4 v4.16.1 h1:JzTglcal01DrghUqt+PmzWsZx/Yh7SC/CTQmSBMTd0Y= +github.com/jackc/puddle v0.0.0-20190413234325-e4ced69a3a2b/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= +github.com/jackc/puddle v0.0.0-20190608224051-11cab39313c9/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= +github.com/jackc/puddle v1.1.3/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= +github.com/jackc/puddle v1.2.0/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= +github.com/jackc/puddle v1.2.1/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= +github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= +github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= +github.com/jinzhu/now v1.1.4/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= +github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ= +github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= +github.com/lib/pq v1.1.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= +github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= +github.com/lib/pq v1.10.2/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= +github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= +github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= +github.com/mattn/go-sqlite3 v1.14.9/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= +github.com/mattn/go-sqlite3 v1.14.12 h1:TJ1bhYJPV44phC+IMu1u2K/i5RriLTPe+yc68XDJ1Z0= +github.com/mattn/go-sqlite3 v1.14.12/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= +github.com/modocache/gover v0.0.0-20171022184752-b58185e213c5/go.mod h1:caMODM3PzxT8aQXRPkAt8xlV/e7d7w8GM5g0fa5F0D8= +github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= +github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= +github.com/onsi/gomega v1.18.1 h1:M1GfJqGRrBrrGGsbxzV5dqM2U2ApXefZCQpkukxYRLE= +github.com/pkg/browser v0.0.0-20180916011732-0a3d74bf9ce4/go.mod h1:4OwLy04Bl9Ef3GJJCoec+30X3LQs/0/m4HFRt/2LUSA= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ= +github.com/rs/zerolog v1.13.0/go.mod h1:YbFCdg8HfsridGWAh22vktObvhZbQsZXe4/zB0OKkWU= +github.com/rs/zerolog v1.15.0/go.mod h1:xYTKnLHcpfU2225ny5qZjxnj9NvkumZYjJHlAThCjNc= +github.com/saracen/go7z v0.0.0-20191010121135-9c09b6bd7fda h1:h+YpzUB/bGVJcLqW+d5GghcCmE/A25KbzjXvWJQi/+o= +github.com/saracen/go7z v0.0.0-20191010121135-9c09b6bd7fda/go.mod h1:MSotTrCv1PwoR8QgU1JurEx+lNNbtr25I+m0zbLyAGw= +github.com/saracen/go7z-fixtures v0.0.0-20190623165746-aa6b8fba1d2f h1:PF9WV5j/x6MT+x/sauUHd4objCvJbZb0wdxZkHSdd5A= +github.com/saracen/solidblock v0.0.0-20190426153529-45df20abab6f h1:1cJITU3JUI8qNS5T0BlXwANsVdyoJQHQ4hvOxbunPCw= +github.com/saracen/solidblock v0.0.0-20190426153529-45df20abab6f/go.mod h1:LyBTue+RWeyIfN3ZJ4wVxvDuvlGJtDgCLgCb6HCPgps= +github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= +github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4= +github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= +github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= +github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/ulikunitz/xz v0.5.10 h1:t92gobL9l3HE202wg3rlk19F6X+JOxl9BBrCCMYEYd8= +github.com/ulikunitz/xz v0.5.10/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= +github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q= +go.dtapp.net/goip v1.0.16 h1:jJoXeLVc8BmlKEc+4T9mL2BFK63RJFd4B9xTMYhFRqg= +go.dtapp.net/goip v1.0.16/go.mod h1:BY2Xo5clizPZFQ8CYOlgg91fHMZR1Ll54f3P0sNHxbg= +go.dtapp.net/gojson v1.0.0 h1:jmRjeWChRyv2tKEByHvnW3kXh1jUcL8B7VurV0Zbygc= +go.dtapp.net/gojson v1.0.0/go.mod h1:TkkpTNxHBKxul0e7gC5MrL1K4ICFB9mQ7wHzjBah3/k= +go.dtapp.net/golog v1.0.13 h1:SnU6G4onDYZPOfZ9cgmj5rHdtGGOWP/Qee31aM49Wj0= +go.dtapp.net/golog v1.0.13/go.mod h1:6w5Lt1x6/yUN3iptAi59irm4kqDJHaolDsrZ9ApsZUQ= +go.dtapp.net/goredis v1.0.0 h1:IvoOvdPeQlT2UR6lbumr+zN0x7ikTz9ro7od7jydD2U= +go.dtapp.net/goredis v1.0.0/go.mod h1:Wmrgb5yfbV7SiIK0NLdBOFWKnrQs+5g8p3t5+cjQkMM= +go.dtapp.net/gorequest v1.0.18 h1:NAogmkEbz4Sln4tt6Li8tF99d3WnHMkbPuYFdNz/xTE= +go.dtapp.net/gorequest v1.0.18/go.mod h1:EwOfdfxsWPszOWrphCWHTN4DbYtU6fyQ/fuWQyQwSnk= +go.dtapp.net/gostring v1.0.3 h1:KSOq4D77/g5yZN/bqWfZ0kOOaPr/P1240vg03+XdENI= +go.dtapp.net/gostring v1.0.3/go.mod h1:+ggrOvgQDQturi1QGsXEpyRN/ZPoRDaqhMujIk5lrgQ= +go.dtapp.net/gotime v1.0.2 h1:CFIJHQXC/4t9bsJhk2cLhjHd6rpdPcJXr8BcHKHDuQo= +go.dtapp.net/gotime v1.0.2/go.mod h1:Gq7eNLr2iMLP18UNWONRq4V3Uhf/ADp4bIrS+Tc6ktY= +go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= +go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= +go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= +go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= +go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= +go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= +go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU= +go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= +go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= +go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= +go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190411191339-88737f569e3a/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE= +golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20201203163018-be400aefbc4c/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= +golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20220214200702-86341886e292/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.0.0-20220518034528-6f7dac969898 h1:SLP7Q4Di66FONjDJbCYrCRrh97focO6sLogHO7/g8F0= +golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= +golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/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-20210610132358-84b48f89b13b/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-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e h1:fLOSk5Q00efkSvAm+4xcoXD+RRmLmmulPn5I3Y9F2EM= +golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190425163242-31fd60d6bfdc/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190823170909-c4a336ef6a2f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20200103221440-774c71fcf114 h1:DnSr2mCsxyCE6ZgIkmcWUQY2R5cH/6wL7eIxEmQOMSE= +golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= +gopkg.in/inconshreveable/log15.v2 v2.0.0-20180818164646-67afb5ed74ec/go.mod h1:aPpfJ7XW+gOuirDoZ8gHhLh3kZ1B08FtV2bbmy7Jv3s= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gorm.io/datatypes v1.0.6 h1:3cqbakp1DIgC+P7wyODb5k+lSjW8g3mjkg/BIsmhjlE= +gorm.io/datatypes v1.0.6/go.mod h1:Gh/Xd/iUWWybMEk8CzYCK/swqlni2r+ROeM1HGIM0ck= +gorm.io/driver/mysql v1.3.2/go.mod h1:ChK6AHbHgDCFZyJp0F+BmVGb06PSIoh9uVYKAlRbb2U= +gorm.io/driver/mysql v1.3.3 h1:jXG9ANrwBc4+bMvBcSl8zCfPBaVoPyBEBshA8dA93X8= +gorm.io/driver/mysql v1.3.3/go.mod h1:ChK6AHbHgDCFZyJp0F+BmVGb06PSIoh9uVYKAlRbb2U= +gorm.io/driver/postgres v1.3.1/go.mod h1:WwvWOuR9unCLpGWCL6Y3JOeBWvbKi6JLhayiVclSZZU= +gorm.io/driver/postgres v1.3.6 h1:Q0iLoYvWwsJVpYQrSrY5p5P4YzW7fJjFMBG2sa4Bz5U= +gorm.io/driver/sqlite v1.3.1 h1:bwfE+zTEWklBYoEodIOIBwuWHpnx52Z9zJFW5F33WLk= +gorm.io/driver/sqlite v1.3.1/go.mod h1:wJx0hJspfycZ6myN38x1O/AqLtNS6c5o9TndewFbELg= +gorm.io/driver/sqlserver v1.3.1 h1:F5t6ScMzOgy1zukRTIZgLZwKahgt3q1woAILVolKpOI= +gorm.io/driver/sqlserver v1.3.1/go.mod h1:w25Vrx2BG+CJNUu/xKbFhaKlGxT/nzRkhWCCoptX8tQ= +gorm.io/gorm v1.23.1/go.mod h1:l2lP/RyAtc1ynaTjFksBde/O8v9oOGIApu2/xRitmZk= +gorm.io/gorm v1.23.2/go.mod h1:l2lP/RyAtc1ynaTjFksBde/O8v9oOGIApu2/xRitmZk= +gorm.io/gorm v1.23.5 h1:TnlF26wScKSvknUC/Rn8t0NLLM22fypYBlvj1+aH6dM= +gorm.io/gorm v1.23.5/go.mod h1:l2lP/RyAtc1ynaTjFksBde/O8v9oOGIApu2/xRitmZk= +honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= diff --git a/order.go b/order.go new file mode 100644 index 0000000..97c8a82 --- /dev/null +++ b/order.go @@ -0,0 +1,77 @@ +package wechatunion + +import ( + "errors" +) + +type OrderSearch struct { + Page int `json:"page,omitempty"` // 页码,起始为 1 + PageSize int `json:"pageSize,omitempty"` // 分页大小,最大 200 + StartTimestamp string `json:"startTimestamp,omitempty"` // 起始时间戳,单位为秒 + EndTimestamp string `json:"endTimestamp,omitempty"` // 结束时间戳,单位为秒 + CommissionStatus string `json:"commissionStatus,omitempty"` // 分佣状态 + SortByCommissionUpdateTime string `json:"sortByCommissionUpdateTime,omitempty"` // 是否按照分佣状态更新时间排序和筛选订单,1:是,0:否 + StartCommissionUpdateTime string `json:"startCommissionUpdateTime,omitempty"` // 分佣状态更新时间起始时间戳,单位为秒 + EndCommissionUpdateTime string `json:"endCommissionUpdateTime,omitempty"` // 分佣状态更新时间结束时间戳,单位为秒 +} + +type OrderSearchResult struct { + Errcode int `json:"errcode"` + Errmsg string `json:"errmsg"` + OrderList []struct { + OrderId string `json:"orderId"` // 订单ID + PayTime int `json:"payTime"` // 支付时间戳,单位为s + ConfirmReceiptTime int `json:"confirmReceiptTime"` // 确认收货时间戳,单位为s,没有时为0 + ShopName string `json:"shopName"` // 店铺名称 + ShopAppid string `json:"shopAppid"` // 店铺 Appid + ProductList []struct { + ProductId string `json:"productId"` // 商品SPU ID + SkuId string `json:"skuId"` // sku ID + Title string `json:"title"` // 商品名称 + ThumbImg string `json:"thumbImg"` // 商品缩略图 url + Price string `json:"price"` // 商品成交总价,前带单位 ¥ + ProductCnt int `json:"productCnt"` // 成交数量 + Ratio int `json:"ratio"` // 分佣比例,单位为万分之一 + CommissionStatus string `json:"commissionStatus"` // 分佣状态 + CommissionStatusUpdateTime string `json:"commissionStatusUpdateTime"` // 分佣状态更新时间戳,单位为s + ProfitShardingSucTime string `json:"profitShardingSucTime"` // 结算时间,当分佣状态为已结算才有值,单位为s + Commission string `json:"commission"` // 分佣金额,前带单位 ¥ + EstimatedCommission int `json:"estimatedCommission"` // 预估分佣金额,单位为分 + CategoryStr string `json:"categoryStr"` // 类目名称,多个用英文逗号分隔 + PromotionInfo struct { + PromotionSourcePid string `json:"promotionSourcePid"` // 推广位 id + PromotionSourceName string `json:"promotionSourceName"` // 推广位名称 + } `json:"promotionInfo"` // 推广信息 + CustomizeInfo string `json:"customizeInfo"` // 自定义信息 + } `json:"productList"` // 商品列表 + } `json:"orderList"` // 订单列表 + PageSize int `json:"pageSize"` // 分页大小 + TotalNum int `json:"totalNum"` // 订单总数 +} + +// OrderSearch 根据订单支付时间、订单分佣状态拉取订单详情 https://developers.weixin.qq.com/doc/ministore/union/access-guidelines/promoter/api/order/order-info.html +func (app *App) OrderSearch(notMustParams ...Params) (result OrderSearchResult, err error) { + if len(app.accessToken) <= 0 { + return result, errors.New("调用凭证异常") + } + + // 参数 + //params := app.NewParamsWith(notMustParams...) + + //if len(orderIdList) <= 0 || len(orderIdList) > 200 { + // return result, errors.New("未传入 orderIdList 或 orderIdList 超过上限 200") + //} + + //body, err := app.request(fmt.Sprintf("https://api.weixin.qq.com/union/promoter/order/info?access_token=%s", app.accessToken), map[string]interface{}{ + // "orderIdList": orderIdList, + //}, http.MethodPost) + //if err != nil { + // return result, err + //} + //err = json.Unmarshal(body, &result) + //if err != nil { + // return result, err + //} + //return result, err + return +} diff --git a/params.go b/params.go new file mode 100644 index 0000000..52823e1 --- /dev/null +++ b/params.go @@ -0,0 +1,27 @@ +package wechatunion + +// Params 请求参数 +type Params map[string]interface{} + +func NewParams() Params { + p := make(Params) + return p +} + +func (app *App) NewParamsWith(params ...Params) Params { + p := make(Params) + for _, v := range params { + p.SetParams(v) + } + return p +} + +func (p Params) Set(key string, value interface{}) { + p[key] = value +} + +func (p Params) SetParams(params Params) { + for key, value := range params { + p[key] = value + } +} diff --git a/pgsql.go b/pgsql.go new file mode 100644 index 0000000..5c38991 --- /dev/null +++ b/pgsql.go @@ -0,0 +1,26 @@ +package wechatunion + +import ( + "go.dtapp.net/gojson" + "go.dtapp.net/golog" + "go.dtapp.net/gorequest" + "gorm.io/datatypes" +) + +// 记录日志 +func (app *App) postgresqlLog(request gorequest.Response) { + app.log.Record(golog.ApiPostgresqlLog{ + RequestTime: golog.TimeString{Time: request.RequestTime}, //【请求】时间 + RequestUri: request.RequestUri, //【请求】链接 + RequestUrl: gorequest.UriParse(request.RequestUri).Url, //【请求】链接 + RequestApi: gorequest.UriParse(request.RequestUri).Path, //【请求】接口 + RequestMethod: request.RequestMethod, //【请求】方式 + RequestParams: datatypes.JSON(gojson.JsonEncodeNoError(request.RequestParams)), //【请求】参数 + RequestHeader: datatypes.JSON(gojson.JsonEncodeNoError(request.RequestHeader)), //【返回】头部 + ResponseHeader: datatypes.JSON(gojson.JsonEncodeNoError(request.ResponseHeader)), //【返回】头部 + ResponseStatusCode: request.ResponseStatusCode, //【返回】状态码 + ResponseBody: request.ResponseBody, //【返回】内容 + ResponseContentLength: request.ResponseContentLength, //【返回】大小 + ResponseTime: golog.TimeString{Time: request.ResponseTime}, //【返回】时间 + }) +} diff --git a/promoter.order.info.go b/promoter.order.info.go new file mode 100644 index 0000000..0b1eb50 --- /dev/null +++ b/promoter.order.info.go @@ -0,0 +1,73 @@ +package wechatunion + +import ( + "encoding/json" + "fmt" + "go.dtapp.net/gorequest" + "net/http" +) + +type PromoterOrderInfoResponse struct { + Errcode int `json:"errcode"` // 错误码 + Errmsg string `json:"errmsg"` // 错误信息 + OrderList []struct { + OrderId string `json:"orderId"` // 订单ID + PayTime int64 `json:"payTime"` // 支付时间戳,单位为s + ConfirmReceiptTime int `json:"confirmReceiptTime"` // 确认收货时间戳,单位为s,没有时为0 + ShopName string `json:"shopName"` // 店铺名称 + ShopAppid string `json:"shopAppid"` // 店铺 Appid + ProductList []struct { + ProductId string `json:"productId"` // 商品SPU ID + SkuId string `json:"skuId"` // sku ID + Title string `json:"title"` // 商品名称 + ThumbImg string `json:"thumbImg"` // 商品缩略图 url + Price string `json:"price"` // 商品成交总价,前带单位 ¥ + ProductCnt int `json:"productCnt"` // 成交数量 + Ratio int64 `json:"ratio"` // 分佣比例,单位为万分之一 + CommissionStatus string `json:"commissionStatus"` // 分佣状态 + CommissionStatusUpdateTime string `json:"commissionStatusUpdateTime"` // 分佣状态更新时间戳,单位为s + ProfitShardingSucTime string `json:"profitShardingSucTime"` // 结算时间,当分佣状态为已结算才有值,单位为s + Commission string `json:"commission"` // 分佣金额,前带单位 ¥ + EstimatedCommission int `json:"estimatedCommission"` // 预估分佣金额,单位为分 + CategoryStr string `json:"categoryStr"` // 类目名称,多个用英文逗号分隔 + PromotionInfo struct { + PromotionSourcePid string `json:"promotionSourcePid"` // 推广位 id + PromotionSourceName string `json:"promotionSourceName"` // 推广位名称 + } `json:"promotionInfo"` // 推广信息 + CustomizeInfo string `json:"customizeInfo"` // 自定义信息 + } `json:"productList"` // 商品列表 + CustomUserId string `json:"customUserId"` // 自定义用户参数 + UserNickName string `json:"userNickName"` // 用户昵称 + OrderPrice string `json:"orderPrice"` // 支付金额,单位为分 + } `json:"orderList"` +} + +type PromoterOrderInfoResult struct { + Result PromoterOrderInfoResponse // 结果 + Body []byte // 内容 + Http gorequest.Response // 请求 + Err error // 错误 +} + +func NewPromoterOrderInfoResult(result PromoterOrderInfoResponse, body []byte, http gorequest.Response, err error) *PromoterOrderInfoResult { + return &PromoterOrderInfoResult{Result: result, Body: body, Http: http, Err: err} +} + +// PromoterOrderInfo 根据订单ID查询订单详情 +// https://developers.weixin.qq.com/doc/ministore/union/access-guidelines/promoter/api/order/order-info.html#_1-%E6%A0%B9%E6%8D%AE%E8%AE%A2%E5%8D%95ID%E6%9F%A5%E8%AF%A2%E8%AE%A2%E5%8D%95%E8%AF%A6%E6%83%85 +func (app *App) PromoterOrderInfo(orderId ...string) *PromoterOrderInfoResult { + app.accessToken = app.GetAccessToken() + // 参数 + params := app.NewParamsWith() + var orderIdList []any + for _, v := range orderId { + orderIdList = append(orderIdList, v) + } + params.Set("orderIdList", orderIdList) + // 请求 + request, err := app.request(UnionUrl+fmt.Sprintf("/promoter/order/info?access_token=%s", app.accessToken), params, http.MethodPost) + // 定义 + var response PromoterOrderInfoResponse + err = json.Unmarshal(request.ResponseBody, &response) + return NewPromoterOrderInfoResult(response, request.ResponseBody, request, err) +} diff --git a/promoter.order.search.go b/promoter.order.search.go new file mode 100644 index 0000000..b6ae169 --- /dev/null +++ b/promoter.order.search.go @@ -0,0 +1,70 @@ +package wechatunion + +import ( + "encoding/json" + "fmt" + "go.dtapp.net/gorequest" + "net/http" +) + +type PromoterOrderSearchResponse struct { + Errcode int `json:"errcode"` // 错误码 + Errmsg string `json:"errmsg"` // 错误信息 + OrderList []struct { + OrderId string `json:"orderId"` // 订单ID + PayTime int64 `json:"payTime"` // 支付时间戳,单位为s + ConfirmReceiptTime int `json:"confirmReceiptTime"` // 确认收货时间戳,单位为s,没有时为0 + ShopName string `json:"shopName"` // 店铺名称 + ShopAppid string `json:"shopAppid"` // 店铺 Appid + ProductList []struct { + ProductId string `json:"productId"` // 商品SPU ID + SkuId string `json:"skuId"` // sku ID + Title string `json:"title"` // 商品名称 + ThumbImg string `json:"thumbImg"` // 商品缩略图 url + Price string `json:"price"` // 商品成交总价,前带单位 ¥ + ProductCnt int `json:"productCnt"` // 成交数量 + Ratio int64 `json:"ratio"` // 分佣比例,单位为万分之一 + CommissionStatus string `json:"commissionStatus"` // 分佣状态 + CommissionStatusUpdateTime string `json:"commissionStatusUpdateTime"` // 分佣状态更新时间戳,单位为s + ProfitShardingSucTime string `json:"profitShardingSucTime"` // 结算时间,当分佣状态为已结算才有值,单位为s + Commission string `json:"commission"` // 分佣金额,前带单位 ¥ + EstimatedCommission int `json:"estimatedCommission"` // 预估分佣金额,单位为分 + CategoryStr string `json:"categoryStr"` // 类目名称,多个用英文逗号分隔 + PromotionInfo struct { + PromotionSourcePid string `json:"promotionSourcePid"` // 推广位 id + PromotionSourceName string `json:"promotionSourceName"` // 推广位名称 + } `json:"promotionInfo"` // 推广信息 + CustomizeInfo string `json:"customizeInfo"` // 自定义信息 + } `json:"productList"` // 商品列表 + CustomUserId string `json:"customUserId"` // 自定义用户参数 + UserNickName string `json:"userNickName"` // 用户昵称 + OrderPrice string `json:"orderPrice"` // 支付金额,单位为分 + } `json:"orderList"` // 订单列表 + PageSize int `json:"pageSize"` // 分页大小 + TotalNum int `json:"totalNum"` // 订单总数 +} + +type PromoterOrderSearchResult struct { + Result PromoterOrderSearchResponse // 结果 + Body []byte // 内容 + Http gorequest.Response // 请求 + Err error // 错误 +} + +func NewPromoterOrderSearchResult(result PromoterOrderSearchResponse, body []byte, http gorequest.Response, err error) *PromoterOrderSearchResult { + return &PromoterOrderSearchResult{Result: result, Body: body, Http: http, Err: err} +} + +// PromoterOrderSearch 根据订单支付时间、订单分佣状态拉取订单详情 +// https://developers.weixin.qq.com/doc/ministore/union/access-guidelines/promoter/api/order/order-info.html#_2-%E6%A0%B9%E6%8D%AE%E8%AE%A2%E5%8D%95%E6%94%AF%E4%BB%98%E6%97%B6%E9%97%B4%E3%80%81%E8%AE%A2%E5%8D%95%E5%88%86%E4%BD%A3%E7%8A%B6%E6%80%81%E6%8B%89%E5%8F%96%E8%AE%A2%E5%8D%95%E8%AF%A6%E6%83%85 +func (app *App) PromoterOrderSearch(notMustParams ...Params) *PromoterOrderSearchResult { + app.accessToken = app.GetAccessToken() + // 参数 + params := app.NewParamsWith(notMustParams...) + // 请求 + request, err := app.request(UnionUrl+fmt.Sprintf("/promoter/order/search?access_token=%s", app.accessToken), params, http.MethodGet) + // 定义 + var response PromoterOrderSearchResponse + err = json.Unmarshal(request.ResponseBody, &response) + return NewPromoterOrderSearchResult(response, request.ResponseBody, request, err) +} diff --git a/promoter.product.category.go b/promoter.product.category.go new file mode 100644 index 0000000..a95f998 --- /dev/null +++ b/promoter.product.category.go @@ -0,0 +1,40 @@ +package wechatunion + +import ( + "encoding/json" + "fmt" + "go.dtapp.net/gorequest" + "net/http" +) + +type PromoterProductCategoryResponse struct { + Errcode int `json:"errcode"` // 错误码 + Errmsg string `json:"errmsg"` // 错误信息 + ProductCats []struct { + CatId string `json:"catId"` // 类目ID + Name string `json:"name"` // 类目名称 + } `json:"productCats"` // 类目数据 +} + +type PromoterProductCategoryResult struct { + Result PromoterProductCategoryResponse // 结果 + Body []byte // 内容 + Http gorequest.Response // 请求 + Err error // 错误 +} + +func NewPromoterProductCategoryResult(result PromoterProductCategoryResponse, body []byte, http gorequest.Response, err error) *PromoterProductCategoryResult { + return &PromoterProductCategoryResult{Result: result, Body: body, Http: http, Err: err} +} + +// PromoterProductCategory 获取联盟商品类目列表及类目ID +// https://developers.weixin.qq.com/doc/ministore/union/access-guidelines/promoter/api/product/category.html#_1-%E8%8E%B7%E5%8F%96%E8%81%94%E7%9B%9F%E5%95%86%E5%93%81%E7%B1%BB%E7%9B%AE%E5%88%97%E8%A1%A8%E5%8F%8A%E7%B1%BB%E7%9B%AEID +func (app *App) PromoterProductCategory() *PromoterProductCategoryResult { + app.accessToken = app.GetAccessToken() + // 请求 + request, err := app.request(UnionUrl+fmt.Sprintf("/promoter/product/category?access_token=%s", app.accessToken), map[string]interface{}{}, http.MethodGet) + // 定义 + var response PromoterProductCategoryResponse + err = json.Unmarshal(request.ResponseBody, &response) + return NewPromoterProductCategoryResult(response, request.ResponseBody, request, err) +} diff --git a/promoter.product.generate.go b/promoter.product.generate.go new file mode 100644 index 0000000..41924f7 --- /dev/null +++ b/promoter.product.generate.go @@ -0,0 +1,69 @@ +package wechatunion + +import ( + "encoding/json" + "fmt" + "go.dtapp.net/gorequest" + "net/http" +) + +type PromoterProductGenerateResponse struct { + Errcode int `json:"errcode"` // 错误码 + Errmsg string `json:"errmsg"` // 错误信息 + List []struct { + ProductId string `json:"productId"` // 商品SPU ID + Pid string `json:"pid"` // 推广位PID + ProductInfo struct { + ProductId string `json:"productId"` // 商品SPU ID + Title string `json:"title"` // 商品标题 + SubTitle string `json:"subTitle"` // 商品子标题 + HeadImg []string `json:"headImg"` // 商品主图 + MinPrice int `json:"minPrice"` // 商品最低价格,单位分 + Discount int `json:"discount"` // 商品优惠金额,单位分 + DiscountPrice int `json:"discountPrice"` // 商品券后最低价格,单位分 + ShopName string `json:"shopName"` // 商店名称 + PluginResult int `json:"pluginResult"` // 是否引用小商店组件(未引用组件的商品不可推广),0:否,1:是 + TotalStockNum int `json:"totalStockNum"` // 商品库存 + } `json:"productInfo"` // 商品相关信息 + ShareInfo struct { + Username string `json:"username"` // 推广商品的小程序原始id + AppId string `json:"appId"` // 推广商品的小程序AppID + Path string `json:"path"` // 推广商品的小程序Path + CouponPath string `json:"couponPath"` // 推广商品的带券小程序Path + WxaCode string `json:"wxaCode"` // 已废弃。推广商品详情页的不带券葵花码图片 + CouponWxaCode string `json:"couponWxaCode"` // 已废弃。推广商品详情页的带券葵花码图片 + PromotionUrl string `json:"promotionUrl"` // 推广商品短链 + CouponPromotionUrl string `json:"couponPromotionUrl"` // 推广商品带券短链 + PromotionWording string `json:"promotionWording"` // 推广商品文案 + CouponPromotionWording string `json:"couponPromotionWording"` // 推广商品带券文案 + PromotionTag string `json:"promotionTag"` // 推广商品tag + CouponPromotionTag string `json:"couponPromotionTag"` // 推广商品带券tag + } `json:"shareInfo"` // 推广相关信息 + } `json:"list"` +} + +type PromoterProductGenerateResult struct { + Result PromoterProductGenerateResponse // 结果 + Body []byte // 内容 + Http gorequest.Response // 请求 + Err error // 错误 +} + +func NewPromoterProductGenerateResult(result PromoterProductGenerateResponse, body []byte, http gorequest.Response, err error) *PromoterProductGenerateResult { + return &PromoterProductGenerateResult{Result: result, Body: body, Http: http, Err: err} +} + +// PromoterProductGenerate 获取商品推广素材 +// https://developers.weixin.qq.com/doc/ministore/union/access-guidelines/promoter/api/product/category.html#_4-%E8%8E%B7%E5%8F%96%E5%95%86%E5%93%81%E6%8E%A8%E5%B9%BF%E7%B4%A0%E6%9D%90 +func (app *App) PromoterProductGenerate(notMustParams ...Params) *PromoterProductGenerateResult { + app.accessToken = app.GetAccessToken() + // 参数 + params := app.NewParamsWith(notMustParams...) + params.Set("pid", app.pid) + // 请求 + request, err := app.request(UnionUrl+fmt.Sprintf("/promoter/product/generate?access_token=%s", app.accessToken), params, http.MethodPost) + // 定义 + var response PromoterProductGenerateResponse + err = json.Unmarshal(request.ResponseBody, &response) + return NewPromoterProductGenerateResult(response, request.ResponseBody, request, err) +} diff --git a/promoter.product.list.go b/promoter.product.list.go new file mode 100644 index 0000000..6897800 --- /dev/null +++ b/promoter.product.list.go @@ -0,0 +1,152 @@ +package wechatunion + +import ( + "encoding/json" + "fmt" + "go.dtapp.net/gorequest" + "net/http" +) + +type PromoterProductListResponse struct { + Errcode int `json:"errcode"` // 错误码 + Errmsg string `json:"errmsg"` // 错误信息 + Msg string `json:"msg"` // 错误信息 + Total int `json:"total"` // 商品总数 + ProductList []struct { + ProductId string `json:"productId"` // 商品SPU ID + Product struct { + ProductId string `json:"productId"` // 商品SPU ID + Info struct { + Title string `json:"title"` // 商品标题 + SubTitle string `json:"subTitle"` // 商品子标题 + HeadImg []string `json:"headImg"` // 商品主图 + Category []struct { + CatId string `json:"catId"` // 类目ID + Name string `json:"name"` // 类目名称 + } `json:"category"` // 商品类目 + Brand string `json:"brand,omitempty"` // 品牌名称 + BrandId string `json:"brandId"` // 品牌ID + Model string `json:"model,omitempty"` // 型号 + Detail struct { + DetailImg []string `json:"detailImg"` // 商品详情图片 + } `json:"detail"` // 商品详细数据 + Param []interface{} `json:"param"` // 商品参数 + MinPrice int64 `json:"minPrice"` // 商品最低价格,单位分 + TotalStockNum int64 `json:"totalStockNum"` // 总库存 + TotalSoldNum int64 `json:"totalSoldNum"` // 累计销量 + TotalOrderNum int `json:"totalOrderNum"` // 累计订单量 + DiscountPrice int64 `json:"discountPrice"` // 商品券后价 + } `json:"info"` // 商品具体信息 + Skus []struct { + SkuId string `json:"skuId"` // 商品SKU ID + ProductSkuInfo struct { + ThumbImg string `json:"thumbImg"` // 商品SKU 小图 + SalePrice int `json:"salePrice"` // 商品SKU 销售价格,单位分 + MarketPrice int `json:"marketPrice"` // 商品SKU 市场价格,单位分 + StockInfo struct { + StockNum int `json:"stockNum"` // 商品SKU 库存 + } `json:"stockInfo"` + } `json:"productSkuInfo"` + } `json:"skus"` // 商品SKU + } `json:"product"` // 商品数据 + LeagueExInfo struct { + HasCommission int `json:"hasCommission"` // 是否有佣金,1/0 + CommissionRatio int64 `json:"commissionRatio"` // 佣金比例,万分之一 + CommissionValue int64 `json:"commissionValue"` // 佣金金额,单位分 + } `json:"leagueExInfo"` // 联盟佣金相关数据 + ShopInfo struct { + Name string `json:"name"` // 小商店名称 + AppId string `json:"appId"` // 小商店AppID + Username string `json:"username"` // 小商店原始id + HeadImgUrl string `json:"headImgUrl"` // 小商店店铺头像 + ShippingMethods struct { + Express int `json:"express"` // 是否支持快递,1:是,0:否 + SameCity int `json:"sameCity"` // 是否支持同城配送,1:是,0:否 + Pickup int `json:"pickup"` // 是否支持上门自提,1:是,0:否 + } `json:"shippingMethods"` // 配送方式 + AddressList []struct { + AddressInfo struct { + ProvinceName string `json:"provinceName"` // 国标收货地址第一级地址 + CityName string `json:"cityName"` // 国标收货地址第二级地址 + CountyName string `json:"countyName"` // 国标收货地址第三级地址 + } `json:"addressInfo"` // 地址信息 + AddressType struct { + Express int `json:"express"` // 是否支持快递,1:是,0:否 + SameCity int `json:"sameCity"` // 是否支持同城配送,1:是,0:否 + Pickup int `json:"pickup"` // 是否支持上门自提,1:是,0:否 + } `json:"addressType"` // 地址类型 + } `json:"addressList"` // 发货地,只有当配送方式包含「同城配送、上门自提」才出该项 + SameCityTemplate struct { + DeliverScopeType int `json:"deliverScopeType"` // 配送范围的定义方式,0:按照距离定义配送范围,1:按照区域定义配送范围 + Scope string `json:"scope"` // 配送范围 + Region struct { + ProvinceName string `json:"provinceName"` // 国标收货地址第一级地址 + CityName string `json:"cityName"` // 国标收货地址第二级地址 + CountyName string `json:"countyName"` // 国标收货地址第三级地址 + } `json:"region"` // 全城配送时的配送范围 + } `json:"sameCityTemplate"` // 配送范围,只有当配送方式包含「同城配送」才出该项 + FreightTemplate struct { + NotSendArea struct { + AddressInfoList []struct { + ProvinceName string `json:"provinceName"` // 国标收货地址第一级地址 + CityName string `json:"cityName"` // 国标收货地址第二级地址 + CountyName string `json:"countyName"` // 国标收货地址第三级地址 + } `json:"addressInfoList"` // 不发货地区地址列表 + } `json:"notSendArea,omitempty"` // 不发货地区 + } `json:"freightTemplate"` // 运费模板,只有当配送方式包含「快递」才出此项 + } `json:"shopInfo"` // 商品所属小商店数据 + CouponInfo struct { + HasCoupon int `json:"hasCoupon"` // 是否有联盟券,1为含券商品,0为全部商品 + CouponId string `json:"couponId"` // 券id + CouponDetail struct { + RestNum int `json:"restNum"` // 券库存 + Type int `json:"type"` // 券类型 + DiscountInfo struct { + DiscountCondition struct { + ProductIds []string `json:"productIds"` // 指定商品 id + ProductCnt string `json:"productCnt"` // 商品数 + ProductPrice string `json:"productPrice"` // 商品金额 + } `json:"discountCondition"` // 指定商品 id + DiscountNum int `json:"discountNum,omitempty"` // 折扣数,如 5.1 折 为 5.1 * 1000 + DiscountFee string `json:"discountFee,omitempty"` // 直减金额,单位为分 + } `json:"discountInfo"` // 券面额 + ValidInfo struct { + ValidType int `json:"validType"` // 有效期类型,1 为商品指定时间区间,2 为生效天数 + ValidDayNum int `json:"validDayNum"` // 生效天数 + StartTime string `json:"startTime"` // 有效开始时间 + EndTime string `json:"endTime"` // 有效结束时间 + } `json:"validInfo"` // 有效期 + ReceiveInfo struct { + StartTime string `json:"startTime"` // 有效结束时间 + EndTime string `json:"endTime"` // 领取结束时间戳 + LimitNumOnePerson int `json:"limitNumOnePerson"` // 每人限领张数 + } `json:"receiveInfo"` // 领券时间 + } `json:"couponDetail"` // 券详情 + } `json:"couponInfo"` // 联盟优惠券数据 + } `json:"productList"` // 商品列表数据 +} + +type PromoterProductListResult struct { + Result PromoterProductListResponse // 结果 + Body []byte // 内容 + Http gorequest.Response // 请求 + Err error // 错误 +} + +func NewPromoterProductListResult(result PromoterProductListResponse, body []byte, http gorequest.Response, err error) *PromoterProductListResult { + return &PromoterProductListResult{Result: result, Body: body, Http: http, Err: err} +} + +// PromoterProductList 查询全量商品 +// https://developers.weixin.qq.com/doc/ministore/union/access-guidelines/promoter/api/product/category.html#_2-%E6%9F%A5%E8%AF%A2%E5%85%A8%E9%87%8F%E5%95%86%E5%93%81 +func (app *App) PromoterProductList(notMustParams ...Params) *PromoterProductListResult { + app.accessToken = app.GetAccessToken() + // 参数 + params := app.NewParamsWith(notMustParams...) + // 请求 + request, err := app.request(UnionUrl+fmt.Sprintf("/promoter/product/list?access_token=%s", app.accessToken), params, http.MethodGet) + // 定义 + var response PromoterProductListResponse + err = json.Unmarshal(request.ResponseBody, &response) + return NewPromoterProductListResult(response, request.ResponseBody, request, err) +} diff --git a/promoter.product.select.go b/promoter.product.select.go new file mode 100644 index 0000000..c9189aa --- /dev/null +++ b/promoter.product.select.go @@ -0,0 +1,153 @@ +package wechatunion + +import ( + "encoding/json" + "fmt" + "go.dtapp.net/gorequest" + "net/http" +) + +type PromoterProductSelectResponse struct { + Errcode int `json:"errcode"` // 错误码 + Errmsg string `json:"errmsg"` // 错误信息 + Total int64 `json:"total"` // 商品总数 + ProductList []struct { + ProductId string `json:"productId"` // 商品SPU ID + Product struct { + ProductId string `json:"productId"` // 商品SPU ID + Info struct { + Title string `json:"title"` // 商品标题 + SubTitle string `json:"subTitle"` // 商品子标题 + HeadImg []string `json:"headImg"` // 商品主图 + Category []struct { + CatId string `json:"catId"` // 类目ID + Name string `json:"name"` // 类目ID + } `json:"category"` // 商品类目 + Brand string `json:"brand"` // 品牌名称 + BrandId string `json:"brandId"` // 品牌ID + Model string `json:"model"` // 型号 + Detail struct { + DetailImg []string `json:"detailImg"` // 商品详情图片 + } `json:"detail"` // 商品详细数据 + Param []interface{} `json:"param"` // 商品参数 + MinPrice int64 `json:"minPrice"` // 商品最低价格,单位分 + TotalStockNum int64 `json:"totalStockNum"` // 总库存 + TotalSoldNum int `json:"totalSoldNum"` // 累计销量 + TotalOrderNum int `json:"totalOrderNum"` // 累计订单量 + DiscountPrice int64 `json:"discountPrice"` // 商品券后价 + } `json:"info"` // 商品具体信息 + Skus []struct { + SkuId string `json:"skuId"` // 商品SKU ID + ProductSkuInfo struct { + ThumbImg string `json:"thumbImg"` // 商品SKU 小图 + SalePrice int `json:"salePrice"` // 商品SKU 销售价格,单位分 + MarketPrice int `json:"marketPrice,omitempty"` // 商品SKU 市场价格,单位分 + StockInfo struct { + StockNum int `json:"stockNum"` // 商品SKU 库存 + } `json:"stockInfo"` + } `json:"productSkuInfo"` + } `json:"skus"` // 商品SKU + } `json:"product"` // 商品数据 + LeagueExInfo struct { + HasCommission int `json:"hasCommission"` // 是否有佣金,1/0 + CommissionRatio int64 `json:"commissionRatio"` // 佣金比例,万分之一 + CommissionValue int64 `json:"commissionValue"` // 佣金金额,单位分 + } `json:"leagueExInfo"` // 联盟佣金相关数据 + ShopInfo struct { + Name string `json:"name"` // 小商店名称 + AppId string `json:"appId"` // 小商店AppID + Username string `json:"username"` // 小商店原始id + HeadImgUrl string `json:"headImgUrl"` // 小商店店铺头像 + AddressList []struct { + AddressInfo struct { + ProvinceName string `json:"provinceName"` // 国标收货地址第一级地址 + CityName string `json:"cityName"` // 国标收货地址第二级地址 + CountyName string `json:"countyName"` // 国标收货地址第三级地址 + } `json:"addressInfo"` // 地址信息 + AddressType struct { + Express int `json:"express"` // 是否支持快递,1:是,0:否 + SameCity int `json:"sameCity"` // 是否支持同城配送,1:是,0:否 + Pickup int `json:"pickup"` // 是否支持上门自提,1:是,0:否 + } `json:"addressType"` // 地址类型 + } `json:"addressList"` // 发货地,只有当配送方式包含「同城配送、上门自提」才出该项 + ShippingMethods struct { + Express int `json:"express"` // 是否支持快递,1:是,0:否 + SameCity int `json:"sameCity"` // 是否支持同城配送,1:是,0:否 + Pickup int `json:"pickup"` // 是否支持上门自提,1:是,0:否 + } `json:"shippingMethods"` // 配送方式 + SameCityTemplate struct { + DeliverScopeType int `json:"deliverScopeType"` // 配送范围的定义方式,0:按照距离定义配送范围,1:按照区域定义配送范围 + Scope string `json:"scope"` // 配送范围 + Region struct { + ProvinceName string `json:"provinceName"` // 国标收货地址第一级地址 + CityName string `json:"cityName"` // 国标收货地址第二级地址 + CountyName string `json:"countyName"` // 国标收货地址第三级地址 + } `json:"region"` // 全城配送时的配送范围 + } `json:"sameCityTemplate"` // 配送范围,只有当配送方式包含「同城配送」才出该项 + FreightTemplate struct { + NotSendArea struct { + AddressInfoList []struct { + ProvinceName string `json:"provinceName"` // 国标收货地址第一级地址 + CityName string `json:"cityName"` // 国标收货地址第二级地址 + CountyName string `json:"countyName"` // 国标收货地址第三级地址 + } `json:"addressInfoList"` // 不发货地区地址列表 + } `json:"notSendArea,omitempty"` // 不发货地区 + } `json:"freightTemplate"` // 运费模板,只有当配送方式包含「快递」才出此项 + } `json:"shopInfo"` // 商品所属小商店数据 + CouponInfo struct { + HasCoupon int `json:"hasCoupon"` // 是否有联盟券,1为含券商品,0为全部商品 + CouponId string `json:"couponId"` // 券id + CouponDetail struct { + RestNum int `json:"restNum"` // 券库存 + Type int `json:"type"` // 券类型 + DiscountInfo struct { + DiscountCondition struct { + ProductIds []string `json:"productIds"` // 指定商品 id + ProductCnt string `json:"productCnt"` // 商品数 + ProductPrice string `json:"productPrice"` // 商品金额 + } `json:"discountCondition"` // 指定商品 id + DiscountNum int `json:"discountNum,omitempty"` // 折扣数,如 5.1 折 为 5.1 * 1000 + DiscountFee int64 `json:"discountFee,omitempty"` // 直减金额,单位为分 + } `json:"discountInfo"` // 券面额 + ValidInfo struct { + ValidType int `json:"validType"` // 有效期类型,1 为商品指定时间区间,2 为生效天数 + ValidDayNum int `json:"validDayNum"` // 生效天数 + StartTime string `json:"startTime"` // 有效开始时间 + EndTime string `json:"endTime"` // 有效结束时间 + } `json:"validInfo"` // 有效期 + ReceiveInfo struct { + StartTime string `json:"startTime"` // 有效结束时间 + EndTime string `json:"endTime"` // 领取结束时间戳 + LimitNumOnePerson int `json:"limitNumOnePerson"` // 每人限领张数 + } `json:"receiveInfo"` // 领券时间 + } `json:"couponDetail"` // 券详情 + } `json:"couponInfo"` // 联盟优惠券数据 + } `json:"productList"` // 商品列表数据 +} + +type PromoterProductSelectResult struct { + Result PromoterProductSelectResponse // 结果 + Body []byte // 内容 + Http gorequest.Response // 请求 + Err error // 错误 +} + +func NewPromoterProductSelectResult(result PromoterProductSelectResponse, body []byte, http gorequest.Response, err error) *PromoterProductSelectResult { + return &PromoterProductSelectResult{Result: result, Body: body, Http: http, Err: err} +} + +// PromoterProductSelect +// 查询联盟精选商品 +// 支持开发者根据多种筛选条件获取联盟精选的商品列表及详情,筛选条件包括商品价格、商品佣金、商品累计销量、佣金比例、是否含有联盟券、配送方式、发货地区 +// https://developers.weixin.qq.com/doc/ministore/union/access-guidelines/promoter/api/product/category.html#3.%E6%9F%A5%E8%AF%A2%E8%81%94%E7%9B%9F%E7%B2%BE%E9%80%89%E5%95%86%E5%93%81 +func (app *App) PromoterProductSelect(notMustParams ...Params) *PromoterProductSelectResult { + app.accessToken = app.GetAccessToken() + // 参数 + params := app.NewParamsWith(notMustParams...) + // 请求 + request, err := app.request(UnionUrl+fmt.Sprintf("/promoter/product/select?access_token=%s", app.accessToken), params, http.MethodGet) + // 定义 + var response PromoterProductSelectResponse + err = json.Unmarshal(request.ResponseBody, &response) + return NewPromoterProductSelectResult(response, request.ResponseBody, request, err) +} diff --git a/promoter.promotion.add.go b/promoter.promotion.add.go new file mode 100644 index 0000000..3e703c9 --- /dev/null +++ b/promoter.promotion.add.go @@ -0,0 +1,40 @@ +package wechatunion + +import ( + "encoding/json" + "fmt" + "go.dtapp.net/gorequest" + "net/http" +) + +type PromotionAddResponse struct { + Errcode int `json:"errcode"` // 错误码 + Errmsg string `json:"errmsg"` // 错误信息 + Pid string `json:"pid"` // 推广位ID,PID +} + +type PromotionAddResult struct { + Result PromotionAddResponse // 结果 + Body []byte // 内容 + Http gorequest.Response // 请求 + Err error // 错误 +} + +func NewPromotionAddResult(result PromotionAddResponse, body []byte, http gorequest.Response, err error) *PromotionAddResult { + return &PromotionAddResult{Result: result, Body: body, Http: http, Err: err} +} + +// PromotionAdd 添加推广位 +// https://developers.weixin.qq.com/doc/ministore/union/access-guidelines/promoter/api/promotion.html#_1-%E6%B7%BB%E5%8A%A0%E6%8E%A8%E5%B9%BF%E4%BD%8D +func (app *App) PromotionAdd(promotionSourceName string) *PromotionAddResult { + app.accessToken = app.GetAccessToken() + // 参数 + params := NewParams() + params.Set("promotionSourceName", promotionSourceName) // 推广位名称 + // 请求 + request, err := app.request(UnionUrl+fmt.Sprintf("/promoter/promotion/add?access_token%s", app.accessToken), params, http.MethodPost) + // 定义 + var response PromotionAddResponse + err = json.Unmarshal(request.ResponseBody, &response) + return NewPromotionAddResult(response, request.ResponseBody, request, err) +} diff --git a/promoter.promotion.del.go b/promoter.promotion.del.go new file mode 100644 index 0000000..02cccf2 --- /dev/null +++ b/promoter.promotion.del.go @@ -0,0 +1,40 @@ +package wechatunion + +import ( + "encoding/json" + "fmt" + "go.dtapp.net/gorequest" + "net/http" +) + +type PromotionDelResponse struct { + Errcode int `json:"errcode"` // 错误码 + Errmsg string `json:"errmsg"` // 错误信息 +} + +type PromotionDelResult struct { + Result PromotionDelResponse // 结果 + Body []byte // 内容 + Http gorequest.Response // 请求 + Err error // 错误 +} + +func NewPromotionDelResult(result PromotionDelResponse, body []byte, http gorequest.Response, err error) *PromotionDelResult { + return &PromotionDelResult{Result: result, Body: body, Http: http, Err: err} +} + +// PromotionDel 删除某个推广位 +// https://developers.weixin.qq.com/doc/ministore/union/access-guidelines/promoter/api/promotion.html#_3-%E7%BC%96%E8%BE%91%E6%8E%A8%E5%B9%BF%E4%BD%8D +func (app *App) PromotionDel(promotionSourcePid, promotionSourceName string) *PromotionDelResult { + app.accessToken = app.GetAccessToken() + // 参数 + params := NewParams() + params.Set("promotionSourcePid", promotionSourcePid) // 推广位PID + params.Set("promotionSourceName", promotionSourceName) // 推广位名称 + // 请求 + request, err := app.request(UnionUrl+fmt.Sprintf("/promoter/promotion/del?access_token%s", app.accessToken), params, http.MethodPost) + // 定义 + var response PromotionDelResponse + err = json.Unmarshal(request.ResponseBody, &response) + return NewPromotionDelResult(response, request.ResponseBody, request, err) +} diff --git a/promoter.promotion.list.go b/promoter.promotion.list.go new file mode 100644 index 0000000..36993e3 --- /dev/null +++ b/promoter.promotion.list.go @@ -0,0 +1,48 @@ +package wechatunion + +import ( + "encoding/json" + "fmt" + "go.dtapp.net/gorequest" + "net/http" +) + +type PromotionListResponse struct { + Errcode int `json:"errcode"` // 错误码 + Errmsg string `json:"errmsg"` // 错误信息 + PromotionSourceList []struct { + PromotionSourceName string `json:"promotionSourceName"` // 推广位名称 + PromotionSourcePid string `json:"promotionSourcePid"` // 推广位ID,PID + Status string `json:"status"` // 状态 + PidId string `json:"pidId"` + } `json:"promotionSourceList"` // 推广位数据 + Total int `json:"total"` // 推广位总数 + PromotionMaxCnt int `json:"promotionMaxCnt"` // 允许创建的推广位最大数量 +} + +type PromotionListResult struct { + Result PromotionListResponse // 结果 + Body []byte // 内容 + Http gorequest.Response // 请求 + Err error // 错误 +} + +func NewPromotionListResult(result PromotionListResponse, body []byte, http gorequest.Response, err error) *PromotionListResult { + return &PromotionListResult{Result: result, Body: body, Http: http, Err: err} +} + +// PromotionList 获取推广位列表 +// https://developers.weixin.qq.com/doc/ministore/union/access-guidelines/promoter/api/promotion.html#_4-%E8%8E%B7%E5%8F%96%E6%8E%A8%E5%B9%BF%E4%BD%8D%E5%88%97%E8%A1%A8 +func (app *App) PromotionList(start int, limit int) *PromotionListResult { + app.accessToken = app.GetAccessToken() + // 参数 + params := NewParams() + params.Set("start", start) // 偏移 + params.Set("limit", limit) // 每页条数 + // 请求 + request, err := app.request(UnionUrl+fmt.Sprintf("/promoter/promotion/list?access_token%s", app.accessToken), params, http.MethodGet) + // 定义 + var response PromotionListResponse + err = json.Unmarshal(request.ResponseBody, &response) + return NewPromotionListResult(response, request.ResponseBody, request, err) +} diff --git a/promoter.promotion.upd.go b/promoter.promotion.upd.go new file mode 100644 index 0000000..0756183 --- /dev/null +++ b/promoter.promotion.upd.go @@ -0,0 +1,38 @@ +package wechatunion + +import ( + "encoding/json" + "fmt" + "go.dtapp.net/gorequest" + "net/http" +) + +type PromotionUpdResponse struct { + Errcode int `json:"errcode"` // 错误码 + Errmsg string `json:"errmsg"` // 错误信息 +} + +type PromotionUpdResult struct { + Result PromotionUpdResponse // 结果 + Body []byte // 内容 + Http gorequest.Response // 请求 + Err error // 错误 +} + +func NewPromotionUpdResult(result PromotionUpdResponse, body []byte, http gorequest.Response, err error) *PromotionUpdResult { + return &PromotionUpdResult{Result: result, Body: body, Http: http, Err: err} +} + +// PromotionUpd 编辑推广位 +// https://developers.weixin.qq.com/doc/ministore/union/access-guidelines/promoter/api/promotion.html#_3-%E7%BC%96%E8%BE%91%E6%8E%A8%E5%B9%BF%E4%BD%8D +func (app *App) PromotionUpd(notMustParams ...Params) *PromotionUpdResult { + app.accessToken = app.GetAccessToken() + // 参数 + params := app.NewParamsWith(notMustParams...) + // 请求 + request, err := app.request(UnionUrl+fmt.Sprintf("/promoter/promotion/upd?access_token%s", app.accessToken), params, http.MethodPost) + // 定义 + var response PromotionUpdResponse + err = json.Unmarshal(request.ResponseBody, &response) + return NewPromotionUpdResult(response, request.ResponseBody, request, err) +} diff --git a/version.go b/version.go new file mode 100644 index 0000000..4e1925f --- /dev/null +++ b/version.go @@ -0,0 +1,3 @@ +package wechatunion + +const Version = "1.0.0"