163 lines
5.4 KiB
PHP
163 lines
5.4 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers;
|
|
|
|
use App\Models\Diagnosis;
|
|
use App\Models\Disease;
|
|
use App\Models\Notification;
|
|
use App\Models\Symptom;
|
|
use Illuminate\Http\Request;
|
|
|
|
class DiagnosisController extends Controller
|
|
{
|
|
public function create()
|
|
{
|
|
$symptoms = Symptom::orderBy('code')->get();
|
|
return view('diagnosis.create', compact('symptoms'));
|
|
}
|
|
|
|
public function store(Request $request)
|
|
{
|
|
$validated = $request->validate([
|
|
'symptoms' => 'required|array|min:4',
|
|
]);
|
|
|
|
$gejalaInput = [];
|
|
$gejalaLabels = [];
|
|
|
|
$namaGejala = Symptom::pluck('name', 'code');
|
|
|
|
foreach ($validated['symptoms'] as $kode => $cfUser) {
|
|
if (isset($cfUser) && $cfUser !== '') {
|
|
$cfUser = (float) $cfUser;
|
|
$cfUser = min($cfUser, 0.8);
|
|
$gejalaInput[$kode] = $cfUser;
|
|
$gejalaLabels[$kode] = [
|
|
'nama' => $namaGejala[$kode] ?? $kode,
|
|
'cf' => $cfUser,
|
|
];
|
|
}
|
|
}
|
|
|
|
if (count($gejalaInput) < 4) {
|
|
return back()->withErrors(['symptoms' => 'Pilih minimal 4 gejala.']);
|
|
}
|
|
|
|
$hasilDiagnosa = $this->diagnosaLengkap($gejalaInput);
|
|
$utama = $hasilDiagnosa[0] ?? null;
|
|
|
|
$diagnosis = Diagnosis::create([
|
|
'user_id' => auth()->id(),
|
|
'plant_name' => 'Tebu',
|
|
'symptoms' => $gejalaLabels,
|
|
'disease_name' => $utama ? $utama['nama'] : 'Tidak Terdeteksi',
|
|
'treatment' => $utama ? implode('; ', $utama['solusi']) : '-',
|
|
'confidence' => $utama ? $utama['persentase'] : 0,
|
|
]);
|
|
|
|
Notification::create([
|
|
'user_id' => auth()->id(),
|
|
'type' => 'diagnosis',
|
|
'title' => 'Diagnosa Selesai',
|
|
'message' => 'Diagnosa tanaman tebu selesai. Penyakit terdeteksi: ' . ($utama ? $utama['nama'] . ' (' . $utama['persentase'] . '%)' : 'Tidak Terdeteksi') . '.',
|
|
'is_read' => false,
|
|
]);
|
|
|
|
$admins = \App\Models\User::where('role', 'admin')
|
|
->where('id', '!=', auth()->id())
|
|
->get();
|
|
|
|
foreach ($admins as $admin) {
|
|
Notification::create([
|
|
'user_id' => $admin->id,
|
|
'type' => 'diagnosis',
|
|
'title' => 'Diagnosa Baru dari ' . auth()->user()->name,
|
|
'message' => 'User ' . auth()->user()->name . ' baru saja melakukan diagnosa. Penyakit terdeteksi: ' . ($utama ? $utama['nama'] . ' (' . $utama['persentase'] . '%)' : 'Tidak Terdeteksi') . '.',
|
|
'is_read' => false,
|
|
]);
|
|
}
|
|
|
|
return redirect()->route('diagnosis.result', $diagnosis->id);
|
|
}
|
|
|
|
public function result($id)
|
|
{
|
|
$diagnosis = Diagnosis::where('user_id', auth()->id())->findOrFail($id);
|
|
|
|
// DEBUG SEMENTARA — hapus setelah selesai debug
|
|
$gejalaInputDebug = collect($diagnosis->symptoms)
|
|
->mapWithKeys(fn($v, $k) => [$k => $v['cf']])
|
|
->toArray();
|
|
|
|
$debugInfo = $this->diagnosaLengkap($gejalaInputDebug, debug: true);
|
|
|
|
return view('diagnosis.result', compact('diagnosis', 'debugInfo'));
|
|
}
|
|
|
|
private function diagnosaLengkap(array $gejalaInput, bool $debug = false): array
|
|
{
|
|
$hasil = [];
|
|
$diseases = Disease::with(['symptoms', 'treatments'])->get();
|
|
|
|
foreach ($diseases as $disease) {
|
|
$cfCombine = 0;
|
|
$first = true;
|
|
$cocok = false;
|
|
$steps = [];
|
|
|
|
foreach ($disease->symptoms as $symptom) {
|
|
$kodeGejala = $symptom->code;
|
|
$cfPakar = (float) $symptom->pivot->cf_value;
|
|
|
|
if (isset($gejalaInput[$kodeGejala])) {
|
|
$cocok = true;
|
|
$cfUser = $gejalaInput[$kodeGejala];
|
|
$cf = $cfUser * $cfPakar;
|
|
|
|
if ($first) {
|
|
$cfCombine = $cf;
|
|
$first = false;
|
|
} else {
|
|
$cfCombine = $cfCombine + ($cf * (1 - $cfCombine));
|
|
}
|
|
|
|
if ($debug) {
|
|
$steps[] = [
|
|
'gejala' => $kodeGejala,
|
|
'cf_pakar' => $cfPakar,
|
|
'cf_user' => $cfUser,
|
|
'cf_komb' => round($cf, 6),
|
|
'cf_akum' => round($cfCombine, 6),
|
|
];
|
|
}
|
|
}
|
|
}
|
|
|
|
if ($cocok) {
|
|
$treatments = [];
|
|
if ($disease->treatments && $disease->treatments->count()) {
|
|
$treatments = $disease->treatments
|
|
->sortBy('order')
|
|
->pluck('description')
|
|
->toArray();
|
|
}
|
|
|
|
$entry = [
|
|
'nama' => $disease->name,
|
|
'persentase' => round($cfCombine * 100, 2),
|
|
'solusi' => count($treatments) ? $treatments : ['-'],
|
|
];
|
|
|
|
if ($debug) {
|
|
$entry['steps'] = $steps;
|
|
}
|
|
|
|
$hasil[] = $entry;
|
|
}
|
|
}
|
|
|
|
usort($hasil, fn($a, $b) => $b['persentase'] <=> $a['persentase']);
|
|
|
|
return $hasil;
|
|
}
|
|
} |