Skip to content

Latest commit

 

History

History
1022 lines (913 loc) · 30.2 KB

File metadata and controls

1022 lines (913 loc) · 30.2 KB

sys/setting.vue 系统设置页面文档

概述

sys/setting.vue是系统设置页面组件,提供系统参数配置、基础设置、安全配置等功能,支持多种配置类型和实时保存。

文件位置: src/views/sys/setting.vue

页面功能

1. 系统设置功能

  • 基础信息设置
  • 系统参数配置
  • 安全策略设置
  • 邮件配置
  • 短信配置
  • 文件上传设置
  • 缓存配置
  • 日志配置

2. 页面结构

<template>
  <div class="setting-container">
    <!-- 页面头部 -->
    <div class="page-header">
      <div class="header-title">
        <h2>系统设置</h2>
        <p>配置系统运行参数和基础设置</p>
      </div>
      <div class="header-actions">
        <el-button type="primary" @click="saveAllSettings" :loading="saveLoading">
          <el-icon><Check /></el-icon>
          保存所有设置
        </el-button>
        <el-button @click="resetSettings">
          <el-icon><Refresh /></el-icon>
          重置设置
        </el-button>
      </div>
    </div>
    
    <!-- 设置标签页 -->
    <el-tabs v-model="activeTab" type="card" class="setting-tabs">
      <!-- 基础设置 -->
      <el-tab-pane label="基础设置" name="basic">
        <div class="setting-panel">
          <el-form
            ref="basicFormRef"
            :model="basicSettings"
            :rules="basicRules"
            label-width="120px"
          >
            <el-card header="网站信息">
              <el-form-item label="网站名称" prop="siteName">
                <el-input
                  v-model="basicSettings.siteName"
                  placeholder="请输入网站名称"
                  maxlength="50"
                  show-word-limit
                />
              </el-form-item>
              
              <el-form-item label="网站标题" prop="siteTitle">
                <el-input
                  v-model="basicSettings.siteTitle"
                  placeholder="请输入网站标题"
                  maxlength="100"
                  show-word-limit
                />
              </el-form-item>
              
              <el-form-item label="网站描述" prop="siteDescription">
                <el-input
                  v-model="basicSettings.siteDescription"
                  type="textarea"
                  :rows="3"
                  placeholder="请输入网站描述"
                  maxlength="200"
                  show-word-limit
                />
              </el-form-item>
              
              <el-form-item label="网站关键词" prop="siteKeywords">
                <el-input
                  v-model="basicSettings.siteKeywords"
                  placeholder="请输入网站关键词,用逗号分隔"
                  maxlength="100"
                  show-word-limit
                />
              </el-form-item>
              
              <el-form-item label="网站Logo" prop="siteLogo">
                <el-upload
                  class="logo-uploader"
                  :action="uploadUrl"
                  :headers="uploadHeaders"
                  :show-file-list="false"
                  :on-success="handleLogoSuccess"
                  :before-upload="beforeLogoUpload"
                >
                  <img v-if="basicSettings.siteLogo" :src="basicSettings.siteLogo" class="logo" />
                  <el-icon v-else class="logo-uploader-icon"><Plus /></el-icon>
                </el-upload>
              </el-form-item>
              
              <el-form-item label="网站图标" prop="siteFavicon">
                <el-upload
                  class="favicon-uploader"
                  :action="uploadUrl"
                  :headers="uploadHeaders"
                  :show-file-list="false"
                  :on-success="handleFaviconSuccess"
                  :before-upload="beforeFaviconUpload"
                >
                  <img v-if="basicSettings.siteFavicon" :src="basicSettings.siteFavicon" class="favicon" />
                  <el-icon v-else class="favicon-uploader-icon"><Plus /></el-icon>
                </el-upload>
              </el-form-item>
            </el-card>
            
            <el-card header="联系信息" style="margin-top: 20px;">
              <el-form-item label="联系电话" prop="contactPhone">
                <el-input
                  v-model="basicSettings.contactPhone"
                  placeholder="请输入联系电话"
                />
              </el-form-item>
              
              <el-form-item label="联系邮箱" prop="contactEmail">
                <el-input
                  v-model="basicSettings.contactEmail"
                  placeholder="请输入联系邮箱"
                />
              </el-form-item>
              
              <el-form-item label="联系地址" prop="contactAddress">
                <el-input
                  v-model="basicSettings.contactAddress"
                  placeholder="请输入联系地址"
                />
              </el-form-item>
              
              <el-form-item label="版权信息" prop="copyright">
                <el-input
                  v-model="basicSettings.copyright"
                  placeholder="请输入版权信息"
                />
              </el-form-item>
            </el-card>
          </el-form>
        </div>
      </el-tab-pane>
      
      <!-- 系统参数 -->
      <el-tab-pane label="系统参数" name="system">
        <div class="setting-panel">
          <el-form
            ref="systemFormRef"
            :model="systemSettings"
            :rules="systemRules"
            label-width="120px"
          >
            <el-card header="系统配置">
              <el-form-item label="系统版本" prop="version">
                <el-input
                  v-model="systemSettings.version"
                  placeholder="请输入系统版本"
                  readonly
                />
              </el-form-item>
              
              <el-form-item label="时区设置" prop="timezone">
                <el-select
                  v-model="systemSettings.timezone"
                  placeholder="请选择时区"
                  style="width: 100%;"
                >
                  <el-option label="北京时间 (UTC+8)" value="Asia/Shanghai" />
                  <el-option label="东京时间 (UTC+9)" value="Asia/Tokyo" />
                  <el-option label="纽约时间 (UTC-5)" value="America/New_York" />
                  <el-option label="伦敦时间 (UTC+0)" value="Europe/London" />
                </el-select>
              </el-form-item>
              
              <el-form-item label="默认语言" prop="defaultLanguage">
                <el-select
                  v-model="systemSettings.defaultLanguage"
                  placeholder="请选择默认语言"
                  style="width: 100%;"
                >
                  <el-option label="简体中文" value="zh-CN" />
                  <el-option label="繁体中文" value="zh-TW" />
                  <el-option label="English" value="en-US" />
                  <el-option label="日本語" value="ja-JP" />
                </el-select>
              </el-form-item>
              
              <el-form-item label="分页大小" prop="pageSize">
                <el-input-number
                  v-model="systemSettings.pageSize"
                  :min="10"
                  :max="100"
                  :step="10"
                  placeholder="默认分页大小"
                />
              </el-form-item>
              
              <el-form-item label="会话超时" prop="sessionTimeout">
                <el-input-number
                  v-model="systemSettings.sessionTimeout"
                  :min="30"
                  :max="1440"
                  placeholder="会话超时时间(分钟)"
                />
              </el-form-item>
              
              <el-form-item label="启用调试" prop="debugMode">
                <el-switch
                  v-model="systemSettings.debugMode"
                  active-text="开启"
                  inactive-text="关闭"
                />
              </el-form-item>
              
              <el-form-item label="启用缓存" prop="cacheEnabled">
                <el-switch
                  v-model="systemSettings.cacheEnabled"
                  active-text="开启"
                  inactive-text="关闭"
                />
              </el-form-item>
            </el-card>
          </el-form>
        </div>
      </el-tab-pane>
      
      <!-- 安全设置 -->
      <el-tab-pane label="安全设置" name="security">
        <div class="setting-panel">
          <el-form
            ref="securityFormRef"
            :model="securitySettings"
            :rules="securityRules"
            label-width="120px"
          >
            <el-card header="密码策略">
              <el-form-item label="最小长度" prop="passwordMinLength">
                <el-input-number
                  v-model="securitySettings.passwordMinLength"
                  :min="6"
                  :max="20"
                  placeholder="密码最小长度"
                />
              </el-form-item>
              
              <el-form-item label="密码复杂度" prop="passwordComplexity">
                <el-checkbox-group v-model="securitySettings.passwordComplexity">
                  <el-checkbox label="uppercase">包含大写字母</el-checkbox>
                  <el-checkbox label="lowercase">包含小写字母</el-checkbox>
                  <el-checkbox label="number">包含数字</el-checkbox>
                  <el-checkbox label="special">包含特殊字符</el-checkbox>
                </el-checkbox-group>
              </el-form-item>
              
              <el-form-item label="密码有效期" prop="passwordExpireDays">
                <el-input-number
                  v-model="securitySettings.passwordExpireDays"
                  :min="0"
                  :max="365"
                  placeholder="密码有效期(天),0表示永不过期"
                />
              </el-form-item>
              
              <el-form-item label="历史密码" prop="passwordHistoryCount">
                <el-input-number
                  v-model="securitySettings.passwordHistoryCount"
                  :min="0"
                  :max="10"
                  placeholder="不能重复使用的历史密码数量"
                />
              </el-form-item>
            </el-card>
            
            <el-card header="登录安全" style="margin-top: 20px;">
              <el-form-item label="最大登录失败" prop="maxLoginAttempts">
                <el-input-number
                  v-model="securitySettings.maxLoginAttempts"
                  :min="3"
                  :max="10"
                  placeholder="最大登录失败次数"
                />
              </el-form-item>
              
              <el-form-item label="锁定时间" prop="lockoutDuration">
                <el-input-number
                  v-model="securitySettings.lockoutDuration"
                  :min="5"
                  :max="60"
                  placeholder="账户锁定时间(分钟)"
                />
              </el-form-item>
              
              <el-form-item label="启用验证码" prop="captchaEnabled">
                <el-switch
                  v-model="securitySettings.captchaEnabled"
                  active-text="开启"
                  inactive-text="关闭"
                />
              </el-form-item>
              
              <el-form-item label="启用双因子认证" prop="twoFactorEnabled">
                <el-switch
                  v-model="securitySettings.twoFactorEnabled"
                  active-text="开启"
                  inactive-text="关闭"
                />
              </el-form-item>
              
              <el-form-item label="IP白名单" prop="ipWhitelist">
                <el-input
                  v-model="securitySettings.ipWhitelist"
                  type="textarea"
                  :rows="3"
                  placeholder="IP白名单,每行一个IP或IP段"
                />
              </el-form-item>
            </el-card>
          </el-form>
        </div>
      </el-tab-pane>
      
      <!-- 邮件设置 -->
      <el-tab-pane label="邮件设置" name="email">
        <div class="setting-panel">
          <el-form
            ref="emailFormRef"
            :model="emailSettings"
            :rules="emailRules"
            label-width="120px"
          >
            <el-card header="SMTP配置">
              <el-form-item label="SMTP服务器" prop="smtpHost">
                <el-input
                  v-model="emailSettings.smtpHost"
                  placeholder="请输入SMTP服务器地址"
                />
              </el-form-item>
              
              <el-form-item label="SMTP端口" prop="smtpPort">
                <el-input-number
                  v-model="emailSettings.smtpPort"
                  :min="1"
                  :max="65535"
                  placeholder="SMTP端口"
                />
              </el-form-item>
              
              <el-form-item label="加密方式" prop="smtpSecurity">
                <el-select
                  v-model="emailSettings.smtpSecurity"
                  placeholder="请选择加密方式"
                  style="width: 100%;"
                >
                  <el-option label="无加密" value="none" />
                  <el-option label="SSL" value="ssl" />
                  <el-option label="TLS" value="tls" />
                </el-select>
              </el-form-item>
              
              <el-form-item label="用户名" prop="smtpUsername">
                <el-input
                  v-model="emailSettings.smtpUsername"
                  placeholder="请输入SMTP用户名"
                />
              </el-form-item>
              
              <el-form-item label="密码" prop="smtpPassword">
                <el-input
                  v-model="emailSettings.smtpPassword"
                  type="password"
                  placeholder="请输入SMTP密码"
                  show-password
                />
              </el-form-item>
              
              <el-form-item label="发件人名称" prop="fromName">
                <el-input
                  v-model="emailSettings.fromName"
                  placeholder="请输入发件人名称"
                />
              </el-form-item>
              
              <el-form-item label="发件人邮箱" prop="fromEmail">
                <el-input
                  v-model="emailSettings.fromEmail"
                  placeholder="请输入发件人邮箱"
                />
              </el-form-item>
              
              <el-form-item>
                <el-button type="primary" @click="testEmailConnection" :loading="testingEmail">
                  测试连接
                </el-button>
              </el-form-item>
            </el-card>
          </el-form>
        </div>
      </el-tab-pane>
      
      <!-- 文件设置 -->
      <el-tab-pane label="文件设置" name="file">
        <div class="setting-panel">
          <el-form
            ref="fileFormRef"
            :model="fileSettings"
            :rules="fileRules"
            label-width="120px"
          >
            <el-card header="上传配置">
              <el-form-item label="最大文件大小" prop="maxFileSize">
                <el-input-number
                  v-model="fileSettings.maxFileSize"
                  :min="1"
                  :max="100"
                  placeholder="最大文件大小(MB)"
                />
              </el-form-item>
              
              <el-form-item label="允许的文件类型" prop="allowedFileTypes">
                <el-checkbox-group v-model="fileSettings.allowedFileTypes">
                  <el-checkbox label="jpg">JPG</el-checkbox>
                  <el-checkbox label="png">PNG</el-checkbox>
                  <el-checkbox label="gif">GIF</el-checkbox>
                  <el-checkbox label="pdf">PDF</el-checkbox>
                  <el-checkbox label="doc">DOC</el-checkbox>
                  <el-checkbox label="docx">DOCX</el-checkbox>
                  <el-checkbox label="xls">XLS</el-checkbox>
                  <el-checkbox label="xlsx">XLSX</el-checkbox>
                  <el-checkbox label="txt">TXT</el-checkbox>
                  <el-checkbox label="zip">ZIP</el-checkbox>
                </el-checkbox-group>
              </el-form-item>
              
              <el-form-item label="存储路径" prop="uploadPath">
                <el-input
                  v-model="fileSettings.uploadPath"
                  placeholder="请输入文件存储路径"
                />
              </el-form-item>
              
              <el-form-item label="URL前缀" prop="urlPrefix">
                <el-input
                  v-model="fileSettings.urlPrefix"
                  placeholder="请输入文件访问URL前缀"
                />
              </el-form-item>
              
              <el-form-item label="启用缩略图" prop="thumbnailEnabled">
                <el-switch
                  v-model="fileSettings.thumbnailEnabled"
                  active-text="开启"
                  inactive-text="关闭"
                />
              </el-form-item>
              
              <el-form-item label="缩略图尺寸" prop="thumbnailSize" v-if="fileSettings.thumbnailEnabled">
                <el-input-number
                  v-model="fileSettings.thumbnailSize"
                  :min="50"
                  :max="500"
                  placeholder="缩略图尺寸(像素)"
                />
              </el-form-item>
            </el-card>
          </el-form>
        </div>
      </el-tab-pane>
    </el-tabs>
  </div>
