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 = 5 * 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 err := notices.addNewSms(task) if err != nil { e := fmt.Sprintf("添加短信通知任务:%+v %s", task, err) log.Logger.Error(e) } } // RunTask 执行短信通知任务 func (notices *notifySms) runTask() { 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: nowTime := time.Now() err := notices.checkSendSms() if err != nil { log.Logger.Error("检查发送短信通知任务:" + err.Error()) } log.Logger.Info(fmt.Sprintf("检查发送短信通知任务消耗时间:%.2f s", time.Since(nowTime).Seconds())) timer.Reset(notices.interval) // 重置定时 } } } // addNewSms 添加新的通知消息 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 } // checkSendSms 检查发送短信通知 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 } // sendSms 发送短信消息 func (notices *notifySms) sendSms(param *domain.LogSms) error { if constant.Env != "prd" { return nil } //单开处理 数据保存操作,发一条短信更新一条数据 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() param.Status = domain.SmsSuccess } 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.Local().Date() t2 := time.Date(y, m, d, 0, 0, 0, 0, time.Local) return t2 }