refactor: standardize pagination response structure and enhance cursor handling
- Update various services and hooks to replace 'items' with 'list' for consistency in pagination responses. - Modify PostRepository, commentService, groupService, messageService, and postService to align with the new response structure. - Enhance cursor pagination logic in hooks and components to ensure proper handling of pagination states. - Refactor HomeScreen, PostDetailScreen, SearchScreen, and other components to utilize the updated pagination structure.
This commit is contained in:
@@ -255,15 +255,18 @@ class CommentService {
|
||||
params: CursorPaginationRequest = {}
|
||||
): Promise<CursorPaginationResponse<Comment>> {
|
||||
try {
|
||||
const response = await api.get<CursorPaginationResponse<Comment>>(
|
||||
`/comments/post/${postId}/cursor`,
|
||||
{ params }
|
||||
);
|
||||
return response.data;
|
||||
const response = await api.get<any>(`/comments/post/${postId}/cursor`, { params });
|
||||
const raw = response.data;
|
||||
return {
|
||||
list: Array.isArray(raw?.list) ? raw.list : [],
|
||||
next_cursor: raw?.next_cursor ?? null,
|
||||
prev_cursor: raw?.prev_cursor ?? null,
|
||||
has_more: raw?.has_more ?? false,
|
||||
};
|
||||
} catch (error) {
|
||||
console.error('获取帖子评论列表失败:', error);
|
||||
return {
|
||||
items: [],
|
||||
list: [],
|
||||
next_cursor: null,
|
||||
prev_cursor: null,
|
||||
has_more: false,
|
||||
@@ -282,15 +285,18 @@ class CommentService {
|
||||
params: CursorPaginationRequest = {}
|
||||
): Promise<CursorPaginationResponse<Comment>> {
|
||||
try {
|
||||
const response = await api.get<CursorPaginationResponse<Comment>>(
|
||||
`/comments/${commentId}/replies/cursor`,
|
||||
{ params }
|
||||
);
|
||||
return response.data;
|
||||
const response = await api.get<any>(`/comments/${commentId}/replies/cursor`, { params });
|
||||
const raw = response.data;
|
||||
return {
|
||||
list: Array.isArray(raw?.list) ? raw.list : [],
|
||||
next_cursor: raw?.next_cursor ?? null,
|
||||
prev_cursor: raw?.prev_cursor ?? null,
|
||||
has_more: raw?.has_more ?? false,
|
||||
};
|
||||
} catch (error) {
|
||||
console.error('获取评论回复列表失败:', error);
|
||||
return {
|
||||
items: [],
|
||||
list: [],
|
||||
next_cursor: null,
|
||||
prev_cursor: null,
|
||||
has_more: false,
|
||||
|
||||
@@ -341,7 +341,7 @@ class GroupService {
|
||||
} catch (error) {
|
||||
console.error('获取群组列表失败:', error);
|
||||
return {
|
||||
items: [],
|
||||
list: [],
|
||||
next_cursor: null,
|
||||
prev_cursor: null,
|
||||
has_more: false,
|
||||
@@ -368,7 +368,7 @@ class GroupService {
|
||||
} catch (error) {
|
||||
console.error('获取群组成员列表失败:', error);
|
||||
return {
|
||||
items: [],
|
||||
list: [],
|
||||
next_cursor: null,
|
||||
prev_cursor: null,
|
||||
has_more: false,
|
||||
@@ -395,7 +395,7 @@ class GroupService {
|
||||
} catch (error) {
|
||||
console.error('获取群公告列表失败:', error);
|
||||
return {
|
||||
items: [],
|
||||
list: [],
|
||||
next_cursor: null,
|
||||
prev_cursor: null,
|
||||
has_more: false,
|
||||
|
||||
@@ -573,11 +573,17 @@ class MessageService {
|
||||
'/conversations/cursor',
|
||||
{ params }
|
||||
);
|
||||
return response.data;
|
||||
const raw = response.data;
|
||||
return {
|
||||
list: Array.isArray(raw?.list) ? raw.list : [],
|
||||
next_cursor: raw?.next_cursor ?? null,
|
||||
prev_cursor: raw?.prev_cursor ?? null,
|
||||
has_more: raw?.has_more ?? false,
|
||||
};
|
||||
} catch (error) {
|
||||
console.error('获取会话列表失败:', error);
|
||||
return {
|
||||
items: [],
|
||||
list: [],
|
||||
next_cursor: null,
|
||||
prev_cursor: null,
|
||||
has_more: false,
|
||||
@@ -596,15 +602,21 @@ class MessageService {
|
||||
params: CursorPaginationRequest = {}
|
||||
): Promise<CursorPaginationResponse<MessageResponse>> {
|
||||
try {
|
||||
const response = await api.get<CursorPaginationResponse<MessageResponse>>(
|
||||
const response = await api.get<any>(
|
||||
`/conversations/${encodeURIComponent(conversationId)}/messages/cursor`,
|
||||
{ params }
|
||||
);
|
||||
return response.data;
|
||||
const raw = response.data;
|
||||
return {
|
||||
list: Array.isArray(raw?.list) ? raw.list : [],
|
||||
next_cursor: raw?.next_cursor ?? null,
|
||||
prev_cursor: raw?.prev_cursor ?? null,
|
||||
has_more: raw?.has_more ?? false,
|
||||
};
|
||||
} catch (error) {
|
||||
console.error('获取消息列表失败:', error);
|
||||
return {
|
||||
items: [],
|
||||
list: [],
|
||||
next_cursor: null,
|
||||
prev_cursor: null,
|
||||
has_more: false,
|
||||
@@ -631,32 +643,36 @@ class MessageService {
|
||||
|
||||
const data = response.data;
|
||||
|
||||
// 兼容两种 API 响应格式
|
||||
// 游标或带 page/total_pages 的分页(统一为 CursorPaginationResponse:list)
|
||||
if (data && typeof data === 'object') {
|
||||
// 游标分页格式
|
||||
if (Array.isArray(data.items)) {
|
||||
const list = Array.isArray(data.list) ? data.list : null;
|
||||
if (list) {
|
||||
const isPageShape =
|
||||
typeof data.page === 'number' &&
|
||||
typeof data.total_pages === 'number' &&
|
||||
data.next_cursor === undefined &&
|
||||
data.prev_cursor === undefined;
|
||||
if (isPageShape) {
|
||||
const currentPage = data.page || 1;
|
||||
const totalPages = data.total_pages || 1;
|
||||
return {
|
||||
list,
|
||||
next_cursor: currentPage < totalPages ? String(currentPage + 1) : null,
|
||||
prev_cursor: currentPage > 1 ? String(currentPage - 1) : null,
|
||||
has_more: currentPage < totalPages,
|
||||
};
|
||||
}
|
||||
return {
|
||||
items: data.items,
|
||||
list,
|
||||
next_cursor: data.next_cursor ?? null,
|
||||
prev_cursor: data.prev_cursor ?? null,
|
||||
has_more: data.has_more ?? false,
|
||||
};
|
||||
}
|
||||
// 传统分页格式 - 转换为游标格式
|
||||
if (Array.isArray(data.list)) {
|
||||
const currentPage = data.page || 1;
|
||||
const totalPages = data.total_pages || 1;
|
||||
return {
|
||||
items: data.list,
|
||||
next_cursor: currentPage < totalPages ? String(currentPage + 1) : null,
|
||||
prev_cursor: currentPage > 1 ? String(currentPage - 1) : null,
|
||||
has_more: currentPage < totalPages,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return {
|
||||
items: [],
|
||||
list: [],
|
||||
next_cursor: null,
|
||||
prev_cursor: null,
|
||||
has_more: false,
|
||||
@@ -664,7 +680,7 @@ class MessageService {
|
||||
} catch (error) {
|
||||
console.error('获取系统消息列表失败:', error);
|
||||
return {
|
||||
items: [],
|
||||
list: [],
|
||||
next_cursor: null,
|
||||
prev_cursor: null,
|
||||
has_more: false,
|
||||
|
||||
@@ -172,7 +172,7 @@ class NotificationService {
|
||||
} catch (error) {
|
||||
console.error('获取通知列表失败:', error);
|
||||
return {
|
||||
items: [],
|
||||
list: [],
|
||||
next_cursor: null,
|
||||
prev_cursor: null,
|
||||
has_more: false,
|
||||
|
||||
@@ -304,37 +304,33 @@ class PostService {
|
||||
const response = await api.get<any>('/posts', requestParams);
|
||||
|
||||
const data = response.data;
|
||||
|
||||
// 兼容两种 API 响应格式:
|
||||
// 1. 游标分页格式:{ items, next_cursor, prev_cursor, has_more }
|
||||
// 2. 传统分页格式:{ list, total, page, page_size, total_pages }
|
||||
if (data && typeof data === 'object') {
|
||||
// 游标分页格式
|
||||
if (Array.isArray(data.items)) {
|
||||
return {
|
||||
items: data.items,
|
||||
next_cursor: data.next_cursor ?? null,
|
||||
prev_cursor: data.prev_cursor ?? null,
|
||||
has_more: data.has_more ?? false,
|
||||
};
|
||||
}
|
||||
// 传统分页格式 - 转换为游标格式
|
||||
if (Array.isArray(data.list)) {
|
||||
const currentPage = data.page || 1;
|
||||
const totalPages = data.total_pages || 1;
|
||||
return {
|
||||
items: data.list,
|
||||
// 使用页码作为游标
|
||||
next_cursor: currentPage < totalPages ? String(currentPage + 1) : null,
|
||||
prev_cursor: currentPage > 1 ? String(currentPage - 1) : null,
|
||||
has_more: currentPage < totalPages,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// 默认返回空数据
|
||||
|
||||
if (data && typeof data === 'object' && Array.isArray(data.list)) {
|
||||
const isPageShape =
|
||||
typeof data.page === 'number' &&
|
||||
typeof data.total_pages === 'number' &&
|
||||
data.next_cursor === undefined &&
|
||||
data.prev_cursor === undefined;
|
||||
if (isPageShape) {
|
||||
const currentPage = data.page || 1;
|
||||
const totalPages = data.total_pages || 1;
|
||||
return {
|
||||
list: data.list,
|
||||
next_cursor: currentPage < totalPages ? String(currentPage + 1) : null,
|
||||
prev_cursor: currentPage > 1 ? String(currentPage - 1) : null,
|
||||
has_more: currentPage < totalPages,
|
||||
};
|
||||
}
|
||||
return {
|
||||
list: data.list,
|
||||
next_cursor: data.next_cursor ?? null,
|
||||
prev_cursor: data.prev_cursor ?? null,
|
||||
has_more: data.has_more ?? false,
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
items: [],
|
||||
list: [],
|
||||
next_cursor: null,
|
||||
prev_cursor: null,
|
||||
has_more: false,
|
||||
@@ -342,7 +338,7 @@ class PostService {
|
||||
} catch (error) {
|
||||
console.error('获取帖子列表失败:', error);
|
||||
return {
|
||||
items: [],
|
||||
list: [],
|
||||
next_cursor: null,
|
||||
prev_cursor: null,
|
||||
has_more: false,
|
||||
@@ -367,31 +363,33 @@ class PostService {
|
||||
});
|
||||
|
||||
const data = response.data;
|
||||
|
||||
// 兼容两种 API 响应格式
|
||||
if (data && typeof data === 'object') {
|
||||
if (Array.isArray(data.items)) {
|
||||
return {
|
||||
items: data.items,
|
||||
next_cursor: data.next_cursor ?? null,
|
||||
prev_cursor: data.prev_cursor ?? null,
|
||||
has_more: data.has_more ?? false,
|
||||
};
|
||||
}
|
||||
if (Array.isArray(data.list)) {
|
||||
|
||||
if (data && typeof data === 'object' && Array.isArray(data.list)) {
|
||||
const isPageShape =
|
||||
typeof data.page === 'number' &&
|
||||
typeof data.total_pages === 'number' &&
|
||||
data.next_cursor === undefined &&
|
||||
data.prev_cursor === undefined;
|
||||
if (isPageShape) {
|
||||
const currentPage = data.page || 1;
|
||||
const totalPages = data.total_pages || 1;
|
||||
return {
|
||||
items: data.list,
|
||||
list: data.list,
|
||||
next_cursor: currentPage < totalPages ? String(currentPage + 1) : null,
|
||||
prev_cursor: currentPage > 1 ? String(currentPage - 1) : null,
|
||||
has_more: currentPage < totalPages,
|
||||
};
|
||||
}
|
||||
return {
|
||||
list: data.list,
|
||||
next_cursor: data.next_cursor ?? null,
|
||||
prev_cursor: data.prev_cursor ?? null,
|
||||
has_more: data.has_more ?? false,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
return {
|
||||
items: [],
|
||||
list: [],
|
||||
next_cursor: null,
|
||||
prev_cursor: null,
|
||||
has_more: false,
|
||||
@@ -399,7 +397,7 @@ class PostService {
|
||||
} catch (error) {
|
||||
console.error('搜索帖子失败:', error);
|
||||
return {
|
||||
items: [],
|
||||
list: [],
|
||||
next_cursor: null,
|
||||
prev_cursor: null,
|
||||
has_more: false,
|
||||
@@ -424,31 +422,33 @@ class PostService {
|
||||
);
|
||||
|
||||
const data = response.data;
|
||||
|
||||
// 兼容两种 API 响应格式
|
||||
if (data && typeof data === 'object') {
|
||||
if (Array.isArray(data.items)) {
|
||||
return {
|
||||
items: data.items,
|
||||
next_cursor: data.next_cursor ?? null,
|
||||
prev_cursor: data.prev_cursor ?? null,
|
||||
has_more: data.has_more ?? false,
|
||||
};
|
||||
}
|
||||
if (Array.isArray(data.list)) {
|
||||
|
||||
if (data && typeof data === 'object' && Array.isArray(data.list)) {
|
||||
const isPageShape =
|
||||
typeof data.page === 'number' &&
|
||||
typeof data.total_pages === 'number' &&
|
||||
data.next_cursor === undefined &&
|
||||
data.prev_cursor === undefined;
|
||||
if (isPageShape) {
|
||||
const currentPage = data.page || 1;
|
||||
const totalPages = data.total_pages || 1;
|
||||
return {
|
||||
items: data.list,
|
||||
list: data.list,
|
||||
next_cursor: currentPage < totalPages ? String(currentPage + 1) : null,
|
||||
prev_cursor: currentPage > 1 ? String(currentPage - 1) : null,
|
||||
has_more: currentPage < totalPages,
|
||||
};
|
||||
}
|
||||
return {
|
||||
list: data.list,
|
||||
next_cursor: data.next_cursor ?? null,
|
||||
prev_cursor: data.prev_cursor ?? null,
|
||||
has_more: data.has_more ?? false,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
return {
|
||||
items: [],
|
||||
list: [],
|
||||
next_cursor: null,
|
||||
prev_cursor: null,
|
||||
has_more: false,
|
||||
@@ -456,7 +456,7 @@ class PostService {
|
||||
} catch (error) {
|
||||
console.error('获取用户帖子列表失败:', error);
|
||||
return {
|
||||
items: [],
|
||||
list: [],
|
||||
next_cursor: null,
|
||||
prev_cursor: null,
|
||||
has_more: false,
|
||||
|
||||
Reference in New Issue
Block a user