fix(web): 监控账号画像对齐抖音主页形态——关注/粉丝/获赞独立数字行,作者介绍去 label 独立行,昵称后挂抖音主页链接,移除平台账号项

This commit is contained in:
2026-09-30 17:03:05 +08:00
parent 2caaf2d606
commit 50aada884f
2 changed files with 61 additions and 37 deletions
+35 -27
View File
@@ -136,42 +136,50 @@ export default function Page() {
{competitor.nickname || competitor.platform_account_key}
</Typography.Title>
<Tag color={syncMeta.color}>{syncMeta.label}</Tag>
<Typography.Link
href={`https://www.douyin.com/user/${competitor.platform_account_key}`}
target="_blank"
>
抖音主页
</Typography.Link>
</Flex>
<Flex align="baseline" gap={24} wrap="wrap">
{[
{ label: '关注', value: competitor.following_count },
{ label: '粉丝', value: competitor.follower_count },
{ label: '获赞', value: competitor.total_favorited },
].map(({ label, value }) => (
<Flex key={label} align="baseline" gap={4}>
<Typography.Text strong style={{ fontSize: 16 }}>{formatCount(value)}</Typography.Text>
<Typography.Text>{label}</Typography.Text>
</Flex>
))}
</Flex>
{competitor.signature ? (
<Flex align="center" gap={8} style={{ minWidth: 0 }}>
<Typography.Text ellipsis style={{ flex: 1, minWidth: 0 }}>
{competitor.signature}
</Typography.Text>
<Popover
title="作者介绍"
content={
<Typography.Paragraph style={{ maxWidth: 420, whiteSpace: 'pre-wrap', marginBottom: 0 }}>
{competitor.signature}
</Typography.Paragraph>
}
>
<Typography.Link>更多</Typography.Link>
</Popover>
</Flex>
) : null}
<Descriptions
column={{ xs: 1, sm: 2 }}
size="small"
style={{ marginTop: 8 }}
items={[
{ key: 'key', label: '平台账号', children: competitor.platform_account_key },
{ key: 'uid', label: '抖音号', children: competitor.unique_id || '—' },
{ key: 'follower', label: '粉丝', children: formatCount(competitor.follower_count) },
{ key: 'following', label: '关注', children: formatCount(competitor.following_count) },
{ key: 'favorited', label: '获赞', children: formatCount(competitor.total_favorited) },
{ key: 'aweme', label: '作品总数', children: formatCount(competitor.aweme_count) },
{ key: 'tags', label: '标签', children: competitor.tags?.length ? competitor.tags.join('、') : '无' },
{
key: 'signature',
label: '作者介绍',
// 对齐抖音主页形态:单行省略,结尾「更多」,hover 弹出全文(保留换行)。
children: competitor.signature ? (
<Flex align="center" gap={8} style={{ minWidth: 0 }}>
<Typography.Text type="secondary" ellipsis style={{ flex: 1, minWidth: 0 }}>
{competitor.signature}
</Typography.Text>
<Popover
title="作者介绍"
content={
<Typography.Paragraph style={{ maxWidth: 420, whiteSpace: 'pre-wrap', marginBottom: 0 }}>
{competitor.signature}
</Typography.Paragraph>
}
>
<Typography.Link>更多</Typography.Link>
</Popover>
</Flex>
) : (
'—'
) },
{ key: 'lastSync', label: '上次同步', children: competitor.last_sync_at ? dateTime(competitor.last_sync_at) : '—' },
{ key: 'nextSync', label: '下次自动同步', children: competitor.next_sync_at ? dateTime(competitor.next_sync_at) : '—' },
{
+26 -10
View File
@@ -12,21 +12,37 @@ const source = ts.createSourceFile(
);
const code = source.getFullText();
test('监控账号详情展示获赞与作者介绍', () => {
assert.ok(code.includes('total_favorited'), '接口类型应包含 total_favorited');
assert.ok(code.includes("competitor.signature"), '接口类型应包含 signature');
assert.ok(code.includes("label: '获赞'"), 'Descriptions 应有获赞项');
assert.ok(code.includes("label: '作者介绍'"), 'Descriptions 应有作者介绍项');
assert.ok(code.includes('formatCount(competitor.total_favorited)'), '获赞应走 formatCount');
test('关注、粉丝、获赞单独一行,正常字体颜色', () => {
// 从 Descriptions 移出,不再以 label+children 形式出现
for (const label of ['粉丝', '关注', '获赞']) {
assert.ok(!code.includes(`label: '${label}', children:`), `${label} 不应留在 Descriptions`);
}
assert.ok(code.includes('competitor.following_count'), '应有关注数');
assert.ok(code.includes('competitor.follower_count'), '应有粉丝数');
assert.ok(code.includes('competitor.total_favorited'), '应有获赞数');
assert.ok(code.includes("{ label: '关注', value: competitor.following_count }"), '关注数据行');
assert.ok(code.includes("{ label: '粉丝', value: competitor.follower_count }"), '粉丝数据行');
assert.ok(code.includes("{ label: '获赞', value: competitor.total_favorited }"), '获赞数据行');
assert.match(code, /formatCount\(value\)/, '计数统一走 formatCount');
// 不灰:画像区不得使用 secondary 灰色文本
assert.doesNotMatch(code, /type="secondary"/, '画像数据应为正常颜色');
});
test('作者介绍单行展示,结尾「更多」hover 弹出全文', () => {
// 单行省略:Typography.Text ellipsis
test('作者介绍单独一行,不展示「作者介绍」label', () => {
assert.ok(!code.includes("label: '作者介绍'"), '不应有作者介绍 label');
assert.ok(code.includes('competitor.signature'), '应有签名数据');
// 单行省略 + 结尾「更多」hover 弹出全文,保留换行
assert.match(code, /<Typography\.Text[^>]*ellipsis/, '作者介绍应为单行省略文本');
// 更多触发器 + Popover 展示全文,保留换行
assert.match(code, /<Popover\b/, '应使用 Popover 承载全文');
assert.match(code, />更多</, '结尾应有「更多」触发器');
assert.match(code, /pre-wrap/, '全文应保留换行');
// 无签名时展示占位符,不渲染更多入口
assert.match(code, /competitor\.signature \?/, '签名应判空');
});
test('昵称后展示抖音主页链接,不再单独展示平台账号', () => {
assert.ok(
code.includes('https://www.douyin.com/user/${competitor.platform_account_key}'),
'主页链接应使用平台账号拼接',
);
assert.doesNotMatch(code, /label: '平台账号'/, '不应再展示平台账号项');
});