|
|
|
|
@@ -0,0 +1,259 @@
|
|
|
|
|
<template>
|
|
|
|
|
<div class="container">
|
|
|
|
|
<Breadcrumb :items="['menu.safety', 'menu.safety.platformConfig']" />
|
|
|
|
|
<a-card class="general-card" :title="'平台客服与官方指引/协议运营配置'">
|
|
|
|
|
<template #extra>
|
|
|
|
|
<a-button type="primary" :loading="loading" @click="fetchConfigs">
|
|
|
|
|
<template #icon><icon-refresh /></template>
|
|
|
|
|
刷新配置
|
|
|
|
|
</a-button>
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
<a-tabs default-active-key="customer_service" type="rounded">
|
|
|
|
|
<!-- Tab 1: 官方客服配置 -->
|
|
|
|
|
<a-tab-pane key="customer_service" title="官方客服与热线配置">
|
|
|
|
|
<div class="tab-pane-content">
|
|
|
|
|
<a-alert type="info" style="margin-bottom: 20px">
|
|
|
|
|
在此配置小程序个人中心“官方在线客服”弹层的联系电话与专属微信号,支持即时保存生效。
|
|
|
|
|
</a-alert>
|
|
|
|
|
|
|
|
|
|
<a-form :model="csForm" layout="vertical" style="max-width: 650px">
|
|
|
|
|
<a-form-item label="配置名称">
|
|
|
|
|
<a-input v-model="csForm.name" placeholder="如:官方在线客服与服务热线" />
|
|
|
|
|
</a-form-item>
|
|
|
|
|
<a-form-item label="7x24h 官方客服服务热线">
|
|
|
|
|
<a-input v-model="csForm.valueJson.hotline" placeholder="例如:400-888-6666" />
|
|
|
|
|
</a-form-item>
|
|
|
|
|
<a-form-item label="热线展示说明">
|
|
|
|
|
<a-input v-model="csForm.valueJson.hotlineDesc" placeholder="例如:7x24h 官方客服服务热线" />
|
|
|
|
|
</a-form-item>
|
|
|
|
|
<a-form-item label="官方 VIP 客服微信号">
|
|
|
|
|
<a-input v-model="csForm.valueJson.wechat" placeholder="例如:peiwan_vip_kefu" />
|
|
|
|
|
</a-form-item>
|
|
|
|
|
<a-form-item label="微信号展示说明">
|
|
|
|
|
<a-input v-model="csForm.valueJson.wechatDesc" placeholder="例如:官方 VIP 客服微信号" />
|
|
|
|
|
</a-form-item>
|
|
|
|
|
<a-form-item label="客服服务时间">
|
|
|
|
|
<a-input v-model="csForm.valueJson.workHours" placeholder="例如:周一至周日 00:00 - 24:00" />
|
|
|
|
|
</a-form-item>
|
|
|
|
|
<a-form-item label="启用状态">
|
|
|
|
|
<a-switch
|
|
|
|
|
:checked-value="1"
|
|
|
|
|
:unchecked-value="0"
|
|
|
|
|
v-model="csForm.status"
|
|
|
|
|
/>
|
|
|
|
|
</a-form-item>
|
|
|
|
|
<a-form-item>
|
|
|
|
|
<a-button type="primary" :loading="saving" @click="saveConfig('customer_service', csForm)">
|
|
|
|
|
保存客服配置
|
|
|
|
|
</a-button>
|
|
|
|
|
</a-form-item>
|
|
|
|
|
</a-form>
|
|
|
|
|
</div>
|
|
|
|
|
</a-tab-pane>
|
|
|
|
|
|
|
|
|
|
<!-- Tab 2: 官方安全履约公告 -->
|
|
|
|
|
<a-tab-pane key="safety_notice" title="安全履约公告指引">
|
|
|
|
|
<div class="tab-pane-content">
|
|
|
|
|
<a-alert type="warning" style="margin-bottom: 20px">
|
|
|
|
|
在此配置小程序个人中心“平台消息与通知”弹层的履约安全指引与风险防范须知。
|
|
|
|
|
</a-alert>
|
|
|
|
|
|
|
|
|
|
<a-form :model="noticeForm" layout="vertical" style="max-width: 750px">
|
|
|
|
|
<a-form-item label="公告标题">
|
|
|
|
|
<a-input v-model="noticeForm.valueJson.title" placeholder="如:平台官方公告与指引" />
|
|
|
|
|
</a-form-item>
|
|
|
|
|
<a-form-item label="安全须知要点 (每行一条)">
|
|
|
|
|
<a-textarea
|
|
|
|
|
v-model="noticePointsText"
|
|
|
|
|
placeholder="每行一条须知要点"
|
|
|
|
|
:auto-size="{ minRows: 5, maxRows: 10 }"
|
|
|
|
|
/>
|
|
|
|
|
</a-form-item>
|
|
|
|
|
<a-form-item label="启用状态">
|
|
|
|
|
<a-switch
|
|
|
|
|
:checked-value="1"
|
|
|
|
|
:unchecked-value="0"
|
|
|
|
|
v-model="noticeForm.status"
|
|
|
|
|
/>
|
|
|
|
|
</a-form-item>
|
|
|
|
|
<a-form-item>
|
|
|
|
|
<a-button type="primary" :loading="saving" @click="saveNoticeConfig">
|
|
|
|
|
保存公告指引
|
|
|
|
|
</a-button>
|
|
|
|
|
</a-form-item>
|
|
|
|
|
</a-form>
|
|
|
|
|
</div>
|
|
|
|
|
</a-tab-pane>
|
|
|
|
|
|
|
|
|
|
<!-- Tab 3: 用户服务协议与规范 -->
|
|
|
|
|
<a-tab-pane key="platform_protocol" title="平台规范与服务协议">
|
|
|
|
|
<div class="tab-pane-content">
|
|
|
|
|
<a-alert type="success" style="margin-bottom: 20px">
|
|
|
|
|
在此配置“平台规范与服务协议”弹层的协议条款与合规内容,严格遵循微信内容安全风控标准。
|
|
|
|
|
</a-alert>
|
|
|
|
|
|
|
|
|
|
<a-form :model="protoForm" layout="vertical" style="max-width: 800px">
|
|
|
|
|
<a-form-item label="协议标题">
|
|
|
|
|
<a-input v-model="protoForm.valueJson.title" placeholder="如:用户服务协议与隐私规范" />
|
|
|
|
|
</a-form-item>
|
|
|
|
|
<a-form-item label="协议摘要概要">
|
|
|
|
|
<a-input v-model="protoForm.valueJson.summary" placeholder="协议概要,一两句话总结" />
|
|
|
|
|
</a-form-item>
|
|
|
|
|
<a-form-item label="服务协议全文内容">
|
|
|
|
|
<a-textarea
|
|
|
|
|
v-model="protoForm.valueJson.content"
|
|
|
|
|
placeholder="请输入完整协议条款"
|
|
|
|
|
:auto-size="{ minRows: 8, maxRows: 15 }"
|
|
|
|
|
/>
|
|
|
|
|
</a-form-item>
|
|
|
|
|
<a-form-item label="启用状态">
|
|
|
|
|
<a-switch
|
|
|
|
|
:checked-value="1"
|
|
|
|
|
:unchecked-value="0"
|
|
|
|
|
v-model="protoForm.status"
|
|
|
|
|
/>
|
|
|
|
|
</a-form-item>
|
|
|
|
|
<a-form-item>
|
|
|
|
|
<a-button type="primary" :loading="saving" @click="saveConfig('platform_protocol', protoForm)">
|
|
|
|
|
保存协议规范
|
|
|
|
|
</a-button>
|
|
|
|
|
</a-form-item>
|
|
|
|
|
</a-form>
|
|
|
|
|
</div>
|
|
|
|
|
</a-tab-pane>
|
|
|
|
|
</a-tabs>
|
|
|
|
|
</a-card>
|
|
|
|
|
</div>
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
<script lang="ts" setup>
|
|
|
|
|
import { ref, reactive, onMounted } from 'vue';
|
|
|
|
|
import { Message } from '@arco-design/web-vue';
|
|
|
|
|
import axios from 'axios';
|
|
|
|
|
|
|
|
|
|
const loading = ref(false);
|
|
|
|
|
const saving = ref(false);
|
|
|
|
|
|
|
|
|
|
const csForm = reactive({
|
|
|
|
|
name: '官方在线客服与服务热线',
|
|
|
|
|
description: '小程序端个人中心客服联系方式',
|
|
|
|
|
status: 1,
|
|
|
|
|
valueJson: {
|
|
|
|
|
hotline: '400-888-6666',
|
|
|
|
|
hotlineDesc: '7x24h 官方客服服务热线',
|
|
|
|
|
wechat: 'peiwan_vip_kefu',
|
|
|
|
|
wechatDesc: '官方 VIP 客服微信号',
|
|
|
|
|
workHours: '周一至周日 00:00 - 24:00'
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
const noticeForm = reactive({
|
|
|
|
|
name: '安全履约须知与官方公告',
|
|
|
|
|
description: '小程序端官方指引与安全红线弹窗',
|
|
|
|
|
status: 1,
|
|
|
|
|
valueJson: {
|
|
|
|
|
title: '平台官方公告与指引',
|
|
|
|
|
points: [
|
|
|
|
|
'【安全履约须知】为保障搭子与陪伴师人身与财产安全,线下约局须在合规公开商业街区进行。',
|
|
|
|
|
'【现场核销】现场碰面后请出示 4 位数字核销码进行签到确认。',
|
|
|
|
|
'【平台兜底】平台提供 7x24 小时争议仲裁与资金托管保障服务,严禁脱离平台私下交易。'
|
|
|
|
|
]
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
const noticePointsText = ref('');
|
|
|
|
|
|
|
|
|
|
const protoForm = reactive({
|
|
|
|
|
name: '平台服务协议与合规规范',
|
|
|
|
|
description: '小程序端服务协议与隐私政策详情',
|
|
|
|
|
status: 1,
|
|
|
|
|
valueJson: {
|
|
|
|
|
title: '用户服务协议与隐私规范',
|
|
|
|
|
summary: '严禁发布任何违规言论及低俗诈骗行为,平台全面遵循微信内容安全风控与用户隐私保护标准。',
|
|
|
|
|
content: ''
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
const fetchConfigs = async () => {
|
|
|
|
|
loading.value = true;
|
|
|
|
|
try {
|
|
|
|
|
const { data: res } = await axios.get('/api/admin/system/configs');
|
|
|
|
|
if (res && res.code === 20000 && Array.isArray(res.data)) {
|
|
|
|
|
res.data.forEach((item: any) => {
|
|
|
|
|
if (item.configKey === 'customer_service') {
|
|
|
|
|
csForm.name = item.name;
|
|
|
|
|
csForm.description = item.description;
|
|
|
|
|
csForm.status = item.status;
|
|
|
|
|
csForm.valueJson = { ...csForm.valueJson, ...(item.valueJson || {}) };
|
|
|
|
|
} else if (item.configKey === 'safety_notice') {
|
|
|
|
|
noticeForm.name = item.name;
|
|
|
|
|
noticeForm.description = item.description;
|
|
|
|
|
noticeForm.status = item.status;
|
|
|
|
|
noticeForm.valueJson = { ...noticeForm.valueJson, ...(item.valueJson || {}) };
|
|
|
|
|
if (Array.isArray(noticeForm.valueJson.points)) {
|
|
|
|
|
noticePointsText.value = noticeForm.valueJson.points.join('\n');
|
|
|
|
|
}
|
|
|
|
|
} else if (item.configKey === 'platform_protocol') {
|
|
|
|
|
protoForm.name = item.name;
|
|
|
|
|
protoForm.description = item.description;
|
|
|
|
|
protoForm.status = item.status;
|
|
|
|
|
protoForm.valueJson = { ...protoForm.valueJson, ...(item.valueJson || {}) };
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
} catch (err: any) {
|
|
|
|
|
Message.error(err.response?.data?.message || '获取系统配置失败');
|
|
|
|
|
} finally {
|
|
|
|
|
loading.value = false;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const saveConfig = async (key: string, form: any) => {
|
|
|
|
|
saving.value = true;
|
|
|
|
|
try {
|
|
|
|
|
const payload = {
|
|
|
|
|
name: form.name,
|
|
|
|
|
description: form.description,
|
|
|
|
|
status: form.status,
|
|
|
|
|
valueJson: form.valueJson
|
|
|
|
|
};
|
|
|
|
|
const { data: res } = await axios.put(`/api/admin/system/configs/${key}`, payload);
|
|
|
|
|
if (res && res.code === 20000) {
|
|
|
|
|
Message.success('配置已保存并同步至小程序端');
|
|
|
|
|
fetchConfigs();
|
|
|
|
|
} else {
|
|
|
|
|
Message.error(res?.message || '保存配置失败');
|
|
|
|
|
}
|
|
|
|
|
} catch (err: any) {
|
|
|
|
|
Message.error(err.response?.data?.message || '保存配置异常,请检查内容是否含敏感词');
|
|
|
|
|
} finally {
|
|
|
|
|
saving.value = false;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const saveNoticeConfig = () => {
|
|
|
|
|
const points = noticePointsText.value
|
|
|
|
|
.split('\n')
|
|
|
|
|
.map((p) => p.trim())
|
|
|
|
|
.filter((p) => Boolean(p));
|
|
|
|
|
noticeForm.valueJson.points = points;
|
|
|
|
|
saveConfig('safety_notice', noticeForm);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
onMounted(() => {
|
|
|
|
|
fetchConfigs();
|
|
|
|
|
});
|
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
<style scoped lang="less">
|
|
|
|
|
.container {
|
|
|
|
|
padding: 0 20px 20px 20px;
|
|
|
|
|
}
|
|
|
|
|
.general-card {
|
|
|
|
|
border-radius: 4px;
|
|
|
|
|
}
|
|
|
|
|
.tab-pane-content {
|
|
|
|
|
padding: 16px 8px;
|
|
|
|
|
}
|
|
|
|
|
</style>
|