</template>

3. 脚本逻辑

<script setup>
import { ref, reactive, computed, onMounted } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import {
  getSystemSettings,
  updateSystemSettings,
  testEmailConnection as testEmailConnectionApi,
  resetSystemSettings
} from '@/api/setting'
import {
  Check,
  Refresh,
  Plus
} from '@element-plus/icons-vue'

// 响应式数据
const basicFormRef = ref(null)
const systemFormRef = ref(null)
const securityFormRef = ref(null)
const emailFormRef = ref(null)
const fileFormRef = ref(null)

const activeTab = ref('basic')
const saveLoading = ref(false)
const testingEmail = ref(false)

// 基础设置
const basicSettings = reactive({
  siteName: '',
  siteTitle: '',
  siteDescription: '',
  siteKeywords: '',
  siteLogo: '',
  siteFavicon: '',
  contactPhone: '',
  contactEmail: '',
  contactAddress: '',
  copyright: ''
})

// 系统设置
const systemSettings = reactive({
  version: '1.0.0',
  timezone: 'Asia/Shanghai',
  defaultLanguage: 'zh-CN',
  pageSize: 20,
  sessionTimeout: 120,
  debugMode: false,
  cacheEnabled: true
})

// 安全设置
const securitySettings = reactive({
  passwordMinLength: 8,
  passwordComplexity: ['lowercase', 'number'],
  passwordExpireDays: 90,
  passwordHistoryCount: 3,
  maxLoginAttempts: 5,
  lockoutDuration: 15,
  captchaEnabled: true,
  twoFactorEnabled: false,
  ipWhitelist: ''
})

