feat: v3.0.1 - 后台获取新闻功能优化

1. 新增后台管理获取新闻API (/api/admin/fetch-news/<code>)
   - 不需要验证码,仅管理员可用
   - 用于后台手动触发新闻获取

2. 后台网站管理添加"手动获取新闻"按钮
   - 在新闻关键词字段旁边显示
   - 编辑模式可用

3. 取消前台detail页面手动获取新闻入口
   - 用户不再需要手动刷新新闻
   - 新闻由管理员在后台控制获取

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Jowe
2026-03-13 22:16:12 +08:00
parent 8b71da2956
commit edbc4288f9
4 changed files with 416 additions and 3 deletions

View File

@@ -55,6 +55,31 @@
border: 1px solid rgba(239, 68, 68, 0.3);
color: #f87171;
}
.fetch-news-btn {
margin-top: 10px;
margin-bottom: 15px;
background-color: #e6a23c;
color: white;
}
.fetch-news-btn:hover {
background-color: #cf9236;
}
.news-status {
margin-top: 10px;
padding: 10px;
border-radius: 8px;
display: none;
}
.news-status.success {
background-color: rgba(34, 197, 94, 0.1);
border: 1px solid rgba(34, 197, 94, 0.3);
color: #4ade80;
}
.news-status.error {
background-color: rgba(239, 68, 68, 0.1);
border: 1px solid rgba(239, 68, 68, 0.3);
color: #f87171;
}
.auto-fetch-btn .loading-icon, .generate-tags-btn .loading-icon {
display: none;
}
@@ -637,6 +662,137 @@ document.addEventListener('DOMContentLoaded', function() {
featuresStatusDiv.style.display = 'block';
}
}
// 在 News Keywords 字段后添加"获取新闻"按钮
const newsKeywordsField = document.querySelector('input[name="news_keywords"]');
if (newsKeywordsField) {
// 创建获取新闻按钮
const fetchNewsBtn = document.createElement('button');
fetchNewsBtn.type = 'button';
fetchNewsBtn.className = 'btn fetch-news-btn';
fetchNewsBtn.innerHTML = '<span class="normal-icon">📰</span><span class="loading-icon">↻</span> 手动获取新闻';
const newsStatusDiv = document.createElement('div');
newsStatusDiv.className = 'news-status';
newsKeywordsField.parentNode.appendChild(fetchNewsBtn);
newsKeywordsField.parentNode.appendChild(newsStatusDiv);
// 获取当前网站code创建时没有code需要保存后才有
// 这里使用一个提示
fetchNewsBtn.addEventListener('click', function() {
showNewsStatus('请先保存网站基本信息,保存后再点击此按钮获取新闻', 'error');
});
function showNewsStatus(message, type) {
newsStatusDiv.textContent = message;
newsStatusDiv.className = 'news-status ' + type;
newsStatusDiv.style.display = 'block';
}
}
// 页面加载后如果有已保存的网站code显示获取新闻按钮
// 从URL中提取site_id来判断是否是编辑模式
const urlParams = new URLSearchParams(window.location.search);
const view = urlParams.get('view');
const siteId = urlParams.get('id');
// 如果是编辑模式,添加获取新闻功能
if (siteId) {
const newsKeywordsFieldEdit = document.querySelector('input[name="news_keywords"]');
const existingBtn = document.querySelector('.fetch-news-btn');
if (newsKeywordsFieldEdit && !existingBtn) {
// 创建获取新闻按钮(编辑模式)
const fetchNewsBtn = document.createElement('button');
fetchNewsBtn.type = 'button';
fetchNewsBtn.className = 'btn fetch-news-btn';
fetchNewsBtn.innerHTML = '<span class="normal-icon">📰</span><span class="loading-icon">↻</span> 手动获取新闻';
const newsStatusDiv = document.createElement('div');
newsStatusDiv.className = 'news-status';
newsKeywordsFieldEdit.parentNode.appendChild(fetchNewsBtn);
newsKeywordsFieldEdit.parentNode.appendChild(newsStatusDiv);
// 获取网站code
let siteCode = '';
const codeField = document.querySelector('input[name="code"]');
if (codeField) {
siteCode = codeField.value;
}
fetchNewsBtn.addEventListener('click', function() {
if (!siteCode) {
// 尝试从其他方式获取code
const urlMatch = window.location.pathname.match(/\/admin\/site\/edit\/(\d+)/);
if (urlMatch) {
// 通过网站ID获取code需要API支持这里先提示
showNewsStatus('正在获取网站信息...', 'success');
// 调用API获取网站信息
fetch('/admin/api/site/' + urlMatch[1], {
credentials: 'same-origin'
})
.then(response => response.json())
.then(data => {
if (data.code) {
fetchNews(siteCode);
}
})
.catch(() => {
showNewsStatus('无法获取网站编码,请确保网站已保存', 'error');
});
} else {
showNewsStatus('请先保存网站', 'error');
}
return;
}
fetchNews(siteCode);
});
function fetchNews(code) {
// 显示加载状态
fetchNewsBtn.disabled = true;
fetchNewsBtn.classList.add('loading');
fetchNewsBtn.innerHTML = '<span class="loading-icon">↻</span> 获取中...';
newsStatusDiv.style.display = 'none';
// 调用后台获取新闻API
fetch('/api/admin/fetch-news/' + code, {
method: 'POST',
credentials: 'same-origin',
headers: {
'Content-Type': 'application/json'
}
})
.then(response => response.json())
.then(data => {
if (data.success) {
showNewsStatus('✓ ' + data.message, 'success');
} else {
showNewsStatus('✗ ' + (data.error || '获取失败'), 'error');
}
})
.catch(error => {
console.error('Error:', error);
showNewsStatus('✗ 网络请求失败', 'error');
})
.finally(() => {
fetchNewsBtn.disabled = false;
fetchNewsBtn.classList.remove('loading');
fetchNewsBtn.innerHTML = '<span class="normal-icon">📰</span><span class="loading-icon">↻</span> 手动获取新闻';
});
}
function showNewsStatus(message, type) {
newsStatusDiv.textContent = message;
newsStatusDiv.className = 'news-status ' + type;
newsStatusDiv.style.display = 'block';
}
}
}
});
</script>
{% endblock %}

View File

@@ -800,9 +800,11 @@
<span>📰</span>
相关新闻
</h2>
<button id="refreshNewsBtn" class="refresh-news-btn" onclick="showCaptchaModal('{{ site.code }}')">
<span class="refresh-icon"></span> <span class="btn-text">{% if has_news %}获取最新资讯{% else %}加载资讯{% endif %}</span>
</button>
{% if news_list %}
<span style="font-size: 13px; color: var(--text-muted);">
共 {{ news_list|length }} 条资讯
</span>
{% endif %}
</div>
<div id="newsContainer">
{% if news_list %}