sign_due_job.go 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295
  1. package service
  2. import (
  3. "bytes"
  4. "context"
  5. "errors"
  6. "fmt"
  7. "html/template"
  8. "time"
  9. //"go-common/app/job/main/up/conf"
  10. "go-common/app/admin/main/up/util"
  11. "go-common/app/job/main/up/dao/upcrm"
  12. "go-common/app/job/main/up/model/signmodel"
  13. "go-common/app/job/main/up/model/upcrmmodel"
  14. account "go-common/app/service/main/account/model"
  15. "go-common/library/log"
  16. "go-common/app/job/main/up/conf"
  17. )
  18. var (
  19. //ErrNoAdminName no admin name
  20. ErrNoAdminName = errors.New("no admin name")
  21. tmplSignDueTitle *template.Template
  22. tmplSignDueContent *template.Template
  23. tmplPayDueTitle *template.Template
  24. tmplPayDueContent *template.Template
  25. tmplTaskDueTitle *template.Template
  26. tmplTaskDueContent *template.Template
  27. )
  28. // use for template function call
  29. var funcHelper = template.FuncMap{
  30. "Now": time.Now,
  31. }
  32. func (s *Service) initEmailTemplate() (err error) {
  33. if conf.Conf.MailTemplateConf.SignTmplTitle == "" ||
  34. conf.Conf.MailTemplateConf.SignTmplContent == "" ||
  35. conf.Conf.MailTemplateConf.PayTmplTitle == "" ||
  36. conf.Conf.MailTemplateConf.PayTmplContent == "" ||
  37. conf.Conf.MailTemplateConf.TaskTmplTitle == "" ||
  38. conf.Conf.MailTemplateConf.TaskTmplContent == "" {
  39. err = fmt.Errorf(`mail template conf is invalid, check mail-template.toml file, make sure all the following has value:
  40. TaskTmplContent
  41. TaskTmplTitle
  42. PayTmplContent
  43. PayTmplTitle
  44. SignTmplContent
  45. SignTmplTitle`)
  46. return
  47. }
  48. tmplSignDueTitle, err = template.New("signTitle").Funcs(funcHelper).Parse(conf.Conf.MailTemplateConf.SignTmplTitle)
  49. if err != nil {
  50. log.Error("parse template fail, err=%v", err)
  51. return
  52. }
  53. tmplSignDueContent, err = template.New("signContent").Funcs(funcHelper).Parse(conf.Conf.MailTemplateConf.SignTmplContent)
  54. if err != nil {
  55. log.Error("parse template fail, err=%v", err)
  56. return
  57. }
  58. tmplPayDueTitle, err = template.New("payTitle").Funcs(funcHelper).Parse(conf.Conf.MailTemplateConf.PayTmplTitle)
  59. if err != nil {
  60. log.Error("parse template fail, err=%v", err)
  61. return
  62. }
  63. tmplPayDueContent, err = template.New("payContent").Funcs(funcHelper).Parse(conf.Conf.MailTemplateConf.PayTmplContent)
  64. if err != nil {
  65. log.Error("parse template fail, err=%v", err)
  66. return
  67. }
  68. tmplTaskDueTitle, err = template.New("taskTitle").Funcs(funcHelper).Parse(conf.Conf.MailTemplateConf.TaskTmplTitle)
  69. if err != nil {
  70. log.Error("parse template fail, err=%v", err)
  71. return
  72. }
  73. tmplTaskDueContent, err = template.New("taskContent").Funcs(funcHelper).Parse(conf.Conf.MailTemplateConf.TaskTmplContent)
  74. if err != nil {
  75. log.Error("parse template fail, err=%v", err)
  76. return
  77. }
  78. return
  79. }
  80. //CheckDateDueJob check task due
  81. /*
  82. 快到期的job提醒
  83. */
  84. func (s *Service) CheckDateDueJob(date time.Time) {
  85. log.Info("start run CheckDateDueJob, date=%s", date)
  86. s.checkSignUpDue(date)
  87. log.Info("finish run CheckDateDueJob, date=%s", date)
  88. }
  89. type dueData struct {
  90. Signs []*upcrm.SignWithName
  91. Pays []*upcrm.PayWithAdmin
  92. Tasks []*upcrm.TaskWithAdmin
  93. }
  94. func (d *dueData) addSign(sign *upcrm.SignWithName) {
  95. d.Signs = append(d.Signs, sign)
  96. }
  97. func (d *dueData) addPay(pay *upcrm.PayWithAdmin) {
  98. d.Pays = append(d.Pays, pay)
  99. }
  100. func (d *dueData) addTask(task *upcrm.TaskWithAdmin) {
  101. d.Tasks = append(d.Tasks, task)
  102. }
  103. func getOrCreate(dataMap map[string]*dueData, key string) *dueData {
  104. var data, ok = dataMap[key]
  105. if !ok {
  106. data = &dueData{}
  107. dataMap[key] = data
  108. }
  109. return data
  110. }
  111. func getName(infoMap map[int64]*account.Info, mid int64) string {
  112. if info, ok := infoMap[mid]; ok {
  113. return info.Name
  114. }
  115. return ""
  116. }
  117. func (s *Service) checkSignUpDue(date time.Time) {
  118. // 30天内到期 sign
  119. list, err := s.crmdb.GetDueSignUp(date, 30)
  120. s.crmdb.StartTask(upcrmmodel.TaskTypeSignCheckDue, date)
  121. defer func() {
  122. if err == nil {
  123. s.crmdb.FinishTask(upcrmmodel.TaskTypeSignCheckDue, date, upcrmmodel.TaskStateFinish)
  124. } else {
  125. s.crmdb.FinishTask(upcrmmodel.TaskTypeSignCheckDue, date, upcrmmodel.TaskStateError)
  126. }
  127. }()
  128. if err != nil {
  129. log.Error("fail to get due sign, date=%+v, err=%+v", date, err)
  130. return
  131. }
  132. var adminDueDataMap = make(map[string]*dueData)
  133. var ids []int64
  134. for _, v := range list {
  135. ids = append(ids, v.Mid)
  136. var data = getOrCreate(adminDueDataMap, v.AdminName)
  137. data.addSign(v)
  138. }
  139. // 7天内到期的pay
  140. listPayDue, err := s.crmdb.GetDuePay(date, 7)
  141. if err != nil {
  142. log.Error("fail to get due pay, date=%+v, err=%+v", date, err)
  143. return
  144. }
  145. for _, v := range listPayDue {
  146. ids = append(ids, v.Mid)
  147. var data = getOrCreate(adminDueDataMap, v.AdminName)
  148. data.addPay(v)
  149. }
  150. // 到期的任务,
  151. listTaskDue, err := s.crmdb.GetDueTask(date)
  152. if err != nil {
  153. log.Error("fail to get due task, date=%+v, err=%+v", date, err)
  154. return
  155. }
  156. for _, v := range listTaskDue {
  157. ids = append(ids, v.Mid)
  158. var data = getOrCreate(adminDueDataMap, v.AdminName)
  159. data.addTask(v)
  160. }
  161. ids = util.Unique(ids)
  162. infoMap, e := s.acc.GetCachedInfos(context.Background(), ids, "")
  163. if e == nil {
  164. for _, v := range list {
  165. v.Name = getName(infoMap, v.Mid)
  166. }
  167. for _, v := range listPayDue {
  168. v.Name = getName(infoMap, v.Mid)
  169. }
  170. for _, v := range listTaskDue {
  171. v.Name = getName(infoMap, v.Mid)
  172. }
  173. }
  174. for admin, v := range adminDueDataMap {
  175. var adminAll = append(conf.Conf.MailConf.DueMailReceivers, admin)
  176. // 发送sign到期邮件
  177. var due = v
  178. s.worker.Add(func() {
  179. var succIds []uint32
  180. if len(due.Signs) > 0 {
  181. var e = s.sendMailWithTemplate(due.Signs, tmplSignDueTitle, tmplSignDueContent, adminAll...)
  182. if e == nil {
  183. for _, data := range due.Signs {
  184. succIds = append(succIds, data.ID)
  185. }
  186. } else {
  187. log.Warn("fail to send email, err=%v", e)
  188. }
  189. // 更新邮件发送标记
  190. s.crmdb.UpdateEmailState(signmodel.TableNameSignUp, succIds, signmodel.EmailStateSendSucc)
  191. }
  192. if len(due.Pays) > 0 {
  193. // 发送pay到期邮件
  194. succIds = nil
  195. e = s.sendMailWithTemplate(due.Pays, tmplPayDueTitle, tmplPayDueContent, adminAll...)
  196. if e == nil {
  197. for _, data := range due.Pays {
  198. succIds = append(succIds, data.ID)
  199. }
  200. } else {
  201. log.Warn("fail to send email, err=%v", e)
  202. }
  203. // 更新邮件发送标记
  204. s.crmdb.UpdateEmailState(signmodel.TableNameSignPay, succIds, signmodel.EmailStateSendSucc)
  205. }
  206. if len(due.Tasks) > 0 {
  207. // 发送task到期邮件
  208. e = s.sendMailWithTemplate(due.Tasks, tmplTaskDueTitle, tmplTaskDueContent, adminAll...)
  209. if e != nil {
  210. log.Warn("fail to send email, err=%v", e)
  211. }
  212. // 这个没有邮件发送的标记
  213. //s.crmdb.UpdateEmailState(signmodel.TableNameSignPay, succIds, signmodel.EmailStateSendSucc)
  214. }
  215. })
  216. }
  217. }
  218. // data, data to generate email content
  219. // contentTmpl, template to generate email content
  220. // adminname, slice for all admin name
  221. //
  222. func (s *Service) sendMailWithTemplate(data interface{}, subjectTmpl, contentTmpl *template.Template, adminName ...string) (err error) {
  223. if contentTmpl == nil {
  224. err = fmt.Errorf("template for email is nil, data=%+v", data)
  225. log.Error("%s", err)
  226. return
  227. }
  228. var contentBuf = bytes.NewBuffer(nil)
  229. err = contentTmpl.Execute(contentBuf, data)
  230. if err != nil {
  231. log.Error("template fail to execute, err=%v", err)
  232. return
  233. }
  234. var subjectBuf = bytes.NewBuffer(nil)
  235. err = subjectTmpl.Execute(subjectBuf, data)
  236. if err != nil {
  237. log.Error("template fail to execute, err=%v", err)
  238. return
  239. }
  240. var addrs []string
  241. for _, v := range adminName {
  242. if v == "" {
  243. log.Warn("admin name is empty")
  244. continue
  245. }
  246. var addr = fmt.Sprintf("%s@bilibili.com", v)
  247. addrs = append(addrs, addr)
  248. }
  249. //log.Info("email sub=%s, content=%s", subjectBuf.String(), contentBuf.String())
  250. if len(addrs) == 0 {
  251. log.Error("admin name is empty, cannot send email, data=%+v", data)
  252. err = ErrNoAdminName
  253. return
  254. }
  255. log.Info("email send , sub=%s, admin=%s, data=%+v", subjectBuf.String(), adminName, data)
  256. err = s.maildao.SendMail(contentBuf.String(), subjectBuf.String(), addrs)
  257. return
  258. }