102 lines
2.6 KiB
TypeScript
102 lines
2.6 KiB
TypeScript
import { z } from "zod";
|
|
import { ChatSDKError } from "@/lib/errors";
|
|
import { listRecentDingTalkNotificationTasks } from "@/lib/jobs/dingtalk-notification-job";
|
|
import { requireAdmin } from "@/lib/middleware/admin";
|
|
import { db } from "@/lib/db";
|
|
import { dingTalkNotificationTask } from "@/lib/db/schema";
|
|
|
|
const createTaskSchema = z.object({
|
|
title: z.string().trim().min(1, "通知标题不能为空").max(100, "通知标题过长"),
|
|
content: z
|
|
.string()
|
|
.trim()
|
|
.min(1, "通知内容不能为空")
|
|
.max(20000, "通知内容过长"),
|
|
scheduledAt: z.string().trim().min(1, "请选择发送时间"),
|
|
});
|
|
|
|
function parseFutureSchedule(value: string) {
|
|
const scheduledAt = new Date(value);
|
|
|
|
if (Number.isNaN(scheduledAt.getTime())) {
|
|
throw new Error("定时发送时间格式不正确");
|
|
}
|
|
|
|
if (scheduledAt.getTime() <= Date.now()) {
|
|
throw new Error("定时发送时间必须晚于当前时间");
|
|
}
|
|
|
|
return scheduledAt;
|
|
}
|
|
|
|
export async function GET(request: Request) {
|
|
try {
|
|
await requireAdmin();
|
|
|
|
const { searchParams } = new URL(request.url);
|
|
const limitParam = Number.parseInt(searchParams.get("limit") || "30", 10);
|
|
const limit = Number.isFinite(limitParam)
|
|
? Math.max(1, Math.min(100, limitParam))
|
|
: 30;
|
|
|
|
const tasks = await listRecentDingTalkNotificationTasks(limit);
|
|
|
|
return Response.json({ tasks });
|
|
} catch (error) {
|
|
if (error instanceof ChatSDKError) {
|
|
return error.toResponse();
|
|
}
|
|
|
|
return Response.json(
|
|
{ error: "获取钉钉通知任务失败" },
|
|
{ status: 500 },
|
|
);
|
|
}
|
|
}
|
|
|
|
export async function POST(request: Request) {
|
|
try {
|
|
const session = await requireAdmin();
|
|
const body = createTaskSchema.parse(await request.json());
|
|
const scheduledAt = parseFutureSchedule(body.scheduledAt);
|
|
|
|
const [task] = await db
|
|
.insert(dingTalkNotificationTask)
|
|
.values({
|
|
title: body.title,
|
|
content: body.content,
|
|
status: "pending",
|
|
scheduledAt,
|
|
createdBy: session.user.id,
|
|
createdAt: new Date(),
|
|
updatedAt: new Date(),
|
|
})
|
|
.returning();
|
|
|
|
return Response.json({
|
|
success: true,
|
|
task,
|
|
});
|
|
} catch (error) {
|
|
if (error instanceof ChatSDKError) {
|
|
return error.toResponse();
|
|
}
|
|
|
|
if (error instanceof z.ZodError) {
|
|
return Response.json(
|
|
{ success: false, error: error.issues[0]?.message || "参数校验失败" },
|
|
{ status: 400 },
|
|
);
|
|
}
|
|
|
|
return Response.json(
|
|
{
|
|
success: false,
|
|
error:
|
|
error instanceof Error ? error.message : "创建钉钉通知任务失败",
|
|
},
|
|
{ status: 500 },
|
|
);
|
|
}
|
|
}
|