Add server and mini-program pagination for shared lists

This commit is contained in:
2026-10-11 10:10:49 +08:00
parent c0a3db5c8e
commit 7854d94e7b
37 changed files with 395 additions and 175 deletions
+27 -18
View File
@@ -1,3 +1,4 @@
const { itemsOf, totalOf, mergeUnique } = require('../../utils/list-pagination');
const { withDataCache } = require('../../utils/page-cache');
const { getLayout } = require('../../utils/layout');
const { api, getImageUrl } = require('../../utils/request');
@@ -8,7 +9,7 @@ Page(withDataCache({
diary: null,
loading: true,
comments: [],
commentPage: 1,
commentPage: 1, commentsLoadingMore: false, commentsMoreError: false, commentsTotal: 0,
hasMoreComments: true,
showCommentInput: false,
commentText: '',
@@ -78,24 +79,28 @@ Page(withDataCache({
return data;
},
loadComments: async function() {
this.setData({ commentsError: false });
loadComments: function() { return this._loadCommentsPage(1); },
_loadCommentsPage: async function(page) {
page = Number(page) || 1;
if (this._commentsFirst || (page > 1 && (this.data.commentsLoadingMore || !this.data.hasMoreComments))) return;
if (page === 1) { this._commentsFirst = true; this._commentsGeneration = (this._commentsGeneration || 0) + 1; }
var generation = this._commentsGeneration;
this.setData(page === 1 ? {commentsError:false,commentsMoreError:false,commentsLoadingMore:false} : {commentsLoadingMore:true,commentsMoreError:false});
try {
var data = await api.diaryCommentList({ diary_id: this.data.diaryId });
if (data && data.length > 0) {
data.forEach(function(c) {
if (c.created_at) {
c._time = c.created_at.substring(0, 16).replace('T', ' ');
} else if (c.create_time) {
c._time = c.create_time.substring(0, 16).replace('T', ' ');
} else {
c._time = '';
}
});
}
this.setData({ comments: data || [] });
} catch (e) { this.setData({ commentsError: true }); console.error(e); }
var result = await api.diaryCommentList({diary_id:this.data.diaryId,page:page,page_size:20});
if (generation !== this._commentsGeneration) return;
var added = itemsOf(result).map(function(comment) {
return Object.assign({}, comment, {_time:String(comment.created_at || comment.create_time || '').slice(0,16).replace('T',' ')});
});
this.setData({comments:page===1?added:mergeUnique(this.data.comments,added),commentPage:page,commentsTotal:totalOf(result),hasMoreComments:!Array.isArray(result)&&(result.has_more != null?!!result.has_more:page*20<totalOf(result))});
} catch(e) {
if (generation === this._commentsGeneration) this.setData(page===1?{commentsError:true}:{commentsMoreError:true});
} finally {
if (generation === this._commentsGeneration) { this._commentsFirst=false;this.setData({commentsLoadingMore:false}); }
}
},
loadMoreComments: function() { return this._loadCommentsPage(this.data.commentPage+1); },
onShareTap: function() {
wx.showActionSheet({
@@ -177,6 +182,9 @@ Page(withDataCache({
}
var res = await api.diaryCommentAdd(params);
if (res.success) {
this._commentsGeneration = (this._commentsGeneration || 0) + 1;
this._commentsFirst = false;
this.setData({commentsLoadingMore:false});
var newComment = res.comment || {};
if (newComment.created_at) {
newComment._time = newComment.created_at.substring(0, 16).replace('T', ' ');
@@ -187,9 +195,10 @@ Page(withDataCache({
newComment._time = now.getFullYear() + '-' + String(now.getMonth()+1).padStart(2,'0') + '-' + String(now.getDate()).padStart(2,'0') + ' ' + String(now.getHours()).padStart(2,'0') + ':' + String(now.getMinutes()).padStart(2,'0');
}
var newComments = this.data.comments.slice();
newComments.push(newComment);
newComments.unshift(newComment);
this.setData({
comments: newComments,
commentsTotal: this.data.commentsTotal + 1,
showCommentInput: false,
replyTo: null,
commentText: '',
+3 -1
View File
@@ -3,7 +3,7 @@
<app-nav title="日记详情" back="{{true}}" /><view class="page-bg">
<view class="read-state" wx:if="{{loading || loadError}}"><page-state wx:if="{{loading}}" kind="loading" title="正在加载日记" /><page-state wx:else kind="error" title="日记加载失败" action="重试" bind:action="loadDiary" /></view>
<scroll-view scroll-y class="read-scroll" wx:if="{{!loading && !loadError && diary}}" show-scrollbar="{{false}}" enhanced>
<scroll-view scroll-y bindscrolltolower="loadMoreComments" lower-threshold="120" class="read-scroll" wx:if="{{!loading && !loadError && diary}}" show-scrollbar="{{false}}" enhanced>
<view class="read-page">
<view class="read-author"><image class="read-avatar" src="{{diary.creator_avatar || '/images/default-avatar.svg'}}" mode="aspectFill" /><view class="read-author-info"><text class="read-name">{{diary.creator_name || 'TA'}}</text><text class="read-date">{{diary.created_time}}</text><text class="read-location" wx:if="{{diary.location_text}}">{{diary.location_text}}</text></view><view class="read-menu" catchtap="onMoreTap" aria-label="日记操作"><image src="/images/more.svg" mode="aspectFit" /></view></view>
<view class="read-paper">
@@ -58,6 +58,8 @@
</text>
</view>
</view>
<view class="j-pagination" wx:if="{{commentsError}}" bindtap="loadComments">留言加载失败,点击重试</view>
<view class="j-pagination" wx:elif="{{comments.length}}"><text wx:if="{{commentsLoadingMore}}">正在加载…</text><text wx:elif="{{commentsMoreError}}" bindtap="loadMoreComments">加载失败,点击重试</text><text wx:elif="{{hasMoreComments}}" bindtap="loadMoreComments">加载更多留言</text><text wx:else>已加载全部留言</text></view>
</view>
</view>