Files
mengyastore/mengyastore-backend/internal/storage/chatstore.go

100 lines
2.6 KiB
Go

package storage
import (
"sync"
"time"
"github.com/google/uuid"
"gorm.io/gorm"
"mengyastore-backend/internal/database"
"mengyastore-backend/internal/models"
)
type ChatStore struct {
db *gorm.DB
mu sync.Mutex
lastSent map[string]time.Time
}
func NewChatStore(db *gorm.DB) (*ChatStore, error) {
return &ChatStore{db: db, lastSent: make(map[string]time.Time)}, nil
}
func chatRowToModel(row database.ChatMessageRow) models.ChatMessage {
return models.ChatMessage{
ID: row.ID,
AccountID: row.AccountID,
AccountName: row.AccountName,
Content: row.Content,
SentAt: row.SentAt,
FromAdmin: row.FromAdmin,
}
}
func (s *ChatStore) GetMessages(accountID string) ([]models.ChatMessage, error) {
var rows []database.ChatMessageRow
if err := s.db.Where("account_id = ?", accountID).Order("sent_at ASC").Find(&rows).Error; err != nil {
return nil, err
}
msgs := make([]models.ChatMessage, len(rows))
for i, r := range rows {
msgs[i] = chatRowToModel(r)
}
return msgs, nil
}
func (s *ChatStore) ListConversations() (map[string][]models.ChatMessage, error) {
var rows []database.ChatMessageRow
if err := s.db.Order("account_id, sent_at ASC").Find(&rows).Error; err != nil {
return nil, err
}
result := make(map[string][]models.ChatMessage)
for _, r := range rows {
result[r.AccountID] = append(result[r.AccountID], chatRowToModel(r))
}
return result, nil
}
func (s *ChatStore) SendUserMessage(accountID, accountName, content string) (models.ChatMessage, bool, error) {
s.mu.Lock()
defer s.mu.Unlock()
if last, ok := s.lastSent[accountID]; ok && time.Since(last) < time.Second {
return models.ChatMessage{}, true, nil
}
s.lastSent[accountID] = time.Now()
row := database.ChatMessageRow{
ID: uuid.New().String(),
AccountID: accountID,
AccountName: accountName,
Content: content,
SentAt: time.Now(),
FromAdmin: false,
}
if err := s.db.Create(&row).Error; err != nil {
return models.ChatMessage{}, false, err
}
return chatRowToModel(row), false, nil
}
func (s *ChatStore) SendAdminMessage(accountID, content string) (models.ChatMessage, error) {
row := database.ChatMessageRow{
ID: uuid.New().String(),
AccountID: accountID,
AccountName: "管理员",
Content: content,
SentAt: time.Now(),
FromAdmin: true,
}
if err := s.db.Create(&row).Error; err != nil {
return models.ChatMessage{}, err
}
return chatRowToModel(row), nil
}
func (s *ChatStore) ClearConversation(accountID string) error {
return s.db.Where("account_id = ?", accountID).Delete(&database.ChatMessageRow{}).Error
}