feat: build collaboration workspaces
This commit is contained in:
95
modules/notices/types.ts
Normal file
95
modules/notices/types.ts
Normal file
@@ -0,0 +1,95 @@
|
||||
export const NOTICE_STATUS_VALUES = ["draft", "published", "retracted"] as const;
|
||||
export type NoticeStatus = (typeof NOTICE_STATUS_VALUES)[number];
|
||||
|
||||
export const NOTICE_STATUS_LABELS: Record<NoticeStatus, string> = {
|
||||
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<T> = {
|
||||
success: true;
|
||||
data: T;
|
||||
};
|
||||
|
||||
type ValidationFailure = {
|
||||
success: false;
|
||||
reason: string;
|
||||
};
|
||||
|
||||
export type ValidationResult<T> = ValidationSuccess<T> | ValidationFailure;
|
||||
|
||||
function isRecord(value: unknown): value is Record<string, unknown> {
|
||||
return typeof value === "object" && value !== null && !Array.isArray(value);
|
||||
}
|
||||
|
||||
function readString(source: Record<string, unknown>, key: string): string {
|
||||
const value = source[key];
|
||||
return typeof value === "string" ? value.trim() : "";
|
||||
}
|
||||
|
||||
function readEnum<T extends string>(value: unknown, values: readonly T[]): T | null {
|
||||
return typeof value === "string" ? values.find((item) => item === value) ?? null : null;
|
||||
}
|
||||
|
||||
export function validateNoticeInput(value: unknown): ValidationResult<NoticeInput> {
|
||||
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,
|
||||
},
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user