微人事 部门管理 模块 (十五)

部门管理的树展示和搜索

数据展示页是个树,我们一次性把数据加载出来也可以通过点一次id加载查询出来出来子部门,我们用一次拿到说有json数据加载出来
数据不多可以用递归,数据很多就用懒加载的方式

由于子部门比较深就不适合,权限组角色之间下展示菜单那样
在这里插入图片描述

在这里插入图片描述

编写后端接口

DepartmentController

@RestController
@RequestMapping("/system/basic/department")
public class DepartmentController {

    @Autowired
    DepartmentService departmentService;

    @GetMapping("/")
    public List<Department>  getAllDepartments(){
        return departmentService.getAllDepartments();
    }
}

DepartmentService

@Service
public class DepartmentService {


    @Autowired
    DepartmentMapper departmentMapper;

    public List<Department> getAllDepartments() {
        //传递-1直接查询最顶级的股东会然后根据mybatis语句进行递归
        return departmentMapper.getAllDepartmentsByParentId(-1);
    }
}

DepartmentMapper

在这里插入图片描述

  <resultMap id="DepartmentWithChildren" type="com.xyg.pojo.Department" extends="BaseResultMap"> <!--当查询的时候会以children属性会调用select把当前id传进去,然后新查询的同会继续调用,形成一个递归-->
    <collection property="children" ofType="com.xyg.pojo.Department" select="com.xyg.mapper.DepartmentMapper.getAllDepartmentsByParentId" column="id" ></collection>
  </resultMap>


  <select id="getAllDepartmentsByParentId" resultMap="DepartmentWithChildren">
     select * from  department where parentid = #{pid}
  </select>

实体类添加一个children字段一对多

在这里插入图片描述

测试
在这里插入图片描述

前端编写

添加elementui 组件
在这里插入图片描述DemMarna.vue

<div  style="width: 500px">
    <el-input
            prefix-icon="el-icon-search"

            placeholder="输入部门名称进行搜索"
            v-model="filterText">         
    </el-input>

    <el-tree
            :data="deps"
            :props="defaultProps"
            default-expand-all
            :filter-node-method="filterNode"     //过滤的方法
            ref="tree">
    </el-tree>
</div>

在这里插入图片描述

 data(){
            return{
                filterText:"",
                deps:[],
                defaultProps: {
                    children: 'children',
                    label: 'name'
                }
            }
        },

