组织机构层级关系设计优化
2017-04-11 17:51
260 查看
本文是基于层级设计以及算法,treetable的实现来说的。
新增:新增通过父节点计算自己是第几个孩子,上篇文章已有描述。
@RequiresPermissions(value = { "dep.save" })
@RequestMapping(value="/save")
@ResponseBody
public String save(Department department,HttpSession session){
Integer uid = (Integer)session.getAttribute("uid");
department.setCreater(uid);
department.setCreateTime(new Date());
department.setDelFlag("0");
int cnt = departmentService.countByPid(department.getPid() == null ? 0 : department.getPid());
Department pdep = departmentService.single(department.getPid()== null ? 0 : department.getPid());
String pseq = pdep == null ? "1" : pdep.getSeq();
department.setSeq(pseq + "." + convertCount(cnt));
departmentService.save(department);
return "SUCCESS";
}
修改:修改可以更改部门的从属关系,这里比较复杂,利用递归算法,每个层级都修改其父节点集和排序号。
@RequiresPermissions(value = { "dep.update" })
@RequestMapping(value="/update", produces="text/plain; charset=UTF-8")
@ResponseBody
public String update(Department department, Integer oldPid, HttpSession session){
if(department.getId().equals(department.getPid()))
return "不可以设置自己为自己的父级";
if(department.getPids().contains(String.valueOf(department.getId())))
return "不能将上级部门设置为本部门或本部门下的子部门";
Integer uid = (Integer)session.getAttribute("uid");
if(!oldPid.equals(department.getPid())){
int cnt = departmentService.countByPid(department.getPid()== null ? 0 : department.getPid());
Department pdep = departmentService.single(department.getPid()== null ? 0 : department.getPid());
String pseq = pdep == null ? "1" : pdep.getSeq();
department.setSeq(pseq + "." + convertCount(cnt));
}
department.setUpdater(uid);
department.setUpdateTime(new Date());
departmentService.update(department);
//修改上级部门更改涉及的部门(其子部门)关系问题,如:pids,seq
updateRelation(department.getId(), uid);
return "SUCCESS";
}
删除:删除时删除该节点及其子节点级以及子节点的子节点,主要是设计数据库的时候利用pids记录了其父子关系。
/**
* 删除部门(逻辑删除)
* @param department
* @param session
* @return
*/
@RequiresPermissions(value = {"dep.delete"})
@RequestMapping(value="/delete", produces="text/plain; charset=UTF-8")
@ResponseBody
public String delete(Department department, HttpSession session){
String pids = departmentService.findLastLeaf(department.getId());
boolean hasUser = departmentService.hasUser(pids);
if(hasUser)
return "该部门或其子部门有用户,不允许删除!";
Integer uid = (Integer)session.getAttribute("uid");
department.setUpdater(uid);
department.setUpdateTime(new Date());
department.setDelFlag("1");
departmentService.delete(department);
return "SUCCESS";
}
mapper:主要是查找子节点,使用到了find_in_set 函数。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.saidian.dao.DepartmentDao">
<insert id="save" parameterType="com.saidian.entity.Department"
useGeneratedKeys="true" keyProperty="id">
INSERT INTO t_department(
<include refid="columns"></include>
)VALUES(
#{id},#{name},#{pid},#{pids},#{remark},#{creater},#{createTime},#{updater},#{updateTime},#{delFlag},#{seq}
)
</insert>
<update id="update" parameterType="com.saidian.entity.Department">
UPDATE t_department
<trim prefix="SET" suffixOverrides=",">
<if test="name neq null">name=#{name},</if>
<if test="pid neq null">pid=#{pid},</if>
<if test="pids neq null">pids=#{pids},</if>
<if test="remark neq null">remark=#{remark},</if>
<if test="updater neq null">updater=#{updater},</if>
<if test="updateTime neq null">update_time=#{updateTime},</if>
<if test="delFlag neq null">del_flag=#{delFlag},</if>
<if test="seq neq null">seq=#{seq},</if>
</trim>
WHERE id=#{id};
</update>
<update id="delete" parameterType="com.saidian.entity.Department">
UPDATE t_department
<trim prefix="SET" suffixOverrides=",">
updater=#{updater},update_time=#{updateTime},del_flag=#{delFlag}
</trim>
<where>
id=#{id} OR FIND_IN_SET(#{id}, pids);
</where>
</update>
<select id="single" parameterType="java.lang.Integer"
resultType="com.saidian.entity.Department">
SELECT
<include refid="columns"></include>
FROM t_department WHERE id=#{id};
</select>
<select id="list" parameterType="com.saidian.entity.Department"
resultType="com.saidian.entity.Department">
SELECT
<include refid="list_columns"></include>
FROM t_department t1
LEFT JOIN t_gov_employee t2 ON t2.id = t1.creater
LEFT JOIN t_gov_employee t3 ON t3.id = t1.updater
<where>
del_flag = '0'
</where>
ORDER BY seq;
</select>
<select id="countByPid" parameterType="java.lang.Integer"
resultType="java.lang.Integer">
SELECT COUNT(1) FROM t_department
<where> pid = #{pid}</where>
</select>
<select id="hasUser" parameterType="java.lang.String"
resultType="java.lang.Integer">
SELECT COUNT(1) FROM t_gov_employee
<where> dep IN(#{ids}) AND state != 1</where>
</select>
<select id="findLastLeaf" parameterType="java.lang.Integer"
resultType="java.lang.String">
SELECT GROUP_CONCAT(id) FROM t_department
<where> FIND_IN_SET(#{id}, pids) AND del_flag = '0'</where>
</select>
<select id="findChildren" parameterType="java.lang.Integer"
resultType="java.lang.String">
SELECT GROUP_CONCAT(id) FROM t_department
<where> pid =#{id} AND del_flag = '0'</where>
</select>
<sql id="columns">
id,name,pid,pids,remark,creater,create_time,updater,update_time,del_flag,seq
</sql>
<sql id="list_columns">
t1.id,t1.name,t1.pid,t1.pids,t1.remark,t1.creater,t1.create_time,t1.updater,t1.update_time,t1.del_flag,t1.seq,t2.`name`
AS createName,t3.`name` AS updateName
</sql>
</mapper>
目前支持同级最多61个部门,有一定局限性,但是满足现实业务需求,如果真正的优化排序,应该用“.”来切割用,然后在内存中进行排序,基于性能和实际业务需求,不需要那么去做。
新增:新增通过父节点计算自己是第几个孩子,上篇文章已有描述。
@RequiresPermissions(value = { "dep.save" })
@RequestMapping(value="/save")
@ResponseBody
public String save(Department department,HttpSession session){
Integer uid = (Integer)session.getAttribute("uid");
department.setCreater(uid);
department.setCreateTime(new Date());
department.setDelFlag("0");
int cnt = departmentService.countByPid(department.getPid() == null ? 0 : department.getPid());
Department pdep = departmentService.single(department.getPid()== null ? 0 : department.getPid());
String pseq = pdep == null ? "1" : pdep.getSeq();
department.setSeq(pseq + "." + convertCount(cnt));
departmentService.save(department);
return "SUCCESS";
}
修改:修改可以更改部门的从属关系,这里比较复杂,利用递归算法,每个层级都修改其父节点集和排序号。
@RequiresPermissions(value = { "dep.update" })
@RequestMapping(value="/update", produces="text/plain; charset=UTF-8")
@ResponseBody
public String update(Department department, Integer oldPid, HttpSession session){
if(department.getId().equals(department.getPid()))
return "不可以设置自己为自己的父级";
if(department.getPids().contains(String.valueOf(department.getId())))
return "不能将上级部门设置为本部门或本部门下的子部门";
Integer uid = (Integer)session.getAttribute("uid");
if(!oldPid.equals(department.getPid())){
int cnt = departmentService.countByPid(department.getPid()== null ? 0 : department.getPid());
Department pdep = departmentService.single(department.getPid()== null ? 0 : department.getPid());
String pseq = pdep == null ? "1" : pdep.getSeq();
department.setSeq(pseq + "." + convertCount(cnt));
}
department.setUpdater(uid);
department.setUpdateTime(new Date());
departmentService.update(department);
//修改上级部门更改涉及的部门(其子部门)关系问题,如:pids,seq
updateRelation(department.getId(), uid);
return "SUCCESS";
}
private String convertCount(int i){ String source[]={"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"}; return source[i]; } /** * 递归更改部门层级关系 * @param id */ private void updateRelation(Integer id, Integer uid){ String childrenDepIds = departmentService.findChildren(id); if(childrenDepIds == null) return; String[] ids = childrenDepIds.split(","); for (String cid : ids) { int cnt = departmentService.countByPid(id); Department pdep = departmentService.single(id); String pseq = pdep == null ? "1" : pdep.getSeq(); Department cDep = departmentService.single(Integer.valueOf(cid)); cDep.setPids(pdep.getPids()+","+pdep.getPid()); cDep.setSeq(pseq + "." + convertCount(cnt)); cDep.setUpdater(uid); cDep.setUpdateTime(new Date()); departmentService.update(cDep); } for (String cid : ids) { updateRelation(Integer.valueOf(cid), uid); } }
删除:删除时删除该节点及其子节点级以及子节点的子节点,主要是设计数据库的时候利用pids记录了其父子关系。
/**
* 删除部门(逻辑删除)
* @param department
* @param session
* @return
*/
@RequiresPermissions(value = {"dep.delete"})
@RequestMapping(value="/delete", produces="text/plain; charset=UTF-8")
@ResponseBody
public String delete(Department department, HttpSession session){
String pids = departmentService.findLastLeaf(department.getId());
boolean hasUser = departmentService.hasUser(pids);
if(hasUser)
return "该部门或其子部门有用户,不允许删除!";
Integer uid = (Integer)session.getAttribute("uid");
department.setUpdater(uid);
department.setUpdateTime(new Date());
department.setDelFlag("1");
departmentService.delete(department);
return "SUCCESS";
}
mapper:主要是查找子节点,使用到了find_in_set 函数。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.saidian.dao.DepartmentDao">
<insert id="save" parameterType="com.saidian.entity.Department"
useGeneratedKeys="true" keyProperty="id">
INSERT INTO t_department(
<include refid="columns"></include>
)VALUES(
#{id},#{name},#{pid},#{pids},#{remark},#{creater},#{createTime},#{updater},#{updateTime},#{delFlag},#{seq}
)
</insert>
<update id="update" parameterType="com.saidian.entity.Department">
UPDATE t_department
<trim prefix="SET" suffixOverrides=",">
<if test="name neq null">name=#{name},</if>
<if test="pid neq null">pid=#{pid},</if>
<if test="pids neq null">pids=#{pids},</if>
<if test="remark neq null">remark=#{remark},</if>
<if test="updater neq null">updater=#{updater},</if>
<if test="updateTime neq null">update_time=#{updateTime},</if>
<if test="delFlag neq null">del_flag=#{delFlag},</if>
<if test="seq neq null">seq=#{seq},</if>
</trim>
WHERE id=#{id};
</update>
<update id="delete" parameterType="com.saidian.entity.Department">
UPDATE t_department
<trim prefix="SET" suffixOverrides=",">
updater=#{updater},update_time=#{updateTime},del_flag=#{delFlag}
</trim>
<where>
id=#{id} OR FIND_IN_SET(#{id}, pids);
</where>
</update>
<select id="single" parameterType="java.lang.Integer"
resultType="com.saidian.entity.Department">
SELECT
<include refid="columns"></include>
FROM t_department WHERE id=#{id};
</select>
<select id="list" parameterType="com.saidian.entity.Department"
resultType="com.saidian.entity.Department">
SELECT
<include refid="list_columns"></include>
FROM t_department t1
LEFT JOIN t_gov_employee t2 ON t2.id = t1.creater
LEFT JOIN t_gov_employee t3 ON t3.id = t1.updater
<where>
del_flag = '0'
</where>
ORDER BY seq;
</select>
<select id="countByPid" parameterType="java.lang.Integer"
resultType="java.lang.Integer">
SELECT COUNT(1) FROM t_department
<where> pid = #{pid}</where>
</select>
<select id="hasUser" parameterType="java.lang.String"
resultType="java.lang.Integer">
SELECT COUNT(1) FROM t_gov_employee
<where> dep IN(#{ids}) AND state != 1</where>
</select>
<select id="findLastLeaf" parameterType="java.lang.Integer"
resultType="java.lang.String">
SELECT GROUP_CONCAT(id) FROM t_department
<where> FIND_IN_SET(#{id}, pids) AND del_flag = '0'</where>
</select>
<select id="findChildren" parameterType="java.lang.Integer"
resultType="java.lang.String">
SELECT GROUP_CONCAT(id) FROM t_department
<where> pid =#{id} AND del_flag = '0'</where>
</select>
<sql id="columns">
id,name,pid,pids,remark,creater,create_time,updater,update_time,del_flag,seq
</sql>
<sql id="list_columns">
t1.id,t1.name,t1.pid,t1.pids,t1.remark,t1.creater,t1.create_time,t1.updater,t1.update_time,t1.del_flag,t1.seq,t2.`name`
AS createName,t3.`name` AS updateName
</sql>
</mapper>
目前支持同级最多61个部门,有一定局限性,但是满足现实业务需求,如果真正的优化排序,应该用“.”来切割用,然后在内存中进行排序,基于性能和实际业务需求,不需要那么去做。
相关文章推荐
- 基于企业上下级关系的组织机构体系数据模型设计
- 我的组织机构表设计。
- 组织_用户_权限关系设计
- 无限层级的组织机构
- 组织机构权限系统设计
- 从零开始写C# MVC框架之--- 设计用户、菜单、组织机构、角色等表
- 组织机构设计器窗体基类 代码分析
- 用拓扑图展现层级和组织关系(二)
- 实现基于组织机构的数据集权限系统的设计思路讲解
- 无限层级的组织机构
- 怎样才能实现排序优化的层次关系表设计_SQL技巧
- 实现基于组织机构的数据集权限系统的设计思路讲解【提供完整数据库设计下载】
- 人员-组织 结构 数据库关系设计
- 组织结构图, 上下关系, 层次关系, 打印, 设计, 编辑, VC++, 示例, 源代码
- 疯狂代码,大型网站架构系列之三,多对多关系的优化设计
- [架构] 大型网站架构系列之三 ---------------- 多对多关系的优化设计
- 组织结构图, 上下关系, 层次关系, 打印, 设计, 编辑, VC++, 示例, 源代码
- oracle统计(当前层级以及所有下级组织机构登录次数总和)
- 以关系为中心的组织设计:系统结构
- 实现基于组织机构的数据集权限系统的设计思路讲解【提供完整数据库设计下载】