Files
ns2.0/templates/site_settings.html

520 lines
16 KiB
HTML
Executable File
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 "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 %}