Initial commit
This commit is contained in:
167
app/Models/DocumentVersion.php
Normal file
167
app/Models/DocumentVersion.php
Normal file
@@ -0,0 +1,167 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
|
||||
class DocumentVersion extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
protected $fillable = [
|
||||
'document_id',
|
||||
'version_number',
|
||||
'version_notes',
|
||||
'is_current',
|
||||
'file_path',
|
||||
'original_filename',
|
||||
'mime_type',
|
||||
'file_size',
|
||||
'file_hash',
|
||||
'uploaded_by_user_id',
|
||||
'uploaded_at',
|
||||
];
|
||||
|
||||
protected $casts = [
|
||||
'is_current' => 'boolean',
|
||||
'uploaded_at' => 'datetime',
|
||||
];
|
||||
|
||||
// Versions are immutable - disable updating
|
||||
protected static function booted()
|
||||
{
|
||||
static::updating(function ($version) {
|
||||
// Only allow updating is_current flag
|
||||
$dirty = $version->getDirty();
|
||||
if (count($dirty) > 1 || !isset($dirty['is_current'])) {
|
||||
throw new \Exception('Document versions are immutable and cannot be modified');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// ==================== Relationships ====================
|
||||
|
||||
/**
|
||||
* Get the document this version belongs to
|
||||
*/
|
||||
public function document()
|
||||
{
|
||||
return $this->belongsTo(Document::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the user who uploaded this version
|
||||
*/
|
||||
public function uploadedBy()
|
||||
{
|
||||
return $this->belongsTo(User::class, 'uploaded_by_user_id');
|
||||
}
|
||||
|
||||
// ==================== File Methods ====================
|
||||
|
||||
/**
|
||||
* Get the full file path
|
||||
*/
|
||||
public function getFullPath(): string
|
||||
{
|
||||
return storage_path('app/' . $this->file_path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if file exists
|
||||
*/
|
||||
public function fileExists(): bool
|
||||
{
|
||||
return Storage::exists($this->file_path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get file download URL
|
||||
*/
|
||||
public function getDownloadUrl(): string
|
||||
{
|
||||
return route('admin.documents.download-version', [
|
||||
'document' => $this->document_id,
|
||||
'version' => $this->id,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify file integrity
|
||||
*/
|
||||
public function verifyIntegrity(): bool
|
||||
{
|
||||
if (!$this->fileExists()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$currentHash = hash_file('sha256', $this->getFullPath());
|
||||
return $currentHash === $this->file_hash;
|
||||
}
|
||||
|
||||
// ==================== Helper Methods ====================
|
||||
|
||||
/**
|
||||
* Get human-readable file size
|
||||
*/
|
||||
public function getFileSizeHuman(): string
|
||||
{
|
||||
$bytes = $this->file_size;
|
||||
$units = ['B', 'KB', 'MB', 'GB'];
|
||||
|
||||
for ($i = 0; $bytes > 1024; $i++) {
|
||||
$bytes /= 1024;
|
||||
}
|
||||
|
||||
return round($bytes, 2) . ' ' . $units[$i];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get file extension
|
||||
*/
|
||||
public function getFileExtension(): string
|
||||
{
|
||||
return pathinfo($this->original_filename, PATHINFO_EXTENSION);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get file icon based on mime type
|
||||
*/
|
||||
public function getFileIcon(): string
|
||||
{
|
||||
return match(true) {
|
||||
str_contains($this->mime_type, 'pdf') => '📄',
|
||||
str_contains($this->mime_type, 'word') || str_contains($this->mime_type, 'document') => '📝',
|
||||
str_contains($this->mime_type, 'sheet') || str_contains($this->mime_type, 'excel') => '📊',
|
||||
str_contains($this->mime_type, 'image') => '🖼️',
|
||||
str_contains($this->mime_type, 'zip') || str_contains($this->mime_type, 'compressed') => '🗜️',
|
||||
default => '📎',
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if version is current
|
||||
*/
|
||||
public function isCurrent(): bool
|
||||
{
|
||||
return $this->is_current;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get version badge class for UI
|
||||
*/
|
||||
public function getBadgeClass(): string
|
||||
{
|
||||
return $this->is_current ? 'bg-green-100 text-green-800' : 'bg-gray-100 text-gray-800';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get version badge text
|
||||
*/
|
||||
public function getBadgeText(): string
|
||||
{
|
||||
return $this->is_current ? '當前版本' : '歷史版本';
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user