100 lines
2.6 KiB
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
|
|
}
|