refactor: remove dataset cron records

This commit is contained in:
2026-07-23 23:08:25 +08:00
parent 3705d75e59
commit fbd142803a
14 changed files with 125 additions and 380 deletions

View File

@@ -281,28 +281,17 @@ await page.route('http://localhost:9150/api/v1/**', async (route) => {
await route.fulfill({ json: updated })
return
}
if (url.pathname === '/api/v1/dataset-crons/sync') {
if (url.pathname === '/api/v1/dataset-sources/sync') {
await route.fulfill({
status: 200,
json: visualDatasetSources.map((source, index) => ({
id: `019b0000-0000-7000-8000-${String(70 + index).padStart(12, '0')}`,
json: visualDatasetSources.map((source) => ({
sourceId: source.id,
schedule: '@once',
status: 'completed',
enabled: false,
nextRunAt: null,
lastRunAt: new Date().toISOString(),
lastResult: 'format=rss fetched=2 inserted=0',
createdAt: new Date().toISOString(),
updatedAt: new Date().toISOString(),
result: 'format=rss fetched=2 inserted=0',
})),
})
return
}
if (url.pathname === '/api/v1/dataset-crons' && route.request().method() === 'GET') {
await route.fulfill({ json: [] })
return
}
await route.fulfill({ status: 404, json: { error: { code: 'not_found', message: '视觉检查未配置该接口' } } })
})

View File

@@ -31,14 +31,10 @@ export type DatasetItemDTO = {
updatedAt: string
}
export type DatasetCronDTO = {
id: string
export type DatasetSyncResultDTO = {
sourceId: string
status: string
lastRunAt: string | null
lastResult: string
createdAt: string
updatedAt: string
result: string
}
export type DatasetItemPageDTO = {
@@ -115,18 +111,14 @@ export function updateDatasetItem(session: ApiSession, itemId: string, input: Da
})
}
export function queueDatasetSync(session: ApiSession) {
return apiRequest<DatasetCronDTO[]>('/api/v1/dataset-crons/sync', {
export function syncDatasetSources(session: ApiSession) {
return apiRequest<DatasetSyncResultDTO[]>('/api/v1/dataset-sources/sync', {
method: 'POST',
token: session.token,
body: {},
})
}
export function listDatasetCrons(session: ApiSession, signal?: AbortSignal) {
return apiRequest<DatasetCronDTO[]>('/api/v1/dataset-crons', { token: session.token, signal })
}
export function depositDatasetItem(session: ApiSession, itemId: string, projectId: string) {
return apiRequest<DatasetDepositDTO>(`/api/v1/dataset-items/${itemId}/deposit`, {
method: 'POST',

View File

@@ -8,10 +8,9 @@ import {
createDatasetSource,
deleteDatasetSource,
depositDatasetItem,
listDatasetCrons,
listDatasetItems,
listDatasetSources,
queueDatasetSync,
syncDatasetSources,
updateDatasetItem,
updateDatasetSource,
type DatasetItemUpdate,
@@ -102,14 +101,9 @@ function App() {
return updateDatasetItem(session, itemId, input)
}, [session])
const handleQueueDatasetSync = useCallback(() => {
const handleSyncDatasetSources = useCallback(() => {
if (!session) return Promise.reject(new Error('未登录'))
return queueDatasetSync(session)
}, [session])
const handleListDatasetCrons = useCallback((signal?: AbortSignal) => {
if (!session) return Promise.reject(new Error('未登录'))
return listDatasetCrons(session, signal)
return syncDatasetSources(session)
}, [session])
const handleDepositDatasetItem = useCallback(async (itemId: string, projectId: string) => {
@@ -440,8 +434,7 @@ function App() {
onUpdateDatasetSource={handleUpdateDatasetSource}
onDeleteDatasetSource={handleDeleteDatasetSource}
onUpdateDatasetItem={handleUpdateDatasetItem}
onQueueDatasetSync={handleQueueDatasetSync}
onListDatasetCrons={handleListDatasetCrons}
onSyncDatasetSources={handleSyncDatasetSources}
onDepositDatasetItem={handleDepositDatasetItem}
/>
) : (

View File

@@ -14,7 +14,6 @@ import {
IconStorage,
} from '@arco-design/web-react/icon'
import type {
DatasetCronDTO,
DatasetDepositDTO,
DatasetItemDTO,
DatasetItemPageDTO,
@@ -22,6 +21,7 @@ import type {
DatasetSourceDTO,
DatasetSourceInput,
DatasetSourceKind,
DatasetSyncResultDTO,
} from '../api/dataset'
const { Row, Col } = Grid
@@ -61,8 +61,7 @@ export function WorkspaceExplorePage({
onUpdateSource,
onDeleteSource,
onUpdateItem,
onQueueSync,
onListCrons,
onSyncSources,
onDepositItem,
}: {
activeProjectID: string
@@ -73,8 +72,7 @@ export function WorkspaceExplorePage({
onUpdateSource: (sourceId: string, input: DatasetSourceInput) => Promise<DatasetSourceDTO>
onDeleteSource: (sourceId: string) => Promise<void>
onUpdateItem: (itemId: string, input: DatasetItemUpdate) => Promise<DatasetItemDTO>
onQueueSync: () => Promise<DatasetCronDTO[]>
onListCrons: (signal?: AbortSignal) => Promise<DatasetCronDTO[]>
onSyncSources: () => Promise<DatasetSyncResultDTO[]>
onDepositItem: (itemId: string, projectId: string) => Promise<DatasetDepositDTO & { refreshFailed?: boolean }>
}) {
const [sourceRecords, setSourceRecords] = useState<DatasetSourceDTO[]>([])
@@ -265,12 +263,10 @@ export function WorkspaceExplorePage({
async function syncSources() {
setSyncing(true)
try {
const queued = await onQueueSync()
if (queued.length === 0) {
const results = await onSyncSources()
if (results.length === 0) {
Message.info('暂无已启用的 RSS 数据源')
} else {
Message.info(`已提交 ${queued.length} 个采集任务`)
const crons = await waitForDatasetRuns(queued, onListCrons)
const sourceID = activeSourceID === 'all' ? undefined : activeSourceID
const [nextSources, nextPage] = await Promise.all([
onListSources(),
@@ -279,11 +275,11 @@ export function WorkspaceExplorePage({
setSourceRecords(nextSources)
setItems(nextPage.items)
setItemTotal(nextPage.total)
const failed = crons.filter((cron) => cron.status === 'failed').length
const failed = results.filter((result) => result.status === 'failed').length
if (failed > 0) {
Message.warning(`${crons.length - failed} 个数据源采集完成,${failed} 个失败`)
Message.warning(`${results.length - failed} 个数据源采集完成,${failed} 个失败`)
} else {
Message.success(`已完成 ${crons.length} 个数据源采集任务`)
Message.success(`已完成 ${results.length} 个数据源采集任务`)
}
}
} catch (error) {
@@ -547,19 +543,3 @@ function sourceSubtitle(source: DatasetSourceDTO) {
if (Number.isNaN(parsed.getTime())) return `${source.itemCount}`
return `${source.itemCount} 条 · ${new Intl.DateTimeFormat('zh-CN', { dateStyle: 'short', timeStyle: 'short' }).format(parsed)}`
}
async function waitForDatasetRuns(
queued: DatasetCronDTO[],
listRuns: (signal?: AbortSignal) => Promise<DatasetCronDTO[]>,
) {
const queuedIDs = new Set(queued.map((run) => run.id))
const deadline = Date.now() + 10 * 60 * 1000
while (Date.now() < deadline) {
const runs = (await listRuns()).filter((run) => queuedIDs.has(run.id))
if (runs.length === queuedIDs.size && runs.every((run) => run.status === 'completed' || run.status === 'failed')) {
return runs
}
await new Promise((resolve) => setTimeout(resolve, 1500))
}
throw new Error('采集任务仍在后台运行,请稍后刷新')
}

View File

@@ -11,13 +11,13 @@ import type { SearchResultDTO } from '../api/search'
import type { InboxSuggestionDTO } from '../api/inbox'
import type { AIExpertDTO, AISessionDTO, CreateAISessionInput } from '../api/ai'
import type {
DatasetCronDTO,
DatasetDepositDTO,
DatasetItemDTO,
DatasetItemPageDTO,
DatasetItemUpdate,
DatasetSourceDTO,
DatasetSourceInput,
DatasetSyncResultDTO,
} from '../api/dataset'
import type { ChannelKey, InboxConfirmationOutcome, Project, ProjectWorkspace, Theme, WorkbenchView } from './projects/project-types'
@@ -63,8 +63,7 @@ export function ProjectPage({
onUpdateDatasetSource,
onDeleteDatasetSource,
onUpdateDatasetItem,
onQueueDatasetSync,
onListDatasetCrons,
onSyncDatasetSources,
onDepositDatasetItem,
}: {
activeView: WorkbenchView
@@ -106,8 +105,7 @@ export function ProjectPage({
onUpdateDatasetSource: (sourceId: string, input: DatasetSourceInput) => Promise<DatasetSourceDTO>
onDeleteDatasetSource: (sourceId: string) => Promise<void>
onUpdateDatasetItem: (itemId: string, input: DatasetItemUpdate) => Promise<DatasetItemDTO>
onQueueDatasetSync: () => Promise<DatasetCronDTO[]>
onListDatasetCrons: (signal?: AbortSignal) => Promise<DatasetCronDTO[]>
onSyncDatasetSources: () => Promise<DatasetSyncResultDTO[]>
onDepositDatasetItem: (itemId: string, projectId: string) => Promise<DatasetDepositDTO & { refreshFailed?: boolean }>
}) {
const isProject = activeView === 'project'
@@ -173,8 +171,7 @@ export function ProjectPage({
onUpdateSource={onUpdateDatasetSource}
onDeleteSource={onDeleteDatasetSource}
onUpdateItem={onUpdateDatasetItem}
onQueueSync={onQueueDatasetSync}
onListCrons={onListDatasetCrons}
onSyncSources={onSyncDatasetSources}
onDepositItem={onDepositDatasetItem}
/>
) : (