实验室预约二

前一个版本不符合领导要求,和实验室资源没有紧密关联,前一个版本是以时间为事件单位,选择时候后,才去选择实验室以及设备。但实际要求是时间与资源强关联,以资源为限制入口,然后才是时间。 在原有的3张数据表:calendar,lab,dev的基础上进行设计,重点是关于预约区域的设计,由于上个版本使用的fullcalendar是以时间为基础,不适用于此版本,于是我需要另一个能够和设备相关联的日程表,刚好公司OA的会议室预约的是和会议室相关联的,所以决定仿照公司OA的会议室预约来设计,但是由于OA系统是第三方公司开发的,拿不到源码,也就不知道用的插件是什么,所以只能自己琢磨着写了。

日历表设计

本来开始是设计的设备与资源相关联,展示设备每天的每小时的使用情况,但是被否决了,之前写的代码也作废了,那就不浪费时间介绍了,直接介绍最终版吧。 日历表是以设备为基础单位,横坐标表示24小时,竖坐标表示天数。获取该月天数的代码如下:

function getDaysInMonth(year,month){ 
month = parseInt(month,10); 
 var temp = new Date(year,month,0); return temp.getDate();
 }
 //year表示年份,month是月份,可以在进入系统或者选择年月的时候分解,依次传参

根据月份循环天数,输出一个天/时的日历表,每个日历表增加预约点击事件。

设备预约情况展示设计

表格好设计,重点是如何展示清楚的设备的预约情况,开始的时候,我想设计成OA会议室预约那样,该天该时间段内有预约的话,该块颜色就变成绿色,如果有多个,那么该td里面会显示数字表示有几个在改天该时间段内被预约(设备有承载量,可以被预约多次)。但是这样,无法直观展示预约的实际情况,而且对于查看预约的信息,比较麻烦,需要根据时间范围去查,效率比较低,所以比较而言,我又改版设计成类似fullcalendar那样的以div块的形式展示预约情况,详细设计如下:

div绝对定位的相对定位

显示的div块需要横跨td并浮于td上方,需要对div进行定位,div有相对定位和绝对定位两种,相比较而言,相对因为适应性表好点,所以用div相对定位,div的css代码如下:

.calen{
position: absolute;
height:15px; 
font-size:0.8em;
border-radius:4px;
 }
 .clear{clear:both;}//清除浮动带来的布局混乱

预约情况展示

然后是根据获取的时间展示,多说无益,直接上代码:

