From a02aeb468e1930eb0da6ddfef70ee635a3929180 Mon Sep 17 00:00:00 2001
From: 疯狂的狮子li <15040126243@163.com>
Date: 星期日, 30 五月 2021 02:25:14 +0800
Subject: [PATCH] add 增加demo模块 树表演示案例(包含数据权限)

---
 ruoyi-demo/src/main/java/com/ruoyi/demo/bo/TestTreeAddBo.java                 |   39 ++
 ruoyi-demo/src/main/resources/mapper/demo/TestTreeMapper.xml                  |   22 +
 ruoyi-demo/src/main/java/com/ruoyi/demo/vo/TestTreeVo.java                    |   55 +++
 ruoyi-demo/src/main/java/com/ruoyi/demo/service/impl/TestTreeServiceImpl.java |   84 +++++
 ruoyi-ui/src/api/demo/tree.js                                                 |   53 +++
 ruoyi-ui/src/views/demo/tree/index.vue                                        |  282 ++++++++++++++++++
 ruoyi-demo/src/main/java/com/ruoyi/demo/bo/TestTreeQueryBo.java               |   42 ++
 ruoyi-demo/src/main/java/com/ruoyi/demo/domain/TestTree.java                  |   67 ++++
 ruoyi-demo/src/main/java/com/ruoyi/demo/mapper/TestTreeMapper.java            |   14 
 ruoyi-demo/src/main/java/com/ruoyi/demo/controller/TestTreeController.java    |  107 +++++++
 ruoyi-demo/src/main/java/com/ruoyi/demo/service/ITestTreeService.java         |   52 +++
 ruoyi-demo/src/main/java/com/ruoyi/demo/bo/TestTreeEditBo.java                |   47 +++
 12 files changed, 864 insertions(+), 0 deletions(-)

