// API基础地址
const API_BASE = '';
// 搜索结果存储
let searchResults = [];
let currentResultIndex = -1;
// 页面加载初始化
document.addEventListener('DOMContentLoaded', () => {
// 回车搜索
document.getElementById('search-keyword').addEventListener('keypress', (e) => {
if (e.key === 'Enter') {
doSearch();
}
});
});
// 执行搜索
async function doSearch() {
const keyword = document.getElementById('search-keyword').value.trim();
const maxResults = parseInt(document.getElementById('search-count').value) || 10;
const autoFetch = document.getElementById('auto-fetch').checked;
const autoSave = document.getElementById('auto-save').checked;
if (!keyword) {
showToast('请输入搜索关键词', 'error');
return;
}
// 更新状态
updateStatus('searching', '搜索中...');
document.getElementById('search-btn').disabled = true;
// 显示进度
const progress = document.getElementById('search-progress');
progress.style.display = 'block';
document.getElementById('progress-fill').style.width = '0%';
document.getElementById('progress-text').textContent = '正在搜索...';
try {
const response = await fetch(`${API_BASE}/api/articles/internet-search`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ keyword, max_results: maxResults })
});
const data = await response.json();
if (data.success) {
searchResults = data.results.map(r => ({
...r,
fetched: false,
saved: false,
content: ''
}));
displayResults();
updateStatus('success', `找到 ${searchResults.length} 条结果`);
document.getElementById('results-count').textContent = `${searchResults.length} 条结果`;
document.getElementById('save-all-btn').disabled = searchResults.length === 0;
document.getElementById('progress-fill').style.width = '100%';
document.getElementById('progress-text').textContent = '搜索完成!';
// 自动抓取和保存
if (autoFetch && searchResults.length > 0) {
setTimeout(() => fetchAllResults(autoSave), 500);
}
} else {
updateStatus('error', '搜索失败');
showToast('搜索失败: ' + data.error, 'error');
}
} catch (error) {
updateStatus('error', '搜索出错');
showToast('搜索出错', 'error');
console.error(error);
}
setTimeout(() => {
progress.style.display = 'none';
}, 1000);
document.getElementById('search-btn').disabled = false;
}
// 显示搜索结果
function displayResults() {
const container = document.getElementById('search-results');
if (searchResults.length === 0) {
container.innerHTML = '
未找到相关结果
';
return;
}
container.innerHTML = searchResults.map((r, i) => `
${i + 1}
${r.saved ? '' : ''}
${escapeHtml(r.title)}
${r.content ? `
${escapeHtml(r.content.substring(0, 100))}...
` : ''}
`).join('');
}
// 抓取单个结果
async function fetchResult(index) {
const result = searchResults[index];
if (!result || result.fetched) return;
const btn = document.getElementById(`fetch-btn-${index}`);
btn.disabled = true;
btn.innerHTML = ' 抓取中...';
try {
const response = await fetch(`${API_BASE}/api/articles/fetch`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
url: result.url,
product_names: [result.title]
})
});
const data = await response.json();
if (data.success) {
searchResults[index].fetched = true;
searchResults[index].content = data.data.content;
searchResults[index].title = data.data.title || result.title;
btn.innerHTML = ' 已抓取';
// 更新结果显示
const item = document.getElementById(`result-${index}`);
item.classList.add('fetched');
showToast('抓取成功', 'success');
displayResults();
} else {
btn.disabled = false;
btn.innerHTML = ' 抓取';
showToast('抓取失败: ' + data.error, 'error');
}
} catch (error) {
btn.disabled = false;
btn.innerHTML = ' 抓取';
showToast('抓取出错', 'error');
}
}
// 保存单个结果
async function saveResult(index) {
const result = searchResults[index];
if (!result) return;
// 如果未抓取,先抓取
if (!result.fetched) {
await fetchResult(index);
if (!searchResults[index].fetched) return;
}
const btn = document.getElementById(`save-btn-${index}`);
btn.disabled = true;
btn.innerHTML = ' 保存中...';
try {
const response = await fetch(`${API_BASE}/api/articles`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
product_names: [searchResults[index].title],
category: '',
keywords: [],
summary: searchResults[index].content.substring(0, 200),
content: searchResults[index].content,
source: searchResults[index].url,
url: searchResults[index].url
})
});
const data = await response.json();
if (data.success) {
searchResults[index].saved = true;
btn.innerHTML = ' 已保存';
const item = document.getElementById(`result-${index}`);
item.classList.add('saved');
showToast('保存成功', 'success');
displayResults();
} else {
btn.disabled = false;
btn.innerHTML = ' 保存';
showToast('保存失败: ' + data.error, 'error');
}
} catch (error) {
btn.disabled = false;
btn.innerHTML = ' 保存';
showToast('保存出错', 'error');
}
}
// 一键保存全部
async function saveAllResults() {
const unsaved = searchResults.filter(r => !r.saved);
if (unsaved.length === 0) {
showToast('没有需要保存的结果', 'error');
return;
}
const progress = document.getElementById('save-progress');
progress.style.display = 'block';
let saved = 0;
const total = unsaved.length;
for (let i = 0; i < searchResults.length; i++) {
if (searchResults[i].saved) continue;
document.getElementById('save-progress-text').textContent =
`正在保存 ${saved + 1}/${total}...`;
document.getElementById('save-fill').style.width =
`${(saved / total) * 100}%`;
await saveResult(i);
saved++;
}
document.getElementById('save-fill').style.width = '100%';
document.getElementById('save-progress-text').textContent = '保存完成!';
setTimeout(() => {
progress.style.display = 'none';
}, 1500);
showToast(`成功保存 ${saved} 条结果`, 'success');
}
// 抓取所有结果
async function fetchAllResults(autoSave) {
const progress = document.getElementById('search-progress');
progress.style.display = 'block';
const total = searchResults.length;
let fetched = 0;
for (let i = 0; i < searchResults.length; i++) {
if (searchResults[i].fetched) {
fetched++;
continue;
}
document.getElementById('progress-text').textContent =
`正在抓取 ${fetched + 1}/${total}...`;
document.getElementById('progress-fill').style.width =
`${(fetched / total) * 100}%`;
await fetchResult(i);
fetched++;
}
document.getElementById('progress-fill').style.width = '100%';
document.getElementById('progress-text').textContent = '抓取完成!';
setTimeout(() => {
progress.style.display = 'none';
}, 1000);
// 自动保存
if (autoSave) {
setTimeout(() => saveAllResults(), 500);
}
}
// 显示结果详情
function showResultDetail(index) {
currentResultIndex = index;
const result = searchResults[index];
const body = document.getElementById('result-detail-body');
body.innerHTML = `
${result.content ? `
页面内容
${escapeHtml(result.content.substring(0, 3000))}${result.content.length > 3000 ? '\n...(内容过长,已截断)' : ''}
` : '尚未抓取内容,点击"保存到内容库"将自动抓取并保存
'}
`;
document.getElementById('result-detail-modal').classList.add('active');
}
// 保存当前结果
async function saveCurrentResult() {
if (currentResultIndex >= 0) {
await saveResult(currentResultIndex);
closeModal('result-detail-modal');
}
}
// 清空结果
function clearResults() {
searchResults = [];
displayResults();
document.getElementById('results-count').textContent = '0 条结果';
document.getElementById('save-all-btn').disabled = true;
updateStatus('ready', '就绪');
}
// 更新状态
function updateStatus(status, text) {
const dot = document.getElementById('search-status');
const statusText = document.getElementById('status-text');
dot.className = 'status-dot';
if (status === 'searching') {
dot.style.background = '#f59e0b';
} else if (status === 'success') {
dot.style.background = '#10b981';
} else if (status === 'error') {
dot.style.background = '#ef4444';
} else {
dot.style.background = '#10b981';
}
statusText.textContent = text;
}
// 关闭模态框
function closeModal(modalId) {
document.getElementById(modalId).classList.remove('active');
}
// 显示提示
function showToast(message, type = '') {
const toast = document.getElementById('toast');
toast.textContent = message;
toast.className = `toast active ${type}`;
setTimeout(() => {
toast.classList.remove('active');
}, 3000);
}
// HTML转义
function escapeHtml(text) {
if (!text) return '';
const div = document.createElement('div');
div.textContent = text;
return div.innerHTML;
}