前言:
今天我给大家分享的是在我的会议功能实现,其中有两个特色的功能点是:实现会议排座,送审。
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/(这是保存下载图片的位置)
如果在写完保存图片的位置后,出现了这样的错误,可以去查看你自己电脑上是不是没有指定的文件目录。
总结:在会议排座中,比较难的地方在于当我们获取到了请求路径后,该如何去保存到指定的路径。