feat(P3): 私信 + #话题标签 + @提及 完成
This commit is contained in:
25
backend/internal/message/entity.go
Normal file
25
backend/internal/message/entity.go
Normal file
@@ -0,0 +1,25 @@
|
||||
package message
|
||||
|
||||
import "time"
|
||||
|
||||
type Message struct {
|
||||
ID uint `gorm:"primaryKey" json:"id"`
|
||||
FromID uint `gorm:"index:idx_message_from;not null" json:"from_id"`
|
||||
ToID uint `gorm:"index:idx_message_to;not null" json:"to_id"`
|
||||
Content string `gorm:"type:text;not null" json:"content"`
|
||||
IsRead bool `gorm:"default:false" json:"is_read"`
|
||||
CreatedAt time.Time `gorm:"autoCreateTime" json:"created_at"`
|
||||
}
|
||||
|
||||
type SendRequest struct {
|
||||
ToID uint `json:"to_id"`
|
||||
Content string `json:"content"`
|
||||
}
|
||||
|
||||
type ListRequest struct {
|
||||
PeerID uint `json:"peer_id"`
|
||||
}
|
||||
|
||||
type ListResponse struct {
|
||||
Messages []Message `json:"messages"`
|
||||
}
|
||||
95
backend/internal/message/handler.go
Normal file
95
backend/internal/message/handler.go
Normal file
@@ -0,0 +1,95 @@
|
||||
package message
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"feedsystem_video_go/internal/apierror"
|
||||
"feedsystem_video_go/internal/middleware/jwt"
|
||||
"net/http"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type Repository struct{ db *gorm.DB }
|
||||
type Service struct{ repo *Repository }
|
||||
type Handler struct{ service *Service }
|
||||
|
||||
func NewRepository(db *gorm.DB) *Repository { return &Repository{db: db} }
|
||||
func NewService(repo *Repository) *Service { return &Service{repo: repo} }
|
||||
func NewHandler(service *Service) *Handler { return &Handler{service: service} }
|
||||
|
||||
func (r *Repository) AutoMigrate(ctx context.Context) error {
|
||||
return r.db.WithContext(ctx).AutoMigrate(&Message{})
|
||||
}
|
||||
|
||||
func (r *Repository) Send(ctx context.Context, m *Message) error {
|
||||
m.Content = strings.TrimSpace(m.Content)
|
||||
if m.Content == "" {
|
||||
return errors.New("content is required")
|
||||
}
|
||||
m.CreatedAt = time.Now()
|
||||
return r.db.WithContext(ctx).Create(m).Error
|
||||
}
|
||||
|
||||
func (r *Repository) List(ctx context.Context, userID, peerID uint, limit int) ([]Message, error) {
|
||||
var msgs []Message
|
||||
err := r.db.WithContext(ctx).
|
||||
Where("(from_id = ? AND to_id = ?) OR (from_id = ? AND to_id = ?)", userID, peerID, peerID, userID).
|
||||
Order("created_at desc").
|
||||
Limit(limit).
|
||||
Find(&msgs).Error
|
||||
return msgs, err
|
||||
}
|
||||
|
||||
func (h *Handler) Send(c *gin.Context) {
|
||||
fromID, err := jwt.GetAccountID(c)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusUnauthorized, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
var req SendRequest
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
if req.ToID == 0 || strings.TrimSpace(req.Content) == "" {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "to_id and content are required"})
|
||||
return
|
||||
}
|
||||
m := &Message{FromID: fromID, ToID: req.ToID, Content: req.Content}
|
||||
if err := h.service.repo.Send(c.Request.Context(), m); err != nil {
|
||||
c.JSON(apierror.ClassifyHTTPStatus(err), gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
c.JSON(http.StatusOK, m)
|
||||
}
|
||||
|
||||
func (h *Handler) List(c *gin.Context) {
|
||||
userID, err := jwt.GetAccountID(c)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusUnauthorized, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
var req ListRequest
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
if req.PeerID == 0 {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "peer_id is required"})
|
||||
return
|
||||
}
|
||||
msgs, err := h.service.repo.List(c.Request.Context(), userID, req.PeerID, 50)
|
||||
if err != nil {
|
||||
c.JSON(apierror.ClassifyHTTPStatus(err), gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
if msgs == nil {
|
||||
msgs = []Message{}
|
||||
}
|
||||
c.JSON(http.StatusOK, ListResponse{Messages: msgs})
|
||||
}
|
||||
Reference in New Issue
Block a user