浏览代码

查研观向6.9

xingzai 2 年之前
父节点
当前提交
9c2133e44a

+ 13 - 0
models/activity.go

@@ -722,3 +722,16 @@ func UpdateCygxActivityName(activityId int, Name string) (err error) {
 	_, err = o.Raw(sql, Name, activityId).Exec()
 	return
 }
+
+//获取已发布但是为开始活动的权限
+func GetActivityWeekPermission() (permission string, err error) {
+	o := orm.NewOrm()
+	sql := ` SELECT
+			GROUP_CONCAT( DISTINCT chart_permission_name SEPARATOR ',' ) AS permission 
+		FROM
+			cygx_activity 
+		WHERE
+			active_state = 1`
+	err = o.Raw(sql).QueryRow(&permission)
+	return
+}

+ 53 - 0
models/activity_appointment.go

@@ -171,3 +171,56 @@ func GetAppointmentListByActivityIdAndMobile(activityIds, mobile string) (items
 	_, err = o.Raw(sql, mobile).QueryRows(&items)
 	return
 }
+
+//通过活动ID获取预约纪要的人数列表
+func GetCygxAppointmentSummaryListBySubjectId(subjectIds string) (item []*CygxAppointmentAndActivity, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT
+			ap.mobile,
+			ap.activity_id,
+			a.activity_name 
+		FROM
+			cygx_activity_appointment AS ap
+			INNER JOIN cygx_activity AS a ON a.activity_id = ap.activity_id
+			INNER JOIN cygx_industrial_activity_group_subject AS sg ON sg.activity_id = a.activity_id 
+		WHERE
+			a.active_state = 3 
+			AND a.chart_permission_id = 31 
+			AND DATE_SUB( CURDATE(), INTERVAL 14 DAY ) <= date( a.activity_time ) 
+			AND a.activity_type_id = 1 
+			AND sg.industrial_subject_id IN (` + subjectIds + `) 
+		GROUP BY
+			ap.mobile,
+			ap.activity_id `
+	_, err = o.Raw(sql).QueryRows(&item)
+	return
+}
+
+type CygxAppointment struct {
+	Mobile         string `description:"手机号"`
+	UserId         int `description:"userId"`
+	ActivityName   string `description:"所属销售"`
+	ActivityTypeId int    `description:"活动类型"`
+}
+
+//通过活动ID获取预约纪要的人数列表
+func GetCygxAppointmentSummaryBySubjectId(subjectIds string) (item []*CygxAppointment, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT
+			ap.user_id,
+			ap.mobile,
+			ap.activity_id,
+			a.activity_name 
+		FROM
+			cygx_activity_appointment AS ap
+			INNER JOIN cygx_activity AS a ON a.activity_id = ap.activity_id
+			INNER JOIN cygx_industrial_activity_group_subject AS sg ON sg.activity_id = a.activity_id 
+		WHERE
+			a.active_state = 3
+			AND sg.industrial_subject_id IN (` + subjectIds + `) 
+		GROUP BY
+			ap.mobile,
+			ap.activity_id `
+	_, err = o.Raw(sql).QueryRows(&item)
+	return
+}

+ 11 - 0
models/article.go

@@ -633,3 +633,14 @@ func GetCygxArticleTypeList() (items []*CygxArticleType, err error) {
 	_, err = o.Raw(sql).QueryRows(&items)
 	return
 }
+
+//通过文章ID获取文章所关联的标的ID
+func GetSubjectIds(articleId int) (subjects string, err error) {
+	sql := ` SELECT
+			GROUP_CONCAT( DISTINCT industrial_subject_id ORDER BY id ASC SEPARATOR ',' ) AS subjects 
+			FROM
+			cygx_industrial_article_group_subject WHERE article_id = ?`
+	o := orm.NewOrm()
+	err = o.Raw(sql, articleId).QueryRow(&subjects)
+	return
+}

+ 15 - 0
models/chart_permission.go

@@ -151,3 +151,18 @@ func GetCompanyPermissionIdWithHtgj() (chartpermissionids string, err error) {
 	err = o.Raw(sql).QueryRow(&chartpermissionids)
 	return
 }
+
+// GetChartPermissionById 主键获取权限
+func GetChartPermissionByRemark(remark string) (item *ChartPermission, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT * FROM chart_permission WHERE remark = ? LIMIT 1`
+	err = o.Raw(sql, remark).QueryRow(&item)
+	return
+}
+
+func GetChartPermissionIdByName(condition string, pars []interface{}) (chartpermissionids string, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT GROUP_CONCAT(DISTINCT chart_permission_id   SEPARATOR ',') AS chartpermissionids FROM chart_permission  WHERE product_id=2  ` + condition
+	err = o.Raw(sql, pars).QueryRow(&chartpermissionids)
+	return
+}

+ 15 - 0
models/industrial_management.go

@@ -455,3 +455,18 @@ func GetActivityIdListBySubjecName(subjectName string) (items []*ActivityIdRep,
 	_, err = o.Raw(sql).QueryRows(&items)
 	return
 }
