快速构建一个权限项目

Posted My丶Ou

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了快速构建一个权限项目相关的知识,希望对你有一定的参考价值。

这次我们所讲解的是部门层级树接口开发和更新部门接口开发两大点:

我们首先定义一个树的层级的接口,这里我们首先创建一个dto包用来做适配,创建一个DeptLevelDto类:

package cn.oyc.dto;

import cn.oyc.entity.SysDept;
import com.google.common.collect.Lists;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import org.springframework.beans.BeanUtils;

import java.util.List;

@Getter
@Setter
@ToString
public class DeptLevelDto extends SysDept {
    private List<DeptLevelDto> deptList = Lists.newArrayList();

    public static DeptLevelDto adapt(SysDept dept){
        DeptLevelDto dto = new DeptLevelDto();
        BeanUtils.copyProperties(dept,dto);
        return dto;
    }
}

因为我们这个项目会涉及多个树,所以我们在定义一个计算树的一个结构SysTreeService:

package cn.oyc.service;

import cn.oyc.dao.SysDeptMapper;
import cn.oyc.dto.DeptLevelDto;
import cn.oyc.entity.SysDept;
import cn.oyc.util.LevelUtil;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Lists;
import com.google.common.collect.Multimap;
import org.springframework.stereotype.Service;
import org.apache.commons.collections.CollectionUtils;

import javax.annotation.Resource;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

@Service
public class SysTreeService {
    @Resource
    private SysDeptMapper sysDeptMapper;

    public List<DeptLevelDto> deptTree(){
        List<SysDept> deptList = sysDeptMapper.getAllDept();
        List<DeptLevelDto> dtoList = Lists.newArrayList();
        for (SysDept dept : deptList){
            DeptLevelDto dto = DeptLevelDto.adapt(dept);
            dtoList.add(dto);
        }
        return deptListToTree(dtoList);
    }
    public List<DeptLevelDto> deptListToTree(List<DeptLevelDto> deptLevelList){
        if (CollectionUtils.isEmpty(deptLevelList)){
            return Lists.newArrayList();
        }
        // level -> [dept1,dept2, ...]
        Multimap<String, DeptLevelDto> levelDeptMap = ArrayListMultimap.create();
        List<DeptLevelDto> rootList = Lists.newArrayList();
        for (DeptLevelDto dto : deptLevelList){
            levelDeptMap.put(dto.getLevel(),dto);
            if (LevelUtil.ROOT.equals(dto.getLevel())){
                rootList.add(dto);
            }
        }
        //按照seq从小到大进行排序
        Collections.sort(rootList, new Comparator<DeptLevelDto>() {
            @Override
            public int compare(DeptLevelDto o1, DeptLevelDto o2) {
                return o1.getSeq() - o2.getSeq();
            }
        });
        //递归生成树
        transformDeptTree(rootList,LevelUtil.ROOT,levelDeptMap);
        return rootList;
    }
    //递归排序
    public void transformDeptTree(List<DeptLevelDto> deptLevelList,String level, Multimap<String, DeptLevelDto> levelDeptMap){
        for (int i = 0; i < deptLevelList.size();i++){
            //遍历该层的每个元素
            DeptLevelDto deptLeveDto = deptLevelList.get(i);
            //处理当前层级的数据
            String nextLevel = LevelUtil.calculateLevel(level,deptLeveDto.getId());
            //处理下一层
            List<DeptLevelDto> tempDeptList = (List<DeptLevelDto>) levelDeptMap.get(nextLevel);
            if (CollectionUtils.isNotEmpty(tempDeptList)){
                // 排序
                Collections.sort(tempDeptList,deptSeqComparator);
                //设置下一层部门
                deptLeveDto.setDeptList(tempDeptList);
                //进入到下一层处理
                transformDeptTree(tempDeptList,nextLevel,levelDeptMap);
            }
        }
    }
    public Comparator<DeptLevelDto> deptSeqComparator = new Comparator<DeptLevelDto>() {
        @Override
        public int compare(DeptLevelDto o1, DeptLevelDto o2) {
            return o1.getSeq() - o2.getSeq();
        }
    };
}

这里需要我们区SysDeptMapper增加一个方法:

List<SysDept> getAllDept();

