package message import ( "fmt" "net/http" "time" "mini-chat/internal/code" "mini-chat/internal/pkg/core" "mini-chat/internal/pkg/validation" "mini-chat/internal/repository/mysql/model" ) type markMessageReadRequest struct { AppID string `json:"app_id" binding:"required"` // 小程序ID UserID string `json:"user_id" binding:"required"` // 用户ID MessageID int32 `json:"message_id" binding:"required"` // 消息ID } type markMessageReadResponse struct { Message string `json:"message"` } // MarkMessageRead 标记消息为已读 // @Summary 标记消息为已读 // @Description 标记指定消息为已读状态 // @Tags 用户端 // @Accept json // @Produce json // @Param RequestBody body markMessageReadRequest true "请求参数" // @Success 200 {object} markMessageReadResponse // @Failure 400 {object} code.Failure // @Router /app/messages/read [post] func (h *handler) MarkMessageRead() core.HandlerFunc { return func(ctx core.Context) { req := new(markMessageReadRequest) res := new(markMessageReadResponse) if err := ctx.ShouldBindJSON(req); err != nil { ctx.AbortWithError(core.Error( http.StatusBadRequest, code.ParamBindError, validation.Error(err)), ) return } // 检查消息是否存在 message, err := h.readDB.AppMessageLog.WithContext(ctx.RequestContext()). Where(h.readDB.AppMessageLog.ID.Eq(req.MessageID)). Where(h.readDB.AppMessageLog.AppID.Eq(req.AppID)). First() if err != nil { ctx.AbortWithError(core.Error( http.StatusBadRequest, code.ListMessageError, fmt.Sprintf("消息不存在:%s", err.Error())), ) return } // 检查用户是否有权限标记此消息为已读(只有接收者可以标记) if message.ReceiverID != req.UserID { ctx.AbortWithError(core.Error( http.StatusBadRequest, code.ListMessageError, "只有消息接收者可以标记消息为已读"), ) return } // 检查是否已经标记为已读 existingReadStatus, _ := h.readDB.AppMessageReadStatus.WithContext(ctx.RequestContext()). Where(h.readDB.AppMessageReadStatus.AppID.Eq(req.AppID)). Where(h.readDB.AppMessageReadStatus.MessageID.Eq(req.MessageID)). Where(h.readDB.AppMessageReadStatus.UserID.Eq(req.UserID)). First() now := time.Now() if existingReadStatus != nil { // 如果已存在记录,更新为已读状态 _, err = h.writeDB.AppMessageReadStatus.WithContext(ctx.RequestContext()). Where(h.writeDB.AppMessageReadStatus.ID.Eq(existingReadStatus.ID)). Updates(map[string]interface{}{ "is_read": 1, "read_time": &now, "updated_at": now, }) } else { // 如果不存在记录,创建新的已读状态记录 newReadStatus := &model.AppMessageReadStatus{ AppID: req.AppID, MessageID: req.MessageID, UserID: req.UserID, IsRead: 1, ReadTime: &now, CreatedAt: now, UpdatedAt: now, } err = h.writeDB.AppMessageReadStatus.WithContext(ctx.RequestContext()).Create(newReadStatus) } if err != nil { ctx.AbortWithError(core.Error( http.StatusBadRequest, code.ListMessageError, fmt.Sprintf("标记消息已读失败:%s", err.Error())), ) return } res.Message = "消息已标记为已读" ctx.Payload(res) } }