From 241d228e9c205054dea2dfcb65845a80396e7373 Mon Sep 17 00:00:00 2001 From: "[Valentino Heman Budiarto]" <[hemanvalentino@gmail.com]> Date: Mon, 22 Jun 2026 08:36:27 +0700 Subject: [PATCH] menambahkan jumlah sks --- backend/controllers/hardwarecontroller.go | 70 +++++++++++++++++------ backend/models/entity.go | 1 + 2 files changed, 53 insertions(+), 18 deletions(-) diff --git a/backend/controllers/hardwarecontroller.go b/backend/controllers/hardwarecontroller.go index 9373ffb..dcdaed1 100644 --- a/backend/controllers/hardwarecontroller.go +++ b/backend/controllers/hardwarecontroller.go @@ -42,7 +42,7 @@ var DeviceStatusCache = map[string]string{ } // ========================================================================= -// FUNGSI 1: VERIFIKASI TOKEN & KODE MATA KULIAH (ON-DEMAND) +// FUNGSI 1: VERIFIKASI TOKEN & KODE MATA KULIAH (DOUBLE-LAYER PROTECTION) // ========================================================================= func VerifyHardwareCode(c *gin.Context) { var req VerifyRequest @@ -63,11 +63,11 @@ func VerifyHardwareCode(c *gin.Context) { // ========================================================= if tokenInput == "CS2026" { fmt.Printf("[VERIFY] Master Token CS digunakan\n") - sisaMenit = 120 + sisaMenit = 60 isTokenValid = true } else if tokenInput == "ADM999" { fmt.Printf("[VERIFY] Master Token Admin digunakan\n") - sisaMenit = 720 // 24 Jam + sisaMenit = 1440 // 24 Jam isTokenValid = true } else { // ========================================================= @@ -77,15 +77,14 @@ func VerifyHardwareCode(c *gin.Context) { errBooking := config.DB.First(&booking, "redeem_code = ? AND status = 'Approved'", tokenInput).Error if errBooking == nil { - // Cek apakah hari ini (tanggal) sama dengan hari booking if booking.StartTime.Format("2006-01-02") != sekarang.Format("2006-01-02") { - c.JSON(http.StatusForbidden, gin.H{"error": "Peminjaman bukan untuk hari ini"}) + c.JSON(http.StatusForbidden, gin.H{"error": "Peminjaman bukan untuk hari ini!"}) return } toleransiMasuk := booking.StartTime.Add(-15 * time.Minute) if sekarang.Before(toleransiMasuk) { - c.JSON(http.StatusForbidden, gin.H{"error": "Belum waktunya. Bisa masuk 15 mnt sblm jam peminjaman!"}) + c.JSON(http.StatusForbidden, gin.H{"error": "Belum waktunya. Bisa masuk 15 menit sebelum kelas!"}) return } if sekarang.After(booking.EndTime) { @@ -101,40 +100,74 @@ func VerifyHardwareCode(c *gin.Context) { } else { // ========================================================= - // 3. CEK KODE MATA KULIAH (ON-DEMAND FLEKSIBEL) + // 3. CEK KODE MATA KULIAH DENGAN DOUBLE-LAYER PROTECTION // ========================================================= - var schedule models.ClassSchedule - // Abaikan hari dan jam, cukup cek apakah kode matkul eksis di database - errSchedule := config.DB.First(&schedule, "kode_mk = ?", tokenInput).Error + var reqSchedule models.ClassSchedule + // Cari apakah Kode MK yang diketik eksis di database (contoh: "EE153") + errSchedule := config.DB.First(&reqSchedule, "kode_mk = ?", tokenInput).Error if errSchedule == nil { - // KODE MATKUL EKSIS. - // CEK BENTROK: Apakah ada orang yang SEDANG booking via web sekarang? + // PROTEKSI LAPIS 1: Cek apakah ada yang sedang Booking via Web sekarang var countBookingAktif int64 config.DB.Model(&models.Booking{}).Where( "room_id = ? AND status = 'Approved' AND start_time <= ? AND end_time >= ?", - schedule.RoomID, sekarang, sekarang, + reqSchedule.RoomID, sekarang, sekarang, ).Count(&countBookingAktif) if countBookingAktif > 0 { - c.JSON(http.StatusConflict, gin.H{"error": "Ruangan sedang dipakai peminjam resmi (Web)!"}) + c.JSON(http.StatusConflict, gin.H{"error": "Akses Ditolak: Ruangan sedang dipakai peminjam resmi (Web)!"}) return } - // Jika aman (tidak ada yang booking), berikan akses 120 Menit! - sisaMenit = 120 + // PROTEKSI LAPIS 2: Cek apakah ada JADWAL KELAS LAIN yang sedang berjalan di jam ini + // Ambil nama hari ini dalam Bahasa Indonesia + hariMap := map[time.Weekday]string{ + time.Sunday: "Minggu", time.Monday: "Senin", time.Tuesday: "Selasa", + time.Wednesday: "Rabu", time.Thursday: "Kamis", time.Friday: "Jumat", time.Saturday: "Sabtu", + } + hariIni := hariMap[sekarang.Weekday()] + jamSekarang := sekarang.Format("15:04:05") + + var activeClass models.ClassSchedule + errActive := config.DB.Where( + "room_id = ? AND hari = ? AND jam_mulai <= ? AND jam_selesai >= ?", + reqSchedule.RoomID, hariIni, jamSekarang, jamSekarang, + ).First(&activeClass).Error + + if errActive == nil { + // Ada kelas yang sedang berlangsung saat ini. + // Cek apakah kelas tersebut BERBEDA dengan Kode MK yang diinputkan pengguna + // 🌟 PERBAIKAN: Ubah KodeMk menjadi KodeMK (K huruf besar) + if activeClass.KodeMK != reqSchedule.KodeMK { + c.JSON(http.StatusConflict, gin.H{ + // 🌟 PERBAIKAN: Ubah NamaMk menjadi NamaMK (K huruf besar) + "error": "Akses Ditolak: Ruangan sedang digunakan oleh jadwal kelas " + activeClass.NamaMK, + }) + return + } + // Jika kodenya SAMA (Dosen menginputkan kodenya di jam yang memang miliknya), abaikan & beri izin masuk. + } + + // JIKA LOLOS SEMUA PROTEKSI: Berikan akses waktu berdasarkan jumlah SKS + // 🌟 PERBAIKAN: Pastikan ini sesuai dengan struct di models (JumlahSks atau JumlahSKS) + durasiMenit := reqSchedule.JumlahSks * 50 + if durasiMenit <= 0 { + durasiMenit = 100 // Nilai aman (default 2 SKS) jika database kosong + } + + sisaMenit = durasiMenit isTokenValid = true } } if !isTokenValid { - c.JSON(http.StatusUnauthorized, gin.H{"error": "Token atau Kode MK tidak ditemukan / salah!"}) + c.JSON(http.StatusUnauthorized, gin.H{"error": "Token Web atau Kode MK tidak ditemukan!"}) return } } // ========================================================= - // 4. JIKA VALID (Master / Matkul / Web), BUKA GEMBOK VIA MQTT + // 4. JIKA VALID, BUKA GEMBOK VIA MQTT & HTTP LOKAL // ========================================================= DeviceStatusCache["lampu1"] = "on" DeviceStatusCache["lampu2"] = "on" @@ -152,6 +185,7 @@ func VerifyHardwareCode(c *gin.Context) { client := mqtt.NewClient(opts) if tokenMQTT := client.Connect(); tokenMQTT.Wait() && tokenMQTT.Error() == nil { client.Publish("sclass/d101/auth", 0, true, "UNLOCK").Wait() + // Opsional: Jika masih mengandalkan MQTT untuk lampu client.Publish("sclass/d101/lampu1", 0, false, "on").Wait() client.Publish("sclass/d101/lampu2", 0, false, "on").Wait() client.Disconnect(250) diff --git a/backend/models/entity.go b/backend/models/entity.go index 9bf03bf..b03733f 100644 --- a/backend/models/entity.go +++ b/backend/models/entity.go @@ -60,4 +60,5 @@ type ClassSchedule struct { Hari string `gorm:"type:varchar(20);not null;column:hari" json:"hari"` JamMulai string `gorm:"type:time;not null;column:jam_mulai" json:"jam_mulai"` JamSelesai string `gorm:"type:time;not null;column:jam_selesai" json:"jam_selesai"` + JumlahSks int `gorm:"column:jumlah_sks" json:"jumlah_sks"` }