目录
一、会议菜单名词讲解
最终我们的目的是完成我的会议界面如图所示:
1.名词介绍
数据库中用到的表:
状态:0取消会议 1新建 2待审核 3驳回 4待开 5进行中 6开启投票 7结束会议,默认值为1
我的会议:
当前登录账号,是 某会议 主持人,则查询出来
通过主持人字段查询出来的
我的审批:
当前登录账号,是 某会议 的指定审批人,并且会议状态是待审核,则查询出来
通过审批人字段,会议状态为2查询出来的会议通知:
当前登录账号,只要是 某会议 的参与者、列席者、主持人中的一员,并且该会议未反馈,则查询出来
要么我是主持人要么是参数者要么是列席者,说白了只要我是参与者的一员列席者的一员或者主持人的一员
通过三个列段来查询反馈结果
待开会议:
当前登录账号,只要是 某会议 的参与者、列席者、主持人中的一员,并且会议状态是待开,则查询出来
那么是为4就应该查询出来,相比上面的会议通知多了一个条件叫会议状态历史会议:
当前登录账号,只要是 某会议 的参与者、列席者、主持人中的一员,并且会议状态是结束,则查询出来
那么就是由2变成7所有会议:
当前登录账号,只要是 某会议 的参与者、列席者、主持人、审批人中的一员,那么必须查询出来
所有会议就比前面查询条件多了一个审批人,比如说某某谁要开个会,那么不管这个会是开了还是没开或者说这个来的人到底有没有来全
我某某老师是不是的知道或者说某某学社导师的知道,你开这个会我通过了,那我通过了之后难道我在我的数据库里我查不到这些数据吗?
她肯定的查的到,万一这个会议存在什么问题,我肯定的回诉。所以说只要你是这四个员中的一员,我们就要把这所有的数据查询出来
二、我的会议SQL编写
我们查询出这条SQL语句是没有支持人显示的
但有些界面就会显示有支持人如图所示:
所以说我们要写的sql语句如下所示:
-- 我的会议
select a.*,b.`name`
from t_oa_meeting_info a,
t_oa_user b where a.zhuchiren=b.id;
接下来明确的目的如图所示:
怎么显示审批人,SQL语句怎么写,我们要加一个表如下所示:
select a.*,b.`name` zhuchirennmae,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;
运行结果如图所示:
但我们查询出来的记录如图所示:
有一个问题审批人有空的,因为我们的会议状态开始的时候是还没有指定审批人,但我们的会议要查询出来,点我的会议,我没有指定审批人就查询不出来,这样就不合理,如果说这样的话,我们的每一个会议都无法送审了要么就是查不出来,查不出来就没办法送审,你只有送审了才能查出来,进那个嘶循环了吧,那么这个SQL语句改怎么写如下所示:
分析:会议没有审批也要查询出来,那么会议信息表就作为主表,用户表作为从表; 用会议信息表左外连接用户表
select a.*,b.`name` zhuchirennmae,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
但这条查询出来的记录如图所示:
说明有5条记录是为空的
注意:
上面的SQL语句大致是这样的实际我们要把它拆开来,因为我们的startTime是时间类型的它并不会直接显示时间到页面上面去,我们需要做这个格式化,啥意思,因为我们上面的SQL语句是直接同a.*把这个数据查询出来返回到页面上面去,它会显示一个字符串一个数字长串null类型的一个长串,所以说我们不能用这个a.*,这是第一个点
第一点:两个时间我们要转换,做数据格式化
时间字段要格式化,否则页面会显示一串数字
第二个点:把这个state显示到页面没有意义
会议状态是数字,前端要显示会议状态描述
SQL语句改写如下所示:
select a.id,a.title,a.content,a.canyuze,a.liexize,a.zhuchiren ,b.`name` zhuchirennmae, a.location, DATE_FORMAT(a.startTime,'%Y-%m-%d %H-%m-%s') startTime, DATE_FORMAT(a.endTime,'%Y-%m-%d %H-%m-%s') 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 ) meetingstate, a.seatPic,a.remark,a.auditor, 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
查询出来结果如图所示:
三、我的会议后台
1.开始写dao层
写我们的MeetingInfoDao代码块:
package com.zking.dao;
import java.sql.SQLException;
import java.util.List;
import java.util.Map;
import com.zking.entity.MeetingInfo;
import com.zking.util.BaseDao;
import com.zking.util.PageBean;
import com.zking.util.StringUtils;
public class MeetingInfoDao extends BaseDao<MeetingInfo>{
// 会议信息新增
public int add(MeetingInfo t) throws Exception {
String sql="insert into t_oa_meeting_info(title,content,canyuze,liexize,zhuchiren,location,startTime,endTime,remark) values(?,?,?,?,?,?,?,?,?)";
return super.executeUpdate(sql, t, new String[] {"title","content","canyuze","liexize","zhuchiren","location","startTime","endTime","remark"});
}
// 我的会议,后续其他的菜单也会使用
private String getSQL() {
return "select a.id,a.title,a.content,a.canyuze,a.liexize,a.zhuchiren\r\n" +
",b.`name` zhuchirennmae,\r\n" +
"a.location,\r\n" +
"DATE_FORMAT(a.startTime,'%Y-%m-%d %H-%m-%s') startTime,\r\n" +
"DATE_FORMAT(a.endTime,'%Y-%m-%d %H-%m-%s') endTime,\r\n" +
"a.state,\r\n" +
"(\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" +
" when 7 then '结束会议'\r\n" +
" else '其他' end\r\n" +
") meetingstate,\r\n" +
"a.seatPic,a.remark,a.auditor,\r\n" +
"c.`name` auditorname 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 and 1=1";
}
// 我的会议
public List<Map<String, Object>> myInfos(MeetingInfo info, PageBean pageBean)
throws SQLException, InstantiationException, IllegalAccessException {
// 拿到那些可能传的条件
// 拿到我们封装好的SQL语句
String sql = getSQL();
// 会议标题
String title = info.getTitle();
if(StringUtils.isNotBlank(title)) {
sql+=" and title like '%"+title+"%'";
}
sql+=" and zhuchiren = "+info.getZhuchiren();
return super.executeQuery(sql, pageBean);
}
}
2.junit测试
MeetingInfoDaoTest代码块:
package com.zking.dao;
import static org.junit.Assert.*;
import java.sql.SQLException;
import java.util.List;
import java.util.Map;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import com.zking.entity.MeetingInfo;
import com.zking.util.PageBean;
public class MeetingInfoDaoTest {
private MeetingInfoDao infoDao = new MeetingInfoDao();
@Before
public void setUp() throws Exception {
}
@After
public void tearDown() throws Exception {
}
@Test
public void testMyInfos() {
MeetingInfo info = new MeetingInfo();
PageBean pageBean = new PageBean();
pageBean.setPagination(true);
try {
List<Map<String,Object>> myInfos = infoDao.myInfos(info, pageBean);
for (Map<String, Object> map : myInfos) {
System.out.println(map);
}
System.out.println(pageBean);
} catch (Exception e) {
e.printStackTrace();
}
}
}
运行结果如图所示:
3.写action
MeetingInfoAction代码块:
package com.zking.web;
import java.util.Date;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.beanutils.ConvertUtils;
import com.zking.dao.MeetingInfoDao;
import com.zking.entity.MeetingInfo;
import com.zking.framework.ActionSupport;
import com.zking.framework.ModelDriver;
import com.zking.util.MyDateConverter;
import com.zking.util.PageBean;
import com.zking.util.R;
import com.zking.util.ResponseUtil;
public class MeetingInfoAction extends ActionSupport implements ModelDriver<MeetingInfo>{
private MeetingInfo info = new MeetingInfo();
private MeetingInfoDao infoDao = new MeetingInfoDao();
@Override
public MeetingInfo getModel() {
// 注册一个转换器
ConvertUtils.register(new MyDateConverter(), Date.class);
return info;
}
public String add(HttpServletRequest req, HttpServletResponse resp) {
try {
// n是sql语句执行的影响行数
int n=infoDao.add(info);
// 如果大于0说明可以新增
if(n>0) {
ResponseUtil.writeJson(resp, R.ok(200, "会议信息数据新增成功"));
}
else {
ResponseUtil.writeJson(resp, R.ok(0, "会议信息数据新增失败"));
}
} catch (Exception e) {
e.printStackTrace();
try {
ResponseUtil.writeJson(resp, R.error(0, "会议信息数据新增失败"));
} catch (Exception e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
return null;
}
// 我的会议
public String myInfos(HttpServletRequest req, HttpServletResponse resp) {
try {
PageBean pageBean = new PageBean();
pageBean.setRequest(req);
List<Map<String, Object>> infos= infoDao.myInfos(info, pageBean);
// 注意:layui中的数据格式
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;
}
}
四、我的会议前端
1.快速定位问题的方法
控制台有可能会告诉你这个单词有问题怎么解决:Ctrl+c------>Ctrl+h就会出现一个界面如图所示
2.前端运行
我们先运行一下界面如图所示:
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="${pageContext.request.contextPath }/static/js/meeting/myMeeting.js"></script>
<title>用户管理</title>
</head>
<style>
body{
margin:15px;
}
.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>
运行结果如图所示:
2.写js
按照对应的去格式去写js代码块
myMeeting.js代码块:
let layer,$,table;
var row;
layui.use(['jquery', 'layer', 'table'], function(){
layer = layui.layer
,$ = layui.jquery
,table = layui.table;
//初始化数据表格
initTable();
//绑定查询按钮的点击事件
$('#btn_search').click(function(){
query();
});
});
//1.初始化数据表格
function initTable(){
table.render({ //执行渲染
elem: '#tb', //指定原始表格元素选择器(推荐id选择器)
// url: 'user.action?methodName=list', //请求地址
height: 340, //自定义高度
loading: false, //是否显示加载条(默认 true)
cols: [[ //设置表头
{field: 'id', title: '会议编号', width: 120},
{field: 'title', title: '会议标题', width: 120},
{field: 'location', title: '会议地点', width: 140},
{field: 'startTime', title: '开始时间', width: 220},
{field: 'endTime', title: '结束时间', width: 120},
{field: 'meetingstate', title: '会议状态', width: 120},
{field: 'seatPic', title: '会议排座', width: 140},
{field: 'auditor', title: '审批人', width: 140},
{field: '', title: '操作', width: 220,toolbar:'#tbar'},
]]
});
//在页面中的<table>中必须配置lay-filter="tb_goods"属性才能触发属性!!!
table.on('tool(tb)', function (obj) {
row = obj.data;
if (obj.event == "seat") {
layer.msg("排座");
}else if(obj.event == "send"){
layer.msg("送审");
}else if(obj.event == "del"){
layer.msg("取消会议");
// 把我们的会议状态改为0
}else if(obj.event == "back"){
layer.msg("反馈详细");
// 把我们的会议状态改为0
}else{
}
});
}
//2.点击查询
function query(){
// console.log($("#ctx").val());
table.reload('tb', {
url: 'info.action', //请求地址
method: 'POST', //请求方式,GET或者POST
loading: true, //是否显示加载条(默认 true)
page: true, //是否分页
where: { //设定异步数据接口的额外参数,任意设
'methodName':'myInfos',
'title':$('#title').val(),
'zhuchiren':$('#zhuchiren').val()
},
request: { //自定义分页请求参数名
pageName: 'page', //页码的参数名称,默认:page
limitName: 'rows' //每页数据量的参数名,默认:limit
}
});
}
运行结果如图所示:
最终我们要把这个结果进行渲染,不希望显示的是字符串吧
看官网怎么去渲染:官网网址:表单 - 在线演示 - Layuihttps://layui.org.cn/demo/form.html
表格点击里面的table模块如图所示:
把这个复制到js里面去,运行结果如下: 它会针对我原有的值进行一个path的渲染,就是改变原有的值渲染我自己想要展示的东西。我希望要把这个变成图片,我们就要把这个改成图片
改成这样如图所示:运行一下:
怎么解决如图所示:
以前我们是要带项目名搜索的如图所示:
现在经过上面的步骤就可以不需要带项目就能直接搜索到如图所示:
因为我们数据却了一个文件里放的就是图片所以我们要在里面新建一个文件夹放图片如图所示:
最终图片效果就出来了如图所示: