OA系统
【项目介绍】
本项目基于b/s架构,实现功能模块如下:
用户登录模块(用户登录、成功则进入主页,否则提示出错信息,登录拦截)
组织结构模块( 加载主页面时, 查询部门表, 显示所有部门信息并带有分页)
权限模块(登陆后显示对应的菜单、拦截用户不具备权限的请求)
考勤管理模块(上下班登记、我的考勤管理、考勤统计)
公文管理模块(公文设计,公文发起,公文流转)
......
【环境搭建】
maven项目搭建参考maven那一章,配置文件参考crm第一章
【登录功能】
主要是一个验证码功能的实现
流程:登录页面加载完毕,发送一个ajax请求到服务器获取验证码
$.get("/oa_maven_ssm/User/checkCode.action",function(data){
$("#code_value").text(data);
});
$("#code_value").click(function(){
$.get("/oa_maven_ssm/User/checkCode.action",function(data){
$("#code_value").text(data);
});
})
控制层首先要移除session中的用户对象和验证码.(有种情况是在已经登录情况下访问登录页面)
获取验证码的方法(service层):
@Override
public String getCode() {
String str = "";
char[] ch = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I',
'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd',
'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y',
'z' };
Random random = new Random();
for (int i = 0; i < 4; i++) {
char num = ch[random.nextInt(ch.length)];
str += num;
}
System.out.println(str);
return str;
}
放到session中.ajax回调函数把验证码渲染到页面
用户输入用户名,密码,验证码点击登录按钮,发送到服务器对应的方法
注意:这里用了queryvo对象,把用户名,密码,验证码放在queryvo中
前端页面的name属性就应该这么写了
用户名
密码
验证码
控制层
@RequestMapping(value="/login.action", method=RequestMethod.POST)
public String login(QueryVo vo,HttpSession session, Model model){
System.out.println(vo);
try {
//去业务逻辑层判断数据是否正确 ,要获取session里面的验证码
User user = us.checkUserAndCode(vo, session);
//登入成功后,进入main.jsp页面
session.setAttribute("user", user);
return "redirect:/main.jsp";
} catch (Exception e) {
e.printStackTrace();
model.addAttribute("queryVo", vo);
model.addAttribute("errorMeg", e.getMessage());
return "/login.jsp";
}
}
调用service层去验证验证码,用户名密码
@Override
public User checkUserAndCode(QueryVo vo,HttpSession session) throws Exception {
if (session.getAttribute("code") == null ) {
throw new Exception("验证码为空");
}
if(!session.getAttribute("code").toString().toLowerCase().equals(vo.getCode().toLowerCase())){
throw new Exception("验证码错误");
}
UserExample example = new UserExample();
Criteria criteria = example.createCriteria();
criteria.andUnameEqualTo(vo.getUser().getUname());
List<User> list = um.selectByExample(example);
if (list != null && list.size() > 0) {
User user = list.get(0);
String upwd = vo.getUser().getUpwd();
String md5 = MD5Utils.md5(upwd);
if (user.getUpwd().equals(md5)) {
return user;
} else {
throw new Exception("密码错误");
}
} else {
throw new Exception("用户名不存在");
}
}
【组织结构模块】
任务:
main页面中, 左侧最后一个选项改为组织结构
表结构:
部门表 (一对多) 角色表 (多对多) 用户表
流程:
1. 加载main页面时, 查询部门表, 显示所有部门信息
main页面发送ajax请求
//加载此页面后,去请求拿到数据库中所有部门的名字数据
$(function() {
$.get("/oa_maven_ssm/depttable/getDepartment.action",
//回调函数后面再看
function(data) {
//对data进行遍历,i的意思是索引,n表示每一个元素
$.each(data,function(i, n) {
//要加转义字符
拼接字符串<li href=""><a></a></li>的形式,注意,这里a标签的href没用,起作用的是li的href
var str = "<li class=\"subnav-li\" href=\"${pageContext.request.contextPath}/depttable/list.action?department.departmentid="
//取出n元素中的departmentid属性
+ n['departmentid']
+ "\" data-id=\""
//模版的特殊性,每一个菜单项要不同的data-id
+ (100 + i)
+ "\"><a class=\"ue-clear\"><i class=\"subnav-icon\"></i><span class=\"subnav-text\">"
+ n['departmentname']
+ "</span></a></li>"
$("#subnav").append(str);
})
}, "json");
});
控制层
@RequestMapping(value="/getDepartment.action", produces="application/json; charset=utf-8")
@ResponseBody
public String getDepartment(){
//获取部门
List<Department> list = dts.getAllDepartment();
String json = new Gson().toJson(list);
System.out.println(json);
return json;
}
部门表的表结构中同时具有部门id和部门名,所以直接查询所有即可.
ajax函数循环组装左侧菜单,,填充到jsp页面(ajax函数代码在前面)
<li class="nav-li last-nav-li">
<a href="javascript:;"class="ue-clear">
<i class="nav-ivon"></i>
<span class="nav-text">组织结构</span>
</a>
<ul id="subnav" class="subnav">
</ul>
</li>
2. 左侧菜单栏点击某个部门信息, 发送部门id给后台,
前面组装的url地址栏如下,
${pageContext.request.contextPath}/depttable/list.action?department.departmentid=
departmentid是放在queryvo中的
查出这个部门包含的所有角色id(角色表)
根据这些角色id, 查出对应的用户id(用户角色表)
根据这些用户id, 查出对应的用户po(用户表),查出他们所对应的角色
注意:用户和角色的关系是多对多关系!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
把UserPo -> UserVo (用户姓名, 所在部门名, 角色名(List))
service层!
@Override
public PageBean<UserVo> getUserListOfDepartment(QueryVo vo) {
List<UserVo> voList = new ArrayList<>();
Integer departmentid = vo.getDepartment().getDepartmentid();
// 拿着部门id去角色表中查到所有的角色id
RoleExample roleExample = new RoleExample();
cn.zzpigt.bean.RoleExample.Criteria roleCriteria = roleExample.createCriteria();
roleCriteria.andDepartmentidEqualTo(departmentid);
List<Role> roleList = roleMapper.selectByExample(roleExample);
// 拿着这些角色id去用户角色表中查到对应的用户id
for (Role role : roleList) {
// 每个角色对应着多个用户
UserRoleExample userRoleExample = new UserRoleExample();
cn.zzpigt.bean.UserRoleExample.Criteria userRoleCriteria = userRoleExample.createCriteria();
userRoleCriteria.andRoleidEqualTo(role.getRoleid());
List<UserRole> urList = userRoleMapper.selectByExample(userRoleExample);
for (UserRole userRole : urList) {
// 更加这些用户id拿到用户po,最后po变Vo
User user = um.selectByPrimaryKey(userRole.getUserid());
// 最后po变Vo
UserVo userVo = new UserVo(user);
// 领导人的名字放进去
userVo.setLeaderid(um.selectByPrimaryKey(user.getLeaderid()));
// 所属部门放进去
userVo.setDepartment(departmentMapper.selectByPrimaryKey(departmentid));
// 所属角色,对应多个角色,是List
UserRoleExample userRoleExample2 = new UserRoleExample();
cn.zzpigt.bean.UserRoleExample.Criteria userRoleCriteria2 = userRoleExample2.createCriteria();
userRoleCriteria2.andUseridEqualTo(user.getUserid());
List<UserRole> urList2 = userRoleMapper.selectByExample(userRoleExample2);
List<Role> rList = new ArrayList<>();
for (UserRole userRole2 : urList2) {
System.out.println(userRole2);
rList.add(roleMapper.selectByPrimaryKey(userRole2.getRoleid()));
}
System.out.println(rList);
userVo.setRoleList(rList);
// 最后这个vo对象放到volist中
System.out.println(userVo);
voList.add(userVo);
}
}
// 返回的就是拿到的userVo,没有分页功能,因为这不是一个表中拿到所有数据
// 用subList方法截取list,得到的就是需要的数据
PageBean<UserVo> pageBean = new PageBean<>(vo.getPageNum(), vo.getPageSize(), voList.size());
//这里的subList第二个参数是判断是不是最后一页,如果是访问的页数大于总页数,那么就取最后一页
pageBean.setList(voList.subList(pageBean.getStart(),
pageBean.getPageSize() + pageBean.getStart() < pageBean.getTotalCount()
? pageBean.getStart() + pageBean.getPageSize()
: pageBean.getTotalCount()));
for (UserVo vo2 : voList) {
System.out.println("这是拿到了的uservo:" + vo2);
}
return pageBean;
}
uservo对象
public class UserVo {
private Integer userid;
private String uname;
private String upwd;
private String nickname;
private User leaderid;
private String face;
//部门
private Department department;
private List<Role> roleList;
在右侧表格中(table.html)显示出这个部门的所有员工
提示: 分页可以试着使用mybatis分页插件(百度)
结果并不能用,只能用List的sublist方法(见service层)
【登录拦截】
禁止用户在未登陆情况下访问动态资源,添加一个拦截器用于拦截
springmvc.xml文件的配置
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**" />
<!-- 登录拦截器 -->
<bean class="cn.zzpigt.interceptor.LoginInterceptor" />
</mvc:interceptor>
</mvc:interceptors>
LoginInterceptor类:
public class LoginInterceptor implements HandlerInterceptor{
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object obj) throws Exception {
System.out.println(request.getRequestURI());
User user = (User) request.getSession().getAttribute("user");
if(user != null || request.getRequestURI().contains("login") || request.getRequestURI().contains("checkCode")){
System.out.println("登入通过:" + request.getRequestURI());
return true;
}else{
System.out.println("登入拦截了:" + request.getRequestURI());
response.sendRedirect(request.getContextPath() + "/User/login.action");
return false;
}
}
}