前言
本功能目的是將學生掃碼選座功能作為一個單獨的功能實現,教師不用登陸就可以實現查看學生選定座位情況,教師又可以登陸綁定課程,統計學生本課程簽到次數。老師不需要繁瑣的注冊登陸就可以實現部分功能,也可以使用本產品建立課程進行綁定,從而利用產品統計學生簽到次數。這將大大增加老師對本產品的體驗,有效增加用戶總數。
本文章具體講學生掃碼功能實現,其他不再具體講述。
前期準備
1.首先將每個教室的每一小節建立一個表,這里稱作classroom_time,這些數據應該在增加教室字段時自動生成,以每天11個小節為例,每個教室生成11個classroom_time字段,如圖。
2.每個座位應該也要存入一個字段用于保存它的行列數,學生id和所對應的classroom_time_id用于保存它是哪個教室的哪個小節的座位。我們在這里稱之為seattable,初始為0條數據。
3.再建立一個網頁用于顯示一個classroom_time的座位表
4.每個座位應該對應一個二維碼,url傳值這個教室id,行列數,同時查看座位表應該有一個單獨的二維碼,不用登錄直接顯示學生選座情況。
立即學習“PHP免費學習筆記(深入)”;
我們學生掃碼功能主要是對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。
總結
寫功能前確定好思路很重要,不然可能會測出漏洞重新寫。
推薦:《最新的10個thinkphp視頻教程》