feat: 完善视频任务与 KOC 资源库

This commit is contained in:
巫凤萍
2026-08-15 03:53:09 +08:00
parent ad3dbdcc86
commit f37d05dd88
66 changed files with 6633 additions and 558 deletions

View File

@@ -17,6 +17,7 @@ import {
type RecoveryWorkbookRow,
} from "../../../lib/recovery-workbook";
import { consumeMcpExportToken } from "../../../lib/mcp-export-token";
import { normalizeWorkbookImage } from "../../../lib/workbook-image";
const env = getRuntimeEnv();
@@ -53,6 +54,7 @@ type ExportRow = {
latest_likes: number | null;
latest_comments: number | null;
latest_collects: number | null;
latest_shares: number | null;
collection_status: string | null;
collection_status_description: string | null;
collection_updated_at: string | null;
@@ -121,12 +123,16 @@ function latestMetrics(row: ExportRow) {
const likes = row.latest_likes ?? legacyLikes;
const comments = row.latest_comments ?? legacyComments;
const collects = row.latest_collects ?? legacyCollects;
const shares = row.latest_shares;
return {
likes,
comments,
collects,
shares,
total:
likes === null ? null : likes + (comments ?? 0) + (collects ?? 0),
likes === null
? null
: likes + (comments ?? 0) + (collects ?? 0) + (shares ?? 0),
};
}
@@ -181,13 +187,13 @@ async function loadImage(reference: ImageReference) {
object = await bucket.get(reference.key);
}
if (!object) return null;
return {
return normalizeWorkbookImage({
bytes: new Uint8Array(await object.arrayBuffer()),
contentType: contentTypeFromObject(object),
width: reference.width,
height: reference.height,
description: reference.description,
} satisfies RecoveryWorkbookImage;
} satisfies RecoveryWorkbookImage);
}
async function loadImages(references: ImageReference[]) {
@@ -236,9 +242,9 @@ export async function GET(request: Request) {
}
const db = getRawDb();
const task = await db
.prepare("SELECT id, name, brand FROM tasks WHERE id = ?")
.prepare("SELECT id, name, brand, platform FROM tasks WHERE id = ?")
.bind(taskId)
.first<{ id: string; name: string; brand: string }>();
.first<{ id: string; name: string; brand: string; platform: string }>();
if (!task) {
return Response.json({ error: "没有找到这个任务" }, { status: 404 });
}
@@ -269,6 +275,7 @@ export async function GET(request: Request) {
d.latest_likes,
d.latest_comments,
d.latest_collects,
d.latest_shares,
d.collection_status,
d.collection_status_description,
d.collection_updated_at,
@@ -318,18 +325,19 @@ export async function GET(request: Request) {
}
});
const loadedImages = await loadImages(references);
const isDouyin = task.platform === "抖音";
const metricHeaders = isDouyin
? ["点赞", "收藏", "转发", "评论", "总互动"]
: ["点赞", "收藏", "评论", "总互动"];
const headers = [
"序号(不能改)",
"标题",
"笔记内容(正文+话题)",
...Array.from({ length: maxContentImages }, (_, index) => `图片${index + 1}`),
"小红书昵称",
`${task.platform}昵称`,
"发布链接",
"发布时间",
"点赞",
"收藏",
"评论",
"总互动",
...metricHeaders,
"曝光量-实际第7天",
"阅读量-实际第7天",
"数据分析截图(单篇笔记数据分析截图)",
@@ -341,7 +349,7 @@ export async function GET(request: Request) {
];
const originalImageStart = 3;
const accountColumn = originalImageStart + maxContentImages;
const creatorScreenshotColumn = accountColumn + 9;
const creatorScreenshotColumn = accountColumn + (isDouyin ? 10 : 9);
const publishScreenshotColumn = creatorScreenshotColumn + 1;
const workbookRows: RecoveryWorkbookRow[] = rows.map((row, rowIndex) => {
const metrics = latestMetrics(row);
@@ -350,7 +358,7 @@ export async function GET(request: Request) {
{ length: maxContentImages },
(_, index) => {
const asset = contentAssets.find((item) => item.index === index + 1);
return asset && loadedImages.get(asset.key) ? "见图" : asset ? "图片读取失败" : "";
return "";
},
);
const creatorImage = row.screenshot_key
@@ -369,12 +377,13 @@ export async function GET(request: Request) {
formatExportDate(row.publish_time),
metrics.likes,
metrics.collects,
...(isDouyin ? [metrics.shares] : []),
metrics.comments,
metrics.total,
row.exposure,
row.views,
creatorImage ? "见图" : row.screenshot_key ? "截图读取失败" : "",
publishImage ? "见图" : row.publish_screenshot_key ? "截图读取失败" : "",
"",
"",
formatExportDate(row.collection_updated_at || row.updated_at),
row.distribution_id ? collectionLabel(row) : "未领取",
row.partner_name || "",
@@ -403,6 +412,7 @@ export async function GET(request: Request) {
20,
11,
11,
...(isDouyin ? [11] : []),
11,
11,
18,