From d876288394c3170f3226bb907624558ddad5f1e3 Mon Sep 17 00:00:00 2001 From: xcbyy <2578898740@qq.com> Date: Thu, 22 Oct 2026 10:52:40 +0800 Subject: [PATCH] =?UTF-8?q?feat(list):=20=E8=AE=A2=E5=8D=95/=E9=80=9A?= =?UTF-8?q?=E7=9F=A5/=E7=BB=84=E5=B1=80=E5=88=97=E8=A1=A8=E5=88=86?= =?UTF-8?q?=E9=A1=B5=EF=BC=8C=E7=94=9F=E4=BA=A7=20NODE=5FENV=20=E5=88=87?= =?UTF-8?q?=E6=8D=A2=20production?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 仓储层 getOrders/getOrdersForUser/getActivities/getUserNotifications 支持 LIMIT/OFFSET,新增 countOrders/countOrdersForUser/countActivities/getUserNotificationTotal - 接口支持 page/pageSize/status/keyword/payType/creatorId/category,返回 list/total/hasMore;未传 page 保持旧数组格式,兼容后台与工作台 - 小程序订单/通知/组局三页触底加载,筛选与搜索下推服务端,避免只过滤当前页 - 新增 116 套件/758 用例,全绿;线上实测分页与筛选接口正常 --- pwuniapp/common/api.js | 68 +++++++-- pwuniapp/pages/activity/list.vue | 128 ++++++++++------- pwuniapp/pages/order/list.vue | 75 ++++++++-- pwuniapp/pages/user/notifications.vue | 62 ++++++-- server/src/db/repository.ts | 199 ++++++++++++++++++++++++-- server/src/index.ts | 86 +++++++++-- server/tests/client-features.spec.ts | 2 +- server/tests/pagination.spec.ts | 60 ++++++++ server/tests/read-scope.spec.ts | 8 +- 9 files changed, 580 insertions(+), 108 deletions(-) create mode 100644 server/tests/pagination.spec.ts diff --git a/pwuniapp/common/api.js b/pwuniapp/common/api.js index b35fd7e..588a020 100644 --- a/pwuniapp/common/api.js +++ b/pwuniapp/common/api.js @@ -51,16 +51,36 @@ export function formatActivityData(raw) { /** * 获取组局活动列表 (真实请求 MySQL,异常时返回空列表) */ -export async function getActivities() { +export async function getActivities(options = {}) { + const paged = Number(options.page) > 0; try { - const list = await http.get('/activities'); - if (Array.isArray(list) && list.length > 0) { - return list.map(formatActivityData); + const qs = []; + if (paged) { + qs.push(`page=${Math.floor(Number(options.page))}`); + qs.push(`pageSize=${Math.floor(Number(options.pageSize) || 20)}`); + if (options.keyword) qs.push(`keyword=${encodeURIComponent(String(options.keyword).trim())}`); + if (options.payType) qs.push(`payType=${encodeURIComponent(options.payType)}`); + if (Number(options.creatorId) > 0) qs.push(`creatorId=${Math.floor(Number(options.creatorId))}`); + if (options.category) qs.push(`category=${encodeURIComponent(options.category)}`); + if (options.categoryName) qs.push(`categoryName=${encodeURIComponent(options.categoryName)}`); + } + const res = await http.get(`/activities${qs.length ? `?${qs.join('&')}` : ''}`); + if (Array.isArray(res)) { + return res.map(formatActivityData); + } + if (res && Array.isArray(res.list)) { + return { + list: res.list.map(formatActivityData), + total: Number(res.total || 0), + page: Number(res.page || 1), + pageSize: Number(res.pageSize || 20), + hasMore: Boolean(res.hasMore) + }; } } catch (err) { console.warn('[API] 获取后端活动列表异常:', err.message); } - return []; + return paged ? { list: [], total: 0, page: 1, pageSize: 20, hasMore: false } : []; } /** @@ -302,16 +322,33 @@ export function formatOrderData(raw) { /** * 获取订单列表 (真实读取 MySQL) */ -export async function getOrders() { +export async function getOrders(options = {}) { + const paged = Number(options.page) > 0; try { - const list = await http.get(`/orders?userId=${normalizeUserId()}`); - if (Array.isArray(list) && list.length > 0) { - return list.map(formatOrderData); + const qs = []; + if (options.status) qs.push(`status=${encodeURIComponent(options.status)}`); + if (paged) { + qs.push(`page=${Math.floor(Number(options.page))}`); + qs.push(`pageSize=${Math.floor(Number(options.pageSize) || 20)}`); + } + const suffix = qs.length ? `&${qs.join('&')}` : ''; + const res = await http.get(`/orders?userId=${normalizeUserId()}${suffix}`); + if (Array.isArray(res)) { + return res.map(formatOrderData); + } + if (res && Array.isArray(res.list)) { + return { + list: res.list.map(formatOrderData), + total: Number(res.total || 0), + page: Number(res.page || 1), + pageSize: Number(res.pageSize || 20), + hasMore: Boolean(res.hasMore) + }; } } catch (err) { console.warn('[API] 获取订单列表异常:', err.message); } - return []; + return paged ? { list: [], total: 0, page: 1, pageSize: 20, hasMore: false } : []; } /** @@ -1368,10 +1405,17 @@ export async function getSubscribeTemplates() { /** * 获取站内消息通知列表与未读数 */ -export async function getNotifications(userId, limit = 50) { +export async function getNotifications(userId, limit = 50, extra = {}) { const uid = normalizeUserId(userId); try { - const res = await http.get(`/notifications?userId=${uid}&limit=${Number(limit) || 50}`); + const qs = [`userId=${uid}`]; + if (Number(extra.page) > 0) { + qs.push(`page=${Math.floor(Number(extra.page))}`); + qs.push(`pageSize=${Math.floor(Number(extra.pageSize) || 20)}`); + } else { + qs.push(`limit=${Number(limit) || 50}`); + } + const res = await http.get(`/notifications?${qs.join('&')}`); return res || { list: [], unread: 0 }; } catch (err) { throw err; diff --git a/pwuniapp/pages/activity/list.vue b/pwuniapp/pages/activity/list.vue index 03febc8..4b6d3cf 100644 --- a/pwuniapp/pages/activity/list.vue +++ b/pwuniapp/pages/activity/list.vue @@ -163,6 +163,13 @@ 清空搜索条件 + + + 正在加载更多… + + + 没有更多了 + @@ -172,8 +179,8 @@