目录
OA项目之项目简介
功能简介:
系统管理(用户表的增删改查)
会议管理(发起会议->会议审批->会议投票)(会议信息表,通知反馈表,投票标题选项表,投票记录表)
会议室管理(安排开会地点)(会议室信息表)
注意:
参会人员:具有投票权
列席人员:具有知情权,不具备投票权
谁发起的会议谁便是主持人
会议发布
要完成图下的功能
1、多功能下拉框上
我们要实现多功能下拉框 要使用layui之formSelects多选组件定义及动态数据绑定
文档地址:formSelects 基于Layui的多选解决方案
下载地址:https://github.com/hnzzmsf/layui-formSelects
文档打开:
下载地址:
解压后:
我们需要:
将我们需要的js和css文件导入
header.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<link rel="stylesheet"
href="${pageContext.request.contextPath }/static/js/layui/css/layui.css">
<!-- 引入layui.js -->
<script type="text/javascript"
src="${pageContext.request.contextPath }/static/js/layui/layui.js"></script>
<!-- 引入formSelects核心css -->
<link rel="stylesheet" href="${pageContext.request.contextPath }/static/js/plugins/formSelects/formSelects-v4.css" />
<!-- 引入formSelects核心js -->
<script src="${pageContext.request.contextPath }/static/js/plugins/formSelects/formSelects-v4.js" type="text/javascript" charset="utf-8"></script>
<!-- 指定整个项目的根路径 -->
<base href="${pageContext.request.contextPath }/"/>
<input id="ctx" value="${pageContext.request.contextPath }" type="hidden"/>
<title>玉渊工作室</title>
在static->js->建一个meeting的文件夹
在改meeting文件夹中写一个addMeeting.js
在 在线文档中找到需要的btns 添加多功能下拉框选项
addMeeting.js
let $,formSelects;
layui.use(['jquery','formSelects'],function(){
$=layui.jquery
,formSelects=layui.formSelects;
formSelects.btns('canyuze', ['select', 'remove', 'reverse']);
formSelects.btns('liexize', ['select', 'remove', 'reverse']);
});
效果:
绑定数据 在在线文档中找到对应的模块
将local模式放入addMeeting.js中 运行看下有没有效果
如图可见 有效果 证明是没有问题可以进行下一步操作了
分析addMeeting.js中的数据可以知道 需要name和value的格式数据,那么sql语句应为
select id as value,name from t_oa_user
可得
2、 多功能下拉框下及会议新增
①、多功能下拉框下
UserDao
package com.zking.dao;
import java.sql.SQLException;
import java.util.List;
import java.util.Map;
import com.zking.entity.User;
import com.zking.util.BaseDao;
import com.zking.util.PageBean;
public class UserDao extends BaseDao<User> {
public User login(User user) throws Exception {
String sql = "select * from t_oa_user where loginName='"+user.getLoginName()+"' and pwd='"+user.getPwd()+"' ";
// return super.executeQuery(sql, clz, pageBean);
//根据sql查询符合条件的用户,通常只会返回一条数据
List<User> users = super.executeQuery(sql, User.class,null);
return users == null || users.size() == 0 ? null : users.get(0);
}
// 查询用户信息及对应的角色 角色是通过case when得到的
public List<Map<String, Object>> list(User user,PageBean pageBean) throws Exception{
String sql = "select * \r\n " +
", \r\n " +
"(case rid \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" +
"else '其他' end ) roleName \r\n" +
"FROM t_oa_user where 1 = 1";
String name = user.getName();
if(com.zking.util.StringUtils.isNotBlank(name)) {
sql += " and name like '%"+name+"%'";
}
//当实体类的属性完全包含数据库查询出来的列段的时候使用
// super.executeQuery(sql, User.class, pageBean) 返回List<Map<String, Object>>,对应的是联表查询,单个实体类对象,不完全包含查询的列段
return super.executeQuery(sql, pageBean);
}
//查询所有用户 用于绑定多功能下拉框
public List<Map<String, Object>> queryUserAll(User user,PageBean pageBean) throws Exception{
String sql = "select id as value,name from t_oa_user";
return super.executeQuery(sql, pageBean);
}
public int add(User user) throws Exception {
String sql = "insert into t_oa_user(name,loginName,pwd) values(?,?,?)";
return super.executeUpdate(sql,user,new String[] {"name","loginName","pwd"});
}
public int del(User user) throws Exception {
String sql = "delete from t_oa_user where id=?";
return super.executeUpdate(sql,user,new String[] {"id"});
}
public int edit(User user) throws Exception {
String sql = "update t_oa_user set name=?,loginName=?,pwd=? where id=?";
return super.executeUpdate(sql,user,new String[] {"name","loginName","pwd","id"});
}
}
UserAction
package com.zking.web;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.catalina.util.RequestUtil;
import com.zking.dao.UserDao;
import com.zking.entity.User;
import com.zking.framework.ActionSupport;
import com.zking.framework.ModelDriver;
import com.zking.util.PageBean;
import com.zking.util.R;
import com.zking.util.ResponseUtil;
public class UserAction extends ActionSupport implements ModelDriver<User>{
private User user = new User();
private UserDao userDao = new UserDao();
public String login(HttpServletRequest req, HttpServletResponse resp) {
try {
User u = userDao.login(user);
//通过账户名密码查到了用户记录
if(u != null) {
// 登录成功
//ResponseUtil.writeJson(resp, new R().data("code", 200).data("msg","成功"));
ResponseUtil.writeJson(resp, R.ok(200, "成功"));
}
else {
// 登录失败
//ResponseUtil.writeJson(resp, new R().data("code",0).data("msg","账户或密码错误"));
ResponseUtil.writeJson(resp, R.error(0, "账户或密码错误"));
}
} catch (Exception e) {
// TODO: handle exception
}
return null;
}
//用户查询
public String list(HttpServletRequest req, HttpServletResponse resp) {
try {
PageBean pageBean = new PageBean();
pageBean.setRequest(req);
List<Map<String, Object>> users = userDao.list(user, pageBean);
// 注意:layui中的数据表格的格式
ResponseUtil.writeJson(resp, R.ok(0, "用户数据查询成功",pageBean.getTotal(),users));
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
try {
ResponseUtil.writeJson(resp, R.error(0, "用户数据查询失败"));
} catch (Exception e2) {
// TODO: handle exception
e2.printStackTrace();
}
}
return null;
}
//查询所有用户用于绑定多功能下拉框
public String queryUserAll(HttpServletRequest req, HttpServletResponse resp) {
try {
List<Map<String, Object>> users = userDao.queryUserAll(user, null);
// 注意:layui中的数据表格的格式
ResponseUtil.writeJson(resp, R.ok(0, "多功能下拉框数据查询成功",users));
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
try {
ResponseUtil.writeJson(resp, R.error(0, "多功能下拉框数据查询失败"));
} catch (Exception e2) {
// TODO: handle exception
e2.printStackTrace();
}
}
return null;
}
public String add(HttpServletRequest req, HttpServletResponse resp) {
try {
//影响行数
int rs = userDao.add(user);
if(rs>0) {
ResponseUtil.writeJson(resp, R.ok(200, "用户数据新增成功"));
}
else {
ResponseUtil.writeJson(resp, R.error(0, "用户数据新增失败"));
}
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
try {
ResponseUtil.writeJson(resp, R.error(0, "用户数据查询失败"));
} catch (Exception e2) {
// TODO: handle exception
e2.printStackTrace();
}
}
return null;
}
public String del(HttpServletRequest req, HttpServletResponse resp) {
try {
//影响行数
int rs = userDao.del(user);
if(rs>0) {
ResponseUtil.writeJson(resp, R.ok(200, "用户数据删除成功"));
}
else {
ResponseUtil.writeJson(resp, R.error(0, "用户数据删除失败"));
}
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
try {
ResponseUtil.writeJson(resp, R.error(0, "用户数据删除失败"));
} catch (Exception e2) {
// TODO: handle exception
e2.printStackTrace();
}
}
return null;
}
public String edit(HttpServletRequest req, HttpServletResponse resp) {
try {
//影响行数
int rs = userDao.edit(user);
if(rs>0) {
ResponseUtil.writeJson(resp, R.ok(200, "用户数据修改成功"));
}
else {
ResponseUtil.writeJson(resp, R.error(0, "用户数据修改失败"));
}
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
try {
ResponseUtil.writeJson(resp, R.error(0, "用户数据修改失败"));
} catch (Exception e2) {
// TODO: handle exception
e2.printStackTrace();
}
}
return null;
}
@Override
public User getModel() {
return user;
}
}
在addMeeting.js中测试一下
let $,formSelects;
layui.use(['jquery','formSelects'],function(){
$=layui.jquery
,formSelects=layui.formSelects;
// 添加多功能下拉框选项
formSelects.btns('canyuze', ['select', 'remove', 'reverse']);
formSelects.btns('liexize', ['select', 'remove', 'reverse']);
$.getJSON("user.action",{methodName:"queryUserAll"},function(rs){
console.log(rs);
});
//local模式
formSelects.data('canyuze', 'local', {
arr: [
{"name": "广州", "value": 3},
{"name": "深圳", "value": 4},
{"name": "天津", "value": 5}
]
});
});
若像如图这样的错误 并且在之前已经拿到数据却报错
错误代码:
let $,formSelects;
layui.use(['jquery','formSelects'],function(){
$=layui.jquery
,formSelects=layui.formSelects;
// 添加多功能下拉框选项
formSelects.btns('canyuze', ['select', 'remove', 'reverse']);
formSelects.btns('liexize', ['select', 'remove', 'reverse']);
$.getJSON("user.action",{methodName:"queryUserAll"},function(rs){
console.log(rs);
});
//local模式
formSelects.data('canyuze', 'local', {
arr:rs.data
});
});
解决办法:看绑定数据的代码是否在得到json方法里面
正确代码
let $,formSelects;
layui.use(['jquery','formSelects'],function(){
$=layui.jquery
,formSelects=layui.formSelects;
// 添加多功能下拉框选项
formSelects.btns('canyuze', ['select', 'remove', 'reverse']);
formSelects.btns('liexize', ['select', 'remove', 'reverse']);
$.getJSON("user.action",{methodName:"queryUserAll"},function(rs){
console.log(rs);
//local模式
formSelects.data('canyuze', 'local', {
arr: rs.data
});
});
});
运行效果:
将列席者实现与参与者一样的效果
addMeeting.js
let $,formSelects;
layui.use(['jquery','formSelects'],function(){
$=layui.jquery
,formSelects=layui.formSelects;
// 添加多功能下拉框选项
formSelects.btns('canyuze', ['select', 'remove', 'reverse']);
formSelects.btns('liexize', ['select', 'remove', 'reverse']);
$.getJSON("user.action",{methodName:"queryUserAll"},function(rs){
console.log(rs);
//local模式
formSelects.data('canyuze','local', {
arr: rs.data
});
formSelects.data('liexize','local', {
arr: rs.data
});
});
});
效果:
要实现会议时间的范围选择 进入layui官网:日期和时间组件文档 - Layui
addMeeting.js
let $,formSelects,laydate;
layui.use(['jquery','formSelects'],function(){
$=layui.jquery
,formSelects=layui.formSelects
,laydate=layui.laydate;
// 添加多功能下拉框选项
formSelects.btns('canyuze', ['select', 'remove', 'reverse']);
formSelects.btns('liexize', ['select', 'remove', 'reverse']);
$.getJSON("user.action",{methodName:"queryUserAll"},function(rs){
console.log(rs);
//local模式
formSelects.data('canyuze','local', {
arr: rs.data
});
formSelects.data('liexize','local', {
arr: rs.data
});
});
//日期时间范围
laydate.render({
elem: '#dt'
,type: 'datetime'
,range: true
});
});
结果:
②.会议新增
如何提交form表单
写一个实体类MeetingInfo
package com.zking.entity;
import java.util.Date;
//数据库会议信息表t_oa_meeting_info对应的实体类
public class MeetingInfo {
private Long id;
private String title;
private String content;
private String canyuze;
private String liexize;
private String zhuchiren;
private String location;
private Date startTime;
private Date endTime;
private String fujian;
private Integer state;
private String seatPic;
private String remark;
private String auditor;
public String getAuditor() {
return auditor;
}
public void setAuditor(String auditor) {
this.auditor = auditor;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public String getCanyuze() {
return canyuze;
}
public void setCanyuze(String canyuze) {
this.canyuze = canyuze;
}
public String getLiexize() {
return liexize;
}
public void setLiexize(String liexize) {
this.liexize = liexize;
}
public String getZhuchiren() {
return zhuchiren;
}
public void setZhuchiren(String zhuchiren) {
this.zhuchiren = zhuchiren;
}
public String getLocation() {
return location;
}
public void setLocation(String location) {
this.location = location;
}
public Date getStartTime() {
return startTime;
}
public void setStartTime(Date startTime) {
this.startTime = startTime;
}
public Date getEndTime() {
return endTime;
}
public void setEndTime(Date endTime) {
this.endTime = endTime;
}
public String getFujian() {
return fujian;
}
public void setFujian(String fujian) {
this.fujian = fujian;
}
public Integer getState() {
return state;
}
public void setState(Integer state) {
this.state = state;
}
public String getSeatPic() {
return seatPic;
}
public void setSeatPic(String seatPic) {
this.seatPic = seatPic;
}
public String getRemark() {
return remark;
}
public void setRemark(String remark) {
this.remark = remark;
}
public MeetingInfo() {
super();
// TODO Auto-generated constructor stub
}
@Override
public String toString() {
return "MeetingInfo [id=" + id + ", title=" + title + ", content=" + content + ", canyuze=" + canyuze
+ ", liexize=" + liexize + ", zhuchiren=" + zhuchiren + ", location=" + location + ", startTime="
+ startTime + ", endTime=" + endTime + ", fujian=" + fujian + ", state=" + state + ", seatPic=" + seatPic + ", remark=" + remark + "]";
}
}
MeetingInfoDao
package com.zking.dao;
import com.zking.entity.MeetingInfo;
import com.zking.util.BaseDao;
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"});
}
}
MeetingInfoAction
package com.zking.web;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.zking.dao.MeetingInfoDao;
import com.zking.entity.MeetingInfo;
import com.zking.framework.ActionSupport;
import com.zking.framework.ModelDriver;
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() {
return info;
}
public String add(HttpServletRequest req, HttpServletResponse resp) {
try {
//影响行数
int rs = infoDao.add(info);
if(rs>0) {
ResponseUtil.writeJson(resp, R.ok(200, "会议信息数据新增成功"));
}
else {
ResponseUtil.writeJson(resp, R.error(0, "会议信息数据新增失败"));
}
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
try {
ResponseUtil.writeJson(resp, R.error(0, "会议信息数据新增失败"));
} catch (Exception e2) {
// TODO: handle exception
e2.printStackTrace();
}
}
return null;
}
}
mvc.xml
<?xml version="1.0" encoding="UTF-8"?>
<config>
<action path="/user" type="com.zking.web.UserAction">
</action>
<action path="/permission" type="com.zking.web.PermissionAction">
</action>
<action path="/info" type="com.zking.web.MeetingInfoAction">
</action>
</config>
从登录界面进去 填完发布会议的立即提交 时 控制台会报错
原因:前端拿的时间时string类型 实体类时date类型
MeetingInfoAction
package com.zking.web;
import java.sql.Date;
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.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 {
//影响行数
int rs = infoDao.add(info);
if(rs>0) {
ResponseUtil.writeJson(resp, R.ok(200, "会议信息数据新增成功"));
}
else {
ResponseUtil.writeJson(resp, R.error(0, "会议信息数据新增失败"));
}
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
try {
ResponseUtil.writeJson(resp, R.error(0, "会议信息数据新增失败"));
} catch (Exception e2) {
// TODO: handle exception
e2.printStackTrace();
}
}
return null;
}
}
从登录进去