MIF_E31222508/app/Http/Controllers/DiagnosaController.php

206 lines
6.8 KiB
PHP

<?php
namespace App\Http\Controllers;
use Log;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use App\Models\{Gejala, Diagnosa, Aturan, Penyakit, RiwayatDiagnosa, RiwayatDiagnosaDetail};
class DiagnosaController extends Controller
{
private const SKALA_CF = [
1 => 0.25,
2 => 0.50,
3 => 0.75,
4 => 1.00,
];
public function index()
{
$gejala = Gejala::orderBy('kode')->get();
return view('auth.diagnosa', compact('gejala'));
}
public function store(Request $request)
{
// Ambil dan filter input gejala yang tidak kosong
$inputGejala = collect($request->gejala)->filter(fn($val) => $val !== null && $val !== '');
// Validasi minimal 3 gejala dipilih
if ($inputGejala->count() < 3) {
return redirect()->back()->with('error', 'Pilih minimal 3 gejala untuk melakukan diagnosa.');
}
DB::beginTransaction();
try {
// Simpan data utama diagnosa
$diagnosa = Diagnosa::create([
'user_id' => auth()->id(),
'tanggal' => now(),
]);
foreach ($inputGejala as $gejala_id => $tingkat) {
// Pastikan nilai tingkat valid
if (!array_key_exists($tingkat, self::SKALA_CF)) {
throw new \InvalidArgumentException("Skala tingkat tidak valid: $tingkat");
}
// Ambil gejala berdasarkan ID
$gejala = \App\Models\Gejala::find($gejala_id);
if (!$gejala) {
throw new \Exception("Gejala dengan ID '$gejala_id' tidak ditemukan.");
}
// Simpan detail diagnosa
DB::table('diagnosa_detail')->insert([
'diagnosa_id' => $diagnosa->id,
'gejala_kode' => $gejala->kode, // ✅ BENAR
'cf_user' => self::SKALA_CF[$tingkat],
'created_at' => now(),
'updated_at' => now()
]);
}
DB::commit();
return redirect()->route('hasil.diagnosa', ['id' => $diagnosa->id]);
} catch (\InvalidArgumentException $e) {
DB::rollback();
\Log::warning('Skala tidak valid: ' . $e->getMessage());
return back()->with('error', 'Tingkat keyakinan tidak valid: ' . $e->getMessage());
} catch (\Exception $e) {
DB::rollback();
\Log::error('Gagal menyimpan diagnosa: ' . $e->getMessage());
return back()->with('error', 'Gagal menyimpan diagnosa: ' . $e->getMessage());
}
}
public function hasil(Request $request)
{
try {
$diagnosa = Diagnosa::with('detail.gejala')->find($request->id);
if (!$diagnosa) {
return back()->with('error', 'Data diagnosa tidak ditemukan.');
}
$aturan = Aturan::with('penyakit')->get();
$hasil = [];
foreach ($diagnosa->detail as $detail) {
if (!$detail->gejala) continue;
$cf_user = $detail->cf_user;
$kode_gejala = $detail->gejala->kode;
$matching_rules = $aturan->where('gejala_kode', $kode_gejala);
foreach ($matching_rules as $rule) {
$cf_pakar = $this->konversiCFPakar($rule->cf_pakar);
$cf = $cf_user * $cf_pakar;
$hasil[$rule->penyakit_kode][] = $cf;
}
}
// Gabungkan semua CF
$hasil_cf = [];
foreach ($hasil as $kode => $cf_array) {
$hasil_cf[$kode] = $this->gabungCF($cf_array);
}
arsort($hasil_cf); // urutkan CF dari besar ke kecil
// Ambil 2 teratas meskipun CF < 0.7
$penyakit_terduga = [];
foreach (array_slice($hasil_cf, 0, 2, true) as $kode => $cf_total) {
$penyakit = Penyakit::with('solusi')->where('kode', $kode)->first();
if ($penyakit) {
$penyakit_terduga[] = [
'penyakit' => $penyakit,
'cf_total' => round($cf_total * 100, 2),
'detail' => $diagnosa->detail
];
}
}
// Simpan hanya penyakit dengan CF ≥ 70 ke riwayat
if (count($penyakit_terduga)) {
DB::beginTransaction();
$cf_tertinggi = $penyakit_terduga[0]['cf_total'];
$riwayat = RiwayatDiagnosa::create([
'user_id' => auth()->id(),
'cf_tertinggi' => $cf_tertinggi,
]);
foreach ($diagnosa->detail as $detail) {
$gejalaModel = $detail->gejala;
if (!$gejalaModel) continue;
$gejala_id = $gejalaModel->id;
foreach ($penyakit_terduga as $item) {
// Simpan hanya yang >= 70
if ($item['cf_total'] >= 70) {
\App\Models\RiwayatDiagnosaDetail::create([
'riwayat_id' => $riwayat->id,
'gejala_kode' => $gejala_id,
'penyakit_kode' => $item['penyakit']->id,
'cf_user' => $detail->cf_user,
'cf_tertinggi' => $item['cf_total'],
]);
}
}
}
DB::commit();
}
return view('auth.hasil', [
'penyakit_terduga' => $penyakit_terduga
]);
} catch (\Exception $e) {
DB::rollback();
\Log::error('Gagal menyimpan riwayat: ' . $e->getMessage());
return back()->with('error', 'Terjadi kesalahan saat menyimpan data diagnosa: ' . $e->getMessage());
}
}
public function riwayat()
{
$riwayat = RiwayatDiagnosa::with('penyakit')
->where('user_id', auth()->id())
->orderBy('created_at', 'desc')
->paginate(10);
return view('auth.riwayat', compact('riwayat'));
}
private function konversiCFPakar($cf_pakar)
{
if ($cf_pakar <= 1) return $cf_pakar;
if (array_key_exists($cf_pakar, self::SKALA_CF)) return self::SKALA_CF[$cf_pakar];
return 0.5;
}
private function gabungCF($cf_array)
{
if (empty($cf_array)) return 0;
if (count($cf_array) === 1) return $cf_array[0];
$cf_total = $cf_array[0];
for ($i = 1; $i < count($cf_array); $i++) {
$cf_total = $cf_total + ($cf_array[$i] * (1 - $cf_total));
}
return $cf_total;
}
}