Forráskód Böngészése

Merge branch 'crm_16.6_ficc' into debug

317699326@qq.com 4 hete
szülő
commit
0e653eebad

+ 10 - 1
models/admin.go

@@ -1,6 +1,9 @@
 package models
 
-import "github.com/beego/beego/v2/client/orm"
+import (
+	"github.com/beego/beego/v2/client/orm"
+	"hongze/hongze_task/utils"
+)
 
 type Admin struct {
 	AdminId      int
@@ -24,6 +27,12 @@ func GetAdminByAdminId(adminId int) (item *Admin, err error) {
 	return
 }
 
+func GetAdminByAdminIds(adminIds []int) (items []*Admin, err error) {
+	sql := `SELECT * FROM admin WHERE admin_id in (` + utils.GetOrmInReplace(len(adminIds)) + `) `
+	_, err = orm.NewOrm().Raw(sql, adminIds).QueryRows(&items)
+	return
+}
+
 type AdminView struct {
 	AdminId      int
 	AdminName    string `description:"系统用户名称"`

+ 14 - 0
models/company.go

@@ -2,6 +2,7 @@ package models
 
 import (
 	"github.com/beego/beego/v2/client/orm"
+	"hongze/hongze_task/utils"
 	"time"
 )
 
@@ -32,6 +33,7 @@ type Company struct {
 	FirstStartDate  string    `description:"首次设置为试用客户开始时间"`
 	FirstEndDate    string    `description:"首次设置为试用客户结束时间"`
 	DateType        int       `description:"设置流失类型,1:1个月,2:2个月,3:3个月"`
+	InteractionNum  int       `description:"用户总的互动量"`
 }
 
 func GetCompanyByName(companyName string) (item *Company, err error) {
@@ -162,3 +164,15 @@ func GetCompanyNeedFreezeXClassRai(endDate string) (items []*CompanyNeedFreeze,
 	_, err = o.Raw(sql, endDate).QueryRows(&items)
 	return
 }
+
+// GetCompanyListByCompanyId 根据公司ID获取公司信息
+func GetCompanyListByCompanyId(companyId []int) (items []*Company, err error) {
+	lenArr := len(companyId)
+	if lenArr == 0 {
+		return
+	}
+	o := orm.NewOrm()
+	sql := `SELECT interaction_num , company_id  FROM  company AS a WHERE a.company_id IN (` + utils.GetOrmInReplace(lenArr) + `)   `
+	_, err = o.Raw(sql, companyId).QueryRows(&items)
+	return
+}

+ 1 - 1
models/company_contract/company_contract.go

@@ -91,7 +91,7 @@ func GetAfterCompanyContractListByCompanyIdListAndEndDate(endDate string, compan
 // GetLastContractListByEndDate 通过最近一份合同的日期获取早于该合同的最晚一份合同
 func GetLastContractListByEndDate(companyId, productId int, endDate string) (item *CompanyContract, err error) {
 	o := orm.NewOrm()
-	sql := "SELECT * FROM company_contract where company_id = ? AND product_id= ? end_date < ? AND status = 1 ORDER BY end_date desc"
+	sql := "SELECT * FROM company_contract where company_id = ? AND product_id= ? AND end_date < ? AND status = 1 ORDER BY end_date desc"
 	err = o.Raw(sql, companyId, productId, endDate).QueryRow(&item)
 
 	return

+ 2 - 2
models/company_product.go

@@ -446,12 +446,12 @@ func GetCompanyProductItemListByCompanyIdList(companyIdList []int, productId int
 // @param productId int
 // @return items []*CompanyProductItem
 // @return err error
-func GetCompanyProductItemByCompanyId(companyId int, productId int) (items *CompanyProductItem, err error) {
+func GetCompanyProductItemByCompanyId(companyId int, productId int) (item *CompanyProductItem, err error) {
 	o := orm.NewOrm()
 	sql := `SELECT a.* FROM company_product as a 
          JOIN company b on a.company_id=b.company_id
          WHERE a.company_id = ? AND a.product_id = ? `
-	_, err = o.Raw(sql, companyId, productId).QueryRows(&items)
+	err = o.Raw(sql, companyId, productId).QueryRow(&item)
 
 	return
 }

+ 27 - 0
models/company_report_permission.go

@@ -23,6 +23,25 @@ type CompanyReportPermission struct {
 	ExpensiveYx               int       `description:"权益研选: 0-3w; 1-5w"`
 }
 
+// 客户授权产品结构体(包含产品名称)
+type CompanyReportPermissionAndName struct {
+	CompanyReportPermissionId int `description:"客户授权产品id"`
+	CompanyId                 int
+	ReportPermissionId        int
+	CreatedTime               time.Time
+	LastUpdatedTime           time.Time
+	ChartPermissionId         int
+	StartDate                 string    `description:"权限开始日期"`
+	EndDate                   string    `description:"权限结束日期"`
+	ProductId                 int       `description:"产品id"`
+	ProductName               string    `description:"产品名称"`
+	CompanyContractId         int       `description:"合同id"`
+	PermissionName            string    `description:"客户授权产品的名称"`
+	ClassifyName              string    `description:"客户授权产品的分类名称"`
+	Status                    string    `description:"'正式','试用','关闭'"`
+	ModifyTime                time.Time `description:"修改时间"`
+}
+
 // Update 更新客户产品权限
 func (item *CompanyReportPermission) Update(cols []string) (err error) {
 	o := orm.NewOrm()
@@ -115,3 +134,11 @@ func GetCompanyReportPermissionByStatus(companyId, productId int, status string)
 	_, err = o.Raw(sql, companyId, productId, status).QueryRows(&items)
 	return
 }
+
+// 根据企业用户id和产品id获取所有正式的权限
+func GetCompanyProductReportPermissionList(companyId []int, productId int) (items []*CompanyReportPermissionAndName, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT a.*,b.permission_name,b.classify_name FROM company_report_permission a left join chart_permission b on a.chart_permission_id=b.chart_permission_id WHERE a.company_id IN (` + utils.GetOrmInReplace(len(companyId)) + `) and a.product_id=?   	AND a.status IN ('正式','试用','永续') `
+	_, err = o.Raw(sql, companyId, productId).QueryRows(&items)
+	return
+}

+ 18 - 0
models/cygx/activity_ask_email.go

@@ -0,0 +1,18 @@
+package cygx
+
+import "github.com/beego/beego/v2/client/orm"
+
+type AskEmailRep struct {
+	Name                string `description:"姓名"`
+	Email               string `description:"邮箱"`
+	Mobile              string `description:"手机号"`
+	ChartPermissionName string `description:"权限名称"`
+	AdminId             int
+}
+
+func GetAskEmail() (item []*AskEmailRep, err error) {
+	o := orm.NewOrmUsingDB("hz_cygx")
+	sql := `SELECT * FROM cygx_activity_ask_email`
+	_, err = o.Raw(sql).QueryRows(&item)
+	return
+}

+ 2 - 1
models/db.go

@@ -88,7 +88,8 @@ func init() {
 		new(ReportSendThsDetail),
 		new(Report),
 		new(UserViewStatistics),
-		new(roadshow.RsReportRecord), //路演记录
+		new(roadshow.RsReportRecord),           //路演记录
+		new(roadshow.RsReportRecordPermission), //路演公司权限记录
 		new(CompanyReportRecord),
 		new(ChartPermission), // 权限表
 		new(ComeinWhiteUser), // 进门财经白名单

+ 41 - 45
models/eta_trial.go

@@ -1,48 +1,44 @@
 package models
 
-import (
-	"github.com/beego/beego/v2/client/orm"
-	"hongze/hongze_task/utils"
-)
+//
+//type ETATrialListRespItem struct {
+//	EtaTrialId     int    `orm:"column(eta_trial_id);pk" description:"eta试用客户id"`
+//	UserName       string `description:"客户名称"`
+//	CompanyName    string `description:"客户公司姓名"`
+//	Position       string `description:"职位"`
+//	Mobile         string `description:"手机号"`
+//	ActiveTime     string `description:"累计活跃时长"`
+//	LastLoginTime  string `description:"最后一次登陆时间"`
+//	SellerId       int    `description:"销售id"`
+//	Seller         string `description:"销售员名称"`
+//	InterestModule string `description:"感兴趣模块"`
+//	Expiration     int    `description:"账号到期时长"`
+//	Enabled        int    `description:"1:有效,0:禁用"`
+//	IndexNum       int    `description:"累计添加指标"`
+//	ChartNum       int    `description:"累计添加图表"`
+//	Password       string
+//	Account        string
+//	CreateTime     string
+//	ModifyTime     string
+//}
 
-type ETATrialListRespItem struct {
-	EtaTrialId     int    `orm:"column(eta_trial_id);pk" description:"eta试用客户id"`
-	UserName       string `description:"客户名称"`
-	CompanyName    string `description:"客户公司姓名"`
-	Position       string `description:"职位"`
-	Mobile         string `description:"手机号"`
-	ActiveTime     string `description:"累计活跃时长"`
-	LastLoginTime  string `description:"最后一次登陆时间"`
-	SellerId       int    `description:"销售id"`
-	Seller         string `description:"销售员名称"`
-	InterestModule string `description:"感兴趣模块"`
-	Expiration     int    `description:"账号到期时长"`
-	Enabled        int    `description:"1:有效,0:禁用"`
-	IndexNum       int    `description:"累计添加指标"`
-	ChartNum       int    `description:"累计添加图表"`
-	Password       string
-	Account        string
-	CreateTime     string
-	ModifyTime     string
-}
-
-func GetETATrialDisableList(endDate string) (items []*ETATrialListRespItem, err error) {
-	o := orm.NewOrm()
-	sql := `SELECT * FROM eta_trial WHERE modify_time < '`+endDate+`'  `
-	_, err = o.Raw(sql).QueryRows(&items)
-	return
-}
-
-func UpdateETATrialDisable(disableIds []int) (err error) {
-	o := orm.NewOrm()
-	sql := `UPDATE eta_trial SET enabled = 0 WHERE eta_trial_id IN (` + utils.GetOrmInReplace(len(disableIds)) + `) `
-	_, err = o.Raw(sql, disableIds, ).Exec()
-	return
-}
-
-func UpdateETATrialAdminDisable(disableMobiles []string) (err error) {
-	o := orm.NewOrmUsingDB("weekly_trial")
-	sql := `UPDATE admin SET enabled = 0 WHERE mobile IN  (` + utils.GetOrmInReplace(len(disableMobiles)) + `) `
-	_, err = o.Raw(sql,disableMobiles).Exec()
-	return
-}
+//func GetETATrialDisableList(endDate string) (items []*ETATrialListRespItem, err error) {
+//	o := orm.NewOrm()
+//	sql := `SELECT * FROM eta_trial WHERE modify_time < '`+endDate+`'  `
+//	_, err = o.Raw(sql).QueryRows(&items)
+//	return
+//}
+//
+//func UpdateETATrialDisable(disableIds []int) (err error) {
+//	o := orm.NewOrm()
+//	sql := `UPDATE eta_trial SET enabled = 0 WHERE eta_trial_id IN (` + utils.GetOrmInReplace(len(disableIds)) + `) `
+//	_, err = o.Raw(sql, disableIds, ).Exec()
+//	return
+//}
+//
+//func UpdateETATrialAdminDisable(disableMobiles []string) (err error) {
+//	o := orm.NewOrmUsingDB("weekly_trial")
+//	sql := `UPDATE admin SET enabled = 0 WHERE mobile IN  (` + utils.GetOrmInReplace(len(disableMobiles)) + `) `
+//	_, err = o.Raw(sql,disableMobiles).Exec()
+//	return
+//}

+ 28 - 0
models/roadshow/calendar.go

@@ -107,3 +107,31 @@ func GetRsCalendarResearcherById(rsCalendarId int) (item *RsCalendarResearcher,
 	err = o.Raw(sql, rsCalendarId).QueryRow(&item)
 	return
 }
+
+type CalendarTesearcherQuestionTips struct {
+	CompanyName            string
+	OpenId                 string
+	RsCalendarId           int
+	RsCalendarResearcherId int
+}
+
+func GetCalendarTesearcherQuestionTips(endTime string) (list []*CalendarTesearcherQuestionTips, err error) {
+	sql := `
+select a.rs_calendar_id,a.rs_calendar_researcher_id,c.company_name,b.open_id 
+from rs_calendar_researcher as a
+inner join admin as b on a.researcher_id=b.admin_id
+inner join rs_calendar as c on a.rs_calendar_id=c.rs_calendar_id
+where 
+a.question_status=0
+and a.status in(2,6)
+and a.question_msg_status=0
+and CONCAT(a.end_date,' ',a.end_time) <= ?
+and b.open_id<>''
+and c.activity_type='路演'
+and c.roadshow_type<>''
+group by a.researcher_id,b.open_id
+`
+	o := orm.NewOrm()
+	_, err = o.Raw(sql, endTime).QueryRows(&list)
+	return nil, err
+}

+ 23 - 7
models/roadshow/report.go

@@ -1,8 +1,8 @@
 package roadshow
 
 import (
-	"time"
 	"github.com/beego/beego/v2/client/orm"
+	"time"
 )
 
 type RsReportRecord struct {
@@ -11,6 +11,7 @@ type RsReportRecord struct {
 	CompanyName                string    `description:"客户名称"`
 	CreditCode                 string    `description:"社会统一信用码"`
 	CompanyStatus              string    `description:"客户状态:'试用','永续','冻结','流失','正式','潜在'"`
+	PermissionName             string    `description:"开通品种"`
 	ResearcherId               int       `description:"研究员id"`
 	ResearcherName             string    `description:"研究员名称"`
 	ResearcherGroupId          int       `description:"研究员分组id"`
@@ -32,6 +33,8 @@ type RsReportRecord struct {
 	ModifyTime                 time.Time `description:"记录修改时间"`
 	ActivityType               string    `description:"活动类型"`
 	RoadshowType               string    `description:"路演形式"`
+	InteractionNum             int       `description:"当时用户总的互动量"`
+	QuestionStatus             int       `description:"问答状态:0-未填写;1-已填写"`
 }
 
 func AddRsReportRecord(item *RsReportRecord) (lastId int64, err error) {
@@ -77,23 +80,25 @@ type RsCalendarResearcherView struct {
 	ApproveTime            time.Time `description:"接受时间"`
 	IsSynced               int       `description:"是否与上海同步 0:未同步 1:已同步"`
 	ResearcherSort         int       `description:"研究员新增排序"`
+	QuestionStatus         int       `description:"问答状态:0-未填写;1-已填写"`
 }
 
 func GetRsCalendarDetail(endDate string) (list []*RsCalendarResearcherView, err error) {
 	sql := ` SELECT * FROM  rs_calendar AS a
 			INNER JOIN rs_calendar_researcher AS b ON a.rs_calendar_id=b.rs_calendar_id
-			WHERE a.source=0 AND b.end_date>=? `
+			WHERE  b.end_date>=? `
 	o := orm.NewOrm()
 	_, err = o.Raw(sql, endDate).QueryRows(&list)
 	return
 }
 
 type CompanySearchView struct {
-	CompanyId   int    `orm:"column(company_id);pk"`
-	CompanyName string `description:"客户名称"`
-	CreditCode  string `description:"社会统一信用码"`
-	CompanyCode string `description:"客户编码"`
-	Status      string `description:"客户状态"`
+	CompanyId      int    `orm:"column(company_id);pk"`
+	CompanyName    string `description:"客户名称"`
+	CreditCode     string `description:"社会统一信用码"`
+	CompanyCode    string `description:"客户编码"`
+	Status         string `description:"客户状态"`
+	PermissionName string `description:"开通品种"`
 }
 
 func RsCompanyList() (list []*CompanySearchView, err error) {
@@ -106,6 +111,17 @@ func RsCompanyList() (list []*CompanySearchView, err error) {
 	return
 }
 
+// 权益客户
+func RsCompanyListRai() (list []*CompanySearchView, err error) {
+	o := orm.NewOrm()
+	sql := ` SELECT b.company_id,b.company_name,a.credit_code,b.status FROM company AS a
+			INNER JOIN company_product AS b ON a.company_id=b.company_id
+			WHERE  b.product_id=2 `
+	sql += ` GROUP BY b.company_id  `
+	_, err = o.Raw(sql).QueryRows(&list)
+	return
+}
+
 func GetExistRsReportRecord(endDate string) (list []*RsReportRecord, err error) {
 	sql := ` SELECT * FROM  rs_report_record
 			WHERE end_date>=? `

+ 47 - 0
models/roadshow/report_record_permission.go

@@ -0,0 +1,47 @@
+package roadshow
+
+import (
+	"github.com/beego/beego/v2/client/orm"
+	"hongze/hongze_task/utils"
+	"time"
+)
+
+type RsReportRecordPermission struct {
+	RsReportRecordPermissionId int64     `orm:"column(rs_report_record_permission_id);pk"`
+	CompanyId                  int       `description:"公司id"`
+	ProductId                  int       `description:"产品id"`
+	ProductName                string    `description:"产品名称"`
+	ReportPermissionId         int       `description:"权限id(作废)"`
+	Status                     string    `description:"状态"`
+	CreatedTime                time.Time `description:"创建时间"`
+	ChartPermissionId          int       `description:"大分类ID"`
+	StartDate                  string    `description:"合同开始日期"`
+	EndDate                    string    `description:"合同结束日期"`
+	ModifyTime                 string    `description:"更新时间"`
+	IsUpgrade                  int       `description:"是否升级,1是,0否"`
+	ExpensiveYx                int       `description:"权益研选: 0-3w; 1-5w"`
+	RsCalendarId               int       `description:"路演活动id"`
+}
+
+// 根据企业用户id和产品id获取所有正式的权限
+func GetCompanyProductReportPermissionList(companyId []int, productId int) (items []*RsReportRecordPermission, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT * FROM company_report_permission  WHERE company_id IN (` + utils.GetOrmInReplace(len(companyId)) + `) and product_id=?  `
+	_, err = o.Raw(sql, companyId, productId).QueryRows(&items)
+	return
+}
+
+// 根据路演ID获取已经存在的路演信息
+func GetCompanyProductReportPermissionrsCalendarIdList(rsCalendarId []int) (items []*RsReportRecordPermission, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT rs_calendar_id FROM rs_report_record_permission  WHERE  rs_calendar_id IN (` + utils.GetOrmInReplace(len(rsCalendarId)) + `) `
+	_, err = o.Raw(sql, rsCalendarId).QueryRows(&items)
+	return
+}
+
+func MultiRsReportRecordPermission(items []*RsReportRecordPermission) (err error) {
+	o := orm.NewOrm()
+	//批量插入
+	_, err = o.InsertMulti(len(items), items)
+	return
+}

+ 110 - 0
models/yb/community_question.go

@@ -0,0 +1,110 @@
+package yb
+
+import (
+	"github.com/beego/beego/v2/client/orm"
+	"time"
+)
+
+const (
+	// 回复状态
+	ReplyStatusDitribute = 1
+	ReplyStatusWait      = 2
+	ReplyStatusDone      = 3
+	ReplyStatusStop      = 4
+)
+
+// CommunityQuestion 问答社区
+type CommunityQuestion struct {
+	CommunityQuestionId     int       `orm:"column(community_question_id);pk" description:"问题ID"`
+	UserId                  int       `description:"提问用户ID"`
+	UserOpenid              string    `description:"提问用户openid"`
+	Mobile                  string    `description:"用户手机号"`
+	RealName                string    `description:"用户名"`
+	QuestionContent         string    `description:"问题描述"`
+	ReplierUserId           int       `description:"回复人的user_id"`
+	ReplierOpenid           string    `description:"回复人openid"`
+	ReplierAdminId          int       `description:"回复人关联的admin_id"`
+	ReplierRealName         string    `description:"回复人姓名"`
+	ReplierAvatar           string    `description:"回复人头像"`
+	ResearchGroupFirstId    int       `description:"回复人研究方向一级分组ID"`
+	ResearchGroupSecondId   int       `description:"回复人研究方向二级分组ID"`
+	ResearchGroupFirstName  string    `description:"研究方向一级分组名称"`
+	ResearchGroupSecondName string    `description:"研究方向二级分组名称"`
+	DistributeAdminId       int       `description:"分配人admin_id"`
+	DistributeTime          time.Time `description:"分配时间"`
+	VarietyTagId            int       `description:"标签ID"`
+	VarietyTagName          string    `description:"标签名称"`
+	IsRead                  int       `description:"用户是否已读 0-未读 1-已读"`
+	ReplierIsRead           int       `description:"回复人是否已读 0-未读 1-已读"`
+	ReplyStatus             int       `description:"状态 1-待分配 2-待回答 3-已回答 4-已终止"`
+	MsgSendStatus           int       `description:"消息推送进度 0-待推送 1-已推送回答人 2-已推送提问人"`
+	ReplyTime               time.Time `description:"回复时间"`
+	CreateTime              time.Time `description:"提问时间"`
+	ModifyTime              time.Time `description:"修改时间"`
+	IsDeleted               int       `description:"是否已删除 0-否 1-是"`
+	DeleteTime              time.Time `description:"删除时间"`
+	StopReason              string    `description:"终止原因"`
+}
+
+type CommunityQuestionMore struct {
+	CommunityQuestion
+	ClickNum    int `description:"点击量"`
+	UserQaCount int `description:"用户提问数"`
+}
+
+func (item *CommunityQuestion) TableName() string {
+	return "yb_community_question"
+}
+
+func (item *CommunityQuestion) Update(cols []string) (err error) {
+	o := orm.NewOrm()
+	_, err = o.Update(item, cols...)
+	return
+}
+
+// GetQuestionById 主键获取提问
+func GetQuestionById(questionId int) (item *CommunityQuestion, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT * FROM yb_community_question WHERE community_question_id = ? AND is_deleted = 0 LIMIT 1`
+	err = o.Raw(sql, questionId).QueryRow(&item)
+	return
+}
+
+// GetCommunityQuestionListByCondition 获取问答列表
+func GetCommunityQuestionListByCondition(condition string, pars []interface{}, order string, startSize, pageSize int) (list []*CommunityQuestion, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT
+				*
+			FROM
+				yb_community_question
+			WHERE
+				is_deleted = 0 `
+	sql += condition
+	if order != "" {
+		sql += order
+	} else {
+		sql += ` ORDER BY create_time DESC`
+	}
+	sql += ` LIMIT ?,?`
+	_, err = o.Raw(sql, pars, startSize, pageSize).QueryRows(&list)
+	return
+}
+
+// GetCommunityQuestionTotalByCondition 获取问答列表
+func GetCommunityQuestionTotalByCondition(condition string, pars []interface{}) (total int, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT
+				*
+			FROM
+				yb_community_question
+			WHERE
+				is_deleted = 0 `
+	sql += condition
+
+	totalSQl := `SELECT COUNT(1) total FROM (` + sql + `) z`
+	if err = o.Raw(totalSQl, pars).QueryRow(&total); err != nil {
+		return
+	}
+
+	return
+}

+ 42 - 0
services/calendar_researcher_question.go

@@ -0,0 +1,42 @@
+package services
+
+import (
+	"context"
+	"fmt"
+	"hongze/hongze_task/models/roadshow"
+	"hongze/hongze_task/utils"
+	"strconv"
+	"time"
+)
+
+func SendCalendarResearcherQuestionTips(cont context.Context) (err error) {
+	endTime := time.Now().Add(-2 * time.Second).Format(utils.FormatDateTime)
+	list, err := roadshow.GetCalendarTesearcherQuestionTips(endTime)
+	if err != nil {
+		fmt.Println("SendCalendarResearcherQuestionTips Err:" + err.Error())
+		utils.FileLog.Info("GetCalendarTesearcherQuestionTips Err:" + err.Error())
+		return
+	}
+
+	var redirectUrl string
+
+	redirectUrl = `/pages-approve/activity/detail?RsCalendarResearcherId=%s&RsCalendarId=%s`
+	for _, v := range list {
+		var openIdArr []string
+		openIdArr = append(openIdArr, v.OpenId)
+
+		keyword1 := v.CompanyName + "路演已结束,请及时填写客户回答"
+		redirectUrl = fmt.Sprintf(redirectUrl, strconv.Itoa(v.RsCalendarResearcherId), strconv.Itoa(v.RsCalendarId))
+		sendInfo := new(SendWxTemplate)
+		sendInfo.WxAppId = utils.AdminWxAppId
+		sendInfo.Keyword1 = keyword1
+		sendInfo.Keyword2 = "待填写"
+		sendInfo.RedirectUrl = redirectUrl
+		sendInfo.RedirectTarget = 2
+		sendInfo.TemplateId = utils.RemindTemplateId
+		sendInfo.Remark = time.Now().Format(utils.FormatDateTime)
+		sendInfo.OpenIdArr = openIdArr
+		err = SendTemplateMsgV2(sendInfo)
+	}
+	return
+}

+ 2 - 0
services/comein/comein.go

@@ -546,6 +546,8 @@ func SyncWhiteList(cont context.Context) (err error) {
 			}
 		}
 	}
+	delMobiles = strings.TrimSuffix(delMobiles, ",")
+	delEmials = strings.TrimSuffix(delEmials, ",")
 	if len(delList) > 0 {
 		err = syncWhiteList(delMobiles, delEmials, 2)
 		if err != nil {

+ 1 - 1
services/company_product.go

@@ -153,7 +153,7 @@ func CompanyTryOut(cont context.Context) (err error) {
 		}
 
 		//正式转试用定时任务更新研选扣点
-		{
+		if v.ProductId == 2 {
 			cygx.YanXuanCompanyCompanyTryOut(v.CompanyId)
 		}
 

+ 35 - 5
services/cygx_research_summary.go

@@ -72,7 +72,7 @@ func CygxResearchSummary(cont context.Context) (err error) {
 
 		//医药
 		{
-			newCondition := condition + ` AND category_id_two IN(65,102)`
+			newCondition := condition + ` AND category_id_two IN(65,102,1001)`
 			list, e := data_manage.GetReportArticleList(newCondition, pars)
 			if e != nil {
 				err = e
@@ -86,7 +86,7 @@ func CygxResearchSummary(cont context.Context) (err error) {
 
 		//消费
 		{
-			newCondition := condition + ` AND category_id_two IN(67,1008)`
+			newCondition := condition + ` AND category_id_two IN(67,1008,10075)`
 			list, e := data_manage.GetReportArticleList(newCondition, pars)
 			if e != nil {
 				err = e
@@ -100,7 +100,7 @@ func CygxResearchSummary(cont context.Context) (err error) {
 
 		//科技
 		{
-			newCondition := condition + ` AND category_id_two IN(57,69,1009)`
+			newCondition := condition + ` AND category_id_two IN(57,69,1009,64)`
 			list, e := data_manage.GetReportArticleList(newCondition, pars)
 			if e != nil {
 				err = e
@@ -114,7 +114,7 @@ func CygxResearchSummary(cont context.Context) (err error) {
 
 		//智造
 		{
-			newCondition := condition + ` AND category_id_two IN(66,85)`
+			newCondition := condition + ` AND category_id_two IN(66,87)`
 			list, e := data_manage.GetReportArticleList(newCondition, pars)
 			if e != nil {
 				err = e
@@ -227,7 +227,7 @@ func CygxResearchSummary(cont context.Context) (err error) {
 
 		//智造
 		{
-			newCondition := condition + ` AND category_id_two IN(84)`
+			newCondition := condition + ` AND category_id_two IN(84, 85)`
 			list, e := data_manage.GetReportArticleList(newCondition, pars)
 			if e != nil {
 				err = e
@@ -438,6 +438,36 @@ func CygxResearchSummary(cont context.Context) (err error) {
 			}
 		}
 
+		//消费
+		{
+			//10083:消费问答
+			newCondition := condition + ` AND category_id_two IN(10083) `
+			list, e := data_manage.GetReportArticleList(newCondition, pars)
+			if e != nil {
+				err = e
+				fmt.Println("GetReportArticleList err:", e)
+				return
+			}
+			for _, article := range list {
+				sjdpList = append(sjdpList, article)
+			}
+		}
+
+		//智造
+		{
+			//10084:问道
+			newCondition := condition + ` AND category_id_two IN(10084) `
+			list, e := data_manage.GetReportArticleList(newCondition, pars)
+			if e != nil {
+				err = e
+				fmt.Println("GetReportArticleList err:", e)
+				return
+			}
+			for _, article := range list {
+				sjdpList = append(sjdpList, article)
+			}
+		}
+
 		var logItems []*data_manage.CygxResearchSummaryLog
 		for _, article := range sjdpList {
 			head := "<div class=\"title-content\">\n 【" + article.Title + "】    "

+ 2 - 9
services/eta_trial.go

@@ -1,14 +1,6 @@
 package services
 
-import (
-	"context"
-	"fmt"
-	"hongze/hongze_task/models"
-	"hongze/hongze_task/utils"
-	"time"
-)
-
-//ETA试用客户 启用->禁用
+/*//ETA试用客户 启用->禁用
 func ETATrialDisabled(cont context.Context) (err error) {
 	defer func() {
 		if err != nil {
@@ -46,3 +38,4 @@ func ETATrialDisabled(cont context.Context) (err error) {
 
 	return
 }
+*/

+ 167 - 5
services/roadshow/report.go

@@ -1,14 +1,16 @@
 package roadshow
 
 import (
+	"context"
 	"errors"
 	"fmt"
 	"hongze/hongze_task/models"
+	"hongze/hongze_task/models/cygx"
 	"hongze/hongze_task/models/roadshow"
 	"hongze/hongze_task/utils"
 	"strconv"
+	"strings"
 	"time"
-	"context"
 )
 
 func AddReportRecord(cont context.Context) (err error) {
@@ -17,44 +19,170 @@ func AddReportRecord(cont context.Context) (err error) {
 			fmt.Println("AddReportRecord Err:" + err.Error())
 		}
 	}()
-
 	adminAll, err := models.GetAdminList()
 	if err != nil {
 		return
 	}
 	adminMap := make(map[int]*models.AdminView)
+	mapRaiSllerId := make(map[int]bool) // 是否为权益销售
 	for _, v := range adminAll {
 		adminMap[v.AdminId] = v
+		if v.RoleTypeCode == utils.ROLE_TYPE_CODE_RAI_SELLER || v.RoleTypeCode == utils.ROLE_TYPE_CODE_RAI_GROUP || v.RoleTypeCode == utils.ROLE_TYPE_CODE_RAI_ADMIN {
+			mapRaiSllerId[v.AdminId] = true
+		}
+	}
+
+	listEmail, err := cygx.GetAskEmail() //权益研究员姓名
+	if err != nil {
+		return
+	}
+	mapResearcherNameRai := make(map[string]bool)
+	for _, v := range listEmail {
+		mapResearcherNameRai[v.Name] = true
 	}
 
 	companyList, err := roadshow.RsCompanyList()
 	if err != nil {
 		return
 	}
+
+	companyListRai, err := roadshow.RsCompanyListRai() //权益客户信息
+	if err != nil {
+		return
+	}
 	companyMap := make(map[int]*roadshow.CompanySearchView)
+	companyMapRai := make(map[int]*roadshow.CompanySearchView)
 	for _, v := range companyList {
 		companyMap[v.CompanyId] = v
 	}
 
-	endDate := time.Now().AddDate(-1, 0, 0).Format(utils.FormatDate)
+	for _, v := range companyListRai {
+		companyMapRai[v.CompanyId] = v
+	}
+
+	endDate := time.Now().AddDate(-0, 0, -3).Format(utils.FormatDate)
 
 	existList, err := roadshow.GetExistRsReportRecord(endDate)
 	if err != nil {
 		return
 	}
 	existMap := make(map[string]*roadshow.RsReportRecord)
+
 	for _, v := range existList {
 		key := strconv.Itoa(v.RsCalendarId) + "_" + strconv.Itoa(v.RsCalendarResearcherId)
 		existMap[key] = v
 	}
+	mapInteractionNum := make(map[int]int)
+	mapPermissionNameFicc := make(map[int][]string)
+	mapPermissionNameRai := make(map[int][]string)
+	mapPermissionFicc := make(map[int][]*roadshow.RsReportRecordPermission)
+	mapPermissionRai := make(map[int][]*roadshow.RsReportRecordPermission)
+
+	var itemsRs []*roadshow.RsReportRecordPermission
 	list, err := roadshow.GetRsCalendarDetail(endDate)
 	if err != nil {
 		return
 	}
+	var companyIds []int
 	for _, v := range list {
+		if v.CompanyId > 0 {
+			companyIds = append(companyIds, v.CompanyId)
+		}
+	}
+	if len(companyIds) > 0 {
+		listPermissionNameFicc, errFicc := models.GetCompanyProductReportPermissionList(companyIds, 1) // FICC权限信息
+		if errFicc != nil {
+			err = errFicc
+			return
+		}
+		mapPermissionArrFicc := make(map[string]bool)
+		for _, v := range listPermissionNameFicc {
+			if companyMap[v.CompanyId] == nil {
+				continue
+			}
+			if mapPermissionArrFicc[fmt.Sprint(v.CompanyId, v.PermissionName)] || v.PermissionName == "" {
+				continue
+			}
+			if companyMap[v.CompanyId].Status == "正式" && v.Status != "正式" {
+				continue // 正式客户只统计正式权限
+			}
+			mapPermissionNameFicc[v.CompanyId] = append(mapPermissionNameFicc[v.CompanyId], v.PermissionName)
+			mapPermissionArrFicc[fmt.Sprint(v.CompanyId, v.PermissionName)] = true
+		}
+
+		listPermissionNameRai, errRai := models.GetCompanyProductReportPermissionList(companyIds, 2) // 权益权限信息
+		if errRai != nil {
+			err = errRai
+			return
+		}
+
+		mapPermissionArrRai := make(map[string]bool)
+		for _, v := range listPermissionNameRai {
+			if companyMapRai[v.CompanyId] == nil {
+				continue
+			}
+			if mapPermissionArrRai[fmt.Sprint(v.CompanyId, v.PermissionName)] || v.PermissionName == "" {
+				continue
+			}
+			if companyMapRai[v.CompanyId].Status == "正式" && v.Status != "正式" {
+				continue // 正式客户只统计正式权限
+			}
+			mapPermissionNameRai[v.CompanyId] = append(mapPermissionNameRai[v.CompanyId], v.PermissionName)
+			mapPermissionArrRai[fmt.Sprint(v.CompanyId, v.PermissionName)] = true
+		}
+
+		listPermissionFicc, errFicc := roadshow.GetCompanyProductReportPermissionList(companyIds, 1) // FICC权限信息
+		if errFicc != nil {
+			err = errFicc
+			return
+		}
+		for _, v := range listPermissionFicc {
+			if companyMap[v.CompanyId] == nil {
+				continue
+			}
+			mapPermissionFicc[v.CompanyId] = append(mapPermissionFicc[v.CompanyId], v)
+		}
+
+		listPermissionRai, errRai := roadshow.GetCompanyProductReportPermissionList(companyIds, 2) // 权益权限信息
+		if errRai != nil {
+			err = errRai
+			return
+		}
+		for _, v := range listPermissionRai {
+			if companyMapRai[v.CompanyId] == nil {
+				continue
+			}
+			mapPermissionRai[v.CompanyId] = append(mapPermissionRai[v.CompanyId], v)
+		}
+		listerrCompanyInteractionNum, errCompany := models.GetCompanyListByCompanyId(companyIds) // 权益客户互动信息
+		if errCompany != nil {
+			err = errCompany
+			return
+		}
+		for _, v := range listerrCompanyInteractionNum {
+			mapInteractionNum[v.CompanyId] = v.InteractionNum
+		}
+
+	}
+
+	mapRsReportRecordPermission := make(map[string]bool) // 一个公司的一场路演,添加了多个研究员只记录一次
+	for _, v := range list {
+		if mapResearcherNameRai[v.ResearcherName] && v.CompanyName == "" && v.Source == 1 && v.ActivityType == "路演" {
+			continue // 如果权益研究员的而且公司名称为空,而且是上海那边同步过来的路演就不做记录
+		}
 		company := new(roadshow.CompanySearchView)
 		if v.CompanyId > 0 {
-			company, _ = companyMap[v.CompanyId]
+			if mapRaiSllerId[v.SysUserId] {
+				company, _ = companyMapRai[v.CompanyId] // 如果是权益销售添加的信息,就用权益相关的客户信息
+				if len(mapPermissionNameRai[v.CompanyId]) > 0 {
+					company.PermissionName = strings.Join(mapPermissionNameRai[v.CompanyId], "/")
+				}
+			} else {
+				company, _ = companyMap[v.CompanyId]
+				if len(mapPermissionNameFicc[v.CompanyId]) > 0 {
+					company.PermissionName = strings.Join(mapPermissionNameFicc[v.CompanyId], "/")
+				}
+			}
 		}
 
 		researcher, ok := adminMap[v.ResearcherId]
@@ -81,7 +209,8 @@ func AddReportRecord(cont context.Context) (err error) {
 				reportUpdateParams["company_id"] = company.CompanyId
 				reportUpdateParams["company_name"] = company.CompanyName
 				reportUpdateParams["credit_code"] = company.CreditCode
-				reportUpdateParams["company_status"] = company.Status
+				reportUpdateParams["company_status"] = company.Status //记录当时的状态
+				reportUpdateParams["permission_name"] = company.PermissionName
 			}
 			reportUpdateParams["activity_type"] = v.ActivityType
 			if researcher != nil {
@@ -116,6 +245,7 @@ func AddReportRecord(cont context.Context) (err error) {
 			reportUpdateParams["rs_calendar_researcher_status"] = v.Status
 			reportUpdateParams["activity_type"] = v.ActivityType
 			reportUpdateParams["roadshow_type"] = v.RoadshowType
+			reportUpdateParams["question_status"] = v.QuestionStatus
 			reportUpdateParams["modify_time"] = time.Now()
 			err = roadshow.UpdateRsReportRecord(reportWhereParams, reportUpdateParams)
 		} else { //新增
@@ -125,6 +255,7 @@ func AddReportRecord(cont context.Context) (err error) {
 				item.CompanyName = company.CompanyName
 				item.CreditCode = company.CreditCode
 				item.CompanyStatus = company.Status
+				item.PermissionName = company.PermissionName
 			}
 			item.ActivityType = v.ActivityType
 			item.ResearcherId = v.ResearcherId
@@ -161,10 +292,41 @@ func AddReportRecord(cont context.Context) (err error) {
 			item.ModifyTime = time.Now()
 			item.RsCalendarResearcherStatus = v.Status
 			item.RoadshowType = v.RoadshowType
+			item.QuestionStatus = v.QuestionStatus
+			item.InteractionNum = mapInteractionNum[v.CompanyId]
 			_, err = roadshow.AddRsReportRecord(item)
 			if err != nil {
 				return
 			}
+
+			if mapRaiSllerId[v.SysUserId] {
+				for _, vP := range mapPermissionRai[v.CompanyId] {
+					pKey := strconv.Itoa(v.RsCalendarId) + "_" + strconv.Itoa(vP.ChartPermissionId)
+					if mapRsReportRecordPermission[pKey] {
+						continue
+					}
+					vP.CreatedTime = time.Now()
+					vP.ModifyTime = time.Now().Format(utils.FormatDateTime)
+					vP.RsCalendarId = v.RsCalendarId
+					itemsRs = append(itemsRs, vP)
+					mapRsReportRecordPermission[pKey] = true
+				}
+			} else {
+				for _, vP := range mapPermissionFicc[v.CompanyId] {
+					pKey := strconv.Itoa(v.RsCalendarId) + "_" + strconv.Itoa(vP.ChartPermissionId)
+					if mapRsReportRecordPermission[pKey] {
+						continue
+					}
+					vP.CreatedTime = time.Now()
+					vP.ModifyTime = time.Now().Format(utils.FormatDateTime)
+					vP.RsCalendarId = v.RsCalendarId
+					itemsRs = append(itemsRs, vP)
+					mapRsReportRecordPermission[pKey] = true
+				}
+			}
+		}
+		if len(itemsRs) > 0 {
+			err = roadshow.MultiRsReportRecordPermission(itemsRs) // 添加公司当时对应的权限信息
 		}
 	}
 	return err

+ 13 - 5
services/task.go

@@ -119,7 +119,7 @@ func Task() {
 	modifyRsCalendarStatus := task.NewTask("modifyRsCalendarStatus", "0 */1 * * * * ", roadshow.ModifyRsCalendarResearcherStatus)
 	task.AddTask("modifyRsCalendarStatus", modifyRsCalendarStatus)
 
-	addReportRecord := task.NewTask("addReportRecord", "0 0 */1 * * *", roadshow.AddReportRecord)
+	addReportRecord := task.NewTask("addReportRecord", "0 */10 * * * *", roadshow.AddReportRecord)
 	task.AddTask("addReportRecord", addReportRecord)
 
 	//ficc存量客户数据统计
@@ -167,7 +167,7 @@ func Task() {
 	//task.AddTask("定时发布英文研报", publishEnglishReport)
 
 	// 定时生成本周研究汇总
-	cygxResearchSummary := task.NewTask("cygxResearchSummary", "0 0 15 * * 5", CygxResearchSummary)
+	cygxResearchSummary := task.NewTask("cygxResearchSummary", "0 0 13 * * 5", CygxResearchSummary)
 	task.AddTask("定时生成本周研究汇总", cygxResearchSummary)
 
 	// 定时生成上周纪要汇总
@@ -180,9 +180,9 @@ func Task() {
 	checkBusinessTripApply := task.NewTask("checkBusinessTripApply", "0 */30 * * * *", CheckBusinessTripApply)
 	task.AddTask("checkBusinessTripApply", checkBusinessTripApply)
 
-	//ETA试用客户 启用->禁用
-	eTATrialDisabled := task.NewTask("eTATrialDisabled", "0 15 2 * * *", ETATrialDisabled)
-	task.AddTask("ETA试用客户 启用->禁用", eTATrialDisabled)
+	////ETA试用客户 启用->禁用
+	//eTATrialDisabled := task.NewTask("eTATrialDisabled", "0 15 2 * * *", ETATrialDisabled)
+	//task.AddTask("ETA试用客户 启用->禁用", eTATrialDisabled)
 
 	//英文研报客户 临时->终止
 	englishReportEmailTermination := task.NewTask("englishReportEmailTermination", "0 30 2 * * *", EnglishReportEmailTermination)
@@ -204,6 +204,10 @@ func Task() {
 	fixCompanyOverseasStatus := task.NewTask("fixCompanyOverseasStatus", "0 */5 * * * *", overseas_custom.FixCompanyOverseasStatus)
 	task.AddTask("同步客户状态", fixCompanyOverseasStatus)
 
+	//路演问答填写提示
+	sendCalendarResearcherQuestionTips := task.NewTask("sendCalendarResearcherQuestionTips", "0 */1 * * * *", SendCalendarResearcherQuestionTips)
+	task.AddTask("sendCalendarResearcherQuestionTips", sendCalendarResearcherQuestionTips)
+
 	task.StartTask()
 
 	fmt.Println("task end")
@@ -292,6 +296,10 @@ func releaseTask() {
 	// 同步进门财经白名单定时任务
 	syncWhiteList := task.NewTask("syncWhiteList", "0 */10 * * * *", comein.SyncWhiteList)
 	task.AddTask("syncWhiteList", syncWhiteList)
+
+	//问答社区定时发送模版消息给研究员
+	notifyNeedAnswerQuestionToResearch := task.NewTask("notifyNeedAnswerQuestionToResearch", "0 0 10 * * *", NotifyNeedAnswerQuestionToResearch)
+	task.AddTask("问答社区定时发送模版消息给研究员", notifyNeedAnswerQuestionToResearch)
 }
 
 //func TaskTest() {

+ 67 - 0
services/wx_template_msg.go

@@ -296,3 +296,70 @@ func SendWxMsgWithEtaBusinessRemind(first, keyword1, keyword2, remark, code stri
 	err = SendTemplateMsgV2(sendInfo)
 	return
 }
+
+// SendYbQuestionToResearcher 给弘则FICC公众号,推送研报小程序模板消息-用户提问时,通知到研究员
+func SendYbQuestionToResearcher(questionId, adminId int, openid, questionTitle, remark string) (err error) {
+	var errMsg string
+	defer func() {
+		if err != nil {
+			alarmMsg := fmt.Sprintf("SendYbQuestionToResearcher-用户提问时,通知到研究员; QuestionId: %d; Err: %s; Msg: %s", questionId, err.Error(), errMsg)
+			utils.FileLog.Error(alarmMsg)
+			go alarm_msg.SendAlarmMsg(alarmMsg, 3)
+		}
+	}()
+
+	//accessToken, err := models.GetWxAccessToken()
+	//if err != nil {
+	//	errMsg = "GetWxAccessToken Err:" + err.Error()
+	//	return
+	//}
+	//if accessToken == "" {
+	//	errMsg = "accessToken is empty"
+	//	return
+	//}
+	openIdArr := make([]string, 0)
+	openIdArr = append(openIdArr, openid)
+
+	//sendUrl := "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=" + accessToken
+	//sendMap := make(map[string]interface{})
+	//sendData := make(map[string]interface{})
+
+	first := time.Now().Format(utils.FormatDate) + ": 您好,有新的提问待回复"
+	keyword1 := questionTitle
+	keyword2 := "待回复"
+	if remark == "" {
+		remark = "请点击详情尽快处理"
+		keyword2 = remark
+	}
+
+	//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["remark"] = map[string]interface{}{"value": remark, "color": "#173177"}
+	//
+	//sendMap["template_id"] = utils.WxMsgTemplateIdWithYbCommunityQuestion
+	//sendMap["data"] = sendData
+
+	wxAppPath := fmt.Sprintf("pages-question/answerDetail?id=%d", questionId)
+	if utils.RunMode == "debug" {
+		// 仅测试环境测试用
+		wxAppPath = "pages-report/chapterList?reportId=3800"
+	}
+
+	sendInfo := new(SendWxTemplate)
+	sendInfo.WxAppId = utils.AdminWxAppId
+	sendInfo.First = first
+	sendInfo.Keyword1 = keyword1
+	sendInfo.Keyword2 = keyword2
+	sendInfo.Remark = remark
+	sendInfo.RedirectUrl = wxAppPath
+	sendInfo.TemplateId = utils.WxMsgTemplateIdWithYbCommunityQuestion
+	sendInfo.RedirectTarget = 1
+	sendInfo.Resource = wxAppPath
+	sendInfo.SendType = utils.TEMPLATE_MSG_YB_COMMUNITY_QUESTION //研报问答社区
+	sendInfo.OpenIdArr = openIdArr
+
+	err = SendTemplateMsgV2(sendInfo)
+
+	return
+}

+ 95 - 0
services/yb_community_question.go

@@ -0,0 +1,95 @@
+package services
+
+import (
+	"context"
+	"errors"
+	"fmt"
+	"hongze/hongze_task/models"
+	"hongze/hongze_task/models/yb"
+	"hongze/hongze_task/services/alarm_msg"
+	"hongze/hongze_task/utils"
+)
+
+// NotifyNeedAnswerQuestionToResearch 定时通知研究员回复新提问
+func NotifyNeedAnswerQuestionToResearch(ctx context.Context) (err error) {
+	errmsg := ""
+	//分页处理沙盘表
+	defer func() {
+		if err != nil {
+			go alarm_msg.SendAlarmMsg("NotifyNeedAnswerQuestionToResearch,errmsg:"+errmsg+err.Error(), 3)
+		}
+		if errmsg != "" {
+			utils.FileLog.Info(fmt.Sprintf("NotifyNeedAnswerQuestionToResearch,errmsg:" + errmsg))
+		}
+	}()
+	condition := " AND reply_status = 2 AND replier_admin_id > 0"
+	var pars []interface{}
+	//遍历查询待回复的问答列表
+	total, err := yb.GetCommunityQuestionTotalByCondition(condition, pars)
+	if err != nil {
+		err = fmt.Errorf("获取问题列表总数失败 Err:%s", err)
+		return
+	}
+	if total == 0 {
+		return
+	}
+
+	pageSize := 100
+	// 根据沙盘列表总数,分页查询
+	// 计算总页数
+	totalPage := (total + pageSize - 1) / pageSize // 使用整数除法,并添加一页以防有余数
+	// 查询管理员信息列表
+	adminInfoMap := make(map[int]*models.Admin)
+	//查询沙盘列表
+	for i := 0; i < totalPage; i += 1 {
+		startSize := i * pageSize
+		list, e := yb.GetCommunityQuestionListByCondition(condition, pars, "", startSize, pageSize)
+		if e != nil {
+			err = fmt.Errorf("查询沙盘列表失败 Err:%s\n", e)
+			errmsg += err.Error()
+			return
+		}
+		// 查询管理员信息列表,已查询过的不再重复查
+		adminIds := make([]int, 0)
+		for _, v := range list {
+			if _, ok := adminInfoMap[v.ReplierAdminId]; !ok {
+				adminIds = append(adminIds, v.ReplierAdminId)
+			}
+		}
+		if len(adminIds) > 0 {
+			//查询管理员信息列表
+			adminList, e := models.GetAdminByAdminIds(adminIds)
+			if e != nil {
+				err = fmt.Errorf("查询管理员信息列表失败 Err:%s\n", e)
+				errmsg += err.Error()
+				return
+			}
+
+			for _, v := range adminList {
+				adminInfoMap[v.AdminId] = v
+			}
+		}
+
+		// 查询问答列表
+		for _, item := range list {
+			// 查询管理员信息列表
+			adminInfo, ok := adminInfoMap[item.ReplierAdminId]
+			if !ok {
+				err = errors.New("发送失败, 研究员账号查询失败")
+				errmsg += fmt.Sprintf("发送失败, 研究员账号查询失败, 研究员id:%d, 提问id:%d\n", item.ReplierAdminId, item.CommunityQuestionId)
+				continue
+			}
+			if adminInfo.OpenId == "" {
+				err = errors.New("该研究员未关注公众号,无法发送消息通知,回复人openid为空, 不可推送")
+				errmsg += fmt.Sprintf("发送失败,该研究员未关注公众号,无法发送消息通知,回复人openid为空, 不可推送 研究员id:%d, 提问id:%d\n", item.ReplierAdminId, item.CommunityQuestionId)
+				continue
+			}
+			// 发送模版消息给研究员
+			if err = SendYbQuestionToResearcher(item.CommunityQuestionId, adminInfo.AdminId, adminInfo.OpenId, item.QuestionContent, ""); err != nil {
+				errmsg += fmt.Sprintf("发送失败,推送模板消息失败 研究员id:%d, 提问id:%d\n", item.ReplierAdminId, item.CommunityQuestionId)
+				return
+			}
+		}
+	}
+	return
+}

+ 8 - 5
utils/config.go

@@ -43,7 +43,8 @@ var (
 	AdminWxAppId     string
 	AdminWxAppSecret string
 
-	TemplateIdByProduct string //产品运行报告通知-模板ID
+	TemplateIdByProduct                    string //产品运行报告通知-模板ID
+	WxMsgTemplateIdWithYbCommunityQuestion string
 )
 
 // oss配置
@@ -95,10 +96,10 @@ var (
 
 // 进门财经账号信息
 var (
-	COMEIN_URL      string
-	COMEIN_APPID    string
-	COMEIN_SECREKEY string
-	COMEIN_WHITELIST_APPID string
+	COMEIN_URL                string
+	COMEIN_APPID              string
+	COMEIN_SECREKEY           string
+	COMEIN_WHITELIST_APPID    string
 	COMEIN_WHITELIST_SECREKEY string
 )
 
@@ -196,6 +197,7 @@ ZwIDAQAB
 
 		SendWxTemplateMsgUrl = "http://127.0.0.1:8086/v1/wechat/send_template_msg"
 		YbCommonTemplateId = "dYg6iHooRq74PyCXmw_Ns7qdJZmbtLoKS2p2FKeaXl0"
+		WxMsgTemplateIdWithYbCommunityQuestion = "rciDm9ThigRBGi1SZ4TFd74XA4aoAxSz_ugdv_tZ450" // 研报小程序->问答社区回复通知
 	} else {
 		CompanyId = 16
 		RealName = "超级管理员"
@@ -217,6 +219,7 @@ ZwIDAQAB
 
 		SendWxTemplateMsgUrl = "http://127.0.0.1:8086/v1/wechat/send_template_msg"
 		YbCommonTemplateId = "CB7bOl7f3viMG4s1uhRo7WM0Jbx3WvodKuIZ8A_z8fM"
+		WxMsgTemplateIdWithYbCommunityQuestion = "rciDm9ThigRBGi1SZ4TFd74XA4aoAxSz_ugdv_tZ450" // 研报小程序->问答社区回复通知
 	}
 
 	// 微信模版消息

+ 40 - 0
utils/constants.go

@@ -45,6 +45,8 @@ const (
 	TEMPLATE_MSG_REPORT = iota + 1 //日度点评报告推送
 )
 
+const TEMPLATE_MSG_YB_COMMUNITY_QUESTION = 11
+
 // 聚合短信
 var (
 	TplId    = "65692"
@@ -183,3 +185,41 @@ const (
 const (
 	EnCompanyIdStep = 10000000
 )
+
+// 管理员,ficc管理员,ficc销售,权益管理员,权益销售。
+// 角色类型/类型编码
+const (
+	ROLE_TYPE_ADMIN       = "管理员"
+	ROLE_TYPE_FICC_ADMIN  = "ficc管理员"
+	ROLE_TYPE_FICC_SELLER = "ficc销售"
+	ROLE_TYPE_RAI_ADMIN   = "权益管理员"
+	ROLE_TYPE_RAI_SELLER  = "权益销售"
+	ROLE_TYPE_RAI_PRODUCT = "权益产品"
+
+	ROLE_TYPE_FICC_GROUP      = "ficc销售组长"
+	ROLE_TYPE_FICC_MANAGER    = "ficc销售主管"
+	ROLE_TYPE_RAI_GROUP       = "权益销售组长"
+	ROLE_TYPE_FICC_DEPARTMENT = "ficc部门经理"
+	ROLE_TYPE_RAI_DEPARTMENT  = "权益部门经理"
+	ROLE_TYPE_FICC_RESEARCHR  = "ficc研究员"
+	ROLE_TYPE_RAI_RESEARCHR   = "权益研究员"
+	ROLE_NAME_FICC_DIRECTOR   = "ficc销售经理" // 实际角色类型为ficc销售主管
+
+	ROLE_TYPE_CODE_ADMIN           = "admin"           //管理员
+	ROLE_TYPE_CODE_FICC_ADMIN      = "ficc_admin"      //ficc管理员
+	ROLE_TYPE_CODE_FICC_SELLER     = "ficc_seller"     //ficc销售
+	ROLE_TYPE_CODE_RAI_ADMIN       = "rai_admin"       //权益管理员
+	ROLE_TYPE_CODE_RAI_SELLER      = "rai_seller"      //权益销售
+	ROLE_TYPE_CODE_FICC_GROUP      = "ficc_group"      //ficc销售主管
+	ROLE_TYPE_CODE_RAI_GROUP       = "rai_group"       //ficc组长
+	ROLE_TYPE_CODE_FICC_DEPARTMENT = "ficc_department" //ficc部门经理
+	ROLE_TYPE_CODE_RAI_DEPARTMENT  = "rai_department"  //权益部门经理
+	ROLE_TYPE_CODE_FICC_RESEARCHR  = "ficc_researcher" //ficc研究员
+	ROLE_TYPE_CODE_RESEARCHR       = "researcher"      //ficc研究员(最早定义的)
+	ROLE_TYPE_CODE_RAI_RESEARCHR   = "rai_researcher"  //权益研究员
+	ROLE_TYPE_CODE_COMPLIANCE      = "compliance"      //合规角色
+	ROLE_TYPE_CODE_FINANCE         = "finance"         //财务角色
+	ROLE_TYPE_CODE_FICC_TEAM       = "ficc_team"       //ficc销售组长
+
+	ROLE_TYPE_SELLERS = "'ficc_admin','ficc_seller','ficc_team','rai_admin','rai_seller','ficc_group','rai_group','ficc_department','rai_department','compliance','finance'"
+)