diff --git a/app/Http/Controllers/Admin/PlatformOrderController.php b/app/Http/Controllers/Admin/PlatformOrderController.php index 22f3a73..ad513f0 100644 --- a/app/Http/Controllers/Admin/PlatformOrderController.php +++ b/app/Http/Controllers/Admin/PlatformOrderController.php @@ -4,12 +4,15 @@ namespace App\Http\Controllers\Admin; use App\Http\Controllers\Concerns\ResolvesPlatformAdminContext; use App\Http\Controllers\Controller; +use App\Models\Merchant; +use App\Models\Plan; use App\Models\PlatformOrder; use App\Support\SubscriptionActivationService; use Illuminate\Database\Eloquent\Builder; use Illuminate\Http\RedirectResponse; use Illuminate\Http\Request; use Illuminate\Support\Facades\DB; +use Illuminate\Validation\Rule; use Illuminate\View\View; use Symfony\Component\HttpFoundation\StreamedResponse; @@ -17,6 +20,89 @@ class PlatformOrderController extends Controller { use ResolvesPlatformAdminContext; + public function create(Request $request): View + { + $this->ensurePlatformAdmin($request); + + $merchants = Merchant::query()->orderBy('id')->get(['id', 'name']); + $plans = Plan::query()->orderBy('sort')->orderByDesc('id')->get(); + + return view('admin.platform_orders.form', [ + 'merchants' => $merchants, + 'plans' => $plans, + 'billingCycleLabels' => $this->billingCycleLabels(), + 'orderTypeLabels' => $this->orderTypeLabels(), + ]); + } + + public function store(Request $request): RedirectResponse + { + $admin = $this->ensurePlatformAdmin($request); + + $data = $request->validate([ + 'merchant_id' => ['required', 'integer', 'exists:merchants,id'], + 'plan_id' => ['required', 'integer', 'exists:plans,id'], + 'order_type' => ['required', Rule::in(array_keys($this->orderTypeLabels()))], + 'quantity' => ['required', 'integer', 'min:1', 'max:120'], + 'discount_amount' => ['nullable', 'numeric', 'min:0'], + 'payment_channel' => ['nullable', 'string', 'max:30'], + 'remark' => ['nullable', 'string', 'max:2000'], + ]); + + $plan = Plan::query()->findOrFail((int) $data['plan_id']); + + $periodMonths = $this->periodMonthsFromBillingCycle((string) $plan->billing_cycle); + $quantity = (int) $data['quantity']; + + $listAmount = (float) $plan->price * $quantity; + $discount = (float) ($data['discount_amount'] ?? 0); + $discount = max(0, min($listAmount, $discount)); + + $payable = max(0, $listAmount - $discount); + + $now = now(); + + // 订单号:PO + 时间 + 4位随机数(足够用于当前阶段演示与手工补单) + $orderNo = 'PO' . $now->format('YmdHis') . str_pad((string) random_int(1, 9999), 4, '0', STR_PAD_LEFT); + + $order = PlatformOrder::query()->create([ + 'merchant_id' => (int) $data['merchant_id'], + 'plan_id' => $plan->id, + 'created_by_admin_id' => $admin->id, + 'order_no' => $orderNo, + 'order_type' => (string) $data['order_type'], + 'status' => 'pending', + 'payment_status' => 'unpaid', + 'payment_channel' => $data['payment_channel'] ?? null, + 'plan_name' => $plan->name, + 'billing_cycle' => $plan->billing_cycle, + 'period_months' => $periodMonths, + 'quantity' => $quantity, + 'list_amount' => $listAmount, + 'discount_amount' => $discount, + 'payable_amount' => $payable, + 'paid_amount' => 0, + 'placed_at' => $now, + 'plan_snapshot' => [ + 'plan_id' => $plan->id, + 'code' => $plan->code, + 'name' => $plan->name, + 'billing_cycle' => $plan->billing_cycle, + 'price' => (float) $plan->price, + 'list_price' => (float) $plan->list_price, + 'status' => $plan->status, + 'published_at' => optional($plan->published_at)->toDateTimeString(), + ], + 'meta' => [ + 'created_from' => 'manual_form', + ], + 'remark' => $data['remark'] ?? null, + ]); + + return redirect('/admin/platform-orders/' . $order->id) + ->with('success', '平台订单已创建:' . $order->order_no . '(待支付/待生效)'); + } + public function index(Request $request): View { $this->ensurePlatformAdmin($request); @@ -610,4 +696,35 @@ class PlatformOrderController extends Controller 'failed' => '支付失败', ]; } + + protected function orderTypeLabels(): array + { + return [ + 'new_purchase' => '新购', + 'renewal' => '续费', + 'upgrade' => '升级', + 'downgrade' => '降级', + ]; + } + + protected function billingCycleLabels(): array + { + return [ + 'monthly' => '月付', + 'quarterly' => '季付', + 'yearly' => '年付', + 'one_time' => '一次性', + ]; + } + + protected function periodMonthsFromBillingCycle(string $billingCycle): int + { + return match ($billingCycle) { + 'monthly' => 1, + 'quarterly' => 3, + 'yearly' => 12, + 'one_time' => 1, + default => 1, + }; + } } diff --git a/resources/views/admin/platform_orders/form.blade.php b/resources/views/admin/platform_orders/form.blade.php new file mode 100644 index 0000000..1350833 --- /dev/null +++ b/resources/views/admin/platform_orders/form.blade.php @@ -0,0 +1,74 @@ +@extends('admin.layouts.app') + +@section('title', '新建平台订单') +@section('page_title', '新建平台订单') + +@section('content') +
用于总台运营手工创建一笔平台订单(演示/补单/线下收款录入)。
+创建后可在「平台订单」列表中继续推进:标记支付并生效 → 同步订阅(形成最小收费闭环)。
+