会议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连接
SELECTa.*,b.NAME zhuchirenname,c.NAME auditorname
FROMt_oa_meeting_info a,t_oa_user b,t_oa_user c
WHEREa.zhuchiren = b.id AND a.auditor = c.id
ORDER BYid DESC -- 2
SELECTa.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,(
CASEa.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
FROMt_oa_meeting_info aINNER JOIN t_oa_user b ON a.zhuchiren = b.idLEFT JOIN t_oa_user c ON a.auditor = c.id
ORDER BYid 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 }" /> <inputtype="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="" /> <selectid="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 "尚未排座";elsereturn "<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或者POSTloading : true, //是否显示加载条(默认 true)page : true, //是否分页where : { //设定异步数据接口的额外参数,任意设'methodName' : 'myInfos','zhuchiren' : $('#zhuchiren').val(),'title' : $('#title').val(),},request : { //自定义分页请求参数名pageName : 'page', //页码的参数名称,默认:pagelimitName : '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
@Overridepublic 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/(这是保存下载图片的位置)
如果在写完保存图片的位置后,出现了这样的错误,可以去查看你自己电脑上是不是没有指定的文件目录。
总结:在会议排座中,比较难的地方在于当我们获取到了请求路径后,该如何去保存到指定的路径。
会议OA之我的会议(会议排座送审)相关推荐
- 会议OA项目(三)---我的会议(会议排座、送审)
目录 前言 一.需求分析 二.准备工作 三.编码 1.后台编码 2.前端编码 四.效果展示 前言 上篇分享了会议OA项目的我的会议功能的查询.取消会议.本篇文章将完善我的会议功能. 我的会议功能有一个 ...
- 会议OA之会议排座送审
目录 最近这段时间一直都在与大家分享会议OA项目,今天继续分享关于会议OA项目的一个亮点功能,会议排座.以及一个送审功能. 一.会议排座 二.送审 最近这段时间一直都在与大家分享会议OA项目,今天继续 ...
- 会议OA项目(我的会议中的会议排座送审功能)
文章目录 一.会议排座插件介绍 1)会议项目为什么要有会议排座的功能 2)完成在页面上元素的拖动功能 2.1分析现有素材的不足 2.2修改现有素材的不足⬇⬇⬇ 2.3 content需要传递到后台,并 ...
- OA之我的会议(会议排座送审)
目录 一.会议排座插件介绍 需求背景: 1.实现思路: 2.明确了开发会议排座的意义 1.查询出本场会议中的所有参与人员2.需要完成在页面上元素的拖动功能,把对应的参会人员放在指定位置,如:重要的人就 ...
- 会议OA(会议排座送审)
目录 一,会议排座 二,会议送审 一,会议排座 分析: 1. 查找资料 做选择,哪一个素材更适合完成需求 2. 素材改造 素材的缺陷: ①:样式:座位小方块重叠/太小 ...
- 会议OA之我的会议(排座送审)
目录 一.排座 后台代码 dao方法 web层 js代码 配置文件 前端代码 二.送审 后台代码 dao方法 web层 js代码 一.排座 实现思路 1.查询出本场会议中的所有参与人员 2.需要完成在 ...
- LayUi——OA项目 03(会议排座送审)
目录 一.后端 1.MeetingInfoDao 2.MeetingInfoAction 3.配置文件和服务器 二.前端 1.myMeeting.js 2.seatPic.jsp 3.myMeetin ...
- 会议OA项目之我的会议(会议排座送审)
目录 一.会议排座 1.为什么会有排座功能 2.查找资料 3.配置路径 3.后台 4.前端 二.会议送审 一.会议排座 1.为什么会有排座功能 集团公司的日常管理会议.人事任命会议所需 在参会人员每个 ...
- 会议OA项目之待开会议所有会议
目录 一.待开和所有会议SQL语句编 二.待开和所有会议功能实现 1.待开会议 后台 前台 2.所有会议 后台 前台 一.待开和所有会议SQL语句编写 1.待开会议 待开会议: 与我的会议的区别在于, ...
最新文章
- 深度解析HashMap
- prometheus+node_exporter+grafana实践
- HDU5514 Frogs
- 执行计划中cpu耗时_面试被问怎么排查遇到的系统CPU飙高和频繁GC,到底该怎么回答?...
- uni-app完整实现小程序获取用户信息
- 菜鸟安装linux虚拟机
- 关于人工智能数据标注学习
- 计算机网络 | 划分子网
- 手机UC浏览器导出书签到电脑Chrome浏览器中
- 【C语言练习——打印空心上三角及其变形】
- 基于微信的分布式系统分析
- VS2017中处理命令行参数的方法----C++语言 Windows系统
- 在win10查看本机linux的文件,Windows 10变身开发者利器:内置Linux内核,轻松查看Linux子系统文件...
- Luogu P4844 LJJ爱数数
- 卷积层和全连接层的区别_CNN卷积层、全连接层的参数量、计算量
- 如何将源生DrawerLayout满屏显示只覆盖ActionBar
- 技巧】利用chromg浏览器自动翻译外文网页的设置方法---电脑版
- 常见图形,圆形、长方形和正方形面积的计算
- 【链表】C++链表反转、链表逆序打印
- php homebrew源少,修改homebrew源解决下载速度慢的问题
热门文章
- 1500多名开发者集体提起诉讼,苹果公司回应:不垄断,还提供价值
- 五、MT8168 音频驱动之SPEAKER
- Python学习:自定义函数,不可或缺
- QoS配置实例——标记和限速
- linux sudo -i 参数,Linux系统中su、sudo、sudo su、sudo -i命令的用法和区别小结
- c语言字符函数isalpha,总结C语言字符检测函数:isalnum、isalpha...
- N32G430学习笔记12-定时器的基本使用
- Oracle Spacial(空间数据库)sdo_Geom包的函数
- 计算机科普知识英文,电脑使用小常识(国外英语资料).doc
- hive 格式化:Error: Table ‘CTLGS‘ already exists (state=42S01,code=1050) Closing: 0: jdbc:mysql://hadoop