程式分為前端index.html,以及後端GAS函式 程式碼.gs。
自動偵測IP,可設定判斷條件,位於允許IP範圍才能簽到。
試算表內一個班級一個工作表,對映下拉選單的代號,圖例為101~107。
工作表欄位:姓名、學號、班級、年級、座號、(日期)
學號:請確保其內容為文字。(數字自動向左靠齊即為文字)
(日期):欄位F、核取方塊,每次上課前向左新增一欄,即可持續每周簽到。
<!DOCTYPE html>
<html>
<head>
<title>線上點名系統</title>
<style>
body {
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
margin: 0;
font-family: Arial, sans-serif;
}
.container {
text-align: center;
border: 5px solid green; /* 將邊框顏色設為綠色 */
padding: 20px;
border-radius: 10px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
}
</style>
<script>
function signIn() {
var classId = document.getElementById("classSelect").value;
var studentId = document.getElementById("studentId").value;
google.script.run.withSuccessHandler(function(response) {
document.getElementById("result").innerText = response;
}).signInStudent(classId, studentId);
}
window.onload = function() {
fetch('https://api.ipify.org?format=json')
.then(response => response.json())
.then(data => {
var userIp = data.ip;
document.getElementById("ipAddress").innerText = "您的IP位址: " + userIp;
if (isIpInRange(userIp)) {
document.getElementById("signInButton").disabled = false;
} else {
document.getElementById("result").innerText = "您的IP位址不在允許的網段內,無法簽到。";
document.getElementById("signInButton").disabled = true;
}
})
.catch(error => {
console.error('Error fetching IP address:', error);
document.getElementById("ipAddress").innerText = "無法取得IP位址";
document.getElementById("signInButton").disabled = true;
});
}
function isIpInRange(ip) {
function ipToInt(ip) {
return ip.split('.').reduce((int, octet) => (int << 8) + parseInt(octet, 10), 0) >>> 0;
}
var ipInt = ipToInt(ip);
var rangeStart = ipToInt("163.16.64.0");
var rangeEnd = ipToInt("163.16.127.255");
return ipInt >= rangeStart && ipInt <= rangeEnd;
}
</script>
</head>
<body>
<div class="container">
<h1>一年級線上點名系統</h1>
<p id="ipAddress">正在取得IP位址...</p>
<label for="classSelect">選擇班級:</label>
<select id="classSelect">
<option value="101">101</option>
<option value="102">102</option>
<option value="103">103</option>
<option value="104">104</option>
<option value="105">105</option>
<option value="106">106</option>
<option value="107">107</option>
</select><br><br>
<label for="studentId">輸入學生學號:</label>
<input type="text" id="studentId"><br><br>
<button id="signInButton" onclick="signIn()" disabled>簽到</button>
<p id="result"></p>
</div>
</body>
</html>
// 試算表ID
var spreadsheetId = '填入Google試算表ID';
function doGet() {
return HtmlService.createHtmlOutputFromFile("index");
}
function signInStudent(classId, studentId) {
// 開啟試算表
var spreadsheet = SpreadsheetApp.openById(spreadsheetId);
// 選擇對應的工作表
var sheet = spreadsheet.getSheetByName(classId);
// 取得工作表中的所有資料
var data = sheet.getDataRange().getValues();
// 尋找對應的學號
for (var i = 1; i < data.length; i++) {
if (data[i][1] == studentId) { // 欄位B:學號
var signed = sheet.getRange(i + 1, 6).getValue();
if(signed){
// 回傳學生姓名已簽到訊息
return data[i][0] + " 本日重複簽到!!"; // 欄位A:姓名
}else{
// 簽到,將欄位F的核取方塊打勾
sheet.getRange(i + 1, 6).setValue(true); // 核取方塊在第6欄
// 回傳學生姓名與簽到成功訊息
return data[i][0] + " 簽到已成功"; // 欄位A:姓名
}
}
}
// 若找不到學號,回傳錯誤訊息
return classId + " 學號 " + studentId + " 不存在!!";
}