zoukankan      html  css  js  c++  java
  • 快速构建一个权限项目(七)

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

    我们首先定义一个树的层级的接口,这里我们首先创建一个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>
  • 相关阅读:
    将10进制数字转成62进制数字(转)
    admin添加用户时报错:(1452, 'Cannot add or update a child row: a foreign key constraint fails (`mxonline`.`django_admin_l
    Django admin 中抛出 'WSGIRequest' object has no attribute 'user'的错误
    分布式爬虫
    Scrapy之CrawlSpider
    Scrapy之Cookie和代理
    Scrapy核心组件
    scrapy之持久化存储
    Scrapy框架的基本使用
    爬虫之request模块高级
  • 原文地址:https://www.cnblogs.com/Myoyc/p/12244153.html
Copyright © 2011-2022 走看看