Browse Source

rpt template tuning

TonyKang 7 years ago
parent
commit
6d34f452d4

+ 83 - 30
modules/reports/controllers/rpt_tpl_controller.js

@@ -60,29 +60,29 @@ let mExport = {
             }
         });
     },
-    getRptTplTree_org: function(req, res) {
-        let params = JSON.parse(req.body.params),
-            grpType = params.grpType,
-            userId = params.userId,
-            tplType = params.tplType;
-        let filter = {"grpType": grpType, "$or": [{"isDeleted": null}, {"isDeleted": false} ]};
-        if (userId) {
-            filter.userId = userId;
-        }
-        if ((tplType && tplType !== rptTplDef.TplType.ALL)) {
-            filter.tplType = tplType;
-        }
-        TreeNodeModel.find(filter, '-_id', function(err, data){
-            if (err) {
-                callback(req,res, true,"", null);
-            } else {
-                callback(req,res,false,"", data);
-            }
-        });
-        // let obj = test_glj_type_util.getStdGljTypeCacheObj();
-        // console.log(obj.toArray());
-        // console.log(obj.getItemById(1));
-    },
+    // getRptTplTree_org: function(req, res) {
+    //     let params = JSON.parse(req.body.params),
+    //         grpType = params.grpType,
+    //         userId = params.userId,
+    //         tplType = params.tplType;
+    //     let filter = {"grpType": grpType, "$or": [{"isDeleted": null}, {"isDeleted": false} ]};
+    //     if (userId) {
+    //         filter.userId = userId;
+    //     }
+    //     if ((tplType && tplType !== rptTplDef.TplType.ALL)) {
+    //         filter.tplType = tplType;
+    //     }
+    //     TreeNodeModel.find(filter, '-_id', function(err, data){
+    //         if (err) {
+    //             callback(req,res, true,"", null);
+    //         } else {
+    //             callback(req,res,false,"", data);
+    //         }
+    //     });
+    //     // let obj = test_glj_type_util.getStdGljTypeCacheObj();
+    //     // console.log(obj.toArray());
+    //     // console.log(obj.getItemById(1));
+    // },
     updateTreeNodes: function(req, res) {
         let params = JSON.parse(req.body.params),
             nodes = params.nodes;
@@ -148,6 +148,41 @@ let mExport = {
             }
         })
     },
