wip
This commit is contained in:
parent
7bf6a94363
commit
cf12ab27e4
@ -2,21 +2,29 @@
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Services\Pacs;
|
||||
use App\Services\Pacs\OrthancRestClient;
|
||||
|
||||
class PacsController extends Controller
|
||||
{
|
||||
public function index()
|
||||
{
|
||||
$studies = (new Pacs)->getStudies();
|
||||
$studies = (new OrthancRestClient)->getStudies();
|
||||
dd($studies[0]);
|
||||
|
||||
return view('pacs.studies', compact('studies'));
|
||||
}
|
||||
|
||||
public function show($id)
|
||||
{
|
||||
$study = (new Pacs)->getStudy($id);
|
||||
$study = (new OrthancRestClient)->getStudy($id);
|
||||
|
||||
return view('pacs.study', compact('study'));
|
||||
}
|
||||
|
||||
public function import($id)
|
||||
{
|
||||
$studies = (new OrthancRestClient)->getStudies();
|
||||
|
||||
return redirect()->route('pacs.index');
|
||||
}
|
||||
}
|
||||
|
@ -2,6 +2,16 @@
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Models\Enums\ReportStatus;
|
||||
use App\Models\Enums\StudyLevelStatus;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class Study extends Model {}
|
||||
class Study extends Model
|
||||
{
|
||||
protected $casts = [
|
||||
'is_locked' => 'boolean',
|
||||
'is_active' => 'boolean',
|
||||
'study_status' => StudyLevelStatus::class,
|
||||
'report_status' => ReportStatus::class,
|
||||
];
|
||||
}
|
||||
|
@ -1,32 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Services;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use GuzzleHttp\Client;
|
||||
|
||||
final class Pacs
|
||||
{
|
||||
public function getClient(): Client
|
||||
{
|
||||
return new Client([
|
||||
'base_uri' => config('pacs.api.endpoint'),
|
||||
]);
|
||||
}
|
||||
|
||||
public function getStudies(): array
|
||||
{
|
||||
$url = '/studies?'.http_build_query(['expand' => '1']);
|
||||
$response = $this->getClient()->get($url);
|
||||
|
||||
$studies = json_decode($response->getBody()->getContents(), true);
|
||||
$result = [];
|
||||
foreach ($studies as $study) {
|
||||
$study['ReceiveDateTime'] = Carbon::parse($study['LastUpdate'], 'UTC');
|
||||
$study['StudyDateTime'] = Carbon::createFromFormat('Ymd His.u', $study['MainDicomTags']['StudyDate'].' '.$study['MainDicomTags']['StudyTime'], 'UTC');
|
||||
$result[] = $study;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
15
app/Services/Pacs/DicomTags.php
Normal file
15
app/Services/Pacs/DicomTags.php
Normal file
@ -0,0 +1,15 @@
|
||||
<?php
|
||||
|
||||
namespace App\Services\Pacs;
|
||||
|
||||
enum DicomTags: string
|
||||
{
|
||||
case AcquisitionDate = 'AcquisitionDate';
|
||||
case AcquisitionTime = 'AcquisitionTime';
|
||||
case AcquisitionDeviceProcessingDescription = 'AcquisitionDeviceProcessingDescription';
|
||||
case BodyPartExamined = 'BodyPartExamined';
|
||||
case Modality = 'Modality';
|
||||
case SoftwareVersions = 'SoftwareVersions';
|
||||
case StationName = 'StationName';
|
||||
case Private10 = '0029,0010';
|
||||
}
|
26
app/Services/Pacs/DicomUtils.php
Normal file
26
app/Services/Pacs/DicomUtils.php
Normal file
@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
namespace App\Services\Pacs;
|
||||
|
||||
use Carbon\Carbon;
|
||||
|
||||
final class DicomUtils
|
||||
{
|
||||
public static function dateToCarbon(?string $datePart, string $timezone = 'UTC'): ?Carbon
|
||||
{
|
||||
if ($datePart === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return Carbon::createFromFormat('Ymd', $datePart, $timezone);
|
||||
}
|
||||
|
||||
public static function dateTimeToCarbon(?string $datePart, ?string $timePart, string $timezone = 'UTC'): ?Carbon
|
||||
{
|
||||
if ($datePart === null || $timePart === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return Carbon::createFromFormat('YmdHis.u', $datePart.$timePart, $timezone);
|
||||
}
|
||||
}
|
29
app/Services/Pacs/OrthancRestClient.php
Normal file
29
app/Services/Pacs/OrthancRestClient.php
Normal file
@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
namespace App\Services\Pacs;
|
||||
|
||||
use GuzzleHttp\Client;
|
||||
|
||||
final class OrthancRestClient
|
||||
{
|
||||
public function getClient(): Client
|
||||
{
|
||||
return new Client([
|
||||
'base_uri' => config('pacs.api.endpoint'),
|
||||
]);
|
||||
}
|
||||
|
||||
public function getStudies(): array
|
||||
{
|
||||
$query = [
|
||||
'expand' => '1',
|
||||
'requested-tags' => implode(';', array_column(DicomTags::cases(), 'value')),
|
||||
];
|
||||
$url = '/studies?'.http_build_query($query);
|
||||
$response = $this->getClient()->get($url);
|
||||
|
||||
$studies = json_decode($response->getBody()->getContents(), true);
|
||||
|
||||
return $studies;
|
||||
}
|
||||
}
|
48
app/Services/Pacs/StudyImporter.php
Normal file
48
app/Services/Pacs/StudyImporter.php
Normal file
@ -0,0 +1,48 @@
|
||||
<?php
|
||||
|
||||
namespace App\Services\Pacs;
|
||||
|
||||
use App\Models\Enums\StudyLevelStatus;
|
||||
use App\Models\Study;
|
||||
use Carbon\Carbon;
|
||||
|
||||
final class StudyImporter
|
||||
{
|
||||
public function import(array $studies): void
|
||||
{
|
||||
foreach ($studies as $study) {
|
||||
$othanc_id = strtolower($study['ID']);
|
||||
$row = Study::where('othanc_id', $othanc_id)->first();
|
||||
if ($row && $row->study_status < StudyLevelStatus::StudyArrived) {
|
||||
// todo: update study
|
||||
return;
|
||||
}
|
||||
|
||||
$data = [
|
||||
'othanc_id' => $othanc_id,
|
||||
'study_status' => StudyLevelStatus::StudyArrived,
|
||||
'study_datetime' => $study['StudyDateTime'],
|
||||
'receive_datetime' => $study['ReceiveDateTime'],
|
||||
'is_locked' => false,
|
||||
'is_active' => true,
|
||||
|
||||
'patient_id' => $study['PatientMainDicomTags']['PatientID'],
|
||||
'patient_name' => $study['PatientMainDicomTags']['PatientName'],
|
||||
'patient_sex' => $study['PatientMainDicomTags']['PatientSex'],
|
||||
'patient_birthdate' => $study['PatientMainDicomTags']['PatientBirthDate'],
|
||||
|
||||
'institution_name' => $study['MainDicomTags']['InstitutionName'],
|
||||
'accession_number' => $study['MainDicomTags']['AccessionNumber'],
|
||||
'referring_physician_name' => $study['MainDicomTags']['ReferringPhysicianName'],
|
||||
'study_id' => $study['MainDicomTags']['StudyID'],
|
||||
|
||||
'study_date' => DicomUtils::dateTimeToCarbon($study['MainDicomTags']['StudyDate'], $study['MainDicomTags']['StudyTime']),
|
||||
'receive_date' => Carbon::parse($study['LastUpdate'], 'UTC'),
|
||||
'study_modality' => $study['MainDicomTags']['Modality'],
|
||||
|
||||
'series_count' => count($study['Series']),
|
||||
];
|
||||
$row = Study::create($data);
|
||||
}
|
||||
}
|
||||
}
|
14
composer.lock
generated
14
composer.lock
generated
@ -7583,16 +7583,16 @@
|
||||
},
|
||||
{
|
||||
"name": "barryvdh/reflection-docblock",
|
||||
"version": "v2.1.3",
|
||||
"version": "v2.2.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/barryvdh/ReflectionDocBlock.git",
|
||||
"reference": "c6fad15f7c878be21650c51e1f841bca7e49752e"
|
||||
"reference": "db125e8df4329bd45f2da405aab007f502f38531"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/barryvdh/ReflectionDocBlock/zipball/c6fad15f7c878be21650c51e1f841bca7e49752e",
|
||||
"reference": "c6fad15f7c878be21650c51e1f841bca7e49752e",
|
||||
"url": "https://api.github.com/repos/barryvdh/ReflectionDocBlock/zipball/db125e8df4329bd45f2da405aab007f502f38531",
|
||||
"reference": "db125e8df4329bd45f2da405aab007f502f38531",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -7608,7 +7608,7 @@
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "2.0.x-dev"
|
||||
"dev-master": "2.2.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
@ -7629,9 +7629,9 @@
|
||||
}
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/barryvdh/ReflectionDocBlock/tree/v2.1.3"
|
||||
"source": "https://github.com/barryvdh/ReflectionDocBlock/tree/v2.2.0"
|
||||
},
|
||||
"time": "2024-10-23T11:41:03+00:00"
|
||||
"time": "2024-12-28T10:00:03+00:00"
|
||||
},
|
||||
{
|
||||
"name": "brianium/paratest",
|
||||
|
@ -21,12 +21,14 @@ public function up(): void
|
||||
$table->unsignedTinyInteger('study_priority')->default(0);
|
||||
$table->string('patient_id')->nullable();
|
||||
$table->string('patient_name');
|
||||
$table->string('patient_sex');
|
||||
$table->string('patient_sex')->nullable();
|
||||
$table->date('patient_birthdate')->nullable();
|
||||
$table->string('study_instance_uid')->unique();
|
||||
$table->string('institution_name');
|
||||
$table->string('study_id')->nullable();
|
||||
$table->string('institution_name')->nullable();
|
||||
$table->string('accession_number')->nullable();
|
||||
$table->string('study_description')->nullable();
|
||||
$table->string('referring_physician_name')->nullable();
|
||||
$table->string('study_modality', 4)->nullable();
|
||||
$table->dateTime('study_date');
|
||||
$table->dateTime('receive_date');
|
||||
|
Loading…
Reference in New Issue
Block a user