fix(web): show five portrait work cards per desktop row
douyin-release-gate / verify (push) Failing after 12m45s
douyin-release-gate / verify (push) Failing after 12m45s
This commit is contained in:
@@ -35,10 +35,10 @@ export function WorkCover({ workID, title }: { workID: string; title?: string })
|
||||
};
|
||||
}, [workID]);
|
||||
if (src) {
|
||||
return <img src={src} alt={title || '作品封面'} style={{ width: '100%', aspectRatio: '16 / 9', objectFit: 'cover' }} />;
|
||||
return <img src={src} alt={title || '作品封面'} style={{ width: '100%', aspectRatio: '9 / 16', objectFit: 'cover' }} />;
|
||||
}
|
||||
return (
|
||||
<Flex align="center" justify="center" style={{ aspectRatio: '16 / 9', background: '#f5f5f5' }}>
|
||||
<Flex align="center" justify="center" style={{ aspectRatio: '9 / 16', background: '#f5f5f5' }}>
|
||||
<Typography.Text type="secondary" style={{ fontSize: 12 }}>{missing ? '封面未缓存' : '封面加载中'}</Typography.Text>
|
||||
</Flex>
|
||||
);
|
||||
@@ -267,7 +267,7 @@ export default function WorksGallery({ sourceId, sourceType, emptyHint, extraFil
|
||||
{works.length ? (
|
||||
<Row gutter={[16, 16]}>
|
||||
{works.map((work) => (
|
||||
<Col key={work.id} xs={24} sm={12} lg={8} xl={6}>
|
||||
<Col key={work.id} xs={24} sm={12} lg={8} xl={{ flex: '20%' }}>
|
||||
<Card
|
||||
hoverable
|
||||
style={{ height: '100%' }}
|
||||
|
||||
@@ -191,6 +191,74 @@ test('详情作品总数使用完整采集历史,而非仅依赖最近指标
|
||||
assert.equal(byType(card(tree, '账号数据'), 'Statistic')[4].props.value, '100');
|
||||
});
|
||||
|
||||
for (const [name, props] of [
|
||||
['我的账号详情', { sourceId: 'owned-1', sourceType: 'owned' }],
|
||||
['监控账号详情', { sourceId: 'monitor-1', sourceType: 'competitor' }],
|
||||
['竞品分析', { sourceType: 'competitor', extraFilters: { min_likes: 100 } }],
|
||||
]) {
|
||||
test(`${name}作品列表桌面五列,窄屏保持一至三列`, async () => {
|
||||
const works = Array.from({ length: 6 }, (_, i) => ({ id: `work-${i}`, title: `作品${i}` }));
|
||||
const page = harness('src/components/creator/WorksGallery.tsx', {
|
||||
workPages: { 1: { data: works, total: 30, hasNext: true } },
|
||||
collectionStatus: { work_count: 30, aweme_count: 30, works: { status: 'succeeded' } },
|
||||
});
|
||||
const tree = await page.mount(props);
|
||||
const columns = byType(card(tree, '作品列表'), 'Col');
|
||||
assert.equal(columns.length, 6);
|
||||
columns.forEach(({ props: column }, i) => {
|
||||
assert.equal(column.xs, 24);
|
||||
assert.equal(column.sm, 12);
|
||||
assert.equal(column.lg, 8);
|
||||
assert.deepEqual(column.xl, { flex: '20%' });
|
||||
assert.equal(column.children.props.cover.props.workID, works[i].id);
|
||||
assert.equal(typeof column.children.props.onClick, 'function');
|
||||
});
|
||||
assert.equal(byType(tree, 'Pagination')[0].props.pageSize, 25);
|
||||
assert.equal(page.calls.lists[0].pageSize, 25);
|
||||
assert.equal(page.calls.lists[0].filters.source_id, props.sourceId);
|
||||
assert.equal(page.calls.lists[0].filters.source_type, props.sourceType);
|
||||
assert.equal(page.calls.lists[0].filters.min_likes, props.extraFilters?.min_likes);
|
||||
page.unmount();
|
||||
});
|
||||
}
|
||||
|
||||
test('作品封面加载占位与成功图片均为9:16,图片裁切显示并释放缓存地址', async (t) => {
|
||||
const blob = new Blob(['cover'], { type: 'image/jpeg' });
|
||||
const createURL = t.mock.method(URL, 'createObjectURL', () => 'blob:portrait-cover');
|
||||
const revokeURL = t.mock.method(URL, 'revokeObjectURL', () => {});
|
||||
const requests = [];
|
||||
const cover = harness('src/components/creator/WorksGallery.tsx', {
|
||||
services: { fetchCreatorBinary: async (url) => { requests.push(url); return blob; } },
|
||||
}, 'WorkCover');
|
||||
let tree = cover.render({ workID: 'work/1', title: '作品标题' });
|
||||
assert.equal(tree.props.style.aspectRatio, '9 / 16');
|
||||
assert.match(text(tree), /封面加载中/);
|
||||
await flush();
|
||||
tree = cover.render();
|
||||
assert.equal(tree.type, 'img');
|
||||
assert.equal(tree.props.style.aspectRatio, '9 / 16');
|
||||
assert.equal(tree.props.style.width, '100%');
|
||||
assert.equal(tree.props.style.objectFit, 'cover');
|
||||
assert.equal(tree.props.src, 'blob:portrait-cover');
|
||||
assert.equal(tree.props.alt, '作品标题');
|
||||
assert.deepEqual(requests, ['/creator/works/work%2F1/cover']);
|
||||
assert.equal(createURL.mock.calls[0].arguments[0], blob);
|
||||
cover.unmount();
|
||||
assert.deepEqual(revokeURL.mock.calls[0].arguments, ['blob:portrait-cover']);
|
||||
});
|
||||
|
||||
test('缺失封面也保持9:16,不使用远程图片代替', async () => {
|
||||
const cover = harness('src/components/creator/WorksGallery.tsx', {
|
||||
services: { fetchCreatorBinary: async () => { throw new Error('封面不存在'); } },
|
||||
}, 'WorkCover');
|
||||
const tree = await cover.mount({ workID: 'missing-work' });
|
||||
assert.equal(tree.type, 'Flex');
|
||||
assert.equal(tree.props.style.aspectRatio, '9 / 16');
|
||||
assert.match(text(tree), /封面未缓存/);
|
||||
assert.equal(byType(tree, 'img').length, 0);
|
||||
cover.unmount();
|
||||
});
|
||||
|
||||
test('自有账号作品展示独立采集进度,历史作品可翻页且筛选不改变进度分母', async () => {
|
||||
const api = {
|
||||
collectionStatus: { work_count: 28, aweme_count: 100, works: { status: 'succeeded' } },
|
||||
|
||||
@@ -48,6 +48,18 @@ function sourceText() {
|
||||
return source.getFullText();
|
||||
}
|
||||
|
||||
for (const [name, pagePath] of [
|
||||
['我的账号详情', 'accounts/$id'],
|
||||
['监控账号详情', 'accounts/monitoring/$id'],
|
||||
['竞品分析', 'creator/competitors'],
|
||||
]) {
|
||||
test(`${name}使用共用作品列表,列数与封面比例保持一致`, () => {
|
||||
const page = readFileSync(`${__dirname}/../src/pages/${pagePath}/index.tsx`, 'utf8');
|
||||
assert.match(page, /import WorksGallery from '@\/components\/creator\/WorksGallery'/);
|
||||
assert.match(page, /<WorksGallery\b/);
|
||||
});
|
||||
}
|
||||
|
||||
const competitorsPageText = readFileSync(`${__dirname}/../src/pages/creator/competitors/index.tsx`, 'utf8');
|
||||
|
||||
test('竞品分析页复用 WorksGallery,不再自建作品卡片/详情抽屉', () => {
|
||||
|
||||
Reference in New Issue
Block a user