201 lines
6.7 KiB
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');
|
|
}
|
|
}
|