feat(core): harden sessions settlement and credit activity
This commit is contained in:
57
app/Services/Settlement/DrawSettlementStartService.php
Normal file
57
app/Services/Settlement/DrawSettlementStartService.php
Normal file
@@ -0,0 +1,57 @@
|
||||
<?php
|
||||
|
||||
namespace App\Services\Settlement;
|
||||
|
||||
use App\Models\Draw;
|
||||
use App\Lottery\DrawStatus;
|
||||
use App\Models\DrawResultBatch;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use App\Lottery\DrawResultBatchStatus;
|
||||
|
||||
/**
|
||||
* 将期号推进到可结算状态。
|
||||
*
|
||||
* 冷静期内的人工操作只跳过当前期剩余的核错窗口,不修改全局冷静期配置。
|
||||
*/
|
||||
final class DrawSettlementStartService
|
||||
{
|
||||
/**
|
||||
* @return array{draw: Draw, cooldown_skipped: bool}
|
||||
*/
|
||||
public function start(Draw $draw): array
|
||||
{
|
||||
return DB::transaction(function () use ($draw): array {
|
||||
/** @var Draw $locked */
|
||||
$locked = Draw::query()->whereKey($draw->id)->lockForUpdate()->firstOrFail();
|
||||
|
||||
if (! in_array($locked->status, [
|
||||
DrawStatus::Cooldown->value,
|
||||
DrawStatus::Settling->value,
|
||||
], true)) {
|
||||
throw new \RuntimeException('draw_not_ready_for_settlement');
|
||||
}
|
||||
|
||||
$hasPublishedResult = DrawResultBatch::query()
|
||||
->where('draw_id', $locked->id)
|
||||
->where('status', DrawResultBatchStatus::Published->value)
|
||||
->exists();
|
||||
|
||||
if (! $hasPublishedResult) {
|
||||
throw new \RuntimeException('draw_result_not_published');
|
||||
}
|
||||
|
||||
$cooldownSkipped = $locked->status === DrawStatus::Cooldown->value;
|
||||
if ($cooldownSkipped) {
|
||||
$locked->forceFill([
|
||||
'status' => DrawStatus::Settling->value,
|
||||
'cooling_end_time' => now(),
|
||||
])->save();
|
||||
}
|
||||
|
||||
return [
|
||||
'draw' => $locked->fresh(),
|
||||
'cooldown_skipped' => $cooldownSkipped,
|
||||
];
|
||||
});
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user