diff --git a/app/Http/Controllers/Admin/PlatformOrderController.php b/app/Http/Controllers/Admin/PlatformOrderController.php index 929631e..7dc1adc 100644 --- a/app/Http/Controllers/Admin/PlatformOrderController.php +++ b/app/Http/Controllers/Admin/PlatformOrderController.php @@ -583,6 +583,105 @@ class PlatformOrderController extends Controller return redirect()->back()->with('success', $msg); } + public function batchMarkActivated(Request $request): RedirectResponse + { + $admin = $this->ensurePlatformAdmin($request); + + // 支持两种 scope: + // - scope=filtered:只处理当前筛选范围内的订单(更安全,默认) + // - scope=all:处理全部订单(谨慎) + $scope = (string) $request->input('scope', 'filtered'); + + $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', ''), + 'synced_only' => (string) $request->input('synced_only', ''), + 'sync_status' => trim((string) $request->input('sync_status', '')), + 'keyword' => trim((string) $request->input('keyword', '')), + 'syncable_only' => (string) $request->input('syncable_only', ''), + 'batch_synced_24h' => (string) $request->input('batch_synced_24h', ''), + ]; + + // 防误操作:批量“仅标记为已生效”默认要求当前筛选口径为「已支付 + 待处理(pending)」 + if ($scope === 'filtered') { + if (($filters['payment_status'] ?? '') !== 'paid' || ($filters['status'] ?? '') !== 'pending') { + return redirect()->back()->with('warning', '为避免误操作,请先筛选「支付状态=已支付」且「订单状态=待处理」,再执行批量仅标记为已生效。'); + } + } + + // 防误操作:scope=all 需要二次确认 + if ($scope === 'all' && (string) $request->input('confirm', '') !== 'YES') { + return redirect()->back()->with('warning', '为避免误操作,执行全量批量生效前请在确认框输入 YES。'); + } + + $query = PlatformOrder::query(); + + if ($scope === 'filtered') { + $query = $this->applyFilters($query, $filters); + } + + // 只处理“已支付 + 待处理”的订单(双保险) + $query = $query + ->where('payment_status', 'paid') + ->where('status', 'pending'); + + $limit = (int) $request->input('limit', 50); + $limit = max(1, min(500, $limit)); + + $matchedTotal = (clone $query)->count(); + + $orders = $query->orderByDesc('id')->limit($limit)->get(['id']); + $processed = $orders->count(); + + $success = 0; + $nowStr = now()->toDateTimeString(); + + foreach ($orders as $row) { + $order = PlatformOrder::query()->find($row->id); + if (! $order) { + continue; + } + + // 再次防御:仅推进 pending + if ($order->payment_status !== 'paid' || $order->status !== 'pending') { + continue; + } + + $order->status = 'activated'; + $order->activated_at = $order->activated_at ?: now(); + + $meta = (array) ($order->meta ?? []); + $audit = (array) (data_get($meta, 'audit', []) ?? []); + $audit[] = [ + 'action' => 'batch_mark_activated', + 'scope' => $scope, + 'at' => $nowStr, + 'admin_id' => $admin->id, + ]; + data_set($meta, 'audit', $audit); + + // 便于筛选/统计:记录最近一次批量生效信息(扁平字段) + data_set($meta, 'batch_mark_activated', [ + 'at' => $nowStr, + 'admin_id' => $admin->id, + 'scope' => $scope, + ]); + + $order->meta = $meta; + $order->save(); + + $success++; + } + + $msg = '批量仅标记为已生效完成:成功 ' . $success . ' 条(命中 ' . $matchedTotal . ' 条,本次处理 ' . $processed . ' 条,limit=' . $limit . ')'; + + return redirect()->back()->with('success', $msg); + } + public function clearSyncErrors(Request $request): RedirectResponse { $this->ensurePlatformAdmin($request); diff --git a/resources/views/admin/platform_orders/index.blade.php b/resources/views/admin/platform_orders/index.blade.php index ecd4681..5c38712 100644 --- a/resources/views/admin/platform_orders/index.blade.php +++ b/resources/views/admin/platform_orders/index.blade.php @@ -200,6 +200,45 @@ +
+ + +