展示:

为了更好的展示数据实现过程:该功能采用mybatis写xml的方式实现,同样的mybatis-plus也能实现该功能,实现树状主要是通过递归这个方法把数据封装到集合里面返回给前端;

1.数据库表与数据:

提供了模板,也可以根据自己的需求自定义结构:玩法多样化

CREATE TABLE `sys_dept` (
  `dept_id` bigint NOT NULL AUTO_INCREMENT COMMENT '部门id',
  `parent_id` bigint DEFAULT '0' COMMENT '父部门id',
  `ancestors` varchar(50) CHARACTER SET utf8 COLLATE utf8_croatian_ci DEFAULT '' COMMENT '祖级列表',
  `dept_name` varchar(30) CHARACTER SET utf8 COLLATE utf8_croatian_ci DEFAULT '' COMMENT '部门名称',
  `order_num` int DEFAULT '0' COMMENT '显示顺序',
  `leader` varchar(20) CHARACTER SET utf8 COLLATE utf8_croatian_ci DEFAULT NULL COMMENT '负责人',
  `phone` varchar(11) CHARACTER SET utf8 COLLATE utf8_croatian_ci DEFAULT NULL COMMENT '联系电话',
  `email` varchar(50) CHARACTER SET utf8 COLLATE utf8_croatian_ci DEFAULT NULL COMMENT '邮箱',
  `status` char(1) CHARACTER SET utf8 COLLATE utf8_croatian_ci DEFAULT '0' COMMENT '部门状态(0正常 1停用)',
  `del_flag` char(1) CHARACTER SET utf8 COLLATE utf8_croatian_ci DEFAULT '0' COMMENT '删除标志(0代表存在 2代表删除)',
  `create_by` varchar(64) CHARACTER SET utf8 COLLATE utf8_croatian_ci DEFAULT '' COMMENT '创建者',
  `create_time` datetime DEFAULT NULL COMMENT '创建时间',
  `update_by` varchar(64) CHARACTER SET utf8 COLLATE utf8_croatian_ci DEFAULT '' COMMENT '更新者',
  `update_time` datetime DEFAULT NULL COMMENT '更新时间',
  PRIMARY KEY (`dept_id`)
) ENGINE=InnoDB AUTO_INCREMENT=201 DEFAULT CHARSET=utf8mb3 COLLATE=utf8_croatian_ci COMMENT='部门表';

INSERT INTO `sys_dept`(`dept_id`, `parent_id`, `ancestors`, `dept_name`, `order_num`, `leader`, `phone`, `email`, `status`, `del_flag`, `create_by`, `create_time`, `update_by`, `update_time`) VALUES (100, 0, '0', '智能科技', 0, '智能', '15888888888', '123@qq.com', '0', '0', 'admin', '2022-05-19 09:11:17', '', NULL);
INSERT INTO `sys_dept`(`dept_id`, `parent_id`, `ancestors`, `dept_name`, `order_num`, `leader`, `phone`, `email`, `status`, `del_flag`, `create_by`, `create_time`, `update_by`, `update_time`) VALUES (101, 100, '0,100', '北京公司', 1, '智能', '15888888888', '123@qq.com', '0', '0', 'admin', '2022-05-19 09:11:17', '', NULL);
INSERT INTO `sys_dept`(`dept_id`, `parent_id`, `ancestors`, `dept_name`, `order_num`, `leader`, `phone`, `email`, `status`, `del_flag`, `create_by`, `create_time`, `update_by`, `update_time`) VALUES (102, 100, '0,100', '上海公司', 2, '智能', '15888888888', '123@qq.com', '0', '0', 'admin', '2022-05-19 09:11:17', '', NULL);
INSERT INTO `sys_dept`(`dept_id`, `parent_id`, `ancestors`, `dept_name`, `order_num`, `leader`, `phone`, `email`, `status`, `del_flag`, `create_by`, `create_time`, `update_by`, `update_time`) VALUES (103, 101, '0,100,101', '研发部门', 1, '智能', '15888888888', '123@qq.com', '0', '0', 'admin', '2022-05-19 09:11:17', '', NULL);
INSERT INTO `sys_dept`(`dept_id`, `parent_id`, `ancestors`, `dept_name`, `order_num`, `leader`, `phone`, `email`, `status`, `del_flag`, `create_by`, `create_time`, `update_by`, `update_time`) VALUES (104, 101, '0,100,101', '测试部门', 2, '智能', '15888888888', '123@qq.com', '0', '0', 'admin', '2022-05-19 09:11:17', '', NULL);
INSERT INTO `sys_dept`(`dept_id`, `parent_id`, `ancestors`, `dept_name`, `order_num`, `leader`, `phone`, `email`, `status`, `del_flag`, `create_by`, `create_time`, `update_by`, `update_time`) VALUES (105, 101, '0,100,101', '运维部门', 3, '智能', '15888888888', '123@qq.com', '0', '0', 'admin', '2022-05-19 09:11:18', '', NULL);
INSERT INTO `sys_dept`(`dept_id`, `parent_id`, `ancestors`, `dept_name`, `order_num`, `leader`, `phone`, `email`, `status`, `del_flag`, `create_by`, `create_time`, `update_by`, `update_time`) VALUES (106, 101, '0,100,101', '业务部门', 4, '智能', '15888888888', '123@qq.com', '0', '0', 'admin', '2022-05-19 09:11:18', '', NULL);
INSERT INTO `sys_dept`(`dept_id`, `parent_id`, `ancestors`, `dept_name`, `order_num`, `leader`, `phone`, `email`, `status`, `del_flag`, `create_by`, `create_time`, `update_by`, `update_time`) VALUES (107, 101, '0,100,101', '客服部门', 5, '智能', '15888888888', '123@qq.com', '0', '0', 'admin', '2022-05-19 09:11:18', '', NULL);
INSERT INTO `sys_dept`(`dept_id`, `parent_id`, `ancestors`, `dept_name`, `order_num`, `leader`, `phone`, `email`, `status`, `del_flag`, `create_by`, `create_time`, `update_by`, `update_time`) VALUES (108, 102, '0,100,102', '销售部门', 1, '智能', '15888888888', '123@qq.com', '0', '0', 'admin', '2022-05-19 09:11:18', '', NULL);
INSERT INTO `sys_dept`(`dept_id`, `parent_id`, `ancestors`, `dept_name`, `order_num`, `leader`, `phone`, `email`, `status`, `del_flag`, `create_by`, `create_time`, `update_by`, `update_time`) VALUES (109, 102, '0,100,102', '人事部门', 2, '智能', '15888888888', '123@qq.com', '0', '0', 'admin', '2022-05-19 09:11:18', '', NULL);
INSERT INTO `sys_dept`(`dept_id`, `parent_id`, `ancestors`, `dept_name`, `order_num`, `leader`, `phone`, `email`, `status`, `del_flag`, `create_by`, `create_time`, `update_by`, `update_time`) VALUES (200, 101, '0,100,101', '后勤部门', 6, '智能', '15288888888', '123@qq.com', '0', '0', 'admin', '2022-05-19 14:11:35', 'admin', '2022-05-19 14:11:53');
 2.基础结构生成:偷懒神奇 3.controller层:根据自己的需要添加或者删除
