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

目录

前言:

2.我的会议:

2.1实现的特色功能:

 2.2思路:

2.3功能实现:

我的会议页面:myMeeting.jsp

myMeeting.js

Dao方法

在mvc中配置info信息

Meeting InfoAction

2.4会议排座的思路:

具体实现功能:

2.4.1.根据id查看的sql语句:

2.4.2.点击可以有一个弹窗的功能:

myMeeting.js层

弹窗层jsp

2.4.3.将查询的内容显示到页面上:

2.4.4.将已经画好的会议座位图,保存下来:

先分析思路:

4.1当我们的座位调整好了,点击下载,将生成的字符串传递到后台去。

4.2借助我们创建的工具类:propertiesUtil(用于存放路径/请求路径的),使用UUID随机去生成一个存放地址的路径,因为我们保存的路径不能带盘符的,在我们获取了路径上,我们还得写一个修改路径的方法,用于去保存更改的会议地址

4.3保存图片

4.4保存图片的步骤:


前言:

今天我给大家分享的是在我的会议功能实现,其中有两个特色的功能点是:实现会议排座,送审。

2.我的会议:

效果展示:

2.1实现的特色功能:

将不同登录人员看到不同的会议通知,具有会议排座

 2.2思路:

注意:这里我们要对sql语句进行优化:根据主持人,id降序查询

这里需要两张表:info,user表
需求:这里要显示审批人(不为空)新建user表通过字段auditor连接

当会议通知没有审批人时,我们也要显示出来:把会议信息表作为主表,用户表作为从表

 这里我们还要优化:将我们需要显示的字段列出来,
-- 时间的格式化,会议状态将数字转成中文
注意:这里我们时间转换后要起名字,因为我们返回的是map集合

-- 1
-- 根据主持人,id降序查询
-- 这里需要两张表:info,user表
-- 需求:这里要显示审批人(不为空)新建user表通过字段auditor连接
SELECT
	a.*,
	b.NAME zhuchirenname,
	c.NAME auditorname 
FROM
	t_oa_meeting_info a,
	t_oa_user b,
	t_oa_user c 
WHERE
	a.zhuchiren = b.id 
	AND a.auditor = c.id 
ORDER BY
	id DESC -- 	2
SELECT
	a.id,
	a.title,
	a.content,
	a.canyuze,
	a.liexize,
	a.zhuchiren,
	a.location,
	date_format( a.startTime, '%Y-%M-%D %H-%M-%S' )as startTime,
	date_format( a.endTime, '%Y-%M-%D %H-%M-%S' )as endTime,
	a.state,
	(
CASE
	a.state 
	WHEN 0 THEN
	'取消会议' 
	WHEN 1 THEN
	'新建会议' 
	WHEN 2 THEN
	'待审核' 
	WHEN 3 THEN
	'驳回' 
	WHEN 4 THEN
	'代开会议' 
	WHEN 5 THEN
	'进行中' 
	WHEN 6 THEN
	'开启会议' 
	WHEN 7 THEN
	'结束会议' ELSE '其他' 
END 
	) mettingname,
	a.seatPic,
	a.remark,
	a.auditor,
	b.NAME zhuchirenname,
	c.NAME auditorname 
FROM
	t_oa_meeting_info a
	INNER JOIN t_oa_user b ON a.zhuchiren = b.id
	LEFT JOIN t_oa_user c ON a.auditor = c.id 
ORDER BY
	id DESC

--状态:0取消会议 1新建 2待审核 3驳回 4待开 5进行中 6开启投票 7结束会议,默认值为1 

2.3功能实现:

我的会议页面:myMeeting.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<%@include file="/common/header.jsp"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<script type="text/javascript"
	src="static/js/meeting/myMeeting.js"></script>
<title>我的会议</title>
</head>
<style>
body {
	margin: 15px;
}
element.style{
	height:100%;
}
.layui-table-cell {
	height: inherit;
}

