增加动画效果

This commit is contained in:
thinkgem
2018-02-06 22:17:55 +08:00
parent 86d3d04f40
commit 23a849c815
13 changed files with 894 additions and 110 deletions

View File

@@ -0,0 +1,18 @@
/**
* Copyright (c) 2013-Now http://jeesite.com All rights reserved.
*/
package com.jeesite.modules.test.dao;
import com.jeesite.common.dao.TreeDao;
import com.jeesite.common.mybatis.annotation.MyBatisDao;
import com.jeesite.modules.test.entity.TestTree;
/**
* 测试树表DAO接口
* @author ThinkGem
* @version 2018-02-06
*/
@MyBatisDao
public interface TestTreeDao extends TreeDao<TestTree> {
}

View File

@@ -0,0 +1,67 @@
/**
* Copyright (c) 2013-Now http://jeesite.com All rights reserved.
*/
package com.jeesite.modules.test.entity;
import org.hibernate.validator.constraints.NotBlank;
import org.hibernate.validator.constraints.Length;
import com.jeesite.common.entity.DataEntity;
import com.jeesite.common.entity.TreeEntity;
import com.jeesite.common.mybatis.annotation.Column;
import com.jeesite.common.mybatis.annotation.Table;
import com.jeesite.common.mybatis.mapper.query.QueryType;
/**
* 测试树表Entity
* @author ThinkGem
* @version 2018-02-06
*/
@Table(name="test_tree", alias="a", columns={
@Column(name="tree_code", attrName="treeCode", label="节点编码", isPK=true),
@Column(includeEntity=TreeEntity.class),
@Column(name="tree_name", attrName="treeName", label="树节点名", queryType=QueryType.LIKE, isTreeName=true),
@Column(includeEntity=DataEntity.class),
}, orderBy="a.tree_sorts, a.tree_code"
)
public class TestTree extends TreeEntity<TestTree> {
private static final long serialVersionUID = 1L;
private String treeCode; // 节点编码
private String treeName; // 树节点名
public TestTree() {
this(null);
}
public TestTree(String id){
super(id);
}
public TestTree getParent() {
return parent;
}
public void setParent(TestTree parent) {
this.parent = parent;
}
public String getTreeCode() {
return treeCode;
}
public void setTreeCode(String treeCode) {
this.treeCode = treeCode;
}
@NotBlank(message="树节点名不能为空")
@Length(min=0, max=200, message="树节点名长度不能超过 200 个字符")
public String getTreeName() {
return treeName;
}
public void setTreeName(String treeName) {
this.treeName = treeName;
}
}

View File

@@ -0,0 +1,75 @@
/**
* Copyright (c) 2013-Now http://jeesite.com All rights reserved.
*/
package com.jeesite.modules.test.service;
import java.util.List;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.jeesite.common.entity.Page;
import com.jeesite.common.service.TreeService;
import com.jeesite.modules.test.entity.TestTree;
import com.jeesite.modules.test.dao.TestTreeDao;
import com.jeesite.modules.file.utils.FileUploadUtils;
/**
* 测试树表Service
* @author ThinkGem
* @version 2018-02-06
*/
@Service
@Transactional(readOnly=true)
public class TestTreeService extends TreeService<TestTreeDao, TestTree> {
/**
* 获取单条数据
* @param testTree
* @return
*/
public TestTree get(TestTree testTree) {
return super.get(testTree);
}
/**
* 查询列表数据
* @param testTree
* @return
*/
public List<TestTree> findList(TestTree testTree) {
return super.findList(testTree);
}
/**
* 保存数据(插入或更新)
* @param testTree
*/
@Transactional(readOnly=false)
public void save(TestTree testTree) {
super.save(testTree);
// 保存上传图片
FileUploadUtils.saveFileUpload(testTree.getId(), "testTree_image");
// 保存上传附件
FileUploadUtils.saveFileUpload(testTree.getId(), "testTree_file");
}
/**
* 更新状态
* @param testTree
*/
@Transactional(readOnly=false)
public void updateStatus(TestTree testTree) {
super.updateStatus(testTree);
}
/**
* 删除数据
* @param testTree
*/
@Transactional(readOnly=false)
public void delete(TestTree testTree) {
super.delete(testTree);
}
}

View File