+
+//通过id 获取详情
+func GetIndustrialManagemenDetailByAaticleID(articleId int) (items []*IndustrialManagementRep, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT
+			article_id,
+			industry_name 
+		FROM
+			cygx_industrial_article_group_management AS mg
+			INNER JOIN cygx_industrial_management AS m ON mg.industrial_management_id = m.industrial_management_id 
+		WHERE
+			mg.article_id = ? `
+	_, err = o.Raw(sql, articleId).QueryRows(&items)
+	return
+}

+ 8 - 0
models/report_mapping.go

@@ -114,6 +114,14 @@ func GetdetailByCategoryId(categoryId int) (item *ReportMapping, err error) {
 	return
 }
 
+//通过分类ID获取详情
+func GetdetailByCategoryIdPush(categoryId int) (item *ReportMapping, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT * FROM cygx_report_mapping WHERE category_id=? `
+	err = o.Raw(sql, categoryId).QueryRow(&item)
+	return
+}
+
 //通过分类ID获取详情主观客观
 func GetdetailByCategoryIdSando(categoryId int) (item *ReportMapping, err error) {
 	o := orm.NewOrm()

+ 23 - 0
models/user_record.go

@@ -140,3 +140,26 @@ func GetUserRecordListByMobile(platform int, bindAccount string) (items []*OpenI
 	_, err = orm.NewOrm().Raw(sql, platform).QueryRows(&items)
 	return
 }
+
+//获取单个用户openid
+func GetOpenIdDetailByMobile(platform int, bindAccount string) (item *OpenIdList, err error) {
+	o := orm.NewOrm()
+	var sql string
+	sql = `SELECT cr.open_id,wu.user_id FROM user_record  as u 
+			INNER JOIN cygx_user_record AS cr ON cr.union_id = u.union_id 
+			INNER JOIN wx_user AS wu ON wu.mobile = u.bind_account 
+			WHERE create_platform=? AND u.bind_account = ?`
+	err = o.Raw(sql, platform, bindAccount).QueryRow(&item)
+	return
+}
+
+func GetOpenIdByUserIds(ids string) (item []*OpenIdList, err error) {
+	o := orm.NewOrm()
+	var sql string
+	sql = `SELECT cr.open_id,wu.user_id FROM user_record  as u 
+			INNER JOIN cygx_user_record AS cr ON cr.union_id = u.union_id 
+			INNER JOIN wx_user AS wu ON wu.mobile = u.bind_account 
+			WHERE create_platform=4 AND u.user_id IN (`+ids+`)`
+	_,err = o.Raw(sql).QueryRows(&item)
+	return
+}

+ 110 - 0
models/wx_user_code.go

@@ -29,3 +29,113 @@ func GetWxUserCode(wxCode string) (item *WxUserCode, err error) {
 	err = o.Raw(sql, wxCode).QueryRow(&item)
 	return
 }
+
+//获取所有有权限的用户的opid
+func GetCygxUserRecordPower(condition string, pars []interface{}) (items []*OpenIdList, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT
+			cr.open_id,
+			u.user_id,
+			u.company_id,
+			u.real_name,
+			u.mobile 
+		FROM
+			company_report_permission AS p
+			INNER JOIN wx_user AS u ON u.company_id = p.company_id
+			INNER JOIN user_record AS r ON r.user_id = u.user_id
+			INNER JOIN cygx_user_record AS cr ON cr.union_id = r.union_id 
+		WHERE
+			 r.create_platform = 4 ` + condition + ` AND p.STATUS IN ('正式','试用','永续')  GROUP BY cr.open_id`
+	_, err = o.Raw(sql, pars).QueryRows(&items)
+	return
+}
+
+//获取关注这个文章对应产业的用户的 openid
+func GetCygxUserFllowOpenid(articleId int) (items []*OpenIdList, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT
+			cr.open_id,
+			f.user_id 
+		FROM
+			cygx_xzs_choose_send AS s
+			INNER JOIN cygx_industry_fllow AS f ON f.user_id = s.user_id
+			INNER JOIN user_record AS r ON r.user_id = f.user_id
+			INNER JOIN cygx_user_record AS cr ON cr.union_id = r.union_id 
+			INNER JOIN cygx_industrial_article_group_management as mg  ON mg.industrial_management_id = f.industrial_management_id
+		WHERE
+			r.create_platform = 4 
+			AND mg.article_id  = ?`
+	_, err = o.Raw(sql, articleId).QueryRows(&items)
+	return
+}
+
+//获取拒绝接收推送的的用户的 openid
+func GetCygxUserRefusetOpenid() (items []*OpenIdList, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT
+			cr.open_id,
+			s.user_id
+			FROM
+			cygx_xzs_choose_send AS s
+			INNER JOIN user_record AS r ON r.user_id = s.user_id
+			INNER JOIN cygx_user_record AS cr ON cr.union_id = r.union_id
+			WHERE
+			r.create_platform = 4
+			AND s.is_refuse = 1`
+	_, err = o.Raw(sql).QueryRows(&items)
+	return
+}
+
+//获取选择策略推送的用户的openid openid
+func GetCygxUserFllowCeLueOpenid(categoryId int) (items []*OpenIdList, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT
+			cr.open_id,
+			f.user_id 
+		FROM
+			cygx_xzs_choose_send AS s
+			INNER JOIN cygx_xzs_choose_category AS f ON f.user_id = s.user_id
+			INNER JOIN user_record AS r ON r.user_id = f.user_id
+			INNER JOIN cygx_user_record AS cr ON cr.union_id = r.union_id 
+		WHERE
+			r.create_platform = 4
+			AND s.is_refuse = 0
+			AND (s.is_subjective = 1 OR s.is_objective = 1)
+			AND f.category_id = ?`
+	_, err = o.Raw(sql, categoryId).QueryRows(&items)
+	return
+}
+
+type CygxXzsChooseSend struct {
+	Id           int       `orm:"column(id);pk"`
+	UserId       int       `description:"用户ID"`
+	Mobile       string    `description:"手机号"`
+	Email        string    `description:"邮箱"`
+	CompanyId    int       `description:"公司id"`
+	CompanyName  string    `description:"公司名称"`
+	RealName     string    `description:"用户实际名称"`
+	IsRefuse     int       `description:"是否拒绝推送,0否、1是  如果为1 则不做任何推送"`
+	IsSubjective int       `description:"是否选择主观推送, 1 是 、 0否"`
+	IsObjective  int       `description:"是否选择客观推送, 1 是 、 0否"`
+	CreateTime   time.Time `description:"创建时间"`
+	ModifyTime   time.Time `description:"更新时间"`
+}
+
+//获取提交过推送规则用户的userId
+func GetCygxXzsChooseSend() (items []*CygxXzsChooseSend, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT * FROM cygx_xzs_choose_send `
+	_, err = o.Raw(sql).QueryRows(&items)
+	return
+}
+
+
+//获取提交过推送规则用户的userId
+func GetCygxXzsChooseSendOpenIdByUserIds(idStr string) (items []*OpenIdList, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT ur.user_id, cr.open_id FROM user_record AS ur
+INNER JOIN cygx_user_record AS cr
+WHERE ur.user_id IN (` + idStr + `) AND create_platform=4 AND ur.union_id=cr.union_id `
+	_, err = o.Raw(sql).QueryRows(&items)
+	return
+}

+ 32 - 0
services/activity.go

@@ -1107,3 +1107,35 @@ func SpecialActivityUserRemind(user *models.WxUserItem, activityDetail *models.C
 	}
 	return
 }
