package gm_services import ( "errors" "gadmin/internal/admin/forms" "gadmin/internal/admin/gmdb/filedb" "github.com/sirupsen/logrus" "os" "sort" "strings" "sync" "time" "github.com/jinzhu/copier" "github.com/jinzhu/now" "github.com/robfig/cron/v3" ) var ( emailDB *filedb.Collection // EmailsPool = forms.EmailList{} duration = 5 * time.Minute cronTab *cron.Cron lock sync.Mutex ) func getEmailDB() *filedb.Collection { if emailDB != nil { return emailDB } emailDB = InitDb() return emailDB } func InitDb() *filedb.Collection { db := filedb.NewCollection(os.Getenv("STORAGE_EMAILS")) if err := db.LoadDb(); err != nil { logrus.Error("emailDB InitDb err:", err) return nil } return db } func SaveEmailDb() { if err := getEmailDB().SaveDb(); err != nil { logrus.Error("emailDB SaveDb err:", err) return } } func EmailCron() { cronTab = cron.New() cronTab.AddFunc("*/1 * * * *", timerSendLetter) cronTab.AddFunc("*/1 * * * *", SaveEmailDb) go cronTab.Run() } func timerSendLetter() { contents, _ := getEmailDB().All() // contents := EmailsPool now := time.Now().Unix() for _, v := range contents { if item, ok := v.(*forms.EmailItem); ok { if item.Deleted || item.Opt != "send" { continue } if item.SentAt == 0 && item.SendAt >= now-int64(duration) && item.SendAt <= now { // sendEmail logrus.WithField("from", "timerSendLetter").Infoln(item) err := sendLetterToWorld(item) if err != nil { logrus.Error("emailDB sendLetterToWorld err:", err) return } } } } } func GetEmails(page, perPage int) (emails []*forms.EmailItem, total int, err error) { mails, _ := getEmailDB().All() contents := forms.EmailList{} for _, v := range mails { contents = append(contents, v.(*forms.EmailItem)) } // page, perPage = 1, 100000 sort.Sort(contents) total = len(contents) if total >= page*perPage { emails = contents[(page-1)*perPage : page*perPage] } else if total > (page-1)*perPage { emails = contents[(page-1)*perPage:] } return } func DeleteEmail(id int64) (err error) { if id > 0 { mail, err := getEmailDB().Find(id) if err == nil { if v, ok := mail.(*forms.EmailItem); ok { v.Status = "已删除" if err = getEmailDB().Add(v); err != nil { logrus.Error("emailDB Add err:", err) return err } } } } else { err = errors.New("ID不能为0") } return } // AddEmails 添加邮件 存草稿|发送|删除 // 只能删除草稿箱里的, func AddEmails(params *forms.EmailItemReq) (*forms.EmailItem, error) { lock.Lock() defer lock.Unlock() var row = new(forms.EmailItem) row.OperatorId = params.OperatorId if params.Id > 0 { mail, err := getEmailDB().Find(params.Id) if err != nil { return nil, err } if email, ok := mail.(*forms.EmailItem); ok { row = email copier.Copy(row, params) row.Title = strings.ReplaceAll(params.Title, "%", "") row.Content = strings.ReplaceAll(params.Content, "%", "") if email.Status == "已发送" || email.Status == "已删除" { return nil, errors.New("邮件状态无法编辑") } } } else { copier.Copy(row, params) row.Title = strings.ReplaceAll(params.Title, "%", "") row.Content = strings.ReplaceAll(params.Content, "%", "") } if params.Opt != "draft" { if params.SendWay == 1 { row.SendAt = time.Now().Unix() } else { if params.SendAt == "" { return nil, errors.New("发送时间不能为空") } stamp, _ := now.Parse(params.SendAt) row.SendAt = stamp.Unix() row.Status = "待发送" if row.SendAt == 0 { return nil, errors.New("发送时间不能为空") } } } else { if row.Status != "" { return nil, errors.New("邮件状态无法编辑") } if params.SendWay == 1 { row.SendAt = time.Now().Unix() } else { stamp, _ := now.Parse(params.SendAt) row.SendAt = stamp.Unix() } } err := getEmailDB().Add(row) if err != nil { return row, err } switch params.Opt { case "draft": // 存草稿 case "send": // 发送邮件 err = sendMail(row) } return row, err } func sendMail(params *forms.EmailItem) (err error) { if params.SendWay == 1 { // // 1 立即发送 0 待发送 if err = sendLetterToWorld(params); err != nil { logrus.Error("emailDB sendLetterToWorld err:", err) return err } if err = getEmailDB().Add(params); err != nil { logrus.Error("emailDB Add err:", err) return err } } return } func sendLetterToWorld(params *forms.EmailItem) (err error) { /*var letter model.GlobalLetter copier.Copy(&letter, params) letter.Extra = makeExtData(params) letter.Type = 6 letter.CreateTime = time.Now() letter.ExpireTime = time.Now().AddDate(0, 0, params.Expired) var ( players []int64 serverIds []int ) serverIds = service.ServerOption.GetServerIds() switch params.RecieverType { case 1: // 全服 msg := msg2.GMLetter{ MsgId: character.GenerateMsgId(), Letter: &letter, Players: players, OperatorId: params.OperatorId, } rpc_share.MsgMap[msg.MsgId] = fmt.Sprintf("%s,GM邮件(编号 %d) 投递成功,全服投递", utility.FormatSecond(time.Now()), params.Id) for _, serverId := range serverIds { DB, err := player.GetDBByServerID(serverId) if err != nil { logrus.Warnf("sendLetterToWorld GetDBByServerID err:%+v", err) continue } var resp *msg2.ResponseGMLetter res, err := config.GmNats.GmRequest(DB, "GMLetter", msg) if err != nil { logrus.Warnf("sendLetterToWorld GmRequest err:%+v", err) continue } if err = json.Unmarshal(res, &resp); err != nil { logrus.Warnf("sendLetterToWorld nats Unmarshal err:%+v", err) continue } rpc_share.LogChan <- rpc_share.LogMsg{ MsgID: msg.MsgId, Data: resp, } } case 2: // 指定服 serverIds := strings.Split(params.Recievers, ",") for _, serverId := range serverIds { sId := cast.ToInt(serverId) if sId > 0 { DB, err := player.GetDBByServerID(sId) if err != nil { logrus.Warnf("sendLetterToWorld2 GetDBByServerID2 err:%+v", err) continue } msg := msg2.GMLetter{ MsgId: character.GenerateMsgId(), Letter: &letter, Players: players, OperatorId: params.OperatorId, } rpc_share.MsgMap[msg.MsgId] = fmt.Sprintf("%s,GM邮件(编号 %d) 投递成功,投递服务器ID:%v", utility.FormatSecond(time.Now()), params.Id, sId) var resp *msg2.ResponseGMLetter res, err := config.GmNats.GmRequest(DB, "GMLetter", msg) if err != nil { logrus.Warnf("sendLetterToWorld2 GmRequest err:%+v", err) continue } if err = json.Unmarshal(res, &resp); err != nil { logrus.Warnf("sendLetterToWorld2 nats Unmarshal err:%+v", err) continue } rpc_share.LogChan <- rpc_share.LogMsg{ MsgID: msg.MsgId, Data: resp, } } } case 3: // 指定玩家 data := strings.Split(params.Recievers, ",") for _, v := range data { playerID := cast.ToInt64(v) if playerID > 0 { DB, err := player.GetDBByUserId(playerID) if err != nil { logrus.Warnf("sendLetterToWorld3 GetDBByUserId err:%+v", err) continue } msg := msg2.GMLetter{ MsgId: character.GenerateMsgId(), Letter: &letter, Players: []int64{playerID}, OperatorId: params.OperatorId, } rpc_share.MsgMap[msg.MsgId] = fmt.Sprintf("%s,GM邮件(编号 %d) 投递成功,投递玩家ID:%v", utility.FormatSecond(time.Now()), params.Id, playerID) var resp *msg2.ResponseGMLetter res, err := config.GmNats.GmRequest(DB, "GMLetter", msg) if err != nil { logrus.Warnf("sendLetterToWorld3 GmRequest err:%+v", err) continue } if err = json.Unmarshal(res, &resp); err != nil { logrus.Warnf("sendLetterToWorld3 nats Unmarshal err:%+v", err) continue } rpc_share.LogChan <- rpc_share.LogMsg{ MsgID: msg.MsgId, Data: resp, } } } } //if params.Recievers != "全员" { // data := strings.Split(params.Recievers, ",") // for _, v := range data { // playerID := cast.ToInt64(v) // if playerID > 0 { // players = append(players, playerID) // } // } //} //msg := msg2.GMLetter{ // MsgId: character.GenerateMsgId(), // Letter: &letter, // Players: players, // OperatorId: params.OperatorId, //} // //err = gate.SendToWorld(0, &msg) //if err == nil { // rpc_share.MsgMap[msg.MsgId] = fmt.Sprintf("%s,GM邮件(编号 %d) 投递成功", // utility.FormatSecond(time.Now()), // params.Id) //} params.Status = "已发送" params.SentAt = time.Now().Unix()*/ return } /*func makeExtData(params *forms.EmailItem) (data model.ExtraData) { var dim int64 = 1000000 //60306070 for _, v := range params.Ext { uid := cast.ToInt64(v.Id) count := cast.ToInt(v.Count) if uid > dim { for i := 0; i < count; i++ { data.Equips = append(data.Equips, uid) } } else if uid > 0 { data.Materials = append(data.Materials, &model.DropMaterial{ID: uid, Count: count}) } } return }*/