- 前台页面全面升级为Tailwind CSS框架 - 引入Google Fonts (Space Grotesk, Noto Sans) - 主色调更新为#25c0f4 (cyan blue) - 实现玻璃态效果和渐变背景 - 优化首页网格卡片布局和悬停动画 - 优化详情页双栏布局和渐变Logo光晕 - 优化管理员登录页,添加科技网格背景 - Flask-Admin后台完整深色主题 - 统一Material Symbols图标系统 - 网站自动抓取功能界面优化 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
125 lines
4.2 KiB
HTML
125 lines
4.2 KiB
HTML
{% extends 'admin/model/edit.html' %}
|
|
|
|
{% block tail %}
|
|
{{ super() }}
|
|
<style>
|
|
.auto-fetch-btn {
|
|
margin-top: 10px;
|
|
margin-bottom: 15px;
|
|
}
|
|
.fetch-status {
|
|
margin-top: 10px;
|
|
padding: 10px;
|
|
border-radius: 8px;
|
|
display: none;
|
|
}
|
|
.fetch-status.success {
|
|
background-color: rgba(34, 197, 94, 0.1);
|
|
border: 1px solid rgba(34, 197, 94, 0.3);
|
|
color: #4ade80;
|
|
}
|
|
.fetch-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 {
|
|
display: none;
|
|
}
|
|
.auto-fetch-btn.loading .loading-icon {
|
|
display: inline-block;
|
|
animation: spin 1s linear infinite;
|
|
}
|
|
.auto-fetch-btn.loading .normal-icon {
|
|
display: none;
|
|
}
|
|
@keyframes spin {
|
|
from { transform: rotate(0deg); }
|
|
to { transform: rotate(360deg); }
|
|
}
|
|
</style>
|
|
|
|
<script>
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
// 在URL字段后添加"自动获取"按钮
|
|
const urlField = document.querySelector('input[name="url"]');
|
|
if (urlField) {
|
|
const fetchBtn = document.createElement('button');
|
|
fetchBtn.type = 'button';
|
|
fetchBtn.className = 'btn btn-info auto-fetch-btn';
|
|
fetchBtn.innerHTML = '<span class="normal-icon">↻</span><span class="loading-icon">↻</span> 自动获取网站信息';
|
|
|
|
const statusDiv = document.createElement('div');
|
|
statusDiv.className = 'fetch-status';
|
|
|
|
urlField.parentNode.appendChild(fetchBtn);
|
|
urlField.parentNode.appendChild(statusDiv);
|
|
|
|
fetchBtn.addEventListener('click', function() {
|
|
const url = urlField.value.trim();
|
|
|
|
if (!url) {
|
|
showStatus('请先输入网站URL', 'error');
|
|
return;
|
|
}
|
|
|
|
// 显示加载状态
|
|
fetchBtn.disabled = true;
|
|
fetchBtn.classList.add('loading');
|
|
statusDiv.style.display = 'none';
|
|
|
|
// 调用API获取网站信息
|
|
fetch('/api/fetch-website-info', {
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
},
|
|
body: JSON.stringify({ url: url })
|
|
})
|
|
.then(response => response.json())
|
|
.then(data => {
|
|
if (data.success) {
|
|
// 自动填充表单字段
|
|
const nameField = document.querySelector('input[name="name"]');
|
|
const shortDescField = document.querySelector('input[name="short_desc"]');
|
|
const descriptionField = document.querySelector('textarea[name="description"]');
|
|
const logoField = document.querySelector('input[name="logo"]');
|
|
|
|
if (nameField && data.data.name) {
|
|
nameField.value = data.data.name;
|
|
}
|
|
if (shortDescField && data.data.description) {
|
|
shortDescField.value = data.data.description.substring(0, 100);
|
|
}
|
|
if (descriptionField && data.data.description) {
|
|
descriptionField.value = data.data.description;
|
|
}
|
|
if (logoField && data.data.logo) {
|
|
logoField.value = data.data.logo;
|
|
}
|
|
|
|
showStatus('✓ 网站信息获取成功!已自动填充表单', 'success');
|
|
} else {
|
|
showStatus('✗ ' + (data.message || '获取失败,请手动填写'), 'error');
|
|
}
|
|
})
|
|
.catch(error => {
|
|
console.error('Error:', error);
|
|
showStatus('✗ 网络请求失败,请手动填写', 'error');
|
|
})
|
|
.finally(() => {
|
|
fetchBtn.disabled = false;
|
|
fetchBtn.classList.remove('loading');
|
|
});
|
|
});
|
|
|
|
function showStatus(message, type) {
|
|
statusDiv.textContent = message;
|
|
statusDiv.className = 'fetch-status ' + type;
|
|
statusDiv.style.display = 'block';
|
|
}
|
|
}
|
|
});
|
|
</script>
|
|
{% endblock %}
|