浏览代码

add:添加模板推送

zqbao 10 月之前
父节点
当前提交
b71502352f
共有 9 个文件被更改,包括 229 次插入29 次删除
  1. 0 1
      controllers/report.go
  2. 134 1
      controllers/wechat.go
  3. 24 0
      models/user.go
  4. 7 0
      models/user_chart_permission_mapping.go
  5. 17 0
      models/user_record.go
  6. 0 5
      services/template_msg.go
  7. 32 22
      services/wechat.go
  8. 10 0
      utils/config.go
  9. 5 0
      utils/constants.go

+ 0 - 1
controllers/report.go

@@ -283,7 +283,6 @@ func (this *ReportController) Detail() {
 		}
 	} else {
 		report.IsPublic = IsPublic
-
 	}
 	resp.Report = report
 	resp.Status = utils.ReportPermissionStatusHas

+ 134 - 1
controllers/wechat.go

@@ -4,6 +4,11 @@ import (
 	"encoding/json"
 	"eta/eta_mini_bridge/models"
 	"eta/eta_mini_bridge/models/request"
+	"eta/eta_mini_bridge/services"
+	"eta/eta_mini_bridge/utils"
+	"fmt"
+	"html"
+	"strconv"
 )
 
 type WeChatController struct {
@@ -12,7 +17,7 @@ type WeChatController struct {
 
 // @Title 发送微信模板接口
 // @Description 发送微信模板接口
-// @Param   Url   query   string  true       "url地址"
+// @Param	request	body request.SendWxTemplateReq true "type json string"
 // @Success 200 {object} models.WechatSign
 // @router /send_template_msg [post]
 func (this *WeChatController) SendTemplateMsg() {
@@ -27,4 +32,132 @@ func (this *WeChatController) SendTemplateMsg() {
 		br.ErrMsg = "参数解析错误,Err:" + err.Error()
 		return
 	}
+	report, err := models.GetReportById(req.ReportId)
+	if err != nil {
+		br.Msg = "该报告已删除"
+		br.ErrMsg = "获取报告详情失败,Err:" + err.Error()
+		return
+	}
+	report.ContentSub = html.UnescapeString(report.ContentSub)
+	report.Content = html.UnescapeString(report.Content)
+	if report == nil {
+		br.Msg = "报告不存在"
+		return
+	}
+	reportChartPermissionIdStrs, err := models.GetChartPermissionIdsListByClassifyId(report.ClassifyIdSecond)
+	if err != nil {
+		br.Msg = "获取研报权限失败"
+		br.ErrMsg = "获取研报权限失败,Err:" + err.Error()
+		return
+	}
+	chartPermissionList, err := models.GetChartPermissionIdsByIds(reportChartPermissionIdStrs)
+	if err != nil {
+		br.Msg = "获取研报权限失败"
+		br.ErrMsg = "获取研报权限失败,Err:" + err.Error()
+		return
+	}
+	permissionMapping, err := models.GetUserChartPermissionMapping()
+	if err != nil {
+		br.Msg = "获取用户权限失败"
+		br.ErrMsg = "获取用户权限失败,Err:" + err.Error()
+		return
+	}
+	// 获取不同二级品种分类下的的小程序用户列表映射
+	permissionMap := make(map[int][]int)
+	for _, v := range permissionMapping {
+		if _, ok := permissionMap[v.ChartPermissionId]; !ok {
+			permissionMap[v.ChartPermissionId] = make([]int, 0)
+		} else {
+			permissionMap[v.ChartPermissionId] = append(permissionMap[v.ChartPermissionId], v.UserId)
+		}
+	}
+	var IsPublic bool
+	for _, v := range chartPermissionList {
+		if v.IsPublic == 1 {
+			IsPublic = true
+			break
+		}
+	}
+	userList, err := models.GetUserBySubscribe()
+	if err != nil {
+		br.Msg = "获取用户列表失败"
+		br.ErrMsg = "获取用户列表失败,Err:" + err.Error()
+		return
+	}
+	var openIds []*services.OpenIdList
+	if IsPublic {
+		var unionIds []string
+		userMap := make(map[int]*models.User)
+		for _, v := range userList {
+			unionIds = append(unionIds, v.UnionId)
+			userMap[v.UserId] = v
+		}
+		// 给所有人,发送模板消息
+		records, err := models.GetUserRecordByUnionids(unionIds)
+		if err != nil {
+			br.Msg = "获取用户记录失败"
+			br.ErrMsg = "获取用户记录失败,Err:" + err.Error()
+			return
+		}
+		for _, v := range records {
+			openIds = append(openIds, &services.OpenIdList{
+				OpenId: v.OpenId,
+				UserId: v.UserId,
+			})
+		}
+	} else {
+		// 给指定用户,发送模板消息
+		// 报告所属的二级品种分类
+		var permissionIds []int
+		for _, v := range reportChartPermissionIdStrs {
+			vv, _ := strconv.Atoi(v)
+			permissionIds = append(permissionIds, vv)
+		}
+		var sendUserIds []int
+		// 获取报告所属的二级品种分类对应的用户列表
+		for _, v := range permissionIds {
+			if _, ok := permissionMap[v]; ok {
+				sendUserIds = append(sendUserIds, permissionMap[v]...)
+			}
+		}
+		unionIds, err := models.GetUserUnionIdListByIds(sendUserIds)
+		if err != nil {
+			br.Msg = "获取用户信息失败"
+			br.ErrMsg = "获取用户unionId失败,Err:" + err.Error()
+			return
+		}
+		records, err := models.GetUserRecordByUnionids(unionIds)
+		if err != nil {
+			br.Msg = "获取用户记录失败"
+			br.ErrMsg = "获取用户记录失败,Err:" + err.Error()
+			return
+		}
+		for _, v := range records {
+			openIds = append(openIds, &services.OpenIdList{
+				OpenId: v.OpenId,
+				UserId: v.UserId,
+			})
+		}
+	}
+	sendMap := make(map[string]interface{})
+	sendMap["template_id"] = utils.TEMPLATE_ID_BY_PRODUCT
+	sendMap["first"] = fmt.Sprintf("Hi,最新一期%s已上线,欢迎查看", report.ClassifyNameFirst)
+	sendMap["keyword1"] = map[string]interface{}{"value": fmt.Sprintf("弘则%s", report.ClassifyNameSecond), "color": "#173177"}
+	sendMap["keyword2"] = map[string]interface{}{"value": report.ContentSub, "color": "#173177"}
+	sendMap["keyword3"] = map[string]interface{}{"value": report.PublishTime, "color": "#173177"}
+	sendMap["keyword4"] = map[string]interface{}{"value": report.Abstract, "color": "#173177"}
+	sendMap["miniprogram"] = map[string]string{
+		"appid":    utils.WX_MINI_APPID,
+		"pagepath": fmt.Sprintf("pages-report/reportDetail/index?id=%d", report.Id),
+	}
+	err = services.SendMultiTemplateMsg(sendMap, openIds, 1)
+	if err != nil {
+		br.Msg = "发送失败"
+		br.ErrMsg = "发送失败,Err:" + err.Error()
+		return
+	}
+
+	br.Ret = 200
+	br.Msg = "发送成功"
+	br.Success = true
 }

+ 24 - 0
models/user.go

@@ -1,6 +1,8 @@
 package models
 
 import (
+	"fmt"
+	"strings"
 	"time"
 
 	"github.com/beego/beego/v2/client/orm"
@@ -59,6 +61,13 @@ func ModifyUserRegisterStatus(userId int, status bool, registerTime, modifyTime
 	return
 }
 
+func GetUserBySubscribe() (user []*User, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT user FROM user WHERE is_subscribed=1 AND is_registered=1 `
+	err = o.Raw(sql).QueryRow(&user)
+	return
+}
+
 func GetUserById(userId int) (item *User, err error) {
 	o := orm.NewOrm()
 	sql := `SELECT * FROM user WHERE user_id=? `
@@ -93,3 +102,18 @@ func GetUserItemByUserId(userId int) (item *UserItem, err error) {
 	err = orm.NewOrm().Raw(sql, userId).QueryRow(&item)
 	return
 }
+
+func GetUserUnionIdListByIds(userIds []int) (items []string, err error) {
+	sql := `SELECT union_id FROM user WHERE user_id IN (%s) `
+	var idsStr string
+	if len(userIds) > 0 {
+		var userIdsStr []string
+		for _, userId := range userIds {
+			userIdsStr = append(userIdsStr, fmt.Sprint(userId))
+		}
+		idsStr = strings.Join(userIdsStr, ",")
+		sql = fmt.Sprintf(sql, idsStr)
+	}
+	_, err = orm.NewOrm().Raw(sql).QueryRows(&items)
+	return
+}

+ 7 - 0
models/user_chart_permission_mapping.go

@@ -14,3 +14,10 @@ func GetChartPermissionIdByUserId(UserId int) (items []string, err error) {
 	_, err = o.Raw(sql, UserId).QueryRows(&items)
 	return
 }
+
+func GetUserChartPermissionMapping() (items []*UserChartPermissionMapping, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT * FROM user_chart_permission_mapping`
+	_, err = o.Raw(sql).QueryRows(&items)
+	return
+}

+ 17 - 0
models/user_record.go

@@ -1,6 +1,7 @@
 package models
 
 import (
+	"strings"
 	"time"
 
 	"github.com/beego/beego/v2/client/orm"
@@ -30,3 +31,19 @@ func GetUserRecordByUserId(userId int) (item *UserRecord, err error) {
 	err = orm.NewOrm().Raw(sql, userId).QueryRow(&item)
 	return
 }
+
+func GetUserRecordByUnionids(unionIds []string) (items []*UserRecord, err error) {
+	if len(unionIds) == 0 {
+		return
+	}
+	sql := `SELECT * FROM user_record WHERE union_id in (`
+	var idsStr string
+	if len(unionIds) > 0 {
+		idsStr = strings.Join(unionIds, ",")
+		sql += idsStr
+	}
+	sql += `) `
+	_, err = orm.NewOrm().Raw(sql).QueryRows(&items)
+	return
+
+}

+ 0 - 5
services/template_msg.go

@@ -142,11 +142,6 @@ func SendMultiTemplateMsg(sendMap map[string]interface{}, items []*OpenIdList, s
 	}
 	for _, item := range items {
 		sendMap["touser"] = item.OpenId
-		sendMap["template_id"] = utils.TEMPLATE_ID_BY_PRODUCT
-		sendMap["miniprogram"] = map[string]string{
-			"appid":    utils.WX_MINI_APPID,
-			"pagepath": "report?report_id",
-		}
 		data, e := json.Marshal(sendMap)
 		if e != nil {
 			err = e

+ 32 - 22
services/wechat.go

@@ -1,7 +1,7 @@
 package services
 
 import (
-	"eta/eta_mini_bridge/models"
+	"errors"
 	"eta/eta_mini_bridge/utils"
 	"fmt"
 	"time"
@@ -15,11 +15,6 @@ import (
 	"github.com/silenceper/wechat/v2/officialaccount/user"
 )
 
-var (
-	WxAppId     string
-	WxAppSecret string
-)
-
 type WechatAccessToken struct {
 }
 
@@ -27,8 +22,8 @@ func GetWxChat() (officialAccount *officialaccount.OfficialAccount) {
 	wc := wechat.NewWechat()
 	memory := cache.NewMemory()
 	conf := &config.Config{
-		AppID:          utils.DW_WX_APPID,
-		AppSecret:      utils.DW_WX_APP_SECRET,
+		AppID:          utils.WX_APPID,
+		AppSecret:      utils.WX_APP_SECRET,
 		Token:          "",
 		EncodingAESKey: "",
 		Cache:          memory,
@@ -41,27 +36,42 @@ func GetWxChat() (officialAccount *officialaccount.OfficialAccount) {
 
 // GetAccessToken 获取accessToken
 func (wechat WechatAccessToken) GetAccessToken() (accessToken string, err error) {
-	wxToken, err := models.GetWxTokenById()
-	if err != nil {
+	accessToken, err = utils.Rc.RedisString(utils.CACHE_WX_ACCESS_TOKEN_HZ)
+	if accessToken != "" {
 		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
+	tmpAccessToken, expires, tmpErr := getTokenFromServer(utils.WX_APPID, utils.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 = wxToken.AccessToken
 	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"

+ 10 - 0
utils/config.go

@@ -43,6 +43,8 @@ var (
 	DW_WX_APPID            string
 	DW_WX_APP_SECRET       string
 	TEMPLATE_ID_BY_PRODUCT string
+	WX_APPID               string // 弘则投研测试公众号
+	WX_APP_SECRET          string
 )
 
 // ES配置
@@ -96,6 +98,14 @@ func init() {
 	DW_WX_APPID = config["dw_wx_appid"]
 	DW_WX_APP_SECRET = config["dw_wx_app_secret"]
 	TEMPLATE_ID_BY_PRODUCT = config["template_id_by_product"]
+	// 仅测试
+	TEMPLATE_ID_BY_PRODUCT = `-YjuPOB7Fqd-S3ilabYa6wvjDY9aXmeEfPN6DCiy-EY`
+
+	// 测试微信配置
+	// WX_APPID = config["wx_appid"]
+	// WX_APP_SECRET = config["wx_app_secret"]
+	WX_APPID = "wx9b5d7291e581233a"
+	WX_APP_SECRET = "f4d52e34021eee262dce9682b31f8861"
 
 	// redis缓存配置
 	REDIS_CACHE = config["beego_cache"]

+ 5 - 0
utils/constants.go

@@ -22,3 +22,8 @@ const (
 	ReportPermissionStatusNo           = 3 //没有权限
 	ReportPermissionStatusHas          = 4 //有该品种权限
 )
+
+// 缓存key
+const (
+	CACHE_WX_ACCESS_TOKEN_HZ = "wx:accesstoken:hzyj" //弘则研究公众号 微信accessToken
+)