kobe6258 7 months ago
parent
commit
eb6e15b54b

+ 65 - 0
controllers/audio.go

@@ -9,6 +9,7 @@ import (
 	"eta/eta_mini_crm_ht/services/elastic"
 	"eta/eta_mini_crm_ht/utils"
 	"fmt"
+	"github.com/rdlucklib/rdluck_tools/paging"
 	"github.com/tcolgate/mp3"
 	"os"
 	"path"
@@ -328,3 +329,67 @@ func (this *AudioController) DeleteAudio() {
 	br.Ret = 200
 	br.Success = true
 }
+
+// AudioList
+// @Title 研报列表
+// @Description pdf研报列表
+// @Param   PageSize   query   int  true       "每页数据条数"
+// @Param   CurrentIndex   query   int  true       "当前页页码,从1开始"
+// @Param   ClassifyIds   query   string  true       "二级分类id,可多选用英文,隔开"
+// @Param   KeyWord   query   string  true       "报告标题/创建人"
+// @Param   SortType   query   string  true       "排序方式"
+// @Success 200 {object} models.ReportAuthorResp
+// @router /audioList [get]
+func (this *AudioController) AudioList() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	pageSize, _ := this.GetInt("PageSize")
+	currentIndex, _ := this.GetInt("CurrentIndex")
+	sortType := this.GetString("SortType")
+	var condition string
+	var pars []interface{}
+
+	if pageSize <= 0 {
+		pageSize = utils.PageSize20
+	}
+	if currentIndex <= 0 {
+		currentIndex = 1
+	}
+
+	sortCondition := " ORDER BY published_time "
+	if sortType == "" {
+		sortType = "DESC"
+	}
+	sortCondition = sortCondition + sortType
+	total, err := models.GetMediaCountByCondition(models.Audio, condition, pars)
+	if err != nil {
+		br.Msg = "获取音频列表失败"
+		br.ErrMsg = "获取音频列表统计失败,Err:" + err.Error()
+		return
+	}
+
+	startSize := utils.StartIndex(currentIndex, pageSize)
+	reportList, err := models.GetMediaByCondition(models.Audio, condition, sortCondition, pars, startSize, pageSize)
+	if err != nil {
+		br.Msg = "获取音频列表失败"
+		br.ErrMsg = "获取音频列表失败,Err:" + err.Error()
+		return
+	}
+	var reportViewList []*models.ESMedia
+	for _, report := range reportList {
+		reportView := report.ToView()
+		reportViewList = append(reportViewList, reportView)
+	}
+	page := paging.GetPaging(currentIndex, pageSize, total)
+	resp := new(response.MediaListResp)
+	resp.List = reportViewList
+	resp.Paging = page
+
+	br.Ret = 200
+	br.Success = true
+	br.Data = resp
+	br.Msg = "获取成功"
+}

+ 14 - 10
controllers/message.go

