This commit is contained in:
Dr Masroor Ehsan 2025-01-22 11:52:20 +06:00
parent 8c580f55d6
commit 5c03963116
8 changed files with 80 additions and 39 deletions

View File

@ -0,0 +1,9 @@
<?php
namespace App\Domain\Rule;
enum MatchCondition: string
{
case And = 'AND';
case Or = 'OR';
}

View File

@ -0,0 +1,12 @@
<?php
namespace App\Domain\Rule;
enum MatchMode: string
{
case Exact = 'EXACT';
case Contains = 'CONTAINS';
case StartsWith = 'STARTS_WITH';
case EndsWith = 'ENDS_WITH';
case Regex = 'REGEX';
}

View File

@ -1,12 +0,0 @@
<?php
namespace App\Domain\Rule;
enum StringMatchMode: int
{
case Exact = 0;
case Contains = 1;
case StartsWith = 2;
case EndsWith = 3;
case Regex = 4;
}

View File

@ -2,7 +2,7 @@
namespace App\Services\Pacs; namespace App\Services\Pacs;
use App\Domain\Rule\StringMatchMode; use App\Domain\Rule\MatchMode;
use App\Services\StringMatcher; use App\Services\StringMatcher;
use Illuminate\Support\Facades\Cache; use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\DB;
@ -21,8 +21,8 @@ public static function map(?string $input): array
if (empty(self::$patterns)) { if (empty(self::$patterns)) {
self::$patterns = Cache::remember('institute_names', self::$patterns = Cache::remember('institute_names',
now()->addMinutes(15), now()->addMinutes(15),
fn () => DB::table('dicom_mapping_rules') fn () => DB::table('dicom_routing_rules')
->orderByDesc('sort_order') ->orderByDesc('priority')
->get()->toArray() ->get()->toArray()
); );
self::$catchAll = DB::table('institutes')->first('id')->id; self::$catchAll = DB::table('institutes')->first('id')->id;
@ -32,7 +32,7 @@ public static function map(?string $input): array
$input = strtolower($input); $input = strtolower($input);
foreach (self::$patterns as $pattern) { foreach (self::$patterns as $pattern) {
if (StringMatcher::match($input, $pattern->name, StringMatchMode::from($pattern->match_mode))) { if (StringMatcher::match($input, $pattern->name, MatchMode::from($pattern->match_mode))) {
return [$pattern->institute_id, $pattern->facility_id]; return [$pattern->institute_id, $pattern->facility_id];
} }
} }

View File

@ -2,27 +2,27 @@
namespace App\Services; namespace App\Services;
use App\Domain\Rule\StringMatchMode; use App\Domain\Rule\MatchMode;
final class StringMatcher final class StringMatcher
{ {
public static function match(string $input, string $pattern, StringMatchMode $mode): bool public static function match(string $input, string $pattern, MatchMode $mode): bool
{ {
if (blank($input) || blank($pattern)) { if (blank($input) || blank($pattern)) {
return false; return false;
} }
if ($mode !== StringMatchMode::Regex) { if ($mode !== MatchMode::Regex) {
$input = strtolower($input); $input = strtolower($input);
$pattern = strtolower($pattern); $pattern = strtolower($pattern);
} }
return match ($mode) { return match ($mode) {
StringMatchMode::Exact => strcasecmp($input, $pattern) === 0, MatchMode::Exact => strcasecmp($input, $pattern) === 0,
StringMatchMode::Contains => str_contains($input, $pattern) , MatchMode::Contains => str_contains($input, $pattern) ,
StringMatchMode::StartsWith => str_starts_with($input, $pattern), MatchMode::StartsWith => str_starts_with($input, $pattern),
StringMatchMode::EndsWith => str_ends_with($input, $pattern), MatchMode::EndsWith => str_ends_with($input, $pattern),
StringMatchMode::Regex => preg_match($pattern, $input) === 1, MatchMode::Regex => preg_match($pattern, $input) === 1,
default => false, default => false,
}; };
} }

View File

@ -1,6 +1,6 @@
<?php <?php
use App\Domain\Rule\StringMatchMode; use App\Domain\Rule\MatchCondition;
use App\Models\Facility; use App\Models\Facility;
use App\Models\Institute; use App\Models\Institute;
use Illuminate\Database\Migrations\Migration; use Illuminate\Database\Migrations\Migration;
@ -11,22 +11,22 @@
{ {
public function up(): void public function up(): void
{ {
Schema::create('dicom_mapping_rules', static function (Blueprint $table) { Schema::create('dicom_routing_rules', static function (Blueprint $table) {
$table->id(); $table->id();
$table->boolean('is_active')->default(true);
$table->foreignIdFor(Institute::class)->constrained()->cascadeOnDelete(); $table->foreignIdFor(Institute::class)->constrained()->cascadeOnDelete();
$table->foreignIdFor(Facility::class)->nullable()->constrained()->cascadeOnDelete(); $table->foreignIdFor(Facility::class)->nullable()->constrained()->cascadeOnDelete();
$table->string('dicom_tag'); $table->string('description')->nullable();
$table->string('search_pattern'); $table->string('match_condition')->default(MatchCondition::Or->value);
$table->unsignedTinyInteger('match_mode')->default(StringMatchMode::Exact->value); $table->unsignedTinyInteger('priority')->default(0);
$table->unsignedTinyInteger('sort_order')->default(0);
$table->timestamps(); $table->timestamps();
$table->unique(['institute_id', 'dicom_tag']); $table->index(['is_active', 'priority']);
}); });
} }
public function down(): void public function down(): void
{ {
Schema::dropIfExists('dicom_mapping_rules'); Schema::dropIfExists('dicom_routing_rules');
} }
}; };

View File

@ -0,0 +1,30 @@
<?php
use App\Domain\Rule\MatchMode;
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
public function up(): void
{
Schema::create('dicom_rule_conditions', function (Blueprint $table) {
$table->id();
$table->foreignId('dicom_routing_rule_id')->constrained()->cascadeOnDelete();
$table->string('dicom_tag');
$table->string('search_pattern');
$table->boolean('case_sensitive')->default(false);
$table->string('match_mode')->default(MatchMode::Exact->value);
$table->unsignedTinyInteger('priority')->default(0);
$table->timestamps();
$table->index(['dicom_mapping_rules_id', 'priority']);
});
}
public function down(): void
{
Schema::dropIfExists('dicom_rule_conditions');
}
};

View File

@ -2,7 +2,7 @@
namespace Database\Seeders; namespace Database\Seeders;
use App\Domain\Rule\StringMatchMode; use App\Domain\Rule\MatchMode;
use App\Models\DicomServer; use App\Models\DicomServer;
use App\Models\Facility; use App\Models\Facility;
use App\Models\Institute; use App\Models\Institute;
@ -45,15 +45,17 @@ public function run(): void
] ]
); );
DB::table('institute_names')->insert([ DB::table('dicom_mapping_rules')->insert([
'dicom_tag' => 'InstitutionName',
'name' => 'CHEVRON CLINICAL LABORATORY , PANCHLAISH,CTG', 'name' => 'CHEVRON CLINICAL LABORATORY , PANCHLAISH,CTG',
'institute_id' => $chev->id, 'search_pattern' => $chev->id,
'match_mode' => StringMatchMode::Exact->value, 'match_mode' => MatchMode::Exact->value,
]); ]);
DB::table('institute_names')->insert([ DB::table('dicom_mapping_rules')->insert([
'name' => 'CHEVRON CLINICAL', 'dicom_tag' => 'InstitutionName',
'search_pattern' => 'CHEVRON CLINICAL',
'institute_id' => $chev->id, 'institute_id' => $chev->id,
'match_mode' => StringMatchMode::StartsWith->value, 'match_mode' => MatchMode::StartsWith->value,
]); ]);
DicomServer::create( DicomServer::create(