108 lines
3.4 KiB
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';
|
|
}
|
|
} |