126 lines
4.0 KiB
Go
126 lines
4.0 KiB
Go
package store
|
|
|
|
import (
|
|
"errors"
|
|
|
|
"mail_go/internal/db"
|
|
|
|
"gorm.io/gorm"
|
|
)
|
|
|
|
// Common store errors
|
|
var (
|
|
ErrInvalidEmail = errors.New("无效的邮箱地址格式")
|
|
ErrInvalidCredentials = errors.New("用户名或密码错误")
|
|
ErrUserInactive = errors.New("用户已被禁用")
|
|
ErrRecordNotFound = errors.New("记录不存在")
|
|
)
|
|
|
|
// MailStore defines the interface for mail message operations.
|
|
type MailStore interface {
|
|
Create(msg *db.Message) error
|
|
GetByID(id uint) (*db.Message, error)
|
|
ListByUserAndFolder(userID uint, folder string, page, size int) ([]db.Message, int64, error)
|
|
ListAllByUserAndFolder(userID uint, folder string) ([]db.Message, error)
|
|
CountByUserAndFolder(userID uint, folder string) (int64, error)
|
|
MarkRead(id uint) error
|
|
MarkFlagged(id uint, flagged bool) error
|
|
MoveToFolder(id uint, folder string) error
|
|
Delete(id uint) error
|
|
CountUnread(userID uint, folder string) (int64, error)
|
|
}
|
|
|
|
// mailStoreGorm implements MailStore using GORM.
|
|
type mailStoreGorm struct {
|
|
db *gorm.DB
|
|
}
|
|
|
|
// newMailStore creates a new GORM-backed MailStore.
|
|
func newMailStore(database *gorm.DB) MailStore {
|
|
return &mailStoreGorm{db: database}
|
|
}
|
|
|
|
// Create inserts a new message record.
|
|
func (s *mailStoreGorm) Create(msg *db.Message) error {
|
|
return s.db.Create(msg).Error
|
|
}
|
|
|
|
// GetByID retrieves a message by primary key.
|
|
func (s *mailStoreGorm) GetByID(id uint) (*db.Message, error) {
|
|
var msg db.Message
|
|
if err := s.db.First(&msg, id).Error; err != nil {
|
|
return nil, err
|
|
}
|
|
return &msg, nil
|
|
}
|
|
|
|
// ListByUserAndFolder retrieves a paginated list of messages for a user and folder.
|
|
func (s *mailStoreGorm) ListByUserAndFolder(userID uint, folder string, page, size int) ([]db.Message, int64, error) {
|
|
var messages []db.Message
|
|
var total int64
|
|
|
|
query := s.db.Where("user_id = ? AND folder = ?", userID, folder)
|
|
if err := query.Model(&db.Message{}).Count(&total).Error; err != nil {
|
|
return nil, 0, err
|
|
}
|
|
|
|
offset := (page - 1) * size
|
|
if err := query.Order("date DESC").Offset(offset).Limit(size).Find(&messages).Error; err != nil {
|
|
return nil, 0, err
|
|
}
|
|
return messages, total, nil
|
|
}
|
|
|
|
// MarkRead sets the IsRead flag to true for a message.
|
|
func (s *mailStoreGorm) MarkRead(id uint) error {
|
|
return s.db.Model(&db.Message{}).Where("id = ?", id).Update("is_read", true).Error
|
|
}
|
|
|
|
// MarkFlagged sets the IsFlagged flag for a message.
|
|
func (s *mailStoreGorm) MarkFlagged(id uint, flagged bool) error {
|
|
return s.db.Model(&db.Message{}).Where("id = ?", id).Update("is_flagged", flagged).Error
|
|
}
|
|
|
|
// MoveToFolder changes the folder of a message.
|
|
func (s *mailStoreGorm) MoveToFolder(id uint, folder string) error {
|
|
return s.db.Model(&db.Message{}).Where("id = ?", id).Update("folder", folder).Error
|
|
}
|
|
|
|
// Delete removes a message by ID.
|
|
func (s *mailStoreGorm) Delete(id uint) error {
|
|
return s.db.Delete(&db.Message{}, id).Error
|
|
}
|
|
|
|
// CountUnread returns the count of unread messages for a user in a folder.
|
|
func (s *mailStoreGorm) CountUnread(userID uint, folder string) (int64, error) {
|
|
var count int64
|
|
if err := s.db.Model(&db.Message{}).
|
|
Where("user_id = ? AND folder = ? AND is_read = ?", userID, folder, false).
|
|
Count(&count).Error; err != nil {
|
|
return 0, err
|
|
}
|
|
return count, nil
|
|
}
|
|
|
|
// ListAllByUserAndFolder retrieves all messages for a user in a folder without pagination.
|
|
// Messages are ordered by ID ascending so that sequence numbers are stable.
|
|
func (s *mailStoreGorm) ListAllByUserAndFolder(userID uint, folder string) ([]db.Message, error) {
|
|
var messages []db.Message
|
|
if err := s.db.Where("user_id = ? AND folder = ?", userID, folder).
|
|
Order("id ASC").Find(&messages).Error; err != nil {
|
|
return nil, err
|
|
}
|
|
return messages, nil
|
|
}
|
|
|
|
// CountByUserAndFolder returns the total count of messages for a user in a folder.
|
|
func (s *mailStoreGorm) CountByUserAndFolder(userID uint, folder string) (int64, error) {
|
|
var count int64
|
|
if err := s.db.Model(&db.Message{}).
|
|
Where("user_id = ? AND folder = ?", userID, folder).
|
|
Count(&count).Error; err != nil {
|
|
return 0, err
|
|
}
|
|
return count, nil
|
|
}
|