zwxi hai 10 meses
pai
achega
d2b3a04781

+ 26 - 0
models/wechat.go

@@ -88,3 +88,29 @@ func ModifyAccessToken(accessToken string, expiresIn int64) (err error) {
 	}
 	return
 }
+
+
+func GetWxTokenMfyx() (item *WxAccessToken, err error) {
+	var getUrl string
+	if utils.RunMode == "debug"{
+		getUrl = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" + utils.WxAppId + "&secret=" + utils.WxAppSecret
+	}else{
+		getUrl = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" + utils.WxAppIdMfyx + "&secret=" + utils.WxAppSecretMfyx
+	}
+
+	result, err := http.Get(getUrl)
+	if err != nil {
+		utils.FileLog.Info("GetWxToken Err:", err.Error())
+		return
+	}
+	utils.FileLog.Info(fmt.Sprintf("GetWxAccessToken :%s", string(result)))
+	err = json.Unmarshal(result, &item)
+	if err != nil {
+		fmt.Println(fmt.Sprintf("GetWxToken Unmarshal Err:%s", err.Error()))
+		return
+	}
+	if item.Errmsg != "" {
+		utils.FileLog.Info(fmt.Sprintf("GetWxToken fail result:%s", string(result)))
+	}
+	return
+}

+ 303 - 0
services/wechat_send_category_msg_mfyx.go