// 邮件设置
const emailSettings = reactive({
  smtpHost: '',
  smtpPort: 587,
  smtpSecurity: 'tls',
  smtpUsername: '',
  smtpPassword: '',
  fromName: '',
  fromEmail: ''
})

// 文件设置
const fileSettings = reactive({
  maxFileSize: 10,
  allowedFileTypes: ['jpg', 'png', 'pdf', 'doc', 'docx'],
  uploadPath: '/uploads',
  urlPrefix: '/files',
  thumbnailEnabled: true,
  thumbnailSize: 200
})

// 上传配置
const uploadUrl = computed(() => '/api/upload')
const uploadHeaders = computed(() => ({
  'Authorization': `Bearer ${localStorage.getItem('token')}`
}))
</script>

核心功能实现

1. 数据加载

// 加载系统设置
const loadSystemSettings = async () => {
  try {
    const result = await getSystemSettings()
    if (result.status) {
      const settings = result.data
      
      // 分配到各个设置对象
      Object.assign(basicSettings, settings.basic || {})
      Object.assign(systemSettings, settings.system || {})
      Object.assign(securitySettings, settings.security || {})
      Object.assign(emailSettings, settings.email || {})
      Object.assign(fileSettings, settings.file || {})
    }
  } catch (error) {
    console.error('加载系统设置失败:', error)
    ElMessage.error('加载设置失败')
  }
}

