206 lines
6.8 KiB
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;
|
|
}
|
|
}
|