+
+//func init() {
+//	DoActivityOnenIdWxTemplateMsg()
+//}
+
+//周日下午四点半推送全部活动
+func DoActivityOnenIdWxTemplateMsg(cont context.Context) (err error) {
+	var msg string
+	defer func() {
+		if err != nil {
+			go utils.SendAlarmMsg("周日下午四点半推送全部活动失败,DoActivityOnenIdWxTemplateMsg ErrMsg:"+err.Error(), 2)
+			go utils.SendEmail(utils.APPNAME+"【"+utils.RunMode+"】"+"失败提醒", "DoActivityOnenIdWxTemplateMsg ErrMsg:"+err.Error(), utils.EmailSendToUsers)
+			fmt.Println(err)
+		}
+		if msg != "" {
+			utils.FileLog.Info("发送模版消息失败,msg:%s", msg)
+		}
+	}()
+	var condition string
+	var pars []interface{}
+	openidPowerList, err := models.GetCygxUserRecordPower(condition, pars)
+	if err != nil {
+		return err
+	}
+	first := "近期所有行业活动预告,欢迎参与"
+	keyword1 := "--"
+	keyword2 := "--"
+	keyword3 := ""
+	keyword4 := "点击查看下周活动列表"
+	SendActivityOnenIdWxTemplateMsg(first, keyword1, keyword2, keyword3, keyword4, openidPowerList)
+	return
+}

+ 479 - 116
services/article.go

