perf: reduce worker order list query load
This commit is contained in:
@@ -110,6 +110,12 @@ test('后台接单工单支持按接单分类筛选', () => {
|
||||
assert.deepEqual(query.params, [7])
|
||||
})
|
||||
|
||||
test('空白搜索词不生成全表 LIKE 条件', () => {
|
||||
const query = buildWorkOrderWhere({ keyword: ' ' })
|
||||
assert.doesNotMatch(query.whereClause, /LIKE LOWER/)
|
||||
assert.deepEqual(query.params, [])
|
||||
})
|
||||
|
||||
test('大厅候选按分类上限取队首后再受全局上限限制', () => {
|
||||
const query = buildWorkOrderWhere({
|
||||
hallCandidateLimit: 20,
|
||||
|
||||
@@ -58,6 +58,13 @@ export const WORK_ORDER_SELECT = `
|
||||
) share_summary ON TRUE
|
||||
`
|
||||
|
||||
// Keep the page and total in one filtered query. This avoids running the same
|
||||
// joins and share aggregation twice for every list request.
|
||||
const LIST_WORK_ORDER_SELECT = WORK_ORDER_SELECT.replace(
|
||||
' SELECT\n',
|
||||
' SELECT\n COUNT(*) OVER()::int AS total_count,\n',
|
||||
)
|
||||
|
||||
type WorkerOrderOverviewRow = {
|
||||
status: string
|
||||
order_count: number
|
||||
@@ -268,15 +275,6 @@ export async function listWorkOrders({
|
||||
createdFrom,
|
||||
createdTo,
|
||||
})
|
||||
const totalResult = await query<{ total: number }>(
|
||||
`
|
||||
SELECT COUNT(*)::int AS total
|
||||
FROM work_orders wo
|
||||
${joins}
|
||||
${whereClause}
|
||||
`,
|
||||
params,
|
||||
)
|
||||
const offset = (page - 1) * pageSize
|
||||
const orderBy =
|
||||
sort === 'worker_claimed_at_desc' && workerSharingId
|
||||
@@ -292,14 +290,30 @@ export async function listWorkOrders({
|
||||
const effectiveOrderBy = pinnedFirst ? `wo.pinned_at DESC NULLS LAST, ${orderBy}` : orderBy
|
||||
params.push(pageSize, offset)
|
||||
const itemsResult = await query<WorkOrderRow>(
|
||||
`${WORK_ORDER_SELECT}
|
||||
`${LIST_WORK_ORDER_SELECT}
|
||||
${joins}
|
||||
${whereClause}
|
||||
ORDER BY ${effectiveOrderBy}
|
||||
LIMIT $${params.length - 1} OFFSET $${params.length}`,
|
||||
params,
|
||||
)
|
||||
return { items: itemsResult.rows, total: Number(totalResult.rows[0]?.total || 0) }
|
||||
// A page beyond the end has no row from which to read the window count.
|
||||
// Keep that uncommon pagination edge case correct without restoring a
|
||||
// second query for normal requests.
|
||||
let total = Number(
|
||||
(itemsResult.rows[0] as WorkOrderRow & { total_count?: number })?.total_count || 0,
|
||||
)
|
||||
if (itemsResult.rows.length === 0 && page > 1) {
|
||||
const totalResult = await query<{ total: number }>(
|
||||
`SELECT COUNT(*)::int AS total FROM work_orders wo ${joins} ${whereClause}`,
|
||||
params.slice(0, -2),
|
||||
)
|
||||
total = Number(totalResult.rows[0]?.total || 0)
|
||||
}
|
||||
return {
|
||||
items: itemsResult.rows,
|
||||
total,
|
||||
}
|
||||
}
|
||||
|
||||
/** 按筛选条件汇总工单,统计范围不受当前分页影响。 */
|
||||
|
||||
Reference in New Issue
Block a user