前言
本功能目的是將學生掃碼選座功能作為一個單獨的功能實現,教師不用登陸就可以實現檢視學生選定座位情況,教師又可以登陸繫結課程,統計學生本課程簽到次數。老師不需要繁瑣的註冊登陸就可以實現部分功能,也可以使用本產品建立課程進行繫結,從而利用產品統計學生簽到次數。這將大大增加老師對本產品的體驗,有效增加使用者總數。
本文章具體講學生掃碼功能實現,其他不再具體講述。
前期準備
1.首先將每個教室的每一小節建立一個表,這裡稱作classroom_time
,這些資料應該在增加教室欄位時自動生成,以每天11個小節為例,每個教室生成11個classroom_time欄位,如圖。
2.每個座位應該也要存入一個欄位用於儲存它的行列數,學生id和所對應的classroom_time_id用於儲存它是哪個教室的哪個小節的座位。我們在這裡稱之為seattable,初始為0條資料。
3.再建立一個網頁用於顯示一個classroom_time的座位表
4.每個座位應該對應一個二維條碼,url傳值這個教室id,行列數,同時檢視座位表應該有一個單獨的二維條碼,不用登入直接顯示學生選座情況。
我們學生掃碼功能主要是對seattable表資料進行操作。
學生掃碼功能實現
1.通過url獲取這個座位的基本資訊
通過掃碼所傳入的url,獲取這個座位的行列號,classroom_id,也要通過靜態方法獲取student_id和第幾小節數,小節數這裡稱為time。同時通過第幾小節和教室id查詢唯一一個classroom_time.
public function entercourse() { $id = $this->request->param('id'); $classroom_id = substr($id,0,4)*1; $row = substr($id,4,2)*1; $column = substr($id,6,2)*1; $time = Term::littleClass(); if ($time<=0 || $time>11) { return $this->error('上課時間已結束', url('/index/student/page')); } $student_id = session('studentId'); $classroom_time = Classroom_time::where('classroom_id',$classroom_id)->where('littleclass',$time)->find(); $seattable = Seattable::where('student_id',$student_id)->where('classroom_time_id',$classroom_time->id)->find(); return ; }
這裡獲取第幾小節的同時判斷一下,如果超出十一小節,說明上課時間已結束,返回到學生主頁。
2.通過classroom_time的id和學生id在seattable表裡找有沒有這個欄位,在這裡定義為$seattable
,我們要通過有無$seattable
進行if語句。
$seattable = Seattable::where('student_id',$student_id)->where('classroom_time_id',$classroom_time->id)->find(); // 如果這個學生原來簽過到 if($seattable) { } else { // 如果這個學生原來沒選過座位 } return $this->success('選座成功', url('/index/student/page'));~~~~
這裡舉個例子,學生進入教室就會有一條資料,他選擇座位就會將行列數填入,別人搶了他的位置,將他的行列數清空,相當於他沒做座位,但是還在教室裡,學生id資料存在,這樣有利於老師繫結課程時簽到數加一。
我原來寫的思路是新建資料定死行列數清空學生id,這樣會導致別人搶了他的位置他再次掃碼時無法判斷這是二次掃碼還是第一第掃碼,從而無法正確統計學生簽到總數。
確立定死student_id改變行列值的思路是實現這個功能的關鍵。
3.如果這個學生簽過到
兩種情況,這個座位原來有人,這個座位原來沒人
有人的話先看這個人是不是他自己,是的話直接提示並返回學生主頁,不是的話得到這個座位原來學生的一條資料,通知原來的人有人佔了座位了,將原來的人的行列資料清除,並將這個學生行列數填上。
沒人直接將行列數填上。
$primaryStudent = Seattable::where('row',$row)->where('column',$column)->where('classroom_time_id',$classroom_time->id)->find(); // 如果這個座位原來有學生 if ($primaryStudent) { // 如果這個學生是他自己 if ($primaryStudent->student_id == $student_id) { return $this->error('您已成功掃碼選擇此座位,請不要重複掃碼', url('/index/student/page')); } // 通知他 // 他行列資訊清空 $primaryStudent->row = 100; $primaryStudent->column = 100; if (!$primaryStudent->save()) { return $this->error('資訊儲存異常,請重新掃碼', url('/index/student/page')); } } // 將新的行列數儲存到學生那條資料裡 $seattable->row = $row; $seattable->column = $column; if (!$seattable->save()) { return $this->error('資訊儲存異常,請重新掃碼', url('/index/student/page')); }
舉例:自己(我叫張三)原來掃過碼並且掃碼的座位上有人。
掃碼前
掃碼後
因為後續會用到對行列排序,為了讓清空的行列數不顯示名字,我們這裡將行列重置為100,100(行列最大值)。
4.如果這個學生沒簽過到,也是先判斷這個座位原來是否有人,有人的話先通知他並清空行列數。沒簽過到seattable就不會有對應的student_id和classroom_time_id的資料,這時直接建立一條新的$seattable並將student_id,行列數填上,如果$seattable所對應的classroom_time->status為1(status為1表示已經跟課程繫結,status為0表示沒有跟課程繫結),再進行簽到總數+1.
// 如果這個學生原來沒選過座位 $primaryStudent = Seattable::where('row',$row)->where('column',$column)->where('classroom_time_id',$classroom_time->id)->find(); // 如果這個座位原來有學生 if ($primaryStudent) { // 通知他 // 他行列資訊清空 $primaryStudent->row = 100; $primaryStudent->column = 100; if (!$primaryStudent->save()) { return $this->error('資訊儲存異常,請重新掃碼', url('/index/student/page')); } } // 建立一條新資料 $seattable = new Seattable; $seattable->classroom_time_id = $classroom_time->id; $seattable->row = $row; $seattable->column = $column; $seattable->student_id = $student_id; $seattable->role = 0; if (!$seattable->save()) { return $this->error('資訊儲存異常,請重新掃碼', url('/index/student/page')); } // 如果這個classroom_time的狀態為1,簽到次數加一 if ($classroom_time->status) { $score = Score::where('student_id',$student_id)->where('course_id',$classroom_time->courseinfo->course_id)->find(); if ($score) { // 如果本學生有本課程的一條資料,簽到次數+1 $score->arrivals++; } else { // 如果沒有,新建之 $score = new Score; $score->student_id = $student_id; $score->course_id = $classroom_time->courseinfo->course_id; $score->usual_score = 0; $score->exam_score = 0; $score->total_score = 0; $score->arrivals = 0; $score->respond = 0; $score->arrivals++; } if (!$score->save()) { return $this->error('資訊儲存異常,請重新掃碼', url('/index/student/page')); } }
大家看看思路就好,完整程式碼僅供參考
// 學生掃碼選座位(新中新) public function entercourse() { $id = $this->request->param('id'); $classroom_id = substr($id,0,4)*1; $row = substr($id,4,2)*1; $column = substr($id,6,2)*1; $time = Term::littleClass(); if ($time<=0 || $time>11) { return $this->error('上課時間已結束', url('/index/student/page')); } $student_id = session('studentId'); $classroom_time = Classroom_time::where('classroom_id',$classroom_id)->where('littleclass',$time)->find(); $seattable = Seattable::where('student_id',$student_id)->where('classroom_time_id',$classroom_time->id)->find(); // 如果這個學生原來簽過到 if($seattable) { $primaryStudent = Seattable::where('row',$row)->where('column',$column)->where('classroom_time_id',$classroom_time->id)->find(); // 如果這個座位原來有學生 if ($primaryStudent) { // 如果這個學生是他自己 if ($primaryStudent->student_id == $student_id) { return $this->error('您已成功掃碼選擇此座位,請不要重複掃碼', url('/index/student/page')); } // 通知他 // 他行列資訊清空 $primaryStudent->row = 100; $primaryStudent->column = 100; if (!$primaryStudent->save()) { return $this->error('資訊儲存異常,請重新掃碼', url('/index/student/page')); } } // 將新的行列數儲存到學生那條資料裡 $seattable->row = $row; $seattable->column = $column; if (!$seattable->save()) { return $this->error('資訊儲存異常,請重新掃碼', url('/index/student/page')); } } else { // 如果這個學生原來沒選過座位 $primaryStudent = Seattable::where('row',$row)->where('column',$column)->where('classroom_time_id',$classroom_time->id)->find(); // 如果這個座位原來有學生 if ($primaryStudent) { // 通知他 // 他行列資訊清空 $primaryStudent->row = 100; $primaryStudent->column = 100; if (!$primaryStudent->save()) { return $this->error('資訊儲存異常,請重新掃碼', url('/index/student/page')); } } // 建立一條新資料 $seattable = new Seattable; $seattable->classroom_time_id = $classroom_time->id; $seattable->row = $row; $seattable->column = $column; $seattable->student_id = $student_id; $seattable->role = 0; if (!$seattable->save()) { return $this->error('資訊儲存異常,請重新掃碼', url('/index/student/page')); } // 如果這個classroom_time的狀態為1,簽到次數加一 if ($classroom_time->status) { $score = Score::where('student_id',$student_id)->where('course_id',$classroom_time->courseinfo->course_id)->find(); if ($score) { // 如果本學生有本課程的一條資料,簽到次數+1 $score->arrivals++; } else { // 如果沒有,新建之 $score = new Score; $score->student_id = $student_id; $score->course_id = $classroom_time->courseinfo->course_id; $score->usual_score = 0; $score->exam_score = 0; $score->total_score = 0; $score->arrivals = 0; $score->respond = 0; $score->arrivals++; } if (!$score->save()) { return $this->error('資訊儲存異常,請重新掃碼', url('/index/student/page')); } } } return $this->success('選座成功', url('/index/student/page')); }
這個功能還需要每天定時清除資料,包括全部清除seattable表裡的資料和classroom_time表裡所有status歸0,courseinfo變為null。
總結
寫功能前確定好思路很重要,不然可能會測出漏洞重新寫。