2. 保存设置

// 保存所有设置
const saveAllSettings = async () => {
  try {
    // 验证所有表单
    const forms = [
      basicFormRef.value,
      systemFormRef.value,
      securityFormRef.value,
      emailFormRef.value,
      fileFormRef.value
    ]
    
    const validationPromises = forms.map(form => {
      return form ? form.validate().catch(() => false) : Promise.resolve(true)
    })
    
    const validationResults = await Promise.all(validationPromises)
    const isValid = validationResults.every(result => result === true)
    
    if (!isValid) {
      ElMessage.error('请检查表单输入')
      return
    }
    
    saveLoading.value = true
    
    const settingsData = {
      basic: basicSettings,
      system: systemSettings,
      security: securitySettings,
      email: emailSettings,
      file: fileSettings
    }
    
    const result = await updateSystemSettings(settingsData)
    if (result.status) {
      ElMessage.success('设置保存成功')
    } else {
      ElMessage.error(result.msg || '保存失败')
    }
  } catch (error) {
    console.error('保存设置失败:', error)
    ElMessage.error('保存失败')
  } finally {
    saveLoading.value = false
  }
}

// 重置设置
const resetSettings = () => {
  ElMessageBox.confirm(
    '确定要重置所有设置为默认值吗?此操作不可恢复。',
    '重置确认',
    {
      confirmButtonText: '确定',
      cancelButtonText: '取消',
      type: 'warning'
    }
  ).then(async () => {
    try {
      const result = await resetSystemSettings()
      if (result.status) {
        ElMessage.success('重置成功')
        loadSystemSettings()
      } else {
        ElMessage.error(result.msg || '重置失败')
      }
    } catch (error) {
      console.error('重置设置失败:', error)
      ElMessage.error('重置失败')
    }
  }).catch(() => {
    // 用户取消
  })
}

