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 }, ); } }