feat(community,faq): support dynamic community topics, notice, and FAQ center

这个提交包含在:
xcbyy
2026-10-10 10:04:49 +08:00
父节点 82ba59f373
当前提交 8845fbe7cb
共有 5 个文件被更改,包括 383 次插入 和 16 次删除

查看文件

@@ -1,7 +1,7 @@
<template>
<div class="container">
<Breadcrumb :items="['menu.safety', 'menu.safety.platformConfig']" />
<a-card class="general-card" :title="'平台客服与官方指引/协议运营配置'">
<a-card class="general-card" :title="'平台运营与内容指引配置中心'">
<template #extra>
<a-button type="primary" :loading="loading" @click="fetchConfigs">
<template #icon><icon-refresh /></template>
@@ -11,7 +11,7 @@
<a-tabs default-active-key="customer_service" type="rounded">
<!-- Tab 1: 官方客服配置 -->
<a-tab-pane key="customer_service" title="官方客服与热线配置">
<a-tab-pane key="customer_service" title="官方客服与热线">
<div class="tab-pane-content">
<a-alert type="info" style="margin-bottom: 20px">
在此配置小程序个人中心“官方在线客服”弹层的联系电话与专属微信号,支持即时保存生效。
@@ -53,7 +53,7 @@
</a-tab-pane>
<!-- Tab 2: 官方安全履约公告 -->
<a-tab-pane key="safety_notice" title="安全履约公告指引">
<a-tab-pane key="safety_notice" title="履约安全公告">
<div class="tab-pane-content">
<a-alert type="warning" style="margin-bottom: 20px">
在此配置小程序个人中心“平台消息与通知”弹层的履约安全指引与风险防范须知。
@@ -87,7 +87,7 @@
</a-tab-pane>
<!-- Tab 3: 用户服务协议与规范 -->
<a-tab-pane key="platform_protocol" title="平台规范与服务协议">
<a-tab-pane key="platform_protocol" title="平台规范协议">
<div class="tab-pane-content">
<a-alert type="success" style="margin-bottom: 20px">
在此配置“平台规范与服务协议”弹层的协议条款与合规内容,严格遵循微信内容安全风控标准。
@@ -122,6 +122,123 @@
</a-form>
</div>
</a-tab-pane>
<!-- Tab 4: 友圈热门话题与社区置顶公告 (P4) -->
<a-tab-pane key="community_config" title="友圈话题与头条公告">
<div class="tab-pane-content">
<a-alert type="info" style="margin-bottom: 20px">
在此管理友圈广场顶部头条横幅公告,以及移动端发布动态时的推荐热门话题库(支持HOT高亮)。
</a-alert>
<!-- 友圈置顶公告 -->
<a-card title="友圈顶部置顶头条公告" :bordered="false" style="margin-bottom: 24px; background: var(--color-fill-2)">
<a-form :model="commNoticeForm" layout="vertical" style="max-width: 750px">
<a-form-item label="头条公告标题">
<a-input v-model="commNoticeForm.valueJson.title" placeholder="如:友圈同城互动与公约置顶" />
</a-form-item>
<a-form-item label="活动角标/标签">
<a-input v-model="commNoticeForm.valueJson.tag" placeholder="如:置顶推荐 / 官方公告" />
</a-form-item>
<a-form-item label="公告详情内容">
<a-textarea v-model="commNoticeForm.valueJson.content" placeholder="输入公告内容" :auto-size="{ minRows: 3, maxRows: 6 }" />
</a-form-item>
<a-form-item label="启用横幅置顶展示">
<a-switch :checked-value="1" :unchecked-value="0" v-model="commNoticeForm.status" />
</a-form-item>
<a-form-item>
<a-button type="primary" :loading="saving" @click="saveConfig('community_notice', commNoticeForm)">
保存头条公告
</a-button>
</a-form-item>
</a-form>
</a-card>
<!-- 热门话题列表 -->
<a-card title="热门推荐话题库 (移动端发帖即选)" :bordered="false" style="background: var(--color-fill-2)">
<template #extra>
<a-button type="outline" size="small" @click="addTopicItem">
<template #icon><icon-plus /></template>
新增话题
</a-button>
</template>
<a-table :data="topicsList" :pagination="false" row-key="id">
<template #columns>
<a-table-column title="话题标签" :width="200">
<template #cell="{ record }">
<a-input v-model="record.name" placeholder="话题名称如: 三里屯探店" />
</template>
</a-table-column>
<a-table-column title="HOT高亮" :width="120" align="center">
<template #cell="{ record }">
<a-switch v-model="record.hot" />
</template>
</a-table-column>
<a-table-column title="讨论热度基数" :width="160">
<template #cell="{ record }">
<a-input-number v-model="record.postsCount" :min="0" />
</template>
</a-table-column>
<a-table-column title="操作" :width="100" align="center">
<template #cell="{ rowIndex }">
<a-button type="text" status="danger" size="small" @click="removeTopicItem(rowIndex)">
删除
</a-button>
</template>
</a-table-column>
</template>
</a-table>
<div style="margin-top: 16px">
<a-button type="primary" :loading="saving" @click="saveTopicsConfig">
保存热门话题库
</a-button>
</div>
</a-card>
</div>
</a-tab-pane>
<!-- Tab 5: 帮助中心与常见问题 FAQ (P5) -->
<a-tab-pane key="faq_config" title="帮助中心与常见问题">
<div class="tab-pane-content">
<a-alert type="success" style="margin-bottom: 20px">
在此维护小程序【常见问题与帮助中心】问答列表,解决买家组局履约、核销码流程、资金退款等高频疑惑。
</a-alert>
<a-card title="常见问题 FAQ 问答列表" :bordered="false" style="background: var(--color-fill-2)">
<template #extra>
<a-button type="outline" size="small" @click="addFaqItem">
<template #icon><icon-plus /></template>
新增问答
</a-button>
</template>
<div v-for="(item, idx) in faqList" :key="item.id || idx" style="margin-bottom: 16px; padding: 16px; background: var(--color-bg-2); border-radius: 6px;">
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 10px;">
<a-space>
<a-tag color="blue">问答 #{{ idx + 1 }}</a-tag>
<a-input v-model="item.category" placeholder="分类如: 新手预约/资金退款" style="width: 180px;" />
</a-space>
<a-button type="text" status="danger" size="small" @click="removeFaqItem(idx)">删除问答</a-button>
</div>
<a-form layout="vertical">
<a-form-item label="问题 (Title)">
<a-input v-model="item.question" placeholder="如:什么是4位纯数字核销码?" />
</a-form-item>
<a-form-item label="回答解答 (Answer)">
<a-textarea v-model="item.answer" placeholder="输入权威解答内容" :auto-size="{ minRows: 2, maxRows: 5 }" />
</a-form-item>
</a-form>
</div>
<div style="margin-top: 16px">
<a-button type="primary" :loading="saving" @click="saveFaqConfig">
保存帮助中心 FAQ
</a-button>
</div>
</a-card>
</div>
</a-tab-pane>
</a-tabs>
</a-card>
</div>
@@ -175,6 +292,50 @@ const protoForm = reactive({
}
});
// P4 友圈配置
const commNoticeForm = reactive({
name: '友圈社区置顶头条公告',
description: '友圈广场顶部置顶横幅公告与社区公约',
status: 1,
valueJson: {
title: '友圈同城互动与公约置顶',
content: '欢迎来到同城搭子友圈!文明交友,发布真实组局诉求;平台全天候对动态与评论实施微信官方内容安全过滤,严禁广告引流及私下交易。',
tag: '置顶推荐',
showInBanner: true
}
});
const topicsList = ref<any[]>([]);
const addTopicItem = () => {
topicsList.value.push({
id: `top_${Date.now()}`,
name: '新同城话题',
hot: false,
postsCount: 100
});
};
const removeTopicItem = (index: number) => {
topicsList.value.splice(index, 1);
};
// P5 帮助中心 FAQ
const faqList = ref<any[]>([]);
const addFaqItem = () => {
faqList.value.push({
id: `faq_${Date.now()}`,
category: '新手预约与组局',
question: '新常见问题',
answer: '在此输入权威官方解答...'
});
};
const removeFaqItem = (index: number) => {
faqList.value.splice(index, 1);
};
const fetchConfigs = async () => {
loading.value = true;
try {
@@ -199,6 +360,15 @@ const fetchConfigs = async () => {
protoForm.description = item.description;
protoForm.status = item.status;
protoForm.valueJson = { ...protoForm.valueJson, ...(item.valueJson || {}) };
} else if (item.configKey === 'community_notice') {
commNoticeForm.name = item.name;
commNoticeForm.description = item.description;
commNoticeForm.status = item.status;
commNoticeForm.valueJson = { ...commNoticeForm.valueJson, ...(item.valueJson || {}) };
} else if (item.configKey === 'community_topics') {
topicsList.value = Array.isArray(item.valueJson) ? item.valueJson : [];
} else if (item.configKey === 'faq_list') {
faqList.value = Array.isArray(item.valueJson) ? item.valueJson : [];
}
});
}
@@ -241,6 +411,24 @@ const saveNoticeConfig = () => {
saveConfig('safety_notice', noticeForm);
};
const saveTopicsConfig = () => {
saveConfig('community_topics', {
name: '友圈热门推荐话题库',
description: '友圈广场发帖推荐话题与热门标签',
status: 1,
valueJson: topicsList.value
});
};
const saveFaqConfig = () => {
saveConfig('faq_list', {
name: '帮助中心与常见问题FAQ',
description: '小程序端帮助中心常见问答与指引',
status: 1,
valueJson: faqList.value
});
};
onMounted(() => {
fetchConfigs();
});