wechat.go 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453
  1. package controllers
  2. import (
  3. "encoding/json"
  4. "encoding/xml"
  5. "fmt"
  6. "hongze/hongze_api/models"
  7. "hongze/hongze_api/services"
  8. "hongze/hongze_api/utils"
  9. "strconv"
  10. "time"
  11. )
  12. type WechatController struct {
  13. BaseAuthController
  14. }
  15. type WechatCommonController struct {
  16. BaseCommonController
  17. }
  18. // @Title 微信登录接口
  19. // @Description 微信登录接口
  20. // @Param Code query string true "微信唯一编码code"
  21. // @Success 200 {object} models.WxLoginResp
  22. // @router /login [get]
  23. func (this *WechatCommonController) WechatLogin() {
  24. br := new(models.BaseResponse).Init()
  25. defer func() {
  26. this.Data["json"] = br
  27. this.ServeJSON()
  28. }()
  29. resp := new(models.WxLoginResp)
  30. code := this.GetString("Code")
  31. fmt.Println("code:", code)
  32. utils.FileLog.Info("WechatLogin code:%s", code)
  33. wxCodeInfo, err := models.GetWxUserCode(code)
  34. if err == nil && wxCodeInfo != nil && wxCodeInfo.Id > 0 {
  35. utils.FileLog.Info("WechatLogin code exist:%s", code)
  36. resp.UserId = wxCodeInfo.UserId
  37. resp.Code = 0
  38. resp.FirstLogin = wxCodeInfo.FirstLogin
  39. resp.Authorization = wxCodeInfo.Authorization
  40. resp.UserPermission = wxCodeInfo.UserPermission
  41. br.Ret = 200
  42. br.Success = true
  43. br.Msg = "登录成功"
  44. br.Data = resp
  45. return
  46. }
  47. item, err := services.WxGetUserOpenIdByCode(code)
  48. if err != nil {
  49. br.Msg = "获取用户信息失败"
  50. br.ErrMsg = "获取用户信息失败,Err:" + err.Error()
  51. return
  52. }
  53. if item.Errcode != 0 {
  54. br.Msg = "获取用户信息失败"
  55. br.ErrMsg = "获取access_token 失败 errcode:" + strconv.Itoa(item.Errcode) + " ;errmsg:" + item.Errmsg
  56. return
  57. }
  58. openId := item.Openid
  59. if openId == "" {
  60. br.Msg = "获取用户信息失败"
  61. br.ErrMsg = "获取openid失败,openid:" + item.Openid
  62. return
  63. }
  64. accessToken, err := services.WxGetAccessToken()
  65. if err != nil {
  66. br.Msg = "获取用户信息失败"
  67. br.ErrMsg = "获取access_token失败,err:" + err.Error()
  68. return
  69. }
  70. //获取用户信息
  71. wxUserInfo, err := services.WxGetUserInfo(openId, accessToken)
  72. if err != nil {
  73. br.Msg = "获取用户信息失败"
  74. br.ErrMsg = "获取微信用户信息失败,Err:" + err.Error()
  75. return
  76. }
  77. if wxUserInfo.Errcode != 0 {
  78. userInfoJson, _ := json.Marshal(wxUserInfo)
  79. br.Msg = "登录失败"
  80. br.ErrMsg = "获取用户信息失败,err:" + string(userInfoJson)
  81. return
  82. }
  83. token, userId, firstLogin, permission, err := services.WxLogin(utils.WxPlatform, code, item, wxUserInfo)
  84. if err != nil {
  85. br.Msg = "微信登录失败"
  86. br.ErrMsg = "微信登录失败,err:" + err.Error()
  87. return
  88. }
  89. resp.UserId = userId
  90. resp.Code = 0
  91. resp.FirstLogin = firstLogin
  92. resp.Authorization = token
  93. resp.UserPermission = permission
  94. br.Ret = 200
  95. br.Success = true
  96. br.Msg = "登录成功"
  97. br.Data = resp
  98. //登录日志
  99. {
  100. returnResult, err := json.Marshal(br)
  101. if err != nil {
  102. utils.FileLog.Info(this.Ctx.Input.URI() + " Err:%s" + err.Error())
  103. }
  104. utils.FileLog.Info(this.Ctx.Input.URI()+" code: %s , return data: %s", code, string(returnResult))
  105. }
  106. }
  107. //作废于2021-03-29 10:14:54
  108. //func (this *WechatCommonController) WechatLoginV1() {
  109. // br := new(models.BaseResponse).Init()
  110. // defer func() {
  111. // this.Data["json"] = br
  112. // this.ServeJSON()
  113. // }()
  114. // resp := new(models.WxLoginResp)
  115. //
  116. // code := this.GetString("Code")
  117. // fmt.Println("code:", code)
  118. // utils.FileLog.Info("WechatLogin code:%s", code)
  119. // wxCodeInfo, err := models.GetWxUserCode(code)
  120. // if err == nil && wxCodeInfo != nil && wxCodeInfo.Id > 0 {
  121. // utils.FileLog.Info("WechatLogin code exist:%s", code)
  122. // resp.UserId = wxCodeInfo.UserId
  123. // resp.Code = 0
  124. // resp.FirstLogin = wxCodeInfo.FirstLogin
  125. // resp.Authorization = wxCodeInfo.Authorization
  126. // resp.UserPermission = wxCodeInfo.UserPermission
  127. // br.Ret = 200
  128. // br.Success = true
  129. // br.Msg = "登录成功"
  130. // br.Data = resp
  131. // return
  132. // }
  133. //
  134. // item, err := services.WxGetUserOpenIdByCode(code)
  135. // if err != nil {
  136. // br.Msg = "获取用户信息失败"
  137. // br.ErrMsg = "获取用户信息失败,Err:" + err.Error()
  138. // return
  139. // }
  140. // if item.Errcode != 0 {
  141. // br.Msg = "获取用户信息失败"
  142. // br.ErrMsg = "获取access_token 失败 errcode:" + strconv.Itoa(item.Errcode) + " ;errmsg:" + item.Errmsg
  143. // return
  144. // }
  145. // openId := item.Openid
  146. // accessToken, err := services.WxGetAccessToken()
  147. // if err != nil {
  148. // br.Msg = "获取用户信息失败"
  149. // br.ErrMsg = "获取access_token失败,err:" + err.Error()
  150. // return
  151. // }
  152. // //获取用户信息
  153. // wxUserInfo, err := services.WxGetUserInfo(openId, accessToken)
  154. // if err != nil {
  155. // br.Msg = "获取用户信息失败"
  156. // br.ErrMsg = "获取微信用户信息失败,Err:" + err.Error()
  157. // return
  158. // }
  159. // if wxUserInfo.Errcode != 0 {
  160. // userInfoJson, _ := json.Marshal(wxUserInfo)
  161. // br.Msg = "登录失败"
  162. // br.ErrMsg = "获取用户信息失败,err:" + string(userInfoJson)
  163. // return
  164. // }
  165. //
  166. // unionid := item.Unionid
  167. // if unionid == "" {
  168. // unionid = wxUserInfo.Unionid
  169. // }
  170. // firstLogin := 1
  171. // userId := 0
  172. // utils.FileLog.Info("openId:%s", openId)
  173. // utils.FileLog.Info("unionid:%s", unionid)
  174. // //获取成功
  175. // if openId != "" {
  176. // wxUser, err := models.GetWxUserItemByOpenId(openId)
  177. // if err != nil && err.Error() != utils.ErrNoRow() {
  178. // br.Msg = "获取用户信息失败"
  179. // br.ErrMsg = "根据openid获取用户信息失败,Eerr:" + err.Error()
  180. // return
  181. // }
  182. // if wxUser == nil || (err != nil && err.Error() == utils.ErrNoRow()) {
  183. // user := new(models.WxUser)
  184. // user.OpenId = openId
  185. // user.CompanyId = 1
  186. // user.CreatedTime = time.Now()
  187. // user.UnionId = unionid
  188. // user.Unionid = unionid
  189. // user.NickName = wxUserInfo.Nickname
  190. // user.Sex = wxUserInfo.Sex
  191. // user.City = wxUserInfo.City
  192. // user.Province = wxUserInfo.Province
  193. // user.Country = wxUserInfo.Country
  194. // user.Headimgurl = wxUserInfo.Headimgurl
  195. // user.FirstLogin = 1
  196. // user.Enabled = 1
  197. // user.RegisterPlatform = 1
  198. // user.RegisterTime = time.Now()
  199. // _, err = models.AddWxUser(user)
  200. // wxUser, err = models.GetWxUserItemByOpenId(openId)
  201. // if err != nil {
  202. // br.Msg = "获取用户信息失败"
  203. // br.ErrMsg = "unionid登录,获取微信用户信息失败,Err:" + err.Error()
  204. // return
  205. // }
  206. // userId = wxUser.UserId
  207. // } else {
  208. // firstLogin = wxUser.FirstLogin
  209. // userId = wxUser.UserId
  210. // }
  211. // } else {
  212. // br.Msg = "获取用户信息失败"
  213. // br.ErrMsg = "获取openid失败,openid:" + item.Openid
  214. // return
  215. // }
  216. // permission, err := services.CheckUserPermission(userId)
  217. // if err != nil {
  218. // utils.FileLog.Info("userId:%s,err:%s", strconv.Itoa(userId), err)
  219. // }
  220. // //if err != nil {
  221. // // br.Msg = "登录失败"
  222. // // br.ErrMsg = "登录失败,判断权限失败:" + err.Error()
  223. // // return
  224. // //}
  225. // var token string
  226. // tokenItem, err := models.GetTokenByUid(userId)
  227. // if err != nil && err.Error() != utils.ErrNoRow() {
  228. // br.Msg = "登录失败"
  229. // br.ErrMsg = "登录失败,获取token失败:" + err.Error()
  230. // return
  231. // }
  232. //
  233. // if tokenItem == nil || (err != nil && err.Error() == utils.ErrNoRow()) {
  234. // timeUnix := time.Now().Unix()
  235. // timeUnixStr := strconv.FormatInt(timeUnix, 10)
  236. // token = utils.MD5(strconv.Itoa(userId)) + utils.MD5(timeUnixStr)
  237. // //新增session
  238. // {
  239. // session := new(models.Session)
  240. // session.OpenId = openId
  241. // session.UserId = userId
  242. // session.CreatedTime = time.Now()
  243. // session.LastUpdatedTime = time.Now()
  244. // session.ExpireTime = time.Now().AddDate(0, 3, 0)
  245. // session.AccessToken = token
  246. // err = models.AddSession(session)
  247. // if err != nil {
  248. // br.Msg = "登录失败"
  249. // br.ErrMsg = "登录失败,新增用户session信息失败:" + err.Error()
  250. // return
  251. // }
  252. // }
  253. // } else {
  254. // token = tokenItem.AccessToken
  255. // }
  256. //
  257. // if wxUserInfo != nil {
  258. // go models.ModifyWxUserInfo(wxUserInfo.Nickname, wxUserInfo.Headimgurl, wxUserInfo.City, wxUserInfo.Province, wxUserInfo.Country, wxUserInfo.Sex, userId)
  259. // }
  260. // //firstLogin==1,强制绑定手机号或者邮箱
  261. // {
  262. // newItem, _ := models.GetWxUserItemByUserId(userId)
  263. // if newItem.Mobile == "" && newItem.Email == "" {
  264. // firstLogin = 1
  265. // }
  266. // }
  267. // //新增登录日志
  268. // {
  269. // loginLog := new(models.WxUserLog)
  270. // loginLog.UserId = userId
  271. // loginLog.OpenId = openId
  272. // loginLog.UnionId = unionid
  273. // loginLog.CreateTime = time.Now()
  274. // loginLog.Handle = "wechat_login"
  275. // loginLog.Remark = token
  276. // go models.AddWxUserLog(loginLog)
  277. // }
  278. //
  279. // {
  280. // codeLog := new(models.WxUserCode)
  281. // codeLog.WxCode = code
  282. // codeLog.UserId = userId
  283. // codeLog.Code = 0
  284. // codeLog.FirstLogin = firstLogin
  285. // codeLog.Authorization = token
  286. // codeLog.UserPermission = permission
  287. // codeLog.CreateTime=time.Now()
  288. // models.AddWxUserCode(codeLog)
  289. // }
  290. //
  291. // resp.UserId = userId
  292. // resp.Code = 0
  293. // resp.FirstLogin = firstLogin
  294. // resp.Authorization = token
  295. // resp.UserPermission = permission
  296. // br.Ret = 200
  297. // br.Success = true
  298. // br.Msg = "登录成功"
  299. // br.Data = resp
  300. // //登录日志
  301. // {
  302. // returnResult, err := json.Marshal(br)
  303. // if err != nil {
  304. // utils.FileLog.Info(this.Ctx.Input.URI() + " Err:%s" + err.Error())
  305. // }
  306. // utils.FileLog.Info(this.Ctx.Input.URI()+" code: %s , return data: %s", code, string(returnResult))
  307. // }
  308. //}
  309. // @Title 微信获取签名接口
  310. // @Description 微信获取签名接口
  311. // @Param Url query string true "url地址"
  312. // @Success 200 {object} models.WechatSign
  313. // @router /getWxSign [get]
  314. func (this *WechatController) GetWxSign() {
  315. br := new(models.BaseResponse).Init()
  316. defer func() {
  317. this.Data["json"] = br
  318. this.ServeJSON()
  319. }()
  320. getUrl := this.GetString("Url")
  321. fmt.Println("getUrl:", getUrl)
  322. accessToken, err := services.WxGetAccessToken()
  323. if err != nil {
  324. br.Msg = "获取用户信息失败"
  325. br.ErrMsg = "获取access_token失败,err:" + err.Error()
  326. return
  327. }
  328. ticket, err := services.GetWxTicket(accessToken)
  329. if err != nil {
  330. br.Msg = "获取Ticket失败,请联系客服"
  331. br.ErrMsg = "获取Ticket失败,Err" + err.Error()
  332. return
  333. }
  334. if ticket == "" {
  335. br.Msg = "获取Ticket失败,请联系客服"
  336. br.ErrMsg = "ticket为空" + ticket
  337. return
  338. }
  339. nonceStr := utils.GetRandStringNoSpecialChar(16)
  340. signature, nonceString, timestamp := services.GetWxSignature(ticket, getUrl, nonceStr)
  341. resp := new(models.WechatSign)
  342. resp.AppId = utils.WxAppId
  343. resp.NonceStr = nonceString
  344. resp.Timestamp = timestamp
  345. resp.Url = getUrl
  346. resp.Signature = signature
  347. br.Ret = 200
  348. br.Success = true
  349. br.Msg = "获取签名成功"
  350. br.Data = resp
  351. }
  352. // @Title 微信获取签名接口
  353. // @Description 微信获取签名接口
  354. // @Param Url query string true "url地址"
  355. // @Success 200 {object} models.WechatSign
  356. // @router /notify [get,post]
  357. func (this *WechatCommonController) Notify() {
  358. echostr := this.GetString("echostr")
  359. method := this.Ctx.Input.Method()
  360. if method == "POST" {
  361. body := this.Ctx.Input.RequestBody
  362. utils.FileLog.Info("wechat notify:" + string(body))
  363. item := new(Notify)
  364. err := xml.Unmarshal(body, &item)
  365. if err != nil {
  366. utils.FileLog.Info("xml.Unmarshal:" + err.Error())
  367. }
  368. contactMsg := "感谢关注弘则研究。\r\n公司地址:上海市世纪大道210号21世纪中心大厦12层1206室\r\n\r\n业务合作:\r\n电话:86-21-61645300\r\n邮箱:service@hzinsights.com\r\n邮编:200120\r\n\r\n海外业务:\r\n邮箱:yyu@hzinsights.com "
  369. var openId, returnResult string
  370. if item.MsgType != "" {
  371. openId = item.FromUserName
  372. }
  373. xmlTpl := `<xml>
  374. <ToUserName><![CDATA[%s]]></ToUserName>
  375. <FromUserName><![CDATA[%s]]></FromUserName>
  376. <CreateTime>%s</CreateTime>
  377. <MsgType><![CDATA[text]]></MsgType>
  378. <Content><![CDATA[%s]]></Content>
  379. </xml>`
  380. createTime := strconv.FormatInt(time.Now().Unix(), 10)
  381. xmlTpl = fmt.Sprintf(xmlTpl, openId, utils.WxId, createTime, contactMsg)
  382. if item.MsgType == "event" {
  383. switch item.Event {
  384. case "subscribe":
  385. fmt.Println("关注")
  386. go models.UserSubscribe(1, openId)
  387. break
  388. case "unsubscribe":
  389. fmt.Println("取消关注")
  390. go models.UserSubscribe(0, openId)
  391. break
  392. case "CLICK":
  393. returnResult = xmlTpl
  394. break
  395. default:
  396. utils.FileLog.Info("wechat notify event:" + item.Event)
  397. }
  398. this.Ctx.WriteString(xmlTpl)
  399. } else {
  400. returnResult = xmlTpl
  401. }
  402. this.Ctx.WriteString(returnResult)
  403. } else {
  404. this.Ctx.WriteString(echostr)
  405. }
  406. }
  407. type Notify struct {
  408. ToUserName string `xml:"ToUserName"`
  409. FromUserName string `xml:"FromUserName"`
  410. CreateTime int `xml:"CreateTime"`
  411. MsgType string `xml:"MsgType"`
  412. Event string `xml:"Event"`
  413. EventKey string `xml:"EventKey"`
  414. }
  415. //func init() {
  416. // str := `<xml><ToUserName><![CDATA[gh_5dc508325c6f]]></ToUserName>
  417. //<FromUserName><![CDATA[oN0jD1eTfIAf68Y2n24RrvIGXFw4]]></FromUserName>
  418. //<CreateTime>1654671283</CreateTime>
  419. //<MsgType><![CDATA[event]]></MsgType>
  420. //<Event><![CDATA[subscribe]]></Event>
  421. //<EventKey><![CDATA[]]></EventKey>
  422. //</xml>`
  423. //
  424. // item := new(Notify)
  425. // err := xml.Unmarshal([]byte(str), &item)
  426. // if err != nil {
  427. // fmt.Println(err.Error())
  428. // }
  429. // fmt.Println(item.ToUserName)
  430. // fmt.Println(item.FromUserName)
  431. // fmt.Println(item.CreateTime)
  432. // fmt.Println(item.MsgType)
  433. // fmt.Println(item.Event)
  434. // fmt.Println(item.EventKey)
  435. //}