mail

package
v0.3.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 5, 2026 License: Apache-2.0 Imports: 3 Imported by: 0

Documentation

Overview

Package mail 提供游戏内信箱原语:泛型附件 + 领取状态 + 过期 + 批量发送 + Store 接口。

核心概念:

  • Mail[T]: 一封邮件,T 为附件类型(由业务定义)
  • Mailbox[T]: 管理器,提供投递/拉取/已读/领取/删除/红点等操作
  • Store[T]: 持久化接口,内存实现用于开发测试,生产接 DB

与 notification 区别: notification 是瞬时推送(轻量); mail 带附件且有领取状态机(未领→已领)。 与 inbox 区别: inbox 是点对点离线消息(纯文本); mail 带泛型附件且有过期机制。

纯标准库、并发安全。

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrNotFound 邮件不存在。
	ErrNotFound = errors.New("mail: not found")
	// ErrAlreadyClaimed 附件已领取。
	ErrAlreadyClaimed = errors.New("mail: already claimed")
	// ErrExpired 邮件已过期。
	ErrExpired = errors.New("mail: expired")
	// ErrNoAttachment 邮件没有附件。
	ErrNoAttachment = errors.New("mail: no attachment")
	// ErrMailboxFull 信箱已满。
	ErrMailboxFull = errors.New("mail: mailbox full")
)

Functions

This section is empty.

Types

type Filter

type Filter struct {
	StatusIn []Status // 为空则不过滤
	Limit    int      // 0 表示不限
	Offset   int
}

Filter 查询过滤条件。

type Mail

type Mail[T any] struct {
	ID          string
	RecipientID string
	SenderID    string
	Title       string
	Body        string
	Attachments []T
	Status      Status
	CreatedAt   time.Time
	ExpiresAt   time.Time // 零值表示永不过期
}

Mail 表示一封邮件。T 为附件类型。

func (*Mail[T]) HasAttachment

func (m *Mail[T]) HasAttachment() bool

HasAttachment 判断是否有附件。

func (*Mail[T]) IsExpired

func (m *Mail[T]) IsExpired(now time.Time) bool

IsExpired 判断邮件是否已过期。

type Mailbox

type Mailbox[T any] struct {
	// contains filtered or unexported fields
}

Mailbox 信箱管理器。并发安全(依赖 Store 实现的并发安全性)。

func NewMailbox

func NewMailbox[T any](store Store[T], opts ...Option) *Mailbox[T]

NewMailbox 创建信箱管理器。

func (*Mailbox[T]) BatchSend

func (mb *Mailbox[T]) BatchSend(recipientIDs []string, template *Mail[T], idGen func() string) []error

BatchSend 群发邮件(模板实例化): 向多个收件人发送相同内容的邮件。 idGen 为邮件 ID 生成器(每封邮件需唯一 ID)。

func (*Mailbox[T]) Claim

func (mb *Mailbox[T]) Claim(id string) ([]T, error)

Claim 领取附件(仅一次)。返回附件内容。

func (*Mailbox[T]) Delete

func (mb *Mailbox[T]) Delete(id string) error

Delete 删除邮件。

func (*Mailbox[T]) DeleteExpired

func (mb *Mailbox[T]) DeleteExpired() (int, error)

DeleteExpired 清理所有过期邮件,返回删除数量。

func (*Mailbox[T]) List

func (mb *Mailbox[T]) List(recipientID string, filter Filter) ([]*Mail[T], error)

List 拉取邮件列表(支持过滤)。自动过滤已过期邮件。

func (*Mailbox[T]) Read

func (mb *Mailbox[T]) Read(id string) error

Read 标记邮件为已读。

func (*Mailbox[T]) Send

func (mb *Mailbox[T]) Send(m *Mail[T]) error

Send 投递一封邮件。自动填充 CreatedAt 和 ExpiresAt(如果为零值)。

func (*Mailbox[T]) Unread

func (mb *Mailbox[T]) Unread(recipientID string) (int, error)

Unread 返回未读邮件数(红点用)。

type MemoryStore

type MemoryStore[T any] struct {
	// contains filtered or unexported fields
}

MemoryStore 内存实现(开发/测试用)。并发安全。

func NewMemoryStore

func NewMemoryStore[T any]() *MemoryStore[T]

NewMemoryStore 创建内存 Store。

func (*MemoryStore[T]) CountByStatus

func (s *MemoryStore[T]) CountByStatus(recipientID string, status Status) (int, error)

func (*MemoryStore[T]) Delete

func (s *MemoryStore[T]) Delete(id string) error

func (*MemoryStore[T]) DeleteExpired

func (s *MemoryStore[T]) DeleteExpired(now time.Time) (int, error)

func (*MemoryStore[T]) Get

func (s *MemoryStore[T]) Get(id string) (*Mail[T], error)

func (*MemoryStore[T]) List

func (s *MemoryStore[T]) List(recipientID string, filter Filter) ([]*Mail[T], error)

func (*MemoryStore[T]) Save

func (s *MemoryStore[T]) Save(m *Mail[T]) error

func (*MemoryStore[T]) Update

func (s *MemoryStore[T]) Update(m *Mail[T]) error

type Option

type Option func(*config)

Option 配置 Mailbox。

func WithDefaultTTL

func WithDefaultTTL(d time.Duration) Option

WithDefaultTTL 设置默认邮件过期时间(默认 30 天)。

func WithMaxPerUser

func WithMaxPerUser(n int) Option

WithMaxPerUser 设置每用户信箱容量上限(默认 100)。

func WithOnClaim

func WithOnClaim(fn func(mailID string, recipientID string)) Option

WithOnClaim 注册领取回调(用于发奖埋点)。

type Status

type Status int

Status 邮件状态。

const (
	StatusUnread  Status = iota // 未读
	StatusRead                  // 已读
	StatusClaimed               // 已领取附件
)

func (Status) String

func (s Status) String() string

type Store

type Store[T any] interface {
	Save(mail *Mail[T]) error
	Get(id string) (*Mail[T], error)
	Update(mail *Mail[T]) error
	Delete(id string) error
	List(recipientID string, filter Filter) ([]*Mail[T], error)
	CountByStatus(recipientID string, status Status) (int, error)
	DeleteExpired(now time.Time) (int, error)
}

Store 持久化接口。

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL