ระบบเช็คเวลาเข้า-ออกด้วย RFID Card, Google Apps Script, Google Sheets และ Bootstrap 5
🚀 โครงสร้างระบบ
- Google Sheets สำหรับเก็บข้อมูล
- Google Apps Script (Server-side) จัดการการบันทึกข้อมูล
- HTML, JavaScript (Client-side) ใช้สร้าง UI และดึงข้อมูลจาก Apps Script
1️⃣ สร้าง Google Sheet
ให้สร้าง Google Sheet แล้วเปลี่ยนชื่อเป็น "RFID_Attendance"
และกำหนด หัวตาราง (เริ่มที่ A1) ดังนี้:
RFID Card ID | ทะเบียนรถ | เวลาเข้า | เวลาออก | ชั่วโมงที่จอด | ค่าจอดรถ (บาท) |
---|
2️⃣ Frontend (HTML + JavaScript)
สร้างไฟล์ index.html
ใน Apps Script
<!DOCTYPE html> <html lang="th"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>ระบบเช็คเวลาเข้า-ออกงาน</title> <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet"> <style> thead { background-color: #333; color: white; } </style> </head> <body class="container mt-4"> <h2 class="text-center">ระบบเช็คเวลาเข้า-ออกงาน</h2> <form id="formSubmit" onsubmit="submitRFID()"> <!-- Input RFID --> <div class="mb-3"> <label for="rfid" class="form-label">สแกน RFID</label> <input type="text" id="rfid" class="form-control" placeholder="กรอกรหัส RFID"> </div> <div class="mb-3"> <label for="license_plate" class="form-label">เลขทะเบียนรถ</label> <input type="text" id="license_plate" class="form-control" placeholder="เลขทะเบียนรถ"> </div> <button type="submit" class="btn btn-primary">บันทึกเวลา</button> </form> <!-- แสดงผลลัพธ์ --> <div id="result" class="alert alert-success mt-3 text-center d-none" role="alert"></div> <h3 class="mt-4">รายการเข้า-ออกล่าสุด</h3> <table id="dataTable" class="table table-bordered mt-3"> <thead> <tr> <th>RFID</th> <th>เลขทะเบียนรถ</th> <th>เวลาเข้า</th> <th>เวลาออก</th> <th>ชั่วโมงที่อยู่</th> <th>ค่าบริการ</th> </tr> </thead> <tbody id="dataTable_tbody"></tbody> </table> <script> window.addEventListener("load", (event) => { document.getElementById("rfid").focus(); }); function submitRFID() { event.preventDefault(); const rfid = document.getElementById("rfid").value; const license_plate = document.getElementById("license_plate").value; if (!rfid) { document.getElementById("rfid").focus(); alert("กรุณากรอกรหัส RFID"); return; } google.script.run.withSuccessHandler(function(data) { const response = JSON.parse(data) const resultDiv = document.getElementById("result"); resultDiv.classList.remove("d-none") resultDiv.innerHTML = response.msg setTimeout(() => { loadTable(); document.getElementById("formSubmit").reset() document.getElementById("rfid").focus(); }, 3000); }).checkInOutRFID(rfid, license_plate); } function loadTable() { document.getElementById("result").classList.add("d-none") const tableBody = document.getElementById("dataTable_tbody"); const tr = document.createElement("tr"); tableBody.innerHTML = ""; google.script.run.withSuccessHandler(function(data) { //console.log(data) //console.log("deta: "+data) if(data.length === 0){ tr.innerHTML = `<td colspan="6" class="text-center">ยังไม่มีข้อมูล</td>` tableBody.appendChild(tr); }else{ let html = "" data.forEach(function(row) { //console.log(row) html += ` <tr> <td>${row.rfid}</td> <td>${row.name}</td> <td>${row.checkIn ? row.checkIn.toLocaleString() : ""}</td> <td>${row.checkOut ? row.checkOut.toLocaleString() : ""}</td> <td>${row.hoursWorked ? row.hoursWorked : ""}</td> <td>${row.charge ? row.charge + " บาท" : ""}</td> </tr> `; }); tableBody.innerHTML = html; } }).getRecentData(); } document.addEventListener("DOMContentLoaded", loadTable); </script> </body> </html>
3️⃣Google Apps Script (Backend)
ไปที่ Extensions → Apps Script แล้วเพิ่มโค้ดนี้
function doGet() { return HtmlService.createHtmlOutputFromFile('index') .setTitle("ระบบเช็คเวลาเข้า-ออกงาน"); } // ฟังก์ชันรับข้อมูล RFID และบันทึกเข้า Google Sheets function checkInOutRFID(rfid, license_plate) { const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("RFID_Attendance"); const data = sheet.getDataRange().getDisplayValues(); const now = new Date(); let lastRow = -1; // ค้นหารายการล่าสุดของ RFID ที่ยังไม่มีเวลาออก for (let i = data.length - 1; i >= 0; i--) { if (data[i][0].toString() === rfid.toString() && data[i][3] === "") { lastRow = i + 1; break; } } if (lastRow === -1) { // ถ้าไม่มีรายการเข้า ให้ Check-in sheet.appendRow([rfid, license_plate, now, "", "", ""]); return JSON.stringify({msg: "Crad "+rfid+" <br> เช็คอินสำเร็จ! <br> เวลาที่บันทึก " + now.toLocaleString()}); } else { // ถ้ามีรายการเข้า ให้ Check-out const response = checkOut(rfid) return response } } function checkOut(rfidCardId) { const sheetLog = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("RFID_Attendance"); const dataLog = sheetLog.getDataRange().getValues(); const now = new Date(); const hourlyRate = 20; // ค่าจอดรถต่อชั่วโมง for (let i = dataLog.length - 1; i > 0; i--) { if (dataLog[i][0] == rfidCardId && dataLog[i][3] == "") { const checkInTime = new Date(dataLog[i][2]); const hoursParked = Math.ceil((now - checkInTime) / (1000 * 60 * 60)); let totalPrice = 0 if(hoursParked > 1){ totalPrice = hoursParked * hourlyRate; }else{ totalPrice = 0 } sheetLog.getRange(i + 1, 4).setValue(now); // บันทึกเวลาออก sheetLog.getRange(i + 1, 5).setValue(hoursParked); sheetLog.getRange(i + 1, 6).setValue(totalPrice); return JSON.stringify({msg: "Crad " +rfidCardId+" <br> เช็คเอาท์สำเร็จ! <br> เวลาที่จอด " + hoursParked + " ชม. <br> ค่าจอด " + totalPrice + " บาท"}); } } } // ดึงข้อมูลล่าสุด function getRecentData() { const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("RFID_Attendance"); const data = sheet.getDataRange().getDisplayValues(); const result = []; //Logger.log(data) for (let i = data.length-1; i > 0; i--) { result.push({ rfid: data[i][0], name: data[i][1], checkIn: data[i][2], checkOut: data[i][3], hoursWorked: data[i][4], charge: data[i][5] }); } //Logger.log(result) return result; }
📌 วิธีใช้งาน
- สร้าง Google Sheets แล้วตั้งชื่อเป็น
"RFID_Attendance"
- เปิด Apps Script และคัดลอก Code.gs และ index.html ไปใส่
- กด Deploy → Web App
- ใช้ URL ที่ได้ เปิดในเว็บเบราว์เซอร์