不罗嗦直接代码,这里按照步骤来放代码,学java的应该都看的懂,实际中可以先尝试在数据库中获取出数据先,我这里是实体类映射数据库生成相应的表,我的项目是springboot+thymeleaf框架,所以说里面的有一些代码需要根据自己的项目实际需求改,这里已经写的很清楚了。
1.FileDirectory.java
package com.mrzeng.myblog.po;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
import javax.persistence.*;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
/**
* author: zzd
* date: 2019/12/27
* description: 文件目录实体类
*/
@Entity
@EntityListeners(AuditingEntityListener.class)
@Table(name = "tb_fileDirectory")
public class FileDirectory {
@Id /*主键*/
@GeneratedValue /*id生成策略,默认为自动生成*/
private Integer id;
private String title;/*目录名*/
private Integer pid; /*父级Id*/
@CreatedDate
@Temporal(TemporalType.TIMESTAMP)
private Date createTime;/*创建时间*/
@LastModifiedDate
@Temporal(TemporalType.TIMESTAMP)
private Date updateTime;/*更新时间*/
@Transient
private List<FileDirectory> children = new ArrayList<>(); //叶子节点集合
public FileDirectory() {
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public Integer getPid() {
return pid;
}
public void setPid(Integer pid) {
this.pid = pid;
}
public Date getCreateTime() {
return createTime;
}
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
public Date getUpdateTime() {
return updateTime;
}
public void setUpdateTime(Date updateTime) {
this.updateTime = updateTime;
}
public List<FileDirectory> getChildren() {
return children;
}
public void setChildren(List<FileDirectory> children) {
this.children = children;
}
@Override
public String toString() {
return "FileDirectory{" +
"id=" + id +
", title='" + title + '\'' +
", pid=" + pid +
", createTime=" + createTime +
", updateTime=" + updateTime +
", children=" + children +
'}';
}
}
2.FileDirectoryRepository.java
package com.mrzeng.myblog.dao;
import com.mrzeng.myblog.po.FileDirectory;
import org.springframework.data.jpa.repository.JpaRepository;
/**
* author: zzd
* date: 2019/12/31
* description: 通过JPA方式操作数据库
*/
public interface FileDirectoryRepository extends JpaRepository<FileDirectory,Integer> {
}
3.FileDirectoryService
package com.mrzeng.myblog.service;
import com.mrzeng.myblog.po.FileDirectory;
import java.util.List;
/**
* author: zzd
* date: 2019/12/27
* description: 文件目录Service
*/
public interface FileDirectoryService {
List<FileDirectory> listFileDirectory(); //获取文件目录
FileDirectory saveFileDirectory(FileDirectory fileDirectory); //增加目录节点
FileDirectory updateFileDirectory(Integer id,FileDirectory fileDirectory); //修改目录节点
void delFileDirectory(Integer id); //删除目录节点
}
4.FileDirectoryServiceImpl
package com.mrzeng.myblog.service.Impl;
import com.mrzeng.myblog.NotFoundException;
import com.mrzeng.myblog.dao.FileDirectoryRepository;
import com.mrzeng.myblog.po.FileDirectory;
import com.mrzeng.myblog.service.FileDirectoryService;
import com.mrzeng.myblog.util.MyBeanUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.Date;
import java.util.List;
/**
* author: zzd
* date: 2019/12/27
* description: 文件目录实现方法
*/
@Service
public class FileDirectoryServiceImpl implements FileDirectoryService {
@Autowired
private FileDirectoryRepository fileDirectoryRepository;
@Override
public List<FileDirectory> listFileDirectory() { //获取文件目录
return fileDirectoryRepository.findAll();
}
/**
* 增加文件目录节点
* */
@Transactional
@Override
public FileDirectory saveFileDirectory(FileDirectory fileDirectory) {
return fileDirectoryRepository.save(fileDirectory);
}
/**
* 修改文件目录
* */
@Transactional
@Override
public FileDirectory updateFileDirectory(Integer id, FileDirectory fileDirectory) {
FileDirectory f = fileDirectoryRepository.findById(id).orElse(null);
if (f == null ){
throw new NotFoundException("不存在该目录");
}
BeanUtils.copyProperties(fileDirectory,f, MyBeanUtils.getNullPropertyNames(fileDirectory));
f.setUpdateTime(new Date());
return fileDirectoryRepository.save(f);
}
/**
* 删除文件目录,同时删除该节点下的所有子节点目录
* */
@Transactional
@Override
public void delFileDirectory(Integer id) {
fileDirectoryRepository.deleteById(id);
}
}
5.FileController , 这里是根据我自己的项目编写的,需要根据自己情况改写
package com.mrzeng.myblog.web.admin;
import com.alibaba.fastjson.JSONObject;
import com.mrzeng.myblog.po.FileDirectory;
import com.mrzeng.myblog.service.FileDirectoryService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import java.util.*;
/**
* 后台-文件管理controller
* */
@Controller
@RequestMapping("/admin")
public class FilesController {
@Autowired
private FileDirectoryService fileDirectoryService;
@GetMapping("/fileManager/files.html")
public String Files(){
return "/admin/fileManager/files.html";
}
/**
* 获取文件目录列表,递归遍历节点
* */
@ResponseBody //必须要写,不然thymeleaf解析不了下面的方法
@PostMapping("/listDirectory")
public List<Object> listFileDirectory() throws Exception{
List<FileDirectory> fileDirectories = fileDirectoryService.listFileDirectory(); //查询所有目录数据
List<Object> list = new ArrayList<>();
for(FileDirectory fd : fileDirectories) {
if (fd.getPid() == 0) { //获取根节点目录,在数据库中加第一行数据,即根目录的数据,pid设为0
JSONObject treeObj = new JSONObject();
treeObj.put("id", fd.getId());
treeObj.put("title", fd.getTitle());
treeObj.put("pid", fd.getPid());
treeObj.put("spread",true); //设置默认展开
treeObj.put("children", getChildren(fd.getId(),fileDirectories)); //查询叶子节点
list.add(treeObj);
}
}
return list;
}
/**
* 获取叶子节点目录,递归遍历
* */
public List<Object> getChildren(Integer Id,List<FileDirectory> fileDirectories){
List<Object> list = new ArrayList<>();
for (FileDirectory f : fileDirectories) {
if(f.getPid().equals(Id)){
JSONObject obj = new JSONObject();
obj.put("id", f.getId());
obj.put("title", f.getTitle());
obj.put("pid", f.getPid());
obj.put("children", getChildren(f.getId(),fileDirectories));
list.add(obj);
}
}
return list;
}
/**
* 增加文件目录
* */
@ResponseBody
@PostMapping("/saveDirectory")
public Object saveFileDirectory(FileDirectory fileDirectory){
// System.out.println(fileDirectory.getPid());
// System.out.println(fileDirectory.getTitle());
fileDirectory.setPid(fileDirectory.getPid()); //获取前面传过来的父ID
fileDirectory.setTitle(fileDirectory.getTitle()); //获取前面传过来的目录名称
return fileDirectoryService.saveFileDirectory(fileDirectory);
}
/**
* 修改文件目录名称
* */
@ResponseBody
@PostMapping("/updateDirectory")
public Object updateFileDirectory(Integer id, FileDirectory fileDirectory){
fileDirectory.setTitle(fileDirectory.getTitle());
return fileDirectoryService.updateFileDirectory(fileDirectory.getId(),fileDirectory);
}
/**
* 删除文件目录,同时删除该目录下所有节点目录
* */
@ResponseBody
@PostMapping("/delDirectory")
public Object delFileDirectory(Integer id) throws Exception{
fileDirectoryService.delFileDirectory(id);
return null;
}
}
前端html,放置layui树tree的地方
js代码
layui.use(['tree', 'util'], function() {
var tree = layui.tree;
var util = layui.util;
tree.render({
elem: '#medium-left-tree',
data: getData(),
id : 'treeId', //设置实例唯一索引
accordion: true, //开启手风琴模式
edit: ['add', 'update', 'del'],//操作节点的图标
operate: function(obj){ // 通过 operate 实现函数,对节点进行增删改等操作
var type = obj.type; //得到操作类型:add、edit、del
var data = obj.data; //得到当前节点的数据
var elem = obj.elem; //得到当前节点元素
//Ajax 操作
var id = data.id; //得到当前操作对象的Id
var title = data.title;
if (type === 'add'){ //新增节点
$.post("/admin/saveDirectory",{pid: id, title: "未命名"},function (result) {
// console.log(result)
tree.reload('treeId',{data: getData()});
// if (result) {
// layer.msg("新增成功")
// }else {
// layer.msg("新增失败")
// }
});
return;
}else if(type === 'update'){ //修改节点
$.post("/admin/updateDirectory",{id : id,title:title},function (result) {
tree.reload('treeId',{data: getData()});
});
return;
}else if (type === 'del'){ //删除节点,删除节点同时删除该节点下的所有字节点
var Ids = getChildId(data);
Ids.push(id); //把当前所选择的节点id加入数组
// console.log(childIds);
for(let ids of Ids){ // for-of 遍历的是值 val,只能遍历数组 (不能遍历对象)
// console.log("子节点id: "+ids);
$.post("/admin/delDirectory", {id: ids}, function (result) {
tree.reload('treeId', {data: getData()});
})
}
return;
}
},
//点击事件
click: function (obj) {
layer.msg(JSON.stringify(obj.data))
var type = obj.type; //得到操作类型:add、edit、del
var data = obj.data; //得到当前节点的数据
var elem = obj.elem; //得到当前节点元素
// console.log(obj.data.children); //当前节点下是否有子节点
}
});
});
function getData(){
var data = [];
$.ajax({
url: "/admin/listDirectory", //后台数据请求地址
type: "post",
async:false,
success: function(result){
data = result;
}
});
return data;
}
/**
* 获取所有子节点id
* */
var ids = [];
function getChildId( data ){
if( data.children.length > 0 ){
$.each( data.children, function(k, v){
ids.push( v.id );
getChildId( v );
});
}
return ids;
}
运行结果截图: