export const NOTICE_STATUS_VALUES = ["draft", "published", "retracted"] as const; export type NoticeStatus = (typeof NOTICE_STATUS_VALUES)[number]; export const NOTICE_STATUS_LABELS: Record = { draft: "草稿", published: "已发布", retracted: "已撤回", }; export type Notice = { id: string; organizationId: string; title: string; content: string; audience: string; status: NoticeStatus; publishedAt?: string; createdByAccountId?: string; createdByName?: string; updatedByAccountId?: string; updatedByName?: string; readCount: number; hasRead: boolean; createdAt: string; updatedAt: string; }; export type NoticeCenterData = { metrics: { published: number; drafts: number; unread: number; retracted: number; }; notices: Notice[]; }; export type NoticeInput = { title: string; content: string; audience: string; status: NoticeStatus; }; type ValidationSuccess = { success: true; data: T; }; type ValidationFailure = { success: false; reason: string; }; export type ValidationResult = ValidationSuccess | ValidationFailure; function isRecord(value: unknown): value is Record { return typeof value === "object" && value !== null && !Array.isArray(value); } function readString(source: Record, key: string): string { const value = source[key]; return typeof value === "string" ? value.trim() : ""; } function readEnum(value: unknown, values: readonly T[]): T | null { return typeof value === "string" ? values.find((item) => item === value) ?? null : null; } export function validateNoticeInput(value: unknown): ValidationResult { if (!isRecord(value)) { return { success: false, reason: "请求数据格式无效" }; } const title = readString(value, "title"); const content = readString(value, "content"); if (!title || !content) { return { success: false, reason: "公告标题和内容不能为空" }; } const status = readEnum(value.status, NOTICE_STATUS_VALUES); if (!status) { return { success: false, reason: "公告状态无效" }; } return { success: true, data: { title, content, audience: readString(value, "audience") || "全体员工", status, }, }; }