3. 文件上传

// Logo上传成功处理
const handleLogoSuccess = (response) => {
  if (response.status) {
    basicSettings.siteLogo = response.data.url
    ElMessage.success('Logo上传成功')
  } else {
    ElMessage.error(response.msg || 'Logo上传失败')
  }
}

// Logo上传前检查
const beforeLogoUpload = (file) => {
  const isImage = file.type.startsWith('image/')
  const isLt2M = file.size / 1024 / 1024 < 2
  
  if (!isImage) {
    ElMessage.error('只能上传图片文件')
    return false
  }
  if (!isLt2M) {
    ElMessage.error('图片大小不能超过2MB')
    return false
  }
  return true
}

// Favicon上传成功处理
const handleFaviconSuccess = (response) => {
  if (response.status) {
    basicSettings.siteFavicon = response.data.url
    ElMessage.success('图标上传成功')
  } else {
    ElMessage.error(response.msg || '图标上传失败')
  }
}

// Favicon上传前检查
const beforeFaviconUpload = (file) => {
  const isIcon = file.type === 'image/x-icon' || file.type === 'image/vnd.microsoft.icon'
  const isLt1M = file.size / 1024 / 1024 < 1
  
  if (!isIcon) {
    ElMessage.error('只能上传ICO格式的图标文件')
    return false
  }
  if (!isLt1M) {
    ElMessage.error('图标大小不能超过1MB')
    return false
  }
  return true
}

