520 lines
16 KiB
HTML
Executable File
520 lines
16 KiB
HTML
Executable File
{% extends "base.html" %}
|
||
|
||
{% block content %}
|
||
{% include 'admin_nav.html' %}
|
||
|
||
<div class="admin-container">
|
||
<div class="admin-content">
|
||
<div class="settings-layout">
|
||
<!-- 左侧导航 -->
|
||
<div class="settings-nav">
|
||
<div class="nav-item active" data-target="basic">
|
||
<i class="fas fa-cog"></i>
|
||
<span>基础设置</span>
|
||
</div>
|
||
<div class="nav-item" data-target="groups">
|
||
<i class="fas fa-users"></i>
|
||
<span>群组设置</span>
|
||
</div>
|
||
<div class="nav-item" data-target="watermark">
|
||
<i class="fas fa-image"></i>
|
||
<span>水印设置</span>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 右侧内容区 -->
|
||
<div class="settings-content">
|
||
<!-- 基础设置 -->
|
||
<div class="settings-section active" id="basic-section">
|
||
<div class="section-header">
|
||
<h2>基础设置</h2>
|
||
<p class="section-desc">设置站点的基本信息和通知内容</p>
|
||
</div>
|
||
<form onsubmit="submitSettings(event, 'basic')" class="admin-form">
|
||
<div class="form-group">
|
||
<label for="site-notice">站点通知</label>
|
||
<textarea id="site-notice" name="site_notice" rows="3" required>{{ settings.site_notice }}</textarea>
|
||
</div>
|
||
|
||
<div class="form-group">
|
||
<label for="feedback-link">反馈链接</label>
|
||
<input type="url" id="feedback-link" name="feedback_link" value="{{ settings.feedback_link }}" required>
|
||
</div>
|
||
|
||
<div class="form-group">
|
||
<label for="discord-link">Discord 频道链接</label>
|
||
<input type="url" id="discord-link" name="discord_link" value="{{ settings.discord_link }}">
|
||
</div>
|
||
|
||
<div class="form-group">
|
||
<label for="icp-number">网站备案号</label>
|
||
<input type="text" id="icp-number" name="icp_number"
|
||
value="{{ settings.icp_number }}"
|
||
placeholder="例如:京ICP备XXXXXXXX号">
|
||
</div>
|
||
|
||
<div class="form-group">
|
||
<label for="grayscale-enabled">网页黑白效果</label>
|
||
<div class="switch-wrapper">
|
||
<label class="switch">
|
||
<input type="checkbox" id="grayscale-enabled" name="grayscale_enabled"
|
||
{% if settings.grayscale_enabled == '1' %}checked{% endif %}>
|
||
<span class="slider round"></span>
|
||
</label>
|
||
<span class="switch-label">启用网页黑白效果(用于特殊纪念日)</span>
|
||
</div>
|
||
</div>
|
||
|
||
<button type="submit" class="btn-primary">
|
||
<i class="fas fa-save"></i> 保存设置
|
||
</button>
|
||
</form>
|
||
</div>
|
||
|
||
<!-- 群组设置 -->
|
||
<div class="settings-section" id="groups-section">
|
||
<div class="section-header">
|
||
<h2>群组设置</h2>
|
||
<p class="section-desc">管理QQ群和微信群的相关配置</p>
|
||
</div>
|
||
<form onsubmit="submitSettings(event, 'groups')" class="admin-form">
|
||
<div class="settings-grid">
|
||
<!-- QQ群设置 -->
|
||
<div class="setting-card">
|
||
<div class="card-header">
|
||
<i class="fab fa-qq"></i>
|
||
<h3>QQ群设置</h3>
|
||
</div>
|
||
<div class="card-body">
|
||
<div class="form-group">
|
||
<label>按钮文字</label>
|
||
<input type="text" name="qq_group_text" value="{{ settings.qq_group_text }}" class="form-control">
|
||
</div>
|
||
|
||
<div class="form-group">
|
||
<label>群号</label>
|
||
<input type="text" name="qq_group_number" value="{{ settings.qq_group_number }}" class="form-control">
|
||
</div>
|
||
|
||
<div class="form-group">
|
||
<label>加群链接</label>
|
||
<input type="text" name="qq_group_link" value="{{ settings.qq_group_link }}" class="form-control">
|
||
</div>
|
||
|
||
<div class="form-group">
|
||
<label>群二维码</label>
|
||
<input type="file" name="qq_group_qrcode" accept="image/*" class="form-control">
|
||
{% if settings.qq_group_qrcode %}
|
||
<div class="preview-image">
|
||
<img src="{{ settings.qq_group_qrcode }}" alt="QQ群二维码">
|
||
</div>
|
||
{% endif %}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 微信群设置 -->
|
||
<div class="setting-card">
|
||
<div class="card-header">
|
||
<i class="fab fa-weixin"></i>
|
||
<h3>微信群设置</h3>
|
||
</div>
|
||
<div class="card-body">
|
||
<div class="form-group">
|
||
<label>按钮文字</label>
|
||
<input type="text" name="wechat_group_text" value="{{ settings.wechat_group_text }}" class="form-control">
|
||
</div>
|
||
|
||
<div class="form-group">
|
||
<label>群二维码</label>
|
||
<input type="file" name="wechat_group_qrcode" accept="image/*" class="form-control">
|
||
{% if settings.wechat_group_qrcode %}
|
||
<div class="preview-image">
|
||
<img src="{{ settings.wechat_group_qrcode }}" alt="微信群二维码">
|
||
</div>
|
||
{% endif %}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<button type="submit" class="btn-primary">
|
||
<i class="fas fa-save"></i> 保存设置
|
||
</button>
|
||
</form>
|
||
</div>
|
||
|
||
<!-- 水印设置 -->
|
||
<div class="settings-section" id="watermark-section">
|
||
<div class="section-header">
|
||
<h2>水印设置</h2>
|
||
<p class="section-desc">设置应用图标的水印文本</p>
|
||
</div>
|
||
<form onsubmit="submitSettings(event, 'watermark')" class="admin-form">
|
||
<div class="form-group">
|
||
<label for="watermark-text-1">水印文本 1</label>
|
||
<input type="text" id="watermark-text-1" name="watermark_text_1"
|
||
value="{{ settings.watermark_text_1 }}"
|
||
placeholder="输入第一个水印文本">
|
||
</div>
|
||
|
||
<div class="form-group">
|
||
<label for="watermark-text-2">水印文本 2</label>
|
||
<input type="text" id="watermark-text-2" name="watermark_text_2"
|
||
value="{{ settings.watermark_text_2 }}"
|
||
placeholder="输入第二个水印文本">
|
||
</div>
|
||
|
||
<button type="submit" class="btn-primary">
|
||
<i class="fas fa-save"></i> 保存设置
|
||
</button>
|
||
</form>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<style>
|
||
/* 主布局 */
|
||
.settings-layout {
|
||
display: flex;
|
||
gap: 15px;
|
||
padding: 15px;
|
||
min-height: calc(100vh - 60px);
|
||
}
|
||
|
||
/* 左侧导航 */
|
||
.settings-nav {
|
||
width: 180px;
|
||
background: white;
|
||
border-radius: 8px;
|
||
padding: 10px;
|
||
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
|
||
}
|
||
|
||
.nav-item {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 8px;
|
||
padding: 10px 12px;
|
||
border-radius: 6px;
|
||
cursor: pointer;
|
||
transition: all 0.3s ease;
|
||
}
|
||
|
||
.nav-item i {
|
||
font-size: 16px;
|
||
width: 20px;
|
||
text-align: center;
|
||
}
|
||
|
||
.nav-item.active {
|
||
background: #007AFF;
|
||
color: white;
|
||
}
|
||
|
||
.nav-item:not(.active):hover {
|
||
background: #f5f5f7;
|
||
}
|
||
|
||
/* 右侧内容区 */
|
||
.settings-content {
|
||
flex: 1;
|
||
background: white;
|
||
border-radius: 8px;
|
||
padding: 20px;
|
||
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
|
||
}
|
||
|
||
.settings-section {
|
||
display: none;
|
||
}
|
||
|
||
.settings-section.active {
|
||
display: block;
|
||
}
|
||
|
||
.section-header {
|
||
margin-bottom: 30px;
|
||
}
|
||
|
||
.section-header h2 {
|
||
margin: 0;
|
||
font-size: 24px;
|
||
color: #333;
|
||
}
|
||
|
||
.section-desc {
|
||
margin: 8px 0 0 0;
|
||
color: #666;
|
||
font-size: 14px;
|
||
}
|
||
|
||
/* 表单样式 */
|
||
.settings-grid {
|
||
display: grid;
|
||
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
|
||
gap: 20px;
|
||
margin-bottom: 20px;
|
||
}
|
||
|
||
.setting-card {
|
||
background: #f5f5f7;
|
||
border-radius: 12px;
|
||
padding: 20px;
|
||
}
|
||
|
||
.card-header {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 10px;
|
||
margin-bottom: 20px;
|
||
}
|
||
|
||
.card-header i {
|
||
font-size: 20px;
|
||
}
|
||
|
||
.card-header h3 {
|
||
margin: 0;
|
||
font-size: 18px;
|
||
}
|
||
|
||
.form-group {
|
||
margin-bottom: 20px;
|
||
}
|
||
|
||
.form-control {
|
||
width: 100%;
|
||
padding: 10px;
|
||
border: 1px solid #d2d2d7;
|
||
border-radius: 8px;
|
||
font-size: 14px;
|
||
transition: all 0.3s ease;
|
||
}
|
||
|
||
.form-control:focus {
|
||
border-color: #007AFF;
|
||
box-shadow: 0 0 0 2px rgba(0,122,255,0.1);
|
||
outline: none;
|
||
}
|
||
|
||
textarea.form-control {
|
||
min-height: 100px;
|
||
resize: vertical;
|
||
}
|
||
|
||
.preview-image {
|
||
margin-top: 10px;
|
||
}
|
||
|
||
.preview-image img {
|
||
max-width: 200px;
|
||
border-radius: 8px;
|
||
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
|
||
}
|
||
|
||
/* 按钮样式 */
|
||
.btn-primary {
|
||
display: inline-flex;
|
||
align-items: center;
|
||
gap: 8px;
|
||
padding: 10px 20px;
|
||
background: #007AFF;
|
||
color: white;
|
||
border: none;
|
||
border-radius: 8px;
|
||
font-size: 14px;
|
||
cursor: pointer;
|
||
transition: all 0.3s ease;
|
||
}
|
||
|
||
.btn-primary:hover {
|
||
background: #0066CC;
|
||
transform: translateY(-1px);
|
||
}
|
||
|
||
/* 暗色模式 */
|
||
[data-theme="dark"] .settings-nav,
|
||
[data-theme="dark"] .settings-content {
|
||
background: #1c1c1e;
|
||
}
|
||
|
||
[data-theme="dark"] .setting-card {
|
||
background: #2c2c2e;
|
||
}
|
||
|
||
[data-theme="dark"] .section-header h2 {
|
||
color: #fff;
|
||
}
|
||
|
||
[data-theme="dark"] .section-desc {
|
||
color: #999;
|
||
}
|
||
|
||
[data-theme="dark"] .form-control {
|
||
background: #2c2c2e;
|
||
border-color: #3a3a3c;
|
||
color: #fff;
|
||
}
|
||
|
||
[data-theme="dark"] .nav-item:not(.active):hover {
|
||
background: #2c2c2e;
|
||
}
|
||
|
||
/* 响应式布局 */
|
||
@media (max-width: 768px) {
|
||
.settings-layout {
|
||
flex-direction: column;
|
||
}
|
||
|
||
.settings-nav {
|
||
width: 100%;
|
||
}
|
||
|
||
.settings-grid {
|
||
grid-template-columns: 1fr;
|
||
}
|
||
}
|
||
|
||
/* 开关样式 */
|
||
.switch-wrapper {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 10px;
|
||
}
|
||
|
||
.switch {
|
||
position: relative;
|
||
display: inline-block;
|
||
width: 50px;
|
||
height: 24px;
|
||
}
|
||
|
||
.switch input {
|
||
opacity: 0;
|
||
width: 0;
|
||
height: 0;
|
||
}
|
||
|
||
.slider {
|
||
position: absolute;
|
||
cursor: pointer;
|
||
top: 0;
|
||
left: 0;
|
||
right: 0;
|
||
bottom: 0;
|
||
background-color: #ccc;
|
||
transition: .4s;
|
||
border-radius: 24px;
|
||
}
|
||
|
||
.slider:before {
|
||
position: absolute;
|
||
content: "";
|
||
height: 18px;
|
||
width: 18px;
|
||
left: 3px;
|
||
bottom: 3px;
|
||
background-color: white;
|
||
transition: .4s;
|
||
border-radius: 50%;
|
||
}
|
||
|
||
input:checked + .slider {
|
||
background-color: #007AFF;
|
||
}
|
||
|
||
input:checked + .slider:before {
|
||
transform: translateX(26px);
|
||
}
|
||
|
||
.switch-label {
|
||
font-size: 14px;
|
||
color: #666;
|
||
}
|
||
|
||
/* 暗色模式适配 */
|
||
[data-theme="dark"] .switch-label {
|
||
color: #999;
|
||
}
|
||
</style>
|
||
|
||
<script>
|
||
// 标签页切换
|
||
document.querySelectorAll('.nav-item').forEach(item => {
|
||
item.addEventListener('click', () => {
|
||
// 更新导航项状态
|
||
document.querySelectorAll('.nav-item').forEach(nav => {
|
||
nav.classList.remove('active');
|
||
});
|
||
item.classList.add('active');
|
||
|
||
// 更新内容区域
|
||
const target = item.dataset.target;
|
||
document.querySelectorAll('.settings-section').forEach(section => {
|
||
section.classList.remove('active');
|
||
});
|
||
document.getElementById(`${target}-section`).classList.add('active');
|
||
});
|
||
});
|
||
|
||
// 表单提交
|
||
function submitSettings(event, type) {
|
||
event.preventDefault();
|
||
const form = event.target;
|
||
const formData = new FormData(form);
|
||
formData.append('type', type);
|
||
|
||
fetch('/admin/update_site_settings', {
|
||
method: 'POST',
|
||
body: formData
|
||
})
|
||
.then(response => response.json())
|
||
.then(data => {
|
||
if (data.success) {
|
||
showNotification(`${type}设置已更新`, 'success');
|
||
setTimeout(() => location.reload(), 1000);
|
||
} else {
|
||
showNotification(data.error || '更新失败', 'error');
|
||
}
|
||
})
|
||
.catch(error => {
|
||
console.error('Error:', error);
|
||
showNotification('更新失败,请重试', 'error');
|
||
});
|
||
}
|
||
|
||
// 通知提示
|
||
function showNotification(message, type = 'success') {
|
||
const notification = document.createElement('div');
|
||
notification.className = `notification ${type}`;
|
||
notification.textContent = message;
|
||
|
||
Object.assign(notification.style, {
|
||
position: 'fixed',
|
||
bottom: '20px',
|
||
right: '20px',
|
||
padding: '10px 20px',
|
||
borderRadius: '8px',
|
||
backgroundColor: type === 'success' ? '#4CAF50' : '#f44336',
|
||
color: 'white',
|
||
zIndex: '1000',
|
||
opacity: '0',
|
||
transform: 'translateY(20px)',
|
||
transition: 'all 0.3s ease'
|
||
});
|
||
|
||
document.body.appendChild(notification);
|
||
notification.offsetHeight;
|
||
notification.style.opacity = '1';
|
||
notification.style.transform = 'translateY(0)';
|
||
|
||
setTimeout(() => {
|
||
notification.style.opacity = '0';
|
||
notification.style.transform = 'translateY(20px)';
|
||
setTimeout(() => notification.remove(), 300);
|
||
}, 3000);
|
||
}
|
||
</script>
|
||
{% endblock %} |