ระบบเช็คเวลาเข้า-ออกด้วย 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 ที่ได้ เปิดในเว็บเบราว์เซอร์