MIF_E31232094/app/Http/Controllers/GuestDiagnosisController.php

108 lines
3.4 KiB
PHP

<?php
namespace App\Http\Controllers;
use App\Models\Disease;
use App\Models\Symptom;
use Illuminate\Http\Request;
class GuestDiagnosisController extends Controller
{
/**
* Tampilkan data gejala untuk modal di landing page (JSON)
*/
public function symptoms()
{
$symptoms = Symptom::orderBy('code')->get(['code', 'name']);
return response()->json($symptoms);
}
/**
* Proses diagnosis guest — hitung CF, kembalikan hasil ringkas (JSON)
* Tidak disimpan ke DB, tidak butuh auth
*/
public function process(Request $request)
{
$validated = $request->validate([
'symptoms' => 'required|array|min:4',
'symptoms.*' => 'numeric|min:0|max:0.8',
]);
$gejalaInput = [];
foreach ($validated['symptoms'] as $kode => $cfUser) {
if ($cfUser !== '' && $cfUser !== null) {
$gejalaInput[$kode] = min((float) $cfUser, 0.8);
}
}
if (count($gejalaInput) < 4) {
return response()->json(['error' => 'Pilih minimal 4 gejala.'], 422);
}
$hasil = $this->hitungCF($gejalaInput);
$utama = $hasil[0] ?? null;
// Kembalikan hasil RINGKAS saja (tanpa penanganan lengkap)
return response()->json([
'disease_name' => $utama ? $utama['nama'] : 'Tidak Terdeteksi',
'confidence' => $utama ? $utama['persentase'] : 0,
'level' => $utama ? $this->level($utama['persentase']) : 'Tidak Terdeteksi',
'top_results' => array_slice(array_map(fn($h) => [
'nama' => $h['nama'],
'persentase' => $h['persentase'],
'level' => $this->level($h['persentase']),
], $hasil), 0, 3),
]);
}
/* ── Helpers ──────────────────────────────────────────────────────── */
private function hitungCF(array $gejalaInput): array
{
$hasil = [];
$diseases = Disease::with('symptoms')->get();
foreach ($diseases as $disease) {
$cfCombine = 0;
$first = true;
$cocok = false;
foreach ($disease->symptoms as $symptom) {
$kode = $symptom->code;
$cfPakar = (float) $symptom->pivot->cf_value;
if (isset($gejalaInput[$kode])) {
$cocok = true;
$cf = $gejalaInput[$kode] * $cfPakar;
if ($first) {
$cfCombine = $cf;
$first = false;
} else {
$cfCombine = $cfCombine + ($cf * (1 - $cfCombine));
}
}
}
if ($cocok) {
$hasil[] = [
'nama' => $disease->name,
'persentase' => round($cfCombine * 100, 2),
];
}
}
usort($hasil, fn($a, $b) => $b['persentase'] <=> $a['persentase']);
return $hasil;
}
private function level(float $persen): string
{
if ($persen <= 20) return 'Sangat Rendah';
if ($persen <= 40) return 'Rendah';
if ($persen <= 60) return 'Sedang';
if ($persen <= 80) return 'Tinggi';
return 'Sangat Tinggi';
}
}