@RestController
@RequestMapping("/sys-dept")
public class SysDeptController {
    @Autowired
    private SysDeptService sysDeptService;
 

  //部门递归树 静态传参形式
    @GetMapping("getSysDept")
    public R getSysDept(){
        List<SysDept> list = sysDeptService.getParentId();
        return R.ok().data("list",list);
    }

}
mapper层:提供了两个简单的查询方法
@Mapper
public interface SysDeptMapper extends BaseMapper<SysDept> {
    /**
     * 根据父类id查询子类菜单
     * @param parentId
     * @return
     */
    List<SysDept> selectByPid(Integer parentId);


    /**
     * 查询除了一级菜单以外的菜单
     * @return
     */
    List<SysDept> selectAllNotBase();

}
mapper.xml :超级简单的语法
<select id="selectByPid" resultType="com.xxx.xxx.entity.SysDept">
        SELECT *
        FROM sys_dept
        WHERE
            parent_id=#{parent_id}
    </select>

    <select id="selectAllNotBase" resultType="com.xxx.xxx.entity.SysDept">
        SELECT *
            FROM sys_dept
            where parent_id != 0
    </select>
3.service层:
public interface SysDeptService extends IService<SysDept> {

    /**
     * 递归部门树 通过传递父部门id查询,递归出子节点
     * @param
     * @return
     */
    List<SysDept> getParentId();
}
4.实现类:对于递归比较疑惑的小伙伴 找度娘
@Service
public class SysDeptServiceImpl extends ServiceImpl<SysDeptMapper, SysDept> implements SysDeptService {
    @Autowired
    private SysDeptMapper sysDeptMapper;

    @Override
    public List<SysDept> getParentId() {
        //通过parentId:获取该值下的部门父数据
        List<SysDept> sysPid = sysDeptMapper.selectByPid(0);
        //查询除了一级菜单以外的菜单 ;parentId!=0 (在xml里面where判断parentId!=0 )
        List<SysDept> sysNotBase = sysDeptMapper.selectAllNotBase();
        //遍历数据
        for (SysDept sysDept : sysPid) {
            //通过方法获取子节点的数据,再通过实体类里面的集合给整合
            List<SysDept> find = recursive(sysNotBase, sysDept.getDeptId());
            //实体类里面的方法
            sysDept.setChildren(find);
        }
        return sysPid;
    }
    /**
     *多级菜单查询方法
     * @param sysList 不包含最高层次菜单的菜单集合
     * @param parentId 父类id
     */
    public List<SysDept> recursive(List<SysDept> sysList,Long parentId){
        //创建一个集合来接收所有子级的数据
        List<SysDept> result = new ArrayList<SysDept>();
        //遍历数据:把list转换成对象
        for (SysDept sysDept : sysList) {
            if(sysDept.getParentId()!=null){
                //递归的结束出口条件
                if(sysDept.getParentId().equals(parentId)){
                    //递归的核心:自己调用自己的方法
                    List<SysDept> iterateSys = recursive(sysList,sysDept.getDeptId());
                    //把递归出来的数据封装到实体类集合里面
                    sysDept.setChildren(iterateSys);
                    //所有子节点的数据通过集合返回
                    result.add(sysDept);
                }
            }
        }
        return result;
    }
}

说明一下为什么写死传递的部门ID,因为父级ID为第一级别在展示的是否一般展示的是所有数据,展示单个部门的意义不大,当然了小伙伴们需要自定义动态传参的话也是没问题的 通过URL传递一个parentId就OK了