我们在添加或者编辑部门(用户)的时候,希望页面中部门这个字段呈现树形结构显示,让用户的体验效果更好点。效果图如下:
我们在做一个小的练习,完成树形结构的显示:
TreeViewPractice.java
package cn.xbmu.oa.test; import java.util.ArrayList; import java.util.Collection; import java.util.LinkedHashSet; import java.util.List; import java.util.Set; import org.junit.Test; import cn.xbmu.oa.domain.Department; /** * 说明:不能使用多层循环的方式,因为需要能支持任意层。 */ public class TreeViewPractice { /** * 练习一:打印所有顶层部门及其子孙部门的信息(名称) 提示:假设有一个 打印部门树 的信息 的方法 * * 要求打印如下效果: * * <pre> * 市场部 * 宣传部 * 业务部 * 业务一部 * 业务二部 * 开发部 * 开发一部 * 开发二部 * </pre> */ @Test public void printAllDepts_1() { List<Department> topList = findTopLevelDepartmentList(); /** * 方法一 for(Department top : topList){ showTree(top); } */ //方法二 showTreeList(topList); } //显示一棵树的信息 private void showTree(Department top){ //顶点 System.out.println(top.getName()); //子树 for(Department child : top.getChildren()){ showTree(child); } } //显示多颗树的信息 private void showTreeList(Collection<Department> topList){ for(Department top : topList){ //顶点 System.out.println(top.getName()); //子树 showTreeList(top.getChildren()); } } /** * 练习二:打印所有顶层部门及其子孙部门的信息(名称),用不同的缩进表示层次(使用全角空格)。<br> * 子部门的名称前比上级部门多一个空格,最顶层部门的名字前没有空格。 提示:假设有一个打印部门集合中所有部门信息的方法 * * 要求打印如下效果: * * <pre> * ┣市场部 * ┣宣传部 * ┣业务部 * ┣业务一部 * ┣业务二部 * ┣开发部 * ┣开发一部 * ┣开发二部 * </pre> */ @Test public void printAllDepts_2() { List<Department> topList = findTopLevelDepartmentList(); showTreeList_2(topList, "┣"); } //显示多棵树的信息 private void showTreeList_2(Collection<Department> topList,String prefix){ for(Department top : topList){ //顶点 System.out.println(prefix + top.getName()); //子树 showTreeList_2(top.getChildren(), " "+prefix); } } /** * 结构如下: * * <pre> * ┣市场部 * ┣宣传部 * ┣业务部 * ┣业务一部 * ┣业务二部 * ┣开发部 * ┣开发一部 * ┣开发二部 * </pre> * * @return 所有最顶层的部门的列表 */ public static List<Department> findTopLevelDepartmentList() { Department dept_1_1 = new Department(); dept_1_1.setId(new Long(11)); dept_1_1.setName("宣传部"); Department dept_1_2 = new Department(); dept_1_2.setId(new Long(12)); dept_1_2.setName("业务部"); Department dept_1_2_1 = new Department(); dept_1_2_1.setId(new Long(121)); dept_1_2_1.setName("业务一部"); Department dept_1_2_2 = new Department(); dept_1_2_2.setId(new Long(122)); dept_1_2_2.setName("业务二部"); dept_1_2_1.setParent(dept_1_2); dept_1_2_2.setParent(dept_1_2); Set<Department> children_0 = new LinkedHashSet<Department>(); children_0.add(dept_1_2_1); children_0.add(dept_1_2_2); dept_1_2.setChildren(children_0); // ================================ Department dept_1 = new Department(); dept_1.setId(new Long(1)); dept_1.setName("市场部"); dept_1_1.setParent(dept_1); dept_1_2.setParent(dept_1); Set<Department> children_1 = new LinkedHashSet<Department>(); children_1.add(dept_1_1); children_1.add(dept_1_2); dept_1.setChildren(children_1); // --- Department dept_2_1 = new Department(); dept_2_1.setId(new Long(21)); dept_2_1.setName("开发一部"); Department dept_2_2 = new Department(); dept_2_2.setId((new Long(22))); dept_2_2.setName("开发二部"); Department dept_2 = new Department(); dept_2.setId(new Long(2)); dept_2.setName("开发部"); dept_2_1.setParent(dept_2); dept_2_2.setParent(dept_2); Set<Department> children_2 = new LinkedHashSet<Department>(); children_2.add(dept_2_1); children_2.add(dept_2_2); dept_2.setChildren(children_2); // --- List<Department> depts = new ArrayList<Department>(); depts.add(dept_1); depts.add(dept_2); return depts; } }将上面树形结构的方法,应用的项目中去,项目中将写一个部门的工具类实现:
package cn.xbmu.oa.utils; import java.util.ArrayList; import java.util.Collection; import java.util.List; import cn.xbmu.oa.domain.Department; public class DepartmentUtils { /** * 遍历部门树,得到所有的部门列表,并修改了名称以表示层次 * @param topList * @return */ public static List<Department> getAllDepartments(List<Department> topList){ List<Department> list = new ArrayList<Department>(); walkDepartmentTrees(topList,"┣",list); return list; } /** * 遍历部门树,把遍历出来的部门都放到指定的集合中 * @param topList * @param string * @param list */ private static void walkDepartmentTrees(Collection<Department> topList, String prefix, List<Department> list) { for(Department top : topList){ //顶点 Department copy = new Department();// copy.setId(top.getId()); copy.setName(prefix+top.getName()); list.add(copy); //子树 walkDepartmentTrees(top.getChildren()," "+prefix, list); } } }DepartmentAction.java
package cn.xbmu.oa.view.action; import java.util.List; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Controller; import cn.xbmu.oa.base.BaseAction; import cn.xbmu.oa.domain.Department; import cn.xbmu.oa.utils.DepartmentUtils; import com.opensymphony.xwork2.ActionContext; @Controller @Scope("prototype") public class DepartmentAction extends BaseAction<Department> { private Long parentId; public String list() throws Exception { List<Department> departmentList = departmentService.findAll(); ActionContext.getContext().put("departmentList", departmentList); return "list"; } public String delete() throws Exception { departmentService.delete(model.getId()); return "toList"; } public String editUI() throws Exception { // 准备数据,departmentList,显示为树形结构 List<Department> topList = departmentService.findTopList(); List<Department> departmentList = DepartmentUtils .getAllDepartments(topList); ActionContext.getContext().put("departmentList", departmentList); // 准备回显信息 Department department = departmentService.getById(model.getId()); ActionContext.getContext().getValueStack().push(department); if (department.getParent() != null) { parentId = department.getParent().getId(); } return "saveUI"; } public String edit() throws Exception { // 1.从数据库中取出原对象 Department department = departmentService.getById(model.getId()); // 2.设置要修改的属性 department.setName(model.getName()); department.setDescription(model.getDescription()); department.setParent(departmentService.getById(parentId));// 上级部门 // 3.更新到数据库中 departmentService.update(department); return "toList"; } public String addUI() throws Exception { // 准备数据,departmentList,显示为树形结构 List<Department> topList = departmentService.findTopList(); List<Department> departmentList = DepartmentUtils .getAllDepartments(topList); ActionContext.getContext().put("departmentList", departmentList); return "saveUI"; } public String add() throws Exception { // 1.新建对象并封装属性,也可以使用model if (parentId != null) { model.setParent(departmentService.getById(parentId)); } // 2.保存到数据库中 departmentService.save(model); return "toList"; } // ------------------------------------------------ public Long getParentId() { return parentId; } public void setParentId(Long parentId) { this.parentId = parentId; } }UserAction.java
package cn.xbmu.oa.view.action; import java.util.HashSet; import java.util.List; import org.apache.commons.codec.digest.DigestUtils; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Controller; import com.opensymphony.xwork2.ActionContext; import cn.xbmu.oa.base.BaseAction; import cn.xbmu.oa.domain.Department; import cn.xbmu.oa.domain.Role; import cn.xbmu.oa.domain.User; import cn.xbmu.oa.utils.DepartmentUtils; @Controller @Scope("prototype") public class UserAction extends BaseAction<User> { private Long departmentId; private Long[] roleIds; public String list() throws Exception { List<User> userList = userSerivce.findAll(); ActionContext.getContext().put("userList", userList); return "list"; } public String delete() throws Exception { userSerivce.delete(model.getId()); return "toList"; } public String addUI() throws Exception { // 准备数据,departmentList,显示为树形结构 List<Department> topList = departmentService.findTopList(); List<Department> departmentList = DepartmentUtils .getAllDepartments(topList); ActionContext.getContext().put("departmentList", departmentList); // 准备数据,roleList List<Role> roleList = roleService.findAll(); ActionContext.getContext().put("roleList", roleList); return "saveUI"; } public String add() throws Exception { // 1.新建对象并设属性(也可以使用model) Department department = departmentService.getById(departmentId); model.setDepartment(department); List<Role> roleList = roleService.getByIds(roleIds); model.setRoles(new HashSet<Role>(roleList)); String passwdMD5 = DigestUtils.md5Hex("1234"); model.setPassword(passwdMD5);// 默认密码为1234,应使用MD5加密 // 2.保存到数据库 userSerivce.save(model); return "toList"; } public String editUI() throws Exception { // 准备数据,departmentList,显示为树形结构 List<Department> topList = departmentService.findTopList(); List<Department> departmentList = DepartmentUtils .getAllDepartments(topList); ActionContext.getContext().put("departmentList", departmentList); // 准备数据,roleList List<Role> roleList = roleService.findAll(); ActionContext.getContext().put("roleList", roleList); // 准备回显的数据 User user = userSerivce.getById(model.getId()); ActionContext.getContext().getValueStack().push(user); if (user.getDepartment() != null) { departmentId = user.getDepartment().getId(); } if (user.getRoles().size() > 0) { roleIds = new Long[user.getRoles().size()]; int index = 0; for (Role role : user.getRoles()) { roleIds[index++] = role.getId(); } } return "saveUI"; } public String edit() throws Exception { // 1,从数据库中取出原对象 User user = userSerivce.getById(model.getId()); // 2,设置要修改的属性 // >> 普通属性 user.setLoginName(model.getLoginName()); user.setName(model.getName()); user.setGender(model.getGender()); user.setPhoneNumber(model.getPhoneNumber()); user.setEmail(model.getEmail()); user.setDescription(model.getDescription()); // >> 所属部门 Department department = departmentService.getById(departmentId); user.setDepartment(department); // >> 关联的岗位 List<Role> roleList = roleService.getByIds(roleIds); user.setRoles(new HashSet<Role>(roleList)); // 3,更新到数据库 userSerivce.update(user); return "toList"; } /** 初始化密码 */ public String initPassword() throws Exception { // 1.从数据库中取出原对象 User user = userSerivce.getById(model.getId()); // 2.设置要修改的属性(要使用MD5摘要) String passwdMD5 = DigestUtils.md5Hex("1234"); user.setPassword(passwdMD5); // 3.更新到数据库 userSerivce.update(user); return "toList"; } // -------------------------------------- public Long getDepartmentId() { return departmentId; } public void setDepartmentId(Long departmentId) { this.departmentId = departmentId; } public Long[] getRoleIds() { return roleIds; } public void setRoleIds(Long[] roleIds) { this.roleIds = roleIds; } }DepartmentService.java
package cn.xbmu.oa.service; import java.util.List; import cn.xbmu.oa.base.BaseDao; import cn.xbmu.oa.domain.Department; public interface DepartmentService extends BaseDao<Department>{ /** * 查询所有顶级部门的列表 * @return */ List<Department> findTopList(); }DepartmentServiceImpl.java
package cn.xbmu.oa.service.impl; import java.util.List; import org.springframework.stereotype.Service; import cn.xbmu.oa.base.BaseDaoImpl; import cn.xbmu.oa.domain.Department; import cn.xbmu.oa.service.DepartmentService; @Service @SuppressWarnings("unchecked") public class DepartmentServiceImpl extends BaseDaoImpl<Department> implements DepartmentService { public List<Department> findTopList() { return getSession().createQuery(// "FROM Department d WHERE d.parent IS NULL")// .list(); } }
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <%@ taglib prefix="s" uri="/struts-tags" %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <title>部门列表</title> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <script language="javascript" src="${pageContext.request.contextPath}/script/jquery.js"></script> <script language="javascript" src="${pageContext.request.contextPath}/script/pageCommon.js" charset="utf-8"></script> <script language="javascript" src="${pageContext.request.contextPath}/script/PageUtils.js" charset="utf-8"></script> <link type="text/css" rel="stylesheet" href="${pageContext.request.contextPath}/style/blue/pageCommon.css" /> <script type="text/javascript"> </script> </head> <body> <div id="Title_bar"> <div id="Title_bar_Head"> <div id="Title_Head"></div> <div id="Title"><!--页面标题--> <img border="0" width="13" height="13" src="${pageContext.request.contextPath}/style/images/title_arrow.gif"/> 部门管理 </div> <div id="Title_End"></div> </div> </div> <div id="MainArea"> <table cellspacing="0" cellpadding="0" class="TableStyle"> <!-- 表头--> <thead> <tr align=center valign=middle id=TableTitle> <td width="150px">部门名称</td> <td width="150px">上级部门名称</td> <td width="200px">职能说明</td> <td>相关操作</td> </tr> </thead> <!--显示数据列表--> <tbody id="TableData" class="dataContainer" datakey="departmentList"> <s:iterator value="#departmentList"> <tr class="TableDetail1 template"> <td><s:a action="departmentAction_list?parentId=%{id}">${name}</s:a> </td> <td>${parent.name} </td> <td>${description} </td> <td> <s:a onClick="return window.confirm('这将删除所有的下级部门,您确定要删除吗?')" action="departmentAction_delete?id=%{id}&parentId=%{parent.id}">删除</s:a> <s:a action="departmentAction_editUI?id=%{id}">修改</s:a> </td> </tr> </s:iterator> </tbody> </table> <!-- 其他功能超链接 --> <div id="TableTail"> <div id="TableTail_inside"> <s:a action="departmentAction_addUI?parentId=%{parentId}"><img src="${pageContext.request.contextPath}/style/images/createNew.png" /></s:a> <s:if test="#parent != null"> <s:a action="departmentAction_list?parentId=%{#parent.parent.id}"><img src="${pageContext.request.contextPath}/style/images/ReturnToPrevLevel.png" /></s:a> </s:if> </div> </div> </div> <!--说明--> <div id="Description"> 说明:<br /> 1,列表页面只显示一层的(同级的)部门数据,默认显示最顶级的部门列表。<br /> 2,点击部门名称,可以查看此部门相应的下级部门列表。<br /> 3,删除部门时,同时删除此部门的所有下级部门。 </div> </body> </html>