hookehuyr

feat(helpCenter): 新增帮助中心页面及完整功能实现

实现帮助中心页面的完整功能,包括:
- 添加搜索框支持关键词搜索帮助内容
- 实现分类筛选功能
- 创建帮助列表展示及详情弹窗
- 设计完整的UI样式和交互逻辑
- 添加示例数据展示功能效果
<!--
* @Date: 2022-09-19 14:11:06
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2025-07-03 20:25:34
* @LastEditTime: 2025-07-03 20:54:14
* @FilePath: /jgdl/src/pages/feedBack/index.vue
* @Description: 意见反馈页面
-->
......
.red {
color: red;
// 帮助中心页面样式
.help-center-page {
background-color: #f5f5f5;
min-height: 100vh;
// ==================== 头部导航 ====================
.header {
display: flex;
align-items: center;
justify-content: space-between;
padding: 20rpx 30rpx;
background-color: #fff;
border-bottom: 1rpx solid #eee;
position: sticky;
top: 0;
z-index: 100;
.header-left {
display: flex;
align-items: center;
padding: 10rpx;
.back-text {
font-size: 28rpx;
color: #1890ff;
}
}
.header-title {
font-size: 36rpx;
font-weight: 600;
color: #333;
}
.header-right {
width: 56rpx; // 保持布局平衡
}
}
// ==================== 搜索框 ====================
.search-section {
padding: 30rpx;
background-color: #fff;
border-bottom: 1rpx solid #eee;
.search-box {
display: flex;
align-items: center;
background-color: #f8f8f8;
border-radius: 50rpx;
padding: 20rpx 30rpx;
border: 1rpx solid #e0e0e0;
.search-input {
flex: 1;
font-size: 28rpx;
color: #333;
background: transparent;
border: none;
outline: none;
&::placeholder {
color: #999;
}
}
}
}
// ==================== 分类选择 ====================
.category-section {
padding: 30rpx;
background-color: #fff;
margin-bottom: 20rpx;
.category-title {
font-size: 32rpx;
font-weight: 600;
color: #333;
margin-bottom: 30rpx;
}
.category-grid {
display: flex;
flex-wrap: wrap;
gap: 20rpx;
.category-item {
display: flex;
flex-direction: column;
align-items: center;
padding: 20rpx;
background-color: #f8f8f8;
border-radius: 20rpx;
border: 2rpx solid transparent;
transition: all 0.3s ease;
min-width: 120rpx;
&.active {
background-color: #e8f4fd;
border-color: #1890ff;
.category-name {
color: #1890ff;
}
}
.category-name {
font-size: 24rpx;
color: #666;
text-align: center;
transition: color 0.3s ease;
}
}
}
}
// ==================== 帮助列表 ====================
.help-list-section {
flex: 1;
background-color: #fff;
margin: 30rpx;
border-radius: 20rpx;
overflow: hidden;
.help-list {
.help-items {
.help-item {
display: flex;
align-items: center;
justify-content: space-between;
padding: 30rpx;
border-bottom: 1rpx solid #f0f0f0;
transition: background-color 0.3s ease;
&:last-child {
border-bottom: none;
}
&:active {
background-color: #f8f8f8;
}
.help-item-left {
display: flex;
align-items: center;
flex: 1;
.help-content {
flex: 1;
.help-title {
display: block;
font-size: 32rpx;
font-weight: 500;
color: #333;
margin-bottom: 10rpx;
line-height: 1.4;
}
.help-desc {
display: block;
font-size: 26rpx;
color: #666;
line-height: 1.4;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
}
}
.help-item-right {
.arrow-text {
font-size: 28rpx;
color: #ccc;
}
}
}
}
// 空状态
.empty-state {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 100rpx 30rpx;
.empty-text {
font-size: 28rpx;
color: #999;
}
}
}
}
// ==================== 右侧弹出详情 ====================
.detail-popup {
height: 100%;
background-color: #fff;
display: flex;
flex-direction: column;
// 详情头部
.detail-header {
display: flex;
align-items: center;
justify-content: space-between;
padding: 30rpx;
border-bottom: 1rpx solid #eee;
background-color: #fff;
position: sticky;
top: 0;
z-index: 10;
.detail-title {
font-size: 36rpx;
font-weight: 600;
color: #333;
flex: 1;
margin-right: 20rpx;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.close-btn {
padding: 10rpx;
.close-text {
font-size: 28rpx;
color: #1890ff;
}
}
}
// 详情内容
.detail-content {
flex: 1;
.detail-body {
padding: 30rpx;
.detail-section {
margin-bottom: 40rpx;
&:last-child {
margin-bottom: 0;
}
.section-title {
font-size: 32rpx;
font-weight: 600;
color: #333;
margin-bottom: 20rpx;
padding-bottom: 10rpx;
border-bottom: 2rpx solid #1890ff;
display: inline-block;
}
.section-content {
font-size: 28rpx;
color: #666;
line-height: 1.6;
display: block;
}
// 解决方案步骤
.solution-content {
.solution-step {
display: flex;
align-items: flex-start;
margin-bottom: 20rpx;
padding: 20rpx;
background-color: #f8f9fa;
border-radius: 12rpx;
border-left: 4rpx solid #1890ff;
&:last-child {
margin-bottom: 0;
}
.step-number {
width: 40rpx;
height: 40rpx;
background-color: #1890ff;
color: #fff;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
font-size: 24rpx;
font-weight: 600;
margin-right: 20rpx;
flex-shrink: 0;
}
.step-content {
font-size: 28rpx;
color: #333;
line-height: 1.5;
flex: 1;
}
}
}
// 相关链接
.related-links {
.related-link {
display: flex;
align-items: center;
justify-content: space-between;
padding: 20rpx;
background-color: #f8f9fa;
border-radius: 12rpx;
margin-bottom: 15rpx;
border: 1rpx solid #e9ecef;
transition: all 0.3s ease;
&:last-child {
margin-bottom: 0;
}
&:active {
background-color: #e9ecef;
}
.link-text {
font-size: 28rpx;
color: #1890ff;
flex: 1;
}
.link-arrow {
font-size: 24rpx;
color: #1890ff;
}
}
}
// 联系客服
.contact-section {
.contact-btn {
width: 100%;
display: flex;
align-items: center;
justify-content: center;
padding: 25rpx;
background: linear-gradient(135deg, #1890ff, #40a9ff);
color: #fff;
border: none;
border-radius: 50rpx;
font-size: 30rpx;
font-weight: 500;
transition: all 0.3s ease;
box-shadow: 0 4rpx 12rpx rgba(24, 144, 255, 0.3);
&:active {
transform: translateY(2rpx);
box-shadow: 0 2rpx 8rpx rgba(24, 144, 255, 0.3);
}
}
}
}
}
}
}
}
......
<!--
* @Date: 2022-09-19 14:11:06
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2025-07-02 14:50:57
* @FilePath: /jgdl/src/pages/demo/index.vue
* @Description: 文件描述
* @LastEditTime: 2025-07-03 20:52:12
* @FilePath: /jgdl/src/pages/helpCenter/index.vue
* @Description: 帮助中心页面
-->
<template>
<div class="red">{{ str }}</div>
<view class="help-center-page">
<!-- 搜索框 -->
<view class="search-section">
<view class="search-box">
<input
v-model="searchKeyword"
placeholder="搜索帮助内容"
class="search-input"
@input="handleSearch"
/>
</view>
</view>
<!-- 帮助分类 -->
<view class="category-section">
<view class="category-title">常见问题</view>
<view class="category-grid">
<view
v-for="category in categories"
:key="category.id"
class="category-item"
@click="filterByCategory(category.id)"
:class="{ active: selectedCategory === category.id }"
>
<text class="category-name">{{ category.name }}</text>
</view>
</view>
</view>
<!-- 帮助列表 -->
<view class="help-list-section">
<scroll-view
class="help-list"
:scroll-y="true"
:style="scrollStyle"
>
<view class="help-items">
<view
v-for="item in filteredHelpItems"
:key="item.id"
class="help-item"
@click="showHelpDetail(item)"
>
<view class="help-item-left">
<view class="help-content">
<text class="help-title">{{ item.title }}</text>
<text class="help-desc">{{ item.description }}</text>
</view>
</view>
<view class="help-item-right">
<text class="arrow-text"><RectRight /></text>
</view>
</view>
</view>
<!-- 空状态 -->
<view
v-if="filteredHelpItems.length === 0"
class="empty-state"
>
<text class="empty-text">暂无相关帮助内容</text>
</view>
</scroll-view>
</view>
<!-- 右侧弹出详情 -->
<nut-popup
v-model:visible="showDetailPopup"
position="right"
:style="{ width: '85%', height: '100%' }"
@close="closeDetail"
>
<view class="detail-popup">
<!-- 详情头部 -->
<view class="detail-header">
<view class="detail-title">{{ currentHelpItem?.title }}</view>
<view class="close-btn" @click="closeDetail">
<text class="close-text">关闭</text>
</view>
</view>
<!-- 详情内容 -->
<scroll-view class="detail-content" :scroll-y="true">
<view class="detail-body">
<!-- 问题描述 -->
<view class="detail-section">
<view class="section-title">问题描述</view>
<text class="section-content">{{ currentHelpItem?.description }}</text>
</view>
<!-- 解决方案 -->
<view class="detail-section">
<view class="section-title">解决方案</view>
<view class="solution-content">
<view
v-for="(step, index) in currentHelpItem?.solution"
:key="index"
class="solution-step"
>
<view class="step-number">{{ index + 1 }}</view>
<text class="step-content">{{ step }}</text>
</view>
</view>
</view>
<!-- 相关链接 -->
<!-- <view v-if="currentHelpItem?.relatedLinks?.length" class="detail-section">
<view class="section-title">相关链接</view>
<view class="related-links">
<view
v-for="link in currentHelpItem.relatedLinks"
:key="link.id"
class="related-link"
@click="openRelatedLink(link)"
>
<text class="link-text">{{ link.title }}</text>
<text class="link-arrow">></text>
</view>
</view>
</view> -->
<!-- 联系客服 -->
<!-- <view class="detail-section">
<view class="section-title">还有问题?</view>
<view class="contact-section">
<button class="contact-btn" @click="contactService">
<text>联系客服</text>
</button>
</view>
</view> -->
</view>
</scroll-view>
</view>
</nut-popup>
<!-- Toast提示 -->
<nut-toast
v-model:visible="toastVisible"
:msg="toastMessage"
:type="toastType"
/>
</view>
</template>
<script setup>
// import '@tarojs/taro/html.css'
import { ref } from "vue";
import "./index.less";
import { ref, computed, onMounted } from 'vue'
import Taro from '@tarojs/taro'
import { RectRight } from '@nutui/icons-vue-taro'
import './index.less'
// ==================== 响应式数据 ====================
/**
* 搜索关键词
*/
const searchKeyword = ref('')
/**
* 选中的分类
*/
const selectedCategory = ref('all')
/**
* 详情弹窗显示状态
*/
const showDetailPopup = ref(false)
/**
* 当前查看的帮助项
*/
const currentHelpItem = ref(null)
/**
* Toast提示
*/
const toastVisible = ref(false)
const toastMessage = ref('')
const toastType = ref('success')
/**
* 帮助分类数据
*/
const categories = ref([
{ id: 'all', name: '全部', icon: 'Ask' },
{ id: 'buy', name: '购买相关', icon: 'Ask' },
{ id: 'sell', name: '出售相关', icon: 'Ask' },
{ id: 'account', name: '账户问题', icon: 'Ask' },
{ id: 'safety', name: '安全保障', icon: 'Ask' }
])
/**
* 帮助事项数据
*/
const helpItems = ref([
{
id: 'h001',
category: 'buy',
icon: 'Ask',
title: '如何购买二手电动车?',
description: '详细介绍购买二手电动车的完整流程',
solution: [
'浏览车辆列表,选择心仪的电动车',
'查看车辆详情,包括图片、参数、价格等信息',
'联系卖家,预约看车时间',
'实地看车,检查车辆状况',
'确认购买,完成交易支付',
'办理过户手续,完成交易'
],
relatedLinks: [
{ id: 'l001', title: '车辆检查指南', url: '/pages/guide/inspection' },
{ id: 'l002', title: '交易安全须知', url: '/pages/guide/safety' }
]
},
{
id: 'h002',
category: 'sell',
icon: 'Ask',
title: '如何发布车辆信息?',
description: '学习如何正确发布您的二手电动车信息',
solution: [
'点击首页的"发布"按钮',
'上传车辆照片(正面、侧面、细节图)',
'填写车辆基本信息(品牌、型号、年份等)',
'设置合理的售价',
'添加车辆描述和联系方式',
'提交审核,等待发布'
],
relatedLinks: [
{ id: 'l003', title: '拍照技巧', url: '/pages/guide/photo' },
{ id: 'l004', title: '定价建议', url: '/pages/guide/pricing' }
]
},
{
id: 'h003',
category: 'buy',
icon: 'Ask',
title: '如何判断车辆质量?',
description: '教您如何识别二手电动车的质量好坏',
solution: [
'检查车辆外观是否有明显损伤',
'测试电池续航能力和充电效果',
'检查刹车系统是否正常',
'测试车辆行驶性能',
'查看车辆保养记录',
'确认车辆手续是否齐全'
]
},
{
id: 'h004',
category: 'account',
icon: 'Ask',
title: '如何完善个人资料?',
description: '完善个人资料有助于提高交易成功率',
solution: [
'进入个人中心页面',
'点击"编辑资料"按钮',
'上传真实头像照片',
'填写真实姓名和联系方式',
'完成实名认证',
'保存并提交资料'
]
},
{
id: 'h005',
category: 'safety',
icon: 'Ask',
title: '交易安全保障措施',
description: '了解平台提供的安全保障措施',
solution: [
'平台提供实名认证服务',
'支持第三方担保交易',
'提供车辆质量检测报告',
'建立用户信用评价体系',
'设立客服投诉处理机制',
'提供交易纠纷调解服务'
]
},
{
id: 'h006',
category: 'buy',
icon: 'Ask',
title: '如何预约看车?',
description: '学习如何与卖家预约看车时间和地点',
solution: [
'在车辆详情页点击"联系卖家"',
'通过平台消息或电话联系',
'协商看车时间和地点',
'确认看车安排',
'按时到达约定地点',
'仔细检查车辆状况'
]
},
{
id: 'h007',
category: 'sell',
icon: 'Ask',
title: '车辆过户流程',
description: '了解二手电动车过户的详细流程',
solution: [
'准备车辆登记证书',
'携带身份证和购车发票',
'前往车管所办理过户',
'填写过户申请表',
'缴纳过户费用',
'领取新的行驶证'
]
},
{
id: 'h008',
category: 'account',
icon: 'Ask',
title: '如何修改密码?',
description: '保护账户安全,定期修改登录密码',
solution: [
'进入个人中心',
'点击"账户设置"',
'选择"修改密码"',
'输入当前密码',
'设置新密码(至少8位)',
'确认新密码并保存'
]
}
])
/**
* 滚动样式
*/
const scrollStyle = computed(() => {
return {
height: 'calc(100vh - 260rpx)' // 减去header、搜索框、分类的高度
}
})
/**
* 过滤后的帮助事项
*/
const filteredHelpItems = computed(() => {
let items = helpItems.value
// 按分类过滤
if (selectedCategory.value !== 'all') {
items = items.filter(item => item.category === selectedCategory.value)
}
// 按搜索关键词过滤
if (searchKeyword.value.trim()) {
const keyword = searchKeyword.value.toLowerCase()
items = items.filter(item =>
item.title.toLowerCase().includes(keyword) ||
item.description.toLowerCase().includes(keyword)
)
}
return items
})
// ==================== 方法 ====================
/**
* 返回上一页
*/
const goBack = () => {
Taro.navigateBack()
}
/**
* 处理搜索
*/
const handleSearch = () => {
// 搜索逻辑已在computed中处理
}
/**
* 按分类过滤
*/
const filterByCategory = (categoryId) => {
selectedCategory.value = categoryId
}
/**
* 显示帮助详情
*/
const showHelpDetail = (item) => {
currentHelpItem.value = item
showDetailPopup.value = true
}
/**
* 关闭详情
*/
const closeDetail = () => {
showDetailPopup.value = false
currentHelpItem.value = null
}
/**
* 打开相关链接
*/
const openRelatedLink = (link) => {
// TODO: 根据实际需求跳转到相关页面
Toast.success(`即将跳转到:${link.title}`)
}
/**
* 联系客服
*/
const contactService = () => {
// TODO: 实现联系客服功能
Toast.success('正在为您转接客服...')
}
// 定义响应式数据
const str = ref('Demo页面')
// ==================== 生命周期 ====================
onMounted(() => {
// 页面初始化逻辑
})
</script>
<script>
export default {
name: "demoPage",
};
name: 'HelpCenterPage'
}
</script>
......
<!--
* @Date: 2025-06-28 10:33:00
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2025-07-03 17:58:15
* @LastEditTime: 2025-07-03 21:01:21
* @FilePath: /jgdl/src/pages/index/index.vue
* @Description: 捡个电驴首页
-->
......@@ -131,7 +131,7 @@
</view>
<view class="flex-1 p-3 relative">
<view class="absolute top-2 right-2" @tap.stop="() => toggleFavorite(scooter.id)">
<Heart1 v-if="!favoriteIds.includes(scooter.id)" size="16" :color="'#ffffff'" />
<Heart1 v-if="!favoriteIds.includes(scooter.id)" size="16" :color="'#9ca3af'" />
<HeartFill v-else size="16" :color="'#ef4444'" />
</view>
<text class="font-medium text-sm block">{{ scooter.name }}</text>
......