package controllers import ( "encoding/json" "fmt" "github.com/medivhzhan/weapp/v2" "hongze/hongze_cygx/models" "hongze/hongze_cygx/services" "hongze/hongze_cygx/utils" "io" "io/ioutil" "net/http" "os" "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() }() code := this.GetString("Code") if code == "" { br.Msg = "参数错误" br.ErrMsg = "Code 为空" return } wxInfo, err := weapp.Login(utils.WxAppId, utils.WxAppSecret, code) if err != nil { br.Msg = "获取用户信息失败" br.ErrMsg = "获取用户信息失败,Err:" + err.Error() return } if err = wxInfo.GetResponseError(); err != nil { br.Msg = "获取用户信息失败" br.ErrMsg = "获取用户信息失败,code:" + strconv.Itoa(wxInfo.ErrCode) + ",msg:" + wxInfo.ErrMSG return } wxUserInfo := new(services.WxUserInfo) wxUserInfo.Unionid = wxInfo.UnionID wxUserInfo.Openid = wxInfo.OpenID wxUserInfo.Errcode = wxInfo.ErrCode wxUserInfo.Errmsg = wxInfo.ErrMSG wxUserInfo.SessionKey = wxInfo.SessionKey token, userId, firstLogin, _, err := services.WxLogin(code, wxInfo.OpenID, wxInfo.UnionID, wxUserInfo) if err != nil && err.Error() != utils.ErrNoRow() { br.Msg = "微信登录失败" br.ErrMsg = "微信登录失败,err:" + err.Error() return } if token == "" { br.Msg = "微信登录失败" br.ErrMsg = "token:" + token + "" + code + " " + wxInfo.OpenID + " " + wxInfo.UnionID return } //新增登录日志 { loginLog := new(models.WxUserLog) loginLog.UserId = userId loginLog.OpenId = wxInfo.OpenID loginLog.UnionId = wxInfo.UnionID loginLog.CreateTime = time.Now() loginLog.Handle = "wechat_login_cygx" 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 = 1 codeLog.CreateTime = time.Now() models.AddWxUserCode(codeLog) } resp := new(models.WxLoginResp) resp.UserId = userId resp.FirstLogin = firstLogin resp.Authorization = token br.Ret = 200 br.Success = true br.Msg = "登录成功" br.Data = resp } // @Title 小程序获取用户信息 // @Description 小程序获取用户信息接口(需要登录) // @Param request body models.WxGetUserInfoReq true "type json string" // @Success 200 {object} models.WxGetUserInfoResp // @router /getUserInfo [post] func (this *WechatController) GetUserInfo() { br := new(models.BaseResponse).Init() defer func() { this.Data["json"] = br this.ServeJSON() }() var req models.WxGetUserInfoReq err := json.Unmarshal(this.Ctx.Input.RequestBody, &req) if err != nil { br.Msg = "参数解析异常!" br.ErrMsg = "参数解析失败,Err:" + err.Error() return } if req.RawData == "" || req.EncryptedData == "" || req.Signature == "" || req.Iv == "" { br.Msg = "参数错误" return } user := this.User if user == nil { br.Msg = "请登陆" br.Ret = 408 return } userId := user.UserId sessionKey := user.SessionKey fmt.Println("sessionKey:", sessionKey) fmt.Println(sessionKey, req.RawData, req.EncryptedData, req.Signature, req.Iv) userInfo, err := weapp.DecryptUserInfo(sessionKey, req.RawData, req.EncryptedData, req.Signature, req.Iv) fmt.Println("weapp.DecryptUserInfo ", err) if err != nil { br.Msg = "解析用户信息失败" br.ErrMsg = "解析用户信息失败,DecryptUserInfo Err:" + err.Error() return } //修改用户微信信息 err = models.ModifyUserRecordByDetail(userInfo.OpenID, userInfo.UnionID, userInfo.Nickname, userInfo.Avatar, userInfo.City, userInfo.Province, userInfo.Country, userInfo.Gender, userId) if err != nil { br.Msg = "授权失败" br.ErrMsg = "授权失败,修改用户信息失败:" + err.Error() return } var token string tokenItem, err := models.GetTokenByOpenId(userInfo.OpenID) 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(userInfo.OpenID) + utils.MD5(timeUnixStr) //新增session { session := new(models.CygxSession) session.OpenId = userInfo.OpenID session.UnionId = userInfo.UnionID 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 } resp := new(models.WxGetUserInfoResp) resp.Authorization = token br.Msg = "获取成功!" br.Ret = 200 br.Success = true } // @Title 小程序获取用户绑定手机号 // @Description 小程序获取用户绑定手机号接口(需要登录) // @Param request body models.WxGetPhoneNumberReq true "type json string" // @Success 200 {object} models.WxGetPhoneNumberResp // @router /getPhoneNumber [post] func (this *WechatController) GetPhoneNumber() { br := new(models.BaseResponse).Init() defer func() { this.Data["json"] = br this.ServeJSON() }() var req models.WxGetPhoneNumberReq err := json.Unmarshal(this.Ctx.Input.RequestBody, &req) if err != nil { br.Msg = "参数解析异常!" br.ErrMsg = "参数解析失败,Err:" + err.Error() return } if req.EncryptedData == "" || req.Iv == "" { br.Msg = "参数错误" return } user := this.User if user == nil { br.Msg = "请登陆" br.Ret = 408 return } sessionKey := user.SessionKey wxMobile, err := weapp.DecryptMobile(sessionKey, req.EncryptedData, req.Iv) if err != nil { br.Msg = "解析用户手机号信息失败" br.ErrMsg = "解析用户手机号信息失败,Err:" + err.Error() return } err = models.ModifyUsersMobile(user.UserId, wxMobile.PurePhoneNumber) if err != nil { br.Msg = "获取失败" br.ErrMsg = "获取失败,Err:" + err.Error() return } resp := new(models.WxGetPhoneNumberResp) resp.PhoneNumber = wxMobile.PhoneNumber resp.PurePhoneNumber = wxMobile.PurePhoneNumber resp.CountryCode = wxMobile.CountryCode br.Msg = "获取成功!" br.Ret = 200 br.Success = true br.Data = resp } // @Title 获取短信验证码 // @Description 获取短信验证码接口 // @Param Mobile query string true "手机号码" // @Param AreaNum query string true "地区编码" // @Success Ret=200 获取成功 // @router /getSmsCode [get] func (this *WechatController) GetSmsCode() { br := new(models.BaseResponse).Init() defer func() { this.Data["json"] = br this.ServeJSON() }() mobile := this.GetString("Mobile") if mobile == "" { br.Msg = "请输入手机号" return } areaNum := this.GetString("AreaNum") msgCode := utils.GetRandDigit(4) var result bool if areaNum == "86" || areaNum == "" || areaNum == "0" { result = services.SendSmsCode(mobile, msgCode) } else { result = services.SendSmsCodeGj(mobile, msgCode, areaNum) } //发送成功 if result { item := new(models.MsgCode) item.OpenId = "" item.Code = msgCode item.Mobile = mobile item.ExpiredIn = time.Now().Add(15 * time.Minute).Unix() item.Enabled = 1 item.CreatedTime = time.Now() err := models.AddMsgCode(item) if err != nil { br.Msg = "发送失败" br.ErrMsg = "发送失败,Err:" + err.Error() return } br.Msg = "发送成功" } else { br.Msg = "发送失败" } br.Ret = 200 br.Success = true } // @Title 获取邮件验证码 // @Description 获取邮件验证码接口 // @Param Email query string true "邮箱" // @Success Ret=200 获取成功 // @router /getEmailCode [get] func (this *WechatController) GetEmailCode() { br := new(models.BaseResponse).Init() defer func() { this.Data["json"] = br this.ServeJSON() }() email := this.GetString("Email") if email == "" { br.Msg = "请输入邮箱地址" return } if !utils.ValidateEmailFormatat(email) { br.Msg = "邮箱格式错误,请重新输入" return } msgCode := utils.GetRandDigit(4) content := "尊敬的用户:
您好,感谢您使用弘则研究,您正在进行邮箱验证,本次请求的验证码为:" + msgCode + "(为了保障您账号的安全性,请在15分钟内完成验证。)
弘则研究团队
2019年05月11日" title := "弘则研究登陆验证" //发送邮件 result, err := utils.SendEmailByHz(title, content, email) if err != nil { br.Msg = "发送失败" br.ErrMsg = "发送失败,Err:" + err.Error() return } if result { item := new(models.MsgCode) item.OpenId = "" item.Code = msgCode item.Mobile = email item.ExpiredIn = time.Now().Add(15 * time.Minute).Unix() item.Enabled = 1 item.CreatedTime = time.Now() err := models.AddMsgCode(item) if err != nil { br.Msg = "发送失败" br.ErrMsg = "发送失败,Err:" + err.Error() return } br.Msg = "发送成功" } else { br.Msg = "发送失败" } br.Ret = 200 br.Success = true } // @Title 更新微信token // @Description 更新微信token // @Success Ret=200 更新成功 // @router /updateWxAccesstoken [get] func (this *WechatController) UpdateWxAccesstoken() { br := new(models.BaseResponse).Init() defer func() { this.Data["json"] = br this.ServeJSON() }() accessToken, err := models.GetWxAccessToken() if err != nil { utils.FileLog.Info("GetWxAccessToken Err:%s", err.Error()) return } br.Data = accessToken br.Ret = 200 br.Success = true } // @Title 微信登录小助手接口 // @Description 微信登录小助手接口 // @Param Code query string true "微信唯一编码code" // @Success 200 {object} models.WxLoginResp // @router /loginByxzs [get] func (this *WechatCommonController) WechatLoginByxzs() { br := new(models.BaseResponse).Init() defer func() { this.Data["json"] = br this.ServeJSON() }() code := this.GetString("Code") if code == "" { br.Msg = "参数错误" br.ErrMsg = "Code 为空" return } item, err := services.WxGetUserOpenIdByCodeXzs(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 } unionId := item.Unionid if unionId == "" { br.Msg = "获取用户信息失败" br.ErrMsg = "获取unionid失败,unionid:" + item.Openid return } total, err := models.GetCygxUserRecordCount(openId) if err != nil { br.Msg = "获取用户信息失败" br.ErrMsg = "查询数量失败,Err:" + err.Error() return } if total == 0 { items := new(models.CygxUserRecord) items.OpenId = openId items.UnionId = unionId items.CreateTime = time.Now() _, err = models.AddCygxUserRecord(items) if err != nil { br.Msg = "获取用户信息失败" br.ErrMsg = "添加openid失败,Err:" + err.Error() return } } br.Ret = 200 br.Success = true br.Msg = "获取成功" br.Data = item } // @Title 获取小程序分享二维码 // @Description 获取小程序分享二维码 // @Success 200 {object} models.ArticleDetailFileLink // @router /shareImage [post] func (this *WechatController) ShareImage() { br := new(models.BaseResponse).Init() defer func() { this.Data["json"] = br this.ServeJSON() }() user := this.User if user == nil { br.Msg = "请登录" br.ErrMsg = "请登录,用户信息为空" br.Ret = 408 return } uid := user.UserId itemToken, err := services.WxGetToken() if err != nil { br.Msg = "分享失败" br.ErrMsg = "获取itemToken失败,Err:" + err.Error() return } if itemToken.AccessToken == "" { br.Msg = "accessToken is empty" return } var envVersion string var resourceUrl string if utils.RunMode == "release" { envVersion = "release" } else { envVersion = "develop" } url := "https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=" + itemToken.AccessToken method := "POST" payload := strings.NewReader(`{ "page":"pageMy/excessivePages/excessivePages", "scene":"` + strconv.Itoa(uid) + `", "env_version":"` + envVersion + `", "check_path":false, "auto_color":true }`) client := &http.Client{} req, err := http.NewRequest(method, url, payload) if err != nil { br.Msg = "分享失败" br.ErrMsg = "获取微信二维码失败,Err:" + err.Error() return } req.Header.Add("Content-Type", "application/json") postBody, err := client.Do(req) if err != nil { br.Msg = "分享失败" br.ErrMsg = "获取微信二维码失败,Err:" + err.Error() return } defer postBody.Body.Close() uploadDir := "static/img/share/" uuid := utils.GetRandStringNoSpecialChar(28) if !utils.FileIsExist(uploadDir) { err = os.MkdirAll(uploadDir, 0755) if err != nil { br.Msg = "分享失败" br.ErrMsg = "生成文件夹失败,Err:" + err.Error() return } } imagePath := uploadDir + uuid + ".jpg" switch header := postBody.Header.Get("Content-Type"); { case strings.HasPrefix(header, "application/json"): tokenResp := models.ReturnBodyRule{} decoder := json.NewDecoder(postBody.Body) if decodeErr := decoder.Decode(&tokenResp); decodeErr != nil { br.Msg = "分享失败" br.ErrMsg = "获取微信二维码失败,Err:" + decodeErr.Error() return } case strings.HasPrefix(header, "image"): reply, err := ioutil.ReadAll(postBody.Body) if err != nil { br.Msg = "分享失败" br.ErrMsg = "获取微信二维码失败,Err:" + err.Error() return } imageContent, createErr := os.Create(imagePath) if createErr != nil { br.Msg = "分享失败" br.ErrMsg = "获取微信二维码失败,Err:" + createErr.Error() return } writeStringRes, writeStringErr := io.WriteString(imageContent, string(reply)) if writeStringErr != nil { fmt.Println(writeStringRes) br.Msg = "分享失败" br.ErrMsg = "获取微信二维码失败,Err:" + writeStringErr.Error() return } closeErr := imageContent.Close() if closeErr != nil { br.Msg = "分享失败" br.ErrMsg = "获取微信二维码失败,Err:" + closeErr.Error() return } randStr := utils.GetRandStringNoSpecialChar(28) fileName := randStr + ".jpg" savePath := uploadDir + time.Now().Format("200601/20060102/") savePath += fileName //上传到阿里云 err = services.UploadFileToAliyun(fileName, imagePath, savePath) if err != nil { fmt.Println("文件上传失败,Err:" + err.Error()) return } fileHost := "https://hzstatic.hzinsights.com/" resourceUrl = fileHost + savePath defer func() { os.Remove(imagePath) }() default: br.Msg = "分享失败" br.ErrMsg = "没有获取到分享二维码" return } resp := new(models.ArticleDetailFileLink) resp.FileLink = resourceUrl resp.Scene = strconv.Itoa(uid) br.Ret = 200 br.Data = resp br.Success = true br.Msg = "提交成功" } // @Title 获取短信验证码(无需token) // @Description 获取短信验证码接口(无需token) // @Param Mobile query string true "手机号码" // @Param AreaNum query string true "地区编码" // @Success Ret=200 获取成功 // @router /getSmsCodePublic [get] func (this *WechatCommonController) GetSmsCode() { br := new(models.BaseResponse).Init() defer func() { this.Data["json"] = br this.ServeJSON() }() mobile := this.GetString("Mobile") if mobile == "" { br.Msg = "请输入手机号" return } areaNum := this.GetString("AreaNum") msgCode := utils.GetRandDigit(4) var result bool if areaNum == "86" || areaNum == "" || areaNum == "0" { result = services.SendSmsCode(mobile, msgCode) } else { result = services.SendSmsCodeGj(mobile, msgCode, areaNum) } //发送成功 if result { item := new(models.MsgCode) item.OpenId = "" item.Code = msgCode item.Mobile = mobile item.ExpiredIn = time.Now().Add(15 * time.Minute).Unix() item.Enabled = 1 item.CreatedTime = time.Now() err := models.AddMsgCode(item) if err != nil { br.Msg = "发送失败" br.ErrMsg = "发送失败,Err:" + err.Error() return } br.Msg = "发送成功" } else { br.Msg = "发送失败" } br.Ret = 200 br.Success = true }