作者 tangxvhui

更新 定时任务

package notify
import "gitlab.fjmaimaimai.com/allied-creation/performance/pkg/domain"
var TaskSmsNotify *notifySms
func RunTaskSmsNotify() {
newSmsNotify := notifySms{}
newSmsNotify.regist(notifyStaffAssess{})
newSmsNotify.regist(notifySummaryEvaluation{})
newSmsNotify.runTask()
}
// 每日自评短信通知 ,预创建待发送的短信消息
func AddNotifyStaffAssess(param *domain.StaffAssess) {
newNotify := notifyStaffAssess{}
newSms := newNotify.makeNotify(param)
TaskSmsNotify.addTask(newSms)
}
// 周期自评短信通知 ,预创建待发送的短信消息
func AddNotifySummaryEvaluation(param *domain.SummaryEvaluation) {
newNotify := notifySummaryEvaluation{}
newSms := newNotify.makeNotify(param)
TaskSmsNotify.addTask(newSms)
}
... ...
package notify
import (
"fmt"
"time"
"gitlab.fjmaimaimai.com/allied-creation/performance/pkg/application/factory"
"gitlab.fjmaimaimai.com/allied-creation/performance/pkg/constant"
"gitlab.fjmaimaimai.com/allied-creation/performance/pkg/domain"
"gitlab.fjmaimaimai.com/allied-creation/performance/pkg/infrastructure/serviceGateway"
"gitlab.fjmaimaimai.com/allied-creation/performance/pkg/log"
)
type notifySendOrNot interface {
from() string
ifSend(index int) (bool, error)
}
// 短信通知
type notifySms struct {
newSms chan *domain.LogSms
interval time.Duration
sendOrNot map[string]notifySendOrNot //到点后判断是否真的发送短信消息
}
func (notices *notifySms) init() {
notices.newSms = make(chan *domain.LogSms, 50)
notices.interval = 10 * time.Minute
if constant.Env != "prd" {
notices.interval = 1 * time.Minute
}
notices.sendOrNot = map[string]notifySendOrNot{}
}
func (notices *notifySms) regist(ifsend notifySendOrNot) {
notices.sendOrNot[ifsend.from()] = ifsend
}
func (notices *notifySms) addTask(task *domain.LogSms) {
notices.newSms <- task
}
// RunTask 执行短信通知任务
func (notices *notifySms) runTask() {
notices.init()
timer := time.NewTimer(notices.interval)
for {
select {
case newSms := <-notices.newSms:
err := notices.addNewSms(newSms)
if err != nil {
e := fmt.Sprintf("添加短信通知任务:%+v %s", newSms, err)
log.Logger.Error(e)
}
case <-timer.C:
err := notices.checkSendSms()
if err != nil {
log.Logger.Error("检查发送短信通知任务:" + err.Error())
}
timer.Reset(notices.interval) // 重置定时
}
}
}
func (notices *notifySms) addNewSms(newSms *domain.LogSms) error {
transactionContext, err := factory.CreateTransactionContext(nil)
if err != nil {
return err
}
if err := transactionContext.StartTransaction(); err != nil {
return err
}
defer func() {
_ = transactionContext.RollbackTransaction()
}()
logSmsRepo := factory.CreateLogSmsRepository(map[string]interface{}{"transactionContext": transactionContext})
err = logSmsRepo.Save(newSms)
if err != nil {
return err
}
if err := transactionContext.CommitTransaction(); err != nil {
return err
}
return nil
}
func (notices *notifySms) checkSendSms() error {
transactionContext, err := factory.CreateTransactionContext(nil)
if err != nil {
return err
}
if err := transactionContext.StartTransaction(); err != nil {
return err
}
defer func() {
_ = transactionContext.RollbackTransaction()
}()
logSmsRepo := factory.CreateLogSmsRepository(map[string]interface{}{"transactionContext": transactionContext})
nowTime := time.Now()
nowDay := dayZeroTime(nowTime)
_, logSmsList, err := logSmsRepo.Find(map[string]interface{}{
"status": string(domain.SmsWait),
"executeAtBegin": nowDay,
"executeAtEnd": nowTime,
})
if err != nil {
return err
}
if err := transactionContext.CommitTransaction(); err != nil {
return err
}
for _, v := range logSmsList {
err = notices.sendSms(v)
if err != nil {
e := fmt.Sprintf("发送短信通知:%+v %s", *v, err)
log.Logger.Error(e)
}
}
return nil
}
func (notices *notifySms) sendSms(param *domain.LogSms) error {
//单开处理 数据保存操作,发一条短信更新一条数据
transactionContext, err := factory.CreateTransactionContext(nil)
if err != nil {
return err
}
if err := transactionContext.StartTransaction(); err != nil {
return err
}
defer func() {
_ = transactionContext.RollbackTransaction()
}()
logSmsRepo := factory.CreateLogSmsRepository(map[string]interface{}{"transactionContext": transactionContext})
sendOk := false
sendOrNot, ok := notices.sendOrNot[param.From]
if ok {
ok, err := sendOrNot.ifSend(param.Index)
if err != nil {
param.Result = err.Error()
}
sendOk = ok
} else {
sendOk = true
}
if !sendOk {
param.Status = domain.SmsIgnore
} else {
sms := serviceGateway.SmsService{}
err = sms.SendNoticeSms(param.Phone, param.TemplateId, param.Value)
if err != nil {
param.Result = err.Error()
} else {
param.Status = domain.SmsSuccess
}
}
err = logSmsRepo.Save(param)
if err != nil {
return err
}
if err := transactionContext.CommitTransaction(); err != nil {
return err
}
return nil
}
func dayZeroTime(t time.Time) time.Time {
y, m, d := t.UTC().Date()
t2 := time.Date(y, m, d, 0, 0, 0, 0, time.UTC)
return t2
}
... ...
package notify
import (
"fmt"
"time"
"gitlab.fjmaimaimai.com/allied-creation/performance/pkg/application/factory"
"gitlab.fjmaimaimai.com/allied-creation/performance/pkg/constant"
"gitlab.fjmaimaimai.com/allied-creation/performance/pkg/domain"
"gitlab.fjmaimaimai.com/allied-creation/performance/pkg/log"
)
// 短信通知
// 每日自评短信通知
// 条件:每日自评结束前30分钟,且还未完成评估填写
type NotifyStaffAssess struct {
newSms chan *domain.LogSms
interval time.Duration
type notifyStaffAssess struct {
}
func (notices *NotifyStaffAssess) init() {
notices.newSms = make(chan *domain.LogSms, 50)
notices.interval = 10 * time.Minute
if constant.Env != "prd" {
notices.interval = 1 * time.Minute
}
}
func (notices *NotifyStaffAssess) From() string {
func (notices notifyStaffAssess) from() string {
return "StaffAssess"
}
// AddTask 添加待执行的短信通知任务
func (notices *NotifyStaffAssess) AddTask(index int, phone string, param map[string]string, executeAt time.Time) {
newSms := &domain.LogSms{
// makeNotify 生成待执行的短信通知内容
func (notices notifyStaffAssess) makeNotify(param *domain.StaffAssess) *domain.LogSms {
newSms := domain.LogSms{
Id: 0,
Phone: phone,
Phone: param.Executor.Account,
TemplateId: 5475050,
Template: "您好,#name#,百忙之中不要忘记填写今天的绩效自评反馈哦",
Value: param,
Result: "",
Status: domain.SmsWait,
From: notices.From(),
Index: index,
ExecuteAt: executeAt,
CreatedAt: time.Now(),
Value: map[string]string{
"name": param.Executor.UserName,
},
Result: "",
Status: domain.SmsWait,
From: notices.from(),
Index: param.Id,
// ExecuteAt: executeAt,
CreatedAt: time.Now(),
}
notices.newSms <- newSms
// 每日自评 结束前30 分钟
newSms.ExecuteAt = param.EndTime.Add(-1800 * time.Second)
return &newSms
}
// RunTask 执行短信通知任务
func (notices *NotifyStaffAssess) RunTask() {
notices.init()
timer := time.NewTimer(notices.interval)
for {
select {
case newSms := <-notices.newSms:
err := notices.addNewSms(newSms)
if err != nil {
e := fmt.Sprintf("添加短信通知任务:%+v %s", newSms, err)
log.Logger.Error(e)
}
case <-timer.C:
err := notices.sendSms()
if err != nil {
log.Logger.Error("发送短信通知任务:" + err.Error())
}
timer.Reset(notices.interval) // 重置定时
}
}
}
func (notices *NotifyStaffAssess) addNewSms(newSms *domain.LogSms) error {
// ifSendSms 确认是否发送通知
func (notices notifyStaffAssess) ifSend(index int) (bool, error) {
transactionContext, err := factory.CreateTransactionContext(nil)
if err != nil {
return err
return false, err
}
if err := transactionContext.StartTransaction(); err != nil {
return err
return false, err
}
defer func() {
_ = transactionContext.RollbackTransaction()
}()
logSmsRepo := factory.CreateLogSmsRepository(map[string]interface{}{"transactionContext": transactionContext})
err = logSmsRepo.Save(newSms)
if err != nil {
return err
}
if err := transactionContext.CommitTransaction(); err != nil {
return err
}
return nil
}
func (notices *NotifyStaffAssess) sendSms() error {
transactionContext, err := factory.CreateTransactionContext(nil)
staffAssessRepo := factory.CreateStaffAssessRepository(map[string]interface{}{"transactionContext": transactionContext})
assessData, err := staffAssessRepo.FindOne(map[string]interface{}{"id": index})
if err != nil {
return err
return false, err
}
if err := transactionContext.StartTransaction(); err != nil {
return err
//还未完成评估填写,时发送短信
if assessData.Status == domain.StaffAssessUncompleted {
return true, nil
}
defer func() {
_ = transactionContext.RollbackTransaction()
}()
logSmsRepo := factory.CreateLogSmsRepository(map[string]interface{}{"transactionContext": transactionContext})
_ = logSmsRepo
if err := transactionContext.CommitTransaction(); err != nil {
return err
return false, err
}
return nil
return false, nil
}
... ...
package notify
import (
"time"
"gitlab.fjmaimaimai.com/allied-creation/performance/pkg/application/factory"
"gitlab.fjmaimaimai.com/allied-creation/performance/pkg/domain"
)
// 周期评估短信通知
// 条件:周期自评结束前4个小时,且还未完成评估填写
type NotifySummaryEvaluation struct {
}
func (notices *NotifySummaryEvaluation) Init() *NotifySummaryEvaluation {
return &NotifySummaryEvaluation{}
type notifySummaryEvaluation struct {
}
func (notices *NotifySummaryEvaluation) From() string {
func (notices notifySummaryEvaluation) from() string {
return "SummaryEvaluation"
}
// AddTask 添加待执行的短信通知任务
func (notices *NotifySummaryEvaluation) AddTask(index string, phone string, param map[string]string) error {
return nil
}
// RunTask 执行短信通知任务
func (notice *NotifySummaryEvaluation) RunTask() error {
return nil
// makeNotify 生成待执行的短信通知内容
func (notices notifySummaryEvaluation) makeNotify(param *domain.SummaryEvaluation) *domain.LogSms {
newSms := domain.LogSms{
Id: 0,
Phone: param.Executor.Account,
TemplateId: 5536232,
Template: "您好,#name#,百忙之中不要忘记填写本月综合自评哦",
Value: map[string]string{
"name": param.Executor.UserName,
},
Result: "",
Status: domain.SmsWait,
From: notices.from(),
Index: param.Id,
// ExecuteAt: executeAt,
CreatedAt: time.Now(),
}
// 周期自评结束前4个小时,
newSms.ExecuteAt = param.EndTime.Add(-4 * time.Hour)
return &newSms
}
func (notice *NotifySummaryEvaluation) addNewSms(newSms *domain.LogSms) error {
// ifSendSms 确认是否发送通知
func (notices notifySummaryEvaluation) ifSend(index int) (bool, error) {
transactionContext, err := factory.CreateTransactionContext(nil)
if err != nil {
return err
return false, err
}
if err := transactionContext.StartTransaction(); err != nil {
return err
return false, err
}
defer func() {
_ = transactionContext.RollbackTransaction()
}()
logSmsRepo := factory.CreateLogSmsRepository(map[string]interface{}{"transactionContext": transactionContext})
err = logSmsRepo.Save(newSms)
summaryEvaluationRepo := factory.CreateSummaryEvaluationRepository(map[string]interface{}{"transactionContext": transactionContext})
summaryEvaluationData, err := summaryEvaluationRepo.FindOne(map[string]interface{}{"id": index})
if err != nil {
return err
return false, err
}
//还未完成评估填写,时发送短信
if summaryEvaluationData.Status == domain.EvaluationUncompleted {
return true, nil
}
if err := transactionContext.CommitTransaction(); err != nil {
return err
return false, err
}
return nil
return false, nil
}
... ...
... ... @@ -328,6 +328,3 @@ func sendSmsEvalation(param []domain.SummaryEvaluation) error {
}
return nil
}
//周期自评 短信提醒
//周期自评 结束前 4个小时发送
... ...
... ... @@ -5,26 +5,24 @@ import "time"
//记录 发送的短信消息
type LogSms struct {
Id int
Phone string
TemplateId int
Template string
Value map[string]string
Result string
Status SmsStatus
From string //业务来源
Index int //业务数据索引
ExecuteAt time.Time
CreatedAt time.Time
Id int `json:"id"`
Phone string `json:"phone"`
TemplateId int `json:"templateId"`
Template string `json:"template"`
Value map[string]string `json:"value"`
Result string `json:"result"`
Status SmsStatus `json:"status"`
From string `json:"from"` //业务来源
Index int `json:"index"` //业务数据索引
ExecuteAt time.Time `json:"executeAt"`
CreatedAt time.Time `json:"createdAt"`
}
type SmsStatus string
const (
SmsWait SmsStatus = "wait" //等待执行
SmsInit SmsStatus = "init" //正在执行
SmsSuccess SmsStatus = "success" //执行成功
SmsFailed SmsStatus = "failed" //执行失败
SmsIgnore SmsStatus = "ignore" //忽略执行
)
... ...
... ... @@ -63,20 +63,16 @@ func (repo *LogSmsRepository) Find(queryOptions map[string]interface{}) (int, []
query.Offset(v)
}
if v, ok := queryOptions["form"]; ok {
query.Where("from=?", v)
}
if v, ok := queryOptions["index"]; ok {
query.Where("index=?", v)
}
if v, ok := queryOptions["status"]; ok {
query.Where("status=?", v)
}
if v, ok := queryOptions["executeAt"]; ok {
query.Where("execute_at=?", v)
if v, ok := queryOptions["executeAtBegin"]; ok {
query.Where("execute_at>=?", v)
}
if v, ok := queryOptions["executeAtEnd"]; ok {
query.Where("execute_at<=?", v)
}
count, err := query.SelectAndCount()
... ...