4. 邮件测试

// 测试邮件连接
const testEmailConnection = async () => {
  if (!emailFormRef.value) return
  
  try {
    await emailFormRef.value.validate()
    
    testingEmail.value = true
    
    const result = await testEmailConnectionApi(emailSettings)
    if (result.status) {
      ElMessage.success('邮件连接测试成功')
    } else {
      ElMessage.error(result.msg || '邮件连接测试失败')
    }
  } catch (error) {
    if (error.fields) {
      ElMessage.error('请先完善邮件配置')
    } else {
      console.error('测试邮件连接失败:', error)
      ElMessage.error('连接测试失败')
    }
  } finally {
    testingEmail.value = false
  }
}

5. 表单验证规则

// 基础设置验证规则
const basicRules = {
  siteName: [
    { required: true, message: '请输入网站名称', trigger: 'blur' }
  ],
  siteTitle: [
    { required: true, message: '请输入网站标题', trigger: 'blur' }
  ],
  contactEmail: [
    { type: 'email', message: '请输入正确的邮箱地址', trigger: 'blur' }
  ]
}

// 系统设置验证规则
const systemRules = {
  timezone: [
    { required: true, message: '请选择时区', trigger: 'change' }
  ],
  defaultLanguage: [
    { required: true, message: '请选择默认语言', trigger: 'change' }
  ],
  pageSize: [
    { required: true, message: '请输入分页大小', trigger: 'blur' },
    { type: 'number', min: 10, max: 100, message: '分页大小必须在10-100之间', trigger: 'blur' }
  ],
  sessionTimeout: [
    { required: true, message: '请输入会话超时时间', trigger: 'blur' },
    { type: 'number', min: 30, max: 1440, message: '会话超时时间必须在30-1440分钟之间', trigger: 'blur' }
  ]
}

// 安全设置验证规则
const securityRules = {
  passwordMinLength: [
    { required: true, message: '请输入密码最小长度', trigger: 'blur' },
    { type: 'number', min: 6, max: 20, message: '密码长度必须在6-20之间', trigger: 'blur' }
  ],
  maxLoginAttempts: [
    { required: true, message: '请输入最大登录失败次数', trigger: 'blur' },
    { type: 'number', min: 3, max: 10, message: '最大登录失败次数必须在3-10之间', trigger: 'blur' }
  ],
  lockoutDuration: [
    { required: true, message: '请输入锁定时间', trigger: 'blur' },
    { type: 'number', min: 5, max: 60, message: '锁定时间必须在5-60分钟之间', trigger: 'blur' }
  ]
}

