wip
This commit is contained in:
parent
0c2dcc62cb
commit
105bea6e15
29
app/Http/Controllers/Guest/ViewSharedStudyController.php
Normal file
29
app/Http/Controllers/Guest/ViewSharedStudyController.php
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers\Guest;
|
||||||
|
|
||||||
|
use App\Http\Controllers\HashidControllerBase;
|
||||||
|
use App\Models\SharedStudy;
|
||||||
|
|
||||||
|
class ViewSharedStudyController extends HashidControllerBase
|
||||||
|
{
|
||||||
|
public function show()
|
||||||
|
{
|
||||||
|
$this->decodeKeys();
|
||||||
|
$share = SharedStudy::findOrFail($this->key);
|
||||||
|
abort_if($share->hasExpired(), 404);
|
||||||
|
|
||||||
|
if ($share->isPasswordProtected()) {
|
||||||
|
return view('guest.shared-study.auth', compact('share'));
|
||||||
|
}
|
||||||
|
|
||||||
|
return view('guest.shared-study.show', compact('share'));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function auth(SharedStudyPasswordRequest $request)
|
||||||
|
{
|
||||||
|
$this->decodeKeys();
|
||||||
|
$share = SharedStudy::findOrFail($this->key);
|
||||||
|
abort_if(! $share->attempt($request->password), 403);
|
||||||
|
}
|
||||||
|
}
|
30
app/Http/Controllers/HashidActionControllerBase.php
Normal file
30
app/Http/Controllers/HashidActionControllerBase.php
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
|
use Throwable;
|
||||||
|
|
||||||
|
use function Sentry\captureException;
|
||||||
|
|
||||||
|
abstract class HashidActionControllerBase extends Controller
|
||||||
|
{
|
||||||
|
protected ?int $key = null;
|
||||||
|
|
||||||
|
protected ?string $hashid = null;
|
||||||
|
|
||||||
|
public function __invoke()
|
||||||
|
{
|
||||||
|
$this->hashid = request('hashid');
|
||||||
|
|
||||||
|
try {
|
||||||
|
$this->key = unhash_it($this->hashid);
|
||||||
|
} catch (Throwable $exception) {
|
||||||
|
captureException($exception);
|
||||||
|
abort(404);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->handle();
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract protected function handle();
|
||||||
|
}
|
20
app/Http/Requests/Guest/SharedStudyPasswordRequest.php
Normal file
20
app/Http/Requests/Guest/SharedStudyPasswordRequest.php
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Requests\Guest;
|
||||||
|
|
||||||
|
use Illuminate\Foundation\Http\FormRequest;
|
||||||
|
|
||||||
|
class SharedStudyPasswordRequest extends FormRequest
|
||||||
|
{
|
||||||
|
public function rules(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'password' => 'required|string|min:4',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function authorize(): bool
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
@ -29,4 +29,27 @@ protected function casts(): array
|
|||||||
'access_flags' => StudyAccessFlags::class,
|
'access_flags' => StudyAccessFlags::class,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function isPasswordProtected(): bool
|
||||||
|
{
|
||||||
|
return ! blank($this->access_password);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function attempt(string $password): bool
|
||||||
|
{
|
||||||
|
if (! $this->isPasswordProtected()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return strcmp($this->access_password, $password) === 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function hasExpired(): bool
|
||||||
|
{
|
||||||
|
if (blank($this->expires_at)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->expires_at->isPast();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
if (! function_exists('hash_it')) {
|
if (! function_exists('_h')) {
|
||||||
function hash_it(int $key): string
|
function _h(int $key): string
|
||||||
{
|
{
|
||||||
return Hashids::encode($key);
|
return Hashids::encode($key);
|
||||||
}
|
}
|
||||||
|
0
resources/views/guest/shared-study/auth.blade.php
Normal file
0
resources/views/guest/shared-study/auth.blade.php
Normal file
0
resources/views/guest/shared-study/show.blade.php
Normal file
0
resources/views/guest/shared-study/show.blade.php
Normal file
@ -12,17 +12,50 @@
|
|||||||
<table class="min-w-full divide-y divide-gray-200">
|
<table class="min-w-full divide-y divide-gray-200">
|
||||||
<thead class="bg-gray-50">
|
<thead class="bg-gray-50">
|
||||||
<tr>
|
<tr>
|
||||||
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Accession Number</th>
|
<th scope="col"
|
||||||
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Patient ID</th>
|
class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
|
||||||
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Patient Name</th>
|
Accession Number
|
||||||
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Patient Sex</th>
|
</th>
|
||||||
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Patient Birth Date</th>
|
<th scope="col"
|
||||||
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Modality</th>
|
class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
|
||||||
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Study Date</th>
|
Patient ID
|
||||||
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Receive Date</th>
|
</th>
|
||||||
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Series</th>
|
<th scope="col"
|
||||||
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Institute Name</th>
|
class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
|
||||||
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider"> </th>
|
Patient Name
|
||||||
|
</th>
|
||||||
|
<th scope="col"
|
||||||
|
class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
|
||||||
|
Patient Sex
|
||||||
|
</th>
|
||||||
|
<th scope="col"
|
||||||
|
class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
|
||||||
|
Patient Birth Date
|
||||||
|
</th>
|
||||||
|
<th scope="col"
|
||||||
|
class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
|
||||||
|
Modality
|
||||||
|
</th>
|
||||||
|
<th scope="col"
|
||||||
|
class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Study
|
||||||
|
Date
|
||||||
|
</th>
|
||||||
|
<th scope="col"
|
||||||
|
class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
|
||||||
|
Receive Date
|
||||||
|
</th>
|
||||||
|
<th scope="col"
|
||||||
|
class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
|
||||||
|
Series
|
||||||
|
</th>
|
||||||
|
<th scope="col"
|
||||||
|
class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
|
||||||
|
Institute Name
|
||||||
|
</th>
|
||||||
|
<th scope="col"
|
||||||
|
class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
|
||||||
|
|
||||||
|
</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody class="bg-white divide-y divide-gray-200">
|
<tbody class="bg-white divide-y divide-gray-200">
|
||||||
@ -30,29 +63,38 @@
|
|||||||
<tr>
|
<tr>
|
||||||
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-900">{{ $study->accession_number }}</td>
|
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-900">{{ $study->accession_number }}</td>
|
||||||
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-900">{{ $study->patient_id }}</td>
|
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-900">{{ $study->patient_id }}</td>
|
||||||
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-900"><a href="{{ route('studies.details', hash_it($study->id)) }}">{{ $study->patient_name }}</a></td>
|
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-900"><a
|
||||||
|
href="{{ route('studies.details', _h($study->id)) }}">{{ $study->patient_name }}</a>
|
||||||
|
</td>
|
||||||
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-900">{{ $study->patient_sex }}</td>
|
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-900">{{ $study->patient_sex }}</td>
|
||||||
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-900">{{ $study->patient_birthdate }}</td>
|
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-900">{{ $study->patient_birthdate }}</td>
|
||||||
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-900">{{ $study->study_modality }}</td>
|
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-900">{{ $study->study_modality }}</td>
|
||||||
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-900">{{ $study->study_date }}</td>
|
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-900">{{ $study->study_date }}</td>
|
||||||
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-900">{{ $study->receive_date }}</td>
|
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-900">{{ $study->receive_date }}</td>
|
||||||
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-900">{{ $study->image_count }} / {{ $study->series_count }}</td>
|
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-900">{{ $study->image_count }}
|
||||||
|
/ {{ $study->series_count }}</td>
|
||||||
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-900">{{ $study->institution_name }}</td>
|
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-900">{{ $study->institution_name }}</td>
|
||||||
|
|
||||||
<td>
|
<td>
|
||||||
<a target="_blank" href="{{ \App\Services\Pacs\PacsUrlGen::stoneViewer($study->study_instance_uid) }}" >St</a>
|
<a target="_blank"
|
||||||
|
href="{{ \App\Services\Pacs\PacsUrlGen::stoneViewer($study->study_instance_uid) }}">St</a>
|
||||||
|
|
|
|
||||||
<a target="_blank" href="{{ \App\Services\Pacs\PacsUrlGen::ohifViewer($study->study_instance_uid) }}">OHF</a>
|
<a target="_blank"
|
||||||
|
href="{{ \App\Services\Pacs\PacsUrlGen::ohifViewer($study->study_instance_uid) }}">OHF</a>
|
||||||
@if($study->image_count > 1 && $study->study_modality != 'CR')
|
@if($study->image_count > 1 && $study->study_modality != 'CR')
|
||||||
|
|
|
|
||||||
<a target="_blank" href="{{ \App\Services\Pacs\PacsUrlGen::ohifViewerMpr($study->study_instance_uid) }}">MPR</a>
|
<a target="_blank"
|
||||||
|
href="{{ \App\Services\Pacs\PacsUrlGen::ohifViewerMpr($study->study_instance_uid) }}">MPR</a>
|
||||||
|
|
|
|
||||||
<a target="_blank" class="btn" href="{{ \App\Services\Pacs\PacsUrlGen::ohifSegmentation($study->study_instance_uid) }}">SEG</a>
|
<a target="_blank" class="btn"
|
||||||
|
href="{{ \App\Services\Pacs\PacsUrlGen::ohifSegmentation($study->study_instance_uid) }}">SEG</a>
|
||||||
@endif
|
@endif
|
||||||
|
|
|
|
||||||
<a target="_blank" class="btn" href="{{ \App\Services\Pacs\PacsUrlGen::archive($study->orthanc_uid) }}">ZIP</a>
|
<a target="_blank" class="btn"
|
||||||
|
href="{{ \App\Services\Pacs\PacsUrlGen::archive($study->orthanc_uid) }}">ZIP</a>
|
||||||
|
|
|
|
||||||
<a target="_blank" class="btn" href="{{ route('radiologist.report-write', $study->id) }}">TXT</a>
|
<a target="_blank" class="btn"
|
||||||
|
href="{{ route('radiologist.report-write', $study->id) }}">TXT</a>
|
||||||
|
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
use App\Http\Controllers\Guest\ViewSharedStudyController;
|
||||||
use App\Http\Controllers\Radiologist\ReportWriteController;
|
use App\Http\Controllers\Radiologist\ReportWriteController;
|
||||||
use App\Http\Controllers\Staff\StudiesController;
|
use App\Http\Controllers\Staff\StudiesController;
|
||||||
use App\Http\Controllers\System\SyncOrthancController;
|
use App\Http\Controllers\System\SyncOrthancController;
|
||||||
@ -33,4 +34,9 @@
|
|||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Route::group(['prefix' => 'shares', 'as' => 'shares.'], function () {
|
||||||
|
Route::get('study/{hashid}', [ViewSharedStudyController::class, 'show'])->name('show');
|
||||||
|
Route::post('auth/{hashid}', [ViewSharedStudyController::class, 'auth'])->name('auth');
|
||||||
|
});
|
||||||
|
|
||||||
Route::view('/ck', 'ck');
|
Route::view('/ck', 'ck');
|
||||||
|
Loading…
Reference in New Issue
Block a user