141 lines
3.0 KiB
Vue
141 lines
3.0 KiB
Vue
<script setup>
|
||
import { ref, onMounted, onUnmounted } from 'vue'
|
||
import request from '../../utils/request.js'
|
||
|
||
const faqList = ref([])
|
||
const loading = ref(false)
|
||
const activeId = ref(null)
|
||
|
||
// 分页
|
||
const currentPage = ref(1)
|
||
const pageSize = ref(15)
|
||
const totalPage = ref(1)
|
||
const finished = ref(false)
|
||
|
||
// 获取列表
|
||
const getFaqList = async () => {
|
||
if (finished.value || loading.value) return
|
||
loading.value = true
|
||
|
||
try {
|
||
const res = await request({
|
||
url: '/go/api/h5/v1/other/get/question/list',
|
||
method: 'get',
|
||
params: {
|
||
page: currentPage.value,
|
||
page_size: pageSize.value
|
||
},
|
||
hideLoading: true
|
||
})
|
||
|
||
totalPage.value = res.total_page || 1
|
||
if (res.list?.length) {
|
||
faqList.value.push(...res.list)
|
||
}
|
||
|
||
// 判断是否还有下一页
|
||
if (currentPage.value >= totalPage.value) {
|
||
finished.value = true
|
||
} else {
|
||
currentPage.value += 1
|
||
}
|
||
} catch (err) {
|
||
console.error('获取FAQ失败', err)
|
||
} finally {
|
||
loading.value = false
|
||
}
|
||
}
|
||
|
||
// 切换展开/收起
|
||
const toggle = (id) => {
|
||
activeId.value = activeId.value === id ? null : id
|
||
}
|
||
|
||
// 滚动监听(触底加载)
|
||
const handleScroll = () => {
|
||
const scrollTop = document.documentElement.scrollTop || document.body.scrollTop
|
||
const clientHeight = document.documentElement.clientHeight
|
||
const scrollHeight = document.documentElement.scrollHeight
|
||
|
||
// 距离底部 100px 加载下一页
|
||
if (scrollTop + clientHeight + 100 >= scrollHeight) {
|
||
getFaqList()
|
||
}
|
||
}
|
||
|
||
onMounted(() => {
|
||
getFaqList()
|
||
window.addEventListener('scroll', handleScroll)
|
||
})
|
||
|
||
onUnmounted(() => {
|
||
window.removeEventListener('scroll', handleScroll)
|
||
})
|
||
</script>
|
||
|
||
<template>
|
||
<div class="faq-container">
|
||
<div v-for="item in faqList" :key="item.id" class="faq-item">
|
||
<div class="faq-title" @click="toggle(item.id)">
|
||
<span>{{ item.title }}</span>
|
||
<span class="arrow">{{ activeId === item.id ? '−' : '+' }}</span>
|
||
</div>
|
||
|
||
<div v-show="activeId === item.id" class="faq-content">
|
||
<div v-html="item.content"></div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 加载提示 -->
|
||
<div v-if="loading" class="loading-tip">加载中...</div>
|
||
<!-- <div v-if="finished && faqList.length > 0" class="finished-tip">已加载全部</div>-->
|
||
</div>
|
||
</template>
|
||
|
||
<style scoped>
|
||
.faq-container {
|
||
margin: 20px 0;
|
||
}
|
||
.faq-item {
|
||
margin-bottom: 12px;
|
||
border: 1px solid #eee;
|
||
border-radius: 8px;
|
||
overflow: hidden;
|
||
}
|
||
.faq-title {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
padding: 14px 16px;
|
||
background: #f9f9f9;
|
||
cursor: pointer;
|
||
font-weight: 500;
|
||
font-size: 15px;
|
||
}
|
||
.faq-title:hover {
|
||
background: #f3f3f3;
|
||
}
|
||
.arrow {
|
||
font-size: 18px;
|
||
font-weight: bold;
|
||
}
|
||
.faq-content {
|
||
padding: 16px;
|
||
line-height: 1.7;
|
||
}
|
||
.faq-content :deep(img) {
|
||
max-width: 100%;
|
||
height: auto;
|
||
margin: 10px 0;
|
||
}
|
||
.loading-tip {
|
||
padding: 16px;
|
||
text-align: center;
|
||
color: #666;
|
||
}
|
||
.finished-tip {
|
||
padding: 16px;
|
||
text-align: center;
|
||
color: #999;
|
||
}
|
||
</style>
|