Kamixitong/app/web/templates/settings/index.html
2025-11-22 16:48:45 +08:00

944 lines
39 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 "base.html" %}
{% block title %}系统设置 - 软件授权管理系统{% endblock %}
{% block page_title %}系统设置{% endblock %}
{% block content %}
<div class="row">
<div class="col-lg-8">
<div class="card shadow mb-4">
<div class="card-header">
<h6 class="mb-0">基本设置</h6>
</div>
<div class="card-body">
<form id="basic-settings-form">
<div class="mb-3">
<label for="site_name" class="form-label">系统名称</label>
<input type="text" class="form-control" id="site_name" name="site_name" value="{{ config.SITE_NAME or '软件授权管理系统' }}">
</div>
<div class="mb-3">
<label for="admin_email" class="form-label">管理员邮箱</label>
<input type="email" class="form-control" id="admin_email" name="admin_email" value="{{ config.ADMIN_EMAIL or '' }}">
</div>
<div class="mb-3">
<label for="frontend_domain" class="form-label">前端域名</label>
<input type="text" class="form-control" id="frontend_domain" name="frontend_domain"
value="{{ config.FRONTEND_DOMAIN or '' }}">
<div class="form-text">前端API请求使用的域名留空则使用当前访问域名</div>
</div>
<div class="mb-3">
<label for="max_failed_attempts" class="form-label">最大失败尝试次数</label>
<input type="number" class="form-control" id="max_failed_attempts" name="max_failed_attempts"
value="{{ config.MAX_FAILED_ATTEMPTS or 5 }}" min="1" max="20">
</div>
<div class="mb-3">
<label for="lockout_minutes" class="form-label">锁定时间(分钟)</label>
<input type="number" class="form-control" id="lockout_minutes" name="lockout_minutes"
value="{{ config.LOCKOUT_MINUTES or 10 }}" min="1" max="1440">
</div>
<div class="mb-3">
<label for="max_unbind_times" class="form-label">最大解绑次数</label>
<input type="number" class="form-control" id="max_unbind_times" name="max_unbind_times"
value="{{ config.MAX_UNBIND_TIMES or 3 }}" min="0" max="100">
</div>
<div class="mb-3">
<label for="auth_secret_key" class="form-label">授权验证密钥</label>
<input type="text" class="form-control" id="auth_secret_key" name="auth_secret_key"
value="{{ config.AUTH_SECRET_KEY or 'auth-validator-secret-key' }}">
<div class="form-text">用于授权验证的密钥,请妥善保管</div>
</div>
<button type="submit" class="btn btn-primary" id="save-basic-btn">
<i class="fas fa-save me-2"></i>
<span id="save-basic-text">保存设置</span>
</button>
</form>
</div>
</div>
<!-- 新增的安全配置 -->
<div class="card shadow mb-4">
<div class="card-header">
<h6 class="mb-0">安全配置</h6>
</div>
<div class="card-body">
<form id="security-settings-form">
<div class="mb-3">
<label for="secret_key" class="form-label">应用密钥</label>
<div class="input-group">
<input type="password" class="form-control" id="secret_key" name="secret_key"
placeholder="••••••••">
<button class="btn btn-outline-secondary" type="button" id="generate-secret-key">
生成新密钥
</button>
</div>
<div class="form-text">Flask应用密钥用于会话和CSRF保护</div>
</div>
<div class="mb-3">
<label for="session_cookie_secure" class="form-label">会话Cookie安全</label>
<select class="form-select" id="session_cookie_secure" name="session_cookie_secure">
<option value="True" {{ 'selected' if config.SESSION_COOKIE_SECURE else '' }}>启用</option>
<option value="False" {{ 'selected' if not config.SESSION_COOKIE_SECURE else '' }}>禁用</option>
</select>
<div class="form-text">在HTTPS环境下启用以增强安全性</div>
</div>
<div class="mb-3">
<label for="session_cookie_httponly" class="form-label">会话Cookie HttpOnly</label>
<select class="form-select" id="session_cookie_httponly" name="session_cookie_httponly">
<option value="True" {{ 'selected' if config.SESSION_COOKIE_HTTPONLY else '' }}>启用</option>
<option value="False" {{ 'selected' if not config.SESSION_COOKIE_HTTPONLY else '' }}>禁用</option>
</select>
<div class="form-text">防止客户端脚本访问Cookie</div>
</div>
<div class="mb-3">
<label for="session_cookie_samesite" class="form-label">会话Cookie SameSite</label>
<select class="form-select" id="session_cookie_samesite" name="session_cookie_samesite">
<option value="Lax" {{ 'selected' if config.SESSION_COOKIE_SAMESITE == 'Lax' else '' }}>Lax</option>
<option value="Strict" {{ 'selected' if config.SESSION_COOKIE_SAMESITE == 'Strict' else '' }}>Strict</option>
<option value="None" {{ 'selected' if config.SESSION_COOKIE_SAMESITE == 'None' else '' }}>None</option>
</select>
<div class="form-text">控制Cookie在跨站请求中的发送</div>
</div>
<button type="submit" class="btn btn-primary" id="save-security-btn">
<i class="fas fa-save me-2"></i>
<span id="save-security-text">保存设置</span>
</button>
</form>
</div>
</div>
<div class="card shadow mb-4">
<div class="card-header">
<h6 class="mb-0">卡密设置</h6>
</div>
<div class="card-body">
<form id="license-settings-form">
<div class="mb-3">
<label for="license_key_length" class="form-label">卡密长度</label>
<input type="number" class="form-control" id="license_key_length" name="license_key_length"
value="{{ config.LICENSE_KEY_LENGTH or 32 }}" min="16" max="128">
</div>
<div class="mb-3">
<label for="license_key_prefix" class="form-label">卡密前缀</label>
<input type="text" class="form-control" id="license_key_prefix" name="license_key_prefix"
value="{{ config.LICENSE_KEY_PREFIX or '' }}" maxlength="10">
</div>
<div class="mb-3">
<label for="trial_prefix" class="form-label">试用卡密前缀</label>
<input type="text" class="form-control" id="trial_prefix" name="trial_prefix"
value="{{ config.TRIAL_PREFIX or 'TRIAL_' }}" maxlength="10">
</div>
<div class="mb-3">
<label for="offline_cache_days" class="form-label">离线缓存天数</label>
<input type="number" class="form-control" id="offline_cache_days" name="offline_cache_days"
value="{{ config.OFFLINE_CACHE_DAYS or 7 }}" min="1" max="365">
</div>
<button type="submit" class="btn btn-primary" id="save-license-btn">
<i class="fas fa-save me-2"></i>
<span id="save-license-text">保存设置</span>
</button>
</form>
</div>
</div>
<div class="card shadow mb-4">
<div class="card-header">
<h6 class="mb-0">API设置</h6>
</div>
<div class="card-body">
<form id="api-settings-form">
<div class="mb-3">
<label for="api_version" class="form-label">API版本</label>
<input type="text" class="form-control" id="api_version" name="api_version"
value="{{ config.API_VERSION or 'v1' }}">
</div>
<div class="mb-3">
<label for="items_per_page" class="form-label">每页显示条目数</label>
<input type="number" class="form-control" id="items_per_page" name="items_per_page"
value="{{ config.ITEMS_PER_PAGE or 20 }}" min="5" max="100">
</div>
<button type="submit" class="btn btn-primary" id="save-api-btn">
<i class="fas fa-save me-2"></i>
<span id="save-api-text">保存设置</span>
</button>
</form>
</div>
</div>
<div class="card shadow mb-4">
<div class="card-header">
<h6 class="mb-0">文件上传设置</h6>
</div>
<div class="card-body">
<form id="upload-settings-form">
<div class="mb-3">
<label for="max_content_length" class="form-label">最大上传文件大小 (MB)</label>
<input type="number" class="form-control" id="max_content_length" name="max_content_length"
value="{{ (config.MAX_CONTENT_LENGTH / 1024 / 1024) | int or 500 }}" min="1" max="1000">
<div class="form-text">当前设置: {{ config.MAX_CONTENT_LENGTH / 1024 / 1024 }} MB</div>
</div>
<div class="mb-3">
<label for="upload_folder" class="form-label">上传文件夹</label>
<input type="text" class="form-control" id="upload_folder" name="upload_folder"
value="{{ config.UPLOAD_FOLDER or 'static/uploads' }}">
</div>
<button type="submit" class="btn btn-primary" id="save-upload-btn">
<i class="fas fa-save me-2"></i>
<span id="save-upload-text">保存设置</span>
</button>
</form>
</div>
</div>
<div class="card shadow mb-4">
<div class="card-header">
<h6 class="mb-0">会话设置</h6>
</div>
<div class="card-body">
<form id="session-settings-form">
<div class="mb-3">
<label for="session_lifetime_hours" class="form-label">会话有效期(小时)</label>
<input type="number" class="form-control" id="session_lifetime_hours" name="session_lifetime_hours"
value="{{ (config.PERMANENT_SESSION_LIFETIME.seconds / 3600) | int or 24 }}" min="1" max="720">
<div class="form-text">当前设置: {{ config.PERMANENT_SESSION_LIFETIME.days * 24 + config.PERMANENT_SESSION_LIFETIME.seconds / 3600 }} 小时</div>
</div>
<button type="submit" class="btn btn-primary" id="save-session-btn">
<i class="fas fa-save me-2"></i>
<span id="save-session-text">保存设置</span>
</button>
</form>
</div>
</div>
<!-- 新增的记住我设置 -->
<div class="card shadow mb-4">
<div class="card-header">
<h6 class="mb-0">记住我设置</h6>
</div>
<div class="card-body">
<form id="remember-settings-form">
<div class="mb-3">
<label for="remember_cookie_duration" class="form-label">记住我持续时间(天)</label>
<input type="number" class="form-control" id="remember_cookie_duration" name="remember_cookie_duration"
value="{{ (config.REMEMBER_COOKIE_DURATION.days) | int or 30 }}" min="1" max="365">
<div class="form-text">记住我功能的持续时间</div>
</div>
<div class="mb-3">
<label for="remember_cookie_secure" class="form-label">记住我Cookie安全</label>
<select class="form-select" id="remember_cookie_secure" name="remember_cookie_secure">
<option value="True" {{ 'selected' if config.REMEMBER_COOKIE_SECURE else '' }}>启用</option>
<option value="False" {{ 'selected' if not config.REMEMBER_COOKIE_SECURE else '' }}>禁用</option>
</select>
<div class="form-text">在HTTPS环境下启用以增强安全性</div>
</div>
<div class="mb-3">
<label for="remember_cookie_httponly" class="form-label">记住我Cookie HttpOnly</label>
<select class="form-select" id="remember_cookie_httponly" name="remember_cookie_httponly">
<option value="True" {{ 'selected' if config.REMEMBER_COOKIE_HTTPONLY else '' }}>启用</option>
<option value="False" {{ 'selected' if not config.REMEMBER_COOKIE_HTTPONLY else '' }}>禁用</option>
</select>
<div class="form-text">防止客户端脚本访问Cookie</div>
</div>
<div class="mb-3">
<label for="remember_cookie_samesite" class="form-label">记住我Cookie SameSite</label>
<select class="form-select" id="remember_cookie_samesite" name="remember_cookie_samesite">
<option value="Lax" {{ 'selected' if config.REMEMBER_COOKIE_SAMESITE == 'Lax' else '' }}>Lax</option>
<option value="Strict" {{ 'selected' if config.REMEMBER_COOKIE_SAMESITE == 'Strict' else '' }}>Strict</option>
<option value="None" {{ 'selected' if config.REMEMBER_COOKIE_SAMESITE == 'None' else '' }}>None</option>
</select>
<div class="form-text">控制Cookie在跨站请求中的发送</div>
</div>
<button type="submit" class="btn btn-primary" id="save-remember-btn">
<i class="fas fa-save me-2"></i>
<span id="save-remember-text">保存设置</span>
</button>
</form>
</div>
</div>
<!-- 新增的日志配置 -->
<div class="card shadow mb-4">
<div class="card-header">
<h6 class="mb-0">日志配置</h6>
</div>
<div class="card-body">
<form id="log-settings-form">
<div class="mb-3">
<label for="log_level" class="form-label">日志级别</label>
<select class="form-select" id="log_level" name="log_level">
<option value="DEBUG" {{ 'selected' if config.LOG_LEVEL == 'DEBUG' else '' }}>DEBUG</option>
<option value="INFO" {{ 'selected' if config.LOG_LEVEL == 'INFO' else '' }}>INFO</option>
<option value="WARNING" {{ 'selected' if config.LOG_LEVEL == 'WARNING' else '' }}>WARNING</option>
<option value="ERROR" {{ 'selected' if config.LOG_LEVEL == 'ERROR' else '' }}>ERROR</option>
<option value="CRITICAL" {{ 'selected' if config.LOG_LEVEL == 'CRITICAL' else '' }}>CRITICAL</option>
</select>
<div class="form-text">设置日志记录的详细程度</div>
</div>
<button type="submit" class="btn btn-primary" id="save-log-btn">
<i class="fas fa-save me-2"></i>
<span id="save-log-text">保存设置</span>
</button>
</form>
</div>
</div>
</div>
<div class="col-lg-4">
<div class="card shadow mb-4">
<div class="card-header">
<h6 class="mb-0">系统信息</h6>
</div>
<div class="card-body">
<dl class="row">
<dt class="col-sm-6">系统版本:</dt>
<dd class="col-sm-6">{{ system_version or 'v1.0.0' }}</dd>
<dt class="col-sm-6">Python版本:</dt>
<dd class="col-sm-6">{{ python_version or 'Unknown' }}</dd>
<dt class="col-sm-6">Flask版本:</dt>
<dd class="col-sm-6">{{ flask_version or 'Unknown' }}</dd>
<dt class="col-sm-6">数据库:</dt>
<dd class="col-sm-6">{{ database_type or 'Unknown' }}</dd>
<dt class="col-sm-6">运行时间:</dt>
<dd class="col-sm-6">{{ uptime or 'Unknown' }}</dd>
<dt class="col-sm-6">API版本:</dt>
<dd class="col-sm-6">{{ config.API_VERSION or 'v1' }}</dd>
<dt class="col-sm-6">上传限制:</dt>
<dd class="col-sm-6">{{ config.MAX_CONTENT_LENGTH / 1024 / 1024 }} MB</dd>
</dl>
</div>
</div>
<div class="card shadow">
<div class="card-header">
<h6 class="mb-0">操作</h6>
</div>
<div class="card-body">
<div class="d-grid gap-2">
<button type="button" class="btn btn-outline-primary" data-bs-toggle="modal" data-bs-target="#backupModal">
<i class="fas fa-database me-2"></i>
数据备份
</button>
<button type="button" class="btn btn-outline-warning" data-bs-toggle="modal" data-bs-target="#clearCacheModal">
<i class="fas fa-broom me-2"></i>
清理缓存
</button>
<button type="button" class="btn btn-outline-danger" data-bs-toggle="modal" data-bs-target="#resetModal">
<i class="fas fa-exclamation-triangle me-2"></i>
重置系统
</button>
</div>
</div>
</div>
</div>
</div>
<!-- 数据备份模态框 -->
<div class="modal fade" id="backupModal" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">数据备份</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body">
<p>确定要创建数据备份吗?</p>
<div class="form-check">
<input class="form-check-input" type="checkbox" id="include_logs" checked>
<label class="form-check-label" for="include_logs">
包含日志文件
</label>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">取消</button>
<button type="button" class="btn btn-primary" id="backup-btn">开始备份</button>
</div>
</div>
</div>
</div>
<!-- 清理缓存模态框 -->
<div class="modal fade" id="clearCacheModal" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">清理缓存</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body">
<p>确定要清理系统缓存吗?这将清除所有临时文件和缓存数据。</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">取消</button>
<button type="button" class="btn btn-warning" id="clear-cache-btn">确认清理</button>
</div>
</div>
</div>
</div>
<!-- 重置系统模态框 -->
<div class="modal fade" id="resetModal" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">重置系统</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body">
<div class="alert alert-danger">
<strong>警告!</strong> 此操作将删除所有数据并重置系统到初始状态,无法恢复。
</div>
<p>请输入"RESET"确认操作:</p>
<input type="text" class="form-control" id="reset-confirm" placeholder="输入RESET确认">
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">取消</button>
<button type="button" class="btn btn-danger" id="reset-btn" disabled>确认重置</button>
</div>
</div>
</div>
</div>
{% endblock %}
{% block extra_js %}
<script>
// 页面加载完成后初始化
document.addEventListener('DOMContentLoaded', function() {
initEventListeners();
});
// 初始化事件监听器
function initEventListeners() {
// 基本设置表单
document.getElementById('basic-settings-form').addEventListener('submit', function(e) {
e.preventDefault();
saveBasicSettings();
});
// 安全设置表单
document.getElementById('security-settings-form').addEventListener('submit', function(e) {
e.preventDefault();
saveSecuritySettings();
});
// 生成密钥按钮
document.getElementById('generate-secret-key').addEventListener('click', function() {
generateSecretKey();
});
// 卡密设置表单
document.getElementById('license-settings-form').addEventListener('submit', function(e) {
e.preventDefault();
saveLicenseSettings();
});
// API设置表单
document.getElementById('api-settings-form').addEventListener('submit', function(e) {
e.preventDefault();
saveApiSettings();
});
// 文件上传设置表单
document.getElementById('upload-settings-form').addEventListener('submit', function(e) {
e.preventDefault();
saveUploadSettings();
});
// 会话设置表单
document.getElementById('session-settings-form').addEventListener('submit', function(e) {
e.preventDefault();
saveSessionSettings();
});
// 记住我设置表单
document.getElementById('remember-settings-form').addEventListener('submit', function(e) {
e.preventDefault();
saveRememberSettings();
});
// 日志设置表单
document.getElementById('log-settings-form').addEventListener('submit', function(e) {
e.preventDefault();
saveLogSettings();
});
// 重置确认输入
document.getElementById('reset-confirm').addEventListener('input', function() {
const resetBtn = document.getElementById('reset-btn');
resetBtn.disabled = this.value !== 'RESET';
});
// 重置按钮
document.getElementById('reset-btn').addEventListener('click', function() {
resetSystem();
});
// 清理缓存按钮
document.getElementById('clear-cache-btn').addEventListener('click', function() {
clearCache();
});
// 备份按钮
document.getElementById('backup-btn').addEventListener('click', function() {
backupData();
});
}
// 生成安全密钥
function generateSecretKey() {
// 生成一个随机的32字符密钥
const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*()_+-=[]{}|;:,.<>?';
let key = '';
for (let i = 0; i < 32; i++) {
key += chars.charAt(Math.floor(Math.random() * chars.length));
}
document.getElementById('secret_key').value = key;
}
// 保存基本设置
function saveBasicSettings() {
const saveBtn = document.getElementById('save-basic-btn');
const saveText = document.getElementById('save-basic-text');
// 显示加载状态
saveBtn.disabled = true;
saveText.textContent = '保存中...';
// 收集表单数据
const formData = {
site_name: document.getElementById('site_name').value,
admin_email: document.getElementById('admin_email').value,
frontend_domain: document.getElementById('frontend_domain').value,
max_failed_attempts: parseInt(document.getElementById('max_failed_attempts').value),
lockout_minutes: parseInt(document.getElementById('lockout_minutes').value),
max_unbind_times: parseInt(document.getElementById('max_unbind_times').value),
auth_secret_key: document.getElementById('auth_secret_key').value
};
// 发送请求保存设置
const saveUrl = '/api/v1/settings';
apiRequest(saveUrl, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(formData)
})
.then(response => response.json())
.then(data => {
if (data.success) {
showNotification('基本设置保存成功', 'success');
// 更新页面标题(如果修改了系统名称)
if (formData.site_name) {
document.title = formData.site_name + ' - 软件授权管理系统';
// 更新页面标题元素
const pageTitle = document.querySelector('h1.h2');
if (pageTitle) {
pageTitle.textContent = formData.site_name;
}
}
} else {
showNotification('保存失败: ' + data.message, 'error');
}
})
.catch(error => {
console.error('Error:', error);
showNotification('保存失败,请查看控制台了解详情', 'error');
})
.finally(() => {
saveBtn.disabled = false;
saveText.textContent = '保存设置';
});
}
// 保存安全设置
function saveSecuritySettings() {
const saveBtn = document.getElementById('save-security-btn');
const saveText = document.getElementById('save-security-text');
// 显示加载状态
saveBtn.disabled = true;
saveText.textContent = '保存中...';
// 收集表单数据
const formData = {
secret_key: document.getElementById('secret_key').value,
session_cookie_secure: document.getElementById('session_cookie_secure').value === 'True',
session_cookie_httponly: document.getElementById('session_cookie_httponly').value === 'True',
session_cookie_samesite: document.getElementById('session_cookie_samesite').value
};
// 如果密钥为空,则不发送
if (!formData.secret_key) {
delete formData.secret_key;
}
// 发送请求保存设置
apiRequest('/api/v1/settings', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(formData)
})
.then(response => response.json())
.then(data => {
if (data.success) {
showNotification('安全设置保存成功', 'success');
// 清空密钥输入框
document.getElementById('secret_key').value = '';
} else {
showNotification('保存失败: ' + data.message, 'error');
}
})
.catch(error => {
console.error('Error:', error);
showNotification('保存失败,请查看控制台了解详情', 'error');
})
.finally(() => {
saveBtn.disabled = false;
saveText.textContent = '保存设置';
});
}
// 保存卡密设置
function saveLicenseSettings() {
const saveBtn = document.getElementById('save-license-btn');
const saveText = document.getElementById('save-license-text');
// 显示加载状态
saveBtn.disabled = true;
saveText.textContent = '保存中...';
// 收集表单数据
const formData = {
license_key_length: parseInt(document.getElementById('license_key_length').value),
license_key_prefix: document.getElementById('license_key_prefix').value,
trial_prefix: document.getElementById('trial_prefix').value,
offline_cache_days: parseInt(document.getElementById('offline_cache_days').value)
};
// 发送请求保存设置
apiRequest('/api/v1/settings', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(formData)
})
.then(response => response.json())
.then(data => {
if (data.success) {
showNotification('卡密设置保存成功', 'success');
} else {
showNotification('保存失败: ' + data.message, 'error');
}
})
.catch(error => {
console.error('Error:', error);
showNotification('保存失败,请查看控制台了解详情', 'error');
})
.finally(() => {
saveBtn.disabled = false;
saveText.textContent = '保存设置';
});
}
// 保存API设置
function saveApiSettings() {
const saveBtn = document.getElementById('save-api-btn');
const saveText = document.getElementById('save-api-text');
// 显示加载状态
saveBtn.disabled = true;
saveText.textContent = '保存中...';
// 收集表单数据
const formData = {
api_version: document.getElementById('api_version').value,
items_per_page: parseInt(document.getElementById('items_per_page').value)
};
// 发送请求保存设置
apiRequest('/api/v1/settings', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(formData)
})
.then(response => response.json())
.then(data => {
if (data.success) {
showNotification('API设置保存成功', 'success');
} else {
showNotification('保存失败: ' + data.message, 'error');
}
})
.catch(error => {
console.error('Error:', error);
showNotification('保存失败,请查看控制台了解详情', 'error');
})
.finally(() => {
saveBtn.disabled = false;
saveText.textContent = '保存设置';
});
}
// 保存文件上传设置
function saveUploadSettings() {
const saveBtn = document.getElementById('save-upload-btn');
const saveText = document.getElementById('save-upload-text');
// 显示加载状态
saveBtn.disabled = true;
saveText.textContent = '保存中...';
// 收集表单数据
const formData = {
max_content_length: parseInt(document.getElementById('max_content_length').value),
upload_folder: document.getElementById('upload_folder').value
};
// 发送请求保存设置
const saveUrl = '/api/v1/settings';
apiRequest(saveUrl, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(formData)
})
.then(response => response.json())
.then(data => {
if (data.success) {
showNotification('文件上传设置保存成功', 'success');
// 更新显示的上传限制信息
const maxContentLength = formData.max_content_length;
const uploadInfoElements = document.querySelectorAll('div.form-text');
uploadInfoElements.forEach(element => {
if (element.textContent.includes('当前设置:')) {
element.textContent = `当前设置: ${maxContentLength} MB`;
}
});
} else {
showNotification('保存失败: ' + data.message, 'error');
}
})
.catch(error => {
console.error('Error:', error);
showNotification('保存失败,请查看控制台了解详情', 'error');
})
.finally(() => {
saveBtn.disabled = false;
saveText.textContent = '保存设置';
});
}
// 保存会话设置
function saveSessionSettings() {
const saveBtn = document.getElementById('save-session-btn');
const saveText = document.getElementById('save-session-text');
// 显示加载状态
saveBtn.disabled = true;
saveText.textContent = '保存中...';
// 收集表单数据
const formData = {
session_lifetime_hours: parseInt(document.getElementById('session_lifetime_hours').value)
};
// 发送请求保存设置
const saveUrl = '/api/v1/settings';
apiRequest(saveUrl, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(formData)
})
.then(response => response.json())
.then(data => {
if (data.success) {
showNotification('会话设置保存成功', 'success');
// 更新显示的会话时间信息
const sessionHours = formData.session_lifetime_hours;
const sessionInfoElements = document.querySelectorAll('div.form-text');
sessionInfoElements.forEach(element => {
if (element.textContent.includes('当前设置:')) {
element.textContent = `当前设置: ${sessionHours} 小时`;
}
});
} else {
showNotification('保存失败: ' + data.message, 'error');
}
})
.catch(error => {
console.error('Error:', error);
showNotification('保存失败,请查看控制台了解详情', 'error');
})
.finally(() => {
saveBtn.disabled = false;
saveText.textContent = '保存设置';
});
}
// 保存记住我设置
function saveRememberSettings() {
const saveBtn = document.getElementById('save-remember-btn');
const saveText = document.getElementById('save-remember-text');
// 显示加载状态
saveBtn.disabled = true;
saveText.textContent = '保存中...';
// 收集表单数据
const formData = {
remember_cookie_duration: parseInt(document.getElementById('remember_cookie_duration').value),
remember_cookie_secure: document.getElementById('remember_cookie_secure').value === 'True',
remember_cookie_httponly: document.getElementById('remember_cookie_httponly').value === 'True',
remember_cookie_samesite: document.getElementById('remember_cookie_samesite').value
};
// 发送请求保存设置
const saveUrl = '/api/v1/settings';
apiRequest(saveUrl, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(formData)
})
.then(response => response.json())
.then(data => {
if (data.success) {
showNotification('记住我设置保存成功', 'success');
} else {
showNotification('保存失败: ' + data.message, 'error');
}
})
.catch(error => {
console.error('Error:', error);
showNotification('保存失败,请查看控制台了解详情', 'error');
})
.finally(() => {
saveBtn.disabled = false;
saveText.textContent = '保存设置';
});
}
// 保存日志设置
function saveLogSettings() {
const saveBtn = document.getElementById('save-log-btn');
const saveText = document.getElementById('save-log-text');
// 显示加载状态
saveBtn.disabled = true;
saveText.textContent = '保存中...';
// 收集表单数据
const formData = {
log_level: document.getElementById('log_level').value
};
// 发送请求保存设置
const saveUrl = '/api/v1/settings';
apiRequest(saveUrl, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(formData)
})
.then(response => response.json())
.then(data => {
if (data.success) {
showNotification('日志设置保存成功', 'success');
} else {
showNotification('保存失败: ' + data.message, 'error');
}
})
.catch(error => {
console.error('Error:', error);
showNotification('保存失败,请查看控制台了解详情', 'error');
})
.finally(() => {
saveBtn.disabled = false;
saveText.textContent = '保存设置';
});
}
// 重置系统
function resetSystem() {
if (confirm('确定要重置系统吗?此操作无法恢复!')) {
showNotification('系统重置功能开发中...', 'info');
// 关闭模态框
const modal = bootstrap.Modal.getInstance(document.getElementById('resetModal'));
modal.hide();
}
}
// 清理缓存
function clearCache() {
showNotification('正在清理缓存...', 'info');
// 关闭模态框
const modal = bootstrap.Modal.getInstance(document.getElementById('clearCacheModal'));
modal.hide();
// 模拟清理过程
setTimeout(() => {
showNotification('缓存清理完成', 'success');
}, 2000);
}
// 数据备份
function backupData() {
showNotification('正在创建数据备份...', 'info');
// 关闭模态框
const modal = bootstrap.Modal.getInstance(document.getElementById('backupModal'));
modal.hide();
// 模拟备份过程
setTimeout(() => {
showNotification('数据备份创建成功', 'success');
}, 3000);
}
</script>
{% endblock %}