变更:修复求婚同意消息未收到问题,重构求婚流程支持直接选婚礼档位

This commit is contained in:
2026-03-01 17:53:43 +08:00
parent b7ded61523
commit 52c252f525
5 changed files with 162 additions and 36 deletions

View File

@@ -37,10 +37,10 @@ class MarriageService
*
* @param User $proposer 求婚方
* @param User $target 被求婚方
* @param int $ringPurchaseId 使用的戒指购买记录 ID
* @param int $weddingTierId 可选的婚礼档位 ID
* @return array{ok: bool, message: string, marriage_id: int|null}
*/
public function propose(User $proposer, User $target, int $ringPurchaseId): array
public function propose(User $proposer, User $target, int $ringPurchaseId, ?int $weddingTierId = null): array
{
// 不能向自己求婚
if ($proposer->id === $target->id) {
@@ -85,7 +85,17 @@ class MarriageService
$expireHours = $this->config->get('proposal_expire_hours', 48);
return DB::transaction(function () use ($proposer, $target, $ring, $expireHours) {
return DB::transaction(function () use ($proposer, $target, $ring, $expireHours, $weddingTierId) {
// 在求婚阶段同时进行婚礼设置(由求婚方一人出全资预扣,属于 "男方付 / scheduled冻结" 模式)
if ($weddingTierId) {
$tier = \App\Models\WeddingTier::find($weddingTierId);
if ($tier && $tier->is_active) {
if (($proposer->jjb ?? 0) < $tier->amount) {
return ['ok' => false, 'message' => "金币不足,该婚礼档位需要 {$tier->amount} 金币。", 'marriage_id' => null];
}
}
}
// 戒指状态改为占用中
$ring->update(['status' => 'used_pending']);
@@ -103,6 +113,15 @@ class MarriageService
'hyname1' => $target->username,
]);
if ($weddingTierId) {
$weddingService = app(WeddingService::class);
// 预扣冻结payerType=groom, ceremonyType=scheduled
$setupRes = $weddingService->setup($marriage, $weddingTierId, 'groom', 'scheduled');
if (!$setupRes['ok']) {
throw new \Exception($setupRes['message']);
}
}
return ['ok' => true, 'message' => '求婚成功,等待对方回应。', 'marriage_id' => $marriage->id];
});
}
@@ -161,6 +180,15 @@ class MarriageService
// 初始亲密度
$this->intimacy->add($marriage, $initIntimacy, IntimacySource::WEDDING_BONUS, "结婚戒指初始亲密度({$ringName}", true);
}
// 如果有预先设置的婚礼(随求婚一起设定的),则将冻结金币转为正式扣除,并触发红包
$ceremony = \App\Models\WeddingCeremony::where('marriage_id', $marriage->id)->where('status', 'pending')->first();
if ($ceremony) {
$weddingService = app(WeddingService::class);
$weddingService->confirmCeremony($ceremony); // 解冻扣除,转为 immediate
$weddingService->trigger($ceremony);
broadcast(new \App\Events\WeddingCelebration($ceremony, $marriage));
}
});
return ['ok' => true, 'message' => '恭喜!你们已正式结婚!'];
@@ -184,9 +212,16 @@ class MarriageService
return ['ok' => false, 'message' => '无权操作此求婚。'];
}
DB::transaction(function () use ($marriage) {
return DB::transaction(function () use ($marriage) {
$marriage->update(['status' => 'rejected']);
// 戒指消失lost = 不退还)
// 检查是否有由于求婚冻结的婚礼金币,若有则退还
$ceremony = \App\Models\WeddingCeremony::where('marriage_id', $marriage->id)->where('status', 'pending')->first();
if ($ceremony) {
app(WeddingService::class)->cancelAndRefund($ceremony);
}
// 戒指拒绝后遗失
UserPurchase::where('id', $marriage->ring_purchase_id)->update(['status' => 'lost']);
// 记录戒指消失流水amount=0仅存档
if ($proposer = $marriage->user) {
@@ -343,6 +378,12 @@ class MarriageService
if ($proposer = $marriage->user) {
$this->currency->change($proposer, 'gold', 0, CurrencySource::RING_LOST, "求婚超时,戒指消失({$marriage->ringItem?->name}");
}
// 退还当时冻结的婚礼金币
$ceremony = \App\Models\WeddingCeremony::where('marriage_id', $marriage->id)->where('status', 'pending')->first();
if ($ceremony) {
app(WeddingService::class)->cancelAndRefund($ceremony);
}
});
}