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中

云oa系统架构 oa办公系统架构_验证码

前端页面的name属性就应该这么写了

用户名

云oa系统架构 oa办公系统架构_User_02

密码

云oa系统架构 oa办公系统架构_List_03

验证码

云oa系统架构 oa办公系统架构_List_04

控制层

@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中的

云oa系统架构 oa办公系统架构_User_05

 

 

    查出这个部门包含的所有角色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;
		}
		
	}
}