- 采用左右分栏布局,左侧新增图标导航 - 全新设计顶部 Banner,提升视觉效果 - 添加学会简介数据亮点和主要职能展示 - 新增组织机构图、主要领导及专家委员会成员展示 - 引入学会章程章节分明条目展示 - 丰富咨询服务内容,新增服务项目卡片和联系方式 - “加入我们”板块支持企业与个人会员申请详情说明 - 支持资料下载并优化排版与交互体验 - 增强响应式支持,保证移动端体验一致 - 页面样式大幅调整,提升整体美观与可读性
827 lines
34 KiB
Vue
827 lines
34 KiB
Vue
<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 :xs="24" :md="5">
|
||
<div class="settings-nav">
|
||
<div
|
||
v-for="tab in tabs"
|
||
:key="tab.key"
|
||
class="settings-nav-item"
|
||
:class="{ active: activeTab === tab.key }"
|
||
@click="activeTab = tab.key"
|
||
>
|
||
<span class="nav-icon">{{ tab.icon }}</span>
|
||
{{ tab.label }}
|
||
</div>
|
||
</div>
|
||
</a-col>
|
||
|
||
<!-- 右侧内容 -->
|
||
<a-col :xs="24" :md="19">
|
||
<div class="settings-panel">
|
||
|
||
<!-- 🌐 基础配置 -->
|
||
<template v-if="activeTab === 'basic'">
|
||
<div class="settings-section-title">🌐 基础配置</div>
|
||
<a-form :model="basicForm" layout="vertical" class="settings-form">
|
||
<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" :rows="3" placeholder="网站简短描述,用于SEO和分享卡片" :maxlength="500" 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 type="primary" :loading="savingBasic" @click="saveBasic">💾 保存基础配置</a-button>
|
||
</div>
|
||
</a-form>
|
||
</template>
|
||
|
||
<!-- 🏠 首页配置 -->
|
||
<template v-if="activeTab === 'homepage'">
|
||
<div class="settings-section-title">🏠 首页配置</div>
|
||
<a-form :model="homepageForm" layout="vertical" class="settings-form">
|
||
<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" :rows="4" placeholder="学会/机构简介,用于首页展示..." :maxlength="1000" 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" :min="0" :max="99999" style="width:100%" />
|
||
</a-form-item>
|
||
</a-col>
|
||
<a-col :span="8">
|
||
<a-form-item label="会员数量">
|
||
<a-input-number v-model:value="homepageForm.memberCount" :min="0" :max="99999" style="width:100%" />
|
||
</a-form-item>
|
||
</a-col>
|
||
<a-col :span="8">
|
||
<a-form-item label="建言数量">
|
||
<a-input-number v-model:value="homepageForm.suggestionCount" :min="0" :max="99999" 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 type="primary" :loading="savingHomepage" @click="saveHomepage">💾 保存首页配置</a-button>
|
||
</div>
|
||
</a-form>
|
||
</template>
|
||
|
||
<!-- 📞 咨询服务配置 -->
|
||
<template v-if="activeTab === 'consultation'">
|
||
<div class="settings-section-title">📞 咨询服务配置</div>
|
||
<a-form :model="consultationForm" layout="vertical" class="settings-form">
|
||
<a-form-item label="咨询服务说明">
|
||
<a-textarea v-model:value="consultationForm.serviceDesc" :rows="4" placeholder="咨询服务范围、内容、流程的详细说明..." :maxlength="1000" 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 type="primary" :loading="savingConsultation" @click="saveConsultation">💾 保存咨询服务配置</a-button>
|
||
</div>
|
||
</a-form>
|
||
</template>
|
||
|
||
<!-- 🔍 审核配置 -->
|
||
<template v-if="activeTab === 'review'">
|
||
<div class="settings-section-title">🔍 审核配置</div>
|
||
<a-form :model="reviewForm" layout="vertical" class="settings-form">
|
||
<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 type="primary" :loading="savingReview" @click="saveReview">💾 保存审核配置</a-button>
|
||
</div>
|
||
</a-form>
|
||
</template>
|
||
|
||
<!-- 🔔 通知配置 -->
|
||
<template v-if="activeTab === 'notify'">
|
||
<div class="settings-section-title">🔔 通知配置</div>
|
||
<a-form :model="notifyForm" layout="vertical" class="settings-form">
|
||
<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 type="primary" :loading="savingNotify" @click="saveNotify">💾 保存通知配置</a-button>
|
||
</div>
|
||
</a-form>
|
||
</template>
|
||
|
||
<!-- 📊 数据服务配置 -->
|
||
<template v-if="activeTab === 'data'">
|
||
<div class="settings-section-title">📊 数据服务配置</div>
|
||
<a-form :model="dataForm" layout="vertical" class="settings-form">
|
||
<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" :rows="4" placeholder="数据服务的详细介绍和内容范围..." :maxlength="1000" 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 type="primary" :loading="savingData" @click="saveData">💾 保存数据服务配置</a-button>
|
||
</div>
|
||
</a-form>
|
||
</template>
|
||
|
||
<!-- 📱 微信配置 -->
|
||
<template v-if="activeTab === 'wechat'">
|
||
<div class="settings-section-title">📱 微信公众号配置</div>
|
||
<a-form :model="wechatForm" layout="vertical" class="settings-form">
|
||
<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
|
||
accept="image/*"
|
||
:show-upload-list="false"
|
||
:before-upload="() => false"
|
||
@change="(info: any) => handleQrUpload(info)"
|
||
>
|
||
<a-button>上传二维码</a-button>
|
||
</a-upload>
|
||
<img v-if="wechatForm.qrcode" :src="wechatForm.qrcode" class="qrcode-preview" alt="公众号二维码" />
|
||
</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 type="primary" :loading="savingWechat" @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 type="info" message="数据备份建议每天执行一次,请联系运维人员配置自动备份" show-icon />
|
||
</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 setup lang="ts">
|
||
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>
|