优化打手订单结算和大厅加载
This commit is contained in:
@@ -48,6 +48,14 @@ const WORK_ORDER_SHARE_SELECT = `
|
||||
LEFT JOIN worker_users wu ON wu.id = wos.worker_id
|
||||
`
|
||||
|
||||
type WorkerOrderOverviewRow = {
|
||||
status: string
|
||||
order_count: number
|
||||
settlement_amount: number
|
||||
vip_evidence_pending_count: number
|
||||
vip_evidence_pending_settlement_amount: number
|
||||
}
|
||||
|
||||
export async function listWorkOrderShares(
|
||||
workOrderId: number | string,
|
||||
): Promise<WorkOrderShareRow[]> {
|
||||
@@ -820,6 +828,81 @@ export async function listWorkOrders({
|
||||
return { items: itemsResult.rows, total: Number(totalResult.rows[0]?.total || 0) }
|
||||
}
|
||||
|
||||
/** 汇总打手本人各订单状态的可结算金额,拼单按个人份额计算。 */
|
||||
export async function getWorkerOrderOverview(workerId: number | string): Promise<
|
||||
Array<{
|
||||
status: string
|
||||
orderCount: number
|
||||
settlementAmount: number
|
||||
vipEvidencePendingCount: number
|
||||
vipEvidencePendingSettlementAmount: number
|
||||
}>
|
||||
> {
|
||||
const normalizedWorkerId = Number(workerId)
|
||||
const result = await query<WorkerOrderOverviewRow>(
|
||||
`
|
||||
WITH worker_orders AS (
|
||||
SELECT
|
||||
wo.status,
|
||||
wo.acceptance_json,
|
||||
wos.id IS NOT NULL AS is_worker_share,
|
||||
CASE
|
||||
WHEN wos.id IS NOT NULL THEN wos.share_reward
|
||||
WHEN wo.assigned_worker_id = $1 THEN wo.reward_amount
|
||||
ELSE 0
|
||||
END AS worker_settlement_amount
|
||||
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.assigned_worker_id = $1
|
||||
OR wo.last_assigned_worker_id = $1
|
||||
OR wos.id IS NOT NULL
|
||||
)
|
||||
SELECT
|
||||
status,
|
||||
COUNT(*)::int AS order_count,
|
||||
COALESCE(
|
||||
SUM(
|
||||
CASE
|
||||
WHEN status IN ('in_progress', 'pending_acceptance', 'problem', 'accepted')
|
||||
OR (status = 'open' AND is_worker_share)
|
||||
THEN worker_settlement_amount
|
||||
ELSE 0
|
||||
END
|
||||
),
|
||||
0
|
||||
)::int AS settlement_amount,
|
||||
COUNT(*) FILTER (
|
||||
WHERE status = 'accepted'
|
||||
AND acceptance_json->>'reviewMode' = 'vip_auto'
|
||||
AND acceptance_json->>'evidenceStatus' = 'pending'
|
||||
AND NULLIF(acceptance_json->>'evidenceDueAt', '')::timestamptz > NOW()
|
||||
)::int AS vip_evidence_pending_count,
|
||||
COALESCE(
|
||||
SUM(worker_settlement_amount) FILTER (
|
||||
WHERE status = 'accepted'
|
||||
AND acceptance_json->>'reviewMode' = 'vip_auto'
|
||||
AND acceptance_json->>'evidenceStatus' = 'pending'
|
||||
AND NULLIF(acceptance_json->>'evidenceDueAt', '')::timestamptz > NOW()
|
||||
),
|
||||
0
|
||||
)::int AS vip_evidence_pending_settlement_amount
|
||||
FROM worker_orders
|
||||
GROUP BY status
|
||||
`,
|
||||
[normalizedWorkerId],
|
||||
)
|
||||
return result.rows.map((row) => ({
|
||||
status: row.status,
|
||||
orderCount: Number(row.order_count || 0),
|
||||
settlementAmount: Number(row.settlement_amount || 0),
|
||||
vipEvidencePendingCount: Number(row.vip_evidence_pending_count || 0),
|
||||
vipEvidencePendingSettlementAmount: Number(row.vip_evidence_pending_settlement_amount || 0),
|
||||
}))
|
||||
}
|
||||
|
||||
export async function updateWorkOrder(
|
||||
workOrderId: number | string,
|
||||
patch: Partial<
|
||||
|
||||
@@ -11,6 +11,7 @@ import {
|
||||
getWorkerProfile,
|
||||
getWorkerSessionSummary,
|
||||
getWorkerHallLeaderboard,
|
||||
getWorkerMyOrderOverview,
|
||||
grabWorkerHallOrder,
|
||||
joinWorkerSharingOrder,
|
||||
listWorkerProfileFinanceRequests,
|
||||
@@ -268,6 +269,16 @@ router.get(
|
||||
}),
|
||||
)
|
||||
|
||||
router.get(
|
||||
'/orders/overview',
|
||||
requireActiveWorker,
|
||||
createRouteHandler((req) => getWorkerMyOrderOverview(getRequiredWorkerSession(req)), {
|
||||
successMessage: 'ok',
|
||||
errorMessage: '读取我的订单概览失败',
|
||||
scope: '[worker/orders/overview]',
|
||||
}),
|
||||
)
|
||||
|
||||
router.get(
|
||||
'/orders/:workOrderId/events',
|
||||
requireActiveWorker,
|
||||
|
||||
@@ -28,6 +28,7 @@ import {
|
||||
getWorkerUserByDisplayName,
|
||||
getWorkOrderById,
|
||||
getWorkOrderShare,
|
||||
getWorkerOrderOverview,
|
||||
grabWorkOrder,
|
||||
incrementWorkerSessionVersion,
|
||||
joinWorkOrderShare,
|
||||
@@ -1148,6 +1149,40 @@ export async function listWorkerMyOrders(query: JsonObject = {}, session: Worker
|
||||
}
|
||||
}
|
||||
|
||||
/** 打手订单标签概览:订单数与预计/已结算金额。 */
|
||||
export async function getWorkerMyOrderOverview(session: WorkerSession) {
|
||||
requireActiveWorkerSession(session)
|
||||
const worker = await getRequiredWorker(session.workerId)
|
||||
await settleOverdueWorkOrders({ workerId: worker.id, limit: 50 })
|
||||
const rows = await getWorkerOrderOverview(worker.id)
|
||||
const items = rows.map((row) => ({
|
||||
status: row.status,
|
||||
orderCount: row.orderCount,
|
||||
settlementAmount: row.settlementAmount,
|
||||
}))
|
||||
const vipEvidencePending = rows.reduce(
|
||||
(summary, row) => ({
|
||||
orderCount: summary.orderCount + row.vipEvidencePendingCount,
|
||||
settlementAmount: summary.settlementAmount + row.vipEvidencePendingSettlementAmount,
|
||||
}),
|
||||
{ orderCount: 0, settlementAmount: 0 },
|
||||
)
|
||||
const all = items.reduce(
|
||||
(summary, item) => ({
|
||||
orderCount: summary.orderCount + item.orderCount,
|
||||
settlementAmount: summary.settlementAmount + item.settlementAmount,
|
||||
}),
|
||||
{ orderCount: 0, settlementAmount: 0 },
|
||||
)
|
||||
return {
|
||||
items: [
|
||||
...items,
|
||||
{ status: 'vip_evidence_pending', ...vipEvidencePending },
|
||||
{ status: 'all', ...all },
|
||||
],
|
||||
}
|
||||
}
|
||||
|
||||
export async function getWorkerMyOrderEvents(workOrderId: number | string, session: WorkerSession) {
|
||||
requireActiveWorkerSession(session)
|
||||
if (runtimeConfig.worker.orderTimelineVisible !== true) {
|
||||
|
||||
Reference in New Issue
Block a user