• 会议OA项目之我的会议(会议排座&送审)


    一、会议排座

    1、为什么会有排座功能

    集团公司的日常管理会议、人事任命会议所需
    在参会人员每个人的位置都是不同的,不是随便坐的
    
    • 1
    • 2

    在这里插入图片描述

    2、查找资料

    我们直接通过jquery上查找相关资料,进行修改即可
    第一种:
    在这里插入图片描述
    第二种:
    在这里插入图片描述
    第三种:

    在这里插入图片描述
    从上面比较,第三中比较好,将其修改

    3、配置路径

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    双击进入tomcat,配置
    在这里插入图片描述

    3、后台

    完成会议排座的sql语句:

    -- 第一个参数:数据库列段
    -- 第二个参数:是列段的条件
    SELECT * from t_oa_user where FIND_IN_SET (id,(select CONCAT(canyuze,',',liexize,',',zhuchiren) from t_oa_meeting_info where id = 8))
    
    • 1
    • 2
    • 3

    dao:

    //	设置会议排座图片
    	public int updateSeatPicById(MeetingInfo info) throws Exception {
    		String sql = "update t_oa_meeting_info set seatPic=? where id=?";
    		return super.executeUpdate(sql, info, new String[] {"seatPic","id"});
    	}
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    web:

    public String updateSeatPicById(HttpServletRequest req, HttpServletResponse resp) {
    		/**
    		 * 1、接受前端页面传递到后台的图片对应的字符串
    		 * 2、借助工具类字符串生产一个图片,保存到配置文件所配置的路径下
    		 * 3、添加服务器硬盘与请求地址的映射,即可访问
    		 * 4、将请求地址保存到数据库中
    		 */
    		try {
    //		获取到图片的存放地址
    			String dirPath = PropertiesUtil.getValue("dirPath");
    //		获取浏览器请求路径,为了保存到数据库	serverPath=upload/paizuo/
    			String serverPath = PropertiesUtil.getValue("serverPath");
    			
    //			随机生产一个图片名称
    			String fileName = UUID.randomUUID().toString().replaceAll("-", "") + ".png";
    			info.getSeatPic();//图片字符串
    			Base64ImageUtils.GenerateImage(info.getSeatPic()
    					.replaceAll("data:image/png;base64,", ""), dirPath+fileName);
    
    //			将setPic中的内容改为请求地址
    			info.setSeatPic(serverPath + fileName);
    			
    			//修改会议排座数据库图片对应的数据库列段
    			int rs = infodao.updateSeatPicById(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;
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41

    4、前端

    <%@ 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>
        
    	<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,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");  // 
    var node = document.createElement("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"); //

    node.setAttribute("class", "tips"); node.setAttribute("id", "tips" + i); node.setAttribute("onmouseover", "dragF.drag('tips" + i + "');"); var textnode = document.createTextNode(dan); // 创建个 文本节点, 将用户输入的弹幕,存入 创建的 元素节点

    // aNode.appendChild(textnode); node.appendChild(textnode); // document.body.appendChild(br); // document.body.appendChild(node); document.getElementById("tu").appendChild(node); return true; } } script> html>

    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    • 164
    • 165
    • 166
    • 167
    • 168
    • 169
    • 170
    • 171
    • 172
    • 173
    • 174
    • 175
    • 176
    • 177
    • 178
    • 179
    • 180
    • 181
    • 182
    • 183
    • 184
    • 185
    • 186
    • 187
    • 188
    • 189
    • 190
    • 191
    • 192
    • 193
    • 194
    • 195
    • 196
    • 197
    • 198
    • 199
    • 200
    • 201
    • 202

    Mymeeting.js:

    //打开会议排座对话框
    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的不同而不同
        });
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    调用:
    在这里插入图片描述
    导入下面两个js文件,目录格式如下:
    在这里插入图片描述展示:
    在这里插入图片描述
    在这里插入图片描述点击下载之后,图片会我们配置好的对应的文件夹里面
    在这里插入图片描述

    二、会议送审

    会议送审的效果图:
    在这里插入图片描述
    mymeeting.js:

    let layer,$,table,form;
    var row;
    layui.use(['jquery', 'layer', 'table','form'], function(){
    	layer = layui.layer
    	,$ = layui.jquery
    	,table = layui.table
    	,form = layui.form;
    	//初始化数据表格
    	initTable();
    	//绑定查询按钮的点击事件
    	$('#btn_search').click(function(){
    		query();
    	});
    	
    	initFormSelects();
    	
    	//送审
    	$('#btn_auditor').click(function(){
    		$.post($("#ctx").val()+'/info.action',{
    			'methodName':'updateAuditorById',
    			'id':$('#meetingId').val(),
    			'auditor':$('#auditor').val()
    		},function(rs){
    			if(rs.success){
    				//关闭对话框
    				layer.closeAll();
    				//刷新列表
    				query();
    			}else{
    				layer.msg(rs.msg,{icon:5},function(){});
    			}
    		},'json');
    		return false;
    	});
    });
    
    //1.初始化数据表格
    function initTable(){
    	table.render({           //执行渲染
            elem: '#tb',         //指定原始表格元素选择器(推荐id选择器)
    //        url: 'user.action?methodName=list',     //请求地址
            height: 340,         //自定义高度
            loading: false,      //是否显示加载条(默认 true)
            cols: [[             //设置表头
                {field: 'id', title: '会议编号', width: 120},
                {field: 'title', title: '会议标题', width: 120},
                {field: 'location', title: '会议地点', width: 140},
                {field: 'startTime', title: '开始时间', width: 140},
                {field: 'endTime', title: '结束时间', width: 140},
                {field: 'meetingstate', title: '会议状态', width: 140},
                {field: 'seatPic', title: '会议排座', width: 140,templet: function(d){
                    console.log(d);
                    //得到当前行数据,并拼接成自定义模板
                    return '<img src="'+d.seatPic+'">'
                  }},
                {field: 'auditorname', title: '审批人', width: 140},
                {field: '', title: '操作', width: 220,toolbar:'#tbar'},
            ]]
        });
    	
    	
    	//在页面中的中必须配置lay-filter="tb_goods"属性才能触发属性!!!
    	table.on('tool(tb)', function (obj){
    		row = obj.data;if(obj.event =="seat"){open(row.id);}elseif(obj.event =="send"){//			layer.msg("送审");//			判断是否已经排座if(row.seatPic==null|| row.seatPic==""){
    				  layer.msg('先请完成会议排座,再进行送审操作!',function(){});returnfalse;}//			弹出层中的会议送审人员必须查询出来,后台已经完成,在多功能下拉框中已完成//在打开送审页面之前,先请完成会议ID的赋值操作
    			  $('#meetingId').val(row.id);//			打开会议送审HTML 页面层openLayerAudit();}elseif(obj.event =="del"){
    			
    			layer.msg("取消会议");}elseif(obj.event =="back"){
    			layer.msg("反馈详情");}});}//2.点击查询
    function query(){
    	console.log($("#ctx").val())
    	table.reload('tb',{
            url: 'info.action',//请求地址
            method:'POST',//请求方式,GET或者POST
            loading:true,//是否显示加载条(默认 true)
            page:true,//是否分页
            where:{//设定异步数据接口的额外参数,任意设
            	'methodName':'myInfos','title':$('#title').val(),
            	'zhuchiren':$("#zhuchiren").val()},  
            request:{//自定义分页请求参数名
                pageName:'page',//页码的参数名称,默认:page
                limitName:'rows'//每页数据量的参数名,默认:limit}});}//打开会议排座对话框
    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的不同而不同});}//初始化审批人,绑定数据
    function initFormSelects(){
    	$.getJSON($("#ctx").val()+'/user.action',{
    		'methodName':'queryUserAll'
    	},function(rs){
    		console.log(rs);
    		let data=rs.data;
    		$.each(data,function(i,e){
    			$('#auditor').append(newOption(e.name,e.value));});//重新渲染
    		form.render('select');});}//会议送审
    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的不同而不同});}
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151

    MymeetingDao:

    //	会议送审
    	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"});
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5

    web
    MeetingInfoAction:

    //	会议送审
    	public String updateAuditorById(HttpServletRequest req, HttpServletResponse resp) {
    		try {
    //				rs是sql语句执行的影响行数
    			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;
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    效果展示:
    在这里插入图片描述
    在这里插入图片描述

  • 相关阅读:
    Nginx + keepalived 集群搭建
    136. 只出现一次的数字
    mongoDB如何根据条件分组汇总
    一比一还原axios源码(零)—— 是结束亦是开始
    vision transformer
    算法题常用
    在Linux上安装部署JDK和Tomcat(超级详细)
    java-net-php-python-java沈阳市地铁应急救援管理系统计算机毕业设计程序
    Pandas数据类型-DataFrame之创建和访问
    基于 Java 解释一下硬编码和非硬编码?
  • 原文地址:https://blog.csdn.net/qq_65345936/article/details/125989748