Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5e3e9e7335 | ||
|
|
1712fb0756 |
@@ -110,11 +110,32 @@ class ProcessMonitor:
|
|||||||
|
|
||||||
fetch_result = search_service.fetch_url_content(url)
|
fetch_result = search_service.fetch_url_content(url)
|
||||||
if fetch_result.get('success'):
|
if fetch_result.get('success'):
|
||||||
|
title = fetch_result.get('title', '')
|
||||||
|
content = fetch_result.get('content', '')
|
||||||
fetched.append({
|
fetched.append({
|
||||||
'url': url,
|
'url': url,
|
||||||
'title': fetch_result.get('title', ''),
|
'title': title,
|
||||||
'content': fetch_result.get('content', '')[:500]
|
'content': content[:500]
|
||||||
})
|
})
|
||||||
|
|
||||||
|
# 保存到内容库
|
||||||
|
try:
|
||||||
|
existing = db.search_articles(url)
|
||||||
|
if not any(a.get('url') == url for a in existing):
|
||||||
|
db.add_article(
|
||||||
|
product_names=[],
|
||||||
|
category=category or '',
|
||||||
|
keywords=[],
|
||||||
|
summary=content[:200] if content else '',
|
||||||
|
content=content,
|
||||||
|
source=url,
|
||||||
|
url=url,
|
||||||
|
search_title=title
|
||||||
|
)
|
||||||
|
logger.info(f"[{session_id}] 已保存到内容库: {title[:30]}")
|
||||||
|
except Exception as save_error:
|
||||||
|
logger.warning(f"[{session_id}] 保存内容库失败: {save_error}")
|
||||||
|
|
||||||
time.sleep(0.3)
|
time.sleep(0.3)
|
||||||
|
|
||||||
all_data['fetched_contents'] = fetched
|
all_data['fetched_contents'] = fetched
|
||||||
|
|||||||
@@ -175,6 +175,31 @@
|
|||||||
max-width: 80px;
|
max-width: 80px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.step-value {
|
||||||
|
font-size: 12px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #10b981;
|
||||||
|
margin-top: 3px;
|
||||||
|
padding: 2px 6px;
|
||||||
|
background: #d1fae5;
|
||||||
|
border-radius: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.step-node.running .step-value {
|
||||||
|
color: #667eea;
|
||||||
|
background: #e0e7ff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.step-node.failed .step-value {
|
||||||
|
color: #ef4444;
|
||||||
|
background: #fee2e2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.step-node.skipped .step-value {
|
||||||
|
color: #6b7280;
|
||||||
|
background: #f3f4f6;
|
||||||
|
}
|
||||||
|
|
||||||
@keyframes pulse {
|
@keyframes pulse {
|
||||||
0%, 100% { transform: scale(1); }
|
0%, 100% { transform: scale(1); }
|
||||||
50% { transform: scale(1.1); }
|
50% { transform: scale(1.1); }
|
||||||
|
|||||||
+29
-2
@@ -133,17 +133,42 @@ function displayActiveProcesses(sessions) {
|
|||||||
function renderStepsProgress(steps, currentStep) {
|
function renderStepsProgress(steps, currentStep) {
|
||||||
const totalSteps = 6;
|
const totalSteps = 6;
|
||||||
const stepStatuses = {};
|
const stepStatuses = {};
|
||||||
|
const stepDataMap = {};
|
||||||
|
|
||||||
// 构建步骤状态映射
|
// 构建步骤状态和数据映射
|
||||||
steps.forEach(s => {
|
steps.forEach(s => {
|
||||||
stepStatuses[s.step_number] = s.step_status;
|
stepStatuses[s.step_number] = s.step_status;
|
||||||
|
if (s.step_data) {
|
||||||
|
try {
|
||||||
|
stepDataMap[s.step_number] = typeof s.step_data === 'string' ? JSON.parse(s.step_data) : s.step_data;
|
||||||
|
} catch (e) {
|
||||||
|
stepDataMap[s.step_number] = s.step_data;
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const stepNames = ['搜索内容库', '搜索互联网', '抓取网页', '提取数据', '填充字段', '提交审核'];
|
const stepNames = ['搜索内容库', '搜索互联网', '抓取网页', '提取数据', '填充字段', '提交审核'];
|
||||||
|
|
||||||
let html = '';
|
// 获取每个步骤的简要数值
|
||||||
|
function getStepValue(stepNum) {
|
||||||
|
const data = stepDataMap[stepNum];
|
||||||
|
if (!data) return '';
|
||||||
|
|
||||||
|
switch (stepNum) {
|
||||||
|
case 1: return data.count !== undefined ? `${data.count}篇` : '';
|
||||||
|
case 2: return data.count !== undefined ? `${data.count}条` : '';
|
||||||
|
case 3: return data.count !== undefined ? `${data.count}个` : '';
|
||||||
|
case 4: return data.has_data !== undefined ? (data.has_data ? '✓' : '✗') : (data.extracted ? '✓' : '');
|
||||||
|
case 5: return data.filled !== undefined ? (data.filled ? '✓' : '✗') : '';
|
||||||
|
case 6: return data.review_id ? '✓' : '';
|
||||||
|
default: return '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let html = '<div class="steps-progress">';
|
||||||
for (let i = 1; i <= totalSteps; i++) {
|
for (let i = 1; i <= totalSteps; i++) {
|
||||||
const status = stepStatuses[i] || (i > currentStep ? 'pending' : '');
|
const status = stepStatuses[i] || (i > currentStep ? 'pending' : '');
|
||||||
|
const stepValue = getStepValue(i);
|
||||||
let className = '';
|
let className = '';
|
||||||
|
|
||||||
if (status === 'completed') className = 'completed';
|
if (status === 'completed') className = 'completed';
|
||||||
@@ -155,9 +180,11 @@ function renderStepsProgress(steps, currentStep) {
|
|||||||
<div class="step-node ${className}">
|
<div class="step-node ${className}">
|
||||||
<div class="step-circle">${i}</div>
|
<div class="step-circle">${i}</div>
|
||||||
<div class="step-label">${stepNames[i-1]}</div>
|
<div class="step-label">${stepNames[i-1]}</div>
|
||||||
|
${stepValue ? `<div class="step-value">${stepValue}</div>` : ''}
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
html += '</div>';
|
||||||
|
|
||||||
return html;
|
return html;
|
||||||
}
|
}
|
||||||
|
|||||||
+6
-1
@@ -773,7 +773,12 @@ async function loadBackgroundTasks() {
|
|||||||
const progressPercent = task.total > 0 ?
|
const progressPercent = task.total > 0 ?
|
||||||
Math.round((task.progress / task.total) * 100) : 0;
|
Math.round((task.progress / task.total) * 100) : 0;
|
||||||
|
|
||||||
const result = task.result ? JSON.parse(task.result) : {};
|
let result = {};
|
||||||
|
try {
|
||||||
|
result = task.result ? JSON.parse(task.result) : {};
|
||||||
|
} catch (e) {
|
||||||
|
result = {};
|
||||||
|
}
|
||||||
|
|
||||||
return `
|
return `
|
||||||
<div class="background-task-item ${statusClass}">
|
<div class="background-task-item ${statusClass}">
|
||||||
|
|||||||
Reference in New Issue
Block a user