新版官网模板
This commit is contained in:
826
app/pages/admin/settings.vue
Normal file
826
app/pages/admin/settings.vue
Normal 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>
|
||||
Reference in New Issue
Block a user