全项目数据库性能优化

This commit is contained in:
yml2213
2026-08-20 23:04:52 +08:00
parent 1c8eda2b5f
commit b5d46b2381
13 changed files with 168 additions and 43 deletions
@@ -4,7 +4,7 @@ import { nowIso } from '../../utils/time.js'
import type { JsonObject } from '../../types/json.js'
export async function getAdminDashboardSummary() {
const todayPrefix = nowIso().slice(0, 10)
const { todayStartIso, tomorrowStartIso } = resolveChinaTodayRange(nowIso())
const paidPendingClaimStatuses = [
TASK_STATUS.PAID,
TASK_STATUS.LINK_GENERATED,
@@ -16,31 +16,36 @@ export async function getAdminDashboardSummary() {
const result = await query(
`
SELECT
(SELECT COUNT(*)::int FROM orders WHERE to_char(created_at AT TIME ZONE 'Asia/Shanghai', 'YYYY-MM-DD') = $1) AS today_orders,
(
SELECT COUNT(*)::int
FROM fulfillment_tasks
WHERE task_status = ANY($2::text[])
) AS paid_pending_claim,
FROM orders
WHERE created_at >= $1 AND created_at < $2
) AS today_orders,
(
SELECT COUNT(*)::int
FROM fulfillment_tasks
WHERE task_status = ANY($3::text[])
) AS paid_pending_claim,
(
SELECT COUNT(*)::int
FROM fulfillment_tasks
WHERE task_status = ANY($4::text[])
) AS claiming_tasks,
(
SELECT COUNT(*)::int
FROM fulfillment_tasks
WHERE task_status = $4
AND to_char(updated_at AT TIME ZONE 'Asia/Shanghai', 'YYYY-MM-DD') = $1
WHERE task_status = $5
AND updated_at >= $1 AND updated_at < $2
) AS redeemed_today,
(
SELECT COUNT(*)::int
FROM fulfillment_tasks
WHERE task_status = ANY($5::text[])
WHERE task_status = ANY($6::text[])
) AS abnormal_tasks
`,
[
todayPrefix,
todayStartIso,
tomorrowStartIso,
paidPendingClaimStatuses,
claimingStatuses,
TASK_STATUS.REDEEMED,
@@ -57,3 +62,28 @@ export async function getAdminDashboardSummary() {
abnormalTasks: Number(summary?.abnormal_tasks || 0),
}
}
/** 返回中国时区当天对应的 UTC 查询范围,便于使用时间索引。 */
function resolveChinaTodayRange(now: string) {
const parts = new Intl.DateTimeFormat('en-US', {
timeZone: 'Asia/Shanghai',
year: 'numeric',
month: '2-digit',
day: '2-digit',
})
.formatToParts(new Date(now))
.reduce<Record<string, string>>((result, part) => {
result[part.type] = part.value
return result
}, {})
const year = Number(parts.year || 0)
const month = Number(parts.month || 1)
const day = Number(parts.day || 1)
const todayStart = Date.UTC(year || 0, (month || 1) - 1, day || 1, -8)
const tomorrowStart = todayStart + 24 * 60 * 60 * 1000
return {
todayStartIso: new Date(todayStart).toISOString(),
tomorrowStartIso: new Date(tomorrowStart).toISOString(),
}
}
@@ -1389,7 +1389,6 @@ export async function listWorkerHallOrders(query: JsonObject = {}, session: Work
const pageSize = normalizePageSize(query.pageSize)
const categoryId = normalizeOptionalId(query.categoryId)
const worker = await getRequiredWorker(session.workerId)
await settleOverdueWorkOrders({ workerId: worker.id, limit: 50 })
const permissions = resolveWorkerPermissions(worker)
const visibleDelaySeconds = Number(permissions.visibleDelaySeconds || 0)
const visibleAfterIso =
@@ -1650,7 +1649,6 @@ export async function settleOverdueWorkOrders(options: { limit?: number; workerI
export async function listWorkerMyOrders(query: JsonObject = {}, session: WorkerSession) {
requireActiveWorkerSession(session)
const worker = await getRequiredWorker(session.workerId)
await settleOverdueWorkOrders({ workerId: worker.id, limit: 50 })
const page = normalizePage(query.page)
const pageSize = normalizePageSize(query.pageSize)
const vipEvidencePending = normalizeBoolean(query.vipEvidencePending, false)