Jelajahi Sumber

Merge branch '1.0.0_online' of http://smartcost.f3322.net:3000/SmartCost/ConstructionOperation into 1.0.0_online

zhongzewei 6 tahun lalu
induk
melakukan
257130882c

+ 6 - 2
modules/reports/routes/rpt_tpl_router.js

@@ -1,5 +1,6 @@
 import express from "express";
 let rptTplRouter = express.Router();
+let config = require("../../../config/config.js");
 import reportTplController from "./../controllers/rpt_tpl_controller";
 import reportCfgController from "./../controllers/rpt_cfg_controller";
 
@@ -10,8 +11,11 @@ module.exports = function (app) {
         }
         else {
             res.render('maintain/report/rpt_tpl_main.html',
-                {userAccount: req.session.managerData.username,
-                    userID: req.session.managerData.userID});
+                {   userAccount: req.session.managerData.username,
+                    userID: req.session.managerData.userID,
+                    LicenseKey:config.getLicenseKey(process.env.NODE_ENV)
+                }
+            );
         }
     });
 

+ 1 - 0
modules/users/models/engineering_lib_model.js

@@ -94,6 +94,7 @@ class EngineeringLibModel extends BaseModel {
         if(data.glj_col){
             data.glj_col =  JSON.parse(data.glj_col);
         }
+        data.isInstall == 'true'?data.isInstall=true:data.isInstall=false;
         let result = false;
         data = this.filterLibData(data);
         try {

+ 28 - 15
test/demo/stringTest.js

@@ -18,6 +18,19 @@ let strUtil = require('../../public/stringUtil');
 //     t.equal(str1, "at('1.1') + at('1.2') + at('1.3') + at('1.4')");
 //     t.end();
 // })
+
+test('string test1', function(t){
+    let str = "abc|def";
+    // let str1 = str.replace('|', '\n');
+    // let str1 = strUtil.replaceAll(str, "|", "\n\r");
+    // let str1 = strUtil.replaceAll(str, "\|", "+");
+    let str1 = str.split('|').join('\n\r');
+    console.log(str1);
+    //t.equal(str1, "@('1.1') + @('1.2') + @('1.3') + @('1.4')");
+    // t.equal(str1, "at('1.1') + at('1.2') + at('1.3') + at('1.4')");
+    t.end();
+})
+
 //
 // test('string test2', function(t){
 //     var str="hello(world)";
@@ -96,18 +109,18 @@ let strUtil = require('../../public/stringUtil');
 //     t.end();
 // });
 
-test('test string replacement of return/new line', function(t){
-    new RegExp('\n\r','g');
-    let str = 'ABC-\n\r-123\r\n-zyx\n-987\r';
-    str = str.replace(new RegExp('\n\r','g'), '|').replace(new RegExp('\r\n','g'), '|').replace(new RegExp('\n','g'), '|').replace(new RegExp('\r','g'), '|');
-    t.pass('test result: ' + str);
-    t.end();
-});
-
-test('test URI', function(t){
-    let str = "测试 ''URI STRING";
-    console.log(encodeURI(str));
-    console.log(decodeURI(str));
-    t.pass('test result: ' + str);
-    t.end();
-});
+// test('test string replacement of return/new line', function(t){
+//     new RegExp('\n\r','g');
+//     let str = 'ABC-\n\r-123\r\n-zyx\n-987\r';
+//     str = str.replace(new RegExp('\n\r','g'), '|').replace(new RegExp('\r\n','g'), '|').replace(new RegExp('\n','g'), '|').replace(new RegExp('\r','g'), '|');
+//     t.pass('test result: ' + str);
+//     t.end();
+// });
+//
+// test('test URI', function(t){
+//     let str = "测试 ''URI STRING";
+//     console.log(encodeURI(str));
+//     console.log(decodeURI(str));
+//     t.pass('test result: ' + str);
+//     t.end();
+// });

+ 62 - 0
web/maintain/common/css/main.css

@@ -293,4 +293,66 @@ body {
 
 .second_header{
     background: #e1e1e1;
+}
+
+.input-group-addon{
+    padding: 6px 12px;
+    font-size: 14px;
+    font-weight: 400;
+    line-height: 1;
+    color: #555;
+    text-align: center;
+    background-color: #eee;
+    border: 1px solid #ccc;
+    border-radius: 4px;
+}
+
+.input-sm{
+    height: 30px;
+    padding: 5px 10px;
+    font-size: 12px;
+    line-height: 1.5;
+    border-radius: 3px;
+}
+.btn-default{
+    color: #333;
+    background-color: #fff;
+    border-color: #ccc;
+}
+.checkbox{
+    position: relative;
+    display: block;
+    margin-top: 10px;
+    margin-bottom: 10px;
+}
+input[type=checkbox]{
+    position: absolute;
+    margin-top: 5px;
+    margin-left: -20px;
+}
+.col-md-2{
+    position: relative;
+    min-height: 1px;
+    padding-right: 15px;
+    padding-left:15px;
+    width:16.66666667%
+}
+.checkbox label, .radio label {
+    min-height: 20px;
+    padding-left: 20px;
+    margin-bottom: 0;
+    font-weight: 400;
+    cursor: pointer;
+    width: 200px;
+}
+
+.close{
+    float: right;
+    font-size: 21px;
+    font-weight: 700;
+    line-height: 1;
+    color: #000;
+    text-shadow: 0 1px 0 #fff;
+    filter: alpha(opacity=20);
+    opacity: .2;
 }

+ 2 - 2
web/maintain/main_col_lib/js/main_col_lib.js

@@ -381,14 +381,14 @@ $('#set-column').on('shown.bs.modal', function () {
     ColSettingObj.initColSetting(ColSettingObj.colSetting);
 });
 
-$('#set-glj-col').on('show.bs.modal', function () {
+/*$('#set-glj-col').on('show.bs.modal', function () {
     let glj_col_setting = JSON.parse($("#glj_col").val());
     if(glj_col_setting.showAdjustPrice){
         $('#adjustPrice_cb').prop('checked',true);
     }else {
         $('#adjustPrice_cb').prop('checked',false);
     }
-});
+});*/
 
 $('#set-glj-comf').click(function () {
 

+ 12 - 2
web/maintain/material_replace_lib/js/material_replace_edit.js

@@ -46,10 +46,20 @@ let materialOjb = {
         this.materialSheet = this.materialSpread .getSheet(0);
         sheetCommonObj.initSheet(this.materialSheet,this.materialSetting, 30);
         this.materialSheet.name('materialSheet');
-
+        this.initRightClick("materialSpread",this.materialSpread);
         this.refreshSheet();
 
     },
+    canDelete : function (sheet) {
+        let sel =  sheet.getSelections()[0];
+        console.log(sel);
+        if(sel.row === undefined || sel.row < 0) return false ;//一行都没选中时,不能删除
+
+        //选中空行时,不能删除
+        // to do
+        return true;
+    },
+
     initRightClick : function(id,spread) {
         let me = this;
         $.contextMenu({
@@ -64,7 +74,7 @@ let materialOjb = {
                     name: "删除",
                     icon: 'fa-trash-o',
                     disabled: function () {
-                        return false;
+                        return !me.canDelete(spread.getActiveSheet());
                     },
                     callback: function (key, opt) {
                        console.log();

+ 1 - 37
web/maintain/report/js/cfg_const.js

@@ -41,7 +41,7 @@ let setting = {
         beforeRemove: zTreeOprObj.onBeforeRemove,
         onRemove: zTreeOprObj.onRemove,
         onRename: zTreeOprObj.onRename,
-        onCheck: zTreeOprObj.oncheck,
+        onCheck: zTreeOprObj.onCheck,
         beforeDrag: zTreeOprObj.onBeforeDrag,
         beforeDrop: zTreeOprObj.onBeforeDrop,
         onDrop: zTreeOprObj.onDrop
@@ -104,42 +104,6 @@ let bandSetting = {
     }
 };
 
-let bandSetting2 = {
-    view: {
-        showIcon: true,
-        expandSpeed: "",
-        selectedMulti: false
-    },
-    edit: {
-        enable: true,
-        editNameSelectAll: false,
-        showRemoveBtn: false,
-        showRenameBtn: false
-    },
-    check: {
-        enable: true,
-        chkStyle: "radio",
-        radioType: "all"
-    },
-    data: {
-        keep: {
-            parent:true,
-            leaf:true
-        },
-        key: {
-            children: 'items',
-            name: "Name"
-        },
-        simpleData: {
-            enable: true
-        }
-    },
-    callback:{
-        onCheck: dataInfoMapTreeOprObj.onCheck,
-        beforeDrag: function() {return false;}
-    }
-};
-
 let selectedFieldMapSetting = {
     view: {
         showIcon: true,

+ 18 - 0
web/maintain/report/js/rpt_tpl_cfg_helper.js

@@ -73,6 +73,7 @@ let rpt_tpl_cfg_helper = {
             $("#element_border")[0].style.display = "";
             $("#element_control")[0].style.display = "";
             $("#element_area_1")[0].style.display = "";
+            $("#element_visual_div")[0].style.display = "none";
             // $("#element_area_2")[0].style.display = "";
             if (treeNode[JV.PROP_FIELD_ID] || treeNode[JV.PROP_PARAM_ID]) {
                 $("#element_pre_suff")[0].style.display = "";
@@ -137,6 +138,23 @@ let rpt_tpl_cfg_helper = {
             $("#element_area_1")[0].style.display = "none";
             // $("#element_area_2")[0].style.display = "none";
             $("#element_pre_suff")[0].style.display = "none";
+            if (treeNode[JV.PROP_NAME] === JV.NODE_FLOW_COLUMN) {
+                //一些可视化操作
+                $("#element_visual_div")[0].style.display = "";
+                let nextNode = treeNode.getNextNode();
+                while (nextNode !== null && nextNode !== undefined) {
+                    if (nextNode[JV.PROP_NAME] === JV.NODE_FLOW_CONTENT) {
+                        break;
+                    } else {
+                        nextNode = nextNode.getNextNode();
+                    }
+                }
+                let rptTpl = (zTreeOprObj.currentNode)?zTreeOprObj.currentNode.rptTpl:null;
+                fieldLocationOprObj.iniSpreadJs(treeNode, treeNode.getNextNode());
+                fieldLocationOprObj.setupColumn(rptTpl, treeNode, treeNode.getNextNode());
+            } else {
+                $("#element_visual_div")[0].style.display = "none";
+            }
         }
     },
     fontChange: function(dom) {

+ 12 - 25
web/maintain/report/js/rpt_tpl_data_map.js

@@ -13,13 +13,20 @@ let dataInfoMapTreeOprObj = {
         let me = this;
         let fieldMapList = me.buildTreeData(rptTpl);
         me.treeObj = $.fn.zTree.init($("#tpl_data_info_reversed"), rptDataInfoSetting, fieldMapList);
-        me.treeObj.expandAll(true);
+        let nodes = me.treeObj.getNodes();
+        for (let node of nodes) {
+            if (node[JV.PROP_NAME].indexOf("_列") < 0 && node[JV.PROP_NAME].indexOf("_数据") < 0) {
+                me.treeObj.expandNode(node, true);
+            }
+        }
+        // me.treeObj.expandAll(true);
         $("#element_font")[0].style.display = "none";
         $("#element_border")[0].style.display = "none";
         $("#element_control")[0].style.display = "none";
         $("#element_area_1")[0].style.display = "none";
         // $("#element_area_2")[0].style.display = "none";
         $("#element_pre_suff")[0].style.display = "none";
+        $("#element_visual_div")[0].style.display = "none";
     },
     iniDataMap: function () {
         let me = this, bandList = bandTreeOprObj.copyBandList(false);
@@ -108,8 +115,8 @@ let dataInfoMapTreeOprObj = {
         let rootPageSumNode = {Name: JV.NODE_FLOW_PAGE_SUM, type: "flow_page_sum_data", isParent: true, Title: ""};
         let rootChapterSumNode = {Name: JV.NODE_FLOW_SEG_SUM, type: "flow_chapter_sum_data", isParent: true, Title: ""};
         let rootGroupSumNode = {Name: JV.NODE_FLOW_GROUP, type: "flow_group_sum_data", isParent: true, Title: ""};
-        rst.push(rootFieldNode);
         rst.push(rootColumnNode);
+        rst.push(rootFieldNode);
         if (rptTpl[JV.NODE_FLOW_INFO][JV.NODE_FLOW_COLUMN].hasOwnProperty(JV.PROP_BAND_NAME)) {
             rootColumnNode[JV.PROP_BAND_NAME] = rptTpl[JV.NODE_FLOW_INFO][JV.NODE_FLOW_COLUMN][JV.PROP_BAND_NAME];
         }
@@ -401,7 +408,7 @@ let dataInfoMapTreeOprObj = {
         me.private_copy_area(source[JV.PROP_AREA], destination[JV.PROP_AREA]);
     },
 
-    private_get_dummy_text_node: function(treeNode) {
+    getDummyTextNode: function(treeNode) {
         let me = this, rst = {};
         rst[JV.PROP_NAME] = "文本";
         rst[JV.PROP_LABEL] = "文本";
@@ -447,30 +454,12 @@ let dataInfoMapTreeOprObj = {
         }
     },
 
-    checkIfShouldHaveBand: function(treeNode) {
-        return treeNode.hasOwnProperty(JV.PROP_BAND_NAME);
-    },
     onTabDataClick: function (event,treeId,treeNode) {
         let me = dataInfoMapTreeOprObj;
         me.currentNode = treeNode;
         //检测是否为field/param/text对象
         rpt_tpl_cfg_helper.checkAndSetSelectedNodeCfg(treeNode);
     },
-    onCheck: function (event,treeId,treeNode) {
-        let me = dataInfoMapTreeOprObj;
-        if (me.currentNode.hasOwnProperty(JV.PROP_BAND_NAME) && me.currentNode[JV.PROP_BAND_NAME] !== treeNode[JV.PROP_NAME])  {
-            // alert("change band from: " + me.currentNode[JV.PROP_BAND_NAME] + " to : " + treeNode[JV.PROP_NAME]);
-            me.currentNode[JV.PROP_BAND_NAME] = treeNode[JV.PROP_NAME];
-            if (me.currentNode[JV.PROP_NAME].indexOf("子项") >= 0) {
-                // me.currentNode[JV.PROP_NAME] = "子项(区域:" + treeNode[JV.PROP_NAME] + ")";
-                me.currentNode[JV.PROP_NAME] = "子项";
-            } else {
-                // me.currentNode.Title = "区域:" + treeNode[JV.PROP_NAME];
-                me.currentNode.Title = "";
-            }
-            me.treeObj.updateNode(me.currentNode);
-        }
-    },
     onBeforeRemove: function(treeId, treeNode){
         let rst = true;
         if (treeNode.isParent) {
@@ -622,7 +611,7 @@ let dataInfoMapTreeOprObj = {
             } else {
                 //text
                 btn.bind("click", function(){
-                    let node = me.private_get_dummy_text_node(treeNode);
+                    let node = me.getDummyTextNode(treeNode);
                     let newNodes = [];
                     newNodes.push(node);
                     me.treeObj.addNodes(treeNode, -1, newNodes, true);
@@ -804,9 +793,7 @@ let dataInfoMapTreeOprObj = {
     },
     extractDiscreteFieldParam: function(rptTpl) {
         let me = dataInfoMapTreeOprObj;
-    },
-    createMapFieldByNode: function (node) {
-        //
+        //待完善中...
     }
 };
 

+ 686 - 0
web/maintain/report/js/rpt_tpl_field_location.js

@@ -0,0 +1,686 @@
+/**
+ * Created by Tony on 2018/8/21.
+ */
+
+let fieldLocationOprObj = {
+    columnWorkBook: null,
+    columnParentNode: null,
+    contentParentNode: null,
+    columnFieldCtrls: null,
+    iniSpreadJs: function (columnParentNode, contentParentNode) {
+        let me = this;
+        if (me.columnWorkBook === null) {
+            me.columnWorkBook = new GC.Spread.Sheets.Workbook($('#rptTplColumnWorkbook')[0], {sheetCount: 1});
+            // me.columnWorkBook.setHei
+            me.columnWorkBook.options.tabStripVisible = false;
+            // me.columnWorkBook.options.scrollbarMaxAlign = true;
+            me.columnWorkBook.options.allowCopyPasteExcelStyle = false;
+            // me.columnWorkBook.options.allowExtendPasteRange = isExtendPaste? true : false;
+            me.columnWorkBook.options.allowUserDragDrop = false;
+            me.columnWorkBook.options.allowContextMenu = false;
+            let sheet = me.columnWorkBook.getActiveSheet();
+            sheet.options.allowCellOverflow = false;
+            sheet.options.clipBoardOptions = GC.Spread.Sheets.ClipboardPasteOptions.values;
+            // sheet.showRowOutline(false);
+            // sheet.setRowCount(10, GC.Spread.Sheets.SheetArea.viewport);
+            sheet.bind(GC.Spread.Sheets.Events.EnterCell, me.onCellEnter);
+        }
+        me.columnParentNode = columnParentNode;
+        me.contentParentNode = contentParentNode;
+    },
+    setupColumn: function (rptTpl, columnParentNode, contentParentNode) {
+        let me = this, yPos = [], xPos = [];
+        me.columnFieldCtrls = [];
+        let bandName = columnParentNode[JV.PROP_BAND_NAME];
+        let private_getBand = function(parentBand) {
+            let rst = null;
+            if (parentBand[JV.PROP_NAME] === bandName) {
+                rst = parentBand;
+            } else {
+                if (parentBand[JV.BAND_PROP_SUB_BANDS] && parentBand[JV.BAND_PROP_SUB_BANDS].length > 0) {
+                    for (let subBand of parentBand[JV.BAND_PROP_SUB_BANDS]) {
+                        rst = private_getBand(subBand);
+                        if (rst !== null) {
+                            break;
+                        }
+                    }
+                }
+            }
+            return rst;
+        };
+        let selectedBand;
+        for (let band of rptTpl[JV.NODE_BAND_COLLECTION]) {
+            selectedBand = private_getBand(band);
+            if (selectedBand !== null) {
+                break;
+            }
+        }
+        if (selectedBand !== null) {
+            let sheet = me.columnWorkBook.getActiveSheet();
+            sheet.suspendPaint();
+            sheet.clearSelection();
+            let spans =sheet.getSpans();
+            for(let i = 0; i < spans.length; i++)
+            {
+                sheet.removeSpan(spans[i].row, spans[i].col, GC.Spread.Sheets.SheetArea.viewport);
+            }
+            // sheet.setRowCount(1);
+            // sheet.setColumnCount(1);
+            let bandH = Math.round(parseFloat(selectedBand[JV.BAND_PROP_HEIGHT]) / 2.54 * 96);
+            let bandW = 700;
+            let pIdx = JV.PAGES_SIZE_STR.indexOf(rptTpl[JV.NODE_MAIN_INFO][JV.NODE_PAGE_INFO][JV.PROP_PAGE_SIZE]);
+            if (pIdx >= 0) {
+                bandW = Math.round(JV.PAGES_SIZE[pIdx][0] * 96 - (parseFloat(rptTpl[JV.NODE_MAIN_INFO][JV.NODE_MARGINS][JV.PROP_LEFT]) + parseFloat(rptTpl[JV.NODE_MAIN_INFO][JV.NODE_MARGINS][JV.PROP_RIGHT])) /2.54*96 );
+                if (rptTpl[JV.NODE_MAIN_INFO][JV.NODE_PAGE_INFO][JV.PROP_ORIENTATION] === JV.ORIENTATION_LANDSCAPE ||
+                    rptTpl[JV.NODE_MAIN_INFO][JV.NODE_PAGE_INFO][JV.PROP_ORIENTATION] === JV.ORIENTATION_LANDSCAPE_CHN) {
+                    bandW = Math.round(JV.PAGES_SIZE[pIdx][1] * 96 - (parseFloat(rptTpl[JV.NODE_MAIN_INFO][JV.NODE_MARGINS][JV.PROP_LEFT]) + parseFloat(rptTpl[JV.NODE_MAIN_INFO][JV.NODE_MARGINS][JV.PROP_RIGHT])) /2.54*96 );
+                }
+            }
+            /*/
+            for (let itemNode of columnParentNode.items) {
+                //预push一下横向坐标,看看会有多少列
+                me.private_pushPos(itemNode, itemNode[JV.PROP_AREA][JV.PROP_H_CALCULATION], JV.PROP_LEFT, bandW, xPos);
+            }
+            if (xPos.length > 5) {
+                if ((xPos.length - 5) < 5) {
+                    bandW *= (xPos.length - 5) * 0.1 + 1; //放大一下,纯属为了UI操作方便,看得清一些
+                } else {
+                    bandW *= 1.5; //最大1.5倍
+                }
+            }
+            xPos = [];
+            //*/
+            for (let itemNode of columnParentNode.items) {
+                me.private_pushPos(itemNode, itemNode[JV.PROP_AREA][JV.PROP_H_CALCULATION], JV.PROP_LEFT, bandW, xPos);
+                me.private_pushPos(itemNode, itemNode[JV.PROP_AREA][JV.PROP_H_CALCULATION], JV.PROP_RIGHT, bandW, xPos);
+                me.private_pushPos(itemNode, itemNode[JV.PROP_AREA][JV.PROP_V_CALCULATION], JV.PROP_TOP, bandH, yPos);
+                me.private_pushPos(itemNode, itemNode[JV.PROP_AREA][JV.PROP_V_CALCULATION], JV.PROP_BOTTOM, bandH, yPos);
+            }
+
+            sheet.setRowCount(yPos.length, GC.Spread.Sheets.SheetArea.viewport);
+            sheet.setColumnCount(xPos.length - 1, GC.Spread.Sheets.SheetArea.viewport);
+            for (let idx = 1; idx < xPos.length; idx++) {
+                me.columnFieldCtrls.push(me.private_create_dft_ctrl());
+            }
+            // sheet.clear();
+            let cellType = new GC.Spread.Sheets.CellTypes.ComboBox();
+            let selectableFields = me.private_getSelectedFields(rptTpl);
+            cellType.items(selectableFields);
+            //设置 最后一行为 行数据选择combobox
+            let iSelectedRow = sheet.getRowCount() - 1;
+            sheet.setRowHeight(iSelectedRow, 20);
+            sheet.getRange(iSelectedRow, -1, 1, -1).backColor("LightCyan");
+            sheet.getRange(iSelectedRow, -1, 1, -1).locked(true);
+            for (let jCol = 0; jCol < sheet.getColumnCount(); jCol++) {
+                sheet.getCell(iSelectedRow, jCol).cellType(cellType);
+            }
+            xPos.sort(function(x1, x2){
+                return (x1 - x2);
+            });
+            yPos.sort(function(y1, y2){
+                return (y1 - y2);
+            });
+            for (let contentItemNode of contentParentNode.items) {
+                let idxCol = xPos.indexOf(me.private_getActPosEx(contentItemNode, contentItemNode[JV.PROP_AREA][JV.PROP_H_CALCULATION], JV.PROP_LEFT, bandW, xPos));
+                sheet.getCell(iSelectedRow, idxCol).value(contentItemNode[JV.PROP_NAME]);
+                me.private_merge_ctrl(rptTpl, idxCol, contentItemNode, null);
+            }
+            for (let idx = 1; idx < xPos.length; idx++) {
+                sheet.setColumnWidth(idx - 1, xPos[idx] - xPos[idx - 1]);
+            }
+            for (let idx = 1; idx < yPos.length; idx++) {
+                sheet.setRowHeight(idx - 1, yPos[idx] - yPos[idx - 1]);
+                sheet.getRange(idx - 1, -1, 1, -1).backColor(undefined);
+            }
+            for (let itemNode of columnParentNode.items) {
+                let idx1 = xPos.indexOf(me.private_getActPosEx(itemNode, itemNode[JV.PROP_AREA][JV.PROP_H_CALCULATION], JV.PROP_LEFT, bandW, xPos));
+                let idx2 = xPos.indexOf(me.private_getActPosEx(itemNode, itemNode[JV.PROP_AREA][JV.PROP_H_CALCULATION], JV.PROP_RIGHT, bandW, xPos));
+                let idy1 = yPos.indexOf(me.private_getActPosEx(itemNode, itemNode[JV.PROP_AREA][JV.PROP_V_CALCULATION], JV.PROP_TOP, bandH, yPos));
+                let idy2 = yPos.indexOf(me.private_getActPosEx(itemNode, itemNode[JV.PROP_AREA][JV.PROP_V_CALCULATION], JV.PROP_BOTTOM, bandH, yPos));
+                if (idx2 - idx1 > 1 || idy2 - idy1 > 1) {
+                    sheet.addSpan(idy1, idx1, idy2 - idy1, idx2 - idx1, GC.Spread.Sheets.SheetArea.viewport);
+                }
+                me.private_setupCell(sheet.getCell(idy1, idx1), rptTpl, itemNode);
+            }
+            sheet.resumePaint();
+        }
+    },
+    onCellEnter: function (sender, args) {
+        let me = fieldLocationOprObj,
+            sheet = me.columnWorkBook.getActiveSheet();
+        if (args.row === sheet.getRowCount() - 1) {
+            me.private_setup_control_options(true);
+            me.private_update_ctrl_cfg(args.col);
+        } else {
+            me.private_setup_control_options(false);
+        }
+    },
+    addRow: function () {
+        let me = fieldLocationOprObj,
+            sheet = me.columnWorkBook.getActiveSheet();
+        sheet.addRows(sheet.getRowCount() - 1, 1);
+    },
+    deleteRow: function () {
+        let me = fieldLocationOprObj,
+            sheet = me.columnWorkBook.getActiveSheet(),
+            selectedRanges = sheet.getSelections()
+        ;
+        if (selectedRanges.length > 0) {
+            sheet.deleteRows(selectedRanges[0].row, 1);
+        }
+    },
+    addCol: function (rptTpl) {
+        let me = fieldLocationOprObj,
+            sheet = me.columnWorkBook.getActiveSheet();
+        sheet.suspendPaint();
+        sheet.addColumns(sheet.getColumnCount(), 1);
+        let cellType = new GC.Spread.Sheets.CellTypes.ComboBox();
+        let selectableFields = me.private_getSelectedFields(rptTpl);
+        cellType.items(selectableFields);
+        //设置 最后一行为 行数据选择combobox
+        // sheet.getRange(sheet.getRowCount() - 1, -1, 1, -1).locked(true);
+        let colIdx = sheet.getColumnCount() - 1;
+        sheet.getCell(sheet.getRowCount() - 1, colIdx).cellType(cellType);
+        for (let iRow = 0; iRow < sheet.getRowCount() - 1; iRow++) {
+            me.private_setupCellDft(sheet.getCell(iRow, colIdx));
+        }
+        //
+        me.columnFieldCtrls.push(me.private_create_dft_ctrl());
+        sheet.resumePaint();
+    },
+    deleteCol: function () {
+        let me = fieldLocationOprObj,
+            sheet = me.columnWorkBook.getActiveSheet(),
+            selectedRanges = sheet.getSelections()
+        ;
+        if (selectedRanges.length > 0) {
+            sheet.deleteColumns(selectedRanges[0].col, 1);
+        }
+    },
+    mergeCells: function () {
+        let me = fieldLocationOprObj,
+            sheet = me.columnWorkBook.getActiveSheet();
+        let selectedRanges = sheet.getSelections();
+        if (selectedRanges.length > 0) {
+            if (selectedRanges[0].row + selectedRanges[0].rowCount < sheet.getRowCount()) {
+                sheet.suspendPaint();
+                sheet.addSpan(selectedRanges[0].row, selectedRanges[0].col, selectedRanges[0].rowCount, selectedRanges[0].colCount);
+                sheet.resumePaint();
+            } else {
+                alert("指标列不能被合并!")
+            }
+        }
+    },
+    dismergeCells: function () {
+        let me = fieldLocationOprObj,
+            sheet = me.columnWorkBook.getActiveSheet();
+        let selectedRanges = sheet.getSelections();
+        let spans =sheet.getSpans();
+        if (selectedRanges.length > 0 && spans.length > 0) {
+            let selectedSpans = [];
+            for(let i = 0; i < spans.length; i++)
+            {
+                for (let j = 0; j < selectedRanges.length; j++) {
+                    if (spans[i].row >= selectedRanges[j].row && spans[i].col >= selectedRanges[j].col &&
+                        spans[i].row <= selectedRanges[j].row + selectedRanges[j].rowCount && spans[i].col <= selectedRanges[j].col + selectedRanges[j].colCount) {
+                        selectedSpans.push(spans[i]);
+                    }
+                }
+            }
+            for (let span of selectedSpans) {
+                sheet.removeSpan(span.row, span.col, GC.Spread.Sheets.SheetArea.viewport);
+            }
+        }
+    },
+    fitTheWidth: function (factor) {
+        let me = this, rptTpl = (zTreeOprObj.currentNode)?zTreeOprObj.currentNode.rptTpl:null;
+        let pIdx = JV.PAGES_SIZE_STR.indexOf(rptTpl[JV.NODE_MAIN_INFO][JV.NODE_PAGE_INFO][JV.PROP_PAGE_SIZE]);
+        let bandW = 700;
+        if (pIdx >= 0) {
+            bandW = Math.round(JV.PAGES_SIZE[pIdx][0] * 96 - (parseFloat(rptTpl[JV.NODE_MAIN_INFO][JV.NODE_MARGINS][JV.PROP_LEFT]) + parseFloat(rptTpl[JV.NODE_MAIN_INFO][JV.NODE_MARGINS][JV.PROP_RIGHT])) /2.54*96 );
+            if (rptTpl[JV.NODE_MAIN_INFO][JV.NODE_PAGE_INFO][JV.PROP_ORIENTATION] === JV.ORIENTATION_LANDSCAPE ||
+                rptTpl[JV.NODE_MAIN_INFO][JV.NODE_PAGE_INFO][JV.PROP_ORIENTATION] === JV.ORIENTATION_LANDSCAPE_CHN) {
+                bandW = Math.round(JV.PAGES_SIZE[pIdx][1] * 96 - (parseFloat(rptTpl[JV.NODE_MAIN_INFO][JV.NODE_MARGINS][JV.PROP_LEFT]) + parseFloat(rptTpl[JV.NODE_MAIN_INFO][JV.NODE_MARGINS][JV.PROP_RIGHT])) /2.54*96 );
+            }
+        }
+        bandW *= factor;
+        let currentWidth = 0;
+        let sheet = me.columnWorkBook.getActiveSheet();
+        for (let idx = 0; idx < sheet.getColumnCount(); idx++) {
+            currentWidth += sheet.getColumnWidth(idx);
+        }
+        let actFactor = bandW / currentWidth;
+        for (let idx = 0; idx < sheet.getColumnCount(); idx++) {
+            sheet.setColumnWidth(idx, Math.round(sheet.getColumnWidth(idx) * actFactor));
+        }
+    },
+    changeCtrl: function (dom) {
+        let me = fieldLocationOprObj,
+            sheet = me.columnWorkBook.getActiveSheet(),
+            fieldRowIdx = sheet.getRowCount() - 1
+        ;
+        //sheet.getSelectio
+        let selectedRanges = sheet.getSelections();
+        for(let i = 0; i < selectedRanges.length; i++){
+            if (selectedRanges[i].row === fieldRowIdx) {
+                let ctrl = me.columnFieldCtrls[selectedRanges[i].col]
+                ctrl[JV.CONTROL_PROPS[JV.CONTROL_PROP_IDX_SHRINK]] = 'F';
+                ctrl[JV.CONTROL_PROPS[JV.CONTROL_PROP_IDX_SHOW_ZERO]] = 'F';
+                ctrl[JV.CONTROL_PROPS[JV.CONTROL_PROP_IDX_WRAP]] = 'F';
+                ctrl.isNarrow = false;
+                ctrl.isAutoHeight = false;
+                if ($("#eleShrinkEx")[0].checked) {
+                    ctrl[JV.CONTROL_PROPS[JV.CONTROL_PROP_IDX_SHRINK]] = 'T';
+                }
+                if ($("#eleShowZeroEx")[0].checked) {
+                    ctrl[JV.CONTROL_PROPS[JV.CONTROL_PROP_IDX_SHOW_ZERO]] = 'T';
+                }
+                if ($("#eleAutoWrapEx")[0].checked) {
+                    ctrl[JV.CONTROL_PROPS[JV.CONTROL_PROP_IDX_WRAP]] = 'T';
+                }
+                if ($("#eleIsNarrowEx")[0].checked) {
+                    ctrl.isNarrow = true;
+                }
+                if ($("#eleIsAutoHeightEx")[0].checked) {
+                    ctrl.isAutoHeight = true;
+                }
+
+                if ($("#hOptionLeft")[0].checked) {
+                    ctrl[JV.CONTROL_PROPS[JV.CONTROL_PROP_IDX_HORIZON]] = JV.OUTPUT_ALIGN.H[0];
+                } else if ($("#hOptionCenter")[0].checked) {
+                    ctrl[JV.CONTROL_PROPS[JV.CONTROL_PROP_IDX_HORIZON]] = JV.OUTPUT_ALIGN.H[1];
+                } else {
+                    ctrl[JV.CONTROL_PROPS[JV.CONTROL_PROP_IDX_HORIZON]] = JV.OUTPUT_ALIGN.H[2];
+                }
+                if ($("#vOptionUp")[0].checked) {
+                    ctrl[JV.CONTROL_PROPS[JV.CONTROL_PROP_IDX_VERTICAL]] = JV.OUTPUT_ALIGN.V[0];
+                } else if ($("#vOptionCenter")[0].checked) {
+                    ctrl[JV.CONTROL_PROPS[JV.CONTROL_PROP_IDX_VERTICAL]] = JV.OUTPUT_ALIGN.V[1];
+                } else {
+                    ctrl[JV.CONTROL_PROPS[JV.CONTROL_PROP_IDX_VERTICAL]] = JV.OUTPUT_ALIGN.V[2];
+                }
+            }
+        }
+    },
+    private_update_ctrl_cfg: function (ctrlIdx) {
+        let me = fieldLocationOprObj;
+        if (ctrlIdx >= 0) {
+            if (stringUtil.convertStrToBoolean(me.columnFieldCtrls[ctrlIdx][JV.CONTROL_PROPS[JV.CONTROL_PROP_IDX_SHRINK]])) {
+                $("#eleShrinkEx")[0].checked = true;
+            } else {
+                $("#eleShrinkEx")[0].checked = false;
+            }
+            if (stringUtil.convertStrToBoolean(me.columnFieldCtrls[ctrlIdx][JV.CONTROL_PROPS[JV.CONTROL_PROP_IDX_SHOW_ZERO]])) {
+                $("#eleShowZeroEx")[0].checked = true;
+            } else {
+                $("#eleShowZeroEx")[0].checked = false;
+            }
+            if (stringUtil.convertStrToBoolean(me.columnFieldCtrls[ctrlIdx][JV.CONTROL_PROPS[JV.CONTROL_PROP_IDX_WRAP]])) {
+                $("#eleAutoWrapEx")[0].checked = true;
+            } else {
+                $("#eleAutoWrapEx")[0].checked = false;
+            }
+            if (me.columnFieldCtrls[ctrlIdx].isNarrow) {
+                $("#eleIsNarrowEx")[0].checked = true;
+            } else {
+                $("#eleIsNarrowEx")[0].checked = false;
+            }
+            if (me.columnFieldCtrls[ctrlIdx].isAutoHeight) {
+                $("#eleIsAutoHeightEx")[0].checked = true;
+            } else {
+                $("#eleIsAutoHeightEx")[0].checked = false;
+            }
+            switch (me.columnFieldCtrls[ctrlIdx][JV.CONTROL_PROPS[JV.CONTROL_PROP_IDX_HORIZON]]) {
+                case JV.OUTPUT_ALIGN.H[0]:
+                    $("#hOptionLeft")[0].checked = `true`;
+                    break;
+                case JV.OUTPUT_ALIGN.H[1]:
+                    $("#hOptionCenter")[0].checked = `true`;
+                    break;
+                default:
+                    $("#hOptionRight")[0].checked = `true`;
+                    break;
+            }
+            switch (me.columnFieldCtrls[ctrlIdx][JV.CONTROL_PROPS[JV.CONTROL_PROP_IDX_VERTICAL]]) {
+                case JV.OUTPUT_ALIGN.V[0]:
+                    $("#vOptionUp")[0].checked = `true`;
+                    break;
+                case JV.OUTPUT_ALIGN.V[1]:
+                    $("#vOptionCenter")[0].checked = `true`;
+                    break;
+                default:
+                    $("#vOptionDown")[0].checked = `true`;
+                    break;
+            }
+        }
+    },
+    private_create_dft_ctrl: function () {
+        return {"Shrink" : "T", "ShowZero" : "T", "Horizon": "left", "Vertical": "bottom", "Wrap": "F", "isNarrow": false, "isAutoHeight": false };
+    },
+    private_merge_ctrl: function (rptTpl, srcIdx, fieldNode, directCtrl) {
+        let me = this, ctrl = null;
+        if (directCtrl) {
+            ctrl = directCtrl;
+        } else {
+            if (typeof fieldNode[JV.PROP_CONTROL] === 'string') {
+                let idx = rpt_tpl_cfg_helper.reportCfg.controlArr.indexOf(fieldNode[JV.PROP_CONTROL]);
+                if (idx >= 0) {
+                    ctrl = rpt_tpl_cfg_helper.reportCfg.ctrls[idx];
+                }
+            } else {
+                ctrl = fieldNode[JV.PROP_CONTROL];
+            }
+            for (let font of rpt_tpl_cfg_helper.reportCfg.fonts) {
+                if (font.ID === fieldNode[JV.PROP_FONT]) {
+                    if (font[JV.FONT_PROPS[JV.FONT_PROP_IDX_NAME]].indexOf(`Narrow`) >= 0) {
+                        ctrl.isNarrow = true;
+                    } else {
+                        ctrl.isNarrow = false;
+                    }
+                    break;
+                }
+            }
+            ctrl[JV.PROP_IS_AUTO_HEIGHT] = fieldNode[JV.PROP_IS_AUTO_HEIGHT];
+        }
+        if (ctrl) {
+            me.columnFieldCtrls[srcIdx][JV.CONTROL_PROPS[JV.CONTROL_PROP_IDX_SHRINK]] = ctrl[JV.CONTROL_PROPS[JV.CONTROL_PROP_IDX_SHRINK]];
+            me.columnFieldCtrls[srcIdx][JV.CONTROL_PROPS[JV.CONTROL_PROP_IDX_SHOW_ZERO]] = ctrl[JV.CONTROL_PROPS[JV.CONTROL_PROP_IDX_SHOW_ZERO]];
+            me.columnFieldCtrls[srcIdx][JV.CONTROL_PROPS[JV.CONTROL_PROP_IDX_HORIZON]] = ctrl[JV.CONTROL_PROPS[JV.CONTROL_PROP_IDX_HORIZON]];
+            me.columnFieldCtrls[srcIdx][JV.CONTROL_PROPS[JV.CONTROL_PROP_IDX_VERTICAL]] = ctrl[JV.CONTROL_PROPS[JV.CONTROL_PROP_IDX_VERTICAL]];
+            me.columnFieldCtrls[srcIdx][JV.CONTROL_PROPS[JV.CONTROL_PROP_IDX_WRAP]] = ctrl[JV.CONTROL_PROPS[JV.CONTROL_PROP_IDX_WRAP]];
+            me.columnFieldCtrls[srcIdx].isNarrow = ctrl.isNarrow;
+            me.columnFieldCtrls[srcIdx][JV.PROP_IS_AUTO_HEIGHT] = ctrl[JV.PROP_IS_AUTO_HEIGHT];
+        }
+    },
+    private_setup_control_options: function (enable) {
+        if (enable) {
+            $("#fieldControlDiv")[0].style.cursor = "";
+            $("#hOptionLeft")[0].removeAttribute("disabled");
+            $("#hOptionCenter")[0].removeAttribute("disabled");
+            $("#hOptionRight")[0].removeAttribute("disabled");
+            $("#vOptionUp")[0].removeAttribute("disabled");
+            $("#vOptionCenter")[0].removeAttribute("disabled");
+            $("#vOptionDown")[0].removeAttribute("disabled");
+            $("#eleShrinkEx")[0].removeAttribute("disabled");
+            $("#eleShowZeroEx")[0].removeAttribute("disabled");
+            $("#eleAutoWrapEx")[0].removeAttribute("disabled");
+            $("#eleIsNarrowEx")[0].removeAttribute("disabled");
+            $("#eleIsAutoHeightEx")[0].removeAttribute("disabled");
+        } else {
+            $("#fieldControlDiv")[0].style.cursor = "not-allowed";
+            $("#hOptionLeft")[0].disabled = "disabled" ;
+            $("#hOptionCenter")[0].disabled = "disabled" ;
+            $("#hOptionRight")[0].disabled = "disabled" ;
+            $("#vOptionUp")[0].disabled = "disabled" ;
+            $("#vOptionCenter")[0].disabled = "disabled" ;
+            $("#vOptionDown")[0].disabled = "disabled" ;
+            $("#eleShrinkEx")[0].disabled = "disabled" ;
+            $("#eleShowZeroEx")[0].disabled = "disabled" ;
+            $("#eleAutoWrapEx")[0].disabled = "disabled" ;
+            $("#eleIsNarrowEx")[0].disabled = "disabled" ;
+            $("#eleIsAutoHeightEx")[0].disabled = "disabled" ;
+        }
+    },
+    private_getSelectedFields: function (rptTpl) {
+        let rst = [];
+        if (rptTpl[JV.NODE_FIELD_MAP][JV.NODE_DETAIL_FIELDS] !== undefined && rptTpl[JV.NODE_FIELD_MAP][JV.NODE_DETAIL_FIELDS].length > 0) {
+            for (let field of rptTpl[JV.NODE_FIELD_MAP][JV.NODE_DETAIL_FIELDS]) {
+                rst.push(field[JV.PROP_NAME]);
+            }
+        }
+        if (rptTpl[JV.NODE_NO_MAPPING_FIELDS] !== undefined && rptTpl[JV.NODE_NO_MAPPING_FIELDS].length > 0) {
+            for (let field of rptTpl[JV.NODE_NO_MAPPING_FIELDS]) {
+                rst.push(field[JV.PROP_NAME]);
+            }
+        }
+        return rst;
+    },
+    private_setupCell: function (cell, rptTpl, textNode) {
+        let me = this;
+        me.private_setCellFont(cell, textNode);
+        me.private_setCellControl(cell, textNode);
+        me.private_setCellStyle(cell, textNode);
+        let value = textNode[JV.PROP_NAME];
+        if (textNode[JV.PROP_NAME].indexOf(`|`) >= 0) {
+            value = textNode[JV.PROP_NAME].split('|').join('\n');
+        }
+        cell.wordWrap(true);
+        cell.value(value);
+    },
+    private_setupCellDft: function (cell) {
+        cell.font(`9pt 宋体`);
+        cell.hAlign(GC.Spread.Sheets.HorizontalAlign.center);
+        cell.vAlign(GC.Spread.Sheets.VerticalAlign.center);
+        cell.wordWrap(true);
+        cell.value(``);
+    },
+    private_setCellControl: function (cell, textNode) {
+        let ctrl = null;
+        if (typeof textNode[JV.PROP_CONTROL] === 'string') {
+            let idx = rpt_tpl_cfg_helper.reportCfg.controlArr.indexOf(textNode[JV.PROP_CONTROL]);
+            ctrl = rpt_tpl_cfg_helper.reportCfg.ctrls[idx];
+        } else {
+            ctrl = textNode[JV.PROP_CONTROL];
+        }
+        if (ctrl) {
+            switch (ctrl.Horizon) {
+                case `center`:
+                    cell.hAlign(GC.Spread.Sheets.HorizontalAlign.center);
+                    break;
+                case `right`:
+                    cell.hAlign(GC.Spread.Sheets.HorizontalAlign.right);
+                    break;
+                default:
+                    cell.hAlign(GC.Spread.Sheets.HorizontalAlign.left);
+                    break;
+            }
+            switch (ctrl.Vertical) {
+                case `center`:
+                    cell.vAlign(GC.Spread.Sheets.VerticalAlign.center);
+                    break;
+                case `bottom`:
+                    cell.vAlign(GC.Spread.Sheets.VerticalAlign.bottom);
+                    break;
+                default:
+                    cell.vAlign(GC.Spread.Sheets.VerticalAlign.top);
+                    break;
+            }
+        }
+    },
+    private_setCellStyle: function (cell, textNode) {
+        //默认是normal,暂时不管
+    },
+    private_setCellFont: function (cell, textNode) {
+        for (let font of rpt_tpl_cfg_helper.reportCfg.fonts) {
+            if (font.ID === textNode[JV.PROP_FONT]) {
+                cell.font(Math.round(font[JV.FONT_PROPS[JV.FONT_PROP_IDX_HEIGHT]] * 3 / 4) + 'pt ' + font[JV.FONT_PROPS[JV.FONT_PROP_IDX_NAME]]);
+                break;
+            }
+        }
+    },
+    private_getActPos: function (textNode, caclStr, typeStr, baseMea) {
+        let rst = 0;
+        if (caclStr === JV.CAL_TYPE[0]) {
+            //percentage
+            rst = Math.round(baseMea * textNode[JV.PROP_AREA][typeStr] / 100);
+        } else {
+            //abstract
+            rst = Math.round(textNode[JV.PROP_AREA][typeStr] / 2.54 * 96);
+        }
+        return rst;
+    },
+    private_getActPosEx: function (textNode, caclObj, typeStr, baseMea) {
+        let me = this;
+        if (typeof caclObj === 'string') {
+            return me.private_getActPos(textNode, caclObj, typeStr, baseMea);
+        } else {
+            return me.private_getActPos(textNode, caclObj[typeStr], typeStr, baseMea);
+        }
+    },
+    private_pushPos: function (textNode, caclObj, typeStr, baseMea, posArr) {
+        let me = this, pos = me.private_getActPosEx(textNode, caclObj, typeStr, baseMea);
+        if (posArr.indexOf(pos) < 0) posArr.push(pos);
+    },
+    private_create_content_node: function (colWidthArr, cellValue, colIdx, rptTpl) {
+        let me = this;
+        let rst = {"Name": cellValue, "Title": '', "FieldID": -1, "font": "Content", "control": "Column", "style" : "Default_Normal", "isAutoHeight" : false,
+            "area" : {"Left" : 0, "Right" : 100, "Top" : 0, "Bottom" : 100, "H_CalculationType" : "percentage", "V_CalculationType" : "percentage"}
+        };
+        //1. 设置FieldID
+        let hasChkField = false;
+        if (rptTpl[JV.NODE_FIELD_MAP][JV.NODE_DETAIL_FIELDS] !== undefined && rptTpl[JV.NODE_FIELD_MAP][JV.NODE_DETAIL_FIELDS].length > 0) {
+            for (let field of rptTpl[JV.NODE_FIELD_MAP][JV.NODE_DETAIL_FIELDS]) {
+                if (field[JV.PROP_NAME] === cellValue) {
+                    rst.FieldID = field[JV.PROP_ID];
+                    rst["Title"] = "ID: " + field[JV.PROP_ID];
+                    hasChkField = true;
+                    break;
+                }
+            }
+        }
+        if (!hasChkField && rptTpl[JV.NODE_NO_MAPPING_FIELDS] !== undefined && rptTpl[JV.NODE_NO_MAPPING_FIELDS].length > 0) {
+            for (let field of rptTpl[JV.NODE_NO_MAPPING_FIELDS]) {
+                if (field[JV.PROP_NAME] === cellValue) {
+                    rst.FieldID = field[JV.PROP_ID];
+                    rst["Title"] = "ID: " + field[JV.PROP_ID];
+                    hasChkField = true;
+                    break;
+                }
+            }
+        }
+        //2. 字体
+        if (me.columnFieldCtrls[colIdx].isNarrow) {
+            rst[JV.PROP_FONT] = "Content_Narrow";
+        }
+        //3. 自动行高
+        if (me.columnFieldCtrls[colIdx][JV.PROP_IS_AUTO_HEIGHT]) {
+            rst[JV.PROP_IS_AUTO_HEIGHT] = true;
+        }
+        //4. 左右位置%
+        let width = colWidthArr[colWidthArr.length - 1];
+        if (colIdx > 0) {
+            rst[JV.PROP_AREA][JV.PROP_LEFT] = (colWidthArr[colIdx - 1] / width * 100).toFixed(2);
+        }
+        rst[JV.PROP_AREA][JV.PROP_RIGHT] = (colWidthArr[colIdx] / width * 100).toFixed(2);
+        if (me.columnFieldCtrls[colIdx]["Vertical"] === "center") {
+            switch (me.columnFieldCtrls[colIdx]["Horizon"]) {
+                case "left":
+                    rst["control"] = "Column_Left";
+                    break;
+                case "center":
+                    rst["control"] = "Column";
+                    break;
+                default:
+                    rst["control"] = "Column_Right";
+                    break;
+            }
+        } else if (me.columnFieldCtrls[colIdx]["Vertical"] === "bottom") {
+            switch (me.columnFieldCtrls[colIdx]["Horizon"]) {
+                case "left":
+                    rst["control"] = "Content_Left";
+                    break;
+                case "center":
+                    rst["control"] = "Content_Center";
+                    break;
+                default:
+                    rst["control"] = "Content_Right";
+                    break;
+            }
+        }
+        //return {"Shrink" : "T", "ShowZero" : "T", "Horizon": "left", "Vertical": "bottom", "Wrap": "F", "isNarrow": false, "isAutoHeight": false };
+        return rst;
+    },
+
+    applyBack: function () {
+        let me = this;
+        let rptTpl = (zTreeOprObj.currentNode)?zTreeOprObj.currentNode.rptTpl:null;
+        if (rptTpl && me.columnParentNode && me.contentParentNode) {
+            let sheet = me.columnWorkBook.getActiveSheet();
+            if (sheet.getRowCount() > 1 && sheet.getColumnCount() > 0) {
+                let spans= sheet.getSpans();
+                let texts = [], colWidthArr = [], rowHeightArr = [];
+                let private_build_pre_text = function (row, col, rowCount, colCount) {
+                    texts.push({"row": row, "col": col, "rowCount": rowCount, "colCount": colCount, "text": sheet.getValue(row, col)});
+                };
+                let private_chk_in_span = function (row, col) {
+                    let rst = false;
+                    for (let span of spans) {
+                        if (span.row <= row && row < (span.row + span.rowCount) && span.col <= col && col < (span.col + span.colCount)) {
+                            rst = true;
+                            break;
+                        }
+                    }
+                    return rst;
+                };
+                for (let span of spans) {
+                    private_build_pre_text(span.row, span.col, span.rowCount, span.colCount);
+                }
+                for (let iRow = 0; iRow < sheet.getRowCount() - 1; iRow++) {
+                    rowHeightArr.push(sheet.getRowHeight(iRow));
+                    if (iRow > 0) {
+                        rowHeightArr[iRow] = rowHeightArr[iRow] + rowHeightArr[iRow - 1];
+                    }
+                    for (let jCol = 0; jCol < sheet.getColumnCount(); jCol++) {
+                        if (iRow === 0) {
+                            colWidthArr.push(sheet.getColumnWidth(jCol));
+                            if (jCol > 0) {
+                                colWidthArr[jCol] = colWidthArr[jCol] + colWidthArr[jCol - 1];
+                            }
+                        }
+                        if (!private_chk_in_span(iRow, jCol)) {
+                            private_build_pre_text(iRow, jCol, 1, 1);
+                        }
+                    }
+                }
+                texts.sort(function(t1, t2){
+                    if (t1.col === t2.col) {
+                        return t1.row - t2.row;
+                    } else {
+                        return t1.col - t2.col;
+                    }
+                });
+                let nodes = [];
+                let width = colWidthArr[colWidthArr.length - 1], height = rowHeightArr[rowHeightArr.length - 1];
+                //表栏重置
+                //0. 先清除原先所有的column text
+                dataInfoMapTreeOprObj.treeObj.removeChildNodes(me.columnParentNode);
+                //1. 需要重新设置columnBand的高度
+                //2. 重新生成text节点
+                for (let text of texts) {
+                    let node = dataInfoMapTreeOprObj.getDummyTextNode(me.columnParentNode);
+                    node[JV.PROP_AREA][JV.PROP_RIGHT] = (colWidthArr[text.col + text.colCount - 1] / width * 100).toFixed(2);
+                    if (text.col > 0) {
+                        node[JV.PROP_AREA][JV.PROP_LEFT] = (colWidthArr[text.col - 1] / width * 100).toFixed(2);
+                    } else {
+                        node[JV.PROP_AREA][JV.PROP_LEFT] = 0;
+                    }
+                    node[JV.PROP_AREA][JV.PROP_BOTTOM] = (rowHeightArr[text.row + text.rowCount - 1] / height * 100).toFixed(2);
+                    if (text.row > 0) {
+                        node[JV.PROP_AREA][JV.PROP_TOP] = (rowHeightArr[text.row - 1] / height * 100).toFixed(2);
+                    } else {
+                        node[JV.PROP_AREA][JV.PROP_TOP] = 0;
+                    }
+                    node[JV.PROP_NAME] = stringUtil.replaceAll(stringUtil.replaceAll(text[`text`], '\n', '|'), '\r', '');
+                    node[JV.PROP_LABEL] = node[JV.PROP_NAME];
+                    nodes.push(node);
+                }
+                dataInfoMapTreeOprObj.treeObj.addNodes(me.columnParentNode, -1, nodes, true);
+                //内容重置
+                //0. 先清除原先所有的content node
+                dataInfoMapTreeOprObj.treeObj.removeChildNodes(me.contentParentNode);
+                //1. 重新生成节点
+                let contentNodes = [];
+                let contenRowIdx = sheet.getRowCount() - 1;
+                let rptTpl = (zTreeOprObj.currentNode)?zTreeOprObj.currentNode.rptTpl:null;
+                for (let iCol = 0; iCol < sheet.getColumnCount(); iCol++) {
+                    let cellValue = sheet.getValue(contenRowIdx, iCol);
+                    if (!(stringUtil.isEmptyString(cellValue))) {
+                        contentNodes.push(me.private_create_content_node(colWidthArr, cellValue, iCol, rptTpl));
+                    }
+                }
+                dataInfoMapTreeOprObj.treeObj.addNodes(me.contentParentNode, -1, contentNodes, true);
+            }
+        }
+    }
+
+};

+ 8 - 44
web/maintain/report/js/rpt_tpl_main.js

@@ -9,16 +9,14 @@ const
     IDMark_Edit = "_edit",
     IDMark_Remove = "_remove",
     IDMark_Ul = "_ul",
-    IDMark_A = "_a";
+    IDMark_A = "_a",
     //以上的常量是在查找zTree默认生成的dom对象时用到(tID + 后缀)
 
-const NODE_LEVEL_COMPILATION_OLD = 0,
     NODE_LEVEL_COMPILATION_NEW = 1,
     NODE_LEVEL_USER = 0;
 
 let rptTplObj = {
     iniPage: function() {
-        // zTreeOprObj.iniEngineerIdList();
         zTreeOprObj.getCompilationList();
         rpt_tpl_cfg_helper.getReportTplCfg();
         selectableFiledTreeOprObj.iniTree();
@@ -35,11 +33,6 @@ let zTreeOprObj = {
     moveSrcTopNode: null,
     dupTplIds: null,
     hasRefreshedDupRefIds: false,
-    iniEngineerIdList: function() {
-        for (let item of engineeringList) {
-            $("#engineerIds").append("<option value='" + item.value + "'>" + item.name + "</option>");
-        }
-    },
     getCompilationList: function(){
         let me = zTreeOprObj, params = {};
         CommonAjax.postEx("report_tpl_api/getCompilationList", params, 20000, true, function(result){
@@ -186,8 +179,8 @@ let zTreeOprObj = {
             sObj.after(addStr);
             let btn = $("#addBtn_"+treeNode.tId);
             if (btn) btn.bind("click", function(){
-                let rawNode = me.createIniComilationNodeNew();
-                if (!me.chkIfDupCompilationNodeNew(rawNode, treeNode)) {
+                let rawNode = me.createIniComilationNode();
+                if (!me.chkIfDupCompilationNode(rawNode, treeNode)) {
                     rawNode.userId = treeNode.userId;
                     me.addNewNodeEx(rawNode, function(rst){
                         if (rst) {
@@ -289,7 +282,7 @@ let zTreeOprObj = {
         params.doc = rawNode;
         CommonAjax.postEx("report_tpl_api/createTreeRootNode", params, 5000, true, callback, failCallback, null);
     },
-    oncheck: function (event, treeId, treeNode) {
+    onCheck: function (event, treeId, treeNode) {
         let me = zTreeOprObj;
         let topPNode = me.getParentNodeByNodeLevel(treeNode, NODE_LEVEL_COMPILATION_NEW);
         let newTopNode = me.buildRootNodeDoc(topPNode);
@@ -692,23 +685,12 @@ let zTreeOprObj = {
         params.scope = scope;
         CommonAjax.postEx("report_tpl_api/getNewNodeID", params, 5000, true, callback, null, null);
     },
-    chkIfDupCompilationNodeNew: function (rawNode, parentUserNode) {
-        let rst = false;
-        if (parentUserNode.items && parentUserNode.items.length > 0) {
-            for (let node of parentUserNode.items) {
-                if (node.compilationId === rawNode.compilationId && node.userId === rawNode.userId) {
-                    rst = true;
-                    break;
-                }
-            }
-        }
-        return rst;
-    },
     chkIfDupCompilationNode: function (rawNode, parentUserNode) {
         let rst = false;
+        //在新的需求下,只需要检测编办与userId即可,无需工程id
         if (parentUserNode.items && parentUserNode.items.length > 0) {
             for (let node of parentUserNode.items) {
-                if (node.compilationId === rawNode.compilationId && node.engineerId === rawNode.engineerId && node.userId === rawNode.userId) {
+                if (node.compilationId === rawNode.compilationId && node.userId === rawNode.userId) {
                     rst = true;
                     break;
                 }
@@ -716,29 +698,16 @@ let zTreeOprObj = {
         }
         return rst;
     },
-    createIniComilationNodeNew: function() {
-        let rst = {
-            compilationId: $("#compilations").get(0).selectedOptions[0].value,
-            // engineerId: parseInt($("#engineerIds").get(0).selectedOptions[0].value),
-            userId: (userAccount ===  'admin')?("-100"):userID,
-            properties: [],
-            released: true,
-            isDeleted: false,
-            items: [],
-            name: $("#compilations").get(0).selectedOptions[0].innerText
-        };
-        return rst;
-    },
     createIniComilationNode: function() {
+        //在新的需求下,无需工程id
         let rst = {
             compilationId: $("#compilations").get(0).selectedOptions[0].value,
-            engineerId: parseInt($("#engineerIds").get(0).selectedOptions[0].value),
             userId: (userAccount ===  'admin')?("-100"):userID,
             properties: [],
             released: true,
             isDeleted: false,
             items: [],
-            name: $("#compilations").get(0).selectedOptions[0].innerText + $("#engineerIds").get(0).selectedOptions[0].innerText
+            name: $("#compilations").get(0).selectedOptions[0].innerText
         };
         return rst;
     },
@@ -808,11 +777,6 @@ let zTreeOprObj = {
         if (!isCancel) {
             let me = zTreeOprObj;
             if (treeNode.level === 0) {
-                // me.updateTopNodeName(treeNode, true, function(rst){
-                //     if (!(rst)) {
-                //         alert('修改名称请求失败!');
-                //     }
-                // }, null);
                 //因结构变化,已经不允许更改顶节点名字
             } else {
                 let subTopNode = me.getParentNodeByNodeLevel(treeNode, NODE_LEVEL_COMPILATION_NEW + 1);

+ 44 - 41
web/maintain/report/rpt_tpl_detail.html

@@ -1,44 +1,47 @@
-<div class="col-lg-6 p-0">
-    <div class="main-data-top">
-        <ul class="nav nav-tabs tools-bar" role="tablist">
-            <li class="nav-item">
-                <a class="nav-link p-1 active" data-toggle="tab" href="#rpttplinfo" role="tab">模板信息</a>
-            </li>
-            <li class="nav-item">
-                <a class="nav-link p-1" data-toggle="tab" href="#rpttpllayout" role="tab">模板布局</a>
-            </li>
-            <li class="nav-item">
-                <a class="nav-link p-1" data-toggle="tab" href="#rpttplfieldmap" role="tab">指标映射</a>
-            </li>
-            <li class="nav-item">
-                <a class="nav-link p-1" data-toggle="tab" href="#rpttplfieldlocation" role="tab" onclick="dataInfoMapTreeOprObj.iniDataMap();">指标摆放</a>
-            </li>
-            <li class="nav-item">
-                <a class="nav-link p-1" data-toggle="tab" href="#rpt_tpl_pre_handle_tab" role="tab">数据预处理</a>
-            </li>
-            <li class="nav-item">
-                <a class="nav-link p-1" data-toggle="tab" href="#rpttplformula" role="tab">计算式</a>
-            </li>
-            <li class="nav-item">
-                <a class="nav-link p-1" data-toggle="tab" href="#rpttplscripttxt" role="tab">模板JS对象</a>
-            </li>
+<div class="col-lg-12 p-0">
+    <ul class="nav nav-tabs tools-bar" role="tablist">
+        <li class="nav-item">
+            <a class="nav-link p-1 active" data-toggle="tab" href="#rpttplinfo" role="tab">模板信息</a>
+        </li>
+        <li class="nav-item">
+            <a class="nav-link p-1" data-toggle="tab" href="#rpttpllayout" role="tab">模板布局</a>
+        </li>
+        <li class="nav-item">
+            <a class="nav-link p-1" data-toggle="tab" href="#rpttplfieldmap" role="tab">指标映射</a>
+        </li>
+        <li class="nav-item">
+            <a class="nav-link p-1" data-toggle="tab" href="#rpttplfieldlocation" role="tab" onclick="dataInfoMapTreeOprObj.iniDataMap();">指标摆放</a>
+        </li>
+        <li class="nav-item">
+            <a class="nav-link p-1" data-toggle="tab" href="#rpt_tpl_pre_handle_tab" role="tab">数据预处理</a>
+        </li>
+        <li class="nav-item">
+            <a class="nav-link p-1" data-toggle="tab" href="#rpttplformula" role="tab">计算式</a>
+        </li>
+        <li class="nav-item">
+            <a class="nav-link p-1" data-toggle="tab" href="#rpttplscripttxt" role="tab">模板JS对象</a>
+        </li>
+        <li class="nav-item">
+            <a class="nav-link p-1" data-toggle="tab" href="#rpt_preview_tab" role="tab" onclick="preview_util.getPreviewPage($('#tplCanvas')[0], zTreeOprObj.getRefTpl());">预览</a>
+        </li>
 
-        </ul>
-        <div class="tab-content">
-            <!--模板信息-->
-            <%include ./rpt_tpl_detail_info.html %>
-            <!--模板布局-->
-            <%include ./rpt_tpl_detail_bands.html %>
-            <!--指标映射-->
-            <%include ./rpt_tpl_detail_mapping_fields.html %>
-            <!--指标摆放-->
-            <%include ./rpt_tpl_detail_field_location.html %>
-            <!--报表数据预处理-->
-            <%include ./rpt_tpl_detail_pre_handle.html %>
-            <!--计算式-->
-            <%include ./rpt_tpl_detail_calculation.html %>
-            <!--java script 对象-->
-            <%include ./rpt_tpl_script_text.html %>
-        </div>
+    </ul>
+    <div class="tab-content">
+        <!--模板信息-->
+        <%include ./rpt_tpl_detail_info.html %>
+        <!--模板布局-->
+        <%include ./rpt_tpl_detail_bands.html %>
+        <!--指标映射-->
+        <%include ./rpt_tpl_detail_mapping_fields.html %>
+        <!--指标摆放-->
+        <%include ./rpt_tpl_detail_field_location.html %>
+        <!--报表数据预处理-->
+        <%include ./rpt_tpl_detail_pre_handle.html %>
+        <!--计算式-->
+        <%include ./rpt_tpl_detail_calculation.html %>
+        <!--java script 对象-->
+        <%include ./rpt_tpl_script_text.html %>
+        <!--预览-->
+        <%include ./rpt_tpl_preview.html %>
     </div>
 </div>

+ 51 - 3
web/maintain/report/rpt_tpl_detail_field_location.html

@@ -2,12 +2,12 @@
     <div class="main-data">
         <div class="p-3">
             <div class="row">
-                <div class="form-group col-md-8" style="max-height: 410px;">
-                    <div class="ztree-warp" style="height: 410px;">
+                <div class="form-group col-md-5" style="max-height: 310px;">
+                    <div class="ztree-warp" style="height: 300px;">
                         <ul id="tpl_data_info_reversed" class="ztree"></ul>
                     </div>
                 </div>
-                <div class="form-group col-md-4" style="max-height: 410px;">
+                <!--
                     <div class="tab-bar">
                         <div class="form-group">
                             <div class="ztree-warp" style="height: 130px;">
@@ -19,6 +19,16 @@
                             </div>
                         </div>
                     </div>
+                -->
+                <div class="form-group col-md-4" style="max-height: 410px;">
+                    <div class="ztree-warp" style="height: 300px;">
+                        <ul id="tpl_data_selected_field_map_reversed" class="ztree"></ul>
+                    </div>
+                </div>
+                <div class="form-group col-md-3" style="max-height: 310px;">
+                    <div class="ztree-warp" style="height: 300px;">
+                        <ul id="tpl_discrete_fields_params_reversed" class="ztree"></ul>
+                    </div>
                 </div>
             </div>
             <div class="row" id="element_font">
@@ -166,6 +176,44 @@
                     <input class="form-control" id="eleDftValue" value="" onkeyup="rpt_tpl_cfg_helper.changeDftValue(this)">
                 </div>
             </div>
+            <div class="row" id="element_visual_div" style="display: none">
+                <div class="input-group col-12">
+                    <div style="width:97%; height: 300px;">
+                        <h5>表栏</h5>
+                        <button class="btn btn-primary btn-sm" onclick="fieldLocationOprObj.applyBack()">应用</button>
+                        <button class="btn btn-primary btn-sm" onclick="fieldLocationOprObj.addCol((zTreeOprObj.currentNode)?zTreeOprObj.currentNode.rptTpl:null)">新增列</button>
+                        <button class="btn btn-primary btn-sm" onclick="fieldLocationOprObj.deleteCol()">删除列</button>
+                        <button class="btn btn-primary btn-sm" onclick="fieldLocationOprObj.addRow()">新增行</button>
+                        <button class="btn btn-primary btn-sm" onclick="fieldLocationOprObj.deleteRow()">删除行</button>
+                        <button class="btn btn-primary btn-sm" onclick="fieldLocationOprObj.mergeCells()">合并单元格</button>
+                        <button class="btn btn-primary btn-sm" onclick="fieldLocationOprObj.dismergeCells()">拆解单元格</button>
+                        <button class="btn btn-primary btn-sm" onclick="fieldLocationOprObj.fitTheWidth(1.0)">X 1.0</button>
+                        <button class="btn btn-primary btn-sm" onclick="fieldLocationOprObj.fitTheWidth(1.5)">X 1.5</button>
+                        <button class="btn btn-primary btn-sm" onclick="fieldLocationOprObj.fitTheWidth(2.0)">X 2.0</button>
+                        <div class='row p-3' id="fieldControlDiv" style="cursor: not-allowed">
+                            <div class="form-group col-md-2">
+                                <label ><input type="radio" name="horizonOptions" id="hOptionLeft" onchange="fieldLocationOprObj.changeCtrl(this)" checked="true" disabled>左</label>&nbsp&nbsp
+                                <label ><input type="radio" name="horizonOptions" id="hOptionCenter" onchange="fieldLocationOprObj.changeCtrl(this)" disabled>中</label>&nbsp&nbsp
+                                <label ><input type="radio" name="horizonOptions" id="hOptionRight" onchange="fieldLocationOprObj.changeCtrl(this)" disabled>右</label>
+                            </div>
+                            <div class="form-group col-md-2">
+                                <label style="display:none" ><input type="radio" name="verticalOptions" id="vOptionUp" onchange="fieldLocationOprObj.changeCtrl(this)" disabled>上</label>&nbsp&nbsp
+                                <label ><input type="radio" name="verticalOptions" id="vOptionCenter" onchange="fieldLocationOprObj.changeCtrl(this)" checked="true" disabled>中</label>&nbsp&nbsp
+                                <label ><input type="radio" name="verticalOptions" id="vOptionDown" onchange="fieldLocationOprObj.changeCtrl(this)" disabled>下</label>
+                            </div>
+                            <div class="form-group col-md-4">
+                                <label style="display:none" class="form-check-label"><input type="checkbox" class="form-check-input" id="eleShrinkEx" onchange="fieldLocationOprObj.changeCtrl(this)" disabled>自动缩放</label>&nbsp&nbsp
+                                <label style="display:none" class="form-check-label"><input type="checkbox" class="form-check-input" id="eleShowZeroEx" onchange="fieldLocationOprObj.changeCtrl(this)" disabled>显示0</label>&nbsp&nbsp
+                                <label style="display:none" class="form-check-label"><input type="checkbox" class="form-check-input" id="eleAutoWrapEx" onchange="fieldLocationOprObj.changeCtrl(this)" disabled>自动折行</label>&nbsp&nbsp
+                                <label class="form-check-label"><input type="checkbox" class="form-check-input" id="eleIsNarrowEx" onchange="fieldLocationOprObj.changeCtrl(this)" disabled>窄体</label>
+                                <label class="form-check-label"><input type="checkbox" class="form-check-input" id="eleIsAutoHeightEx" onchange="fieldLocationOprObj.changeCtrl(this)" disabled>自动行高</label>
+                            </div>
+
+                        </div>
+                        <div id="rptTplColumnWorkbook"></div>
+                    </div>
+                </div>
+            </div>
         </div>
     </div>
 </div>

+ 13 - 21
web/maintain/report/rpt_tpl_main.html

@@ -13,6 +13,8 @@
     -->
     <link rel="stylesheet" href="/web/maintain/report/css/main.css">
     <link rel="stylesheet" href="/lib/font-awesome/font-awesome.min.css">
+    <!--spread-->
+    <link rel="stylesheet" href="/lib/spreadjs/sheets/css/gc.spread.sheets.sc.css">
     <!--zTree-->
     <link rel="stylesheet" href="/lib/ztree/css/zTreeStyle.css" type="text/css">
     <style type="text/css">
@@ -24,8 +26,8 @@
     </style>
     <script>
         // 这里的变量供页面调用
-        var userAccount = '<%- userAccount %>';
-        var userID = '<%- userID %>';
+        let userAccount = '<%- userAccount %>';
+        let userID = '<%- userID %>';
     </script>
 </head>
 
@@ -35,16 +37,10 @@
             <span class="header-logo px-2">Smartcost</span>
             <div class="navbar-text"><a>报表模板库</a> > <a id="rpt_tpl_display_label">...</a></div>
         </nav>
-        <nav class="navbar navbar-toggleable-lg navbar-light p-0">
+        <nav class="navbar navbar-toggleable-lg justify-content-between navbar-light p-0">
             <div>
             <ul class="nav nav-tabs" role="tablist">
                 <li class="nav-item">
-                    <a class="nav-link px-3" href="#"><i class="fa fa-sign-out fa-flip-horizontal" aria-hidden="true"></i></a>
-                </li>
-                <li class="nav-item">
-                    <a class="nav-link px-3" href="#"><i class="fa fa-sign-out" aria-hidden="true"></i></a>
-                </li>
-                <li class="nav-item">
                     <a class="nav-link px-3" ><select class="form-control form-control-sm" id="compilations" onchange="zTreeOprObj.getReportTemplateTree(this)"></select></a>
                 </li>
                 <li class="nav-item" style="display:none">
@@ -53,17 +49,11 @@
             </ul>
             </div>
             <!--
-            <div class="btn-group">
-                <div class="input-group">
-                    <input type="text" class="form-control input-sm" id="rpt_user_input" placeholder="手机/邮箱/姓名/公司" list="users_list">
-                    <datalist id=users_list>
-                    </datalist>
-                    <span class="input-group-btn">
-                        <button class="btn btn-primary" id="rpt_user_find_btn" onclick="userListObj.findUser()">查询</button>
-                    </span>
-                </div>
-            </div>
             -->
+            <div class="p-2">
+                <label id="id_after_saved_lbl" style="color:yellowgreen;font-weight:bold">...</label>
+                <button class="btn btn-primary btn-sm" onclick="tplHelper.saveRptTpl()">保存</button>
+            </div>
         </nav>
     </div>
     <div class="main">
@@ -78,8 +68,6 @@
                             <div class="row">
                                 <!-- 报表设置 -->
                                 <%include ./rpt_tpl_detail.html %>
-                                <!-- 报表预览 -->
-                                <%include ./rpt_tpl_preview.html %>
                             </div>
                         </div>
                     </div>
@@ -90,6 +78,9 @@
     <!--弹出新建模板-->
     <%include ./rpt_tpl_popup.html %>
     <!-- JS. -->
+
+    <script src="/lib/spreadjs/sheets/gc.spread.sheets.all.11.1.2.min.js"></script>
+    <script>GC.Spread.Sheets.LicenseKey =  '<%- LicenseKey %>';</script>
     <script src="/lib/jquery/jquery.min.js"></script>
     <script src="/lib/tether/tether.min.js"></script>
     <script src="/lib/bootstrap/bootstrap.min.js"></script>
@@ -101,6 +92,7 @@
     <script src="/web/maintain/report/js/rpt_tpl_calculation.js"></script>
     <script src="/web/maintain/report/js/rpt_tpl_helper.js"></script>
     <script src="/web/maintain/report/js/rpt_tpl_data_map.js"></script>
+    <script src="/web/maintain/report/js/rpt_tpl_field_location.js"></script>
     <script src="/web/maintain/report/js/rpt_tpl_pre_handle.js"></script>
     <script src="/web/maintain/report/js/cfg_const.js"></script>
     <script src="/web/maintain/report/js/rpt_tpl_preview_util.js"></script>

+ 3 - 10
web/maintain/report/rpt_tpl_preview.html

@@ -1,12 +1,5 @@
-<div class="form-view col-lg-6 p-0">
-    <div class="main-data-h" style="position:relative">
-        <div class="sub-button p-2">
-            <button class="btn btn-primary" onclick="tplHelper.saveRptTpl()">保存</button>
-            <button class="btn btn-primary" onclick="preview_util.getPreviewPage($('#tplCanvas')[0], zTreeOprObj.getRefTpl()) ">预览</button>
-            <label id="id_after_saved_lbl" style="color:yellowgreen;font-weight:bold">...</label>
-        </div>
-        <div class="main-data">
-            <canvas id="tplCanvas" height="800" width="900"></canvas>
-        </div>
+<div class="tab-pane" id="rpt_preview_tab" role="tabpanel">
+    <div class="main-data">
+        <canvas id="tplCanvas" height="800" width="900"></canvas>
     </div>
 </div>

+ 7 - 8
web/maintain/report/rpt_tpl_tree.html

@@ -1,12 +1,11 @@
-<div class="sub-button p-1">
-    <div class="input-group">
-        <input type="text" class="form-control input-sm" id="rpt_user_input1" placeholder="姓名/手机/邮箱/公司" list="users_list1">
-        <datalist id=users_list1>
-        </datalist>
+<div class="tab-bar">
+    <div class="input-group input-group-sm">
+        <input type="text" class="form-control" id="rpt_user_input1" placeholder="姓名/手机/邮箱/公司">
         <span class="input-group-btn">
-            <button class="btn btn-primary" id="rpt_user_find_btn1" onclick="userListObj.findUser()">查询</button>
+            <button class="btn btn-primary" id="rpt_user_find_btn1" type="button" onclick="userListObj.findUser()">查询</button>
         </span>
     </div>
-    <label> </label>
-    <ul id="rptTplTree" class="ztree"></ul>
+</div>
+<div class="tab-content">
+    <ul id="rptTplTree" class="ztree" style="-moz-user-select: none;"></ul>
 </div>

+ 7 - 8
web/users/js/col_setting.js

@@ -321,22 +321,21 @@ $('#set-column').on('shown.bs.modal', function () {
     }
 });
 
-$('#set-glj-col').on('show.bs.modal', function () {
+$('#other_setting').on('show.bs.modal', function () {
     let glj_col_setting = JSON.parse($("#glj_col").val());
-    if(glj_col_setting.showAdjustPrice){
-        $('#adjustPrice_cb').prop('checked',true);
-    }else {
-        $('#adjustPrice_cb').prop('checked',false);
-    }
+    glj_col_setting.showAdjustPrice?$('#adjustPrice_cb').prop('checked',true): $('#adjustPrice_cb').prop('checked',false);
+    let isInstall = $("#isInstall").val() == 'true'?true:false;
+    $('#isInstall_cb').prop('checked',isInstall);
 });
 
-$('#set-glj-comf').click(function () {
-
+$('#other_setting_comf').click(function () {
     let showAdjustPrice =  $('#adjustPrice_cb').prop('checked');
+    let isInstall =  $('#isInstall_cb').prop('checked');
     let glj_col_setting = {
         showAdjustPrice :showAdjustPrice
     };
     $("#glj_col").val(JSON.stringify(glj_col_setting));
+    $("#isInstall").val(isInstall);
 });
 
 $('#col-count').change(function () {

+ 9 - 5
web/users/js/compilation.js

@@ -645,13 +645,17 @@ function confirmUpdate(selector,engineerID) {
      inputDiv.hide();
 }
 
-function deleteEngineerClick(engineerID) {
+function deleteEngineerClick(engineerID,element) {
     console.log(engineerID);
+    console.log(element);
     hintBox.infoBox('操作确认', '是否删除所选工程专业?', 2, async function () {
-        console.log(engineerID+'删除')
-    }, function () {
-        console.log('取消')
-    },['确定','取消'],false);
+        try {
+            let result  = await ajaxPost('/compilation/delete-engineer',{id:engineerID});
+            $(element).parent("td").parent("tr").remove();
+        }catch (err){
+            console.log(err);
+        }
+    }, null,['确定','取消'],false);
 }
 
 

+ 1 - 1
web/users/views/compilation/add.html

@@ -77,7 +77,7 @@
                                     <td><%= engineering.ration_lib.length %></td>
                                     <td><%= engineering.glj_lib.length %></td>
                                     <td><label><input type="checkbox"  <% if (engineering.visible) { %>checked<% } %>  onclick='engineerVisibleChange(this,"<%= engineering._id.toString()%>")'> 显示</label></td>
-                                    <td><a class="btn-link" href="/compilation/<%= section %>/<%= valuationId %>/<%= engineering._id.toString()%>">编辑</a>/<a onclick="deleteEngineerClick('<%= engineering._id.toString()%>')" class='btn btn-link btn-sm' style="padding: 0px">删除</a></td>
+                                    <td><a class="btn-link" href="/compilation/<%= section %>/<%= valuationId %>/<%= engineering._id.toString()%>">编辑</a>/<a onclick="deleteEngineerClick('<%= engineering._id.toString()%>',this)" class='btn btn-link btn-sm' style="padding: 0px">删除</a></td>
                                 </tr>
                                 <% }) %>
                             </tbody>

+ 2 - 1
web/users/views/compilation/engineering.html

@@ -125,7 +125,7 @@
                             </div>
                     </div>
                     <div class="col-md-12">
-                        <a data-toggle="modal" data-target="#set-glj-col" class="btn btn-primary btn-sm " style="margin-right:5px">人材机列</a>
+                        <a data-toggle="modal" data-target="#other_setting" class="btn btn-primary btn-sm " style="margin-right:5px">显示设置</a>
                     </div>
                     <div class="col-md-12" style="padding-top:20px">
                         <legend>计算程序/清单模板/列设置</legend>
@@ -183,6 +183,7 @@
                     </div>
                 </div>
                 <input type="hidden" name="glj_col" value="<%= gljCol %>" id="glj_col">
+                <input type="hidden" name="isInstall" value="<%= libData.isInstall %>" id="isInstall">
                 <input type="hidden" name="engineering" value="<%= libData.engineering %>" id="engineering">
                 <input type="hidden" name="section" value="<%= section %>" id="section">
                 <input type="hidden" name="id" value="<%= libData._id.toString()%>">

+ 11 - 4
web/users/views/compilation/modal.html

@@ -204,13 +204,13 @@
     </div>
 </div>
 
-<!-- 弹窗人材机列设置 -->
-<div class="modal fade" id="set-glj-col" tabindex="-1" role="dialog">
+<!-- 弹窗工程专业其它设置 -->
+<div class="modal fade" id="other_setting" tabindex="-1" role="dialog">
     <div class="modal-dialog " role="document">
         <div class="modal-content">
             <div class="modal-header">
                 <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
-                <h4 class="modal-title" id="glj_tit">人材机列设置</h4>
+                <h4 class="modal-title" id="glj_tit">显示设置</h4>
             </div>
             <div class="modal-body">
                 <div class="row">
@@ -221,11 +221,18 @@
                             </label>
                         </div>
                     </div>
+                    <div class="col-md-12">
+                        <div class="checkbox">
+                            <label>
+                                <input type="checkbox" id="isInstall_cb"> 显示安装增加费
+                            </label>
+                        </div>
+                    </div>
                 </div>
             </div>
             <div class="modal-footer">
                 <button type="button" class="btn btn-default" data-dismiss="modal">关闭</button>
-                <button type="button" class="btn btn-primary" data-dismiss="modal" id = "set-glj-comf">确定</button>
+                <button type="button" class="btn btn-primary" data-dismiss="modal" id = "other_setting_comf">确定</button>
             </div>
         </div>
     </div>