Procházet zdrojové kódy

change package and add some apis

张延森 před 3 roky
rodič
revize
e11b8e4707

authorization/authorizer_info.go → api/authorization/authorizer_info.go Zobrazit soubor

@@ -17,16 +17,11 @@ import (
17 17
 	"errors"
18 18
 	"net/url"
19 19
 
20
+	"gitee.com/yansen_zh/wxcomponent/config"
20 21
 	wxerr "gitee.com/yansen_zh/wxcomponent/errors"
21 22
 	"gitee.com/yansen_zh/wxcomponent/utils/request"
22 23
 )
23 24
 
24
-// AuthorizerInfoParam 获取授权帐号信息参数
25
-type AuthorizerInfoParam struct {
26
-	ComponentAppId  string `json:"component_appid"`
27
-	AuthorizerAppId string `json:"authorizer_appid"`
28
-}
29
-
30 25
 // AuthorizerInfoResult 获取授权帐号信息结果
31 26
 type AuthorizerInfoResult struct {
32 27
 	wxerr.Error
@@ -39,21 +34,18 @@ const (
39 34
 )
40 35
 
41 36
 // GetAuthorizerInfo 获取授权帐号信息
42
-func GetAuthorizerInfo(componentAccessToken string, data AuthorizerInfoParam) (*AuthorizerInfoResult, error) {
43
-	if componentAccessToken == "" {
44
-		return nil, errors.New("获取授权帐号信息 第三方平台的 component_access_token 不能为空")
45
-	}
46
-
47
-	if data.ComponentAppId == "" {
48
-		return nil, errors.New("获取授权帐号信息 第三方平台的 appid 不能为空")
49
-	}
50
-
51
-	if data.AuthorizerAppId == "" {
37
+func GetAuthorizerInfo(authorizerAppID string) (*AuthorizerInfoResult, error) {
38
+	if authorizerAppID == "" {
52 39
 		return nil, errors.New("获取授权帐号信息 授权方 appid 不能为空")
53 40
 	}
54 41
 
55 42
 	queryParam := url.Values{}
56
-	queryParam.Set("component_access_token", componentAccessToken)
43
+	queryParam.Set("component_access_token", config.GetAccessToken())
44
+
45
+	data := map[string]string{
46
+		"component_appid":  config.GetAppID(),
47
+		"authorizer_appid": authorizerAppID,
48
+	}
57 49
 
58 50
 	resp, e2 := request.PostJSON(apiGetAuthorizerInfo, &queryParam, data)
59 51
 	if e2 != nil {

authorization/authorizer_token.go → api/authorization/authorizer_token.go Zobrazit soubor

@@ -17,17 +17,11 @@ import (
17 17
 	"errors"
18 18
 	"net/url"
19 19
 
20
+	"gitee.com/yansen_zh/wxcomponent/config"
20 21
 	wxerr "gitee.com/yansen_zh/wxcomponent/errors"
21 22
 	"gitee.com/yansen_zh/wxcomponent/utils/request"
22 23
 )
23 24
 
24
-// AuthorizerTokenParam 获取/刷新接口调用令牌参数
25
-type AuthorizerTokenParam struct {
26
-	ComponentAppId         string `json:"component_appid"`
27
-	AuthorizerAppId        string `json:"authorizer_appid"`
28
-	AuthorizerRefreshToken string `json:"authorizer_refresh_token"`
29
-}
30
-
31 25
 // AuthorizerTokenResult 获取/刷新接口调用令牌结果
32 26
 type AuthorizerTokenResult struct {
33 27
 	wxerr.Error
@@ -41,25 +35,23 @@ const (
41 35
 )
42 36
 
43 37
 // RefreshAuthorizerToken 获取/刷新接口调用令牌
44
-func RefreshAuthorizerToken(componentAccessToken string, data AuthorizerTokenParam) (*AuthorizerTokenResult, error) {
45
-	if componentAccessToken == "" {
46
-		return nil, errors.New("获取/刷新接口调用令牌 第三方平台的 component_access_token 不能为空")
47
-	}
48
-
49
-	if data.ComponentAppId == "" {
50
-		return nil, errors.New("获取/刷新接口调用令牌 第三方平台的 appid 不能为空")
51
-	}
52
-
53
-	if data.AuthorizerAppId == "" {
38
+func RefreshAuthorizerToken(authorizerAppID, authorizerRefreshToken string) (*AuthorizerTokenResult, error) {
39
+	if authorizerAppID == "" {
54 40
 		return nil, errors.New("获取/刷新接口调用令牌 授权方 appid 不能为空")
55 41
 	}
56 42
 
57
-	if data.AuthorizerRefreshToken == "" {
43
+	if authorizerRefreshToken == "" {
58 44
 		return nil, errors.New("获取/刷新接口调用令牌 刷新令牌 不能为空")
59 45
 	}
60 46
 
61 47
 	queryParam := url.Values{}
62
-	queryParam.Set("component_access_token", componentAccessToken)
48
+	queryParam.Set("component_access_token", config.GetAccessToken())
49
+
50
+	data := map[string]string{
51
+		"component_appid":          config.GetAppID(),
52
+		"authorizer_appid":         authorizerAppID,
53
+		"authorizer_refresh_token": authorizerRefreshToken,
54
+	}
63 55
 
64 56
 	resp, e2 := request.PostJSON(apiAuthorizerToken, &queryParam, data)
65 57
 	if e2 != nil {

authorization/bind_component.go → api/authorization/bind_component.go Zobrazit soubor

@@ -17,7 +17,7 @@ import (
17 17
 	"net/url"
18 18
 	"strconv"
19 19
 
20
-	"gitee.com/yansen_zh/wxcomponent/utils/request"
20
+	"gitee.com/yansen_zh/wxcomponent/config"
21 21
 )
22 22
 
23 23
 // AuthLinkParam 构建授权链接入参
@@ -37,33 +37,30 @@ const (
37 37
 )
38 38
 
39 39
 // GetPCAuthLink 构建PC端授权链接
40
-func GetPCAuthLink(param AuthLinkParam) (*url.URL, error) {
41
-	return GetAuthLink("PC", param)
40
+func GetPCAuthLink(preAuthCode, redirectURI, bizAppID string, authType int) (string, error) {
41
+	return GetAuthLink("PC", preAuthCode, redirectURI, bizAppID, authType)
42 42
 }
43 43
 
44 44
 // GetH5AuthLink 构建H5端授权链接
45
-func GetH5AuthLink(param AuthLinkParam) (*url.URL, error) {
46
-	return GetAuthLink("H5", param)
45
+func GetH5AuthLink(preAuthCode, redirectURI, bizAppID string, authType int) (string, error) {
46
+	return GetAuthLink("H5", preAuthCode, redirectURI, bizAppID, authType)
47 47
 }
48 48
 
49 49
 // GetAuthLink 构建授权链接
50
-func GetAuthLink(client string, param AuthLinkParam) (*url.URL, error) {
50
+// redirectURI 回调地址必须是未经过处理的原始URL字符串
51
+func GetAuthLink(client, preAuthCode, redirectURI, bizAppID string, authType int) (string, error) {
51 52
 	isH5 := client == "H5"
52 53
 
53
-	if param.ComponentAppId == "" {
54
-		return nil, errors.New("构建授权链接 第三方平台的 appid 不能为空")
54
+	if preAuthCode == "" {
55
+		return "", errors.New("构建授权链接 预授权码 不能为空")
55 56
 	}
56 57
 
57
-	if param.PreAuthCode == "" {
58
-		return nil, errors.New("构建授权链接 预授权码 不能为空")
58
+	if redirectURI == "" {
59
+		return "", errors.New("构建授权链接 回调 URI 不能为空")
59 60
 	}
60 61
 
61
-	if param.RedirectUri == "" {
62
-		return nil, errors.New("构建授权链接 回调 URI 不能为空")
63
-	}
64
-
65
-	if param.AuthType < 1 || param.AuthType > 3 {
66
-		param.AuthType = 3
62
+	if authType < 1 || authType > 3 {
63
+		authType = 3
67 64
 	}
68 65
 
69 66
 	queryParams := url.Values{}
@@ -71,28 +68,26 @@ func GetAuthLink(client string, param AuthLinkParam) (*url.URL, error) {
71 68
 		queryParams.Set("action", "bindcomponent")
72 69
 		queryParams.Set("no_scan", "1")
73 70
 	}
74
-	queryParams.Set("component_appid", param.ComponentAppId)
75
-	queryParams.Set("pre_auth_code", param.PreAuthCode)
76
-	queryParams.Set("redirect_uri", param.RedirectUri)
71
+	queryParams.Set("component_appid", config.GetAppID())
72
+	queryParams.Set("pre_auth_code", preAuthCode)
73
+	queryParams.Set("redirect_uri", redirectURI)
77 74
 	// auth_type、biz_appid 两个字段互斥
78
-	if param.BizAppId != "" {
79
-		queryParams.Set("biz_appid", param.BizAppId)
75
+	if bizAppID != "" {
76
+		queryParams.Set("biz_appid", bizAppID)
80 77
 	} else {
81
-		queryParams.Set("auth_type", strconv.Itoa(param.AuthType))
78
+		queryParams.Set("auth_type", strconv.Itoa(authType))
82 79
 	}
83 80
 
84
-	apiUrl := componentloginpage
81
+	link := componentloginpage
85 82
 	if isH5 {
86
-		apiUrl = bindcomponent
87
-	}
88
-	u, err := request.ParseURL(apiUrl, &queryParams)
89
-	if err != nil {
90
-		return nil, err
83
+		link = bindcomponent
91 84
 	}
92 85
 
86
+	link += "?" + queryParams.Encode()
87
+
93 88
 	if isH5 {
94
-		u.Fragment = "wechat_redirect"
89
+		link += "#wechat_redirect"
95 90
 	}
96 91
 
97
-	return u, nil
92
+	return link, nil
98 93
 }

authorization/component_token.go → api/authorization/component_token.go Zobrazit soubor

@@ -14,19 +14,12 @@ package authorization
14 14
 
15 15
 import (
16 16
 	"encoding/json"
17
-	"errors"
18 17
 
18
+	"gitee.com/yansen_zh/wxcomponent/config"
19 19
 	wxerr "gitee.com/yansen_zh/wxcomponent/errors"
20 20
 	"gitee.com/yansen_zh/wxcomponent/utils/request"
21 21
 )
22 22
 
23
-// ComponentTokenParam 获取令牌参数
24
-type ComponentTokenParam struct {
25
-	ComponentAppId        string `json:"component_appid"`
26
-	ComponentAppSecret    string `json:"component_appsecret"`
27
-	ComponentVerifyTicket string `json:"component_verify_ticket"`
28
-}
29
-
30 23
 // ComponentTokenResult 获取令牌结果
31 24
 type ComponentTokenResult struct {
32 25
 	wxerr.Error
@@ -39,17 +32,11 @@ const (
39 32
 )
40 33
 
41 34
 // GetComponentToken 获取令牌
42
-func GetComponentToken(data ComponentTokenParam) (*ComponentTokenResult, error) {
43
-	if data.ComponentAppId == "" {
44
-		return nil, errors.New("获取令牌 第三方平台的 appid 不能为空")
45
-	}
46
-
47
-	if data.ComponentAppSecret == "" {
48
-		return nil, errors.New("获取令牌 第三方平台的 appsecret 不能为空")
49
-	}
50
-
51
-	if data.ComponentVerifyTicket == "" {
52
-		return nil, errors.New("获取令牌 推送 ticket 不能为空")
35
+func GetComponentToken() (*ComponentTokenResult, error) {
36
+	data := map[string]string{
37
+		"component_appid":         config.GetAppID(),
38
+		"component_appsecret":     config.GetAppSecret(),
39
+		"component_verify_ticket": config.GetVerifyTicket(),
53 40
 	}
54 41
 
55 42
 	resp, e2 := request.PostJSON(apiComponentToken, nil, data)

authorization/pre_auth_code.go → api/authorization/pre_auth_code.go Zobrazit soubor

@@ -14,18 +14,13 @@ package authorization
14 14
 
15 15
 import (
16 16
 	"encoding/json"
17
-	"errors"
18 17
 	"net/url"
19 18
 
19
+	"gitee.com/yansen_zh/wxcomponent/config"
20 20
 	wxerr "gitee.com/yansen_zh/wxcomponent/errors"
21 21
 	"gitee.com/yansen_zh/wxcomponent/utils/request"
22 22
 )
23 23
 
24
-// PreAuthCodeParam 获取预授权码参数
25
-type PreAuthCodeParam struct {
26
-	ComponentAppId string `json:"component_appid"`
27
-}
28
-
29 24
 // PreAuthCodeResult 获取预授权码结果
30 25
 type PreAuthCodeResult struct {
31 26
 	wxerr.Error
@@ -38,18 +33,14 @@ const (
38 33
 )
39 34
 
40 35
 // CreatePreAuthCode 获取预授权码
41
-func CreatePreAuthCode(componentAccessToken string, data PreAuthCodeParam) (*PreAuthCodeResult, error) {
42
-	if componentAccessToken == "" {
43
-		return nil, errors.New("获取预授权码 第三方平台的 component_access_token 不能为空")
44
-	}
36
+func CreatePreAuthCode() (*PreAuthCodeResult, error) {
37
+	queryParam := url.Values{}
38
+	queryParam.Set("component_access_token", config.GetAccessToken())
45 39
 
46
-	if data.ComponentAppId == "" {
47
-		return nil, errors.New("获取预授权码 第三方平台的 appid 不能为空")
40
+	data := map[string]string{
41
+		"component_appid": config.GetAppID(),
48 42
 	}
49 43
 
50
-	queryParam := url.Values{}
51
-	queryParam.Set("component_access_token", componentAccessToken)
52
-
53 44
 	resp, e2 := request.PostJSON(apiCreatePreauthcode, &queryParam, data)
54 45
 	if e2 != nil {
55 46
 		return nil, e2

+ 34
- 0
api/authorization/push_ticket.go Zobrazit soubor

@@ -0,0 +1,34 @@
1
+/**
2
+ * Copyright (c) 2022 Yansen Zhang
3
+ * wxcomponent is licensed under Mulan PSL v2.
4
+ * You can use this software according to the terms and conditions of the Mulan PSL v2.
5
+ * You may obtain a copy of Mulan PSL v2 at:
6
+ *          http://license.coscl.org.cn/MulanPSL2
7
+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
8
+ * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
9
+ * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
10
+ * See the Mulan PSL v2 for more details.
11
+**/
12
+
13
+package authorization
14
+
15
+import (
16
+	"gitee.com/yansen_zh/wxcomponent/config"
17
+	"gitee.com/yansen_zh/wxcomponent/utils/request"
18
+)
19
+
20
+const (
21
+	apiStartPushTicket = "https://apies.weixin.qq.com/cgi-bin/component/api_start_push_ticket"
22
+)
23
+
24
+// StartPushTicket 启动 ticket 推送服务
25
+func StartPushTicket() error {
26
+	data := map[string]string{
27
+		"component_appid":  config.GetAppID(),
28
+		"component_secret": config.GetAppSecret(),
29
+	}
30
+
31
+	_, err := request.PostJSON(apiStartPushTicket, nil, data)
32
+
33
+	return err
34
+}

authorization/query_auth.go → api/authorization/query_auth.go Zobrazit soubor

@@ -17,16 +17,11 @@ import (
17 17
 	"errors"
18 18
 	"net/url"
19 19
 
20
+	"gitee.com/yansen_zh/wxcomponent/config"
20 21
 	wxerr "gitee.com/yansen_zh/wxcomponent/errors"
21 22
 	"gitee.com/yansen_zh/wxcomponent/utils/request"
22 23
 )
23 24
 
24
-// QueryAuthParam 获取授权信息参数
25
-type QueryAuthParam struct {
26
-	ComponentAppId    string `json:"component_appid"`
27
-	AuthorizationCode string `json:"authorization_code"`
28
-}
29
-
30 25
 // QueryAuthResult 获取授权信息结果
31 26
 type QueryAuthResult struct {
32 27
 	wxerr.Error
@@ -38,21 +33,18 @@ const (
38 33
 )
39 34
 
40 35
 // GetQueryAuth 获取授权信息
41
-func GetQueryAuth(componentAccessToken string, data QueryAuthParam) (*QueryAuthResult, error) {
42
-	if componentAccessToken == "" {
43
-		return nil, errors.New("获取授权信息 第三方平台的 component_access_token 不能为空")
44
-	}
45
-
46
-	if data.ComponentAppId == "" {
47
-		return nil, errors.New("获取授权信息 第三方平台的 appid 不能为空")
48
-	}
49
-
50
-	if data.AuthorizationCode == "" {
36
+func GetQueryAuth(authorizationCode string) (*QueryAuthResult, error) {
37
+	if authorizationCode == "" {
51 38
 		return nil, errors.New("获取授权信息 授权码 不能为空")
52 39
 	}
53 40
 
54 41
 	queryParam := url.Values{}
55
-	queryParam.Set("component_access_token", componentAccessToken)
42
+	queryParam.Set("component_access_token", config.GetAccessToken())
43
+
44
+	data := map[string]string{
45
+		"component_appid":    config.GetAppID(),
46
+		"authorization_code": authorizationCode,
47
+	}
56 48
 
57 49
 	resp, e2 := request.PostJSON(apiQueryAuth, &queryParam, data)
58 50
 	if e2 != nil {

authorization/types.go → api/authorization/types.go Zobrazit soubor


authorization/verify_ticket.go → api/authorization/verify_ticket.go Zobrazit soubor


authorizer/authorizer_list.go → api/authorizer/authorizer_list.go Zobrazit soubor

@@ -14,20 +14,13 @@ package authorizer
14 14
 
15 15
 import (
16 16
 	"encoding/json"
17
-	"errors"
18 17
 	"net/url"
19 18
 
19
+	"gitee.com/yansen_zh/wxcomponent/config"
20 20
 	wxerr "gitee.com/yansen_zh/wxcomponent/errors"
21 21
 	"gitee.com/yansen_zh/wxcomponent/utils/request"
22 22
 )
23 23
 
24
-// AuthorizerListParam 拉取所有已授权的帐号信息参数
25
-type AuthorizerListParam struct {
26
-	ComponentAppId string `json:"component_appid"`
27
-	Offset         int    `json:"offset"`
28
-	Count          int    `json:"count"`
29
-}
30
-
31 24
 // AuthorizerListResult 拉取所有已授权的帐号信息结果
32 25
 type AuthorizerListResult struct {
33 26
 	wxerr.Error
@@ -40,30 +33,28 @@ const (
40 33
 )
41 34
 
42 35
 // GetAuthorizerList 拉取所有已授权的帐号信息
43
-func GetAuthorizerList(componentAccessToken string, data AuthorizerListParam) (*AuthorizerListResult, error) {
44
-	if componentAccessToken == "" {
45
-		return nil, errors.New("拉取所有已授权的帐号信息 第三方平台的 component_access_token 不能为空")
36
+func GetAuthorizerList(offset, count int) (*AuthorizerListResult, error) {
37
+	if offset < 0 {
38
+		offset = 0
46 39
 	}
47 40
 
48
-	if data.ComponentAppId == "" {
49
-		return nil, errors.New("拉取所有已授权的帐号信息 第三方平台的 appid 不能为空")
41
+	if count < 0 {
42
+		count = 100
50 43
 	}
51 44
 
52
-	if data.Offset < 0 {
53
-		data.Offset = 0
45
+	if count > 500 {
46
+		count = 500
54 47
 	}
55 48
 
56
-	if data.Count < 0 {
57
-		data.Count = 100
58
-	}
49
+	queryParam := url.Values{}
50
+	queryParam.Set("component_access_token", config.GetAccessToken())
59 51
 
60
-	if data.Count > 500 {
61
-		data.Count = 500
52
+	data := map[string]interface{}{
53
+		"component_appid": config.GetAppID(),
54
+		"offset":          offset,
55
+		"count":           count,
62 56
 	}
63 57
 
64
-	queryParam := url.Values{}
65
-	queryParam.Set("component_access_token", componentAccessToken)
66
-
67 58
 	resp, e2 := request.PostJSON(apiGetAuthorizerList, &queryParam, data)
68 59
 	if e2 != nil {
69 60
 		return nil, e2

authorizer/get_authorizer_option.go → api/authorizer/get_authorizer_option.go Zobrazit soubor

@@ -17,17 +17,11 @@ import (
17 17
 	"errors"
18 18
 	"net/url"
19 19
 
20
+	"gitee.com/yansen_zh/wxcomponent/config"
20 21
 	wxerr "gitee.com/yansen_zh/wxcomponent/errors"
21 22
 	"gitee.com/yansen_zh/wxcomponent/utils/request"
22 23
 )
23 24
 
24
-// GetAuthorizerOptionParam 获取授权方选项信息参数
25
-type GetAuthorizerOptionParam struct {
26
-	ComponentAppId  string `json:"component_appid"`
27
-	AuthorizerAppId string `json:"authorizer_appid"`
28
-	OptionName      string `json:"option_name"`
29
-}
30
-
31 25
 // GetAuthorizerOptionResult 获取授权方选项信息结果
32 26
 type GetAuthorizerOptionResult struct {
33 27
 	wxerr.Error
@@ -41,25 +35,23 @@ const (
41 35
 )
42 36
 
43 37
 // GetAuthorizerOption 获取授权方选项信息
44
-func GetAuthorizerOption(componentAccessToken string, data GetAuthorizerOptionParam) (*GetAuthorizerOptionResult, error) {
45
-	if componentAccessToken == "" {
46
-		return nil, errors.New("获取授权方选项信息 第三方平台的 component_access_token 不能为空")
47
-	}
48
-
49
-	if data.ComponentAppId == "" {
50
-		return nil, errors.New("获取授权方选项信息 授权公众号或小程序的 appid 不能为空")
51
-	}
52
-
53
-	if data.AuthorizerAppId == "" {
38
+func GetAuthorizerOption(authorizerAppID string, optionName string) (*GetAuthorizerOptionResult, error) {
39
+	if authorizerAppID == "" {
54 40
 		return nil, errors.New("获取授权方选项信息 第三方平台的 appid 不能为空")
55 41
 	}
56 42
 
57
-	if data.OptionName == "" {
43
+	if optionName == "" {
58 44
 		return nil, errors.New("获取授权方选项信息 选项名称 不能为空")
59 45
 	}
60 46
 
61 47
 	queryParam := url.Values{}
62
-	queryParam.Set("component_access_token", componentAccessToken)
48
+	queryParam.Set("component_access_token", config.GetAccessToken())
49
+
50
+	data := map[string]string{
51
+		"component_appid":  config.GetAppID(),
52
+		"authorizer_appid": authorizerAppID,
53
+		"option_name":      optionName,
54
+	}
63 55
 
64 56
 	resp, e2 := request.PostJSON(apiGetAuthorizerOption, &queryParam, data)
65 57
 	if e2 != nil {

+ 53
- 0
api/authorizer/set_authorizer_option.go Zobrazit soubor

@@ -0,0 +1,53 @@
1
+/**
2
+ * Copyright (c) 2022 Yansen Zhang
3
+ * wxcomponent is licensed under Mulan PSL v2.
4
+ * You can use this software according to the terms and conditions of the Mulan PSL v2.
5
+ * You may obtain a copy of Mulan PSL v2 at:
6
+ *          http://license.coscl.org.cn/MulanPSL2
7
+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
8
+ * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
9
+ * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
10
+ * See the Mulan PSL v2 for more details.
11
+**/
12
+
13
+package authorizer
14
+
15
+import (
16
+	"errors"
17
+	"net/url"
18
+
19
+	"gitee.com/yansen_zh/wxcomponent/config"
20
+	"gitee.com/yansen_zh/wxcomponent/utils/request"
21
+)
22
+
23
+const (
24
+	apiSetAuthorizerOption = "https://apies.weixin.qq.com/cgi-bin/component/api_set_authorizer_option"
25
+)
26
+
27
+// SetAuthorizerOption 设置授权方选项信息
28
+func SetAuthorizerOption(authorizerAppID, optionName, optionValue string) error {
29
+	if authorizerAppID == "" {
30
+		return errors.New("设置授权方选项信息 第三方平台的 appid 不能为空")
31
+	}
32
+
33
+	if optionName == "" {
34
+		return errors.New("设置授权方选项信息 选项名称 不能为空")
35
+	}
36
+
37
+	if optionValue == "" {
38
+		return errors.New("设置授权方选项信息 设置的选项值 不能为空")
39
+	}
40
+
41
+	queryParam := url.Values{}
42
+	queryParam.Set("component_access_token", config.GetAccessToken())
43
+
44
+	data := map[string]string{
45
+		"component_appid":  config.GetAppID(),
46
+		"authorizer_appid": authorizerAppID,
47
+		"option_name":      optionName,
48
+		"option_value":     optionValue,
49
+	}
50
+
51
+	_, err := request.PostJSON(apiSetAuthorizerOption, &queryParam, data)
52
+	return err
53
+}

authorizer/types.go → api/authorizer/types.go Zobrazit soubor


+ 77
- 0
api/mp/jsapi.go Zobrazit soubor

@@ -0,0 +1,77 @@
1
+package mp
2
+
3
+import (
4
+	"crypto/sha1"
5
+	"encoding/json"
6
+	"errors"
7
+	"fmt"
8
+	"net/url"
9
+	"strconv"
10
+	"time"
11
+
12
+	wxerr "gitee.com/yansen_zh/wxcomponent/errors"
13
+	"gitee.com/yansen_zh/wxcomponent/utils"
14
+	"gitee.com/yansen_zh/wxcomponent/utils/request"
15
+)
16
+
17
+// JsapiTicketResult 通过 access_token 获取 jsapi_ticket 结果
18
+type JsapiTicketResult struct {
19
+	wxerr.Error
20
+	Ticket    string `json:"ticket"`
21
+	ExpiresIn int    `json:"expires_in"`
22
+}
23
+
24
+// JsapiSignature 可以用来初始化 JS SDK
25
+type JsapiSignature struct {
26
+	Timestamp int64  `json:"timestamp"`
27
+	NonceStr  string `json:"nonceStr"`
28
+	Signature string `json:"signature"`
29
+}
30
+
31
+const (
32
+	apiGetJSTicket = "https://api.weixin.qq.com/cgi-bin/ticket/getticket"
33
+)
34
+
35
+// GetJSTicket 通过 access_token 获取 jsapi_ticket
36
+func GetJSTicket(authorizerToken string) (*JsapiTicketResult, error) {
37
+	if authorizerToken == "" {
38
+		return nil, errors.New("获取 jsapi_ticket authorizerToken 不能为空")
39
+	}
40
+
41
+	param := url.Values{}
42
+	param.Set("access_token", authorizerToken)
43
+	param.Set("type", "jsapi")
44
+
45
+	resp, e2 := request.GetJSON(apiGetJSTicket, &param)
46
+	if e2 != nil {
47
+		return nil, e2
48
+	}
49
+
50
+	result := JsapiTicketResult{}
51
+	if err := json.Unmarshal(resp, &result); err != nil {
52
+		return nil, err
53
+	}
54
+
55
+	return &result, nil
56
+}
57
+
58
+// GetJSAPISignature 获取 JsapiSignature
59
+func GetJSAPISignature(ticket, url string) *JsapiSignature {
60
+	timestamp := time.Now().Unix()
61
+	timestampStr := strconv.FormatInt(timestamp, 10)
62
+	nonceStr := utils.RandStr(16)
63
+
64
+	s1 := "jsapi_ticket=" + ticket
65
+	s2 := "&noncestr=" + nonceStr
66
+	s3 := "&timestamp=" + timestampStr
67
+	s4 := "&url=" + url
68
+
69
+	plain := s1 + s2 + s3 + s4
70
+	signature := fmt.Sprintf("%x", sha1.Sum([]byte(plain)))
71
+
72
+	return &JsapiSignature{
73
+		Timestamp: timestamp,
74
+		NonceStr:  nonceStr,
75
+		Signature: signature,
76
+	}
77
+}

+ 71
- 0
api/mp/webpage.go Zobrazit soubor

@@ -0,0 +1,71 @@
1
+package mp
2
+
3
+// 代公众号发起网页授权
4
+
5
+import (
6
+	"encoding/json"
7
+	"errors"
8
+	"net/url"
9
+	"strings"
10
+
11
+	"gitee.com/yansen_zh/wxcomponent/config"
12
+	wxerr "gitee.com/yansen_zh/wxcomponent/errors"
13
+	"gitee.com/yansen_zh/wxcomponent/utils/request"
14
+)
15
+
16
+// GetOAuthCodeLink 代公众号发起网页授权, 构造授权链接
17
+// redirectURI 必须是未经编码的原始网址字符串
18
+func GetOAuthCodeLink(appID, redirectURI, state string, scopes ...string) string {
19
+	params := url.Values{}
20
+	params.Set("appid", appID)
21
+	params.Set("redirect_uri", redirectURI)
22
+	params.Set("response_type", "code")
23
+	params.Set("scope", strings.Join(scopes, ","))
24
+	params.Set("state", state)
25
+	params.Set("component_appid", config.GetAppID())
26
+
27
+	return "https://open.weixin.qq.com/connect/oauth2/authorize?" + params.Encode()
28
+}
29
+
30
+// MpOAuthAccessTokenResult 网页授权, 通过 code 换取 access_token 返回值
31
+type MpOAuthAccessTokenResult struct {
32
+	wxerr.Error
33
+	// AccessToken 接口调用凭证
34
+	AccessToken string `json:"access_token"`
35
+	// ExpiresIn access_token 接口调用凭证超时时间,单位(秒)
36
+	ExpiresIn int `json:"expires_in"`
37
+	// RefreshToken 用户刷新 access_token
38
+	RefreshToken string `json:"refresh_token"`
39
+	// Openid 授权用户唯一标识
40
+	OpenID string `json:"openid"`
41
+	// Scope 用户授权的作用域,使用逗号(,)分隔
42
+	Scope string `json:"scope"`
43
+}
44
+
45
+const apiOAuthAccessToken = "https://api.weixin.qq.com/sns/oauth2/component/access_token"
46
+
47
+// GetOAuthAccessToken 网页授权, 通过 code 换取 access_token
48
+func GetOAuthAccessToken(appID, code string) (*MpOAuthAccessTokenResult, error) {
49
+	if appID == "" || code == "" {
50
+		return nil, errors.New("获取网页授权Token appID 或者 code 不能为空")
51
+	}
52
+
53
+	param := url.Values{}
54
+	param.Set("appid", appID)
55
+	param.Set("code", code)
56
+	param.Set("grant_type", "authorization_code")
57
+	param.Set("component_appid", config.GetAppID())
58
+	param.Set("component_access_token", config.GetAccessToken())
59
+
60
+	resp, e2 := request.GetJSON(apiOAuthAccessToken, &param)
61
+	if e2 != nil {
62
+		return nil, e2
63
+	}
64
+
65
+	result := MpOAuthAccessTokenResult{}
66
+	if err := json.Unmarshal(resp, &result); err != nil {
67
+		return nil, err
68
+	}
69
+
70
+	return &result, nil
71
+}

+ 0
- 59
authorization/push_ticket.go Zobrazit soubor

@@ -1,59 +0,0 @@
1
-/**
2
- * Copyright (c) 2022 Yansen Zhang
3
- * wxcomponent is licensed under Mulan PSL v2.
4
- * You can use this software according to the terms and conditions of the Mulan PSL v2.
5
- * You may obtain a copy of Mulan PSL v2 at:
6
- *          http://license.coscl.org.cn/MulanPSL2
7
- * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
8
- * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
9
- * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
10
- * See the Mulan PSL v2 for more details.
11
-**/
12
-
13
-package authorization
14
-
15
-import (
16
-	"encoding/json"
17
-	"errors"
18
-
19
-	wxerr "gitee.com/yansen_zh/wxcomponent/errors"
20
-	"gitee.com/yansen_zh/wxcomponent/utils/request"
21
-)
22
-
23
-// PushTicketParam 启动票据推送服务参数
24
-type PushTicketParam struct {
25
-	ComponentAppId  string `json:"component_appid"`
26
-	ComponentSecret string `json:"component_secret"`
27
-}
28
-
29
-// PushTicketResult 启动票据推送服务参数
30
-type PushTicketResult struct {
31
-	wxerr.Error
32
-}
33
-
34
-const (
35
-	apiStartPushTicket = "https://apies.weixin.qq.com/cgi-bin/component/api_start_push_ticket"
36
-)
37
-
38
-// StartPushTicket 启动 ticket 推送服务
39
-func StartPushTicket(data PushTicketParam) (*PushTicketResult, error) {
40
-	if data.ComponentAppId == "" {
41
-		return nil, errors.New("启动 ticket 推送服务 第三方平台的 appid 不能为空")
42
-	}
43
-
44
-	if data.ComponentSecret == "" {
45
-		return nil, errors.New("启动 ticket 推送服务 第三方平台的 appsecret 不能为空")
46
-	}
47
-
48
-	resp, e2 := request.PostJSON(apiStartPushTicket, nil, data)
49
-	if e2 != nil {
50
-		return nil, e2
51
-	}
52
-
53
-	result := PushTicketResult{}
54
-	if err := json.Unmarshal(resp, &result); err != nil {
55
-		return nil, err
56
-	}
57
-
58
-	return &result, nil
59
-}

+ 0
- 77
authorizer/set_authorizer_option.go Zobrazit soubor

@@ -1,77 +0,0 @@
1
-/**
2
- * Copyright (c) 2022 Yansen Zhang
3
- * wxcomponent is licensed under Mulan PSL v2.
4
- * You can use this software according to the terms and conditions of the Mulan PSL v2.
5
- * You may obtain a copy of Mulan PSL v2 at:
6
- *          http://license.coscl.org.cn/MulanPSL2
7
- * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
8
- * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
9
- * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
10
- * See the Mulan PSL v2 for more details.
11
-**/
12
-
13
-package authorizer
14
-
15
-import (
16
-	"encoding/json"
17
-	"errors"
18
-	"net/url"
19
-
20
-	wxerr "gitee.com/yansen_zh/wxcomponent/errors"
21
-	"gitee.com/yansen_zh/wxcomponent/utils/request"
22
-)
23
-
24
-// SetAuthorizerOptionParam 设置授权方选项信息参数
25
-type SetAuthorizerOptionParam struct {
26
-	ComponentAppId  string `json:"component_appid"`
27
-	AuthorizerAppId string `json:"authorizer_appid"`
28
-	OptionName      string `json:"option_name"`
29
-	OptionValue     string `json:"option_value"`
30
-}
31
-
32
-// SetAuthorizerOptionResult 设置授权方选项信息结果
33
-type SetAuthorizerOptionResult struct {
34
-	wxerr.Error
35
-}
36
-
37
-const (
38
-	apiSetAuthorizerOption = "https://apies.weixin.qq.com/cgi-bin/component/api_set_authorizer_option"
39
-)
40
-
41
-// SetAuthorizerOption 设置授权方选项信息
42
-func SetAuthorizerOption(componentAccessToken string, data SetAuthorizerOptionParam) (*SetAuthorizerOptionResult, error) {
43
-	if componentAccessToken == "" {
44
-		return nil, errors.New("设置授权方选项信息 第三方平台的 component_access_token 不能为空")
45
-	}
46
-
47
-	if data.ComponentAppId == "" {
48
-		return nil, errors.New("设置授权方选项信息 授权公众号或小程序的 appid 不能为空")
49
-	}
50
-
51
-	if data.AuthorizerAppId == "" {
52
-		return nil, errors.New("设置授权方选项信息 第三方平台的 appid 不能为空")
53
-	}
54
-
55
-	if data.OptionName == "" {
56
-		return nil, errors.New("设置授权方选项信息 选项名称 不能为空")
57
-	}
58
-
59
-	if data.OptionValue == "" {
60
-		return nil, errors.New("设置授权方选项信息 设置的选项值 不能为空")
61
-	}
62
-
63
-	queryParam := url.Values{}
64
-	queryParam.Set("component_access_token", componentAccessToken)
65
-
66
-	resp, e2 := request.PostJSON(apiSetAuthorizerOption, &queryParam, data)
67
-	if e2 != nil {
68
-		return nil, e2
69
-	}
70
-
71
-	result := SetAuthorizerOptionResult{}
72
-	if err := json.Unmarshal(resp, &result); err != nil {
73
-		return nil, err
74
-	}
75
-
76
-	return &result, nil
77
-}

+ 28
- 0
config/config.go Zobrazit soubor

@@ -0,0 +1,28 @@
1
+package config
2
+
3
+import "time"
4
+
5
+type Config interface {
6
+	// GetAppID 获取平台 APPID
7
+	GetAppID() string
8
+
9
+	// GetAppSecret 获取平台 APPSECRET
10
+	GetAppSecret() string
11
+
12
+	// GetAppSecret 获取平台消息校验Token
13
+	GetMsgToken() string
14
+
15
+	// GetToken 获取 Token
16
+	GetAccessToken() string
17
+
18
+	// RefreshToken 刷新 Token
19
+	RefreshToken(token string, expire time.Time) error
20
+
21
+	// GetTicket 获取票据
22
+	GetVerifyTicket() string
23
+
24
+	// RefreshTicket 刷新票据
25
+	RefreshVerifyTicket(ticket string, expire time.Time) error
26
+}
27
+
28
+var conf Config

+ 59
- 0
config/index.go Zobrazit soubor

@@ -0,0 +1,59 @@
1
+package config
2
+
3
+import (
4
+	"errors"
5
+	"time"
6
+)
7
+
8
+// Init 初始化平台实例
9
+func Init(config Config) error {
10
+	if config == nil {
11
+		return errors.New("平台初始化参数不能为空")
12
+	}
13
+
14
+	appID := config.GetAppID()
15
+	secret := config.GetAppSecret()
16
+	token := config.GetMsgToken()
17
+
18
+	if appID == "" || secret == "" || token == "" {
19
+		return errors.New("平台组件初始化内容不能为空")
20
+	}
21
+
22
+	conf = config
23
+	return nil
24
+}
25
+
26
+// GetAppID 获取平台 APPID
27
+func GetAppID() string {
28
+	return conf.GetAppID()
29
+}
30
+
31
+// GetAppSecret 获取平台 APPSECRET
32
+func GetAppSecret() string {
33
+	return conf.GetAppSecret()
34
+}
35
+
36
+// GetAppSecret 获取平台消息校验Token
37
+func GetMsgToken() string {
38
+	return conf.GetMsgToken()
39
+}
40
+
41
+// GetToken 获取 Token
42
+func GetAccessToken() string {
43
+	return conf.GetAccessToken()
44
+}
45
+
46
+// RefreshToken 刷新 Token
47
+func RefreshToken(token string, expire time.Time) error {
48
+	return conf.RefreshToken(token, expire)
49
+}
50
+
51
+// GetTicket 获取票据
52
+func GetVerifyTicket() string {
53
+	return conf.GetVerifyTicket()
54
+}
55
+
56
+// RefreshTicket 刷新票据
57
+func RefreshVerifyTicket(ticket string, expire time.Time) error {
58
+	return conf.RefreshVerifyTicket(ticket, expire)
59
+}

+ 0
- 37
mp/webpage.go Zobrazit soubor

@@ -1,37 +0,0 @@
1
-package mp
2
-
3
-import (
4
-	"net/url"
5
-	"strings"
6
-
7
-	wxerr "gitee.com/yansen_zh/wxcomponent/errors"
8
-)
9
-
10
-// MpWebAccessTokenResult 网页授权, 通过 code 换取 access_token 返回值
11
-type MpWebAccessTokenResult struct {
12
-	wxerr.Error
13
-	// AccessToken 接口调用凭证
14
-	AccessToken string `json:"access_token"`
15
-	// ExpiresIn access_token 接口调用凭证超时时间,单位(秒)
16
-	ExpiresIn int `json:"expires_in"`
17
-	// RefreshToken 用户刷新 access_token
18
-	RefreshToken string `json:"refresh_token"`
19
-	// Openid 授权用户唯一标识
20
-	OpenID string `json:"openid"`
21
-	// Scope 用户授权的作用域,使用逗号(,)分隔
22
-	Scope string `json:"scope"`
23
-}
24
-
25
-// GetAuthorizationCodeLink 代公众号发起网页授权, 构造授权链接
26
-// redirectURI 必须是未经编码的原始网址字符串
27
-func GetAuthorizationCodeLink(componentAppID, appID, redirectURI, state string, scopes ...string) string {
28
-	params := url.Values{}
29
-	params.Set("appid", appID)
30
-	params.Set("redirect_uri", redirectURI)
31
-	params.Set("response_type", "code")
32
-	params.Set("scope", strings.Join(scopes, ","))
33
-	params.Set("state", state)
34
-	params.Set("component_appid", componentAppID)
35
-
36
-	return "https://open.weixin.qq.com/connect/oauth2/authorize?" + params.Encode()
37
-}

+ 37
- 6
utils/request/request.go Zobrazit soubor

@@ -24,18 +24,26 @@ import (
24 24
 	"gitee.com/yansen_zh/wxcomponent/utils/log"
25 25
 )
26 26
 
27
-func post(url string, contentType string, body []byte) ([]byte, error) {
27
+func Fetch(method, url string, contentType string, body []byte) ([]byte, error) {
28 28
 
29 29
 	logger := log.GetLogger()
30
-	logger.Info("发送请求: ", url)
30
+	logger.Info("发送请求: [", method, "] ", url)
31 31
 
32 32
 	if len(body) > 0 {
33 33
 		logger.Info(body)
34 34
 	}
35 35
 
36
-	resp, e1 := http.Post(url, contentType, bytes.NewReader(body))
37
-	if e1 != nil {
38
-		return nil, e1
36
+	var resp *http.Response
37
+	var err error
38
+
39
+	if method == "POST" {
40
+		resp, err = http.Post(url, contentType, bytes.NewReader(body))
41
+	} else {
42
+		resp, err = http.Get(url)
43
+	}
44
+
45
+	if err != nil {
46
+		return nil, err
39 47
 	}
40 48
 
41 49
 	if resp.StatusCode > 299 {
@@ -65,7 +73,30 @@ func PostJSON(addr string, query *url.Values, body interface{}) ([]byte, error)
65 73
 		return nil, e1
66 74
 	}
67 75
 
68
-	resp, e2 := post(apiURL.String(), ContentTypeJSON, data)
76
+	resp, e2 := Fetch("POST", apiURL.String(), ContentTypeJSON, data)
77
+	if e2 != nil {
78
+		return nil, e2
79
+	}
80
+
81
+	e3 := wxerr.Error{}
82
+	if err := json.Unmarshal(resp, &e3); err != nil {
83
+		return nil, err
84
+	}
85
+
86
+	if e3.Code != 0 {
87
+		return nil, e3
88
+	}
89
+
90
+	return resp, nil
91
+}
92
+
93
+func GetJSON(addr string, query *url.Values) ([]byte, error) {
94
+	apiURL, e0 := ParseURL(addr, query)
95
+	if e0 != nil {
96
+		return nil, e0
97
+	}
98
+
99
+	resp, e2 := Fetch("GET", apiURL.String(), "", nil)
69 100
 	if e2 != nil {
70 101
 		return nil, e2
71 102
 	}

+ 24
- 0
utils/utils.go Zobrazit soubor

@@ -0,0 +1,24 @@
1
+package utils
2
+
3
+import (
4
+	"math/rand"
5
+	"strings"
6
+	"time"
7
+)
8
+
9
+// RandStr 获取指定 n 长度的随机字符串
10
+func RandStr(n int) string {
11
+	arr := strings.Split("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ", "")
12
+	arrLen := len(arr)
13
+	seed := time.Now().Unix()
14
+
15
+	r := rand.New(rand.NewSource(seed))
16
+	dst := make([]string, n)
17
+
18
+	for i := range dst {
19
+		p := r.Intn(arrLen)
20
+		dst[i] = arr[p]
21
+	}
22
+
23
+	return strings.Join(dst, "")
24
+}