您的位置:首页 > 其它

组织机构层级关系设计优化

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";
}
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个部门,有一定局限性,但是满足现实业务需求,如果真正的优化排序,应该用“.”来切割用,然后在内存中进行排序,基于性能和实际业务需求,不需要那么去做。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: