Files
zjpb.net/templates/admin/site/edit.html
Jowe 9e47ebe749 release: v2.0 - 完整功能管理系统
主要功能:
- 完整的Flask-Admin后台管理系统
- 网站/标签/新闻管理功能
- 用户登录认证系统
- 科技感/未来风UI设计
- 标签分类系统(取代传统分类)
- 详情页面展示
- 数据库迁移脚本
- 书签导入解析工具

技术栈:
- Flask + SQLAlchemy
- Flask-Admin管理界面
- Bootstrap 4响应式设计
- 用户认证与权限管理

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-28 19:21:17 +08:00

204 lines
7.4 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{% extends 'admin/model/edit.html' %}
{% block tail %}
{{ super() }}
<style>
.auto-fetch-btn {
margin-top: 10px;
margin-bottom: 15px;
}
.generate-tags-btn {
margin-top: 10px;
margin-bottom: 15px;
}
.fetch-status {
margin-top: 10px;
padding: 10px;
border-radius: 8px;
display: none;
}
.tags-status {
margin-top: 10px;
padding: 10px;
border-radius: 8px;
display: none;
}
.fetch-status.success, .tags-status.success {
background-color: rgba(34, 197, 94, 0.1);
border: 1px solid rgba(34, 197, 94, 0.3);
color: #4ade80;
}
.fetch-status.error, .tags-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;
}
.auto-fetch-btn.loading .loading-icon, .generate-tags-btn.loading .loading-icon {
display: inline-block;
animation: spin 1s linear infinite;
}
.auto-fetch-btn.loading .normal-icon, .generate-tags-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';
}
}
// 在标签字段后添加"AI生成标签"按钮
const tagsField = document.querySelector('select[name="tags"]');
if (tagsField) {
const generateBtn = document.createElement('button');
generateBtn.type = 'button';
generateBtn.className = 'btn btn-success generate-tags-btn';
generateBtn.innerHTML = '<span class="normal-icon">✨</span><span class="loading-icon">↻</span> AI生成标签';
const tagsStatusDiv = document.createElement('div');
tagsStatusDiv.className = 'tags-status';
tagsField.parentNode.appendChild(generateBtn);
tagsField.parentNode.appendChild(tagsStatusDiv);
generateBtn.addEventListener('click', function() {
const nameField = document.querySelector('input[name="name"]');
const descriptionField = document.querySelector('textarea[name="description"]');
const name = nameField ? nameField.value.trim() : '';
const description = descriptionField ? descriptionField.value.trim() : '';
if (!name || !description) {
showTagsStatus('请先填写网站名称和描述', 'error');
return;
}
// 显示加载状态
generateBtn.disabled = true;
generateBtn.classList.add('loading');
tagsStatusDiv.style.display = 'none';
// 调用API生成标签
fetch('/api/generate-tags', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
name: name,
description: description
})
})
.then(response => response.json())
.then(data => {
if (data.success && data.tags && data.tags.length > 0) {
// 显示生成的标签
const tagsText = data.tags.join(', ');
showTagsStatus('✓ AI生成的标签建议: ' + tagsText + '\n请在标签字段中手动选择或创建这些标签', 'success');
} else {
showTagsStatus('✗ ' + (data.message || '标签生成失败'), 'error');
}
})
.catch(error => {
console.error('Error:', error);
showTagsStatus('✗ 网络请求失败,请重试', 'error');
})
.finally(() => {
generateBtn.disabled = false;
generateBtn.classList.remove('loading');
});
});
function showTagsStatus(message, type) {
tagsStatusDiv.textContent = message;
tagsStatusDiv.className = 'tags-status ' + type;
tagsStatusDiv.style.display = 'block';
}
}
});
</script>
{% endblock %}