You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

119 lines
3.3 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Validation\ValidationException;
class Application extends Model
{
protected $fillable = [
'user_id',
'competition_id',
'status',
'player_name',
'school',
'degree',
'contact_email',
'contact_mobile',
'entry_group',
'company_name',
'project_name',
'track',
'location_country',
'location_province',
'location_city',
'oversea_country',
'intro',
'promise_signed_at',
'promise_signature',
'submitted_at',
];
protected $casts = [
'promise_signed_at' => 'datetime',
'submitted_at' => 'datetime',
];
public function user(): BelongsTo
{
return $this->belongsTo(User::class);
}
public function competition(): BelongsTo
{
return $this->belongsTo(Competition::class);
}
public function files(): HasMany
{
return $this->hasMany(ApplicationFile::class);
}
public function reviewRecords(): HasMany
{
return $this->hasMany(ApplicationReviewRecord::class);
}
public function reviewScores(): HasMany
{
return $this->hasMany(ApplicationReviewScore::class);
}
public function isSubmitted(): bool
{
return $this->status === 'submitted';
}
/** 评委已产生评审记录或打分后,选手端不可再修改报名/附件 */
public function isSignupLockedByReview(): bool
{
return $this->reviewRecords()->exists() || $this->reviewScores()->exists();
}
/** 已超过赛事设置的报名截止时间(未设置截止时间则不据此拦截) */
public function isPastSignupCloseForCompetition(): bool
{
$this->loadMissing('competition');
$close = $this->competition?->signup_close_at;
return $close !== null && now()->isAfter($close);
}
/**
* 选手是否仍可编辑报名表:报名截止时间内且评委尚未评审;草稿与已提交均可继续改报直至截止或评审落库。
*/
public function participantMayEditSignup(): bool
{
if ($this->isSignupLockedByReview()) {
return false;
}
return ! $this->isPastSignupCloseForCompetition();
}
/**
* @param 'status'|'file' $field 422 时 errors 字段名(报名表用 status附件接口用 file
*/
public function assertMayEditSignup(string $field = 'status'): void
{
if ($this->isSignupLockedByReview()) {
$msg = $field === 'file'
? '已有评委评审或打分记录,不可再上传或删除附件'
: '已有评委评审或打分记录,报名内容不可再修改';
throw ValidationException::withMessages([$field => [$msg]]);
}
if ($this->isPastSignupCloseForCompetition()) {
$msg = $field === 'file'
? '报名已截止,不可再上传或删除附件'
: '报名已截止,无法再修改或提交报名';
throw ValidationException::withMessages([$field => [$msg]]);
}
}
}