说起刷卡操作或者是扫描器扫描二维码,我们平时接触最多的可能是桌面软件客户端,随着B/S架构的不断完善以及网站系统的技术成熟,目前很多系统像是ERP/OA都是基于网站系统进行开发的,因此在有事情况下不可避免的要接触到刷卡或者是扫描器的操作。

2

刷卡机或者是扫描器说白了就是以某种形式读出一串有用的数字而已,再根据这个数字进行相关的操作,之前参与的一个ERP系统是生成了条形码通过扫描器扫描自动确认货物进入仓库,另外barberShopUMS-理发店会员提成解决方案是进行的刷卡操作,今天做学院科创管理系统的讲座人数确认情况时也用到了刷卡机。

1

描述:

之前讲座系统是报名后,学生通过参加讲座现场签到,根据签到,整理成txt文档,进行php的读取和逐步认证或者是签到后,根据签到名字逐个查找签到,无论是哪种方式,某种程度上,对于讲座管理人员都是比较麻烦的。

 

3

根据上述情况,结合同学使用的校园卡,进行刷卡认证参加讲座

问题:

刷卡要解决的问题不是特别麻烦,首先是机器,这一点倒也不是很麻烦,能读出学号这一串数字就足够了,别的也不需要。

其次是代码的部分:

1、保证刷卡的人都是报名的人,未报名不允许刷卡。

2、保证能够根据刷卡自动增加表单,不需要手动去增加。

3、能够判断刷卡是否重复,剔除重复。

4、一键验证。

实现:

:系统使用ThinkPHP开发。

已经写好的html代码如下所示:

其中,每次增加都是增加一个<tr>,而每个<td>?id 实际上是不同的,同时使用oninput="listenUnum(this);" onpropertychange="listenUnum(this);来实时监听,防止误刷。(当前系统卡号是9位),刷卡号,姓名自动识别 ?readonly

form提交的时候使用的是stunum[]stuname[]数组的形式,因此增加多少input都无所谓。

ja5

每个input的id是唯一标示,将通过代码累加计数的方式进行操作,如果不符合刷卡的要求,就将当前的input的值全部置空,再次进行刷卡即可。

< tr class="card-tr-1" guid="1" >
 < td >< input type="text" class="form-control" name="stunum[]" id="unum-1" placeholder="学号....." oninput="listenUnum(this);" onpropertychange="listenUnum(this);">< /td >
 < td >< input type="text" class="form-control" name="stuname[]" id="uname-1"placeholder="姓名自动识别....."readonly="readonly" value=""> < /td >
 < /tr >

postbird

 

1、页面初始化,使用ajax请求数据,获取所有报名的人员名单,这里使用了同步加载,因为绑定到js的全局变量只能进行同步(使用了函数返回)。

 

ja6

function getInfo(){
			var tstu;
			$.ajax({
				url:u+"/view/"+view,
				async:false,
				success:function(data){
					if(data.status=="ok"){
						tstu=data.stu;
						return tstu;
					}else{
						alert("加载失败,重新加载");
						window.reaload();
						return ;
					}
				}
			});
			return tstu;
		}

2、页面初始化,自动获得焦点。而且每次增加新的input的时候,都需要自动获得焦点。

ja7

$("document").ready(function(){
	stu=getInfo();
	if(stu.length>0){
		$("#ltitle").text(stu[0].lecture_title);
			alert("成功获取用户数据,正常刷卡操作");
		}else{
			alert("获取用户数据失败,重新获取");
			window.reaload();
		}
		$("#unum-1").focus();
	});

 

3、每次刷入卡号,都会进行验证,也就是前面提到的实时监听,而实时监听的时候是需要两步验证的。

实时监听主要做两个操作:

1)检查卡号是否在前面通过ajax请求的数组中

2)将刷入的卡号重新记录在另一个数组中。

其中第1)个操作主要是为了只有报名的人才能参加讲座,并进行签到获得讲座单,第2)个操作是为了防止多次刷了一张卡。

 

ja8

 

ja9

//每次输入检查卡号
		//如果返回的是数组 证明可以操作
		//返回0 代表没有报名
		//返回1 代表已经刷过卡了
		function checkUnum(unum){
			for(var i=0;i<stu.length;i++){
				if(stu[i].user_num==unum){
					//如果验证没有刷过,则保存在验证的数组中
					if(checkAlready(unum)==0){
						alArr[alArrCount]=stu[i];//保存
						alArrCount++;
						return stu[i];//正常
					}else{
						return 1;//已经刷过卡
					}
				}else{
					continue;
				}
			}
			return 0;//不存在
		}
		//每次检查是否已经刷过该卡。
		// 返回1 表示已经刷过 也就是数组中存了
		// 0 表示没有
		function checkAlready(unum){
			for(var i=0;i<alArr.length;i++){
				if(alArr[i].user_num==unum){
					return 1;//刷过卡了
				}else{
					continue;
				}
			}
			return 0; //没有刷过
		}

4、如果上面两次验证都能通过,说明这个号码是有效的,因此自动增加一行input,不过id是需要变化的。

ja10


// 实时监听
function listenUnum(obj){
	var inp=$(obj);//获得对象
	var tmpValue=inp.val().replace(" ","");//将空格替换掉
	if(tmpValue.length==9){//判断卡号长度
		var tmp=checkUnum(tmpValue);//进行卡号检测主要检测是否参加和是否刷过
		//返回0表示不在ajax请求的对象中
		if(tmp==0){
			alert("未报名!");
			inp.val("");
			inp.focus();
		//1表示刚才已经刷过卡了,也就是在另一个数组中已经存了
		}else if(tmp==1){
			alert("已经刷过卡!");
			inp.val("");
			inp.focus();
		}else{//如果验证都能通过,那么久需要增加一行input
			//首先需要将姓名输出到input中,这个是自动是别的。
			$("#uname-"+inpCount).val(tmp['user_name']);
			//其次id值需要变化,从1开始,因此inpCount++控制di值
			inpCount++;
			//增加一个 tr 标签,里面唯一的区别就是id值变换了
			var htm='< tr class="card-tr-'+inpCount+'" guid="'+inpCount+'">';
			htm+='< td >< input type="text" class="form-control" name="unum[]" id="unum-'+inpCount+'" placeholder="学号....." oninput="listenUnum(this);" onpropertychange="listenUnum(this);" >< /td >';

			htm+='< td >< input type="text" class="form-control" name="uname[]" id="uname-'+inpCount+'" placeholder="姓名自动识别....."readonly="readonly" value="">< /td >'
			htm+='< /tr >';
				//在tbody中追加html
	 		$(".card-body").append(htm);
	 		//增加后自动获得焦点
	 		$("#unum-"+inpCount).focus();
		}
	}
}
本篇文章完整代码示例请访问:https://git.oschina.net/postbird/codes/vechsm2fj9x1kzurp6byn55

(不知道为什么,git@osc的代码片段html没有下面的滚动条。。。)