function resulte(id){
//id值是设备的id值
document.getElementById('chuid').value=id;	
var time=document.getElementById('testt').innerText;
var str=time.split("-");
var year=parseInt(str[0]);
var month=parseInt(str[1]);
var endm=year+"-"+parseInt(month+1);
var a=time.replace(/\-/gi,"/");
var starts=new Date(a).getTime();//月初的时间戳
var b=endm.replace(/\-/gi,"/");
var ends=new Date(b).getTime();//月末的时间戳

var table=document.getElementById('table');
$('#table td').css('background-color','white');
$('.time').html('');
var width=$('#table').width();//获取table calendar的宽度
var vtd=parseFloat(width/25);
var row=table.rows.length;
var cell=table.rows[0].cells.length;
//获取当前时间 去数据库查询当前实验室的当前日期的数据,
//处理,并返回,将数据放在相应地方,改变颜色
$.ajax({
	url:"calendar.php?id="+id+'&start='+time+'&end='+endm,
	type:"POST",
	dataType:'text',
	success:function(result){
	//获取了开始时间为当天的当前实验室的数据
     var str=JSON.parse(result);
	//当前数据是由数组组成的json数据,先转换
	//首先要匹配到table表中的设备,然后再匹配到对应小时时间
	//先循环table,再循环结果	
	for(i=0;i<str.length;i++)
	{
		var eventid=str[i].id;
		var title=str[i].title;
		var color=str[i].color;
		var dev_sty=str[i].dev_sty;
		//获取开始时间戳
		var time=str[i].starttime;
		var times=getLocalTime(time);
		//获取开始时间的小时
		var shour=parseInt(gethour(times))+parseInt(1);
		//获取开始时间天数
		var sday=parseInt(getday(times));
		var etime=str[i].endtime;
		var etimes=getLocalTime(etime);
		//获取结束时间的小时
		var ehour=parseInt(gethour(etimes))+parseInt(1);
		//获取开始时间天数
		var eday=parseInt(getday(etimes));
		//将设备与table表中的设备对应上
	if(sday==eday){//如果是在同一天的话
			var dv=parseInt(ehour-shour);
			var wid=parseFloat(dv*4);
				var dis=document.getElementsByName('dis').length;
				var heig=parseInt(15+3*1);
				//根据时长决定div的长度,开始时是获取table的宽度,然后决定div的宽度
				//但是浏览器缩小后div不变化,所以改成百分比
				var spans='<div name="dis" onclick="showd('+eventid+')" oncontextmenu="details('+eventid+',event)" style="background-color:'+color+';width:'+wid+'%;height:'+heig+'px;color:white;" class="calen">'+eventid+'  '+title+'</div><br class="clear"/>';
				$("#table tr:eq('"+(sday-1)+"') td:eq('"+shour+"')").append(spans);
			    $("#table tr:eq('"+(sday-1)+"') td:eq('"+shour+"')").removeAttr('onclick');	
			}
			else{//如果跨天的话
				var ddv=parseInt(eday-sday);//获取天数差
				//第一天是从开始小时数到结束
				var std=parseInt(25-shour);
				var wid1=parseFloat(4*std);
				var dis1=document.getElementsByName('dis').length;
				var heig1=parseInt(15+3*1);
				var spans1='<div name="dis" onclick="showd('+eventid+')" oncontextmenu="details('+eventid+',event)"style="background-color:'+color+';width:'+wid1+'%;height:'+heig1+'px;color:white;" class="calen">'+eventid+'  '+title+'</div><br class="clear"/>';
				$("#table tr:eq('"+(sday-1)+"') td:eq('"+shour+"')").append(spans1);
				$("#table tr:eq('"+(sday-1)+"') td:eq('"+shour+"')").removeAttr('onclick');	
			//}
			//接下来的n-1是整行都充满颜色
			for(m=0;m<ddv-1;m++){
			var wid2=parseFloat(vtd*24);
				var dis2=document.getElementsByName('dis').length;
				var heig2=parseInt(15+3*1);
				var spans2='<div name="dis"onclick="showd('+eventid+')" oncontextmenu="details('+eventid+',event)" style="background-color:'+color+';width:96%;height:'+heig2+'px;color:white;" class="calen">'+eventid+'  '+title+'</div><br class="clear"/>';
			$("#table tr:eq('"+(sday+m)+"') td:eq(1)").append(spans2);
			$("#table tr:eq('"+(sday-1)+"') td:eq('"+shour+"')").removeAttr('onclick');	
			}
			//最后一天是从0到结束小时
			var etd=parseInt(ehour);
				var wid3=parseFloat(4*(ehour-1));
				var dis3=document.getElementsByName('dis').length;
				var heig3=parseInt(15+3*1);
				var spans3='<div name="dis" onclick="showd('+eventid+')" oncontextmenu="details('+eventid+',event)" style="background-color:'+color+';width:'+wid3+'%;height:'+heig3+'px;color:white;" class="calen">'+eventid+'  '+title+'</div><br class="clear"/>';
				$("#table tr:eq('"+(eday-1)+"') td:eq(1)").append(spans3);
				$("#table tr:eq('"+(sday-1)+"') td:eq('"+shour+"')").removeAttr('onclick');	
			}
		
	}	
	},
	error:function(errMsg){
	alert(errMsg);	
	}
	
});
	
}

预约信息展示

实际展示中,只会显示预约事件的title,需要展示详细信息,鼠标左键有别的用处,所以设计的是点击鼠标右键弹出详细信息,代码如下:

function details(id,e){
 window.event.returnValue = false;//一定要加上这句,不然就会弹出浏览器本身的事件
  var e = e || window.event;
  //鼠标点的坐标
  var oX = e.clientX;
  var oY = e.clientY;
  //菜单出现后的位置
	$.ajax({
		url:"search.php?id="+id+'&action=1',
		type:"POST",
	dataType: 'text',
    error: function(errMsg){    
                 alert('Error loading XML document'); 
                console.log(errMsg);				 
             },    
	success:function(data){
		       var str=JSON.parse(data);
			  
			   var title=str.title;
			   var starttime=str.starttime;
			   var endtime=str.endtime;
			   var lab=str.l_id;
			   var user=str.user;
			   var project=str.project;
			   var remark=str.remark;
			   var start=getLocalTime(starttime);
			   var st=new Date(start).Format("yyyy-MM-dd HH:mm:ss");
			   var end=getLocalTime(endtime);
			   var ed=new Date(end).Format("yyyy-MM-dd HH:mm:ss");
			   document.getElementById('t1').innerHTML=title;
			    document.getElementById('t2').innerHTML=user;
				 document.getElementById('t3').innerHTML=project;
				  document.getElementById('t4').innerHTML=remark;
				   document.getElementById('t5').innerHTML=st;
				    document.getElementById('t6').innerHTML=ed;
			   layer.open({
	            type: 1,
				title:false,
				offset: [oY,oX],
				shadeClose:true,
				closeBtn: 0,
				skin: 'layui-layer-rim', //加上边框
				area: ['300px', 'auto'], //宽高
				content:$("#bes")
				
	              });
	}
		
	});
	
	}

大致的介绍就是这个了,思路设计差不多就是这样,代码太多,不可能全部展示。因为公司网络原因,上传不了网盘,所以源码后面再补。