功能:婚姻系统第11步(Horizon Jobs + 定时任务)

5个 Job:
- ExpireMarriageProposals:每5分钟扫描超时求婚(广播通知)
- TriggerScheduledWeddings:每5分钟触发定时婚礼(广播庆典)
- AutoExpireDivorces:每小时处理离婚超时自动解除
- ExpireWeddingEnvelopes:每小时清理过期红包
- ProcessMarriageIntimacy:每日00:05全量亲密度时间奖励

console.php 注册5个 Schedule
This commit is contained in:
2026-03-01 15:16:46 +08:00
parent d2797d5b59
commit 143601c251
6 changed files with 222 additions and 0 deletions

View File

@@ -0,0 +1,46 @@
<?php
/**
* 文件功能扫描协议离婚超时自动升级处理72h无响应则自动解除
*
* 每小时执行一次,超时的协议离婚申请自动执行发起方惩罚并解除婚姻。
*
* @author ChatRoom Laravel
*
* @version 1.0.0
*/
namespace App\Jobs;
use App\Events\MarriageDivorced;
use App\Models\Marriage;
use App\Services\MarriageConfigService;
use App\Services\MarriageService;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Queue\Queueable;
class AutoExpireDivorces implements ShouldQueue
{
use Queueable;
/**
* 执行 Job扫描离婚申请超时并自动解除。
*/
public function handle(MarriageService $service, MarriageConfigService $config): void
{
// 超时小时数从配置读取默认72h
$timeoutHours = $config->get('divorce_request_timeout', 72);
Marriage::query()
->where('status', 'married')
->where('divorce_type', 'mutual')
->whereNotNull('divorce_requested_at')
->where('divorce_requested_at', '<=', now()->subHours($timeoutHours))
->cursor()
->each(function (Marriage $marriage) use ($service) {
$service->autoExpireDivorce($marriage);
$marriage->refresh();
broadcast(new MarriageDivorced($marriage, 'auto'));
});
}
}

View File

@@ -0,0 +1,42 @@
<?php
/**
* 文件功能扫描并处理超时的求婚记录48h无响应后失效
*
* 5 分钟执行一次,将到期的 pending 求婚设为 expired戒指标记遗失。
* 同时广播 MarriageExpired 事件通知求婚方。
*
* @author ChatRoom Laravel
*
* @version 1.0.0
*/
namespace App\Jobs;
use App\Events\MarriageExpired;
use App\Models\Marriage;
use App\Services\MarriageService;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Queue\Queueable;
class ExpireMarriageProposals implements ShouldQueue
{
use Queueable;
/**
* 执行 Job扫描超时求婚并处理。
*/
public function handle(MarriageService $service): void
{
// 查找所有已超时但仍为 pending 的求婚
Marriage::query()
->where('status', 'pending')
->where('expires_at', '<=', now())
->cursor()
->each(function (Marriage $marriage) use ($service) {
$service->expireProposal($marriage);
// 广播通知求婚方(若在线则收到)
broadcast(new MarriageExpired($marriage));
});
}
}

View File

@@ -0,0 +1,36 @@
<?php
/**
* 文件功能清理过期婚礼红包24h 后自动消失)
*
* 每小时执行一次,将超过 expires_at 且有未领取 claims 的婚礼标记为 expired。
* 未领取的金额不退还(设计决定:促进即时领取)。
*
* @author ChatRoom Laravel
*
* @version 1.0.0
*/
namespace App\Jobs;
use App\Models\WeddingCeremony;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Queue\Queueable;
class ExpireWeddingEnvelopes implements ShouldQueue
{
use Queueable;
/**
* 执行 Job将过期的 active 婚礼标记为 completed已过领取期
*/
public function handle(): void
{
// 将已过期的婚礼状态改为 completed
WeddingCeremony::query()
->where('status', 'active')
->whereNotNull('expires_at')
->where('expires_at', '<', now())
->update(['status' => 'completed']);
}
}

View File

@@ -0,0 +1,31 @@
<?php
/**
* 文件功能:每日批量处理婚姻亲密度增加(每日时间奖励)
*
* 每天 00:05 执行一次,给所有 married 状态的婚姻对各加 intimacy_daily_time 积分。
* 同时同步 marriages.online_minutes Redis 计数器(如有)。
*
* @author ChatRoom Laravel
*
* @version 1.0.0
*/
namespace App\Jobs;
use App\Services\MarriageIntimacyService;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Queue\Queueable;
class ProcessMarriageIntimacy implements ShouldQueue
{
use Queueable;
/**
* 执行 Job批量添加每日时间亲密度。
*/
public function handle(MarriageIntimacyService $intimacy): void
{
$intimacy->dailyBatch();
}
}

View File

@@ -0,0 +1,50 @@
<?php
/**
* 文件功能:触发定时婚礼(到时间后自动执行红包分发)
*
* 5 分钟执行一次,扫描 ceremony_at <= now() status=pending 的婚礼,
* 调用 WeddingService::trigger() 分发红包并广播庆典事件。
*
* @author ChatRoom Laravel
*
* @version 1.0.0
*/
namespace App\Jobs;
use App\Events\WeddingCelebration;
use App\Models\WeddingCeremony;
use App\Services\WeddingService;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Queue\Queueable;
class TriggerScheduledWeddings implements ShouldQueue
{
use Queueable;
/**
* 执行 Job检查并触发到时的定时婚礼。
*/
public function handle(WeddingService $wedding): void
{
WeddingCeremony::query()
->where('status', 'pending')
->where('ceremony_type', 'scheduled')
->where('ceremony_at', '<=', now())
->with('marriage')
->cursor()
->each(function (WeddingCeremony $ceremony) use ($wedding) {
if (! $ceremony->marriage) {
return;
}
$result = $wedding->trigger($ceremony);
if ($result['ok']) {
// 广播全房间婚礼庆典
broadcast(new WeddingCelebration($ceremony, $ceremony->marriage));
}
});
}
}

View File

@@ -13,3 +13,20 @@ Schedule::command('messages:purge')->dailyAt('03:00');
// 每 5 分钟为所有在线用户自动存点(经验/金币/等级)
Schedule::command('chatroom:auto-save-exp')->everyFiveMinutes();
// ──────────── 婚姻系统定时任务 ────────────────────────────────────
// 每 5 分钟扫描超时求婚48h后失效 + 戒指消失 + 广播通知)
Schedule::job(new \App\Jobs\ExpireMarriageProposals)->everyFiveMinutes();
// 每 5 分钟:触发到时的定时婚礼(红包分发 + 广播庆典)
Schedule::job(new \App\Jobs\TriggerScheduledWeddings)->everyFiveMinutes();
// 每小时协议离婚超时自动升级为强制72h无响应
Schedule::job(new \App\Jobs\AutoExpireDivorces)->hourly();
// 每小时清理过期婚礼红包expired_at 过后标记 completed
Schedule::job(new \App\Jobs\ExpireWeddingEnvelopes)->hourly();
// 每天 00:05全量处理婚姻亲密度时间奖励每日加分
Schedule::job(new \App\Jobs\ProcessMarriageIntimacy)->dailyAt('00:05');