@@ -34,6 +34,7 @@ func (this *MessageController) ReportList() {
 	permissionIds := this.GetString("PermissionIds")
 	analystNames := this.GetString("AnalystNames")
 	sortType := this.GetString("SortType")
+	KeyWord := this.GetString("KeyWord")
 	var permissionCondition string
 	var condition string
 	var pars []interface{}
@@ -44,6 +45,9 @@ func (this *MessageController) ReportList() {
 	if currentIndex <= 0 {
 		currentIndex = 1
 	}
+	if KeyWord != "" {
+		condition += " AND title like '%" + KeyWord + "%'"
+	}
 	var permissionPars []interface{}
 	var classifyPars []interface{}
 	if permissionIds != "" {
@@ -192,13 +196,13 @@ func (this *MessageController) AudioList() {
 		br.ErrMsg = "获取研报列表失败,Err:" + err.Error()
 		return
 	}
-	var reportViewList []*models.ESMedia
+	var reportViewList []*models.MessageMedia
 	for _, report := range reportList {
-		reportView := report.ToView()
+		reportView := report.ToMessageView()
 		reportViewList = append(reportViewList, reportView)
 	}
 	page := paging.GetPaging(currentIndex, pageSize, total)
-	resp := new(response.MediaListResp)
+	resp := new(response.MessageMediaListResp)
 	resp.List = reportViewList
 	resp.Paging = page
 
@@ -275,25 +279,25 @@ func (this *MessageController) VideoList() {
 	sortCondition = sortCondition + sortType
 	total, err := models.GetMediaCountByCondition(models.Video, condition, pars)
 	if err != nil {
-		br.Msg = "获取研报列表失败"
-		br.ErrMsg = "获取研报列表统计失败,Err:" + err.Error()
+		br.Msg = "获取视频列表失败"
+		br.ErrMsg = "获取视频列表统计失败,Err:" + err.Error()
 		return
 	}
 
 	startSize := utils.StartIndex(currentIndex, pageSize)
 	List, err := models.GetMediaByCondition(models.Video, condition, sortCondition, pars, startSize, pageSize)
 	if err != nil {
-		br.Msg = "获取研报列表失败"
-		br.ErrMsg = "获取研报列表失败,Err:" + err.Error()
+		br.Msg = "获取视频列表失败"
+		br.ErrMsg = "获取视频列表失败,Err:" + err.Error()
 		return
 	}
-	var reportViewList []*models.ESMedia
+	var reportViewList []*models.MessageMedia
 	for _, report := range List {
-		reportView := report.ToView()
+		reportView := report.ToMessageView()
 		reportViewList = append(reportViewList, reportView)
 	}
 	page := paging.GetPaging(currentIndex, pageSize, total)
-	resp := new(response.MediaListResp)
+	resp := new(response.MessageMediaListResp)
 	resp.List = reportViewList
 	resp.Paging = page
 

+ 64 - 0
controllers/video.go

@@ -9,6 +9,7 @@ import (
 	"eta/eta_mini_crm_ht/services/elastic"
 	"eta/eta_mini_crm_ht/utils"
 	"fmt"
+	"github.com/rdlucklib/rdluck_tools/paging"
 	"os"
 	"path"
 	"strconv"
@@ -296,3 +297,66 @@ func (this *VideoController) DeleteVideo() {
 	br.Ret = 200
 	br.Success = true
 }
+
+// VideoList
+// @Title 研报列表
+// @Description pdf研报列表
+// @Param   PageSize   query   int  true       "每页数据条数"
+// @Param   CurrentIndex   query   int  true       "当前页页码,从1开始"
+// @Param   ClassifyIds   query   string  true       "二级分类id,可多选用英文,隔开"
+// @Param   KeyWord   query   string  true       "报告标题/创建人"
+// @Param   SortType   query   string  true       "排序方式"
+// @Success 200 {object} models.ReportAuthorResp
+// @router /videoList [get]
+func (this *VideoController) VideoList() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	pageSize, _ := this.GetInt("PageSize")
+	currentIndex, _ := this.GetInt("CurrentIndex")
+	sortType := this.GetString("SortType")
+	var condition string
+	var pars []interface{}
+
+	if pageSize <= 0 {
+		pageSize = utils.PageSize20
+	}
+	if currentIndex <= 0 {
+		currentIndex = 1
+	}
+	sortCondition := " ORDER BY published_time "
+	if sortType == "" {
+		sortType = "DESC"
+	}
+	sortCondition = sortCondition + sortType
+	total, err := models.GetMediaCountByCondition(models.Video, condition, pars)
+	if err != nil {
+		br.Msg = "获取视频列表失败"
+		br.ErrMsg = "获取视频列表统计失败,Err:" + err.Error()
+		return
+	}
+
+	startSize := utils.StartIndex(currentIndex, pageSize)
+	List, err := models.GetMediaByCondition(models.Video, condition, sortCondition, pars, startSize, pageSize)
+	if err != nil {
+		br.Msg = "获取视频列表失败"
+		br.ErrMsg = "获取视频列表失败,Err:" + err.Error()
+		return
+	}
+	var reportViewList []*models.ESMedia
+	for _, report := range List {
+		reportView := report.ToView()
+		reportViewList = append(reportViewList, reportView)
+	}
+	page := paging.GetPaging(currentIndex, pageSize, total)
+	resp := new(response.MediaListResp)
+	resp.List = reportViewList
+	resp.Paging = page
+
+	br.Ret = 200
+	br.Success = true
+	br.Data = resp
+	br.Msg = "获取成功"
+}

+ 8 - 0
go.mod

@@ -15,14 +15,17 @@ require (
 	github.com/minio/minio-go/v7 v7.0.74
 	github.com/olivere/elastic/v7 v7.0.32
 	github.com/rdlucklib/rdluck_tools v1.0.3
+	github.com/silenceper/wechat/v2 v2.1.6
 	github.com/tcolgate/mp3 v0.0.0-20170426193717-e79c5a46d300
 )
 
 require (
 	github.com/beorn7/perks v1.0.1 // indirect
+	github.com/bradfitz/gomemcache v0.0.0-20220106215444-fb4bf637b56d // indirect
 	github.com/cespare/xxhash/v2 v2.2.0 // indirect
 	github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
 	github.com/dustin/go-humanize v1.0.1 // indirect
+	github.com/fatih/structs v1.1.0 // indirect
 	github.com/go-ini/ini v1.67.0 // indirect
 	github.com/goccy/go-json v0.10.3 // indirect
 	github.com/golang/protobuf v1.5.3 // indirect
@@ -46,6 +49,11 @@ require (
 	github.com/prometheus/procfs v0.9.0 // indirect
 	github.com/rs/xid v1.5.0 // indirect
 	github.com/shiena/ansicolor v0.0.0-20200904210342-c7312218db18 // indirect
+	github.com/sirupsen/logrus v1.9.0 // indirect
+	github.com/spf13/cast v1.4.1 // indirect
+	github.com/tidwall/gjson v1.14.1 // indirect
+	github.com/tidwall/match v1.1.1 // indirect
+	github.com/tidwall/pretty v1.2.0 // indirect
 	golang.org/x/crypto v0.24.0 // indirect
 	golang.org/x/net v0.26.0 // indirect
 	golang.org/x/sys v0.21.0 // indirect

+ 30 - 0
models/media.go

@@ -47,6 +47,36 @@ type ESMedia struct {
 	PublishedTime         string    `json:"publishedTime"`
 }
 
+func (m *Media) ToMessageView() *MessageMedia {
+	return &MessageMedia{
+		MediaId:               m.Id,
+		AuthorId:              m.AuthorId,
+		AuthorName:            m.AuthorName,
+		MediaType:             m.MediaType,
+		Src:                   m.Src,
+		MediaName:             m.MediaName,
+		SourceType:            m.SourceType,
+		SendStatus:            m.SendStatus,
+		MediaPlayMilliseconds: m.MediaPlayMilliseconds,
+		PermissionIds:         m.PermissionIds,
+		PublishedTime:         m.PublishedTime.Format(time.DateTime),
+	}
+}
+
+type MessageMedia struct {
+	MediaId               int        `json:"mediaId"`
+	AuthorId              int        `json:"authorId"`
+	AuthorName            string     `json:"authorName"`
+	CoverSrc              string     `json:"coverSrc"`
+	MediaType             MediaType  `json:"mediaType"`
+	Src                   string     `json:"src"`
+	MediaName             string     `json:"mediaName"`
+	SourceType            string     `json:"sourceType"`
+	SendStatus            SendStatus `json:"sendStatus"`
+	MediaPlayMilliseconds int        `json:"mediaPlayMilliseconds"`
+	PermissionIds         string     `json:"permissionIds"`
+	PublishedTime         string     `json:"publishedTime"`
+}
 type Media struct {
 	Id                    int        `orm:"pk;auto" description:"id"`
 	AuthorId              int        `description:"author_id"`

+ 4 - 0
models/response/media.go

@@ -10,6 +10,10 @@ type MediaListResp struct {
 	Paging *paging.PagingItem `description:"分页数据"`
 }
 
+type MessageMediaListResp struct {
+	List   []*models.MessageMedia
+	Paging *paging.PagingItem `description:"分页数据"`
+}
 type MediaUploadResp struct {
 	FileName            string `description:"上传文件名称"`
 	Url                 string `description:"上传文件URL"`

+ 21 - 0
models/user_template_record.go

@@ -0,0 +1,21 @@
+package models
+
+import "github.com/beego/beego/v2/client/orm"
+
+type UserTemplateRecord struct {
+	Id         int    `orm:"pk" description:"id"`
+	UserId     int    `description:"用户id"`
+	OpenId     string `description:"用户openid"`
+	SendData   string `description:"发送内容"`
+	Result     string `description:"响应结果"`
+	CreateDate string `description:"创建日期"`
+	CreateTime string `description:"创建时间"`
+	SendStatus int    `description:"发送状态"`   // 1:发送成功,0:发送失败
+	SendType   int    `description:"发送消息类型"` // 1:报告模板消息
+}
+
+func (u *UserTemplateRecord) Insert() (err error) {
+	o := orm.NewOrm()
+	_, err = o.Insert(u)
+	return
+}

+ 24 - 0
models/wx_token.go

@@ -0,0 +1,24 @@
+package models
+
+import (
+	"github.com/beego/beego/v2/client/orm"
+)
+
+type WxToken struct {
+	id          int
+	AccessToken string
+	ExpiresIn   int64
+}
+
+func GetWxTokenById() (token WxToken, err error) {
+	o := orm.NewOrm()
+	sql := "select * from wx_token"
+	err = o.Raw(sql).QueryRow(&token)
+	return
+}
+
+func (w *WxToken) Update(columns []string) (err error) {
+	o := orm.NewOrm()
+	_, err = o.Update(w, columns...)
+	return
+}

+ 18 - 0
routers/commentsRouter.go

@@ -54,6 +54,15 @@ func init() {
             Filters: nil,
             Params: nil})
 
+    beego.GlobalControllerRouter["eta/eta_mini_crm_ht/controllers:AudioController"] = append(beego.GlobalControllerRouter["eta/eta_mini_crm_ht/controllers:AudioController"],
+        beego.ControllerComments{
+            Method: "AudioList",
+            Router: `/audioList`,
+            AllowHTTPMethods: []string{"get"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
     beego.GlobalControllerRouter["eta/eta_mini_crm_ht/controllers:AudioController"] = append(beego.GlobalControllerRouter["eta/eta_mini_crm_ht/controllers:AudioController"],
         beego.ControllerComments{
             Method: "DeleteAudio",
@@ -675,4 +684,13 @@ func init() {
             Filters: nil,
             Params: nil})
 
+    beego.GlobalControllerRouter["eta/eta_mini_crm_ht/controllers:VideoController"] = append(beego.GlobalControllerRouter["eta/eta_mini_crm_ht/controllers:VideoController"],
+        beego.ControllerComments{
+            Method: "VideoList",
+            Router: `/videoList`,
+            AllowHTTPMethods: []string{"get"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
 }

+ 189 - 0
services/template_msg.go

@@ -0,0 +1,189 @@
+package services
+
+import (
+	"bytes"
+	"encoding/json"
+	"errors"
+	"eta/eta_mini_crm_ht/models"
+	"eta/eta_mini_crm_ht/utils"
+	"fmt"
+	"io"
+	"net/http"
+	"time"
+)
+
+var (
+	TemplateMsgSendUrl       = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=%s"
+	TemplateMsgClearQuotaUrl = "https://api.weixin.qq.com/cgi-bin/clear_quota?access_token=%s"
+)
+
+type TemplateMsgSendClient struct {
+	AccessToken string
+	Data        []byte
+}
+
+type SendTemplateResponse struct {
+	Errcode int    `json:"errcode"`
+	Errmsg  string `json:"errmsg"`
+	MsgID   int    `json:"msgid"`
+}
+
+type ClearQuotaResponse struct {
+	Errcode int    `json:"errcode"`
+	Errmsg  string `json:"errmsg"`
+}
+
+type OpenIdList struct {
+	OpenId string
+	UserId int
+}
+
+// TemplateMsgSendClient.ClearQuota 清除发送超过当日10万次限制
+func (c *TemplateMsgSendClient) ClearQuota() (result *ClearQuotaResponse, err error) {
+	key := "CACHE_SendTemplateMsg_ERR"
+	exists := utils.Rc.IsExist(key)
+	if exists {
+		return
+	}
+	_ = utils.Rc.SetEX(key, 1, 6*time.Minute)
+
+	sendUrl := fmt.Sprintf(TemplateMsgClearQuotaUrl, c.AccessToken)
+	client := http.Client{}
+	clearData := make(map[string]interface{})
+	clearData["appid"] = utils.HT_WX_APPID
+	clearJson, _ := json.Marshal(clearData)
+	resp, err := client.Post(sendUrl, "application/json", bytes.NewBuffer(clearJson))
+	if err != nil {
+		return
+	}
+	defer func() {
+		_ = resp.Body.Close()
+	}()
+	clearBody, err := io.ReadAll(resp.Body)
+	err = json.Unmarshal(clearBody, &result)
+	return
+}
+
+// TemplateMsgSendClient.SendMsg 推送消息
+func (c *TemplateMsgSendClient) SendMsg() (sendRes *SendTemplateResponse, err error) {
+	// 请求接口
+	sendUrl := fmt.Sprintf(TemplateMsgSendUrl, c.AccessToken)
+	client := http.Client{}
+	resp, err := client.Post(sendUrl, "application/json", bytes.NewBuffer(c.Data))
+	if err != nil {
+		return
+	}
+	defer func() {
+		_ = resp.Body.Close()
+	}()
+	body, _ := io.ReadAll(resp.Body)
+	if err = json.Unmarshal(body, &sendRes); err != nil {
+		return
+	}
+	// 模板消息发送超过当日10万次限制错误处理
+	if sendRes.Errcode == 45009 {
+		// 发送提示邮件
+		// go alarm_msg.SendAlarmMsg("模板消息发送超过当日10万次限制, SendTemplateResponse: "+string(body), 3)
+		// 清理限制
+		clearRes, e := c.ClearQuota()
+		if e != nil {
+			err = e
+			return
+		}
+		if clearRes.Errcode != 0 {
+			clearJson, er := json.Marshal(clearRes)
+			if er != nil {
+				return nil, er
+			}
+			fmt.Println("自动清理模板消息限制接口, 调用失败, ClearQuotaResponse: " + string(clearJson))
+			// go alarm_msg.SendAlarmMsg("自动清理模板消息限制接口, 调用失败, ClearQuotaResponse: "+string(clearJson), 3)
+			return
+		}
+		// 发送成功邮件
+		// go alarm_msg.SendAlarmMsg("自动清理模板消息限制接口, 调用成功", 1)
+		// 重新推送
+		go func() {
+			_, e := c.SendMsg()
+			if e != nil {
+				return
+				// reSendJson, _ := json.Marshal(reSend)
+				// alarm_msg.SendAlarmMsg("重新推送模板消息失败, SendTemplateResponse: "+string(reSendJson), 3)
+			}
+		}()
+	}
+	if sendRes.Errcode != 0 {
+		err = errors.New("推送模板消息失败, SendTemplateResponse: " + string(body))
+	}
+	return
+}
+
+// AddUserTemplateRecord 新增模板消息推送记录
+func AddUserTemplateRecord(userId, sendStatus, sendType int, openid, sendData, result string) (err error) {
+	item := &models.UserTemplateRecord{
+		UserId:     userId,
+		OpenId:     openid,
+		SendData:   sendData,
+		Result:     result,
+		CreateDate: time.Now().Format(utils.FormatDate),
+		CreateTime: time.Now().Format(utils.FormatDateTime),
+		SendStatus: sendStatus,
+		SendType:   sendType,
+	}
+	err = item.Insert()
+	return
+}
+
+// SendMultiTemplateMsg 推送模板消息至多个用户
+func SendMultiTemplateMsg(sendData map[string]interface{}, items []*OpenIdList, sendType, reportId int) (err error) {
+	ws := GetWxChat()
+	accessToken, err := ws.GetAccessToken()
+	if err != nil {
+		utils.FileLog.Info("获取微信token失败, Err:" + err.Error())
+		// alarm_msg.SendAlarmMsg("获取微信token失败, Err:"+err.Error(), 1)
+		return
+	}
+
+	sendMap := make(map[string]interface{})
+	for _, item := range items {
+		sendMap["template_id"] = utils.TEMPLATE_ID_BY_PRODUCT
+		sendMap["miniprogram"] = map[string]interface{}{
+			//"appid":    utils.HT_MINI_APPID,
+			"pagepath": fmt.Sprintf("pages-report/reportDetail/index?id=%d", reportId),
+		}
+		sendMap["touser"] = item.OpenId
+		sendMap["data"] = sendData
+		data, e := json.Marshal(sendMap)
+		if e != nil {
+			utils.FileLog.Info("新增模板消息推送记录失败, Err:" + e.Error())
+			return
+		}
+		ts := &TemplateMsgSendClient{
+			AccessToken: accessToken,
+			Data:        data,
+		}
+		result, e := ts.SendMsg()
+		if e != nil {
+			utils.FileLog.Info("新增模板消息推送记录失败, Err:" + e.Error())
+			return
+		}
+		if result == nil {
+			return
+		}
+		// 推送消息记录
+		{
+			go func() {
+				sendStatus := 1
+				if e != nil {
+					sendStatus = 0
+				}
+				resultJson, _ := json.Marshal(result)
+				err = AddUserTemplateRecord(item.UserId, sendStatus, sendType, item.OpenId, string(data), string(resultJson))
+				if err != nil {
+					utils.FileLog.Info("新增模板消息推送记录失败, Err:" + err.Error())
+					return
+				}
+			}()
+		}
+	}
+	return
+}

+ 123 - 0
services/wechat.go

@@ -0,0 +1,123 @@
+package services
+
+import (
+	"eta/eta_mini_crm_ht/models"
+	"eta/eta_mini_crm_ht/utils"
+	"fmt"
+	"github.com/silenceper/wechat/v2"
+	"github.com/silenceper/wechat/v2/cache"
+	"github.com/silenceper/wechat/v2/credential"
+	"github.com/silenceper/wechat/v2/officialaccount"
+	"github.com/silenceper/wechat/v2/officialaccount/config"
+	"github.com/silenceper/wechat/v2/officialaccount/js"
+	"github.com/silenceper/wechat/v2/officialaccount/user"
+	"time"
+)
+
+type WechatAccessToken struct {
+}
+
+func GetWxChat() (officialAccount *officialaccount.OfficialAccount) {
+	wc := wechat.NewWechat()
+	memory := cache.NewMemory()
+	conf := &config.Config{
+		AppID:          utils.HT_WX_APPID,
+		AppSecret:      utils.HT_WX_APP_SECRET,
+		Token:          "",
+		EncodingAESKey: "",
+		Cache:          memory,
+	}
+	officialAccount = wc.GetOfficialAccount(conf)
+	wechatAccessToken := &WechatAccessToken{}
+	officialAccount.SetAccessTokenHandle(wechatAccessToken)
+	return
+}
+
+// GetAccessToken 获取accessToken
+func (wechat WechatAccessToken) GetAccessToken() (accessToken string, err error) {
+	//如果300s就要过期了,那么就去刷新accessToken
+	wxToken, err := models.GetWxTokenById()
+	if err != nil {
+		return
+	}
+	//如果300s就要过期了,那么就去刷新accessToken
+	if wxToken.ExpiresIn < time.Now().Unix()+300 {
+		tmpAccessToken, expires, tmpErr := getTokenFromServer(utils.HT_WX_APPID, utils.HT_WX_APP_SECRET)
+		if tmpErr != nil {
+			err = tmpErr
+			return
+		}
+
+		var updateCols = []string{"access_token", "expires_in"}
+		wxToken.AccessToken = tmpAccessToken
+		wxToken.ExpiresIn = time.Now().Unix() + expires - 600 //快过期前10分钟就刷新掉
+		wxToken.Update(updateCols)
+	}
+	accessToken = wxToken.AccessToken
+	return
+}
+
+// accessToken, err = utils.Rc.RedisString(utils.CACHE_WX_ACCESS_TOKEN_DW)
+// if accessToken != "" {
+// 	return
+// }
+
+// // 缓存中没有取到数据,那么就需要强制刷新的accessToken
+// tmpAccessToken, _, tmpErr := getTokenFromServer(utils.DW_WX_APPID, utils.DW_WX_APP_SECRET)
+// if tmpAccessToken == "" {
+// 	err = errors.New("获取微信token失败,Err:" + tmpErr.Error())
+// 	return
+// }
+
+// redisTimeExpire := time.Duration(expires-600) * time.Second
+// err = utils.Rc.Put(utils.CACHE_WX_ACCESS_TOKEN_HZ, tmpAccessToken, redisTimeExpire)
+// if err != nil {
+// 	err = errors.New("更新微信token失败")
+// 	return
+// }
+// accessToken = tmpAccessToken
+// return
+// //如果300s就要过期了,那么就去刷新accessToken
+// if wxToken.ExpiresIn < time.Now().Unix()+300 {
+// 	tmpAccessToken, expires, tmpErr := getTokenFromServer(WxAppId, WxAppSecret)
+// 	if tmpErr != nil {
+// 		err = tmpErr
+// 		return
+// 	}
+
+// 	var updateCols = []string{"access_token", "expires_in"}
+// 	wxToken.AccessToken = tmpAccessToken
+// 	wxToken.ExpiresIn = expires - 600 //快过期前10分钟就刷新掉
+// 	wxToken.Update(updateCols)
+// }
+// accessToken = wxToken.AccessToken
+// return refreshWxAccessToken(wxAppId, wxAppSecret)
+
+// getTokenFromServer 服务端获取accessToken
+func getTokenFromServer(appid, wxSecret string) (accessToken string, expires int64, err error) {
+	apiUrl := "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s"
+	resAccessToken, err := credential.GetTokenFromServer(fmt.Sprintf(apiUrl, appid, wxSecret))
+	if err != nil {
+		return
+	}
+
+	expires = resAccessToken.ExpiresIn
+	accessToken = resAccessToken.AccessToken
+	return
+}
+
+// GetUserInfo 获取微信用户详情
+func GetUserInfo(openid string) (userInfo *user.Info, err error) {
+	wechatClient := GetWxChat()
+	userClient := wechatClient.GetUser()
+	userInfo, err = userClient.GetUserInfo(openid)
+	return
+}
+
+// GetJsConfig 获取公众号jsConfig
+func GetJsConfig(signUrl string) (jsConf *js.Config, err error) {
+	wechatClient := GetWxChat()
+	j := wechatClient.GetJs()
+	jsConf, err = j.GetConfig(signUrl)
+	return
+}

+ 10 - 1
utils/config.go

@@ -69,6 +69,11 @@ var (
 	ES_USERNAME string // ES账号
 	ES_PASSWORD string // ES密码
 )
+var (
+	HT_WX_APP_SECRET       string
+	HT_WX_APPID            string
+	TEMPLATE_ID_BY_PRODUCT string
+)
 
 // ES索引配置
 var (
@@ -171,7 +176,11 @@ func init() {
 	{
 		MINI_REPORT_INDEX_NAME = config["mini_report_index_name"]
 	}
-
+	{
+		HT_WX_APPID = config["ht_wx_appid"]
+		HT_WX_APP_SECRET = config["ht_wx_app_secret"]
+		TEMPLATE_ID_BY_PRODUCT = config["template_id_by_product"]
+	}
 	// 初始化ES
 	initEs()
 

+ 1 - 0
utils/redis.go

@@ -12,6 +12,7 @@ type RedisClient interface {
 	RedisInt(key string) (data int, err error)
 	Put(key string, val interface{}, timeout time.Duration) error
 	SetNX(key string, val interface{}, timeout time.Duration) bool
+	SetEX(key string, val interface{}, timeout time.Duration) bool
 	Delete(key string) error
 	IsExist(key string) bool
 	LPush(key string, val interface{}) error

+ 8 - 0
utils/redis/cluster_redis.go

@@ -155,6 +155,14 @@ func (rc *ClusterRedisClient) SetNX(key string, val interface{}, timeout time.Du
 	return result
 }
 
+func (rc *ClusterRedisClient) SetEX(key string, val interface{}, timeout time.Duration) bool {
+	_, err := rc.redisClient.SetEX(context.TODO(), key, val, timeout).Result()
+	if err != nil {
+		return false
+	}
+	return true
+}
+
 // Delete
 // @Description: 删除redis中的键值对
 // @receiver rc

+ 8 - 0
utils/redis/standalone_redis.go

@@ -78,6 +78,14 @@ func (rc *StandaloneRedisClient) Get(key string) interface{} {
 	return data
 }
 
+func (rc *StandaloneRedisClient) SetEX(key string, val interface{}, timeout time.Duration) bool {
+	_, err := rc.redisClient.SetEX(context.TODO(), key, val, timeout).Result()
+	if err != nil {
+		return false
+	}
+	return true
+}
+
 // RedisBytes
 // @Description: 根据key获取字节编码数据
 // @receiver rc