ソースを参照

Merge branch 'master' of http://git.ycjcjy.com/default/wechat-conf

胡轶钦 6 年 前
コミット
2fa8bc290b
共有8 個のファイルを変更した192 個の追加110 個の削除を含む
  1. 4
    1
      bootstrap/bootstrap.go
  2. 2
    0
      conf/wechat.conf
  3. 73
    0
      controllers/component.go
  4. 10
    7
      models/model/sys_wechat_conf.go
  5. 26
    0
      models/wechat.go
  6. 1
    1
      service/user/user.go
  7. 49
    0
      utils/aes.go
  8. 27
    101
      utils/wechat.go

+ 4
- 1
bootstrap/bootstrap.go ファイルの表示

@@ -14,8 +14,11 @@ func SystemInit() {
14 14
 	// 系统日志
15 15
 	utils.LogInit()
16 16
 
17
+	// 第三方平台
18
+	utils.ComponentInit()
19
+
17 20
 	// 微信系统
18
-	utils.WechatInit()
21
+	models.InitWechat()
19 22
 
20 23
 	// 路由系统
21 24
 	routers.RouteInit()

+ 2
- 0
conf/wechat.conf ファイルの表示

@@ -0,0 +1,2 @@
1
+appid = test
2
+aeskey = aeskey

+ 73
- 0
controllers/component.go ファイルの表示

@@ -0,0 +1,73 @@
1
+package controllers
2
+
3
+import (
4
+	"encoding/base64"
5
+	"io/ioutil"
6
+	"wechat-conf/utils"
7
+
8
+	"github.com/zjxpcyc/wechat/core"
9
+)
10
+
11
+const (
12
+	INFOTYPE_TICKET           = "component_verify_ticket"
13
+	INFOTYPE_AUTHORIZED       = "authorized"
14
+	INFOTYPE_UNAUTHORIZED     = "unauthorized"
15
+	INFOTYPE_UPDATEAUTHORIZED = "updateauthorized"
16
+)
17
+
18
+// ComponentPush 第三方平台推送
19
+func (c *BaseController) ComponentPush() {
20
+	r := c.Ctx.Request
21
+	defer r.Body.Close()
22
+	con, _ := ioutil.ReadAll(r.Body)
23
+
24
+	// timestamp := c.GetString("timestamp")
25
+	// nonce := c.GetString("nonce")
26
+
27
+	// token := "testtoken"
28
+	EncodingAESKey := "key"
29
+	// appid := "appid"
30
+
31
+	AESKey, err := base64.StdEncoding.DecodeString(EncodingAESKey + "=")
32
+	if err != nil {
33
+		utils.LogError("DecodeString失败:", err)
34
+	}
35
+	xp := &core.XMLParse{}
36
+	// 解析xml
37
+	val, err := xp.Parse(string(con))
38
+	if err != nil {
39
+		utils.LogError("xml解析失败:", err)
40
+	}
41
+
42
+	msgbyte, err := utils.AesDecrypt([]byte(val["Encrypt"]), AESKey)
43
+	if err != nil {
44
+		utils.LogError("解密失败:", err)
45
+	}
46
+	msg, err := xp.Parse(string(msgbyte))
47
+	if err != nil {
48
+		utils.LogError("msgxml解析失败:", err)
49
+	}
50
+	switch msg["InfoType"] {
51
+	case INFOTYPE_TICKET:
52
+		// 更新ticket
53
+		utils.RefreshComponentTicket(msg["ComponentVerifyTicket"])
54
+		break
55
+	case INFOTYPE_AUTHORIZED:
56
+		// 授权成功
57
+		var cert = map[string]string{
58
+			"appid":              msg["AuthorizerAppid"],
59
+			"authorization_code": msg["AuthorizationCode"],
60
+		}
61
+
62
+		wxclient := utils.WechatInit(cert)
63
+		utils.AppendWxClient(wxclient)
64
+		break
65
+	case INFOTYPE_UPDATEAUTHORIZED:
66
+		// 授权更新
67
+		break
68
+	case INFOTYPE_UNAUTHORIZED:
69
+		// 取消授权
70
+		break
71
+	}
72
+
73
+}

+ 10
- 7
models/model/sys_wechat_conf.go ファイルの表示

@@ -1,14 +1,17 @@
1 1
 package model
2 2
 
3
+import "time"
4
+
3 5
 type SysWechatConf struct {
4 6
 	ConfId string `xorm:"not null pk VARCHAR(64)"`
5 7
 	Type   string `xorm:"comment('wechat 微信公众号
6 8
             mini 小程序') VARCHAR(20)"`
7
-	Appid  string `xorm:"VARCHAR(50)"`
8
-	Secret string `xorm:"VARCHAR(50)"`
9
-	Token  string `xorm:"VARCHAR(50)"`
10
-	Aeskey string `xorm:"VARCHAR(100)"`
11
-	Wxid   string `xorm:"VARCHAR(50)"`
12
-	Remark string `xorm:"TEXT"`
13
-	Status int    `xorm:"SMALLINT(6)"`
9
+	Appid             string    `xorm:"VARCHAR(50)"`
10
+	AuthorizationCode string    `xorm:"VARCHAR(100)"`
11
+	RefreshToken      string    `xorm:"VARCHAR(100)"`
12
+	Token             string    `xorm:"VARCHAR(100)"`
13
+	Remark            string    `xorm:"TEXT"`
14
+	Status            int       `xorm:"SMALLINT(6)"`
15
+	AuthorizationInfo string    `xorm:"TEXT"`
16
+	BindDate          time.Time `xorm:"DATETIME"`
14 17
 }

+ 26
- 0
models/wechat.go ファイルの表示

@@ -0,0 +1,26 @@
1
+package models
2
+
3
+import (
4
+	"wechat-conf/models/model"
5
+	"wechat-conf/utils"
6
+)
7
+
8
+// InitWechat 初始化微信
9
+func InitWechat() {
10
+	var wxconfs []model.SysWechatConf
11
+	err := DBEngine.Where("status=1").Find(&wxconfs)
12
+	if err != nil {
13
+		utils.LogError("初始化微信失败:", err)
14
+		return
15
+	}
16
+	for _, conf := range wxconfs {
17
+		var cert = map[string]string{
18
+			"authorizer_access_token":  conf.Token,
19
+			"authorizer_refresh_token": conf.RefreshToken,
20
+			"authorization_code":       conf.AuthorizationCode,
21
+			"appid":                    conf.Appid,
22
+		}
23
+		client := utils.WechatInit(cert)
24
+		utils.AppendWxClient(client)
25
+	}
26
+}

+ 1
- 1
service/user/user.go ファイルの表示

@@ -48,7 +48,7 @@ func (s *UserServ) ValidUserNameLogin(userName, pass string) (*model.SysUser, er
48 48
 	}
49 49
 
50 50
 	if !s.ValidatePassword(&user, pass) {
51
-		return nil, helper.LogError("用户密码不正确")
51
+		return nil, utils.LogError("用户密码不正确")
52 52
 	}
53 53
 
54 54
 	return &user, nil

+ 49
- 0
utils/aes.go ファイルの表示

@@ -0,0 +1,49 @@
1
+package utils
2
+
3
+import (
4
+	"bytes"
5
+	"crypto/aes"
6
+	"crypto/cipher"
7
+)
8
+
9
+// PKCS7Padding 填充序列的每个字节都填paddingSize
10
+func PKCS7Padding(ciphertext []byte, blockSize int) []byte {
11
+	padding := blockSize - len(ciphertext)%blockSize
12
+	padtext := bytes.Repeat([]byte{byte(padding)}, padding)
13
+	return append(ciphertext, padtext...)
14
+}
15
+
16
+// PKCS7UnPadding 取消填充序列的每个字节都填paddingSize
17
+func PKCS7UnPadding(origData []byte) []byte {
18
+	length := len(origData)
19
+	unpadding := int(origData[length-1])
20
+	return origData[:(length - unpadding)]
21
+}
22
+
23
+// AesEncrypt 加密
24
+func AesEncrypt(origData, key []byte) ([]byte, error) {
25
+	block, err := aes.NewCipher(key)
26
+	if err != nil {
27
+		return nil, err
28
+	}
29
+	blockSize := block.BlockSize()
30
+	origData = PKCS7Padding(origData, blockSize)
31
+	blockMode := cipher.NewCBCEncrypter(block, key[:blockSize])
32
+	crypted := make([]byte, len(origData))
33
+	blockMode.CryptBlocks(crypted, origData)
34
+	return crypted, nil
35
+}
36
+
37
+// AesDecrypt 解密
38
+func AesDecrypt(crypted, key []byte) ([]byte, error) {
39
+	block, err := aes.NewCipher(key)
40
+	if err != nil {
41
+		return nil, err
42
+	}
43
+	blockSize := block.BlockSize()
44
+	blockMode := cipher.NewCBCDecrypter(block, key[:blockSize])
45
+	origData := make([]byte, len(crypted))
46
+	blockMode.CryptBlocks(origData, crypted)
47
+	origData = PKCS7UnPadding(origData)
48
+	return origData, nil
49
+}

+ 27
- 101
utils/wechat.go ファイルの表示

@@ -1,116 +1,42 @@
1 1
 package utils
2 2
 
3 3
 import (
4
-	"github.com/zjxpcyc/wechat/mini"
5
-	"github.com/zjxpcyc/wechat/wx"
4
+	"github.com/astaxie/beego/config"
5
+	"github.com/kinisky564477/wechat/component"
6 6
 )
7 7
 
8
-var wxClients map[string]*wx.Client
9
-var miniClients map[string]*mini.Client
8
+// Component 微信开放平台
9
+var Component *component.ComponentClient
10 10
 
11
-type WechatUser struct {
12
-	OpenID     string  `json:"openid"`
13
-	NickName   string  `json:"nickname"`
14
-	Sex        float64 `json:"sex"`
15
-	Province   string  `json:"province"`
16
-	City       string  `json:"city"`
17
-	Country    string  `json:"country"`
18
-	HeadImgURL string  `json:"headimgurl"`
19
-	UnionID    string  `json:"unionid"`
11
+// ComponentInit 第三方初始化
12
+func ComponentInit() {
13
+	// 初始化第三方
14
+	var cert map[string]string
15
+	wechat, _ := config.NewConfig("ini", appRoot+"/conf/db.conf")
16
+	cert["component_appid"] = wechat.String("appid")
17
+	cert["aeskey"] = wechat.String("aeskey")
18
+	Component = component.NewComponentClient(cert)
20 19
 }
21 20
 
22
-// WxClientSingleton 初始化
23
-func WxClientSingleton(org string, cert map[string]string) {
24
-	if wxClients == nil {
25
-		wxClients = map[string]*wx.Client{
26
-			org: wx.NewClient(cert),
27
-		}
28
-	} else {
29
-		if _, ok := wxClients[org]; !ok {
30
-			wxClients[org] = wx.NewClient(cert)
31
-		}
32
-	}
21
+// RefreshComponentTicket ticket
22
+func RefreshComponentTicket(ticket string) {
23
+	Component.RefreshTicket(ticket)
33 24
 }
34 25
 
35
-// MiniClientSingleton 初始化
36
-func MiniClientSingleton(org string, cert map[string]string) {
37
-	if miniClients == nil {
38
-		miniClients = map[string]*mini.Client{
39
-			org: mini.NewClient(cert),
40
-		}
41
-	} else {
42
-		if _, ok := miniClients[org]; !ok {
43
-			miniClients[org] = mini.NewClient(cert)
44
-		}
45
-	}
46
-}
47
-
48
-// WxClientFor 微信客户端
49
-func WxClientFor(org string) *wx.Client {
50
-	return wxClients[org]
51
-}
52
-
53
-// MiniClientFor 小程序客户端
54
-func MiniClientFor(org string) *mini.Client {
55
-	return miniClients[org]
56
-}
26
+// WechatInit 微信初始化
27
+func WechatInit(cert map[string]string) *component.WxClient {
28
+	var wechatClient *component.WxClient
57 29
 
58
-// GetWxAppID 获取微信ID
59
-func GetWxAppID(org string) string {
60
-	return wxClients[org].GetAppID()
61
-}
30
+	wechatClient = component.NewWxClient(
31
+		cert,
32
+		Component.GetToken,
33
+		Component.GetCertificate,
34
+	)
62 35
 
63
-func WechatInit() {
64
-	logger := GetDefaultLogger()
65
-	wx.SetLogInst(logger)
66
-	mini.SetLogInst(logger)
36
+	return wechatClient
67 37
 }
68 38
 
69
-// MapToWechatUser 映射微信人员
70
-func MapToWechatUser(data map[string]interface{}) *WechatUser {
71
-	subscribe, has := data["subscribe"]
72
-	if has {
73
-		if subscribe == nil {
74
-			return nil
75
-		}
76
-
77
-		sub := subscribe.(float64)
78
-		if sub == 0 {
79
-			return nil
80
-		}
81
-	}
82
-
83
-	user := WechatUser{
84
-		OpenID: data["openid"].(string),
85
-	}
86
-
87
-	if data["sex"] != nil {
88
-		user.Sex = data["sex"].(float64)
89
-	}
90
-
91
-	if data["nickname"] != nil {
92
-		user.NickName = data["nickname"].(string)
93
-	}
94
-
95
-	if data["province"] != nil {
96
-		user.Province = data["province"].(string)
97
-	}
98
-
99
-	if data["city"] != nil {
100
-		user.City = data["city"].(string)
101
-	}
102
-
103
-	if data["country"] != nil {
104
-		user.Country = data["country"].(string)
105
-	}
106
-
107
-	if data["headimgurl"] != nil {
108
-		user.HeadImgURL = data["headimgurl"].(string)
109
-	}
110
-
111
-	if data["unionid"] != nil {
112
-		user.UnionID = data["unionid"].(string)
113
-	}
114
-
115
-	return &user
39
+// AppendWxClient 增加微信实例
40
+func AppendWxClient(wx *component.WxClient) {
41
+	Component.AppendWxClient(wx)
116 42
 }