wechat.go 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413
  1. package controllers
  2. import (
  3. "encoding/json"
  4. "encoding/xml"
  5. "eta/eta_mini_api/models"
  6. "eta/eta_mini_api/models/request"
  7. "eta/eta_mini_api/models/response"
  8. "eta/eta_mini_api/services/alarm_msg"
  9. "eta/eta_mini_api/services/wechat"
  10. "eta/eta_mini_api/services/wx_app"
  11. "eta/eta_mini_api/utils"
  12. "fmt"
  13. "strconv"
  14. "time"
  15. )
  16. type WechatController struct {
  17. BaseCommonController
  18. }
  19. type Notify struct {
  20. ToUserName string `xml:"ToUserName"`
  21. FromUserName string `xml:"FromUserName"`
  22. CreateTime int `xml:"CreateTime"`
  23. MsgType string `xml:"MsgType"`
  24. Event string `xml:"Event"`
  25. EventKey string `xml:"EventKey"`
  26. Content string `xml:"Content"`
  27. }
  28. // @Title 微信获取签名接口
  29. // @Description 微信获取签名接口
  30. // @Param Url query string true "url地址"
  31. // @Success 200 {object} models.WechatSign
  32. // @router /notify [get,post]
  33. func (this *WechatController) Notify() {
  34. echostr := this.GetString("echostr")
  35. method := this.Ctx.Input.Method()
  36. if method == "POST" {
  37. body := this.Ctx.Input.RequestBody
  38. utils.FileLog.Info("wechat notify:" + string(body))
  39. item := new(Notify)
  40. err := xml.Unmarshal(body, &item)
  41. if err != nil {
  42. utils.FileLog.Info("xml.Unmarshal:" + err.Error())
  43. }
  44. contactMsg := "感谢关注东吴期货研究所\r\n公司地址:上海市黄浦区西藏南路1208号东吴证券大厦19楼\r\n\r\n业务合作:\r\n电话:021-6312 3065\r\n邮箱:lvan@dwqh88.com\r\n邮编:200001"
  45. var openId, returnResult string
  46. if item.MsgType != "" {
  47. openId = item.FromUserName
  48. }
  49. xmlTpl := `<xml>
  50. <ToUserName><![CDATA[%s]]></ToUserName>
  51. <FromUserName><![CDATA[%s]]></FromUserName>
  52. <CreateTime>%s</CreateTime>
  53. <MsgType><![CDATA[text]]></MsgType>
  54. <Content><![CDATA[%s]]></Content>
  55. </xml>`
  56. createTime := strconv.FormatInt(time.Now().Unix(), 10)
  57. // WxId := "gh_5dc508325c6f" // 弘则投研公众号原始id
  58. xmlTpl = fmt.Sprintf(xmlTpl, openId, utils.DW_WX_Id, createTime, contactMsg)
  59. if item.MsgType == "event" {
  60. switch item.Event {
  61. case "subscribe":
  62. fmt.Println("关注")
  63. go subscribe(openId)
  64. case "unsubscribe":
  65. fmt.Println("取消关注")
  66. go unsubscribe(openId)
  67. case "CLICK":
  68. returnResult = xmlTpl
  69. default:
  70. utils.FileLog.Info("wechat notify event:" + item.Event)
  71. }
  72. this.Ctx.WriteString(xmlTpl)
  73. } else {
  74. returnResult = xmlTpl
  75. }
  76. this.Ctx.WriteString(returnResult)
  77. } else {
  78. this.Ctx.WriteString(echostr)
  79. }
  80. }
  81. // subscribe 关注后的处理逻辑
  82. func subscribe(openId string) {
  83. userRecord, err := models.GetUserRecordByOpenId(openId)
  84. if err != nil && err.Error() != utils.ErrNoRow() {
  85. utils.FileLog.Info("通过openid获取user_record记录失败,err:" + err.Error())
  86. return
  87. }
  88. // openId已存在
  89. if userRecord != nil {
  90. if userRecord.UserId > 0 && userRecord.UnionId != "" { //已经绑定了的话,那么就去修改用户状态
  91. err = models.UserSubscribe(1, openId)
  92. if err != nil {
  93. utils.FileLog.Info("关注后,通过openid修改user_record异常,err:" + err.Error())
  94. }
  95. user, err := models.GetUserByUnionId(userRecord.UnionId)
  96. if err != nil {
  97. utils.FileLog.Info("关注后,通过unionid获取user记录失败,err:" + err.Error())
  98. return
  99. }
  100. if user != nil {
  101. user.IsSubscribed = true
  102. user.ModifyTime = time.Now()
  103. err = user.Update([]string{"modify_time", "is_subscribed"})
  104. if err != nil {
  105. utils.FileLog.Info("关注后,修改绑定用户状态异常,err:" + err.Error())
  106. return
  107. }
  108. userRecord.UserId = user.UserId
  109. err = userRecord.Update([]string{"user_id"})
  110. if err != nil {
  111. utils.FileLog.Info("关注后,修改公众号绑定用户异常,err:" + err.Error())
  112. return
  113. }
  114. }
  115. } else {
  116. // 没有绑定的话,那么校验下unionid,然后再去修改
  117. unionId := userRecord.UnionId
  118. if unionId == `` {
  119. wxUserItem, err := wechat.GetUserInfo(openId)
  120. if err != nil {
  121. utils.FileLog.Info("获取用户信息失败,err:" + err.Error())
  122. return
  123. }
  124. if wxUserItem.UnionID != `` {
  125. unionId = wxUserItem.UnionID
  126. }
  127. }
  128. userRecord.UnionId = unionId
  129. userRecord.Subscribe = 1
  130. userRecord.SubscribeTime = time.Now()
  131. err = userRecord.Update([]string{"union_id", "subscribe", "subscribe_time"})
  132. if err != nil {
  133. utils.FileLog.Info("关注后,通过openid更新user_record异常,err:" + err.Error())
  134. return
  135. }
  136. user, err := models.GetUserByUnionId(unionId)
  137. if err != nil {
  138. utils.FileLog.Info("关注后,通过unionid获取user记录失败,err:" + err.Error())
  139. return
  140. }
  141. if user != nil {
  142. user.IsSubscribed = true
  143. user.ModifyTime = time.Now()
  144. err = user.Update([]string{"modify_time", "is_subscribed"})
  145. if err != nil {
  146. utils.FileLog.Info("关注后,修改绑定用户状态异常,err:" + err.Error())
  147. return
  148. }
  149. userRecord.UserId = user.UserId
  150. err = userRecord.Update([]string{"user_id"})
  151. if err != nil {
  152. utils.FileLog.Info("关注后,修改公众号绑定用户异常,err:" + err.Error())
  153. return
  154. }
  155. }
  156. }
  157. return
  158. }
  159. // 没有记录,那么需要获取下unionid
  160. wxUserItem, err := wechat.GetUserInfo(openId)
  161. if err != nil {
  162. utils.FileLog.Info("获取用户信息失败,err:" + err.Error())
  163. return
  164. }
  165. newUserRecord := &models.UserRecord{
  166. OpenId: openId,
  167. UnionId: wxUserItem.UnionID,
  168. Subscribe: 1,
  169. SubscribeTime: time.Now(),
  170. NickName: wxUserItem.Nickname,
  171. Sex: int(wxUserItem.Sex),
  172. Province: wxUserItem.Province,
  173. City: wxUserItem.City,
  174. Country: wxUserItem.Country,
  175. Headimgurl: wxUserItem.Headimgurl,
  176. CreateTime: time.Now(),
  177. }
  178. insertId, err := newUserRecord.Insert()
  179. newUserRecord.UserRecordId = int(insertId)
  180. if err != nil {
  181. utils.FileLog.Info("关注后,添加user_record信息失败,err:" + err.Error())
  182. return
  183. }
  184. // 检测用户是否绑定小程序,如果绑定修改用户状态
  185. user, err := models.GetUserByUnionId(newUserRecord.UnionId)
  186. if err != nil {
  187. utils.FileLog.Info("修改绑定用户状态异常,err:" + err.Error())
  188. return
  189. }
  190. if user != nil {
  191. user.IsSubscribed = true
  192. user.ModifyTime = time.Now()
  193. err = user.Update([]string{"is_subscribed", "modify_time"})
  194. if err != nil {
  195. utils.FileLog.Info("关注后,修改绑定用户状态异常,err:" + err.Error())
  196. return
  197. }
  198. newUserRecord.UserId = user.UserId
  199. err = newUserRecord.Update([]string{"user_id"})
  200. if err != nil {
  201. utils.FileLog.Info("关注后,修改公众号绑定用户异常,err:" + err.Error())
  202. return
  203. }
  204. }
  205. }
  206. // unsubscribe 取消关注后的处理逻辑
  207. func unsubscribe(openId string) {
  208. userRecord, err := models.GetUserRecordByOpenId(openId)
  209. if err != nil {
  210. return
  211. }
  212. userRecord.Subscribe = 0
  213. err = userRecord.Update([]string{"subscribe"})
  214. if err != nil {
  215. return
  216. }
  217. if userRecord.UnionId != "" {
  218. user, err := models.GetUserByUnionId(userRecord.UnionId)
  219. if err != nil {
  220. return
  221. }
  222. if user != nil {
  223. user.IsSubscribed = false
  224. user.ModifyTime = time.Now()
  225. err = user.Update([]string{"is_subscribed", "modify_time"})
  226. if err != nil {
  227. return
  228. }
  229. }
  230. }
  231. }
  232. // @Title 微信登录
  233. // @Description 微信登录
  234. // @Param request body models.LoginReq true "type json string"
  235. // @Success 200 {object} models.LoginResp
  236. // @router /login [post]
  237. func (this *WechatController) Login() {
  238. br := new(models.BaseResponse).Init()
  239. defer func() {
  240. if err := recover(); err != nil {
  241. fmt.Println(err)
  242. }
  243. this.Data["json"] = br
  244. this.ServeJSON()
  245. }()
  246. var req request.WeChatLoginReq
  247. err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
  248. if err != nil {
  249. br.Msg = "参数解析失败"
  250. br.ErrMsg = "参数解析失败,Err:" + err.Error()
  251. return
  252. }
  253. if req.Code == "" {
  254. br.Msg = "授权码不存在"
  255. return
  256. }
  257. userInfo, err := wx_app.GetSession(req.Code)
  258. if err != nil {
  259. br.Msg = "登录失败,请重新尝试"
  260. br.ErrMsg = "用户信息获取失败,系统错误,Err:" + err.Error()
  261. return
  262. }
  263. session, err := models.GetWxSessionByOpenId(userInfo.OpenID)
  264. if err != nil && err.Error() != utils.ErrNoRow() {
  265. br.Msg = "登录失败,请重新尝试"
  266. br.ErrMsg = "用户信息获取失败,系统错误,Err:" + err.Error()
  267. return
  268. }
  269. if session == nil {
  270. session = &models.WxSession{
  271. OpenId: userInfo.OpenID,
  272. UnionId: userInfo.UnionID,
  273. CreateTime: time.Now(),
  274. }
  275. insertId, er := session.Insert()
  276. session.WxSessionId = int(insertId)
  277. if er != nil {
  278. br.Msg = "用户登录失败"
  279. br.ErrMsg = "用户登录获取失败,系统错误,Err:" + er.Error()
  280. return
  281. }
  282. }
  283. var token string
  284. timeUnix := time.Now().Unix()
  285. timeUnixStr := strconv.FormatInt(timeUnix, 10)
  286. token = utils.MD5(session.OpenId) + utils.MD5(timeUnixStr)
  287. session.AccessToken = token
  288. session.LastUpdateTime = time.Now()
  289. err = session.Update([]string{"access_token", "last_update_time"})
  290. if err != nil {
  291. br.Msg = "微信登录失败"
  292. br.ErrMsg = "微信登录失败,更新用户信息失败:" + err.Error()
  293. return
  294. }
  295. token = session.AccessToken
  296. resp := new(response.WeChatLoginResp)
  297. resp.Authorization = token
  298. br.Data = resp
  299. br.Msg = "登录成功"
  300. br.Success = true
  301. br.Ret = 200
  302. }
  303. // @Title 公众号绑定
  304. // @Description 公众号绑定
  305. // @Param request body request.WeChatLoginReq true "type json string"
  306. // @Success 200 {object} models.LoginResp
  307. // @router /subscribe [post]
  308. func (this *WechatController) Subscribe() {
  309. br := new(models.BaseResponse).Init()
  310. defer func() {
  311. if br.Ret != 200 {
  312. b, _ := json.Marshal(br)
  313. alarm_msg.SendAlarmMsg(string(b), 1)
  314. }
  315. this.Data["json"] = br
  316. this.ServeJSON()
  317. }()
  318. var req request.WeChatLoginReq
  319. err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
  320. if err != nil {
  321. br.Msg = "参数解析失败"
  322. br.ErrMsg = "参数解析失败,Err:" + err.Error()
  323. return
  324. }
  325. if req.Code == "" {
  326. br.Msg = "授权码不存在"
  327. return
  328. }
  329. info, err := wechat.GetWxUserInfo(req.Code)
  330. if err != nil {
  331. br.Msg = "获取失败"
  332. br.ErrMsg = "获取失败,Err:" + err.Error()
  333. return
  334. }
  335. if info.ErrCode != 0 {
  336. br.Msg = "获取失败"
  337. br.ErrMsg = "获取失败,Err:" + info.ErrMsg
  338. return
  339. }
  340. userRecord, err := models.GetUserRecordByOpenId(info.OpenId)
  341. if err != nil && err.Error() != utils.ErrNoRow() {
  342. br.Msg = "获取用户关注记录失败"
  343. br.ErrMsg = "获取用户关注记录失败,Err:" + err.Error()
  344. return
  345. }
  346. // 如果不存在就新增一条记录
  347. if userRecord == nil {
  348. userRecord := &models.UserRecord{
  349. OpenId: info.OpenId,
  350. }
  351. insertId, err := userRecord.Insert()
  352. if err != nil {
  353. br.Msg = "新增失败"
  354. br.ErrMsg = "新增失败,Err:" + err.Error()
  355. return
  356. }
  357. userRecord.UserRecordId = int(insertId)
  358. }
  359. if userRecord.UnionId == "" {
  360. wxInfo, er := wechat.GetUserInfo(userRecord.OpenId)
  361. if er != nil {
  362. br.Msg = "获取失败"
  363. br.ErrMsg = "获取失败,Err:" + er.Error()
  364. return
  365. }
  366. userRecord.UnionId = wxInfo.UnionID
  367. er = userRecord.Update([]string{"union_id"})
  368. if er != nil {
  369. br.Msg = "获取失败"
  370. br.ErrMsg = "获取失败,Err:" + er.Error()
  371. return
  372. }
  373. }
  374. user, err := models.GetUserByUnionId(userRecord.UnionId)
  375. if err != nil && err.Error() != utils.ErrNoRow() {
  376. br.Msg = "获取用户信息失败"
  377. br.ErrMsg = "获取用户信息失败,Err:" + err.Error()
  378. return
  379. }
  380. if user != nil {
  381. user.IsSubscribed = true
  382. err := user.Update([]string{"is_subscribed"})
  383. if err != nil {
  384. br.Msg = "更新用户信息失败"
  385. br.ErrMsg = "更新用户信息失败,Err:" + err.Error()
  386. return
  387. }
  388. userRecord.UserId = user.UserId
  389. userRecord.Update([]string{"user_id"})
  390. }
  391. br.Msg = "获取成功"
  392. br.Success = true
  393. br.Ret = 200
  394. }