欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

ztree实现拖拽功能

程序员文章站 2024-03-05 15:08:30
...

最近在做仓储的功能,需要实现对仓库树的拖拽功能,测试了很长时间才完成,后端使用了SpringMVC + Spring Data Jpa图片和代码展示如下:
ztree实现拖拽功能
ztree实现拖拽功能
ztree实现拖拽功能

Jsp程序

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ include file="/common/taglibs.jsp"%>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="renderer" content="webkit">
    <title>物品分类</title>
    <style>
        .ztree * {font-size:14px !important;}
    </style>
</head>
<body style="background: #f1f1f1;border:1px solid #f1f1f1;">
    <div class="row" id="page_content">
        <div class="col-sm-12">
            <div class="ibox float-e-margins">
                <div class="ibox-title">
                    <h3>物品分类</h3>
                </div>
                <div class="ibox-content">
                    <div class="col-sm-12 no-padding" id="tree">
                        <div class="zTreeDemoBackground left">
                            <ul id="treeDemo" class="ztree" url="${ctx}/baseinfo/wpfl/renderTree"></ul>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>
    <input type="hidden" id="wpflOrCkgl" value="wpfl">
    <script type="text/javascript">
    var wpfl = true;
    var ckgl = false;
    var modal = {
        saveURL : "${ctx}/baseinfo/wpfl",
        deleteURL: "${ctx}/baseinfo/wpfl/delete",
        sameLevel: "${ctx}/baseinfo/wpfl/sameLevel",
        differentLevel:"${ctx}/baseinfo/wpfl/differentLevel",
        diffLevel:"${ctx}/baseinfo/wpfl/diffLevel",
        checkURL:"${ctx}/baseinfo/wpfl/check"
    }
    </script>
</body>
</html> 

JS代码

var setting = {
    view: {
        addHoverDom: addHoverDom,
        removeHoverDom: removeHoverDom,
        selectedMulti: false,
        showLine: false,
        showIcon: showIconForTree
    },
    edit: {
        drag: {
            autoExpandTrigger: true,
            prev: dropPrev,
            inner: dropInner,
            next: dropNext
        },
        enable: true,
        editNameSelectAll: true,
        showRemoveBtn : showRemoveBtn,
        showRenameBtn : showRenameBtn
    },
    data: {
        simpleData: {
            enable: true
        }
    },
    callback: {
        beforeDrag: beforeDrag,
        beforeEditName: beforeEditName,
        beforeRemove: beforeRemove,
        beforeRename: beforeRename,
        onRemove: onRemove,
        onRename: onRename,
        beforeDrop: beforeDrop,
        beforeDragOpen: beforeDragOpen,
        onDrag: onDrag,
        onDrop: onDrop,
        onExpand: onExpand,
        onAsyncSuccess: zTreeOnAsyncSuccess,
    },
    async: {
        enable: true,
        type: "get",
        //表示异步加载采用 post 方法请求
        url: $("#treeDemo").attr("url"),
        autoParam: ["id", "type"] //传递节点的id 和 type值给后台(当异步加载数据时)
    }
};

/**数异步加载成功*/
function zTreeOnAsyncSuccess(event, treeId, node, msg) {
    var treeObj = $.fn.zTree.getZTreeObj("treeDemo");
    var nodes = treeObj.getNodes();
    // 异步展开一级子节点
    if (nodes.length > 0) {
        treeObj.expandNode(nodes[0], true, false, false);
    }
}

var log, className = "dark";
function beforeDrag(treeId, treeNodes) {
    return false;
}
function beforeEditName(treeId, treeNode) {
    className = (className === "dark" ? "":"dark");
    showLog("[ "+getTime()+" beforeEditName ]&nbsp;&nbsp;&nbsp;&nbsp; " + treeNode.name);
    var zTree = $.fn.zTree.getZTreeObj("treeDemo");
    zTree.selectNode(treeNode);
    return;
}
function beforeRemove(treeId, treeNode) {
    className = (className === "dark" ? "":"dark");
    showLog("[ "+getTime()+" beforeRemove ]&nbsp;&nbsp;&nbsp;&nbsp; " + treeNode.name);
    var zTree = $.fn.zTree.getZTreeObj("treeDemo");
    zTree.selectNode(treeNode);
    var flag = false;
    if(confirm("确认删除 节点 -- " + treeNode.name + " 吗?")){

        // 删除节点
        flag=delNode(modal,treeNode.id);
    }
    return flag;
}
function onRemove(e, treeId, treeNode) {
    showLog("[ "+getTime()+" onRemove ]&nbsp;&nbsp;&nbsp;&nbsp; " + treeNode.name);
}
function beforeRename(treeId, treeNode, newName, isCancel) {
    className = (className === "dark" ? "":"dark");
    showLog((isCancel ? "<span style='color:red'>":"") + "[ "+getTime()+" beforeRename ]&nbsp;&nbsp;&nbsp;&nbsp; " + treeNode.name + (isCancel ? "</span>":""));
    if (newName.length == 0) {
        alert("节点名称不能为空.");
        var zTree = $.fn.zTree.getZTreeObj("treeDemo");
        setTimeout(function(){zTree.editName(treeNode)}, 10);
        return false;
    }
    else if(newName.length > 20){
        confirm("名称长度在20字以内");
        return false;
    }

    // 修改的名字没变
    if(treeNode.name == newName){
        return true;
    }

    // 判断是否重名
    var flag1 = check(newName);
    if(flag1 == false){
        alert("名称不能重复");
        return false;
    }
    return true;
}
function onRename(e, treeId, treeNode, isCancel) {
    showLog((isCancel ? "<span style='color:red'>":"") + "[ "+getTime()+" onRename ]&nbsp;&nbsp;&nbsp;&nbsp; " + treeNode.name + (isCancel ? "</span>":""));
    if(treeNode.type == 'add'){ // 新增节点
        nodeAdd(treeNode); 
        treeNode.type='edit';
    }else{ // 编辑节点
        nodeEdit(treeNode);
    }
}
function showIconForTree(treeId, treeNode) {
    return !treeNode.isParent;
}
function showLog(str) {
    if (!log) log = $("#log");
    log.append("<li class='"+className+"'>"+str+"</li>");
    if(log.children("li").length > 8) {
        log.get(0).removeChild(log.children("li")[0]);
    }
}
function getTime() {
    var now= new Date(),
        h=now.getHours(),
        m=now.getMinutes(),
        s=now.getSeconds(),
        ms=now.getMilliseconds();
    return (h+":"+m+":"+s+ " " +ms);
}

var newCount = 1;

/** 是否显示编辑按钮 */
function showRenameBtn(treeId, treeNode){
    // 根节点不显示编辑按钮
    if(treeNode.level == 0){
        return false;
    }else{
        return true;
    }
}
/** 是否显示删除按钮 */
function showRemoveBtn(treeId, treeNode){
    // 根节点不显示删除按钮
    if(treeNode.level == 0){
        return false;
    }else{
        return true;
    }
}

/** 新增节点 */
function addHoverDom(treeId, treeNode) {
    if(wpfl == true && treeNode.level == 3){ // 物品分类最多支持三级
        return;
    }else if(ckgl == true && treeNode.level == 2){ // 仓库管理最多支持二级
        return;
    }
    var sObj = $("#" + treeNode.tId + "_span");
    if (treeNode.editNameFlag || $("#addBtn_"+treeNode.tId).length>0) return;
    var addStr = "<span class='button add' id='addBtn_" + treeNode.tId
        + "' title='新增' onfocus='this.blur();'></span>";
    sObj.after(addStr);
    var btn = $("#addBtn_"+treeNode.tId);
    if (btn) btn.bind("click", function(){
        var zTree = $.fn.zTree.getZTreeObj("treeDemo");
        var newName = "new node" + (newCount++);
        zTree.addNodes(treeNode, {id:(100 + newCount), pId:treeNode.id, name:newName,type : 'add'});
        var newNode=treeNode.children[treeNode.children.length-1];
        zTree.editName(newNode);

        return false;
    });
}
function removeHoverDom(treeId, treeNode) {
    $("#addBtn_"+treeNode.tId).unbind().remove();
}
function selectAll() {
    var zTree = $.fn.zTree.getZTreeObj("treeDemo");
    zTree.setting.edit.editNameSelectAll =  $("#selectAll").attr("checked");
}
function dropPrev(treeId, nodes, targetNode) {
    var pNode = targetNode.getParentNode();
    if (pNode && pNode.dropInner === false) {
        return false;
    } else {
        for (var i=0,l=curDragNodes.length; i<l; i++) {
            var curPNode = curDragNodes[i].getParentNode();
            if (curPNode && curPNode !== targetNode.getParentNode() && curPNode.childOuter === false) {
                return false;
            }
        }
    }
    return true;
}
function dropInner(treeId, nodes, targetNode) {
    if (targetNode && targetNode.dropInner === false) {
        return false;
    } else {
        for (var i=0,l=curDragNodes.length; i<l; i++) {
            if (!targetNode && curDragNodes[i].dropRoot === false) {
                return false;
            } else if (curDragNodes[i].parentTId && curDragNodes[i].getParentNode() !== targetNode && curDragNodes[i].getParentNode().childOuter === false) {
                return false;
            }
        }
    }
    return true;
}
function dropNext(treeId, nodes, targetNode) {
    var pNode = targetNode.getParentNode();
    if (pNode && pNode.dropInner === false) {
        return false;
    } else {
        for (var i=0,l=curDragNodes.length; i<l; i++) {
            var curPNode = curDragNodes[i].getParentNode();
            if (curPNode && curPNode !== targetNode.getParentNode() && curPNode.childOuter === false) {
                return false;
            }
        }
    }
    return true;
}

var log, className = "dark", curDragNodes, autoExpandNode;
var dragId ; //拖拽节点的父节点的id
/** 拖拽前执行 */
function beforeDrag(treeId, treeNodes) {
    className = (className === "dark" ? "":"dark");
    showLog("[ "+getTime()+" beforeDrag ]&nbsp;&nbsp;&nbsp;&nbsp; drag: " + treeNodes.length + " nodes." );
    for (var i=0,l=treeNodes.length; i<l; i++) {
        dragId = treeNodes[i].pId;
        if (treeNodes[i].drag === false) {
            curDragNodes = null;
            return false;
        } else if (treeNodes[i].parentTId && treeNodes[i].getParentNode().childDrag === false) {
            curDragNodes = null;
            return false;
        }
    }
    curDragNodes = treeNodes;
    return true;
}
function beforeDragOpen(treeId, treeNode) {
    autoExpandNode = treeNode;
    return true;
}

/** 拖拽释放之后执行 */
function beforeDrop(treeId, treeNodes, targetNode, moveType, isCopy) {
    className = (className === "dark" ? "":"dark");
    showLog("[ "+getTime()+" beforeDrop ]&nbsp;&nbsp;&nbsp;&nbsp; moveType:" + moveType);
    showLog("target: " + (targetNode ? targetNode.name : "root") + "  -- is "+ (isCopy==null? "cancel" : isCopy ? "copy" : "move"));

  if(dragId == targetNode.pId && moveType != 'inner'){// 同级位置调整
      var data = 'pId='+dragId+'&currentNodeId='+treeNodes[0].id+'&newNodeId='+targetNode.id+'&moveType='+moveType;
      nodeExchange(data,modal.sameLevel);
  }else if(moveType == 'inner'){ // 一个节点变成另一个节点的子节点
      // 不能移到仓库管理第二节点,物品分类第三节点
      if((ckgl == true && targetNode.level == 2) || (wpfl == true && targetNode.level == 3)){
          return false;
      }else{
          var data = 'currentNodeId='+treeNodes[0].id+'&newParentNodeId='+targetNode.id;
      }
      nodeExchange(data,modal.differentLevel);
  }else if(dragId != targetNode.pId && moveType != 'inner'){ // 不同级之间的调整
      var flag1 = canMove(treeNodes[0].id);
      if(flag1 == false){
          alert("您选择的节点已经被引用,不能被拖动");
          return false;
      }

    // 物品管理最高3级,仓库管理最高2级  isParent
      if(ckgl == true && treeNodes[0].pId == 0 && targetNode.level == 2){
          alert("最多支持二级分类");
          return false;
      }else if((wpfl == true && targetNode.level == 3 && treeNodes[0].isParent == true) || (wpfl == true && targetNode.level == 2 && treeNodes[0].pId == 0)){
          alert("最多支持三级分类");
          return false;
      }
      var data = 'currentNodeId='+treeNodes[0].id+'&newNodeId='+targetNode.id+'&moveType='+moveType;
      nodeExchange(data,modal.diffLevel);
  }
    return true;
}
function onDrag(event, treeId, treeNodes) {
    className = (className === "dark" ? "":"dark");
    showLog("[ "+getTime()+" onDrag ]&nbsp;&nbsp;&nbsp;&nbsp; drag: " + treeNodes.length + " nodes." );
}
function onDrop(event, treeId, treeNodes, targetNode, moveType, isCopy) {
    className = (className === "dark" ? "":"dark");
    showLog("[ "+getTime()+" onDrop ]&nbsp;&nbsp;&nbsp;&nbsp; moveType:" + moveType);
    showLog("target: " + (targetNode ? targetNode.name : "root") + "  -- is "+ (isCopy==null? "cancel" : isCopy ? "copy" : "move"))
}
function onExpand(event, treeId, treeNode) {
    if (treeNode === autoExpandNode) {
        className = (className === "dark" ? "":"dark");
        showLog("[ "+getTime()+" onExpand ]&nbsp;&nbsp;&nbsp;&nbsp;" + treeNode.name);
    }
}

function showLog(str) {
    if (!log) log = $("#log");
    log.append("<li class='"+className+"'>"+str+"</li>");
    if(log.children("li").length > 8) {
        log.get(0).removeChild(log.children("li")[0]);
    }
}
function getTime() {
    var now= new Date(),
        h=now.getHours(),
        m=now.getMinutes(),
        s=now.getSeconds(),
        ms=now.getMilliseconds();
    return (h+":"+m+":"+s+ " " +ms);
}

function setTrigger() {
    var zTree = $.fn.zTree.getZTreeObj("treeDemo");
    zTree.setting.edit.drag.autoExpandTrigger = $("#callbackTrigger").attr("checked");
}

/** 鼠标移入移出显示操作图标 */
function over(aa){
    $(aa).children(".hides").css("display","block");
}
function out(aa){
    $(aa).children(".hides").css("display","none");
}

function change_bgcolor(aa){
    $(aa).addClass("active")
        .parent().siblings().children().removeClass("active");
    $("#table-body").animate({
        scrollTop:'0px',
        scrollLeft:'0px'
    },0);
}

/** 点击物品分类 */
function kind_click(a,b,c){
    $(a).addClass("active").parent().siblings().children().removeClass("active");
    var oUl = $(a).parent().parent();
    var oDiv = oUl.parent();
    if(oUl.index() == 0){
        $(".show_kind").children("span").html('');
        $(".show_kind").children("span").eq(0).html($(a).html());
    }
    else if(oUl.index() == 1){
        if(oDiv.children("ul").eq(0).find(".active").length){
            $(".show_kind").children("span").eq(oUl.index()).html("-> "+$(a).html());
            $(".show_kind").children("span").eq(2).html('');
        }
        else{
            confirm("请选中上一级菜单,再点击");
        }
    }else{
         if(oUl.index() == 2 && oDiv.children("ul").eq(0).find(".active").length && oDiv.children("ul").eq(1).find(".active").length){
             $(".show_kind").children("span").eq(oUl.index()).html("-> "+$(a).html());
         }
         else{
            confirm("请选中上一级菜单,再点击");
        }
    }
    myKindClick(a,b,c);
}

/** 删除table记录 */
function delete_tr(p){
    var y=p.parentNode.parentNode;
    y.parentNode.removeChild(y);//只能上找一层parentNode
    againPx();
}

/** 重新排序 */
function againPx(){
    var index = 1;
    $("td[name='px']").each(function(){
        $(this).find('span').html(index);
        index++;
    });
}

/** 新增节点 */
function nodeAdd(treeNode){
    $.ajax({
        type: 'post',
        url: modal.saveURL,
        data: {
            'id':null,
            'sjfl':treeNode.pId,
            'mc':treeNode.name
        },
        dataType: 'json',
//        async : false,
        traditional: true,
        success: function(result) {
            if (result.success) {
                var treeObj = $.fn.zTree.getZTreeObj("treeDemo");
                var obj=result.data.obj;
                treeNode.id = obj['id'];
                treeNode.pId = obj['sjfl'];
                treeObj.updateNode(treeNode);

                showRemindMsg();

                try {
                    mySave(modal);
                } catch(e) {}
            } else {
                alert(result.errorMsg);
            }
        },
        error: function(XMLHttpRequest, textStatus, errorThrown) {
            btn.disabled = false;
            alert("请求异常");
        }
    });
}

/** 编辑节点 */
function nodeEdit(treeNode){
    $.ajax({
        type: 'post',
        url: modal.saveURL,
        data: {
            'id':treeNode.id,
            'sjfl':treeNode.pId,
            'mc':treeNode.name
        },
        dataType: 'json',
        traditional: true,
        success: function(result) {
//            btn.disabled = false;

            if (result.success) {

                showRemindMsg();

                try {
                    mySave(modal);
                } catch(e) {}
            } else {
                alert(result.errorMsg);
            }
        },
        error: function(XMLHttpRequest, textStatus, errorThrown) {
            btn.disabled = false;
            alert("请求异常");
        }
    });
}

/**执行删除*/
function delNode(modal, id) {
    var flag=true;
    $.ajax({
        type: 'post',
        url: modal.deleteURL,
        data: {
            ids: id
        },
        async:false,
        dataType: 'json',
        traditional: true,
        success: function(result) {
            if (result.success) {
                showRemindMsg();
            } else {
                flag = false;
                if (result.errorMsg.indexOf("ConstraintViolationException") > 0) {
                    alert("您选择的记录已经被引用,不能被删除");
                }

            }
        }
    });
    return flag;
}
/** 节点位置调换 */
function nodeExchange(data,ways){
      $.ajax({
             type:"get",
             data:data,
             url: ways,
             dataType:'json',
             success: function(result) {
                if (result.success) {
                    showRemindMsg();

                    try {
                        mySave(modal);
                    } catch(e) {}
                } else {
                    alert(result.errorMsg);
                }
             },
             error: function(XMLHttpRequest, textStatus, errorThrown) {
                 alert("请求异常");
             }


          });
}

/**
 * 验证节点名字唯一性
 * 
 * @param name
 * @returns {Boolean}
 */
function check(name){
    var flag = true;
    $.ajax({
        type: 'post',
        url: modal.checkURL,
        data: {
            name:name
        },
        dataType: 'json',
        traditional: true,
        async:false,
        success: function(result) {
            if (result.success) {
                var check = result.data.check;
                if(check == false){
                    flag = false;
                }else{
                    flag = true;
                }
                try {
                    mySave(modal);
                } catch(e) {}
            } else {
                alert(result.errorMsg);
            }
        },
        error: function(XMLHttpRequest, textStatus, errorThrown) {
            btn.disabled = false;
            alert("请求异常");
        }
    });
    return flag;
}

/**
 * 仓库管理二级节点被引用的不能被拖动
 * @param kfkwId
 * @returns {Boolean}
 */
function canMove(kfkwId){
    var flag = true;
    $.ajax({
        type: 'get',
        url: modal.canMoveURL,
        data: {
            id:kfkwId
        },
        dataType: 'json',
        traditional: true,
        async:false,
        success: function(result) {
            if (result.success) {
                var can = result.data.canMove;
                if(can == false){
                    flag = false;
                }else{
                    flag = true;
                }
                try {
                    mySave(modal);
                } catch(e) {}
            } else {
                alert(result.errorMsg);
            }
        },
        error: function(XMLHttpRequest, textStatus, errorThrown) {
            btn.disabled = false;
            alert("请求异常");
        }
    });
    return flag;
}

Controller代码

package com.dtyun.ccgl.web.controller.baseinfo;

/**
 * 仓库管理Controller
 * 
 * @author WangYuanJun
 */
@Controller
@RequestMapping(value = "/baseinfo/ckgl")
@FunctionModule(value = "仓库管理", entry = "/baseinfo/ckgl", parent = "基础数据")
public class KfkwController extends BaseController {

    /** 仓库管理Service */
    @Autowired
    private KfkwService kfkwService;

    /** 库存历史Service */
    @Autowired
    private KcglHisService kcglHisService;

    /** 系统配置Service */
    @Autowired
    private CcSysConfigService sysConfigService;

    private Logger logger = LoggerFactory.getLogger(this.getClass());

    @RequestMapping(method = RequestMethod.GET)
    public String index(Model model) {
        CcSysConfigEntity sysConfigEntity= sysConfigService.findGjdmcBySchool(AuthUtils.getCurrentSchoolId());
        Boolean boolean1 = false;

        // 设置了仓库根节点名称
        if(sysConfigEntity != null){
            boolean1 = true;
        }
        model.addAttribute("ssxx", AuthUtils.getCurrentSchoolId());
        model.addAttribute("booleanSetGjdmc", boolean1);
        return "/baseinfo/ckgl/ckgl";
    }

    /**
     * 添加物品分类
     * 
     * @param dto
     * @param result
     * @return
     */
    @ResponseBody
    @RequestMapping(method = RequestMethod.POST)
    public Retval save(@Valid KfkwDto dto, BindingResult result) {
        Retval retval = Retval.newInstance();

        // 表单校验
        if (result.hasErrors()) {
            retval.fail(getErrorMessage(result));
            return retval;
        }

        // 保存
        try {
            // 当上级分类为0时,为一级目录
            if (dto.getSjfl() == null || dto.getSjfl() == 0) {
                dto.setSjfl(null);
            }
            KfkwEntity kfkwEntity = kfkwService.save(dto);
            retval.put("obj", kfkwEntity);
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            retval.fail(e.getMessage());
        }
        return retval;
    }

    /**
     * 删除物品分类
     * 
     * @param ids
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "/delete", method = RequestMethod.POST)
    public Retval delete(@RequestParam Long[] ids) {
        Retval retval = Retval.newInstance();
        try {
            kfkwService.deleteByIds(ids);
        } catch (DataIntegrityViolationException e) {
            retval.fail(e.getMessage());
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            retval.fail(e.getMessage());
        }
        return retval;
    }

    /**
     * 判断被引用的二级节点能否被移动
     * 
     * @param id
     * @return
     */
    @ResponseBody
    @RequestMapping(value="/canMove",method=RequestMethod.GET)
    public Retval canMove(@RequestParam Long id){
        Retval retval = Retval.newInstance();
        Boolean boolean1 = kcglHisService.findKfkwById(id);
        retval.put("canMove", boolean1);
        return retval;
    }

    /**
     *同级之间拖拽
     *
     * @param pId 拖拽节点父节点id
     * @param currentNodeId 拖拽节点id
     * @param newNodeId 目标节点id
     * @param moveType 拖拽类型
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "/sameLevel", method = RequestMethod.GET)
    public Retval sameLevel(@RequestParam Long pId, @RequestParam Long currentNodeId, @RequestParam Long newNodeId,
            @RequestParam String moveType) {
        Retval retval = Retval.newInstance();
        try {

            kfkwService.sameLevel(pId, currentNodeId, newNodeId, moveType);
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            retval.fail(e.getMessage());
        }
        return retval;
    }

    /**
     * 拖拽节点成为目标节点的子节点
     * 
     * @param currentNodeId 拖拽节点id
     * @param newParentNodeId 目标父节点id
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "/differentLevel", method = RequestMethod.GET)
    public Retval differentLevel(@RequestParam Long currentNodeId, @RequestParam Long newParentNodeId) {
        Retval retval = Retval.newInstance();
        try {
            kfkwService.differentLevel(currentNodeId, newParentNodeId);
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            retval.fail(e.getMessage());
        }
        return retval;
    }

    /**
     * 不同级节点为位置调换
     * 
     * @param currentNodeId 被拖拽节点id
     * @param newNodeId 新的节点id
     * @param moveType
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "/diffLevel", method = RequestMethod.GET)
    public Retval diffLevel(@RequestParam Long currentNodeId, @RequestParam Long newNodeId,@RequestParam String moveType) {
        Retval retval = Retval.newInstance();
        try {
             kfkwService.diffLevel(currentNodeId, newNodeId, moveType);
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            retval.fail(e.getMessage());
        }
        return retval;
    }

    /**
     * 加载树
     * 
     * @param id
     * @param type
     * @return
     * @throws Exception
     */
    @ResponseBody
    @RequestMapping(value = "/renderTree", method = RequestMethod.GET)
    public List<Map<String, Object>> renderTree(Long id, String type) throws Exception {

        List<Map<String, Object>> returnList = new ArrayList<Map<String, Object>>();
        CcSysConfigEntity sysConfigEntity= sysConfigService.findGjdmcBySchool(AuthUtils.getCurrentSchoolId());
        // 加载根节点
        if (StringUtils.isEmpty(id)) {
            Map<String, Object> root = new HashMap<String, Object>();

            root.put("id", 0);
            root.put("name", sysConfigEntity.getCckcgjdmc());
            root.put("isParent", true);

            // 加载一级节点
            List<Map<String, Object>> returnList1 = new ArrayList<Map<String, Object>>();
            List<KfkwEntity> list1 = kfkwService.findLeveL1Node();
            for (KfkwEntity kfkw : list1) {
                Map<String, Object> node = new HashMap<String, Object>();
                node.put("id", kfkw.getId());
                node.put("name", kfkw.getMc());
                Boolean isParent = kfkwService.hasSubNodeById(kfkw.getId());
                node.put("isParent", isParent);
                returnList1.add(node);
            }

            root.put("children", returnList1);
            returnList.add(root);

            return returnList;
        }

        // 加载子节点
        List<KfkwEntity> list = null;
        if (id != null && id > 0L) {
            list = kfkwService.findSubNodeById(id);
            for (KfkwEntity kfkw : list) {
                Map<String, Object> node = new HashMap<String, Object>();
                node.put("id", kfkw.getId());
                node.put("name", kfkw.getMc());
                Boolean isParent = kfkwService.hasSubNodeById(kfkw.getId());
                node.put("isParent", isParent);
                returnList.add(node);
            }
        }

        return returnList;
    }

    /**
     * 查重
     * 
     * @param name
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "/check", method = RequestMethod.POST)
    public Retval check(@RequestParam String name) {
        Retval retval = Retval.newInstance();
        Boolean boolean1 = kfkwService.check(name);
        retval.put("check", boolean1);
        return retval;
    }

}

service代码

/**
 * 仓库管理Service
 * 
 * @author WangYuanJun
 */
@Service
public class KfkwService extends BaseService{

    /** 物品分类Dao */
    @Autowired
    private KfkwDao kfkwDao;


    /**
     * 找该级的子目录
     * 
     * @param sjfl
     * @return
     */
    public List<KfkwEntity> findByMaxPx(Long sjfl) {
        Sort sort = new Sort(Direction.DESC,"px");
        return kfkwDao.findAll(spc3(sjfl),sort);
    }

