浏览代码

Merge branch 'master' of http://8.136.199.33:3000/cxzhang/hongze_mfyx into mfyx_2.0

xingzai 10 月之前
父节点
当前提交
cc8a18c7c4

+ 13 - 3
controllers/activity.go

@@ -2,6 +2,7 @@ package controllers
 
 import (
 	"encoding/json"
+	"errors"
 	"fmt"
 	"hongze/hongze_mfyx/models"
 	"hongze/hongze_mfyx/services"
@@ -929,6 +930,7 @@ func (this *ActivityCoAntroller) SignupAdd() {
 	//公司线下调研活动客户报名后给建会人,所属销售推送模板信息
 	if signupStatus == "Success" {
 		go services.SendResearchActivitiesTemplateMsg(user, activityInfo, "报名")
+		go services.SendResearchActivitiesTemplateMsg(user, activityInfo, "报名")
 	}
 	if signupType == 1 && user.IsMsgOutboundMobile == 0 {
 		resp.GoOutboundMobile = true
@@ -1072,6 +1074,7 @@ func (this *ActivityCoAntroller) SignupCancel() {
 	// 如果是买方研选下的专家沙龙,同时推给内容组四人
 	if activityInfo.ActivityTypeId == 5 {
 		go services.SendActivitieCancelSignTemplateMsg(user, activityInfo)
+		go services.SendActivitieCancelSignCategoryTemplateMsg(user, activityInfo)
 	}
 
 	go services.SendResearchActivitiesTemplateMsg(user, activityInfo, "取消报名") //公司线下调研活动客户报名后给建会人,所属销售推送模板信息
@@ -1469,10 +1472,17 @@ func (this *ActivityCoAntroller) AskAdd() {
 		}
 		// 给所属销售发送消息
 		if sellerItem != nil {
-			openIpItem, _ := models.GetUserRecordByMobile(4, sellerItem.Mobile)
-			if openIpItem != nil && openIpItem.OpenId != "" {
-				//services.SendActivityAskApplyTemplateMsgV2(user.RealName+"——"+user.CompanyName+"("+sellerItem.RealName+")", "提问:"+activityInfo.ActivityName, time.Now().Format(utils.FormatDateTime), req.Content, activityInfo.ActivityName, openIpItem, activityInfo, int(msgId))
+			openIdList, e := models.GetUserRecordListByMobile(4, sellerItem.Mobile+","+utils.WxMsgTemplateIdAskMsgMobilePublic)
+			if e != nil {
+				err = errors.New("GetUserRecordListByMobile, Err: " + e.Error())
+				return
 			}
+			go services.SendWxCategoryMsgWithAsk(user.RealName, user.CompanyName, sellerItem.RealName, content, openIdList, req.ActivityId)
+
+			//openIpItem, _ := models.GetUserRecordByMobile(4, sellerItem.Mobile)
+			//if openIpItem != nil && openIpItem.OpenId != "" {
+				//services.SendActivityAskApplyTemplateMsgV2(user.RealName+"——"+user.CompanyName+"("+sellerItem.RealName+")", "提问:"+activityInfo.ActivityName, time.Now().Format(utils.FormatDateTime), req.Content, activityInfo.ActivityName, openIpItem, activityInfo, int(msgId))
+			//}
 		}
 	}
 

+ 1 - 0
controllers/activity_sign.go

@@ -139,6 +139,7 @@ func (this *ActivitySignCoAntroller) Detail() {
 
 		//线下调研活动扫码签到给对应销售发模版消息
 		services.SendActivitieSignTemplateMsg(user, activityInfo)
+		services.SendActivitieSignCategoryTemplateMsg(user, activityInfo)
 
 		//处理用户标签
 		services.ActivityUserLabelLogAdd(activityId, []string{user.Mobile})

+ 55 - 4
controllers/article.go

@@ -152,6 +152,55 @@ func (this *ArticleController) Detail() {
 		if !utils.Rc.IsExist(key) {
 			go services.ArticleUserRemind(user, detail, 1)
 			utils.Rc.Put(key, 1, 30*time.Second)
+			go services.ArticleHistory(articleId, user)
+			//30分钟之内阅读同一篇文章不错二次推送
+			key := "CYGX_ARTICLE_READ" + strconv.Itoa(articleId) + "_" + strconv.Itoa(uid)
+			if !utils.Rc.IsExist(key) {
+				go services.ArticleUserRemind(user, detail, 1)
+				// 互动提醒
+				go services.SendWxCategoryMsgInteractive(user, "阅读报告", articleId, detail.Title)
+				utils.Rc.Put(key, 1, 30*time.Second)
+			}
+		}
+
+		interviewApplyItem, err := models.GetArticleInterviewApply(uid, articleId)
+		if err != nil && err.Error() != utils.ErrNoRow() {
+			br.Msg = "获取信息失败"
+			br.ErrMsg = "判断是否已申请访谈失败,Err:" + strconv.Itoa(uid) + ";articleId" + strconv.Itoa(articleId)
+			return
+		}
+		if interviewApplyItem != nil && interviewApplyItem.InterviewApplyId > 0 {
+			detail.IsInterviewApply = true
+			detail.InterviewApplyStatus = interviewApplyItem.Status
+		}
+		//获取销售手机号
+		sellerItem, err := models.GetSellerByCompanyId(user.CompanyId)
+		if err != nil && err.Error() != utils.ErrNoRow() {
+			br.Msg = "获取信息失败"
+			br.ErrMsg = "获取销售数据失败2,Err:" + err.Error() + strconv.Itoa(uid) + ";articleId" + strconv.Itoa(articleId)
+			return
+		}
+		if sellerItem != nil {
+			detail.SellerMobile = sellerItem.Mobile
+			detail.SellerName = sellerItem.RealName
+		}
+		sellerList, err := models.GetSellerList(articleId)
+		if err != nil {
+			br.Msg = "获取信息失败"
+			br.ErrMsg = "获取销售数据失败,Err:" + err.Error() + strconv.Itoa(uid) + ";articleId" + strconv.Itoa(articleId)
+			return
+		}
+		if detail.ArticleId >= utils.SummaryArticleId && strings.Contains(detail.SellerAndMobile, "-") {
+			strnum := strings.Index(detail.SellerAndMobile, "-")
+			detail.SellerAndMobile = detail.SellerAndMobile[0:strnum]
+			if strnum > 0 {
+				nickName := detail.SellerAndMobile[0:strnum]
+				sellerAndMobile := &models.SellerRep{
+					SellerMobile: "",
+					SellerName:   nickName,
+				}
+				sellerList = append(sellerList, sellerAndMobile)
+			}
 		}
 
 		articleFollowdetail, err := models.GetArticleFollowDetail(articleId, uid)
@@ -292,8 +341,10 @@ func (this *ArticleController) ArticleCollect() {
 		br.Msg = "收藏成功"
 		resp.Status = 1
 		// 文章收藏消息发送
-		go services.ArticleUserRemind(user, detail, 2)
+		//go services.ArticleUserRemind(user, detail, 2)
 		go services.ArticleHistoryUserLabelLogAdd(articleId, user.UserId)
+		// 互动提醒
+		go services.SendWxCategoryMsgInteractive(user, "收藏报告", articleId, detail.Title)
 	} else {
 		err = models.RemoveArticleCollect(uid, articleId)
 		if err != nil {
@@ -648,10 +699,9 @@ func (this *ArticleController) AskAdd() {
 	}
 	var mobile string
 	if utils.RunMode == "release" {
-		//mobile = utils.WxMsgTemplateIdAskMsgMobileAll + "," + companyItem.Mobile
-		mobile = utils.WxMsgTemplateIdAskMsgMobileAll
+		mobile = utils.WxMsgTemplateIdAskMsgMobileAll + "," + companyItem.Mobile
 	} else {
-		mobile = utils.WxMsgTemplateIdAskMsgMobile
+		mobile = utils.WxMsgTemplateIdAskMsgMobile + "," + companyItem.Mobile
 	}
 	openIdList, err := models.GetWxOpenIdByMobileList(mobile)
 	if err != nil {
@@ -667,6 +717,7 @@ func (this *ArticleController) AskAdd() {
 	}
 	companyName := user.CompanyName + "-" + user.RealName + "(" + companyItem.SellerName + ")"
 	go services.SendWxMsgWithAsk(companyName, time.Now().Format(utils.FormatDateTime), content, detail.Title, openIdList, req.ArticleId)
+	//go services.SendWxCategoryMsgWithAsk(user.CompanyName, user.RealName, companyItem.SellerName, time.Now().Format(utils.FormatDateTimeMinute2), content, openIdList, req.ArticleId)
 	br.Ret = 200
 	br.Success = true
 	br.Msg = "提交成功"

+ 3 - 0
controllers/base_auth_mobile.go

@@ -38,6 +38,7 @@ func (this *BaseAuthMobileController) Prepare() {
 	if method != "HEAD" {
 		if method == "POST" || method == "GET" {
 			authorization := this.Ctx.Input.Header("Authorization")
+			inviteCompany := this.Ctx.Input.Header("From")
 			if authorization == "" {
 				authorization = this.GetString("Authorization")
 			}
@@ -83,6 +84,8 @@ func (this *BaseAuthMobileController) Prepare() {
 					return
 				}
 				this.User = wxUser
+				wxUser.InviteCompany = inviteCompany
+				go services.AddCygxPageHistoryRecord(this.User, this.Ctx)
 			}
 		} else {
 			this.JSON(models.BaseResponse{Ret: 408, Msg: "请求异常,请联系客服!", ErrMsg: "POST之外的请求,暂不支持"}, false, false)

+ 1 - 0
controllers/config.go

@@ -112,6 +112,7 @@ func (this *ConfigController) PageHistory() {
 	item.ChartPermissionId = req.ChartPermissionId
 	item.IndustrialManagementId = req.IndustrialManagementId
 	item.PageType = req.PageType
+	item.RegisterPlatform = utils.REGISTER_PLATFORM
 	_, err = models.AddCygxPageHistoryRecord(item)
 	if err != nil {
 		br.Msg = "新增访问记录失败"

+ 2 - 2
controllers/home.go

@@ -74,8 +74,8 @@ func (this *HomeController) NewList() {
 		if labelKeyword == "" {
 			//查询近一个月的数据
 			condition += " AND search_order_time  >   '" + time.Now().AddDate(0, 0, -60).Format(utils.FormatDateTime) + "'"
-			yanxuanActivityIds = services.GetYanxuanActivityIds(user) // 获取所有的研选活动ID
-			yanxuanArticleIds = services.GetYanxuanArticleIds()       //获取所有研选文章ID
+			yanxuanActivityIds = services.GetYanxuanActivityIds(user, "1,2") // 获取所有的研选活动ID
+			yanxuanArticleIds = services.GetYanxuanArticleIds()              //获取所有研选文章ID
 		} else {
 			yanxuanActivityIds, yanxuanArticleIds, err = services.GetConditionInitByTagIds(user, labelKeyword)
 			if err != nil {

+ 1 - 0
controllers/report.go

@@ -341,6 +341,7 @@ func (this *ReportController) CommentAdd() {
 	}
 
 	services.SendCommentWxTemplateMsg(req, user, articleInfo, int(msgId))
+	go services.SendCommentWxCategoryTemplateMsg(req, user, articleInfo, int(msgId))
 	br.Ret = 200
 	br.Success = true
 	br.Msg = "提交成功"

+ 15 - 1
controllers/user.go

@@ -940,6 +940,7 @@ func (this *UserController) ApplyTryOut() {
 	detailId := req.DetailId
 	sourceId = detailId
 	source = tryType
+	redirectUrl := ""
 	var isResearch bool // 是否属于研选
 	if tryType == "Article" {
 		detail, err := models.GetArticleDetailById(detailId)
@@ -952,6 +953,7 @@ func (this *UserController) ApplyTryOut() {
 		if detail.ArticleTypeId > 0 {
 			isResearch = true
 		}
+		redirectUrl = utils.WX_MSG_PATH_YX_ARTICLE_DETAIL + strconv.Itoa(detailId)
 	} else if tryType == "Activity" {
 		detail, err := models.GetAddActivityInfoById(detailId)
 		if err != nil {
@@ -963,6 +965,7 @@ func (this *UserController) ApplyTryOut() {
 		if strings.Contains(detail.ChartPermissionName, utils.CHART_PERMISSION_NAME_YANXUAN) {
 			isResearch = true
 		}
+		redirectUrl = utils.WX_MSG_PATH_YX_ACTIVITY_DETAIL + strconv.Itoa(detailId)
 	} else if tryType == "MicroAudio" {
 		// 微路演音频
 		microAudio, e := models.GetCygxActivityVoiceById(detailId)
@@ -1150,6 +1153,7 @@ func (this *UserController) ApplyTryOut() {
 	//用户状态,1:潜在客户 、2:现有客户 、3:FICC客户 、4:现有客户(正式,无对应权限) 、5:现有客户(试用,无对应权限)  、6:现有客户(试用暂停) 、7:现有客户(冻结) 、8:现有客户(流失)?
 	CompanyIdType := 1
 	applyMethod := ""
+	categoryApplyMethod := ""
 	if sellerItem != nil {
 		companyItem, err := models.GetCompanyDetailById(user.CompanyId)
 		if err != nil && err.Error() != utils.ErrNoRow() {
@@ -1174,17 +1178,21 @@ func (this *UserController) ApplyTryOut() {
 					CompanyIdType = 5
 				case "冻结":
 					CompanyIdType = 7
+					categoryApplyMethod = "冻结客户"
 				case "流失":
 					CompanyIdType = 8
+					categoryApplyMethod = "流失客户"
 				}
 			}
 			applyMethod = companyItem.Status + "客户申请"
 			if detailId > 0 {
 				if companyProduct != nil && companyProduct.IsSuspend == 1 {
 					applyMethod = "试用暂停客户"
+					categoryApplyMethod = "试用暂停客户"
 				} else {
 					if companyItem.Status == "正式" || companyItem.Status == "试用" {
 						applyMethod = companyItem.Status + "客户申请,无对应权限"
+						categoryApplyMethod = companyItem.Status + "客户无对应权限"
 					} else if companyItem.Status == "冻结" || companyItem.Status == "流失" {
 						applyMethod = companyItem.Status + "客户"
 					}
@@ -1211,14 +1219,19 @@ func (this *UserController) ApplyTryOut() {
 		if sellerItem != nil {
 			CompanyIdType = 3
 			applyMethod = "FICC客户"
+			categoryApplyMethod = "FICC客户"
 		} else {
 			CompanyIdType = 1
 			applyMethod = "潜在客户"
+			categoryApplyMethod = "潜在客户"
 		}
 		if detailId > 0 {
 			applyMethod = applyMethod + "," + title
 		}
 	}
+	if categoryApplyMethod == "" {
+		categoryApplyMethod = applyMethod
+	}
 	item := new(models.CygxApplyRecord)
 	item.UserId = user.UserId
 	item.BusinessCardUrl = req.BusinessCardUrl
@@ -1245,11 +1258,12 @@ func (this *UserController) ApplyTryOut() {
 		return
 	}
 	if sellerItem == nil {
-		go services.SendPermissionApplyTemplateMsgAdmin(req, mobile, applyMethod, isResearch)
+		go services.SendPermissionApplyTemplateMsgAdmin(req, mobile, applyMethod, categoryApplyMethod, redirectUrl, isResearch)
 	} else {
 		openIpItem, _ := models.GetUserRecordByMobile(4, sellerItem.Mobile)
 		if openIpItem != nil && openIpItem.OpenId != "" {
 			go services.SendPermissionApplyTemplateMsg(req.RealName, req.CompanyName, mobile, applyMethod, openIpItem)
+			go services.SendPermissionApplyCategoryTemplateMsg(req.RealName, req.CompanyName, mobile, categoryApplyMethod, openIpItem, redirectUrl)
 		}
 	}
 	//添加成功后,设置5分钟缓存,不允许重复添加

+ 34 - 18
controllers/yanxuan_special.go

@@ -457,11 +457,14 @@ func (this *YanxuanSpecialController) Save() {
 		go services.UpdateYanxuanSpecialResourceData(specialId)        //  写入首页最新  cygx_resource_data 表
 		go services.EsAddYanxuanSpecial(specialId)                     //  写入es 综合搜索
 		go services.SendWxMsgSpecialFollow(req.Id)                     //研选专栏有新内容审核通过时,给关注此专栏的客户发送模板消息
-		go services.SendWxMsgSpecialAuthor(req.Id, 2)                  //研选专栏审核完成时,给提交人发送模板消息
+		go services.SendWxCategoryMsgSpecialFollow(req.Id)                     //研选专栏有新内容审核通过时,给关注此专栏的客户发送模板消息
+		go services.SendWxMsgSpecialAuthor(req.Id, 1)                  //研选专栏审核完成时,给提交人发送模板消息
+		go services.SendWxCategoryMsgSpecialAuthor(req.Id, 1)          //研选专栏审核完成时,给提交人发送类目模板消息
 		go services.UdpateYanxuanSpecialauthorArticleNum(authorUserId) //  更新作者发布文章的数量
 	} else {
 		if req.DoType == 2 {
 			go services.SendReviewTemplateMsgAdmin(specialId)
+			go services.SendReviewCategoryTemplateMsgAdmin(specialId)
 			go services.UpdateYanxuanSpecialResourceData(specialId) //  写入首页最新  cygx_resource_data 表
 			go services.EsAddYanxuanSpecial(specialId)              //  写入es 综合搜索
 		}
@@ -501,6 +504,9 @@ func (this *YanxuanSpecialController) AuthorDetail() {
 		br.ErrMsg = "获取失败, Err:" + tmpErr.Error()
 		return
 	}
+	if item.IsFollow > 0 {
+		item.IsFollow = 1
+	}
 
 	br.Data = item
 	br.Ret = 200
@@ -561,8 +567,10 @@ func (this *YanxuanSpecialController) Enable() {
 	}
 	if req.Status == 1 {
 		go services.SendWxMsgSpecialFollow(req.Id)
+		go services.SendWxCategoryMsgSpecialFollow(req.Id)
 	}
 	go services.SendWxMsgSpecialAuthor(req.Id, req.Status)
+	go services.SendWxCategoryMsgSpecialAuthor(req.Id, req.Status)
 	go services.UpdateYanxuanSpecialResourceData(req.Id)                                  //  写入首页最新  cygx_resource_data 表
 	go services.EsAddYanxuanSpecial(req.Id)                                               //  写入es 综合搜索
 	go services.AddAddCygxYanxuanSpecialApprovalLog(user, req.Id, req.Status, req.Reason) //  添加审核记录日志
@@ -804,26 +812,34 @@ func (this *YanxuanSpecialController) Follow() {
 		}
 	}
 	if req.Status == 1 {
-		item := models.CygxYanxuanSpecialFollow{
-			UserId:           user.UserId,
-			FollowUserId:     req.FollowUserId,
-			Mobile:           user.Mobile,
-			Email:            user.Email,
-			CompanyId:        user.CompanyId,
-			CompanyName:      user.CompanyName,
-			RealName:         user.RealName,
-			SellerName:       sellerName,
-			CreateTime:       time.Now(),
-			ModifyTime:       time.Now(),
-			RegisterPlatform: utils.REGISTER_PLATFORM,
-			YanxuanSpecialId: req.SpecialId,
-		}
-		err = models.AddCygxYanxuanSpecialFollow(&item)
+		followCount, err := models.GetCygxYanxuanSpecialFollowCountByUser(user.UserId, req.FollowUserId)
 		if err != nil {
-			br.Msg = "新增失败"
-			br.ErrMsg = "新增失败,Err:" + err.Error()
+			br.Msg = "获取失败"
+			br.ErrMsg = "获取失败, Err:" + err.Error()
 			return
 		}
+		if followCount == 0 && user.UserId > 0 {
+			item := models.CygxYanxuanSpecialFollow{
+				UserId:           user.UserId,
+				FollowUserId:     req.FollowUserId,
+				Mobile:           user.Mobile,
+				Email:            user.Email,
+				CompanyId:        user.CompanyId,
+				CompanyName:      user.CompanyName,
+				RealName:         user.RealName,
+				SellerName:       sellerName,
+				CreateTime:       time.Now(),
+				ModifyTime:       time.Now(),
+				RegisterPlatform: utils.REGISTER_PLATFORM,
+				YanxuanSpecialId: req.SpecialId,
+			}
+			err = models.AddCygxYanxuanSpecialFollow(&item)
+			if err != nil {
+				br.Msg = "新增失败"
+				br.ErrMsg = "新增失败,Err:" + err.Error()
+				return
+			}
+		}
 		br.Msg = "关注成功"
 	} else {
 		err = models.DelCygxYanxuanSpecialFollow(user.UserId, req.FollowUserId)

+ 62 - 0
models/activity.go

@@ -626,3 +626,65 @@ func GetCygxActivityIdList(condition string, pars []interface{}) (items []*CygxA
 	_, err = o.Raw(sql, pars).QueryRows(&items)
 	return
 }
+
+// 活动详情
+type WxMsgCygxActivityList struct {
+	Id                      int    `description:"报名ID"`
+	UserId                  int    `description:"用户ID"`
+	ActivityId              int    `description:"活动ID 等于0新增活动,大于0修改活动"`
+	ActivityTypeId          int    `description:"活动类型id"`
+	ActivityName            string `description:"活动名称"`
+	ActivityTypeName        string `description:"活动类型名称"`
+	Speaker                 string `description:"主讲人"`
+	SignupType              int    `description:"报名方式,1预约外呼,2我要报名"`
+	ChartPermissionId       int    `description:"行业id"`
+	ChartPermissionName     string `description:"行业名称"`
+	IsLimitPeople           int    `description:"是否限制人数 1是,0否"`
+	LimitPeopleNum          int    `description:"限制的人数数量"`
+	ActivityTime            string `description:"活动时间"`
+	ActivityTimeText        string `description:"活动时间带文字"`
+	City                    string `description:"城市"`
+	Address                 string `description:"活动地址"`
+	DistinguishedGuest      string `description:"嘉宾"`
+	Expert                  string `description:"专家"`
+	IsSignup                int    `description:"是否已报名 1是 ,0 否"`
+	SignupNum               int    `description:"已报名人数"`
+	ActiveState             string `description:"活动进行状态 未开始:1、进行中2、已结束3"`
+	IsCancelMeetingReminder int    `description:"是否取消会议提醒 1展示取消会议提醒 ,0展示会议提醒"`
+	IsBrackets              int    `description:"是否有方括号 1是 ,0 否"`
+	OpenId                  string `description:"OenId"`
+	FailType                int    `description:"失败原因,0,未失败,1总人数已满,2单机构超限制,3,爽约次数超限"`
+}
+
+func GetYxActivitySendMsgListAll(endDate string) (items []*WxMsgCygxActivityList, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT
+	s.id,
+	s.user_id,
+	s.fail_type,
+	cr.open_id,
+	a.*
+FROM
+	cygx_activity AS a
+	INNER JOIN cygx_activity_signup AS s ON s.activity_id = a.activity_id
+	INNER JOIN cygx_user_record AS cr ON cr.cygx_bind_account = s.mobile 
+WHERE
+	1 = 1 
+	AND s.is_send_wx_msg = 0 
+	AND s.do_fail_type = 0 
+	AND a.publish_status = 1
+	AND a.chart_permission_id = 31
+	AND a.activity_time <= ? AND a.activity_time >= NOW() 
+	AND s.is_cancel = 0
+	GROUP BY s.id`
+	_, err = o.Raw(sql, endDate).QueryRows(&items)
+	return
+}
+
+// 修改是否推送消息状态
+func UPdateSendedMsgStatus(signupIds string) (err error) {
+	sql := ` UPDATE cygx_activity_signup SET  is_send_wx_msg= 1  WHERE id IN(` + signupIds + `)`
+	o := orm.NewOrm()
+	_, err = o.Raw(sql).Exec()
+	return
+}

+ 13 - 12
models/article_history_record_newpv.go

@@ -9,18 +9,19 @@ import (
 )
 
 type CygxArticleHistoryRecordNewpv struct {
-	Id          int `orm:"column(id);pk"`
-	ArticleId   int
-	UserId      int
-	CreateTime  time.Time
-	ModifyTime  time.Time
-	Mobile      string `description:"手机号"`
-	Email       string `description:"邮箱"`
-	CompanyId   int    `description:"公司id"`
-	CompanyName string `description:"公司名称"`
-	StopTime    int    `description:"停留时间"`
-	OutType     int    `description:"退出方式,1正常退出,2强制关闭"`
-	Source      string `description:"来源,MOBILE:手机端,PC:电脑端"`
+	Id               int `orm:"column(id);pk"`
+	ArticleId        int
+	UserId           int
+	CreateTime       time.Time
+	ModifyTime       time.Time
+	Mobile           string `description:"手机号"`
+	Email            string `description:"邮箱"`
+	CompanyId        int    `description:"公司id"`
+	CompanyName      string `description:"公司名称"`
+	StopTime         int    `description:"停留时间"`
+	OutType          int    `description:"退出方式,1正常退出,2强制关闭"`
+	Source           string `description:"来源,MOBILE:手机端,PC:电脑端"`
+	RegisterPlatform int    `description:"来源 1小程序,2:网页"`
 }
 
 // 添加阅读记录信息

+ 1 - 1
models/company.go

@@ -202,7 +202,7 @@ func GetCompanyDetailAllById(companyId int) (item *CompanyDetail, err error) {
 
 // 获取对应销售以及销售的手机号
 func GetSellerDetailAllByCompanyId(companyId int) (item *CompanyDetail, err error) {
-	sql := ` SELECT c.mobile ,c.real_name as seller_name
+	sql := ` SELECT c.mobile ,c.real_name as seller_name, a.company_name 
 			FROM
 			company AS a
 			INNER JOIN company_product AS b ON a.company_id = b.company_id

+ 8 - 0
models/cygx_yanxuan_special_follow.go

@@ -66,3 +66,11 @@ func GetCygxYanxuanSpecialFollowCount(condition string, pars []interface{}) (cou
 	err = o.Raw(sqlCount, pars).QueryRow(&count)
 	return
 }
+
+// 获取数量判断用户是否关注专栏
+func GetCygxYanxuanSpecialFollowCountByUser(userId, followUserId int) (count int, err error) {
+	sqlCount := ` SELECT COUNT(1) AS count  FROM cygx_yanxuan_special_follow as a WHERE user_id=? AND follow_user_id=? `
+	o := orm.NewOrm()
+	err = o.Raw(sqlCount, userId, followUserId).QueryRow(&count)
+	return
+}

+ 16 - 2
services/activity.go

@@ -7,6 +7,7 @@ import (
 	"hongze/hongze_mfyx/utils"
 	"strconv"
 	"strings"
+	"time"
 )
 
 // 获取 用户类型   //1、永续客户 //2、大套餐客户(4个行业全开通的正式客户) //3、分行业套餐客户(开通对应行业的正式客户) //4、仅开通专家套餐的正式客户 //5、开通对应行业套餐或专家套餐的试用客户;6、冻结客户;7、流失客户
@@ -760,6 +761,7 @@ func ActivityUserRemind(user *models.WxUserItem, activityDetail *models.Activity
 	// 如果是买方研选下的专家沙龙,同时推给内容组四人
 	if activityDetail.ActivityTypeId == 5 {
 		go SendNeiRongZuActivitieSignTemplateMsg(user, activityDetail)
+		go SendNeiRongZuActivitieSignCategoryTemplateMsg(user, activityDetail)
 	}
 	//获取销售手机号
 	sellerItemQy, e := models.GetSellerByCompanyIdCheckFicc(user.CompanyId, 2)
@@ -783,6 +785,7 @@ func ActivityUserRemind(user *models.WxUserItem, activityDetail *models.Activity
 		return
 	}
 	var sourceMsg string
+	var redirectUrl string
 	if source == 1 {
 		sourceMsg = "预约外呼"
 	} else if source == 2 {
@@ -802,6 +805,14 @@ func ActivityUserRemind(user *models.WxUserItem, activityDetail *models.Activity
 	keyword1 = activityDetail.ActivityName
 	keyword2 = fmt.Sprint("互动:", sourceMsg, ",", user.RealName, "--", user.CompanyName)
 	SendWxMsgWithActivityUserRemind(keyword1, keyword2, openIdList, activityDetail.ActivityId)
+
+	// 类目模版
+	keyword1 = utils.TruncateActivityNameString(user.RealName + "-" + user.CompanyName)
+	keyword2 = fmt.Sprint("互动提醒:", sourceMsg)
+	keyword3 := utils.TruncateActivityNameString(activityDetail.ActivityName)
+	keyword4 := time.Now().Format(utils.FormatDateTimeMinute2)
+	redirectUrl = utils.WX_MSG_PATH_YX_ACTIVITY_DETAIL + strconv.Itoa(activityDetail.ActivityId)
+	SendWxCategoryMsgWithActivityUserRemind(keyword1, keyword2, keyword3, keyword4, redirectUrl, openIdList, activityDetail.ActivityId)
 	return
 }
 
@@ -1336,7 +1347,7 @@ func GetActivityTypeIdMap() (mapResp map[int]int) {
 }
 
 // GetYanxuanActivityIds 获取研选活动ID
-func GetYanxuanActivityIds(user *models.WxUserItem) (activityIds []int) {
+func GetYanxuanActivityIds(user *models.WxUserItem, activeState string) (activityIds []int) {
 	var err error
 	defer func() {
 		if err != nil {
@@ -1346,7 +1357,10 @@ func GetYanxuanActivityIds(user *models.WxUserItem) (activityIds []int) {
 	}()
 	var condition string
 	var pars []interface{}
-	condition = `  AND  chart_permission_id  = 31  AND art.publish_status = 1  `
+	condition = `  AND  chart_permission_id  = 31  AND yidong_activity_id = '' AND art.publish_status = 1  `
+	if activeState != "" {
+		condition += ` AND  active_state IN  (` + activeState + `) `
+	}
 	//pars = append(pars, utils.CHART_PERMISSION_ID_YANXUAN)
 	if user.CompanyId > 1 {
 		conditionActivity, e := ActivityConditioninitSql(user, condition, 0)

+ 1 - 0
services/article_history.go

@@ -108,6 +108,7 @@ func ArticleHistoryStopTime(articleId, stopTime, outType int, user *models.WxUse
 		record.CompanyName = user.CompanyName
 		record.StopTime = stopTime
 		record.OutType = outType
+		record.RegisterPlatform = utils.REGISTER_PLATFORM
 		record.Source = "MOBILE"
 		newId, e := models.AddCygxArticleViewRecordNewpv(record)
 		if e != nil {

+ 2 - 2
services/es_comprehensive.go

@@ -649,8 +649,8 @@ func GetResourceDataEsList(list []*SearchComprehensiveItem, user *models.WxUserI
 }
 
 func SqlComprehensiveSearch(user *models.WxUserItem, keyWord string, startSize, pageSize int) (result []*SearchComprehensiveItem, total int, err error) {
-	yanxuanActivityIds := GetYanxuanActivityIds(user) // 获取所有的研选活动ID
-	yanxuanArticleIds := GetYanxuanArticleIds()       //获取所有研选文章ID
+	yanxuanActivityIds := GetYanxuanActivityIds(user, "") // 获取所有的研选活动ID
+	yanxuanArticleIds := GetYanxuanArticleIds()           //获取所有研选文章ID
 	yanxuanArticleIds = append(yanxuanArticleIds, 0)
 	yanxuanActivityIds = append(yanxuanActivityIds, 0)
 

+ 1 - 0
services/keyword.go

@@ -29,6 +29,7 @@ func AddSearchKeyWord(user *models.WxUserItem, keyWord string, source int) (err
 	_, err = models.AddSearchKeyWord(keyWordItem)
 	go AddUserSearchLog(user, keyWord, source)
 	go SearchKeywordUserRmind(user, keyWord)
+	go SearchKeywordUserRmindCategoryMsg(user, keyWord)
 	////一分钟之内的相同搜索词不重复记录
 	//setNX := utils.Rc.SetNX(cacheKey, keyWord, time.Minute*1)
 	//if !setNX {

+ 6 - 6
services/sms.go

@@ -21,7 +21,7 @@ func SendSmsCode(mobile, vcode string) bool {
 	var netReturn map[string]interface{}
 	err = json.Unmarshal(result, &netReturn)
 	if err != nil {
-		go utils.SendAlarmMsg("短信验证码发送失败", 1)
+		go utils.SendAlarmMsg("短信验证码发送失败err:"+err.Error()+" result"+string(result)+"mobile:"+mobile, 1)
 		go utils.SendEmail("短信验证码发送失败", "err:"+err.Error()+" result"+string(result), utils.EmailSendToUsers)
 		flag = false
 	}
@@ -29,7 +29,7 @@ func SendSmsCode(mobile, vcode string) bool {
 		fmt.Printf("接口返回result字段是:\r\n%v", netReturn["result"])
 		flag = true
 	} else {
-		go utils.SendAlarmMsg("短信验证码发送失败", 1)
+		go utils.SendAlarmMsg("短信验证码发送失败err:"+err.Error()+" result"+string(result)+"mobile:"+mobile, 1)
 		go utils.SendEmail("短信验证码发送失败", " result"+string(result), utils.EmailSendToUsers)
 		flag = false
 	}
@@ -74,16 +74,16 @@ func SendSmsCodeGj(mobile, vcode, areaNum string) bool {
 	var netReturn map[string]interface{}
 	err = json.Unmarshal(result, &netReturn)
 	if err != nil {
-		go utils.SendAlarmMsg("短信验证码发送失败", 1)
-		go utils.SendEmail("短信验证码发送失败", "err:"+err.Error()+" result"+string(result), utils.EmailSendToUsers)
+		go utils.SendAlarmMsg("国际短信验证码发送失败err:"+err.Error()+" result"+string(result)+"mobile:"+mobile, 1)
+		go utils.SendEmail("国际短信验证码发送失败", "err:"+err.Error()+" result"+string(result), utils.EmailSendToUsers)
 		flag = false
 	}
 	if netReturn["error_code"].(float64) == 0 {
 		fmt.Printf("接口返回result字段是:\r\n%v", netReturn["result"])
 		flag = true
 	} else {
-		go utils.SendAlarmMsg("短信验证码发送失败", 1)
-		go utils.SendEmail("短信验证码发送失败", " result"+string(result), utils.EmailSendToUsers)
+		go utils.SendAlarmMsg("国际短信验证码发送失败err:"+err.Error()+" result"+string(result)+"mobile:"+mobile, 1)
+		go utils.SendEmail("国际短信验证码发送失败", " result"+string(result), utils.EmailSendToUsers)
 		flag = false
 	}
 	return flag

+ 16 - 16
services/tag.go

@@ -66,9 +66,9 @@ func GetConditionInitByTagIds(user *models.WxUserItem, labelKeyword string) (yan
 	var pars []interface{}
 	switch labelKeyword {
 	case utils.LABEL_L1_1: // 全部活动
-		yanxuanActivityIds = GetYanxuanActivityIds(user) // 获取所有的研选活动ID
+		yanxuanActivityIds = GetYanxuanActivityIds(user, "1,2") // 获取所有的研选活动ID
 	case "买方交流": // 买方交流 ->买方线下交流
-		condition = `   AND  chart_permission_id  = ? AND yidong_activity_id = ''  AND activity_type_id = 8  `
+		condition = `   AND  chart_permission_id  = ? AND yidong_activity_id = ''  AND activity_type_id = 8  AND  active_state IN (1,2) `
 		pars = append(pars, utils.CHART_PERMISSION_ID_YANXUAN)
 		list, e := models.GetCygxActivityIdList(condition, pars)
 		if e != nil {
@@ -79,7 +79,7 @@ func GetConditionInitByTagIds(user *models.WxUserItem, labelKeyword string) (yan
 			yanxuanActivityIds = append(yanxuanActivityIds, v.ActivityId)
 		}
 	case "专家调研": // 专家调研->专家电话会+专家线下沙龙
-		condition = `   AND  chart_permission_id  = ? AND yidong_activity_id = ''  AND activity_type_id IN  (1,5) `
+		condition = `   AND  chart_permission_id  = ? AND yidong_activity_id = ''  AND activity_type_id IN  (1,5)  AND  active_state IN (1,2) `
 		pars = append(pars, utils.CHART_PERMISSION_ID_YANXUAN)
 		list, e := models.GetCygxActivityIdList(condition, pars)
 		if e != nil {
@@ -91,7 +91,7 @@ func GetConditionInitByTagIds(user *models.WxUserItem, labelKeyword string) (yan
 		}
 
 	case "上市公司小范围": // 上市公司小范围->公司调研电话会
-		condition = `   AND  chart_permission_id  = ? AND yidong_activity_id = ''  AND activity_type_id = 3 `
+		condition = `   AND  chart_permission_id  = ? AND yidong_activity_id = ''  AND activity_type_id = 3  AND  active_state IN (1,2) `
 		pars = append(pars, utils.CHART_PERMISSION_ID_YANXUAN)
 		list, e := models.GetCygxActivityIdList(condition, pars)
 		if e != nil {
@@ -108,7 +108,7 @@ func GetConditionInitByTagIds(user *models.WxUserItem, labelKeyword string) (yan
 
 	case "纪要": //纪要
 
-		condition = ` AND  article_type_id > 0  AND  article_type_id != 12  `
+		condition = ` AND  article_type_id > 0   `
 		list, e := models.GetCygxCygxArticleIdList(condition, pars)
 		if e != nil {
 			err = errors.New("GetCygxCygxArticleIdList, Err: " + e.Error())
@@ -118,19 +118,19 @@ func GetConditionInitByTagIds(user *models.WxUserItem, labelKeyword string) (yan
 			yanxuanArticleIds = append(yanxuanArticleIds, v.ArticleId)
 		}
 
-	case "买方沙龙": // 买方沙龙
-		condition = `  AND  article_type_id = 12  `
-		list, e := models.GetCygxCygxArticleIdList(condition, pars)
-		if e != nil {
-			err = errors.New("GetCygxCygxArticleIdList, Err: " + e.Error())
-			return
-		}
-		for _, v := range list {
-			yanxuanArticleIds = append(yanxuanArticleIds, v.ArticleId)
-		}
+		//case "买方沙龙": // 买方沙龙
+		//	condition = `  AND  article_type_id = 12  `
+		//	list, e := models.GetCygxCygxArticleIdList(condition, pars)
+		//	if e != nil {
+		//		err = errors.New("GetCygxCygxArticleIdList, Err: " + e.Error())
+		//		return
+		//	}
+		//	for _, v := range list {
+		//		yanxuanArticleIds = append(yanxuanArticleIds, v.ArticleId)
+		//	}
 	}
 
-	yanxuanActivityIdsPerssion := GetYanxuanActivityIds(user) // 获取所有有权限的研选活动ID
+	yanxuanActivityIdsPerssion := GetYanxuanActivityIds(user, "1,2") // 获取所有有权限的研选活动ID
 	mapyanxuanActivityIds := make(map[int]bool)
 	for _, v := range yanxuanActivityIdsPerssion {
 		mapyanxuanActivityIds[v] = true

+ 10 - 0
services/task.go

@@ -6,6 +6,16 @@ import (
 
 func Task() {
 	fmt.Println("start")
+
+	//sendEmailFileForAskMsgResearch := task.NewTask("sendEmailFileForAskMsgResearch", "0 */5 6-23 * * *", SendEmailFileForAskMsgResearch) //研选系列专家电话会,会前1小时将问题列表发送给邮箱
+	//task.AddTask("sendEmailFileForAskMsgResearch", sendEmailFileForAskMsgResearch)
+	//
+	//sendActivityBeginMsgMeeting := task.NewTask("sendActivityBeginMsgMeeting", "0 */5 6-23 * * *", SendActivityBeginMsgMeeting) //会议前15分钟的提醒
+	//task.AddTask("sendActivityBeginMsgMeeting", sendActivityBeginMsgMeeting)
+	//
+	//sendActivityBeginMsg := task.NewTask("sendActivityBeginMsg", "0 */5 6-23 * * *", SendActivityBeginMsg) //会议前60分钟的提醒
+	//task.AddTask("sendActivityBeginMsg", sendActivityBeginMsg)
+
 	fmt.Println("end")
 }
 

+ 2 - 1
services/user.go

@@ -1154,7 +1154,7 @@ func UpdateCygxSubscribe(uid int, unionId string) (err error) {
 }
 
 // SendPermissionApplyTemplateMsgAdmin 处理试用申请给王芳,汪洋发消息
-func SendPermissionApplyTemplateMsgAdmin(req models.ApplyTryReq, usermobile, applyMethod string, isResearch bool) (err error) {
+func SendPermissionApplyTemplateMsgAdmin(req models.ApplyTryReq, usermobile, applyMethod, categoryApplyMethod ,redirectUrl string, isResearch bool) (err error) {
 	defer func() {
 		if err != nil {
 			go utils.SendAlarmMsg("处理试用申请给王芳,汪洋发消息失败, ErrMsg: "+err.Error(), 3)
@@ -1176,6 +1176,7 @@ func SendPermissionApplyTemplateMsgAdmin(req models.ApplyTryReq, usermobile, app
 
 	for _, v := range openIdList {
 		go SendPermissionApplyTemplateMsg(req.RealName, req.CompanyName, usermobile, applyMethod, v)
+		go SendPermissionApplyCategoryTemplateMsg(req.RealName, req.CompanyName, usermobile, categoryApplyMethod, v, redirectUrl)
 	}
 
 	//openIpItem, e := models.GetUserRecordByMobile(4, cnf.ConfigValue)

+ 1 - 1
services/user_admin_share.go

@@ -71,7 +71,7 @@ func AddCygxUserAdminShareHistory(user *models.WxUserItem, source, sourceTitle,
 	defer func() {
 		if err != nil {
 			fmt.Println(err)
-			go utils.SendAlarmMsg(fmt.Sprint("记录分享来源失败 AddCygxUserAdminShareHistory, err:", err.Error(), "inviteShareCode:", inviteShareCode), 2)
+			go utils.SendAlarmMsg(fmt.Sprint("记录分享来源失败 AddCygxUserAdminShareHistory, err:", err.Error(), "inviteShareCode:", inviteShareCode, "source", source), 2)
 		}
 	}()
 	adminDetail, e := models.GetUserAdminShareCodeByShareCode(inviteShareCode)

+ 765 - 0
services/wx_category_template_msg.go

@@ -0,0 +1,765 @@
+package services
+
+import (
+	"encoding/json"
+	"errors"
+	"fmt"
+	"hongze/hongze_mfyx/models"
+	"hongze/hongze_mfyx/utils"
+	"io/ioutil"
+	"net/http"
+	"strconv"
+	"strings"
+	"time"
+)
+
+type SendWxCategoryTemplate struct {
+	WxAppId        string   `description:"公众号appId"`
+	Keywords       []string `description:"模板消息keyword字段"`
+	TemplateId     string   `description:"模板id"`
+	RedirectUrl    string   `description:"跳转地址"`
+	RedirectTarget int      `description:"小程序跳转目标:1:弘则研报小程序,2:随手办公小程序,3:查研观向,4:买方研选"`
+	Resource       string   `description:"资源唯一标识"`
+	SendType       int      `description:"发送的消息类型:1:报告,2:指标更新提醒,3:审批通知,4:销售领取客户通知,5:活动取消通知,6活动更改时间通知,7:关注的作者发布报告通知,8:发送日报(周报、双周报、月报)模板消息,9:活动预约/报名时间通知"`
+	OpenIdArr      []string `description:"消息接收者openid"`
+}
+
+// 推送类目模板消息
+func SendCategoryTemplateMsg(sendInfo *SendWxCategoryTemplate) (err error) {
+	postData, err := json.Marshal(sendInfo)
+	if err != nil {
+		go utils.SendAlarmMsg("SendCategoryTemplateMsg json.Marshal Err:"+err.Error(), 1)
+		return err
+	}
+	body := ioutil.NopCloser(strings.NewReader(string(postData)))
+	client := &http.Client{}
+	req, err := http.NewRequest("POST", utils.SendWxCategoryTemplateMsgUrl, body)
+	if err != nil {
+		go utils.SendAlarmMsg("SendCategoryTemplateMsg http.NewRequest Err:"+err.Error(), 1)
+		return err
+	}
+	contentType := "application/json;charset=utf-8"
+	req.Header.Set("Content-Type", contentType)
+	req.Header.Set("Authorization", utils.SendTemplateMsgAuthorization)
+	resp, err := client.Do(req)
+	if err != nil {
+		fmt.Println("http client.Do Err:" + err.Error())
+		return err
+	}
+	defer resp.Body.Close()
+	b, err := ioutil.ReadAll(resp.Body)
+	if err != nil {
+		return err
+	}
+	result := new(models.BaseResponse)
+	err = json.Unmarshal(b, &result)
+	if err != nil {
+		return err
+	}
+	if result.Ret != 200 {
+		err = errors.New(string(b))
+		return err
+	}
+	return
+}
+
+// 发送用户操作活动消息提醒
+func SendWxCategoryMsgWithActivityUserRemind(keyWord1, keyWord2, keyWord3, keyWord4, redirectUrl string, openIdList []*models.OpenIdList, activityId int) (err error) {
+	if len(openIdList) == 0 {
+		return
+	}
+	var msg string
+	defer func() {
+		if err != nil {
+			go utils.SendEmail("发送模版消息失败"+"【"+utils.APPNAME+"】"+time.Now().Format("2006-01-02 15:04:05"), msg+";Err:"+err.Error(), utils.EmailSendToUsers)
+			go utils.SendAlarmMsg(fmt.Sprint("发送用户操作活动消息提醒,文章ID:", activityId), 2)
+			utils.FileLog.Info("发送模版消息失败,Err:%s", err.Error())
+		}
+	}()
+	keyWord1 = utils.TruncateActivityNameString(keyWord1)
+	accessToken, err := models.GetWxAccessTokenByXzs()
+	if err != nil {
+		msg = "GetWxAccessToken Err:" + err.Error()
+		return
+	}
+	if accessToken == "" {
+		msg = "accessToken is empty"
+		return
+	}
+	openIdArr := make([]string, 0)
+	for _, v := range openIdList {
+		openIdArr = append(openIdArr, v.OpenId)
+	}
+	var keywords []string
+	keywords = append(keywords, keyWord1, keyWord2, keyWord3, keyWord4)
+
+	sendInfo := new(SendWxCategoryTemplate)
+	sendInfo.Keywords = keywords
+	sendInfo.TemplateId = utils.WxMsgCategoryTemplateIdActivityPublishApply
+	sendInfo.RedirectTarget = 4
+	sendInfo.RedirectUrl = redirectUrl
+	sendInfo.SendType = utils.TEMPLATE_MSG_CYGX_APPLY
+	sendInfo.OpenIdArr = openIdArr
+	err = SendCategoryTemplateMsg(sendInfo)
+
+	//sendMap["miniprogram"] = map[string]interface{}{"appid": utils.WxAppId, "pagepath": "activityPages/activityDetail/activityDetail?id=" + strconv.Itoa(activityId)}
+	return
+}
+
+// 试用申请模板消息
+func SendPermissionApplyCategoryTemplateMsg(realName, companyName, mobile, applyMethod string, itemOpenid *models.OpenIdList, redirectUrl string) (err error) {
+
+	defer func() {
+		if err != nil {
+			go utils.SendAlarmMsg(fmt.Sprint("权限申请模板消息推送消息失败,手机号", mobile, "公司:", companyName, "手机号:", mobile, ";Err:"+err.Error()), 2)
+		}
+	}()
+	var keyword1 string
+	var keyword2 string
+	var keyword3 string
+	var keyword4 string
+	var keyword5 string
+
+	detail, e := models.GetCygxApplyRecordByMobile(mobile)
+	if e != nil {
+		err = errors.New("GetActivitySignupNomeetingCountList" + e.Error())
+		return
+	}
+	//如果是潜在客户就推送可查看详情的模版消息
+	if utils.RunMode == "release" {
+		if detail.ApplyMethod == 2 {
+			redirectUrl = utils.WX_MSG_PATH_APPLY_DETAIL + strconv.Itoa(detail.ApplyRecordId)
+		}
+	}
+
+	openIdArr := make([]string, 0)
+	openIdArr = append(openIdArr, itemOpenid.OpenId)
+	sendInfo := new(SendWxCategoryTemplate)
+
+	keyword1 = realName
+	keyword2 = companyName
+	keyword3 = "权限申请"
+	keyword4 = time.Now().Format(utils.FormatDateTimeMinute2)
+	keyword5 = applyMethod
+
+	sendInfo.Keywords = []string{keyword1, keyword2, keyword3, keyword4, keyword5}
+	sendInfo.TemplateId = utils.WxCategoryMsgTemplateIdApplyXzs
+	sendInfo.RedirectUrl = redirectUrl
+	sendInfo.RedirectTarget = 4
+	sendInfo.Resource = mobile
+	sendInfo.SendType = utils.TEMPLATE_MSG_CYGX_APPLY
+	sendInfo.OpenIdArr = openIdArr
+	err = SendCategoryTemplateMsg(sendInfo)
+	return
+}
+
+// 发送用户操作活动消息提醒
+func SendNeiRongZuActivitieSignCategoryTemplateMsg(user *models.WxUserItem, activityDetail *models.ActivityDetail) (err error) {
+	var msg string
+	defer func() {
+		if err != nil {
+			go utils.SendEmail("发送模版消息失败"+"【"+utils.APPNAME+"】"+time.Now().Format("2006-01-02 15:04:05"), msg+";Err:"+err.Error(), utils.EmailSendToUsers)
+			go utils.SendAlarmMsg(fmt.Sprint("发送用户操作活动消息提醒,文章ID:", activityDetail.ActivityId), 2)
+			utils.FileLog.Info("发送模版消息失败,Err:%s", err.Error())
+		}
+	}()
+	accessToken, err := models.GetWxAccessTokenByXzs()
+	if err != nil {
+		msg = "GetWxAccessToken Err:" + err.Error()
+		return
+	}
+	if accessToken == "" {
+		msg = "accessToken is empty"
+		return
+	}
+	sellerItemQy, err := models.GetSellerByCompanyIdCheckFicc(user.CompanyId, 2)
+	if err != nil && err.Error() != utils.ErrNoRow() {
+		return
+	}
+	configCode := utils.TPL_MSG_NEI_RONG_ZU
+	cnf, e := models.GetConfigByCode(configCode)
+	if e != nil {
+		err = errors.New("GetConfigByCode, Err: " + e.Error() + configCode)
+		return
+	}
+	openIdList, e := models.GetUserRecordListByMobile(4, cnf.ConfigValue+","+sellerItemQy.Mobile+","+utils.MobileShenTao)
+	if e != nil && e.Error() != utils.ErrNoRow() {
+		err = errors.New("GetUserRecordListByMobile, Err: " + e.Error() + cnf.ConfigValue)
+		return
+	}
+
+	openIdArr := make([]string, 0)
+	for _, v := range openIdList {
+		openIdArr = append(openIdArr, v.OpenId)
+	}
+	var keywords []string
+	keywords = append(keywords, user.RealName, user.CompanyName,
+		sellerItemQy.RealName, time.Now().Format(utils.FormatDateTimeMinute2),
+		"报名:"+activityDetail.ActivityName)
+
+	//sendMap["miniprogram"] = map[string]interface{}{"appid": utils.WxAppId, "pagepath": "activityPages/activityDetail/activityDetail?id=" + strconv.Itoa(activityDetail.ActivityId)}
+	sendInfo := new(SendWxCategoryTemplate)
+	sendInfo.Keywords = keywords
+	sendInfo.TemplateId = utils.WxCategoryMsgTemplateIdApplyXzs
+	sendInfo.RedirectTarget = 4
+	sendInfo.SendType = utils.TEMPLATE_MSG_CYGX_APPLY
+	sendInfo.OpenIdArr = openIdArr
+	err = SendCategoryTemplateMsg(sendInfo)
+	return
+}
+
+func SendActivitieCancelSignCategoryTemplateMsg(user *models.WxUserItem, activityDetail *models.ActivityDetail) (err error) {
+	var msg string
+	defer func() {
+		if err != nil {
+			go utils.SendEmail("发送模版消息失败"+"【"+utils.APPNAME+"】"+time.Now().Format("2006-01-02 15:04:05"), msg+";Err:"+err.Error(), utils.EmailSendToUsers)
+			go utils.SendAlarmMsg(fmt.Sprint("发送用户操作活动消息提醒,文章ID:", activityDetail.ActivityId), 2)
+			utils.FileLog.Info("发送模版消息失败,Err:%s", err.Error())
+		}
+	}()
+	accessToken, err := models.GetWxAccessTokenByXzs()
+	if err != nil {
+		msg = "GetWxAccessToken Err:" + err.Error()
+		return
+	}
+	if accessToken == "" {
+		msg = "accessToken is empty"
+		return
+	}
+	sellerItemQy, err := models.GetSellerByCompanyIdCheckFicc(user.CompanyId, 2)
+	if err != nil && err.Error() != utils.ErrNoRow() {
+		return
+	}
+	configCode := utils.TPL_MSG_NEI_RONG_ZU
+	cnf, e := models.GetConfigByCode(configCode)
+	if e != nil {
+		err = errors.New("GetConfigByCode, Err: " + e.Error() + configCode)
+		return
+	}
+	openIdList, e := models.GetUserRecordListByMobile(4, cnf.ConfigValue+","+sellerItemQy.Mobile+","+utils.MobileShenTao)
+	if e != nil && e.Error() != utils.ErrNoRow() {
+		err = errors.New("GetUserRecordListByMobile, Err: " + e.Error() + cnf.ConfigValue)
+		return
+	}
+
+	openIdArr := make([]string, 0)
+	for _, v := range openIdList {
+		openIdArr = append(openIdArr, v.OpenId)
+	}
+
+	var keywords []string
+	keywords = append(keywords, user.RealName, user.CompanyName,
+		sellerItemQy.RealName, time.Now().Format(utils.FormatDateTimeMinute2),
+		"取消报名"+"【"+activityDetail.ActivityName+"】")
+
+	//sendMap["miniprogram"] = map[string]interface{}{"appid": utils.WxAppId}
+
+	sendInfo := new(SendWxCategoryTemplate)
+	sendInfo.WxAppId = utils.WxAppId
+	sendInfo.Keywords = keywords
+	sendInfo.TemplateId = utils.WxCategoryMsgTemplateIdApplyXzs
+	sendInfo.RedirectTarget = 4
+	sendInfo.SendType = utils.TEMPLATE_MSG_CYGX_APPLY
+	sendInfo.OpenIdArr = openIdArr
+	err = SendCategoryTemplateMsg(sendInfo)
+	return
+}
+
+// 发送用户留言提醒
+func SendCommentWxCategoryTemplateMsg(req models.AddCygxArticleCommentReq, user *models.WxUserItem, articleInfo *models.ArticleDetail, msgId int) (err error) {
+	var msg string
+	defer func() {
+		if err != nil {
+			go utils.SendEmail("发送类目模版消息失败"+"【"+utils.APPNAME+"】"+time.Now().Format("2006-01-02 15:04:05"), msg+";Err:"+err.Error(), utils.EmailSendToUsers)
+			go utils.SendAlarmMsg(fmt.Sprint("发送用户用户留言提醒失败,文章ID:", req.ArticleId), 2)
+			utils.FileLog.Info("发送类目模版消息失败,Err:%s", err.Error())
+		}
+	}()
+
+	companyItem, e := models.GetSellerDetailAllByCompanyId(user.CompanyId)
+	if e != nil {
+		return
+	}
+	if companyItem == nil {
+		msg = "获取客户所属销售信息失败,UserID:" + strconv.Itoa(user.UserId)
+	}
+	var keyword1 string
+	var keyword2 string
+	var keyword3 string
+	var keyword4 string
+	var keyword5 string
+	var redirectUrl string
+	var mobile string
+
+	var keywords []string
+	keyword1 = user.RealName
+	keyword2 = companyItem.CompanyName
+	keyword3 = companyItem.SellerName
+	keyword4 = time.Now().Format(utils.FormatDateTimeMinute2)
+	keyword5 = "报告留言:" + req.Content
+	keyword5 = utils.TruncateActivityNameString(keyword5)
+	keywords = append(keywords, keyword1, keyword2, keyword3, keyword4, keyword5)
+
+	if articleInfo.ArticleTypeId > 0 {
+		//研选报告添加汪洋
+		mobile = companyItem.Mobile + "," + utils.WxMsgTemplateIdAskMsgMobilePublic + "," + utils.ActSendMsgMobile
+	} else {
+		mobile = companyItem.Mobile + "," + utils.WxMsgTemplateIdAskMsgMobilePublic
+	}
+	openIdList, e := models.GetWxOpenIdByMobileList(mobile)
+	if e != nil {
+		err = errors.New("GetWxOpenIdByMobileList, Err: " + e.Error())
+		return
+	}
+	openIdArr := make([]string, 0)
+	for _, v := range openIdList {
+		openIdArr = append(openIdArr, v.OpenId)
+	}
+
+	redirectUrl = utils.WX_MSG_PATH_YX_COMMENT_DETAIL + strconv.Itoa(msgId) + "&type=文章"
+
+	sendInfo := new(SendWxCategoryTemplate)
+	sendInfo.Keywords = keywords
+	sendInfo.TemplateId = utils.WxCategoryMsgTemplateIdApplyXzs
+	sendInfo.RedirectTarget = 4
+	sendInfo.SendType = utils.TEMPLATE_MSG_CYGX_APPLY
+	sendInfo.OpenIdArr = openIdArr
+	sendInfo.RedirectUrl = redirectUrl
+	err = SendCategoryTemplateMsg(sendInfo)
+	return
+}
+
+// 发送活动提问消息提醒
+func SendWxCategoryMsgWithAsk(realName, companyName, sellerName, askMsg string, openIdList []*models.OpenIdList, askId int) (err error) {
+	if len(openIdList) == 0 {
+		return
+	}
+	var msg string
+	defer func() {
+		if err != nil {
+			go utils.SendEmail("发送类目模版消息失败"+"【"+utils.APPNAME+"】"+time.Now().Format("2006-01-02 15:04:05"), msg+";Err:"+err.Error(), utils.EmailSendToUsers)
+			go utils.SendAlarmMsg(fmt.Sprint("发送活动提问消息提醒类目模版消息失败,用户名", realName, "提问ID:", askId), 2)
+			utils.FileLog.Info("发送类目模版消息失败,Err:%s", err.Error())
+		}
+		fmt.Println("line 21", err, msg)
+	}()
+	var keyword1 string
+	var keyword2 string
+	var keyword3 string
+	var keyword4 string
+	var keyword5 string
+
+	keyword1 = realName
+	keyword2 = utils.TruncateActivityNameString(companyName)
+	keyword3 = sellerName
+	keyword4 = time.Now().Format(utils.FormatDateTimeMinute2)
+	keyword5 = "活动提问:" + askMsg
+
+	keywords := []string{keyword1, keyword2, keyword3, keyword4, keyword5}
+
+	openIdArr := make([]string, 0)
+	for _, v := range openIdList {
+		openIdArr = append(openIdArr, v.OpenId)
+	}
+	redirectUrl := utils.WX_MSG_PATH_YX_ACTIVITY_DETAIL + strconv.Itoa(askId)
+	//redirectUrl := utils.WX_MSG_PATH_TEMPLATE_MSG + "SourceId=" + strconv.Itoa(askId) + "&SourceType=2"
+
+	sendInfo := new(SendWxCategoryTemplate)
+	sendInfo.Keywords = keywords
+	sendInfo.TemplateId = utils.WxCategoryMsgTemplateIdApplyXzs
+	sendInfo.RedirectTarget = 4
+	sendInfo.SendType = utils.TEMPLATE_MSG_CYGX_ARTICLE_ADD
+	sendInfo.OpenIdArr = openIdArr
+	sendInfo.RedirectUrl = redirectUrl
+	err = SendCategoryTemplateMsg(sendInfo)
+	return
+}
+
+// 线下调研活动扫码签到给对应销售发类目模班消息
+func SendActivitieSignCategoryTemplateMsg(user *models.WxUserItem, activityDetail *models.ActivityDetail) (err error) {
+	defer func() {
+		if err != nil {
+			go utils.SendAlarmMsg(fmt.Sprint("线下调研活动扫码签到给对应销售发模班消息推送失败Err:", err.Error(), "活动ID:", activityDetail.ActivityId, "手机号:", user.Mobile), 2)
+		}
+	}()
+	var mobiles []string
+	//获取销售信息
+	sellerItem, err := models.GetSellerByCompanyIdCheckFicc(user.CompanyId, 2)
+	if err != nil && err.Error() != utils.ErrNoRow() {
+		return
+	}
+	if sellerItem != nil {
+		mobiles = append(mobiles, sellerItem.Mobile, utils.MobileWuAngDi, utils.MobileDongHeng, utils.MobileShenTao)
+	}
+
+	var keyword1 string
+	var keyword2 string
+	var keyword3 string
+	var keyword4 string
+	var keyword5 string
+
+	var redirectUrl string
+
+	keyword1 = user.RealName
+	keyword2 = user.CompanyName
+	keyword3 = sellerItem.RealName
+	keyword4 = activityDetail.ActivityName
+	keyword5 = time.Now().Format(utils.FormatDateTimeMinute2)
+
+	openIdList, e := models.GetWxOpenIdByMobileSliceList(mobiles)
+	if e != nil {
+		err = errors.New("GetWxOpenIdByMobileList, Err: " + e.Error())
+		return
+	}
+	openIdArr := make([]string, 0)
+	for _, v := range openIdList {
+		openIdArr = append(openIdArr, v.OpenId)
+	}
+
+	redirectUrl = utils.WX_MSG_PATH_YX_SIGNUP_DETAIL + strconv.Itoa(activityDetail.ActivityId)
+
+	keywords := []string{keyword1, keyword2, keyword3, keyword4, keyword5}
+	sendInfo := new(SendWxCategoryTemplate)
+	sendInfo.Keywords = keywords
+	sendInfo.TemplateId = utils.WxCategoryMsgTemplateIdActivitySign
+	sendInfo.RedirectTarget = 4
+	sendInfo.SendType = utils.TEMPLATE_MSG_CYGX_ARTICLE_ADD
+	sendInfo.OpenIdArr = openIdArr
+	sendInfo.RedirectUrl = redirectUrl
+	err = SendCategoryTemplateMsg(sendInfo)
+	if err != nil {
+		return
+	}
+	return
+}
+
+// SendReviewCategoryTemplateMsgAdmin 提交审核时给王芳,汪洋发消息
+func SendReviewCategoryTemplateMsgAdmin(specialId int) (err error) {
+	defer func() {
+		if err != nil {
+			go utils.SendAlarmMsg(fmt.Sprint("处理试用申请给王芳,汪洋发消息失败, specialId:", specialId, "ErrMsg", err.Error()), 2)
+		}
+	}()
+	//王芳、葛琳和沈涛
+	openIdList, e := models.GetUserRecordListByMobile(4, utils.WxMsgTemplateIdYXSpecialReview)
+	if e != nil && e.Error() != utils.ErrNoRow() {
+		err = errors.New("GetUserRecordListByMobile, Err: " + e.Error())
+		return err
+	}
+	specialItem, e := models.GetYanxuanSpecialItemById(specialId)
+	if e != nil {
+		err = errors.New("GetYanxuanSpecialFollowUserById, Err: " + e.Error())
+		return
+	}
+	user, e := models.GetWxUserItemByUserId(specialItem.UserId)
+	if e != nil {
+		err = errors.New("GetWxUserItemByUserId, Err: " + e.Error())
+		return err
+	}
+	var keyword1 string
+	var keyword2 string
+	var keyword3 string
+	var keyword4 string
+	var keyword5 string
+	keyword1 = specialItem.NickName
+	keyword2 = specialItem.RealName + "-" + user.CompanyName
+	keyword3 = specialItem.SpecialName
+	keyword4 = time.Now().Format(utils.FormatDateTimeMinute2)
+	keyword5 = "研选专栏提交了内容待审核"
+	openIdArr := make([]string, 0)
+	for _, v := range openIdList {
+		openIdArr = append(openIdArr, v.OpenId)
+	}
+	redirectUrl := ""
+	redirectUrl = utils.WX_MSG_PATH_YX_SPECIAL_ENABLE_DETAIL + strconv.Itoa(specialId)
+
+	keywords := []string{keyword1, keyword2, keyword3, keyword4, keyword5}
+
+	sendInfo := new(SendWxCategoryTemplate)
+	sendInfo.Keywords = keywords
+	sendInfo.TemplateId = utils.WxCategoryMsgTemplateIdApplyXzs
+	sendInfo.RedirectTarget = 4
+	sendInfo.SendType = utils.TEMPLATE_MSG_CYGX_ARTICLE_ADD
+	sendInfo.OpenIdArr = openIdArr
+	sendInfo.RedirectUrl = redirectUrl
+	err = SendCategoryTemplateMsg(sendInfo)
+	if err != nil {
+		return
+	}
+	return
+}
+
+// 研选专栏审核完成时,给提交人发送类目模板消息
+func SendWxCategoryMsgSpecialAuthor(specialId, status int) (err error) {
+	defer func() {
+		if err != nil {
+			go utils.SendAlarmMsg(fmt.Sprint("研选专栏审核完成时,给提交人发送模板消息", specialId, ", specialId", err.Error()), 2)
+		}
+	}()
+	var keyword1 string
+	var keyword2 string
+	var keyword3 string
+	var keyword4 string
+	var redirectUrl string
+
+	specialItem, e := models.GetYanxuanSpecialItemById(specialId)
+	if e != nil {
+		err = errors.New("GetYanxuanSpecialFollowUserById, Err: " + e.Error())
+		return
+	}
+	user, e := models.GetWxUserItemByUserId(specialItem.UserId)
+	if e != nil {
+		err = errors.New("GetWxUserItemByUserId, Err: " + e.Error())
+		return err
+	}
+
+	openIdList, err := models.GetUserRecordListByMobile(4, user.Mobile)
+	if err != nil && err.Error() != utils.ErrNoRow() {
+		return err
+	}
+
+	keyword1 = specialItem.Title
+	keyword2 = specialItem.NickName
+	if status == 1 {
+		keyword3 = "文章已通过审核,点击查看详情"
+		redirectUrl = utils.WX_MSG_PATH_YX_SPECIAL_DETAIL + strconv.Itoa(specialId)
+	} else {
+		keyword3 = "文章未通过审核,点击查看驳回原因"
+		redirectUrl = utils.WX_MSG_PATH_YX_SPECIAL_CENTER
+	}
+	keyword4 = time.Now().Format(utils.FormatDateTimeMinute2)
+	openIdArr := make([]string, 0)
+	for _, v := range openIdList {
+		openIdArr = append(openIdArr, v.OpenId)
+	}
+
+	keywords := []string{keyword1, keyword2, keyword3, keyword4}
+
+	sendInfo := new(SendWxCategoryTemplate)
+	sendInfo.Keywords = keywords
+	sendInfo.TemplateId = utils.WxMsgCategoryTemplateIdCompanyApprovalMessageRai
+	sendInfo.RedirectTarget = 4
+	sendInfo.SendType = utils.TEMPLATE_MSG_CYGX_ARTICLE_ADD
+	sendInfo.OpenIdArr = openIdArr
+	sendInfo.RedirectUrl = redirectUrl
+	err = SendCategoryTemplateMsg(sendInfo)
+	if err != nil {
+		return
+	}
+	return
+}
+
+// 研选专栏有新内容审核通过时,给关注此专栏的客户发送模板消息
+func SendWxCategoryMsgSpecialFollow(specialId int) (err error) {
+	defer func() {
+		if err != nil {
+			go utils.SendAlarmMsg(fmt.Sprint("研选专栏有新内容审核通过时,给关注此专栏的客户发送类目模板消息失败", specialId, ", specialId", err.Error()), 2)
+		}
+	}()
+	var keyword1 string
+	var keyword2 string
+	var keyword3 string
+	var keyword4 string
+
+	followers, e := models.GetYanxuanSpecialFollowUserById(specialId)
+	if e != nil {
+		err = errors.New("GetYanxuanSpecialFollowUserById, Err: " + e.Error())
+		return
+	}
+	if len(followers) == 0 {
+		return
+	}
+	specialItem, e := models.GetYanxuanSpecialItemById(specialId)
+	if e != nil {
+		err = errors.New("GetYanxuanSpecialFollowUserById, Err: " + e.Error())
+		return
+	}
+	var allInUserId string
+	for _, v := range followers {
+		allInUserId += strconv.Itoa(v) + ","
+	}
+
+	allInUserId = strings.TrimRight(allInUserId, ",")
+
+	userList, err := models.GetWxUserListByUserIds(allInUserId)
+	if err != nil && err.Error() != utils.ErrNoRow() {
+		return err
+	}
+
+	mobile := ``
+
+	for _, v := range userList {
+		mobile += v.Mobile + ","
+	}
+
+	mobile = strings.TrimRight(mobile, ",")
+
+	openIdList, e := models.GetWxOpenIdByMobileList(mobile)
+	if e != nil {
+		err = errors.New("GetSellerByAdminId, Err: " + e.Error())
+		return
+	}
+	if len(openIdList) == 0 {
+		return
+	}
+
+	keyword1 = specialItem.SpecialName
+	keyword2 = "发布了新报告"
+	keyword3 = specialItem.Title
+	keyword4 = time.Now().Format(utils.FormatDateTimeMinute2)
+	openIdArr := make([]string, 0)
+	for _, v := range openIdList {
+		openIdArr = append(openIdArr, v.OpenId)
+	}
+	redirectUrl := ""
+	redirectUrl = utils.WX_MSG_PATH_YX_SPECIAL_DETAIL + strconv.Itoa(specialId)
+	keywords := []string{keyword1, keyword2, keyword3, keyword4}
+
+	sendInfo := new(SendWxCategoryTemplate)
+	sendInfo.Keywords = keywords
+	sendInfo.TemplateId = utils.WxMsgCategoryTemplateIdActivityPublishApply
+	sendInfo.RedirectTarget = 4
+	sendInfo.SendType = utils.TEMPLATE_MSG_CYGX_ARTICLE_ADD
+	sendInfo.OpenIdArr = openIdArr
+	sendInfo.RedirectUrl = redirectUrl
+	err = SendCategoryTemplateMsg(sendInfo)
+	if err != nil {
+		return
+	}
+	return
+}
+
+// 文章互动相关类目模版消息
+func SendWxCategoryMsgInteractive(user *models.WxUserItem, interactive string, articleId int, title string) (err error) {
+	if interactive == "阅读报告" {
+		//30秒内阅读同一篇报告不做重复推送
+		key := "CYGX_" + utils.CYGX_OBJ_RESEARCHSUMMARY + "_READ" + strconv.Itoa(articleId) + "_" + strconv.Itoa(user.UserId) + "_CATEGORY"
+		if utils.Rc.IsExist(key) {
+			return
+		}
+		utils.Rc.Put(key, 1, 30*time.Second)
+	}
+	defer func() {
+		if err != nil {
+			go utils.SendAlarmMsg(fmt.Sprint("文章互动相关,类目模板消息推送 ,SendWxCategoryMsgInteractive"+err.Error(), "userId:", user.UserId, "互动类型:", interactive), 2)
+		}
+	}()
+	countUser, err := models.GetUserRemind(user.UserId)
+	if err != nil {
+		return err
+	}
+	if err != nil {
+		return err
+	}
+	if countUser == 0 {
+		return err
+	}
+	var keyword1 string
+	var keyword2 string
+	var keyword3 string
+	var keyword4 string
+	//获取销售手机号
+	sellerItemQy, err := models.GetSellerByCompanyIdCheckFicc(user.CompanyId, 2)
+	if err != nil && err.Error() != utils.ErrNoRow() {
+		return err
+	}
+	if sellerItemQy != nil {
+		openIdList, e := models.GetWxOpenIdByMobileList(sellerItemQy.Mobile)
+		if e != nil {
+			err = errors.New("GetSellerByAdminId, Err: " + e.Error())
+			return
+		}
+		if len(openIdList) == 0 {
+			return
+		}
+
+		keyword1 = user.RealName + "-" + user.CompanyName
+		keyword1 = utils.TruncateActivityNameString(keyword1)
+		keyword2 = fmt.Sprint("互动提醒:", interactive)
+		keyword3 = utils.TruncateActivityNameString(title)
+		keyword4 = time.Now().Format(utils.FormatDateTimeMinute2)
+		openIdArr := make([]string, 0)
+		for _, v := range openIdList {
+			openIdArr = append(openIdArr, v.OpenId)
+		}
+
+		redirectUrl := ``
+		redirectUrl = utils.WX_MSG_PATH_YX_ARTICLE_DETAIL + strconv.Itoa(articleId)
+
+		keywords := []string{keyword1, keyword2, keyword3, keyword4}
+
+		sendInfo := new(SendWxCategoryTemplate)
+		sendInfo.Keywords = keywords
+		sendInfo.TemplateId = utils.WxMsgCategoryTemplateIdActivityPublishApply
+		sendInfo.RedirectTarget = 4
+		sendInfo.SendType = utils.TEMPLATE_MSG_CYGX_ARTICLE_ADD
+		sendInfo.OpenIdArr = openIdArr
+		sendInfo.RedirectUrl = redirectUrl
+		err = SendCategoryTemplateMsg(sendInfo)
+		if err != nil {
+			return
+		}
+	}
+	return
+}
+
+// 用户搜索操作操作行为,类目模板消息推送
+func SearchKeywordUserRmindCategoryMsg(user *models.WxUserItem, keyWord string) (err error) {
+	defer func() {
+		if err != nil {
+			fmt.Println(err)
+			go utils.SendAlarmMsg(fmt.Sprint("用户搜索操作操作行为,类目模板消息推送失败"+err.Error(), "UserId:", user.UserId, "keyWord:", keyWord), 2)
+		}
+	}()
+	countUser, e := models.GetUserRemind(user.UserId)
+	if e != nil {
+		err = errors.New("GetUserRemind, Err: " + e.Error())
+		return
+	}
+	if countUser == 0 {
+		return
+	}
+	var keyword1 string
+	var keyword2 string
+	var keyword3 string
+	var keyword4 string
+	//获取销售手机号
+	sellerItemQy, e := models.GetSellerByCompanyIdCheckFicc(user.CompanyId, 2)
+	if e != nil && e.Error() != utils.ErrNoRow() {
+		err = errors.New("GetSellerByCompanyIdCheckFicc, Err: " + e.Error())
+		return
+	}
+	if sellerItemQy != nil {
+		openIdList, e := models.GetWxOpenIdByMobileList(sellerItemQy.Mobile)
+		if e != nil {
+			err = errors.New("GetSellerByAdminId, Err: " + e.Error())
+			return
+		}
+		if len(openIdList) == 0 {
+			return
+		}
+		keyword1 = user.RealName + "-" + user.CompanyName
+		keyword2 = fmt.Sprint("互动提醒:搜索")
+		keyword3 = keyWord
+		keyword4 = time.Now().Format(utils.FormatDateTimeMinute2)
+		openIdArr := make([]string, 0)
+		for _, v := range openIdList {
+			openIdArr = append(openIdArr, v.OpenId)
+		}
+		redirectUrl := ""
+		keywords := []string{keyword1, keyword2, keyword3, keyword4}
+
+		sendInfo := new(SendWxCategoryTemplate)
+		sendInfo.Keywords = keywords
+		sendInfo.TemplateId = utils.WxMsgCategoryTemplateIdCompanyApprovalMessageRai
+		sendInfo.RedirectTarget = 4
+		sendInfo.SendType = utils.TEMPLATE_MSG_CYGX_ARTICLE_ADD
+		sendInfo.OpenIdArr = openIdArr
+		sendInfo.RedirectUrl = redirectUrl
+		err = SendCategoryTemplateMsg(sendInfo)
+		if err != nil {
+			return
+		}
+	}
+	return
+}

+ 23 - 0
utils/common.go

@@ -21,6 +21,7 @@ import (
 	"strings"
 	"time"
 	"unicode"
+	"unicode/utf8"
 )
 
 // 随机数种子
@@ -962,6 +963,28 @@ func StrDateToDate(strTime string) time.Time {
 	return resultTime
 }
 
+// 处理活动名称
+func TruncateActivityNameString(s string) string {
+	// 计算字符串总字数(按汉字、数字、字母和特殊符号计算)
+	totalCharCount := utf8.RuneCountInString(s)
+	// 如果总字数不超过18,则直接返回整个字符串
+	if totalCharCount <= 18 {
+		return s
+	}
+	// 计算前15个汉字所需的字节位置
+	hanziCount := 0
+	byteIndex := 0
+	for byteIndex < len(s) && hanziCount < 15 {
+		r, size := utf8.DecodeRuneInString(s[byteIndex:])
+		if r != utf8.RuneError {
+			hanziCount++
+		}
+		byteIndex += size
+	}
+	// 截取前15个汉字,并添加省略号
+	return s[:byteIndex] + "…"
+}
+
 func GetOrdernum() string {
 	now := time.Now().UnixNano()
 	// 生成4位随机数

+ 53 - 25
utils/config.go

@@ -22,30 +22,39 @@ var (
 // 微信配置信息
 var (
 	WxId        string //微信原始ID
-	WxAppId     string //查研观向小程序
-	WxAppSecret string //查研观向小程序
+	WxAppId     string //买方研选小程序
+	WxAppSecret string //买方研选小程序
 
 	WxPublicIdXzs     string //查研观向小助手公众号
 	WxPublicSecretXzs string //查研观向小助手公众号
 
-	WxMsgTemplateIdApply                  string //申请待处理
-	WxMsgTemplateIdApplyXzs               string //申请待处理(小助手)
-	WxMsgTemplateIdApplyCancel            string //预约取消提醒
-	WxMsgTemplateIdApplyCancelXzs         string //预约取消提醒(小助手)
-	WxMsgTemplateIdPermissionApply        string //预约取消提醒
-	WxMsgTemplateIdActivityApply          string //活动预约消息提醒
-	WxMsgTemplateIdActivityApplyXzs       string //活动预约消息提醒(小助手)
-	WxMsgTemplateIdActivityChange         string //活动预约变更提醒
-	WxMsgTemplateIdAskMsg                 string //手机号用户【XXX】发送模板消息模板ID
-	WxMsgTemplateIdAskMsgXzs              string //手机号用户【XXX】发送模板消息模板ID(小助手)
-	WxMsgTemplateIdAskMsgMobile           string //手机号用户【XXX】发送模板消息
-	WxMsgTemplateIdAskMsgMobileAll        string //手机号用户【XXX】发送模板消rm --
-	WxMsgTemplateIdAskMsgMobilePublic     string //手机号用户【XXX】发送模板消rm --
-	TemplateIdByProductXzs                string //产品运行报告通知-模板ID(小助手)
-	WxMsgTemplateIdArticleUserRemind      string //用户阅读报告通知-模板ID
-	WxMsgTemplateIdArticleUserRemindXzs   string //用户阅读报告通知-模板ID(小助手)
-	WxMsgTemplateIdActivityChangeApplyXzs string //查研观向活动变更通知-模板ID(小助手)
-	WxMsgTemplateIdActivitySign           string //查研观向活动签到通知-模板ID(小助手)
+	WxMsgTemplateIdApply                     string //申请待处理
+	WxMsgTemplateIdApplyXzs                  string //申请待处理(小助手)
+	WxMsgTemplateIdApplyCancel               string //预约取消提醒
+	WxMsgTemplateIdApplyCancelXzs            string //预约取消提醒(小助手)
+	WxMsgTemplateIdPermissionApply           string //预约取消提醒
+	WxMsgTemplateIdActivityApply             string //活动预约消息提醒
+	WxMsgTemplateIdActivityApplyXzs          string //活动预约消息提醒(小助手)
+	WxMsgTemplateIdActivityChange            string //活动预约变更提醒
+	WxMsgTemplateIdAskMsg                    string //手机号用户【XXX】发送模板消息模板ID
+	WxMsgTemplateIdAskMsgXzs                 string //手机号用户【XXX】发送模板消息模板ID(小助手)
+	WxMsgTemplateIdAskMsgMobile              string //手机号用户【XXX】发送模板消息
+	WxMsgTemplateIdAskMsgMobileAll           string //手机号用户【XXX】发送模板消rm --
+	WxMsgTemplateIdAskMsgMobilePublic        string //手机号用户【XXX】发送模板消rm --
+	WxMsgTemplateIdYXSpecialReview           string //王芳、葛琳和沈涛--
+	TemplateIdByProductXzs                   string //产品运行报告通知-模板ID(小助手)
+	WxMsgTemplateIdArticleUserRemind         string //用户阅读报告通知-模板ID
+	WxMsgCategoryTemplateIdArticleUserRemind string //用户阅读报告通知-类目模板ID
+	WxMsgTemplateIdArticleUserRemindXzs      string //用户阅读报告通知-模板ID(小助手)
+	WxMsgTemplateIdActivityChangeApplyXzs    string //查研观向活动变更通知-模板ID(小助手)
+	WxMsgTemplateIdActivitySign              string //查研观向活动签到通知-模板ID(小助手)
+
+	// 类目模板
+	WxCategoryMsgTemplateIdApplyXzs                  string //申请待处理(买方研选)
+	WxCategoryMsgTemplateIdActivitySign              string //买方研选活动签到通知-类目模板ID(买方研选)
+	WxMsgCategoryTemplateIdCompanyApprovalMessageRai string //权益销售签约成功通知买方研选类目模版消息通知-类目模板ID
+	WxMsgCategoryTemplateIdActivityPublishApply      string //买方研选关注的产业下,单个活动/研选报告发布通知-类目模板ID
+
 )
 
 // 微信公众号配置信息
@@ -90,7 +99,8 @@ var (
 
 // 模板消息推送
 var (
-	SendWxTemplateMsgUrl string
+	SendWxTemplateMsgUrl         string
+	SendWxCategoryTemplateMsgUrl string
 )
 
 func init() {
@@ -147,8 +157,9 @@ func init() {
 	SummaryArticleId = 1000000         //手动添加的纪要库开始ID
 	YanxSummaryPermissionId = 1001     //研选纪要分类ID
 	YanxViewpointPermissionId = 1002   //研选观点分类ID
-	WxMsgTemplateIdAskMsgMobileAll = "15557270714,18767183922,18621268829"
-	WxMsgTemplateIdAskMsgMobilePublic = "15557270714,18767183922,18621268829" // 沈涛:18767183922、 王芳:18621268829
+	WxMsgTemplateIdAskMsgMobileAll = "15557270714,18767183922,18621268829,17758061174"
+	WxMsgTemplateIdAskMsgMobilePublic = "15557270714,18767183922,18621268829,17758061174,18258485832,15000123056,15216736473,18701809782" // 沈涛:18767183922、 王芳:18621268829、葛琳18258485832、高亦文15000123056、董衡15216736473、吴昂迪和沈涛
+	WxMsgTemplateIdYXSpecialReview = "18621268829,18258485832,18767183922"                                                                // 王芳、葛琳和沈涛
 	HtgjDefaultSaleName = "王芳"
 	HtgjSalt = "HTGJ&HZ"
 	HtgjName = "海通国际"
@@ -180,6 +191,7 @@ func init() {
 		EmaiWhiteUserList = "tshen@hzinsights.com;cxzhang@hzinsights.com;yyli@hzinsights.com"                                                                 //白名单邮箱
 		WxMsgTemplateIdAskMsg = "PaoDanHGlt1kFw5q-4_ipJSwO3FyZpxSSNg4rwB7YCk"
 		WxMsgTemplateIdArticleUserRemind = "fxnlsjx-gm3dAZVJf6f3w27wA7anETl42kexXLP8FDs"
+		WxMsgCategoryTemplateIdArticleUserRemind = "4fwzgJ-YQndzH5OJWLkd0grvftgqhvP285t_oXUboi7DaaIhMI"
 		WxMsgTemplateIdAskMsgMobile = ""
 		//ActSendMsgMobile = "15618524605"
 		ActSendMsgMobile = "15557270714" // 汪洋手机号
@@ -187,6 +199,7 @@ func init() {
 
 		ShangHaiCrmApiLink = "https://crm.hzinsights.com/"
 		SendWxTemplateMsgUrl = "http://127.0.0.1:8086/v1/wechat/send_template_msg"
+		SendWxCategoryTemplateMsgUrl = "http://127.0.0.1:8086/v1/wechat/send_category_template_msg"
 		WxPayJsapiNotifyUrl = "https://mfyx.hzinsights.com/api/wechat/wxpay/notify"
 	} else {
 		WxAppId = "wx5e3240ab90c247ac"
@@ -200,6 +213,7 @@ func init() {
 
 		WxMsgTemplateIdActivityChange = "qfNuops-CB7bOl7f3viMG4s1uhRo7WM0Jbx3WvodKuIZ8A_z8fM"
 		WxMsgTemplateIdArticleUserRemind = "CB7bOl7f3viMG4s1uhRo7WM0Jbx3WvodKuIZ8A_z8fM"
+		WxMsgCategoryTemplateIdArticleUserRemind = "4fwzgJ-2xUiyQqNkFCPd8vsGpOnNWWE2inZO4BXjfio"
 
 		WxPublicAppId = "wx9b5d7291e581233a"
 		WxPublicAppSecret = "f4d52e34021eee262dce9682b31f8861"
@@ -217,12 +231,14 @@ func init() {
 		EmailExpert = "jhwang@hzinsights.com;cxzhang@hzinsights.com"      //研选行业专家邮箱
 		EmaiWhiteUserList = "cxzhang@hzinsights.com"
 		WxMsgTemplateIdAskMsg = "qfNuops-sKrfIkbA7U97A7gSrX03mUpoEpJksRUdloo"
-		WxMsgTemplateIdAskMsgMobile = "15557270714,17634786714,18767183922,17516315016"
+		WxMsgTemplateIdAskMsgMobile = "15557270714,17634786714,18767183922,17516315016,17758061174"
 		ActSendMsgMobile = "15557270714"
-		ArticleTaskClassMobile = "15557270714,18767183922,17706316791"
+		ArticleTaskClassMobile = "15557270714,18767183922,17706316791,17758061174"
 
 		ShangHaiCrmApiLink = "http://106.15.192.100:8100/"
 		SendWxTemplateMsgUrl = "http://127.0.0.1:8086/v1/wechat/send_template_msg"
+		SendWxCategoryTemplateMsgUrl = "http://127.0.0.1:8086/v1/wechat/send_category_template_msg"
+		//SendWxCategoryTemplateMsgUrl = "http://8.136.199.33:8086/v1/wechat/send_category_template_msg"
 		WxPayJsapiNotifyUrl = "https://testmfyx.hzinsights.com/api/wechat/wxpay/notify"
 	}
 
@@ -238,6 +254,12 @@ func init() {
 		TemplateIdByProductXzs = "-YjuPOB7Fqd-S3ilabYa6wvjDY9aXmeEfPN6DCiy-EY"                //产品运行报告通知-模板ID(小助手)
 		WxMsgTemplateIdActivityChangeApplyXzs = "CB7bOl7f3viMG4s1uhRo7WM0Jbx3WvodKuIZ8A_z8fM" //查研观向活动变更通知-模板ID(小助手)
 		WxMsgTemplateIdActivitySign = "3l5cxpqH6c9kkLe9ow7qzqd0uYEOdY3A_PB8wRWkiHk"           //查研观向活动签到通知-模板ID(小助手)
+
+		// 类目模版
+		WxCategoryMsgTemplateIdApplyXzs = "IemWOTzbnLBqJ2ozSiFqm13WjaotoC3V4uXaxTij08I"
+		WxCategoryMsgTemplateIdActivitySign = "aczgUYZASO97UJiCD_nDmD1eNWZAWudzw3JYcvjJ2x4"
+		WxMsgCategoryTemplateIdCompanyApprovalMessageRai = "wU4x_c5XruwuA44VZelyklRNOfq4XrU9ILckTtDs6hg" //权益销售签约成功通知买方研选类目模版消息通知-类目模板ID
+		WxMsgCategoryTemplateIdActivityPublishApply = "wLeV7tVK4ZJBoAvsmfXkHveVW8yefGAkwnVKQWRi8uQ"
 	} else {
 		//新的模板ID
 		WxPublicIdXzs = "wxb7cb8a15abad5b8e"                                                  //查研观向小助手
@@ -249,6 +271,12 @@ func init() {
 		TemplateIdByProductXzs = "tNcCUiK_uUkuxaFF7M9NP2RwLkw8uHFjG-TDIxGUKxo"                //产品运行报告通知-模板ID(小助手)
 		WxMsgTemplateIdActivityChangeApplyXzs = "7qe3i4MrGxAIPhJeMgoqqw6j0A_foUB65DLSmxKe05s" //查研观向活动变更通知-模板ID(小助手)
 		WxMsgTemplateIdActivitySign = "GIcOqewJql4rQ_dvhUna2knWIVogKulaqRxtZKnWZeo"           //查研观向活动签到通知-模板ID(小助手)
+
+		// 类目模版
+		WxCategoryMsgTemplateIdApplyXzs = "HKD03oZfSv8LJgeoHz0pynai3G2Ls4h8zZ6BfOpZmIA"
+		WxCategoryMsgTemplateIdActivitySign = "11rITVC5Gl8qwetxl92NqY887Uk14kg3nPtEA_i_zLo"
+		WxMsgCategoryTemplateIdCompanyApprovalMessageRai = "t1CcxcOkoZkWZrDRs6zYUlceBGYMV3mhkBYUa8a6Mx0" //权益销售签约成功通知买方研选类目模版消息通知-类目模板ID
+		WxMsgCategoryTemplateIdActivityPublishApply = "IBMqiE61lVgUfFM4rsH0XCH57R_G3PbWvRbnzg9JHPI"
 	}
 
 	//易董开放api配置

+ 13 - 5
utils/constants.go

@@ -11,6 +11,8 @@ const (
 	FormatDateTime         = "2006-01-02 15:04:05"     //完整时间格式
 	HlbFormatDateTime      = "2006-01-02_15:04:05.999" //完整时间格式
 	FormatDateTimeNoSecond = "2006-01-02 15:04"        //完整时间格式
+	FormatDateTimeMinute   = "2006/01/02 15:04"        //时间格式 年/月/日 时:分
+	FormatDateTimeMinute2  = "2006-01-02 15:04"        //时间格式 年-月-日 时:分
 	FormatDateTimeUnSpace  = "20060102150405"          //完整时间格式
 	FormatDateTimeInit     = "0000-00-00 00:00:00"     //为空的初始化时间格式
 	PageSize15             = 15                        //列表页每页数据量
@@ -39,7 +41,7 @@ const (
 )
 
 const (
-	APPNAME           = "弘则-买方研选"
+	APPNAME           = "弘则-买方研选小程序"
 	EmailSendToUsers  = "cxzhang@hzinsights.com"
 	EmailSendToExpert = "cxzhang@hzinsights.com"
 	DefaultHeadimgurl = "https://hzstatic.hzinsights.com/static/images/202401/20240103/u6Ykx23BMTnwtvYhZnJktgD54MLp.png"
@@ -202,9 +204,14 @@ const (
 	WX_MSG_PATH_APPLY_DETAIL             = "pages-message/applyFor/applyFor?id="                          //潜在用户试用权限申请
 	WX_MSG_PATH_YX_SURVEY_DETAIL         = "pages-purchaser/survey/surveyDetail?surveyId="                //用户提交研选调研需求
 	WX_MSG_PATH_APPLY_COLLECTION_DETAIL  = "reportPages/bulletinDetail/bulletinDetail?id="                //精选看板申请详情页
-	WX_MSG_PATH_YX_SPECIAL_DETAIL        = "pages-purchaser/noteAndViewpoint/noteAndViewpoint?id="        //研选专栏详情
-	WX_MSG_PATH_YX_SPECIAL_ENABLE_DETAIL = "pages-purchaser/toExamine/toExamine?isMessage=模板&id="         //研选专栏审核详情页面
-	WX_MSG_PATH_YX_SPECIAL_CENTER        = "pages-purchaser/contentAllPage/contentAllPage?Status=4"       //研选专栏内容中心
+
+	WX_MSG_PATH_YX_SPECIAL_DETAIL        = "pages-purchaser/noteAndViewpoint/noteAndViewpoint?id="  //研选专栏详情
+	WX_MSG_PATH_YX_SPECIAL_ENABLE_DETAIL = "pages-purchaser/toExamine/toExamine?isMessage=模板&id="   //研选专栏审核详情页面
+	WX_MSG_PATH_YX_SPECIAL_CENTER        = "pages-purchaser/contentAllPage/contentAllPage?Status=4" //研选专栏内容中心
+	WX_MSG_PATH_YX_COMMENT_DETAIL        = "pages-activity/generationAsk/generationAsk?id="         //研选报告留言详情
+	WX_MSG_PATH_YX_ACTIVITY_DETAIL       = "pages-activity/activityDetail/activityDetail?id="       //研选活动详情
+	WX_MSG_PATH_YX_SIGNUP_DETAIL         = "pages-message/activityTemplate/activityTemplate?id="    //研选报名详情
+	WX_MSG_PATH_YX_ARTICLE_DETAIL        = "pages-user/reportDetail/reportDetail?id="               //研选纪要详情
 )
 
 //2:文章详情  https://web.hzinsights.com/material/info/8436  小程序路径:/pageMy/reportDetail/reportDetail?id=
@@ -244,10 +251,11 @@ const (
 )
 
 const (
-	MobileShenTao       = "18767183922" //沈涛手机号
+	MobileShenTao       = "17758061174" //沈涛手机号18767183922
 	MobileZhangChuanXin = "15557270714" // 张传星手机号
 	MobileWangFang      = "18621268829" // 王芳手机号
 	MobileWuAngDi       = "18701809782" // 吴昂迪手机号
+	MobileDongHeng      = "15216736473" // 董衡手机号
 )
 
 const (