@@ -1002,142 +1002,505 @@ func HandleArticleListByApi(artcleId, celuePushId int) (err error) {
 
 		//类型ID 医药(医享会:28 、药调研:301)、消费【渠道新声:32】、科技【科技前言:79】、智造【匠心智造:84】或者是纪要做消息模板推送
 		fmt.Println(v.CategoryId)
-		if v.IsSummary == 1 || (v.CategoryId == 28 || v.CategoryId == 301 || v.CategoryId == 32 || v.CategoryId == 79 || v.CategoryId == 84) {
-			sliceSubjects := strings.Split(v.Stock, "/")
-			fmt.Println(sliceSubjects)
-			if len(sliceSubjects) > 0 {
-				var subjectStr string
-				for _, vSubject := range sliceSubjects {
-					sliceKuohao := strings.Split(vSubject, "(")           //过滤括号
-					sliceXiahuaxian := strings.Split(sliceKuohao[0], "-") //过滤下划线
-					subject := sliceXiahuaxian[0]
-					subjectStr += "'" + subject + "',"
-				}
-				if subjectStr != "" {
-					subjectStr = strings.TrimRight(subjectStr, ",")
-					activityIdList, err := models.GetActivityIdListBySubjecName(subjectStr)
+		//if v.IsSummary == 1 || (v.CategoryId == 28 || v.CategoryId == 301 || v.CategoryId == 32 || v.CategoryId == 79 || v.CategoryId == 84) {
+		//	sliceSubjects := strings.Split(v.Stock, "/")
+		//	fmt.Println(sliceSubjects)
+		//	if len(sliceSubjects) > 0 {
+		//		var subjectStr string
+		//		for _, vSubject := range sliceSubjects {
+		//			sliceKuohao := strings.Split(vSubject, "(")           //过滤括号
+		//			sliceXiahuaxian := strings.Split(sliceKuohao[0], "-") //过滤下划线
+		//			subject := sliceXiahuaxian[0]
+		//			subjectStr += "'" + subject + "',"
+		//		}
+		//		if subjectStr != "" {
+		//			subjectStr = strings.TrimRight(subjectStr, ",")
+		//			activityIdList, err := models.GetActivityIdListBySubjecName(subjectStr)
+		//			if err != nil {
+		//				fmt.Println("GetActivityIdListBySubjecName Err:", err.Error())
+		//				return err
+		//			}
+		//			if len(activityIdList) > 0 {
+		//				var activityIdStr string
+		//				for _, vAct := range activityIdList {
+		//					activityIdStr += strconv.Itoa(vAct.ActivityId) + ","
+		//				}
+		//				activityIdStr = strings.TrimRight(activityIdStr, ",")
+		//				if activityIdStr != "" {
+		//					appointmentList, err := models.GetAppointmentListByActivityId(activityIdStr, "1,2,5")
+		//					if err != nil {
+		//						fmt.Println("GetAppointmentListByActivityId Err:", err.Error())
+		//						return err
+		//					}
+		//					if len(appointmentList) > 0 {
+		//						for _, vApp := range appointmentList {
+		//
+		//							appointmentByMobileList, err := models.GetAppointmentListByActivityIdAndMobile(activityIdStr, vApp.Mobile)
+		//							if err != nil {
+		//								fmt.Println("GetAppointmentListByActivityId Err:", err.Error())
+		//								return err
+		//							}
+		//							var appointmentActivityName string
+		//							if len(appointmentByMobileList) > 0 {
+		//								for _, vAppM := range appointmentByMobileList {
+		//									appointmentActivityName += vAppM.ActivityName + ","
+		//								}
+		//							}
+		//							appointmentActivityName = strings.TrimRight(appointmentActivityName, ",")
+		//							if vApp.ActivityTypeId == 5 && v.CategoryId != 301 {
+		//								continue
+		//							}
+		//
+		//							if vApp.Mobile != "" {
+		//								openIdListByAppointment, err := models.GetUserRecordListByMobile(4, vApp.Mobile)
+		//								if err != nil {
+		//									fmt.Println(err)
+		//									return err
+		//								}
+		//								keyword1 := "您预约的调研,有关联的纪要发布/更新了"
+		//								keyword2 := appointmentActivityName
+		//								keyword3 := v.Title
+		//								keyword4 := v.PublishDate.Format(utils.FormatDateTime)
+		//								SendWxMsgWithArticleClassToAdmin(keyword1, keyword2, keyword3, keyword4, openIdListByAppointment, artcleId)
+		//							}
+		//						}
+		//					}
+		//				}
+		//			}
+		//		}
+		//	}
+		//}
+		//
+		////【公司调研】系列纪要发布/更新后
+		//if v.CategoryId == 45 || v.CategoryId == 74 || v.CategoryId == 86 || v.CategoryId == 88 {
+		//	fmt.Println("处理预约纪要")
+		//	sliceSubjects := strings.Split(v.Stock, "/")
+		//	if len(sliceSubjects) > 0 {
+		//		var subjectStr string
+		//		for _, vSubject := range sliceSubjects {
+		//			sliceKuohao := strings.Split(vSubject, "(")           //过滤括号
+		//			sliceXiahuaxian := strings.Split(sliceKuohao[0], "-") //过滤下划线
+		//			subject := sliceXiahuaxian[0]
+		//			subjectStr += "'" + subject + "',"
+		//		}
+		//		if subjectStr != "" {
+		//			subjectStr = strings.TrimRight(subjectStr, ",")
+		//			activityIdList, err := models.GetActivityIdListBySubjecName(subjectStr)
+		//			if err != nil {
+		//				fmt.Println("GetActivityIdListBySubjecName Err:", err.Error())
+		//				return err
+		//			}
+		//			if len(activityIdList) > 0 {
+		//				var activityIdStr string
+		//				for _, vAct := range activityIdList {
+		//					activityIdStr += strconv.Itoa(vAct.ActivityId) + ","
+		//				}
+		//				activityIdStr = strings.TrimRight(activityIdStr, ",")
+		//				if activityIdStr != "" {
+		//					appointmentList, err := models.GetAppointmentListByActivityId(activityIdStr, "3,4")
+		//					if err != nil {
+		//						fmt.Println("GetAppointmentListByActivityId Err:", err.Error())
+		//						return err
+		//					}
+		//					if len(appointmentList) > 0 {
+		//						for _, vApp := range appointmentList {
+		//							appointmentByMobileList, err := models.GetAppointmentListByActivityIdAndMobile(activityIdStr, vApp.Mobile)
+		//							if err != nil {
+		//								fmt.Println("GetAppointmentListByActivityId Err:", err.Error())
+		//								return err
+		//							}
+		//							var appointmentActivityName string
+		//							if len(appointmentByMobileList) > 0 {
+		//								for _, vAppM := range appointmentByMobileList {
+		//									appointmentActivityName += vAppM.ActivityName + ","
+		//								}
+		//							}
+		//							appointmentActivityName = strings.TrimRight(appointmentActivityName, ",")
+		//							if vApp.Mobile != "" {
+		//								openIdListByAppointment, err := models.GetUserRecordListByMobile(4, vApp.Mobile)
+		//								if err != nil {
+		//									fmt.Println(err)
+		//									return err
+		//								}
+		//								keyword1 := "您预约的调研,有关联的纪要发布/更新了"
+		//								keyword2 := appointmentActivityName
+		//								keyword3 := v.Title
+		//								keyword4 := v.PublishDate.Format(utils.FormatDateTime)
+		//								SendWxMsgWithArticleClassToAdmin(keyword1, keyword2, keyword3, keyword4, openIdListByAppointment, artcleId)
+		//
+		//							}
+		//						}
+		//					}
+		//				}
+		//			}
+		//		}
+		//	}
+		//}
+
+		//【公司调研】系列纪要发布/更新后 end
+
+		//查研观向6.9模板消息推送规则
+		go DoArticleOnenIdWxTemplateMsg(v.ArticleId)
+	}
+	go models.UpdateCygxArticleCeluePush(celuePushId)
+
+	return err
+}
+
+//func init() {
+//	DoArticleOnenIdWxTemplateMsg(6940)
+//}
+
+//过滤策略平台报告,研选报告重复推送,以及权限勾选的推送
+func DoArticleOnenIdWxTemplateMsg(articleId int) (err error) {
+	var msg string
+	defer func() {
+		if err != nil {
+			go utils.SendAlarmMsg("处理同步策略平台数据失败"+"GetArticleListByApi ErrMsg:"+err.Error(), 2)
+			go utils.SendEmail(utils.APPNAME+"【"+utils.RunMode+"】"+"失败提醒", "GetArticleListByApi ErrMsg:"+err.Error(), utils.EmailSendToUsers)
+			fmt.Println(err)
+		}
+		if msg != "" {
+			utils.FileLog.Info("发送模版消息失败,msg:%s", msg)
+		}
+	}()
+
+	//获取文章详情
+	articleInfo, err := models.GetArticleDetailById(articleId)
+	if err != nil {
+		return
+	}
+	articleInfo.Abstract, _ = GetReportContentTextSub(articleInfo.Abstract)
+	var chartPermissionId int
+
+	var chartPermissionName string
+	reportMapDetail, err := models.GetdetailByCategoryIdPush(articleInfo.CategoryId)
+	if err != nil {
+		return err
+	}
+	if reportMapDetail.ChartPermissionId == utils.CE_LUE_ID {
+		chartPermissionId = utils.CE_LUE_ID
+	} else {
+		if reportMapDetail.PermissionType == 1 {
+			chartPermissionName = reportMapDetail.ChartPermissionName + "(主观)"
+		} else {
+			chartPermissionName = reportMapDetail.ChartPermissionName + "(客观)"
+		}
+		chartPermissionDetail, err := models.GetChartPermissionByRemark(chartPermissionName)
+		if err != nil {
+			return err
+		}
+		chartPermissionId = chartPermissionDetail.ChartPermissionId
+	}
+	// 获取所有有权的用户的 openid
+	mapOpenidPower := make(map[int]string)
+	permissionIdList := make([]string, 0)
+	var condition string
+	var pars []interface{}
+	slicepermissionId := strings.Split(strconv.Itoa(chartPermissionId), ",")
+	if len(slicepermissionId) > 0 {
+		for _, v := range slicepermissionId {
+			permissionIdList = append(permissionIdList, v)
+		}
+		condition += ` AND p.chart_permission_id  IN (` + utils.GetOrmInReplace(len(slicepermissionId)) + ` )  `
+		pars = append(pars, permissionIdList)
+	}
+	openidPowerList, err := models.GetCygxUserRecordPower(condition, pars)
+	if err != nil {
+		return err
+	}
+	for _, v := range openidPowerList {
+		mapOpenidPower[v.UserId] = v.OpenId
+	}
+	//获取关注这个文章对应产业的用户的 openid
+	mapOpenidFllow := make(map[int]string)
+	if chartPermissionId != utils.CE_LUE_ID {
+		openidFllowList, err := models.GetCygxUserFllowOpenid(articleId)
+		if err != nil {
+			return err
+		}
+		for _, v := range openidFllowList {
+			mapOpenidFllow[v.UserId] = v.OpenId
+		}
+	}
+
+	//获取拒绝接收推送的的用户的 openid
+	mapOpenidRefuset := make(map[int]string)
+	openidRefusetList, err := models.GetCygxUserRefusetOpenid()
+	if err != nil {
+		return err
+	}
+	for _, v := range openidRefusetList {
+		mapOpenidRefuset[v.UserId] = v.OpenId
+	}
+	//获取提交过推送规则的用户的 openid
+	mapUserIdChooseSend := make(map[int]int)
+	mapUserIdChooseSendTypeNoPermission := make(map[int]int)
+	chooseSendtList, err := models.GetCygxXzsChooseSend()
+	for _, v := range chooseSendtList {
+		mapUserIdChooseSend[v.UserId] = v.UserId
+		if v.IsRefuse == 1 {
+			continue
+		}
+		//获取选择主客观赛道的用户
+		if reportMapDetail.PermissionType == 1 {
+			if v.IsSubjective == 1 {
+				mapUserIdChooseSendTypeNoPermission[v.UserId] = v.UserId
+			}
+		} else {
+			if v.IsObjective == 1 {
+				mapUserIdChooseSendTypeNoPermission[v.UserId] = v.UserId
+			}
+		}
+	}
+	//已经推送了的openid
+	mapOpenidPushed := make(map[int]string)
+	//文章关联的产业
+	var industryName string
+	if chartPermissionId != utils.CE_LUE_ID {
+		detailIndustryNameList, err := models.GetIndustrialManagemenDetailByAaticleID(articleId)
+		if err != nil && err.Error() != utils.ErrNoRow() {
+			return err
+		}
+		for _, v := range detailIndustryNameList {
+			industryName += v.IndustryName + ","
+		}
+		industryName = strings.TrimRight(industryName, ",")
+	} else {
+		industryName = reportMapDetail.SubCategoryName
+	}
+	keyword2 := articleInfo.Title
+	keyword3 := articleInfo.PublishDate
+	keyword4 := articleInfo.Abstract
+	mapAlreadySend := make(map[int]int)
+	//如果是策略就按照策略的推送方式来写
+	if reportMapDetail.ChartPermissionName == utils.CE_LUE_NAME {
+		//获取提交过推送规则的用户的 openid
+		mapUserFllowCeLue := make(map[int]string)
+		userFllowCeLueList, err := models.GetCygxUserFllowCeLueOpenid(articleInfo.CategoryId)
+		if err != nil {
+			return err
+		}
+		for _, v := range userFllowCeLueList {
+			mapUserFllowCeLue[v.UserId] = v.OpenId
+		}
+		for k, v := range mapOpenidPower {
+			if mapOpenidPushed[k] != "" {
+				continue
+			}
+			openIditem := new(models.OpenIdList)
+			openIditem.UserId = k
+			openIditem.OpenId = v
+			first := "您关注的赛道,有新的报告发布/更新,欢迎查看"
+			keyword1 := "所属赛道:" + industryName
+			mapActivityUserId := make(map[int]string)
+			if articleInfo.IsSummary == 1 {
+				sliceSubjectId, _ := models.GetSubjectIds(articleId)
+				if sliceSubjectId != ""{
+					appointmentList, err := models.GetCygxAppointmentSummaryBySubjectId(sliceSubjectId)
 					if err != nil {
-						fmt.Println("GetActivityIdListBySubjecName Err:", err.Error())
+						fmt.Println("GetCygxAppointmentSummaryListBySubjectId Err:", err.Error())
 						return err
 					}
-					if len(activityIdList) > 0 {
-						var activityIdStr string
-						for _, vAct := range activityIdList {
-							activityIdStr += strconv.Itoa(vAct.ActivityId) + ","
+					var userIds []string
+					if len(appointmentList) > 0 {
+						for _, v := range appointmentList {
+							//fmt.Println("mapActivityUserId:", v.UserId)
+							userIds = append(userIds, strconv.Itoa(v.UserId))
+							mapActivityUserId[v.UserId] += v.ActivityName + ","
 						}
-						activityIdStr = strings.TrimRight(activityIdStr, ",")
-						if activityIdStr != "" {
-							appointmentList, err := models.GetAppointmentListByActivityId(activityIdStr, "1,2,5")
-							if err != nil {
-								fmt.Println("GetAppointmentListByActivityId Err:", err.Error())
-								return err
-							}
-							if len(appointmentList) > 0 {
-								for _, vApp := range appointmentList {
-
-									appointmentByMobileList, err := models.GetAppointmentListByActivityIdAndMobile(activityIdStr, vApp.Mobile)
-									if err != nil {
-										fmt.Println("GetAppointmentListByActivityId Err:", err.Error())
-										return err
-									}
-									var appointmentActivityName string
-									if len(appointmentByMobileList) > 0 {
-										for _, vAppM := range appointmentByMobileList {
-											appointmentActivityName += vAppM.ActivityName + ","
-										}
-									}
-									appointmentActivityName = strings.TrimRight(appointmentActivityName, ",")
-									if vApp.ActivityTypeId == 5 && v.CategoryId != 301 {
-										continue
-									}
-
-									if vApp.Mobile != "" {
-										openIdListByAppointment, err := models.GetUserRecordListByMobile(4, vApp.Mobile)
-										if err != nil {
-											fmt.Println(err)
-											return err
-										}
-										keyword1 := "您预约的调研,有关联的纪要发布/更新了"
-										keyword2 := appointmentActivityName
-										keyword3 := v.Title
-										keyword4 := v.PublishDate.Format(utils.FormatDateTime)
-										SendWxMsgWithArticleClassToAdmin(keyword1, keyword2, keyword3, keyword4, openIdListByAppointment, artcleId)
-									}
-								}
+						userIdstr := strings.Join(userIds, ",")
+						openIdLists, err := models.GetOpenIdByUserIds(userIdstr)
+						if err != nil {
+							fmt.Println("GetOpenIdByUserIds Err:", err.Error())
+							return err
+						}
+						for _, item := range openIdLists {
+							first := "您预约的调研,有关联的纪要发布/更新了1"
+							keyword1 := industryName
+							openIditem := new(models.OpenIdList)
+							openIditem.OpenId = item.OpenId
+							openIditem.UserId = item.UserId
+							if _, ok := mapAlreadySend[openIditem.UserId]; !ok{
+								SendWxMsgWithArticleUpdate(first, keyword1, keyword2, keyword3, keyword4, openIditem, articleId)
+								delete(mapUserIdChooseSendTypeNoPermission, openIditem.UserId)
+								fmt.Println("AlreadySend:", openIditem.UserId)
+								mapAlreadySend[openIditem.UserId] = openIditem.UserId
 							}
 						}
 					}
 				}
+				//fmt.Println("openIditem.UserId:", openIditem.UserId)
+				//if _,ok := mapActivityUserId[openIditem.UserId]; ok{
+				//	first = "您预约的调研,有关联的纪要发布/更新了"
+				//	keyword1 = industryName
+				//	SendWxMsgWithArticleUpdate(first, keyword1, keyword2, keyword3, keyword4, openIditem, articleId)
+				//	delete(mapUserIdChooseSendTypeNoPermission, openIditem.UserId)
+				//	mapAlreadySend[openIditem.UserId] = openIditem.UserId
+				//}
+			}
+			_, ok := mapAlreadySend[openIditem.UserId]
+			//如果有权限而且小助手没有提交过信息的 就做正常推送
+			if mapUserIdChooseSend[openIditem.UserId] == 0  && !ok {
+				fmt.Println("1:", articleId)
+				SendWxMsgWithArticleUpdate(first, keyword1, keyword2, keyword3, keyword4, openIditem, articleId)
+			}
+			//如果小助手勾选了对应的权限信息 就做正常推送
+			if mapUserIdChooseSend[openIditem.UserId] != 0 && mapUserFllowCeLue[openIditem.UserId] != ""  && !ok {
+				fmt.Println("2:", articleId)
+				SendWxMsgWithArticleUpdate(first, keyword1, keyword2, keyword3, keyword4, openIditem, articleId)
 			}
 		}
-
-		//【公司调研】系列纪要发布/更新后
-		if v.CategoryId == 45 || v.CategoryId == 74 || v.CategoryId == 86 || v.CategoryId == 88 {
-			fmt.Println("处理预约纪要")
-			sliceSubjects := strings.Split(v.Stock, "/")
-			if len(sliceSubjects) > 0 {
-				var subjectStr string
-				for _, vSubject := range sliceSubjects {
-					sliceKuohao := strings.Split(vSubject, "(")           //过滤括号
-					sliceXiahuaxian := strings.Split(sliceKuohao[0], "-") //过滤下划线
-					subject := sliceXiahuaxian[0]
-					subjectStr += "'" + subject + "',"
+	} else {
+		for k, v := range mapOpenidPower {
+			if mapOpenidPushed[k] != "" {
+				continue
+			}
+			chooseSendtList, err := models.GetCygxXzsChooseSend()
+			if err != nil {
+				return err
+			}
+			mapUserIdChooseSendType := make(map[int]int)
+			for _, v := range chooseSendtList {
+				if v.IsRefuse == 1 {
+					continue
 				}
-				if subjectStr != "" {
-					subjectStr = strings.TrimRight(subjectStr, ",")
-					activityIdList, err := models.GetActivityIdListBySubjecName(subjectStr)
+				//获取选择主客观赛道的用户
+				if reportMapDetail.PermissionType == 1 {
+					if v.IsSubjective == 1 {
+						mapUserIdChooseSendType[v.UserId] = v.UserId
+					}
+				} else if reportMapDetail.PermissionType == 2 {
+					if v.IsObjective == 1 {
+						mapUserIdChooseSendType[v.UserId] = v.UserId
+					}
+				}else {
+					if v.IsSubjective == 1 || v.IsObjective == 1 {
+						mapUserIdChooseSendType[v.UserId] = v.UserId
+					}
+				}
+			}
+			openIditem := new(models.OpenIdList)
+			openIditem.UserId = k
+			openIditem.OpenId = v
+			first := "您关注的赛道,有新的报告发布/更新,欢迎查看"
+			keyword1 := "所属赛道:" + industryName
+			mapActivityUserId := make(map[int]string)
+			if articleInfo.IsSummary == 1 {
+				sliceSubjectId, _ := models.GetSubjectIds(articleId)
+				if sliceSubjectId != ""{
+					appointmentList, err := models.GetCygxAppointmentSummaryBySubjectId(sliceSubjectId)
 					if err != nil {
-						fmt.Println("GetActivityIdListBySubjecName Err:", err.Error())
+						fmt.Println("GetCygxAppointmentSummaryListBySubjectId Err:", err.Error())
 						return err
 					}
-					if len(activityIdList) > 0 {
-						var activityIdStr string
-						for _, vAct := range activityIdList {
-							activityIdStr += strconv.Itoa(vAct.ActivityId) + ","
+					var userIds []string
+					if len(appointmentList) > 0 {
+						for _, v := range appointmentList {
+							//fmt.Println("mapActivityUserId:", v.UserId)
+							userIds = append(userIds, strconv.Itoa(v.UserId))
+							mapActivityUserId[v.UserId] += v.ActivityName + ","
 						}
-						activityIdStr = strings.TrimRight(activityIdStr, ",")
-						if activityIdStr != "" {
-							appointmentList, err := models.GetAppointmentListByActivityId(activityIdStr, "3,4")
-							if err != nil {
-								fmt.Println("GetAppointmentListByActivityId Err:", err.Error())
-								return err
-							}
-							if len(appointmentList) > 0 {
-								for _, vApp := range appointmentList {
-									appointmentByMobileList, err := models.GetAppointmentListByActivityIdAndMobile(activityIdStr, vApp.Mobile)
-									if err != nil {
-										fmt.Println("GetAppointmentListByActivityId Err:", err.Error())
-										return err
-									}
-									var appointmentActivityName string
-									if len(appointmentByMobileList) > 0 {
-										for _, vAppM := range appointmentByMobileList {
-											appointmentActivityName += vAppM.ActivityName + ","
-										}
-									}
-									appointmentActivityName = strings.TrimRight(appointmentActivityName, ",")
-									if vApp.Mobile != "" {
-										openIdListByAppointment, err := models.GetUserRecordListByMobile(4, vApp.Mobile)
-										if err != nil {
-											fmt.Println(err)
-											return err
-										}
-										keyword1 := "您预约的调研,有关联的纪要发布/更新了"
-										keyword2 := appointmentActivityName
-										keyword3 := v.Title
-										keyword4 := v.PublishDate.Format(utils.FormatDateTime)
-										SendWxMsgWithArticleClassToAdmin(keyword1, keyword2, keyword3, keyword4, openIdListByAppointment, artcleId)
-
-									}
-								}
+						userIdstr := strings.Join(userIds, ",")
+						openIdLists, err := models.GetOpenIdByUserIds(userIdstr)
+						if err != nil {
+							fmt.Println("GetOpenIdByUserIds Err:", err.Error())
+							return err
+						}
+						for _, item := range openIdLists {
+							first := "您预约的调研,有关联的纪要发布/更新了1"
+							keyword1 := industryName
+							openIditem := new(models.OpenIdList)
+							openIditem.OpenId = item.OpenId
+							openIditem.UserId = item.UserId
+							if _, ok := mapAlreadySend[openIditem.UserId]; !ok{
+								SendWxMsgWithArticleUpdate(first, keyword1, keyword2, keyword3, keyword4, openIditem, articleId)
+								delete(mapUserIdChooseSendTypeNoPermission, openIditem.UserId)
+								fmt.Println("AlreadySend:", openIditem.UserId)
+								mapAlreadySend[openIditem.UserId] = openIditem.UserId
 							}
 						}
 					}
 				}
+				//fmt.Println("openIditem.UserId:", openIditem.UserId)
+				//if _,ok := mapActivityUserId[openIditem.UserId]; ok{
+				//	first = "您预约的调研,有关联的纪要发布/更新了"
+				//	keyword1 = industryName
+				//	SendWxMsgWithArticleUpdate(first, keyword1, keyword2, keyword3, keyword4, openIditem, articleId)
+				//	delete(mapUserIdChooseSendTypeNoPermission, openIditem.UserId)
+				//	mapAlreadySend[openIditem.UserId] = openIditem.UserId
+				//}
+			}
+			
+			//如果有权限而且小助手没有提交过信息的 就做正常推送
+			_, ok := mapAlreadySend[openIditem.UserId]
+			if mapUserIdChooseSend[openIditem.UserId] == 0 && !ok {
+				SendWxMsgWithArticleUpdate(first, keyword1, keyword2, keyword3, keyword4, openIditem, articleId)
+				delete(mapUserIdChooseSendTypeNoPermission, openIditem.UserId)
+				mapAlreadySend[openIditem.UserId] = openIditem.UserId
+			}
+			//如果小助手勾选了对应的权限信息 就做正常推送
+			if mapUserIdChooseSend[openIditem.UserId] != 0 && mapOpenidFllow[openIditem.UserId] != "" && mapUserIdChooseSendType[openIditem.UserId] > 0 && !ok {
+				SendWxMsgWithArticleUpdate(first, keyword1, keyword2, keyword3, keyword4, openIditem, articleId)
+				delete(mapUserIdChooseSendTypeNoPermission, openIditem.UserId)
+				mapAlreadySend[openIditem.UserId] = openIditem.UserId
+			}
+		}
+
+		//获取提交过推送规则的用户的 openid 并推送模版消息
+		openIditem := new(models.OpenIdList)
+		first := "您关注的赛道,有新的报告发布/更新,欢迎查看"
+		keyword1 := "所属赛道:" + industryName
+		//mapActivityUserId := make(map[int]string)
+		//if articleInfo.IsSummary == 1 {
+		//	sliceSubjectId, _ := models.GetSubjectIds(articleId)
+		//	if sliceSubjectId != ""{
+		//		appointmentList, err := models.GetCygxAppointmentSummaryBySubjectId(sliceSubjectId)
+		//		if err != nil {
+		//			fmt.Println("GetCygxAppointmentSummaryListBySubjectId Err:", err.Error())
+		//			return err
+		//		}
+		//		if len(appointmentList) > 0 {
+		//			for _, v := range appointmentList {
+		//				fmt.Println("mapActivityUserId:", v.UserId)
+		//				mapActivityUserId[v.UserId] += v.ActivityName + ","
+		//				first = "您预约的调研,有关联的纪要发布/更新了"
+		//				keyword1 = industryName
+		//				if _, ok := mapAlreadySend[openIditem.UserId]; !ok{
+		//					SendWxMsgWithArticleUpdate(first, keyword1, keyword2, keyword3, keyword4, openIditem, articleId)
+		//					delete(mapUserIdChooseSendTypeNoPermission, openIditem.UserId)
+		//					mapAlreadySend[openIditem.UserId] = openIditem.UserId
+		//				}
+		//			}
+		//		}
+		//	}
+		//	//fmt.Println("openIditem.UserId:", openIditem.UserId)
+		//	//if _,ok := mapActivityUserId[openIditem.UserId]; ok{
+		//	//	first = "您预约的调研,有关联的纪要发布/更新了"
+		//	//	keyword1 = industryName
+		//	//	SendWxMsgWithArticleUpdate(first, keyword1, keyword2, keyword3, keyword4, openIditem, articleId)
+		//	//	delete(mapUserIdChooseSendTypeNoPermission, openIditem.UserId)
+		//	//	mapAlreadySend[openIditem.UserId] = openIditem.UserId
+		//	//}
+		//}
+		var ids []string
+		for k, _ := range mapUserIdChooseSendTypeNoPermission {
+			ids = append(ids, strconv.Itoa(k))
+		}
+		if len(ids) > 0 {
+			idStr := strings.Join(ids, ",")
+			openidIlist, err := models.GetCygxXzsChooseSendOpenIdByUserIds(idStr)
+			if err != nil {
+				return err
+			}
+			for _, item := range openidIlist {
+				openIditem.OpenId = item.OpenId
+				openIditem.UserId = item.UserId
+				if _, ok := mapAlreadySend[openIditem.UserId]; !ok{
+					SendWxMsgWithArticleUpdate(first, keyword1, keyword2, keyword3, keyword4, openIditem, articleId)
+				}
 			}
 		}
-		//【公司调研】系列纪要发布/更新后 end
 	}
-	go models.UpdateCygxArticleCeluePush(celuePushId)
-	return err
+	return
 }

+ 4 - 0
services/task.go

@@ -74,6 +74,10 @@ func Task() {
 
 		getCeLueArticlePv := task.NewTask("getCeLueArticlePv", "0 */10 * * * *", GetCeLueArticlePv) //通过三方接口获取策略平台上的阅读记录
 		task.AddTask("getCeLueArticlePv", getCeLueArticlePv)
+
+		doActivityOnenIdWxTemplateMsg := task.NewTask("doActivityOnenIdWxTemplateMsg", "0 0 16 * * 0", DoActivityOnenIdWxTemplateMsg) ////周日下午四点半推送全部活动
+		task.AddTask("doActivityOnenIdWxTemplateMsg", doActivityOnenIdWxTemplateMsg)
+
 	}
 	if utils.RunMode != "release" {
 		getArticleListByApi := task.NewTask("getArticleListByApi", "0 */60 * * * *", GetArticleListByApi) //通过三方接口获取策略平台上的文章

+ 77 - 0
services/wx_template_msg.go

@@ -487,3 +487,80 @@ func SendTemplateMsg(sendUrl string, data []byte, resource string, sendType int,
 	}
 	return
 }
+
+//发送报告更新的消息给预约的用户
+func SendWxMsgWithArticleUpdate(first, keyWord1, keyWord2, keyWord3, keyWord4 string, item *models.OpenIdList, articleId 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:", articleId), 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
+	}
+	var openIdList []*models.OpenIdList
+	openIdList = append(openIdList, item)
+	sendUrl := "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=" + accessToken
+	templateId := utils.TemplateIdByProductXzs
+	sendMap := make(map[string]interface{})
+	sendData := make(map[string]interface{})
+	sendMap["template_id"] = templateId
+	sendMap["miniprogram"] = map[string]interface{}{"appid": utils.WxAppId, "pagepath": "pageMy/reportDetail/reportDetail?id=" + strconv.Itoa(articleId)}
+	sendData["first"] = map[string]interface{}{"value": first, "color": "#173177"}
+	sendData["keyword1"] = map[string]interface{}{"value": keyWord1, "color": "#173177"}
+	sendData["keyword2"] = map[string]interface{}{"value": keyWord2, "color": "#173177"}
+	sendData["keyword3"] = map[string]interface{}{"value": keyWord3, "color": "#173177"}
+	sendData["keyword4"] = map[string]interface{}{"value": keyWord4, "color": "#173177"}
+	sendData["remark"] = map[string]interface{}{"value": "点击查看活动详情", "color": "#173177"}
+	sendMap["data"] = sendData
+	WxSendTemplateMsg(sendUrl, sendMap, openIdList, strconv.Itoa(articleId), utils.TEMPLATE_MSG_CYGX_ARTICLE_ADD)
+	return
+}
+
+//周日下午4点半,推送全部活动
+func SendActivityOnenIdWxTemplateMsg(first, keyWord1, keyWord2, keyWord3, keyWord4 string, openIdList []*models.OpenIdList) (err error) {
+	var msg string
+	defer func() {
+		if err != nil {
+			go utils.SendEmail("周日下午4点半,推送全部活"+"【"+utils.APPNAME+"】"+time.Now().Format("2006-01-02 15:04:05"), msg+";Err:"+err.Error(), utils.EmailSendToUsers)
+			go utils.SendAlarmMsg(fmt.Sprint("发送周日下午4点半,推送全部活模版消息失败,"), 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
+	}
+	//var openIdList []*models.OpenIdList
+	//openIdList = append(openIdList, item)
+	sendUrl := "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=" + accessToken
+	templateId := utils.WxMsgTemplateIdArticleUserRemind
+	sendMap := make(map[string]interface{})
+	sendData := make(map[string]interface{})
+	sendMap["template_id"] = templateId
+	sendMap["miniprogram"] = map[string]interface{}{"appid": utils.WxAppId, "pagepath": "pages/activity/activity"}
+	//sendMap["miniprogram"] = map[string]interface{}{"appid": utils.WxAppId}
+	sendData["first"] = map[string]interface{}{"value": first, "color": "#173177"}
+	sendData["keyword1"] = map[string]interface{}{"value": keyWord1, "color": "#173177"}
+	sendData["keyword2"] = map[string]interface{}{"value": keyWord2, "color": "#173177"}
+	sendData["keyword3"] = map[string]interface{}{"value": keyWord3, "color": "#173177"}
+	sendData["keyword4"] = map[string]interface{}{"value": keyWord4, "color": "#173177"}
+	sendData["remark"] = map[string]interface{}{"value": "点击查看下周活动列表", "color": "#173177"}
+	sendMap["data"] = sendData
+	WxSendTemplateMsg(sendUrl, sendMap, openIdList, "", utils.TEMPLATE_MSG_CYGX_ARTICLE_ADD)
+	return
+}

+ 9 - 0
utils/common.go

@@ -677,6 +677,15 @@ func GetAttendanceDetailSeconds(secondNum int) string {
 	return timeStr
 }
 
+// GetOrmInReplace 获取orm的in查询替换?的方法
+func GetOrmInReplace(num int) string {
+	template := make([]string, num)
+	for i := 0; i < num; i++ {
+		template[i] = "?"
+	}
+	return strings.Join(template, ",")
+}
+
 func GetLocalIP() (ip string, err error) {
 	addrs, err := net.InterfaceAddrs()
 	if err != nil {

+ 5 - 3
utils/constants.go

@@ -72,9 +72,11 @@ const (
 )
 
 const (
-	CHART_PERMISSION_NAME_YANXUAN    = "研选"
-	CHART_PERMISSION_NAME_MF_YANXUAN = "买方研选"
-	CHART_PERMISSION_ID_YANXUAN      = 31
+	CHART_PERMISSION_NAME_YANXUAN    string = "研选"
+	CHART_PERMISSION_NAME_MF_YANXUAN string = "买方研选"
+	CHART_PERMISSION_ID_YANXUAN      int    = 31
+	CE_LUE_NAME                      string = "策略"
+	CE_LUE_ID                        int    = 23
 )
 
 const (