team member 分页修改
This commit is contained in:
parent
20a0e462aa
commit
8ff23c000e
@ -3,11 +3,20 @@ import {get, post} from '../utils/http.js'
|
|||||||
/**
|
/**
|
||||||
* 获取团队成员列表
|
* 获取团队成员列表
|
||||||
* @param {string} teamId - 团队ID
|
* @param {string} teamId - 团队ID
|
||||||
|
* @param {object} params - 可选参数,包含lastId等分页参数
|
||||||
* @returns {Promise}
|
* @returns {Promise}
|
||||||
*/
|
*/
|
||||||
export const getTeamMembers = async (teamId) => {
|
export const getTeamMembers = async (teamId, params = {}) => {
|
||||||
try {
|
try {
|
||||||
const response = await get(`/team/members?id=${teamId}`)
|
// 构建查询参数
|
||||||
|
const queryParams = new URLSearchParams({ id: teamId })
|
||||||
|
console.log('params', queryParams)
|
||||||
|
// 添加分页参数
|
||||||
|
if (params.lastId) {
|
||||||
|
queryParams.append('lastId', params.lastId)
|
||||||
|
}
|
||||||
|
|
||||||
|
const response = await get(`/team/members?${queryParams.toString()}`)
|
||||||
return response
|
return response
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Failed to fetch team members:', error)
|
console.error('Failed to fetch team members:', error)
|
||||||
@ -17,11 +26,24 @@ export const getTeamMembers = async (teamId) => {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取BD代理商列表
|
* 获取BD代理商列表
|
||||||
|
* @param {object} params - 可选参数,包含lastId等分页参数
|
||||||
* @returns {Promise}
|
* @returns {Promise}
|
||||||
*/
|
*/
|
||||||
export const getBdAgentList = async () => {
|
export const getBdAgentList = async (params = {}) => {
|
||||||
try {
|
try {
|
||||||
const response = await get('/team/bd/bd-agent/list')
|
// 构建查询参数
|
||||||
|
const queryParams = new URLSearchParams()
|
||||||
|
|
||||||
|
// 添加分页参数
|
||||||
|
if (params.lastId) {
|
||||||
|
queryParams.append('lastId', params.lastId)
|
||||||
|
}
|
||||||
|
|
||||||
|
const url = queryParams.toString()
|
||||||
|
? `/team/bd/bd-agent/list?${queryParams.toString()}`
|
||||||
|
: '/team/bd/bd-agent/list'
|
||||||
|
|
||||||
|
const response = await get(url)
|
||||||
return response
|
return response
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Failed to fetch BD agent list:', error)
|
console.error('Failed to fetch BD agent list:', error)
|
||||||
|
|||||||
@ -10,7 +10,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 成员列表 -->
|
<!-- 成员列表 -->
|
||||||
<div v-else-if="members.length > 0" class="member-list">
|
<div v-else-if="members.length > 0" class="member-list" ref="memberListRef">
|
||||||
<div
|
<div
|
||||||
v-for="member in members"
|
v-for="member in members"
|
||||||
:key="member.id"
|
:key="member.id"
|
||||||
@ -41,6 +41,20 @@
|
|||||||
<span v-else>🗑️</span>
|
<span v-else>🗑️</span>
|
||||||
</button>-->
|
</button>-->
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- 加载更多状态 -->
|
||||||
|
<div v-if="loadingMore" class="loading-more">
|
||||||
|
<div class="loading-spinner small"></div>
|
||||||
|
<p>Loading more...</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 没有更多数据提示 -->
|
||||||
|
<div v-else-if="noMoreData && members.length > 0" class="no-more-data">
|
||||||
|
<p>No more members</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 无形的加载触发器 -->
|
||||||
|
<div v-if="!noMoreData && members.length > 0" ref="loadMoreTrigger" class="load-more-trigger"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 空状态 -->
|
<!-- 空状态 -->
|
||||||
@ -72,7 +86,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, onMounted } from 'vue'
|
import { ref, onMounted, nextTick, onUnmounted } from 'vue'
|
||||||
import { useRouter, useRoute } from 'vue-router'
|
import { useRouter, useRoute } from 'vue-router'
|
||||||
import MobileHeader from '../components/MobileHeader.vue'
|
import MobileHeader from '../components/MobileHeader.vue'
|
||||||
import {
|
import {
|
||||||
@ -91,6 +105,14 @@ const membersTotal = ref(0)
|
|||||||
const deletingMemberId = ref(null)
|
const deletingMemberId = ref(null)
|
||||||
const showDeleteModal = ref(false)
|
const showDeleteModal = ref(false)
|
||||||
const memberToDelete = ref(null)
|
const memberToDelete = ref(null)
|
||||||
|
const memberListRef = ref(null)
|
||||||
|
|
||||||
|
// 分页相关状态
|
||||||
|
const loadingMore = ref(false)
|
||||||
|
const noMoreData = ref(false)
|
||||||
|
const lastId = ref(null)
|
||||||
|
const intersectionObserver = ref(null)
|
||||||
|
const loadMoreTrigger = ref(null)
|
||||||
|
|
||||||
// 检查是否来自BD Center
|
// 检查是否来自BD Center
|
||||||
const isFromBdCenter = ref(false)
|
const isFromBdCenter = ref(false)
|
||||||
@ -103,30 +125,76 @@ const fetchTeamTotal = async () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 获取团队成员列表
|
// 获取团队成员列表
|
||||||
const fetchTeamMembers = async () => {
|
const fetchTeamMembers = async (isLoadMore = false) => {
|
||||||
try {
|
try {
|
||||||
loading.value = true
|
if (isLoadMore) {
|
||||||
|
loadingMore.value = true
|
||||||
|
} else {
|
||||||
|
loading.value = true
|
||||||
|
// 重新开始时清除分页状态
|
||||||
|
lastId.value = null
|
||||||
|
noMoreData.value = false
|
||||||
|
}
|
||||||
|
|
||||||
let response
|
let response
|
||||||
|
const params = {}
|
||||||
|
if (lastId.value) {
|
||||||
|
params.lastId = lastId.value
|
||||||
|
}
|
||||||
|
|
||||||
if (isFromBdCenter.value) {
|
if (isFromBdCenter.value) {
|
||||||
// 如果来自BD Center,调用BD代理商列表接口
|
// BD代理商列表也支持分页
|
||||||
response = await getBdAgentList()
|
response = await getBdAgentList(params)
|
||||||
} else {
|
} else {
|
||||||
// 否则调用普通团队成员接口
|
// 普通团队成员接口分页
|
||||||
const teamId = getTeamId()
|
const teamId = getTeamId()
|
||||||
response = await getTeamMembers(teamId)
|
response = await getTeamMembers(teamId, params)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (response.status && response.body) {
|
if (response.status && response.body) {
|
||||||
members.value = response.body || []
|
const newMembers = response.body || []
|
||||||
|
|
||||||
|
if (isLoadMore) {
|
||||||
|
// 加载更多时,追加到现有列表
|
||||||
|
members.value = [...members.value, ...newMembers]
|
||||||
|
} else {
|
||||||
|
// 初始加载时,替换列表
|
||||||
|
members.value = newMembers
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新lastId用于下次分页
|
||||||
|
if (newMembers.length > 0) {
|
||||||
|
lastId.value = newMembers[newMembers.length - 1].id
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果返回的数据少于预期(比如少于20条),说明没有更多数据
|
||||||
|
// 这里假设每页显示20条,你可以根据实际API调整
|
||||||
|
if (newMembers.length < 20) {
|
||||||
|
noMoreData.value = true
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('Fetched members:', {
|
||||||
|
isLoadMore,
|
||||||
|
newCount: newMembers.length,
|
||||||
|
totalCount: members.value.length,
|
||||||
|
lastId: lastId.value,
|
||||||
|
noMoreData: noMoreData.value
|
||||||
|
})
|
||||||
} else {
|
} else {
|
||||||
members.value = []
|
if (!isLoadMore) {
|
||||||
|
members.value = []
|
||||||
|
}
|
||||||
|
noMoreData.value = true
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Failed to fetch team members:', error)
|
console.error('Failed to fetch team members:', error)
|
||||||
members.value = []
|
if (!isLoadMore) {
|
||||||
|
members.value = []
|
||||||
|
}
|
||||||
|
showError('Failed to load team members')
|
||||||
} finally {
|
} finally {
|
||||||
loading.value = false
|
loading.value = false
|
||||||
|
loadingMore.value = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -146,7 +214,7 @@ const formatAccount = (userProfile) => {
|
|||||||
// 处理图片加载错误
|
// 处理图片加载错误
|
||||||
const handleImageError = (event) => {
|
const handleImageError = (event) => {
|
||||||
event.target.style.display = 'none'
|
event.target.style.display = 'none'
|
||||||
event.target.nextElementSibling.style.display = 'flex'
|
// event.target.nextElementSibling.style.display = 'flex'
|
||||||
}
|
}
|
||||||
|
|
||||||
// 关闭删除模态框
|
// 关闭删除模态框
|
||||||
@ -180,12 +248,103 @@ const confirmDelete = async () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 监听滚动事件
|
||||||
|
const handleScroll = () => {
|
||||||
|
console.log('handleScroll triggered')
|
||||||
|
|
||||||
|
if (loadingMore.value || noMoreData.value) {
|
||||||
|
console.log('Skip loading:', { loadingMore: loadingMore.value, noMoreData: noMoreData.value })
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const scrollTop = window.pageYOffset || document.documentElement.scrollTop
|
||||||
|
const windowHeight = window.innerHeight
|
||||||
|
const documentHeight = document.documentElement.scrollHeight
|
||||||
|
|
||||||
|
console.log('Scroll info:', {
|
||||||
|
scrollTop,
|
||||||
|
windowHeight,
|
||||||
|
documentHeight,
|
||||||
|
distanceToBottom: documentHeight - (scrollTop + windowHeight)
|
||||||
|
})
|
||||||
|
|
||||||
|
// 当滚动到距离底部100px时开始加载
|
||||||
|
if (scrollTop + windowHeight >= documentHeight - 100) {
|
||||||
|
console.log('Triggering load more')
|
||||||
|
fetchTeamMembers(true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置 Intersection Observer
|
||||||
|
const setupIntersectionObserver = () => {
|
||||||
|
if (!loadMoreTrigger.value) return
|
||||||
|
|
||||||
|
intersectionObserver.value = new IntersectionObserver(
|
||||||
|
(entries) => {
|
||||||
|
const entry = entries[0]
|
||||||
|
console.log('Intersection observer triggered:', entry.isIntersecting)
|
||||||
|
|
||||||
|
if (entry.isIntersecting && !loadingMore.value && !noMoreData.value) {
|
||||||
|
console.log('Loading more via intersection observer')
|
||||||
|
fetchTeamMembers(true)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
rootMargin: '100px'
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
intersectionObserver.value.observe(loadMoreTrigger.value)
|
||||||
|
console.log('Intersection observer set up')
|
||||||
|
}
|
||||||
|
|
||||||
// 组件挂载时获取数据
|
// 组件挂载时获取数据
|
||||||
onMounted(() => {
|
onMounted(async () => {
|
||||||
|
console.log('Component mounted')
|
||||||
|
|
||||||
// 检查是否来自BD Center
|
// 检查是否来自BD Center
|
||||||
isFromBdCenter.value = route.query.source === 'bd-center'
|
isFromBdCenter.value = route.query.source === 'bd-center'
|
||||||
fetchTeamMembers()
|
|
||||||
fetchTeamTotal()
|
await fetchTeamMembers()
|
||||||
|
await fetchTeamTotal()
|
||||||
|
|
||||||
|
// 添加滚动监听
|
||||||
|
await nextTick()
|
||||||
|
|
||||||
|
console.log('Adding scroll listener')
|
||||||
|
window.addEventListener('scroll', handleScroll, { passive: true })
|
||||||
|
|
||||||
|
// 也监听 document 的滚动
|
||||||
|
document.addEventListener('scroll', handleScroll, { passive: true })
|
||||||
|
|
||||||
|
// 设置 Intersection Observer
|
||||||
|
setTimeout(() => {
|
||||||
|
setupIntersectionObserver()
|
||||||
|
|
||||||
|
const windowHeight = window.innerHeight
|
||||||
|
const documentHeight = document.documentElement.scrollHeight
|
||||||
|
console.log('Page height check:', {
|
||||||
|
windowHeight,
|
||||||
|
documentHeight,
|
||||||
|
hasScroll: documentHeight > windowHeight
|
||||||
|
})
|
||||||
|
|
||||||
|
// 如果页面没有滚动条,但是数据不多,可能需要加载更多
|
||||||
|
if (documentHeight <= windowHeight + 50 && !noMoreData.value && members.value.length > 0) {
|
||||||
|
console.log('Auto loading more due to insufficient content height')
|
||||||
|
fetchTeamMembers(true)
|
||||||
|
}
|
||||||
|
}, 500)
|
||||||
|
})
|
||||||
|
|
||||||
|
// 组件卸载时清理监听器
|
||||||
|
onUnmounted(() => {
|
||||||
|
window.removeEventListener('scroll', handleScroll)
|
||||||
|
document.removeEventListener('scroll', handleScroll)
|
||||||
|
|
||||||
|
if (intersectionObserver.value) {
|
||||||
|
intersectionObserver.value.disconnect()
|
||||||
|
}
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@ -221,11 +380,48 @@ onMounted(() => {
|
|||||||
margin-bottom: 12px;
|
margin-bottom: 12px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.loading-spinner.small {
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
border-width: 2px;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
@keyframes spin {
|
@keyframes spin {
|
||||||
0% { transform: rotate(0deg); }
|
0% { transform: rotate(0deg); }
|
||||||
100% { transform: rotate(360deg); }
|
100% { transform: rotate(360deg); }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 加载更多状态 */
|
||||||
|
.loading-more {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
padding: 20px;
|
||||||
|
color: #666;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 没有更多数据提示 */
|
||||||
|
.no-more-data {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
padding: 20px;
|
||||||
|
color: #999;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.no-more-data p {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 加载触发器 */
|
||||||
|
.load-more-trigger {
|
||||||
|
height: 1px;
|
||||||
|
width: 100%;
|
||||||
|
margin: 10px 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* 成员列表 */
|
/* 成员列表 */
|
||||||
.member-list {
|
.member-list {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user