    public Specification<KfkwEntity> spc3(Long sjfl) {
        Specification<KfkwEntity> sp = new Specification<KfkwEntity>() {
            @Override
            public Predicate toPredicate(Root<KfkwEntity> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
                List<Predicate> predicates = Lists.newArrayList();
                if(sjfl == null){
                    Predicate pSjfl = cb.isNull(root.get("sjfl").as(Long.class));
                    predicates.add(pSjfl);
                }else{
                    Predicate pSjfl = cb.equal(root.get("sjfl").as(Long.class), sjfl);
                    predicates.add(pSjfl);
                }
                Predicate pXx = cb.equal(root.get("ssxx").as(Long.class), getSchoolId());// 所属学校
                predicates.add(pXx);
                query.where(cb.and(predicates.toArray(new Predicate[predicates.size()])));
                return query.getRestriction();
            }
        };
        return sp;
    }

    /**
     * 同级之间拖拽
     * 
     * @param pId 父节点
     * @param currentNodeId 拖拽的id
     * @param newNodeId 拖拽新的id
     */
    @Transactional
    public void sameLevel(Long pId, Long currentNodeId, Long newNodeId, String moveType) {
        // 将他们中间的影响的记录跟新

        if ("next".equals(moveType)) {
            KfkwEntity currentKfkw = kfkwDao.findOne(currentNodeId);
            KfkwEntity newKfkw = kfkwDao.findOne(newNodeId);
            // 向下拖拽
            if(currentKfkw.getPx()<newKfkw.getPx()){
                // 跟新受影响的记录
                List<KfkwEntity> kfkwList = findInfluenceData(pId, currentKfkw.getPx(), newKfkw.getPx());
                for (int i = 0; i < kfkwList.size(); i++) {
                    KfkwEntity kfkw = kfkwList.get(i);
                    if (!(kfkw.getId().equals(currentKfkw.getId())) && !(kfkw.getId().equals(newKfkw.getId()))) {
                        KfkwEntity kfkwEntity2 = kfkwDao.findOne(kfkw.getId());
                        kfkwEntity2.setPx(kfkwEntity2.getPx() - 1);
                        kfkwDao.save(kfkwEntity2);
                    }

                }
                // 拖拽节点排序变为目标节点的排序
                currentKfkw.setPx(newKfkw.getPx());
                kfkwDao.save(currentKfkw);
                // 目标排序节点排序为其排序-1
                newKfkw.setPx(newKfkw.getPx() - 1);
                kfkwDao.save(newKfkw);
            }else{

                // 向上拖拽,movetpe=next
                // 目标节点wpflList.get(0),去除目标节点,将目标节点的下一个节点变为目标节点
                List<KfkwEntity> kfkwList = findInfluenceData(pId, currentKfkw.getPx(), newKfkw.getPx());
                kfkwList.remove(0);
                KfkwEntity kfkwNew=kfkwDao.findOne(kfkwList.get(0).getId());
                int kfkwNewPx = kfkwNew.getPx();
                for (int i = 0; i < kfkwList.size(); i++) {
                    KfkwEntity kfkw = kfkwList.get(i);
                    if (!(kfkw.getId().equals(currentKfkw.getId())) ) {
                        KfkwEntity kfkwEntity2 = kfkwDao.findOne(kfkw.getId());
                        kfkwEntity2.setPx(kfkwEntity2.getPx() + 1);
                        kfkwDao.save(kfkwEntity2);
                    }
                }
                // 拖拽的排序变为目标节点排序
                currentKfkw.setPx(kfkwNewPx);
                kfkwDao.save(currentKfkw);
            }

        } else if ("prev".equals(moveType)) {
            KfkwEntity currentKfkw = kfkwDao.findOne(currentNodeId);
            KfkwEntity newKfkw = kfkwDao.findOne(newNodeId);
            // 向上拖拽
            if(currentKfkw.getPx()>newKfkw.getPx()){
                // 跟新受影响的记录
                List<KfkwEntity> kfkwList = findInfluenceData(pId, currentKfkw.getPx(), newKfkw.getPx());
                for (int i = 0; i < kfkwList.size(); i++) {
                    KfkwEntity kfkw = kfkwList.get(i);
                    if (!(kfkw.getId().equals(currentKfkw.getId())) && !(kfkw.getId().equals(newKfkw.getId()))) {
                        KfkwEntity kfkwEntity2 = kfkwDao.findOne(kfkw.getId());
                        kfkwEntity2.setPx(kfkwEntity2.getPx() + 1);
                        kfkwDao.save(kfkwEntity2);
                    }

                }
                // 拖拽的排序变为目标节点排序
                currentKfkw.setPx(newKfkw.getPx());
                kfkwDao.save(currentKfkw);
                // 目标排序的排序为其排序至+1
                newKfkw.setPx(newKfkw.getPx() + 1);
                kfkwDao.save(newKfkw);
            }else{
                    // 向下拖拽,movetype=prev
                    // 跟新受影响的记录
                    // 目标节点wpflList.get(最大值),去除目标节点,将目标节点的上一个节点变为目标节点
                    List<KfkwEntity> kfkwList = findInfluenceData(pId, currentKfkw.getPx(), newKfkw.getPx());
                    kfkwList.remove(kfkwList.size()-1);
                    KfkwEntity kfkwNew=kfkwDao.findOne(kfkwList.get(kfkwList.size()-1).getId()); //新的目标节点
                    int kfkwNewPx = kfkwNew.getPx();
                    for (int i = 0; i < kfkwList.size(); i++) {
                        KfkwEntity kfkw = kfkwList.get(i);
                        if (!(kfkw.getId().equals(currentKfkw.getId())) ) {
                            KfkwEntity kfkwEntity2 = kfkwDao.findOne(kfkw.getId());
                            kfkwEntity2.setPx(kfkwEntity2.getPx() - 1);
                            kfkwDao.save(kfkwEntity2);
                        }

                    }
                    // 拖拽节点排序变为目标节点的排序
                    currentKfkw.setPx(kfkwNewPx);
                    kfkwDao.save(currentKfkw);
            }

        }

    }

