feat: connect explore datasets to backend

This commit is contained in:
2026-07-23 15:07:35 +08:00
parent 0ca2898ac0
commit 26dd3004a1
14 changed files with 1445 additions and 196 deletions

View File

@@ -32,6 +32,37 @@ const visualExperts = [
name: '前端开发者', description: '负责现代 Web 应用实现与性能优化。', emoji: '💻', color: '#0FC6C2',
},
]
let visualDatasetSources = [
{
id: '019b0000-0000-7000-8000-000000000030', name: '手动收集', kind: 'manual', url: '',
description: '手动收集的文章与线索', enabled: true, lastSyncedAt: null, itemCount: 1,
createdAt: '2026-07-22T06:00:00Z', updatedAt: '2026-07-22T06:00:00Z',
},
{
id: '019b0000-0000-7000-8000-000000000031', name: '需求文档', kind: 'link', url: 'https://example.com/requirements',
description: '产品需求与业务文档', enabled: true, lastSyncedAt: null, itemCount: 1,
createdAt: '2026-07-22T06:00:00Z', updatedAt: '2026-07-22T06:00:00Z',
},
{
id: '019b0000-0000-7000-8000-000000000032', name: '架构讨论', kind: 'link', url: 'https://example.com/architecture',
description: '架构方案与系统设计讨论', enabled: true, lastSyncedAt: null, itemCount: 0,
createdAt: '2026-07-22T06:00:00Z', updatedAt: '2026-07-22T06:00:00Z',
},
]
let visualDatasetItems = [
{
id: '019b0000-0000-7000-8000-000000000040', sourceId: visualDatasetSources[0].id,
title: '森林项目体验优化需求', summary: '整理工作台信息层级,并沉淀为可跟进计划。', content: '探索数据条目的正文内容。',
url: 'https://example.com/article-1', status: 'unread', starred: false, publishedAt: '2026-07-22T08:00:00Z',
createdAt: '2026-07-22T08:00:00Z', updatedAt: '2026-07-22T08:00:00Z',
},
{
id: '019b0000-0000-7000-8000-000000000041', sourceId: visualDatasetSources[1].id,
title: '项目资料组织方案', summary: '围绕项目上下文统一组织任务、笔记、资料和 AI 会话。', content: '资料组织方案正文。',
url: 'https://example.com/article-2', status: 'read', starred: true, publishedAt: '2026-07-22T07:00:00Z',
createdAt: '2026-07-22T07:00:00Z', updatedAt: '2026-07-22T07:00:00Z',
},
]
page.on('console', (message) => {
if (message.type() === 'error') errors.push(message.text())
})
@@ -185,6 +216,71 @@ await page.route('http://localhost:9150/api/v1/**', async (route) => {
await route.fulfill({ json: visualExperts })
return
}
if (url.pathname === '/api/v1/dataset-sources' && route.request().method() === 'GET') {
await route.fulfill({ json: visualDatasetSources })
return
}
if (url.pathname === '/api/v1/dataset-sources' && route.request().method() === 'POST') {
const input = route.request().postDataJSON()
const created = {
id: `019b0000-0000-7000-8000-${String(50 + visualDatasetSources.length).padStart(12, '0')}`,
...input,
lastSyncedAt: null,
itemCount: 0,
createdAt: new Date().toISOString(),
updatedAt: new Date().toISOString(),
}
visualDatasetSources = [...visualDatasetSources, created]
await route.fulfill({ status: 201, json: created })
return
}
if (url.pathname.startsWith('/api/v1/dataset-sources/') && route.request().method() === 'PATCH') {
const id = url.pathname.split('/').at(-1)
const input = route.request().postDataJSON()
const current = visualDatasetSources.find((source) => source.id === id)
const updated = { ...current, ...input, updatedAt: new Date().toISOString() }
visualDatasetSources = visualDatasetSources.map((source) => source.id === id ? updated : source)
await route.fulfill({ json: updated })
return
}
if (url.pathname.startsWith('/api/v1/dataset-sources/') && route.request().method() === 'DELETE') {
const id = url.pathname.split('/').at(-1)
visualDatasetSources = visualDatasetSources.filter((source) => source.id !== id)
visualDatasetItems = visualDatasetItems.filter((item) => item.sourceId !== id)
await route.fulfill({ status: 204, body: '' })
return
}
if (url.pathname === '/api/v1/dataset-items' && route.request().method() === 'GET') {
await route.fulfill({ json: visualDatasetItems })
return
}
if (url.pathname.startsWith('/api/v1/dataset-items/') && route.request().method() === 'PATCH') {
const id = url.pathname.split('/').at(-1)
const input = route.request().postDataJSON()
const current = visualDatasetItems.find((item) => item.id === id)
const updated = { ...current, ...input, updatedAt: new Date().toISOString() }
visualDatasetItems = visualDatasetItems.map((item) => item.id === id ? updated : item)
await route.fulfill({ json: updated })
return
}
if (url.pathname === '/api/v1/dataset-crons/sync') {
await route.fulfill({
status: 202,
json: visualDatasetSources.map((source, index) => ({
id: `019b0000-0000-7000-8000-${String(70 + index).padStart(12, '0')}`,
sourceId: source.id,
schedule: '@once',
status: 'pending',
enabled: true,
nextRunAt: new Date().toISOString(),
lastRunAt: null,
lastResult: '',
createdAt: new Date().toISOString(),
updatedAt: new Date().toISOString(),
})),
})
return
}
await route.fulfill({ status: 404, json: { error: { code: 'not_found', message: '视觉检查未配置该接口' } } })
})
@@ -304,6 +400,7 @@ const addSourceModalCheck = await page.evaluate(() => ({
inputCount: document.querySelectorAll('.explore-source-modal input, .explore-source-modal textarea').length,
}))
await page.locator('.explore-source-modal input').first().fill('行业资讯')
await page.locator('.explore-source-modal input[placeholder="https://example.com/feed"]').fill('https://example.com/feed')
await page.locator('.explore-source-modal .arco-modal-footer .arco-btn-primary').click()
const addedSourceVisible = await page.locator('.explore-source-card', { hasText: '行业资讯' }).count() === 1