Browse Source

从数据库中获取微信配置

xyxie 1 year ago
parent
commit
a201230cd4
7 changed files with 224 additions and 20 deletions
  1. 8 1
      controllers/report_share.go
  2. 50 11
      controllers/wechat.go
  3. 5 1
      models/business_conf.go
  4. 4 2
      models/report.go
  5. 28 1
      models/wx_token.go
  6. 124 4
      services/wechat.go
  7. 5 0
      utils/constants.go

+ 8 - 1
controllers/report_share.go

@@ -49,7 +49,14 @@ func (this *ReportShareController) Detail() {
 	if conf[models.BusinessConfDisclaimer] != "" {
 		resp.Disclaimer = conf[models.BusinessConfDisclaimer]
 	}
-
+	// 研报分享抬头
+	if v, ok := conf[models.BusinessConfH5ShareName]; ok {
+		resp.H5ShareName = v
+	}
+	if v, ok := conf[models.BusinessConfH5ReportShareImg]; ok {
+		resp.H5ReportShareImg = v
+	}
+	
 	resp.Report = report
 	br.Ret = 200
 	br.Success = true

+ 50 - 11
controllers/wechat.go

@@ -68,10 +68,10 @@ func (this *WechatCommonController) WechatLogin() {
 		br.ErrMsg = "获取openid失败,openid:" + item.Openid
 		return
 	}
-	accessToken, err := services.WxGetAccessToken()
+	accessToken, err, errMsg := services.GetDefaultWxAccessToken()
 	if err != nil {
 		br.Msg = "获取用户信息失败"
-		br.ErrMsg = "获取access_token失败,err:" + err.Error()
+		br.ErrMsg = errMsg
 		return
 	}
 	//获取用户信息
@@ -329,12 +329,32 @@ func (this *WechatController) GetWxSign() {
 		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)
-	accessToken, err := services.WxGetAccessToken()
+	accessToken, err, errMsg := services.GetWxAccessToken(appId, appSecret)
 	if err != nil {
 		br.Msg = "获取用户信息失败"
-		br.ErrMsg = "获取access_token失败,err:" + err.Error()
+		br.ErrMsg = "获取access_token失败,err:" + errMsg
 		return
 	}
 
@@ -351,9 +371,8 @@ func (this *WechatController) GetWxSign() {
 	}
 	nonceStr := utils.GetRandStringNoSpecialChar(16)
 	signature, nonceString, timestamp := services.GetWxSignature(ticket, getUrl, nonceStr)
-
 	resp := new(models.WechatSign)
-	resp.AppId = utils.WxAppId
+	resp.AppId = appId
 	resp.NonceStr = nonceString
 	resp.Timestamp = timestamp
 	resp.Url = getUrl
@@ -483,7 +502,7 @@ type Notify struct {
 
 // subscribe 关注后的处理逻辑
 func subscribe(openId string) {
-	accessToken, err := services.WxGetAccessToken()
+	accessToken, err, _ := services.GetDefaultWxAccessToken()
 	if err != nil {
 		fmt.Println("获取access_token失败,err:" + err.Error())
 		return
@@ -592,12 +611,33 @@ func (this *WechatCommonController) GetWxSign() {
 		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)
-	accessToken, err := services.WxGetAccessToken()
+	accessToken, err, errMsg := services.GetWxAccessToken(appId, appSecret)
 	if err != nil {
 		br.Msg = "获取用户信息失败"
-		br.ErrMsg = "获取access_token失败,err:" + err.Error()
+		br.ErrMsg = "获取access_token失败,err:" + errMsg
 		return
 	}
 
@@ -614,9 +654,8 @@ func (this *WechatCommonController) GetWxSign() {
 	}
 	nonceStr := utils.GetRandStringNoSpecialChar(16)
 	signature, nonceString, timestamp := services.GetWxSignature(ticket, getUrl, nonceStr)
-
 	resp := new(models.WechatSign)
-	resp.AppId = utils.WxAppId
+	resp.AppId = appId
 	resp.NonceStr = nonceString
 	resp.Timestamp = timestamp
 	resp.Url = getUrl

+ 5 - 1
models/business_conf.go

@@ -7,7 +7,11 @@ import (
 )
 
 const (
-	BusinessConfDisclaimer = "Disclaimer"
+	BusinessConfDisclaimer       = "Disclaimer"
+	BusinessConfH5ShareName      = "H5ShareName"
+	BusinessConfH5ReportShareImg = "H5ReportShareImg"
+	BusinessConfWxAppId          = "WxAppId"
+	BusinessConfWxAppSecret      = "WxAppSecret"
 )
 
 // BusinessConf 商户配置表

+ 4 - 2
models/report.go

@@ -227,8 +227,10 @@ func GetReportByCode(reportCode string) (item *Report, err error) {
 }
 
 type ReportShareDetailResp struct {
-	Report     *Report `description:"报告"`
-	Disclaimer string  `description:"免责声明"`
+	Report           *Report `description:"报告"`
+	Disclaimer       string  `description:"免责声明"`
+	H5ShareName      string  `description:"研报分享抬头"`
+	H5ReportShareImg string  `description:"研报分享图片"`
 }
 
 type PcReport struct {

+ 28 - 1
models/wx_token.go

@@ -1,6 +1,10 @@
 package models
 
-import "github.com/beego/beego/v2/client/orm"
+import (
+	"fmt"
+	"github.com/beego/beego/v2/client/orm"
+	"hongze/hongze_api/utils"
+)
 
 type WxToken struct {
 	AccessToken string
@@ -28,3 +32,26 @@ func UpdateWxToken(token string, expiresIn int64, id int) (err error) {
 	_, err = o.Raw(sql, token, expiresIn, id).Exec()
 	return
 }
+
+// ModifyAccessToken 修改wx_access_token
+func ModifyAccessToken(accessToken string, expiresIn int64) (err error) {
+	o := orm.NewOrm()
+	sql := `SELECT * FROM wx_token LIMIT 1`
+	wxToken := new(WxToken)
+	err = o.Raw(sql).QueryRow(&wxToken)
+	if err != nil && err.Error() != utils.ErrNoRow() {
+		utils.FileLog.Info("Get wxToken Err:", err.Error())
+		return
+	}
+	if wxToken == nil {
+		fmt.Println("wxToken is empty")
+		addSql := "insert into wx_token (access_token,expires_in) values (?,?)"
+		_, err = o.Raw(addSql, accessToken, expiresIn).Exec()
+	} else {
+		//判断token是否过期
+		updateSql := "update wx_token set access_token = ?,expires_in = ? "
+		_, err = o.Raw(updateSql, accessToken, expiresIn).Exec()
+		fmt.Println("更新 TOKEN:", err)
+	}
+	return
+}

+ 124 - 4
services/wechat.go

@@ -6,6 +6,7 @@ import (
 	"fmt"
 	"github.com/rdlucklib/rdluck_tools/http"
 	"hongze/hongze_api/models"
+	"hongze/hongze_api/services/go_redis"
 	"hongze/hongze_api/utils"
 	"strconv"
 	"strings"
@@ -46,9 +47,9 @@ type WxToken struct {
 	Errmsg      string `json:"errmsg"`
 }
 
-func WxGetToken() (item *WxToken, err error) {
+func WxGetToken(wxAppId, wxAppSecret string) (item *WxToken, err error) {
 	requestUrl := `https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s`
-	requestUrl = fmt.Sprintf(requestUrl, utils.WxAppId, utils.WxAppSecret)
+	requestUrl = fmt.Sprintf(requestUrl, wxAppId, wxAppSecret)
 	fmt.Println("requestUrl:", requestUrl)
 	result, err := http.Get(requestUrl)
 	if err != nil {
@@ -61,7 +62,7 @@ func WxGetToken() (item *WxToken, err error) {
 	return
 }
 
-func WxGetAccessToken() (accessToken string, err error) {
+/*func WxGetAccessToken() (accessToken string, err error) {
 	wxToken, err := models.GetWxToken()
 	fmt.Println(err, wxToken)
 	if err != nil && err.Error() != utils.ErrNoRow() {
@@ -106,7 +107,7 @@ func WxGetAccessToken() (accessToken string, err error) {
 		}
 	}
 	return
-}
+}*/
 
 type WxUserInfo struct {
 	Openid         string `json:"openid"`
@@ -205,3 +206,122 @@ func FixUnionId() {
 		}
 	}
 }
+
+// GetDefaultWxAccessToken 获取微信token
+func GetDefaultWxAccessToken() (accessToken string, err error, errMsg string) {
+	// 微信配置信息
+	conf, e := models.GetBusinessConf()
+	if e != nil {
+		errMsg = "获取配置信息失败, Err: " + e.Error()
+		err = errors.New(errMsg)
+		return
+	}
+	appId := ""
+	appSecret := ""
+	if v, ok := conf[models.BusinessConfWxAppId]; ok {
+		appId = v
+	}
+	if v, ok := conf[models.BusinessConfWxAppSecret]; ok {
+		appSecret = v
+	}
+
+	if appId == "" || appSecret == "" {
+		errMsg = "获取微信公众号未配置"
+		err = errors.New(errMsg)
+		return
+	}
+	accessToken, err, errMsg = GetWxAccessToken(appId, appSecret)
+	return
+}
+
+// GetWxAccessToken 获取微信token
+func GetWxAccessToken(wxAppId, wxAppSecret string) (accessToken string, err error, errMsg string) {
+	redisKey := getRedisKeyByAppid(wxAppId)
+	if redisKey == `` {
+		errMsg = "未配置缓存key"
+		err = errors.New(errMsg)
+		return
+	}
+
+	accessToken, err = go_redis.RedisString(redisKey)
+	//fmt.Println(err)
+	//fmt.Println(accessToken)
+	//if err != nil {
+	//	errMsg = "GetWxAccessToken Err:" + err.Error()
+	//	utils.FileLog.Info("获取Token失败,msg:" + errMsg)
+	//	return
+	//}
+	//取到数据后就直接返回了,没有后续了
+	if accessToken != "" {
+		return
+	}
+
+	//缓存中没有取到数据,那么需要去强制刷新新的accessToken
+	return refreshWxAccessToken(wxAppId, wxAppSecret)
+}
+
+// refreshWxAccessToken 强制刷新微信token
+func refreshWxAccessToken(wxAppId, wxAppSecret string) (accessToken string, err error, errMsg string) {
+	fmt.Println("强制刷新" + wxAppId + "微信token")
+	defer func() {
+		if errMsg != `` {
+			utils.FileLog.Info(fmt.Sprintf("强制刷新%s微信token异常:%s", wxAppId, errMsg))
+		}
+	}()
+	redisKey := getRedisKeyByAppid(wxAppId)
+	if redisKey == `` {
+		errMsg = "未配置缓存key"
+		err = errors.New(errMsg)
+		return
+	}
+	if wxAppSecret == "" {
+		err = errors.New("缺少密钥信息")
+		utils.FileLog.Info(fmt.Sprintf("获取Token失败, errMsg:%s", err.Error()))
+		return
+	}
+
+	//调用微信官方接口获取新的accessToken
+	wxAccessToken, tmpErr := WxGetToken(wxAppId, wxAppSecret)
+	if tmpErr != nil {
+		err = tmpErr
+		errMsg = "通过微信接口获取accessToken失败 Err:" + err.Error()
+		return
+	}
+
+	//如果没有token数据
+	if wxAccessToken.AccessToken == "" {
+		errMsg = "微信返回的accessToken异常: Err:" + wxAccessToken.Errmsg
+		err = errors.New(errMsg)
+		return
+	}
+
+	accessToken = wxAccessToken.AccessToken
+	//如果是弘则研究的appid,那么需要更新mysql的accessToken
+	if wxAppId == utils.WxAppId {
+		expiresIn := time.Now().Add(time.Duration(wxAccessToken.ExpiresIn) * time.Second).Unix()
+		err = models.ModifyAccessToken(wxAccessToken.AccessToken, expiresIn)
+		if err != nil {
+			errMsg = "更新mysql中的accessToken失败 Err:" + err.Error()
+			return
+		}
+	}
+
+	//更新redis的accessToken(过期时间提前十分钟)
+	redisTimeExpire := time.Duration(wxAccessToken.ExpiresIn-600) * time.Second
+	bo := go_redis.SetNX(redisKey, accessToken, redisTimeExpire)
+	if !bo {
+		errMsg = "更新redis中的accessToken失败"
+		return
+	}
+
+	return
+}
+
+// 根据微信appid获取对应的缓存key
+func getRedisKeyByAppid(wxAppId string) (redisKey string) {
+	switch wxAppId {
+	case utils.WxAppId:
+		redisKey = utils.CACHE_WX_ACCESS_TOKEN_HZ
+	}
+	return redisKey
+}

+ 5 - 0
utils/constants.go

@@ -85,6 +85,11 @@ const (
 	CACHE_KEY_USER_VIEW = "user_view_record" //用户阅读数据
 )
 
+// 缓存key
+const (
+	CACHE_WX_ACCESS_TOKEN_HZ = "wx:accesstoken:hzyj" //公众号 微信accessToken
+)
+
 const (
 	key = "KcSJaJoUBC2ZAA7HEWpaiH49" //全局加密KEY
 )