Files
ttstd-infinite-canvas/web/src/services/api/announcements.ts

133 lines
4.6 KiB
TypeScript
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.
import { http, apiBaseURL } from "@/services/api/request";
import type { RemoteResource } from "@/services/api/resources";
import type { BannerNoticeType } from "@/lib/announcements/banner-notice";
import type { BannerTitleRun } from "@/lib/announcements/banner-title";
export type { BannerTitleRun };
export type AnnouncementLevel = "info" | "success" | "warning" | "critical";
export type AnnouncementStatus = "active" | "closed";
export type SystemAnnouncement = {
id: string;
title: string;
content: string;
imageResourceId?: string;
imageUrl?: string;
level: AnnouncementLevel;
pinned: boolean;
status: AnnouncementStatus;
createdBy: string;
publishedAt: string;
closedAt?: string;
createdAt: string;
updatedAt: string;
};
export type AnnouncementFeed = {
announcements: SystemAnnouncement[];
unreadCount: number;
};
export type AdminAnnouncementListParams = {
keyword?: string;
status?: AnnouncementStatus;
page?: number;
pageSize?: number;
};
export function getAnnouncementFeed() {
return http.get<AnnouncementFeed>("/announcements");
}
export function announcementImageUrl(announcement: Pick<SystemAnnouncement, "imageUrl">) {
const imageUrl = announcement.imageUrl;
if (!imageUrl || !imageUrl.startsWith("/api/")) return imageUrl || "";
const base = String(apiBaseURL).replace(/\/+$/, "");
return base === "/api" ? imageUrl : `${base}${imageUrl.slice("/api".length)}`;
}
export function markAnnouncementsRead(announcementIds: string[]) {
return http.post<{ unreadCount: number }>("/announcements/read", { announcementIds });
}
export function listAdminAnnouncements(params: AdminAnnouncementListParams = {}) {
return http.get<{ announcements: SystemAnnouncement[]; total: number; page: number; pageSize: number }>("/admin/announcements", { params });
}
export function uploadAdminAnnouncementImage(file: File) {
const formData = new FormData();
formData.append("file", file, file.name);
return http.post<{ resource: RemoteResource }>("/admin/announcement-images", formData);
}
export function discardAdminAnnouncementImage(id: string) {
return http.delete<{ ok: boolean }>(`/admin/announcement-images/${encodeURIComponent(id)}`);
}
export function createAdminAnnouncement(input: { title: string; content: string; imageResourceId?: string; level: AnnouncementLevel; pinned: boolean }) {
return http.post<{ announcement: SystemAnnouncement }>("/admin/announcements", input);
}
export function updateAdminAnnouncement(id: string, input: { title: string; content: string; imageResourceId?: string; level: AnnouncementLevel; pinned: boolean }) {
return http.patch<{ announcement: SystemAnnouncement }>(`/admin/announcements/${encodeURIComponent(id)}`, input);
}
export function closeAdminAnnouncement(id: string) {
return http.post<{ announcement: SystemAnnouncement }>(`/admin/announcements/${encodeURIComponent(id)}/close`);
}
export type BannerAnnouncement = {
id: string;
title: string;
/** 标题样式分段;为空表示纯文本标题(取值白名单见 lib/announcements/banner-title)。 */
titleRuns?: BannerTitleRun[];
/** 通知类型,决定通知条底色;未知值按「公告」处理。 */
noticeType?: BannerNoticeType;
link?: string;
status: "active" | "disabled";
startsAt?: string;
endsAt?: string;
createdBy: string;
createdAt: string;
updatedAt: string;
};
export type AdminBannerListParams = {
keyword?: string;
status?: string;
page?: number;
pageSize?: number;
};
export type AdminBannerPayload = {
title: string;
titleRuns?: BannerTitleRun[];
noticeType?: BannerNoticeType;
link?: string;
status: "active" | "disabled";
startsAt?: string;
endsAt?: string;
};
export function getActiveBanners() {
return http.get<{ banners: BannerAnnouncement[] }>("/banner-announcements");
}
export function listAdminBanners(params: AdminBannerListParams = {}) {
return http.get<{ banners: BannerAnnouncement[]; total: number; page: number; pageSize: number }>("/admin/banner-announcements", { params });
}
export function createAdminBanner(input: AdminBannerPayload) {
return http.post<{ banner: BannerAnnouncement }>("/admin/banner-announcements", input);
}
export function updateAdminBanner(id: string, input: AdminBannerPayload) {
return http.put<{ banner: BannerAnnouncement }>(`/admin/banner-announcements/${encodeURIComponent(id)}`, input);
}
export function deleteAdminBanner(id: string) {
return http.delete<{ ok: boolean }>(`/admin/banner-announcements/${encodeURIComponent(id)}`);
}