// 邮件设置验证规则
const emailRules = {
  smtpHost: [
    { required: true, message: '请输入SMTP服务器地址', trigger: 'blur' }
  ],
  smtpPort: [
    { required: true, message: '请输入SMTP端口', trigger: 'blur' },
    { type: 'number', min: 1, max: 65535, message: '端口必须在1-65535之间', trigger: 'blur' }
  ],
  smtpUsername: [
    { required: true, message: '请输入SMTP用户名', trigger: 'blur' }
  ],
  smtpPassword: [
    { required: true, message: '请输入SMTP密码', trigger: 'blur' }
  ],
  fromEmail: [
    { required: true, message: '请输入发件人邮箱', trigger: 'blur' },
    { type: 'email', message: '请输入正确的邮箱地址', trigger: 'blur' }
  ]
}

// 文件设置验证规则
const fileRules = {
  maxFileSize: [
    { required: true, message: '请输入最大文件大小', trigger: 'blur' },
    { type: 'number', min: 1, max: 100, message: '文件大小必须在1-100MB之间', trigger: 'blur' }
  ],
  uploadPath: [
    { required: true, message: '请输入存储路径', trigger: 'blur' }
  ],
  urlPrefix: [
    { required: true, message: '请输入URL前缀', trigger: 'blur' }
  ]
}

样式定义

1. 页面布局样式

.setting-container {
  padding: 20px;
}

.page-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 20px;
  padding-bottom: 20px;
  border-bottom: 1px solid var(--el-border-color);
}

.header-title h2 {
  margin: 0 0 8px 0;
  color: var(--el-text-color-primary);
}

.header-title p {
  margin: 0;
  color: var(--el-text-color-regular);
  font-size: 14px;
}

.header-actions {
  display: flex;
  gap: 12px;
}

2. 标签页样式

.setting-tabs {
  .el-tabs__header {
    margin-bottom: 20px;
  }
  
  .el-tabs__content {
    padding: 0;
  }
}

.setting-panel {
  .el-card {
    border-radius: 8px;
    
    .el-card__header {
      background: var(--el-fill-color-lighter);
      font-weight: 600;
    }
  }
}

3. 上传组件样式

.logo-uploader {
  .logo {
    width: 120px;
    height: 60px;
    object-fit: contain;
    border: 1px solid var(--el-border-color);
    border-radius: 6px;
  }
  
  .logo-uploader-icon {
    font-size: 28px;
    color: var(--el-text-color-secondary);
    width: 120px;
    height: 60px;
    line-height: 60px;
    text-align: center;
    border: 1px dashed var(--el-border-color);
    border-radius: 6px;
    cursor: pointer;
    transition: border-color 0.2s ease;
    
    &:hover {
      border-color: var(--el-color-primary);
    }
  }
}

.favicon-uploader {
  .favicon {
    width: 32px;
    height: 32px;
    object-fit: contain;
    border: 1px solid var(--el-border-color);
    border-radius: 4px;
  }
  
  .favicon-uploader-icon {
    font-size: 16px;
    color: var(--el-text-color-secondary);
    width: 32px;
    height: 32px;
    line-height: 32px;
    text-align: center;
    border: 1px dashed var(--el-border-color);
    border-radius: 4px;
    cursor: pointer;
    transition: border-color 0.2s ease;
    
    &:hover {
      border-color: var(--el-color-primary);
    }
  }
}

生命周期

1. 组件挂载

onMounted(() => {
  loadSystemSettings()
})

使用示例

1. 路由配置

{
  path: 'setting',
  name: 'Setting',
  component: () => import('@/views/sys/setting.vue'),
  meta: {
    title: '系统设置',
    icon: 'Setting',
    requiresAuth: true,
    permissions: ['setting:manage']
  }
}

2. API接口调用

// 获取系统设置
const result = await getSystemSettings()

// 更新系统设置
const updateResult = await updateSystemSettings({
  basic: { siteName: '新网站名称' },
  system: { pageSize: 30 }
})

注意事项

  1. 权限控制: 只有超级管理员才能修改系统设置
  2. 数据验证: 严格验证所有配置参数的有效性
  3. 安全配置: 密码策略等安全配置要谨慎设置
  4. 备份恢复: 重要配置修改前应备份原设置
  5. 实时生效: 某些配置可能需要重启服务才能生效

相关文档


最后更新时间:2025-09-19