【GAS】自製點名系統
文章目錄
大眼蛙教練的課程是以堂數做計算,也就是來一次算一次,而不是一段時間。因此每次學生上課都需要簽到,最後還需要人工來統計。因此我做了一個簡單的點名系統,讓電腦來做統計和計算的工作。
這篇文章出乎意料地幫助到許多人,因此我在2023年重新寫了一次,比上次更容易製作和操作,也更好看一些(我覺得啦)。
建議閱讀這篇文章: https://emtech.cc/post/rol-call/
- 開發者:毛哥EM(我)
- 類型:網站
- 網址:EM's Base
功能
新增學生
輸入名稱並按新增即可。
電腦會自動在Google Sheet建立好欄位。教練只需要到試算表設定學生的課程數就好了。如果沒有課了會用紅色表示,而未設定會被判斷為沒有課程。
- 學生姓名不可以有空格,如果有空格會自動刪除
- 要刪除學生請刪除整列,不可留一整列空白
點名
網站會從表單取得學生名單並顯示。只需要點擊名稱即可完成報到。
完成報到後會使用Line Notify通知完成報到的學生和報到時間到指定的群組。
- 為了配合不同螢幕大小,沒有限制每行出現的學生數。盡可能多顯示一些,比較容易找到。
- 為避免重複點名,報到後學生會隱藏。重新整理頁面即可顯現
- 下方方框會顯示自開啟網頁後已完成報到的學生。
- 如果要刪除記錄(如誤按到)請務必要「刪除整列」。不可留空
查詢記錄
如果要查詢之前報到的紀錄,請到查詢頁面並輸入姓名。
教學
我們分成三個步驟:
- 建立試算表(Google Sheet)
- 生成Line Notify仗權(若不需要Line通知可省略)
- 創建API(Google App Script)來處理資料、發送訊息、以及更新試算表
- 建立一個漂亮的網站方便操作
建立試算表(Google Sheet)
我分成兩個表格,分別叫做紀錄
和統計
。為了方便辨識第一排插入標題
紀錄
編號 | 姓名 | 時間 | 剩餘課堂數 |
---|---|---|---|
統計
學生 | 上課次數 | 剩餘課堂數 | 總課堂數 |
---|---|---|---|
接著請你複製這個試算表的ID,也就是網址https://docs.google.com/spreadsheets/d/
和/
之間那一串(如1fjX-prGu0hfb65LCQkrktWa-JavvjSz7tWMmYWAb7RA
)。等一下會用到。
生成Line Notify仗權
Line Notify是個比較冷門但是非常好用的工具。我們可以透過他來從第三方(如你的網站、或是ios捷徑)無限量的廣播訊息到指定的群組,或是單獨發給你。我們會在報到成功後請Line用Line Notify來在群組裡廣播提醒。
請依照圖片步驟建立一個仗權,要給Line看這一串他才知道要傳送信息到哪裡。使用Line Lontify而不是Line機器人的原因是免費版的官方帳號一個月只能傳送500則訊息,但老師的學生數量大,可能會吃不消;且Line Notify設定較簡單。
建立API(Google App Script)
想要讓網站編輯試算表需要透過Google App Script(GAS)來完成。我們要建立四個API,分別用來:
- 紀錄出缺席
- 獲取學生列表(以進行報到)
- 查詢紀錄
- 新增學生
到時候我們建立的網站會向這四個API發送請求來更新試算表或獲取資料
google 官方文件 spreadsheet method,裡面有非常詳盡的介紹,包括可以讀取欄位、讀取資料、排序資料、插入資料等等的功能,其實某方面來說算是功能齊全的類資料庫了。有興趣可以點開來看裡面文件。
文件裡面 method 一大堆,還是直接實作比較快。
出缺席紀錄
請建立一個新的專案並貼上以下內容。記得貼上excel那段ID
為避免程式碼站太多空間,可能會部分隱藏。請記得展開或直接複製。
1function doGet(e) {
2 var params = e.parameter;
3 // 可以針對你帶入的資料變化 params.xxxxxx xxxxx = 你帶進來的key值
4 var name = params.name;
5 var time = params.time;
6 var remain = params.remain;
7 //將Sheet指定為"資料庫"試算表 SpreadSheet = 試算表 ,貼上excel那段參數
8 var SpreadSheet = SpreadsheetApp.openById("XXXXXXXXXXXXXXXXXXX");
9 //取得頁籤:"工作表1" Sheet = 頁籤
10 var Sheet = SpreadSheet.getSheets()[0];
11 //取得有資料的最後一行的"行數"(目的要在最後一行插入新資料)
12 var LastRow = Sheet.getLastRow();
13 // 編號為行數(如要輸入編號2時裡面已經有2行了)
14 var orderNum = LastRow;
15
16 //開始寫入資料 擋住沒填時間 不給寫入資料,防止被亂撞api
17 if(time !== undefined){
18 //在最後一行的下一行寫入資料
19 Sheet.getRange(LastRow+1, 1).setValue(orderNum);
20 Sheet.getRange(LastRow+1, 2).setValue(name);
21 Sheet.getRange(LastRow+1, 3).setValue(time);
22 Sheet.getRange(LastRow+1, 4).setValue(remain);
23 return ContentService.createTextOutput(true);
24 }
25 // 被亂撞 會回吐這段文字給前端
26 return ContentService.createTextOutput('別亂撞我~ :)');
27}
在這個程式當中,我們說當我們拿著資料到這個應用程式時,將我們給的姓名、時間、剩餘課堂數、以及編號寫入到試算表第一頁最後一行的下一行。但是這樣還沒結束,會後我們還要請Line Notify幫我們廣播。請在return ContentService.createTextOutput(true);
之前插入以下程式碼。記得填入剛才生成的仗權。
編輯完成後請按執行。第一次執行時系統會要求你登入Google,請登入現在使用的帳號並提供編輯試算表的權限。Google會告訴你不安全因為這是是你自己製作的應用程式,沒有經過Google審查。直接點選進階,並繼續前往即可。成功部署後請保存應用程式的網址,之後網站就會傳送資料到這個網站來寫入和讀取資料。
完成後可能會看到紅色警告說無法執行,因為我們直接執行了程式,沒有給資料(學生名稱)。因此請建立一個程式碼檔案叫做debug
,並貼上以下內容:
1//呼叫
2function debug() {
3 var Result = doGet({
4 parameter: {
5 name: '測試先生',
6 time: '2021/10/10 22:46:00',
7 remain: 10
8 }
9 });
10 Logger.log('Result: %s', Result);
11}
執行後你應該會看到底下顯示執行完畢,且表單多出了一列如下
編號 | 姓名 | 時間 | 剩餘課堂數 |
---|---|---|---|
1 | 測試先生 | 2021/10/10 22:46:00 | 10 |
做好了之後點擊執行▶️,你會需要授予你的程式讀取資料的權限。因為你寫的程式沒有被Google驗證過所以會顯示不安全,但我相信你不會把你的帳號搞爆,對吧
接下來我們要部署它,讓它成為一個網站來讓我們抓。這裡選擇網頁應用程式,所有人都以你的身份讀取。按下部署就可以囉
這裡我們把部署的網址複製起來。如果要做修改除了按儲存之外要記得重新部署成新版本才會更新喔
若發布後還有做修改,既得要再次發布且要發布為新版本。
學生列表
學生列表不需要輸入,直接讀取內容就好了。這裡使用的輸出格式是JSON。JSON就是ios捷徑APP裡的辭典,簡單來說就是一個對照表。比如說你想要紀錄一個人的基本資料如下
1{
2 "姓": "毛",
3 "名": "宥鈞",
4 "性別": "男",
5 "年齡": 15,
6 "住址":
7 {
8 "路名": "大馬路",
9 "city": "台中市",
10 "國家": "台灣",
11 "郵遞區號": "40763"
12 }
13}
我們可以輕鬆的讓JavaScript讀懂它。請以相同方式建立以下API
1function doGet(e){
2 var id = 'XXXXXXXXXXXXXXXXXXX'; //抓取表單
3 var spreadsheet = SpreadsheetApp.openById(id); // Sheet id
4 var sheet = spreadsheet.getSheets()[1]; // 要第幾個sheet? 1 就是第2個
5 var rowLength = sheet.getLastRow()-1; //取行長度
6 var columnLength = sheet.getLastColumn(); //取列長度
7 var data = sheet.getRange(2,1,rowLength,columnLength).getValues(); // 取得的資料
8 var dataExport = {};
9 // 一個個加入json
10 for(i in data){
11 if(data[i][0] != ""){
12 dataExport[i] = {
13 name: data[i][0],
14 left: data[i][2],
15 };
16 };
17 };
18 // 回傳JSON
19 var dataExportFormat = JSON.stringify(dataExport);
20 return ContentService.createTextOutput(dataExportFormat).setMimeType(ContentService.MimeType.JSON);
21 }
在這段程式當中,我們一列一列的把試算表的資料塞進JSON裡,最後再回傳給我們。
查詢紀錄
這裡使用Post來傳送而不是Get。其實都可以,只是想說換一個方式。差別在於使用Get時資料是存在網址當中,而Post像是還有一個附件。因為資料量很小,所以都可以使用。
1function doPost(e) {
2 var params = e.parameter;
3 // 可以針對你帶入的資料變化 params.xxxxxx xxxxx = 你帶進來的key值
4 var name = params.name;
5 var SpreadSheet = SpreadsheetApp.openById('XXXXXXXXXXXXXXXXXXX'); //抓取表單
6 var Sheet = SpreadSheet.getSheets()[0];
7 var LastRow = Sheet.getLastRow();
8 var data = [];
9 var listAll = Sheet.getSheetValues(1, 2, LastRow, 4);
10 // 把符合的抓出來
11 for (var i = 0; i < listAll.length; i++) {
12 if (listAll[i].indexOf(name) === 0) {
13 data.push({ data: listAll[i], index: i + 1 });
14 }
15 }
16 // 回傳JSON
17 return ContentService.createTextOutput(JSON.stringify(data)).setMimeType(
18 ContentService.MimeType.JSON
19 );
20}
在這段程式當中雖然一樣是回傳資料,但是在塞進JSON前先判斷一下姓名是否符合。直得注意的是我們是從第2欄開始抓,因為使用者不需要知道這是所有資料當中的第幾筆資料。
新增學生
1function doGet(e) {
2 var params = e.parameter;
3 // 可以針對你帶入的資料變化 params.xxxxxx xxxxx = 你帶進來的key值
4 var name = params.name;
5 //將Sheet指定為"資料庫"試算表 SpreadSheet = 試算表 ,貼上excel那段參數
6 var SpreadSheet = SpreadsheetApp.openById("XXXXXXXXXXXXXXXXXXX");
7 //取得頁籤:"工作表1" Sheet = 頁籤
8 var Sheet = SpreadSheet.getSheets()[1];
9 //取得有資料的最後一行的"行數"(目的要在最後一行插入新資料)
10 var LastRow = Sheet.getLastRow();
11 var now = LastRow+1;
12 //格字內加入函式統計課程數
13 var his="=COUNTIF('紀錄'!B:B,A"+now+")";
14 //格字內加入函式計算剩餘課程數
15 var less='=D'+now+'-B'+now;
16 if(name !== undefined){
17 //在最後一行的下一行寫入資料
18 Sheet.getRange(LastRow+1, 1).setValue(name);
19 Sheet.getRange(LastRow+1, 2).setValue(his);
20 Sheet.getRange(LastRow+1, 3).setValue(less);
21 return ContentService.createTextOutput(true);
22 }
23 // 被亂撞 會回吐這段文字給前端
24 return ContentService.createTextOutput('別亂撞我~ :)');
25}
我們在其中一個儲存格中插入了一個叫做COUNTIF
的函式。他會統計在紀錄當中有幾筆資料的姓名和他左邊的姓名一樣。而剩餘課堂數就是全部課堂數減統計出來已經上的課堂數。
建立網站
最後,讓我們來做一個的簡單漂亮的網站吧。 請選一個地方建立以下幾個純文字檔案
- check-in.html
- search.html
- sign-up.html
- index.html
- style.css
HTML是網頁的檔案,有點像Word檔,而CSS是用來裝飾HTML的。你可以用它來決定字要多大、什麼顏色、間距要多少等。
而我們在HTML檔中還插入了一些JavaScript來傳送和讀取資料和顯示資料。我使用了一個叫做jQuery的JavaScript函式庫,它可以讓程式變得更簡略。記得把傳送到的網址改成你剛才建的Google App Script的網址,其他你可以直接複製貼上。
index.html
1<!DOCTYPE html>
2<head>
3 <meta charset="utf-8" />
4 <title>點名系統</title>
5 <!-- 網站資訊 -->
6 <meta name="description" content="使用Google sheet的api紀錄出缺席" />
7 <meta name="author" content="毛哥EM" />
8 <!-- 讓網址正常顯示以及裝飾 -->
9 <meta name="viewport" content="width=device-width, initial-scale=1" />
10 <meta name="theme-color" content="00BFFF" />
11 <link rel="stylesheet" type="text/css" href="style.css" media="screen" />
12</head>
13<body>
14 <main>
15 <h1>點名系統</h1>
16 <p>主選單</p>
17 <button onclick="window.location='check-in.html';">報到</button>
18 <button onclick="window.location='search.html';">查詢紀錄</button>
19 <button onclick="window.location='sign-up.html';">新增學生</button>
20 <p>
21 <a href="https://Edit-Mr.github.io">毛哥EM</a>製作
22 </p>
23 </main>
24</body>
sign-up.html
1<!DOCTYPE html>
2<head>
3 <meta charset="utf-8" />
4 <title>新增學生 - 點名系統</title>
5 <!-- 網站資訊 -->
6 <meta name="description" content="使用Google sheet的api紀錄出缺席" />
7 <meta name="author" content="毛哥EM" />
8 <!-- 讓網址正常顯示以及裝飾 -->
9 <meta name="viewport" content="width=device-width, initial-scale=1" />
10 <meta name="theme-color" content="00BFFF" />
11 <link rel="stylesheet" type="text/css" href="style.css" media="screen" />
12 <!-- 載入jQuery -->
13 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
14</head>
15<body>
16 <main>
17 <h1><a href="index.html">點名系統</a></h1>
18 <p>新增學生</p>
19 <input type="text" class="form-control" id="name" />
20 <button type="button" id="sendOrder">新增</button>
21 <p>
22 <a href="https://Edit-Mr.github.io">毛哥EM</a>製作<br />
23 送出後請稍等數秒 勿重複新增
24 </p>
25 </main>
26 <script>
27 $(function () {
28 // 監聽 按鈕點擊
29
30 $("#sendOrder").click(function (e) {
31 // 姓名
32
33 var name = $("#name").val();
34
35 $("input").focus(function () {
36 $(this).css("border", "");
37 });
38
39 // 擋住不填資料
40
41 if (name == "") {
42 $("#name").css("border", "1px solid #ff0000");
43 } else {
44 var name = name.replace(" ", "");
45
46 var data = {
47 name: name,
48 };
49
50 $.ajax({
51 // 這邊用get type
52
53 type: "get",
54
55 // api url - google appscript 產出的 url
56
57 url: "https://script.google.com/............",
58
59 // 剛剛整理好的資料帶入
60
61 data: data,
62
63 // 資料格式是JSON
64
65 dataType: "JSON",
66
67 // 成功送出 會回頭觸發下面這塊
68
69 success: function (response) {
70 console.log(response);
71
72 alert("新增成功!!");
73 },
74 });
75 }
76 });
77 });
78 </script>
79</body>
check-in.html
1<!DOCTYPE html>
2<head>
3 <meta charset="utf-8" />
4 <title>報到 - 點名系統</title>
5 <!-- 網站資訊 -->
6 <meta name="description" content="使用Google sheet的api紀錄出缺席" />
7 <meta name="author" content="毛哥EM" />
8 <!-- 讓網址正常顯示已經裝飾 -->
9 <meta name="viewport" content="width=device-width, initial-scale=1" />
10 <meta name="theme-color" content="00BFFF" />
11 <link rel="stylesheet" type="text/css" href="style.css" media="screen" />
12 <!-- 載入jQuery和學生列表 -->
13 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
14</head>
15<script>
16 //用Get讀取資料
17 window.onload = () => {
18 // api url - google appscript 產出的 url
19 let requestURL = "https://script.google.com/.........";
20 let request = new XMLHttpRequest();
21 request.open("GET", requestURL);
22 request.responseType = "json";
23 request.send();
24 //收到資料後輪流做成按鈕
25 request.onload = function () {
26 let student = request.response;
27 for (var i in student) {
28 var now = student[i];
29 var stu = now.name;
30 var left = now.left;
31 --left;
32 var but = '<button id="' + stu + '">' + stu + "</button>";
33 console.log(but);
34 $("#students").append(but);
35 var iden = "#" + stu;
36 var click = 'to("' + stu + '", ' + left + ");";
37 $(iden).attr("onclick", click);
38 }
39 //載入完成後更改副標題
40 $("#header").text("點擊姓名即可完成報到");
41 };
42 };
43 function to(name, have) {
44 var currentdate = new Date();
45 var filltime = currentdate.getFullYear() + "/" + (currentdate.getMonth() + 1) + "/" + currentdate.getDate() + " " + currentdate.getHours() + ":" + currentdate.getMinutes() + ":" + currentdate.getSeconds();
46 // 打包 要的資料
47 var course = have;
48 console.log(course);
49 var data = {
50 name: name,
51 time: filltime,
52 remain: course,
53 };
54 var tag = name;
55 $.ajax({
56 // 這邊用get type
57 type: "get",
58 // api url - google appscript 產出的 url
59 url: "https://script.google.com/.........",
60 // 剛剛整理好的資料帶入
61 data: data,
62 // 資料格式是JSON
63 dataType: "JSON",
64 // 成功送出 會回頭觸發下面這塊
65 success: function (response) {
66 var msg = response;
67 alert("報到成功! 還剩" + course + "堂課");
68 },
69 });
70 //報到完成的顯示在下方框框並將按鈕隱藏
71 $("#ed").prepend("<li>" + tag + "</li>");
72 var id = "#" + tag;
73 $(id).fadeOut();
74 }
75</script>
76</head>
77<body>
78 <main>
79 <h1><a href="index.html">點名系統</a></h1>
80 <p id="header">載入中</p>
81 <div id="students"></div>
82 <h2>已到學生</h2>
83 <p class="ed" id="ed"></p>
84 <p><a href="https://Edit-Mr.github.io">毛哥EM</a>製作</p>
85 </main>
86</body>
search.html
1<!DOCTYPE html>
2<head>
3 <meta charset="utf-8" />
4 <title>查詢 - 點名系統</title>
5 <!-- 網站資訊 -->
6 <meta name="description" content="使用Google sheet的api紀錄出缺席" />
7 <meta name="author" content="毛哥EM" />
8 <!-- 讓網址正常顯示以及裝飾 -->
9 <meta name="viewport" content="width=device-width, initial-scale=1" />
10 <meta name="theme-color" content="00BFFF" />
11 <link rel="stylesheet" type="text/css" href="style.css" media="screen" />
12 <!-- 載入jQuery -->
13 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
14</head>
15<body>
16 <main>
17 <h1><a href="index.html">點名系統</a></h1>
18 <p>紀錄查詢</p>
19 <input type="text" id="name" />
20 <button type="button" id="send">查詢</button>
21 <!-- 顯示查詢結果的表格 先隱藏 -->
22 <table class="table table-striped" style="display: none;">
23 <thead>
24 <tr>
25 <th>姓名</th>
26 <th>報到時間</th>
27 <th>剩下課堂</th>
28 </tr>
29 </thead>
30 <tbody id="dataView">
31 <!-- 查詢到的資料會插入到這裡 -->
32 </tbody>
33 </table>
34 <p>
35 <a href="https://Edit-Mr.github.io">毛哥EM</a>製作<br />
36 送出後請稍等數秒
37 </p>
38 </main>
39 <script>
40 //當傳送按鈕被點擊
41 $(function () {
42 $("#send").click(function (e) {
43 var status = true;
44 var name = $("#name").val();
45 $("input").focus(function () {
46 $(this).css("border", "");
47 });
48 //擋住沒有輸入姓名
49 if (name == "") {
50 $("#name").css("border", "1px solid #ff0000");
51 } else {
52 var data = {
53 name: name,
54 };
55 //Post到前面做的API,記得更改網址
56 $.ajax({
57 // 這邊用post type
58 type: "post",
59 // api url - google appscript 產出的 url
60 url: "https://script.google.com/...........",
61 data: data,
62 dataType: "JSON",
63 success: function (response) {
64 var content = "";
65 //把資料一行行做出表格
66 response.forEach((element) => {
67 var [name, time, remain] = element.data;
68 var index = element.index;
69 content += `<tr>
70 <td>${name}</td>
71 <td>${new Date(time)}</td>
72 <td>${remain}</td>
73 </tr>`;
74 });
75 //如果有資料的話顯示表格,否則提示查無資料
76 if (content) {
77 document.getElementsByClassName("table-striped")[0].style.display = "table";
78 } else {
79 alert("查無資料");
80 }
81 var dataView = document.getElementById("dataView");
82 dataView.innerHTML = content;
83 $("#name").val("");
84 },
85 });
86 }
87 });
88 });
89 </script>
90</body>
style.css
1@charset "utf-8";
2/*按鈕
3-----------------*/
4button {
5 outline: 0;
6 font-size: 1.5em;
7 font-weight: 600;
8 background: #fff;
9 border: none;
10 margin: 5px;
11 padding: 0.5em;
12 transition: all 0.3s ease-out;
13 box-shadow: inset 0 -8px 0 0 rgba(0, 0, 0, 0.2), 1px 1px 0 0 deepskyblue, 2px 2px 0 0 deepskyblue, 3px 3px 0 0 deepskyblue, 4px 4px 0 0 deepskyblue, 5px 5px 0 0 deepskyblue, 6px 6px 0 0 deepskyblue, 7px 7px 0 0 deepskyblue,
14 8px 8px 0 0 deepskyblue, 9px 9px 0 0 deepskyblue, 10px 10px 0 0 deepskyblue, 11px 11px 0 0 deepskyblue, 12px 12px 0 0 deepskyblue;
15}
16button:hover {
17 color: #444;
18 box-shadow: inset 0 -4px 0 0 rgba(0, 0, 0, 0.2), 1px 1px 0 0 deepskyblue, 2px 2px 0 0 deepskyblue, 3px 3px 0 0 deepskyblue, 4px 4px 0 0 deepskyblue, 5px 5px 0 0 deepskyblue;
19}
20button:active {
21 color: #222;
22}
23/*其他
24-----------------*/
25a {
26 color: white;
27 text-decoration: none;
28}
29a:hover {
30 text-decoration: underline;
31}
32.ed {
33 padding: 5px;
34 border: 5px white solid;
35 border-radius: 10px;
36}
37input {
38 outline: 0;
39 font-size: 1.5em;
40 font-weight: 600;
41 background: #fff;
42 border: none;
43 box-shadow: inset 0 -4px 0 0 rgba(0, 0, 0, 0.2), 1px 1px 0 0 deepskyblue, 2px 2px 0 0 deepskyblue, 3px 3px 0 0 deepskyblue, 4px 4px 0 0 deepskyblue, 5px 5px 0 0 deepskyblue;
44 margin: 5px;
45 padding: 0.5em;
46 transition: all 0.3s ease-out;
47 box-shadow: inset 0 -8px 0 0 rgba(0, 0, 0, 0.2), 1px 1px 0 0 deepskyblue, 2px 2px 0 0 deepskyblue, 3px 3px 0 0 deepskyblue, 4px 4px 0 0 deepskyblue, 5px 5px 0 0 deepskyblue, 6px 6px 0 0 deepskyblue, 7px 7px 0 0 deepskyblue,
48 8px 8px 0 0 deepskyblue, 9px 9px 0 0 deepskyblue, 10px 10px 0 0 deepskyblue, 11px 11px 0 0 deepskyblue, 12px 12px 0 0 deepskyblue;
49}
50body {
51 background-color: lightskyblue;
52 color: white;
53}
54main {
55 position: relative;
56 margin: auto;
57 width: 100%;
58 height: 100%;
59 text-align: center;
60}
61h1 {
62 margin-bottom: -10px;
63}
64
65table {
66 margin-top: 30px;
67 color: black;
68 border-spacing: 1;
69 border-collapse: collapse;
70 background: white;
71 border-radius: 6px;
72 max-width: 100%;
73 width: 100%;
74}
75table * {
76 position: relative;
77}
78table td,
79table th {
80 padding-left: 8px;
81}
82table thead tr {
83 height: 60px;
84 background: deepskyblue;
85 font-size: 16px;
86}
87table tbody tr {
88 height: 48px;
89 border-bottom: 1px solid #e3f1d5;
90}
這樣就完成囉