wangfei před 6 roky
rodič
revize
4e82e6d4f1
4 změnil soubory, kde provedl 109 přidání a 66 odebrání
  1. 106
    64
      controllers/component.go
  2. 1
    1
      models/models.go
  3. 1
    0
      service/sysorg/sysorg.go
  4. 1
    1
      service/user/user.go

+ 106
- 64
controllers/component.go Zobrazit soubor

@@ -4,7 +4,6 @@ import (
4 4
 	"bytes"
5 5
 	"encoding/base64"
6 6
 	"encoding/json"
7
-	"io/ioutil"
8 7
 	"net/http"
9 8
 	"strings"
10 9
 	"wechat-conf/models"
@@ -25,8 +24,22 @@ type WechatController struct {
25 24
 	BaseController
26 25
 	serv       *autoreply.AutoreplyServ
27 26
 	wechatServ *wechat.WechatServ
27
+	compConf   *model.SysComponentConf
28
+	cipher     core.IOCipher
28 29
 }
29 30
 
31
+const (
32
+	INFOTYPE_TICKET           = "component_verify_ticket"
33
+	INFOTYPE_AUTHORIZED       = "authorized"
34
+	INFOTYPE_UNAUTHORIZED     = "unauthorized"
35
+	INFOTYPE_UPDATEAUTHORIZED = "updateauthorized"
36
+)
37
+
38
+const (
39
+	WX_OFFICE_TEST_APPID    = "wx570bc396a51b8ff8"
40
+	WX_OFFICE_TEST_USERNAME = "gh_3c884a361561"
41
+)
42
+
30 43
 var nilData = []byte("success")
31 44
 
32 45
 // Constructor 初始化 Controller
@@ -35,83 +48,96 @@ var nilData = []byte("success")
35 48
 func (c *WechatController) Constructor() {
36 49
 	c.serv = autoreply.NewAutoreplyServ(c.Context)
37 50
 	c.wechatServ = wechat.NewWechatServ(c.Context)
38
-}
39 51
 
40
-const (
41
-	INFOTYPE_TICKET           = "component_verify_ticket"
42
-	INFOTYPE_AUTHORIZED       = "authorized"
43
-	INFOTYPE_UNAUTHORIZED     = "unauthorized"
44
-	INFOTYPE_UPDATEAUTHORIZED = "updateauthorized"
45
-)
52
+	var err error
53
+	c.compConf, err = c.wechatServ.GetComponentInfo()
54
+	if err != nil {
55
+		utils.LogError("获取平台配置失败", err)
56
+		return
57
+	}
46 58
 
47
-// ComponentPush 第三方平台推送
48
-func (c *WechatController) ComponentPush() {
49
-	utils.LogError("推送开始")
50
-	r := c.Ctx.Request
51
-	defer r.Body.Close()
52
-	con, _ := ioutil.ReadAll(r.Body)
53
-	utils.LogError("推送消息:", string(con))
54
-	// 解析xml
55
-	xp := &core.XMLParse{}
56
-	resMsg, err := xp.Parse(string(con))
59
+	c.cipher, err = core.NewCipher(c.compConf.OriginToken, c.compConf.Aeskey, c.compConf.Appid)
57 60
 	if err != nil {
58
-		utils.LogError("xml解析失败:", err)
59
-		c.ResponseRaw(nilData)
61
+		utils.LogError("初始化加解密算法失败", err)
62
+		return
60 63
 	}
61
-	encrypt := resMsg["Encrypt"]
62
-	conf, err := c.wechatServ.GetComponentInfo()
63
-	if err != nil || conf == nil || conf.Appid == "" {
64
-		utils.LogError("读取微信配置文件失败")
65
-		c.ResponseRaw(nilData)
64
+}
65
+
66
+// preCheck 如果有需要用到加解密之前, 请先调用这个方法
67
+func (c *WechatController) preCheck(resp []byte) {
68
+	if c.compConf == nil || c.compConf.Appid == "" {
69
+		c.ResponseRaw(resp)
66 70
 	}
67
-	EncodingAESKey := conf.Aeskey
68 71
 
69
-	AESKey, err := base64.StdEncoding.DecodeString(EncodingAESKey + "=")
70
-	if err != nil {
71
-		utils.LogError("DecodeString失败:", err)
72
-		c.ResponseRaw(nilData)
72
+	if c.cipher == nil {
73
+		c.ResponseRaw(resp)
73 74
 	}
74
-	EncryptVal, err := base64.StdEncoding.DecodeString(encrypt)
75
-	if err != nil {
76
-		utils.LogError("密文base64解析", err)
75
+}
76
+
77
+// ComponentPush 接收第三方平台推送
78
+// 主要有 ticket, 取消授权等
79
+func (c *WechatController) ComponentPush() {
80
+	utils.LogInfo("接收平台推送")
81
+	c.preCheck(nilData)
82
+
83
+	// 接收内容
84
+	receiveData := string(c.Ctx.Input.RequestBody)
85
+	utils.LogInfo("接收内容", receiveData)
86
+	if receiveData == "" {
77 87
 		c.ResponseRaw(nilData)
78 88
 	}
79
-	msgbyte, err := utils.AesDecrypt(EncryptVal, AESKey)
89
+
90
+	// 解密内容
91
+	r := bytes.NewBufferString(receiveData)
92
+	dt, err := c.cipher.Decrypt(r)
80 93
 	if err != nil {
81
-		utils.LogError("解密失败:", err)
94
+		utils.LogError("解密数据失败", err)
82 95
 		c.ResponseRaw(nilData)
83 96
 	}
84
-	utils.LogError("解密成功")
97
+
98
+	receiveMessage := string(dt)
99
+	utils.LogInfo("解密内容: ", receiveMessage)
100
+
85 101
 	// 解析xml
86
-	msg, err := xp.Parse(string(msgbyte))
102
+	xp := &core.XMLParse{}
103
+	data, err := xp.Parse(receiveMessage)
87 104
 	if err != nil {
88
-		utils.LogError("xml解析失败:", err)
105
+		utils.LogError("解析解密数据失败:", err)
89 106
 		c.ResponseRaw(nilData)
90 107
 	}
91
-	utils.LogError("xml解析成功:", msg)
92
-	switch msg["InfoType"] {
108
+
109
+	infoType := data["InfoType"]
110
+	fromWXOffice := data["AppId"] == WX_OFFICE_TEST_APPID
111
+
112
+	switch infoType {
93 113
 	case INFOTYPE_TICKET:
114
+		// 微信测试推送 component_verify_ticket, 只需要返回 success
115
+		if fromWXOffice {
116
+			c.ResponseRaw(nilData)
117
+		}
118
+
94 119
 		// 更新ticket
95
-		conf.Ticket = msg["ComponentVerifyTicket"]
96
-		err := c.wechatServ.UpdateComponentTicket(conf)
120
+		c.compConf.Ticket = data["ComponentVerifyTicket"]
121
+		err := c.wechatServ.UpdateComponentTicket(c.compConf)
97 122
 		if err != nil {
98 123
 			utils.LogError("修改ticket失败:", err)
99 124
 		}
100
-		utils.RefreshComponentTicket(msg["ComponentVerifyTicket"])
125
+		utils.RefreshComponentTicket(data["ComponentVerifyTicket"])
101 126
 		break
127
+
102 128
 	case INFOTYPE_AUTHORIZED:
103 129
 		// 授权成功
104 130
 		var cert = map[string]string{
105
-			"appid":              msg["AuthorizerAppid"],
106
-			"authorization_code": msg["AuthorizationCode"],
131
+			"appid":              data["AuthorizerAppid"],
132
+			"authorization_code": data["AuthorizationCode"],
107 133
 		}
108
-		beego.Error("授权成功参数:", cert)
134
+
109 135
 		wxclient := utils.WechatInit(cert, c.wechatServ.UpdateToken)
110 136
 		if wxclient == nil {
111 137
 			utils.LogError("获取wxclient失败")
112 138
 			c.ResponseRaw(nilData)
113 139
 		}
114
-		beego.Error(wxclient)
140
+
115 141
 		utils.AppendWxClient(wxclient)
116 142
 
117 143
 		// 获取微信信息
@@ -120,18 +146,18 @@ func (c *WechatController) ComponentPush() {
120 146
 			utils.LogError("获取微信信息失败")
121 147
 			c.ResponseRaw(nilData)
122 148
 		}
123
-		beego.Error(info)
149
+
124 150
 		authorizerInfo := (info["authorizer_info"]).(map[string]interface{})
125
-		beego.Error(info["authorizer_info"])
151
+
126 152
 		// 插入数据库
127
-		mjson, _ := json.Marshal(msg)
153
+		mjson, _ := json.Marshal(data)
128 154
 		HeadImg := ""
129 155
 		if authorizerInfo["head_img"] != nil {
130 156
 			HeadImg = authorizerInfo["head_img"].(string)
131 157
 		}
132 158
 		var conf = model.SysWechatConf{
133
-			Appid:             msg["AuthorizerAppid"],
134
-			AuthorizationCode: msg["AuthorizationCode"],
159
+			Appid:             data["AuthorizerAppid"],
160
+			AuthorizationCode: data["AuthorizationCode"],
135 161
 			AuthorizationInfo: string(mjson),
136 162
 			WxNikeName:        authorizerInfo["nick_name"].(string),
137 163
 			HeadImg:           HeadImg,
@@ -152,12 +178,13 @@ func (c *WechatController) ComponentPush() {
152 178
 	case INFOTYPE_UNAUTHORIZED:
153 179
 		// 取消授权
154 180
 		// 删除wechatConf信息,同时将org解绑
155
-		appid := msg["AuthorizerAppid"]
181
+		appid := data["AuthorizerAppid"]
156 182
 		c.wechatServ.UnAuthorized(appid)
157 183
 		// 删除第三方中的微信信息
158 184
 		utils.Component.DelWxClient(appid)
159 185
 		break
160 186
 	}
187
+
161 188
 	c.ResponseRaw(nilData)
162 189
 }
163 190
 
@@ -175,6 +202,7 @@ func (c *WechatController) WechatInfo() {
175 202
 // WxReceive 微信消息接收
176 203
 func (c *WechatController) WxReceive() {
177 204
 	utils.LogInfo("接收微信事件, URI: ", c.Ctx.Input.URI())
205
+	c.preCheck(nilData)
178 206
 
179 207
 	// 初始化微信客户端
180 208
 	appid := c.GetString(":appid")
@@ -184,14 +212,8 @@ func (c *WechatController) WxReceive() {
184 212
 		c.ResponseRaw(nilData)
185 213
 	}
186 214
 
187
-	conf, err := c.wechatServ.GetComponentInfo()
188
-	if err != nil || conf == nil || conf.Appid == "" {
189
-		utils.LogError("读取微信配置文件失败", err)
190
-		c.ResponseRaw(nilData)
191
-	}
192
-
193 215
 	// 校验接收数据
194
-	receiveData, err := c.validReceiveData(c.Ctx.Input.RequestBody, conf.Aeskey, wechat)
216
+	receiveData, err := c.validReceiveData(c.Ctx.Input.RequestBody, c.compConf.Aeskey, wechat)
195 217
 	if err != nil {
196 218
 		c.ResponseRaw(nilData)
197 219
 	}
@@ -205,7 +227,7 @@ func (c *WechatController) WxReceive() {
205 227
 	utils.LogInfo("反馈微信内容: ", string(replyMessage))
206 228
 
207 229
 	// 加密内容
208
-	sendData, err := c.encryptMessage(replyMessage, conf.Aeskey, conf.OriginToken, wechat)
230
+	sendData, err := c.encryptMessage(replyMessage, c.compConf.Aeskey, c.compConf.OriginToken, c.compConf.Appid, wechat)
209 231
 	if err != nil {
210 232
 		c.ResponseRaw(nilData)
211 233
 	}
@@ -270,8 +292,8 @@ func (c *WechatController) validReceiveData(receiveData []byte, aesKey string, w
270 292
 }
271 293
 
272 294
 // encryptReceiveMessage 加密需要发送的信息
273
-func (c *WechatController) encryptMessage(message []byte, aesKey, token string, wechat *component.WxClient) ([]byte, error) {
274
-	cipher, err := core.NewCipher(token, aesKey, wechat.GetAppID())
295
+func (c *WechatController) encryptMessage(message []byte, aesKey, token, appID string, wechat *component.WxClient) ([]byte, error) {
296
+	cipher, err := core.NewCipher(token, aesKey, appID)
275 297
 	// cipher, err := core.NewCipher("pamtest", "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFG", "wxb11529c136998cb6")
276 298
 	if err != nil {
277 299
 		utils.LogError("NewCipher 失败: " + err.Error())
@@ -295,11 +317,31 @@ func (c *WechatController) getReplayMessage(receviceData map[string]string, wech
295 317
 	from := receviceData["ToUserName"]
296 318
 	openID := receviceData["FromUserName"]
297 319
 	appID := wechat.GetAppID()
320
+	fromWXOffice := openID == WX_OFFICE_TEST_USERNAME
298 321
 
299 322
 	// 暂时支持 文本以及订阅事件消息
300 323
 	switch msgType {
301 324
 	case "text":
302
-		if replay, err = c.serv.GetAutoReplayByAppID(appID, receviceData["Content"]); err != nil {
325
+		content := receviceData["Content"]
326
+
327
+		// 微信文本消息测试
328
+		if fromWXOffice {
329
+			// 普通文本测试, 返回 TESTCOMPONENT_MSG_TYPE_TEXT_callback
330
+			if content == "TESTCOMPONENT_MSG_TYPE_TEXT" {
331
+				replay = &model.TaAutoReply{
332
+					MessageType:      models.MESSAGE_TYPE_PARAGRAPH,
333
+					MessageParagraph: "TESTCOMPONENT_MSG_TYPE_TEXT_callback",
334
+					IsUse:            models.AUTOREPLY_IS_USE_ON,
335
+				}
336
+
337
+				// 发送 query_auth_code , 返回空, 并立即调用客服接口
338
+			} else if strings.Index(content, "QUERY_AUTH_CODE") > -1 {
339
+				replay = nil
340
+			}
341
+			break
342
+		}
343
+
344
+		if replay, err = c.serv.GetAutoReplayByAppID(appID, content); err != nil {
303 345
 			utils.LogError("获取微信自动回复信息失败: " + err.Error())
304 346
 			return
305 347
 		}

+ 1
- 1
models/models.go Zobrazit soubor

@@ -22,7 +22,7 @@ func NewDBEngine() *xorm.Engine {
22 22
 	dns := getMySQLDNS()
23 23
 
24 24
 	engine, err := xorm.NewEngine(dbType, dns)
25
-	engine.ShowSQL()
25
+	// engine.ShowSQL()
26 26
 
27 27
 	if err != nil {
28 28
 		panic(err)

+ 1
- 0
service/sysorg/sysorg.go Zobrazit soubor

@@ -86,6 +86,7 @@ func (s *SysorgServ) DeleteOrg(orgId string) error {
86 86
 		utils.LogError("删除项目失败: " + err.Error())
87 87
 		return errors.New("删除项目失败")
88 88
 	}
89
+
89 90
 	if user != nil {
90 91
 		return errors.New("当前项目已被用户绑定,请先进行解绑操作")
91 92
 	}

+ 1
- 1
service/user/user.go Zobrazit soubor

@@ -26,13 +26,13 @@ func NewUserServ(ctx *utils.Context) *UserServ {
26 26
 
27 27
 // CheckUserRoute 判断用户理由
28 28
 func (s *UserServ) CheckUserRoute(userId, route, method string) (int, error) {
29
-
30 29
 	if strings.Index(route, "admin") < 0 {
31 30
 		return http.StatusOK, nil
32 31
 	}
33 32
 
34 33
 	// 如果没有登录
35 34
 	if userId == "" {
35
+		utils.LogError("当前 API", route)
36 36
 		return http.StatusUnauthorized, utils.LogError("请先登录系统")
37 37
 	}
38 38