本设计实现工作记录列表的后端分页功能,将当前的一次性加载全部数据改为按需加载当前页数据。主要修改涉及后端服务层、API路由层和前端组件。
经代码分析,WorkRecordService.get_all() 方法仅在 /work-records GET 端点中被调用。其他功能模块(导出、汇总统计等)使用独立的查询方法,不受影响:
| 模块 | 方法 | 影响 |
|---|---|---|
| 工作记录列表 | get_all() |
✅ 需要修改 |
| 每日汇总 | get_daily_summary() |
❌ 不受影响 |
| 月度汇总 | get_monthly_summary() |
❌ 不受影响 |
| 年度汇总 | get_yearly_summary() |
❌ 不受影响 |
| 批量结算 | batch_update_settlement() |
❌ 不受影响 |
| 导出功能 | ExportService |
❌ 不受影响(独立查询) |
page 和 page_size 均为可选参数,有默认值pagination 字段,原有 data 字段保持不变┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ Frontend │ │ Backend API │ │ Database │
│ WorkRecordList │────▶│ /work-records │────▶│ WorkRecord │
│ │ │ │ │ │
│ - page │ │ - get_all() │ │ - LIMIT │
│ - page_size │ │ - pagination │ │ - OFFSET │
│ - total │ │ - filters │ │ - COUNT │
└─────────────────┘ └─────────────────┘ └─────────────────┘
page、page_size 和筛选参数修改 WorkRecordService.get_all() 方法:
@staticmethod
def get_all(person_id=None, start_date=None, end_date=None,
year=None, month=None, is_settled=None,
page=1, page_size=20):
"""Get work records with pagination and filters.
Args:
person_id: Filter by person ID (optional)
start_date: Filter by start date (optional)
end_date: Filter by end date (optional)
year: Filter by year (optional)
month: Filter by month 1-12 (optional)
is_settled: Filter by settlement status (optional)
page: Page number, starting from 1 (default: 1)
page_size: Number of records per page (default: 20, max: 100)
Returns:
Dictionary with:
- data: List of work record dictionaries
- total: Total number of matching records
- page: Current page number
- page_size: Records per page
- total_pages: Total number of pages
"""
修改 /work-records GET 端点:
@work_record_ns.param('page', '页码,从1开始', type=int, default=1)
@work_record_ns.param('page_size', '每页数量,默认20,最大100', type=int, default=20)
{
"success": true,
"data": [...],
"pagination": {
"total": 150,
"page": 1,
"page_size": 20,
"total_pages": 8
},
"message": "Work records retrieved successfully"
}
修改 workRecordApi.getAll() 调用:
getAll: (params) => api.get('/work-records', {
params: {
...params,
page: params.page || 1,
page_size: params.page_size || 20
}
})
修改 WorkRecordList 组件:
currentPage 和 pageSize 状态total 状态存储后端返回的总数pagination 配置使用后端返回的 totalonChange 处理器响应分页变化| 参数 | 类型 | 默认值 | 范围 | 说明 |
|---|---|---|---|---|
| page | int | 1 | >= 1 | 页码,小于1时使用1 |
| page_size | int | 20 | 1-100 | 每页数量,超出范围使用20 |
| 字段 | 类型 | 说明 |
|---|---|---|
| total | int | 匹配筛选条件的总记录数 |
| page | int | 当前页码 |
| page_size | int | 每页数量 |
| total_pages | int | 总页数,计算公式: ceil(total / page_size) |
A property is a characteristic or behavior that should hold true across all valid executions of a system—essentially, a formal statement about what the system should do. Properties serve as the bridge between human-readable specifications and machine-verifiable correctness guarantees.
For any valid page and page_size parameters, the number of records returned should equal min(page_size, total - (page - 1) * page_size) when page is within valid range, or 0 when page exceeds total_pages.
Validates: Requirements 1.4, 4.3
For any pagination request, the returned metadata should satisfy:
total_pages == ceil(total / page_size)page == requested_page (after normalization)page_size == requested_page_size (after normalization)len(data) <= page_sizeValidates: Requirements 1.5
For any combination of filter parameters and pagination parameters, the returned total should equal the count of all records matching the filter criteria, and the returned data should be a correct subset of filtered records for the requested page.
Validates: Requirements 2.1, 2.2
For any pagination request, the returned records should be sorted by work_date descending, then by id ascending. This order should be consistent across all pages.
Validates: Requirements 2.3
For any page < 1, the service should return page 1 data. For any page_size < 1 or page_size > 100, the service should use page_size = 20.
Validates: Requirements 4.1, 4.2
| 场景 | 处理方式 |
|---|---|
| page < 1 | 使用 page = 1 |
| page_size < 1 或 > 100 | 使用 page_size = 20 |
| page > total_pages | 返回空数据列表,分页元数据正确 |
| 无匹配数据 | 返回空列表,total = 0,total_pages = 0 |
使用 hypothesis 库进行属性测试:
每个属性测试运行至少 100 次迭代。