Files
construprogress/app/Livewire/LayerUpload.php
T

124 lines
4.1 KiB
PHP

<?php
namespace App\Livewire;
use Livewire\Component;
use Livewire\WithFileUploads;
use App\Models\Project;
use App\Models\Phase;
use App\Models\Layer;
use App\Models\Feature;
use App\Services\SpatialFileConverter;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Storage;
class LayerUpload extends Component
{
use WithFileUploads;
public $projectId;
public $phaseId;
public $uploadFile = null;
public $layerName = '';
public $layerColor = '#3b82f6';
protected $rules = [
'uploadFile' => 'required|file|max:51200',
'layerName' => 'required|string|max:255',
'layerColor' => 'nullable|string|size:7',
];
public function mount($projectId = null, $phaseId = null)
{
$this->projectId = $projectId;
$this->phaseId = $phaseId;
}
public function upload()
{
$user = Auth::user();
if (!$user->can('upload layers') && !$user->hasRole('Admin')) {
session()->flash('error', 'Sin permisos.');
return;
}
$this->validate();
if (!$this->projectId || !$this->phaseId) {
session()->flash('error', 'Faltan datos del proyecto/fase.');
return;
}
$project = Project::findOrFail($this->projectId);
$phase = Phase::findOrFail($this->phaseId);
$extension = strtolower($this->uploadFile->getClientOriginalExtension());
$mime = $this->uploadFile->getMimeType();
$allowedExtensions = ['geojson', 'kmz', 'kml', 'shp', 'dwg', 'zip'];
$allowedMimes = [
'application/vnd.google-earth.kml+xml',
'application/vnd.google-earth.kmz',
'application/zip',
'application/x-zip-compressed',
'application/x-shapefile',
'image/vnd.dwg',
'application/acad',
'application/geo+json',
'text/xml',
'application/xml',
];
if (!in_array($extension, $allowedExtensions) && !in_array($mime, $allowedMimes)) {
session()->flash('error', 'Tipo de archivo no permitido.');
return;
}
$projectDir = "uploads/projects/{$project->id}/layers";
$originalPath = $this->uploadFile->store($projectDir, 'public');
$geojson = SpatialFileConverter::convertToGeoJson($this->uploadFile);
if (!$geojson) {
session()->flash('error', 'Conversión fallida.');
return;
}
$layerColor = $this->layerColor ?: '#3b82f6';
$geojson['style'] = ['color' => $layerColor];
$layer = Layer::create([
'project_id' => $project->id,
'phase_id' => $phase->id,
'name' => $this->layerName,
'color' => $layerColor,
'original_file' => $originalPath,
'uploaded_by' => $user->id,
]);
if (isset($geojson['features'])) {
foreach ($geojson['features'] as $featureData) {
Feature::create([
'layer_id' => $layer->id,
'name' => $featureData['properties']['name'] ?? null,
'geometry' => $featureData['geometry'],
'properties' => $featureData['properties'] ?? [],
'template_id' => $featureData['properties']['template_id'] ?? null,
'progress' => $featureData['properties']['progress'] ?? 0,
'responsible' => $featureData['properties']['responsible'] ?? null,
]);
}
}
$this->reset(['uploadFile', 'layerName']);
session()->flash('message', "Capa '{$layer->name}' importada correctamente con " . count($geojson['features'] ?? []) . ' elementos.');
$this->dispatch('layerUploaded', projectId: $project->id);
}
public function render()
{
$projects = Project::accessibleBy(Auth::user())->get();
$phases = $this->projectId ? Phase::where('project_id', $this->projectId)->orderBy('order')->get() : collect();
return view('livewire.layer-upload', compact('projects', 'phases'));
}
}