Marriage::where('status', 'married')->count(), 'total_pending' => Marriage::where('status', 'pending')->count(), 'total_divorced' => Marriage::where('status', 'divorced')->count(), 'total_weddings' => WeddingCeremony::whereIn('status', ['active', 'completed'])->count(), 'total_envelopes' => WeddingEnvelopeClaim::sum('amount'), 'claimed_amount' => WeddingEnvelopeClaim::where('claimed', true)->sum('amount'), ]; $recentMarriages = Marriage::with(['user:id,username', 'partner:id,username', 'ringItem:id,name,icon']) ->where('status', 'married') ->orderByDesc('married_at') ->limit(10) ->get(); $recentDivorces = Marriage::with(['user:id,username', 'partner:id,username']) ->where('status', 'divorced') ->orderByDesc('divorced_at') ->limit(8) ->get(); return view('admin.marriages.index', compact('stats', 'recentMarriages', 'recentDivorces')); } /** * 婚姻列表(支持按状态/用户名筛选)。 */ public function list(Request $request): View { $query = Marriage::with(['user:id,username', 'partner:id,username', 'ringItem:id,name,icon']) ->orderByDesc('id'); if ($status = $request->get('status')) { $query->where('status', $status); } if ($search = $request->get('search')) { $query->where(function ($q) use ($search) { $q->whereHas('user', fn ($u) => $u->where('username', 'like', "%{$search}%")) ->orWhereHas('partner', fn ($u) => $u->where('username', 'like', "%{$search}%")); }); } $marriages = $query->paginate(20)->withQueryString(); return view('admin.marriages.list', compact('marriages')); } /** * 求婚记录列表(含 pending/expired/rejected)。 */ public function proposals(Request $request): View { $proposals = Marriage::with(['user:id,username', 'partner:id,username', 'ringItem:id,name,icon']) ->orderByDesc('proposed_at') ->paginate(20) ->withQueryString(); return view('admin.marriages.proposals', compact('proposals')); } /** * 婚礼红包记录。 */ public function ceremonies(Request $request): View { $ceremonies = WeddingCeremony::with([ 'marriage.user:id,username', 'marriage.partner:id,username', 'tier:id,name,tier,icon', ]) ->orderByDesc('id') ->paginate(20) ->withQueryString(); return view('admin.marriages.ceremonies', compact('ceremonies')); } /** * 红包领取明细(某场婚礼)。 */ public function claimDetail(WeddingCeremony $ceremony): View { $ceremony->load(['marriage.user:id,username', 'marriage.partner:id,username', 'tier:id,name,icon']); $claims = WeddingEnvelopeClaim::with('user:id,username,headface') ->where('ceremony_id', $ceremony->id) ->orderBy('amount', 'desc') ->paginate(30); return view('admin.marriages.claim-detail', compact('ceremony', 'claims')); } /** * 亲密度日志列表(支持按用户筛选)。 */ public function intimacyLogs(Request $request): View { $query = MarriageIntimacyLog::with(['marriage.user:id,username', 'marriage.partner:id,username']) ->orderByDesc('id'); if ($search = $request->get('search')) { $query->whereHas('marriage', function ($q) use ($search) { $q->whereHas('user', fn ($u) => $u->where('username', 'like', "%{$search}%")) ->orWhereHas('partner', fn ($u) => $u->where('username', 'like', "%{$search}%")); }); } if ($source = $request->get('source')) { $query->where('source', $source); } $logs = $query->paginate(30)->withQueryString(); return view('admin.marriages.intimacy-logs', compact('logs')); } /** * 参数配置页面(读取所有分组配置)。 */ public function configs(): View { $groups = $this->config->allGrouped(); return view('admin.marriages.configs', compact('groups')); } /** * 批量保存参数配置。 */ public function updateConfigs(Request $request): RedirectResponse { $data = $request->validate([ 'configs' => 'required|array', 'configs.*' => 'required|integer', ]); $this->config->batchSet($data['configs']); return redirect()->route('admin.marriages.configs')->with('success', '婚姻参数配置已保存!'); } /** * 婚礼档位配置页面。 */ public function tiers(): View { $tiers = WeddingTier::orderBy('tier')->get(); return view('admin.marriages.tiers', compact('tiers')); } /** * 更新婚礼档位。 */ public function updateTier(Request $request, WeddingTier $tier): RedirectResponse { $data = $request->validate([ 'name' => 'required|string|max:30', 'icon' => 'required|string|max:20', 'amount' => 'required|integer|min:1', 'description' => 'nullable|string|max:100', 'is_active' => 'boolean', ]); $data['is_active'] = $request->boolean('is_active', true); $tier->update($data); return redirect()->route('admin.marriages.tiers')->with('success', "档位【{$tier->name}】已更新!"); } /** * 管理员强制离婚。 */ public function forceDissolve(Request $request, Marriage $marriage): RedirectResponse { $data = $request->validate([ 'admin_note' => 'required|string|max:200', ]); if ($marriage->status !== 'married') { return back()->with('error', '该婚姻不是已婚状态,无法操作。'); } $admin = $request->user(); $result = $this->marriageService->forceDissolve($marriage, $admin, true); // 写入管理员备注 $marriage->update(['admin_note' => $data['admin_note']]); $msg = $result['ok'] ? '强制离婚已完成。' : $result['message']; $type = $result['ok'] ? 'success' : 'error'; return back()->with($type, $msg); } /** * 管理员取消求婚(释放戒指 → 退还状态 active)。 */ public function cancelProposal(Request $request, Marriage $marriage): RedirectResponse { if ($marriage->status !== 'pending') { return back()->with('error', '该求婚不是进行中状态,无法取消。'); } $this->marriageService->expireProposal($marriage); $marriage->update(['admin_note' => '管理员手动取消求婚:'.($request->input('reason', ''))]); return back()->with('success', '求婚已取消,戒指标记遗失。'); } }