json([ 'mutual_charm_penalty' => (int) $this->config->get('divorce_mutual_charm', 100), 'forced_charm_penalty' => (int) $this->config->get('divorce_forced_charm', 300), 'mutual_cooldown_days' => (int) $this->config->get('divorce_mutual_cooldown', 70), 'forced_cooldown_days' => (int) $this->config->get('divorce_forced_cooldown', 90), ]); } /** * 获取当前用户的婚姻状态(名片/用户列表用)。 */ public function status(Request $request): JsonResponse { $user = $request->user(); $marriage = Marriage::currentFor($user->id); if (! $marriage) { return response()->json(['married' => false]); } $marriage->load(['user:id,username,headface', 'partner:id,username,headface', 'ringItem:id,name,slug,icon']); return response()->json([ 'married' => $marriage->status === 'married', 'status' => $marriage->status, 'marriage' => [ 'id' => $marriage->id, 'user' => $marriage->user, 'partner' => $marriage->partner, 'ring' => $marriage->ringItem?->only(['name', 'icon']), 'intimacy' => $marriage->intimacy, 'level' => $marriage->level, 'level_name' => \App\Services\MarriageIntimacyService::levelName($marriage->level), 'level_icon' => \App\Services\MarriageIntimacyService::levelIcon($marriage->level), 'married_at' => $marriage->married_at?->toDateString(), 'days' => $marriage->married_at?->diffInDays(now()), 'proposed_at' => $marriage->proposed_at, 'expires_at' => $marriage->expires_at, 'divorce_type' => $marriage->divorce_type, 'divorcer_id' => $marriage->divorcer_id, ], ]); } /** * 查询目标用户的婚姻信息(用于双击名片展示)。 */ public function targetStatus(Request $request): JsonResponse { $request->validate(['username' => 'required|string']); $target = \App\Models\User::where('username', $request->username)->firstOrFail(); $marriage = Marriage::query() ->where('status', 'married') ->where(function ($q) use ($target) { $q->where('user_id', $target->id)->orWhere('partner_id', $target->id); }) ->with(['user:id,username,headface', 'partner:id,username,headface', 'ringItem:id,name,icon']) ->first(); if (! $marriage) { return response()->json(['married' => false, 'marriage' => ['status' => 'none']]); } $partner = $marriage->user_id === $target->id ? $marriage->partner : $marriage->user; return response()->json([ 'married' => true, 'marriage' => [ 'status' => $marriage->status, 'marriage_id' => $marriage->id, 'partner_name' => $partner?->username, 'is_my_partner' => $partner?->id === $request->user()?->id, 'ring' => $marriage->ringItem?->only(['name', 'icon']), 'level_icon' => \App\Services\MarriageIntimacyService::levelIcon($marriage->level), 'level_name' => \App\Services\MarriageIntimacyService::levelName($marriage->level), 'days' => $marriage->married_at?->diffInDays(now()), 'intimacy' => $marriage->intimacy, ], ]); } /** * 发起求婚。 */ public function propose(Request $request): JsonResponse { $data = $request->validate([ 'target_username' => 'required|string', 'ring_purchase_id' => 'required|integer', 'wedding_tier_id' => 'nullable|integer', ]); $proposer = $request->user(); $target = \App\Models\User::where('username', $data['target_username'])->first(); if (! $target) { return response()->json(['ok' => false, 'message' => '用户不存在。'], 404); } $result = $this->marriage->propose($proposer, $target, $data['ring_purchase_id'], $data['wedding_tier_id'] ?? null); if ($result['ok']) { $marriage = Marriage::find($result['marriage_id']); // 广播给被求婚方(私人频道) broadcast(new MarriageProposed($marriage, $proposer, $target)); } return response()->json($result); } /** * 获取当前用户持有的有效戒指列表(求婚前选择用)。 */ public function myRings(Request $request): JsonResponse { $rings = UserPurchase::query() ->where('user_id', $request->user()->id) ->where('status', 'active') ->whereHas('item', fn ($q) => $q->where('type', 'ring')) ->with('item:id,name,slug,icon,price,intimacy_bonus,charm_bonus') ->get() ->map(fn ($p) => [ 'purchase_id' => $p->id, 'name' => $p->item->name, 'icon' => $p->item->icon, 'slug' => $p->item->slug, 'intimacy_bonus' => (int) ($p->item->intimacy_bonus ?? 0), 'charm_bonus' => (int) ($p->item->charm_bonus ?? 0), ]); return response()->json(['status' => 'success', 'rings' => $rings]); } /** * 接受求婚。 */ public function accept(Request $request, Marriage $marriage): JsonResponse { $result = $this->marriage->accept($marriage, $request->user()); if ($result['ok']) { $marriage->refresh(); // 广播全房间结婚公告 broadcast(new MarriageAccepted($marriage)); } return response()->json($result); } /** * 拒绝求婚。 */ public function reject(Request $request, Marriage $marriage): JsonResponse { $result = $this->marriage->reject($marriage, $request->user()); if ($result['ok']) { broadcast(new MarriageRejected($marriage)); } return response()->json($result); } /** * 申请离婚(协议或强制)。 */ public function divorce(Request $request, Marriage $marriage): JsonResponse { $type = $request->input('type', 'mutual'); // mutual | forced $result = $this->marriage->divorce($marriage, $request->user(), $type); if ($result['ok']) { $marriage->refresh(); if ($marriage->status === 'divorced') { broadcast(new MarriageDivorced($marriage, $type)); } else { // 协议离婚:通知对方 broadcast(new MarriageDivorceRequested($marriage)); } } return response()->json($result); } /** * 确认协议离婚。 */ public function confirmDivorce(Request $request, Marriage $marriage): JsonResponse { $result = $this->marriage->confirmDivorce($marriage, $request->user()); if ($result['ok']) { $marriage->refresh(); broadcast(new MarriageDivorced($marriage, 'mutual')); } return response()->json($result); } /** * 拒绝协议离婚申请(被申请方选择不同意 = 视为强制离婚)。 * 申请人赔偿一半金币给对方,婚姻以 forced 类型解除。 */ public function rejectDivorce(Request $request, Marriage $marriage): JsonResponse { $result = $this->marriage->rejectDivorce($marriage, $request->user()); if ($result['ok']) { $marriage->refresh(); broadcast(new MarriageDivorced($marriage, 'forced')); } return response()->json($result); } }