package service import ( "fmt" "strconv" "time" "crazy-fox-backend-api/storage/redis" "github.com/jmoiron/sqlx/types" jsoniter "github.com/json-iterator/go" "crazy-fox-backend-api/config" "crazy-fox-backend-api/model" "crazy-fox-backend-api/repo" "crazy-fox-backend-api/repo/okeys" "crazy-fox-backend-api/utils" "github.com/pkg/errors" ) const ( sendFinished = 1 // 已发送 sendRunning = 2 // 发送中 sendUnStart = 3 // 未开始 ) // sysMailService 系统邮件模块服务 type sysMailService struct{} func (This *sysMailService) TemplateList(req model.PageInfo) ([]model.TSysMailTemplate, int64) { return repo.SearchOnePage[model.TSysMailTemplate](req.Page, req.PageSize, "Order By id desc") } func (This *sysMailService) TemplateEdit(req *model.TSysMailTemplate) (err error) { if utils.IsEmpty(req.Id) { _, err = repo.Insert(req) } else { err = repo.Update(req, "id") } return errors.WithStack(err) } func (This *sysMailService) handleTemplateImport(sheets [][][]string) (templateConf map[string]model.SystemMailContent, err error) { templateConf, err = This.parseTemplateSheet(sheets[0]) if err != nil { return templateConf, errors.WithStack(err) } return templateConf, err } func (This *sysMailService) parseTemplateSheet(sheet [][]string) (map[string]model.SystemMailContent, error) { var err error confMap := make(map[string]model.SystemMailContent, len(sheet)) for i := 1; i < len(sheet); i++ { var lang string var one model.SystemMailContent if err = utils.DestructAssign(sheet[i], &lang, &one.Title, &one.Body); err != nil { return nil, errors.WithStack(err) } for k, v := range config.LangUpper { if v == lang { confMap[k] = one break } } } return confMap, err } func (This *sysMailService) GetTemplateOption() []model.Option { list := repo.Search[model.TSysMailTemplate]("") options := make([]model.Option, 0, len(list)) for _, template := range list { options = append(options, model.Option{ Value: template.Id, Label: template.Remark, }) } return options } func (This *sysMailService) GetMailHistory(req model.PageInfo) ([]model.SysMailScheduleShow, int64) { curTime := utils.CurTimestamp() where := repo.SysMail.GetHistoryListWhere(req.Keyword) list, total := repo.SearchOnePage[model.SysMailScheduleSub](req.Page, req.PageSize, where) templateList := repo.Search[model.TSysMailTemplate]("") history := make([]model.SysMailScheduleShow, 0, len(list)) for _, sub := range list { historyStatus := func() int64 { if sub.Uids != "" || curTime > sub.AliveEnd { return sendFinished } if curTime < sub.AliveStart { return sendUnStart } return sendRunning }() historyTemplate := func() string { for _, template := range templateList { if template.Id == sub.TemplateId { return fmt.Sprintf("%s (ID:%d)", template.Remark, template.Id) } } return "-" }() history = append(history, model.SysMailScheduleShow{ Id: sub.Id, Template: historyTemplate, Rewards: sub.Rewards, Remark: sub.Remark, Type: utils.Ternary(sub.Uids == "", int64(0), 1), Status: historyStatus, CreateTime: utils.Ternary(sub.CreateTime == 0, "-", time.Unix(sub.CreateTime, 0).Format(config.DateTime)), Operator: sub.Operator, }) } return history, total } func (This *sysMailService) MailSend(m *model.TSysMailSchedule) (err error) { if _, err = repo.Insert(m); err != nil { return errors.WithStack(err) } // 指定条件发送 if utils.IsEmpty(m.Uids) { schedules := repo.Search[model.TSysMailSchedule]("Where `uids` = '' And `alive_end` > ?", utils.CurTimestamp()) updateMap := make(map[string]any, len(schedules)) for _, s := range schedules { updateMap[strconv.FormatInt(s.Id, 10)] = s } repo.ClearAndHMSetCache(okeys.SysMailSchedule(), updateMap) return err } // 指定uid发送 var uidArr []int64 if err = utils.Explode(&uidArr, m.Uids, ","); err != nil { return err } var insertId int64 var mailInfo model.UserSysMail for _, uid := range uidArr { if utils.IsEmpty(uid) { continue } mailInfo = This.buildUserMailInfo(uid, m) if insertId, err = repo.SysMail.InsertUserSysMail(&mailInfo); err != nil { return errors.WithStack(err) } mailInfo.Id = insertId if err = repo.SysMail.HSetUserSysMail(&mailInfo); err != nil { return errors.WithStack(err) } } return err } func (This *sysMailService) GetOneHistory(id int64) model.TSysMailSchedule { return repo.SearchOne[model.TSysMailSchedule]("Where id = ?", id) } func (This *sysMailService) buildUserMailInfo(uid int64, m *model.TSysMailSchedule) model.UserSysMail { curTime := utils.CurTimestamp() mail := model.UserSysMail{ Uid: uid, Msgid: m.TemplateId, Got: 0, Rewards: m.Rewards, Expire: curTime + config.OneDay*m.Days, CreateTime: curTime, } return mail } // 发送邮件奖励 func (This *sysMailService) SendEmailRewards(uid, msgId int64, rewards []model.PropPrize) error { var ( err error jsonText types.JSONText rc = redis.SelectConn(redis.Games) redisKey = okeys.SysMsgGet(uid) timestamp = time.Now().Unix() ) if jsonText, err = jsoniter.Marshal(rewards); err != nil { return err } emailData := model.EmailRepo{ Uid: uid, Msgid: msgId, Got: 0, Rewards: jsonText, Expire: timestamp + 86400*7, CreateTime: timestamp, } if emailData.Id, err = repo.Insert(emailData, emailData.TableName(uid)); err != nil { return err } hKey := fmt.Sprintf("%v_%v", msgId, emailData.Id) emailData.Rewards = rewards if jsonText, err = jsoniter.Marshal(emailData); err != nil { return err } if err = rc.HSet(redisKey, hKey, string(jsonText)); err != nil { return err } rc.ExpireAt(redisKey, timestamp+86400*16) return nil }