然后去他对应的mapper编写sql:

<select id="getAllDept" resultMap="BaseResultMap">
    select
    <include refid="Base_Column_List" />
    from sys_dept
  </select>

在去Controller编写请求

  @Resource
  private SysTreeService sysTreeService;
  //部门树的请求
    @RequestMapping("/tree.json")
    @ResponseBody
    public JsonData tree(){
        List<DeptLevelDto> dtoList = sysTreeService.deptTree();
        return JsonData.success(dtoList);
    }

我们的一个部门树到这就写完了,再来看我们的更新部门接口

先编写我们的请求:

//更新部门请求
    @RequestMapping("/update.json")
    @ResponseBody
    public JsonData updateDept(DeptParam param){
        sysDeptService.update(param);
        return JsonData.success("");
    }

去DeptService里添加更新的方法:

 public void update(DeptParam param) {
        BeanValidator.check(param);
        if (checkExist(param.getParentId(),param.getName(),param.getId())){
            throw new ParamException("同一层级下存在相同名称的部门");
        }
        SysDept before = sysDeptMapper.selectByPrimaryKey(param.getId());
        Preconditions.checkNotNull(before,"待更新的部门不存在");
        if (checkExist(param.getParentId(),param.getName(),param.getId())){
            throw new ParamException("同一层级下存在相同名称的部门");
        }
        SysDept after = SysDept.builder().id(param.getId()).name(param.getName()).parentId(param.getParentId())
                .seq(param.getSeq()).remark(param.getRemark()).build();
        after.setLevel(LevelUtil.calculateLevel(getLevel(param.getParentId()),param.getParentId()));
        after.setOperator("system-update");//TODO:
        after.setOperateIp("127.0.0.1"); //TODO
        after.setOperateTime(new Date());
        updateWithChild(before,after);
    }
    @Transactional
    void updateWithChild(SysDept before, SysDept after){
        String newLevelPrefix = after.getLevel();
        String oldLevelPrefix = before.getLevel();
        if (!after.getLevel().equals(before.getLevel())){
            List<SysDept> deptList = sysDeptMapper.getChildDeptListByLevel(before.getLevel());
            if (CollectionUtils.isNotEmpty(deptList)){
                for (SysDept dept : deptList){
                    String level = dept.getLevel();
                    if (level.indexOf(oldLevelPrefix) == 0){
                        level = newLevelPrefix + level.substring(oldLevelPrefix.length());
                        dept.setLevel(level);
                    }
                }
                sysDeptMapper.batchUpdateLevel(deptList);
            }
        }
        sysDeptMapper.updateByPrimaryKey(after);
    }

顺便完善我们上节内容的checkExist方法:

 //判断数据是否有重复
    private boolean checkExist(Integer parentId,String deptName,Integer deptId){
        // TODD:
        return sysDeptMapper.countByNameAndParentId(parentId,deptName,deptId) > 0;
    }

我们得去mapper里增加几个方法:

  List<SysDept> getChildDeptListByLevel(@Param("level")String level);
    //批量更新
    void batchUpdateLevel(@Param("sysDeptList") List<SysDept> sysDeptList);

    int countByNameAndParentId(@Param("parentId")int parentId,@Param("name")String name,@Param("id") Integer id);

到SysDeptMapper.xml添加sql:

<select id="getChildDeptListByLevel" resultMap="BaseResultMap">
    select
    <include refid="Base_Column_List" />
    from sys_dept
    where level like #{level} || ‘.%‘
  </select>
  <update id="batchUpdateLevel" parameterType="map">
    <foreach collection="sysDeptList" item="sysDept" separator=";">
        update sys_dept
        set level = #{dept.level}
        where id = #{dept.id}
    </foreach>
  </update>
  <select id="countByNameAndParentId" parameterType="map" resultType="int">
    select count(1)
    form sys_dept
    where parent_id = #{parentId}
    and name = #{name}
    <if test="id != null">
      and id != #{id}
    </if>
  </select>

 

以上是关于快速构建一个权限项目的主要内容,如果未能解决你的问题,请参考以下文章

快速构建一个权限项目

c#代码片段快速构建代码

react快速构建一个应用项目

vs2003:快速片段工具

快速构建一个权限项目

快速构建一个权限项目