浏览代码

Merge branch 'activity'

# Conflicts:
#	models/db.go
#	services/task.go
Roc 3 年之前
父节点
当前提交
e051414ffc

+ 2 - 2
models/company/company.go

@@ -19,7 +19,7 @@ func TryOutToFormal(companyId, productId, sellerId, companyContractId int, start
 			o.Commit()
 		}
 	}()
-	sql := `UPDATE company_product SET status='正式',start_date=?,end_date=?,modify_time=NOW(),formal_time=NOW() WHERE company_id=? AND product_id=? `
+	sql := `UPDATE company_product SET status='正式',is_suspend=0,start_date=?,end_date=?,modify_time=NOW(),formal_time=NOW() WHERE company_id=? AND product_id=? `
 	_, err = o.Raw(sql, startDate, endDate, companyId, productId).Exec()
 	if err != nil {
 		return
@@ -210,7 +210,7 @@ func ApplyServiceUpdate(companyId, productId, sellerId, companyContractId int, s
 	//}
 
 	//更新客户产品信息
-	sql = `UPDATE company_product SET status='正式',start_date=?,end_date=?,modify_time=NOW() WHERE company_id=? AND product_id=? `
+	sql = `UPDATE company_product SET status='正式',is_suspend=0,start_date=?,end_date=?,modify_time=NOW() WHERE company_id=? AND product_id=? `
 	_, err = o.Raw(sql, updateStartDateTime, updateEndDateTime, companyId, productId).Exec()
 	if err != nil {
 		return

+ 6 - 0
models/db.go

@@ -5,6 +5,7 @@ import (
 	"hongze/hongze_task/models/company_approval"
 	"hongze/hongze_task/models/company_contract"
 	"hongze/hongze_task/models/data_manage"
+	"hongze/hongze_task/models/yb"
 	"hongze/hongze_task/utils"
 	"time"
 
@@ -86,5 +87,10 @@ func init() {
 		new(data_manage.EdbInfo),                 //hz_data库的edb_info表
 		new(data_manage.EdbDataCalculateZjpj),    //直接拼接
 		new(data_manage.EdbDataCalculateLjztbpj), //累计同比值拼接
+		new(yb.Activity),         // 研报活动表
+		new(yb.ActivityType),     //研报活动分类表
+		new(yb.ActivityVoice),    //研报活动语音表
+		new(yb.ActivityRegister), //研报活动报名表
+		new(yb.Speaker),          //研报主持人表
 	)
 }

+ 11 - 0
models/users.go

@@ -2,6 +2,7 @@ package models
 
 import (
 	"rdluck_tools/orm"
+	"strings"
 )
 
 type HongzeUsers struct {
@@ -81,3 +82,13 @@ func GetUserOpenidListByUserId(userId int) (list []*OpenIdList, err error) {
 	_, err = orm.NewOrm().Raw(sql, userId).QueryRows(&list)
 	return
 }
+
+// GetUserOpenidListByUserIds 根据用户id字符串集合来获取他的openid列表集合
+func GetUserOpenidListByUserIds(userIdStr []string) (list []*OpenIdList, err error) {
+	if len(userIdStr) <= 0 {
+		return
+	}
+	sql := `SELECT open_id FROM user_record WHERE user_id in (` + strings.Join(userIdStr, ",") + `) and create_platform = 1`
+	_, err = orm.NewOrm().Raw(sql).QueryRows(&list)
+	return
+}

+ 129 - 0
models/yb/activity.go

@@ -0,0 +1,129 @@
+package yb
+
+import (
+	"rdluck_tools/orm"
+	"time"
+)
+
+// Activity 活动表
+type Activity struct {
+	ActivityId            int       `orm:"column(activity_id);pk" description:"活动ID"`
+	FirstActivityTypeId   int       `description:"第一级的活动类型ID"`
+	FirstActivityTypeName string    `description:"第一级的活动类型名称"`
+	ActivityTypeId        int       `description:"活动类型ID"`
+	ActivityTypeName      string    `description:"活动类型名称"`
+	ChartPermissionId     int       `description:"对应的权限id,表chart_permission中id"`
+	ChartPermissionName   string    `description:"对应的权限名称,表chart_permission中name"`
+	ActivityName          string    `description:"活动标题"`
+	StartTime             time.Time `description:"活动开始时间"`
+	EndTime               time.Time `description:"活动结束时间"`
+	Speaker               string    `description:"主讲人"`
+	SpeakerHeadPic        string    `description:"主讲人头像"`
+	SpeakerBackgroundPic  string    `description:"主讲人背景图"`
+	MainlandTel           string    `description:"大陆拨入"`
+	HongKongTel           string    `description:"香港拨入"`
+	TaiwanTel             string    `description:"台湾拨入"`
+	AmericaTel            string    `description:"美国拨入"`
+	SingaporeTel          string    `description:"新加坡拨入"`
+	ParticipationCode     string    `description:"参会密码"`
+	LinkParticipants      string    `description:"参会链接"`
+	IsLimitPeople         int8      `description:"是否限制人数 1是,0否"`
+	LimitPeopleNum        int       `description:"限制人数数量"`
+	ReportLink            string    `description:"报告链接"`
+	City                  string    `description:"城市"`
+	Address               string    `description:"活动地址"`
+	PosterUrl             string    `description:"活动海报地址"`
+	Remarks               string    `description:"备注"`
+	UserId                int       `description:"创建者id"`
+	PublishStatus         int8      `description:"发布状态,0未发布,1已发布"`
+	IsSendWxMsg           int8      `description:"是否推送过会议提醒微信消息,未推送:0,已推送:1"`
+	IsSendSalonWxMsg      int8      `description:"是否推送过沙龙提醒微信消息,未推送:0,已推送:1"`
+	IsDelete              int8      `description:"是否删除,0:未删除,1:已删除"`
+	ArticleId             int       `description:"报告链接所关联的文章ID"`
+	ModifyTime            time.Time `description:"修改时间"`
+	CreateTime            time.Time `description:"创建时间"`
+}
+
+// TableName 表名变更
+func (activity *Activity) TableName() string {
+	return "yb_activity"
+}
+
+// GetById 根据id获取活动详情
+func GetById(activityId int) (item *Activity, err error) {
+	o := orm.NewOrm()
+	sql := "select * from yb_activity where activity_id=? AND is_delete = 0 "
+	err = o.Raw(sql, activityId).QueryRow(&item)
+	return
+}
+
+type ActivityList struct {
+	ActivityId            int              `orm:"column(activity_id);pk" description:"活动ID"`
+	FirstActivityTypeId   int              `description:"第一级的活动类型ID"`
+	FirstActivityTypeName string           `description:"第一级的活动类型名称"`
+	ActivityTypeId        int              `description:"活动类型ID"`
+	ActivityTypeName      string           `description:"活动类型名称"`
+	ChartPermissionId     int              `description:"对应的权限id,表chart_permission中id"`
+	ChartPermissionName   string           `description:"对应的权限名称,表chart_permission中name"`
+	ActivityName          string           `description:"活动标题"`
+	StartTime             time.Time        `description:"活动开始时间"`
+	EndTime               time.Time        `description:"活动结束时间"`
+	Speaker               string           `description:"主讲人"`
+	MainlandTel           string           `description:"大陆拨入"`
+	HongKongTel           string           `description:"香港拨入"`
+	TaiwanTel             string           `description:"台湾拨入"`
+	AmericaTel            string           `description:"美国拨入"`
+	SingaporeTel          string           `description:"新加坡拨入"`
+	ParticipationCode     string           `description:"参会密码"`
+	LinkParticipants      string           `description:"参会链接"`
+	IsLimitPeople         int8             `description:"是否限制人数 1是,0否"`
+	LimitPeopleNum        int              `description:"限制人数数量"`
+	ReportLink            string           `description:"报告链接"`
+	City                  string           `description:"城市"`
+	Address               string           `description:"活动地址"`
+	PosterUrl             string           `description:"活动海报地址"`
+	Remarks               string           `description:"备注"`
+	UserId                int              `description:"创建者id"`
+	PublishStatus         int8             `description:"发布状态,0未发布,1已发布"`
+	IsSendWxMsg           int8             `description:"是否推送过会议提醒微信消息,未推送:0,已推送:1"`
+	IsSendSalonWxMsg      int8             `description:"是否推送过沙龙提醒微信消息,未推送:0,已推送:1"`
+	ArticleId             int              `description:"报告链接所关联的文章ID"`
+	ModifyTime            time.Time        `description:"修改时间"`
+	CreateTime            time.Time        `description:"创建时间"`
+	VoiceList             []*ActivityVoice `description:"音频文件列表"`
+}
+
+// GetList 获取活动列表数据
+func GetList(condition string, pars []interface{}, startSize, pageSize int) (total int, list []*Activity, err error) {
+	o := orm.NewOrm()
+	sql := "select * from yb_activity where 1=1 AND is_delete = 0 "
+	sql += condition
+	sql += ` order by modify_time desc `
+
+	totalSql := `select count(1) total from (` + sql + `) z `
+	err = o.Raw(totalSql, pars).QueryRow(&total)
+	if err != nil {
+		return
+	}
+	sql += ` LIMIT ?,? `
+	_, err = o.Raw(sql, pars, startSize, pageSize).QueryRows(&list)
+	return
+}
+
+// Update 更新活动
+func (activity *Activity) Update(cols []string) (err error) {
+	o := orm.NewOrm()
+	_, err = o.Update(activity, cols...)
+	return
+}
+
+// AddActivity 新增活动
+func AddActivity(activity *Activity) (err error) {
+	o := orm.NewOrm()
+	id, err := o.Insert(activity)
+	if err != nil {
+		return
+	}
+	activity.ActivityId = int(id)
+	return
+}

+ 121 - 0
models/yb/activity_register.go

@@ -0,0 +1,121 @@
+package yb
+
+import (
+	"rdluck_tools/orm"
+	"time"
+)
+
+// ActivityRegister 活动报名表
+type ActivityRegister struct {
+	Id            int       `orm:"column(activity_register_id);pk" description:"活动报名ID"`
+	ActivityId    int       `description:"活动ID"`
+	UserId        int       `description:"微信用户表ID"`
+	CompanyId     int       `description:"客户id"`
+	CompanyName   string    `description:"客户名称"`
+	SellerName    string    `description:"所属销售名称"`
+	RealName      string    `description:"用户实际名称"`
+	Mobile        string    `description:"用户手机号"`
+	RegisterState int8      `description:"报名状态 0-取消报名 1-已报名"`
+	CreateTime    time.Time `description:"创建时间"`
+}
+
+// TableName 表名变更
+func (activity *ActivityRegister) TableName() string {
+	return "yb_activity_register"
+}
+
+type ActivityRegisterList struct {
+	ActivityId        int       `orm:"column(activity_id);pk" description:"活动ID"`
+	ActivityTypeId    int       `description:"活动类型ID"`
+	ActivityTypeName  string    `description:"活动类型名称"`
+	ActivityName      string    `description:"活动标题"`
+	StartTime         time.Time `description:"活动开始时间"`
+	EndTime           time.Time `description:"活动结束时间"`
+	IsLimitPeople     int8      `description:"是否限制人数 1是,0否"`
+	LimitPeopleNum    int       `description:"限制人数数量"`
+	RegisterPeopleNum int       `description:"已报名人数数量"`
+}
+
+// GetActivityRegisterList 获取活动报名列表数据
+func GetActivityRegisterList(condition string, pars []interface{}, startSize, pageSize int) (total int, list []*ActivityRegisterList, err error) {
+	o := orm.NewOrm()
+	sql := "select * from yb_activity where 1=1 AND is_delete = 0 "
+	sql += condition
+	sql += ` order by start_time asc ` //按照开始时间正序
+
+	totalSql := `select count(1) total from (` + sql + `) z `
+	err = o.Raw(totalSql, pars).QueryRow(&total)
+	if err != nil {
+		return
+	}
+	sql += ` LIMIT ?,? `
+	_, err = o.Raw(sql, pars, startSize, pageSize).QueryRows(&list)
+	return
+}
+
+// Update 更新活动报名
+func (activityRegister *ActivityRegister) Update(cols []string) (err error) {
+	o := orm.NewOrm()
+	_, err = o.Update(activityRegister, cols...)
+	return
+}
+
+// AddActivityRegister 新增活动报名
+func AddActivityRegister(activityRegister *ActivityRegister) (err error) {
+	o := orm.NewOrm()
+	id, err := o.Insert(activityRegister)
+	if err != nil {
+		return
+	}
+	activityRegister.Id = int(id)
+	return
+}
+
+type ActivityRegisterTotal struct {
+	Total      int `description:"报名总人数"`
+	ActivityId int `description:"活动id"`
+}
+
+// GetActivityRegisterTotalListByActivityIds 根据活动id集合获取报名总人数列表
+func GetActivityRegisterTotalListByActivityIds(activityIds string) (list []*ActivityRegisterTotal, err error) {
+	if activityIds == "" {
+		return
+	}
+	o := orm.NewOrm()
+	sql := `select count(*) total,activity_id from yb_activity_register where activity_id in (` + activityIds + `) where register_state = 1  group by activity_id`
+	_, err = o.Raw(sql).QueryRows(&list)
+	return
+}
+
+// GetActivityRegisterListByActivityId 获取已经报名活动的用户列表数据
+func GetActivityRegisterListByActivityId(activityId, startSize, pageSize int) (total int, list []*ActivityRegister, err error) {
+	o := orm.NewOrm()
+	sql := "select * from yb_activity_register  where register_state = 1 and activity_id = ? "
+	sql += ` order by create_time desc `
+
+	totalSql := `select count(1) total from (` + sql + `) z `
+	err = o.Raw(totalSql, activityId).QueryRow(&total)
+	if err != nil {
+		return
+	}
+	sql += ` LIMIT ?,? `
+	_, err = o.Raw(sql, activityId, startSize, pageSize).QueryRows(&list)
+	return
+}
+
+// GetActivityRegister 获取活动报名用户详情
+func GetActivityRegister(activityId, userId int) (item *ActivityRegister, err error) {
+	o := orm.NewOrm()
+	sql := "select * from yb_activity_register where activity_id = ? and user_id = ? order by id desc"
+	err = o.Raw(sql, activityId, userId).QueryRow(&item)
+	return
+}
+
+// GetAllActivityRegisterListByActivityId 根据活动id获取所有的线下报名用户
+func GetAllActivityRegisterListByActivityId(activityId int) (list []*ActivityRegister, err error) {
+	o := orm.NewOrm()
+	sql := "select * from yb_activity_register where register_state = 1 and activity_id = ? "
+	sql += ` order by activity_register_id asc ` //按照预约时间正序
+	_, err = o.Raw(sql, activityId).QueryRows(&list)
+	return
+}

+ 39 - 0
models/yb/activity_remind.go

@@ -0,0 +1,39 @@
+package yb
+
+import (
+	"rdluck_tools/orm"
+	"time"
+)
+
+// ActivityRemind 活动会议提醒表
+type ActivityRemind struct {
+	ActivityRemindId int    `orm:"column(activity_remind_id);pk" description:"活动提醒ID"`
+	ActivityId       int    `description:"活动ID"`
+	UserId           int    `description:"微信用户表ID"`
+	CompanyId        int    `description:"客户id"`
+	RealName         string `description:"用户实际名称"`
+	Mobile           string `description:"用户手机号"`
+	//RegisterState int8      `description:"报名状态 0-取消报名 1-已报名"`
+	CreateTime time.Time `description:"创建时间"`
+}
+
+// TableName 表名变更
+func (activityRemind *ActivityRemind) TableName() string {
+	return "yb_activity_remind"
+}
+
+// GetAllActivityRemindListByActivityId 根据活动id获取所有的提醒用户
+func GetAllActivityRemindListByActivityId(activityId int) (list []*ActivityRemind, err error) {
+	o := orm.NewOrm()
+	sql := "select * from yb_activity_remind where activity_id = ? "
+	sql += ` order by activity_remind_id asc ` //按照预约时间正序
+	_, err = o.Raw(sql, activityId).QueryRows(&list)
+	return
+}
+
+// Update 更新活动报名
+func (activityRemind *ActivityRemind) Update(cols []string) (err error) {
+	o := orm.NewOrm()
+	_, err = o.Update(activityRemind, cols...)
+	return
+}

+ 47 - 0
models/yb/activity_type.go

@@ -0,0 +1,47 @@
+package yb
+
+import (
+	"rdluck_tools/orm"
+	"time"
+)
+
+// ActivityType 活动分类表
+type ActivityType struct {
+	ActivityTypeId   int       `orm:"column(activity_type_id);pk" description:"活动类型ID"`
+	ActivityTypeName string    `description:"活动类型名称"`
+	Pid              int       `description:"父级id,默认是:0"`
+	Sort             int       `description:"排序字段"`
+	FrontIsShow      int8      `description:"是否在前台展示,0:不展示,1:展示"`
+	CreateTime       time.Time `description:"创建时间"`
+}
+
+// TableName 表名变更
+func (activityType *ActivityType) TableName() string {
+	return "yb_activity_type"
+}
+
+type ActivityTypeList struct {
+	ActivityTypeId   int                 `description:"活动类型ID"`
+	ActivityTypeName string              `description:"活动类型名称"`
+	Pid              int                 `description:"父级id,默认是:0"`
+	Sort             int                 `description:"排序字段"`
+	FrontIsShow      int8                `description:"是否在前台展示,0:不展示,1:展示"`
+	CreateTime       time.Time           `description:"创建时间"`
+	ChildList        []*ActivityTypeList `description:"下级活动类型列表"`
+}
+
+// GetActivityTypeListByPid 获取最高级的活动分类
+func GetActivityTypeListByPid(pid int) (list []*ActivityType, err error) {
+	o := orm.NewOrm()
+	sql := `select * from yb_activity_type where pid=? order by sort asc ,activity_type_id asc`
+	_, err = o.Raw(sql, pid).QueryRows(&list)
+	return
+}
+
+// GetActivityTypeByActivityTypeId 根据id获取活动分类详情
+func GetActivityTypeByActivityTypeId(pid int) (list []*ActivityTypeList, err error) {
+	o := orm.NewOrm()
+	sql := `select * from yb_activity_type where pid=? order by sort asc ,activity_type_id asc`
+	_, err = o.Raw(sql, pid).QueryRows(&list)
+	return
+}

+ 54 - 0
models/yb/activity_voice.go

@@ -0,0 +1,54 @@
+package yb
+
+import (
+	"rdluck_tools/orm"
+	"time"
+)
+
+// ActivityVoice 活动语音表结构体
+type ActivityVoice struct {
+	ActivityVoiceId  int       `orm:"column(activity_voice_id);pk" description:"活动音频ID"`
+	ActivityId       int       ` description:"活动ID"`
+	VoiceUrl         string    `description:"音频地址"`
+	VoiceName        string    `description:"音频名称"`
+	VoicePlaySeconds string    `description:"音频时长"`
+	CreateTime       time.Time `description:"创建时间"`
+}
+
+// TableName 表名变更
+func (activityVoice *ActivityVoice) TableName() string {
+	return "yb_activity_voice"
+}
+
+// DelByActivityId 根据活动id删除所有音频
+func DelByActivityId(activityId int) (err error) {
+	o := orm.NewOrm()
+	sql := "delete from yb_activity_voice where activity_id=?"
+	_, err = o.Raw(sql, activityId).Exec()
+	return
+}
+
+// AddActivityVoice 新增活动音频
+func AddActivityVoice(activityVoiceInfo *ActivityVoice) (err error) {
+	o := orm.NewOrm()
+	_, err = o.Insert(activityVoiceInfo)
+	return
+}
+
+// AddActivityVoiceMulti 批量新增活动音频
+func AddActivityVoiceMulti(activityVoiceList []*ActivityVoice) (err error) {
+	o := orm.NewOrm()
+	_, err = o.InsertMulti(len(activityVoiceList), activityVoiceList)
+	return
+}
+
+// GetVoiceListByActivityIds 根据活动id集合获取音频列表
+func GetVoiceListByActivityIds(activityIds string) (list []*ActivityVoice, err error) {
+	if activityIds == "" {
+		return
+	}
+	o := orm.NewOrm()
+	sql := `select * from yb_activity_voice where activity_id in (` + activityIds + `) `
+	_, err = o.Raw(sql).QueryRows(&list)
+	return
+}

+ 34 - 0
models/yb/yb_speaker.go

@@ -0,0 +1,34 @@
+package yb
+
+import (
+	"rdluck_tools/orm"
+)
+
+// Speaker 活动表
+type Speaker struct {
+	SpeakerId            int    `orm:"column(speaker_id);pk" description:"主讲人ID"`
+	SpeakerName          string `description:"主讲人"`
+	SpeakerHeadPic       string `description:"主讲人头像"`
+	SpeakerBackgroundPic string `description:"主讲人背景图"`
+}
+
+// TableName 表名变更
+func (speaker *Speaker) TableName() string {
+	return "yb_speaker"
+}
+
+// GetSpeakerById 根据id获取主讲人详情
+func GetSpeakerById(id int) (item *Speaker, err error) {
+	o := orm.NewOrm()
+	sql := "select * from yb_speaker where speaker_id=? "
+	err = o.Raw(sql, id).QueryRow(&item)
+	return
+}
+
+// GetAllSpeakerList 获取所有主讲人列表数据
+func GetAllSpeakerList() (list []*Speaker, err error) {
+	o := orm.NewOrm()
+	sql := "select * from yb_speaker order by speaker_id desc "
+	_, err = o.Raw(sql).QueryRows(&list)
+	return
+}

+ 154 - 0
services/activity.go

@@ -0,0 +1,154 @@
+package services
+
+import (
+	"context"
+	"fmt"
+	"hongze/hongze_task/models"
+	"hongze/hongze_task/models/yb"
+	"hongze/hongze_task/utils"
+	"time"
+)
+
+// YbTelRemind 研报电话会提醒
+func YbTelRemind(cont context.Context) (err error) {
+	defer func() {
+		if err != nil {
+			//fmt.Println(utils.APPNAME+"【"+utils.RunMode+"】"+"失败提醒", "发送消息至同花顺失败 ErrMsg:"+err.Error(), utils.EmailSendToUsers)
+			go utils.SendEmail(utils.APPNAME+"【"+utils.RunMode+"】"+"失败提醒", "发送电话会提醒失败 ErrMsg:"+err.Error(), utils.EmailSendToUsers)
+		}
+	}()
+
+	condition := ""
+	pars := make([]interface{}, 0)
+
+	startTime := time.Now().Add(time.Second * 60 * 15).Format(utils.FormatDateTime) //15分钟后就要开始的会议
+	condition += ` and publish_status = 1 and is_send_wx_msg = 0 and is_delete = 0 and start_time <= ? and end_time >= now() `
+	pars = append(pars, startTime)
+
+	condition += ` and first_activity_type_id in (1,3) `
+
+	_, list, err := yb.GetList(condition, pars, 0, 1000)
+
+	for _, activityInfo := range list {
+		activityInfo.IsSendWxMsg = 1
+		activityInfo.Update([]string{"IsSendWxMsg"})
+		go sendWxMsg(activityInfo, "会议提醒")
+	}
+	return
+}
+
+// YbSalonRemind 研报沙龙提醒
+func YbSalonRemind(cont context.Context) (err error) {
+	defer func() {
+		if err != nil {
+			//fmt.Println(utils.APPNAME+"【"+utils.RunMode+"】"+"失败提醒", "发送消息至同花顺失败 ErrMsg:"+err.Error(), utils.EmailSendToUsers)
+			go utils.SendEmail(utils.APPNAME+"【"+utils.RunMode+"】"+"失败提醒", "发送电话会提醒失败 ErrMsg:"+err.Error(), utils.EmailSendToUsers)
+		}
+	}()
+
+	condition := ""
+	pars := make([]interface{}, 0)
+
+	startTime := time.Now().Add(time.Second * 60 * 60).Format(utils.FormatDateTime) //1小时后就要开始的沙龙
+	condition += ` and publish_status = 1 and is_send_salon_wx_msg = 0 and is_delete = 0 and start_time <= ? and end_time >= now() `
+	pars = append(pars, startTime)
+
+	condition += ` and first_activity_type_id =3 `
+
+	_, list, err := yb.GetList(condition, pars, 0, 1000)
+
+	for _, activityInfo := range list {
+		activityInfo.IsSendSalonWxMsg = 1
+		activityInfo.Update([]string{"IsSendSalonWxMsg"})
+		go sendWxMsg(activityInfo, "沙龙提醒")
+	}
+	return
+}
+
+func sendWxMsg(activityInfo *yb.Activity, remindType string) (err error) {
+	defer func() {
+		if err != nil {
+			fmt.Println(utils.APPNAME+"【"+utils.RunMode+"】"+"失败提醒", "发送电话会提醒失败 ErrMsg:"+err.Error())
+			utils.FileLog.Info(utils.APPNAME+"【"+utils.RunMode+"】"+"失败提醒", "发送电话会提醒失败 ErrMsg:"+err.Error())
+			//go utils.SendEmail(utils.APPNAME+"【"+utils.RunMode+"】"+"失败提醒", "发送电话会提醒失败 ErrMsg:"+err.Error(), utils.EmailSendToUsers)
+		}
+	}()
+
+	keyword4 := "- -"
+
+	//您有一场【橡胶双周报】将在15分钟后开始
+	timeStr := ``
+	userIdList := make([]string, 0) //提醒用户列表
+	if remindType == "会议提醒" {
+		timeStr = `15分钟`
+		list, tmpErr := yb.GetAllActivityRemindListByActivityId(activityInfo.ActivityId)
+		if tmpErr != nil {
+			err = tmpErr
+			return
+		}
+		for _, v := range list {
+			userIdList = append(userIdList, fmt.Sprint(v.UserId))
+		}
+
+	} else {
+		timeStr = `1小时`
+		list, tmpErr := yb.GetAllActivityRegisterListByActivityId(activityInfo.ActivityId)
+		if tmpErr != nil {
+			err = tmpErr
+			return
+		}
+		for _, v := range list {
+			userIdList = append(userIdList, fmt.Sprint(v.UserId))
+		}
+
+		keyword4 = activityInfo.Address
+	}
+
+	if len(userIdList) <= 0 {
+		return
+	}
+
+	first := `您有一场【` + activityInfo.ActivityTypeName + `】将在` + timeStr + `后开始`
+	keyword1 := activityInfo.ActivityName
+	keyword2 := "- -"
+	//keyword3 := `2021-10-18 16:30-17:00 星期一`
+	keyword3 := formatActivityTimeStr(activityInfo.StartTime, activityInfo.EndTime)
+
+	remark := `点击查看活动详情`
+
+	//获取所有用户的openid列表
+	openidList, err := models.GetUserOpenidListByUserIds(userIdList)
+	if err != nil {
+		return
+	}
+	//小程序跳转地址
+	wxAppPath := `pages-activity/detail?id=` + fmt.Sprint(activityInfo.ActivityId)
+	err = SendWxMsgWithActivityAppointmentRemind(first, keyword1, keyword2, keyword3, keyword4, remark, wxAppPath, openidList)
+	return
+}
+
+// formatActivityTimeStr 格式化活动的开始结束时间
+func formatActivityTimeStr(startTime, endTime time.Time) string {
+	startStr := startTime.Format("2006-01-02 15:04")
+	endStr := endTime.Format("15:04")
+	weekStr := ``
+	weekInt := startTime.Weekday()
+	switch weekInt {
+	case 0:
+		weekStr = `星期日`
+	case 1:
+		weekStr = `星期一`
+	case 2:
+		weekStr = `星期二`
+	case 3:
+		weekStr = `星期三`
+	case 4:
+		weekStr = `星期四`
+	case 5:
+		weekStr = `星期五`
+	case 6:
+		weekStr = `星期六`
+	}
+
+	return startStr + `-` + endStr + ` ` + weekStr
+}

+ 9 - 1
services/task.go

@@ -53,7 +53,13 @@ func Task() {
 	sendWaitReport := task.NewTask("sendWaitReport", "0 */1 * * * * ", SendWaitReport)
 	task.AddTask("定时往同花顺推送报告", sendWaitReport)
 
-	task.StartTask()
+	// 研报电话会提醒
+	ybTelRemind := task.NewTask("YbTelRemind", "0 */1 * * * * ", YbTelRemind)
+	task.AddTask("研报电话会提醒", ybTelRemind)
+
+	// 研报沙龙提醒
+	ybSalonRemind := task.NewTask("ybSalonRemind", "0 */1 * * * * ", YbSalonRemind)
+	task.AddTask("研报沙龙提醒", ybSalonRemind)
 	//GetHistoryLzProductDetail()
 	//GetLzPrice()
 	//GetLzProductDetail()
@@ -69,6 +75,8 @@ func Task() {
 	//每日用户阅读数据统计
 	statisticsUserView := task.NewTask("statisticsUserView", "0 5 2 * * *", StatisticsUserView)
 	task.AddTask("每日用户阅读数据统计", statisticsUserView)
+	
+	task.StartTask()
 
 	fmt.Println("task end")
 }

+ 42 - 2
services/wx_template_msg.go

@@ -59,7 +59,7 @@ func WxSendTemplateMsg(sendUrl string, sendMap map[string]interface{}, items []*
 			fmt.Println("SendTemplateMsgOne Marshal Err:", err.Error())
 			return err
 		}
-		utils.FileLog.Info("One SendData:%s", string(data))
+		utils.FileLog.Info(fmt.Sprintf("One SendData:%s", string(data)))
 		err = SendTemplateMsg(sendUrl, data)
 		if err != nil {
 			fmt.Println("send err:", err.Error())
@@ -78,7 +78,7 @@ func SendTemplateMsg(sendUrl string, data []byte) (err error) {
 	defer resp.Body.Close()
 
 	body, _ := ioutil.ReadAll(resp.Body)
-	utils.FileLog.Info("SendResult:%s", string(body))
+	utils.FileLog.Info(fmt.Sprintf("SendResult:%s", string(body)))
 	var templateResponse models.SendTemplateResponse
 	err = json.Unmarshal(body, &templateResponse)
 	if err != nil {
@@ -120,3 +120,43 @@ func SendWxMsgWithCompanyRemind(first, keyword1, keyword2, remark string, openId
 	WxSendTemplateMsg(sendUrl, sendMap, openIdList)
 	return
 }
+
+// SendWxMsgWithActivityAppointmentRemind 活动预约/报名时间通知
+func SendWxMsgWithActivityAppointmentRemind(first, keyword1, keyword2, keyword3, keyword4, remark, wxAppPath string, openIdList []*models.OpenIdList) (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)
+			utils.FileLog.Info(fmt.Sprintf("发送模版消息失败,Err:%s", err.Error()))
+		}
+	}()
+	utils.FileLog.Info("%s", "services SendMsg")
+	accessToken, err := models.GetWxAccessToken()
+	if err != nil {
+		msg = "GetWxAccessToken Err:" + err.Error()
+		return
+	}
+	if accessToken == "" {
+		msg = "accessToken is empty"
+		return
+	}
+
+	sendUrl := "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=" + accessToken
+	sendMap := make(map[string]interface{})
+	sendData := make(map[string]interface{})
+
+	sendMap["template_id"] = utils.AppointmentRemindTemplateId
+	sendData["first"] = map[string]interface{}{"value": first, "color": "#173177"}
+	sendData["activity_name"] = map[string]interface{}{"value": keyword1, "color": "#173177"}
+	sendData["reserve_results"] = map[string]interface{}{"value": keyword2, "color": "#173177"}
+	sendData["activity_time"] = map[string]interface{}{"value": keyword3, "color": "#173177"}
+	sendData["activity_address"] = map[string]interface{}{"value": keyword4, "color": "#173177"}
+	sendData["remark"] = map[string]interface{}{"value": remark, "color": "#173177"}
+
+	if wxAppPath != "" {
+		sendMap["miniprogram"] = map[string]interface{}{"appid": utils.WxYbAppId, "pagepath": wxAppPath}
+	}
+	sendMap["data"] = sendData
+	WxSendTemplateMsg(sendUrl, sendMap, openIdList)
+	return
+}

+ 12 - 4
utils/config.go

@@ -20,10 +20,14 @@ var (
 )
 
 var (
-	WxAppId          string
-	WxAppSecret      string
-	TemplateId       string
-	RemindTemplateId string
+	WxAppId                     string
+	WxAppSecret                 string
+	TemplateId                  string
+	RemindTemplateId            string
+	AppointmentRemindTemplateId string //活动预约通知模板id
+
+	WxYbAppId string //微信研报小程序
+
 )
 
 //oss配置
@@ -68,6 +72,8 @@ jRS9hreKFKb0BUQ4TB26e7IDCstbMRvUp4+OGezexzic5NYPQ8uLo5OTaS7f7PrW
 ZwIDAQAB
 -----END PUBLIC KEY-----`
 
+	WxYbAppId = "wxb059c872d79b9967" //弘则研报小程序
+
 	if RunMode == "release" {
 		CompanyId = 16
 		RealName = "超级管理员"
@@ -88,6 +94,8 @@ ZwIDAQAB
 		WxAppSecret = "f4d52e34021eee262dce9682b31f8861"
 		TemplateId = "pDk4o924gSZWj80ZdNnHodnLMIXjPSlKZU0ciQMOhec"
 		RemindTemplateId = "9JYV6sHMJlu2EHRBIj_8ift6wkrrTb9_UO-M_-YXKBw"
+		AppointmentRemindTemplateId = `Y59n_AHg-RLCKaz293geW76KDHpGL1qOnE7eF_lxelY` //活动预约通知模板id
+
 		//同花顺测试地址
 		THS_SendUrl = `https://mtest.10jqka.com.cn/gateway/ps/syncNews`
 		THS_SyncWxGroupUrl = `https://mtest.10jqka.com.cn/gateway/ps/syncWechatGroupInfo`