浏览代码

Merge branch 'cygx_12.2' of http://8.136.199.33:3000/hongze/hongze_cygx

xingzai 1 年之前
父节点
当前提交
cb35e06731

+ 70 - 4
controllers/activity.go

@@ -30,6 +30,7 @@ type ActivityNoLoginController struct {
 
 // @Title 活动类型列表
 // @Description活动类型列表接口
+// @Param   IsResearch   query   bool  true       "是否为研选"
 // @Success 200 {object} models.ActivityTypeListResp
 // @router /activityTypelist [get]
 func (this *ActivityCoAntroller) List() {
@@ -46,7 +47,14 @@ func (this *ActivityCoAntroller) List() {
 		return
 	}
 	resp := new(models.ActivityTypeListResp)
-	list, err := models.GetActivityTypeList()
+	isResearch, _ := this.GetBool("IsResearch", false)
+	var condition string
+
+	//是否仅展示研选下的活动类型
+	if isResearch {
+		condition = " AND source_type IN (0,2) "
+	}
+	list, err := models.GetActivityTypeList(condition)
 	if err != nil {
 		br.Msg = "获取失败"
 		br.ErrMsg = "获取数据失败,Err:" + err.Error()
@@ -679,6 +687,18 @@ func (this *ActivityCoAntroller) SignupAdd() {
 			br.Data = resp
 			return
 		}
+		//限制人数为1人的专家电话会 用户操作时的消息提示
+		if activityInfo.LimitPeopleNum == 1 && activityInfo.ActivityTypeId == 1 {
+			resp.HasPermission = hasPermission
+			resp.SignupStatus = utils.FULLSTARFFED_MSG
+			resp.PopupMsg = utils.ACTIVITY_ZJDHH_V1_MSG
+			br.Ret = 200
+			br.Success = true
+			br.Msg = ""
+			br.Data = resp
+			return
+		}
+
 		var sellerName string
 		sellerName, err = models.GetCompanySellerName(user.CompanyId)
 		if err != nil {
@@ -879,7 +899,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
@@ -1020,6 +1040,8 @@ func (this *ActivityCoAntroller) SignupCancel() {
 		go services.SendActivitieCancelSignTemplateMsg(user, activityInfo)
 	}
 
+	go services.SendResearchActivitiesTemplateMsg(user, activityInfo, "取消报名") //公司线下调研活动客户报名后给建会人,所属销售推送模板信息
+
 	go services.YanXuanActivityPointsBillSignupCancel(activityId, uid) // 用户取消报名添加到处理研选扣点
 	br.Ret = 200
 	br.Success = true
@@ -1058,7 +1080,7 @@ func (this *ActivityCoAntroller) GetUserSearchContent() {
 		detail = detailSeearch
 	}
 	isShowJurisdiction, _ := this.GetInt("IsShowJurisdiction")
-	listActivityType, errActivityType := models.GetActivityTypeList()
+	listActivityType, errActivityType := models.GetActivityTypeList("")
 	if errActivityType != nil {
 		br.Msg = "获取失败"
 		br.ErrMsg = "获取数据失败,Err:" + errActivityType.Error()
@@ -1218,6 +1240,19 @@ func (this *ActivityCoAntroller) MeetingReminderAdd() {
 	if havePower {
 		hasPermission = 1
 		signupStatus = "Success"
+
+		//限制人数为1人的专家电话会 用户操作时的消息提示
+		if activityInfo.LimitPeopleNum == 1 && activityInfo.ActivityTypeId == 1 {
+			resp.HasPermission = hasPermission
+			resp.SignupStatus = utils.FULLSTARFFED_MSG
+			resp.PopupMsg = utils.ACTIVITY_ZJDHH_V1_MSG
+			br.Ret = 200
+			br.Success = true
+			br.Msg = ""
+			br.Data = resp
+			return
+		}
+
 		totalMeeting, errMeeting := models.GetActivityMeetingReminderCount(uid, activityId)
 		if errMeeting != nil {
 			br.Msg = "获取失败"
@@ -1766,6 +1801,10 @@ func (this *ActivityCoAntroller) ActivityListNew() {
 	if activityTypeId == "undefined" {
 		activityTypeId = ""
 	}
+
+	if activityTypeId == "5" {
+		activityTypeId = "5,8" //专家线下沙龙可以查看买方线下交流
+	}
 	var startSize int
 	if pageSize <= 0 {
 		pageSize = utils.PageSize20
@@ -1938,7 +1977,7 @@ func (this *ActivityCoAntroller) ActivityListNew() {
 	}
 	//未开始进行中默认按照时间正序
 	if activeState == "1" || activeState == "1,2" || activeState == "" {
-		conditionOrder = ` ORDER BY art.activity_time ASC  `
+		conditionOrder = ` ORDER BY  art.top_time DESC , art.activity_time ASC  `
 	}
 	//conditionActivityKey += condition + conditionOrder
 	condition += conditionOrder
@@ -2184,6 +2223,17 @@ func (this *ActivityCoAntroller) CheckAsk() {
 	if havePower {
 		hasPermission = 1
 		signupStatus = "Success"
+		//限制人数为1人的专家电话会 用户操作时的消息提示
+		if activityInfo.LimitPeopleNum == 1 && activityInfo.ActivityTypeId == 1 {
+			resp.HasPermission = hasPermission
+			resp.SignupStatus = utils.FULLSTARFFED_MSG
+			resp.PopupMsg = utils.ACTIVITY_ZJDHH_V1_MSG
+			br.Ret = 200
+			br.Success = true
+			br.Msg = ""
+			br.Data = resp
+			return
+		}
 		resp.HaqveJurisdiction = true
 		resp.HasPermission = hasPermission
 		resp.SignupStatus = signupStatus
@@ -2392,6 +2442,11 @@ func (this *ActivityCoAntroller) LabelTypeListV5() {
 		if v.ActivityTypeId == 7 {
 			v.ActivityTypeId = 2
 		}
+
+		// 如果是买方线下交流的活动,合并到专家线下交流
+		if v.ActivityTypeId == 8 {
+			v.ActivityTypeId = 5
+		}
 		item := new(models.CygxActivityLabelList)
 		item.IsResearchPoints = activityPointsByUserAllMap[v.ActivityId]
 		item.City = mapCity[fmt.Sprint(v.KeyWord, "{|}", v.ActivityTypeId)]
@@ -3451,6 +3506,17 @@ func (this *ActivityCoAntroller) ActivityAppointmentAdd() {
 	if havePower {
 		hasPermission = 1
 		signupStatus = "Success"
+		//限制人数为1人的专家电话会 用户操作时的消息提示
+		if activityInfo.LimitPeopleNum == 1 && activityInfo.ActivityTypeId == 1 {
+			resp.HasPermission = hasPermission
+			resp.SignupStatus = utils.FULLSTARFFED_MSG
+			resp.PopupMsg = utils.ACTIVITY_ZJDHH_V1_MSG
+			br.Ret = 200
+			br.Success = true
+			br.Msg = ""
+			br.Data = resp
+			return
+		}
 		totalMeeting, errMeeting := models.GetUserCygxActivityAppointmentCount(uid, activityId)
 		if errMeeting != nil {
 			br.Msg = "获取失败"

+ 32 - 0
controllers/chart_permission.go

@@ -321,3 +321,35 @@ func (this *ChartPermissionAuthController) ReportDetailV7() {
 	br.Msg = "获取成功"
 	br.Data = resp
 }
+
+// @Title 获取报告医药、消费、科技、智造、策略权限列表(没有买方研选)
+// @Description 获取报告医药、消费、科技、智造、策略权限列表(没有买方研选)
+// @Success 200 {object} models.ChartPermissionResp
+// @router /noyx [get]
+func (this *ChartPermissionAuthController) Noyx() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	user := this.User
+	if user == nil {
+		br.Msg = "请重新登录"
+		br.Ret = 408
+		return
+	}
+	var condition string
+	condition += ` AND permission_name IN ('医药','消费','科技','智造','策略') `
+	list, err := models.GetChartPermissionReportAll(condition)
+	if err != nil {
+		br.Msg = "获取信息失败"
+		br.ErrMsg = "获取品种信息失败,Err:" + err.Error()
+		return
+	}
+	resp := new(models.ChartPermissionResp)
+	resp.List = list
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+	br.Data = resp
+}

+ 3 - 1
controllers/micro_roadshow.go

@@ -28,6 +28,7 @@ type MicroRoadShowController struct {
 // @Param   VideoIds			query	string		false	"视频IDs"
 // @Param   ActivityVideoId			query	int		false	"活动视频ID"
 // @Param   Filter			query	string		false	"筛选条件 为空:全部 1:视频 2:音频 3:逻辑解析 4:路演回放 多个用 , 隔开"
+// @Param   ChartPermissionIds   query   string  false     "行业id 多个用 , 隔开"
 // @Success 200 {object} models.HomeListResp
 // @router /list [get]
 func (this *MicroRoadShowController) List() {
@@ -53,6 +54,7 @@ func (this *MicroRoadShowController) List() {
 	activityVideoIds := this.GetString("ActivityVideoIds")
 	activityVideoId, _ := this.GetInt("ActivityVideoId")
 	filter := this.GetString("Filter")
+	chartPermissionIds := this.GetString("ChartPermissionIds")
 	if pageSize <= 0 {
 		pageSize = utils.PageSize20
 	}
@@ -74,7 +76,7 @@ func (this *MicroRoadShowController) List() {
 	var total int
 	var e error
 	// 微路演列表
-	list, total, e = services.GetMicroRoadShowPageListV8(pageSize, currentIndex, audioId, videoId, activityVideoId, filter, keywords, audioIds, videoIds, activityVideoIds)
+	list, total, e = services.GetMicroRoadShowPageListV8(pageSize, currentIndex, audioId, videoId, activityVideoId, filter, keywords, audioIds, videoIds, activityVideoIds, chartPermissionIds)
 	if e != nil {
 		br.Msg = "获取失败"
 		br.ErrMsg = "获取微路演列表失败, Err: " + e.Error()

+ 35 - 0
controllers/morning_meeting.go

@@ -1,6 +1,7 @@
 package controllers
 
 import (
+	"encoding/json"
 	"github.com/rdlucklib/rdluck_tools/paging"
 	"hongze/hongze_cygx/models"
 	"hongze/hongze_cygx/services"
@@ -193,3 +194,37 @@ func (this *MorningMeetingController) GatherDetail() {
 	br.Msg = "获取成功"
 	br.Data = resp
 }
+
+// @Title 晨会精华点击记录
+// @Description 晨会精华点击记录接口
+// @Param	request	body models.ArticleCollectResp true "type json string"
+// @Success 200
+// @router /history/add [post]
+func (this *MorningMeetingController) SpecialMsg() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	user := this.User
+	if user == nil {
+		br.Msg = "请重新登录"
+		br.Ret = 408
+		return
+	}
+	var req models.AddCygxMorningMeetingReviewChapterHistoryReq
+
+	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+	articleId := req.Id
+	sourcePage := req.SourcePage
+
+	go services.AddCygxMorningMeetingReviewChapterHistory(user, articleId, sourcePage)
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "操作成功!"
+}

+ 1 - 0
controllers/product_interior.go

@@ -132,6 +132,7 @@ func (this *ProductInteriorController) Detail() {
 		br.ErrMsg = "获取用户权限信息失败,Err:" + err.Error()
 	}
 	go services.AddCygxProductInteriorHistory(user, productInteriorId)
+	go services.ProductInteriorHistoryUserRmind(user, productInteriorId)
 	br.Ret = 200
 	br.Success = true
 	br.Msg = "获取成功"

+ 18 - 0
controllers/report.go

@@ -544,14 +544,22 @@ func (this *ReportController) List() {
 			imgUrlChart = vslice[len(vslice)-1]
 			mapCategoryUrl[categoryIdStr] = imgUrlChart
 		}
+		var articleIds []int
 		lenList := len(list)
 		for i := 0; i < lenList; i++ {
 			item := list[i]
 			list[i].Body, _ = services.GetReportContentTextSub(item.Body)
 			//list[i].Abstract = html.UnescapeString(item.Abstract)
 			list[i].Abstract, _ = services.GetReportContentTextSub(item.Abstract)
+
+			if item.Resource == 1 {
+				articleIds = append(articleIds, item.ArticleId)
+			}
 		}
 
+		articleMapPv := services.GetArticleHistoryByArticleId(articleIds)                       //文章Pv
+		articleCollectMap, _ := services.GetCygxArticleCollectMap(user.UserId)                  //用户收藏的文章
+		articleCollectNumMap, _ := services.GetCygxArticleCollectNumMapByArtcileIds(articleIds) //文章收藏的数量
 		for k, v := range list {
 			if v.Readnum == 0 && user.CreatedTime.Before(utils.StrTimeToTime(v.PublishDate)) && utils.StrTimeToTime(utils.OnlineTime).Before(utils.StrTimeToTime(v.PublishDate)) {
 				list[k].IsRed = true
@@ -560,6 +568,12 @@ func (this *ReportController) List() {
 				list[k].IsHaveVideo = true
 			}
 			list[k].ImgUrlPc = mapCategoryUrl[v.CategoryId]
+
+			if v.Resource == 1 {
+				v.Pv = articleMapPv[v.ArticleId]
+				v.IsCollect = articleCollectMap[v.ArticleId]
+				v.CollectNum = articleCollectNumMap[v.ArticleId]
+			}
 			if v.Resource == 2 {
 				v.PublishDate = utils.TimeRemoveHms2(v.PublishDate)
 			}
@@ -1893,6 +1907,8 @@ func (this *ReportController) ResearchDetail() {
 	//	historyRecord.SellerName = sellerItem.RealName
 	//}
 	//go models.AddCygxReportHistoryRecord(historyRecord)
+
+	go services.ResearchSummaryHistoryUserRmind(user, articleId) // 本周研究汇总用户阅读操作操作行为,模板消息推送
 	resp.List = listFirst
 	resp.Detail = detail
 	br.Ret = 200
@@ -2041,6 +2057,8 @@ func (this *ReportController) MinutesDetailV4() {
 	//	historyRecord.SellerName = sellerItem.RealName
 	//}
 	//go models.AddCygxReportHistoryRecord(historyRecord)
+
+	go services.MinutesSummaryHistoryUserRmind(user, articleId) // 上周纪要汇总用户阅读,给销售发消息提醒
 	resp.List = listFirst
 	resp.Detail = detail
 	br.Ret = 200

+ 8 - 1
controllers/report_billboard.go

@@ -8,7 +8,7 @@ import (
 	"time"
 )
 
-//报告榜单
+// 报告榜单
 type ReportBillboardController struct {
 	BaseAuthController
 }
@@ -341,6 +341,10 @@ func (this *ReportBillboardController) ReadList() {
 		articleIds = append(articleIds, list[i].ArticleId)
 	}
 
+	articleMapPv := services.GetArticleHistoryByArticleId(articleIds)                       //文章Pv
+	articleCollectMap, _ := services.GetCygxArticleCollectMap(user.UserId)                  //用户收藏的文章
+	articleCollectNumMap, _ := services.GetCygxArticleCollectNumMapByArtcileIds(articleIds) //文章收藏的数量
+
 	// 报告关联产业信息
 	industryMap := make(map[int][]*models.IndustrialManagementIdInt, 0)
 	if len(articleIds) > 0 {
@@ -369,6 +373,9 @@ func (this *ReportBillboardController) ReadList() {
 		} else {
 			list[k].List = make([]*models.IndustrialManagementIdInt, 0)
 		}
+		v.Pv = articleMapPv[v.ArticleId]
+		v.IsCollect = articleCollectMap[v.ArticleId]
+		v.CollectNum = articleCollectNumMap[v.ArticleId]
 	}
 
 	resp := new(models.ArticleReportBillboardLIstResp)

+ 2 - 0
controllers/search.go

@@ -692,8 +692,10 @@ func (this *SearchController) ListHomeArtAndChartPage() {
 		result = make([]*models.SearchItem, 0)
 	} else {
 		yxArticleIdMap := services.GetYxArticleIdMap(articleIds)
+		articleMapPv := services.GetArticleHistoryByArticleId(articleIds) //文章Pv
 		for _, v := range result {
 			v.IsResearch = yxArticleIdMap[v.ArticleId] // 添加是否属于研选的标识
+			v.Pv = articleMapPv[v.ArticleId]           // Pv
 		}
 	}
 	page := paging.GetPaging(currentIndex, pageSize, int(total))

+ 12 - 1
controllers/tactics.go

@@ -86,7 +86,8 @@ func (this *TacticsController) List() {
 		}
 	}
 	ArticleHistoryMap := services.GetArticleHistoryByUser(articleIds, user)
-	ProductInteriorHistoryMap := services.GetCygxProductInteriorHistoryListMap(articleIds, user)
+	ProductInteriorHistoryMap := services.GetCygxProductInteriorHistoryListMap(productInteriorIs, user)
+	productInteriorMapPv := services.GetCygxProductInteriorHistoryListPvMap(productInteriorIs) //产品内测Pv
 	for k, v := range list {
 		if v.Resource == 1 {
 			if ArticleHistoryMap[v.ArticleId] == 0 && user.CreatedTime.Before(utils.StrTimeToTime(v.PublishDate)) && utils.StrTimeToTime(utils.OnlineTime).Before(utils.StrTimeToTime(v.PublishDate)) {
@@ -112,9 +113,19 @@ func (this *TacticsController) List() {
 		}
 	}
 
+	articleMapPv := services.GetArticleHistoryByArticleId(articleIds)                       //文章Pv
+	articleCollectMap, _ := services.GetCygxArticleCollectMap(user.UserId)                  //用户收藏的文章
+	articleCollectNumMap, _ := services.GetCygxArticleCollectNumMapByArtcileIds(articleIds) //文章收藏的数量
+
 	for _, v := range list {
+		if v.Resource == 1 {
+			v.Pv = articleMapPv[v.ArticleId]
+			v.IsCollect = articleCollectMap[v.ArticleId]
+			v.CollectNum = articleCollectNumMap[v.ArticleId]
+		}
 		if v.Resource == 2 {
 			v.PublishDate = utils.TimeRemoveHms2(v.PublishDate)
+			v.Pv = productInteriorMapPv[v.ArticleId]
 		}
 	}
 	resp.List = list

+ 2 - 1
models/activity.go

@@ -239,6 +239,7 @@ type ActivityDetail struct {
 	ImgUrlBgYx                string                     `description:"研选背景图片"`
 	CancelDeadline            string                     `description:"取消报名截止时间"`
 	ChartPermissionNameDeputy string                     `description:"副行业名称"`
+	TopTime                   int                        `description:"置顶时间"`
 }
 type ListArticleActivity struct {
 	Title   string `description:"文章标题"`
@@ -555,7 +556,7 @@ func UpdateActivitySattusToHaveInHand() (err error) {
 	sqlOr = condition
 	condition += ` AND (activity_type_id IN ( 1, 2, 3, 7 ) AND  activity_time > ` + "'" + resultTime_30 + "'" + ")"
 	condition += ` OR(activity_type_id IN ( 4, 5, 6, 8 ) AND  activity_time > ` + "'" + resultTime_60 + "'" + sqlOr + ")"
-	msql := " UPDATE cygx_activity SET active_state = 2 WHERE 1 = 1 " + condition
+	msql := " UPDATE cygx_activity SET active_state = 2, top_time = 0  WHERE 1 = 1 " + condition
 	_, err = o.Raw(msql).Exec()
 	return
 }

+ 3 - 3
models/activity_type.go

@@ -6,7 +6,7 @@ import (
 
 type ActivityType struct {
 	ActivityTypeId   int    `description:"活动类型id"`
-	ActivityTypeName string `description:"活动名称"`
+	ActivityTypeName string `description:"活动类型名称"`
 	//TemplateP        string `description:"活动模板,带P标签"`
 	//Template         string `description:"活动模板"`
 	ShowType  string `description:"人数限制类型,1不展示限制,2可选限制,3强制限制"`
@@ -19,9 +19,9 @@ type ActivityTypeListResp struct {
 }
 
 // 列表
-func GetActivityTypeList() (items []*ActivityType, err error) {
+func GetActivityTypeList(condition string) (items []*ActivityType, err error) {
 	o := orm.NewOrm()
-	sql := `SELECT * FROM cygx_activity_type ORDER BY sort DESC`
+	sql := `SELECT * FROM cygx_activity_type WHERE 1= 1  ` + condition + `  ORDER BY sort DESC`
 	_, err = o.Raw(sql).QueryRows(&items)
 	return
 }

+ 4 - 0
models/article.go

@@ -424,6 +424,10 @@ type ReportArticle struct {
 	CategoryId       string `description:"文章分类"`
 	Annotation       string `description:"核心观点"`
 	Resource         int    `description:"来源类型,1:文章、2:产品内测"`
+	MyCollectNum     int    `description:"本人是否收藏"`
+	IsCollect        bool   `description:"本人是否收藏"`
+	Pv               int    `description:"PV"`
+	CollectNum       int    `description:"收藏人数"`
 }
 
 type ReportMappingCategoryRep struct {

+ 12 - 0
models/article_collect.go

@@ -160,6 +160,18 @@ func GetArticleCollectNum(articleId []string, uid int) (items []*CygxArticleNum,
 	return
 }
 
+// GetArticleCollectNum 根据文章ID获取收藏数量的列表
+func GetArticleCollectListNum(articleIds []int) (items []*CygxArticleNum, err error) {
+	lenArr := len(articleIds)
+	if lenArr == 0 {
+		return
+	}
+	sql := `SELECT  COUNT(1) as collect_num , article_id  FROM cygx_article_collect  WHERE   article_id IN  (` + utils.GetOrmInReplace(lenArr) + `)   GROUP BY article_id `
+	o := orm.NewOrm()
+	_, err = o.Raw(sql, articleIds).QueryRows(&items)
+	return
+}
+
 type MicroRoadshowCollectList struct {
 	AudioIds         string
 	VideoIds         string

+ 22 - 0
models/article_history_record_newpv.go

@@ -302,3 +302,25 @@ func GetCygxArticleHistoryRecordNewpvList(condition string, pars []interface{})
 	_, err = o.Raw(sql, pars).QueryRows(&items)
 	return
 }
+
+type ListPvUvResp struct {
+	ArticleId int `description:"文章ID"`
+	Pv        int `description:"pv"`
+	Uv        int `description:"pv"`
+}
+
+// 列表
+func GetCygxArticleHistoryRecordNewpvListPv(condition string, pars []interface{}) (items []*ListPvUvResp, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT
+			COUNT( 1 ) AS pv,
+			article_id
+		FROM
+			cygx_article_history_record_newpv  WHERE 1 = 1  `
+	if condition != "" {
+		sql += condition
+	}
+	sql += ` GROUP BY article_id `
+	_, err = o.Raw(sql, pars).QueryRows(&items)
+	return
+}

+ 8 - 0
models/cygx_morning_meeting_review_chapter.go

@@ -20,6 +20,14 @@ type CygxMorningMeetingReviewChapter struct {
 	Content              string    `json:"content"`             // 内容
 }
 
+// 通过ID获取详情
+func GetCygxMorningMeetingReviewChapterDetail(id int) (item *CygxMorningMeetingReviewChapter, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT * FROM cygx_morning_meeting_review_chapter  WHERE id =? `
+	err = o.Raw(sql, id).QueryRow(&item)
+	return
+}
+
 // 列表
 func GetCygxMorningMeetingReviewChapterList(condition string, pars []interface{}) (items []*CygxMorningMeetingGatherDetailListResp, err error) {
 	o := orm.NewOrm()

+ 1 - 0
models/db.go

@@ -179,6 +179,7 @@ func init() {
 		new(CygxYanxuanSpecialCompany),
 		new(CygxQuestionnaireVote),
 		new(CygxQuestionnaireVoteOtherTheme),
+		new(CygxMorningMeetingReviewChapterHistory),
 	)
 	// 记录ORM查询日志
 	orm.Debug = true

+ 36 - 0
models/morning_meeting_review_chapter_history.go

@@ -0,0 +1,36 @@
+package models
+
+import (
+	"github.com/beego/beego/v2/client/orm"
+	"time"
+)
+
+type CygxMorningMeetingReviewChapterHistory struct {
+	Id               int       `orm:"column(id);pk"`
+	ArticleId        int       `description:"文章ID"`
+	UserId           int       `description:"用户ID"`
+	CreateTime       time.Time `description:"创建时间"`
+	Mobile           string    `description:"手机号"`
+	Email            string    `description:"邮箱"`
+	CompanyId        int       `description:"公司id"`
+	CompanyName      string    `description:"公司名称"`
+	RealName         string    `description:"用户实际名称"`
+	SellerName       string    `description:"所属销售"`
+	SourcePage       string    `description:"页面来源 微信、首页、展开"`
+	RegisterPlatform int       `description:"来源 1小程序,2:网页"`
+	ModifyTime       time.Time `description:"更新时间"`
+	MeetingId        int       `description:"晨会精华主表ID"`
+}
+
+type AddCygxMorningMeetingReviewChapterHistoryReq struct {
+	Id         int    `description:"晨会精华ID"`
+	SourcePage string `description:"页面来源 微信、首页、展开"`
+}
+
+// 添加历史信息
+func AddCygxMorningMeetingReviewChapterHistory(item *CygxMorningMeetingReviewChapterHistory) (lastId int64, err error) {
+	o := orm.NewOrm()
+	item.ModifyTime = time.Now()
+	lastId, err = o.Insert(item)
+	return
+}

+ 1 - 0
models/product_interior.go

@@ -54,6 +54,7 @@ type CygxProductInteriorResp struct {
 	VisibleRange      int                       `description:"设置可见范围1全部,0内部"`
 	Abstract          string                    `description:"摘要"`
 	Department        string                    `description:"作者"`
+	Pv                int                       `description:"PV"`
 }
 
 type ProductInteriorUrlResp struct {

+ 30 - 2
models/product_interior_history.go

@@ -27,13 +27,41 @@ func AddCygxProductInteriorHistory(item *CygxProductInteriorHistory) (lastId int
 	return
 }
 
+type ListProductInteriorPvUvResp struct {
+	ProductInteriorId int `description:"文章ID"`
+	Pv                int `description:"pv"`
+	Uv                int `description:"pv"`
+}
+
+// 列表
+func GetCygxProductInteriorHistoryList(condition string, pars []interface{}) (items []*ListProductInteriorPvUvResp, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT
+			COUNT( 1 ) AS pv,
+			product_interior_id
+		FROM
+			cygx_product_interior_history  WHERE 1 = 1  `
+	if condition != "" {
+		sql += condition
+	}
+	sql += ` GROUP BY product_interior_id `
+	_, err = o.Raw(sql, pars).QueryRows(&items)
+	return
+}
+
+type ListProductInteriorPvResp struct {
+	ProductInteriorId int `description:"文章ID"`
+	Pv                int `description:"pv"`
+}
+
 // 列表
-func GetCygxProductInteriorHistoryList(condition string, pars []interface{}) (items []*CygxProductInteriorHistory, err error) {
+func GetCygxProductInteriorHistoryListPv(condition string, pars []interface{}) (items []*ListProductInteriorPvResp, err error) {
 	o := orm.NewOrm()
-	sql := `SELECT * FROM cygx_product_interior_history as art WHERE 1= 1 `
+	sql := `SELECT  product_interior_id ,COUNT(*)  as  pv  FROM cygx_product_interior_history WHERE 1= 1 `
 	if condition != "" {
 		sql += condition
 	}
+	sql += " GROUP BY product_interior_id "
 	_, err = o.Raw(sql, pars).QueryRows(&items)
 	return
 }

+ 17 - 0
models/report_history_record.go

@@ -56,3 +56,20 @@ func AddCygxReportHistoryRecordLog(item *CygxReportHistoryRecordLog) (lastId int
 	lastId, err = o.Insert(item)
 	return
 }
+
+type ListPvResp struct {
+	ArticleId int `description:"文章ID"`
+	Pv        int `description:"pv"`
+}
+
+// 列表
+func GetCygxReportHistoryRecordListPv(condition string, pars []interface{}) (items []*ListPvResp, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT  article_id ,COUNT(*)  as  pv  FROM cygx_report_history_record WHERE 1= 1 `
+	if condition != "" {
+		sql += condition
+	}
+	sql += " GROUP BY article_id "
+	_, err = o.Raw(sql, pars).QueryRows(&items)
+	return
+}

+ 1 - 0
models/report_selection.go

@@ -18,6 +18,7 @@ type CygxReportSelectionRep struct {
 	SubjectName       string `description:"标的名称"`
 	Periods           string `description:"期数"`
 	MarketStrategy    string `description:"市场策略核心逻辑汇总"`
+	Pv                int    `description:"pv"`
 }
 
 type CygxReportSelectionListPublicRep struct {

+ 1 - 0
models/search.go

@@ -16,6 +16,7 @@ type SearchItem struct {
 	Source           int      `description:"来源  1:文章, 2:图表"`
 	IsNeedJump       bool     `description:"是否需要跳转链接地址"`
 	IsResearch       bool     `description:"是否属于研选"`
+	Pv               int      `description:"Pv"`
 }
 
 type CategoryItem struct {

+ 0 - 5
models/wx_template_msg.go

@@ -31,11 +31,6 @@ func GetOpenIdList() (items []*OpenIdList, err error) {
 }
 
 func GetWxOpenIdByMobileList(mobile string) (items []*OpenIdList, err error) {
-	//sql := `SELECT * FROM user_record WHERE bind_account IN (` + utils.WxMsgTemplateIdAskMsgMobile + `) AND create_platform = 1`
-	//sql := `SELECT cr.*,user_id FROM user_record  as c
-	//		INNER JOIN cygx_user_record AS cr ON cr.union_id = c.union_id
-	//		WHERE bind_account IN (` + mobile + `) AND create_platform = 4`
-
 	sql := ` SELECT
 				union_id,open_id,
 				cygx_user_id AS user_id

+ 18 - 0
routers/commentsRouter.go

@@ -655,6 +655,15 @@ func init() {
             Filters: nil,
             Params: nil})
 
+    beego.GlobalControllerRouter["hongze/hongze_cygx/controllers:ChartPermissionAuthController"] = append(beego.GlobalControllerRouter["hongze/hongze_cygx/controllers:ChartPermissionAuthController"],
+        beego.ControllerComments{
+            Method: "Noyx",
+            Router: `/noyx`,
+            AllowHTTPMethods: []string{"get"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
     beego.GlobalControllerRouter["hongze/hongze_cygx/controllers:ChartPermissionAuthController"] = append(beego.GlobalControllerRouter["hongze/hongze_cygx/controllers:ChartPermissionAuthController"],
         beego.ControllerComments{
             Method: "ReportDetail",
@@ -889,6 +898,15 @@ func init() {
             Filters: nil,
             Params: nil})
 
+    beego.GlobalControllerRouter["hongze/hongze_cygx/controllers:MorningMeetingController"] = append(beego.GlobalControllerRouter["hongze/hongze_cygx/controllers:MorningMeetingController"],
+        beego.ControllerComments{
+            Method: "SpecialMsg",
+            Router: `/history/add`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
     beego.GlobalControllerRouter["hongze/hongze_cygx/controllers:ProductInteriorController"] = append(beego.GlobalControllerRouter["hongze/hongze_cygx/controllers:ProductInteriorController"],
         beego.ControllerComments{
             Method: "Detail",

+ 4 - 1
services/activity_points.go

@@ -938,10 +938,13 @@ func YanXuanCompanyApprovalReduce(log models.YanXuanActivityPointsRedis) (err er
 
 	var billDetailed float64
 	var content string
-	//ExpensiveYx               int       `description:"权益研选: 0->3w; 1->5w"` 3W3次、5W 15次
+	//ExpensiveYx               int       `description:"权益研选: 0->3w; 1->5w;2->10W"` 3W3次、5W 15次,20w:40次 ,
 	if companyReportPermissionDetail.ExpensiveYx == 1 {
 		billDetailed = 15
 		content = "买方研选(5W)转正"
+	} else if companyReportPermissionDetail.ExpensiveYx == 2 {
+		billDetailed = 40
+		content = "买方研选(10w)转正"
 	} else {
 		billDetailed = 3
 		content = "买方研选(3W)转正"

+ 9 - 9
services/activity_wx_template_msg.go

@@ -10,7 +10,7 @@ import (
 )
 
 // SendResearchActivitiesTemplateMsg 线下调研活动报名给所属销售跟建会人员推送
-func SendResearchActivitiesTemplateMsg(user *models.WxUserItem, activityDetail *models.ActivityDetail) (err error) {
+func SendResearchActivitiesTemplateMsg(user *models.WxUserItem, activityDetail *models.ActivityDetail, doStatus string) (err error) {
 	//如果不是公司线下调研就返回
 	if activityDetail.ActivityTypeId != 4 {
 		return
@@ -47,12 +47,12 @@ func SendResearchActivitiesTemplateMsg(user *models.WxUserItem, activityDetail *
 	var remark string
 	var redirectUrl string
 
-	first = "【" + activityDetail.ActivityName + "】有客户报名"
-	keyword1 = user.RealName + "——" + user.CompanyName + "(所属销售:" + sellerItem.RealName + ")"
+	//first = "【" + activityDetail.ActivityName + "】有客户报名"
+	keyword1 = user.RealName + "——" + user.CompanyName + "(" + sellerItem.RealName + ")"
 	keyword2 = user.Mobile
 	keyword3 = time.Now().Format(utils.FormatDateTime)
-	keyword4 = activityDetail.ActivityName
-	remark = "点击查看报告详情"
+	keyword4 = doStatus + ":" + activityDetail.ActivityName
+	//remark = "点击查看报告详情"
 
 	openIdList, e := models.GetWxOpenIdByMobileSliceList(mobiles)
 	if e != nil {
@@ -174,10 +174,10 @@ func SendActivitieCancelSignTemplateMsg(user *models.WxUserItem, activityDetail
 		err = errors.New("GetUserRecordListByMobile, Err: " + e.Error() + cnf.ConfigValue)
 		return
 	}
-	keyword1 := user.RealName + "--" + user.CompanyName + "(" + sellerItemQy.RealName +")"
+	keyword1 := user.RealName + "--" + user.CompanyName + "(" + sellerItemQy.RealName + ")"
 	keyword2 := user.Mobile
 	keyword3 := time.Now().Format(utils.FormatDateTime)
-	keyword4 := "取消报名" + "【" +activityDetail.ActivityName+"】"
+	keyword4 := "取消报名" + "【" + activityDetail.ActivityName + "】"
 	openIdArr := make([]string, 0)
 	for _, v := range openIdList {
 		openIdArr = append(openIdArr, v.OpenId)
@@ -219,10 +219,10 @@ func SendNeiRongZuActivitieSignTemplateMsg(user *models.WxUserItem, activityDeta
 		err = errors.New("GetUserRecordListByMobile, Err: " + e.Error() + cnf.ConfigValue)
 		return
 	}
-	keyword1 := user.RealName + "--" + user.CompanyName + "(" + sellerItemQy.RealName +")"
+	keyword1 := user.RealName + "--" + user.CompanyName + "(" + sellerItemQy.RealName + ")"
 	keyword2 := user.Mobile
 	keyword3 := time.Now().Format(utils.FormatDateTime)
-	keyword4 := "报名"  + "【" +activityDetail.ActivityName+"】"
+	keyword4 := "报名" + "【" + activityDetail.ActivityName + "】"
 	openIdArr := make([]string, 0)
 	for _, v := range openIdList {
 		openIdArr = append(openIdArr, v.OpenId)

+ 29 - 2
services/article_history.go

@@ -25,13 +25,40 @@ func GetArticleHistoryByUser(articleIds []int, user *models.WxUserItem) (mapResp
 	var pars []interface{}
 	condition = ` AND article_id IN (` + utils.GetOrmInReplace(lenIds) + `) AND  user_id = ?`
 	pars = append(pars, articleIds, user.UserId)
-	list, err := models.GetCygxArticleHistoryRecordNewpvList(condition, pars)
+	list, err := models.GetCygxArticleHistoryRecordNewpvListPv(condition, pars)
 	if err != nil {
 		return
 	}
 	mapResp = make(map[int]int, 0)
 	for _, v := range list {
-		mapResp[v.ArticleId]++
+		mapResp[v.ArticleId] = v.Pv
+	}
+	return
+}
+
+func GetArticleHistoryByArticleId(articleIds []int) (mapResp map[int]int) {
+	var err error
+	defer func() {
+		if err != nil {
+			fmt.Println(err)
+			go utils.SendAlarmMsg("获取用户的阅读数据,信息失败,Err:"+err.Error(), 3)
+		}
+	}()
+	lenIds := len(articleIds)
+	if lenIds == 0 {
+		return
+	}
+	var condition string
+	var pars []interface{}
+	condition = ` AND article_id IN (` + utils.GetOrmInReplace(lenIds) + `) `
+	pars = append(pars, articleIds)
+	list, err := models.GetCygxArticleHistoryRecordNewpvListPv(condition, pars)
+	if err != nil {
+		return
+	}
+	mapResp = make(map[int]int, 0)
+	for _, v := range list {
+		mapResp[v.ArticleId] = v.Pv
 	}
 	return
 }

+ 23 - 0
services/articlt_collect.go

@@ -2,6 +2,7 @@ package services
 
 import (
 	"errors"
+	"fmt"
 	"hongze/hongze_cygx/models"
 	"hongze/hongze_cygx/utils"
 )
@@ -31,3 +32,25 @@ func GetCygxArticleCollectMap(userId int) (mapResp map[int]bool, err error) {
 	}
 	return
 }
+
+// GetCygxArticleCollectNumMapByArtcileIds 根据文章ID获取对应文章被收藏的数量
+func GetCygxArticleCollectNumMapByArtcileIds(articleIds []int) (mapResp map[int]int, err error) {
+	defer func() {
+		if err != nil {
+			go utils.SendAlarmMsg("根据文章ID获取对应文章被收藏的数量  GetCygxArticleCollectNumMapByArtcileIds ErrMsg:"+err.Error()+fmt.Sprint(articleIds), 2)
+
+		}
+	}()
+	list, e := models.GetArticleCollectListNum(articleIds)
+	if e != nil && e.Error() != utils.ErrNoRow() {
+		err = errors.New("GetArticleCollectListNum " + e.Error())
+		return
+	}
+	mapResp = make(map[int]int, 0)
+	if len(list) > 0 {
+		for _, v := range list {
+			mapResp[v.ArticleId] = v.CollectNum
+		}
+	}
+	return
+}

+ 9 - 1
services/micro_roadshow.go

@@ -165,7 +165,7 @@ func GetHomeNewestList(userId, companyId, startSize, pageSize int, condition str
 }
 
 // GetMicroRoadShowPageList 获取微路演列表添加活动视频 更新与8.1版本
-func GetMicroRoadShowPageListV8(pageSize, currentIndex, audioId, videoId, activityVideoId int, filter, keywords, audioIds, videoIds, activityVideoIds string) (respList []*models.MicroRoadShowPageList, total int, err error) {
+func GetMicroRoadShowPageListV8(pageSize, currentIndex, audioId, videoId, activityVideoId int, filter, keywords, audioIds, videoIds, activityVideoIds, chartPermissionIds string) (respList []*models.MicroRoadShowPageList, total int, err error) {
 	var e error
 	// 根据每页数据量获取音视频配比
 	startSize := utils.StartIndex(currentIndex, pageSize)
@@ -204,6 +204,7 @@ func GetMicroRoadShowPageListV8(pageSize, currentIndex, audioId, videoId, activi
 		idSqlStr = strings.TrimRight(idSqlStr, ",")
 		audioCond += ` AND a.activity_voice_id IN (` + idSqlStr + `)`
 	}
+
 	//}
 	//视频的处理
 	var videoCond string
@@ -273,6 +274,13 @@ func GetMicroRoadShowPageListV8(pageSize, currentIndex, audioId, videoId, activi
 		videoCond += ` AND video_id IN (` + idSqlStr + `)`
 	}
 	videoCond += ` AND publish_status = 1`
+
+	if chartPermissionIds != "" {
+		videoCond += ` AND chart_permission_id IN (` + chartPermissionIds + `)`
+		audioCond += ` AND b.chart_permission_id IN (` + chartPermissionIds + `)`
+		videoCondAct += ` AND art.chart_permission_id IN (` + chartPermissionIds + `)`
+	}
+
 	//}
 	total, videoList, e = models.GetMicroRoadShowVideoPageListV8(startSize, pageSize, videoCond, videoPars, videoCondAct, videoParsAct, audioCond, audioPars)
 	if e != nil {

+ 87 - 0
services/minutes_summary.go

@@ -0,0 +1,87 @@
+package services
+
+import (
+	"errors"
+	"fmt"
+	"hongze/hongze_cygx/models"
+	"hongze/hongze_cygx/utils"
+	"strconv"
+	"time"
+)
+
+// 上周纪要汇总用户阅读,给销售发消息提醒
+func MinutesSummaryHistoryUserRmind(user *models.WxUserItem, articleId int) (err error) {
+	//30秒内阅读同一篇报告不做重复推送
+	key := "CYGX_" + utils.CYGX_OBJ_MINUTESSUMMARY + "_READ" + strconv.Itoa(articleId) + "_" + strconv.Itoa(user.UserId)
+	if utils.Rc.IsExist(key) {
+		return
+	}
+	utils.Rc.Put(key, 1, 30*time.Second)
+	defer func() {
+		if err != nil {
+			go utils.SendAlarmMsg(fmt.Sprint("上周纪要汇总用户阅读,给销售发消息提醒,模板消息推送 ,MinutesSummaryHistoryUserRmind"+err.Error(), "userId:", user.UserId, "articleId:", articleId), 2)
+		}
+	}()
+	countUser, err := models.GetUserRemind(user.UserId)
+	if err != nil {
+		return err
+	}
+	if countUser == 0 {
+		return err
+	}
+	var first string
+	var keyword1 string
+	var keyword2 string
+	var keyword3 string
+	var keyword4 string
+	var remark 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
+		}
+		detail, e := models.GetCygxMinutesSummaryInfoById(articleId)
+		if e != nil {
+			err = errors.New("GetCygxProductInteriorDetail, Err: " + e.Error())
+			return
+		}
+		if detail == nil {
+			return
+		}
+		keyword1 = detail.Title
+		keyword2 = fmt.Sprint("互动:阅读报告,", user.RealName, "--", user.CompanyName)
+		openIdArr := make([]string, 0)
+		for _, v := range openIdList {
+			openIdArr = append(openIdArr, v.OpenId)
+		}
+		redirectUrl := utils.WX_MSG_PATH_LAST_WEEK_DETAIL + strconv.Itoa(articleId)
+		sendInfo := new(SendWxTemplate)
+		sendInfo.First = first
+		sendInfo.Keyword1 = keyword1
+		sendInfo.Keyword2 = keyword2
+		sendInfo.Keyword3 = keyword3
+		sendInfo.Keyword4 = keyword4
+		sendInfo.Remark = remark
+		sendInfo.TemplateId = utils.WxMsgTemplateIdArticleUserRemind
+		sendInfo.RedirectUrl = redirectUrl
+		sendInfo.RedirectTarget = 3
+		sendInfo.Resource = strconv.Itoa(articleId)
+		sendInfo.SendType = utils.TEMPLATE_MSG_CYGX_ARTICLE_ADD
+		sendInfo.OpenIdArr = openIdArr
+		e = PublicSendTemplateMsg(sendInfo)
+		if e != nil {
+			err = errors.New("PublicSendTemplateMsg, Err: " + e.Error())
+			return
+		}
+	}
+	return
+}

+ 40 - 0
services/morning_meeting.go

@@ -2,6 +2,7 @@ package services
 
 import (
 	"context"
+	"errors"
 	"fmt"
 	"hongze/hongze_cygx/models"
 	"hongze/hongze_cygx/utils"
@@ -70,5 +71,44 @@ func MakeMorningMeetingReviews(cont context.Context) (err error) {
 	item.Status = 1
 	err = models.AddCygxMorningMeetingGather(item)
 	return
+}
 
+// 添加晨会点评点击记录
+func AddCygxMorningMeetingReviewChapterHistory(user *models.WxUserItem, articleId int, sourcePage string) (err error) {
+	defer func() {
+		if err != nil {
+			go utils.SendAlarmMsg(fmt.Sprint("添加晨会点评点击记录失败 ,AddCygxMorningMeetingReviewChapterHistory err"+err.Error(), "id:", articleId, "sourcePage:", sourcePage, "userid:", user.UserId), 2)
+		}
+	}()
+	detail, e := models.GetCygxMorningMeetingReviewChapterDetail(articleId)
+	if e != nil {
+		err = errors.New("GetCygxMorningMeetingReviewChapterDetail, Err: " + e.Error())
+		return
+	}
+	historyRecord := new(models.CygxMorningMeetingReviewChapterHistory)
+	historyRecord.UserId = user.UserId
+	historyRecord.ArticleId = articleId
+	historyRecord.SourcePage = sourcePage
+	historyRecord.CreateTime = time.Now()
+	historyRecord.Mobile = user.Mobile
+	historyRecord.Email = user.Email
+	historyRecord.CompanyId = user.CompanyId
+	historyRecord.CompanyName = user.CompanyName
+	historyRecord.MeetingId = int(detail.MeetingId)
+	historyRecord.RegisterPlatform = utils.REGISTER_PLATFORM
+	sellerItem, e := models.GetSellerByCompanyIdCheckFicc(user.CompanyId, 2)
+	if e != nil && e.Error() != utils.ErrNoRow() {
+		err = errors.New("GetSellerByCompanyIdCheckFicc, Err: " + e.Error())
+		return
+	}
+	historyRecord.RealName = user.RealName
+	if sellerItem != nil {
+		historyRecord.SellerName = sellerItem.RealName
+	}
+	_, e = models.AddCygxMorningMeetingReviewChapterHistory(historyRecord)
+	if e != nil {
+		err = errors.New("AddCygxMorningMeetingReviewChapterHistorymodels, Err: " + e.Error())
+		return
+	}
+	return
 }

+ 106 - 1
services/product_interior.go

@@ -215,7 +215,112 @@ func GetCygxProductInteriorHistoryListMap(productInteriorIs []int, user *models.
 	}
 	mapPv = make(map[int]int, 0)
 	for _, v := range list {
-		mapPv[v.ProductInteriorId]++
+		mapPv[v.ProductInteriorId] = v.Pv
+	}
+	return
+}
+
+// 获取产品内测的阅读数据
+func GetCygxProductInteriorHistoryListPvMap(productInteriorIs []int) (mapPv map[int]int) {
+	var err error
+	defer func() {
+		if err != nil {
+			fmt.Println(err)
+			go utils.SendAlarmMsg("获取产品内测的阅读数据,信息失败,Err:"+err.Error(), 3)
+		}
+	}()
+	lenproductInteriorIs := len(productInteriorIs)
+	if lenproductInteriorIs == 0 {
+		return
+	}
+	var condition string
+	var pars []interface{}
+	condition = ` AND product_interior_id IN (` + utils.GetOrmInReplace(lenproductInteriorIs) + `) `
+	pars = append(pars, productInteriorIs)
+	list, err := models.GetCygxProductInteriorHistoryList(condition, pars)
+	if err != nil {
+		return
+	}
+	mapPv = make(map[int]int, 0)
+	for _, v := range list {
+		mapPv[v.ProductInteriorId] = v.Pv
+	}
+	return
+}
+
+// 用户产品内测阅读,模板消息推送
+func ProductInteriorHistoryUserRmind(user *models.WxUserItem, productInteriorId int) (err error) {
+	//30秒内阅读同一篇报告不做重复推送
+	key := "CYGX_" + utils.CYGX_OBJ_PRODUCTINTERIOR + "_READ" + strconv.Itoa(productInteriorId) + "_" + strconv.Itoa(user.UserId)
+	if utils.Rc.IsExist(key) {
+		return
+	}
+	utils.Rc.Put(key, 1, 30*time.Second)
+	defer func() {
+		if err != nil {
+			go utils.SendAlarmMsg(fmt.Sprint("用户产品内测阅读,模板消息推送,模板消息推送失败 ,ProductInteriorHistoryUserRmind"+err.Error(), "userId:", user.UserId, "productInteriorId:", productInteriorId), 2)
+		}
+	}()
+	countUser, err := models.GetUserRemind(user.UserId)
+	if err != nil {
+		return err
+	}
+	if countUser == 0 {
+		return err
+	}
+	var first string
+	var keyword1 string
+	var keyword2 string
+	var keyword3 string
+	var keyword4 string
+	var remark 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
+		}
+		detail, e := models.GetCygxProductInteriorDetail(productInteriorId)
+		if e != nil {
+			err = errors.New("GetCygxProductInteriorDetail, Err: " + e.Error())
+			return
+		}
+		if detail == nil {
+			return
+		}
+		keyword1 = detail.Title
+		keyword2 = fmt.Sprint("互动:阅读报告,", user.RealName, "--", user.CompanyName)
+		openIdArr := make([]string, 0)
+		for _, v := range openIdList {
+			openIdArr = append(openIdArr, v.OpenId)
+		}
+		redirectUrl := utils.WX_MSG_PATH_PRODUCTINTERIOR_DETAIL + strconv.Itoa(productInteriorId)
+		sendInfo := new(SendWxTemplate)
+		sendInfo.First = first
+		sendInfo.Keyword1 = keyword1
+		sendInfo.Keyword2 = keyword2
+		sendInfo.Keyword3 = keyword3
+		sendInfo.Keyword4 = keyword4
+		sendInfo.Remark = remark
+		sendInfo.TemplateId = utils.WxMsgTemplateIdArticleUserRemind
+		sendInfo.RedirectUrl = redirectUrl
+		sendInfo.RedirectTarget = 3
+		sendInfo.Resource = strconv.Itoa(productInteriorId)
+		sendInfo.SendType = utils.TEMPLATE_MSG_CYGX_ARTICLE_ADD
+		sendInfo.OpenIdArr = openIdArr
+		e = PublicSendTemplateMsg(sendInfo)
+		if e != nil {
+			err = errors.New("PublicSendTemplateMsg, Err: " + e.Error())
+			return
+		}
 	}
 	return
 }

+ 27 - 0
services/report_history_record.go

@@ -39,3 +39,30 @@ func AddCygxReportHistoryRecord(item *models.CygxReportHistoryRecord) (err error
 	}
 	return
 }
+
+// 获取 报告精选,本周研究汇总、上周纪要汇总Pv 阅读数据
+func GetCygxReportHistoryRecordListMap(articleIds []int, reportType string) (mapPv map[int]int) {
+	var err error
+	defer func() {
+		if err != nil {
+			go utils.SendAlarmMsg("获取产品内测的阅读数据,信息失败,Err:"+err.Error(), 3)
+		}
+	}()
+	lenArr := len(articleIds)
+	if lenArr == 0 {
+		return
+	}
+	var condition string
+	var pars []interface{}
+	condition = ` AND article_id IN (` + utils.GetOrmInReplace(lenArr) + `) AND  report_type = ?`
+	pars = append(pars, articleIds, reportType)
+	list, e := models.GetCygxReportHistoryRecordListPv(condition, pars)
+	if e != nil && e.Error() != utils.ErrNoRow() {
+		return
+	}
+	mapPv = make(map[int]int, 0)
+	for _, v := range list {
+		mapPv[v.ArticleId] = v.Pv
+	}
+	return
+}

+ 87 - 0
services/research_summary.go

@@ -0,0 +1,87 @@
+package services
+
+import (
+	"errors"
+	"fmt"
+	"hongze/hongze_cygx/models"
+	"hongze/hongze_cygx/utils"
+	"strconv"
+	"time"
+)
+
+// 本周研究汇总用户阅读操作操作行为,模板消息推送
+func ResearchSummaryHistoryUserRmind(user *models.WxUserItem, articleId int) (err error) {
+	//30秒内阅读同一篇报告不做重复推送
+	key := "CYGX_" + utils.CYGX_OBJ_RESEARCHSUMMARY + "_READ" + strconv.Itoa(articleId) + "_" + strconv.Itoa(user.UserId)
+	if utils.Rc.IsExist(key) {
+		return
+	}
+	utils.Rc.Put(key, 1, 30*time.Second)
+	defer func() {
+		if err != nil {
+			go utils.SendAlarmMsg(fmt.Sprint("本周研究汇总用户阅读操作操作行为,模板消息推送 ,ResearchSummaryHistoryUserRmind"+err.Error(), "userId:", user.UserId, "articleId:", articleId), 2)
+		}
+	}()
+	countUser, err := models.GetUserRemind(user.UserId)
+	if err != nil {
+		return err
+	}
+	if countUser == 0 {
+		return err
+	}
+	var first string
+	var keyword1 string
+	var keyword2 string
+	var keyword3 string
+	var keyword4 string
+	var remark 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
+		}
+		detail, e := models.GetCygxResearchSummaryInfoById(articleId)
+		if e != nil {
+			err = errors.New("GetCygxProductInteriorDetail, Err: " + e.Error())
+			return
+		}
+		if detail == nil {
+			return
+		}
+		keyword1 = detail.Title
+		keyword2 = fmt.Sprint("互动:阅读报告,", user.RealName, "--", user.CompanyName)
+		openIdArr := make([]string, 0)
+		for _, v := range openIdList {
+			openIdArr = append(openIdArr, v.OpenId)
+		}
+		redirectUrl := utils.WX_MSG_PATH_THIS_WEEK_DETAIL + strconv.Itoa(articleId)
+		sendInfo := new(SendWxTemplate)
+		sendInfo.First = first
+		sendInfo.Keyword1 = keyword1
+		sendInfo.Keyword2 = keyword2
+		sendInfo.Keyword3 = keyword3
+		sendInfo.Keyword4 = keyword4
+		sendInfo.Remark = remark
+		sendInfo.TemplateId = utils.WxMsgTemplateIdArticleUserRemind
+		sendInfo.RedirectUrl = redirectUrl
+		sendInfo.RedirectTarget = 3
+		sendInfo.Resource = strconv.Itoa(articleId)
+		sendInfo.SendType = utils.TEMPLATE_MSG_CYGX_ARTICLE_ADD
+		sendInfo.OpenIdArr = openIdArr
+		e = PublicSendTemplateMsg(sendInfo)
+		if e != nil {
+			err = errors.New("PublicSendTemplateMsg, Err: " + e.Error())
+			return
+		}
+	}
+	return
+}

+ 8 - 0
services/resource_data.go

@@ -125,7 +125,9 @@ func GetResourceDataList(condition string, pars []interface{}, startSize, pageSi
 			err = errors.New("GetResourceDataList, Err: " + e.Error())
 			return
 		}
+		mapPv := GetCygxReportHistoryRecordListMap(minutessummaryIds, "szjyhz")
 		for _, v := range listresearchsummary {
+			v.Pv = mapPv[v.ArticleId]
 			v.PublishDate = utils.TimeRemoveHms2(v.PublishDate)
 			mapItems[fmt.Sprint("minutessummary", v.ArticleId)].Minutessummary = v
 		}
@@ -142,7 +144,9 @@ func GetResourceDataList(condition string, pars []interface{}, startSize, pageSi
 			err = errors.New("GetReportSelectionListHome, Err: " + e.Error())
 			return
 		}
+		mapPv := GetCygxReportHistoryRecordListMap(researchsummaryIds, "bzyjhz")
 		for _, v := range listresearchsummary {
+			v.Pv = mapPv[v.ArticleId]
 			v.PublishDate = utils.TimeRemoveHms2(v.PublishDate)
 			mapItems[fmt.Sprint("researchsummary", v.ArticleId)].Researchsummary = v
 		}
@@ -158,8 +162,10 @@ func GetResourceDataList(condition string, pars []interface{}, startSize, pageSi
 			err = errors.New("GetCygxProductInteriorList, Err: " + e.Error())
 			return
 		}
+		ProductInteriorHistoryMap := GetCygxProductInteriorHistoryListPvMap(productinteriorIds)
 		for _, v := range listProductInterior {
 			v.Body = ProductInteriorHtml(v.Body)
+			v.Pv = ProductInteriorHistoryMap[v.ProductInteriorId]
 			v.PublishTime = utils.TimeRemoveHms2(v.PublishTime)
 			mapItems[fmt.Sprint("productinterior", v.ProductInteriorId)].ProductInterior = v
 		}
@@ -434,10 +440,12 @@ func GetResourceDataList(condition string, pars []interface{}, startSize, pageSi
 			err = errors.New("GetReportSelectionList, Err: " + e.Error())
 			return
 		}
+		mapPv := GetCygxReportHistoryRecordListMap(reportselectionIds, "bgjx")
 		for _, v := range listreportselection {
 			v.Title += "(第" + v.Periods + "期)"
 			v.MarketStrategy = AnnotationHtml(v.MarketStrategy)
 			v.PublishDate = utils.TimeRemoveHms2(v.PublishDate)
+			v.Pv = mapPv[v.ArticleId]
 			mapItems[fmt.Sprint("reportselection", v.ArticleId)].ReportSelection = v
 		}
 	}

+ 6 - 1
utils/constants.go

@@ -240,7 +240,7 @@ const (
 	CYGX_OBJ_REPORTSELECTION    string = "reportselection"    // 对象类型:报告精选(重点公司)
 	CYGX_OBJ_PRODUCTINTERIOR    string = "productinterior"    // 对象类型:产品内测
 	CYGX_OBJ_RESEARCHSUMMARY    string = "researchsummary"    // 对象类型:本周研究汇总
-	CYGX_OBJ_MINUTESSUMMARY     string = "minutessummary"     // 对象类型:本周研究汇总
+	CYGX_OBJ_MINUTESSUMMARY     string = "minutessummary"     // 对象类型:上周纪要汇总
 	CYGX_OBJ_YANXUANSPECIAL     string = "yanxuanspecial"     // 对象类型:研选专栏
 )
 
@@ -248,3 +248,8 @@ const (
 	CYGX_YANXUAN_SPECIAL = "研选专栏" //用户阅读数据
 	CYGX_YANXUAN_ARTICLE = "买方研选" //用户阅读数据
 )
+
+const (
+	ACTIVITY_ZJDHH_V1_MSG string = "该活动为非公开活动,如有专家访谈需求请联系对口销售" // 限制人数为1的专家电话会用户C端报名,提示消息内容
+	FULLSTARFFED_MSG      string = "FullStarffed"              // 报名的时候人数已满的状态
+)