目录
1.左侧导航
导航一般指页面引导性频道集合,多以菜单的形式呈现,可应用于头部和侧边,是整个网页画龙点晴般的存在。 面包屑结构简单,支持自定义分隔符。 注:千万不要忘了加载 element模块。虽然大部分行为都是在加载完该模块后自动完成的,但一些交互操作, 如呼出二级菜单等,需借助element模块才能使用。
2.导入数据表及无限级分类
1) 数据导入(此步骤在第一次文章已完成) 2) 无限级分类:父亲找儿子的过程,将对应的儿子放在父亲下面,形成树结构。(递归算法)
3.实现左侧菜单后台代码接口
4.前端左侧菜单绑定
5.Tab选项卡
Tab广泛应用于Web页面,因此我们也对其进行了良好的支持(简约风格、卡片风格、响应式Tab以及带删除的Tab等等)。Layui内置多种Tab风格,支持删除选项卡、并提供响应式支持。
Tab分类
参考地址:http://layui.org.cn/doc/element/tab.html
1)Tab简约风格
2)Tab卡片风格
3)响应式Tab 当容器的宽度不足以显示全部的选项时,即会自动出现展开图标。
4)带删除的Tab
与默认相比没有什么特别的结构,就是多了个属性 lay-allowClose="true"
5)动态Tab
1)根据模块名称判断是否已经存在tab选项卡 $(".layui-tab-title li[lay-id='" + name + "']").length > 0
2)切换到指定选项卡 element.tabChange('tabs', name);
3)动态添加选项卡
// 新增一个Tab项 element.tabAdd('tabs', { title : name, content : tabContent, id : name }) // 切换刷新 element.tabChange('tabs', name);
注:tabs为tab选项卡的lay-filter=""
附录一:什么是lay-filter事件过滤器。你可能会在很多地方看到他,他一般是用于监听特定的自定义事件。你可以把它看作是一个ID选择器
附录二:iframe
注:在index.jsp首页页面中请将更改成:不然会导致使用iframe动态打开页面的高度无法100%填充父容器;
附录三:如何隐藏tab第一个选项卡的删除图标
一.会议发布
二.动态选项卡&左侧菜单
三.效果展示
左侧菜单
动态选项卡
会议发布界面
1.左侧导航
导航一般指页面引导性频道集合,多以菜单的形式呈现,可应用于头部和侧边,是整个网页画龙点晴般的存在。
面包屑结构简单,支持自定义分隔符。
注:千万不要忘了加载 element模块。虽然大部分行为都是在加载完该模块后自动完成的,但一些交互操作,
如呼出二级菜单等,需借助element模块才能使用。
参考地址:http://layui.org.cn/doc/element/nav.html
2.导入数据表及无限级分类
1) 数据导入(此步骤在第一次文章已完成)
2) 无限级分类:父亲找儿子的过程,将对应的儿子放在父亲下面,形成树结构。(递归算法)
3.实现左侧菜单后台代码接口
4.前端左侧菜单绑定
5.Tab选项卡
Tab广泛应用于Web页面,因此我们也对其进行了良好的支持(简约风格、卡片风格、响应式Tab以及带删除的Tab等等)。Layui内置多种Tab风格,支持删除选项卡、并提供响应式支持。
Tab分类
参考地址:http://layui.org.cn/doc/element/tab.html
1)Tab简约风格
<div class="layui-tab layui-tab-brief" lay-filter="docDemoTabBrief">
<ul class="layui-tab-title">
<li class="layui-this">网站设置</li>
<li>用户管理</li>
<li>权限分配</li>
<li>商品管理</li>
<li>订单管理</li>
</ul>
<div class="layui-tab-content"></div>
</div>
2)Tab卡片风格
<div class="layui-tab layui-tab-card">
<ul class="layui-tab-title">
<li class="layui-this">网站设置</li>
<li>用户管理</li>
<li>权限分配</li>
<li>商品管理</li>
<li>订单管理</li>
</ul>
<div class="layui-tab-content" style="height: 100px;">
<div class="layui-tab-item layui-show">1</div>
<div class="layui-tab-item">2</div>
<div class="layui-tab-item">3</div>
<div class="layui-tab-item">4</div>
<div class="layui-tab-item">5</div>
<div class="layui-tab-item">6</div>
</div>
</div>
3)响应式Tab
当容器的宽度不足以显示全部的选项时,即会自动出现展开图标。
4)带删除的Tab
与默认相比没有什么特别的结构,就是多了个属性 lay-allowClose="true"
<div class="layui-tab" lay-allowClose="true">
<ul class="layui-tab-title">
<li class="layui-this">网站设置</li>
<li>用户基本管理</li>
<li>权限分配</li>
<li>全部历史商品管理文字长一点试试</li>
<li>订单管理</li>
</ul>
<div class="layui-tab-content">
<div class="layui-tab-item layui-show">1</div>
<div class="layui-tab-item">2</div>
<div class="layui-tab-item">3</div>
<div class="layui-tab-item">4</div>
<div class="layui-tab-item">5</div>
<div class="layui-tab-item">6</div>
</div>
</div>
5)动态Tab
1)根据模块名称判断是否已经存在tab选项卡
$(".layui-tab-title li[lay-id='" + name + "']").length > 0
2)切换到指定选项卡
element.tabChange('tabs', name);
3)动态添加选项卡
// 新增一个Tab项
element.tabAdd('tabs', {
title : name,
content : tabContent,
id : name
})
// 切换刷新
element.tabChange('tabs', name);
注:tabs为tab选项卡的lay-filter=""
<div class="layui-tab" lay-filter="tabs" lay-allowClose="true" style="margin:0px;">
附录一:什么是lay-filter
事件过滤器。你可能会在很多地方看到他,他一般是用于监听特定的自定义事件。你可以把它看作是一个ID选择器
附录二:iframe
<iframe frameborder='0' src='"+url+"' scrolling='auto' style='width:100%;height:100%;'></iframe>
注:在index.jsp首页页面中请将
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
更改成:
<!DOCTYPE>
不然会导致使用iframe动态打开页面的高度无法100%填充父容器;
附录三:如何隐藏tab第一个选项卡的删除图标
<style>
.layui-tab-title>li:first-child>i{
display:none;
}
</style>
附录四:首页tab选项卡及body样式处理
.layui-tab>.layui-tab-content{
padding:0px;
}
body,html{
padding:0px;
margin:0px;
overflow:hidden;
}
一.会议发布
初始化会议发布页面
addMeeting.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
<%@include file="/common/head.jsp" %>
<style type="text/css">
.layui-form {
margin: 10px 10px 30px 10px;
}
</style>
</head>
<body>
<form class="layui-form layui-form-pane" lay-filter="meetinginfo" >
<div class="layui-form-item">
<label class="layui-form-label">会议标题</label>
<div class="layui-input-block">
<input type="text" name="title" autocomplete="off" placeholder="请输入会议标题" class="layui-input">
</div>
</div>
<div class="layui-form-item layui-form-text">
<label class="layui-form-label">会议内容</label>
<div class="layui-input-block">
<textarea placeholder="请输入内容" name="content" class="layui-textarea"></textarea>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">参与者</label>
<div class="layui-input-block">
<select name="canyuze" xm-select="canyuze">
<option value="" disabled="disabled">--请选择--</option>
</select>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">列席者</label>
<div class="layui-input-block">
<select name="liexize" xm-select="liexize">
<option value="" disabled="disabled">--请选择--</option>
</select>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">主持人员</label>
<div class="layui-input-block">
<input type="text" readonly="readonly" value="${sessionScope.user.name}" placeholder="会议标题" class="layui-input">
<input type="hidden" name="zhuchiren" readonly="readonly" value="${sessionScope.user.id}">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">会议地点</label>
<div class="layui-input-block">
<input type="text" name="location" placeholder="请输入会议地点" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">会议时间</label>
<div class="layui-input-block">
<input type="text" class="layui-input" id="meetingdt" name="meetingDt" placeholder="请输入会议时间">
</div>
</div>
<div class="layui-form-item layui-form-text">
<label class="layui-form-label">备注</label>
<div class="layui-input-block">
<textarea placeholder="请输入备注" name="remark" class="layui-textarea"></textarea>
</div>
</div>
<div class="layui-form-item" style="text-align:center;">
<button type="button" lay-submit="" lay-filter="meetinginfo" class="layui-btn layui-btn-normal">保存</button>
<button type="reset" class="layui-btn">重置</button>
</div>
</form>
</body>
</html>
addMeeting.js
<script>
let formSelects = null;
let laydate = null;
let form = null;
let $ = null;
layui.use(['jquery', 'formSelects','laydate','form'], function() {
formSelects = layui.formSelects;
laydate = layui.laydate;
form = layui.form;
$ = layui.$;
//参与者多选
formSelects.btns('canyuze', ['select', 'remove', 'reverse']);
formSelects.data('canyuze', 'server', {
url: ctx + '/meetinginfoAction.action?methodName=listMeetingMember'
});
//列席者多选
formSelects.btns('liexize', ['select', 'remove', 'reverse']);
formSelects.data('liexize', 'server', {
url: ctx + '/meetinginfoAction.action?methodName=listMeetingMember'
});
//日期时间范围
laydate.render({
elem: '#meetingdt',
type: 'datetime',
range: '至'
});
//提交表单
form.on('submit(meetinginfo)', function(data) {
//console.log(data);
let dt = data.field.meetingDt;
let start = dt.split("至")[0].trim();
let end = dt.split("至")[1].trim();
data.field["startTime"] = start;
data.field["endTime"] = end;
//console.log(data);
$.ajax({
url: ctx + '/meetinginfoAction.action?methodName=addMeetinginfo',
data: data.field,
type: 'post',
dataType: 'json',
success: function(resp) {
layer.msg(resp.msg);
}
})
});
});
</script>
会议发布功能实现
IMeetingInfoDao.java
package com.zking.oa.dao;
import java.util.List;
import java.util.Map;
import org.lisen.mvc.util.PageBean;
import com.zking.oa.model.MeetingMember;
import com.zking.oa.model.Meetinginfo;
import com.zking.oa.model.User;
public interface IMeetinginfoDao {
List<MeetingMember> listMeetingMember();
/**
* 增加
* @param meetinginfo
*/
void addMeetinginfo(Meetinginfo meetinginfo);
/**
* 获取我的会议信息
* @param meetingInfo
* @param pageBean
* @return
*/
List<Map<String,Object>> listMeetingInfo(Meetinginfo meetingInfo, PageBean pageBean);
List<User> listMeetingMembersById(Integer id);
void updateSeatPicById(Meetinginfo meetingInfo);
/**
* 更新送审信息
* @param meetingInfo
*/
void sendAudit(Meetinginfo meetingInfo);
/**
* 更新审核记录到指定装
* @param meetingInfo
*/
void updateMeetingState(Meetinginfo meetingInfo);
/**
* 查询与当前登录用户相关的状态为待开的会议信息
* @param uid
* @param pageBean
* @return
*/
List<Meetinginfo> listRelatedMeetingInfoByUserId(Integer uid,String title,Integer state, PageBean pageBean);
/**
* 历史会议
* @param uid
* @param title
* @param state
* @param pageBean
* @return
*/
List<Meetinginfo> listRelatedMeetingInfoByUserId2(Integer uid, String title, Integer state, PageBean pageBean);
}
MeetingInfoDao.java
package com.zking.oa.dao;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.lisen.mvc.util.DbTemplate;
import org.lisen.mvc.util.PageBean;
import com.mysql.cj.util.StringUtils;
import com.zking.oa.model.MeetingMember;
import com.zking.oa.model.Meetinginfo;
import com.zking.oa.model.User;
import com.zking.oa.util.BaseDao;
import com.zking.oa.util.CommonUtils;
@SuppressWarnings("unchecked")
public class MeetinginfoDao extends BaseDao implements IMeetinginfoDao {
@Override
public List<MeetingMember> listMeetingMember(){
String sql="select name,id from t_oa_user";
return DbTemplate.query(sql, MeetingMember.class);
}
@Override
public void addMeetinginfo(Meetinginfo meetinginfo) {
DbTemplate.save(meetinginfo);
}
/**
* 封装sql:作为我的会议、我的审批、会议通知、代开会议、
* 历史会议级所有会议的基础SQL语句
* @return
*/
private String getSql() {
return "SELECT \r\n" +
"m.id,m.title,m.content,m.canyuze,m.zhuchiren,m.liexize,u.name\r\n" +
",m.location,\r\n" +
"DATE_FORMAT(m.startTime,'%Y-%m-%d %H:%i:%s') as startTime,\r\n" +
"DATE_FORMAT(m.endTime,'%Y-%m-%d %H:%i:%s') as endTime,\r\n" +
"(case m.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,m.state,m.seatPic,m.remark,m.auditor,\r\n" +
"u2.name as auditName\r\n" +
"from \r\n" +
"t_oa_meeting_info m inner join t_oa_user u\r\n" +
"on m.zhuchiren=u.id\r\n" +
"LEFT JOIN t_oa_user u2\r\n" +
"on u2.id=m.auditor where 1=1 ";
}
@Override
public List<Map<String,Object>> listMeetingInfo(Meetinginfo meetingInfo, PageBean pageBean) {
String sql=this.getSql();
//按照会议标题模糊查询
if(!StringUtils.isNullOrEmpty(meetingInfo.getTitle()))
sql+=" and title like '%"+meetingInfo.getTitle()+"%'";
//按照 当前登录ID作为主持人字段条件
sql+=" and zhuchiren="+meetingInfo.getZhuchiren();
//sql +=" and state="+meetingInfo.getState();
//按照会议ID降序排序
sql+=" order by m.id desc";
return super.executeQuery(sql, pageBean, new convert<Map<String, Object>>() {
@Override
public List<Map<String, Object>> forEach(ResultSet rs) throws SQLException, Exception {
return CommonUtils.toList(rs);
}
});
}
@Override
public void updateMeetingState(Meetinginfo meetingInfo) {
String sql = "update t_oa_meeting_info set state = ? where id = ?";
DbTemplate.update(sql, new Object[] {meetingInfo.getState(), meetingInfo.getId()});
}
@Override
public List<Meetinginfo> listRelatedMeetingInfoByUserId(Integer uid, String title,Integer state,PageBean pageBean) {
String sql = "SELECT t1.id,t1.auditor,t1.canyuze,t1.liexize,t1.content,DATE_FORMAT(t1.endTime,'%Y-%m-%d %H:%i:%s') as endTime,t1.fujian,\r\n" +
" t1.location,t1.seatPic,DATE_FORMAT(t1.startTime,'%Y-%m-%d %H:%i:%s') as startTime,"
+ "(case t1.state "
+ " when 0 then '取消会议' "
+ " when 1 then '新建' "
+ " when 2 then '待审核'"
+ " when 3 then '驳回'"
+ " when 4 then '待开'"
+ " when 5 then '进行中' "
+ " when 6 then '开启投票' "
+ " ELSE '结束会议' end) as meetingState,"
+ "t1.title,t1.zhuchiren\r\n" +
" FROM t_oa_meeting_info t1 INNER JOIN \r\n" +
" (SELECT a.id,\r\n" +
" SUBSTRING_INDEX(SUBSTRING_INDEX( a.canyuze, ',', b.help_topic_id + 1 ), ',',- 1) AS userid \r\n" +
" FROM t_oa_meeting_info AS a\r\n" +
" JOIN mysql.help_topic AS b ON b.help_topic_id < ( LENGTH( a.canyuze ) - LENGTH( REPLACE ( a.canyuze, ',', '' ) ) + 1 )\r\n" +
" UNION ALL\r\n" +
" SELECT a.id,\r\n" +
" SUBSTRING_INDEX(SUBSTRING_INDEX( a.liexize, ',', b.help_topic_id + 1 ), ',',- 1) AS userid \r\n" +
" FROM t_oa_meeting_info AS a\r\n" +
" JOIN mysql.help_topic AS b ON b.help_topic_id < ( LENGTH( a.liexize ) - LENGTH( REPLACE ( a.liexize, ',', '' ) ) + 1 )\r\n" +
" ) tmp ON t1.id = tmp.id\r\n" +
"WHERE tmp.userid = "+uid+" and t1.state ="+state;
if(title!=null&&!"".equals(title)) {
sql+=" and t1.title like '"+title+"%'";
}
return super.executeQuery(sql, pageBean, new convert<Map<String, Object>>() {
@Override
public List<Map<String, Object>> forEach(ResultSet rs) throws SQLException, Exception {
return CommonUtils.toList(rs);
}
});
}
@Override
public List<Meetinginfo> listRelatedMeetingInfoByUserId2(Integer uid, String title,Integer state,PageBean pageBean) {
String sql = "SELECT t1.id,t1.auditor,t1.canyuze,t1.liexize,t1.content,DATE_FORMAT(t1.endTime,'%Y-%m-%d %H:%i:%s') as endTime,t1.fujian,\r\n" +
" t1.location,t1.seatPic,DATE_FORMAT(t1.startTime,'%Y-%m-%d %H:%i:%s') as startTime,(case t1.state when 0 then '取消会议' when 1 then '新建' when 2 then '待审核' when 3 then '驳回' when 4 then '待开' when 5 then '进行中' when 6 then '开启投票' ELSE '结束会议' end) as meetingState,t1.title,t1.zhuchiren\r\n" +
" FROM t_oa_meeting_info t1\r\n" +
"WHERE t1.state=7 and FIND_IN_SET("+uid+",concat(t1.zhuchiren,',',t1.canyuze,',',t1.liexize))";
if(title!=null&&!"".equals(title)) {
sql+=" and t1.title like '"+title+"%'";
}
return super.executeQuery(sql, pageBean, new convert<Map<String, Object>>() {
@Override
public List<Map<String, Object>> forEach(ResultSet rs) throws SQLException, Exception {
return CommonUtils.toList(rs);
}
});
}
@Override
public List<User> listMeetingMembersById(Integer id) {
String sql = "SELECT id,name,loginName,pwd,rid "
+ "FROM t_oa_user id "
+ "WHERE FIND_IN_SET(id, (SELECT CONCAT(t.canyuze,',',t.liexize,',',t.zhuchiren) FROM t_oa_meeting_info t WHERE t.id = ?))";
return DbTemplate.query(sql, new Object[] {id}, User.class);
}
@Override
public void updateSeatPicById(Meetinginfo meetingInfo) {
String sql = "UPDATE t_oa_meeting_info SET seatPic = ? WHERE id = ? ";
DbTemplate.update(sql, new Object[] {meetingInfo.getSeatPic(), meetingInfo.getId()});
}
@Override
public void sendAudit(Meetinginfo meetingInfo) {
String sql = "update t_oa_meeting_info set state = 2, auditor=? where id = ?";
DbTemplate.update(sql, new Object[] {meetingInfo.getAuditor(), meetingInfo.getId()});
}
public static void main(String[] args) {
MeetinginfoDao md = new MeetinginfoDao();
Meetinginfo info = new Meetinginfo();
// info.setZhuchiren("1");
// List<Map<String,Object>> listMeetingInfo = md.listMeetingInfo(info, new PageBean());
// System.out.println(listMeetingInfo);
//List<Meetinginfo> listRelatedMeetingInfoByUserId = md.listRelatedMeetingInfoByUserId(1, 4, new PageBean());
//System.out.println(listRelatedMeetingInfoByUserId);
}
}
MeetingInfoAction.java
package com.zking.oa.action;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.beanutils.ConvertUtils;
import org.apache.commons.beanutils.converters.DateConverter;
import org.lisen.mvc.framework.AbstractDispatchAction;
import org.lisen.mvc.framework.ModelDrive;
import org.lisen.mvc.util.PageBean;
import com.zking.oa.dao.MeetinginfoDao;
import com.zking.oa.model.MeetingMember;
import com.zking.oa.model.Meetinginfo;
import com.zking.oa.model.User;
import com.zking.oa.service.IMeetinginfoService;
import com.zking.oa.service.MeetinginfoService;
import com.zking.oa.util.Base64ImageUtils;
import com.zking.oa.util.CommonUtil;
public class MeetinginfoAction extends AbstractDispatchAction implements ModelDrive{
private Meetinginfo meetinginfo = new Meetinginfo();
private IMeetinginfoService service = new MeetinginfoService();
@Override
public Object getModel() {
//日期转换器
DateConverter converter = new DateConverter();
converter.setPattern("yyyy-MM-dd HH:mm:ss");
ConvertUtils.register(converter, Date.class);
return meetinginfo;
}
public void listMeetingMember(HttpServletRequest req,HttpServletResponse resp) {
try {
List<MeetingMember> list = service.listMeetingMember();
CommonUtil.sendResponse(0, "成功", list,resp);
} catch (Exception e) {
e.printStackTrace();
CommonUtil.sendResponse(-1, "获取会议参与人员失败", resp);
}
}
public void addMeetinginfo(HttpServletRequest req,HttpServletResponse resp) {
try {
service.addMeetinginfo(meetinginfo);
CommonUtil.sendResponse(0, "会议发布成功", resp);
} catch (Exception e) {
e.printStackTrace();
CommonUtil.sendResponse(-1, "会议发布失败", resp);
}
}
/**
* 获取以当前用户为主持人的会议信息,即我的会议功能
* @param req
* @param resp
*/
public void listMeetingInfo(HttpServletRequest req, HttpServletResponse resp) {
try {
PageBean pageBean = new PageBean();
pageBean.setRequest(req);
//从session中获取当前用户放入条件
User user = (User)req.getSession().getAttribute("user");
meetinginfo.setZhuchiren(user.getId().toString());
List<Map<String,Object>> list = service.listMeetingInfo(meetinginfo, pageBean);
CommonUtil.sendResponse(0, "会议信息查询成功", pageBean.getTotal(), list, resp);
} catch (Exception e) {
e.printStackTrace();
CommonUtil.sendResponse(-1, "会议信息查询失败",resp);
}
}
/**
* 查询与当前登录用户相关的状态为待开的会议信息
* @return
*/
public void listRelatedMeetingInfoByUserId(HttpServletRequest req, HttpServletResponse resp) {
MeetinginfoDao ma=new MeetinginfoDao();
try {
PageBean pageBean = new PageBean();
pageBean.setRequest(req);
//从session中获取当前用户,并且只查询待审记录
User user = (User)req.getSession().getAttribute("user");
List<Meetinginfo> list = ma.listRelatedMeetingInfoByUserId(user.getId(),meetinginfo.getTitle(),4, pageBean);
CommonUtil.sendResponse(0, "会议信息查询成功", pageBean.getTotal(), list, resp);
} catch (Exception e) {
e.printStackTrace();
CommonUtil.sendResponse(-1, "会议信息查询失败",resp);
}
}
/**
* 历史会议
* @return
*/
public void listRelatedMeetingInfoNotify(HttpServletRequest req, HttpServletResponse resp) {
MeetinginfoDao ma=new MeetinginfoDao();
try {
PageBean pageBean = new PageBean();
pageBean.setRequest(req);
//从session中获取当前用户,并且只查询待审记录
User user = (User)req.getSession().getAttribute("user");
List<Meetinginfo> list = ma.listRelatedMeetingInfoByUserId2(user.getId(),meetinginfo.getTitle(),7, pageBean);
CommonUtil.sendResponse(0, "历史会议查询成功", pageBean.getTotal(), list, resp);
} catch (Exception e) {
e.printStackTrace();
CommonUtil.sendResponse(-1, "历史会议查询失败",resp);
}
}
/**
* 通过会议的Id获取与本次会议相关的参与人员信息
* @param req
* @param resp
*/
public void listMeetingMemberById(HttpServletRequest req, HttpServletResponse resp) {
try {
PageBean pageBean = new PageBean();
pageBean.setRequest(req);
List<User> list = service.listMeetingMembersById(meetinginfo.getId().intValue());
CommonUtil.sendResponse(0, "会议信息查询成功", pageBean.getTotal(), list, resp);
} catch (Exception e) {
e.printStackTrace();
CommonUtil.sendResponse(-1, "会议信息查询失败",resp);
}
}
/**
* 保存排座图片到服务器的指定目录,并更新相关会议信息的排座图片字段
* @param req
* @param resp
*/
public void addArrangeSeat(HttpServletRequest req, HttpServletResponse resp) {
try {
String fName = UUID.randomUUID().toString().replace("-", "").concat(".jpg");
String path = "D:\\temp\\images\\seatPic\\uploads\\" + fName;
String base64Image = meetinginfo.getSeatPic().replace("data:image/png;base64,", "");
//生成图片
Base64ImageUtils.GenerateImage(base64Image, path);
//更新会议信息表中的排座信息,需要设置tomcat的设置增加一个扩展web模块
meetinginfo.setSeatPic("/uploads/"+fName);
service.updateSeatPicById(meetinginfo);
CommonUtil.sendResponse(0, "排座成功", resp);
} catch (Exception e) {
e.printStackTrace();
CommonUtil.sendResponse(-1, "排座失败", resp);
}
}
/**
* 我的审核,会议的审核人员是当前登录的用户,且会议的状态为待审
* @param req
* @param resp
*/
public void listMyAuditMeetingInfo(HttpServletRequest req, HttpServletResponse resp) {
try {
PageBean pageBean = new PageBean();
pageBean.setRequest(req);
//从session中获取当前用户,并且只查询待审记录
User user = (User)req.getSession().getAttribute("user");
meetinginfo.setAuditor(user.getId().toString());
meetinginfo.setState(2);
List<Map<String,Object>> list = service.listMeetingInfo(meetinginfo, pageBean);
CommonUtil.sendResponse(0, "会议信息查询成功", pageBean.getTotal(), list, resp);
} catch (Exception e) {
e.printStackTrace();
CommonUtil.sendResponse(-1, "会议信息查询失败",resp);
}
}
/**
* 会议送审,能够送审的前提是该会议已经排座,否则不能送审,此外
* 对于审核通过,结束,取消,进行中等状态的会议不能执行送审
* @param rep
* @param resp
*/
public void sendAudit(HttpServletRequest rep, HttpServletResponse resp) {
try {
service.sendAudit(meetinginfo);
CommonUtil.sendResponse(0, "送审成功", resp);
} catch (Exception e) {
e.printStackTrace();
CommonUtil.sendResponse(-1, "送审失败", resp);
}
}
}
二.动态选项卡&左侧菜单
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE>
<html>
<head>
<%@include file="/common/head.jsp" %>
</head>
<style>
.layui-tab-title>li:first-child>i{
display:none;
}
.layui-tab>.layui-tab-content{
padding:0px;
}
body,html{
padding:0px;
margin:0px;
overflow:hidden;
}
.layui-body{
background: url(images/壁纸03.jpg) ;
}
</style>
<body>
<div class="layui-layout layui-layout-admin">
<div class="layui-header ">
<div class="layui-logo layui-hide-xs layui-bg-black">会议OA管理系统</div>
<!-- 头部区域(可配合layui 已有的水平导航) -->
<ul class="layui-nav layui-layout-left">
<!-- 移动端显示 -->
<li class="layui-nav-item layui-show-xs-inline-block layui-hide-sm" lay-header-event="menuLeft">
<i class="layui-icon layui-icon-spread-left"></i>
</li>
</ul>
<!-- 个人头像及账号操作 -->
<ul class="layui-nav layui-layout-right">
<li class="layui-nav-item layui-hide layui-show-md-inline-block">
<a href="javascript:;">
<img src="${ctx }/images/壁纸3.png" class="layui-nav-img">
${sessionScope.user.name }
</a>
<dl class="layui-nav-child">
<dd><a href="#">个人中心</a></dd>
<dd><a href="#">系统设置</a></dd>
<dd><a href="#" id="logout">安全退出</a></dd>
</dl>
</li>
<li class="layui-nav-item" lay-header-event="menuRight" lay-unselect>
<a href="javascript:;">
<i class="layui-icon layui-icon-more-vertical"></i>
</a>
</li>
</ul>
</div>
<div class="layui-side layui-bg-black">
<div class="layui-side-scroll">
<!-- 左侧导航区域(可配合layui已有的垂直导航) -->
<ul id="menu" class="layui-nav layui-nav-tree">
</ul>
</div>
</div>
<div class="layui-body">
<div class="layui-tab" lay-filter="tabs" lay-allowClose="true" style="margin:0px;">
<ul class="layui-tab-title">
<li class="layui-this">首页</li>
</ul>
<div class="layui-tab-content">
<div class="layui-tab-item layui-show">
<!-- <i class="bi bi-balloon-heart">欢迎来到瑶大头工作室</i> -->
<!-- <img alt="" src="/images/壁纸3.png"> -->
</div>
</div>
</div>
</div>
<div class="layui-footer" style="text-align:center;">
<!-- 底部固定区域 -->
Copyright @ 2008-2022 www.zking.com
</div>
</div>
<script>
//JS
var element, $, layer, util;
layui.use(['element', 'layer', 'util', 'jquery'], function(){
element = layui.element
,layer = layui.layer
,util = layui.util
,$ = layui.$;
//头部事件
util.event('lay-header-event', {
//左侧菜单事件
menuLeft: function(othis){
layer.msg('展开左侧菜单的操作', {icon: 0});
}
,menuRight: function(){
layer.open({
type: 1
,content: '<div style="padding: 15px;">处理右侧面板的操作</div>'
,area: ['260px', '100%']
,offset: 'rt' //右上角
,anim: 5
,shadeClose: true
});
}
});
//动态生成菜单
$.ajax({
url: ctx+"/permissionAction.action?methodName=listPermission",
type: "get",
dataType: 'json',
success:function(resp) {
//循环生成菜单
$.each(resp.data, function(index, val) {
//默认打开第一个菜单,layui-nav-itemed样式为打开菜单样式
let selected = index == 0 ? 'layui-nav-itemed' : '';
let li = $('<li class="layui-nav-item ' + selected + '"></li>');
//一级菜单
li.append('<a class="" href="javascript:;"><i class="layui-icon '
+ val.icon
+ '" style="font-size:16px;margin-right:10px;"></i>'
+ val.name + '</a>');
//如果有子菜单,则生成子菜单
let chidren=val.children;
let dl = $('<dl class="layui-nav-child"></dl>');
$.each(chidren, function(i, n) {
//dl.append('<dd style="margin-left:40px;">'+n.name+'</dd>');
//添加菜单点击事件
dl.append('<dd style="margin-left:40px;"><a href="javascript:openFuncTab(\''+n.name+'\', \''+n.url+'\', \''+n.id+'\');">'+n.name+'</a></dd>');
});
li.append(dl);
//将生成的菜单挂载到menu容器
$("#menu").append(li);
});
//动态的生成菜单后,调用render方法进行重新渲染,可以使用init()方法进行初始化达到同样的效果
element.render('menu');
}
});
//安全退出
$("#logout").click(function() {
layer.confirm('亲,你舍得走吗?', {icon: 3, title:'提示'}, function(index) {
$.ajax({
url: ctx+"/userAction.action?methodName=logout",
type: 'get',
dataType: "json",
success: function(resp) {
if(resp.code == 1) {
layer.msg("安全退出");
location.href="login.jsp";
}
}
});
});
});
});
//动态打开TAB页
function openFuncTab(name, url,id) {
let exit = $("li[lay-id='"+id+"']").length;
debugger;
//如果不存在对应的TAB则动态生成
if(exit == 0) {
//注意此处的tabs,要与TAB页容器的lay-filter="tabs"报错保持一致
element.tabAdd('tabs', {
title: name,
//在TAB页中打开指定的页面
content: '<iframe id="myiframe" frameborder="0" src="' + url+ '" scrolling="auto" style="width:100%;height:100%;"></iframe>',
id: id
});
}
//将点击的功能设置为当前TAB
element.tabChange('tabs', id);
setIframHeight();
//添加页面尺寸变化的监听事件
$(window).resize(function() {
setIframHeight();
})
}
//解决页面的自适应高度问题
function setIframHeight() {
let h = $('.layui-body').height() - 40;
$('#myiframe').css("height", h+"px");
}
</script>
</body>
</html>
三.效果展示
左侧菜单
动态选项卡
会议发布界面