OA之会议排座与送审

一、会议排座

1、会议排座插件
为了实现会议排座功能,我们需要再网上寻找一个会议排座的插件。可以上百度搜索
在这里插入图片描述
在网上找到的一个插件,但是发现了以下两个问题:
①、发现元素重叠,无法判定有几个人参会 ②、元素块太小看不清

所以我们不能直接使用素材,需要改造以适用于我们的项目
改造后:
在这里插入图片描述
下面展示 源代码

<html>
 
	<head>
 
		<title>会议座位安排</title>
 
		<style type="text/css">
			* {
				padding: 0;
				margin: 0;
			}
 
			.tips {
				/* position: absolute; */
				background: #eee;
				display: inline-block;
				height: 60px;
				width: 60px;
				line-height: 60px;
				text-align: center;
				margin: 5px;
			}
.add {
				position: fixed;
				right: 0;
				top: 0
			}
 
			#tu {
				width: 564px;
				height: 330px;
				background: lightblue
					/*background: url('u=3318199716,2583790385&fm=26&gp=0.jpg');*/
			}
		</style>
		<script src="https://ajax.aspnetcdn.com/ajax/jquery/jquery-3.5.1.min.js"></script>
		<script type="text/javascript" src="http://html2canvas.hertzen.com/dist/html2canvas.js"></script>
	</head>
 
	<body>

 
		<div id="tu"></div>
		<!-- <div class="tips" id="tips1" onmouseover="dragF.drag('tips1');">
			<img src="/images/skinslogo.gif"><br>图片可以拖动</div>
		<div class="tips" id="tips2" onmouseover="dragF.drag('tips2');">座位1
		</div>
		<div class="tips" id="tips3" onmouseover="dragF.drag('tips3');">座位2
		</div> -->
 
		<div class="add">
			<input id="dan_input" type="text" value="">
			<button onclick="return addDanMu()">添加座位</button>
			<input id="jie_input" type="button" value='下载'>
		</div>
 
 
 
	</body>

<script type="text/javascript">
		var $id = function(id) {
			return document.getElementById(id);
		}
 
		var dragF = {
			locked: false,
			lastObj: undefined,
			drag: function(obj) {
				$id(obj).onmousedown = function(e) {
					var e = e ? e : window.event;
					if (!window.event) {
						e.preventDefault();
					} /* 阻止标注<a href='/site/js-5791-1.html' target='_blank'><u>浏览器</u></a>下拖动a,img的默认事件 */
					dragF.locked = true;
					$id(obj).style.position = "absolute";
					$id(obj).style.zIndex = "100";
					if (dragF.lastObj && dragF.lastObj != $id(obj)) { /* 多元素拖动需要恢复上次元素状态 */
						dragF.lastObj.style.zIndex = "1";

	}
 
					dragF.lastObj = $id(obj);
					var tempX = $id(obj).offsetLeft;
					var tempY = $id(obj).offsetTop;
 
					dragF.x = e.clientX;
					dragF.y = e.clientY;
					document.onmousemove = function(e) {
						var e = e ? e : window.event;
						if (dragF.locked == false) return false;
						$id(obj).style.left = tempX + e.clientX - dragF.x + "px";
						$id(obj).style.top = tempY + e.clientY - dragF.y + "px";
						if (window.event) {
							e.returnValue = false;
						} /* 阻止ie下a,img的默认事件 */
 
					}
 
					document.onmouseup = function() {
						dragF.locked = false;
					}
				}
			}
	}
	</script>
	<script>
		function addDanMu() {
			var dan = document.getElementById("dan_input").value;
			if (dan == "") {
				alert("请输入弹幕~");
				return false;
			} else {
				document.getElementById("dan_input").value = ""; //清空 弹幕输入框
				// var br = document.createElement("BR");  // <br />
				var node = document.createElement("DIV"); // <div>
				var tipsArr = document.getElementsByClassName('tips');
				var i;
				// console.log(parseInt(tipsArr[tipsArr.length-1].id.substr(4))+1);
				if (tipsArr.length == 0) {
					i = 1
				} else {
 
					i = parseInt(tipsArr[tipsArr.length - 1].id.substr(4)) + 1;
}
				// var aNode = document.createElement("P");   // <p>
				node.setAttribute("class", "tips");
				node.setAttribute("id", "tips" + i);
				node.setAttribute("onmouseover", "dragF.drag('tips" + i + "');");
				var textnode = document.createTextNode(dan); // 创建个 文本节点, 将用户输入的弹幕,存入 创建的 元素节点 <p>  中
				// aNode.appendChild(textnode);
				node.appendChild(textnode);
				// document.body.appendChild(br);
				// document.body.appendChild(node);
 
				document.getElementById("tu").appendChild(node);
				return true;
			}
 
 
		}
	</script>
