fix: remove publication verification filter from work analysis
This commit is contained in:
@@ -48,7 +48,9 @@
|
||||
|
||||
自有账号作品:作品总数使用抖音最新非空 `aweme_count`,已保存 `work_count` 仅表示采集进度,不得互相替代;未知总数与零作品必须区分。自有账号作品库保存平台分页返回的全部历史作品,不受采集回看天数限制;回看天数仍限制监控账号作品和评论采集。详情分页浏览已采集作品,并明确展示采集进度与未完整状态,不能将采集成功等同于已采齐。
|
||||
|
||||
作品分析:左侧原“竞品分析”统一为“作品分析”,页面通过“竞品账号”“我的账号”两个 TAB 严格区分作品来源;各 TAB 独立保留筛选与分页。支持所属账号、发布时间、时间核验状态和互动阈值筛选,以及发布时间、点赞、评论、分享、收藏、24h 点赞增量升降序;自有作品额外支持观看量。默认最新发布在前,条件变化回到第一页,筛选与排序作用于全部已采集作品后再分页;缺失指标显示“—”,排序放末尾、阈值筛选不将其当作 0。未采集作品不参与分析。
|
||||
作品分析:左侧原“竞品分析”统一为“作品分析”,页面通过“竞品账号”“我的账号”两个 TAB 严格区分作品来源;各 TAB 独立保留筛选与分页。支持所属账号、发布时间和互动阈值筛选,以及发布时间、点赞、评论、分享、收藏、24h 点赞增量升降序;自有作品额外支持观看量,不展示“时间核验状态”筛选。默认最新发布在前,条件变化回到第一页,筛选与排序作用于全部已采集作品后再分页;缺失指标显示“—”,排序放末尾、阈值筛选不将其当作 0。未采集作品不参与分析。
|
||||
|
||||
评论聚合:独立页面通过“我的作品评论”“竞品作品评论”两个 TAB 严格区分来源,各 TAB 保留筛选与页码。列表展示评论发布时间、评论者、内容、所属账号(昵称与 UID)及对应作品;支持所属账号筛选,以及最近 1/6/12 小时、1/3/5/7 天筛选,默认最近 1 天。按评论发布时间计算范围,最新评论在前,同时间按评论 ID 倒序;未记录发布时间、未来时间及未采集评论不参与。筛选先作用于全部已采集评论再分页,条件或每页数量变化回到第一页;只读展示,不新增采集机制。
|
||||
|
||||
前端框架:Umi Max 4.7 + React 19;
|
||||
|
||||
|
||||
@@ -9,7 +9,6 @@ type SourceType = 'owned' | 'competitor';
|
||||
interface Filters {
|
||||
sourceId?: string;
|
||||
dates?: [Dayjs, Dayjs];
|
||||
publishedAtStatus?: string;
|
||||
minLikes?: number;
|
||||
minComments?: number;
|
||||
minShares?: number;
|
||||
@@ -25,12 +24,6 @@ interface AccountOption {
|
||||
nickname?: string;
|
||||
platform_account_key: string;
|
||||
}
|
||||
const publishedAtStatusOptions = [
|
||||
{ value: 'verified', label: '已核验' },
|
||||
{ value: 'future', label: '未来时间' },
|
||||
{ value: 'pending_verification', label: '待核验' },
|
||||
{ value: 'invalid', label: '无效时间' },
|
||||
];
|
||||
const metricFilters: { key: keyof Filters; label: string }[] = [
|
||||
{ key: 'minLikes', label: '最低点赞' },
|
||||
{ key: 'minComments', label: '最低评论' },
|
||||
@@ -86,7 +79,6 @@ export function WorkAnalysisTab({ sourceType }: { sourceType: SourceType }) {
|
||||
sort_order: filters.sortOrder ?? 'desc',
|
||||
published_after: filters.dates?.[0].startOf('day').toISOString(),
|
||||
published_before: filters.dates?.[1].endOf('day').toISOString(),
|
||||
published_at_status: filters.publishedAtStatus,
|
||||
min_likes: filters.minLikes,
|
||||
min_comments: filters.minComments,
|
||||
min_shares: filters.minShares,
|
||||
@@ -133,22 +125,6 @@ export function WorkAnalysisTab({ sourceType }: { sourceType: SourceType }) {
|
||||
}
|
||||
/>
|
||||
</Form.Item>
|
||||
<Form.Item label="时间核验状态">
|
||||
<Select
|
||||
aria-label="时间核验状态"
|
||||
placeholder="全部状态"
|
||||
allowClear
|
||||
style={{ width: 140 }}
|
||||
value={filters.publishedAtStatus}
|
||||
options={publishedAtStatusOptions}
|
||||
onChange={(value) =>
|
||||
setFilters((current) => ({
|
||||
...current,
|
||||
publishedAtStatus: value,
|
||||
}))
|
||||
}
|
||||
/>
|
||||
</Form.Item>
|
||||
</Form>
|
||||
<Form layout="inline">
|
||||
{metrics.map(({ key, label }) => (
|
||||
|
||||
@@ -69,7 +69,8 @@ for (const sourceType of ['competitor', 'owned']) {
|
||||
assert.equal(account.props.options[0].value, `${sourceType}-1`);
|
||||
account.props.onChange(`${sourceType}-1`);
|
||||
for (const [label, value] of [['最低点赞', 0], ['最低评论', 2], ['最低分享', 3], ['最低收藏', 4], ['最低24h点赞增量', 5]]) control(tree, 'InputNumber', label).props.onChange(value);
|
||||
control(tree, 'Select', '时间核验状态').props.onChange('verified');
|
||||
assert.equal(control(tree, 'Select', '时间核验状态'), undefined);
|
||||
assert.equal('published_at_status' in nodes(tree, 'WorksGallery')[0].props.extraFilters, false);
|
||||
control(tree, 'Select', '排序指标').props.onChange('likes_growth');
|
||||
control(tree, 'Select', '排序方向').props.onChange('asc');
|
||||
const dates = [{ startOf: () => ({ toISOString: () => '2026-01-01T00:00:00.000Z' }) }, { endOf: () => ({ toISOString: () => '2026-01-03T23:59:59.999Z' }) }];
|
||||
@@ -79,7 +80,7 @@ for (const sourceType of ['competitor', 'owned']) {
|
||||
tree = app.render();
|
||||
const gallery = nodes(tree, 'WorksGallery')[0];
|
||||
assert.equal(gallery.props.sourceId, `${sourceType}-1`);
|
||||
assert.deepEqual(plain(gallery.props.extraFilters), { growth_hours: 24, sort_by: 'likes_growth', sort_order: 'asc', published_after: '2026-01-01T00:00:00.000Z', published_before: '2026-01-03T23:59:59.999Z', published_at_status: 'verified', min_likes: 0, min_comments: 2, min_shares: 3, min_collect_count: 4, min_likes_growth: 5, ...(sourceType === 'owned' ? { min_play_count: 0 } : {}) });
|
||||
assert.deepEqual(plain(gallery.props.extraFilters), { growth_hours: 24, sort_by: 'likes_growth', sort_order: 'asc', published_after: '2026-01-01T00:00:00.000Z', published_before: '2026-01-03T23:59:59.999Z', min_likes: 0, min_comments: 2, min_shares: 3, min_collect_count: 4, min_likes_growth: 5, ...(sourceType === 'owned' ? { min_play_count: 0 } : {}) });
|
||||
const sorts = control(tree, 'Select', '排序指标').props.options.map(option => option.value);
|
||||
assert.equal(sorts.includes('play_count'), sourceType === 'owned');
|
||||
assert(sorts.includes('collect_count'));
|
||||
|
||||
Reference in New Issue
Block a user