    public List<KfkwEntity> findInfluenceData(Long sjfl, Integer currentNodePx, Integer newNodePx) {
        Specification<KfkwEntity> spec = new Specification<KfkwEntity>() {

            @Override
            public Predicate toPredicate(Root<KfkwEntity> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
                List<Predicate> predicates = Lists.newArrayList();

                if(sjfl != 0){
                    Predicate p1 = cb.equal(root.get("sjfl").as(Long.class), sjfl);
                    predicates.add(p1);
                }else{
                    Predicate p1 = cb.isNull(root.get("sjfl").as(Long.class));
                    predicates.add(p1);
                }
                Predicate p2 = cb.equal(root.get("ssxx").as(Long.class), getSchoolId());
                predicates.add(p2);
                if(currentNodePx<newNodePx){
                    Predicate p3 = cb.between(root.get("px"), currentNodePx, newNodePx);
                    predicates.add(p3);
                }else if(currentNodePx>newNodePx){
                    Predicate p3 = cb.between(root.get("px"), newNodePx, currentNodePx);
                    predicates.add(p3);;
                }
                query.orderBy(cb.asc(root.get("px").as(Long.class)));
                query.where(cb.and(predicates.toArray(new Predicate[predicates.size()])));
                return query.getRestriction();
            }
        };

        List<KfkwEntity> wpflList = kfkwDao.findAll(spec);

        return wpflList;
    }

    //成为目标节点的子节点
    /**
     * 
     * @param currentNodeId 拖拽节点id
     * @param newParentNodeId 目标父节点id
     * @throws Exception 
     */
    @Transactional
    public void differentLevel(Long currentNodeId,Long newParentNodeId) throws Exception{

        KfkwEntity kfkwEntity=kfkwDao.findOne(currentNodeId);  // 拖拽节点
        List<KfkwEntity> kfkwEntities = null;
        if(kfkwEntity.getSjfl() != null){
            kfkwEntities= findInfluenceData1(kfkwEntity.getSjfl().getId(), kfkwEntity.getPx());
        }else{
            kfkwEntities= findInfluenceData1(null, kfkwEntity.getPx());
        }
        if(CollectionUtils.isNotEmpty(kfkwEntities)){ // 当前节点为同级最后节点时wpflEntities=[]
            for (int i = 0; i < kfkwEntities.size(); i++) {
                KfkwEntity kfkwEntity2= kfkwEntities.get(i);
                kfkwEntity2.setPx(kfkwEntity2.getPx()-1);
                kfkwDao.save(kfkwEntity2);
            }
        }
        //当前节点成为目标节点(父节点)的最后一个节点
        KfkwDto kfkwDto = new KfkwDto();
        List<KfkwEntity> kfkwEntities2= kfkwDao.findByMaxPx(newParentNodeId, getSchoolId()); //  得到目标节点子节点的集合
        if(CollectionUtils.isEmpty(kfkwEntities2)){
            kfkwDto.setPx(1);
        }else{
            kfkwDto.setPx(kfkwEntities2.get(0).getPx()+1);
        }
        kfkwEntity.setSjfl(kfkwDao.findOne(newParentNodeId));
        super.save(kfkwEntity, kfkwDto);
    }


    public List<KfkwEntity> findInfluenceData1(Long sjfl, Integer currentNodePx) {
        Specification<KfkwEntity> spec = new Specification<KfkwEntity>() {

            @Override
            public Predicate toPredicate(Root<KfkwEntity> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
                List<Predicate> predicates = Lists.newArrayList();

                if(sjfl != null){
                    Predicate p1 = cb.equal(root.get("sjfl").as(Long.class), sjfl);
                    predicates.add(p1);
                }else{
                    Predicate p1 = cb.isNull(root.get("sjfl").as(Long.class));
                    predicates.add(p1);
                }
                Predicate p2 = cb.equal(root.get("ssxx").as(Long.class), getSchoolId());
                predicates.add(p2);
                Predicate p3 = cb.greaterThan(root.get("px"), currentNodePx);
                predicates.add(p3);
                query.orderBy(cb.asc(root.get("px").as(Long.class)));
                query.where(cb.and(predicates.toArray(new Predicate[predicates.size()])));
                return query.getRestriction();
            }
        };

        List<KfkwEntity> wpflList = kfkwDao.findAll(spec);

        return wpflList;
    }


