平台订单:新增退款不一致 refund_inconsistent 筛选与摘要卡

This commit is contained in:
萝卜
2026-03-11 04:29:52 +00:00
parent 9de9a44318
commit 35ab780f8c
3 changed files with 205 additions and 0 deletions

View File

@@ -155,6 +155,8 @@ class PlatformOrderController extends Controller
'receipt_status' => trim((string) $request->query('receipt_status', '')),
// 退款轨迹筛选has有退款/none无退款
'refund_status' => trim((string) $request->query('refund_status', '')),
// 退款数据不一致(可治理):基于 refund_summary.total_amount 与 paid_amount 对比
'refund_inconsistent' => (string) $request->query('refund_inconsistent', ''),
];
@@ -328,6 +330,13 @@ class PlatformOrderController extends Controller
return $this->applyFilters(PlatformOrder::query(), $mismatchFilters)->count();
})(),
// 退款数据不一致订单数(在当前筛选范围基础上叠加 inconsistent 口径)
'refund_inconsistent_orders' => (function () use ($filters) {
$f = $filters;
$f['refund_inconsistent'] = '1';
return $this->applyFilters(PlatformOrder::query(), $f)->count();
})(),
],
'failedReasonStats' => $failedReasonStats,
]);
@@ -634,6 +643,8 @@ class PlatformOrderController extends Controller
'receipt_status' => trim((string) $request->query('receipt_status', '')),
// 退款轨迹筛选has有退款/none无退款
'refund_status' => trim((string) $request->query('refund_status', '')),
// 退款数据不一致(可治理):基于 refund_summary.total_amount 与 paid_amount 对比
'refund_inconsistent' => (string) $request->query('refund_inconsistent', ''),
];
@@ -823,6 +834,7 @@ class PlatformOrderController extends Controller
'reconcile_mismatch' => (string) $request->input('reconcile_mismatch', ''),
'receipt_status' => trim((string) $request->input('receipt_status', '')),
'refund_status' => trim((string) $request->input('refund_status', '')),
'refund_inconsistent' => (string) $request->input('refund_inconsistent', ''),
];
// 防误操作:批量同步默认要求先勾选“只看可同步”,避免无意识扩大处理范围
@@ -967,6 +979,7 @@ class PlatformOrderController extends Controller
'reconcile_mismatch' => (string) $request->input('reconcile_mismatch', ''),
'receipt_status' => trim((string) $request->input('receipt_status', '')),
'refund_status' => trim((string) $request->input('refund_status', '')),
'refund_inconsistent' => (string) $request->input('refund_inconsistent', ''),
];
// 防误操作:批量“仅标记为已生效”默认要求当前筛选口径为「已支付 + 待处理(pending)」
@@ -1088,6 +1101,7 @@ class PlatformOrderController extends Controller
'reconcile_mismatch' => (string) $request->input('reconcile_mismatch', ''),
'receipt_status' => trim((string) $request->input('receipt_status', '')),
'refund_status' => trim((string) $request->input('refund_status', '')),
'refund_inconsistent' => (string) $request->input('refund_inconsistent', ''),
];
$query = PlatformOrder::query()
@@ -1277,6 +1291,46 @@ class PlatformOrderController extends Controller
$builder->whereRaw("JSON_EXTRACT(meta, '$.refund_summary.total_amount') IS NULL")
->whereRaw("JSON_EXTRACT(meta, '$.refund_receipts[0].amount') IS NULL");
}
})
->when(($filters['refund_inconsistent'] ?? '') !== '', function (Builder $builder) {
// 退款数据不一致(可治理):
// - 状态=refunded 但 退款总额 < 已付金额(允许 0.01 容差)
// - 状态!=refunded 且 已付金额>0 且 退款总额 >= 已付金额
// 退款总额口径:优先 refund_summary.total_amount缺省回退汇总 refund_receipts[].amount
$driver = $builder->getQuery()->getConnection()->getDriverName();
if ($driver === 'sqlite') {
$refundTotalExpr = "(CASE WHEN JSON_EXTRACT(meta, '$.refund_summary.total_amount') IS NOT NULL THEN CAST(JSON_EXTRACT(meta, '$.refund_summary.total_amount') AS REAL) ELSE (SELECT IFNULL(SUM(CAST(JSON_EXTRACT(value, '$.amount') AS REAL)), 0) FROM json_each(COALESCE(JSON_EXTRACT(meta, '$.refund_receipts'), '[]'))) END)";
$builder->where(function (Builder $q) use ($refundTotalExpr) {
// refunded 但退款不够
$q->where(function (Builder $q2) use ($refundTotalExpr) {
$q2->where('payment_status', 'refunded')
->whereRaw("paid_amount > 0")
->whereRaw("(ROUND($refundTotalExpr * 100) + 1) < ROUND(paid_amount * 100)");
})
// 非 refunded 但退款已达到/超过已付
->orWhere(function (Builder $q2) use ($refundTotalExpr) {
$q2->where('payment_status', '!=', 'refunded')
->whereRaw("paid_amount > 0")
->whereRaw("ROUND($refundTotalExpr * 100) >= ROUND(paid_amount * 100)");
});
});
} else {
$refundTotalExpr = "(CASE WHEN JSON_EXTRACT(meta, '$.refund_summary.total_amount') IS NOT NULL THEN CAST(JSON_UNQUOTE(JSON_EXTRACT(meta, '$.refund_summary.total_amount')) AS DECIMAL(12,2)) ELSE (SELECT IFNULL(SUM(j.amount), 0) FROM JSON_TABLE(meta, '$.refund_receipts[*]' COLUMNS(amount DECIMAL(12,2) PATH '$.amount')) j) END)";
$builder->where(function (Builder $q) use ($refundTotalExpr) {
$q->where(function (Builder $q2) use ($refundTotalExpr) {
$q2->where('payment_status', 'refunded')
->whereRaw("paid_amount > 0")
->whereRaw("(ROUND($refundTotalExpr * 100) + 1) < ROUND(paid_amount * 100)");
})->orWhere(function (Builder $q2) use ($refundTotalExpr) {
$q2->where('payment_status', '!=', 'refunded')
->whereRaw("paid_amount > 0")
->whereRaw("ROUND($refundTotalExpr * 100) >= ROUND(paid_amount * 100)");
});
});
}
});
}