Compare commits
50 Commits
Author | SHA1 | Date |
---|---|---|
李光春 | f646934937 | 1 year ago |
李光春 | 3b3e91bb17 | 1 year ago |
李光春 | 72e2014313 | 1 year ago |
李光春 | 82ea709f82 | 2 years ago |
李光春 | 486fe027e0 | 2 years ago |
李光春 | 0f2b443f26 | 2 years ago |
李光春 | 07fd234a98 | 2 years ago |
李光春 | acda52aee9 | 2 years ago |
李光春 | 04c6685b75 | 2 years ago |
李光春 | d1cda7f385 | 2 years ago |
李光春 | 734bb80833 | 2 years ago |
李光春 | 85c983e6ab | 2 years ago |
李光春 | b84e516018 | 2 years ago |
李光春 | a527ea8800 | 2 years ago |
李光春 | 99a5eeb96c | 2 years ago |
李光春 | 6247c136f5 | 2 years ago |
李光春 | ac4496c7e8 | 2 years ago |
李光春 | ab0ff7b934 | 2 years ago |
李光春 | 7eb51ea505 | 2 years ago |
李光春 | f48879bea6 | 2 years ago |
李光春 | b34320ffa3 | 2 years ago |
李光春 | b1dd60284d | 2 years ago |
李光春 | 2401d39ae2 | 2 years ago |
李光春 | 11cb134490 | 2 years ago |
李光春 | bcdc0ba95c | 2 years ago |
李光春 | 1dd03cefc0 | 2 years ago |
李光春 | 1564015f98 | 2 years ago |
李光春 | f6113e7c99 | 2 years ago |
李光春 | d88cb69527 | 2 years ago |
李光春 | 3bd29edc4b | 2 years ago |
李光春 | 758f9ff5c0 | 2 years ago |
李光春 | ecabbba061 | 2 years ago |
李光春 | 147fbbac4a | 2 years ago |
李光春 | 6486410d35 | 2 years ago |
李光春 | 4714174013 | 2 years ago |
李光春 | 8fde8e6191 | 2 years ago |
李光春 | ca0fe58783 | 2 years ago |
李光春 | 0f9a19f832 | 2 years ago |
李光春 | 2150d671be | 2 years ago |
李光春 | ab5bb603c9 | 2 years ago |
李光春 | 2bffadd116 | 2 years ago |
李光春 | 1defa20a76 | 2 years ago |
李光春 | bb4857963d | 2 years ago |
李光春 | 61aa7fbac9 | 2 years ago |
李光春 | ff1e4f9b8f | 2 years ago |
李光春 | 321a6d5b00 | 2 years ago |
李光春 | a3664d42b0 | 2 years ago |
李光春 | 503a1ab383 | 2 years ago |
李光春 | e2df81c3a4 | 2 years ago |
李光春 | f75570d0c8 | 2 years ago |
@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2018 李光春
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
@ -1,88 +0,0 @@
|
||||
package wechatopen
|
||||
|
||||
import (
|
||||
"go.dtapp.net/golog"
|
||||
"go.dtapp.net/goredis"
|
||||
"go.dtapp.net/gorequest"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
// App 微信公众号服务
|
||||
type App struct {
|
||||
componentAccessToken string // 第三方平台 access_token
|
||||
componentVerifyTicket string // 微信后台推送的 ticket
|
||||
preAuthCode string // 预授权码
|
||||
authorizerAccessToken string // 接口调用令牌
|
||||
authorizerRefreshToken string // 刷新令牌
|
||||
authorizerAppid string // 授权方 appid
|
||||
componentAppId string // 第三方平台 appid
|
||||
componentAppSecret string // 第三方平台 app_secret
|
||||
messageToken string
|
||||
messageKey string
|
||||
redis *goredis.Client // 缓存数据库
|
||||
pgsql *gorm.DB // pgsql数据库
|
||||
client *gorequest.App // 请求客户端
|
||||
log *golog.Api // 日志服务
|
||||
logTableName string // 日志表名
|
||||
logStatus bool // 日志状态
|
||||
}
|
||||
|
||||
// NewApp 实例化
|
||||
func NewApp(componentAppId string, componentAppSecret string, messageToken string, messageKey string, redis *goredis.Client, pgsql *gorm.DB) *App {
|
||||
app := &App{componentAppId: componentAppId, componentAppSecret: componentAppSecret, messageToken: messageToken, messageKey: messageKey, redis: redis}
|
||||
app.client = gorequest.NewHttp()
|
||||
if pgsql != nil {
|
||||
app.pgsql = pgsql
|
||||
app.logStatus = true
|
||||
app.logTableName = "wechatopen"
|
||||
app.log = golog.NewApi(&golog.ApiConfig{
|
||||
Db: pgsql,
|
||||
TableName: app.logTableName,
|
||||
})
|
||||
}
|
||||
return app
|
||||
}
|
||||
|
||||
// Config 配置
|
||||
func (app *App) Config(componentAppId, componentAppSecret string) *App {
|
||||
app.componentAppId = componentAppId
|
||||
app.componentAppSecret = componentAppSecret
|
||||
return app
|
||||
}
|
||||
|
||||
// ConfigAuthorizer 配置第三方
|
||||
func (app *App) ConfigAuthorizer(authorizerAppid string) *App {
|
||||
app.authorizerAppid = authorizerAppid
|
||||
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)
|
||||
|
||||
// 设置格式
|
||||
client.SetContentTypeJson()
|
||||
|
||||
// 设置参数
|
||||
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
|
||||
}
|
@ -0,0 +1,70 @@
|
||||
package wechatopen
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"go.dtapp.net/gorequest"
|
||||
"go.dtapp.net/gostorage"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
type CgiBinMaterialGetMaterialResponse struct {
|
||||
Errcode int `json:"errcode"`
|
||||
Errmsg string `json:"errmsg"`
|
||||
}
|
||||
|
||||
type CgiBinMaterialGetMaterialResult struct {
|
||||
Result CgiBinMaterialGetMaterialResponse // 结果
|
||||
Body []byte // 内容
|
||||
Http gorequest.Response // 请求
|
||||
}
|
||||
|
||||
func newCgiBinMaterialGetMaterialResult(result CgiBinMaterialGetMaterialResponse, body []byte, http gorequest.Response) *CgiBinMaterialGetMaterialResult {
|
||||
return &CgiBinMaterialGetMaterialResult{Result: result, Body: body, Http: http}
|
||||
}
|
||||
|
||||
// CgiBinMaterialGetMaterial 获取永久素材
|
||||
// https://developers.weixin.qq.com/doc/offiaccount/Asset_Management/Getting_Permanent_Assets.html
|
||||
func (c *Client) CgiBinMaterialGetMaterial(ctx context.Context, mediaId string) (*CgiBinMaterialGetMaterialResult, error) {
|
||||
// 检查
|
||||
err := c.checkComponentIsConfig()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = c.checkAuthorizerIsConfig()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// 参数
|
||||
params := gorequest.NewParams()
|
||||
params["media_id"] = mediaId // 要获取的素材的media_id
|
||||
// 请求
|
||||
request, err := c.request(ctx, fmt.Sprintf(apiUrl+"/cgi-bin/material/get_material?access_token=%s", c.GetAuthorizerAccessToken(ctx)), params, http.MethodPost)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// 定义
|
||||
var response CgiBinMaterialGetMaterialResponse
|
||||
// 判断内容是否为图片
|
||||
err = json.Unmarshal(request.ResponseBody, &response)
|
||||
if err != nil {
|
||||
// 可能是图片
|
||||
return newCgiBinMaterialGetMaterialResult(CgiBinMaterialGetMaterialResponse{}, request.ResponseBody, request), nil
|
||||
}
|
||||
return newCgiBinMaterialGetMaterialResult(response, request.ResponseBody, request), err
|
||||
}
|
||||
|
||||
func (cr *CgiBinMaterialGetMaterialResult) SaveImg(db *gostorage.AliYun, fileName, filePath string) error {
|
||||
if cr.Result.Errcode != 0 {
|
||||
return errors.New(cr.Result.Errmsg)
|
||||
}
|
||||
// 上传
|
||||
_, err := db.PutObject(bytes.NewReader(cr.Body), filePath, fileName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
package wechatopen
|
||||
|
||||
func (c *Client) checkComponentIsConfig() error {
|
||||
componentAppId := c.GetComponentAppId()
|
||||
if componentAppId == "" {
|
||||
return componentAppIdNoConfig
|
||||
}
|
||||
componentAppSecret := c.GetComponentAppSecret()
|
||||
if componentAppSecret == "" {
|
||||
return componentAppSecretNoConfig
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Client) checkAuthorizerIsConfig() error {
|
||||
authorizerAppid := c.GetAuthorizerAppid()
|
||||
if authorizerAppid == "" {
|
||||
return authorizerAppidNoConfig
|
||||
}
|
||||
return nil
|
||||
}
|
@ -0,0 +1,75 @@
|
||||
package wechatopen
|
||||
|
||||
import (
|
||||
"go.dtapp.net/dorm"
|
||||
"go.dtapp.net/golog"
|
||||
"go.dtapp.net/gorequest"
|
||||
)
|
||||
|
||||
// 缓存前缀
|
||||
// wechat_open:component_verify_ticket:
|
||||
// wechat_open:component_access_token:
|
||||
// wechat_open:authorizer_access_token:
|
||||
// wechat_open:pre_auth_code:
|
||||
type redisCachePrefixFun func() (componentVerifyTicket, componentAccessToken, authorizerAccessToken, preAuthCode string)
|
||||
|
||||
// ClientConfig 实例配置
|
||||
type ClientConfig struct {
|
||||
AuthorizerAppid string // 授权方 appid
|
||||
ComponentAppId string // 第三方平台 appid
|
||||
ComponentAppSecret string // 第三方平台 app_secret
|
||||
MessageToken string
|
||||
MessageKey string
|
||||
RedisClient *dorm.RedisClient // 缓存数据库
|
||||
RedisCachePrefixFun redisCachePrefixFun // 缓存前缀
|
||||
}
|
||||
|
||||
// Client 实例
|
||||
type Client struct {
|
||||
requestClient *gorequest.App // 请求服务
|
||||
config struct {
|
||||
componentAccessToken string // 第三方平台 access_token
|
||||
componentVerifyTicket string // 微信后台推送的 ticket
|
||||
preAuthCode string // 预授权码
|
||||
authorizerAccessToken string // 接口调用令牌
|
||||
authorizerRefreshToken string // 刷新令牌
|
||||
authorizerAppid string // 授权方 appid
|
||||
componentAppId string // 第三方平台appid
|
||||
componentAppSecret string // 第三方平台app_secret
|
||||
messageToken string
|
||||
messageKey string
|
||||
}
|
||||
cache struct {
|
||||
redisClient *dorm.RedisClient // 缓存数据库
|
||||
componentVerifyTicketPrefix string
|
||||
componentAccessTokenPrefix string
|
||||
authorizerAccessTokenPrefix string
|
||||
preAuthCodePrefix string
|
||||
}
|
||||
log struct {
|
||||
status bool // 状态
|
||||
client *golog.ApiClient // 日志服务
|
||||
}
|
||||
}
|
||||
|
||||
// NewClient 创建实例化
|
||||
func NewClient(config *ClientConfig) (*Client, error) {
|
||||
|
||||
c := &Client{}
|
||||
|
||||
c.config.componentAppId = config.ComponentAppId
|
||||
c.config.componentAppSecret = config.ComponentAppSecret
|
||||
c.config.messageToken = config.MessageToken
|
||||
c.config.messageKey = config.MessageKey
|
||||
|
||||
c.requestClient = gorequest.NewHttp()
|
||||
|
||||
c.cache.redisClient = config.RedisClient
|
||||
|
||||
c.cache.componentVerifyTicketPrefix, c.cache.componentAccessTokenPrefix, c.cache.authorizerAccessTokenPrefix, c.cache.preAuthCodePrefix = config.RedisCachePrefixFun()
|
||||
if c.cache.componentVerifyTicketPrefix == "" || c.cache.componentAccessTokenPrefix == "" || c.cache.authorizerAccessTokenPrefix == "" || c.cache.preAuthCodePrefix == "" {
|
||||
return nil, redisCachePrefixNoConfig
|
||||
}
|
||||
|
||||
return c, nil
|
||||
}
|
@ -0,0 +1,25 @@
|
||||
package wechatopen
|
||||
|
||||
import "go.dtapp.net/golog"
|
||||
|
||||
// ConfigComponent 配置
|
||||
func (c *Client) ConfigComponent(componentAppId, componentAppSecret string) *Client {
|
||||
c.config.componentAppId = componentAppId
|
||||
c.config.componentAppSecret = componentAppSecret
|
||||
return c
|
||||
}
|
||||
|
||||
// ConfigAuthorizer 配置第三方
|
||||
func (c *Client) ConfigAuthorizer(authorizerAppid string) *Client {
|
||||
c.config.authorizerAppid = authorizerAppid
|
||||
return c
|
||||
}
|
||||
|
||||
// ConfigApiClientFun 日志配置
|
||||
func (c *Client) ConfigApiClientFun(apiClientFun golog.ApiClientFun) {
|
||||
apiClient := apiClientFun()
|
||||
if apiClient != nil {
|
||||
c.log.client = apiClient
|
||||
c.log.status = true
|
||||
}
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
package wechatopen
|
||||
|
||||
const (
|
||||
apiUrl = "https://api.weixin.qq.com"
|
||||
)
|
||||
|
||||
const (
|
||||
LogTable = "wechatopen"
|
||||
Version = "1.0.44"
|
||||
)
|
@ -0,0 +1,16 @@
|
||||
package wechatopen
|
||||
|
||||
import "errors"
|
||||
|
||||
var (
|
||||
redisCachePrefixNoConfig = errors.New("请配置 RedisCachePrefix")
|
||||
)
|
||||
|
||||
var (
|
||||
componentAppIdNoConfig = errors.New("请配置 ComponentAppId")
|
||||
componentAppSecretNoConfig = errors.New("请配置 ComponentAppSecret")
|
||||
)
|
||||
|
||||
var (
|
||||
authorizerAppidNoConfig = errors.New("请配置 AuthorizerAppid 或 ConfigAuthorizer")
|
||||
)
|
@ -1,5 +1,47 @@
|
||||
package wechatopen
|
||||
|
||||
func (app *App) GetComponentAppId() string {
|
||||
return app.componentAppId
|
||||
import "go.dtapp.net/golog"
|
||||
|
||||
//func (c *Client) GetComponentAccessToken() string {
|
||||
// return c.config.componentAccessToken
|
||||
//}
|
||||
|
||||
//func (c *Client) GetComponentVerifyTicket() string {
|
||||
// return c.config.componentVerifyTicket
|
||||
//}
|
||||
|
||||
//func (c *Client) GetPreAuthCode() string {
|
||||
// return c.config.preAuthCode
|
||||
//}
|
||||
|
||||
//func (c *Client) GetAuthorizerAccessToken() string {
|
||||
// return c.config.authorizerAccessToken
|
||||
//}
|
||||
|
||||
func (c *Client) GetAuthorizerRefreshToken() string {
|
||||
return c.config.authorizerRefreshToken
|
||||
}
|
||||
|
||||
func (c *Client) GetAuthorizerAppid() string {
|
||||
return c.config.authorizerAppid
|
||||
}
|
||||
|
||||
func (c *Client) GetComponentAppId() string {
|
||||
return c.config.componentAppId
|
||||
}
|
||||
|
||||
func (c *Client) GetComponentAppSecret() string {
|
||||
return c.config.componentAppSecret
|
||||
}
|
||||
|
||||
func (c *Client) GetMessageToken() string {
|
||||
return c.config.messageToken
|
||||
}
|
||||
|
||||
func (c *Client) GetMessageKey() string {
|
||||
return c.config.messageKey
|
||||
}
|
||||
|
||||
func (c *Client) GetLog() *golog.ApiClient {
|
||||
return c.log.client
|
||||
}
|
||||
|
@ -1,35 +1,129 @@
|
||||
module go.dtapp.net/wechatopen
|
||||
|
||||
go 1.18
|
||||
go 1.19
|
||||
|
||||
require (
|
||||
github.com/gin-gonic/gin v1.8.1
|
||||
github.com/mitchellh/mapstructure v1.5.0
|
||||
go.dtapp.net/gojson v1.0.0
|
||||
go.dtapp.net/golog v1.0.13
|
||||
go.dtapp.net/goredis v1.0.1
|
||||
go.dtapp.net/gorequest v1.0.19
|
||||
gorm.io/datatypes v1.0.6
|
||||
gorm.io/gorm v1.23.6
|
||||
go.dtapp.net/dorm v1.0.54
|
||||
go.dtapp.net/golog v1.0.102
|
||||
go.dtapp.net/gorequest v1.0.38
|
||||
go.dtapp.net/gostorage v1.0.13
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/cespare/xxhash/v2 v2.1.2 // indirect
|
||||
github.com/aliyun/aliyun-oss-go-sdk v2.2.6+incompatible // indirect
|
||||
github.com/aws/aws-sdk-go v1.44.153 // indirect
|
||||
github.com/aws/aws-sdk-go-v2 v1.17.2 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.10 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/config v1.18.4 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/credentials v1.13.4 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.12.20 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.26 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.20 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/ini v1.3.27 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/v4a v1.0.17 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.9.11 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.1.21 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.20 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.13.20 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/s3 v1.29.5 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/sso v1.11.26 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.13.9 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/sts v1.17.6 // indirect
|
||||
github.com/aws/smithy-go v1.13.5 // indirect
|
||||
github.com/baidubce/bce-sdk-go v0.9.138 // indirect
|
||||
github.com/basgys/goxml2json v1.1.0 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.2.0 // indirect
|
||||
github.com/clbanning/mxj v1.8.4 // indirect
|
||||
github.com/deckarep/golang-set v1.8.0 // 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/gin-contrib/sse v0.1.0 // indirect
|
||||
github.com/go-ole/go-ole v1.2.6 // indirect
|
||||
github.com/go-playground/locales v0.14.0 // indirect
|
||||
github.com/go-playground/universal-translator v0.18.0 // indirect
|
||||
github.com/go-playground/validator/v10 v10.11.1 // indirect
|
||||
github.com/go-redis/redis/v9 v9.0.0-rc.2 // indirect
|
||||
github.com/go-sql-driver/mysql v1.7.0 // indirect
|
||||
github.com/goccy/go-json v0.10.0 // indirect
|
||||
github.com/golang/snappy v0.0.4 // indirect
|
||||
github.com/google/go-querystring v1.1.0 // indirect
|
||||
github.com/huaweicloud/huaweicloud-sdk-go-obs v3.22.11+incompatible // indirect
|
||||
github.com/jackc/chunkreader/v2 v2.0.1 // indirect
|
||||
github.com/jackc/pgconn v1.13.0 // indirect
|
||||
github.com/jackc/pgio v1.0.0 // indirect
|
||||
github.com/jackc/pgpassfile v1.0.0 // indirect
|
||||
github.com/jackc/pgproto3/v2 v2.3.1 // indirect
|
||||
github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b // indirect
|
||||
github.com/jackc/pgtype v1.13.0 // indirect
|
||||
github.com/jackc/pgx/v4 v4.17.2 // indirect
|
||||
github.com/jinzhu/inflection v1.0.0 // indirect
|
||||
github.com/jinzhu/now v1.1.5 // indirect
|
||||
github.com/jmespath/go-jmespath v0.4.0 // indirect
|
||||
github.com/json-iterator/go v1.1.12 // indirect
|
||||
github.com/klauspost/compress v1.15.12 // indirect
|
||||
github.com/ks3sdklib/aws-sdk-go v1.1.8 // indirect
|
||||
github.com/leodido/go-urn v1.2.1 // indirect
|
||||
github.com/lib/pq v1.10.7 // indirect
|
||||
github.com/mattn/go-isatty v0.0.16 // indirect
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||
github.com/montanaflynn/stats v0.6.6 // indirect
|
||||
github.com/mozillazg/go-httpheader v0.3.1 // indirect
|
||||
github.com/natefinch/lumberjack v2.0.0+incompatible // indirect
|
||||
github.com/oschwald/geoip2-golang v1.8.0 // indirect
|
||||
github.com/oschwald/maxminddb-golang v1.10.0 // indirect
|
||||
github.com/pelletier/go-toml/v2 v2.0.6 // indirect
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
github.com/qiniu/go-sdk/v7 v7.14.0 // indirect
|
||||
github.com/saracen/go7z v0.0.0-20191010121135-9c09b6bd7fda // indirect
|
||||
github.com/saracen/solidblock v0.0.0-20190426153529-45df20abab6f // indirect
|
||||
github.com/segmentio/fasthash v1.0.3 // indirect
|
||||
github.com/shirou/gopsutil v3.21.11+incompatible // indirect
|
||||
github.com/sirupsen/logrus v1.9.0 // indirect
|
||||
github.com/syndtr/goleveldb v1.0.0 // indirect
|
||||
github.com/tencentyun/cos-go-sdk-v5 v0.7.40 // indirect
|
||||
github.com/tklauser/go-sysconf v0.3.11 // indirect
|
||||
github.com/tklauser/numcpus v0.6.0 // indirect
|
||||
github.com/tmthrgd/go-hex v0.0.0-20190904060850-447a3041c3bc // indirect
|
||||
github.com/ugorji/go/codec v1.2.7 // indirect
|
||||
github.com/ulikunitz/xz v0.5.10 // indirect
|
||||
go.dtapp.net/goip v1.0.17 // indirect
|
||||
go.dtapp.net/gostring v1.0.3 // indirect
|
||||
go.dtapp.net/gotime v1.0.2 // indirect
|
||||
golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e // indirect
|
||||
golang.org/x/net v0.0.0-20220607020251-c690dde0001d // indirect
|
||||
golang.org/x/sys v0.0.0-20220610221304-9f5ed59c137d // indirect
|
||||
golang.org/x/text v0.3.7 // indirect
|
||||
golang.org/x/tools v0.1.5 // indirect
|
||||
gorm.io/driver/mysql v1.3.4 // indirect
|
||||
gorm.io/driver/postgres v1.3.7 // indirect
|
||||
github.com/upper/db/v4 v4.6.0 // indirect
|
||||
github.com/uptrace/bun v1.1.9 // indirect
|
||||
github.com/uptrace/bun/dialect/mysqldialect v1.1.9 // indirect
|
||||
github.com/uptrace/bun/dialect/pgdialect v1.1.9 // indirect
|
||||
github.com/uptrace/bun/driver/pgdriver v1.1.9 // indirect
|
||||
github.com/upyun/go-sdk/v3 v3.0.3 // indirect
|
||||
github.com/vmihailenco/msgpack/v5 v5.3.5 // indirect
|
||||
github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect
|
||||
github.com/xdg-go/pbkdf2 v1.0.0 // indirect
|
||||
github.com/xdg-go/scram v1.1.1 // indirect
|
||||
github.com/xdg-go/stringprep v1.0.3 // indirect
|
||||
github.com/youmark/pkcs8 v0.0.0-20201027041543-1326539a0a0a // indirect
|
||||
github.com/yusufpapurcu/wmi v1.2.2 // indirect
|
||||
go.dtapp.net/goip v1.0.40 // indirect
|
||||
go.dtapp.net/gorandom v1.0.1 // indirect
|
||||
go.dtapp.net/gostring v1.0.10 // indirect
|
||||
go.dtapp.net/gotime v1.0.5 // indirect
|
||||
go.dtapp.net/gotrace_id v1.0.6 // indirect
|
||||
go.dtapp.net/gourl v1.0.0 // indirect
|
||||
go.mongodb.org/mongo-driver v1.11.0 // indirect
|
||||
go.uber.org/atomic v1.10.0 // indirect
|
||||
go.uber.org/multierr v1.8.0 // indirect
|
||||
go.uber.org/zap v1.24.0 // indirect
|
||||
golang.org/x/crypto v0.3.0 // indirect
|
||||
golang.org/x/mod v0.7.0 // indirect
|
||||
golang.org/x/net v0.3.0 // indirect
|
||||
golang.org/x/sync v0.1.0 // indirect
|
||||
golang.org/x/sys v0.3.0 // indirect
|
||||
golang.org/x/text v0.5.0 // indirect
|
||||
golang.org/x/time v0.3.0 // indirect
|
||||
google.golang.org/protobuf v1.28.1 // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
gorm.io/driver/mysql v1.4.4 // indirect
|
||||
gorm.io/driver/postgres v1.4.5 // indirect
|
||||
gorm.io/gorm v1.24.2 // indirect
|
||||
mellium.im/sasl v0.3.0 // indirect
|
||||
xorm.io/builder v0.3.12 // indirect
|
||||
xorm.io/xorm v1.3.2 // indirect
|
||||
)
|
||||
|
@ -1,27 +0,0 @@
|
||||
package wechatopen
|
||||
|
||||
// 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
|
||||
}
|
||||
}
|
@ -1,26 +0,0 @@
|
||||
package wechatopen
|
||||
|
||||
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}, //【返回】时间
|
||||
})
|
||||
}
|
@ -0,0 +1,40 @@
|
||||
package wechatopen
|
||||
|
||||
import (
|
||||
"context"
|
||||
"go.dtapp.net/gorequest"
|
||||
)
|
||||
|
||||
func (c *Client) request(ctx context.Context, url string, params map[string]interface{}, method string) (resp gorequest.Response, err error) {
|
||||
|
||||
// 创建请求
|
||||
client := c.requestClient
|
||||
|
||||
// 设置请求地址
|
||||
client.SetUri(url)
|
||||
|
||||
// 设置方式
|
||||
client.SetMethod(method)
|
||||
|
||||
// 设置格式
|
||||
client.SetContentTypeJson()
|
||||
|
||||
// 设置用户代理
|
||||
client.SetUserAgent(gorequest.GetRandomUserAgentSystem())
|
||||
|
||||
// 设置参数
|
||||
client.SetParams(params)
|
||||
|
||||
// 发起请求
|
||||
request, err := client.Request(ctx)
|
||||
if err != nil {
|
||||
return gorequest.Response{}, err
|
||||
}
|
||||
|
||||
// 记录日志
|
||||
if c.log.status {
|
||||
go c.log.client.Middleware(ctx, request, Version)
|
||||
}
|
||||
|
||||
return request, err
|
||||
}
|
@ -0,0 +1,41 @@
|
||||
package wechatopen
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
// ResponseServeHttpGin 推送信息
|
||||
type ResponseServeHttpGin struct {
|
||||
MsgSignature string // 签名串,对应 URL 参数的msg_signature
|
||||
Timestamp string // 时间戳,对应 URL 参数的timestamp
|
||||
Nonce string // 随机串,对应 URL 参数的nonce
|
||||
Signature string
|
||||
EncryptType string // 加密类型
|
||||
AppId string // 第三方平台 appid
|
||||
Encrypt string // 加密内容
|
||||
}
|
||||
|
||||
// ServeHttpGin 验证票据推送
|
||||
func (c *Client) ServeHttpGin(ctx context.Context, ginCtx *gin.Context) (ResponseServeHttpGin, error) {
|
||||
|
||||
query := ginCtx.Request.URL.Query()
|
||||
|
||||
// 声明接收的变量
|
||||
var validateJson struct {
|
||||
AppId string `form:"AppId" json:"AppId" xml:"AppId" uri:"AppId" binding:"omitempty"` // 第三方平台 appid
|
||||
Encrypt string `form:"Encrypt" json:"Encrypt" xml:"Encrypt" uri:"Encrypt" binding:"omitempty"` // 加密内容
|
||||
}
|
||||
|
||||
err := ginCtx.ShouldBind(&validateJson)
|
||||
|
||||
return ResponseServeHttpGin{
|
||||
MsgSignature: query.Get("msg_signature"),
|
||||
Timestamp: query.Get("timestamp"),
|
||||
Nonce: query.Get("nonce"),
|
||||
Signature: query.Get("signature"),
|
||||
EncryptType: query.Get("encrypt_type"),
|
||||
AppId: validateJson.AppId,
|
||||
Encrypt: validateJson.Encrypt,
|
||||
}, err
|
||||
}
|
@ -1,7 +0,0 @@
|
||||
package wechatopen
|
||||
|
||||
// SetAuthorizerAppid 设置代理商小程序
|
||||
func (app *App) SetAuthorizerAppid(authorizerAppid string) {
|
||||
app.authorizerAppid = authorizerAppid
|
||||
return
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
package wechatopen
|
||||
|
||||
// SignDecryptParams 入参
|
||||
type SignDecryptParams struct {
|
||||
Signature string // 签名串,对应 URL 参数的msg_signature
|
||||
Timestamp string // 时间戳,对应 URL 参数的timestamp
|
||||
Nonce string // 随机串,对应 URL 参数的nonce
|
||||
EncryptType string // 加密类型
|
||||
MsgSignature string
|
||||
AppId string // 第三方平台 appid
|
||||
Encrypt string // 加密内容
|
||||
}
|
@ -0,0 +1,67 @@
|
||||
package wechatopen
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"go.dtapp.net/gorequest"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
type TckWxPayListResponse struct {
|
||||
Errcode int `json:"errcode"`
|
||||
Errmsg string `json:"errmsg"`
|
||||
List []struct {
|
||||
MerchantCode string `json:"merchant_code"`
|
||||
MerchantName string `json:"merchant_name"`
|
||||
CompanyName string `json:"company_name"`
|
||||
MchRelationState string `json:"mch_relation_state"`
|
||||
JsapiAuthState string `json:"jsapi_auth_state"`
|
||||
RefundAuthState string `json:"refund_auth_state"`
|
||||
} `json:"list"`
|
||||
}
|
||||
|
||||
type TckWxPayListResult struct {
|
||||
Result TckWxPayListResponse // 结果
|
||||
Body []byte // 内容
|
||||
Http gorequest.Response // 请求
|
||||
}
|
||||
|
||||
func newTckWxPayListResult(result TckWxPayListResponse, body []byte, http gorequest.Response) *TckWxPayListResult {
|
||||
return &TckWxPayListResult{Result: result, Body: body, Http: http}
|
||||
}
|
||||
|
||||
// TckWxPayList 获取授权绑定的商户号列表
|
||||
// https://developers.weixin.qq.com/doc/oplatform/openApi/OpenApiDoc/cloudbase-common/wechatpay/getWechatPayList.html
|
||||
func (c *Client) TckWxPayList(ctx context.Context) (*TckWxPayListResult, error) {
|
||||
// 检查
|
||||
err := c.checkComponentIsConfig()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// 参数
|
||||
// 参数
|
||||
params := gorequest.NewParams()
|
||||
// 请求
|
||||
request, err := c.request(ctx, apiUrl+"/tcb/wxpaylist?access_token="+c.GetComponentAccessToken(ctx), params, http.MethodPost)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// 定义
|
||||
var response TckWxPayListResponse
|
||||
err = json.Unmarshal(request.ResponseBody, &response)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return newTckWxPayListResult(response, request.ResponseBody, request), nil
|
||||
}
|
||||
|
||||
// ErrcodeInfo 错误描述
|
||||
func (resp *TckWxPayListResult) ErrcodeInfo() string {
|
||||
switch resp.Result.Errcode {
|
||||
case 85064:
|
||||
return "找不到草稿"
|
||||
case 85065:
|
||||
return "模板库已满"
|
||||
}
|
||||
return "系统繁忙"
|
||||
}
|
@ -1,3 +0,0 @@
|
||||
package wechatopen
|
||||
|
||||
const Version = "1.0.0"
|
@ -0,0 +1 @@
|
||||
package wechatopen
|
@ -0,0 +1 @@
|
||||
package wechatopen
|
@ -0,0 +1 @@
|
||||
package wechatopen
|
@ -0,0 +1,61 @@
|
||||
package wechatopen
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"go.dtapp.net/gorequest"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
type WxaSecurityApplySetOrderPathInfoResponse struct {
|
||||
Errcode int `json:"errcode"` // 返回码
|
||||
Errmsg string `json:"errmsg"` // 返回码信息
|
||||
}
|
||||
|
||||
type WxaSecurityApplySetOrderPathInfoResult struct {
|
||||
Result WxaSecurityApplySetOrderPathInfoResponse // 结果
|
||||
Body []byte // 内容
|
||||
Http gorequest.Response // 请求
|
||||
}
|
||||
|
||||
func newWxaSecurityApplySetOrderPathInfoResult(result WxaSecurityApplySetOrderPathInfoResponse, body []byte, http gorequest.Response) *WxaSecurityApplySetOrderPathInfoResult {
|
||||
return &WxaSecurityApplySetOrderPathInfoResult{Result: result, Body: body, Http: http}
|
||||
}
|
||||
|
||||
// WxaSecurityApplySetOrderPathInfo 申请设置订单页 path 信息
|
||||
// https://developers.weixin.qq.com/doc/oplatform/openApi/OpenApiDoc/miniprogram-management/basic-info-management/applySetOrderPathInfo.html
|
||||
func (c *Client) WxaSecurityApplySetOrderPathInfo(ctx context.Context, notMustParams ...gorequest.Params) (*WxaSecurityApplySetOrderPathInfoResult, error) {
|
||||
// 检查
|
||||
err := c.checkComponentIsConfig()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// 参数
|
||||
params := gorequest.NewParamsWith(notMustParams...)
|
||||
// 请求
|
||||
request, err := c.request(ctx, fmt.Sprintf(apiUrl+"/wxa/security/applysetorderpathinfo?access_token=%s", c.GetAuthorizerAccessToken(ctx)), params, http.MethodPost)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// 定义
|
||||
var response WxaSecurityApplySetOrderPathInfoResponse
|
||||
err = json.Unmarshal(request.ResponseBody, &response)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return newWxaSecurityApplySetOrderPathInfoResult(response, request.ResponseBody, request), nil
|
||||
}
|
||||
|
||||
// ErrcodeInfo 错误描述
|
||||
func (resp *WxaSecurityApplySetOrderPathInfoResult) ErrcodeInfo() string {
|
||||
switch resp.Result.Errcode {
|
||||
case 61042:
|
||||
return "批量提交超过最大数量,一次提交的 appid 数量不超过100个"
|
||||
case 61043:
|
||||
return "参数填写错误"
|
||||
case 61044:
|
||||
return "path填写不规范"
|
||||
}
|
||||
return "系统繁忙"
|
||||
}
|
@ -0,0 +1,68 @@
|
||||
package wechatopen
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"go.dtapp.net/gorequest"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
type WxaSecurityGetOrderPathInfoResponse struct {
|
||||
Errcode int `json:"errcode"` // 返回码
|
||||
Errmsg string `json:"errmsg"` // 返回码信息
|
||||
msg struct {
|
||||
Path string `json:"path"`
|
||||
ImgList []string `json:"img_list"`
|
||||
Video string `json:"video"`
|
||||
TestAccount string `json:"test_account"`
|
||||
TestPwd string `json:"test_pwd"`
|
||||
TestRemark string `json:"test_remark"`
|
||||
Status int `json:"status"`
|
||||
ApplyTime int64 `json:"apply_time"`
|
||||
} `json:"msg"`
|
||||
}
|
||||
|
||||
type WxaSecurityGetOrderPathInfoResult struct {
|
||||
Result WxaSecurityGetOrderPathInfoResponse // 结果
|
||||
Body []byte // 内容
|
||||
Http gorequest.Response // 请求
|
||||
}
|
||||
|
||||
func newWxaSecurityGetOrderPathInfoResult(result WxaSecurityGetOrderPathInfoResponse, body []byte, http gorequest.Response) *WxaSecurityGetOrderPathInfoResult {
|
||||
return &WxaSecurityGetOrderPathInfoResult{Result: result, Body: body, Http: http}
|
||||
}
|
||||
|
||||
// WxaSecurityGetOrderPathInfo 获取订单页 path 信息
|
||||
// https://developers.weixin.qq.com/doc/oplatform/openApi/OpenApiDoc/miniprogram-management/basic-info-management/getOrderPathInfo.html
|
||||
func (c *Client) WxaSecurityGetOrderPathInfo(ctx context.Context, infoType int) (*WxaSecurityGetOrderPathInfoResult, error) {
|
||||
// 检查
|
||||
err := c.checkComponentIsConfig()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// 参数
|
||||
params := gorequest.NewParams()
|
||||
params.Set("info_type", infoType)
|
||||
// 请求
|
||||
request, err := c.request(ctx, fmt.Sprintf(apiUrl+"/wxa/security/getorderpathinfo?access_token=%s", c.GetAuthorizerAccessToken(ctx)), params, http.MethodPost)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// 定义
|
||||
var response WxaSecurityGetOrderPathInfoResponse
|
||||
err = json.Unmarshal(request.ResponseBody, &response)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return newWxaSecurityGetOrderPathInfoResult(response, request.ResponseBody, request), nil
|
||||
}
|
||||
|
||||
// ErrcodeInfo 错误描述
|
||||
func (resp *WxaSecurityGetOrderPathInfoResult) ErrcodeInfo() string {
|
||||
switch resp.Result.Errcode {
|
||||
case 61041:
|
||||
return "订单页 path 未设置"
|
||||
}
|
||||
return "系统繁忙"
|
||||
}
|
@ -0,0 +1 @@
|
||||
package wechatopen
|
@ -0,0 +1 @@
|
||||
package wechatopen
|
Loading…
Reference in new issue