- Document 모델 (상태 관리, 다형성 연결, 결재 처리) - DocumentApproval 모델 (결재 단계, 상태 처리) - DocumentData 모델 (EAV 패턴 데이터 저장) - DocumentAttachment 모델 (파일 첨부 연결) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
106 lines
2.8 KiB
PHP
106 lines
2.8 KiB
PHP
<?php
|
|
|
|
namespace App\Models\Documents;
|
|
|
|
use Illuminate\Database\Eloquent\Model;
|
|
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
|
|
|
/**
|
|
* 문서 데이터 모델 (EAV 패턴)
|
|
*
|
|
* @property int $id
|
|
* @property int $document_id
|
|
* @property int|null $section_id 섹션 ID
|
|
* @property int|null $column_id 컬럼 ID
|
|
* @property int $row_index 행 인덱스
|
|
* @property string $field_key 필드 키
|
|
* @property string|null $field_value 필드 값
|
|
* @property \Carbon\Carbon|null $created_at
|
|
* @property \Carbon\Carbon|null $updated_at
|
|
*/
|
|
class DocumentData extends Model
|
|
{
|
|
protected $table = 'document_data';
|
|
|
|
// =========================================================================
|
|
// Fillable & Casts
|
|
// =========================================================================
|
|
|
|
protected $fillable = [
|
|
'document_id',
|
|
'section_id',
|
|
'column_id',
|
|
'row_index',
|
|
'field_key',
|
|
'field_value',
|
|
];
|
|
|
|
protected $casts = [
|
|
'section_id' => 'integer',
|
|
'column_id' => 'integer',
|
|
'row_index' => 'integer',
|
|
];
|
|
|
|
protected $attributes = [
|
|
'row_index' => 0,
|
|
];
|
|
|
|
// =========================================================================
|
|
// Relationships
|
|
// =========================================================================
|
|
|
|
/**
|
|
* 문서
|
|
*/
|
|
public function document(): BelongsTo
|
|
{
|
|
return $this->belongsTo(Document::class);
|
|
}
|
|
|
|
// =========================================================================
|
|
// Scopes
|
|
// =========================================================================
|
|
|
|
/**
|
|
* 특정 섹션의 데이터
|
|
*/
|
|
public function scopeForSection($query, int $sectionId)
|
|
{
|
|
return $query->where('section_id', $sectionId);
|
|
}
|
|
|
|
/**
|
|
* 특정 필드 키의 데이터
|
|
*/
|
|
public function scopeForField($query, string $fieldKey)
|
|
{
|
|
return $query->where('field_key', $fieldKey);
|
|
}
|
|
|
|
/**
|
|
* 특정 행의 데이터
|
|
*/
|
|
public function scopeForRow($query, int $rowIndex)
|
|
{
|
|
return $query->where('row_index', $rowIndex);
|
|
}
|
|
|
|
// =========================================================================
|
|
// Helper Methods
|
|
// =========================================================================
|
|
|
|
/**
|
|
* 값을 특정 타입으로 캐스팅
|
|
*/
|
|
public function getTypedValue(string $type = 'string'): mixed
|
|
{
|
|
return match ($type) {
|
|
'integer', 'int' => (int) $this->field_value,
|
|
'float', 'double' => (float) $this->field_value,
|
|
'boolean', 'bool' => filter_var($this->field_value, FILTER_VALIDATE_BOOLEAN),
|
|
'array', 'json' => json_decode($this->field_value, true),
|
|
default => $this->field_value,
|
|
};
|
|
}
|
|
}
|