Files
koc-loop/tests/koc-detail.test.mjs
ABAPPLO 87f4d4066d feat: KOC详情弹窗 + 任务中心单入口改版 + 资源池默认合作方/采集兜底
KOC 详情弹窗(合作方/数据回收/工作台三处入口):
- 新增 KocDetailModal:基本信息 / 绑定KOC账号画像 / 参与任务记录 / 履约漏斗
- 工作台最近分发、回收队列账号名、截图回收合作方名、合作方页名称、分发详情头部合作方均可点开
- 分发表行点击仍打开分发详情(stopPropagation 隔离)

任务中心单入口改版(对齐"单任务双阶段"模型):
- 任务卡发布/回收面板整块可点,全卡仅保留一个「查看明细」,回收面板重复按钮移除
- 详情页自述身份:动态 label(任务详情·分发与回收一体/仅分发)+ 阶段徽章(含回收·截止/未开通回收)
- 内容分发表新增阶段筛选 chips(全部/待发布/已发布待数据/待收截图,未开通回收不显示截图项),筛选落空给专用空态文案
- 数据回收页入口文案改为「选择一个任务进入回收队列」,全站不再区分发布/回收两种任务类型

资源池 KOC 默认加入合作方 + 采集兜底:
- partners 新增 released_account_id(mysql/0023):显式解绑/被顶替的账号不再被默认合作方同步回填
- 任务未设置采集计划时,默认按发布时间起连续采集 7 天,等待文案显示「等待D1 · 默认7天」
2026-10-12 11:11:31 +08:00

91 lines
4.4 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { strict as assert } from "node:assert";
import { readFileSync } from "node:fs";
import test from "node:test";
const source = readFileSync(new URL("../app/admin-app.tsx", import.meta.url), "utf8");
test("KOC 详情弹窗组件:三段式(基本信息 / 绑定账号 / 参与记录)", () => {
const start = source.indexOf("function KocDetailModal");
assert.ok(start > 0, "应存在 KocDetailModal 组件");
const body = source.slice(start, source.indexOf("function RecoveryPage"));
assert.match(body, /KOC详情:\$\{partner\.name\}/);
assert.match(body, /① 基本信息/);
assert.match(body, /② 绑定 KOC 账号(资源)/);
assert.match(body, /③ 参与任务记录/);
assert.match(body, /暂无领取记录/);
// 概览漏斗:领取 → 发布 → 回收完成
assert.match(body, /领取 <b>\{history\.length\}<\/b>/);
assert.match(body, /发布 <b>\{publishedCount\}<\/b>/);
assert.match(body, /回收完成 <b>\{completedCount\}<\/b>/);
// 绑定账号缺失时的兜底文案区分群主与外部KOC
assert.match(body, /群主合作方无需绑定 KOC 资源账号/);
});
test("工作台:按 id 挂载 KOC 详情,操作刷新后内容自动更新", () => {
assert.match(source, /const \[detailPartnerId, setDetailPartnerId\] = useState<string \| null>\(null\);/);
assert.match(
source,
/data\.partners\.find\(\(partner\) => partner\.id === detailPartnerId\)/,
);
assert.match(source, /item\.partner_id === partnerRow\.id/);
assert.match(source, /<KocDetailModal/);
});
test("工作台最近分发:行可点开分发详情,合作方可点开 KOC 详情", () => {
const start = source.indexOf("function OverviewPage");
const body = source.slice(start, source.indexOf("function OwnerLinkRow"));
assert.match(body, /onOpenDetail=\{onOpenDetail\}/);
assert.match(body, /onOpenPartner=\{onOpenPartner\}/);
});
test("分发表/截图回收表:合作方名为 KOC 详情入口且不触发行点击", () => {
const tableStart = source.indexOf("function DistributionTable");
const tableBody = source.slice(tableStart, source.indexOf("type AdminPreviewImage"));
assert.match(tableBody, /onOpenPartner\?: \(partnerId: string\) => void;/);
assert.match(tableBody, /className="koc-link"/);
assert.match(tableBody, /event\.stopPropagation\(\);\s*onOpenPartner\(item\.partner_id\)/);
const shotStart = source.indexOf("function ScreenshotTaskTable");
const shotBody = source.slice(shotStart, source.indexOf("const RESOURCE_PAGE_SIZE"));
assert.match(shotBody, /onOpenPartner\?: \(partnerId: string\) => void;/);
assert.match(shotBody, /onOpenPartner\(item\.partner_id\)/);
});
test("数据回收页:回收队列账号名与截图回收合作方均可点开 KOC 详情", () => {
const start = source.indexOf("function RecoveryPage");
const body = source.slice(start);
assert.match(body, /onOpenPartner: \(partnerId: string\) => void;/);
// 回收队列:账号名(待识别账号兜底)为入口,且阻断行点击冒泡
assert.match(body, /\{item\.account_nickname \|\| "待识别账号"\}\s*<\/button>/);
assert.match(
body,
/event\.stopPropagation\(\);\s*onOpenPartner\(item\.partner_id\)/,
);
// 截图回收表透传
assert.match(body, /<ScreenshotTaskTable\s+distributions=\{taskDistributions\}\s+onOpenPartner=\{onOpenPartner\}/);
});
test("合作方页:合作方名称单元格可点开 KOC 详情", () => {
const start = source.indexOf("function PartnersPage");
const body = source.slice(start, source.indexOf("function ResourcesPage"));
assert.match(body, /onOpenPartner: \(partner: Partner\) => void;/);
assert.match(body, /className="partner-name-cell"/);
assert.match(body, /onClick=\{\(\) => onOpenPartner\(partner\)\}/);
});
test("分发详情弹窗:头部合作方可跳转 KOC 详情", () => {
const start = source.indexOf("function DistributionDetailModal");
const body = source.slice(start, source.indexOf("function KocDetailModal"));
assert.match(body, /onOpenPartner\?: \(partnerId: string\) => void;/);
assert.match(body, /detail-meta-koc/);
assert.match(body, /onOpenPartner\(item\.partner_id\)/);
});
test("KOC 详情样式:入口链接与历史记录列表", () => {
const css = readFileSync(new URL("../app/globals.css", import.meta.url), "utf8");
assert.match(css, /^\.koc-link \{/m);
assert.match(css, /^\.partner-name-cell \{/m);
assert.match(css, /^\.koc-history-list \{/m);
assert.match(css, /^\.koc-summary-strip \{/m);
});