*/ protected $casts = [ 'vars_json' => 'array', 'fee' => 'integer', 'sent_at' => 'datetime', 'delivered_at' => 'datetime', 'last_synced_at' => 'datetime', ]; public function competition(): BelongsTo { return $this->belongsTo(Competition::class); } public function registration(): BelongsTo { return $this->belongsTo(AudienceRegistration::class, 'audience_registration_id'); } public function isFailed(): bool { return in_array($this->status, [self::STATUS_DROPPED, self::STATUS_FAILED], true); } public function isTerminalSuccess(): bool { return $this->status === self::STATUS_DELIVERED; } public function canResend(): bool { return $this->isFailed(); } public function isLoginScene(): bool { return in_array($this->scene, [self::SCENE_AUDIENCE_LOGIN, self::SCENE_PARTICIPANT_LOGIN], true); } public static function sceneLabel(string $scene): string { return match ($scene) { self::SCENE_APPROVED => '审核通过', self::SCENE_PRE_REGISTER => '预报名成功', self::SCENE_AUDIENCE_LOGIN => '观众登录验证码', self::SCENE_PARTICIPANT_LOGIN => '选手登录验证码', default => '短信', }; } }