若依获取部门列表递归实例

项目场景:

若依递归算法实例


1 接口部分
/**
     * 获取部门下拉树列表
     */
    @GetMapping("/treeselect")
    public AjaxResult treeselect(SysDept dept)
    {
    	//获取所有部门
        List<SysDept> depts = deptService.selectDeptList(dept);
        //生成属性结构
        return AjaxResult.success(deptService.buildDeptTreeSelect(depts));
    }
//-----------------------------下面是递归实例------------------------
 /**
     * 构建前端所需要下拉树结构
     * 
     * @param depts 部门列表
     * @return 下拉树结构列表
     */
    @Override
    public List<TreeSelect> buildDeptTreeSelect(List<SysDept> depts)
    {
        List<SysDept> deptTrees = buildDeptTree(depts);
        return deptTrees.stream().map(TreeSelect::new).collect(Collectors.toList());
    }
    //递归入口方法----------------
     /**
     * 构建前端所需要树结构
     * 
     * @param depts 部门列表
     * @return 树结构列表
     */
    @Override
    public List<SysDept> buildDeptTree(List<SysDept> depts)
    {
        List<SysDept> returnList = new ArrayList<SysDept>();
        List<Long> tempList = new ArrayList<Long>();
        for (SysDept dept : depts)
        {
            tempList.add(dept.getDeptId());
        }
        for (Iterator<SysDept> iterator = depts.iterator(); iterator.hasNext();)
        {
            SysDept dept = (SysDept) iterator.next();
            // 如果是顶级节点, 遍历该父节点的所有子节点
            if (!tempList.contains(dept.getParentId()))
            {
                recursionFn(depts, dept);
                returnList.add(dept);
            }
        }
        if (returnList.isEmpty())
        {
            returnList = depts;
        }
        return returnList;
    }
    //--------开始递归--------
     /**
     * 递归列表
     */
    private void recursionFn(List<SysDept> list, SysDept t)
    {
        // 得到子节点列表
        List<SysDept> childList = getChildList(list, t);
        t.setChildren(childList);
        for (SysDept tChild : childList)
        {
            if (hasChild(list, tChild))
            {
                recursionFn(list, tChild);
            }
        }
    }
//-------获得子节点方法---------------- 

    /**
     * 得到子节点列表
     */
    private List<SysDept> getChildList(List<SysDept> list, SysDept t)
    {
        List<SysDept> tlist = new ArrayList<SysDept>();
        Iterator<SysDept> it = list.iterator();
        while (it.hasNext())
        {
            SysDept n = (SysDept) it.next();
            if (StringUtils.isNotNull(n.getParentId()) && n.getParentId().longValue() == t.getDeptId().longValue())
            {
                tlist.add(n);
            }
        }
        return tlist;
    }

### 宜搭中获取上级部门名称的实现方法 在宜搭平台中,可以通过自定义脚本或者配置逻辑来实现获取上级部门名称的功能。以下是基于 Java 和 MySQL 的具体实现方式。 #### 方法一:通过递归查询数据库中的部门关系 假设已经存在一个存储部门及其父子关系的数据表 `sys_department`,其字段包括 `id`, `name`, `parent_id`。可以利用 SQL 查询和递归算法来获取某个部门的所有上级部门名称。 ##### 数据库设计示例 ```sql CREATE TABLE sys_department ( id BIGINT PRIMARY KEY, name VARCHAR(255), parent_id BIGINT DEFAULT NULL ); ``` ##### 使用自定义函数获取部门层级名称 参考 MySQL 中的自定义函数实现[^3],可以直接调用该函数返回指定部门的完整路径名: ```sql SELECT read_group_names(department_id) AS department_path FROM sys_department WHERE id = target_department_id; ``` 此方法适用于需要频繁访问部门层级的应用场景。 --- #### 方法二:前端动态加载并显示上级部门名称 如果使用的是 Vue.js 框架,在前端展示表格时也可以通过懒加载机制实时更新子节点数据[^4]。以下是一个简单的实现思路: 1. **初始化表格组件** 配置 Element UI 表格组件支持树形结构,并设置 `lazy` 属性为 true。 ```html <el-table ref="departmentTable" :data="tableData" row-key="id" lazy :load="loadChildren"> </el-table> ``` 2. **编写异步加载方法** 当展开某一行时触发回调函数 `loadChildren`,向服务器请求当前行对应的子节点数据。 ```javascript async loadChildren(treeNode, resolve) { const parentId = treeNode.id; try { const response = await fetch(`/api/departments?parentId=${parentId}`); const children = await response.json(); resolve(children); // 返回子节点列表 } catch (error) { console.error('Failed to load child nodes:', error); resolve([]); // 如果失败则返回空数组 } } ``` 3. **手动刷新特定节点** 在执行增删改操作后,可通过 `$set` 更新目标节点的状态以保持视图同步。 ```javascript this.$set( this.$refs.departmentTable.store.states.lazyTreeNodeMap, parentNodeId, updatedChildNodes ); ``` 这种方法适合处理复杂的分层数据结构,能够有效减少初始页面加载时间。 --- #### 方法三:服务端封装 RESTful API 接口 为了提高系统的可维护性和扩展性,建议将业务逻辑集中到后端服务中。例如开发一个专门用于检索上级部门链路的服务接口 `/departments/{id}/ancestors`。 ##### 请求参数说明 | 参数名 | 类型 | 描述 | |--------|--------|--------------------------| | id | Long | 目标部门 ID | ##### 响应体样例 ```json { "success": true, "message": "", "result": [ {"id": 1, "name": "总公司"}, {"id": 2, "name": "分公司A"} ] } ``` 后端代码片段如下所示: ```java @RestController @RequestMapping("/departments") public class DepartmentController { @Autowired private DepartmentService departmentService; @GetMapping("/{id}/ancestors") public ResponseEntity<List<Department>> getAncestors(@PathVariable Long id) { List<Department> ancestors = departmentService.findAncestorDepartments(id); return ResponseEntity.ok(ancestors); } } @Service public class DepartmentServiceImpl implements DepartmentService { @Override public List<Department> findAncestorDepartments(Long currentId) { List<Department> result = new ArrayList<>(); while (currentId != null && !Objects.equals(currentId, 0L)) { Optional<Department> optionalDept = repository.findById(currentId); if (!optionalDept.isPresent()) break; Department dept = optionalDept.get(); result.add(dept); currentId = dept.getParentId(); // 迭代至更高级别的父部门 } Collections.reverse(result); // 确保顺序由顶层到底部排列 return result; } } ``` 以上方案不仅简化了客户端的工作量,还增强了程序的安全性和性能表现。 --- ### 总结 针对不同需求可以选择合适的解决方案。如果是轻量化项目推荐采用纯前端技术栈;而对于大型企业应用,则优先考虑前后分离架构配合高效稳定的 Web Service 提供支撑。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值