重构打手订单概览查询为索引可用的UNION分支避免work_orders全表扫描

This commit is contained in:
yml2213
2026-08-22 15:41:01 +08:00
parent 2224dd06d3
commit 0dfe363d35
@@ -365,74 +365,111 @@ export async function getWorkerOrderOverview(workerId: number | string): Promise
const normalizedWorkerId = Number(workerId) const normalizedWorkerId = Number(workerId)
const result = await query<WorkerOrderOverviewRow>( const result = await query<WorkerOrderOverviewRow>(
` `
WITH worker_orders AS ( WITH worker_base AS (
SELECT SELECT
CASE wo.id,
WHEN ( wo.status AS wo_status,
CASE wos.status AS wos_status,
WHEN wos.id IS NOT NULL AND wo.status NOT IN ('accepted', 'cancelled', 'problem')
THEN CASE wos.status
WHEN 'joined' THEN 'in_progress'
WHEN 'submitted' THEN 'pending_acceptance'
WHEN 'accepted' THEN 'accepted'
WHEN 'cancelled' THEN 'cancelled'
ELSE wo.status
END
ELSE wo.status
END
) = 'in_progress' AND (
EXISTS (
SELECT 1
FROM worker_order_cancel_requests wcr
WHERE wcr.work_order_id = wo.id
AND wcr.worker_id = $1
AND wcr.status = 'pending'
) OR EXISTS (
SELECT 1
FROM worker_order_feedbacks wf
WHERE wf.work_order_id = wo.id
AND wf.worker_id = $1
AND wf.status = 'pending'
)
) THEN 'problem'
ELSE CASE
WHEN wos.id IS NOT NULL AND wo.status NOT IN ('accepted', 'cancelled', 'problem')
THEN CASE wos.status
WHEN 'joined' THEN 'in_progress'
WHEN 'submitted' THEN 'pending_acceptance'
WHEN 'accepted' THEN 'accepted'
WHEN 'cancelled' THEN 'cancelled'
ELSE wo.status
END
ELSE wo.status
END
END AS status,
wo.acceptance_json,
wos.id IS NOT NULL AS is_worker_share, wos.id IS NOT NULL AS is_worker_share,
CASE CASE
WHEN wos.id IS NOT NULL THEN wos.share_reward WHEN wos.id IS NOT NULL THEN wos.share_reward
WHEN wo.assigned_worker_id = $1 THEN wo.reward_amount WHEN wo.assigned_worker_id = $1 THEN wo.reward_amount
ELSE 0 ELSE 0
END AS worker_settlement_amount END AS worker_settlement_amount,
wo.acceptance_json
FROM work_orders wo FROM work_orders wo
LEFT JOIN work_order_shares wos LEFT JOIN work_order_shares wos
ON wos.work_order_id = wo.id ON wos.work_order_id = wo.id
AND wos.worker_id = $1 AND wos.worker_id = $1
AND wos.status != 'cancelled' AND wos.status != 'cancelled'
WHERE wo.assigned_worker_id = $1 WHERE wo.assigned_worker_id = $1
OR ( UNION
wo.last_assigned_worker_id = $1 SELECT
AND ( wo.id,
wo.status <> 'open' wo.status,
OR EXISTS ( wos.status,
SELECT 1 wos.id IS NOT NULL,
FROM work_order_events timeout_event CASE
WHERE timeout_event.work_order_id = wo.id WHEN wos.id IS NOT NULL THEN wos.share_reward
AND timeout_event.event_type = 'timeout_reopen' WHEN wo.assigned_worker_id = $1 THEN wo.reward_amount
) ELSE 0
END,
wo.acceptance_json
FROM work_orders wo
LEFT JOIN work_order_shares wos
ON wos.work_order_id = wo.id
AND wos.worker_id = $1
AND wos.status != 'cancelled'
WHERE wo.last_assigned_worker_id = $1
AND (
wo.status <> 'open'
OR EXISTS (
SELECT 1
FROM work_order_events timeout_event
WHERE timeout_event.work_order_id = wo.id
AND timeout_event.event_type = 'timeout_reopen'
) )
) )
OR wos.id IS NOT NULL UNION
SELECT
wo.id,
wo.status,
wos.status,
TRUE,
wos.share_reward,
wo.acceptance_json
FROM work_orders wo
INNER JOIN work_order_shares wos
ON wos.work_order_id = wo.id
AND wos.worker_id = $1
AND wos.status != 'cancelled'
),
worker_orders AS (
SELECT
CASE
WHEN (
CASE
WHEN is_worker_share AND wo_status NOT IN ('accepted', 'cancelled', 'problem')
THEN CASE wos_status
WHEN 'joined' THEN 'in_progress'
WHEN 'submitted' THEN 'pending_acceptance'
WHEN 'accepted' THEN 'accepted'
WHEN 'cancelled' THEN 'cancelled'
ELSE wo_status
END
ELSE wo_status
END
) = 'in_progress' AND (
EXISTS (
SELECT 1
FROM worker_order_cancel_requests wcr
WHERE wcr.work_order_id = worker_base.id
AND wcr.worker_id = $1
AND wcr.status = 'pending'
) OR EXISTS (
SELECT 1
FROM worker_order_feedbacks wf
WHERE wf.work_order_id = worker_base.id
AND wf.worker_id = $1
AND wf.status = 'pending'
)
) THEN 'problem'
ELSE CASE
WHEN is_worker_share AND wo_status NOT IN ('accepted', 'cancelled', 'problem')
THEN CASE wos_status
WHEN 'joined' THEN 'in_progress'
WHEN 'submitted' THEN 'pending_acceptance'
WHEN 'accepted' THEN 'accepted'
WHEN 'cancelled' THEN 'cancelled'
ELSE wo_status
END
ELSE wo_status
END
END AS status,
acceptance_json,
is_worker_share,
worker_settlement_amount
FROM worker_base
) )
SELECT SELECT
status, status,