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


    目录

    一、排座

    后台代码

    dao方法

    web层 

    js代码 

    配置文件 

    前端代码

    二、送审

    后台代码

    dao方法

    web层

    js代码


    一、排座

    实现思路

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

    后台代码

    dao方法

    userDao.java

    1. public List queryUserByMeetingId(Long meetingId) throws Exception{
    2. String sql="select * from t_oa_user where FIND_IN_SET(id,"
    3. + "(select concat(canyuze,',',liexize,',',zhuchiren) "
    4. + "from t_oa_meeting_info where id="+meetingId+"))";
    5. return super.executeQuery(sql, User.class, null);
    6. }

    web层 

    userAction.java

    1. // 获取排座用户数据
    2. public String queryUserByMeetingId(HttpServletRequest req, HttpServletResponse resp) {
    3. try {
    4. Long meetingId = Long.parseLong(req.getParameter("meetingId"));
    5. List users = userdao.queryUserByMeetingId(meetingId);
    6. ResponseUtil.writeJson(resp, R.ok(200, "获取排座用户数据成功!!!", users));
    7. } catch (Exception e) {
    8. e.printStackTrace();
    9. try {
    10. ResponseUtil.writeJson(resp, R.error(0, "获取排座用户数据失败!!!"));
    11. } catch (Exception e1) {
    12. e1.printStackTrace();
    13. }
    14. }
    15. return null;
    16. }

    MeetingInfoAction.java 

    1. package com.maomao.web;
    2. import java.io.IOException;
    3. import java.util.Date;
    4. import java.util.List;
    5. import java.util.Map;
    6. import java.util.UUID;
    7. import javax.servlet.ServletException;
    8. import javax.servlet.http.HttpServletRequest;
    9. import javax.servlet.http.HttpServletResponse;
    10. import org.apache.commons.beanutils.ConvertUtils;
    11. import com.maomao.dao.MeetingInfoDao;
    12. import com.maomao.entity.MeetingInfo;
    13. import com.zking.framework.ActionSupport;
    14. import com.zking.framework.ModelDriver;
    15. import com.zking.util.Base64ImageUtils;
    16. import com.zking.util.MyDateConverter;
    17. import com.zking.util.PageBean;
    18. import com.zking.util.PropertiesUtil;
    19. import com.zking.util.R;
    20. import com.zking.util.ResponseUtil;
    21. public class MeetingInfoAction extends ActionSupport implements ModelDriver{
    22. private MeetingInfo info = new MeetingInfo();
    23. private MeetingInfoDao meetingInfoDao = new MeetingInfoDao();
    24. @Override
    25. public MeetingInfo getModel() {
    26. //方式二:
    27. ConvertUtils.register(new MyDateConverter(),Date.class);
    28. return info;
    29. }
    30. // 根据会议ID更新会议的排座图片
    31. public String updateSeatPicById(HttpServletRequest req,
    32. HttpServletResponse resp) throws ServletException,IOException{
    33. try {
    34. //1.将排座图片保存到指定的位置并得到图片路径
    35. //1) 定义会议图片的保存路径
    36. String serverPath=PropertiesUtil.getValue("serverPath");
    37. String dirPath=PropertiesUtil.getValue("dirPath");
    38. //2) 定义会议排座图片的名称(最终要保存到数据库表中),例如:/uploads/xxxxx.jpg
    39. String fileName=UUID.randomUUID().toString().replace("-", "")+".jpg";
    40. //3) 拼接成完整的路径
    41. String realPath=dirPath+fileName;
    42. //4) 将图片保存到指定位置
    43. Base64ImageUtils.GenerateImage(info.getSeatPic().replace("data:image/png;base64,",""), realPath);
    44. //2.根据会议ID修改会议图片信息
    45. info.setSeatPic(serverPath+fileName);
    46. meetingInfoDao.updateSeatPicById(info);
    47. ResponseUtil.writeJson(resp, R.ok(200, "更新会议的排座图片成功"));
    48. } catch (Exception e) {
    49. e.printStackTrace();
    50. try {
    51. ResponseUtil.writeJson(resp, R.error(0, "更新会议的排座图片失败"));
    52. } catch (Exception e1) {
    53. e1.printStackTrace();
    54. }
    55. }
    56. return null;
    57. }
    58. }

    js代码 

    meeting.js

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

    配置文件 

    建一个配置文件以properties为后缀的文件

    1.在这里的E盘是本人的保存排座的路径,可以自己修改;
    2.该配置文件要放在根目录,并在server里进行配置

    1. dirPath=E:/temp/images/T280/
    2. serverPath=/upload/paizuo/(在/upload前不要加项目名,防止当其他项目用的时候,图片路径错误,提高使用率)
    3. dirPathSign=E:/temp/images/T280/sign/
    4. serverPathSign=/upload/sign/

     

    前端代码

    setPic.jsp

    1. <%@ page language="java" contentType="text/html; charset=UTF-8"
    2. pageEncoding="UTF-8"%>
    3. html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    4. <html>
    5. <head>
    6. <base href="${pageContext.request.contextPath }/"/>
    7. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    8. <link href="static/js/layui/css/layui.css" rel="stylesheet" type="text/css"/>
    9. <script type="text/javascript" src="static/js/jquery-3.3.1.min.js">script>
    10. <script type="text/javascript" src="static/js/layui/layui.js">script>
    11. <script type="text/javascript" src="static/js/plugins/html2canvas/html2canvas.js">script>
    12. <title>会议座位安排title>
    13. head>
    14. <style type="text/css">
    15. * {
    16. padding: 0;
    17. margin: 0;
    18. }
    19. body{
    20. width: 100%;
    21. height: 100%;
    22. /* background: red; */
    23. }
    24. .tips {
    25. /* position: absolute; */
    26. background: pink;
    27. display: inline-block;
    28. height: 60px;
    29. /* width: 60px; */
    30. line-height: 60px;
    31. text-align: center;
    32. margin: 5px;
    33. padding: 0 10px;
    34. }
    35. .add {
    36. position: fixed;
    37. right: 10px;
    38. top: 10px;
    39. display:inline;
    40. }
    41. #tu {
    42. width: 100%;
    43. height: 100%;
    44. /* background: lightblue; */
    45. /*background: url('u=3318199716,2583790385&fm=26&gp=0.jpg');*/
    46. }
    47. .layui-input{
    48. height:30px;
    49. }
    50. style>
    51. <body id="screen_body">
    52. <div id="tu">div>
    53. <div class="add">
    54. <div style="display:inline-block;">
    55. <input id="dan_input" type="text" value="" class="layui-input">
    56. div>
    57. <div style="display:inline-block;">
    58. <button onclick="return addDanMu()" class="layui-btn layui-btn-sm">添加座位button><input id="jie_input" type="button" class="layui-btn layui-btn-sm" value='下载'>
    59. div>
    60. div>
    61. body>
    62. <script type="text/javascript">
    63. var $id = function(id) {
    64. return document.getElementById(id);
    65. }
    66. //会议排座拖拽
    67. var dragF = {
    68. locked: false,
    69. lastObj: undefined,
    70. drag: function(obj) {
    71. $id(obj).onmousedown = function(e) {
    72. var e = e ? e : window.event;
    73. if (!window.event) {
    74. e.preventDefault();
    75. } /* 阻止标注浏览器下拖动a,img的默认事件 */
    76. dragF.locked = true;
    77. $id(obj).style.position = "absolute";
    78. $id(obj).style.zIndex = "100";
    79. if (dragF.lastObj && dragF.lastObj != $id(obj)) { /* 多元素拖动需要恢复上次元素状态 */
    80. dragF.lastObj.style.zIndex = "1";
    81. }
    82. dragF.lastObj = $id(obj);
    83. var tempX = $id(obj).offsetLeft;
    84. var tempY = $id(obj).offsetTop;
    85. dragF.x = e.clientX;
    86. dragF.y = e.clientY;
    87. document.onmousemove = function(e) {
    88. var e = e ? e : window.event;
    89. if (dragF.locked == false) return false;
    90. $id(obj).style.left = tempX + e.clientX - dragF.x + "px";
    91. $id(obj).style.top = tempY + e.clientY - dragF.y + "px";
    92. if (window.event) {
    93. e.returnValue = false;
    94. } /* 阻止ie下a,img的默认事件 */
    95. }
    96. document.onmouseup = function() {
    97. dragF.locked = false;
    98. }
    99. }
    100. }
    101. }
    102. script>
    103. <script type="text/javascript">
    104. var layer;
    105. layui.use(['layer'],function(){
    106. layer=layui.layer;
    107. //初始化会议排座:根据会议ID获取参会的所有人员的名字(主持人+参会人+列席人)
    108. initMeetingUsers();
    109. //绘制会议排座图片
    110. $("#jie_input").on("click", function(event) {
    111. $('.add').hide();
    112. event.preventDefault();
    113. html2canvas(document.getElementById("screen_body")).then(function(canvas) {
    114. var dataUrl = canvas.toDataURL();
    115. console.log(dataUrl);
    116. var param = {};
    117. param['seatPic'] = dataUrl;
    118. param['id'] = '${param.id}';
    119. param['methodName']='updateSeatPicById';
    120. console.log(param);
    121. //此处需要完成会议排座图片上传操作
    122. $.post('${pageContext.request.contextPath }/info.action',param,function(rs){
    123. console.log(rs);
    124. if(rs.success){
    125. //先得到当前iframe层的索引
    126. var index = parent.layer.getFrameIndex(window.name);
    127. //再执行关闭
    128. parent.layer.close(index);
    129. //调用父页面的刷新方法
    130. parent.query();
    131. }else{
    132. layer.msg(rs.msg,{icon:5},function(){});
    133. }
    134. },'json');
    135. });
    136. });
    137. });
    138. function initMeetingUsers(){
    139. $.getJSON('${pageContext.request.contextPath }/user.action',{
    140. 'methodName':'queryUserByMeetingId',
    141. 'meetingId':'${param.id}'
    142. },function(rs){
    143. console.log(rs);
    144. let data=rs.data;
    145. $.each(data,function(i,e){
    146. $('#dan_input').val(e.name);
    147. addDanMu();
    148. });
    149. });
    150. }
    151. //添加会议排座
    152. function addDanMu() {
    153. var dan = document.getElementById("dan_input").value;
    154. if (dan == "") {
    155. alert("请输入弹幕~");
    156. return false;
    157. } else {
    158. document.getElementById("dan_input").value = ""; //清空 弹幕输入框
    159. // var br = document.createElement("BR"); //
    160. var node = document.createElement("DIV"); //
    161. var tipsArr = document.getElementsByClassName('tips');
    162. var i;
    163. // console.log(parseInt(tipsArr[tipsArr.length-1].id.substr(4))+1);
    164. if (tipsArr.length == 0) {
    165. i = 1
    166. } else {
    167. i = parseInt(tipsArr[tipsArr.length - 1].id.substr(4)) + 1;
    168. }
    169. // var aNode = document.createElement("P"); //

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

    174. // aNode.appendChild(textnode);
    175. node.appendChild(textnode);
    176. // document.body.appendChild(br);
    177. // document.body.appendChild(node);
    178. document.getElementById("tu").appendChild(node);
    179. return true;
    180. }
    181. }
    182. script>
    183. html>

     展示:

     

    二、送审

    后台代码

    dao方法

    MeetingInfoDao.java

    1. // 根据会议ID更新会议的审批人(送审)
    2. public int updateAuditorById(MeetingInfo info) throws Exception {
    3. String sql="update t_oa_meeting_info set auditor=?,state=2 where id=?";
    4. return super.executeUpdate(sql, info, new String[] {"auditor","id"});
    5. }

    web层

    MeetingInfoAction.java

    1. // 根据会议ID更新会议的审批人(送审)
    2. public String updateAuditorById(HttpServletRequest req, HttpServletResponse resp) {
    3. try {
    4. int rs = meetingInfoDao.updateAuditorById(info);
    5. if (rs > 0) {
    6. ResponseUtil.writeJson(resp, R.ok(200, "会议审批成功"));
    7. }else {
    8. ResponseUtil.writeJson(resp, R.error(0, "会议审批失败"));
    9. }
    10. } catch (Exception e) {
    11. e.printStackTrace();
    12. try {
    13. ResponseUtil.writeJson(resp, R.error(0, "会议审批失败"));
    14. } catch (Exception e1) {
    15. e1.printStackTrace();
    16. }
    17. }
    18. return null;
    19. }

    js代码

    1. let layer,table,$,form;
    2. let row;
    3. layui.use(['layer','table','jquery','form'],function(){
    4. layer=layui.layer,
    5. table=layui.table,
    6. form=layui.form,
    7. $=layui.jquery;
    8. initTable();
    9. //查询事件
    10. $('#btn_search').click(function(){
    11. query();
    12. });
    13. //初始化审批人
    14. initFormSelects();
    15. //送审
    16. $('#btn_auditor').click(function(){
    17. $.post($("#ctx").val()+'/info.action',{
    18. 'methodName':'updateAuditorById',
    19. 'id':$('#meetingId').val(),
    20. 'auditorName':$('#auditorName').val()
    21. },function(rs){
    22. if(rs.success){
    23. //关闭对话框
    24. layer.closeAll();
    25. //刷新列表
    26. query();
    27. }else{
    28. layer.msg(rs.msg,{icon:5},function(){});
    29. }
    30. },'json');
    31. return false;
    32. });
    33. });
    34. //1.初始化数据表格
    35. function initTable(){
    36. table.render({ //执行渲染
    37. elem: '#tb', //指定原始表格元素选择器(推荐id选择器)
    38. height: 400, //自定义高度
    39. loading: false, //是否显示加载条(默认 true)
    40. cols: [[ //设置表头
    41. {field: 'id', title: '会议编号', width: 90},
    42. {field: 'title', title: '会议标题', width: 120},
    43. {field: 'location', title: '会议地点', width: 140},
    44. {field: 'startTime', title: '开始时间', width: 120},
    45. {field: 'endTime', title: '结束时间', width: 120},
    46. {field: 'meetingState', title: '会议状态', width: 120},
    47. {field: 'seatPic', title: '会议排座', width: 120,
    48. templet: function(d){
    49. if(d.seatPic==null || d.seatPic=="")
    50. return "尚未排座";
    51. else
    52. return "";
    53. }
    54. },
    55. {field: 'auditorName', title: '审批人', width: 120},
    56. {field: '', title: '操作', width: 200,toolbar:'#tbar'},
    57. ]]
    58. });
    59. }
    60. //2.点击查询
    61. function query(){
    62. table.reload('tb', {
    63. url: $("#ctx").val()+'/info.action', //请求地址
    64. method: 'POST', //请求方式,GET或者POST
    65. loading: true, //是否显示加载条(默认 true)
    66. page: true, //是否分页
    67. where: { //设定异步数据接口的额外参数,任意设
    68. 'methodName':'myInfos',
    69. 'zhuchiren':$('#zhuchiren').val(),
    70. 'title':$('#title').val(),
    71. },
    72. request: { //自定义分页请求参数名
    73. pageName: 'page', //页码的参数名称,默认:page
    74. limitName: 'rows' //每页数据量的参数名,默认:limit
    75. },
    76. done: function (res, curr, count) {
    77. console.log(res);
    78. }
    79. });
    80. //工具条事件
    81. table.on('tool(tb)', function(obj){ //注:tool 是工具条事件名,test 是 table 原始容器的属性 lay-filter="对应的值"
    82. row = obj.data; //获得当前行数据
    83. var layEvent = obj.event; //获得 lay-event 对应的值(也可以是表头的 event 参数对应的值)
    84. var tr = obj.tr; //获得当前行 tr 的 DOM 对象(如果有的话)
    85. console.log(row);
    86. if(layEvent === 'seat'){ //会议排座
    87. open(row.id);
    88. } else if(layEvent === 'send'){ //送审
    89. if(row.seatPic==null || row.seatPic==""){
    90. layer.msg('先请完成会议排座,再进行送审操作!',function(){});
    91. return false;
    92. }
    93. //在打开送审页面之前,先请完成会议ID的赋值操作
    94. $('#meetingId').val(row.id);
    95. openLayerAudit();
    96. } else if(layEvent==="back"){ //反馈详情
    97. } else {//删除
    98. layer.confirm('确认要取消会议吗?', {icon: 3, title:'提示'}, function(index){
    99. $.post($("#ctx").val()+'/info.action',{
    100. 'methodName':'updatezt',
    101. 'state':0,
    102. 'id':row.id
    103. },function(rs){
    104. if(rs.success){
    105. //调用查询方法刷新数据
    106. query();
    107. }else{
    108. layer.msg(rs.msg,function(){});
    109. }
    110. },'json');
    111. layer.close(index);
    112. });
    113. }
    114. });
    115. }
    116. //打开会议排座对话框
    117. function open(id){
    118. layer.open({
    119. type: 2, //layer提供了5种层类型。可传入的值有:0(信息框,默认)1(页面层)2(iframe层)3(加载层)4(tips层)
    120. title: '会议排座', //对话框标题
    121. area: ['460px', '340px'], //宽高
    122. skin: 'layui-layer-rim', //样式类名
    123. content: $("#ctx").val()+'/jsp/meeting/seatPic.jsp?id='+id, //弹出内容。可以传入普通的html内容,还可以指定DOM,更可以随着type的不同而不同
    124. });
    125. }
    126. //会议送审
    127. function openLayerAudit(){
    128. //每次打开都对送审人进行初始化默认值设置
    129. $('#auditor').val("");
    130. //必须重新渲染
    131. form.render('select');
    132. //弹出对话框
    133. layer.open({
    134. type: 1, //layer提供了5种层类型。可传入的值有:0(信息框,默认)1(页面层)2(iframe层)3(加载层)4(tips层)
    135. title:'会议送审',
    136. area: ['426px', '140px'], //宽高
    137. skin: 'layui-layer-rim', //样式类名
    138. content: $('#audit'), //弹出内容。可以传入普通的html内容,还可以指定DOM,更可以随着type的不同而不同
    139. });
    140. }
    141. //初始化审批人
    142. function initFormSelects(){
    143. $.getJSON($("#ctx").val()+'/user.action',{
    144. 'methodName':'queryUserAll'
    145. },function(rs){
    146. console.log(rs);
    147. let data=rs.data;
    148. $.each(data,function(i,e){
    149. $('#auditor').append(new Option(e.name,e.value));
    150. });
    151. //重新渲染
    152. form.render('select');
    153. });
    154. }

     

  • 相关阅读:
    课本在servlet中检索参数并验证,最后向用户发送验证消息
    QT+OSG/osgEarth编译之四十二:osgDB+Qt编译(一套代码、一套框架,跨平台编译,版本:OSG-3.6.5核心库osgDB)
    代码随想录训练营 DP
    【毕业设计】后端实现——账单通过关键词简单分析收支
    小红书数据分析工具 | 新中式内容营销怎么做?
    Si24R2F+2.4GHz ISM 频段低功耗无线集成嵌入式发射基带无线发射芯片
    委托及观察者模式
    【docker windows安装】
    JDK API文档地址(中文和英文)
    mysql-通过binlog日志复制主从同步
  • 原文地址:https://blog.csdn.net/m12120426/article/details/125991600