diff --git a/src/content/market/audience-profile-csv.ts b/src/content/market/audience-profile-csv.ts index a544283..999df22 100644 --- a/src/content/market/audience-profile-csv.ts +++ b/src/content/market/audience-profile-csv.ts @@ -11,10 +11,9 @@ import type { AudienceProfileKind, AudienceProfileResult, BusinessAbilityDurationKind, - BusinessAbilityEstimateMetrics, - BusinessAbilityVideoKind, - BusinessAbilityVideoMetrics + BusinessAbilityEstimateMetrics } from "./audience-profile-types"; +import { buildSpreadInfoColumns } from "./spread-info"; type AudienceProfileCsvColumn = { header: string; @@ -60,29 +59,6 @@ const CROWD_LABELS = [ "小镇青年" ]; -const BUSINESS_VIDEO_LAYOUTS: Array<{ - key: BusinessAbilityVideoKind; - label: string; -}> = [ - { key: "personalVideo", label: "个人视频" }, - { key: "xingtuVideo", label: "星图视频" } -]; - -const BUSINESS_VIDEO_METRIC_LAYOUTS: Array<{ - key: keyof BusinessAbilityVideoMetrics; - label: string; -}> = [ - { key: "medianPlay", label: "播放量中位数" }, - { key: "finishRate", label: "完播率" }, - { key: "interactionRate", label: "互动率" }, - { key: "publishedItems", label: "发布作品" }, - { key: "averageDuration", label: "平均时长" }, - { key: "averageLike", label: "平均点赞" }, - { key: "averageComment", label: "平均评论" }, - { key: "averageShare", label: "平均转发" } -]; - -const BUSINESS_VIDEO_SECTION_LABEL = "内容数据"; const BUSINESS_ESTIMATE_SECTION_LABEL = "效果预估"; const BUSINESS_ESTIMATE_LAYOUTS: Array<{ @@ -146,7 +122,7 @@ export function listAudienceProfileSelectableFieldGroups(): AudienceProfileCsvFi label: "秒思api数据" }, { - headers: buildBusinessVideoColumns().map((column) => column.header), + headers: buildSpreadInfoColumns(), label: "内容数据" }, { @@ -184,19 +160,7 @@ function listAudienceProfileSelectableHeaders(): string[] { } function buildBusinessAbilityColumns(): AudienceProfileCsvColumn[] { - return [...buildBusinessVideoColumns(), ...buildBusinessEstimateColumns()]; -} - -function buildBusinessVideoColumns(): AudienceProfileCsvColumn[] { - return [ - ...BUSINESS_VIDEO_LAYOUTS.flatMap((videoLayout) => - BUSINESS_VIDEO_METRIC_LAYOUTS.map((metricLayout) => ({ - header: `${BUSINESS_VIDEO_SECTION_LABEL}-${videoLayout.label}-${metricLayout.label}`, - readValue: (row: AudienceProfileExportRow) => - readBusinessVideoValue(row, videoLayout.key, metricLayout.key) - })) - ) - ]; + return buildBusinessEstimateColumns(); } function buildBusinessEstimateColumns(): AudienceProfileCsvColumn[] { @@ -211,19 +175,6 @@ function buildBusinessEstimateColumns(): AudienceProfileCsvColumn[] { ]; } -function readBusinessVideoValue( - row: AudienceProfileExportRow, - videoKey: BusinessAbilityVideoKind, - metricKey: keyof BusinessAbilityVideoMetrics -): string { - const businessAbility = row.businessAbility; - if (!businessAbility || businessAbility.status !== "success") { - return ""; - } - - return businessAbility.videos[videoKey]?.[metricKey] ?? ""; -} - function readBusinessEstimateValue( row: AudienceProfileExportRow, durationKey: BusinessAbilityDurationKind, diff --git a/src/content/market/audience-profile-types.ts b/src/content/market/audience-profile-types.ts index a05640a..5b8342b 100644 --- a/src/content/market/audience-profile-types.ts +++ b/src/content/market/audience-profile-types.ts @@ -42,21 +42,6 @@ export interface AudienceProfileExportRow { record: MarketRecord; } -export type BusinessAbilityVideoKind = - | "personalVideo" - | "xingtuVideo"; - -export interface BusinessAbilityVideoMetrics { - averageComment: string; - averageDuration: string; - averageLike: string; - averageShare: string; - finishRate: string; - interactionRate: string; - medianPlay: string; - publishedItems: string; -} - export type BusinessAbilityDurationKind = | "oneToTwenty" | "twentyToSixty" @@ -74,7 +59,6 @@ export interface BusinessAbilitySuccess { Record >; status: "success"; - videos: Partial>; } export interface BusinessAbilityFailure { diff --git a/src/content/market/business-ability-client.ts b/src/content/market/business-ability-client.ts index f11f927..da2f9e9 100644 --- a/src/content/market/business-ability-client.ts +++ b/src/content/market/business-ability-client.ts @@ -3,8 +3,7 @@ import type { BusinessAbilityDurationKind, BusinessAbilityEstimateMetrics, BusinessAbilityResult, - BusinessAbilitySuccess, - BusinessAbilityVideoMetrics + BusinessAbilitySuccess } from "./audience-profile-types"; interface FetchResponseLike { @@ -23,11 +22,6 @@ interface BusinessAbilityClientOptions { timeoutMs?: number; } -const VIDEO_TYPES = { - personalVideo: 1, - xingtuVideo: 2 -} as const; - export function createBusinessAbilityClient( options: BusinessAbilityClientOptions = {} ) { @@ -37,33 +31,20 @@ export function createBusinessAbilityClient( return { async loadBusinessAbility(record: MarketRecord): Promise { - const personalVideo = await loadJson( - buildBusinessAbilityVideoUrl(record.authorId, baseUrl, VIDEO_TYPES.personalVideo) - ); - const xingtuVideo = await loadJson( - buildBusinessAbilityVideoUrl(record.authorId, baseUrl, VIDEO_TYPES.xingtuVideo) - ); const estimates = await loadJson( buildBusinessAbilityEstimateUrl(record.authorId, baseUrl) ); - if (!personalVideo.ok || !xingtuVideo.ok || !estimates.ok) { + if (!estimates.ok) { return { - failureReason: - personalVideo.failureReason ?? - xingtuVideo.failureReason ?? - estimates.failureReason, + failureReason: estimates.failureReason, status: "failed" }; } return { estimates: mapBusinessAbilityEstimateResponse(estimates.payload), - status: "success", - videos: { - personalVideo: mapBusinessAbilityVideoResponse(personalVideo.payload), - xingtuVideo: mapBusinessAbilityVideoResponse(xingtuVideo.payload) - } + status: "success" } satisfies BusinessAbilitySuccess; } }; @@ -101,22 +82,6 @@ export function createBusinessAbilityClient( } } -export function buildBusinessAbilityVideoUrl( - authorId: string, - baseUrl: string, - videoType: number -): string { - const url = new URL("/gw/api/data_sp/get_author_spread_info", baseUrl); - url.searchParams.set("o_author_id", authorId); - url.searchParams.set("platform_source", "1"); - url.searchParams.set("platform_channel", "1"); - url.searchParams.set("type", String(videoType)); - url.searchParams.set("flow_type", "0"); - url.searchParams.set("only_assign", "true"); - url.searchParams.set("range", "2"); - return url.toString(); -} - export function buildBusinessAbilityEstimateUrl( authorId: string, baseUrl: string @@ -129,25 +94,6 @@ export function buildBusinessAbilityEstimateUrl( return url.toString(); } -export function mapBusinessAbilityVideoResponse( - payload: unknown -): BusinessAbilityVideoMetrics { - const data = getPayloadData(payload); - - return { - averageComment: formatWan(readNumber(data?.comment_avg)), - averageDuration: formatDuration(readNumber(data?.avg_duration)), - averageLike: formatWan(readNumber(data?.like_avg)), - averageShare: formatWan(readNumber(data?.share_avg)), - finishRate: formatBasisPointRate(readNestedNumber(data, "play_over_rate", "value")), - interactionRate: formatBasisPointRate( - readNestedNumber(data, "interact_rate", "value") - ), - medianPlay: formatWan(readNumber(data?.play_mid)), - publishedItems: formatPublishedItems(readNumber(data?.item_num)) - }; -} - export function mapBusinessAbilityEstimateResponse( payload: unknown ): Partial> { @@ -177,30 +123,6 @@ export function mapBusinessAbilityEstimateResponse( }; } -function formatPublishedItems(value: number | null): string { - if (value === null) { - return ""; - } - - return value > 0 && value < 5 ? "<5" : formatDecimal(value, 0); -} - -function formatDuration(value: number | null): string { - if (value === null) { - return ""; - } - - return `${formatDecimal(value / 100, 0)}s`; -} - -function formatBasisPointRate(value: number | null): string { - if (value === null) { - return ""; - } - - return `${formatDecimal(value / 100, 1)}%`; -} - function formatDecimalRate(value: number | null): string { if (value === null) { return "缺失"; @@ -238,19 +160,6 @@ function formatFixedDecimal(value: number | null, digits: number): string { return value.toFixed(digits); } -function readNestedNumber( - data: Record | null, - objectKey: string, - valueKey: string -): number | null { - const objectValue = data?.[objectKey]; - if (!isRecord(objectValue)) { - return null; - } - - return readNumber(objectValue[valueKey]); -} - function readNumber(value: unknown): number | null { if (typeof value === "number" && Number.isFinite(value)) { return value; diff --git a/src/content/market/index.ts b/src/content/market/index.ts index f0075be..bf3f14a 100644 --- a/src/content/market/index.ts +++ b/src/content/market/index.ts @@ -265,6 +265,7 @@ export function createMarketController(options: CreateMarketControllerOptions) { try { const selectedRecords = filterRecordsBySelectionStrict( await exportRecords(exportTarget.target, "画像导出中", { + includeSpreadMetrics: true, showDetailedProgress: false }) ); @@ -878,13 +879,17 @@ export function createMarketController(options: CreateMarketControllerOptions) { loadAuthorBaseInfoSafe(authorId), loadAuthorMetricsSafe(authorId) ]); + const spreadMetrics = baseRecord.spreadAuthorId + ? await loadSpreadMetrics(baseRecord.spreadAuthorId) + : {}; const recordForRequests = { ...baseRecord, authorName: baseRecord.authorName || authorId, ...(metricsResult.success ? { rates: metricsResult.rates } : {}), ...(backendMetrics ? { backendMetrics, backendMetricsStatus: "success" as const } - : {}) + : {}), + ...(Object.keys(spreadMetrics).length > 0 ? { spreadMetrics } : {}) }; const [profiles, businessAbility] = await Promise.all([ loadAudienceProfileSet(recordForRequests), diff --git a/src/content/market/spread-info.ts b/src/content/market/spread-info.ts index ac3fe92..66673b0 100644 --- a/src/content/market/spread-info.ts +++ b/src/content/market/spread-info.ts @@ -226,7 +226,7 @@ function buildSpreadInfoColumnHeader( config: SpreadInfoConfig, metric: SpreadInfoMetricDefinition ): string { - return [...buildConfigPrefixParts(config), metric.label].join("_"); + return ["内容数据", ...buildConfigPrefixParts(config), metric.label].join("-"); } function buildConfigPrefixParts(config: SpreadInfoConfig): string[] { diff --git a/tests/audience-profile-csv.test.ts b/tests/audience-profile-csv.test.ts index e99e67e..c714d4b 100644 --- a/tests/audience-profile-csv.test.ts +++ b/tests/audience-profile-csv.test.ts @@ -54,29 +54,7 @@ describe("audience-profile-csv", () => { hotRate: "缺失" } }, - status: "success", - videos: { - personalVideo: { - averageComment: "4.5w", - averageDuration: "150s", - averageLike: "113.2w", - averageShare: "26.5w", - finishRate: "15.8%", - interactionRate: "3.9%", - medianPlay: "3738.4w", - publishedItems: "<5" - }, - xingtuVideo: { - averageComment: "5.1w", - averageDuration: "170s", - averageLike: "150.3w", - averageShare: "68.4w", - finishRate: "19.9%", - interactionRate: "5.5%", - medianPlay: "4059.7w", - publishedItems: "<5" - } - } + status: "success" }, record: { authorId: "123", @@ -85,6 +63,10 @@ describe("audience-profile-csv", () => { 达人信息: "达人 A", 连接用户数: "300w" }, + spreadMetrics: { + "内容数据-个人视频-近30天-播放量中位数": "10913233", + "内容数据-只看指派-不排除营销流量-星图视频-近90天-作品平均评论数": "7502" + }, status: "success" } } satisfies AudienceProfileExportRow @@ -95,8 +77,10 @@ describe("audience-profile-csv", () => { expect(headerLine).toContain("达人信息,连接用户数"); expect(headerLine).not.toContain("抓取状态"); expect(headerLine).not.toContain("失败原因"); - expect(headerLine).toContain("内容数据-个人视频-播放量中位数"); - expect(headerLine).toContain("内容数据-星图视频-平均转发"); + expect(headerLine).toContain("内容数据-个人视频-近30天-播放量中位数"); + expect(headerLine).toContain( + "内容数据-只看指派-不排除营销流量-星图视频-近90天-作品平均评论数" + ); expect(headerLine).toContain("效果预估-1-20s视频-预期CPM"); expect(headerLine).toContain("效果预估-20-60s视频-爆文率"); expect(headerLine).toContain("效果预估-60s以上视频-预期播放量"); @@ -116,8 +100,15 @@ describe("audience-profile-csv", () => { expect(headerLine).not.toContain("兴趣TOP"); expect(rowLine).toContain("71.7%"); expect(rowLine).toContain("60%"); - expect(readCsvValue(csv, "内容数据-个人视频-播放量中位数")).toBe("3738.4w"); - expect(readCsvValue(csv, "内容数据-星图视频-平均转发")).toBe("68.4w"); + expect(readCsvValue(csv, "内容数据-个人视频-近30天-播放量中位数")).toBe( + "10913233" + ); + expect( + readCsvValue( + csv, + "内容数据-只看指派-不排除营销流量-星图视频-近90天-作品平均评论数" + ) + ).toBe("7502"); expect(readCsvValue(csv, "效果预估-1-20s视频-预期CPM")).toBe("120.0"); expect(readCsvValue(csv, "效果预估-20-60s视频-爆文率")).toBe("缺失"); }); @@ -202,7 +193,7 @@ describe("audience-profile-csv", () => { const row = buildSuccessRow(); const csv = buildAudienceProfileCsv([row], { selectedHeaders: [ - "内容数据-个人视频-播放量中位数", + "内容数据-个人视频-近30天-播放量中位数", "观众画像-男性占比" ] }); @@ -210,9 +201,9 @@ describe("audience-profile-csv", () => { const [headerLine, rowLine] = csv.split("\n"); expect(headerLine).toBe( - "达人信息,连接用户数,内容数据-个人视频-播放量中位数,观众画像-男性占比" + "达人信息,连接用户数,内容数据-个人视频-近30天-播放量中位数,观众画像-男性占比" ); - expect(rowLine).toBe("达人 A,300w,3738.4w,71.7%"); + expect(rowLine).toBe("达人 A,300w,10913233,71.7%"); expect(headerLine).not.toContain("秒思api-看后搜数"); expect(headerLine).not.toContain("粉丝画像-女性占比"); }); @@ -227,15 +218,15 @@ describe("audience-profile-csv", () => { } }); const csv = buildAudienceProfileCsv([row], { - selectedHeaders: ["内容数据-个人视频-播放量中位数"] + selectedHeaders: ["内容数据-个人视频-近30天-播放量中位数"] }); const [headerLine, rowLine] = csv.split("\n"); expect(headerLine).toBe( - "达人ID,达人名称,导出状态,失败原因,内容数据-个人视频-播放量中位数" + "达人ID,达人名称,导出状态,失败原因,内容数据-个人视频-近30天-播放量中位数" ); - expect(rowLine).toBe("123,达人 A,成功,,3738.4w"); + expect(rowLine).toBe("123,达人 A,成功,,10913233"); }); test("lists headers for field picker defaults", () => { @@ -244,7 +235,7 @@ describe("audience-profile-csv", () => { "达人信息", "连接用户数", "秒思api-看后搜数", - "内容数据-个人视频-播放量中位数", + "内容数据-个人视频-近30天-播放量中位数", "效果预估-20-60s视频-预期CPM", "观众画像-男性占比", "铁粉画像-小镇青年占比" @@ -260,7 +251,9 @@ describe("audience-profile-csv", () => { label: "秒思api数据" }), expect.objectContaining({ - headers: expect.arrayContaining(["内容数据-个人视频-播放量中位数"]), + headers: expect.arrayContaining([ + "内容数据-只看指派-不排除营销流量-星图视频-近90天-作品平均评论数" + ]), label: "内容数据" }), expect.objectContaining({ @@ -310,12 +303,7 @@ function buildSuccessRow( hotRate: "缺失" } }, - status: "success", - videos: { - personalVideo: { - medianPlay: "3738.4w" - } - } + status: "success" }, record: { authorId: "123", @@ -324,6 +312,10 @@ function buildSuccessRow( 达人信息: "达人 A", 连接用户数: "300w" }, + spreadMetrics: { + "内容数据-个人视频-近30天-播放量中位数": "10913233", + "内容数据-只看指派-不排除营销流量-星图视频-近90天-作品平均评论数": "7502" + }, status: "success", ...overrides } diff --git a/tests/business-ability-client.test.ts b/tests/business-ability-client.test.ts index 7b05969..cfe61ef 100644 --- a/tests/business-ability-client.test.ts +++ b/tests/business-ability-client.test.ts @@ -2,24 +2,12 @@ import { describe, expect, test, vi } from "vitest"; import { buildBusinessAbilityEstimateUrl, - buildBusinessAbilityVideoUrl, createBusinessAbilityClient, - mapBusinessAbilityEstimateResponse, - mapBusinessAbilityVideoResponse + mapBusinessAbilityEstimateResponse } from "../src/content/market/business-ability-client"; describe("business-ability-client", () => { - test("builds commercial ability urls used by the Xingtu detail page", () => { - expect( - buildBusinessAbilityVideoUrl( - "6724241209444794382", - "https://www.xingtu.cn", - 2 - ) - ).toBe( - "https://www.xingtu.cn/gw/api/data_sp/get_author_spread_info?o_author_id=6724241209444794382&platform_source=1&platform_channel=1&type=2&flow_type=0&only_assign=true&range=2" - ); - + test("builds the commerce spread estimate url used by the Xingtu detail page", () => { expect( buildBusinessAbilityEstimateUrl( "6724241209444794382", @@ -30,19 +18,6 @@ describe("business-ability-client", () => { ); }); - test("maps video content metrics into page-style display values", () => { - expect(mapBusinessAbilityVideoResponse(buildVideoPayload())).toEqual({ - averageComment: "5.1w", - averageDuration: "170s", - averageLike: "150.3w", - averageShare: "68.4w", - finishRate: "19.9%", - interactionRate: "5.5%", - medianPlay: "4059.7w", - publishedItems: "<5" - }); - }); - test("maps duration estimates into page-style display values", () => { expect(mapBusinessAbilityEstimateResponse(buildEstimatePayload())).toEqual({ oneToTwenty: { @@ -98,15 +73,12 @@ describe("business-ability-client", () => { }); }); - test("loads personal video, Xingtu video, and duration estimate metrics", async () => { + test("loads duration estimate metrics without requesting legacy video content metrics", async () => { const requestedUrls: string[] = []; const fetchImpl = vi.fn(async (input: string) => { requestedUrls.push(input); return { - json: async () => - input.includes("get_author_commerce_spread_info") - ? buildEstimatePayload() - : buildVideoPayload(), + json: async () => buildEstimatePayload(), ok: true }; }); @@ -126,35 +98,15 @@ describe("business-ability-client", () => { estimates: expect.objectContaining({ twentyToSixty: expect.objectContaining({ expectedCpm: "212.0" }) }), - status: "success", - videos: { - personalVideo: expect.objectContaining({ medianPlay: "4059.7w" }), - xingtuVideo: expect.objectContaining({ medianPlay: "4059.7w" }) - } + status: "success" }); expect(requestedUrls).toEqual([ - "https://www.xingtu.cn/gw/api/data_sp/get_author_spread_info?o_author_id=6724241209444794382&platform_source=1&platform_channel=1&type=1&flow_type=0&only_assign=true&range=2", - "https://www.xingtu.cn/gw/api/data_sp/get_author_spread_info?o_author_id=6724241209444794382&platform_source=1&platform_channel=1&type=2&flow_type=0&only_assign=true&range=2", "https://www.xingtu.cn/gw/api/aggregator/get_author_commerce_spread_info?o_author_id=6724241209444794382" ]); }); }); -function buildVideoPayload() { - return { - avg_duration: 17002, - base_resp: { status_code: 0, status_message: "" }, - comment_avg: 51404, - interact_rate: { value: 551 }, - item_num: 2, - like_avg: 1503028, - play_mid: 40596960, - play_over_rate: { value: 1991 }, - share_avg: 684318 - }; -} - function buildEstimatePayload() { return { base_resp: { status_code: 0, status_message: "" }, diff --git a/tests/csv-exporter.test.ts b/tests/csv-exporter.test.ts index cdb23f8..0f1f390 100644 --- a/tests/csv-exporter.test.ts +++ b/tests/csv-exporter.test.ts @@ -196,8 +196,8 @@ describe("csv-exporter", () => { authorId: "123", authorName: "Alice", spreadMetrics: { - "个人视频_近30天_完播率": "28.24%", - "只看指派_排除营销流量_星图视频_近30天_互动率": "4.02%" + "内容数据-个人视频-近30天-完播率": "28.24%", + "内容数据-只看指派-排除营销流量-星图视频-近30天-互动率": "4.02%" }, status: "success" } satisfies MarketRecord @@ -207,12 +207,12 @@ describe("csv-exporter", () => { expect(headerLine).toContain( [ "秒思api-cp_search", - "个人视频_近30天_完播率", - "个人视频_近30天_播放量中位数" + "内容数据-个人视频-近30天-完播率", + "内容数据-个人视频-近30天-播放量中位数" ].join(",") ); expect(headerLine).toContain( - "只看指派_排除营销流量_星图视频_近30天_互动率" + "内容数据-只看指派-排除营销流量-星图视频-近30天-互动率" ); expect(rowLine).toContain("28.24%"); expect(rowLine).toContain("4.02%"); diff --git a/tests/market-content-entry.test.ts b/tests/market-content-entry.test.ts index 9af6b6b..db5ed0d 100644 --- a/tests/market-content-entry.test.ts +++ b/tests/market-content-entry.test.ts @@ -1285,7 +1285,7 @@ describe("market-content-entry", () => { ]); const buildCsv = vi.fn(() => "csv-output"); const loadSpreadMetrics = vi.fn(async (spreadAuthorId: string) => ({ - "个人视频_近30天_完播率": spreadAuthorId === "spread-a" ? "28.24%" : "18.24%" + "内容数据-个人视频-近30天-完播率": spreadAuthorId === "spread-a" ? "28.24%" : "18.24%" })); const { createMarketController } = await import("../src/content/market/index"); @@ -1314,14 +1314,14 @@ describe("market-content-entry", () => { authorId: "a", spreadAuthorId: "spread-a", spreadMetrics: { - "个人视频_近30天_完播率": "28.24%" + "内容数据-个人视频-近30天-完播率": "28.24%" } }), expect.objectContaining({ authorId: "b", spreadAuthorId: "spread-b", spreadMetrics: { - "个人视频_近30天_完播率": "18.24%" + "内容数据-个人视频-近30天-完播率": "18.24%" } }) ]); @@ -1829,8 +1829,7 @@ describe("market-content-entry", () => { const buildAudienceProfileCsv = vi.fn(() => "profile-csv"); const loadBusinessAbility = vi.fn(async () => ({ estimates: {}, - status: "success" as const, - videos: {} + status: "success" as const })); const loadAudienceProfile = vi.fn(async (_record, target) => { if (target.source === "fansDistribution" && target.authorType === 5) { @@ -1918,8 +1917,7 @@ describe("market-content-entry", () => { })); const loadBusinessAbility = vi.fn(async () => ({ estimates: {}, - status: "success" as const, - videos: {} + status: "success" as const })); const loadAudienceProfile = vi.fn(async () => ({ age: [{ label: "31-40", value: "60%" }], @@ -2051,13 +2049,12 @@ describe("market-content-entry", () => { ]); window.localStorage.setItem( "sces:audience-profile:selectedHeaders", - JSON.stringify(["内容数据-个人视频-播放量中位数", "秒思api-看后搜数"]) + JSON.stringify(["内容数据-个人视频-近30天-播放量中位数", "秒思api-看后搜数"]) ); const buildAudienceProfileCsv = vi.fn(() => "profile-csv"); const loadBusinessAbility = vi.fn(async () => ({ estimates: {}, - status: "success" as const, - videos: {} + status: "success" as const })); const loadAudienceProfile = vi.fn(async () => ({ age: [], @@ -2091,7 +2088,7 @@ describe("market-content-entry", () => { await waitForMockCall(buildAudienceProfileCsv, 40, 50); expect(buildAudienceProfileCsv.mock.calls[0][1]).toEqual({ - selectedHeaders: ["内容数据-个人视频-播放量中位数", "秒思api-看后搜数"] + selectedHeaders: ["内容数据-个人视频-近30天-播放量中位数", "秒思api-看后搜数"] }); }); @@ -2127,7 +2124,7 @@ describe("market-content-entry", () => { window.localStorage.getItem("sces:audience-profile:selectedHeaders") ?? "[]" ) as string[]; expect(savedHeaders).not.toContain("秒思api-看后搜数"); - expect(savedHeaders).toContain("内容数据-个人视频-播放量中位数"); + expect(savedHeaders).toContain("内容数据-个人视频-近30天-播放量中位数"); expect( document.querySelector('[data-plugin-export-status="text"]')?.textContent ).toContain("字段已保存"); diff --git a/tests/spread-info.test.ts b/tests/spread-info.test.ts index 5b5627e..4ff7fc7 100644 --- a/tests/spread-info.test.ts +++ b/tests/spread-info.test.ts @@ -47,8 +47,8 @@ describe("spread-info", () => { } ]); expect(buildSpreadInfoColumns(personalConfigs).slice(0, 2)).toEqual([ - "个人视频_近30天_完播率", - "个人视频_近30天_播放量中位数" + "内容数据-个人视频-近30天-完播率", + "内容数据-个人视频-近30天-播放量中位数" ]); }); @@ -78,13 +78,13 @@ describe("spread-info", () => { type: 2 } ])).toEqual([ - "只看指派_排除营销流量_星图视频_近30天_完播率", - "只看指派_排除营销流量_星图视频_近30天_播放量中位数", - "只看指派_排除营销流量_星图视频_近30天_互动率", - "只看指派_排除营销流量_星图视频_近30天_作品平均时长", - "只看指派_排除营销流量_星图视频_近30天_作品平均评论数", - "只看指派_排除营销流量_星图视频_近30天_作品平均点赞数", - "只看指派_排除营销流量_星图视频_近30天_作品平均转发数" + "内容数据-只看指派-排除营销流量-星图视频-近30天-完播率", + "内容数据-只看指派-排除营销流量-星图视频-近30天-播放量中位数", + "内容数据-只看指派-排除营销流量-星图视频-近30天-互动率", + "内容数据-只看指派-排除营销流量-星图视频-近30天-作品平均时长", + "内容数据-只看指派-排除营销流量-星图视频-近30天-作品平均评论数", + "内容数据-只看指派-排除营销流量-星图视频-近30天-作品平均点赞数", + "内容数据-只看指派-排除营销流量-星图视频-近30天-作品平均转发数" ]); }); @@ -150,13 +150,13 @@ describe("spread-info", () => { await expect( client.loadAuthorSpreadMetrics("7361012802036695050") ).resolves.toEqual({ - "个人视频_近30天_互动率": "4.02%", - "个人视频_近30天_作品平均点赞数": "494458", - "个人视频_近30天_作品平均评论数": "7502", - "个人视频_近30天_作品平均时长": "56", - "个人视频_近30天_作品平均转发数": "188267", - "个人视频_近30天_完播率": "28.24%", - "个人视频_近30天_播放量中位数": "10913233" + "内容数据-个人视频-近30天-互动率": "4.02%", + "内容数据-个人视频-近30天-作品平均点赞数": "494458", + "内容数据-个人视频-近30天-作品平均评论数": "7502", + "内容数据-个人视频-近30天-作品平均时长": "56", + "内容数据-个人视频-近30天-作品平均转发数": "188267", + "内容数据-个人视频-近30天-完播率": "28.24%", + "内容数据-个人视频-近30天-播放量中位数": "10913233" }); expect(fetchImpl).toHaveBeenCalledWith( "https://www.xingtu.cn/gw/api/data_sp/get_author_spread_info?o_author_id=7361012802036695050&platform_source=1&platform_channel=1&type=1&flow_type=0&only_assign=false&range=2",