<script type="text/javascript">
		$("#jie_input").on("click", function(event) {
			event.preventDefault();
			html2canvas(document.getElementById("tu")).then(function(canvas) {
				var dataUrl = canvas.toDataURL();
				var newImg = document.createElement("img");
				newImg.src = dataUrl;
				// document.body.appendChild(newImg);
				// console.log(dataUrl)
				this.downloadFile('测试.png', dataUrl);
 
			});
		});
 
		//下载
		function downloadFile(fileName, content) {
			debugger;
			let aLink = document.createElement('a');
			let blob = this.base64ToBlob(content); //new Blob([content]);
 
			let evt = document.createEvent("HTMLEvents");
			evt.initEvent("click", true, true); //initEvent 不加后两个参数在FF下会报错  事件类型,是否冒泡,是否阻止浏览器的默认行为
aLink.download = fileName;
			aLink.href = URL.createObjectURL(blob);
 
			// aLink.dispatchEvent(evt);
			//aLink.click()
			aLink.dispatchEvent(new MouseEvent('click', {
				bubbles: true,
				cancelable: true,
				view: window
			})); //兼容火狐
		}
		//base64转blob
		function base64ToBlob(code) {
			let parts = code.split(';base64,');
			let contentType = parts[0].split(':')[1];
			let raw = window.atob(parts[1]);
			let rawLength = raw.length;
 
			let uInt8Array = new Uint8Array(rawLength);
 
			for (let i = 0; i < rawLength; ++i) {
				uInt8Array[i] = raw.charCodeAt(i);
}
			return new Blob([uInt8Array], {
				type: contentType
			});
		}
	</script>
 
</html>


2、将会议排座插件运用到项目中
我们需要将会议排座以html的格式转换为jsp页面,同时当我们点击会议排座时,能够弹出会议排座这个页面
2.1会议排座jsp页面
下面展示一些 会议排座jsp代码

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<base href="${pageContext.request.contextPath }/"/>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<link href="static/js/layui/css/layui.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="static/js/jquery-3.3.1.min.js"></script>
<script type="text/javascript" src="static/js/layui/layui.js"></script>
<script type="text/javascript" src="static/js/plugins/html2canvas/html2canvas.js"></script>
<title>会议座位安排</title>
</head>
<style type="text/css">
* {
	padding: 0;
	margin: 0;
}

body{
	width: 100%;
	height: 100%;
	/* background: red; */
}
 
.tips {
	/* position: absolute; */
	background: pink;
	display: inline-block;
	height: 60px;
	/* width: 60px; */
	line-height: 60px;
	text-align: center;
	margin: 5px;
	padding: 0 10px;
}
 
.add {
	position: fixed;
	right: 10px;
	top: 10px;
	display:inline;
}

#tu {
	width: 100%;
	height: 100%;
	/* background: lightblue; */
		/*background: url('u=3318199716,2583790385&fm=26&gp=0.jpg');*/
}
.layui-input{
	height:30px;
}
</style>
<body id="screen_body">
    <div id="tu"></div>
    <!-- 下面不要使用layui的表单行内模式,会导致canvas的toDataURL()数据为 data:, -->
	<div class="add">
		<div style="display:inline-block;">
			<input id="dan_input" type="text" value="" class="layui-input">
		</div>
		<div style="display:inline-block;">
			<button onclick="return addDanMu()" class="layui-btn layui-btn-sm">添加座位</button><input id="jie_input" type="button" class="layui-btn layui-btn-sm" value='下载'>
		</div>
	</div>
