From 121d0c9e1f599d214e524d135896ddf81e83458e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=96=87=E7=9D=BF=20=E5=BC=A0?= Date: Mon, 21 Sep 2026 16:00:35 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E7=94=B3=E8=AF=B7=E4=B8=8E=E5=AE=A1?= =?UTF-8?q?=E6=89=B9=E9=A1=B5=E7=BF=BB=E9=A1=B5=E5=A4=B1=E6=95=88=EF=BC=8C?= =?UTF-8?q?=E9=A1=B5=E7=A0=81=E6=8D=A2=E7=AE=97=E6=88=90=E5=90=8E=E7=AB=AF?= =?UTF-8?q?=E8=AE=A4=E8=AF=86=E7=9A=84=20limit/offset?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 后端 GetMyApplications / GetAllApplications 只读 limit/offset,前端原先发 page/pageSize,无法识别的参数被静默忽略并退回默认的 limit=20 offset=0, 于是翻页不报错但始终返回第一页。 转换点固定在 api/application.js,对外签名 (status, page, pageSize) 不变, stores/application.js 与 stores/approval.js 两个调用点无需改动;同时对非法 页码兜底,避免算出负 offset。 application.test.js 覆盖换算结果与边界,其中「第 2 页不再是 offset=0」 是本次的回归点。 --- frontend/src/api/application.js | 14 +++++++-- frontend/src/api/application.test.js | 47 ++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+), 2 deletions(-) create mode 100644 frontend/src/api/application.test.js diff --git a/frontend/src/api/application.js b/frontend/src/api/application.js index 3a41de7f..a0523afd 100644 --- a/frontend/src/api/application.js +++ b/frontend/src/api/application.js @@ -1,17 +1,27 @@ import request from './index' +// 后端的分页接口只认 limit/offset,收到分页参数后会直接忽略并退回默认的 +// limit=20, offset=0,所以「点第 2 页还是第一页数据」这种失效是不报错的。 +// 转换点固定在这里,调用方(stores/application.js、stores/approval.js) +// 继续按页码语义传参,不需要各自记一套后端字段名。 +function toPageParams(status, page, pageSize) { + const size = pageSize > 0 ? pageSize : 20 + const currentPage = page > 0 ? page : 1 + return { status, limit: size, offset: (currentPage - 1) * size } +} + export const applicationApi = { create(data) { return request.post('/applications', data) }, getMy(status = '', page = 1, pageSize = 20) { return request.get('/applications/my', { - params: { status, page, pageSize } + params: toPageParams(status, page, pageSize) }) }, getAll(status = '', page = 1, pageSize = 20) { return request.get('/applications', { - params: { status, page, pageSize } + params: toPageParams(status, page, pageSize) }) }, cancel(id) { diff --git a/frontend/src/api/application.test.js b/frontend/src/api/application.test.js new file mode 100644 index 00000000..2a4a8a71 --- /dev/null +++ b/frontend/src/api/application.test.js @@ -0,0 +1,47 @@ +import { beforeEach, describe, expect, it, vi } from 'vitest' +import { applicationApi } from './application' + +const request = vi.hoisted(() => ({ + get: vi.fn() +})) + +vi.mock('./index', () => ({ default: request })) + +describe('application API 分页参数', () => { + beforeEach(() => { + vi.clearAllMocks() + request.get.mockResolvedValue({ data: { items: [], total: 0 } }) + }) + + it('把页码换算成后端认识的 limit/offset,第 2 页不再是 offset=0', async () => { + await applicationApi.getMy('', 2, 20) + + expect(request.get).toHaveBeenCalledWith('/applications/my', { + params: { status: '', limit: 20, offset: 20 } + }) + }) + + it('审批页的 getAll 同样换算,且不落下 status 筛选', async () => { + await applicationApi.getAll('pending', 3, 10) + + expect(request.get).toHaveBeenCalledWith('/applications', { + params: { status: 'pending', limit: 10, offset: 20 } + }) + }) + + it('第 1 页从 offset=0 开始', async () => { + await applicationApi.getAll('', 1, 20) + + expect(request.get).toHaveBeenCalledWith('/applications', { + params: { status: '', limit: 20, offset: 0 } + }) + }) + + it('页码或每页条数非法时退回第 1 页的默认值,不产生负 offset', async () => { + await applicationApi.getMy('', 0, 0) + + expect(request.get).toHaveBeenCalledWith('/applications/my', { + params: { status: '', limit: 20, offset: 0 } + }) + }) +})