diff --git a/ruoyi-demo/src/main/java/com/ruoyi/demo/bo/TestTreeAddBo.java b/ruoyi-demo/src/main/java/com/ruoyi/demo/bo/TestTreeAddBo.java
new file mode 100644
index 0000000..a9a4b5e
--- /dev/null
+++ b/ruoyi-demo/src/main/java/com/ruoyi/demo/bo/TestTreeAddBo.java
@@ -0,0 +1,39 @@
+package com.ruoyi.demo.bo;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.Data;
+import java.util.Date;
+import javax.validation.constraints.*;
+
+
+
+/**
+ * 娴嬭瘯鏍戣〃娣诲姞瀵硅薄 test_tree
+ *
+ * @author Lion Li
+ * @date 2021-05-30
+ */
+@Data
+@ApiModel("娴嬭瘯鏍戣〃娣诲姞瀵硅薄")
+public class TestTreeAddBo {
+
+    /** 鐖秈d */
+    @ApiModelProperty("鐖秈d")
+    private Long parentId;
+
+    /** 閮ㄩ棬id */
+    @ApiModelProperty("閮ㄩ棬id")
+    private Long deptId;
+
+    /** 鐢ㄦ埛id */
+    @ApiModelProperty("鐢ㄦ埛id")
+    private Long userId;
+
+    /** 鏍戣妭鐐瑰悕 */
+    @ApiModelProperty("鏍戣妭鐐瑰悕")
+    @NotBlank(message = "鏍戣妭鐐瑰悕涓嶈兘涓虹┖")
+    private String treeName;
+
+}
diff --git a/ruoyi-demo/src/main/java/com/ruoyi/demo/bo/TestTreeEditBo.java b/ruoyi-demo/src/main/java/com/ruoyi/demo/bo/TestTreeEditBo.java
new file mode 100644
index 0000000..e3d359d
--- /dev/null
+++ b/ruoyi-demo/src/main/java/com/ruoyi/demo/bo/TestTreeEditBo.java
@@ -0,0 +1,47 @@
+package com.ruoyi.demo.bo;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.Data;
+import java.util.Date;
+import javax.validation.constraints.*;
+
+
+/**
+ * 娴嬭瘯鏍戣〃缂栬緫瀵硅薄 test_tree
+ *
+ * @author Lion Li
+ * @date 2021-05-30
+ */
+@Data
+@ApiModel("娴嬭瘯鏍戣〃缂栬緫瀵硅薄")
+public class TestTreeEditBo {
+
+
+    /** 涓婚敭 */
+    @ApiModelProperty("涓婚敭")
+    private Long id;
+
+
+    /** 鐖秈d */
+    @ApiModelProperty("鐖秈d")
+    private Long parentId;
+
+
+    /** 閮ㄩ棬id */
+    @ApiModelProperty("閮ㄩ棬id")
+    private Long deptId;
+
+
+    /** 鐢ㄦ埛id */
+    @ApiModelProperty("鐢ㄦ埛id")
+    private Long userId;
+
+
+    /** 鏍戣妭鐐瑰悕 */
+    @ApiModelProperty("鏍戣妭鐐瑰悕")
+    @NotBlank(message = "鏍戣妭鐐瑰悕涓嶈兘涓虹┖")
+    private String treeName;
+
+}
diff --git a/ruoyi-demo/src/main/java/com/ruoyi/demo/bo/TestTreeQueryBo.java b/ruoyi-demo/src/main/java/com/ruoyi/demo/bo/TestTreeQueryBo.java
new file mode 100644
index 0000000..3ed482b
--- /dev/null
+++ b/ruoyi-demo/src/main/java/com/ruoyi/demo/bo/TestTreeQueryBo.java
@@ -0,0 +1,42 @@
+package com.ruoyi.demo.bo;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.util.Date;
+
+import com.ruoyi.common.core.domain.BaseEntity;
+
+/**
+ * 娴嬭瘯鏍戣〃鍒嗛〉鏌ヨ瀵硅薄 test_tree
+ *
+ * @author Lion Li
+ * @date 2021-05-30
+ */
+
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ApiModel("娴嬭瘯鏍戣〃鍒嗛〉鏌ヨ瀵硅薄")
+public class TestTreeQueryBo extends BaseEntity {
+
+	/** 鍒嗛〉澶у皬 */
+	@ApiModelProperty("鍒嗛〉澶у皬")
+	private Integer pageSize;
+	/** 褰撳墠椤垫暟 */
+	@ApiModelProperty("褰撳墠椤垫暟")
+	private Integer pageNum;
+	/** 鎺掑簭鍒� */
+	@ApiModelProperty("鎺掑簭鍒�")
+	private String orderByColumn;
+	/** 鎺掑簭鐨勬柟鍚慸esc鎴栬�卆sc */
+	@ApiModelProperty(value = "鎺掑簭鐨勬柟鍚�", example = "asc,desc")
+	private String isAsc;
+
+
+	/** 鏍戣妭鐐瑰悕 */
+	@ApiModelProperty("鏍戣妭鐐瑰悕")
+	private String treeName;
+
+}
diff --git a/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/TestTreeController.java b/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/TestTreeController.java
new file mode 100644
index 0000000..54f1027
--- /dev/null
+++ b/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/TestTreeController.java
@@ -0,0 +1,107 @@
+package com.ruoyi.demo.controller;
+
+import com.ruoyi.common.annotation.Log;
+import com.ruoyi.common.core.controller.BaseController;
+import com.ruoyi.common.core.domain.AjaxResult;
+import com.ruoyi.common.enums.BusinessType;
+import com.ruoyi.common.utils.poi.ExcelUtil;
+import com.ruoyi.demo.bo.TestTreeAddBo;
+import com.ruoyi.demo.bo.TestTreeEditBo;
+import com.ruoyi.demo.bo.TestTreeQueryBo;
+import com.ruoyi.demo.service.ITestTreeService;
+import com.ruoyi.demo.vo.TestTreeVo;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.RequiredArgsConstructor;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import javax.validation.constraints.NotEmpty;
+import javax.validation.constraints.NotNull;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * 娴嬭瘯鏍戣〃Controller
+ *
+ * @author Lion Li
+ * @date 2021-05-30
+ */
+@Api(value = "娴嬭瘯鏍戣〃鎺у埗鍣�", tags = {"娴嬭瘯鏍戣〃绠$悊"})
+@RequiredArgsConstructor(onConstructor_ = @Autowired)
+@RestController
+@RequestMapping("/demo/tree")
+public class TestTreeController extends BaseController {
+
+    private final ITestTreeService iTestTreeService;
+
+    /**
+     * 鏌ヨ娴嬭瘯鏍戣〃鍒楄〃
+     */
+    @ApiOperation("鏌ヨ娴嬭瘯鏍戣〃鍒楄〃")
+    @PreAuthorize("@ss.hasPermi('demo:tree:list')")
+    @GetMapping("/list")
+    public AjaxResult<List<TestTreeVo>> list(@Validated TestTreeQueryBo bo) {
+        return AjaxResult.success(iTestTreeService.queryList(bo));
+    }
+
+    /**
+     * 瀵煎嚭娴嬭瘯鏍戣〃鍒楄〃
+     */
+    @ApiOperation("瀵煎嚭娴嬭瘯鏍戣〃鍒楄〃")
+    @PreAuthorize("@ss.hasPermi('demo:tree:export')")
+    @Log(title = "娴嬭瘯鏍戣〃", businessType = BusinessType.EXPORT)
+    @GetMapping("/export")
+    public AjaxResult<TestTreeVo> export(@Validated TestTreeQueryBo bo) {
+        List<TestTreeVo> list = iTestTreeService.queryList(bo);
+        ExcelUtil<TestTreeVo> util = new ExcelUtil<TestTreeVo>(TestTreeVo.class);
+        return util.exportExcel(list, "娴嬭瘯鏍戣〃");
+    }
+
+    /**
+     * 鑾峰彇娴嬭瘯鏍戣〃璇︾粏淇℃伅
+     */
+    @ApiOperation("鑾峰彇娴嬭瘯鏍戣〃璇︾粏淇℃伅")
+    @PreAuthorize("@ss.hasPermi('demo:tree:query')")
+    @GetMapping("/{id}")
+    public AjaxResult<TestTreeVo> getInfo(@NotNull(message = "涓婚敭涓嶈兘涓虹┖")
+                                                  @PathVariable("id") Long id) {
+        return AjaxResult.success(iTestTreeService.queryById(id));
+    }
+
+    /**
+     * 鏂板娴嬭瘯鏍戣〃
+     */
+    @ApiOperation("鏂板娴嬭瘯鏍戣〃")
+    @PreAuthorize("@ss.hasPermi('demo:tree:add')")
+    @Log(title = "娴嬭瘯鏍戣〃", businessType = BusinessType.INSERT)
+    @PostMapping()
+    public AjaxResult<Void> add(@Validated @RequestBody TestTreeAddBo bo) {
+        return toAjax(iTestTreeService.insertByAddBo(bo) ? 1 : 0);
+    }
+
+    /**
+     * 淇敼娴嬭瘯鏍戣〃
+     */
+    @ApiOperation("淇敼娴嬭瘯鏍戣〃")
+    @PreAuthorize("@ss.hasPermi('demo:tree:edit')")
+    @Log(title = "娴嬭瘯鏍戣〃", businessType = BusinessType.UPDATE)
+    @PutMapping()
+    public AjaxResult<Void> edit(@Validated @RequestBody TestTreeEditBo bo) {
+        return toAjax(iTestTreeService.updateByEditBo(bo) ? 1 : 0);
+    }
+
+    /**
+     * 鍒犻櫎娴嬭瘯鏍戣〃
+     */
+    @ApiOperation("鍒犻櫎娴嬭瘯鏍戣〃")
+    @PreAuthorize("@ss.hasPermi('demo:tree:remove')")
+    @Log(title = "娴嬭瘯鏍戣〃" , businessType = BusinessType.DELETE)
+    @DeleteMapping("/{ids}")
+    public AjaxResult<Void> remove(@NotEmpty(message = "涓婚敭涓嶈兘涓虹┖")
+                                       @PathVariable Long[] ids) {
+        return toAjax(iTestTreeService.deleteWithValidByIds(Arrays.asList(ids), true) ? 1 : 0);
+    }
+}
diff --git a/ruoyi-demo/src/main/java/com/ruoyi/demo/domain/TestTree.java b/ruoyi-demo/src/main/java/com/ruoyi/demo/domain/TestTree.java
new file mode 100644
index 0000000..43d1efe
--- /dev/null
+++ b/ruoyi-demo/src/main/java/com/ruoyi/demo/domain/TestTree.java
@@ -0,0 +1,67 @@
+package com.ruoyi.demo.domain;
+
+import com.baomidou.mybatisplus.annotation.*;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import lombok.experimental.Accessors;
+import java.io.Serializable;
+import java.util.Date;
+import java.math.BigDecimal;
+import com.ruoyi.common.annotation.Excel;
+
+/**
+ * 娴嬭瘯鏍戣〃瀵硅薄 test_tree
+ *
+ * @author Lion Li
+ * @date 2021-05-30
+ */
+@Data
+@NoArgsConstructor
+@Accessors(chain = true)
+@TableName("test_tree")
+public class TestTree implements Serializable {
+
+    private static final long serialVersionUID=1L;
+
+
+    /** 涓婚敭 */
+    @TableId(value = "id")
+    private Long id;
+
+    /** 鐖秈d */
+    private Long parentId;
+
+    /** 閮ㄩ棬id */
+    private Long deptId;
+
+    /** 鐢ㄦ埛id */
+    private Long userId;
+
+    /** 鏍戣妭鐐瑰悕 */
+    private String treeName;
+
+    /** 鐗堟湰 */
+    @Version
+    private Long version;
+
+    /** 鍒涘缓鏃堕棿 */
+    @TableField(fill = FieldFill.INSERT)
+    private Date createTime;
+
+    /** 鍒涘缓浜� */
+    @TableField(fill = FieldFill.INSERT)
+    private String createBy;
+
+    /** 鏇存柊鏃堕棿 */
+    @TableField(fill = FieldFill.INSERT_UPDATE)
+    private Date updateTime;
+
+    /** 鏇存柊浜� */
+    @TableField(fill = FieldFill.INSERT_UPDATE)
+    private String updateBy;
+
+    /** 鍒犻櫎鏍囧織 */
+    @TableLogic
+    private Long delFlag;
+
+}
diff --git a/ruoyi-demo/src/main/java/com/ruoyi/demo/mapper/TestTreeMapper.java b/ruoyi-demo/src/main/java/com/ruoyi/demo/mapper/TestTreeMapper.java
new file mode 100644
index 0000000..6dd75c5
--- /dev/null
+++ b/ruoyi-demo/src/main/java/com/ruoyi/demo/mapper/TestTreeMapper.java
@@ -0,0 +1,14 @@
+package com.ruoyi.demo.mapper;
+
+import com.ruoyi.demo.domain.TestTree;
+import com.ruoyi.common.core.page.BaseMapperPlus;
+
+/**
+ * 娴嬭瘯鏍戣〃Mapper鎺ュ彛
+ *
+ * @author Lion Li
+ * @date 2021-05-30
+ */
+public interface TestTreeMapper extends BaseMapperPlus<TestTree> {
+
+}
diff --git a/ruoyi-demo/src/main/java/com/ruoyi/demo/service/ITestTreeService.java b/ruoyi-demo/src/main/java/com/ruoyi/demo/service/ITestTreeService.java
new file mode 100644
index 0000000..605b3df
--- /dev/null
+++ b/ruoyi-demo/src/main/java/com/ruoyi/demo/service/ITestTreeService.java
@@ -0,0 +1,52 @@
+package com.ruoyi.demo.service;
+
+import com.ruoyi.common.core.page.IServicePlus;
+import com.ruoyi.demo.bo.TestTreeAddBo;
+import com.ruoyi.demo.bo.TestTreeEditBo;
+import com.ruoyi.demo.bo.TestTreeQueryBo;
+import com.ruoyi.demo.domain.TestTree;
+import com.ruoyi.demo.vo.TestTreeVo;
+
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * 娴嬭瘯鏍戣〃Service鎺ュ彛
+ *
+ * @author Lion Li
+ * @date 2021-05-30
+ */
+public interface ITestTreeService extends IServicePlus<TestTree> {
+	/**
+	 * 鏌ヨ鍗曚釜
+	 * @return
+	 */
+	TestTreeVo queryById(Long id);
+
+	/**
+	 * 鏌ヨ鍒楄〃
+	 */
+	List<TestTreeVo> queryList(TestTreeQueryBo bo);
+
+	/**
+	 * 鏍规嵁鏂板涓氬姟瀵硅薄鎻掑叆娴嬭瘯鏍戣〃
+	 * @param bo 娴嬭瘯鏍戣〃鏂板涓氬姟瀵硅薄
+	 * @return
+	 */
+	Boolean insertByAddBo(TestTreeAddBo bo);
+
+	/**
+	 * 鏍规嵁缂栬緫涓氬姟瀵硅薄淇敼娴嬭瘯鏍戣〃
+	 * @param bo 娴嬭瘯鏍戣〃缂栬緫涓氬姟瀵硅薄
+	 * @return
+	 */
+	Boolean updateByEditBo(TestTreeEditBo bo);
+
+	/**
+	 * 鏍¢獙骞跺垹闄ゆ暟鎹�
+	 * @param ids 涓婚敭闆嗗悎
+	 * @param isValid 鏄惁鏍¢獙,true-鍒犻櫎鍓嶆牎楠�,false-涓嶆牎楠�
+	 * @return
+	 */
+	Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
+}
diff --git a/ruoyi-demo/src/main/java/com/ruoyi/demo/service/impl/TestTreeServiceImpl.java b/ruoyi-demo/src/main/java/com/ruoyi/demo/service/impl/TestTreeServiceImpl.java
new file mode 100644
index 0000000..ae93ef3
--- /dev/null
+++ b/ruoyi-demo/src/main/java/com/ruoyi/demo/service/impl/TestTreeServiceImpl.java
@@ -0,0 +1,84 @@
+package com.ruoyi.demo.service.impl;
+
+import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.util.StrUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.ruoyi.common.annotation.DataScope;
+import com.ruoyi.demo.bo.TestTreeAddBo;
+import com.ruoyi.demo.bo.TestTreeEditBo;
+import com.ruoyi.demo.bo.TestTreeQueryBo;
+import com.ruoyi.demo.domain.TestTree;
+import com.ruoyi.demo.mapper.TestTreeMapper;
+import com.ruoyi.demo.service.ITestTreeService;
+import com.ruoyi.demo.vo.TestTreeVo;
+import org.springframework.stereotype.Service;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 娴嬭瘯鏍戣〃Service涓氬姟灞傚鐞�
+ *
+ * @author Lion Li
+ * @date 2021-05-30
+ */
+@Service
+public class TestTreeServiceImpl extends ServiceImpl<TestTreeMapper, TestTree> implements ITestTreeService {
+
+	@Override
+	public TestTreeVo queryById(Long id) {
+		return getVoById(id, TestTreeVo.class);
+	}
+
+	@DataScope(isUser = true)
+	@Override
+	public List<TestTreeVo> queryList(TestTreeQueryBo bo) {
+		return listVo(buildQueryWrapper(bo), TestTreeVo.class);
+	}
+
+	private LambdaQueryWrapper<TestTree> buildQueryWrapper(TestTreeQueryBo bo) {
+		Map<String, Object> params = bo.getParams();
+		Object dataScope = params.get("dataScope");
+		LambdaQueryWrapper<TestTree> lqw = Wrappers.lambdaQuery();
+		lqw.like(StrUtil.isNotBlank(bo.getTreeName()), TestTree::getTreeName, bo.getTreeName());
+		lqw.between(params.get("beginCreateTime") != null && params.get("endCreateTime") != null,
+			TestTree::getCreateTime, params.get("beginCreateTime"), params.get("endCreateTime"));
+		lqw.apply(dataScope != null && StrUtil.isNotBlank(dataScope.toString()),
+			dataScope != null ? dataScope.toString() : null);
+		return lqw;
+	}
+
+	@Override
+	public Boolean insertByAddBo(TestTreeAddBo bo) {
+		TestTree add = BeanUtil.toBean(bo, TestTree.class);
+		validEntityBeforeSave(add);
+		return save(add);
+	}
+
+	@Override
+	public Boolean updateByEditBo(TestTreeEditBo bo) {
+		TestTree update = BeanUtil.toBean(bo, TestTree.class);
+		validEntityBeforeSave(update);
+		return updateById(update);
+	}
+
+	/**
+	 * 淇濆瓨鍓嶇殑鏁版嵁鏍¢獙
+	 *
+	 * @param entity 瀹炰綋绫绘暟鎹�
+	 */
+	private void validEntityBeforeSave(TestTree entity) {
+		//TODO 鍋氫竴浜涙暟鎹牎楠�,濡傚敮涓�绾︽潫
+	}
+
+	@Override
+	public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
+		if (isValid) {
+			//TODO 鍋氫竴浜涗笟鍔′笂鐨勬牎楠�,鍒ゆ柇鏄惁闇�瑕佹牎楠�
+		}
+		return removeByIds(ids);
+	}
+}
diff --git a/ruoyi-demo/src/main/java/com/ruoyi/demo/vo/TestTreeVo.java b/ruoyi-demo/src/main/java/com/ruoyi/demo/vo/TestTreeVo.java
new file mode 100644
index 0000000..44413b1
--- /dev/null
+++ b/ruoyi-demo/src/main/java/com/ruoyi/demo/vo/TestTreeVo.java
@@ -0,0 +1,55 @@
+package com.ruoyi.demo.vo;
+
+import com.ruoyi.common.annotation.Excel;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import java.util.Date;
+
+
+
+/**
+ * 娴嬭瘯鏍戣〃瑙嗗浘瀵硅薄 test_tree
+ *
+ * @author Lion Li
+ * @date 2021-05-30
+ */
+@Data
+@ApiModel("娴嬭瘯鏍戣〃瑙嗗浘瀵硅薄")
+public class TestTreeVo {
+
+	private static final long serialVersionUID = 1L;
+
+	/** 涓婚敭 */
+	@ApiModelProperty("涓婚敭")
+	private Long id;
+
+	/** 鐖秈d */
+	@Excel(name = "鐖秈d")
+	@ApiModelProperty("鐖秈d")
+	private Long parentId;
+
+	/** 閮ㄩ棬id */
+	@Excel(name = "閮ㄩ棬id")
+	@ApiModelProperty("閮ㄩ棬id")
+	private Long deptId;
+
+	/** 鐢ㄦ埛id */
+	@Excel(name = "鐢ㄦ埛id")
+	@ApiModelProperty("鐢ㄦ埛id")
+	private Long userId;
+
+	/** 鏍戣妭鐐瑰悕 */
+	@Excel(name = "鏍戣妭鐐瑰悕")
+	@ApiModelProperty("鏍戣妭鐐瑰悕")
+	private String treeName;
+
+	/** 鍒涘缓鏃堕棿 */
+	@Excel(name = "鍒涘缓鏃堕棿" , width = 30, dateFormat = "yyyy-MM-dd")
+	@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+	@ApiModelProperty("鍒涘缓鏃堕棿")
+	private Date createTime;
+
+
+}
diff --git a/ruoyi-demo/src/main/resources/mapper/demo/TestTreeMapper.xml b/ruoyi-demo/src/main/resources/mapper/demo/TestTreeMapper.xml
new file mode 100644
index 0000000..0943d5b
--- /dev/null
+++ b/ruoyi-demo/src/main/resources/mapper/demo/TestTreeMapper.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper
+PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.ruoyi.demo.mapper.TestTreeMapper">
+
+    <resultMap type="com.ruoyi.demo.domain.TestTree" id="TestTreeResult">
+        <result property="id" column="id"/>
+        <result property="parentId" column="parent_id"/>
+        <result property="deptId" column="dept_id"/>
+        <result property="userId" column="user_id"/>
+        <result property="treeName" column="tree_name"/>
+        <result property="version" column="version"/>
+        <result property="createTime" column="create_time"/>
+        <result property="createBy" column="create_by"/>
+        <result property="updateTime" column="update_time"/>
+        <result property="updateBy" column="update_by"/>
+        <result property="delFlag" column="del_flag"/>
+    </resultMap>
+
+
+</mapper>
\ No newline at end of file
diff --git a/ruoyi-ui/src/api/demo/tree.js b/ruoyi-ui/src/api/demo/tree.js
new file mode 100644
index 0000000..d597e72
--- /dev/null
+++ b/ruoyi-ui/src/api/demo/tree.js
@@ -0,0 +1,53 @@
+import request from '@/utils/request'
+
+// 鏌ヨ娴嬭瘯鏍戣〃鍒楄〃
+export function listTree(query) {
+  return request({
+    url: '/demo/tree/list',
+    method: 'get',
+    params: query
+  })
+}
+
+// 鏌ヨ娴嬭瘯鏍戣〃璇︾粏
+export function getTree(id) {
+  return request({
+    url: '/demo/tree/' + id,
+    method: 'get'
+  })
+}
+
+// 鏂板娴嬭瘯鏍戣〃
+export function addTree(data) {
+  return request({
+    url: '/demo/tree',
+    method: 'post',
+    data: data
+  })
+}
+
+// 淇敼娴嬭瘯鏍戣〃
+export function updateTree(data) {
+  return request({
+    url: '/demo/tree',
+    method: 'put',
+    data: data
+  })
+}
+
+// 鍒犻櫎娴嬭瘯鏍戣〃
+export function delTree(id) {
+  return request({
+    url: '/demo/tree/' + id,
+    method: 'delete'
+  })
+}
+
+// 瀵煎嚭娴嬭瘯鏍戣〃
+export function exportTree(query) {
+  return request({
+    url: '/demo/tree/export',
+    method: 'get',
+    params: query
+  })
+}
\ No newline at end of file
diff --git a/ruoyi-ui/src/views/demo/tree/index.vue b/ruoyi-ui/src/views/demo/tree/index.vue
new file mode 100644
index 0000000..ddf7677
--- /dev/null
+++ b/ruoyi-ui/src/views/demo/tree/index.vue
@@ -0,0 +1,282 @@
+<template>
+  <div class="app-container">
+    <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
+      <el-form-item label="鏍戣妭鐐瑰悕" prop="treeName">
+        <el-input
+          v-model="queryParams.treeName"
+          placeholder="璇疯緭鍏ユ爲鑺傜偣鍚�"
+          clearable
+          size="small"
+          @keyup.enter.native="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="鍒涘缓鏃堕棿">
+        <el-date-picker
+          v-model="daterangeCreateTime"
+          size="small"
+          style="width: 240px"
+          value-format="yyyy-MM-dd"
+          type="daterange"
+          range-separator="-"
+          start-placeholder="寮�濮嬫棩鏈�"
+          end-placeholder="缁撴潫鏃ユ湡"
+        ></el-date-picker>
+      </el-form-item>
+      <el-form-item>
+        <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">鎼滅储</el-button>
+        <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">閲嶇疆</el-button>
+      </el-form-item>
+    </el-form>
+
+    <el-row :gutter="10" class="mb8">
+      <el-col :span="1.5">
+        <el-button
+          type="primary"
+          plain
+          icon="el-icon-plus"
+          size="mini"
+          @click="handleAdd"
+          v-hasPermi="['demo:tree:add']"
+        >鏂板</el-button>
+      </el-col>
+      <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
+    </el-row>
+
+    <el-table
+      v-loading="loading"
+      :data="treeList"
+      row-key="id"
+      default-expand-all
+      :tree-props="{children: 'children', hasChildren: 'hasChildren'}"
+    >
+      <el-table-column label="鐖秈d" prop="parentId" />
+      <el-table-column label="閮ㄩ棬id" align="center" prop="deptId" />
+      <el-table-column label="鐢ㄦ埛id" align="center" prop="userId" />
+      <el-table-column label="鏍戣妭鐐瑰悕" align="center" prop="treeName" />
+      <el-table-column label="鍒涘缓鏃堕棿" align="center" prop="createTime" width="180">
+        <template slot-scope="scope">
+          <span>{{ parseTime(scope.row.createTime, '{y}-{m}-{d}') }}</span>
+        </template>
+      </el-table-column>
+      <el-table-column label="鎿嶄綔" align="center" class-name="small-padding fixed-width">
+        <template slot-scope="scope">
+          <el-button
+            size="mini"
+            type="text"
+            icon="el-icon-edit"
+            @click="handleUpdate(scope.row)"
+            v-hasPermi="['demo:tree:edit']"
+          >淇敼</el-button>
+          <el-button
+            size="mini"
+            type="text"
+            icon="el-icon-plus"
+            @click="handleAdd(scope.row)"
+            v-hasPermi="['demo:tree:add']"
+          >鏂板</el-button>
+          <el-button
+            size="mini"
+            type="text"
+            icon="el-icon-delete"
+            @click="handleDelete(scope.row)"
+            v-hasPermi="['demo:tree:remove']"
+          >鍒犻櫎</el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+
+    <!-- 娣诲姞鎴栦慨鏀规祴璇曟爲琛ㄥ璇濇 -->
+    <el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
+      <el-form ref="form" :model="form" :rules="rules" label-width="80px">
+        <el-form-item label="鐖秈d" prop="parentId">
+          <treeselect v-model="form.parentId" :options="treeOptions" :normalizer="normalizer" placeholder="璇烽�夋嫨鐖秈d" />
+        </el-form-item>
+        <el-form-item label="閮ㄩ棬id" prop="deptId">
+          <el-input v-model="form.deptId" placeholder="璇疯緭鍏ラ儴闂╥d" />
+        </el-form-item>
+        <el-form-item label="鐢ㄦ埛id" prop="userId">
+          <el-input v-model="form.userId" placeholder="璇疯緭鍏ョ敤鎴穒d" />
+        </el-form-item>
+        <el-form-item label="鏍戣妭鐐瑰悕" prop="treeName">
+          <el-input v-model="form.treeName" placeholder="璇疯緭鍏ユ爲鑺傜偣鍚�" />
+        </el-form-item>
+      </el-form>
+      <div slot="footer" class="dialog-footer">
+        <el-button type="primary" @click="submitForm">纭� 瀹�</el-button>
+        <el-button @click="cancel">鍙� 娑�</el-button>
+      </div>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import { listTree, getTree, delTree, addTree, updateTree, exportTree } from "@/api/demo/tree";
+import Treeselect from "@riophae/vue-treeselect";
+import "@riophae/vue-treeselect/dist/vue-treeselect.css";
+
+export default {
+  name: "Tree",
+  components: {
+    Treeselect
+  },
+  data() {
+    return {
+      // 閬僵灞�
+      loading: true,
+      // 鏄剧ず鎼滅储鏉′欢
+      showSearch: true,
+      // 娴嬭瘯鏍戣〃琛ㄦ牸鏁版嵁
+      treeList: [],
+      // 娴嬭瘯鏍戣〃鏍戦�夐」
+      treeOptions: [],
+      // 寮瑰嚭灞傛爣棰�
+      title: "",
+      // 鏄惁鏄剧ず寮瑰嚭灞�
+      open: false,
+      // 鍒涘缓鏃堕棿鏃堕棿鑼冨洿
+      daterangeCreateTime: [],
+      // 鏌ヨ鍙傛暟
+      queryParams: {
+        treeName: null,
+        createTime: null,
+      },
+      // 琛ㄥ崟鍙傛暟
+      form: {},
+      // 琛ㄥ崟鏍¢獙
+      rules: {
+        treeName: [
+          { required: true, message: "鏍戣妭鐐瑰悕涓嶈兘涓虹┖", trigger: "blur" }
+        ],
+      }
+    };
+  },
+  created() {
+    this.getList();
+  },
+  methods: {
+    /** 鏌ヨ娴嬭瘯鏍戣〃鍒楄〃 */
+    getList() {
+      this.loading = true;
+      this.queryParams.params = {};
+      if (null != this.daterangeCreateTime && '' != this.daterangeCreateTime) {
+        this.queryParams.params["beginCreateTime"] = this.daterangeCreateTime[0];
+        this.queryParams.params["endCreateTime"] = this.daterangeCreateTime[1];
+      }
+      listTree(this.queryParams).then(response => {
+        this.treeList = this.handleTree(response.data, "id", "parentId");
+        this.loading = false;
+      });
+    },
+    /** 杞崲娴嬭瘯鏍戣〃鏁版嵁缁撴瀯 */
+    normalizer(node) {
+      if (node.children && !node.children.length) {
+        delete node.children;
+      }
+      return {
+        id: node.id,
+        label: node.treeName,
+        children: node.children
+      };
+    },
+    /** 鏌ヨ娴嬭瘯鏍戣〃涓嬫媺鏍戠粨鏋� */
+    getTreeselect() {
+      listTree().then(response => {
+        this.treeOptions = [];
+        const data = { id: 0, treeName: '椤剁骇鑺傜偣', children: [] };
+        data.children = this.handleTree(response.data, "id", "parentId");
+        this.treeOptions.push(data);
+      });
+    },
+    // 鍙栨秷鎸夐挳
+    cancel() {
+      this.open = false;
+      this.reset();
+    },
+    // 琛ㄥ崟閲嶇疆
+    reset() {
+      this.form = {
+        id: null,
+        parentId: null,
+        deptId: null,
+        userId: null,
+        treeName: null,
+        version: null,
+        createTime: null,
+        createBy: null,
+        updateTime: null,
+        updateBy: null,
+        delFlag: null
+      };
+      this.resetForm("form");
+    },
+    /** 鎼滅储鎸夐挳鎿嶄綔 */
+    handleQuery() {
+      this.getList();
+    },
+    /** 閲嶇疆鎸夐挳鎿嶄綔 */
+    resetQuery() {
+      this.daterangeCreateTime = [];
+      this.resetForm("queryForm");
+      this.handleQuery();
+    },
+    /** 鏂板鎸夐挳鎿嶄綔 */
+    handleAdd(row) {
+      this.reset();
+      this.getTreeselect();
+      if (row != null && row.id) {
+        this.form.parentId = row.id;
+      } else {
+        this.form.parentId = 0;
+      }
+      this.open = true;
+      this.title = "娣诲姞娴嬭瘯鏍戣〃";
+    },
+    /** 淇敼鎸夐挳鎿嶄綔 */
+    handleUpdate(row) {
+      this.reset();
+      this.getTreeselect();
+      if (row != null) {
+        this.form.parentId = row.id;
+      }
+      getTree(row.id).then(response => {
+        this.form = response.data;
+        this.open = true;
+        this.title = "淇敼娴嬭瘯鏍戣〃";
+      });
+    },
+    /** 鎻愪氦鎸夐挳 */
+    submitForm() {
+      this.$refs["form"].validate(valid => {
+        if (valid) {
+          if (this.form.id != null) {
+            updateTree(this.form).then(response => {
+              this.msgSuccess("淇敼鎴愬姛");
+              this.open = false;
+              this.getList();
+            });
+          } else {
+            addTree(this.form).then(response => {
+              this.msgSuccess("鏂板鎴愬姛");
+              this.open = false;
+              this.getList();
+            });
+          }
+        }
+      });
+    },
+    /** 鍒犻櫎鎸夐挳鎿嶄綔 */
+    handleDelete(row) {
+      this.$confirm('鏄惁纭鍒犻櫎娴嬭瘯鏍戣〃缂栧彿涓�"' + row.id + '"鐨勬暟鎹」?', "璀﹀憡", {
+        confirmButtonText: "纭畾",
+        cancelButtonText: "鍙栨秷",
+        type: "warning"
+      }).then(function() {
+        return delTree(row.id);
+      }).then(() => {
+        this.getList();
+        this.msgSuccess("鍒犻櫎鎴愬姛");
+      })
+    }
+  }
+};
+</script>

--
Gitblit v1.9.3