.layui-layer-page .layui-layer-content {
	overflow: visible !important;
}
</style>
<body>
	<!-- 搜索栏 -->
	<div class="layui-form-item" style="margin: 15px 0px;">
		<div class="layui-inline">
			<label class="layui-form-label">会议标题</label>
			<div class="layui-input-inline">
				<input type="hidden" id="zhuchiren" value="${user.id }" /> <input
					type="text" id="title" autocomplete="off" class="layui-input">
			</div>
		</div>
		<div class="layui-inline">
			<button id="btn_search" type="button" class="layui-btn">
				<i class="layui-icon layui-icon-search"></i> 查询
			</button>
		</div>
	</div>
	<!-- 数据表格 -->
	<table id="tb" lay-filter="tb" class="layui-table"
		style="margin-top: -15px"></table>
	<!-- 对话框(送审) -->
	<div id="audit" style="display: none;">
		<form style="margin: 20px 15px;" class="layui-form layui-form-pane"
			lay-filter="audit">
			<div class="layui-inline">
				<label class="layui-form-label">送审人</label>
				<div class="layui-input-inline">
					<input type="hidden" id="meetingId" value="" /> <select
						id="auditor" style="poistion: relative; z-index: 1000">
						<option value="">---请选择---</option>
					</select>
				</div>
				<div class="layui-input-inline">
					<button id="btn_auditor" class="layui-btn">送审</button>
				</div>
			</div>
		</form>
	</div>
	<!-- 对话框(反馈详情) -->
	<div id="feedback" style="display: none; padding: 15px;">
		<fieldset class="layui-elem-field layui-field-title">
			<legend>参会人员</legend>
		</fieldset>
		<blockquote class="layui-elem-quote" id="meeting_ok"></blockquote>
		<fieldset class="layui-elem-field layui-field-title">
			<legend>缺席人员</legend>
		</fieldset>
		<blockquote class="layui-elem-quote" id="meeting_no"></blockquote>
		<fieldset class="layui-elem-field layui-field-title">
			<legend>未读人员</legend>
		</fieldset>
		<blockquote class="layui-elem-quote" id="meeting_noread"></blockquote>
	</div>
	<script type="text/html" id="tbar">
  {
   
   {#  if(d.state==1 || d.state==3){ }}
  <a class="layui-btn layui-btn-xs" lay-event="seat">会议排座</a>
  <a class="layui-btn layui-btn-xs" lay-event="send">送审</a>
  <a class="layui-btn layui-btn-danger layui-btn-xs" lay-event="del">删除</a>
  {
   
   {#  } }}
  {
   
   {#  if(d.state!=1 && d.state!=2 && d.state!=3){ }}
  <a class="layui-btn layui-btn-xs" lay-event="back">反馈详情</a>
  {
   
   {#  } }}
</script>
</body>
</html>

myMeeting.js

let layer, table, $, form;
let row;
layui.use([ 'layer', 'table', 'jquery', 'form' ], function() {
	layer = layui.layer, table = layui.table, form = layui.form,
			$ = layui.jquery;

	initTable();

	//查询事件
	$('#btn_search').click(function() {
		query();
	});

});

//1.初始化数据表格
function initTable() {
	table.render({ //执行渲染
		elem : '#tb', //指定原始表格元素选择器(推荐id选择器)
		height : 400, //自定义高度
		loading : false, //是否显示加载条(默认 true)
		cols : [ [ //设置表头
		{
			field : 'id',
			title : '会议编号',
			width : 90
		}, {
			field : 'title',
			title : '会议标题',
			width : 120
		}, {
			field : 'location',
			title : '会议地点',
			width : 140
		}, {
			field : 'startTime',
			title : '开始时间',
			width : 120
		}, {
			field : 'endTime',
			title : '结束时间',
			width : 120
		}, {
			field : 'meetingState',
			title : '会议状态',
			width : 120
		}, {
			field : 'seatPic',
			title : '会议排座',
			width : 120,
			templet : function(d) {
				if (d.seatPic == null || d.seatPic == "")
					return "尚未排座";
				else
					return "<img width='120px' src='" + d.seatPic + "'/>";
			}
		}, {
			field : 'auditName',
			title : '审批人',
			width : 120
		}, {
			field : '',
			title : '操作',
			width : 200,
			toolbar : '#tbar'
		}, ] ]
	});
}

//2.点击查询
function query() {
	table.reload('tb', {
		url : $("#ctx").val() + '/info.action', //请求地址
		method : 'POST', //请求方式,GET或者POST
		loading : true, //是否显示加载条(默认 true)
		page : true, //是否分页
		where : { //设定异步数据接口的额外参数,任意设
			'methodName' : 'myInfos',
			'zhuchiren' : $('#zhuchiren').val(),
			'title' : $('#title').val(),
		},
		request : { //自定义分页请求参数名
			pageName : 'page', //页码的参数名称,默认:page
			limitName : 'rows' //每页数据量的参数名,默认:limit
		},
		done : function(res, curr, count) {
			//console.log(res);
		}
	});

	//工具条事件
	table.on('tool(tb)', function(obj) { //注:tool 是工具条事件名,test 是 table 原始容器的属性 lay-filter="对应的值"
		row = obj.data; //获得当前行数据
		var layEvent = obj.event; //获得 lay-event 对应的值(也可以是表头的 event 参数对应的值)
		var tr = obj.tr; //获得当前行 tr 的 DOM 对象(如果有的话)
		console.log(row);
		console.log("delee"+row.id);
		if (layEvent === 'seat') { //会议排座
			open(row.id);
		} else if (layEvent === 'send') { //送审
			//是否排座了
			if (row.seatPic == null || row.seatPic == "") {
				layer.msg('先请完成会议排座,再进行送审操作!', function() {
				});
				return false;
			}
			//在打开送审页面之前,先请完成会议ID的赋值操作
			$('#meetingId').val(row.id);
			openLayerAudit();
		} else if (layEvent === "del") { //删除
			opendel(row.id);
		} else if (layEvent === "back") { //反馈详情
			openLayerFeedBack(row.id);
		} else {

		}
	});
}

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

	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;
	});

});

//会议送审
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的不同而不同
	});
}



//初始化审批人
function initFormSelects() {
	$.getJSON($("#ctx").val() + '/user.action', {
		'methodName' : 'queryUserAll'
	}, function(rs) {
		let data = rs.data;
		$.each(data, function(i, e) {
			$('#auditor').append(new Option(e.name, e.value));
		});
		//重新渲染
		form.render('select');
	});
}

//删除
function opendel(id) {
	//弹出对话框
	layer.open({
	    type: 1
	    ,title: '删除该会议' //不显示标题栏
	    ,closeBtn: false
	    ,area: '300px;'
	    ,shade: 0.8
	    ,id: 'LAY_layuipro' //设定一个id,防止重复弹出
	    ,btn: ['确定删除','我再想想']
	    ,btnAlign: 'c'
	    ,moveType: 1 //拖拽模式,0或者1
	    ,content: '<div style="padding: 50px; line-height: 22px; background-color: #393D49; color: #fff; font-weight: 300;">确定删除该会议?</div>'
	    ,yes:function(index,layero){
        	//调用子页面中提供的getData方法,快速获取子页面的form表单数据
            addMeetingFeedBack(id);
            layer.msg('删除成功');
          //关闭对话框
			layer.closeAll();
			//刷新列表
			query();
        },
        btn2:function(){
        	layer.closeAll();
        }
	  });
}

//对会议通知确定删除的
function addMeetingFeedBack(id){
	$.post($("#ctx").val() + '/info.action', {
		'methodName' : 'delnotesById',
		'id' : id,
	}, function(rs) {
		if (rs.success) {
			//关闭对话框
			layer.closeAll();
			//刷新列表
			query();
		} else {
			layer.msg(rs.msg, {
				icon : 5
			}, function() {
			});
		}
	}, 'json');
	return false;
}

//反馈详情
function openLayerFeedBack(id) {

	$.getJSON('feedBack.action',{
		methodName:'queryMeetingBackByMeetingId',
            meetingId:id
	},function(data){
		$('#meeting_ok').html("");
		$('#meeting_no').html("");
		$('#meeting_noread').html("");
		if(data.success){
			console.log(data.data);
			$.each(data.data,function(i,e){
				if(e.result==1)
					$('#meeting_ok').html(e.names);
				else if(e.result==2)
					$('#meeting_no').html(e.names);
				else
					$('#meeting_noread').html(e.names);
			});
			//弹出对话框
		    layer.open({
		        type: 1,                    //layer提供了5种层类型。可传入的值有:0(信息框,默认)1(页面层)2(iframe层)3(加载层)4(tips层)
		        title:'反馈详情',
		        area: ['426px', '420px'],   //宽高
		        skin: 'layui-layer-rim',    //样式类名
		        content: $('#feedback'),   //弹出内容。可以传入普通的html内容,还可以指定DOM,更可以随着type的不同而不同
		        btn:['关闭'],
		        yes:function(index,layero){
		        	layer.closeAll();
		        }
		    });
		}
	});
	}

Dao方法


	/**
	 * 显示我的会议
	 * 
	 * @param meetingInfo
	 * @param pageBean
	 * @return
	 * @throws Exception
	 */
	private String getSQL() {
		return "SELECT a.id,a.title,a.content,a.canyuze,a.liexize,a.zhuchiren,b.`name`,a.location\r\n"
				+ ",DATE_FORMAT(a.startTime,'%Y-%m-%d %H:%i:%s') as startTime\r\n"
				+ ",DATE_FORMAT(a.endTime,'%Y-%m-%d %H:%i:%s') as endTime\r\n" + ",a.state\r\n" + ",(case a.state\r\n"
				+ "when 0 then '取消会议'\r\n" + "when 1 then '新建'\r\n" + "when 2 then '待审核'\r\n" + "when 3 then '驳回'\r\n"
				+ "when 4 then '待开'\r\n" + "when 5 then '进行中'\r\n" + "when 6 then '开启投票'\r\n" + "else '结束会' end\r\n"
				+ ") as meetingState\r\n" + ",a.seatPic,a.remark,a.auditor,c.`name` as auditorName\r\n"
				+ "FROM t_oa_meeting_info a\r\n" + "inner join t_oa_user b on a.zhuchiren = b.id\r\n"
				+ "left JOIN t_oa_user c on a.auditor = c.id where 1=1 ";
	}
	/*
	 * 带条件的查询
	 * 
	 */

	public List<Map<String, Object>> myInfos(MeetingInfo info, PageBean pageBean) throws Exception {
		String sql = getSQL();
		String title = info.getTitle();
		if (StringUtils.isNotBlank(title)) {
			sql += " and title like '%" + title + "%'";
		}
		// 根据当前登陆用户ID作为主持人字段的条件
		if (StringUtils.isNotBlank(info.getZhuchiren())) {
			sql += " and zhuchiren=" + info.getZhuchiren();
		}
		// 按照会议ID降序排序
		sql += " order by a.id desc";
		return super.executeQuery(sql, pageBean);
	}

在mvc中配置info信息

	<action path="/info" type="com.lya.web.MeetingInfoAction">
	</action>

Meeting InfoAction

	@Override
	public MeetingInfo getModel() {
		// 注册一个转接器(用于时间date类型转页面显示)
//		ConvertUtils.register(new MysqlxDatatypes, Date.class);
		return info;
	}
//查看我的会议
	public String myInfos(HttpServletRequest req, HttpServletResponse resp) {
		try {
			PageBean pageBean = new PageBean();
			pageBean.setRequest(req);
			List<Map<String, Object>> infos = meetingInfoDao.myInfos(info, pageBean);
			ResponseUtil.writeJson(resp, R.ok(0, "我的会议查询成功!!!", pageBean.getTotal(), infos));
		} catch (Exception e) {
			e.printStackTrace();
			try {
				ResponseUtil.writeJson(resp, R.error(0, "我的会议查询失败!!!"));
			} catch (Exception e1) {
				e1.printStackTrace();
			}
		}
		return null;
	}

/**
	 * 会议排座
	 * 下载图片
	 * 
	 * @param req
	 * @param resp
	 * @throws Exception 
	 */
	public void updateSeatPicById(HttpServletRequest req, HttpServletResponse resp) throws Exception {
		// 1.接收图片存放的地址(字符串)
		// 2.生成图片,放到指定的路径下
		// 3.添加服务器
		// 4.将地址保存至数据库中
		// dirPath=E:/temp/images/t_oao/(这是保存下载图片的位置)

		// 1.接收图片存放的地址(字符串)
		String dirPath = PropertiesUtil.getValue("dirPath");// dirPath=E:/temp/images/t_oao/(这是保存下载图片的位置)

		// 接收浏览器请求的地址➡用于保存到数据库中
		String serverPath = PropertiesUtil.getValue("serverPath");

		// 保存图片前先去设置一个随机的路径字符将-换成空的因为这里我们保存路径是连着的
		String savepic = UUID.randomUUID().toString().replaceAll("-", "") + ".png";

		// 2.调用无参获取当前的保存的地址
		//info.getSeatPic();
		
		// 3.图片转换工具Baseutil中的generataImage并且重新保存路径
		Base64ImageUtils.GenerateImage(info.getSeatPic().toString().replaceAll("data:image/png;base64,", ""), dirPath+savepic);
		// 调用无参去重新保存的地址
		info.setSeatPic(serverPath+savepic);
		
		// 4.将地址保存至数据库中修改对应的字段
			int rs = meetingInfoDao.updateSeatPicById(info);
			if (rs > 0) {
				ResponseUtil.writeJson(resp, R.ok(200, "会议图片保存成功"));
			} else {
				ResponseUtil.writeJson(resp, R.error(0, "会议图片保存失败"));
			}
	}
	

2.4会议排座的思路:

1.查询出本场会议中的所有参与人员
2.需要完成在页面上元素的拖动功能,把对应的参会人员放在指定位置,如:重要的人就放在主位
3.将已经画好的会议座位图,保存下来,并且绑定到本次会议数据上去;
代码的实现顺序是2、1、3

2.页面上元素的拖动功能(特殊的功能)
    出发点:可以自己写、网上会有素材(在网上找到50%相似的资源。改成与业务相关的模板。)
    流程:先找网上素材,改动素材中的源码,变为自己想要的
    1.找网上素材,多找几个,挑出一个最适合的
    2.分析现有素材的不足
        ①、发现元素重叠,无法判定有几个人参会
        ②、元素块太小看不清
    3.修改现有素材的不足
    4.分析现有素材,怎么与业务需求进行关联(最重要的一步)
        其实需要做的是,查看源代码,分析图片生成的原因/步骤
        下载 按钮是绑定了一个方法,这个主要的方法是downloadFile方法
        downloadFile方法有两个参数:FileName、content,接下就是思考哪个参数与图片有关系
        结论:通过分析downloadFile方法中content参数就代表了那张图片-前端

        5.content需要传递到后台,并且生成图片,只有这样,我们才能通过代码决定图片存放在哪里
        ①、怎么传后台-$.post
            $.get(不行的,因为参数太大)    错
        ②、String content 字符串要转换成图片

具体实现功能:

2.4.1.根据id查看的sql语句:

SELECT * FROM t_oa_user where FIND_IN_SET(id,(SELECT CONCAT(canyuze,',',liexize,',',zhuchiren) uid FROM t_oa_meeting_info where id = 4))
	

2.4.2.点击可以有一个弹窗的功能:

myMeeting.js层

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

弹窗层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.4.3.将查询的内容显示到页面上:

3.1当我们弹出窗口时,我们通过初始化页面内容的ajax发送请求到user.action

 这里我们的数据还是未显示出来:通过开发者工具得到问题:

我们导入jquery插件,html的js就可以解决了

2.4.4.将已经画好的会议座位图,保存下来:

先分析思路:

1.当我们的座位调整好了,点击下载,将生成的字符串传递到后台去。

2.我们使用后台工具将得到的字符串生成一张图片,保存到指定的文件夹中。

3.添加服务器,硬盘,请求路径的映射,访问

4.将地址保存至数据库中

4.1当我们的座位调整好了,点击下载,将生成的字符串传递到后台去。

4.2借助我们创建的工具类:propertiesUtil(用于存放路径/请求路径的),使用UUID随机去生成一个存放地址的路径,因为我们保存的路径不能带盘符的,在我们获取了路径上,我们还得写一个修改路径的方法,用于去保存更改的会议地址

4.3保存图片

我们从前台获取到的数据是这样的

data:image/png;base64,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

4.4保存图片的步骤:

    // 1.接收图片存放的地址(字符串)
    // 2.生成图片,放到指定的路径下
    // 3.添加服务器
    // 4.将地址保存至数据库中
    // dirPath=E:/temp/images/T280/(这是保存下载图片的位置)

如果在写完保存图片的位置后,出现了这样的错误,可以去查看你自己电脑上是不是没有指定的文件目录。

总结:在会议排座中,比较难的地方在于当我们获取到了请求路径后,该如何去保存到指定的路径。

猜你喜欢

转载自blog.csdn.net/m0_73647713/article/details/131987715
今日推荐