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
}