TKK_E32220316/app/Http/Controllers/TimbanganController.php

201 lines
6.7 KiB
PHP

<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Models\Balita;
use App\Models\RiwayatPemeriksaan;
use App\Services\FirebaseService;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Http;
class TimbanganController extends Controller
{
protected $firebase;
public function __construct(FirebaseService $firebase)
{
$this->firebase = $firebase;
}
public function index()
{
$firebaseData = $this->firebase->getTimbanganData();
$tinggi = $firebaseData['tinggi'] ?? null;
$berat = $firebaseData['berat'] ?? null;
$balitas = Balita::all();
$riwayatPemeriksaan = RiwayatPemeriksaan::latest()->get();
$oldInput = session('oldInput');
return view('timbangan', compact('tinggi', 'berat', 'balitas', 'riwayatPemeriksaan', 'oldInput'));
}
public function getRealtimeData()
{
$firebaseData = $this->firebase->getTimbanganData();
return response()->json([
'tinggi' => $firebaseData['tinggi'] ?? null,
'berat' => $firebaseData['berat'] ?? null,
]);
}
public function store(Request $request)
{
try {
// Validasi input berat dan tinggi
$request->merge([
'berat' => is_numeric($request->berat) ? $request->berat : null,
'tinggi' => is_numeric($request->tinggi) ? $request->tinggi : null,
]);
$validated = $request->validate([
'nik' => 'required|string',
'nama' => 'required|string',
'umur' => 'required|integer',
'berat' => 'required|numeric|min:0.1',
'tinggi' => 'required|numeric|min:0.1',
'hasil_analisis' => 'nullable|string',
'tanggal_pemeriksaan' => 'nullable|date',
'catatan' => 'nullable|string',
]);
// Jika tanggal tidak diisi, gunakan tanggal sekarang
if (empty($validated['tanggal_pemeriksaan'])) {
$validated['tanggal_pemeriksaan'] = now()->toDateString();
}
RiwayatPemeriksaan::create($validated);
session()->forget('oldInput');
return redirect()->route('timbangan.index')->with('success', 'Berhasil simpan riwayat pemeriksaan!');
} catch (\Exception $e) {
Log::error('Gagal simpan riwayat pemeriksaan: ' . $e->getMessage());
return redirect()->route('timbangan.index')->with('error', 'Gagal menyimpan! ' . $e->getMessage());
}
}
public function analisisAI(Request $request)
{
$validated = $request->validate([
'nama' => 'required|string',
'umur' => 'required|integer',
'berat' => 'required|numeric',
'tinggi' => 'required|numeric',
'catatan' => 'nullable|string',
'nik' => 'nullable|string',
]);
$catatan = $validated['catatan'] ?? 'No notes.';
$prompt = "Give a brief growth analysis for a toddler with the following data:\n".
"- Weight: {$validated['berat']} kg\n".
"- Height: {$validated['tinggi']} cm\n".
"- Age: {$validated['umur']} months\n".
"- Notes: {$catatan}\n\n".
"Respond in this format (no long explanations):\n".
"Analysis result: [Growth status]. Advice: [short 1-2 sentence nutrition advice based on the notes if needed].";
$hasil_en = $this->analisisDenganCohere($prompt);
$hasil_id = $this->translateToIndonesianLong($hasil_en);
try {
$riwayat = RiwayatPemeriksaan::create([
'nik' => $validated['nik'] ?? '-',
'nama' => $validated['nama'],
'umur' => $validated['umur'],
'berat' => $validated['berat'],
'tinggi' => $validated['tinggi'],
'hasil_analisis' => $hasil_id,
'tanggal_pemeriksaan' => now()->toDateString(),
'catatan' => $catatan,
]);
return view('analisisai', [
'nama' => $riwayat->nama,
'umur' => $riwayat->umur,
'berat' => $riwayat->berat,
'tinggi' => $riwayat->tinggi,
'hasil_analisis' => $riwayat->hasil_analisis,
'catatan' => $riwayat->catatan,
'tanggal' => $riwayat->tanggal_pemeriksaan
]);
} catch (\Exception $e) {
Log::error('Gagal menyimpan hasil analisis AI: ' . $e->getMessage());
return redirect()->route('timbangan.index')->with('error', 'Gagal simpan hasil analisis AI!');
}
}
private function translateToIndonesianLong(string $text): string
{
$chunks = str_split($text, 480);
$translated = '';
foreach ($chunks as $chunk) {
try {
$response = Http::timeout(10)->get('https://api.mymemory.translated.net/get', [
'q' => $chunk,
'langpair' => 'en|id'
]);
if ($response->successful() && isset($response['responseData']['translatedText'])) {
$translated .= $response['responseData']['translatedText'] . ' ';
} else {
$translated .= '[Gagal terjemahkan sebagian teks] ';
}
} catch (\Exception $e) {
$translated .= '[Error jaringan] ';
Log::error('Translate error: ' . $e->getMessage());
}
}
return trim($translated);
}
private function analisisDenganCohere(string $prompt): string
{
try {
$apiKey = env('COHERE_API_KEY');
if (!$apiKey) {
Log::error('API Key Cohere belum diset di .env');
return 'API Key AI belum diset. Hubungi admin.';
}
$response = Http::timeout(30)->withHeaders([
'Authorization' => 'Bearer ' . $apiKey,
'Content-Type' => 'application/json',
])->post('https://api.cohere.ai/generate', [
'model' => 'command',
'prompt' => $prompt,
'max_tokens' => 200, // pendek
'temperature' => 0.7,
]);
if ($response->failed()) {
Log::error('Gagal memanggil Cohere API: ' . $response->body());
return 'Gagal memanggil AI: ' . $response->body();
}
$result = $response->json();
return isset($result['text']) ? trim($result['text']) : 'Respons AI tidak valid.';
} catch (\Exception $e) {
Log::error('Exception Cohere API: ' . $e->getMessage());
return 'Kesalahan saat analisis AI: ' . $e->getMessage();
}
}
public function kembali()
{
return redirect()->route('timbangan.index');
}
public function showAnalisis()
{
return view('analisisai');
}
}