go-common/app/job/main/up/service/sign_due_job.go
2019-04-22 18:49:16 +08:00

296 lines
7.8 KiB
Go

package service
import (
"bytes"
"context"
"errors"
"fmt"
"html/template"
"time"
//"go-common/app/job/main/up/conf"
"go-common/app/admin/main/up/util"
"go-common/app/job/main/up/dao/upcrm"
"go-common/app/job/main/up/model/signmodel"
"go-common/app/job/main/up/model/upcrmmodel"
account "go-common/app/service/main/account/model"
"go-common/library/log"
"go-common/app/job/main/up/conf"
)
var (
//ErrNoAdminName no admin name
ErrNoAdminName = errors.New("no admin name")
tmplSignDueTitle *template.Template
tmplSignDueContent *template.Template
tmplPayDueTitle *template.Template
tmplPayDueContent *template.Template
tmplTaskDueTitle *template.Template
tmplTaskDueContent *template.Template
)
// use for template function call
var funcHelper = template.FuncMap{
"Now": time.Now,
}
func (s *Service) initEmailTemplate() (err error) {
if conf.Conf.MailTemplateConf.SignTmplTitle == "" ||
conf.Conf.MailTemplateConf.SignTmplContent == "" ||
conf.Conf.MailTemplateConf.PayTmplTitle == "" ||
conf.Conf.MailTemplateConf.PayTmplContent == "" ||
conf.Conf.MailTemplateConf.TaskTmplTitle == "" ||
conf.Conf.MailTemplateConf.TaskTmplContent == "" {
err = fmt.Errorf(`mail template conf is invalid, check mail-template.toml file, make sure all the following has value:
TaskTmplContent
TaskTmplTitle
PayTmplContent
PayTmplTitle
SignTmplContent
SignTmplTitle`)
return
}
tmplSignDueTitle, err = template.New("signTitle").Funcs(funcHelper).Parse(conf.Conf.MailTemplateConf.SignTmplTitle)
if err != nil {
log.Error("parse template fail, err=%v", err)
return
}
tmplSignDueContent, err = template.New("signContent").Funcs(funcHelper).Parse(conf.Conf.MailTemplateConf.SignTmplContent)
if err != nil {
log.Error("parse template fail, err=%v", err)
return
}
tmplPayDueTitle, err = template.New("payTitle").Funcs(funcHelper).Parse(conf.Conf.MailTemplateConf.PayTmplTitle)
if err != nil {
log.Error("parse template fail, err=%v", err)
return
}
tmplPayDueContent, err = template.New("payContent").Funcs(funcHelper).Parse(conf.Conf.MailTemplateConf.PayTmplContent)
if err != nil {
log.Error("parse template fail, err=%v", err)
return
}
tmplTaskDueTitle, err = template.New("taskTitle").Funcs(funcHelper).Parse(conf.Conf.MailTemplateConf.TaskTmplTitle)
if err != nil {
log.Error("parse template fail, err=%v", err)
return
}
tmplTaskDueContent, err = template.New("taskContent").Funcs(funcHelper).Parse(conf.Conf.MailTemplateConf.TaskTmplContent)
if err != nil {
log.Error("parse template fail, err=%v", err)
return
}
return
}
//CheckDateDueJob check task due
/*
快到期的job提醒
*/
func (s *Service) CheckDateDueJob(date time.Time) {
log.Info("start run CheckDateDueJob, date=%s", date)
s.checkSignUpDue(date)
log.Info("finish run CheckDateDueJob, date=%s", date)
}
type dueData struct {
Signs []*upcrm.SignWithName
Pays []*upcrm.PayWithAdmin
Tasks []*upcrm.TaskWithAdmin
}
func (d *dueData) addSign(sign *upcrm.SignWithName) {
d.Signs = append(d.Signs, sign)
}
func (d *dueData) addPay(pay *upcrm.PayWithAdmin) {
d.Pays = append(d.Pays, pay)
}
func (d *dueData) addTask(task *upcrm.TaskWithAdmin) {
d.Tasks = append(d.Tasks, task)
}
func getOrCreate(dataMap map[string]*dueData, key string) *dueData {
var data, ok = dataMap[key]
if !ok {
data = &dueData{}
dataMap[key] = data
}
return data
}
func getName(infoMap map[int64]*account.Info, mid int64) string {
if info, ok := infoMap[mid]; ok {
return info.Name
}
return ""
}
func (s *Service) checkSignUpDue(date time.Time) {
// 30天内到期 sign
list, err := s.crmdb.GetDueSignUp(date, 30)
s.crmdb.StartTask(upcrmmodel.TaskTypeSignCheckDue, date)
defer func() {
if err == nil {
s.crmdb.FinishTask(upcrmmodel.TaskTypeSignCheckDue, date, upcrmmodel.TaskStateFinish)
} else {
s.crmdb.FinishTask(upcrmmodel.TaskTypeSignCheckDue, date, upcrmmodel.TaskStateError)
}
}()
if err != nil {
log.Error("fail to get due sign, date=%+v, err=%+v", date, err)
return
}
var adminDueDataMap = make(map[string]*dueData)
var ids []int64
for _, v := range list {
ids = append(ids, v.Mid)
var data = getOrCreate(adminDueDataMap, v.AdminName)
data.addSign(v)
}
// 7天内到期的pay
listPayDue, err := s.crmdb.GetDuePay(date, 7)
if err != nil {
log.Error("fail to get due pay, date=%+v, err=%+v", date, err)
return
}
for _, v := range listPayDue {
ids = append(ids, v.Mid)
var data = getOrCreate(adminDueDataMap, v.AdminName)
data.addPay(v)
}
// 到期的任务,
listTaskDue, err := s.crmdb.GetDueTask(date)
if err != nil {
log.Error("fail to get due task, date=%+v, err=%+v", date, err)
return
}
for _, v := range listTaskDue {
ids = append(ids, v.Mid)
var data = getOrCreate(adminDueDataMap, v.AdminName)
data.addTask(v)
}
ids = util.Unique(ids)
infoMap, e := s.acc.GetCachedInfos(context.Background(), ids, "")
if e == nil {
for _, v := range list {
v.Name = getName(infoMap, v.Mid)
}
for _, v := range listPayDue {
v.Name = getName(infoMap, v.Mid)
}
for _, v := range listTaskDue {
v.Name = getName(infoMap, v.Mid)
}
}
for admin, v := range adminDueDataMap {
var adminAll = append(conf.Conf.MailConf.DueMailReceivers, admin)
// 发送sign到期邮件
var due = v
s.worker.Add(func() {
var succIds []uint32
if len(due.Signs) > 0 {
var e = s.sendMailWithTemplate(due.Signs, tmplSignDueTitle, tmplSignDueContent, adminAll...)
if e == nil {
for _, data := range due.Signs {
succIds = append(succIds, data.ID)
}
} else {
log.Warn("fail to send email, err=%v", e)
}
// 更新邮件发送标记
s.crmdb.UpdateEmailState(signmodel.TableNameSignUp, succIds, signmodel.EmailStateSendSucc)
}
if len(due.Pays) > 0 {
// 发送pay到期邮件
succIds = nil
e = s.sendMailWithTemplate(due.Pays, tmplPayDueTitle, tmplPayDueContent, adminAll...)
if e == nil {
for _, data := range due.Pays {
succIds = append(succIds, data.ID)
}
} else {
log.Warn("fail to send email, err=%v", e)
}
// 更新邮件发送标记
s.crmdb.UpdateEmailState(signmodel.TableNameSignPay, succIds, signmodel.EmailStateSendSucc)
}
if len(due.Tasks) > 0 {
// 发送task到期邮件
e = s.sendMailWithTemplate(due.Tasks, tmplTaskDueTitle, tmplTaskDueContent, adminAll...)
if e != nil {
log.Warn("fail to send email, err=%v", e)
}
// 这个没有邮件发送的标记
//s.crmdb.UpdateEmailState(signmodel.TableNameSignPay, succIds, signmodel.EmailStateSendSucc)
}
})
}
}
// data, data to generate email content
// contentTmpl, template to generate email content
// adminname, slice for all admin name
//
func (s *Service) sendMailWithTemplate(data interface{}, subjectTmpl, contentTmpl *template.Template, adminName ...string) (err error) {
if contentTmpl == nil {
err = fmt.Errorf("template for email is nil, data=%+v", data)
log.Error("%s", err)
return
}
var contentBuf = bytes.NewBuffer(nil)
err = contentTmpl.Execute(contentBuf, data)
if err != nil {
log.Error("template fail to execute, err=%v", err)
return
}
var subjectBuf = bytes.NewBuffer(nil)
err = subjectTmpl.Execute(subjectBuf, data)
if err != nil {
log.Error("template fail to execute, err=%v", err)
return
}
var addrs []string
for _, v := range adminName {
if v == "" {
log.Warn("admin name is empty")
continue
}
var addr = fmt.Sprintf("%s@bilibili.com", v)
addrs = append(addrs, addr)
}
//log.Info("email sub=%s, content=%s", subjectBuf.String(), contentBuf.String())
if len(addrs) == 0 {
log.Error("admin name is empty, cannot send email, data=%+v", data)
err = ErrNoAdminName
return
}
log.Info("email send , sub=%s, admin=%s, data=%+v", subjectBuf.String(), adminName, data)
err = s.maildao.SendMail(contentBuf.String(), subjectBuf.String(), addrs)
return
}