2026-03-01 15:09:33 +08:00
|
|
|
|
<?php
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 文件功能:前台婚姻控制器
|
|
|
|
|
|
*
|
|
|
|
|
|
* 处理求婚、接受/拒绝、查询婚姻状态、申请离婚等前台操作。
|
|
|
|
|
|
* 所有操作通过 MarriageService 执行,Events 负责广播。
|
|
|
|
|
|
*
|
|
|
|
|
|
* @author ChatRoom Laravel
|
|
|
|
|
|
*
|
|
|
|
|
|
* @version 1.0.0
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
namespace App\Http\Controllers;
|
|
|
|
|
|
|
|
|
|
|
|
use App\Events\MarriageAccepted;
|
|
|
|
|
|
use App\Events\MarriageDivorced;
|
|
|
|
|
|
use App\Events\MarriageDivorceRequested;
|
|
|
|
|
|
use App\Events\MarriageProposed;
|
|
|
|
|
|
use App\Events\MarriageRejected;
|
|
|
|
|
|
use App\Models\Marriage;
|
|
|
|
|
|
use App\Models\UserPurchase;
|
|
|
|
|
|
use App\Services\MarriageService;
|
|
|
|
|
|
use Illuminate\Http\JsonResponse;
|
|
|
|
|
|
use Illuminate\Http\Request;
|
|
|
|
|
|
|
|
|
|
|
|
class MarriageController extends Controller
|
|
|
|
|
|
{
|
|
|
|
|
|
public function __construct(
|
|
|
|
|
|
private readonly MarriageService $marriage,
|
|
|
|
|
|
) {}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 获取当前用户的婚姻状态(名片/用户列表用)。
|
|
|
|
|
|
*/
|
|
|
|
|
|
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) {
|
2026-03-01 15:31:07 +08:00
|
|
|
|
return response()->json(['married' => false, 'marriage' => ['status' => 'none']]);
|
2026-03-01 15:09:33 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2026-03-01 15:31:07 +08:00
|
|
|
|
$partner = $marriage->user_id === $target->id ? $marriage->partner : $marriage->user;
|
|
|
|
|
|
|
2026-03-01 15:09:33 +08:00
|
|
|
|
return response()->json([
|
|
|
|
|
|
'married' => true,
|
2026-03-01 15:31:07 +08:00
|
|
|
|
'marriage' => [
|
|
|
|
|
|
'status' => $marriage->status,
|
|
|
|
|
|
'marriage_id' => $marriage->id,
|
|
|
|
|
|
'partner_name' => $partner?->username,
|
|
|
|
|
|
'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,
|
|
|
|
|
|
],
|
2026-03-01 15:09:33 +08:00
|
|
|
|
]);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 发起求婚。
|
|
|
|
|
|
*/
|
|
|
|
|
|
public function propose(Request $request): JsonResponse
|
|
|
|
|
|
{
|
|
|
|
|
|
$data = $request->validate([
|
|
|
|
|
|
'target_username' => 'required|string',
|
|
|
|
|
|
'ring_purchase_id' => 'required|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']);
|
|
|
|
|
|
|
|
|
|
|
|
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'))
|
2026-03-01 15:31:07 +08:00
|
|
|
|
->with('item:id,name,slug,icon,price,intimacy_bonus,charm_bonus')
|
2026-03-01 15:09:33 +08:00
|
|
|
|
->get()
|
|
|
|
|
|
->map(fn ($p) => [
|
|
|
|
|
|
'purchase_id' => $p->id,
|
|
|
|
|
|
'name' => $p->item->name,
|
|
|
|
|
|
'icon' => $p->item->icon,
|
|
|
|
|
|
'slug' => $p->item->slug,
|
2026-03-01 15:31:07 +08:00
|
|
|
|
'intimacy_bonus' => (int) ($p->item->intimacy_bonus ?? 0),
|
|
|
|
|
|
'charm_bonus' => (int) ($p->item->charm_bonus ?? 0),
|
2026-03-01 15:09:33 +08:00
|
|
|
|
]);
|
|
|
|
|
|
|
2026-03-01 15:31:07 +08:00
|
|
|
|
return response()->json(['status' => 'success', 'rings' => $rings]);
|
2026-03-01 15:09:33 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 接受求婚。
|
|
|
|
|
|
*/
|
|
|
|
|
|
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);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|