platform orders: add clear bmpa errors tool and audit
This commit is contained in:
@@ -991,10 +991,12 @@ class PlatformOrderController extends Controller
|
||||
'plan_id' => trim((string) $request->input('plan_id', '')),
|
||||
'site_subscription_id' => trim((string) $request->input('site_subscription_id', '')),
|
||||
'fail_only' => (string) $request->input('fail_only', ''),
|
||||
'bmpa_failed_only' => (string) $request->input('bmpa_failed_only', ''),
|
||||
'synced_only' => (string) $request->input('synced_only', ''),
|
||||
'sync_status' => trim((string) $request->input('sync_status', '')),
|
||||
'keyword' => trim((string) $request->input('keyword', '')),
|
||||
'sync_error_keyword' => trim((string) $request->input('sync_error_keyword', '')),
|
||||
'bmpa_error_keyword' => trim((string) $request->input('bmpa_error_keyword', '')),
|
||||
'syncable_only' => (string) $request->input('syncable_only', ''),
|
||||
'batch_synced_24h' => (string) $request->input('batch_synced_24h', ''),
|
||||
// 与列表页筛选保持一致(可治理):用于在批量操作后仍能回到同一口径
|
||||
@@ -1151,10 +1153,12 @@ class PlatformOrderController extends Controller
|
||||
'plan_id' => trim((string) $request->input('plan_id', '')),
|
||||
'site_subscription_id' => trim((string) $request->input('site_subscription_id', '')),
|
||||
'fail_only' => (string) $request->input('fail_only', ''),
|
||||
'bmpa_failed_only' => (string) $request->input('bmpa_failed_only', ''),
|
||||
'synced_only' => (string) $request->input('synced_only', ''),
|
||||
'sync_status' => trim((string) $request->input('sync_status', '')),
|
||||
'keyword' => trim((string) $request->input('keyword', '')),
|
||||
'sync_error_keyword' => trim((string) $request->input('sync_error_keyword', '')),
|
||||
'bmpa_error_keyword' => trim((string) $request->input('bmpa_error_keyword', '')),
|
||||
'syncable_only' => (string) $request->input('syncable_only', ''),
|
||||
'batch_synced_24h' => (string) $request->input('batch_synced_24h', ''),
|
||||
'batch_mark_activated_24h' => (string) $request->input('batch_mark_activated_24h', ''),
|
||||
@@ -1348,10 +1352,12 @@ class PlatformOrderController extends Controller
|
||||
'plan_id' => trim((string) $request->input('plan_id', '')),
|
||||
'site_subscription_id' => trim((string) $request->input('site_subscription_id', '')),
|
||||
'fail_only' => (string) $request->input('fail_only', ''),
|
||||
'bmpa_failed_only' => (string) $request->input('bmpa_failed_only', ''),
|
||||
'synced_only' => (string) $request->input('synced_only', ''),
|
||||
'sync_status' => trim((string) $request->input('sync_status', '')),
|
||||
'keyword' => trim((string) $request->input('keyword', '')),
|
||||
'sync_error_keyword' => trim((string) $request->input('sync_error_keyword', '')),
|
||||
'bmpa_error_keyword' => trim((string) $request->input('bmpa_error_keyword', '')),
|
||||
'syncable_only' => (string) $request->input('syncable_only', ''),
|
||||
'batch_synced_24h' => (string) $request->input('batch_synced_24h', ''),
|
||||
// 与列表页筛选保持一致(可治理):用于在批量操作后仍能回到同一口径
|
||||
@@ -1450,7 +1456,7 @@ class PlatformOrderController extends Controller
|
||||
}
|
||||
|
||||
public function clearSyncErrors(Request $request): RedirectResponse
|
||||
{
|
||||
{
|
||||
$this->ensurePlatformAdmin($request);
|
||||
|
||||
// 支持两种模式:
|
||||
@@ -1470,10 +1476,12 @@ class PlatformOrderController extends Controller
|
||||
'plan_id' => trim((string) $request->input('plan_id', '')),
|
||||
'site_subscription_id' => trim((string) $request->input('site_subscription_id', '')),
|
||||
'fail_only' => (string) $request->input('fail_only', ''),
|
||||
'bmpa_failed_only' => (string) $request->input('bmpa_failed_only', ''),
|
||||
'synced_only' => (string) $request->input('synced_only', ''),
|
||||
'sync_status' => trim((string) $request->input('sync_status', '')),
|
||||
'keyword' => trim((string) $request->input('keyword', '')),
|
||||
'sync_error_keyword' => trim((string) $request->input('sync_error_keyword', '')),
|
||||
'bmpa_error_keyword' => trim((string) $request->input('bmpa_error_keyword', '')),
|
||||
'syncable_only' => (string) $request->input('syncable_only', ''),
|
||||
'batch_synced_24h' => (string) $request->input('batch_synced_24h', ''),
|
||||
// 与列表页筛选保持一致(可治理):用于在批量操作后仍能回到同一口径
|
||||
@@ -1525,6 +1533,83 @@ class PlatformOrderController extends Controller
|
||||
return redirect()->back()->with('success', $msg . $cleared . ' 条(命中 ' . $matched . ' 条)');
|
||||
}
|
||||
|
||||
public function clearBmpaErrors(Request $request): RedirectResponse
|
||||
{
|
||||
$this->ensurePlatformAdmin($request);
|
||||
|
||||
// 支持两种模式:
|
||||
// - scope=all(默认):清理所有订单的 BMPA 失败标记(需要 confirm=YES)
|
||||
// - scope=filtered:仅清理当前筛选结果命中的订单(更安全)
|
||||
$scope = (string) $request->input('scope', 'all');
|
||||
|
||||
// 防误操作:scope=all 需要二次确认
|
||||
if ($scope === 'all' && (string) $request->input('confirm', '') !== 'YES') {
|
||||
return redirect()->back()->with('warning', '为避免误操作,清除全部 BMPA 失败标记前请在确认框输入 YES。');
|
||||
}
|
||||
|
||||
$filters = [
|
||||
'status' => trim((string) $request->input('status', '')),
|
||||
'payment_status' => trim((string) $request->input('payment_status', '')),
|
||||
'merchant_id' => trim((string) $request->input('merchant_id', '')),
|
||||
'plan_id' => trim((string) $request->input('plan_id', '')),
|
||||
'site_subscription_id' => trim((string) $request->input('site_subscription_id', '')),
|
||||
'fail_only' => (string) $request->input('fail_only', ''),
|
||||
'bmpa_failed_only' => (string) $request->input('bmpa_failed_only', ''),
|
||||
'synced_only' => (string) $request->input('synced_only', ''),
|
||||
'sync_status' => trim((string) $request->input('sync_status', '')),
|
||||
'keyword' => trim((string) $request->input('keyword', '')),
|
||||
'sync_error_keyword' => trim((string) $request->input('sync_error_keyword', '')),
|
||||
'bmpa_error_keyword' => trim((string) $request->input('bmpa_error_keyword', '')),
|
||||
'syncable_only' => (string) $request->input('syncable_only', ''),
|
||||
'batch_synced_24h' => (string) $request->input('batch_synced_24h', ''),
|
||||
'batch_mark_activated_24h' => (string) $request->input('batch_mark_activated_24h', ''),
|
||||
'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()
|
||||
->whereRaw("JSON_EXTRACT(meta, '$.batch_mark_paid_and_activate_error.message') IS NOT NULL");
|
||||
|
||||
if ($scope === 'filtered') {
|
||||
$query = $this->applyFilters($query, $filters);
|
||||
}
|
||||
|
||||
$orders = $query->get(['id', 'meta']);
|
||||
$matched = $orders->count();
|
||||
|
||||
$cleared = 0;
|
||||
foreach ($orders as $order) {
|
||||
$meta = (array) ($order->meta ?? []);
|
||||
if (! data_get($meta, 'batch_mark_paid_and_activate_error')) {
|
||||
continue;
|
||||
}
|
||||
|
||||
data_forget($meta, 'batch_mark_paid_and_activate_error');
|
||||
|
||||
// 轻量审计:记录清理动作(不做独立表,先落 meta,便于排查)
|
||||
$audit = (array) (data_get($meta, 'audit', []) ?? []);
|
||||
$audit[] = [
|
||||
'action' => 'clear_bmpa_error',
|
||||
'scope' => $scope,
|
||||
'at' => now()->toDateTimeString(),
|
||||
'admin_id' => $this->platformAdminId($request),
|
||||
];
|
||||
data_set($meta, 'audit', $audit);
|
||||
|
||||
$order->meta = $meta;
|
||||
$order->save();
|
||||
$cleared++;
|
||||
}
|
||||
|
||||
$msg = $scope === 'filtered'
|
||||
? '已清除当前筛选范围内的 BMPA 失败标记:'
|
||||
: '已清除全部订单的 BMPA 失败标记:';
|
||||
|
||||
return redirect()->back()->with('success', $msg . $cleared . ' 条(命中 ' . $matched . ' 条)');
|
||||
}
|
||||
|
||||
protected function applyFilters(Builder $query, array $filters): Builder
|
||||
{
|
||||
return $query
|
||||
|
||||
Reference in New Issue
Block a user