+    updateTopNodeName: function (req, res) {
+        let params = JSON.parse(req.body.params),
+            compilationId = params.compilationId, engineerId = params.engineerId, userId = params.userId,
+            nodeName = params.nodeName
+        ;
+        let filter = {"compilationId": compilationId, "engineerId": engineerId, "userId": userId, "$or": [{"isDeleted": null}, {"isDeleted": false}]};
+        let updateStatement = {"$set": {"name": nodeName}};
+        rttFacade.updateTreeInDetail(filter, updateStatement).then(function (rst) {
+            if (rst) {
+                //success
+                callback(req,res, false, "", rst);
+            } else {
+                //failed
+                callback(req,res, true, "更新失败!", null);
+            }
+        });
+    },
+    updateSubLevelOneNode: function (req, res) {
+        let params = JSON.parse(req.body.params),
+            compilationId = params.compilationId, engineerId = params.engineerId, userId = params.userId,
+            subNode = params.subNode
+        ;
+        let filter = {"compilationId": compilationId, "engineerId": engineerId, "userId": userId, "items.ID": subNode.ID, "$or": [{"isDeleted": null}, {"isDeleted": false}]};
+        let updateStatement = {$set: {"items.$": subNode}};
+        rttFacade.updateTreeInDetail(filter, updateStatement).then(function (rst) {
+            if (rst) {
+                //success
+                callback(req,res, false, "", rst);
+            } else {
+                //failed
+                callback(req,res, true, "更新失败!", null);
+            }
+        });
+    },
+
     removeTreeRootNode: function (req, res) {
         let params = JSON.parse(req.body.params),
             compilationId = params.compilationId,
@@ -201,29 +236,47 @@ let mExport = {
     //         });
     //     });
     // },
+    getNewNodeID: function(req, res) {
+        let params = JSON.parse(req.body.params),
+            scope = params.scope;
+        counter.counterDAO.getIDAfterCount(counter.moduleName.report, scope, function(err, result){
+            callback(req,res, false, "", result.value.sequence_value);
+        });
+    },
     createDftRptTpl: function(req, res) {
         let params = JSON.parse(req.body.params),
             treeNodeId = params.treeNodeId,
-            //grpChars = stringUtil.getPinYinFullChars(params.grpChars),
-            rptDftTplId = params.rptDftTplId;
+            rptDftTplId = params.rptDftTplId,
+            rptName = params.rptName,
+            grpKey = params.grpKey,
+            compilationId = params.compilationId,
+            engineerId = params.engineerId,
+            userId = params.userId,
+            subNode = params.subNode
+        ;
         let filter = {"ID": rptDftTplId};
         RptTplModel.findOne(filter, '-_id').exec().then(function(dftTplRst) {
             if (dftTplRst) {
                 let _doc = dftTplRst["_doc"];
                 _doc["ID"] = treeNodeId;
-                _doc["GROUP_KEY"] = "";
+                _doc["GROUP_KEY"] = grpKey;
                 _doc["ID_KEY"] = "";
+                _doc[JV.NODE_MAIN_INFO][JV.NODE_MAIN_INFO_RPT_NAME] = rptName;
                 let rptTpl = new RptTplModel(_doc);
                 rptTpl.save(function (err, actTplRst) {
                     if (err) {
                         callback(req,res, "报表模板创建错误", "", null);
                     } else {
                         //TreeNodeModel.update();
-                        TreeNodeModel.update({ID: treeNodeId}, {"refId": treeNodeId}, function(err, rst){
-                            if (err) {
-                                callback(req,res, "报表模板创建错误", "", null);
-                            } else {
+                        let filter = {"compilationId": compilationId, "engineerId": engineerId, "userId": userId, "items.ID": subNode.ID, "$or": [{"isDeleted": null}, {"isDeleted": false}]};
+                        let updateStatement = {$set: {"items.$": subNode}};
+                        rttFacade.updateTreeInDetail(filter, updateStatement).then(function (rst) {
+                            if (rst) {
+                                //success
                                 callback(req,res, false, "", actTplRst);
+                            } else {
+                                //failed
+                                callback(req,res, true, "更新失败!", null);
                             }
                         });
                     }

+ 11 - 6
modules/reports/facade/rpt_tpl_tree_node_facade.js

@@ -33,6 +33,10 @@ async function updateTree(compilationId, engineerId, userId, doc) {
     return await rpt_tpl_tree_mdl.update(filter, doc);
 }
 
+async function updateTreeInDetail(filter, updateStatement) {
+    return await rpt_tpl_tree_mdl.update(filter, updateStatement);
+}
+
 async function removeTree(compilationId, engineerId, userId, cb) {
     let filter = {"compilationId": compilationId, "engineerId": engineerId, "userId": userId, "$or": [{"isDeleted": null}, {"isDeleted": false}]};
     return await rpt_tpl_tree_mdl.findAndModify(filter, [], { $set: { "isDeleted": true } }, {'new':true}, cb);
@@ -66,12 +70,13 @@ async function findTplTreeByOid(objectId) {
 
 
 let expObj = {
-    createNewTree:  createNewTree,
-    updateTree:     updateTree,
-    removeTree:     removeTree,
-    removeTreePhycically: removeTreePhycically,
-    findTplTree:    findTplTree,
-    findTplTreeByOid: findTplTreeByOid
+    createNewTree:          createNewTree,
+    updateTree:             updateTree,
+    updateTreeInDetail:     updateTreeInDetail,
+    removeTree:             removeTree,
+    removeTreePhycically:   removeTreePhycically,
+    findTplTree:            findTplTree,
+    findTplTreeByOid:       findTplTreeByOid
 };
 
 export {expObj as default};

+ 1 - 0
modules/reports/models/tpl_tree_node.js

@@ -20,6 +20,7 @@ let TreeNodeSchema = new Schema({
 
 let TplNodeSchema = new Schema({
     nodeType: Number,   //节点类型:树节点(枝) 或 模板节点(叶)
+    ID: Number,         //template节点ID,只有在nodeType是模板节点有效
     refId: Number,      //引用报表模板id (引用 collection: rpt_templates)
     name: String,       //显示名称
     items: []           //子节点

+ 3 - 0
modules/reports/routes/rpt_tpl_router.js

@@ -17,8 +17,11 @@ module.exports = function (app) {
 
     rptTplRouter.post('/createTreeRootNode', reportTplController.createTreeRootNode);
     rptTplRouter.post('/updateTreeRootNode', reportTplController.updateTreeRootNode);
+    rptTplRouter.post('/updateTopNodeName', reportTplController.updateTopNodeName);
+    rptTplRouter.post('/updateSubLevelOneNode', reportTplController.updateSubLevelOneNode);
     rptTplRouter.post('/removeTreeRootNode', reportTplController.removeTreeRootNode);
     rptTplRouter.post('/getRptTplTree', reportTplController.getRptTplTree);
+    rptTplRouter.post('/getNewNodeID', reportTplController.getNewNodeID);
     rptTplRouter.post('/updateRptTplNodes', reportTplController.updateTreeNodes);
     rptTplRouter.post('/deleteRptTplNodes', reportTplController.deleteRptTplNodes);
     rptTplRouter.post('/createDftRptTpl', reportTplController.createDftRptTpl);

+ 22 - 18
test/unit/reports/rpt_tpl_tree_test.js

@@ -7,31 +7,35 @@ let config = require("../../../config/config.js");
 //config.setupDb(process.env.NODE_ENV);
 config.setupDb('qa');
 import dbm from "../../../config/db/db_manager";
-import mdl from "../../../modules/reports/models/tpl_tree_node";
+//import mdl from "../../../modules/reports/models/tpl_tree_node";
 import rttFacade from "../../../modules/reports/facade/rpt_tpl_tree_node_facade";
+import counter from "../../../public/counter/counter";
 
 dbm.connect();
 
 /*
 test('测试 - 创建dummy报表树: ', function (t) {
-    let tprTplTree = {};
-    tprTplTree.compilationId = "598d239605cdd825682925d1";
-    tprTplTree.engineerId = 1;
-    tprTplTree.userId = -100;
-    tprTplTree.properties = [{"isZhaoBiao": false}, {"isBills": true}];
-    tprTplTree.name = "重庆市建筑工程";
-    tprTplTree.released = true;
-    tprTplTree.isDeleted = false;
-    tprTplTree.items = [];
+    counter.counterDAO.getIDAfterCount(counter.moduleName.report, 2, function(err, result){
+        //result.value.sequence_value
+        let tprTplTree = {};
+        tprTplTree.compilationId = "598d239605cdd825682925d1";
+        tprTplTree.engineerId = 1;
+        tprTplTree.userId = -100;
+        tprTplTree.properties = [{"isZhaoBiao": false}, {"isBills": true}];
+        tprTplTree.name = "重庆市建筑工程";
+        tprTplTree.released = true;
+        tprTplTree.isDeleted = false;
+        tprTplTree.items = [];
 
-    tprTplTree.items.push( {nodeType: 2, refId: -1, name: "【封-1】招标工程量清单", items: null} );
-    tprTplTree.items.push( {nodeType: 2, refId: -1, name: "【表-09】分部分项工程/施工技术措施项目清单计价表", items: null} );
+        tprTplTree.items.push( {nodeType: 2, ID: result.value.sequence_value - 1, refId: -1, name: "【封-1】招标工程量清单", items: null} );
+        tprTplTree.items.push( {nodeType: 2, ID: result.value.sequence_value, refId: -1, name: "【表-09】分部分项工程/施工技术措施项目清单计价表", items: null} );
 
-    let results = rttFacade.createNewTree(tprTplTree);
-    results.then(function(rst) {
-        console.log(rst);
-        t.pass('just pass!');
-        t.end();
+        let results = rttFacade.createNewTree(tprTplTree);
+        results.then(function(rst) {
+            console.log(rst);
+            t.pass('just pass!');
+            t.end();
+        });
     });
 });
  //*/
@@ -60,7 +64,7 @@ test('测试 - 创建dummy报表树2: ', function (t) {
 });
 //*/
 
-//*
+/*
 test('测试 - 更新 dummy报表树2: ', function (t) {
     let tprTplTree = {};
     tprTplTree.compilationId = "598d239605cdd825682925d1";

+ 201 - 118
web/maintain/report/js/rpt_tpl_main.js

@@ -4,7 +4,6 @@ let rptTplObj = {
     iniPage: function() {
         zTreeOprObj.iniEngineerIdList();
         zTreeOprObj.getCompilationList();
-        // zTreeOprObj.getReportTemplateTree(RT.GrpType.CONSTRUCT);
         bandTreeOprObj.getReportTplCfg();
         selectableFiledTreeOprObj.iniTree();
         preview_util.drawBorder($("#tplCanvas")[0]);
@@ -52,59 +51,47 @@ let zTreeOprObj = {
         }
         me.treeObj.refresh();
     },
-    updateNodes: function(nodes){
-        if (nodes && nodes.length > 0) {
-            let me = this;
-            for (let i = 0; i < nodes.length; i++) {
-                if (nodes[i].__v != null) node.__v = nodes[i].__v + 1
-                else nodes[i].__v = 0;
-            }
-            let params = {};
-            params.nodes = nodes;
-            CommonAjax.postEx("report_tpl_api/updateRptTplNodes", params, 5000, true, null, null, null);
-        }
-    },
-    removeTreeRootNode: function(rawNode, isSync, callback, failCallback) {
+    removeTreeRootNode: function(rawNode, isAsync, callback, failCallback) {
         let params = {};
         params.compilationId = rawNode.compilationId;
         params.engineerId = rawNode.engineerId;
         params.userId = rawNode.userId;
         params.isPhysically = true;
-        CommonAjax.postEx("report_tpl_api/removeTreeRootNode", params, 5000, isSync, callback, failCallback, null);
+        CommonAjax.postEx("report_tpl_api/removeTreeRootNode", params, 5000, isAsync, callback, failCallback, null);
     },
-    updateTreeRootNode: function(rawNode, isSync, callback, failCallback) {
+    updateTreeRootNode: function(rawNode, isAsync, callback, failCallback) {
         let params = {};
         params.doc = rawNode;
-        CommonAjax.postEx("report_tpl_api/updateTreeRootNode", params, 5000, isSync, callback, failCallback, null);
+        CommonAjax.postEx("report_tpl_api/updateTreeRootNode", params, 5000, isAsync, callback, failCallback, null);
+    },
+    updateTopNodeName: function (topNode, isAsync, callback, failCallback) {
+        let params = {};
+        params.compilationId = topNode.compilationId;
+        params.engineerId = topNode.engineerId;
+        params.userId = topNode.userId;
+        params.nodeName = topNode.name;
+        CommonAjax.postEx("report_tpl_api/updateTopNodeName", params, 5000, isAsync, callback, failCallback, null);
+    },
+    updateSubNode: function (topNode, subNode, isAsync, callback, failCallback) {
+        let params = {};
+        params.compilationId = topNode.compilationId;
+        params.engineerId = topNode.engineerId;
+        params.userId = topNode.userId;
+        params.subNode = subNode;
+        CommonAjax.postEx("report_tpl_api/updateSubLevelOneNode", params, 5000, isAsync, callback, failCallback, null);
     },
     createIniNode: function() {
         let rst = {
             nodeType: RT.NodeType.TEMPLATE,
             refId: -1,
             name: "",
+            ID: -1,
             items: null
         };
         return rst;
     },
     buildRootNodeDoc: function(topNode, excludeNode) {
         let me = this, rst = null;
-        let private_build_items = function (items) {
-            let itemRst = null;
-            if (items && items.length > 0) {
-                itemRst = [];
-                for (let item of items) {
-                    if (item !== excludeNode) {
-                        let ir = {};
-                        ir.nodeType = item.nodeType;
-                        ir.refId = item.refId;
-                        ir.name = item.name;
-                        ir.items = private_build_items(item.items);
-                        itemRst.push(ir);
-                    }
-                }
-            }
-            return itemRst;
-        }
         if (topNode) {
             rst = {
                 compilationId: topNode.compilationId,
@@ -113,26 +100,45 @@ let zTreeOprObj = {
                 properties: topNode.properties,
                 released: topNode.released,
                 isDeleted: topNode.isDeleted,
-                items: private_build_items(topNode.items),
+                items: me.private_build_items(topNode.items, excludeNode),
                 name: topNode.name
             };
         }
         return rst;
     },
-    createNodeFromZTreeNode: function(treeNode) {
-        let rst = {};
-        rst.ID = treeNode.ID;
-        rst.ParentID = treeNode.ParentID;
-        rst.NextSiblingID = treeNode.NextSiblingID;
-        rst.grpType = treeNode.grpType;
-        rst.nodeType = treeNode.nodeType;
-        rst.tplType = treeNode.tplType;
-        rst.userId = treeNode.userId;
-        rst.refId = treeNode.refId;
-        rst.name = treeNode.name;
+    buildSubRootNodeDoc: function(subNode) {
+        let me = this, rst = null;
+        if (subNode) {
+            rst = {
+                nodeType: subNode.nodeType,
+                refId: subNode.refId,
+                ID: subNode.ID,
+                items: me.private_build_items(subNode.items, null),
+                name: subNode.name
+            };
+        }
         return rst;
     },
 
+    private_build_items: function (items, excludeNode) {
+        let me = this, itemRst = null;
+        if (items && items.length > 0) {
+            itemRst = [];
+            for (let item of items) {
+                if (item !== excludeNode) {
+                    let ir = {};
+                    ir.nodeType = item.nodeType;
+                    ir.refId = item.refId;
+                    ir.name = item.name;
+                    ir.ID = item.ID;
+                    ir.items = me.private_build_items(item.items);
+                    itemRst.push(ir);
+                }
+            }
+        }
+        return itemRst;
+    },
+
     //*
     addHoverDom: function(treeId, treeNode) {
         let me = zTreeOprObj, sObj = $("#" + treeNode.tId + "_span");
@@ -141,35 +147,36 @@ let zTreeOprObj = {
         sObj.after(addStr);
         let btn = $("#addBtn_"+treeNode.tId);
         if (btn) btn.bind("click", function(){
-            let rawNode = me.createIniNode();
-            rawNode.nodeType = RT.NodeType.NODE;
-            rawNode.name = "新增子节点";
-            let newNodes = [], isSilent = false;
-            newNodes.push(rawNode);
-            if (me.treeObj) {
-                let insertIdx = -1;
-                if (treeNode.items.length > 0) {
-                    for (let i = treeNode.items.length - 1; i >= 0; i--) {
-                        if (treeNode.items[i].nodeType === RT.NodeType.NODE) {
-                            insertIdx = i + 1;
-                            break;
-                        } else {
-                            insertIdx = i;
+            me.getNewNodeID(1, function (newNodeID) {
+                let rawNode = me.createIniNode();
+                rawNode.nodeType = RT.NodeType.NODE;
+                rawNode.name = "新增子节点";
+                rawNode.ID = newNodeID;
+                let newNodes = [], isSilent = false;
+                newNodes.push(rawNode);
+                if (me.treeObj) {
+                    let insertIdx = -1;
+                    if (treeNode.items && treeNode.items.length > 0) {
+                        for (let i = treeNode.items.length - 1; i >= 0; i--) {
+                            if (treeNode.items[i].nodeType === RT.NodeType.NODE) {
+                                insertIdx = i + 1;
+                                break;
+                            } else {
+                                insertIdx = i;
+                            }
                         }
                     }
+                    me.treeObj.addNodes(treeNode, insertIdx, newNodes, isSilent);
+                    let tn = me.getTopNodeByCurrentNode(treeNode);
+                    let newTopNode = me.buildRootNodeDoc(tn);
+                    me.updateTreeRootNode(newTopNode, true, function(rst){
+                        if (!(rst)) {
+                            alert("新增节点失败!");
+                        }
+                        me.refreshNodes();
+                    }, null);
                 }
-                me.treeObj.addNodes(treeNode, insertIdx, newNodes, isSilent);
-                let tn = me.getTopNodeByCurrentNode(treeNode);
-                let newTopNode = me.buildRootNodeDoc(tn);
-                me.updateTreeRootNode(newTopNode, true, function(rst){
-                    if (rst) {
-                        //
-                    } else {
-                        alert("新增节点失败!");
-                    }
-                    me.refreshNodes();
-                }, null);
-            }
+            });
         });
     },
     removeHoverDom: function(treeId, treeNode) {
@@ -240,26 +247,29 @@ let zTreeOprObj = {
     addTplNode: function (){
         let me = this;
         if (me.currentNode && me.currentNode.nodeType === RT.NodeType.NODE || me.currentNode.level === 0) {
-            let rawNode = me.createIniNode();
-            rawNode.nodeType = RT.NodeType.TEMPLATE;
-            rawNode.name = "新增报表模板";
-            let newNodes = [], isSilent = false;
-            newNodes.push(rawNode);
-            if (me.treeObj) {
+            me.getNewNodeID(1, function (newNodeID) {
+                let rawNode = me.createIniNode();
+                rawNode.nodeType = RT.NodeType.TEMPLATE;
+                rawNode.name = "新增报表模板";
+                rawNode.ID = newNodeID;
+                let newNodes = [], isSilent = false;
+                newNodes.push(rawNode);
                 me.treeObj.addNodes(me.currentNode, -1, newNodes, isSilent);
-                let rawNode = me.buildRootNodeDoc(me.currentNode);
-                me.updateTreeRootNode(rawNode, true, function(rst){
-                    if (rst) {
-                        //
-                    } else {
-                        //
+                let topNode = me.buildRootNodeDoc(me.currentNode);
+                me.updateTreeRootNode(topNode, true, function(rst){
+                    if (!(rst)) {
+                        alert("新增空白模板失败!");
                     }
                     me.refreshNodes();
                 }, null);
-
-            }
+            });
         }
     },
+    getNewNodeID: function (scope, callback) {
+        let params = {};
+        params.scope = scope;
+        CommonAjax.postEx("report_tpl_api/getNewNodeID", params, 5000, true, callback, null, null);
+    },
     addRootNode: function() {
         let me = this, rawNode = me.createIniRootNode();
         if (!me.chkIfDupRootNode(rawNode)) {
@@ -329,12 +339,19 @@ let zTreeOprObj = {
     onRemove: function(e, treeId, treeNode){
         let me = zTreeOprObj, topPNode = me.getTopNodeByCurrentNode(treeNode);
         let rawNode = me.buildRootNodeDoc(topPNode, treeNode);
-        if (treeNode.level === 0) rawNode.isDeleted = true;
-        me.removeTreeRootNode(rawNode, true, function(rst){
-            if (!(rst)) {
-                alert("删除请求失败!");
-            }
-        });
+        if (treeNode.level === 0) {
+            me.removeTreeRootNode(rawNode, true, function(rst){
+                if (!(rst)) {
+                    alert("删除请求失败!");
+                }
+            });
+        } else {
+            me.updateTreeRootNode(rawNode, true, function(rst){
+                if (!(rst)) {
+                    alert("删除请求失败!");
+                }
+            });
+        }
         me.refreshNodes();
     },
     beforeRename: function(treeId, treeNode, newName, isCancel) {
@@ -345,15 +362,23 @@ let zTreeOprObj = {
     },
     onRename : function(e, treeId, treeNode, isCancel) {
         if (!isCancel) {
-            let me = zTreeOprObj, topPNode = me.getTopNodeByCurrentNode(treeNode);
-            let rawNode = me.buildRootNodeDoc(topPNode);
-            me.updateTreeRootNode(rawNode, true, function(rst){
-                if (rst) {
-                    //
-                } else {
-                    alert('修改名称请求失败!');
-                }
-            });
+            let me = zTreeOprObj;
+            if (treeNode.level === 0) {
+                me.updateTopNodeName(treeNode, true, function(rst){
+                    if (!(rst)) {
+                        alert('修改名称请求失败!');
+                    }
+                }, null);
+            } else {
+                let subTopNode = me.getSubTopNodeByCurrentNode(treeNode);
+                let topPNode = subTopNode.getParentNode();
+                let rawNode = me.buildSubRootNodeDoc(subTopNode);
+                me.updateSubNode(topPNode, rawNode, true, function(rst){
+                    if (!(rst)) {
+                        alert('修改名称请求失败!');
+                    }
+                });
+            }
         }
     },
     /*/
@@ -487,6 +512,18 @@ let zTreeOprObj = {
         }
     },
 
+    updateNodes: function(nodes){
+        if (nodes && nodes.length > 0) {
+            let me = this;
+            for (let i = 0; i < nodes.length; i++) {
+                if (nodes[i].__v != null) node.__v = nodes[i].__v + 1
+                else nodes[i].__v = 0;
+            }
+            let params = {};
+            params.nodes = nodes;
+            CommonAjax.postEx("report_tpl_api/updateRptTplNodes", params, 5000, true, null, null, null);
+        }
+    },
     addRootNode: function() {
         let me = this, rawNode = me.createIniRootNode(), lastNodeId = -1, lastNode = null;
         if (me.treeObj) {
@@ -580,7 +617,50 @@ let zTreeOprObj = {
             }
         }
     },
+    createNodeFromZTreeNode: function(treeNode) {
+        let rst = {};
+        rst.ID = treeNode.ID;
+        rst.ParentID = treeNode.ParentID;
+        rst.NextSiblingID = treeNode.NextSiblingID;
+        rst.grpType = treeNode.grpType;
+        rst.nodeType = treeNode.nodeType;
+        rst.tplType = treeNode.tplType;
+        rst.userId = treeNode.userId;
+        rst.refId = treeNode.refId;
+        rst.name = treeNode.name;
+        return rst;
+    },
+
     //*/
+    createNewTpl: function () {
+        let me = zTreeOprObj, params = {};
+        if (me.currentNode && me.currentNode.nodeType === RT.NodeType.TEMPLATE) {
+            params.treeNodeId = me.currentNode.ID;
+            let rptTypeId = common_rpt_type_ids.flow;
+            if ($("#crossTypeOpt")[0].checked) rptTypeId = common_rpt_type_ids.cross;
+            if ($("#billTypeOpt")[0].checked) rptTypeId = common_rpt_type_ids.bill;
+            params.rptDftTplId = rptTypeId;
+            params.rptName = me.currentNode.name;
+            params.grpKey = me.getFolderText(me.currentNode, "_");
+            me.currentNode.refId = me.currentNode.ID;
+            let subTopNode = me.getSubTopNodeByCurrentNode(me.currentNode);
+            let topPNode = me.getTopNodeByCurrentNode(subTopNode);
+            let rawNode = me.buildSubRootNodeDoc(subTopNode);
+            params.compilationId = topPNode.compilationId;
+            params.engineerId = topPNode.engineerId;
+            params.userId = topPNode.userId;
+            params.subNode = rawNode;
+            CommonAjax.postEx("report_tpl_api/createDftRptTpl", params, 10000, true, function(result){
+                    if (result) {
+                        me.currentNode.rptTpl = result;
+                        me.chkAndRreshRefTpl();
+                    } else {
+                        alert('update error!');
+                    }
+                }, null, null
+            );
+        }
+    },
     onClick: function(event,treeId,treeNode) {
         let me = zTreeOprObj;
         me.currentNode = treeNode;
@@ -588,11 +668,7 @@ let zTreeOprObj = {
         if (treeNode.nodeType === RT.NodeType.NODE) {
             $("#rpt_tpl_display_label")[0].innerText = "...";
         } else if (treeNode.nodeType === RT.NodeType.TEMPLATE) {
-            let showText = treeNode.name, parentNode = treeNode.getParentNode();
-            while (parentNode !== null) {
-                showText = parentNode.name + ' > ' + showText;
-                parentNode = parentNode.getParentNode();
-            }
+            let showText = me.getFolderText(me.currentNode, " > ");
             $("#rpt_tpl_display_label")[0].innerText = showText;
             if (treeNode.refId < 0) {
                 //创建新报表模板
@@ -603,19 +679,17 @@ let zTreeOprObj = {
             }
         }
     },
-    createNewTpl: function () {
-        let me = zTreeOprObj, params = {};
-        if (me.currentNode && me.currentNode.nodeType === RT.NodeType.TEMPLATE) {
-            params.treeNodeId = me.currentNode.ID;
-            let rptTypeId = common_rpt_type_ids.flow;
-            if ($("#crossTypeOpt")[0].checked) rptTypeId = common_rpt_type_ids.cross;
-            if ($("#billTypeOpt")[0].checked) rptTypeId = common_rpt_type_ids.bill;
-            params.rptDftTplId = rptTypeId;
-            CommonAjax.postEx("report_tpl_api/createDftRptTpl", params, 20000, true, function(result){
-                    me.currentNode.rptTpl = result;
-                }, null, null
-            );
+    getFolderText: function (treeNode, separator) {
+        let rst = "";
+        if (treeNode) {
+            rst = treeNode.name;
+            let parentNode = treeNode.getParentNode();
+            while (parentNode !== null) {
+                rst = parentNode.name + separator + rst;
+                parentNode = parentNode.getParentNode();
+            }
         }
+        return rst;
     },
     chkAndRreshRefTpl: function() {
         let me = zTreeOprObj, params = {};
@@ -665,5 +739,14 @@ let zTreeOprObj = {
             pNode = pNode.getParentNode();
         }
         return topPNode;
+    },
+    getSubTopNodeByCurrentNode: function (currentNode) {
+        let startNode = currentNode, resultPNode = null, pNode = startNode.getParentNode();
+        while (pNode !== null) {
+            resultPNode = startNode;
+            startNode = pNode;
+            pNode = startNode.getParentNode();
+        }
+        return resultPNode;
     }
 };