@@ -0,0 +1,303 @@
+package services
+
+import (
+	"bytes"
+	"encoding/json"
+	"errors"
+	"fmt"
+	"eta/eta_pub/models"
+	"eta/eta_pub/services/alarm_msg"
+	"eta/eta_pub/utils"
+	"io/ioutil"
+	"net/http"
+	"time"
+)
+
+// sendCategoryTemplateMsgMfyx 整理openid以及以往历史推送记录,移除已经推送的记录,并开始依次推送
+func sendCategoryTemplateMsgMfyx(sendMap map[string]interface{}, openIdArr []string, resource, uniqueCode string, sendType int) (err error) {
+	for _, openId := range openIdArr {
+		sendMap["touser"] = openId
+		data, err := json.Marshal(sendMap)
+		if err != nil {
+			fmt.Println("SendTemplateMsgOne Marshal Err:", err.Error())
+			utils.FileLog.Info(fmt.Sprintf("SendTemplateMsgOne Marshal Err:%s", err.Error()))
+			err = errors.New("SendTemplateMsgOne Marshal Err:" + err.Error())
+			return err
+		}
+		err = toSendCategoryTemplateMsgMfyx(data, resource, sendType, openId, uniqueCode)
+		if err != nil {
+			err = errors.New("toSendTemplateMsgCygx Err:" + err.Error())
+			fmt.Println("send err:", err.Error())
+			utils.FileLog.Info(fmt.Sprintf("ToSendTemplateMsg Err:%s", err.Error()))
+		}
+	}
+	return
+}
+
+// toSendCategoryTemplateMsgMfyx 实际推送微信
+func toSendCategoryTemplateMsgMfyx(data []byte, resource string, sendType int, openId, uniqueCode string) (err error) {
+	utils.FileLog.Info("Send:" + string(data))
+	//获取accessToken
+	accessToken, err, errMsg := getWxMfyxAccessTokenCygx()
+	if err != nil {
+		err = errors.New("getWxAccessTokenCygx Err:" + err.Error())
+		utils.FileLog.Info(fmt.Sprintf("获取Token失败,err:%s,errMsg:%s", err.Error(), errMsg))
+		return
+	}
+	sendUrl := "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=" + accessToken
+
+	client := http.Client{}
+	resp, err := client.Post(sendUrl, "application/json", bytes.NewBuffer(data))
+	if err != nil {
+		err = errors.New("Post Err:" + err.Error())
+		return
+	}
+	defer resp.Body.Close()
+
+	body, _ := ioutil.ReadAll(resp.Body)
+	utils.FileLog.Info("Cygx_SendResult:" + string(body))
+	var templateResponse SendTemplateResponse
+	err = json.Unmarshal(body, &templateResponse)
+	if err != nil {
+		err = errors.New("SendResult Unmarshal Err:" + err.Error())
+		utils.FileLog.Info(fmt.Sprintf("SendResult Unmarshal Err:%s", err.Error()))
+		return err
+	}
+	//新增模板消息推送记录
+	{
+		tr := new(models.UserTemplateRecord)
+		tr.OpenId = openId
+		tr.Resource = resource
+		tr.SendData = string(data)
+		tr.Result = string(body)
+		tr.CreateDate = time.Now().Format(utils.FormatDate)
+		tr.CreateTime = time.Now().Format(utils.FormatDateTime)
+		if templateResponse.Errcode == 0 {
+			tr.SendStatus = 1
+		} else {
+			tr.SendStatus = 0
+		}
+		tr.UniqueCode = uniqueCode
+		tr.SendType = sendType
+		go func() {
+			err = models.AddUserTemplateRecord(tr)
+			if err != nil {
+				err = errors.New("AddUserTemplateRecord Err:" + err.Error())
+				utils.FileLog.Info(fmt.Sprintf("AddUserTemplateRecord Err:%s", err.Error()))
+			}
+		}()
+	}
+
+	//accessToken过期
+	if templateResponse.Errcode == 40001 {
+		//强刷token并重新推送
+		accessToken, err, errMsg = refreshWxMfyxAccessTokenCygx()
+		if err != nil {
+			err = errors.New("refreshWxAccessToken Err:" + err.Error())
+			utils.FileLog.Info(fmt.Sprintf("refreshWxAccessToken Err:%s", err.Error()))
+			return err
+		}
+		return toSendTemplateMsgCygx(data, resource, sendType, openId, uniqueCode)
+	}
+
+	//模板消息发送超过当日10万次限制错误处理
+	if templateResponse.Errcode == 45009 {
+		key := "CACHE_SendTemplateMsg_ERR"
+		isExist := utils.Rc.IsExist(key)
+		if isExist == true {
+			return
+		} else {
+			result, _ := json.Marshal(templateResponse)
+			if err != nil {
+				utils.FileLog.Info(fmt.Sprintf("templateResponse Marshal Err:%s", err.Error()))
+				return err
+			}
+			//发送邮件提醒异常
+			go alarm_msg.SendAlarmMsg("模板消息发送超过当日10万次限制,templateResponse = "+string(result), 3)
+			//go utils.SendEmail("异常提醒:", "模板消息发送超过当日10万次限制,templateResponse = "+string(result), utils.EmailSendToUsers)
+			//设置3分钟缓存,不允许重复添加
+			utils.Rc.SetNX(key, 1, 6*time.Minute)
+		}
+		//清空发送次数
+		sendUrl := fmt.Sprintf("https://api.weixin.qq.com/cgi-bin/clear_quota?access_token=%s", accessToken)
+		clearData := make(map[string]interface{})
+		clearData["appid"] = utils.WxAppIdCygx
+		clearJson, _ := json.Marshal(clearData)
+		utils.FileLog.Info("clear_quota data:" + string(clearJson))
+		resp, err := client.Post(sendUrl, "application/json", bytes.NewBuffer(clearJson))
+		if err != nil {
+			return err
+		}
+		defer resp.Body.Close()
+		clearBody, err := ioutil.ReadAll(resp.Body)
+		utils.FileLog.Info("clear_quota result:" + string(clearBody))
+		var clearQuotaResponse ClearQuotaResponse
+		err = json.Unmarshal(clearBody, &clearQuotaResponse)
+		if err != nil {
+			utils.FileLog.Info(fmt.Sprintf("clearQuotaResponse Unmarshal Err:%s", err.Error()))
+			return err
+		}
+		//if clearQuotaResponse.Errcode == 0 {
+		//	//发送邮件解决异常
+		//	go alarm_msg.SendAlarmMsg("异常已解决,自动清理限制接口,调用成功", 3)
+		//	//go utils.SendEmail("异常已解决:", "自动清理限制接口,调用成功", utils.EmailSendToUsers)
+		//	//重新推送一次
+		//	toSendTemplateMsgCygx(data, resource, sendType, openId, uniqueCode)
+		//}
+	}
+	return
+}
+
+
+// getWxMfyxAccessTokenCygx 获取微信token
+func getWxMfyxAccessTokenCygx() (accessToken string, err error, errMsg string) {
+	var tokenKey string
+	if utils.RunMode == "debug" {
+		tokenKey = utils.CACHE_WX_ACCESS_TOKEN_HZ
+	} else {
+		tokenKey = utils.CACHE_WX_ACCESS_TOKEN_MFYX
+	}
+	accessToken, err = utils.Rc.RedisString(tokenKey)
+	if accessToken != "" {
+		return
+	}
+
+	//缓存中没有取到数据,那么需要去强制刷新新的accessToken
+	return refreshWxMfyxAccessTokenCygx()
+}
+
+// refreshWxMfyxAccessTokenCygx 强制刷新微信token
+func refreshWxMfyxAccessTokenCygx() (accessToken string, err error, errMsg string) {
+	fmt.Println("强制刷新" + utils.WxAppIdCygx + "微信token")
+	if errMsg != `` {
+		utils.FileLog.Info(fmt.Sprintf("强制刷新%s微信token异常:%s", utils.WxAppIdCygx, errMsg))
+	}
+	//调用微信官方接口获取新的accessToken
+	wxAccessToken, tmpErr := models.GetWxTokenMfyx()
+	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
+	//更新mysql的accessToken(如果是debug环境的话)
+	var tokenKey string
+	if utils.RunMode == "debug" {
+		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
+		}
+		tokenKey = utils.CACHE_WX_ACCESS_TOKEN_HZ
+	} else {
+		tokenKey = utils.CACHE_WX_ACCESS_TOKEN_MFYX
+	}
+	//更新redis的accessToken(过期时间提前十分钟)
+	redisTimeExpire := time.Duration(wxAccessToken.ExpiresIn-600) * time.Second
+	err = utils.Rc.Put(tokenKey, accessToken, redisTimeExpire)
+	if err != nil {
+		errMsg = "更新redis中的accessToken失败 Err:" + err.Error()
+		return
+	}
+	return
+}
+
+
+func TemplateList() (err error) {
+	//utils.FileLog.Info("Send:" + string(data))
+	//获取accessToken
+	accessToken, err, errMsg := getWxMfyxAccessTokenCygx()
+	if err != nil {
+		utils.FileLog.Info(fmt.Sprintf("获取Token失败,err:%s,errMsg:%s", err.Error(), errMsg))
+		return
+	}
+	sendUrl := "https://api.weixin.qq.com/cgi-bin/template/get_all_private_template?access_token=" + accessToken
+
+	client := http.Client{}
+	//resp, err := client.Post(sendUrl, "application/json", bytes.NewBuffer(data))
+	resp, err := client.Get(sendUrl)
+	if err != nil {
+		return
+	}
+	defer resp.Body.Close()
+
+	body, _ := ioutil.ReadAll(resp.Body)
+	utils.FileLog.Info("Cygx_SendResult:" + string(body))
+	var templateResponse models.TemplateLibraryResp
+	err = json.Unmarshal(body, &templateResponse)
+	if err != nil {
+		utils.FileLog.Info(fmt.Sprintf("SendResult Unmarshal Err:%s", err.Error()))
+		fmt.Println("SendResult Unmarshal Err:%s", err.Error())
+		return err
+	}
+
+	//添加到数据库
+	err = models.AddTemplates(templateResponse.TemplateList)
+	if err != nil {
+		utils.FileLog.Info(fmt.Sprintf("添加到数据库失败,err:%s", err.Error()))
+		fmt.Println("添加到数据库失败,err:%s", err.Error())
+		return err
+	}
+
+	return
+}
+
+// 发送类目模板消息
+func SendWxCategoryTemplateMsgCygx(sendInfo *models.SendWxCategoryTemplate) (err error) {
+	var msg string
+	defer func() {
+		if err != nil {
+			go alarm_msg.SendAlarmMsg("查研观向小助手发送类目模版消息失败,Err:"+err.Error()+";msg:"+msg, 3)
+			utils.FileLog.Info(fmt.Sprintf("发送类目模版消息失败,Err:%s,%s", err.Error(), msg))
+		}
+		if msg != "" {
+			utils.FileLog.Info(fmt.Sprintf("发送类目模版消息失败,msg:%s", msg))
+		}
+	}()
+	utils.FileLog.Info("services SendMsg")
+	fmt.Println("send start")
+	utils.FileLog.Info("send start")
+
+	sendMap := make(map[string]interface{})
+	sendData := make(map[string]interface{})
+	var uniqueCodeStr string
+
+	templateItem, err := models.GetTemplateLibraryByTemplateId(sendInfo.TemplateId)
+	if err != nil {
+		utils.FileLog.Info(fmt.Sprintf("获取模板库失败,err:%s", err.Error()))
+		err = errors.New("获取模板库失败 Err:" + err.Error())
+		return err
+	}
+	keywords := utils.ExtractDataFields(templateItem.Content)
+	if len(keywords) == len(sendInfo.Keywords) {
+		for i, v := range keywords {
+			sendData[v] = map[string]interface{}{"value": sendInfo.Keywords[i], "color": "#173177"}
+			//sendData[v] = map[string]interface{}{"value": "", "color": "#173177"}
+			uniqueCodeStr += sendInfo.Keywords[i]
+			//uniqueCodeStr += ""
+		}
+	}
+
+	sendMap["data"] = sendData
+	if sendInfo.TemplateId != "" {
+		sendMap["template_id"] = sendInfo.TemplateId
+		uniqueCodeStr += sendInfo.TemplateId
+	}
+	uniqueCode := utils.MD5(uniqueCodeStr)
+
+	err = sendCategoryTemplateMsgMfyx(sendMap, sendInfo.OpenIdArr, sendInfo.Resource, uniqueCode, sendInfo.SendType)
+	if err != nil {
+		err = errors.New("sendTemplateMsgCygx Err:" + err.Error())
+		utils.FileLog.Info("send err:" + err.Error())
+	}
+	fmt.Println("send end")
+	utils.FileLog.Info("send end")
+	return
+}

