fix(chat): 发送后切会话不再误标未读,管理端撤回实时同步到对话页
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -6,6 +6,7 @@ import (
|
||||
"strconv"
|
||||
|
||||
"github.com/freefire/jiang13-bbs/middleware"
|
||||
"github.com/freefire/jiang13-bbs/model"
|
||||
"github.com/freefire/jiang13-bbs/realtime"
|
||||
"github.com/freefire/jiang13-bbs/service"
|
||||
"github.com/gin-gonic/gin"
|
||||
@@ -387,26 +388,7 @@ func (h *Handlers) RecallChatMessage(c *gin.Context) {
|
||||
c.JSON(chatErrToStatus(err), gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
data := gin.H{
|
||||
"id": msg.ID,
|
||||
"room_id": roomID,
|
||||
"sender_id": msg.SenderID,
|
||||
"recalled_by": msg.RecalledBy,
|
||||
"recalled_at": msg.RecalledAt,
|
||||
}
|
||||
if msg.Recaller != nil && msg.Recaller.ID > 0 {
|
||||
data["recaller"] = gin.H{
|
||||
"id": msg.Recaller.ID,
|
||||
"username": msg.Recaller.Username,
|
||||
"nickname": msg.Recaller.Nickname,
|
||||
"avatar": msg.Recaller.Avatar,
|
||||
"role": msg.Recaller.Role,
|
||||
}
|
||||
}
|
||||
h.Hub.BroadcastRoom(realtime.RoomChat(roomID), realtime.Envelope{
|
||||
Type: realtime.EventChatRecalled,
|
||||
Data: data,
|
||||
})
|
||||
h.broadcastChatRecalled(roomID, msg)
|
||||
// 监管者保留正文供界面展示;撤回者本人保留正文供「重新编辑」;其余不回传
|
||||
if !oversee && msg.SenderID != claims.ID {
|
||||
msg.Content = ""
|
||||
@@ -471,3 +453,80 @@ func (h *Handlers) ChatUnreadSummary(c *gin.Context) {
|
||||
}
|
||||
c.JSON(http.StatusOK, gin.H{"total": total, "rooms": rooms})
|
||||
}
|
||||
|
||||
// AdminChatMessages 管理端消息监管队列;room_type=group|direct
|
||||
func (h *Handlers) AdminChatMessages(c *gin.Context) {
|
||||
page, _ := strconv.Atoi(c.DefaultQuery("page", "1"))
|
||||
q := c.Query("q")
|
||||
roomType := c.Query("room_type")
|
||||
msgs, total, err := h.Chat.AdminListMessages(page, q, roomType)
|
||||
if err != nil {
|
||||
if err.Error() == "房间类型无效" {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": "加载聊天消息失败"})
|
||||
return
|
||||
}
|
||||
c.JSON(http.StatusOK, gin.H{"messages": msgs, "total": total, "page": page})
|
||||
}
|
||||
|
||||
// AdminRecallChatMessage 管理端撤回群聊消息(staff;监管者可撤任意)
|
||||
func (h *Handlers) AdminRecallChatMessage(c *gin.Context) {
|
||||
claims := middleware.CurrentUser(c)
|
||||
roomID, err := strconv.ParseUint(c.Param("roomId"), 10, 64)
|
||||
if err != nil || roomID == 0 {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "房间 ID 无效"})
|
||||
return
|
||||
}
|
||||
mid, err := strconv.ParseUint(c.Param("mid"), 10, 64)
|
||||
if err != nil || mid == 0 {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "消息 ID 无效"})
|
||||
return
|
||||
}
|
||||
oversee := h.chatOversee(claims.ID)
|
||||
// 非监管 staff:仅允许撤回自己发送的(与前台一致)
|
||||
msg, err := h.Chat.RecallMessage(claims.ID, uint(roomID), uint(mid), oversee)
|
||||
if err != nil {
|
||||
c.JSON(chatErrToStatus(err), gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
h.broadcastChatRecalled(uint(roomID), msg)
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"ok": true, "id": msg.ID, "room_id": roomID, "recalled_at": msg.RecalledAt,
|
||||
})
|
||||
}
|
||||
|
||||
// broadcastChatRecalled 会话内撤回与管理端撤回共用:先落库再推 chat:{roomID}
|
||||
func (h *Handlers) broadcastChatRecalled(roomID uint, msg *model.ChatMessage) {
|
||||
if h.Hub == nil || msg == nil {
|
||||
return
|
||||
}
|
||||
data := gin.H{
|
||||
"id": msg.ID,
|
||||
"room_id": roomID,
|
||||
"sender_id": msg.SenderID,
|
||||
"recalled_by": msg.RecalledBy,
|
||||
"recalled_at": msg.RecalledAt,
|
||||
}
|
||||
if msg.Recaller != nil && msg.Recaller.ID > 0 {
|
||||
data["recaller"] = gin.H{
|
||||
"id": msg.Recaller.ID,
|
||||
"username": msg.Recaller.Username,
|
||||
"nickname": msg.Recaller.Nickname,
|
||||
"avatar": msg.Recaller.Avatar,
|
||||
"role": msg.Recaller.Role,
|
||||
}
|
||||
}
|
||||
env := realtime.Envelope{Type: realtime.EventChatRecalled, Data: data}
|
||||
h.Hub.BroadcastRoom(realtime.RoomChat(roomID), env)
|
||||
// 未订阅该房间的成员(侧栏在看别的会话)也需要实时改预览
|
||||
if h.Chat == nil {
|
||||
return
|
||||
}
|
||||
if memberIDs, err := h.Chat.ListMemberIDs(roomID); err == nil {
|
||||
for _, uid := range memberIDs {
|
||||
h.Hub.BroadcastUser(uid, env)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user