wxlogin.go 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. package talent_service
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "github.com/gogf/gf/crypto/gmd5"
  6. "github.com/gogf/gf/frame/g"
  7. "github.com/gogf/gf/net/ghttp"
  8. "github.com/gogf/gf/os/gtime"
  9. "net/http"
  10. "youngmini_server/app/dao"
  11. "youngmini_server/app/model/talent_model"
  12. )
  13. type WxLoginResult struct {
  14. OpenId string `json:"openid"`
  15. SessionKey string `json:"session_key"`
  16. UnionId string `json:"unionid"`
  17. ErrCode int `json:"errcode"`
  18. ErrMsg string `json:"errmsg"`
  19. }
  20. const (
  21. urlformat = "https://api.weixin.qq.com/sns/jscode2session?appid=%s&secret=%s&js_code=%s&grant_type=authorization_code"
  22. )
  23. func WxLogin(r *ghttp.Request) *TalentHttpResult {
  24. l := talent_model.WxLoginInfo{}
  25. err := r.ParseForm(&l)
  26. if err != nil {
  27. return &TalentHttpResult{Code: -1, Msg: "param error"}
  28. }
  29. //if e := gvalid.CheckStruct(context.TODO(), l, nil); e != nil {
  30. // return &TalentHttpResult{Code: -2, Msg: "param invalid "}
  31. //}
  32. appId := g.Config().GetString("miniapp.appid")
  33. secret := g.Config().GetString("miniapp.appsecret")
  34. url := fmt.Sprintf(urlformat, appId, secret, l.Code)
  35. resp, err := http.Get(url)
  36. if err != nil {
  37. return &TalentHttpResult{Code: -2, Msg: err.Error()}
  38. }
  39. defer resp.Body.Close()
  40. // 解码微信服务端传来的信息
  41. wxResp := WxLoginResult{}
  42. decoder := json.NewDecoder(resp.Body)
  43. if err = decoder.Decode(&wxResp); err != nil {
  44. return &TalentHttpResult{Code: -3, Msg: "decode json from wx fail"}
  45. }
  46. if wxResp.ErrCode != 0 {
  47. return &TalentHttpResult{Code: -4, Msg: fmt.Sprintf("errCode:%d, errmsg:%s", wxResp.ErrCode, wxResp.ErrMsg)}
  48. }
  49. // 根据openid查询达人信息
  50. rec, err := g.DB().Model("talent_info").One("talent_wx_openid", wxResp.OpenId)
  51. if err != nil {
  52. return &TalentHttpResult{Code: -5, Msg: "get talent info failed"}
  53. }
  54. // 如果达人被拉黑,则返回
  55. if rec != nil && rec[dao.TalentInfo.Columns.InBlacklist].Int() > 0 {
  56. return &TalentHttpResult{Code: -6, Msg: "in black list"}
  57. }
  58. var newTalentId int64
  59. if rec == nil {
  60. // 如果数据库中不存在此达人,则插入新的达人信息
  61. newTalentId, err = g.DB().Model(dao.TalentInfo.Table).
  62. Data(g.Map{"talent_wx_openid": wxResp.OpenId, "last_login_date": gtime.Now(),
  63. "talent_wx_nickname": l.Nickname}).InsertAndGetId()
  64. if err != nil {
  65. return &TalentHttpResult{Code: -7, Msg: "add talent info failed"}
  66. }
  67. } else {
  68. // 如果已存在达人,则读取达人id
  69. newTalentId = rec["id"].Int64()
  70. // 更新达人最近登录时间
  71. _, err = g.DB().Model(dao.TalentInfo.Table).Data(
  72. g.Map{
  73. "last_login_date": gtime.Now(),
  74. }).Where("id", newTalentId).Update()
  75. if err != nil {
  76. return &TalentHttpResult{Code: -8, Msg: "update talent last login date failed"}
  77. }
  78. }
  79. // 用微信的openid和SessionKey的md5做为token
  80. token, err := gmd5.EncryptString(wxResp.OpenId + wxResp.SessionKey)
  81. if err != nil {
  82. return &TalentHttpResult{Code: -9, Msg: "generate key failed"}
  83. }
  84. // 以token为键保存session
  85. err = r.Session.Set(token, g.Map{
  86. "talentId": newTalentId,
  87. "wxOpenId": wxResp.OpenId,
  88. "wxSessionKey": wxResp.SessionKey,
  89. })
  90. if err != nil {
  91. return &TalentHttpResult{Code: -10, Msg: "set session failed"}
  92. }
  93. // 生成自己的session_key返回给小程序
  94. return &TalentHttpResult{Code: 0, Msg: "success", Data: talent_model.LoginResultData{Token: token}}
  95. }