@@ -0,0 +1,226 @@
/**
* Copyright (c) 2013-Now http://jeesite.com All rights reserved.
*/
package com.jeesite.modules.test.web;
import java.util.List;
import java.util.Map;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import com.jeesite.common.config.Global;
import com.jeesite.common.collect.ListUtils;
import com.jeesite.common.collect.MapUtils;
import com.jeesite.common.lang.StringUtils;
import com.jeesite.common.idgen.IdGen;
import com.jeesite.modules.sys.utils.UserUtils;
import com.jeesite.common.web.BaseController;
import com.jeesite.modules.test.entity.TestTree;
import com.jeesite.modules.test.service.TestTreeService;
/**
* 测试树表Controller
* @author ThinkGem
* @version 2018-02-06
*/
@Controller
@RequestMapping(value = "${adminPath}/test/testTree")
public class TestTreeController extends BaseController {
@Autowired
private TestTreeService testTreeService;
/**
* 获取数据
*/
@ModelAttribute
public TestTree get(String treeCode, boolean isNewRecord) {
return testTreeService.get(treeCode, isNewRecord);
}
/**
* 查询列表
*/
@RequiresPermissions("test:testTree:view")
@RequestMapping(value = {"list", ""})
public String list(TestTree testTree, Model model) {
model.addAttribute("testTree", testTree);
return "modules/test/testTreeList";
}
/**
* 查询列表数据
*/
@RequiresPermissions("test:testTree:view")
@RequestMapping(value = "listData")
@ResponseBody
public List<TestTree> listData(TestTree testTree) {
if (StringUtils.isBlank(testTree.getParentCode())) {
testTree.setParentCode(TestTree.ROOT_CODE);
}
if (StringUtils.isNotBlank(testTree.getTreeName())){
testTree.setParentCode(null);
}
if (StringUtils.isNotBlank(testTree.getStatus())){
testTree.setParentCode(null);
}
if (StringUtils.isNotBlank(testTree.getRemarks())){
testTree.setParentCode(null);
}
List<TestTree> list = testTreeService.findList(testTree);
return list;
}
/**
* 查看编辑表单
*/
@RequiresPermissions("test:testTree:view")
@RequestMapping(value = "form")
public String form(TestTree testTree, Model model) {
// 创建并初始化下一个节点信息
testTree = createNextNode(testTree);
model.addAttribute("testTree", testTree);
return "modules/test/testTreeForm";
}
/**
* 创建并初始化下一个节点信息,如:排序号、默认值
*/
@RequiresPermissions("test:testTree:edit")
@RequestMapping(value = "createNextNode")
@ResponseBody
public TestTree createNextNode(TestTree testTree) {
if (StringUtils.isNotBlank(testTree.getParentCode())){
testTree.setParent(testTreeService.get(testTree.getParentCode()));
}
if (testTree.getIsNewRecord()) {
TestTree where = new TestTree();
where.setParentCode(testTree.getParentCode());
TestTree last = testTreeService.getLastByParentCode(where);
// 获取到下级最后一个节点
if (last != null){
testTree.setTreeSort(last.getTreeSort() + 30);
testTree.setTreeCode(IdGen.nextCode(last.getTreeCode()));
}else if (testTree.getParent() != null){
testTree.setTreeCode(testTree.getParent().getTreeCode() + "001");
}
}
// 以下设置表单默认数据
if (testTree.getTreeSort() == null){
testTree.setTreeSort(TestTree.DEFAULT_TREE_SORT);
}
return testTree;
}
/**
* 保存数据
*/
@RequiresPermissions("test:testTree:edit")
@PostMapping(value = "save")
@ResponseBody
public String save(@Validated TestTree testTree) {
testTreeService.save(testTree);
return renderResult(Global.TRUE, "保存数据成功!");
}
/**
* 停用数据
*/
@RequiresPermissions("test:testTree:edit")
@RequestMapping(value = "disable")
@ResponseBody
public String disable(TestTree testTree) {
TestTree where = new TestTree();
where.setStatus(TestTree.STATUS_NORMAL);
where.setParentCodes("," + testTree.getId() + ",");
long count = testTreeService.findCount(where);
if (count > 0) {
return renderResult(Global.FALSE, "该数据包含未停用的子数据!");
}
testTree.setStatus(TestTree.STATUS_DISABLE);
testTreeService.updateStatus(testTree);
return renderResult(Global.TRUE, "停用数据成功");
}
/**
* 启用数据
*/
@RequiresPermissions("test:testTree:edit")
@RequestMapping(value = "enable")
@ResponseBody
public String enable(TestTree testTree) {
testTree.setStatus(TestTree.STATUS_NORMAL);
testTreeService.updateStatus(testTree);
return renderResult(Global.TRUE, "启用数据成功");
}
/**
* 删除数据
*/
@RequiresPermissions("test:testTree:edit")
@RequestMapping(value = "delete")
@ResponseBody
public String delete(TestTree testTree) {
testTreeService.delete(testTree);
return renderResult(Global.TRUE, "删除数据成功!");
}
/**
* 获取树结构数据
* @param excludeCode 排除的Code
* @param isShowCode 是否显示编码true or 1显示在左侧2显示在右侧false or null不显示
* @return
*/
@RequiresPermissions("test:testTree:view")
@RequestMapping(value = "treeData")
@ResponseBody
public List<Map<String, Object>> treeData(String excludeCode, String isShowCode) {
List<Map<String, Object>> mapList = ListUtils.newArrayList();
List<TestTree> list = testTreeService.findList(new TestTree());
for (int i=0; i<list.size(); i++){
TestTree e = list.get(i);
// 过滤非正常的数据
if (!TestTree.STATUS_NORMAL.equals(e.getStatus())){
continue;
}
// 过滤被排除的编码(包括所有子级)
if (StringUtils.isNotBlank(excludeCode)){
if (e.getId().equals(excludeCode)){
continue;
}
if (e.getParentCodes().contains("," + excludeCode + ",")){
continue;
}
}
Map<String, Object> map = MapUtils.newHashMap();
map.put("id", e.getId());
map.put("pId", e.getParentCode());
map.put("name", StringUtils.getTreeNodeName(isShowCode, e.getTreeCode(), e.getTreeName()));
mapList.add(map);
}
return mapList;
}
/**
* 修复表结构相关数据
*/
@RequiresPermissions("test:testTree:edit")
@RequestMapping(value = "fixTreeData")
@ResponseBody
public String fixTreeData(TestTree testTree){
if (!UserUtils.getUser().isAdmin()){
return renderResult(Global.FALSE, "操作失败,只有管理员才能进行修复!");
}
testTreeService.fixTreeData();
return renderResult(Global.TRUE, "数据修复成功");
}
}

