@@ -0,0 +1,169 @@
|
||||
package noticefmtmod
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sort"
|
||||
"time"
|
||||
|
||||
"91porn-server/common/timeutil/timeslice"
|
||||
)
|
||||
|
||||
// TimeSlice
|
||||
type TimeSlice = timeslice.TimeSlice
|
||||
|
||||
// UIDSlice
|
||||
type UIDSlice []uint64
|
||||
|
||||
func (u UIDSlice) Len() int {
|
||||
return len(u)
|
||||
}
|
||||
|
||||
func (u UIDSlice) Swap(i, j int) {
|
||||
u[i], u[j] = u[j], u[i]
|
||||
}
|
||||
|
||||
func (u UIDSlice) Less(i, j int) bool {
|
||||
return u[i] < u[j]
|
||||
}
|
||||
|
||||
// 定时通知 从指定的开始时间起,根据设置的时间间隔周期性通知
|
||||
type RegularNotice struct {
|
||||
StartAt *time.Time `bson:"regularStartAt,omitempty"` //开始时间
|
||||
TimeUnit *TimeUnit `bson:"regularTimeUnit,omitempty"` //单位 分钟/小时/天/周
|
||||
TimeCount *int64 `bson:"regularTimeCount,omitempty"` //量
|
||||
}
|
||||
|
||||
func (t *RegularNotice) NextSendTimeList(current time.Time, lastSendAt time.Time) TimeSlice {
|
||||
if t.StartAt == nil || t.TimeUnit == nil || t.TimeCount == nil {
|
||||
return TimeSlice{}
|
||||
}
|
||||
if t.StartAt.After(current) {
|
||||
return TimeSlice{}
|
||||
}
|
||||
per := t.TimeUnit.ToDuration() * time.Duration(*t.TimeCount)
|
||||
if per == 0 {
|
||||
return TimeSlice{}
|
||||
}
|
||||
curDelta := current.Sub(*t.StartAt)
|
||||
nextSendTime := t.StartAt.Add(curDelta / per * per)
|
||||
if lastSendAt.Before(nextSendTime) || lastSendAt.IsZero() {
|
||||
return TimeSlice{nextSendTime}
|
||||
}
|
||||
return TimeSlice{}
|
||||
}
|
||||
|
||||
func (t *RegularNotice) Rule() string {
|
||||
nextSendTime := t.NextSendTimeList(time.Now(), time.Time{})
|
||||
nextSendTimeStr := "无"
|
||||
if nextSendTime.Len() != 0 {
|
||||
nextSendTimeStr = nextSendTime[0].String()
|
||||
}
|
||||
return fmt.Sprintf("从 %s 开始, 每 %d %v, 发送消息\n 下次发送时间: %s", t.StartAt, t.TimeCount, t.TimeUnit, nextSendTimeStr)
|
||||
}
|
||||
|
||||
// 计划通知 根据指定的开始时间、结束时间和通知次数发起通知
|
||||
type PlanNotice struct {
|
||||
StartAt *time.Time `bson:"planStartAt,omitempty"` //开始时间
|
||||
EndAt *time.Time `bson:"planEndAt,omitempty"` //结束时间
|
||||
PlanCount *int64 `bson:"planPlanCount,omitempty"` //执行次数
|
||||
}
|
||||
|
||||
func (t *PlanNotice) NextSendTimeList(current time.Time, lastSendAt time.Time) TimeSlice {
|
||||
if t.StartAt == nil || t.EndAt == nil || t.PlanCount == nil || *t.PlanCount == 0 {
|
||||
return TimeSlice{}
|
||||
}
|
||||
if t.StartAt.After(current) || current.After(*t.EndAt) {
|
||||
return TimeSlice{}
|
||||
}
|
||||
totalDelta := t.EndAt.Sub(*t.StartAt)
|
||||
curDelta := t.EndAt.Sub(current)
|
||||
per := totalDelta / time.Duration(*t.PlanCount)
|
||||
nextSendTime := t.StartAt.Add(curDelta / per * per)
|
||||
if lastSendAt.Before(nextSendTime) || lastSendAt.IsZero() {
|
||||
return TimeSlice{nextSendTime}
|
||||
}
|
||||
return TimeSlice{}
|
||||
}
|
||||
|
||||
func (t *PlanNotice) Rule() string {
|
||||
nextSendTime := t.NextSendTimeList(time.Now(), time.Time{})
|
||||
nextSendTimeStr := "无"
|
||||
if nextSendTime.Len() != 0 {
|
||||
nextSendTimeStr = nextSendTime[0].String()
|
||||
}
|
||||
return fmt.Sprintf("从 %s 开始 至 %s 结束, 计划发送 %d 次消息\n 下次发送时间: %s", t.StartAt, t.EndAt, t.PlanCount, nextSendTimeStr)
|
||||
}
|
||||
|
||||
// 规定通知 到达指定的多个时间点时通知
|
||||
type SpecifyNotice struct {
|
||||
SpecifyTimeList TimeSlice `bson:"specifyTimeList,omitempty"` //指定执行时间数组
|
||||
}
|
||||
|
||||
func (t *SpecifyNotice) NextSendTimeList(current time.Time, lastSendAt time.Time) TimeSlice {
|
||||
if len(t.SpecifyTimeList) == 0 {
|
||||
return TimeSlice{}
|
||||
}
|
||||
sort.Sort(t.SpecifyTimeList)
|
||||
index := sort.Search(t.SpecifyTimeList.Len(), func(i int) bool {
|
||||
return t.SpecifyTimeList[i].After(current)
|
||||
})
|
||||
index = index - 1 //前一个才是已经过去的时间
|
||||
if index < 0 {
|
||||
index = 0
|
||||
}
|
||||
nextSendTime := t.SpecifyTimeList[index]
|
||||
if lastSendAt.Before(nextSendTime) || lastSendAt.IsZero() {
|
||||
return TimeSlice{nextSendTime}
|
||||
}
|
||||
return TimeSlice{}
|
||||
}
|
||||
|
||||
func (t *SpecifyNotice) Rule() string {
|
||||
nextSendTime := t.NextSendTimeList(time.Now(), time.Time{})
|
||||
nextSendTimeStr := "无"
|
||||
if nextSendTime.Len() != 0 {
|
||||
nextSendTimeStr = nextSendTime[0].String()
|
||||
}
|
||||
return fmt.Sprintf("指定时间: %+v 发送\n 下次发送时间: %s", t.SpecifyTimeList, nextSendTimeStr)
|
||||
}
|
||||
|
||||
// 注册后通知 用户注册后开始计时, 消耗指定的时间后通知一次
|
||||
type AfterRegistNotice struct {
|
||||
TimeUnit *TimeUnit `bson:"afterTimeUnit,omitempty"` //单位 分钟/小时/天/周
|
||||
TimeCount *int64 `bson:"afterTimeCount,omitempty"` //量
|
||||
}
|
||||
|
||||
func (t *AfterRegistNotice) Rule() string {
|
||||
return fmt.Sprintf("用户注册后 %d %v 发送", t.TimeCount, t.TimeUnit)
|
||||
}
|
||||
|
||||
type AfterRegistNoticeEx struct {
|
||||
AfterRegistNotice
|
||||
CreatedAt time.Time
|
||||
}
|
||||
|
||||
func (a *AfterRegistNoticeEx) NextSendTimeList(current time.Time, lastSendAt time.Time) TimeSlice {
|
||||
if a.TimeCount == nil {
|
||||
return TimeSlice{}
|
||||
}
|
||||
interval := a.TimeUnit.ToDuration() * time.Duration(*a.TimeCount)
|
||||
sendTime := a.CreatedAt.Add(interval)
|
||||
if current.After(sendTime) && lastSendAt.IsZero() {
|
||||
return TimeSlice{sendTime}
|
||||
}
|
||||
return TimeSlice{}
|
||||
}
|
||||
|
||||
type MailNotice struct {
|
||||
SendAt *time.Time `bson:"mailSendAt,omitempty"` //发送时间
|
||||
}
|
||||
|
||||
func (m *MailNotice) NextSendTimeList(current time.Time, lastSendAt time.Time) TimeSlice {
|
||||
if m.SendAt == nil {
|
||||
return TimeSlice{}
|
||||
}
|
||||
if current.After(*m.SendAt) && lastSendAt.IsZero() {
|
||||
return TimeSlice{*m.SendAt}
|
||||
}
|
||||
return TimeSlice{}
|
||||
}
|
||||
Reference in New Issue
Block a user