428 lines
17 KiB
Vue
428 lines
17 KiB
Vue
<template>
|
||
<div class="space-y-6">
|
||
<!-- 页面标题 -->
|
||
<div>
|
||
<h1 class="text-2xl font-bold text-gray-900">系统设置</h1>
|
||
<p class="text-gray-600 mt-1">配置系统参数和功能选项</p>
|
||
</div>
|
||
|
||
<!-- 设置选项卡 -->
|
||
<div class="bg-white rounded-lg shadow-sm border border-gray-200">
|
||
<nav class="flex border-b border-gray-200">
|
||
<button
|
||
v-for="tab in tabs"
|
||
:key="tab.key"
|
||
@click="activeTab = tab.key"
|
||
:class="[
|
||
'px-6 py-4 text-sm font-medium border-b-2 transition-colors',
|
||
activeTab === tab.key
|
||
? 'border-blue-500 text-blue-600'
|
||
: 'border-transparent text-gray-500 hover:text-gray-700 hover:border-gray-300'
|
||
]"
|
||
>
|
||
{{ tab.name }}
|
||
</button>
|
||
</nav>
|
||
|
||
<div class="p-6">
|
||
<!-- 基础设置 -->
|
||
<div v-if="activeTab === 'basic'" class="space-y-6">
|
||
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
|
||
<div>
|
||
<label class="block text-sm font-medium text-gray-700 mb-2">网站名称</label>
|
||
<input
|
||
v-model="settings.siteName"
|
||
type="text"
|
||
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent"
|
||
/>
|
||
</div>
|
||
<div>
|
||
<label class="block text-sm font-medium text-gray-700 mb-2">网站标语</label>
|
||
<input
|
||
v-model="settings.siteSlogan"
|
||
type="text"
|
||
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent"
|
||
/>
|
||
</div>
|
||
<div class="md:col-span-2">
|
||
<label class="block text-sm font-medium text-gray-700 mb-2">网站描述</label>
|
||
<textarea
|
||
v-model="settings.siteDescription"
|
||
rows="3"
|
||
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent"
|
||
></textarea>
|
||
</div>
|
||
<div>
|
||
<label class="block text-sm font-medium text-gray-700 mb-2">联系邮箱</label>
|
||
<input
|
||
v-model="settings.contactEmail"
|
||
type="email"
|
||
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent"
|
||
/>
|
||
</div>
|
||
<div>
|
||
<label class="block text-sm font-medium text-gray-700 mb-2">备案号</label>
|
||
<input
|
||
v-model="settings.icp"
|
||
type="text"
|
||
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent"
|
||
/>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 安全设置 -->
|
||
<div v-if="activeTab === 'security'" class="space-y-6">
|
||
<div class="space-y-4">
|
||
<div class="flex items-center justify-between p-4 bg-gray-50 rounded-lg">
|
||
<div>
|
||
<h4 class="text-sm font-medium text-gray-900">启用两步验证</h4>
|
||
<p class="text-sm text-gray-500">为管理员账户启用两步验证以提高安全性</p>
|
||
</div>
|
||
<label class="relative inline-flex items-center cursor-pointer">
|
||
<input
|
||
v-model="settings.twoFactorAuth"
|
||
type="checkbox"
|
||
class="sr-only peer"
|
||
/>
|
||
<div class="w-11 h-6 bg-gray-200 peer-focus:outline-none peer-focus:ring-4 peer-focus:ring-blue-300 rounded-full peer peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-[2px] after:left-[2px] after:bg-white after:border-gray-300 after:border after:rounded-full after:h-5 after:w-5 after:transition-all peer-checked:bg-blue-600"></div>
|
||
</label>
|
||
</div>
|
||
|
||
<div class="flex items-center justify-between p-4 bg-gray-50 rounded-lg">
|
||
<div>
|
||
<h4 class="text-sm font-medium text-gray-900">登录验证码</h4>
|
||
<p class="text-sm text-gray-500">登录时需要输入图形验证码</p>
|
||
</div>
|
||
<label class="relative inline-flex items-center cursor-pointer">
|
||
<input
|
||
v-model="settings.loginCaptcha"
|
||
type="checkbox"
|
||
class="sr-only peer"
|
||
/>
|
||
<div class="w-11 h-6 bg-gray-200 peer-focus:outline-none peer-focus:ring-4 peer-focus:ring-blue-300 rounded-full peer peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-[2px] after:left-[2px] after:bg-white after:border-gray-300 after:border after:rounded-full after:h-5 after:w-5 after:transition-all peer-checked:bg-blue-600"></div>
|
||
</label>
|
||
</div>
|
||
|
||
<div>
|
||
<label class="block text-sm font-medium text-gray-700 mb-2">密码最小长度</label>
|
||
<select
|
||
v-model="settings.minPasswordLength"
|
||
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent"
|
||
>
|
||
<option value="6">6位</option>
|
||
<option value="8">8位</option>
|
||
<option value="10">10位</option>
|
||
<option value="12">12位</option>
|
||
</select>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 邮件设置 -->
|
||
<div v-if="activeTab === 'email'" class="space-y-6">
|
||
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
|
||
<div>
|
||
<label class="block text-sm font-medium text-gray-700 mb-2">SMTP服务器</label>
|
||
<input
|
||
v-model="settings.smtpHost"
|
||
type="text"
|
||
placeholder="smtp.example.com"
|
||
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent"
|
||
/>
|
||
</div>
|
||
<div>
|
||
<label class="block text-sm font-medium text-gray-700 mb-2">SMTP端口</label>
|
||
<input
|
||
v-model="settings.smtpPort"
|
||
type="number"
|
||
placeholder="587"
|
||
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent"
|
||
/>
|
||
</div>
|
||
<div>
|
||
<label class="block text-sm font-medium text-gray-700 mb-2">发件人邮箱</label>
|
||
<input
|
||
v-model="settings.fromEmail"
|
||
type="email"
|
||
placeholder="noreply@example.com"
|
||
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent"
|
||
/>
|
||
</div>
|
||
<div>
|
||
<label class="block text-sm font-medium text-gray-700 mb-2">发件人名称</label>
|
||
<input
|
||
v-model="settings.fromName"
|
||
type="text"
|
||
placeholder="系统管理员"
|
||
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent"
|
||
/>
|
||
</div>
|
||
<div>
|
||
<label class="block text-sm font-medium text-gray-700 mb-2">用户名</label>
|
||
<input
|
||
v-model="settings.smtpUsername"
|
||
type="text"
|
||
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent"
|
||
/>
|
||
</div>
|
||
<div>
|
||
<label class="block text-sm font-medium text-gray-700 mb-2">密码</label>
|
||
<input
|
||
v-model="settings.smtpPassword"
|
||
type="password"
|
||
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent"
|
||
/>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 存储设置 -->
|
||
<div v-if="activeTab === 'storage'" class="space-y-6">
|
||
<div>
|
||
<label class="block text-sm font-medium text-gray-700 mb-2">存储类型</label>
|
||
<select
|
||
v-model="settings.storageType"
|
||
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent"
|
||
>
|
||
<option value="local">本地存储</option>
|
||
<option value="oss">阿里云OSS</option>
|
||
<option value="cos">腾讯云COS</option>
|
||
<option value="qiniu">七牛云</option>
|
||
</select>
|
||
</div>
|
||
|
||
<div v-if="settings.storageType !== 'local'" class="grid grid-cols-1 md:grid-cols-2 gap-6">
|
||
<div>
|
||
<label class="block text-sm font-medium text-gray-700 mb-2">Access Key</label>
|
||
<input
|
||
v-model="settings.accessKey"
|
||
type="text"
|
||
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent"
|
||
/>
|
||
</div>
|
||
<div>
|
||
<label class="block text-sm font-medium text-gray-700 mb-2">Secret Key</label>
|
||
<input
|
||
v-model="settings.secretKey"
|
||
type="password"
|
||
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent"
|
||
/>
|
||
</div>
|
||
<div>
|
||
<label class="block text-sm font-medium text-gray-700 mb-2">存储桶名称</label>
|
||
<input
|
||
v-model="settings.bucket"
|
||
type="text"
|
||
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent"
|
||
/>
|
||
</div>
|
||
<div>
|
||
<label class="block text-sm font-medium text-gray-700 mb-2">访问域名</label>
|
||
<input
|
||
v-model="settings.domain"
|
||
type="text"
|
||
placeholder="https://example.com"
|
||
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent"
|
||
/>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
|
||
<div>
|
||
<label class="block text-sm font-medium text-gray-700 mb-2">最大文件大小(MB)</label>
|
||
<input
|
||
v-model="settings.maxFileSize"
|
||
type="number"
|
||
min="1"
|
||
max="100"
|
||
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent"
|
||
/>
|
||
</div>
|
||
<div>
|
||
<label class="block text-sm font-medium text-gray-700 mb-2">允许的文件类型</label>
|
||
<div class="grid grid-cols-2 md:grid-cols-4 gap-4 mt-2">
|
||
<label v-for="type in fileTypes" :key="type.value" class="flex items-center">
|
||
<input
|
||
v-model="settings.allowedFileTypes"
|
||
:value="type.value"
|
||
type="checkbox"
|
||
class="h-4 w-4 text-blue-600 focus:ring-blue-500 border-gray-300 rounded"
|
||
/>
|
||
<span class="ml-2 text-sm text-gray-700">{{ type.label }}</span>
|
||
</label>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 系统信息 -->
|
||
<div v-if="activeTab === 'system'" class="space-y-6">
|
||
<div class="grid grid-cols-1 md:grid-cols-3 gap-6">
|
||
<div class="bg-gray-50 p-4 rounded-lg">
|
||
<h4 class="text-sm font-medium text-gray-900 mb-2">系统版本</h4>
|
||
<p class="text-lg font-semibold text-blue-600">v1.0.0</p>
|
||
</div>
|
||
<div class="bg-gray-50 p-4 rounded-lg">
|
||
<h4 class="text-sm font-medium text-gray-900 mb-2">数据库大小</h4>
|
||
<p class="text-lg font-semibold text-purple-600">45.2 MB</p>
|
||
</div>
|
||
<div class="bg-gray-50 p-4 rounded-lg">
|
||
<h4 class="text-sm font-medium text-gray-900 mb-2">存储空间</h4>
|
||
<p class="text-lg font-semibold text-green-600">2.1 GB</p>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="bg-yellow-50 border border-yellow-200 rounded-lg p-4">
|
||
<div class="flex">
|
||
<div class="flex-shrink-0">
|
||
<WarningIcon class="h-5 w-5 text-yellow-400" />
|
||
</div>
|
||
<div class="ml-3">
|
||
<h3 class="text-sm font-medium text-yellow-800">系统维护建议</h3>
|
||
<div class="mt-2 text-sm text-yellow-700">
|
||
<p>建议定期清理系统缓存和日志文件以保持系统性能。</p>
|
||
</div>
|
||
<div class="mt-4 flex space-x-3">
|
||
<button
|
||
@click="clearCache"
|
||
class="bg-yellow-100 hover:bg-yellow-200 text-yellow-800 px-3 py-1 rounded text-sm"
|
||
>
|
||
清理缓存
|
||
</button>
|
||
<button
|
||
@click="clearLogs"
|
||
class="bg-yellow-100 hover:bg-yellow-200 text-yellow-800 px-3 py-1 rounded text-sm"
|
||
>
|
||
清理日志
|
||
</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 保存按钮 -->
|
||
<div class="flex justify-end pt-6 border-t border-gray-200">
|
||
<button
|
||
@click="saveSettings"
|
||
class="bg-blue-600 hover:bg-blue-700 text-white px-6 py-2 rounded-lg"
|
||
>
|
||
保存设置
|
||
</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</template>
|
||
|
||
<script setup>
|
||
import { ref } from 'vue'
|
||
|
||
// 图标组件
|
||
const WarningIcon = {
|
||
template: `<svg fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-2.5L13.732 4c-.77-.833-1.964-.833-2.732 0L4.082 16.5c-.77.833.192 2.5 1.732 2.5z"></path></svg>`
|
||
}
|
||
|
||
// 响应式数据
|
||
const activeTab = ref('basic')
|
||
|
||
const tabs = [
|
||
{ key: 'basic', name: '基础设置' },
|
||
{ key: 'security', name: '安全设置' },
|
||
{ key: 'email', name: '邮件设置' },
|
||
{ key: 'storage', name: '存储设置' },
|
||
{ key: 'system', name: '系统信息' }
|
||
]
|
||
|
||
const settings = ref({
|
||
// 基础设置
|
||
siteName: 'CMS管理系统',
|
||
siteSlogan: '高效、安全、易用的内容管理系统',
|
||
siteDescription: '这是一个基于Vue3和TailwindCSS构建的现代化内容管理系统,提供完整的文章管理、用户管理和系统配置功能。',
|
||
contactEmail: 'admin@example.com',
|
||
icp: '京ICP备12345678号',
|
||
|
||
// 安全设置
|
||
twoFactorAuth: false,
|
||
loginCaptcha: true,
|
||
minPasswordLength: '8',
|
||
|
||
// 邮件设置
|
||
smtpHost: '',
|
||
smtpPort: 587,
|
||
fromEmail: 'noreply@example.com',
|
||
fromName: '系统管理员',
|
||
smtpUsername: '',
|
||
smtpPassword: '',
|
||
|
||
// 存储设置
|
||
storageType: 'local',
|
||
accessKey: '',
|
||
secretKey: '',
|
||
bucket: '',
|
||
domain: '',
|
||
maxFileSize: 10,
|
||
allowedFileTypes: ['jpg', 'png', 'gif', 'pdf', 'doc']
|
||
})
|
||
|
||
const fileTypes = [
|
||
{ value: 'jpg', label: 'JPG图片' },
|
||
{ value: 'png', label: 'PNG图片' },
|
||
{ value: 'gif', label: 'GIF图片' },
|
||
{ value: 'pdf', label: 'PDF文档' },
|
||
{ value: 'doc', label: 'Word文档' },
|
||
{ value: 'xls', label: 'Excel表格' },
|
||
{ value: 'zip', label: 'ZIP压缩包' },
|
||
{ value: 'mp4', label: 'MP4视频' }
|
||
]
|
||
|
||
// 保存设置
|
||
const saveSettings = () => {
|
||
console.log('保存设置:', settings.value)
|
||
// 这里应该调用API保存设置
|
||
alert('设置保存成功!')
|
||
}
|
||
|
||
// 清理缓存
|
||
const clearCache = () => {
|
||
if (confirm('确定要清理系统缓存吗?')) {
|
||
console.log('清理缓存')
|
||
// 这里应该调用API清理缓存
|
||
alert('缓存清理完成!')
|
||
}
|
||
}
|
||
|
||
// 清理日志
|
||
const clearLogs = () => {
|
||
if (confirm('确定要清理系统日志吗?此操作不可恢复!')) {
|
||
console.log('清理日志')
|
||
// 这里应该调用API清理日志
|
||
alert('日志清理完成!')
|
||
}
|
||
}
|
||
</script>
|
||
|
||
<style lang='scss' scoped>
|
||
/* 开关样式 */
|
||
.peer:checked ~ .peer-checked\:bg-blue-600 {
|
||
background-color: #2563eb;
|
||
}
|
||
|
||
/* 响应式优化 */
|
||
@media (max-width: 1024px) {
|
||
.grid-cols-1.md\:grid-cols-2 {
|
||
grid-template-columns: 1fr;
|
||
}
|
||
|
||
.grid-cols-1.md\:grid-cols-3 {
|
||
grid-template-columns: 1fr;
|
||
}
|
||
}
|
||
|
||
/* 标签页导航样式 */
|
||
nav ul li button {
|
||
transition: all 0.2s ease-in-out;
|
||
}
|
||
</style>
|