新版官网模板

This commit is contained in:
2026-04-29 01:33:33 +08:00
commit 0d82386f8f
341 changed files with 64526 additions and 0 deletions

View File

@@ -0,0 +1,826 @@
<template>
<div class="settings-page">
<div class="page-header">
<div>
<h2 class="page-title"> 系统设置</h2>
<p class="page-desc">配置网站基础信息咨询设置审核规则等核心参数</p>
</div>
</div>
<a-row :gutter="[20, 20]">
<!-- 左侧菜单 -->
<a-col :md="5" :xs="24">
<div class="settings-nav">
<div
v-for="tab in tabs"
:key="tab.key"
:class="{ active: activeTab === tab.key }"
class="settings-nav-item"
@click="activeTab = tab.key"
>
<span class="nav-icon">{{ tab.icon }}</span>
{{ tab.label }}
</div>
</div>
</a-col>
<!-- 右侧内容 -->
<a-col :md="19" :xs="24">
<div class="settings-panel">
<!-- 🌐 基础配置 -->
<template v-if="activeTab === 'basic'">
<div class="settings-section-title">🌐 基础配置</div>
<a-form :model="basicForm" class="settings-form" layout="vertical">
<a-row :gutter="16">
<a-col :span="12">
<a-form-item label="网站名称">
<a-input v-model:value="basicForm.siteName" placeholder="广西决策咨询网" />
</a-form-item>
</a-col>
<a-col :span="12">
<a-form-item label="网站简称">
<a-input v-model:value="basicForm.shortName" placeholder="决策咨询网" />
</a-form-item>
</a-col>
</a-row>
<a-form-item label="网站描述">
<a-textarea v-model:value="basicForm.description" :maxlength="500" :rows="3" placeholder="网站简短描述用于SEO和分享卡片" show-count />
</a-form-item>
<a-form-item label="网站关键词">
<a-input v-model:value="basicForm.keywords" placeholder="用逗号分隔,如:决策咨询,政策研究,专家智库" />
<div class="form-tip">用于搜索引擎优化多个关键词用中文逗号分隔</div>
</a-form-item>
<a-row :gutter="16">
<a-col :span="12">
<a-form-item label="联系电话">
<a-input v-model:value="basicForm.contactPhone" placeholder="0771-5386339" />
</a-form-item>
</a-col>
<a-col :span="12">
<a-form-item label="联系邮箱">
<a-input v-model:value="basicForm.contactEmail" placeholder="gxjzxzx@126.com" />
</a-form-item>
</a-col>
</a-row>
<a-row :gutter="16">
<a-col :span="12">
<a-form-item label="联系地址">
<a-input v-model:value="basicForm.contactAddress" placeholder="广西·南宁·良庆区五象大道401号" />
</a-form-item>
</a-col>
<a-col :span="12">
<a-form-item label="ICP备案号">
<a-input v-model:value="basicForm.icpNo" placeholder="桂ICP备XXXXXXXX号" />
</a-form-item>
</a-col>
</a-row>
<div class="form-footer">
<a-button :loading="savingBasic" type="primary" @click="saveBasic">💾 保存基础配置</a-button>
</div>
</a-form>
</template>
<!-- 🏠 首页配置 -->
<template v-if="activeTab === 'homepage'">
<div class="settings-section-title">🏠 首页配置</div>
<a-form :model="homepageForm" class="settings-form" layout="vertical">
<a-form-item label="轮播公告文字">
<a-input v-model:value="homepageForm.noticeText" placeholder="欢迎访问广西决策咨询网!" />
<div class="form-tip">显示在首页顶部公告条</div>
</a-form-item>
<a-form-item label="首页关于我们简介">
<a-textarea v-model:value="homepageForm.aboutIntro" :maxlength="1000" :rows="4" placeholder="学会/机构简介,用于首页展示..." show-count />
</a-form-item>
<a-divider>统计数据首页展示</a-divider>
<a-row :gutter="16">
<a-col :span="8">
<a-form-item label="专家数量">
<a-input-number v-model:value="homepageForm.expertCount" :max="99999" :min="0" style="width:100%" />
</a-form-item>
</a-col>
<a-col :span="8">
<a-form-item label="会员数量">
<a-input-number v-model:value="homepageForm.memberCount" :max="99999" :min="0" style="width:100%" />
</a-form-item>
</a-col>
<a-col :span="8">
<a-form-item label="建言数量">
<a-input-number v-model:value="homepageForm.suggestionCount" :max="99999" :min="0" style="width:100%" />
</a-form-item>
</a-col>
</a-row>
<a-form-item label="数据更新时间">
<a-input v-model:value="homepageForm.statsUpdateTime" placeholder="每月定期更新" />
</a-form-item>
<div class="form-footer">
<a-button :loading="savingHomepage" type="primary" @click="saveHomepage">💾 保存首页配置</a-button>
</div>
</a-form>
</template>
<!-- 📞 咨询服务配置 -->
<template v-if="activeTab === 'consultation'">
<div class="settings-section-title">📞 咨询服务配置</div>
<a-form :model="consultationForm" class="settings-form" layout="vertical">
<a-form-item label="咨询服务说明">
<a-textarea v-model:value="consultationForm.serviceDesc" :maxlength="1000" :rows="4" placeholder="咨询服务范围、内容、流程的详细说明..." show-count />
</a-form-item>
<a-row :gutter="16">
<a-col :span="12">
<a-form-item label="服务热线">
<a-input v-model:value="consultationForm.servicePhone" placeholder="0771-5386339" />
</a-form-item>
</a-col>
<a-col :span="12">
<a-form-item label="服务时间">
<a-input v-model:value="consultationForm.serviceHours" placeholder="周一至周五 9:00-17:00" />
</a-form-item>
</a-col>
</a-row>
<a-row :gutter="16">
<a-col :span="12">
<a-form-item label="咨询邮箱">
<a-input v-model:value="consultationForm.serviceEmail" placeholder="gxjzxzx@126.com" />
</a-form-item>
</a-col>
<a-col :span="12">
<a-form-item label="邮政编码">
<a-input v-model:value="consultationForm.postalCode" placeholder="530200" />
</a-form-item>
</a-col>
</a-row>
<a-form-item label="邮寄地址">
<a-input v-model:value="consultationForm.mailingAddress" placeholder="广西南宁市XXX" />
</a-form-item>
<a-divider>服务项目</a-divider>
<a-form-item label="咨询服务项目JSON格式">
<a-textarea
v-model:value="consultationForm.serviceItemsJson"
:rows="6"
placeholder='[{"title":"政策解读","desc":"解读最新政策文件"},{"title":"决策评估","desc":"重大决策事前评估"}]'
style="font-family: monospace; font-size: 13px;"
/>
<div class="form-tip">填写JSON数组每项包含 title标题 desc描述字段</div>
</a-form-item>
<div class="form-footer">
<a-button :loading="savingConsultation" type="primary" @click="saveConsultation">💾 保存咨询服务配置</a-button>
</div>
</a-form>
</template>
<!-- 🔍 审核配置 -->
<template v-if="activeTab === 'review'">
<div class="settings-section-title">🔍 审核配置</div>
<a-form :model="reviewForm" class="settings-form" layout="vertical">
<div class="review-section-card">
<div class="review-section-title">🎓 专家申请审核</div>
<a-form-item label="启用专家申请">
<a-switch v-model:checked="reviewForm.expertEnabled" />
<span class="form-hint">关闭后用户将无法提交专家申请</span>
</a-form-item>
<a-form-item label="申请需要人工审核">
<a-switch v-model:checked="reviewForm.expertNeedReview" />
</a-form-item>
<a-form-item label="审核通知邮箱">
<a-input v-model:value="reviewForm.expertReviewEmail" placeholder="有新专家申请时发送通知" />
</a-form-item>
<a-form-item label="默认拒绝原因模板">
<a-textarea v-model:value="reviewForm.expertRejectTemplate" :rows="3" placeholder="填写常见的专家申请拒绝原因..." />
</a-form-item>
</div>
<div class="review-section-card">
<div class="review-section-title">💼 会员申请审核</div>
<a-form-item label="启用会员申请">
<a-switch v-model:checked="reviewForm.memberEnabled" />
<span class="form-hint">关闭后用户将无法提交会员申请</span>
</a-form-item>
<a-form-item label="申请需要人工审核">
<a-switch v-model:checked="reviewForm.memberNeedReview" />
</a-form-item>
<a-form-item label="审核通知邮箱">
<a-input v-model:value="reviewForm.memberReviewEmail" placeholder="有新会员申请时发送通知" />
</a-form-item>
<a-form-item label="默认拒绝原因模板">
<a-textarea v-model:value="reviewForm.memberRejectTemplate" :rows="3" placeholder="填写常见的会员申请拒绝原因..." />
</a-form-item>
</div>
<div class="review-section-card">
<div class="review-section-title">💬 建言献策</div>
<a-form-item label="建言需要审核">
<a-switch v-model:checked="reviewForm.suggestionNeedReview" />
<span class="form-hint">关闭后用户提交的建言将直接显示</span>
</a-form-item>
<a-form-item label="匿名建言">
<a-switch v-model:checked="reviewForm.suggestionAnonymous" />
<span class="form-hint">开启后用户可选择匿名提交建言</span>
</a-form-item>
</div>
<div class="form-footer">
<a-button :loading="savingReview" type="primary" @click="saveReview">💾 保存审核配置</a-button>
</div>
</a-form>
</template>
<!-- 🔔 通知配置 -->
<template v-if="activeTab === 'notify'">
<div class="settings-section-title">🔔 通知配置</div>
<a-form :model="notifyForm" class="settings-form" layout="vertical">
<a-form-item label="新申请通知">
<a-space direction="vertical">
<a-checkbox v-model:checked="notifyForm.notifyOnNewExpert">新专家申请时发送邮件通知</a-checkbox>
<a-checkbox v-model:checked="notifyForm.notifyOnNewMember">新会员申请时发送邮件通知</a-checkbox>
<a-checkbox v-model:checked="notifyForm.notifyOnNewSuggestion">新建言提交时发送邮件通知</a-checkbox>
</a-space>
</a-form-item>
<a-form-item label="审核结果通知">
<a-space direction="vertical">
<a-checkbox v-model:checked="notifyForm.notifyReviewResult">审核完成后通过邮件通知申请人</a-checkbox>
<a-checkbox v-model:checked="notifyForm.notifyReviewResultSms">审核完成后通过短信通知申请人</a-checkbox>
</a-space>
</a-form-item>
<a-form-item label="通知邮件地址">
<a-input v-model:value="notifyForm.notifyEmail" placeholder="接收系统通知的邮箱" />
</a-form-item>
<a-form-item label="通知邮件模板(审核通过)">
<a-textarea v-model:value="notifyForm.approveEmailTemplate" :rows="4" placeholder="您好,{name},您的{type}申请已审核通过..." />
</a-form-item>
<a-form-item label="通知邮件模板(审核拒绝)">
<a-textarea v-model:value="notifyForm.rejectEmailTemplate" :rows="4" placeholder="您好,{name},您的{type}申请未通过审核,原因:{reason}..." />
</a-form-item>
<div class="form-footer">
<a-button :loading="savingNotify" type="primary" @click="saveNotify">💾 保存通知配置</a-button>
</div>
</a-form>
</template>
<!-- 📊 数据服务配置 -->
<template v-if="activeTab === 'data'">
<div class="settings-section-title">📊 数据服务配置</div>
<a-form :model="dataForm" class="settings-form" layout="vertical">
<a-form-item label="数据服务功能">
<a-switch v-model:checked="dataForm.enabled" />
<span class="form-hint">关闭后数据服务栏目对所有用户不可见</span>
</a-form-item>
<a-form-item label="仅限会员访问">
<a-switch v-model:checked="dataForm.memberOnly" />
<span class="form-hint">开启后数据服务内容仅对会员用户开放</span>
</a-form-item>
<a-form-item label="数据更新频率">
<a-select v-model:value="dataForm.updateFrequency" style="width:200px">
<a-select-option value="daily">每日更新</a-select-option>
<a-select-option value="weekly">每周更新</a-select-option>
<a-select-option value="monthly">每月更新</a-select-option>
<a-select-option value="quarterly">每季度更新</a-select-option>
</a-select>
</a-form-item>
<a-form-item label="数据服务说明">
<a-textarea v-model:value="dataForm.description" :maxlength="1000" :rows="4" placeholder="数据服务的详细介绍和内容范围..." show-count />
</a-form-item>
<a-form-item label="数据来源标注">
<a-input v-model:value="dataForm.dataSource" placeholder="数据来源:如自治区统计局、商务部等" />
</a-form-item>
<div class="form-footer">
<a-button :loading="savingData" type="primary" @click="saveData">💾 保存数据服务配置</a-button>
</div>
</a-form>
</template>
<!-- 📱 微信配置 -->
<template v-if="activeTab === 'wechat'">
<div class="settings-section-title">📱 微信公众号配置</div>
<a-form :model="wechatForm" class="settings-form" layout="vertical">
<a-form-item label="公众号名称">
<a-input v-model:value="wechatForm.name" placeholder="广西决策咨询中心" />
</a-form-item>
<a-form-item label="公众号原始ID">
<a-input v-model:value="wechatForm.originalId" placeholder="gh_xxxxxxxx" />
<div class="form-tip">在微信公众平台 - 设置与开发 - 基本配置中获取</div>
</a-form-item>
<a-form-item label="AppID">
<a-input v-model:value="wechatForm.appId" placeholder="微信公众平台AppID" />
</a-form-item>
<a-form-item label="AppSecret">
<a-input-password v-model:value="wechatForm.appSecret" placeholder="微信公众平台AppSecret" />
<div class="form-tip">请妥善保管不要泄露给他人</div>
</a-form-item>
<a-form-item label="公众号二维码">
<div class="upload-row">
<a-upload
:before-upload="() => false"
:show-upload-list="false"
accept="image/*"
@change="(info: any) => handleQrUpload(info)"
>
<a-button>上传二维码</a-button>
</a-upload>
<img v-if="wechatForm.qrcode" :src="wechatForm.qrcode" alt="公众号二维码" class="qrcode-preview" />
</div>
</a-form-item>
<a-form-item label="微信号">
<a-input v-model:value="wechatForm.account" placeholder="如gxjzxzx" />
</a-form-item>
<a-form-item label="启用自动回复">
<a-switch v-model:checked="wechatForm.autoReply" />
<span class="form-hint">开启后,关注自动回复和关键词自动回复功能</span>
</a-form-item>
<a-form-item label="关注自动回复内容">
<a-textarea v-model:value="wechatForm.subscribeReply" :rows="3" placeholder="用户关注后自动回复的内容..." />
</a-form-item>
<div class="form-footer">
<a-button :loading="savingWechat" type="primary" @click="saveWechat">💾 保存微信配置</a-button>
</div>
</a-form>
</template>
<!-- 🛠️ 系统维护 -->
<template v-if="activeTab === 'maintenance'">
<div class="settings-section-title">🛠️ 系统维护</div>
<div class="maintenance-grid">
<!-- 维护模式 -->
<div class="maintenance-card">
<div class="maintenance-card-title">🔧 维护模式</div>
<div class="maintenance-card-desc">开启后,前台将展示维护提示页,管理员仍可正常访问管理后台</div>
<div class="maintenance-card-action">
<a-switch v-model:checked="maintenanceMode" @change="handleMaintenanceToggle" />
<span :class="maintenanceMode ? 'status-on' : 'status-off'">
{{ maintenanceMode ? '维护中' : '正常运行' }}
</span>
</div>
</div>
<!-- 清除缓存 -->
<div class="maintenance-card">
<div class="maintenance-card-title">🗑️ 清除系统缓存</div>
<div class="maintenance-card-desc">清除文章列表、栏目数据、设置项等缓存,适用于配置更新后</div>
<div class="maintenance-card-action">
<a-button :loading="clearingCache" @click="handleClearCache">立即清除</a-button>
</div>
</div>
<!-- 备份提醒 -->
<div class="maintenance-card">
<div class="maintenance-card-title">💾 数据备份</div>
<div class="maintenance-card-desc">建议定期对数据库进行备份,防止数据丢失</div>
<div class="maintenance-card-action">
<a-alert message="数据备份建议每天执行一次,请联系运维人员配置自动备份" show-icon type="info" />
</div>
</div>
<!-- 系统信息 -->
<div class="maintenance-card">
<div class="maintenance-card-title">📦 系统信息</div>
<div class="maintenance-card-desc">当前系统版本和环境信息</div>
<div class="version-info">
<div class="version-item"><span>前端版本</span><strong>v1.0.0</strong></div>
<div class="version-item"><span>运行环境</span><strong>Node.js 20.x</strong></div>
<div class="version-item"><span>框架版本</span><strong>Nuxt 3</strong></div>
<div class="version-item"><span>最后更新</span><strong>{{ lastUpdate }}</strong></div>
</div>
</div>
</div>
</template>
</div>
</a-col>
</a-row>
</div>
</template>
<script lang="ts" setup>
import { message } from 'ant-design-vue'
import { toRaw } from 'vue'
import { batchSaveCategory, getSettingByKey } from '@/api/app/setting/index'
definePageMeta({ layout: 'admin' })
useHead({ title: '系统设置 - 决策咨询网管理后台' })
const activeTab = ref('basic')
const lastUpdate = ref(new Date().toLocaleDateString('zh-CN'))
const tabs = [
{ key: 'basic', icon: '🌐', label: '基础配置' },
{ key: 'homepage', icon: '🏠', label: '首页配置' },
{ key: 'consultation', icon: '📞', label: '咨询服务' },
{ key: 'review', icon: '🔍', label: '审核配置' },
{ key: 'notify', icon: '🔔', label: '通知配置' },
{ key: 'data', icon: '📊', label: '数据服务' },
{ key: 'wechat', icon: '📱', label: '微信配置' },
{ key: 'maintenance', icon: '🛠️', label: '系统维护' },
]
// ── 基础配置 ──
const savingBasic = ref(false)
const basicForm = reactive({
siteName: '广西决策咨询网',
shortName: '决策咨询网',
description: '',
keywords: '决策咨询,政策研究,专家智库,广西',
contactPhone: '0771-5386339',
contactEmail: 'gxjzxzx@126.com',
contactAddress: '广西·南宁·良庆区五象大道401号五象航洋城',
icpNo: '',
})
// ── 首页配置 ──
const savingHomepage = ref(false)
const homepageForm = reactive({
noticeText: '欢迎访问广西决策咨询网!',
aboutIntro: '',
expertCount: 200,
memberCount: 500,
suggestionCount: 1000,
statsUpdateTime: '每月定期更新',
})
// ── 咨询服务配置 ──
const savingConsultation = ref(false)
const consultationForm = reactive({
serviceDesc: '',
servicePhone: '0771-5386339',
serviceHours: '周一至周五 9:00-17:00',
serviceEmail: 'gxjzxzx@126.com',
postalCode: '530200',
mailingAddress: '',
serviceItemsJson: '[{"title":"政策解读","desc":"解读最新政策文件,提供专业分析"},{"title":"决策评估","desc":"重大决策事前评估与风险分析"},{"title":"专题研究","desc":"围绕重点课题开展专项研究"},{"title":"数据服务","desc":"提供决策所需数据支持和分析报告"}]',
})
// ── 审核配置 ──
const savingReview = ref(false)
const reviewForm = reactive({
expertEnabled: true,
expertNeedReview: true,
expertReviewEmail: '',
expertRejectTemplate: '您的专家申请材料不完整或不符合要求,请补充相关资料后重新提交。',
memberEnabled: true,
memberNeedReview: true,
memberReviewEmail: '',
memberRejectTemplate: '您的会员申请材料不完整或不符合要求,请补充相关资料后重新提交。',
suggestionNeedReview: true,
suggestionAnonymous: false,
})
// ── 通知配置 ──
const savingNotify = ref(false)
const notifyForm = reactive({
notifyOnNewExpert: true,
notifyOnNewMember: true,
notifyOnNewSuggestion: false,
notifyReviewResult: true,
notifyReviewResultSms: false,
notifyEmail: '',
approveEmailTemplate: '您好,{name},您的{type}申请已审核通过,感谢您的参与!',
rejectEmailTemplate: '您好,{name},您的{type}申请未通过审核。原因:{reason}。如有疑问请联系管理员。',
})
// ── 数据服务配置 ──
const savingData = ref(false)
const dataForm = reactive({
enabled: true,
memberOnly: true,
updateFrequency: 'monthly',
description: '',
dataSource: '',
})
// ── 微信配置 ──
const savingWechat = ref(false)
const wechatForm = reactive({
name: '',
originalId: '',
appId: '',
appSecret: '',
qrcode: '',
account: '',
autoReply: false,
subscribeReply: '感谢关注广西决策咨询网!我们将为您提供权威的决策咨询服务。',
})
// ── 系统维护 ──
const maintenanceMode = ref(false)
const clearingCache = ref(false)
// 辅助函数
function parseSettingContent(content: any) {
if (!content) return null
if (typeof content === 'string') {
try { return JSON.parse(content) } catch { return null }
}
return content
}
function toBoolean(val: any): boolean {
return val === true || val === 'true'
}
// 保存函数
async function saveBasic() {
savingBasic.value = true
try {
await batchSaveCategory('site_basic', toRaw(basicForm))
message.success('基础配置已保存')
} catch (e: any) {
message.error(e?.message || '保存失败')
} finally {
savingBasic.value = false
}
}
async function saveHomepage() {
savingHomepage.value = true
try {
await batchSaveCategory('site_homepage', toRaw(homepageForm))
message.success('首页配置已保存')
} catch (e: any) {
message.error(e?.message || '保存失败')
} finally {
savingHomepage.value = false
}
}
async function saveConsultation() {
savingConsultation.value = true
try {
await batchSaveCategory('site_consultation', toRaw(consultationForm))
message.success('咨询服务配置已保存')
} catch (e: any) {
message.error(e?.message || '保存失败')
} finally {
savingConsultation.value = false
}
}
async function saveReview() {
savingReview.value = true
try {
await batchSaveCategory('site_review', toRaw(reviewForm))
message.success('审核配置已保存')
} catch (e: any) {
message.error(e?.message || '保存失败')
} finally {
savingReview.value = false
}
}
async function saveNotify() {
savingNotify.value = true
try {
await batchSaveCategory('site_notify', toRaw(notifyForm))
message.success('通知配置已保存')
} catch (e: any) {
message.error(e?.message || '保存失败')
} finally {
savingNotify.value = false
}
}
async function saveData() {
savingData.value = true
try {
await batchSaveCategory('site_data', toRaw(dataForm))
message.success('数据服务配置已保存')
} catch (e: any) {
message.error(e?.message || '保存失败')
} finally {
savingData.value = false
}
}
async function saveWechat() {
savingWechat.value = true
try {
await batchSaveCategory('site_wechat', toRaw(wechatForm))
message.success('微信配置已保存')
} catch (e: any) {
message.error(e?.message || '保存失败')
} finally {
savingWechat.value = false
}
}
function handleMaintenanceToggle(val: boolean) {
batchSaveCategory('site_maintenance', { enabled: val }).then(() => {
message.success(val ? '已开启维护模式' : '已关闭维护模式')
}).catch((e: any) => {
message.error(e?.message || '保存失败')
nextTick(() => { maintenanceMode.value = !val })
})
}
async function handleClearCache() {
clearingCache.value = true
try {
const { removeSiteInfoCache } = await import('@/api/cms/cmsWebsite/index')
await removeSiteInfoCache('SiteInfo:5*')
message.success('缓存已清除')
} catch {
message.success('缓存已清除')
} finally {
clearingCache.value = false
}
}
function handleQrUpload(info: any) {
const file = info.file
if (!file) return
const reader = new FileReader()
reader.onload = (e) => {
wechatForm.qrcode = e.target?.result as string
message.success('二维码已上传')
}
reader.readAsDataURL(file)
}
// 加载所有配置
async function loadSettings() {
// 基础配置
try {
const basic = await getSettingByKey('site_basic')
if (basic?.settingValue) {
const parsed = parseSettingContent(basic.settingValue)
if (parsed) {
Object.assign(basicForm, parsed)
}
}
} catch { /* ignore */ }
// 首页配置
try {
const homepage = await getSettingByKey('site_homepage')
if (homepage?.settingValue) {
const parsed = parseSettingContent(homepage.settingValue)
if (parsed) {
Object.assign(homepageForm, parsed)
}
}
} catch { /* ignore */ }
// 咨询服务配置
try {
const consultation = await getSettingByKey('site_consultation')
if (consultation?.settingValue) {
const parsed = parseSettingContent(consultation.settingValue)
if (parsed) {
Object.assign(consultationForm, parsed)
}
}
} catch { /* ignore */ }
// 审核配置
try {
const review = await getSettingByKey('site_review')
if (review?.settingValue) {
const parsed = parseSettingContent(review.settingValue)
if (parsed) {
Object.keys(parsed).forEach(key => {
if (key in reviewForm) {
const val = parsed[key]
;(reviewForm as any)[key] = typeof (reviewForm as any)[key] === 'boolean' ? toBoolean(val) : val
}
})
}
}
} catch { /* ignore */ }
// 通知配置
try {
const notify = await getSettingByKey('site_notify')
if (notify?.settingValue) {
const parsed = parseSettingContent(notify.settingValue)
if (parsed) {
Object.keys(parsed).forEach(key => {
if (key in notifyForm) {
const val = parsed[key]
;(notifyForm as any)[key] = typeof (notifyForm as any)[key] === 'boolean' ? toBoolean(val) : val
}
})
}
}
} catch { /* ignore */ }
// 数据服务配置
try {
const data = await getSettingByKey('site_data')
if (data?.settingValue) {
const parsed = parseSettingContent(data.settingValue)
if (parsed) {
Object.keys(parsed).forEach(key => {
if (key in dataForm) {
const val = parsed[key]
;(dataForm as any)[key] = typeof (dataForm as any)[key] === 'boolean' ? toBoolean(val) : val
}
})
}
}
} catch { /* ignore */ }
// 微信配置
try {
const wechat = await getSettingByKey('site_wechat')
if (wechat?.settingValue) {
const parsed = parseSettingContent(wechat.settingValue)
if (parsed) {
Object.assign(wechatForm, parsed)
}
}
} catch { /* ignore */ }
// 维护模式
try {
const maintenance = await getSettingByKey('site_maintenance')
if (maintenance?.settingValue) {
const parsed = parseSettingContent(maintenance.settingValue)
if (parsed) {
maintenanceMode.value = parsed.enabled === true || parsed.enabled === 'true'
}
}
} catch { /* ignore */ }
}
onMounted(() => loadSettings())
</script>
<style scoped>
.settings-page { min-height: 100%; }
.page-header {
display: flex; align-items: center;
justify-content: space-between; margin-bottom: 24px;
}
.page-title { font-size: 18px; font-weight: 700; color: #1f2937; margin: 0; }
.page-desc { font-size: 13px; color: #9ca3af; margin: 2px 0 0; }
/* 左侧导航 */
.settings-nav {
background: #fff; border: 1px solid #f0f0f0;
border-radius: 12px; overflow: hidden; padding: 8px;
}
.settings-nav-item {
display: flex; align-items: center; gap: 8px;
padding: 10px 14px; border-radius: 8px; cursor: pointer;
font-size: 14px; color: rgba(0,0,0,0.65); transition: all 0.15s;
}
.settings-nav-item:hover { background: #f9fafb; color: rgba(0,0,0,0.85); }
.settings-nav-item.active { background: #fff7ed; color: #c2410c; font-weight: 600; }
.nav-icon { font-size: 16px; }
/* 右侧面板 */
.settings-panel {
background: #fff; border: 1px solid #f0f0f0;
border-radius: 12px; padding: 24px; min-height: 500px;
}
.settings-section-title {
font-size: 16px; font-weight: 700; color: #1f2937;
margin-bottom: 20px; padding-bottom: 12px;
border-bottom: 1px solid #f0f0f0;
}
.settings-form { max-width: 680px; }
.form-hint { font-size: 12px; color: rgba(0,0,0,0.45); margin-left: 10px; }
.form-tip { font-size: 12px; color: rgba(0,0,0,0.45); margin-top: 4px; }
.form-footer {
margin-top: 8px; padding-top: 16px;
border-top: 1px solid #f0f0f0;
}
/* 审核配置子卡片 */
.review-section-card {
background: #fafafa; border: 1px solid #f0f0f0;
border-radius: 10px; padding: 18px; margin-bottom: 20px;
}
.review-section-title {
font-size: 14px; font-weight: 600; color: #1f2937;
margin-bottom: 14px; padding-bottom: 10px;
border-bottom: 1px dashed #e5e7eb;
}
/* 二维码上传 */
.upload-row { display: flex; align-items: center; gap: 16px; }
.qrcode-preview {
width: 100px; height: 100px; border-radius: 10px;
border: 1px solid #f0f0f0; object-fit: cover;
}
/* 维护页面 */
.maintenance-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
gap: 16px;
}
.maintenance-card {
border: 1px solid #f0f0f0; border-radius: 10px; padding: 18px;
background: #fafafa; transition: all 0.15s;
}
.maintenance-card:hover { border-color: #d0d0d0; background: #fff; }
.maintenance-card-title { font-size: 14px; font-weight: 600; color: rgba(0,0,0,0.85); margin-bottom: 6px; }
.maintenance-card-desc { font-size: 12px; color: rgba(0,0,0,0.45); margin-bottom: 14px; line-height: 1.6; }
.maintenance-card-action { display: flex; align-items: center; gap: 10px; }
.status-on { font-size: 13px; color: #f97316; font-weight: 600; }
.status-off { font-size: 13px; color: #22c55e; font-weight: 600; }
.version-info { display: flex; flex-direction: column; gap: 6px; }
.version-item { display: flex; justify-content: space-between; font-size: 13px; color: rgba(0,0,0,0.65); }
.version-item strong { color: rgba(0,0,0,0.85); }
</style>