+ 0 - 102
services/wechat_send_msg_cygx.go

@@ -282,106 +282,4 @@ func refreshWxAccessTokenCygx() (accessToken string, err error, errMsg string) {
 		return
 	}
 	return
-}
-
-func TemplateList() (err error) {
-	//utils.FileLog.Info("Send:" + string(data))
-	//获取accessToken
-	accessToken, err, errMsg := getWxAccessTokenCygx()
-	if err != nil {
-		utils.FileLog.Info(fmt.Sprintf("获取Token失败,err:%s,errMsg:%s", err.Error(), errMsg))
-		return
-	}
-	sendUrl := "https://api.weixin.qq.com/cgi-bin/template/get_all_private_template?access_token=" + accessToken
-
-	client := http.Client{}
-	//resp, err := client.Post(sendUrl, "application/json", bytes.NewBuffer(data))
-	resp, err := client.Get(sendUrl)
-	if err != nil {
-		return
-	}
-	defer resp.Body.Close()
-
-	body, _ := ioutil.ReadAll(resp.Body)
-	utils.FileLog.Info("Cygx_SendResult:" + string(body))
-	var templateResponse models.TemplateLibraryResp
-	err = json.Unmarshal(body, &templateResponse)
-	if err != nil {
-		utils.FileLog.Info(fmt.Sprintf("SendResult Unmarshal Err:%s", err.Error()))
-		fmt.Println("SendResult Unmarshal Err:%s", err.Error())
-		return err
-	}
-
-	//添加到数据库
-	err = models.AddTemplates(templateResponse.TemplateList)
-	if err != nil {
-		utils.FileLog.Info(fmt.Sprintf("添加到数据库失败,err:%s", err.Error()))
-		fmt.Println("添加到数据库失败,err:%s", err.Error())
-		return err
-	}
-
-	return
-}
-
-// 发送类目模板消息
-func SendWxCategoryTemplateMsgCygx(sendInfo *models.SendWxCategoryTemplate) (err error) {
-	var msg string
-	defer func() {
-		if err != nil {
-			go alarm_msg.SendAlarmMsg("查研观向小助手发送类目模版消息失败,Err:"+err.Error()+";msg:"+msg, 3)
-			utils.FileLog.Info(fmt.Sprintf("发送类目模版消息失败,Err:%s,%s", err.Error(), msg))
-		}
-		if msg != "" {
-			utils.FileLog.Info(fmt.Sprintf("发送类目模版消息失败,msg:%s", msg))
-		}
-	}()
-	utils.FileLog.Info("services SendMsg")
-	fmt.Println("send start")
-	utils.FileLog.Info("send start")
-
-	sendMap := make(map[string]interface{})
-	sendData := make(map[string]interface{})
-	var uniqueCodeStr string
-
-	templateItem, err := models.GetTemplateLibraryByTemplateId(sendInfo.TemplateId)
-	if err != nil {
-		utils.FileLog.Info(fmt.Sprintf("获取模板库失败,err:%s", err.Error()))
-		err = errors.New("获取模板库失败 Err:" + err.Error())
-		return err
-	}
-	keywords := utils.ExtractDataFields(templateItem.Content)
-	if len(keywords) == len(sendInfo.Keywords) {
-		for i, v := range keywords {
-			sendData[v] = map[string]interface{}{"value": sendInfo.Keywords[i]}
-			//sendData[v] = map[string]interface{}{"value": "", "color": "#173177"}
-			uniqueCodeStr += sendInfo.Keywords[i]
-			//uniqueCodeStr += ""
-		}
-	}
-
-	sendMap["data"] = sendData
-	if sendInfo.TemplateId != "" {
-		sendMap["template_id"] = sendInfo.TemplateId
-		uniqueCodeStr += sendInfo.TemplateId
-	}
-
-	if sendInfo.RedirectUrl != "" {
-		if strings.Contains(sendInfo.RedirectUrl, "http") || strings.Contains(sendInfo.RedirectUrl, "https") || sendInfo.RedirectTarget == 0 {
-			sendMap["url"] = sendInfo.RedirectUrl
-		} else {
-			sendMap["miniprogram"] = map[string]interface{}{"appid": utils.WxMfyxAppId, "pagepath": sendInfo.RedirectUrl}
-		}
-		uniqueCodeStr += sendInfo.RedirectUrl
-	}
-
-	uniqueCode := utils.MD5(uniqueCodeStr)
-
-	err = sendTemplateMsgCygx(sendMap, sendInfo.OpenIdArr, sendInfo.Resource, uniqueCode, sendInfo.SendType)
-	if err != nil {
-		err = errors.New("sendTemplateMsgCygx Err:" + err.Error())
-		utils.FileLog.Info("send err:" + err.Error())
-	}
-	fmt.Println("send end")
-	utils.FileLog.Info("send end")
-	return
 }