    /**
     * 不同级节点为位置调换,movetype != inner
     * 
     * @param currentNodeId
     * @param newNodeId
     * @param moveType
     * @throws Exception
     */
    @Transactional
    public void diffLevel(Long currentNodeId, Long newNodeId, String moveType) throws Exception {
        if("next".equals(moveType)){
            KfkwEntity currentKfkw = kfkwDao.findOne(currentNodeId);// 拖拽节点
            KfkwEntity newKfkw = kfkwDao.findOne(newNodeId);//目标节点 
            KfkwEntity newKfkwSjfl =null;
            // 移到第一节点
            if(newKfkw.getSjfl() != null){
                newKfkwSjfl = kfkwDao.findOne(newKfkw.getSjfl().getId()); //目标节点的父类
            }

            List<KfkwEntity> ccKfkwEntities = null;
            if(newKfkw.getSjfl() != null){
                // 目标节点后面的数据排序+1,如果是最后一位不要+1
                ccKfkwEntities = this.findInfluenceData2(newKfkw.getSjfl().getId(), newKfkw.getPx());
            }else{
                ccKfkwEntities = this.findInfluenceData2(null, newKfkw.getPx());
            }

            if(CollectionUtils.isNotEmpty(ccKfkwEntities)){
                for (int i = 0; i < ccKfkwEntities.size(); i++) {
                    KfkwEntity ccKfkwEntity=ccKfkwEntities.get(i);
                    ccKfkwEntity.setPx(ccKfkwEntity.getPx()+1);
                    kfkwDao.save(ccKfkwEntity);
                }
            }

            List<KfkwEntity> cckfkwEntities2 = null;
            if(currentKfkw.getSjfl() != null){
                // 当前节点之后的排序值减一,判断是不是最后一个节点,如果是最后一个节点,就不需要-1了
                cckfkwEntities2 = this.findInfluenceData2(currentKfkw.getSjfl().getId(), currentKfkw.getPx());
            }else{
                cckfkwEntities2 = this.findInfluenceData2(null, currentKfkw.getPx());
            }
            if(CollectionUtils.isNotEmpty(cckfkwEntities2)){
                for (int i = 0; i < cckfkwEntities2.size(); i++) {
                    KfkwEntity ccKfkwEntity=cckfkwEntities2.get(i);
                    ccKfkwEntity.setPx(ccKfkwEntity.getPx()-1);
                    kfkwDao.save(ccKfkwEntity);
                }
            }

            currentKfkw.setPx(newKfkw.getPx()+1); 
            currentKfkw.setSjfl(newKfkwSjfl);
            kfkwDao.save(currentKfkw);
        }else{
            KfkwEntity currentKfkw = kfkwDao.findOne(currentNodeId);// 拖拽节点
            KfkwEntity newKfkw = kfkwDao.findOne(newNodeId);//目标节点 
            KfkwEntity newKfkwSjfl =null;
            // 移到第一节点
            if(newKfkw.getSjfl() != null){
                newKfkwSjfl = kfkwDao.findOne(newKfkw.getSjfl().getId()); //目标节点的父类
            }

            List<KfkwEntity> ccKfkwEntities2 = null;
            if(currentKfkw.getSjfl() !=null){
                // 当前节点之后的排序值减一,判断是不是最后一个节点,如果是最后一个节点,就不需要-1了
                ccKfkwEntities2 = this.findInfluenceData2(currentKfkw.getSjfl().getId(), currentKfkw.getPx());
            }else{
                ccKfkwEntities2 = this.findInfluenceData2(null, currentKfkw.getPx());
            }

            if(CollectionUtils.isNotEmpty(ccKfkwEntities2)){
                for (int i = 0; i < ccKfkwEntities2.size(); i++) {
                    KfkwEntity ccKfkwEntity=ccKfkwEntities2.get(i);
                    ccKfkwEntity.setPx(ccKfkwEntity.getPx()-1);
                    kfkwDao.save(ccKfkwEntity);
                }
            }

            List<KfkwEntity> ccKfkwEntities = null;
            if(newKfkw.getSjfl() !=null){
                // 目标节点之后的排序值加一
                ccKfkwEntities = this.findInfluenceData2(newKfkw.getSjfl().getId(), newKfkw.getPx());
            }else{
                ccKfkwEntities = this.findInfluenceData2(null, newKfkw.getPx());
            }

            if(CollectionUtils.isNotEmpty(ccKfkwEntities)){
                for (int i = 0; i < ccKfkwEntities.size(); i++) {
                    KfkwEntity ccKfkwEntity=ccKfkwEntities.get(i);
                    ccKfkwEntity.setPx(ccKfkwEntity.getPx()+1);
                    kfkwDao.save(ccKfkwEntity);
                }
            }

            currentKfkw.setPx(newKfkw.getPx()); 
            currentKfkw.setSjfl(newKfkwSjfl);
            kfkwDao.save(currentKfkw);

//            目标节点的排序值加一
            newKfkw.setPx(newKfkw.getPx()+1);
            kfkwDao.save(newKfkw);

        }
    }

    public List<KfkwEntity> findInfluenceData2(Long sjfl, Integer currentNodePx) {
        Specification<KfkwEntity> spec = new Specification<KfkwEntity>() {

            @Override
            public Predicate toPredicate(Root<KfkwEntity> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
                List<Predicate> predicates = Lists.newArrayList();

                if(sjfl != null){
                    Predicate p1 = cb.equal(root.get("sjfl").as(Long.class), sjfl);
                    predicates.add(p1);
                }else{
                    Predicate p1 = cb.isNull(root.get("sjfl").as(Long.class));
                    predicates.add(p1);
                }
                Predicate p2 = cb.equal(root.get("ssxx").as(Long.class), getSchoolId());
                predicates.add(p2);
                Predicate p3 = cb.greaterThan(root.get("px"), currentNodePx);
                predicates.add(p3);
                query.orderBy(cb.asc(root.get("px").as(Long.class)));
                query.where(cb.and(predicates.toArray(new Predicate[predicates.size()])));
                return query.getRestriction();
            }
        };

        List<KfkwEntity> wpflList = kfkwDao.findAll(spec);

        return wpflList;
    }

}

dao代码

/**
 * 仓库管理Dao
 * 
 * @author WangYuanJun
 */
public interface KfkwDao extends JpaRepository<KfkwEntity, Long>, JpaSpecificationExecutor<KfkwEntity> {

    @Query("select o from KfkwEntity o where o.sjfl.id=?1 and o.ssxx.id=?2 order by o.px desc")
    public List<KfkwEntity> findByMaxPx(Long sjfl,Long ssxx);

}
相关标签: jquery ztree

上一篇: ztree 实现表格树

下一篇: