Files
jiang13-bbs/backend/handler/notification.go
freefire ff2ab286fb feat: 书库导入导出/图片变体/书籍搜索/小组件运行时等
新增:
- 书库导入导出(library_import/library_export)及测试
- 图片变体生成(image_variants)与响应式图片(responsiveImage)
- 书籍搜索(bookSearch)+ BookSearch/LibrarySearchGrid 组件
- 小组件运行时(widgetRuntime)与静态检查(widgetLint)
- 上传缓存中间件(upload_cache)与字体 CSS 提取脚本

其它:
- 后端 handlers/services 全量调整
- 前端页面、组件、库函数与配置更新
2026-10-01 03:06:05 +08:00

90 lines
2.6 KiB
Go

package handler
import (
"net/http"
"strconv"
"github.com/freefire/jiang13-bbs/middleware"
"github.com/freefire/jiang13-bbs/model"
"github.com/gin-gonic/gin"
)
// notificationView 通知列表项:附带关联评论的楼层相对锚点,
// 供前端拼 #comment-{floor}(主楼)或 #comment-{floor}-r{comment_id}(楼中楼)。
type notificationView struct {
*model.Notification
CommentFloor uint `json:"comment_floor"`
CommentIsRoot bool `json:"comment_is_root"`
}
// Notifications 获取当前用户的通知列表(分页)
func (h *Handlers) Notifications(c *gin.Context) {
claims := middleware.CurrentUser(c)
page, _ := strconv.Atoi(c.DefaultQuery("page", "1"))
size, _ := strconv.Atoi(c.DefaultQuery("size", "20"))
list, total, err := h.Notification.List(claims.ID, page, size)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
commentIDs := make([]uint, 0, len(list))
for _, n := range list {
if n.CommentID > 0 {
commentIDs = append(commentIDs, n.CommentID)
}
}
anchors := h.Comment.AnchorsByCommentIDs(commentIDs)
views := make([]notificationView, 0, len(list))
for i := range list {
v := notificationView{Notification: &list[i]}
if a, ok := anchors[list[i].CommentID]; ok {
v.CommentFloor = a.Floor
v.CommentIsRoot = a.IsRoot
}
views = append(views, v)
}
c.JSON(http.StatusOK, gin.H{
"notifications": nonNilSlice(views),
"total": total,
"page": page,
"size": size,
})
}
// UnreadCount 获取未读通知数
func (h *Handlers) UnreadCount(c *gin.Context) {
claims := middleware.CurrentUser(c)
count, err := h.Notification.UnreadCount(claims.ID)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusOK, gin.H{"count": count})
}
// MarkRead 标记单条通知为已读
func (h *Handlers) MarkRead(c *gin.Context) {
claims := middleware.CurrentUser(c)
id, err := strconv.ParseUint(c.Param("id"), 10, 64)
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": "无效的通知 ID"})
return
}
if err := h.Notification.MarkRead(uint(id), claims.ID); err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusOK, gin.H{"message": "已标记为已读"})
}
// MarkAllRead 标记所有通知为已读
func (h *Handlers) MarkAllRead(c *gin.Context) {
claims := middleware.CurrentUser(c)
if err := h.Notification.MarkAllRead(claims.ID); err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusOK, gin.H{"message": "已全部标记为已读"})
}