View File

@@ -0,0 +1,15 @@
<?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.jeesite.modules.test.dao.TestTreeDao">
<!-- 查询数据
<select id="findList" resultType="TestTree">
SELECT ${sqlMap.column.toSql()}
FROM ${sqlMap.table.toSql()}
<where>
${sqlMap.where.toSql()}
</where>
ORDER BY ${sqlMap.order.toSql()}
</select> -->
</mapper>

View File

@@ -0,0 +1,134 @@
<% layout('/layouts/default.html', {title: '数据管理', libs: ['validate','fileupload']}){ %>
<div class="main-content">
<div class="box box-main">
<div class="box-header with-border">
<div class="box-title">
<i class="fa fa-list-alt"></i> ${testTree.isNewRecord ? '新增数据' : '编辑数据'}
</div>
<div class="box-tools pull-right">
<button type="button" class="btn btn-box-tool" data-widget="collapse"><i class="fa fa-minus"></i></button>
</div>
</div>
<#form:form id="inputForm" model="${testTree}" action="${ctx}/test/testTree/save" method="post" class="form-horizontal">
<div class="box-body">
<div class="form-unit">基本信息</div>
<div class="row">
<div class="col-xs-6">
<div class="form-group">
<label class="control-label col-sm-4">上级数据:</label>
<div class="col-sm-8">
<#form:treeselect id="parent" title="上级数据"
path="parent.id" labelPath="parent.treeName"
url="${ctx}/test/testTree/treeData?excludeCode=${testTree.id}"
class="" allowClear="true" canSelectRoot="true" canSelectParent="true"/>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-xs-6">
<div class="form-group">
<label class="control-label col-sm-4" title="">
<span class="required ">*</span> 节点编码:<i class="fa icon-question hide"></i></label>
<div class="col-sm-8">
<#form:hidden path="isNewRecord"/>
<#form:input path="treeCode" maxlength="64" readonly="${!testTree.isNewRecord}" class="form-control required abc"/>
</div>
</div>
</div>
<div class="col-xs-6">
<div class="form-group">
<label class="control-label col-sm-4" title="">
<span class="required ">*</span> 本级排序号:<i class="fa icon-question hide"></i></label>
<div class="col-sm-8">
<#form:input path="treeSort" class="form-control required digits"/>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-xs-6">
<div class="form-group">
<label class="control-label col-sm-4" title="">
<span class="required ">*</span> 树节点名:<i class="fa icon-question hide"></i></label>
<div class="col-sm-8">
<#form:input path="treeName" maxlength="200" class="form-control required"/>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-xs-12">
<div class="form-group">
<label class="control-label col-sm-2" title="">
<span class="required hide">*</span> 备注信息:<i class="fa icon-question hide"></i></label>
<div class="col-sm-10">
<#form:textarea path="remarks" rows="4" maxlength="500" class="form-control"/>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-xs-12">
<div class="form-group">
<label class="control-label col-sm-2">图片上传:</label>
<div class="col-sm-10">
<#form:fileupload id="uploadImage" bizKey="${testTree.id}" bizType="testTree_image"
uploadType="image" class="" readonly="false"/>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-xs-12">
<div class="form-group">
<label class="control-label col-sm-2">附件上传:</label>
<div class="col-sm-10">
<#form:fileupload id="uploadFile" bizKey="${testTree.id}" bizType="testTree_file"
uploadType="all" class="" readonly="false"/>
</div>
</div>
</div>
</div>
</div>
<div class="box-footer">
<div class="row">
<div class="col-sm-offset-2 col-sm-10">
<% if (hasPermi('test:testTree:edit')){ %>
<button type="submit" class="btn btn-sm btn-primary" id="btnSubmit"><i class="fa fa-check"></i> 保 存</button>&nbsp;
<% } %>
<button type="button" class="btn btn-sm btn-default" id="btnCancel" onclick="js.closeCurrentTabPage()"><i class="fa fa-reply-all"></i> 关 闭</button>
</div>
</div>
</div>
</#form:form>
</div>
</div>
<% } %>
<script>
$("#inputForm").validate({
submitHandler: function(form){
js.ajaxSubmitForm($(form), function(data){
js.showMessage(data.message);
if(data.result == Global.TRUE){
js.closeCurrentTabPage(function(contentWindow){
contentWindow.$('#dataGrid').dataGrid('refreshTreeChildren',
$('#parentCode').val(), '${testTree.id}');
});
}
}, "json");
}
});
// 选择父级菜单回调方法
function treeselectCallback(id, act, index, layero){
if (id == 'parent' && (act == 'ok' || act == 'clear')){
// 创建并初始化下一个节点信息,如:排序号、默认值
$.get('${ctx}/test/testTree/createNextNode?parentCode='
+$('#parentCode').val(), function(data){
$('#treeSort').val(data.treeSort);
});
}
}
</script>

