package controllers import ( "encoding/json" "encoding/xml" "fmt" "hongze/hongze_api/models" "hongze/hongze_api/services" "hongze/hongze_api/services/wechat" "hongze/hongze_api/utils" "strconv" "strings" "time" ) type WechatController struct { BaseAuthController } type WechatCommonController struct { BaseCommonController } // @Title 微信登录接口 // @Description 微信登录接口 // @Param Code query string true "微信唯一编码code" // @Success 200 {object} models.WxLoginResp // @router /login [get] func (this *WechatCommonController) WechatLogin() { br := new(models.BaseResponse).Init() defer func() { this.Data["json"] = br this.ServeJSON() }() resp := new(models.WxLoginResp) code := this.GetString("Code") fmt.Println("code:", code) utils.FileLog.Info("WechatLogin code:%s", code) wxCodeInfo, err := models.GetWxUserCode(code) if err == nil && wxCodeInfo != nil && wxCodeInfo.Id > 0 { utils.FileLog.Info("WechatLogin code exist:%s", code) resp.UserId = wxCodeInfo.UserId resp.Code = 0 resp.FirstLogin = wxCodeInfo.FirstLogin resp.Authorization = wxCodeInfo.Authorization resp.UserPermission = wxCodeInfo.UserPermission br.Ret = 200 br.Success = true br.Msg = "登录成功" br.Data = resp return } item, err := services.WxGetUserOpenIdByCode(code) if err != nil { br.Msg = "获取用户信息失败" br.ErrMsg = "获取用户信息失败,Err:" + err.Error() return } if item.Errcode != 0 { br.Msg = "获取用户信息失败" br.ErrMsg = "获取access_token 失败 errcode:" + strconv.Itoa(item.Errcode) + " ;errmsg:" + item.Errmsg return } openId := item.Openid if openId == "" { br.Msg = "获取用户信息失败" br.ErrMsg = "获取openid失败,openid:" + item.Openid return } accessToken, err, errMsg := services.GetDefaultWxAccessToken() if err != nil { br.Msg = "获取用户信息失败" br.ErrMsg = errMsg return } //获取用户信息 wxUserInfo, err := services.WxGetUserInfo(openId, accessToken) if err != nil { br.Msg = "获取用户信息失败" br.ErrMsg = "获取微信用户信息失败,Err:" + err.Error() return } if wxUserInfo.Errcode != 0 { userInfoJson, _ := json.Marshal(wxUserInfo) br.Msg = "登录失败" br.ErrMsg = "获取用户信息失败,err:" + string(userInfoJson) return } token, userId, firstLogin, permission, err := services.WxLogin(utils.WxPlatform, code, item, wxUserInfo) if err != nil { br.Msg = "微信登录失败" br.ErrMsg = "微信登录失败,err:" + err.Error() return } resp.UserId = userId resp.Code = 0 resp.FirstLogin = firstLogin resp.Authorization = token resp.UserPermission = permission br.Ret = 200 br.Success = true br.Msg = "登录成功" br.Data = resp //登录日志 { returnResult, err := json.Marshal(br) if err != nil { utils.FileLog.Info(this.Ctx.Input.URI() + " Err:%s" + err.Error()) } utils.FileLog.Info(this.Ctx.Input.URI()+" code: %s , return data: %s", code, string(returnResult)) } } //作废于2021-03-29 10:14:54 //func (this *WechatCommonController) WechatLoginV1() { // br := new(models.BaseResponse).Init() // defer func() { // this.Data["json"] = br // this.ServeJSON() // }() // resp := new(models.WxLoginResp) // // code := this.GetString("Code") // fmt.Println("code:", code) // utils.FileLog.Info("WechatLogin code:%s", code) // wxCodeInfo, err := models.GetWxUserCode(code) // if err == nil && wxCodeInfo != nil && wxCodeInfo.Id > 0 { // utils.FileLog.Info("WechatLogin code exist:%s", code) // resp.UserId = wxCodeInfo.UserId // resp.Code = 0 // resp.FirstLogin = wxCodeInfo.FirstLogin // resp.Authorization = wxCodeInfo.Authorization // resp.UserPermission = wxCodeInfo.UserPermission // br.Ret = 200 // br.Success = true // br.Msg = "登录成功" // br.Data = resp // return // } // // item, err := services.WxGetUserOpenIdByCode(code) // if err != nil { // br.Msg = "获取用户信息失败" // br.ErrMsg = "获取用户信息失败,Err:" + err.Error() // return // } // if item.Errcode != 0 { // br.Msg = "获取用户信息失败" // br.ErrMsg = "获取access_token 失败 errcode:" + strconv.Itoa(item.Errcode) + " ;errmsg:" + item.Errmsg // return // } // openId := item.Openid // accessToken, err := services.WxGetAccessToken() // if err != nil { // br.Msg = "获取用户信息失败" // br.ErrMsg = "获取access_token失败,err:" + err.Error() // return // } // //获取用户信息 // wxUserInfo, err := services.WxGetUserInfo(openId, accessToken) // if err != nil { // br.Msg = "获取用户信息失败" // br.ErrMsg = "获取微信用户信息失败,Err:" + err.Error() // return // } // if wxUserInfo.Errcode != 0 { // userInfoJson, _ := json.Marshal(wxUserInfo) // br.Msg = "登录失败" // br.ErrMsg = "获取用户信息失败,err:" + string(userInfoJson) // return // } // // unionid := item.Unionid // if unionid == "" { // unionid = wxUserInfo.Unionid // } // firstLogin := 1 // userId := 0 // utils.FileLog.Info("openId:%s", openId) // utils.FileLog.Info("unionid:%s", unionid) // //获取成功 // if openId != "" { // wxUser, err := models.GetWxUserItemByOpenId(openId) // if err != nil && err.Error() != utils.ErrNoRow() { // br.Msg = "获取用户信息失败" // br.ErrMsg = "根据openid获取用户信息失败,Eerr:" + err.Error() // return // } // if wxUser == nil || (err != nil && err.Error() == utils.ErrNoRow()) { // user := new(models.WxUser) // user.OpenId = openId // user.CompanyId = 1 // user.CreatedTime = time.Now() // user.UnionId = unionid // user.Unionid = unionid // user.NickName = wxUserInfo.Nickname // user.Sex = wxUserInfo.Sex // user.City = wxUserInfo.City // user.Province = wxUserInfo.Province // user.Country = wxUserInfo.Country // user.Headimgurl = wxUserInfo.Headimgurl // user.FirstLogin = 1 // user.Enabled = 1 // user.RegisterPlatform = 1 // user.RegisterTime = time.Now() // _, err = models.AddWxUser(user) // wxUser, err = models.GetWxUserItemByOpenId(openId) // if err != nil { // br.Msg = "获取用户信息失败" // br.ErrMsg = "unionid登录,获取微信用户信息失败,Err:" + err.Error() // return // } // userId = wxUser.UserId // } else { // firstLogin = wxUser.FirstLogin // userId = wxUser.UserId // } // } else { // br.Msg = "获取用户信息失败" // br.ErrMsg = "获取openid失败,openid:" + item.Openid // return // } // permission, err := services.CheckUserPermission(userId) // if err != nil { // utils.FileLog.Info("userId:%s,err:%s", strconv.Itoa(userId), err) // } // //if err != nil { // // br.Msg = "登录失败" // // br.ErrMsg = "登录失败,判断权限失败:" + err.Error() // // return // //} // var token string // tokenItem, err := models.GetTokenByUid(userId) // if err != nil && err.Error() != utils.ErrNoRow() { // br.Msg = "登录失败" // br.ErrMsg = "登录失败,获取token失败:" + err.Error() // return // } // // if tokenItem == nil || (err != nil && err.Error() == utils.ErrNoRow()) { // timeUnix := time.Now().Unix() // timeUnixStr := strconv.FormatInt(timeUnix, 10) // token = utils.MD5(strconv.Itoa(userId)) + utils.MD5(timeUnixStr) // //新增session // { // session := new(models.Session) // session.OpenId = openId // session.UserId = userId // session.CreatedTime = time.Now() // session.LastUpdatedTime = time.Now() // session.ExpireTime = time.Now().AddDate(0, 3, 0) // session.AccessToken = token // err = models.AddSession(session) // if err != nil { // br.Msg = "登录失败" // br.ErrMsg = "登录失败,新增用户session信息失败:" + err.Error() // return // } // } // } else { // token = tokenItem.AccessToken // } // // if wxUserInfo != nil { // go models.ModifyWxUserInfo(wxUserInfo.Nickname, wxUserInfo.Headimgurl, wxUserInfo.City, wxUserInfo.Province, wxUserInfo.Country, wxUserInfo.Sex, userId) // } // //firstLogin==1,强制绑定手机号或者邮箱 // { // newItem, _ := models.GetWxUserItemByUserId(userId) // if newItem.Mobile == "" && newItem.Email == "" { // firstLogin = 1 // } // } // //新增登录日志 // { // loginLog := new(models.WxUserLog) // loginLog.UserId = userId // loginLog.OpenId = openId // loginLog.UnionId = unionid // loginLog.CreateTime = time.Now() // loginLog.Handle = "wechat_login" // loginLog.Remark = token // go models.AddWxUserLog(loginLog) // } // // { // codeLog := new(models.WxUserCode) // codeLog.WxCode = code // codeLog.UserId = userId // codeLog.Code = 0 // codeLog.FirstLogin = firstLogin // codeLog.Authorization = token // codeLog.UserPermission = permission // codeLog.CreateTime=time.Now() // models.AddWxUserCode(codeLog) // } // // resp.UserId = userId // resp.Code = 0 // resp.FirstLogin = firstLogin // resp.Authorization = token // resp.UserPermission = permission // br.Ret = 200 // br.Success = true // br.Msg = "登录成功" // br.Data = resp // //登录日志 // { // returnResult, err := json.Marshal(br) // if err != nil { // utils.FileLog.Info(this.Ctx.Input.URI() + " Err:%s" + err.Error()) // } // utils.FileLog.Info(this.Ctx.Input.URI()+" code: %s , return data: %s", code, string(returnResult)) // } //} // @Title 微信获取签名接口 // @Description 微信获取签名接口 // @Param Url query string true "url地址" // @Success 200 {object} models.WechatSign // @router /getWxSign [get] func (this *WechatController) GetWxSign() { br := new(models.BaseResponse).Init() defer func() { this.Data["json"] = br this.ServeJSON() }() // 微信配置信息 conf, e := models.GetBusinessConf() if e != nil { br.Msg = "获取失败" br.ErrMsg = "获取配置失败, Err: " + e.Error() return } appId := "" appSecret := "" if v, ok := conf[models.BusinessConfWxAppId]; ok { appId = v } if v, ok := conf[models.BusinessConfWxAppSecret]; ok { appSecret = v } if appId == "" || appSecret == "" { br.Msg = "微信公众号信息未配置" return } getUrl := this.GetString("Url") fmt.Println("getUrl:", getUrl) tReq := wechat.WxTokenReq{ WxAppId: appId, WxAppSecret: appSecret, } accessToken, err, errMsg := wechat.GetAccessToken(tReq) if err != nil { br.Msg = "获取微信配置失败" br.ErrMsg = "获取access_token失败,err:" + errMsg return } errCode, ticket, err := services.GetWxTicket(accessToken) if err != nil { if errCode == 40001 { accessToken, err, errMsg = wechat.GetAccessToken(tReq) if err != nil { br.Msg = "获取微信配置失败" br.ErrMsg = "获取access_token失败,err:" + errMsg return } errCode, ticket, err = services.GetWxTicket(accessToken) if err != nil { br.Msg = "获取Ticket失败,请联系客服" br.ErrMsg = "获取Ticket失败,Err" + err.Error() return } } br.Msg = "获取Ticket失败,请联系客服" br.ErrMsg = "获取Ticket失败,Err" + err.Error() return } if ticket == "" { br.Msg = "获取Ticket失败,请联系客服" br.ErrMsg = "ticket为空" + ticket return } nonceStr := utils.GetRandStringNoSpecialChar(16) signature, nonceString, timestamp := services.GetWxSignature(ticket, getUrl, nonceStr) resp := new(models.WechatSign) resp.AppId = appId resp.NonceStr = nonceString resp.Timestamp = timestamp resp.Url = getUrl resp.Signature = signature br.Ret = 200 br.Success = true br.Msg = "获取签名成功" br.Data = resp } // @Title 微信获取签名接口 // @Description 微信获取签名接口 // @Param Url query string true "url地址" // @Success 200 {object} models.WechatSign // @router /notify [get,post] func (this *WechatCommonController) Notify() { echostr := this.GetString("echostr") method := this.Ctx.Input.Method() if method == "POST" { body := this.Ctx.Input.RequestBody utils.FileLog.Info("wechat notify:" + string(body)) item := new(Notify) err := xml.Unmarshal(body, &item) if err != nil { utils.FileLog.Info("xml.Unmarshal:" + err.Error()) } 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 " var openId, returnResult string if item.MsgType != "" { openId = item.FromUserName } xmlTpl := ` %s ` createTime := strconv.FormatInt(time.Now().Unix(), 10) xmlTpl = fmt.Sprintf(xmlTpl, openId, utils.WxId, createTime, contactMsg) if item.MsgType == "event" { switch item.Event { case "subscribe": fmt.Println("关注") go subscribe(openId) break case "unsubscribe": fmt.Println("取消关注") go models.UserSubscribe(0, openId) break case "CLICK": returnResult = xmlTpl break default: utils.FileLog.Info("wechat notify event:" + item.Event) } this.Ctx.WriteString(xmlTpl) } else if item.MsgType == "text" { textXmlTpl := ` %s ` createTime := strconv.FormatInt(time.Now().Unix(), 10) classifyArr := utils.ClassifyArr var flag bool for _, v := range classifyArr { if strings.Contains(v, item.Content) || strings.Contains(item.Content, v) { flag = true } } if flag { contactMsg = `请点击研究报告-FICC研报,查看报告` textXmlTpl = fmt.Sprintf(textXmlTpl, item.FromUserName, utils.WxId, createTime, contactMsg) this.Ctx.WriteString(textXmlTpl) return } reportNameArr := utils.ReportNameArr for _, v := range reportNameArr { if strings.Contains(v, item.Content) || strings.Contains(item.Content, v) { flag = true } } if flag { contactMsg = `请点击研究报告-FICC研报-研报(左上),查看报告` textXmlTpl = fmt.Sprintf(textXmlTpl, item.FromUserName, utils.WxId, createTime, contactMsg) this.Ctx.WriteString(textXmlTpl) return } if strings.Contains("解绑", item.Content) || strings.Contains(item.Content, "解绑") || strings.Contains("手机号", item.Content) || strings.Contains(item.Content, "手机号") { flag = true } if flag { contactMsg = `请通过电话联系我们或者联系销售人员处理` textXmlTpl = fmt.Sprintf(textXmlTpl, item.FromUserName, utils.WxId, createTime, contactMsg) this.Ctx.WriteString(textXmlTpl) return } returnResult = xmlTpl this.Ctx.WriteString(returnResult) } else { returnResult = xmlTpl } this.Ctx.WriteString(returnResult) } else { this.Ctx.WriteString(echostr) } } type Notify struct { ToUserName string `xml:"ToUserName"` FromUserName string `xml:"FromUserName"` CreateTime int `xml:"CreateTime"` MsgType string `xml:"MsgType"` Event string `xml:"Event"` EventKey string `xml:"EventKey"` Content string `xml:"Content"` } // subscribe 关注后的处理逻辑 func subscribe(openId string) { accessToken, err, _ := services.GetDefaultWxAccessToken() if err != nil { fmt.Println("获取access_token失败,err:" + err.Error()) return } userRecord, err := models.GetUserRecordByOpenId(openId) if err != nil && err.Error() != utils.ErrNoRow() { fmt.Println("通过openid获取user_record记录失败,err:" + err.Error()) return } err = nil // openId已存在 if userRecord != nil { if userRecord.UserId > 0 { //已经绑定了的话,那么就去修改用户状态 models.UserSubscribe(1, openId) } else { // 没有绑定的话,那么校验下unionid,然后再去修改 unionId := userRecord.UnionId if unionId == `` { wxUserItem, err := services.WxGetUserInfo(openId, accessToken) if err != nil { fmt.Println("获取用户信息失败,err:" + err.Error()) return } if wxUserItem.Unionid != `` { unionId = wxUserItem.Unionid } } updateCol := make([]string, 0) userRecord.Subscribe = 1 userRecord.SubscribeTime = time.Now() updateCol = append(updateCol, "Subscribe") if unionId != `` { userRecord.UnionId = unionId // 通过unionid获取已绑定用户的user_record信息 bindUserRecord, _ := models.GetBindUserRecordByUnionId(unionId) if bindUserRecord != nil { userRecord.UserId = bindUserRecord.UserId userRecord.RealName = bindUserRecord.RealName userRecord.BindAccount = bindUserRecord.BindAccount userRecord.Sex = bindUserRecord.Sex updateCol = append(updateCol, "UserId", "RealName", "BindAccount") } } err = userRecord.Update(updateCol) if err != nil { fmt.Println("关注后,通过openid更新user_record异常,ERR:", err) } } return } // 没有记录,那么需要获取下unionid wxUserItem, err := services.WxGetUserInfo(openId, accessToken) if err != nil { fmt.Println("获取用户信息失败,err:" + err.Error()) return } newUserRecord := &models.UserRecord{ UserRecordId: 0, OpenId: openId, UnionId: wxUserItem.Unionid, Subscribe: 1, SubscribeTime: time.Now(), NickName: wxUserItem.Nickname, Sex: wxUserItem.Sex, Province: wxUserItem.Province, City: wxUserItem.City, Country: wxUserItem.Country, Headimgurl: wxUserItem.Headimgurl, CreateTime: time.Now(), CreatePlatform: 1, SessionKey: "", } if wxUserItem.Unionid != `` { // 通过unionid获取已绑定用户的user_record信息 bindUserRecord, _ := models.GetBindUserRecordByUnionId(wxUserItem.Unionid) if bindUserRecord != nil { newUserRecord.UserId = bindUserRecord.UserId newUserRecord.RealName = bindUserRecord.RealName newUserRecord.BindAccount = bindUserRecord.BindAccount newUserRecord.Sex = bindUserRecord.Sex newUserRecord.Province = bindUserRecord.Province newUserRecord.City = bindUserRecord.City newUserRecord.Country = bindUserRecord.Country newUserRecord.Headimgurl = bindUserRecord.Headimgurl } } _, err = models.AddUserRecord(newUserRecord) if err != nil { fmt.Println("关注后,添加user_record信息失败,err:" + err.Error()) return } } // @Title 微信获取签名接口-无token校验 // @Description 微信获取签名接口 // @Param Url query string true "url地址" // @Success 200 {object} models.WechatSign // @router /open/getWxSign [get] func (this *WechatCommonController) GetWxSign() { br := new(models.BaseResponse).Init() defer func() { this.Data["json"] = br this.ServeJSON() }() // 微信配置信息 conf, e := models.GetBusinessConf() if e != nil { br.Msg = "获取失败" br.ErrMsg = "获取配置信息失败, Err: " + e.Error() return } appId := "" appSecret := "" if v, ok := conf[models.BusinessConfWxAppId]; ok { appId = v } if v, ok := conf[models.BusinessConfWxAppSecret]; ok { appSecret = v } if appId == "" || appSecret == "" { br.Msg = "微信公众号信息未配置" return } getUrl := this.GetString("Url") fmt.Println("getUrl:", getUrl) tReq := wechat.WxTokenReq{ WxAppId: appId, WxAppSecret: appSecret, } accessToken, err, errMsg := wechat.GetAccessToken(tReq) if err != nil { br.Msg = "获取微信配置失败" br.ErrMsg = "获取access_token失败,err:" + errMsg return } errCode, ticket, err := services.GetWxTicket(accessToken) if err != nil { if errCode == 40001 { accessToken, err, errMsg = wechat.GetAccessToken(tReq) if err != nil { br.Msg = "获取微信配置失败" br.ErrMsg = "获取access_token失败,err:" + errMsg return } errCode, ticket, err = services.GetWxTicket(accessToken) if err != nil { br.Msg = "获取Ticket失败,请联系客服" br.ErrMsg = "获取Ticket失败,Err" + err.Error() return } } br.Msg = "获取Ticket失败,请联系客服" br.ErrMsg = "获取Ticket失败,Err" + err.Error() return } if ticket == "" { br.Msg = "获取Ticket失败,请联系客服" br.ErrMsg = "ticket为空" + ticket return } nonceStr := utils.GetRandStringNoSpecialChar(16) signature, nonceString, timestamp := services.GetWxSignature(ticket, getUrl, nonceStr) resp := new(models.WechatSign) resp.AppId = appId resp.NonceStr = nonceString resp.Timestamp = timestamp resp.Url = getUrl resp.Signature = signature br.Ret = 200 br.Success = true br.Msg = "获取签名成功" br.Data = resp }