如何开发课程签到软件:从Web端到微信小程序的完整指南

2025-01-09
来源:网络整理

一、前言

首先,我们来说说您为什么会接触软件编码和开发?这是因为本学期的《软件工程》必修课要求每个小组开发一款软件。我们计划开发的是一个课程登录软件,包括登录、注册、签到、查询、添加、删除、修改等功能。技术方面涉及网页开发、小程序开发和服务器数据库建设。我们主要使用PHP进行网页开发,使用微信开发者工具进行小程序开发。

我负责的是发起登录和扫描二维码登录。即用户在Web端点击发起登录后,Web浏览器显示二维码并动态刷新。同时,手机微信小程序用户可以点击扫码功能进行扫码登录,如果扫码成功,则将登录记录到服务器数据库中。将一条学生签到信息插入记录表中,并在微信小程序弹窗中提示成功信息。

为什么我们需要动态刷新网页浏览器上的二维码?其实就是为了防止“学生在教室拿二维码发给睡在宿舍的室友,让他即使不上课也能逃课”的现象~

2. 带有有效期的二维码

为什么我拍照并发回室友的二维码无效?原因是什么?主要实现思路是在生成的二维码中添加额外的计数信息。当二维码不断刷新时,计数会不断增加。当您拍照并发送给室友时,照片中的二维码将被计算在内。该信息远远滞后于当前计数信息,导致二维码失效,签到失败。

使用库生成二维码(1.php):

include "./phpqrcode/phpqrcode.php"; $numdata = intval($checking_num); $qrdata = intval($checking_id + $numdata*10000); # 合并成一个数据,解码即可获取计数和checking id $level = "L"; # 纠错级别,最多可识别已损失的数据, L--7%,M--15%,Q--25%,H--30% $size = 15; # 二维码尺寸 $margin = 2; # 二维码边缘填充 QRcode::png($qrdata,false,$level,$size,$margin,false);

其中, 是课程签到表的主键,代表某门课程发起签到的ID号。由此,我们可以了解相应时间对应课程的整体课堂签到情况。

二维码信息在函数的第一个参数(任意命名)中,包含两个信息,即计数num和num,对其进行num×+的编码操作,将两个变量合二为一数据并将其插入到二维码中。中,简单解码即可得到 num sum,如:

% = 10()

(-)/=12(数字)

二维码动态刷新(2.php):

<p> <script> function myrefresh() { //window.location.reload(); //只有这句就够了,下一行意思也是定位当前页面 window.location.replace("teacher_make_checking_go.php?class_id="+ echo $class_id;?>+"&checking_id="+ echo $checking_id;?>); } setTimeout('myrefresh()',1000); //指定1秒刷新一次 </script> //展示二维码,并传参数,传入的php可用 GET获取checking_id <img src="teacher_make_checking.php?checking_id=" . $checking_id;?>"> </p>

3. Web客户端和小程序之间共享变量

以上基本说明了带有效期的二维码生成和动态刷新的原理。二维码的有效期只与num和num'有关。当小程序将扫码得到的计数num'上传到服务器时,服务器需要将num'与num进行比较。如果num - num' < 一定范围(几秒,比照片回发时间短),则表示登录成功。

我一开始想到的方法是使用全局变量在不同的PHP之间传递 num,这样就可以比较3.php中小程序上传的num'和num(1.php,2.php.. .参考不同页面)差异,判断是否登录成功。不过我忽略了一个问题:在第一次创建服务端和客户端时,客户端会保存返回给客户端的内容,以便下次请求服务端时,服务端可以根据请求中的信息来确定客户端标头。然而,当小程序请求服务器启动时,又是另外一种情况了。不同之间的变量不共享,因此无法从请求服务器的小程序的php中获取Web客户端当前的num。两者不能相提并论。如下图:

考虑到上述方法中递增的 num无法共享,导致num - num'无法计算的问题,我们需要考虑一种方法,可以将 num变量存储在服务器中,以便不同的客户端可以访问它。 。

于是我决定在Web端刷新二维码、递增num的同时,根据主键将num存储到数据库中。这样,当移动终端扫码上传num'到服务器时,服务器可以读取当前计数num,然后计算num - num'来判断登录是否成功或超时。

访问逻辑如下图所示:

数据库设计如下:

通过扫描小程序中的代码并进行判断来获取数据库中存储的计数num和上传的num'的PHP代码如下。如果签到成功,学生的签到信息会被保存到签到信息表中,并设置发送到小程序中,供小程序中使用。弹窗提示签到结果:

if ($conn->connect_error) { die("Could not connect to database!");} //获取小程序传递数据 $qrdata = intval(isset($_GET['qrdata_send']) ? $_GET['qrdata_send'] : 0); $student_id = intval(isset($_GET['student_id']) ? $_GET['student_id'] : 0); $checking_id = $qrdata % 10000; $num_get = ($qrdata - $checking_id) / 10000; $status = '0'; // 签到成功标志, 1成功,0失败 include "scan_mysql.php"; foreach ($sql_2_presented_result as $row){ $checking_num = $row['checking_num']; } // 保证GET到了数据 if ($qrdata!=0 && $student_id!=0) { if ($checking_num-$num_get<4) { $sql = "INSERT INTO signin_info(checking_id, student_id) value('$checking_id', '$student_id')"; $status = '1'; if (!mysqli_query($conn, $sql)){ die('Error: ' . mysqli_error($con)); $status = '0'; } } } // 关闭连接 $conn->close(); $res['status'] = $status; header("Content-type:application/json"); echo json_encode($res); die();

至此,动态刷新二维码并为每一帧二维码附加有效期的功能就已经成功实现,一定程度上解决了点名费时费力、容易点名的问题。通过扫描二维码伪造正常考勤签到。让大家在宿舍里都睡不好觉了~

如果有更好的解决方案也欢迎指教~

分享