</body>
<script type="text/javascript">
var $id = function(id) {
	return document.getElementById(id);
}
//会议排座拖拽
var dragF = {
	locked: false,
	lastObj: undefined,
	drag: function(obj) {
		$id(obj).onmousedown = function(e) {
			var e = e ? e : window.event;
			if (!window.event) {
				e.preventDefault();
			} /* 阻止标注<a href='/site/js-5791-1.html' target='_blank'><u>浏览器</u></a>下拖动a,img的默认事件 */
			dragF.locked = true;
			$id(obj).style.position = "absolute";
			$id(obj).style.zIndex = "100";
			if (dragF.lastObj && dragF.lastObj != $id(obj)) { /* 多元素拖动需要恢复上次元素状态 */
				dragF.lastObj.style.zIndex = "1";
			}
 
			dragF.lastObj = $id(obj);
			var tempX = $id(obj).offsetLeft;
			var tempY = $id(obj).offsetTop;
dragF.x = e.clientX;
			dragF.y = e.clientY;
			document.onmousemove = function(e) {
				var e = e ? e : window.event;
				if (dragF.locked == false) return false;
				$id(obj).style.left = tempX + e.clientX - dragF.x + "px";
				$id(obj).style.top = tempY + e.clientY - dragF.y + "px";
				if (window.event) {
					e.returnValue = false;
				} /* 阻止ie下a,img的默认事件 */
 
			}
 
			document.onmouseup = function() {
				dragF.locked = false;
			}
		}
	}
}
</script>
 
<script type="text/javascript">
var layer;
layui.use(['layer'],function(){
	layer=layui.layer;
 
    //初始化会议排座:根据会议ID获取参会的所有人员的名字(主持人+参会人+列席人)
	initMeetingUsers();
	
	//绘制会议排座图片
	$("#jie_input").on("click", function(event) {
		$('.add').hide();
		event.preventDefault();
		html2canvas(document.getElementById("screen_body")).then(function(canvas) {
			var dataUrl = canvas.toDataURL();
			console.log(dataUrl);
			var param = {};
			param['seatPic'] = dataUrl;
			param['id'] = '${param.id}';
			param['methodName']='updateSeatPicById';
			console.log(param);
			//此处需要完成会议排座图片上传操作
			$.post('${pageContext.request.contextPath }/info.action',param,function(rs){
				if(rs.success){
					//先得到当前iframe层的索引
					var index = parent.layer.getFrameIndex(window.name); 
					//再执行关闭
					parent.layer.close(index); 
//调用父页面的刷新方法
					parent.query();
				}else{
					layer.msg(rs.msg,{icon:5},function(){});
				}
			},'json');
		});
	});
});
 
function initMeetingUsers(){
	//http://localhost:8080/xxx/seatPic.jsp?id=12  -> ${param.id}
	$.getJSON('${pageContext.request.contextPath }/user.action',{
		'methodName':'queryUserByMeetingId',
		'meetingId':'${param.id}'
	},function(rs){
		console.log(rs);
		let data=rs.data;
		$.each(data,function(i,e){
			$('#dan_input').val(e.name);
			addDanMu();
		});
	});
}

//添加会议排座
function addDanMu() {
	var dan = document.getElementById("dan_input").value;
	if (dan == "") {
		alert("请输入弹幕~");
		return false;
	} else {
		document.getElementById("dan_input").value = ""; //清空 弹幕输入框
		// var br = document.createElement("BR");  // <br />
		var node = document.createElement("DIV"); // <div>
		var tipsArr = document.getElementsByClassName('tips');
		var i;
		// console.log(parseInt(tipsArr[tipsArr.length-1].id.substr(4))+1);
		if (tipsArr.length == 0) {
			i = 1
		} else {
 
			i = parseInt(tipsArr[tipsArr.length - 1].id.substr(4)) + 1;
		}
		// var aNode = document.createElement("P");   // <p>
		node.setAttribute("class", "tips");
node.setAttribute("id", "tips" + i);
		node.setAttribute("onmouseover", "dragF.drag('tips" + i + "');");
		var textnode = document.createTextNode(dan); // 创建个 文本节点, 将用户输入的弹幕,存入 创建的 元素节点 <p>  中
		// aNode.appendChild(textnode);
		node.appendChild(textnode);
		// document.body.appendChild(br);
		// document.body.appendChild(node);
 
		document.getElementById("tu").appendChild(node);
		return true;
	}
}
	</script>
</html>

2.2在我的会议js代码中添加打开会议排座的ajax方法 layer.open

下面展示 会议排座界面.open方法

//打开会议排座对话框
function open(id){
	layer.open({
        type: 2,                    //layer提供了5种层类型。可传入的值有:0(信息框,默认)1(页面层)2(iframe层)3(加载层)4(tips层)
        title: '会议排座',                   //对话框标题
        area: ['460px', '340px'],   //宽高
        skin: 'layui-layer-rim',    //样式类名
        content: $("#ctx").val()+'/jsp/meeting/seatPic.jsp?id='+id,                //弹出内容。可以传入普通的html内容,还可以指定DOM,更可以随着type的不同而不同
    });
}

