Files
gochat/internal/repository/widget_offline_message_repo.go
T
2026-06-04 15:44:48 +08:00

116 lines
3.9 KiB
Go

package repository
import (
"context"
"fmt"
"gorm.io/gorm"
"github.com/gochat/gochat/internal/model"
)
// WidgetOfflineMessageRepo implements GORM repository for WidgetOfflineMessage.
type WidgetOfflineMessageRepo struct {
db *gorm.DB
}
// NewWidgetOfflineMessageRepo creates a new WidgetOfflineMessage repository.
func NewWidgetOfflineMessageRepo(db *gorm.DB) *WidgetOfflineMessageRepo {
return &WidgetOfflineMessageRepo{db: db}
}
// Create inserts a new offline message.
func (r *WidgetOfflineMessageRepo) Create(ctx context.Context, msg *model.WidgetOfflineMessage) error {
return r.db.WithContext(ctx).Create(msg).Error
}
// FindByID retrieves an offline message by primary key.
func (r *WidgetOfflineMessageRepo) FindByID(ctx context.Context, id uint) (*model.WidgetOfflineMessage, error) {
var msg model.WidgetOfflineMessage
err := r.db.WithContext(ctx).First(&msg, id).Error
if err != nil {
return nil, err
}
return &msg, nil
}
// FindByInboxID retrieves all pending offline messages for a specific inbox.
func (r *WidgetOfflineMessageRepo) FindByInboxID(ctx context.Context, inboxID uint) ([]model.WidgetOfflineMessage, error) {
var msgs []model.WidgetOfflineMessage
err := r.db.WithContext(ctx).Where("inbox_id = ? AND status = ?", inboxID, model.OfflineStatusPending).
Order("created_at ASC").Find(&msgs).Error
if err != nil {
return nil, err
}
return msgs, nil
}
// FindByAccountID retrieves all pending offline messages for an account (admin listing).
func (r *WidgetOfflineMessageRepo) FindByAccountID(ctx context.Context, accountID uint, offset, limit int) ([]model.WidgetOfflineMessage, int64, error) {
var msgs []model.WidgetOfflineMessage
var total int64
query := r.db.WithContext(ctx).Model(&model.WidgetOfflineMessage{}).
Where("account_id = ?", accountID)
if err := query.Count(&total).Error; err != nil {
return nil, 0, err
}
err := query.Order("created_at DESC").Offset(offset).Limit(limit).Find(&msgs).Error
if err != nil {
return nil, 0, err
}
return msgs, total, nil
}
// Update modifies an existing offline message (e.g., status change).
func (r *WidgetOfflineMessageRepo) Update(ctx context.Context, msg *model.WidgetOfflineMessage) error {
return r.db.WithContext(ctx).Save(msg).Error
}
// MarkConverted updates an offline message to converted status with a conversation ID.
func (r *WidgetOfflineMessageRepo) MarkConverted(ctx context.Context, id uint, conversationID uint) error {
result := r.db.WithContext(ctx).Model(&model.WidgetOfflineMessage{}).
Where("id = ?", id).
Updates(map[string]interface{}{
"status": model.OfflineStatusConverted,
"conversation_id": conversationID,
"converted_at": gorm.Expr("CURRENT_TIMESTAMP"),
})
if result.Error != nil {
return result.Error
}
if result.RowsAffected == 0 {
return fmt.Errorf("offline message with id %d not found", id)
}
return nil
}
// MarkDismissed updates an offline message to dismissed status.
func (r *WidgetOfflineMessageRepo) MarkDismissed(ctx context.Context, id uint) error {
result := r.db.WithContext(ctx).Model(&model.WidgetOfflineMessage{}).
Where("id = ?", id).
Update("status", model.OfflineStatusDismissed)
if result.Error != nil {
return result.Error
}
if result.RowsAffected == 0 {
return fmt.Errorf("offline message with id %d not found", id)
}
return nil
}
// Delete soft-deletes an offline message.
func (r *WidgetOfflineMessageRepo) Delete(ctx context.Context, id uint) error {
return r.db.WithContext(ctx).Delete(&model.WidgetOfflineMessage{}, id).Error
}
// CountPendingByInboxID counts how many pending offline messages exist for an inbox.
func (r *WidgetOfflineMessageRepo) CountPendingByInboxID(ctx context.Context, inboxID uint) (int64, error) {
var count int64
err := r.db.WithContext(ctx).Model(&model.WidgetOfflineMessage{}).
Where("inbox_id = ? AND status = ?", inboxID, model.OfflineStatusPending).
Count(&count).Error
return count, err
}