数据展示页是个树,我们一次性把数据加载出来也可以通过点一次id加载查询出来出来子部门,我们用一次拿到说有json数据加载出来
数据不多可以用递归,数据很多就用懒加载的方式
@RestController
@RequestMapping("/system/basic/department")
public class DepartmentController {
@Autowired
DepartmentService departmentService;
@GetMapping("/")
public List<Department> getAllDepartments(){
return departmentService.getAllDepartments();
}
}
@Service
public class DepartmentService {
@Autowired
DepartmentMapper departmentMapper;
public List<Department> getAllDepartments() {
//传递-1直接查询最顶级的股东会然后根据mybatis语句进行递归
return departmentMapper.getAllDepartmentsByParentId(-1);
}
}
<resultMap id="DepartmentWithChildren" type="com.xyg.pojo.Department" extends="BaseResultMap">
<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字段一对多
<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加事务分三步
@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("添加失败");
}
@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());
}
mapper就只编写这一个接口,其它都是存在的
int insertDep(Department record);
<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
}
})
},
@DeleteMapping("/{id}")
public RespBean delDep(@PathVariable Integer id){
if(departmentService.delDep(id)==1){
return RespBean.ok("删除成功");
}
return RespBean.err("删除失败");
}
public Integer delDep(Integer id) {
return departmentMapper.delDep(id);
}
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 的数组
},