目录
前言:
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、32.页面上元素的拖动功能(特殊的功能)
出发点:可以自己写、网上会有素材(在网上找到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/(这是保存下载图片的位置)
如果在写完保存图片的位置后,出现了这样的错误,可以去查看你自己电脑上是不是没有指定的文件目录。
总结:在会议排座中,比较难的地方在于当我们获取到了请求路径后,该如何去保存到指定的路径。