132 lines
3.6 KiB
PHP
132 lines
3.6 KiB
PHP
<?php
|
|
|
|
namespace App\Models\Business;
|
|
|
|
use App\Abstracts\Model;
|
|
use Illuminate\Database\Eloquent\Relations\HasMany;
|
|
|
|
class SystemizationTodo extends Model
|
|
{
|
|
public const STATUS_INCOMPLETE = '未完成';
|
|
|
|
public const STATUS_COMPLETED = '已完成';
|
|
|
|
public const STATUSES = [
|
|
self::STATUS_INCOMPLETE,
|
|
self::STATUS_COMPLETED,
|
|
];
|
|
|
|
public const LEGACY_INCOMPLETE_STATUSES = ['待办', '进行中', '已延期'];
|
|
|
|
// Keep old constant names for imports and existing callers without rewriting data.
|
|
public const STATUS_PENDING = self::STATUS_INCOMPLETE;
|
|
|
|
public const STATUS_IN_PROGRESS = self::STATUS_INCOMPLETE;
|
|
|
|
public const STATUS_DELAYED = self::STATUS_INCOMPLETE;
|
|
|
|
protected $table = 'business_systemization_todos';
|
|
|
|
protected $fillable = [
|
|
'company_id',
|
|
'category',
|
|
'section',
|
|
'title',
|
|
'owner',
|
|
'assignee',
|
|
'start_date',
|
|
'start_note',
|
|
'due_date',
|
|
'due_note',
|
|
'status',
|
|
'completed_at',
|
|
'progress',
|
|
'notes',
|
|
'sort_order',
|
|
'source_key',
|
|
'imported_at',
|
|
'created_by',
|
|
'updated_by',
|
|
];
|
|
|
|
protected $casts = [
|
|
'company_id' => 'integer',
|
|
'start_date' => 'date',
|
|
'due_date' => 'date',
|
|
'completed_at' => 'date',
|
|
'sort_order' => 'integer',
|
|
'imported_at' => 'datetime',
|
|
];
|
|
|
|
public function attachments(): HasMany
|
|
{
|
|
return $this->hasMany(SystemizationTodoAttachment::class, 'systemization_todo_id')
|
|
->orderBy('id');
|
|
}
|
|
|
|
public function isCompleted(): bool
|
|
{
|
|
return $this->status === self::STATUS_COMPLETED;
|
|
}
|
|
|
|
public function statusLabel(): string
|
|
{
|
|
return $this->isCompleted() ? self::STATUS_COMPLETED : self::STATUS_INCOMPLETE;
|
|
}
|
|
|
|
public static function mergeNotesIntoProgress(?string $progress, ?string $notes): ?string
|
|
{
|
|
$progress = trim(str_replace(["\r\n", "\r"], "\n", (string) $progress));
|
|
$notes = trim(str_replace(["\r\n", "\r"], "\n", (string) $notes));
|
|
if ($notes === '') {
|
|
return $progress !== '' ? $progress : null;
|
|
}
|
|
if ($progress === '' || str_contains($progress, $notes)) {
|
|
return $progress !== '' ? $progress : $notes;
|
|
}
|
|
|
|
return $progress . "\n" . $notes;
|
|
}
|
|
|
|
public function displayProgress(): string
|
|
{
|
|
$progress = trim((string) self::mergeNotesIntoProgress($this->progress, $this->notes));
|
|
if ($progress === '') {
|
|
return '';
|
|
}
|
|
|
|
$normalized = (string) preg_replace('/[\s。.]+$/u', '', $progress);
|
|
|
|
return $this->isCompleted() && $normalized === self::STATUS_COMPLETED
|
|
? ''
|
|
: $progress;
|
|
}
|
|
|
|
public function reminder(): array
|
|
{
|
|
if ($this->isCompleted()) {
|
|
return ['label' => '—', 'tone' => 'muted'];
|
|
}
|
|
if ($this->due_date === null) {
|
|
return ['label' => '时间待定', 'tone' => 'muted'];
|
|
}
|
|
|
|
$today = today()->startOfDay();
|
|
$dueDate = $this->due_date->copy()->startOfDay();
|
|
if ($dueDate->lt($today)) {
|
|
return [
|
|
'label' => '逾期 ' . $dueDate->diffInDays($today) . ' 天',
|
|
'tone' => 'danger',
|
|
];
|
|
}
|
|
if ($dueDate->equalTo($today)) {
|
|
return ['label' => '今天到期', 'tone' => 'warning'];
|
|
}
|
|
|
|
return [
|
|
'label' => '剩余 ' . $today->diffInDays($dueDate) . ' 天',
|
|
'tone' => 'info',
|
|
];
|
|
}
|
|
}
|