在这里插入图片描述
3、会议参会用户数据 初始化
现在我们已经成功将插件运用到项目中,但是实际上该会议的参会者数据我们应该拿到并且绑定在会议排座的界面上,然后在拖动元素进行排座。
3.1编写SQL语句
SQL语句对比
在这里插入图片描述
使用函数Find_in_set
在这里插入图片描述
最终sql
在这里插入图片描述
3.2后台编码

下面展示 userDao


public List<User> queryUserByMeetingId(Long meetingId) throws Exception{
		String sql="select * from t_oa_user where FIND_IN_SET(id,"
				+ "(select concat(canyuze,',',liexize,',',zhuchiren) uid "
				+ "from t_oa_meeting_info where id="+meetingId+"))";
		return super.executeQuery(sql, User.class, null);
	}

下面展示 useraction


public String queryUserByMeetingId(HttpServletRequest req,HttpServletResponse resp) throws Exception{
		try {
			String meetingId = req.getParameter("meetingId");
			List<User> users = userDao.queryUserByMeetingId(Long.valueOf(meetingId));
			CommonUtils.toJson(true, users, resp);
		} catch (Exception e) {
			CommonUtils.toJson(false,"获取参会人员信息失败", resp);
			e.printStackTrace();
		}
		return null;
	}

运行结果
在这里插入图片描述
4、生成会议排座图片
4.1meetinginfoDao
下面展示 meetinginfoDao


//	根据会议id更新排座
	public String updateSeatPicById(HttpServletRequest req,
			HttpServletResponse resp) throws Exception{
		try {
			//1.将排座图片保存到指定的位置并得到图片路径
			//1) 定义会议图片的保存路径
			String serverPath=PropertiesUtil.getValue("serverPath");
			String dirPath=PropertiesUtil.getValue("dirPath");
			//2) 定义会议排座图片的名称(最终要保存到数据库表中),例如:/uploads/xxxxx.jpg
			String fileName=UUID.randomUUID().toString().replace("-", "")+".jpg";
			//3) 拼接成完整的路径
			String realPath=dirPath+fileName;
			//4) 将图片保存到指定位置
			Base64ImageUtils.GenerateImage(info.getSeatPic().replace("data:image/png;base64,",""), realPath);
			
			//2.根据会议ID修改会议图片信息
			info.setSeatPic(serverPath+fileName);
			infoDao.updateSeatPicById(info);
			ResponseUtil.writeJson(resp, R.ok(200, "更新会议的排座图片成功"));
		} catch (Exception e) {
			e.printStackTrace();
try {
				ResponseUtil.writeJson(resp, R.error(0, "更新会议的排座图片失败"));
			} catch (Exception e1) {
				e1.printStackTrace();
			}
		}
		return null;
	}

在这里插入图片描述

在这里插入图片描述

二、送审

下面展示 meetinginfoDao


//	根据会议ID更新会议的审批人(送审)
	public int updateAuditorById(MeetingInfo info) throws Exception {
		String sql="update t_oa_meeting_info set auditor=?,state=2 where id=?";
		return super.executeUpdate(sql, info, new String[] {"auditor","id"});
 
 
}

下面展示 meetinginfoAction

//	根据会议ID更新会议的审批人(送审)
	public String updateAuditorById(HttpServletRequest req, HttpServletResponse resp) {
		try {
			int rs = infoDao.updateAuditorById(info);
			if (rs > 0) {
				ResponseUtil.writeJson(resp, R.ok(200, "会议审批成功"));
			}else {
				ResponseUtil.writeJson(resp, R.error(0, "会议审批失败"));
			}
		} catch (Exception e) {
			e.printStackTrace();
			try {
				ResponseUtil.writeJson(resp, R.error(0, "会议审批失败"));
			} catch (Exception e1) {
				e1.printStackTrace();
			}
		}
		return null;
	}

2、前台编码
下面展示 meetinginfo.js

//会议送审
function openLayerAudit(){
	//每次打开都对送审人进行初始化默认值设置
	$('#auditor').val("");
	//必须重新渲染
	form.render('select');
	//弹出对话框
    layer.open({
        type: 1,                    //layer提供了5种层类型。可传入的值有:0(信息框,默认)1(页面层)2(iframe层)3(加载层)4(tips层)
        title:'会议送审',
        area: ['426px', '140px'],   //宽高
        skin: 'layui-layer-rim',    //样式类名
        content: $('#audit'),   //弹出内容。可以传入普通的html内容,还可以指定DOM,更可以随着type的不同而不同
    });
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值