增加每日接单排行榜
This commit is contained in:
@@ -0,0 +1,8 @@
|
||||
-- 每日排行榜按验收时间筛选,避免全表扫描已完成工单与拼单记录。
|
||||
CREATE INDEX IF NOT EXISTS idx_work_orders_accepted_at_worker
|
||||
ON work_orders(accepted_at DESC, assigned_worker_id)
|
||||
WHERE status = 'accepted' AND assigned_worker_id IS NOT NULL;
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_work_order_shares_accepted_at_worker
|
||||
ON work_order_shares(accepted_at DESC, worker_id)
|
||||
WHERE status = 'accepted';
|
||||
@@ -960,6 +960,7 @@ export async function countWorkerAcceptedOrders(workerId: number | string): Prom
|
||||
export async function listWorkerCompletionLeaderboard(input: {
|
||||
limit: number
|
||||
currentWorkerId: number
|
||||
period?: 'all' | 'daily'
|
||||
}): Promise<
|
||||
Array<{
|
||||
rank: number
|
||||
@@ -970,6 +971,7 @@ export async function listWorkerCompletionLeaderboard(input: {
|
||||
}>
|
||||
> {
|
||||
const limit = Math.min(50, Math.max(1, Math.floor(Number(input.limit || 10))))
|
||||
const dailyOnly = input.period === 'daily'
|
||||
const result = await query<{
|
||||
rank: number
|
||||
worker_id: number
|
||||
@@ -978,7 +980,12 @@ export async function listWorkerCompletionLeaderboard(input: {
|
||||
accepted_order_count: number
|
||||
}>(
|
||||
`
|
||||
WITH accepted_totals AS (
|
||||
WITH leaderboard_day AS (
|
||||
SELECT
|
||||
date_trunc('day', CURRENT_TIMESTAMP AT TIME ZONE 'Asia/Shanghai')
|
||||
AT TIME ZONE 'Asia/Shanghai' AS starts_at
|
||||
),
|
||||
accepted_totals AS (
|
||||
SELECT
|
||||
worker_id,
|
||||
SUM(accepted_order_count)::int AS accepted_order_count,
|
||||
@@ -989,7 +996,13 @@ export async function listWorkerCompletionLeaderboard(input: {
|
||||
COUNT(*)::int AS accepted_order_count,
|
||||
MAX(accepted_at) AS last_accepted_at
|
||||
FROM work_orders
|
||||
WHERE assigned_worker_id IS NOT NULL AND status = 'accepted'
|
||||
CROSS JOIN leaderboard_day
|
||||
WHERE assigned_worker_id IS NOT NULL
|
||||
AND status = 'accepted'
|
||||
AND (
|
||||
$3::boolean = false
|
||||
OR (accepted_at >= leaderboard_day.starts_at AND accepted_at < leaderboard_day.starts_at + INTERVAL '1 day')
|
||||
)
|
||||
GROUP BY assigned_worker_id
|
||||
|
||||
UNION ALL
|
||||
@@ -999,7 +1012,12 @@ export async function listWorkerCompletionLeaderboard(input: {
|
||||
COALESCE(SUM(quantity), 0)::int AS accepted_order_count,
|
||||
MAX(accepted_at) AS last_accepted_at
|
||||
FROM work_order_shares
|
||||
CROSS JOIN leaderboard_day
|
||||
WHERE status = 'accepted'
|
||||
AND (
|
||||
$3::boolean = false
|
||||
OR (accepted_at >= leaderboard_day.starts_at AND accepted_at < leaderboard_day.starts_at + INTERVAL '1 day')
|
||||
)
|
||||
GROUP BY worker_id
|
||||
) AS accepted_records
|
||||
GROUP BY worker_id
|
||||
@@ -1023,7 +1041,7 @@ export async function listWorkerCompletionLeaderboard(input: {
|
||||
WHERE rank <= $1 OR worker_id = $2
|
||||
ORDER BY rank ASC
|
||||
`,
|
||||
[limit, Number(input.currentWorkerId)],
|
||||
[limit, Number(input.currentWorkerId), dailyOnly],
|
||||
)
|
||||
return result.rows.map((row) => ({
|
||||
rank: Number(row.rank || 0),
|
||||
|
||||
@@ -304,11 +304,14 @@ router.get(
|
||||
router.get(
|
||||
'/hall/leaderboard',
|
||||
requireActiveWorker,
|
||||
createRouteHandler((req) => getWorkerHallLeaderboard(getRequiredWorkerSession(req)), {
|
||||
successMessage: 'ok',
|
||||
errorMessage: '读取接单排行榜失败',
|
||||
scope: '[worker/hall/leaderboard]',
|
||||
}),
|
||||
createRouteHandler(
|
||||
(req) => getWorkerHallLeaderboard(getRequiredWorkerSession(req), req.query?.period),
|
||||
{
|
||||
successMessage: 'ok',
|
||||
errorMessage: '读取接单排行榜失败',
|
||||
scope: '[worker/hall/leaderboard]',
|
||||
},
|
||||
),
|
||||
)
|
||||
|
||||
router.post(
|
||||
|
||||
@@ -1202,11 +1202,13 @@ export async function listWorkerHallOrders(query: JsonObject = {}, session: Work
|
||||
}
|
||||
}
|
||||
|
||||
export async function getWorkerHallLeaderboard(session: WorkerSession) {
|
||||
export async function getWorkerHallLeaderboard(session: WorkerSession, period: unknown = 'all') {
|
||||
requireActiveWorkerSession(session)
|
||||
const leaderboardPeriod = period === 'daily' ? 'daily' : 'all'
|
||||
const entries = await listWorkerCompletionLeaderboard({
|
||||
limit: 10,
|
||||
currentWorkerId: session.workerId,
|
||||
period: leaderboardPeriod,
|
||||
})
|
||||
const current = entries.find((entry) => entry.workerId === session.workerId)
|
||||
return {
|
||||
|
||||
Reference in New Issue
Block a user