bindbox-game/internal/api/app/app_latest_messages.go
2025-10-21 18:30:28 +08:00

164 lines
5.4 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package app
import (
"fmt"
"net/http"
"time"
"mini-chat/internal/code"
"mini-chat/internal/pkg/core"
"mini-chat/internal/pkg/timeutil"
"mini-chat/internal/pkg/validation"
)
type latestMessageByAppIdRequest struct {
AppID string `form:"app_id" binding:"required"` // 小程序ID
Page int `form:"page"` // 当前页码默认1
PageSize int `form:"page_size"` // 每页返回的数据量默认20
}
type latestMessageData struct {
SendTime string `json:"send_time"` // 发送时间
SenderID string `json:"sender_id"` // 发送人ID
SenderName string `json:"sender_name"` // 发送人昵称
SenderAvatar string `json:"sender_avatar"` // 发送人头像
UnreadCount int `json:"unread_count"` // 未读消息数量
Content string `json:"content"` // 消息内容
MsgType int32 `json:"msg_type"` // 消息类型(1:文本 2:图片)
}
type latestMessageByAppIdResponse struct {
Page int `json:"page"` // 当前页码
PageSize int `json:"page_size"` // 每页返回的数据量
Total int64 `json:"total"` // 符合查询条件的总记录数
List []latestMessageData `json:"list"`
}
// LatestMessageByAppId 根据appid获取最新消息记录
// @Summary 根据appid获取最新消息记录
// @Description 管理端根据appid获取最新消息记录包含已读未读状态访问时自动标记为已读
// @Tags 管理端.小程序
// @Accept json
// @Produce json
// @Param app_id query string true "小程序ID"
// @Param page query int true "当前页码" default(1)
// @Param page_size query int true "每页返回的数据量,最多 100 条" default(20)
// @Success 200 {object} latestMessageByAppIdResponse
// @Failure 400 {object} code.Failure
// @Router /api/admin/messages/latest [get]
// @Security LoginVerifyToken
func (h *handler) LatestMessageByAppId() core.HandlerFunc {
return func(ctx core.Context) {
req := new(latestMessageByAppIdRequest)
res := new(latestMessageByAppIdResponse)
if err := ctx.ShouldBindForm(req); err != nil {
ctx.AbortWithError(core.Error(
http.StatusBadRequest,
code.ParamBindError,
validation.Error(err)),
)
return
}
if req.Page == 0 {
req.Page = 1
}
if req.PageSize == 0 {
req.PageSize = 20
}
if req.PageSize > 100 {
ctx.AbortWithError(core.Error(
http.StatusBadRequest,
code.ListMessageError,
fmt.Sprintf("%s: 一次最多只能查询 100 条", code.Text(code.ListMessageError)),
))
return
}
type unreadMessageResult struct {
SenderID string `json:"sender_id"`
SenderName string `json:"sender_name"`
SendTime time.Time `json:"send_time"`
AvatarURL string `json:"avatar_url"`
UnreadCount int `json:"unread_count"`
Content string `json:"content"` // 消息内容
MsgType int32 `json:"msg_type"` // 消息类型(1:文本 2:图片)
}
var results []unreadMessageResult
var total int64
countErr := h.db.GetDbR().Table("app_message_log m").
Select("m.send_time, m.sender_id, m.sender_name, u.user_avatar as avatar_url").
Joins("LEFT JOIN app_user u ON m.sender_id = u.user_id").
Where("m.app_id = ? AND m.sender_id != ?", req.AppID, "888888").
Group("m.sender_id").
Count(&total).
Error
if countErr != nil {
ctx.AbortWithError(core.Error(
http.StatusBadRequest,
code.ListMessageError,
fmt.Sprintf("%s%s", code.Text(code.ListMessageError), countErr.Error())),
)
return
}
subQuery := h.db.GetDbR().Table("app_message_log").
Select("sender_id, MAX(send_time) as latest_time").
Where("app_id = ? AND sender_id != ?", req.AppID, "888888").
Group("sender_id")
resultErr := h.db.GetDbR().Table("app_message_log m").
Select("m.send_time, m.content, m.msg_type, m.sender_id, m.sender_name, u.user_avatar as avatar_url, (SELECT COUNT(*) FROM app_message_log WHERE sender_id = m.sender_id AND is_read = 0) as unread_count").
Joins("LEFT JOIN app_user u ON m.sender_id = u.user_id").
Joins("JOIN (?) as latest ON m.sender_id = latest.sender_id AND m.send_time = latest.latest_time", subQuery).
Where("m.app_id = ? AND m.sender_id != ?", req.AppID, "888888").
Group("m.sender_id").
Order("unread_count DESC, send_time DESC").
Offset((req.Page - 1) * req.PageSize).
Limit(req.PageSize).
Find(&results).
Error
if resultErr != nil {
ctx.AbortWithError(core.Error(
http.StatusBadRequest,
code.ListMessageError,
fmt.Sprintf("%s%s", code.Text(code.ListMessageError), resultErr.Error())),
)
return
}
// 自动标记该appid下的所有消息为已读管理端访问时
//_, err := h.writeDB.AppMessageLog.WithContext(ctx.RequestContext()).
// Where(h.writeDB.AppMessageLog.AppID.Eq(req.AppID)).
// Where(h.writeDB.AppMessageLog.IsRead.Eq(0)).
// Update(h.writeDB.AppMessageLog.IsRead, 1)
//if err != nil {
// // 记录错误但不影响查询结果
// // TODO: 可以添加日志记录
//}
res.Page = req.Page
res.PageSize = req.PageSize
res.Total = total
res.List = make([]latestMessageData, len(results))
for k, v := range results {
res.List[k] = latestMessageData{
SendTime: timeutil.FriendlyTime(v.SendTime),
SenderID: v.SenderID,
SenderName: v.SenderName,
SenderAvatar: v.AvatarURL,
UnreadCount: v.UnreadCount,
Content: v.Content,
MsgType: v.MsgType,
}
}
ctx.Payload(res)
}
}