106 lines
5.1 KiB
TypeScript
106 lines
5.1 KiB
TypeScript
import { NextResponse } from "next/server";
|
|
import { prisma } from "@/lib/prisma";
|
|
import { requireAdmin } from "@/lib/admin-auth";
|
|
import { badRequest, notFound, serverError } from "@/lib/api-error";
|
|
|
|
export const dynamic = "force-dynamic";
|
|
|
|
|
|
export async function GET() {
|
|
try {
|
|
const tasks = [
|
|
{ taskKey: "task1-discover-tools", taskName: "发现AI工具", cronExpr: "0 6 * * *", enabled: true, desc: "每天从多源搜索新AI工具,过滤去重后入库等待审核" },
|
|
{ taskKey: "task3-check-tools", taskName: "工具巡检", cronExpr: "0 3 * * *", enabled: true, desc: "检查所有已入库工具的网站可用性、Logo完整性、自动发布合格工具" },
|
|
{ taskKey: "task4-discover-skills", taskName: "发现AI技能", cronExpr: "0 2 * * *", enabled: true, desc: "从GitHub搜索热门AI开源项目(≥1000 stars),获取README并入库" },
|
|
{ taskKey: "task5-update-stars", taskName: "更新星值", cronExpr: "0 1 * * *", enabled: true, desc: "更新所有GitHub技能的最新Stars数,计算日/周/月变化趋势" },
|
|
{ taskKey: "task6-review-hot", taskName: "评测热门", cronExpr: "0 4 * * *", enabled: true, desc: "对未评测的最热门2个AI技能进行五维深度评测并自动发布" },
|
|
{ taskKey: "daily-news", taskName: "AI日报生成", cronExpr: "30 7 * * *", enabled: true, desc: "搜索真实新闻素材,AI整理格式生成当日AI日报" },
|
|
{ taskKey: "task7-news-to-community", taskName: "新闻分发到社区", cronExpr: "0 8 * * *", enabled: true, desc: "将AI日报条目自动分发到社区对应板块创建话题" },
|
|
{ taskKey: "bot-activity", taskName: "Bot活动引擎", cronExpr: "0 9-23 * * *", enabled: true, desc: "Bot发帖/回复主循环:每小时从活跃时段挑选bot在主板块生成内容" },
|
|
{ taskKey: "bot-affinity-update", taskName: "Bot亲和度与画像", cronExpr: "0 */6 * * *", enabled: true, desc: "每6小时统计bot跨板块互动,更新画像(话题/回复长度/立场关键词)" },
|
|
{ taskKey: "bot-feedback-loop", taskName: "Bot反馈循环", cronExpr: "0 */3 * * *", enabled: true, desc: "每3小时基于bot历史回复生成follow-up,跟进讨论" },
|
|
{ taskKey: "bot-skill-crystallize", taskName: "Bot技能沉淀", cronExpr: "0 */12 * * *", enabled: true, desc: "把高互动话题沉淀为bot的'技能经验'写入botMemory" },
|
|
{ taskKey: "bot-weekly-review", taskName: "Bot周复盘", cronExpr: "30 2 * * 1", enabled: true, desc: "每周一凌晨生成本周bot表现报告,调整活跃度配额" },
|
|
{ taskKey: "cleanup-task-logs", taskName: "清理任务日志", cronExpr: "30 6 * * 0", enabled: true, desc: "每周日凌晨清理 30 天前的 task_log 数据,避免表无限膨胀" },
|
|
];
|
|
|
|
const configs = await prisma.taskConfig.findMany();
|
|
const configMap = new Map(configs.map((c) => [c.taskKey, c]));
|
|
|
|
const merged = tasks.map((t) => {
|
|
const cfg = configMap.get(t.taskKey);
|
|
return {
|
|
taskKey: t.taskKey,
|
|
taskName: t.taskName,
|
|
cronExpr: cfg?.cronExpr || t.cronExpr,
|
|
enabled: cfg?.enabled ?? t.enabled,
|
|
description: t.desc,
|
|
config: cfg?.config || null,
|
|
updatedAt: cfg?.updatedAt?.toISOString() || null,
|
|
};
|
|
});
|
|
|
|
return NextResponse.json({ tasks: merged });
|
|
} catch (error) {
|
|
return serverError(error);
|
|
}
|
|
}
|
|
|
|
export async function PUT(request: Request) {
|
|
const authError = await requireAdmin();
|
|
if (authError) return authError;
|
|
try {
|
|
const body = await request.json();
|
|
const taskKey = body.taskKey as string;
|
|
const { enabled, cronExpr, config } = body;
|
|
|
|
if (!taskKey) {
|
|
return NextResponse.json({ error: "缺少taskKey" }, { status: 400 });
|
|
}
|
|
|
|
const existing = await prisma.taskConfig.findUnique({ where: { taskKey } });
|
|
let result;
|
|
|
|
if (existing) {
|
|
result = await prisma.taskConfig.update({
|
|
where: { taskKey },
|
|
data: {
|
|
enabled: enabled ?? existing.enabled,
|
|
cronExpr: cronExpr ?? existing.cronExpr,
|
|
config: config ?? existing.config,
|
|
},
|
|
});
|
|
} else {
|
|
const taskMeta: Record<string, string> = {
|
|
"task1-discover-tools": "发现AI工具",
|
|
"task3-check-tools": "工具巡检",
|
|
"task4-discover-skills": "发现AI技能",
|
|
"task5-update-stars": "更新星值",
|
|
"task6-review-hot": "评测热门",
|
|
"daily-news": "AI日报生成",
|
|
"task7-news-to-community": "新闻分发到社区",
|
|
"bot-activity": "Bot活动引擎",
|
|
"bot-affinity-update": "Bot亲和度与画像",
|
|
"bot-feedback-loop": "Bot反馈循环",
|
|
"bot-skill-crystallize": "Bot技能沉淀",
|
|
"bot-weekly-review": "Bot周复盘",
|
|
"cleanup-task-logs": "清理任务日志",
|
|
};
|
|
result = await prisma.taskConfig.create({
|
|
data: {
|
|
taskKey,
|
|
taskName: taskMeta[taskKey] || taskKey,
|
|
enabled: enabled ?? true,
|
|
cronExpr: cronExpr || null,
|
|
config: config || null,
|
|
},
|
|
});
|
|
}
|
|
|
|
return NextResponse.json({ task: result });
|
|
} catch (error) {
|
|
return serverError(error);
|
|
}
|
|
}
|
|
|