sistem_rekomendasi/app/Http/Controllers/Api/Admin/RiwayatController.php

190 lines
6.7 KiB
PHP

<?php
namespace App\Http\Controllers\Api\Admin;
use App\Http\Controllers\Controller;
use App\Models\RiwayatRekomendasi;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Schema;
use Exception;
class RiwayatController extends Controller
{
public function index(Request $request)
{
try {
$perPage = (int) $request->input('per_page', 7);
$perPage = in_array($perPage, [5, 7]) ? $perPage : 7;
$search = trim((string) $request->input('search', ''));
$query = RiwayatRekomendasi::with('user:id,name,email')
->orderBy('created_at', 'desc');
if ($search !== '') {
$query->where(function ($q) use ($search) {
$q->where('hasil_rekomendasi_jurusan', 'like', "%{$search}%")
->orWhereHas('user', function ($user) use ($search) {
$user->where('name', 'like', "%{$search}%")
->orWhere('email', 'like', "%{$search}%");
});
});
}
$riwayat = $query->paginate($perPage);
$riwayat->getCollection()->transform(function ($item) {
return [
'id' => $item->id,
'tanggal' => $item->created_at ? $item->created_at->format('d M Y') : '-',
'jam' => $item->created_at ? $item->created_at->format('H:i') : '-',
'nama_siswa' => $item->user ? $item->user->name : 'Siswa Tidak Diketahui',
'email_siswa' => $item->user ? $item->user->email : '-',
'hasil' => $item->hasil_rekomendasi_jurusan ?? 'Belum ada hasil',
'akurasi_prediksi' => $this->getAkurasiPrediksi($item),
'minat_utama' => $this->getMinatUtama($item),
'rata_nilai' => $this->getRataNilai($item),
];
});
return response()->json([
'success' => true,
'data' => $riwayat->items(),
'current_page' => $riwayat->currentPage(),
'last_page' => $riwayat->lastPage(),
'per_page' => $riwayat->perPage(),
'total' => $riwayat->total(),
'from' => $riwayat->firstItem(),
'to' => $riwayat->lastItem(),
], 200);
} catch (Exception $e) {
return response()->json([
'success' => false,
'message' => 'Error: ' . $e->getMessage()
], 500);
}
}
public function show($id)
{
try {
$detail = RiwayatRekomendasi::with('user:id,name,email')->findOrFail($id);
return response()->json([
'success' => true,
'data' => [
'id' => $detail->id,
'tanggal' => $detail->created_at ? $detail->created_at->format('d M Y H:i:s') : '-',
'nama_siswa' => $detail->user ? $detail->user->name : 'Siswa Tidak Diketahui',
'email_siswa' => $detail->user ? $detail->user->email : '-',
'hasil_rekomendasi' => $detail->hasil_rekomendasi_jurusan ?? 'Belum ada hasil',
'akurasi_prediksi' => $this->getAkurasiPrediksi($detail),
'minat_utama' => $this->getMinatUtama($detail),
'rata_nilai' => $this->getRataNilai($detail),
'kondisi_ekonomi' => $this->getLabelEkonomi($detail->gaji_ortu),
'gaji_ortu' => $detail->gaji_ortu,
'nilai_ringkas' => [
'Matematika' => $detail->matematika,
'B. Indonesia' => $detail->bahasa_indonesia,
'B. Inggris' => $detail->bahasa_inggris,
'Fisika' => $detail->fisika,
'Kimia' => $detail->kimia,
'Biologi' => $detail->biologi,
'Ekonomi' => $detail->ekonomi_mapel,
'Informatika' => $detail->informatika,
],
'riasec' => [
'Realistic' => $detail->riasec_r,
'Investigative' => $detail->riasec_i,
'Artistic' => $detail->riasec_a,
'Social' => $detail->riasec_s,
'Enterprising' => $detail->riasec_e,
'Conventional' => $detail->riasec_c,
],
]
], 200);
} catch (Exception $e) {
return response()->json([
'success' => false,
'message' => 'Data detail tidak ditemukan: ' . $e->getMessage()
], 404);
}
}
private function getAkurasiPrediksi($riwayat): ?float
{
$tableName = (new RiwayatRekomendasi())->getTable();
if (!Schema::hasColumn($tableName, 'akurasi_prediksi')) {
return null;
}
if ($riwayat->akurasi_prediksi === null) {
return null;
}
return round((float) $riwayat->akurasi_prediksi, 2);
}
private function getRataNilai($riwayat): float
{
$nilai = [
$riwayat->agama,
$riwayat->pkn,
$riwayat->bahasa_indonesia,
$riwayat->bahasa_inggris,
$riwayat->matematika,
$riwayat->fisika,
$riwayat->kimia,
$riwayat->biologi,
$riwayat->sejarah,
$riwayat->geografi,
$riwayat->ekonomi_mapel,
$riwayat->sosiologi,
$riwayat->seni_budaya,
$riwayat->pjok,
$riwayat->informatika,
];
$nilai = array_filter($nilai, fn ($item) => $item !== null);
if (count($nilai) === 0) {
return 0;
}
return round(array_sum($nilai) / count($nilai), 2);
}
private function getMinatUtama($riwayat): string
{
$scores = [
'Teknis & Lapangan' => (float) $riwayat->riasec_r,
'Sains, Riset & Analitis' => (float) $riwayat->riasec_i,
'Kreatif & Desain' => (float) $riwayat->riasec_a,
'Sosial & Pelayanan' => (float) $riwayat->riasec_s,
'Bisnis & Kepemimpinan' => (float) $riwayat->riasec_e,
'Administratif & Terstruktur' => (float) $riwayat->riasec_c,
];
arsort($scores);
return array_key_first($scores) ?? 'Belum teridentifikasi';
}
private function getLabelEkonomi($gaji): string
{
$gaji = (float) $gaji;
if ($gaji < 2000000) {
return 'Kurang Mampu';
}
if ($gaji <= 5000000) {
return 'Menengah';
}
return 'Mampu';
}
}