feat: 完善视频任务与 KOC 资源库
This commit is contained in:
@@ -2,7 +2,10 @@ import { getRuntimeEnv } from "../../../lib/runtime-env";
|
||||
import { runInBackground } from "../../../lib/background";
|
||||
|
||||
const env = getRuntimeEnv();
|
||||
import { backfillAccountProfiles } from "../../../lib/account-enrichment-service";
|
||||
import {
|
||||
backfillAccountProfiles,
|
||||
enrichDistributionAccount,
|
||||
} from "../../../lib/account-enrichment-service";
|
||||
import {
|
||||
ensureSchema,
|
||||
getDashboardData,
|
||||
@@ -35,6 +38,7 @@ import {
|
||||
releaseUnfinishedDistribution,
|
||||
} from "../../../lib/distribution-release-service";
|
||||
import { isManagerRequest } from "../../../lib/user-auth";
|
||||
import { extractPublishUrl } from "../../../lib/publish-url";
|
||||
|
||||
type ActionBody = {
|
||||
action?: string;
|
||||
@@ -63,6 +67,14 @@ export async function POST(request: Request) {
|
||||
sheetName: source.sheetName,
|
||||
syncedAt: source.syncedAt,
|
||||
rowCount: source.rows.length,
|
||||
imageCount: source.rows.reduce(
|
||||
(total, row) => total + row.images.length,
|
||||
0,
|
||||
),
|
||||
videoCount: source.rows.reduce(
|
||||
(total, row) => total + row.videos.length,
|
||||
0,
|
||||
),
|
||||
columns: source.columns,
|
||||
preview: source.rows.slice(0, 3),
|
||||
});
|
||||
@@ -72,6 +84,8 @@ export async function POST(request: Request) {
|
||||
const name = String(body.name ?? "").trim();
|
||||
const brand = String(body.brand ?? "").trim();
|
||||
const dueAt = String(body.dueAt ?? "").trim();
|
||||
const platform = body.platform === "抖音" ? "抖音" : "小红书";
|
||||
const contentFormat = body.contentFormat === "video" ? "video" : "image_text";
|
||||
if (!name || !brand || !dueAt) {
|
||||
return Response.json(
|
||||
{ error: "请补全任务名称、品牌和截止日期" },
|
||||
@@ -84,6 +98,8 @@ export async function POST(request: Request) {
|
||||
name,
|
||||
brand,
|
||||
dueAt,
|
||||
platform,
|
||||
contentFormat,
|
||||
},
|
||||
env as unknown as FeishuBindings,
|
||||
);
|
||||
@@ -146,6 +162,159 @@ export async function POST(request: Request) {
|
||||
db,
|
||||
String(body.distributionId ?? "").trim(),
|
||||
);
|
||||
} else if (body.action === "update_distribution_publish_url") {
|
||||
if (!(await isManagerRequest(request))) return adminForbidden();
|
||||
const distributionId = String(body.distributionId ?? "").trim();
|
||||
if (!distributionId) {
|
||||
return Response.json(
|
||||
{ error: "作品记录不存在" },
|
||||
{ status: 400 },
|
||||
);
|
||||
}
|
||||
const current = await db
|
||||
.prepare(
|
||||
`SELECT d.id, d.task_id, d.partner_id, d.publish_url,
|
||||
t.task_type, t.platform, t.collection_start_date, t.collection_days,
|
||||
COALESCE(a.nickname, '待识别账号') AS account_nickname
|
||||
FROM distributions d
|
||||
JOIN tasks t ON t.id = d.task_id
|
||||
LEFT JOIN accounts a ON a.id = d.account_id
|
||||
WHERE d.id = ?`,
|
||||
)
|
||||
.bind(distributionId)
|
||||
.first<{
|
||||
id: string;
|
||||
task_id: string;
|
||||
partner_id: string;
|
||||
publish_url: string | null;
|
||||
task_type?: string | null;
|
||||
platform: string;
|
||||
collection_start_date: string | null;
|
||||
collection_days: string;
|
||||
account_nickname: string;
|
||||
}>();
|
||||
if (!current) {
|
||||
return Response.json({ error: "作品记录不存在" }, { status: 404 });
|
||||
}
|
||||
if (current.task_type === "screenshot_collect") {
|
||||
return Response.json(
|
||||
{ error: "截图回收任务不需要填写发布链接" },
|
||||
{ status: 400 },
|
||||
);
|
||||
}
|
||||
const platform = current.platform === "抖音" ? "抖音" : "小红书";
|
||||
const publishUrl = extractPublishUrl(
|
||||
String(body.publishUrl ?? "").trim(),
|
||||
platform,
|
||||
);
|
||||
if (!publishUrl) {
|
||||
return Response.json(
|
||||
{ error: `请填写包含${platform}作品链接的发布内容` },
|
||||
{ status: 400 },
|
||||
);
|
||||
}
|
||||
if (current.publish_url === publishUrl) {
|
||||
return Response.json(await getDashboardData());
|
||||
}
|
||||
let collectionDays: number[] = [];
|
||||
try {
|
||||
const parsed = JSON.parse(current.collection_days || "[]");
|
||||
if (Array.isArray(parsed)) {
|
||||
collectionDays = [...new Set(parsed.map(Number))]
|
||||
.filter(
|
||||
(day) =>
|
||||
Number.isInteger(day) && day >= 1 && day <= 7,
|
||||
)
|
||||
.sort((a, b) => a - b);
|
||||
}
|
||||
} catch {
|
||||
collectionDays = [];
|
||||
}
|
||||
const isScheduled = Boolean(
|
||||
current.collection_start_date && collectionDays.length > 0,
|
||||
);
|
||||
const statements = [
|
||||
db
|
||||
.prepare(
|
||||
`UPDATE distributions SET
|
||||
publish_url = ?,
|
||||
publish_time = CURRENT_TIMESTAMP,
|
||||
status = 'published',
|
||||
d2_likes = NULL,
|
||||
d2_comments = NULL,
|
||||
d2_collects = NULL,
|
||||
d5_likes = NULL,
|
||||
d5_comments = NULL,
|
||||
d5_collects = NULL,
|
||||
d7_likes = NULL,
|
||||
d7_comments = NULL,
|
||||
d7_collects = NULL,
|
||||
latest_likes = NULL,
|
||||
latest_comments = NULL,
|
||||
latest_collects = NULL,
|
||||
latest_shares = NULL,
|
||||
collection_status = ?,
|
||||
collection_status_description = ?,
|
||||
collection_updated_at = NULL,
|
||||
last_collection_day = NULL,
|
||||
updated_at = CURRENT_TIMESTAMP
|
||||
WHERE id = ?`,
|
||||
)
|
||||
.bind(
|
||||
publishUrl,
|
||||
isScheduled ? "scheduled" : "pending",
|
||||
isScheduled
|
||||
? `管理员已更新链接,等待${collectionDays.length}个采集日`
|
||||
: "管理员已更新链接,等待设置采集计划",
|
||||
distributionId,
|
||||
),
|
||||
db
|
||||
.prepare("DELETE FROM collection_runs WHERE distribution_id = ?")
|
||||
.bind(distributionId),
|
||||
];
|
||||
if (!current.publish_url) {
|
||||
statements.push(
|
||||
db
|
||||
.prepare(
|
||||
`UPDATE partners SET completed_total = completed_total + 1
|
||||
WHERE id = ?`,
|
||||
)
|
||||
.bind(current.partner_id),
|
||||
);
|
||||
}
|
||||
await db.batch(statements);
|
||||
if (isScheduled && current.collection_start_date) {
|
||||
await createCollectionRunTasks(
|
||||
db,
|
||||
current.task_id,
|
||||
current.collection_start_date,
|
||||
collectionDays,
|
||||
);
|
||||
runInBackground(
|
||||
runDueScheduledCollections(
|
||||
db,
|
||||
Date.now(),
|
||||
resolveCollectionMcpConfig(
|
||||
env as unknown as CollectionMcpBindings,
|
||||
),
|
||||
"catchup",
|
||||
current.task_id,
|
||||
).catch(() => undefined),
|
||||
"collection catchup after publish URL update",
|
||||
);
|
||||
}
|
||||
runInBackground(
|
||||
enrichDistributionAccount(
|
||||
db,
|
||||
distributionId,
|
||||
publishUrl,
|
||||
current.account_nickname,
|
||||
resolveCollectionMcpConfig(
|
||||
env as unknown as CollectionMcpBindings,
|
||||
),
|
||||
).catch(() => undefined),
|
||||
"account enrichment after publish URL update",
|
||||
);
|
||||
} else if (body.action === "save_collection_schedule") {
|
||||
const taskId = String(body.taskId ?? "").trim();
|
||||
const startDate = String(body.startDate ?? "").trim();
|
||||
|
||||
Reference in New Issue
Block a user