+ 7 - 0
utils/config.go

@@ -35,6 +35,10 @@ var (
 	WxAppIdCygx     string
 	WxAppSecretCygx string
 
+
+	WxAppIdMfyx     string
+	WxAppSecretMfyx string
+
 	// 小程序相关
 
 	// WxCrmAppId 随手办公小程序
@@ -182,6 +186,9 @@ func init() {
 		WxAppIdCygx = config["wx_cygx_appid"]
 		WxAppSecretCygx = config["wx_cygx_app_secret"]
 
+		WxAppIdMfyx = config["wx_mfyx_appid"]
+		WxAppSecretMfyx = config["wx_mfyx_app_secret"]
+
 		// 小程序相关
 		WxCrmAppId = config["wx_crm_miniprogram_appid"]
 		// WxCygxAppId 弘则研报小程序

+ 1 - 0
utils/constants.go

@@ -24,4 +24,5 @@ const (
 	CACHE_WX_ACCESS_TOKEN_HZ   = "wx:accesstoken:hzyj" //弘则研究公众号 微信accessToken
 	HZ_ADMIN_WX_ACCESS_TOEKN   = "hz_admin:wx:access_token:"
 	CACHE_WX_ACCESS_TOKEN_CYGX = "xygxxzs_wxtoken" //查研观向小助手公众号 微信accessToken
+	CACHE_WX_ACCESS_TOKEN_MFYX = "mfyx_wxtoken" //买方研选公众号 微信accessToken
 )