在这里插入图片描述

 mounted(){
            this.getDeps()
        },

        methods: {

            getDeps(){
                this.getRequest("/system/basic/department/").then(resp=>{
                    if(resp){
                        this.deps=resp
                    }
                })
            },

数据展示效果
在这里插入图片描述

前端查询过滤

在这里插入图片描述
在这里插入图片描述


            filterNode(value, data) {//过滤的方法,value传过来的最新值,data的Json数组得出每一项,
                if (!value) return true;  //进行比较,如果value不存在的话直接返回true,表示当前的data留着,否则剔除掉
                return data.name.indexOf(value) !== -1;//ata.name是否包含这个值,如果不等于-1就返回值这个值
            }

        watch: { //监控filterText值发生变化
            filterText(val) {
                this.$refs.tree.filter(val);//会触发这个方法
            }
        },

总之就是监听输入框绑定的变量进行监听是否有变化,触发filter方法,
通过方法实现前端查询
在这里插入图片描述

部门树展示添加与删除

使用这个
在这里插入图片描述
粘贴到树组件里
在这里插入图片描述
在这里插入图片描述
用这个方法即可解决 :expand-on-click-node=“false” 是否在点击节点的时候展开或者收缩节点, 默认值为 true,如果为 false,则只有点箭头图标的时候才会展开或者收缩节点。

  <!--  :expand-on-click-node="false" 是否在点击节点的时候展开或者收缩节点, 默认值为 true,如果为 false,则只有点箭头图标的时候才会展开或者收缩节点。-->
    <el-tree

            :data="deps"
            node-key="id"
            :props="defaultProps"
            :expand-on-click-node="false"
            :filter-node-method="filterNode"
            ref="tree">
        <!--slot-scope="{ node, data }   node指当前的元素( :props="defaultProps"),data值得到就是服务端返回的json对象-->
        <span class="custom-tree-node" style="display: flex; justify-content: space-between; width: 100%" slot-scope="{ node, data }">

        <span>{{ data.name }}</span>
        <span>
          <el-button
                  class="depBtn"
                  type="primary"
                  size="mini"
                  @click="() => showAddDep(data)">
            添加部门
          </el-button>
          <el-button
                  class="depBtn"
                  type="danger"
                  size="mini"
                  @click="() => delDeps(node, data)">
            删除部门
          </el-button>
        </span>
      </span>
    </el-tree>
</div>

效果
在这里插入图片描述

后端部门树的添加

如果在董事会上点添加部门就是董事会的子部门,所以要传的参数一个是父部门的id,一个添加的部门名字

在这里插入图片描述
第一步做添加操作把name,和partentid字段加进来,id会自动生成
第二步就要去根据生成的id,查询到他partentid生成组成自己的depPath, 第三步 isParent没有子部门为flash,有了自己的子部门就为true

这个 不难,写service加事务分三步

DepartmentController

 @PostMapping("/")
    public RespBean AddDep(@RequestBody Department department) {
        if(department.getName()!=""){
            Department department1 = departmentService.AddDep(department);
            if (department1 != null) {
                return RespBean.ok("添加成功",department1);
            }
        }
        return RespBean.err("添加失败");
    }

DepartmentService

@Transactional
    public Department AddDep(Department department) {

        //第一步做添加操作把name,和partentid字段加进来,id会自动生成,数据库返回新增的id
        departmentMapper.insertDep(department);

        //第二步就要去根据生成的id,查询到他partentid生成组成自己的depPath,
        //根据id查询出自己的对象
        Department dep = departmentMapper.selectByPrimaryKey(department.getId());
        //获取当前对象父id的对象
        Department parDep = departmentMapper.selectParentDepath(dep.getParentid());

        //获取父id的deppath加自己的id,生成自己Deppath
        String Deppath=parDep.getDeppath()+'.'+department.getId();

        if (Deppath.toString().startsWith("null")){
            throw new RuntimeException("操作错误");
        }
        //设置自己Deppath
        department.setDeppath(Deppath);
        //设自己是可启用
        department.setEnabled(true);
        //设置自己刚添加是没有子部门
        department.setIsparent(false);
        //进行更新操作
        departmentMapper.updateByPrimaryKey(department);
        //如果有新数据进行添加如果有父部门,都把父部门的Isparent 更新为 true
        Department department1 = departmentMapper.selectByPrimaryKey(department.getParentid());
        department1.setIsparent(true);
        departmentMapper.updateByPrimaryKey(department1);

        return departmentMapper.selectByPrimaryKey(department.getId());

    }

DepartmentMapper

mapper就只编写这一个接口,其它都是存在的

int insertDep(Department record);
<!--useGeneratedKeys="true" keyProperty="id"   实现id回调,获取插入数据库的id-->
  <insert id="insertDep" parameterType="com.xyg.pojo.Department" useGeneratedKeys="true" keyProperty="id" >
    insert into department (id, name, parentId,
                            depPath, enabled, isParent)
    values (#{id,jdbcType=INTEGER}, #{name,jdbcType=VARCHAR}, #{parentid,jdbcType=INTEGER},
            #{deppath,jdbcType=VARCHAR}, #{enabled,jdbcType=BIT}, #{isparent,jdbcType=BIT})
  </insert>

前端对接

当点击添加的时候应该弹出输入框

<el-dialog
            title="添加部门"
            :visible.sync="dialogVisible"
            width="30%">
        <div>
            <el-tag size="small">上级部门</el-tag>
            <span >{{this.parDep.name}}</span>
        </div>
        <div  style="margin-top: 8px">
            <el-tag size="small">部门名称</el-tag>
            <el-input  size="mini" v-model="chalDep.name"   placeholder="请输入部门名称" style="width: 200px"></el-input>
        </div>
        <span slot="footer" class="dialog-footer">
    <el-button @click="cannelChal">取 消</el-button>
    <el-button type="primary" @click="chalAdd">确 定</el-button>
  </span>
    </el-dialog>
   

在这里插入图片描述

   showAddDep(data){
                console.log(data)
                this.dialogVisible=true
                this.parDep=data
                this.chalDep.parentid=data.id
            },

在这里插入图片描述

在这里插入图片描述
#接口对接
在这里插入图片描述

在这里插入图片描述


            cannelChal(){
              this.dialogVisible=false;
              this.chalDep.name=""
            },

            chalAdd(){
              this.postRequest("/system/basic/department/",this.chalDep).then(resp=>{
                  if (resp){
                      this.getDeps()
                      this.chalDep.name=""
                      this.dialogVisible=false
                  }
              })
            },

后端部门的删除

DepartmentController

    @DeleteMapping("/{id}")
    public RespBean delDep(@PathVariable Integer id){
        if(departmentService.delDep(id)==1){
            return RespBean.ok("删除成功");
        }
        return RespBean.err("删除失败");
    }

DepartmentService

    public Integer delDep(Integer id) {
        return departmentMapper.delDep(id);
    }

DepartmentMapper

Integer delDep(Integer id) ;
  <delete id="delDep" >
    delete from  department where id=#{id}
  </delete>

前端对接

在这里插入图片描述

 delDeps(node,data){
                this.$confirm('此操作将永久删除, 是否继续?', '提示', {
                    confirmButtonText: '确定',
                    cancelButtonText: '取消',
                    type: 'warning'
                }).then(() => {
                    this.deleteRequest("/system/basic/department/"+data.id).then(resp=>{
                        if(resp){
                            this.getDeps()
                        }
                    })

                }).catch(() => {
                    this.$message({
                        type: 'info',
                        message: '已取消删除'
                    });
                });
            },
            getDeps(){
                this.getRequest("/system/basic/department/").then(resp=>{
                    if(resp){
                        this.deps=resp
                    }
                })
            },
            filterNode(value, data) {//过滤的方法,value传过来的最新值,data的Json数组得出每一项,
                if (!value) return true;  //进行比较,如果value不存在的话直接返回true,表示当前的data留着,否则剔除掉
                return data.name.indexOf(value) !== -1;//ata.name是否包含这个值,如果不等于-1就返回值这个值
            }
        },
        watch: { //监控filterText值发生变化
            filterText(val) {
                this.$refs.tree.filter(val);//会触发这个方法
            }
        },

解决树组件添加和删除收缩问题

element-ui中的el-tree在添加或者删除子节点后,也就是每次数据刷新后树就会收上去,但是如果我们还需要在当前节点下进行后续操作,而且有很多层节点的情况下,就很麻烦了,对用户体验感非常差,那么怎么解决呢?

解决办法:定义一个数组,然后点击树节点时,保存下来,存进数据内,刷新后树之前展开的节点就能还是展开的状态。
在这里插入图片描述
在这里插入图片描述

 handleNodeClick(data) {
                this.defaultExpandKeys.push(data.id) ;//记录当前点击节点,并赋值给默认展开的节点的 key 的数组
            },

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值