View File

@@ -0,0 +1,89 @@
<% layout('/layouts/default.html', {title: '数据管理', libs: ['dataGrid']}){ %>
<div class="main-content">
<div class="box box-main">
<div class="box-header">
<div class="box-title">
<i class="fa fa-list-alt"></i> 数据管理
</div>
<div class="box-tools pull-right">
<a href="#" class="btn btn-default" id="btnSearch" title="查询"><i class="fa fa-filter"></i> 查询</a>
<a href="#" class="btn btn-default" id="btnRefreshTree" title="刷新"><i class="fa fa-refresh"></i> 刷新</a>
<a href="#" class="btn btn-default" id="btnExpandTreeNode" title="展开一级"><i class="fa fa-angle-double-down"></i> 展开</a>
<a href="#" class="btn btn-default" id="btnCollapseTreeNode" title="折叠全部"><i class="fa fa-angle-double-up"></i> 折叠</a>
<% if(hasPermi('test:testTree:edit')){ %>
<a href="${ctx}/test/testTree/form" class="btn btn-default btnTool" title="新增数据"><i class="fa fa-plus"></i> 新增</a>
<% } %>
</div>
</div>
<div class="box-body">
<#form:form id="searchForm" model="${testTree}" action="${ctx}/test/testTree/listData" method="post" class="form-inline hide"
data-page-no="${parameter.pageNo}" data-page-size="${parameter.pageSize}" data-order-by="${parameter.orderBy}">
<div class="form-group">
<label class="control-label">树节点名:</label>
<div class="control-inline">
<#form:input path="treeName" maxlength="200" class="form-control width-120"/>
</div>
</div>
<div class="form-group">
<label class="control-label">状态:</label>
<div class="control-inline width-120">
<#form:select path="status" dictType="sys_search_status" blankOption="true" class="form-control"/>
</div>
</div>
<div class="form-group">
<label class="control-label">备注信息:</label>
<div class="control-inline">
<#form:input path="remarks" maxlength="500" class="form-control width-120"/>
</div>
</div>
<div class="form-group">
<button type="submit" class="btn btn-primary btn-sm">查询</button>
<button type="reset" class="btn btn-default btn-sm">重置</button>
</div>
</#form:form>
<table id="dataGrid"></table>
</div>
</div>
</div>
<% } %>
<script>
// 初始化DataGrid对象
$('#dataGrid').dataGrid({
searchForm: $("#searchForm"),
columnModel: [
{header:'父级编号', name:'parentCode', index:'a.parent_code', width:150, align:"left", frozen:true, formatter: function(val, obj, row, act){
return '<a href="${ctx}/test/testTree/form?treeCode='+row.treeCode+'" class="btnList" data-title="编辑数据">'+(val||row.id)+'</a>';
}},
{header:'所有父级编号', name:'parentCodes', index:'a.parent_codes', width:150, align:"left"},
{header:'本级排序号', name:'treeSort', index:'a.tree_sort', width:150, align:"left"},
{header:'全节点名', name:'treeNames', index:'a.tree_names', width:150, align:"left"},
{header:'树节点名', name:'treeName', index:'a.tree_name', width:150, align:"left"},
{header:'状态', name:'status', index:'a.status', width:150, align:"center", formatter: function(val, obj, row, act){
return js.getDictLabel(${@DictUtils.getDictListJson('sys_search_status')}, val, '未知', true);
}},
{header:'创建时间', name:'createDate', index:'a.create_date', width:150, align:"left"},
{header:'备注信息', name:'remarks', index:'a.remarks', width:150, align:"left"},
{header:'操作', name:'actions', width:120, sortable:false, title:false, formatter: function(val, obj, row, act){
var actions = [];
<% if(hasPermi('test:testTree:edit')){ %>
actions.push('<a href="${ctx}/test/testTree/form?treeCode='+row.treeCode+'" class="btnList" title="编辑数据"><i class="fa fa-pencil"></i></a>&nbsp;');
if (row.status == Global.STATUS_NORMAL){
actions.push('<a href="${ctx}/test/testTree/disable?treeCode='+row.treeCode+'" class="btnList" title="停用数据" data-confirm="确认要停用该数据吗?"><i class="glyphicon glyphicon-ban-circle"></i></a>&nbsp;');
}
if (row.status == Global.STATUS_DISABLE){
actions.push('<a href="${ctx}/test/testTree/enable?treeCode='+row.treeCode+'" class="btnList" title="启用数据" data-confirm="确认要启用该数据吗?"><i class="glyphicon glyphicon-ok-circle"></i></a>&nbsp;');
}
actions.push('<a href="${ctx}/test/testTree/delete?treeCode='+row.treeCode+'" class="btnList" title="删除数据" data-confirm="确认要删除该数据及所有子数据吗?" data-deltreenode="'+row.id+'"><i class="fa fa-trash-o"></i></a>&nbsp;');
actions.push('<a href="${ctx}/test/testTree/form?parentCode='+row.id+'" class="btnList" title="新增下级数据"><i class="fa fa-plus-square"></i></a>&nbsp;');
<% } %>
return actions.join('');
}}
],
treeGrid: true, // 启用树结构表格
defaultExpandLevel: 0, // 默认展开的层次
expandNodeClearPostData: 'treeName,status,remarks,', // 展开节点清理请求参数数据(一般设置查询条件的字段属性,否则在查询后,不能展开子节点数据) // 加载成功后执行事件
ajaxSuccess: function(data){
}
});
</script>