fix: 统一处理流程和后台任务显示
- 处理流程抓取失败时记录到失败URL库 - /search页面新增产品处理会话展示区 - 同时显示后台抓取任务和产品处理会话 - 自动刷新同时更新三种数据:任务、会话、失败URL
This commit is contained in:
@@ -102,6 +102,7 @@ class ProcessMonitor:
|
||||
self._start_step(session_id, product_name, 3, '抓取网页内容')
|
||||
try:
|
||||
fetched = []
|
||||
failed_count = 0
|
||||
urls_to_fetch = [r['url'] for r in all_data['internet_results'][:5]]
|
||||
|
||||
for i, url in enumerate(urls_to_fetch):
|
||||
@@ -135,12 +136,21 @@ class ProcessMonitor:
|
||||
logger.info(f"[{session_id}] 已保存到内容库: {title[:30]}")
|
||||
except Exception as save_error:
|
||||
logger.warning(f"[{session_id}] 保存内容库失败: {save_error}")
|
||||
else:
|
||||
# 记录失败URL
|
||||
failed_count += 1
|
||||
error_msg = fetch_result.get('error', '抓取失败')
|
||||
try:
|
||||
db.add_failed_url(url, product_name, error_msg, source='process_monitor')
|
||||
logger.warning(f"[{session_id}] 抓取失败,已记录: {url}")
|
||||
except Exception as e:
|
||||
logger.error(f"[{session_id}] 记录失败URL出错: {e}")
|
||||
|
||||
time.sleep(0.3)
|
||||
|
||||
all_data['fetched_contents'] = fetched
|
||||
self._complete_step(session_id, 3, {'count': len(fetched)})
|
||||
logger.info(f"[{session_id}] 步骤3完成: 抓取 {len(fetched)} 个网页")
|
||||
self._complete_step(session_id, 3, {'count': len(fetched), 'failed': failed_count})
|
||||
logger.info(f"[{session_id}] 步骤3完成: 抓取 {len(fetched)} 个网页, 失败 {failed_count} 个")
|
||||
except Exception as e:
|
||||
self._fail_step(session_id, 3, str(e))
|
||||
|
||||
|
||||
@@ -472,6 +472,22 @@
|
||||
color: #3730a3;
|
||||
}
|
||||
|
||||
/* 产品处理会话区域 */
|
||||
.process-sessions-section {
|
||||
background: white;
|
||||
border-radius: 12px;
|
||||
box-shadow: 0 2px 4px rgba(0,0,0,0.05);
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.process-sessions-section .panel-header {
|
||||
background: #fef3c7;
|
||||
}
|
||||
|
||||
.process-sessions-section .panel-header h2 {
|
||||
color: #92400e;
|
||||
}
|
||||
|
||||
.background-tasks-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
@@ -22,6 +22,7 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
// 加载失败URL和后台任务
|
||||
loadFailedUrls();
|
||||
loadBackgroundTasks();
|
||||
loadProcessSessions();
|
||||
|
||||
// 启动自动刷新后台任务列表(每3秒)
|
||||
startAutoRefreshTasks();
|
||||
@@ -880,6 +881,8 @@ function startAutoRefreshTasks() {
|
||||
|
||||
autoRefreshTasksInterval = setInterval(() => {
|
||||
loadBackgroundTasks();
|
||||
loadProcessSessions(); // 同时刷新处理会话
|
||||
loadFailedUrls(); // 同时刷新失败URL
|
||||
}, 3000); // 每3秒刷新一次
|
||||
}
|
||||
|
||||
@@ -889,4 +892,65 @@ function stopAutoRefreshTasks() {
|
||||
clearInterval(autoRefreshTasksInterval);
|
||||
autoRefreshTasksInterval = null;
|
||||
}
|
||||
}
|
||||
|
||||
// 加载产品处理会话
|
||||
async function loadProcessSessions() {
|
||||
try {
|
||||
const response = await fetch(`${API_BASE}/api/process/recent?limit=10`);
|
||||
const data = await response.json();
|
||||
|
||||
if (data.success) {
|
||||
const container = document.getElementById('process-sessions-list');
|
||||
|
||||
if (data.sessions.length === 0) {
|
||||
container.innerHTML = '<div class="empty-text">暂无处理会话</div>';
|
||||
} else {
|
||||
container.innerHTML = data.sessions.map(session => {
|
||||
const statusClass = {
|
||||
'pending': 'status-pending',
|
||||
'running': 'status-running',
|
||||
'paused': 'status-warning',
|
||||
'completed': 'status-success',
|
||||
'failed': 'status-error',
|
||||
'stopped': 'status-warning'
|
||||
}[session.status] || '';
|
||||
|
||||
const statusText = {
|
||||
'pending': '等待中',
|
||||
'running': '处理中',
|
||||
'paused': '已暂停',
|
||||
'completed': '已完成',
|
||||
'failed': '失败',
|
||||
'stopped': '已停止'
|
||||
}[session.status] || session.status;
|
||||
|
||||
return `
|
||||
<div class="background-task-item ${statusClass}">
|
||||
<div class="task-info">
|
||||
<div class="task-id">${escapeHtml(session.product_name)}</div>
|
||||
<div class="task-status">
|
||||
<span class="status-badge ${statusClass}">${statusText}</span>
|
||||
${session.status === 'running' || session.status === 'paused' ?
|
||||
`<span class="task-progress">步骤 ${session.current_step || 0}/6</span>` : ''}
|
||||
${session.category ? `<span>分类: ${escapeHtml(session.category)}</span>` : ''}
|
||||
${session.review_id ? `<span>审核ID: ${escapeHtml(session.review_id)}</span>` : ''}
|
||||
</div>
|
||||
<div class="task-time">${session.created_at || ''}
|
||||
${session.finished_at ? ' → ' + session.finished_at : ''}
|
||||
</div>
|
||||
</div>
|
||||
<div class="task-actions">
|
||||
<a href="/process" class="btn btn-sm btn-secondary">
|
||||
<i class="ri-eye-line"></i> 监控
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
}).join('');
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('加载处理会话出错:', error);
|
||||
}
|
||||
}
|
||||
@@ -111,6 +111,26 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 产品处理会话区域 -->
|
||||
<div class="panel process-sessions-section">
|
||||
<div class="panel-header">
|
||||
<h2><i class="ri-play-circle-line"></i> 产品处理会话</h2>
|
||||
<div class="panel-actions">
|
||||
<a href="/process" class="btn btn-primary btn-sm">
|
||||
<i class="ri-external-link-line"></i> 监控页面
|
||||
</a>
|
||||
<button onclick="loadProcessSessions()" class="btn btn-secondary btn-sm">
|
||||
<i class="ri-refresh-line"></i> 刷新
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<div id="process-sessions-list" class="background-tasks-list">
|
||||
<div class="empty-text">暂无处理会话</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 失败URL区域 -->
|
||||
<div class="panel failed-urls-section">
|
||||
<div class="panel-header">
|
||||
|
||||
Reference in New Issue
Block a user