62 lines
1.8 KiB
Go
62 lines
1.8 KiB
Go
package notices
|
|
|
|
import (
|
|
"encoding/json"
|
|
"net/http"
|
|
"time"
|
|
|
|
"github.com/wangjia/pangolin/server/internal/apierr"
|
|
"github.com/wangjia/pangolin/server/internal/auth"
|
|
)
|
|
|
|
// listLimit 是 GET /v1/notices 单次返回的最大条数(合并广播+定向后按 published_at 倒序截断)。
|
|
const listLimit = 50
|
|
|
|
// Handler 承载 /v1/notices、/v1/notices/read 两个受保护端点。
|
|
type Handler struct {
|
|
st *Store
|
|
}
|
|
|
|
func NewHandler(st *Store) *Handler {
|
|
return &Handler{st: st}
|
|
}
|
|
|
|
// List handles GET /v1/notices: 返回该用户可见的通知(广播 ∪ 定向)与未读数。
|
|
func (h *Handler) List(w http.ResponseWriter, r *http.Request) {
|
|
ctx := r.Context()
|
|
uid, ok := auth.UserIDFromContext(ctx)
|
|
if !ok {
|
|
apierr.WriteJSON(w, http.StatusUnauthorized, apierr.ErrUnauthorized)
|
|
return
|
|
}
|
|
items, unreadCount, err := h.st.ListForUser(ctx, uid, time.Now().UTC(), listLimit)
|
|
if err != nil {
|
|
apierr.WriteJSON(w, http.StatusInternalServerError, apierr.ErrInternal)
|
|
return
|
|
}
|
|
if items == nil {
|
|
items = []Notice{}
|
|
}
|
|
w.Header().Set("Content-Type", "application/json; charset=utf-8")
|
|
_ = json.NewEncoder(w).Encode(map[string]any{
|
|
"notices": items,
|
|
"unread_count": unreadCount,
|
|
})
|
|
}
|
|
|
|
// MarkRead handles POST /v1/notices/read: 把用户已读水位推进到当前时间。
|
|
func (h *Handler) MarkRead(w http.ResponseWriter, r *http.Request) {
|
|
ctx := r.Context()
|
|
uid, ok := auth.UserIDFromContext(ctx)
|
|
if !ok {
|
|
apierr.WriteJSON(w, http.StatusUnauthorized, apierr.ErrUnauthorized)
|
|
return
|
|
}
|
|
if err := h.st.MarkRead(ctx, uid, time.Now().UTC()); err != nil {
|
|
apierr.WriteJSON(w, http.StatusInternalServerError, apierr.ErrInternal)
|
|
return
|
|
}
|
|
w.Header().Set("Content-Type", "application/json; charset=utf-8")
|
|
_ = json.NewEncoder(w).Encode(map[string]any{"ok": true})
|
|
}
|