增加接单工单筛选统计

This commit is contained in:
yml2213
2026-08-17 15:49:47 +08:00
parent f938ab0cba
commit ecac7b63db
7 changed files with 180 additions and 2 deletions
@@ -253,6 +253,14 @@ export type ListInput = {
sort?: 'id_desc' | 'worker_claimed_at_desc'
}
export type WorkOrderStatistics = {
totalCount: number
userPaymentAmount: number
rewardAmount: number
refundAmount: number
statusCounts: Record<string, number>
}
export type ProductRuleListInput = {
enabled?: boolean | null
keyword?: string
@@ -15,6 +15,7 @@ import type {
WorkerDepositUnfreezeRow,
WorkOrderRow,
WorkOrderShareRow,
WorkOrderStatistics,
WorkProductRuleRow,
} from './types.js'
import type { PoolClient } from 'pg'
@@ -56,6 +57,14 @@ type WorkerOrderOverviewRow = {
vip_evidence_pending_settlement_amount: number
}
type WorkOrderStatisticsRow = {
status: string
total_count: number
user_payment_amount: number | string
reward_amount: number | string
refund_amount: number | string
}
export async function listWorkOrderShares(
workOrderId: number | string,
): Promise<WorkOrderShareRow[]> {
@@ -830,6 +839,64 @@ export async function listWorkOrders({
return { items: itemsResult.rows, total: Number(totalResult.rows[0]?.total || 0) }
}
/** 按筛选条件汇总工单,统计范围不受当前分页影响。 */
export async function getWorkOrderStatistics(input: ListInput = {}): Promise<WorkOrderStatistics> {
const { whereClause, params } = buildWorkOrderWhere(input)
const vipEvidencePendingWhere = `
wo.status = 'accepted'
AND wo.acceptance_json->>'reviewMode' = 'vip_auto'
AND wo.acceptance_json->>'evidenceStatus' = 'pending'
AND NULLIF(wo.acceptance_json->>'evidenceDueAt', '')::timestamptz > NOW()
`
const statusExpression = input.vipEvidencePending
? `CASE WHEN ${vipEvidencePendingWhere} THEN 'vip_evidence_pending' ELSE wo.status END`
: 'wo.status'
const paymentExpression = `
CASE
WHEN COALESCE(wo.material_json->'source'->>'orderAmountFen', '') ~ '^-?[0-9]+$'
THEN (wo.material_json->'source'->>'orderAmountFen')::bigint
ELSE COALESCE(o.total_amount, 0)
END
`
const result = await query<WorkOrderStatisticsRow>(
`
SELECT
${statusExpression} AS status,
COUNT(*)::int AS total_count,
COALESCE(SUM(${paymentExpression}), 0)::bigint AS user_payment_amount,
COALESCE(SUM(wo.reward_amount), 0)::bigint AS reward_amount,
COALESCE(SUM(
CASE
WHEN o.pay_status = 'refunded' OR o.order_status = 'refunded'
THEN ${paymentExpression}
ELSE 0
END
), 0)::bigint AS refund_amount
FROM work_orders wo
LEFT JOIN orders o ON o.id = wo.order_id
${whereClause}
GROUP BY ${statusExpression}
`,
params,
)
const statistics: WorkOrderStatistics = {
totalCount: 0,
userPaymentAmount: 0,
rewardAmount: 0,
refundAmount: 0,
statusCounts: {},
}
for (const row of result.rows) {
const count = Number(row.total_count || 0)
statistics.totalCount += count
statistics.userPaymentAmount += Number(row.user_payment_amount || 0)
statistics.rewardAmount += Number(row.reward_amount || 0)
statistics.refundAmount += Number(row.refund_amount || 0)
statistics.statusCounts[row.status] = count
}
return statistics
}
/** 汇总打手本人各订单状态的可结算金额,拼单按个人份额计算。 */
export async function getWorkerOrderOverview(workerId: number | string): Promise<
Array<{
@@ -23,6 +23,7 @@ import {
getWorkerLevelById,
getWorkerLevelByKey,
getWorkerUserById,
getWorkOrderStatistics,
getWorkOrderByOrderItemId,
getWorkProductRuleByKey,
listAllWorkCategories,
@@ -761,6 +762,13 @@ export async function listAdminWorkOrders(query: JsonObject = {}) {
workerSharingId: workerId,
vipEvidencePending,
})
const statistics = await getWorkOrderStatistics({
statuses,
workOrderId,
keyword: String(query.keyword || '').trim(),
workerSharingId: workerId,
vipEvidencePending,
})
const shares = await listWorkOrderSharesByOrderIds(items.map((item) => Number(item.id)))
const sharesByOrderId = new Map<number, WorkOrderShareRow[]>()
for (const share of shares) {
@@ -789,6 +797,7 @@ export async function listAdminWorkOrders(query: JsonObject = {}) {
}
}),
pagination: { page, pageSize, total },
statistics,
}
}