package workbench import ( "net/http" "strconv" "aigateway.local/core/internal/identity" "aigateway.local/core/internal/platform/apiresponse" ) // InboxPortalHTTPHandler 向门户端暴露个人收件箱与未读徽标。 type InboxPortalHTTPHandler struct { inbox *InboxService identity *identity.Service mux *http.ServeMux } func NewInboxPortalHTTPHandler(inbox *InboxService, identityService *identity.Service) *InboxPortalHTTPHandler { h := &InboxPortalHTTPHandler{inbox: inbox, identity: identityService, mux: http.NewServeMux()} h.mux.HandleFunc("GET /api/v1/portal/inbox", h.list) h.mux.HandleFunc("GET /api/v1/portal/inbox/unread", h.unread) h.mux.HandleFunc("POST /api/v1/portal/inbox/read-all", h.readAll) h.mux.HandleFunc("POST /api/v1/portal/inbox/{id}/read", h.read) return h } func (h *InboxPortalHTTPHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { h.mux.ServeHTTP(w, r) } func (h *InboxPortalHTTPHandler) account(w http.ResponseWriter, r *http.Request) (identity.Account, bool) { account, err := h.identity.Authenticate(r.Context(), identity.KindPortal, r.Header.Get("Authorization")) if err != nil { apiresponse.Error(w, http.StatusUnauthorized, "登录状态无效或已过期") return identity.Account{}, false } return account, true } func (h *InboxPortalHTTPHandler) list(w http.ResponseWriter, r *http.Request) { a, ok := h.account(w, r) if !ok { return } limit, _ := strconv.Atoi(r.URL.Query().Get("limit")) items, err := h.inbox.List(r.Context(), "portal", a.ID, limit) if err != nil { apiresponse.Error(w, http.StatusBadRequest, err.Error()) return } apiresponse.OK(w, items) } func (h *InboxPortalHTTPHandler) unread(w http.ResponseWriter, r *http.Request) { a, ok := h.account(w, r) if !ok { return } count, err := h.inbox.UnreadCount(r.Context(), "portal", a.ID) if err != nil { apiresponse.Error(w, http.StatusBadRequest, err.Error()) return } apiresponse.OK(w, map[string]int{"unread": count}) } func (h *InboxPortalHTTPHandler) read(w http.ResponseWriter, r *http.Request) { a, ok := h.account(w, r) if !ok { return } changed, err := h.inbox.MarkRead(r.Context(), r.PathValue("id"), "portal", a.ID) if err != nil { apiresponse.Error(w, http.StatusBadRequest, err.Error()) return } apiresponse.OK(w, map[string]bool{"read": changed}) } func (h *InboxPortalHTTPHandler) readAll(w http.ResponseWriter, r *http.Request) { a, ok := h.account(w, r) if !ok { return } count, err := h.inbox.MarkAllRead(r.Context(), "portal", a.ID) if err != nil { apiresponse.Error(w, http.StatusBadRequest, err.Error()) return } apiresponse.OK(w, map[string]any{"read_all": count}) }