wangfei 6 年前
父节点
当前提交
4e82e6d4f1
共有 4 个文件被更改,包括 109 次插入66 次删除
  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 查看文件

4
 	"bytes"
4
 	"bytes"
5
 	"encoding/base64"
5
 	"encoding/base64"
6
 	"encoding/json"
6
 	"encoding/json"
7
-	"io/ioutil"
8
 	"net/http"
7
 	"net/http"
9
 	"strings"
8
 	"strings"
10
 	"wechat-conf/models"
9
 	"wechat-conf/models"
25
 	BaseController
24
 	BaseController
26
 	serv       *autoreply.AutoreplyServ
25
 	serv       *autoreply.AutoreplyServ
27
 	wechatServ *wechat.WechatServ
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
 var nilData = []byte("success")
43
 var nilData = []byte("success")
31
 
44
 
32
 // Constructor 初始化 Controller
45
 // Constructor 初始化 Controller
35
 func (c *WechatController) Constructor() {
48
 func (c *WechatController) Constructor() {
36
 	c.serv = autoreply.NewAutoreplyServ(c.Context)
49
 	c.serv = autoreply.NewAutoreplyServ(c.Context)
37
 	c.wechatServ = wechat.NewWechatServ(c.Context)
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
 	if err != nil {
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
 		c.ResponseRaw(nilData)
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
 	if err != nil {
93
 	if err != nil {
81
-		utils.LogError("解密失败:", err)
94
+		utils.LogError("解密数据失败", err)
82
 		c.ResponseRaw(nilData)
95
 		c.ResponseRaw(nilData)
83
 	}
96
 	}
84
-	utils.LogError("解密成功")
97
+
98
+	receiveMessage := string(dt)
99
+	utils.LogInfo("解密内容: ", receiveMessage)
100
+
85
 	// 解析xml
101
 	// 解析xml
86
-	msg, err := xp.Parse(string(msgbyte))
102
+	xp := &core.XMLParse{}
103
+	data, err := xp.Parse(receiveMessage)
87
 	if err != nil {
104
 	if err != nil {
88
-		utils.LogError("xml解析失败:", err)
105
+		utils.LogError("解析解密数据失败:", err)
89
 		c.ResponseRaw(nilData)
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
 	case INFOTYPE_TICKET:
113
 	case INFOTYPE_TICKET:
114
+		// 微信测试推送 component_verify_ticket, 只需要返回 success
115
+		if fromWXOffice {
116
+			c.ResponseRaw(nilData)
117
+		}
118
+
94
 		// 更新ticket
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
 		if err != nil {
122
 		if err != nil {
98
 			utils.LogError("修改ticket失败:", err)
123
 			utils.LogError("修改ticket失败:", err)
99
 		}
124
 		}
100
-		utils.RefreshComponentTicket(msg["ComponentVerifyTicket"])
125
+		utils.RefreshComponentTicket(data["ComponentVerifyTicket"])
101
 		break
126
 		break
127
+
102
 	case INFOTYPE_AUTHORIZED:
128
 	case INFOTYPE_AUTHORIZED:
103
 		// 授权成功
129
 		// 授权成功
104
 		var cert = map[string]string{
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
 		wxclient := utils.WechatInit(cert, c.wechatServ.UpdateToken)
135
 		wxclient := utils.WechatInit(cert, c.wechatServ.UpdateToken)
110
 		if wxclient == nil {
136
 		if wxclient == nil {
111
 			utils.LogError("获取wxclient失败")
137
 			utils.LogError("获取wxclient失败")
112
 			c.ResponseRaw(nilData)
138
 			c.ResponseRaw(nilData)
113
 		}
139
 		}
114
-		beego.Error(wxclient)
140
+
115
 		utils.AppendWxClient(wxclient)
141
 		utils.AppendWxClient(wxclient)
116
 
142
 
117
 		// 获取微信信息
143
 		// 获取微信信息
120
 			utils.LogError("获取微信信息失败")
146
 			utils.LogError("获取微信信息失败")
121
 			c.ResponseRaw(nilData)
147
 			c.ResponseRaw(nilData)
122
 		}
148
 		}
123
-		beego.Error(info)
149
+
124
 		authorizerInfo := (info["authorizer_info"]).(map[string]interface{})
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
 		HeadImg := ""
154
 		HeadImg := ""
129
 		if authorizerInfo["head_img"] != nil {
155
 		if authorizerInfo["head_img"] != nil {
130
 			HeadImg = authorizerInfo["head_img"].(string)
156
 			HeadImg = authorizerInfo["head_img"].(string)
131
 		}
157
 		}
132
 		var conf = model.SysWechatConf{
158
 		var conf = model.SysWechatConf{
133
-			Appid:             msg["AuthorizerAppid"],
134
-			AuthorizationCode: msg["AuthorizationCode"],
159
+			Appid:             data["AuthorizerAppid"],
160
+			AuthorizationCode: data["AuthorizationCode"],
135
 			AuthorizationInfo: string(mjson),
161
 			AuthorizationInfo: string(mjson),
136
 			WxNikeName:        authorizerInfo["nick_name"].(string),
162
 			WxNikeName:        authorizerInfo["nick_name"].(string),
137
 			HeadImg:           HeadImg,
163
 			HeadImg:           HeadImg,
152
 	case INFOTYPE_UNAUTHORIZED:
178
 	case INFOTYPE_UNAUTHORIZED:
153
 		// 取消授权
179
 		// 取消授权
154
 		// 删除wechatConf信息,同时将org解绑
180
 		// 删除wechatConf信息,同时将org解绑
155
-		appid := msg["AuthorizerAppid"]
181
+		appid := data["AuthorizerAppid"]
156
 		c.wechatServ.UnAuthorized(appid)
182
 		c.wechatServ.UnAuthorized(appid)
157
 		// 删除第三方中的微信信息
183
 		// 删除第三方中的微信信息
158
 		utils.Component.DelWxClient(appid)
184
 		utils.Component.DelWxClient(appid)
159
 		break
185
 		break
160
 	}
186
 	}
187
+
161
 	c.ResponseRaw(nilData)
188
 	c.ResponseRaw(nilData)
162
 }
189
 }
163
 
190
 
175
 // WxReceive 微信消息接收
202
 // WxReceive 微信消息接收
176
 func (c *WechatController) WxReceive() {
203
 func (c *WechatController) WxReceive() {
177
 	utils.LogInfo("接收微信事件, URI: ", c.Ctx.Input.URI())
204
 	utils.LogInfo("接收微信事件, URI: ", c.Ctx.Input.URI())
205
+	c.preCheck(nilData)
178
 
206
 
179
 	// 初始化微信客户端
207
 	// 初始化微信客户端
180
 	appid := c.GetString(":appid")
208
 	appid := c.GetString(":appid")
184
 		c.ResponseRaw(nilData)
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
 	if err != nil {
217
 	if err != nil {
196
 		c.ResponseRaw(nilData)
218
 		c.ResponseRaw(nilData)
197
 	}
219
 	}
205
 	utils.LogInfo("反馈微信内容: ", string(replyMessage))
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
 	if err != nil {
231
 	if err != nil {
210
 		c.ResponseRaw(nilData)
232
 		c.ResponseRaw(nilData)
211
 	}
233
 	}
270
 }
292
 }
271
 
293
 
272
 // encryptReceiveMessage 加密需要发送的信息
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
 	// cipher, err := core.NewCipher("pamtest", "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFG", "wxb11529c136998cb6")
297
 	// cipher, err := core.NewCipher("pamtest", "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFG", "wxb11529c136998cb6")
276
 	if err != nil {
298
 	if err != nil {
277
 		utils.LogError("NewCipher 失败: " + err.Error())
299
 		utils.LogError("NewCipher 失败: " + err.Error())
295
 	from := receviceData["ToUserName"]
317
 	from := receviceData["ToUserName"]
296
 	openID := receviceData["FromUserName"]
318
 	openID := receviceData["FromUserName"]
297
 	appID := wechat.GetAppID()
319
 	appID := wechat.GetAppID()
320
+	fromWXOffice := openID == WX_OFFICE_TEST_USERNAME
298
 
321
 
299
 	// 暂时支持 文本以及订阅事件消息
322
 	// 暂时支持 文本以及订阅事件消息
300
 	switch msgType {
323
 	switch msgType {
301
 	case "text":
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
 			utils.LogError("获取微信自动回复信息失败: " + err.Error())
345
 			utils.LogError("获取微信自动回复信息失败: " + err.Error())
304
 			return
346
 			return
305
 		}
347
 		}

+ 1
- 1
models/models.go 查看文件

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

+ 1
- 0
service/sysorg/sysorg.go 查看文件

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

+ 1
- 1
service/user/user.go 查看文件

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