/**
 * 块模板库管理。
 * Created by CSL on 2018-09-19.
 */
var blockLibObj = {
    // libs: [],
    activeLib: null,
    mainSpread: null,
    mainSheet: null,
    mainTree: null,
    mainTreeController: null,
    mainSetting: {
        "emptyRowHeader": true,
        "rowHeaderWidth": 15,
        "emptyRows":0,
        "headRows":1,
        "headRowHeight":[30],
        "defaultRowHeight": 21,
        "treeCol": 9,
        "cols":[{
            "width":400,
            "readOnly": true,
            "head":{
                "titleNames":["名称"],
                "spanCols":[1],
                "spanRows":[1],
                "vAlign":[1],
                "hAlign":[1],
                "font":["Arial"]
            },
            "data":{
                "field":"nodeName",
                "vAlign":1,
                "hAlign":0,
                "font":"Arial"
            }
        }]
    },
    mainDatas: [],
    billSpread: null,
    billSheet: null,
    billSetting: {
        header: [
            {headerName: "项目编码", headerWidth: 90, dataCode: "code", dataType: "String", hAlign: "center"},
            {headerName: "项目名称", headerWidth: 100, dataCode: "name", dataType: "String"},
            {headerName: "单位", headerWidth: 40, dataCode: "unit", dataType: "String", hAlign: "center"},
            {headerName: "综合单价", headerWidth: 70, dataCode: "unitFee", dataType: "Number"},
            {headerName: "项目特征", headerWidth: 160, dataCode: "itemCharacterText", dataType: "String"}
        ],
        view: {
            lockColumns: [0, 1, 2, 3, 4]
        }
    },
    rationSpread: null,
    rationSheet: null,
    rationSetting: {
        header: [
            {headerName: "编码", headerWidth: 50, dataCode: "code", dataType: "String", hAlign: "center"},
            {headerName: "名称", headerWidth: 200, dataCode: "name", dataType: "String"},
            {headerName: "单位", headerWidth: 70, dataCode: "unit", dataType: "String", hAlign: "center"},
            /* {headerName: "含量", headerWidth: 40, dataCode: "contain", dataType: "Number"},
            {headerName: "取费专业", headerWidth: 70, dataCode: "programName", dataType: "String", hAlign: "center"}, */
            {headerName: "综合单价", headerWidth: 70, dataCode: "unitFee", dataType: "Number"},
           //{headerName: "子目换算状态", headerWidth: 90, dataCode: "adjustState", dataType: "String"}
        ],
        view: {
            lockColumns: [0, 1, 2, 3, 4, 5, 6]
        }
    },
    cloneType: null,
    initialShareTip: '',

    buildSheet: async function () {
        $.bootstrapLoading.start();
        let me = this;
        let namesAndLib = await ajaxPost('/blockLib/getLibNamesAndFirstLib',
            {userID: userID, compilationID: projectObj.project.projectInfo.compilation});
        function getLibNamesHtml(libsArr) {
            let result = '';
            for (let lib of libsArr) {
                result += '<option value="' + lib.libID + '">' + lib.libName + '</option>';
            };
            return result;
        };
        let html = getLibNamesHtml(namesAndLib.libNames);
        $("#select_block_lib_names").html(html);
        this.initialShareTip = namesAndLib.shareList && namesAndLib.shareList.length
            ? namesAndLib.shareList.reduce((acc, user) => acc += ` ${user.real_name}`, '已分享给')
            : '';
        $('#btn_block_share').attr('data-original-title', this.initialShareTip);
        await me.loadLib(namesAndLib.firstLib);
        $.bootstrapLoading.end();
    },
    loadLib: async function (lib){
        let me = this;
        if (me.mainSpread) {
            me.mainSpread.destroy();
            me.mainSpread = null;
        };
        if (me.billSpread) {
            me.billSpread.destroy();
            me.billSpread = null;
        };
        if (me.rationSpread) {
            me.rationSpread.destroy();
            me.rationSpread = null;
        };

        me.mainDatas = lib.datas;
        me.activeLib = lib;
        me.mainSpread = SheetDataHelper.createNewSpread($('#div_block_tree')[0]);
        me.mainSheet = me.mainSpread.getSheet(0);
        me.mainSheet.name('blockLibSheet');
        sheetCommonObj.spreadDefaultStyle(me.mainSpread);

        function showBlockTree(datas) {
            me.mainTree = idTree.createNew({id: 'ID', pid: 'ParentID', nid: 'NextSiblingID', rootId: -1, autoUpdate: false});
            me.mainTreeController = TREE_SHEET_CONTROLLER.createNew(me.mainTree, me.mainSheet, me.mainSetting);
            me.mainTree.loadDatas(datas);
            me.mainTreeController.showTreeData();
            me.mainSheet.getRange(-1, 0, -1, 1).cellType(me.getTreeCell(me.mainTree));
            me.mainTree.selected = me.mainTree.items[0];
            me.mainTreeController.bind(TREE_SHEET_CONTROLLER.eventName.treeSelectedChanged, function (node) {
                blockLibObj.loadDetailDatas(node);
            });
        };
        showBlockTree(me.mainDatas);

        /* me.billSpread = sheetCommonObj.buildSheet($('#div_block_bill')[0], me.billSetting, 1);
        me.billSheet = me.billSpread.getSheet(0);
        sheetCommonObj.spreadDefaultStyle(me.billSpread);
        me.billSheet.setColumnWidth(0, 20, GC.Spread.Sheets.SheetArea.rowHeader); */

        me.rationSpread = sheetCommonObj.buildSheet($('#div_block_ration')[0], me.rationSetting, 1);
        me.rationSheet = me.rationSpread.getSheet(0);
        sheetCommonObj.spreadDefaultStyle(me.rationSpread);
        me.rationSheet.setColumnWidth(0, 20, GC.Spread.Sheets.SheetArea.rowHeader);

        me.loadTreeContextMenu();

        me.mainSpread.bind(GC.Spread.Sheets.Events.EnterCell, me.onEnterCell);
        me.mainSpread.bind(GC.Spread.Sheets.Events.CellDoubleClick, this.onCellDoubleClick);
    },
    loadDetailDatas: function (node){
        let me = this;
        if (!node) return;
        if (node.data.type == 2){
            let bill = node.data;
            let rations = bill.children;
            //sheetCommonObj.showData(me.billSheet, me.billSetting, [bill]);
            let rCount = (rations.length > 0) ? rations.length : 1;
            me.rationSheet.setRowCount(rCount, GC.Spread.Sheets.SheetArea.viewport);
            sheetCommonObj.showData(me.rationSheet, me.rationSetting, rations);
        }
        else{
            //sheetCommonObj.cleanSheet(me.billSheet, me.billSetting, 1);
            sheetCommonObj.cleanSheet(me.rationSheet, me.rationSetting, 1);
        }
    },
    getTreeCell: function (tree) {
        let me = this;
        let indent = 20, levelIndent = -5, halfBoxLength = 5, halfExpandLength = 3, imgWidth = 14, imgHeight = 14;
        let TreeCell = function () {};
        TreeCell.prototype = new GC.Spread.Sheets.CellTypes.Text();
        TreeCell.prototype.paint = function (ctx, value, x, y, w, h, style, options) {
            if (style.backColor) {
                ctx.save();
                ctx.fillStyle = style.backColor;
                ctx.fillRect(x, y, w, h);
                ctx.restore();
            } else {
                ctx.clearRect(x, y, w, h);
            };

            let drawLine = function (canvas, x1, y1, x2, y2, color) {
                ctx.save();
                ctx.translate(0.5, 0.5);
                ctx.beginPath();
                ctx.moveTo(x1, y1);
                ctx.lineTo(x2, y2);
                ctx.strokeStyle = color;
                ctx.stroke();
                ctx.restore();
            };
            let drawExpandBox = function (ctx, x, y, w, h, centerX, centerY, expanded) {
                let rect = {}, h1, h2, offset = 1;
                rect.top = centerY - halfBoxLength;
                rect.bottom = centerY + halfBoxLength;
                rect.left = centerX - halfBoxLength;
                rect.right = centerX + halfBoxLength;

                if (rect.left < x + w) {
                    rect.right = Math.min(rect.right, x + w);

                    ctx.save();
                    ctx.translate(0.5, 0.5);
                    ctx.strokeStyle = 'black';
                    ctx.beginPath();
                    ctx.moveTo(rect.left, rect.top);
                    ctx.lineTo(rect.left, rect.bottom);
                    ctx.lineTo(rect.right, rect.bottom);
                    ctx.lineTo(rect.right, rect.top);
                    ctx.lineTo(rect.left, rect.top);
                    ctx.stroke();
                    ctx.fillStyle = 'white';
                    ctx.fill();
                    ctx.restore();

                    // Draw Horizontal Line
                    h1 = centerX - halfExpandLength;
                    h2 = Math.min(centerX + halfExpandLength, x + w);
                    if (h2 > h1) {
                        drawLine(ctx, h1, centerY, h2, centerY, 'black');
                    }
                    // Draw Vertical Line
                    if (!expanded && (centerX < x + w)) {
                        drawLine(ctx, centerX, centerY - halfExpandLength, centerX, centerY + halfExpandLength, 'black');
                    }
                }

            };

            let node = tree.items[options.row];
            if (!node) return;
            let showTreeLine = true;
            let centerX = Math.floor(x) + node.depth() * indent + node.depth() * levelIndent + indent / 2;
            let x1 = centerX + indent / 2;
            let centerY = Math.floor((y + (y + h)) / 2);
            let y1;
            const lineColor = '#ababab';
            // Draw Horizontal Line、Image、sibling Vertical Line
            if (centerX < x + w) {
                // Draw Horizontal Line
                drawLine(ctx, centerX, centerY, Math.min(x1, x + w), centerY, lineColor);

                // Draw Image
                let imgId;
                if (node.data.type === 0) imgId = 'blockLib_pic'
                else if (node.data.type === 1) imgId = 'folder_pic'
                else if (node.data.type === 2) {
                    imgId = 'block_pic';
                };
                let img = document.getElementById(imgId);
                ctx.drawImage(img, centerX+indent/2+3, centerY - 7, imgWidth, imgHeight);

                // Draw Vertical Line
                y1 = node.isLast() ? centerY : y + h;
                if (node.isFirst() && !node.parent/*.parent*/) {
                    drawLine(ctx, centerX, centerY, centerX, y1, lineColor);
                } else {
                    drawLine(ctx, centerX, y, centerX, y1, lineColor);
                }
            }

            // Draw Expand Box
            if (node.children.length > 0) {
                drawExpandBox(ctx, x, y, w, h, centerX, centerY, node.expanded);
            }

            // Draw Parent Line
            var curNode = node.parent, parentCenterX = centerX - indent - levelIndent;
            while (curNode) {
                if (!curNode.isLast()) {
                    if (parentCenterX < x + w) {
                        drawLine(ctx, parentCenterX, y, parentCenterX, y + h, lineColor);
                    }
                }
                curNode = curNode.parent;
                parentCenterX -= (indent + levelIndent);
            }

            // Draw Text
            x = x + (node.depth() + 1) * indent +  node.depth() * levelIndent + imgWidth + 3;
            w = w - (node.depth() + 1) * indent - node.depth() * levelIndent - imgWidth - 3;
            GC.Spread.Sheets.CellTypes.Text.prototype.paint.apply(this, arguments);
        };
        TreeCell.prototype.getHitInfo = function (x, y, cellStyle, cellRect, context) {
            let info = {x: x, y: y, row: context.row, col: context.col, cellStyle: cellStyle, cellRect: cellRect, sheetArea: context.sheetArea};
            let node = tree.items[info.row];
            let offset = -1;
            let centerX = info.cellRect.x + offset + node.depth() * indent + node.depth() * levelIndent + indent / 2;
            let text = context.sheet.getText(info.row, info.col);
            let value = context.sheet.getValue(info.row, info.col);
            let acStyle = context.sheet.getActualStyle(info.row, info.col),
                zoom = context.sheet.zoom();
            let textLength = this.getAutoFitWidth(value, text, acStyle, zoom, {sheet: context.sheet, row: info.row, col: info.col, sheetArea: GC.Spread.Sheets.SheetArea.viewport});
            if(info.x > centerX + halfBoxLength && info.x < centerX + halfBoxLength + imgWidth + indent/2+3 + textLength){
                info.isReservedLocation = true;
            }
            return info;
        };
        TreeCell.prototype.processMouseDown = function (hitinfo) {
            let offset = -1;
            let node = tree.items[hitinfo.row];
            let centerX = hitinfo.cellRect.x + offset + node.depth() * indent + node.depth() * levelIndent + indent / 2;
            let centerY = (hitinfo.cellRect.y + offset + (hitinfo.cellRect.y + offset + hitinfo.cellRect.height)) / 2;
            let text = hitinfo.sheet.getText(hitinfo.row, hitinfo.col);
            let value = hitinfo.sheet.getValue(hitinfo.row, hitinfo.col);
            let acStyle = hitinfo.sheet.getActualStyle(hitinfo.row, hitinfo.col),
                zoom = hitinfo.sheet.zoom();
            let textLength = this.getAutoFitWidth(value, text, acStyle, zoom, {sheet: hitinfo.sheet, row: hitinfo.row, col: hitinfo.col, sheetArea: GC.Spread.Sheets.SheetArea.viewport});
            //(图标+名字)区域
            function withingClickArea(){
                return hitinfo.x > centerX + halfBoxLength && hitinfo.x < centerX + halfBoxLength + imgWidth + indent/2+3 + textLength;
            }

            //方框外1像素内都有效
            if (hitinfo.x >= centerX - halfBoxLength - 2 && hitinfo.x <= centerX + halfBoxLength + 2 &&
                hitinfo.y >= centerY - halfBoxLength - 2 && hitinfo.y <= centerY + halfBoxLength + 2) {
                node.setExpanded(!node.expanded);
                TREE_SHEET_HELPER.massOperationSheet(hitinfo.sheet, function () {
                    let iCount = node.posterityCount(), i, child;
                    for (i = 0; i < iCount; i++) {
                        child = tree.items[hitinfo.row + i + 1];
                        hitinfo.sheet.setRowVisible(hitinfo.row + i + 1, child.visible, hitinfo.sheetArea);
                    }
                    hitinfo.sheet.invalidateLayout();
                });
                hitinfo.sheet.repaint();
            }
        };
        TreeCell.prototype.processMouseMove = function (hitInfo) {
            let sheet = hitInfo.sheet;
            let div = sheet.getParent().getHost();
            let canvasId = div.id + "vp_vp";
/*            let canvas = $(`#${canvasId}`)[0];
            //改变鼠标图案
            if (sheet && hitInfo.isReservedLocation) {
                canvas.style.cursor='pointer';
                return true;
            }else{
                canvas.style.cursor='default';
            }*/
            return false;
        };
        TreeCell.prototype.processMouseEnter = function (hitinfo) {
            let text = hitinfo.sheet.getText(hitinfo.row, hitinfo.col);
            let value = hitinfo.sheet.getValue(hitinfo.row, hitinfo.col);
            let tag = hitinfo.sheet.getTag(hitinfo.row, hitinfo.col);
            let acStyle = hitinfo.sheet.getActualStyle(hitinfo.row, hitinfo.col),
                zoom = hitinfo.sheet.zoom();
            let node = me.mainTree.items[hitinfo.row];
            let nodeIndent = node ? (node.depth() + 1) * indent +  node.depth() * levelIndent + imgWidth + 3 : 0;
            let textLength = this.getAutoFitWidth(value, text, acStyle, zoom, {sheet: hitinfo.sheet, row: hitinfo.row, col: hitinfo.col, sheetArea: GC.Spread.Sheets.SheetArea.viewport});
            let cellWidth = hitinfo.sheet.getCell(-1, hitinfo.col).width();
            if(textLength > cellWidth - nodeIndent){
                TREE_SHEET_HELPER.showTipsDiv(text,{pos: {}},hitinfo);
            }
        };
        TreeCell.prototype.processMouseLeave = function (hitinfo) {
            let me = this;
            TREE_SHEET_HELPER.tipDiv = 'hide';
            if (TREE_SHEET_HELPER._toolTipElement) {
                $(TREE_SHEET_HELPER._toolTipElement).hide();
                TREE_SHEET_HELPER._toolTipElement = null;
            };
            TREE_SHEET_HELPER.tipDivCheck();//延时检查：当tips正在show的时候，就调用了hide方法，会导致tips一直存在，所以设置一个超时处理
        };
        return new TreeCell();
    },
    newNode: async function (nodeType, nodeName, categoryID, source){     // 1 分类(只用前两个参数)  2 块文件
        if (nodeName == '') return;
        let tree = blockLibObj.mainTree;
        let ID = uuid.v1();
        let pID = (nodeType == 2) ? categoryID : -1;
        let nID = -1;

        // 先生成临时结点数据用于提交入库，成功后才生成树结点，并在UI上刷新显示。
        let temp = {};
        temp.data = {
            ID: ID,
            ParentID: pID,
            NextSiblingID: nID,
            libID: blockLibObj.activeLib.libID,
            type: nodeType,
            nodeName: nodeName
        };
        if (nodeType == 2)
            blockLibObj.assignData(temp, source);

        try {
            let obj = {
                libID: blockLibObj.activeLib.libID,
                nodeID: temp.data.ID,
                create: temp.data
            };
            await ajaxPost('/blockLib/saveBlock', obj);
            let newN = tree.insertByID(ID, pID, nID);
            newN.data = temp.data;
            tree.selected = newN;
            let sheet = blockLibObj.mainSheet;
            sheet.suspendPaint();
            sheet.suspendEvent();
            let idx = tree.items.indexOf(newN);
            sheet.addRows(idx, 1);
            sheet.getRange(idx, 0, 1, 1).locked(true);
            sheet.setValue(idx, 0, newN.data.nodeName);
            sheet.setSelection(idx, 0, 1, 1);
            sheet.resumeEvent();
            sheet.resumePaint();
        }
        catch (err) {
            console.log(err.message);
            return;
        };
    },
    assignData: function (block, source){
        block.data.compilationID = source.compilationID;
        block.data.copyTime = source.copyTime;
        block.data.firstNodeType = source.firstNodeType;
        block.data.isFBFX = source.isFBFX;

        let bill = source.datas[0];
        block.data.code = bill.code;
        block.data.name = bill.name;
        block.data.unit = bill.unit;
        block.data.itemCharacterText = bill.itemCharacterText;
        block.data.unitFee = (bill.feesIndex && bill.feesIndex.common) ? bill.feesIndex.common.unitFee : 0;
        block.data.children = bill.children;

        for (let r of bill.children){
            r.unitFee =  (r.feesIndex && r.feesIndex.common) ? r.feesIndex.common.unitFee : 0;
            if (r.programID)
                r.programName = projectObj.project.calcProgram.compiledTemplateMaps[r.programID];
            // delete r.ID;         // 这个不能删！
            delete r.billsItemID;
            delete r.fees;
            delete r.feesIndex;
        };
    },
    reName: async function (node, newName){
        if (newName == '') return;
        let obj = {
            libID: blockLibObj.activeLib.libID,
            nodeID: node.data.ID,
            update: {nodeName: newName}
        };
        await ajaxPost('/blockLib/saveBlock', obj);
        node.data.nodeName = newName;
        let idx = blockLibObj.mainTree.items.indexOf(node);
        blockLibObj.mainSheet.setValue(idx, 0, newName);
    },
    moveBlock: function (parentID) {
        // this.mainTreeController.moveTo(parentID);
    },
    delete: async function () {
        let node = blockLibObj.mainTree.selected;
        let obj = {
            libID: blockLibObj.activeLib.libID,
            nodeID: node.data.ID,
            delete: {nodeType: node.data.type}
        };
        await ajaxPost('/blockLib/saveBlock', obj);
        this.mainTreeController.delete();
    },
    getCategories: function () {
        let nodes = [], node = blockLibObj.mainTree.items[0];
        nodes.push(node);
        while (node.nextSibling != null){
            node = node.nextSibling;
            nodes.push(node);
        };
        return nodes;
    },
    curIsBlock: function () {
        return this.mainTree.selected.data.type == 2;
    },
    curIsCategory: function () {
        return this.mainTree.selected.data.type == 1;
    },
    getSameNameNode: function(name){
        let rst = null;
        let nodes = blockLibObj.mainTree.items;
        for (let i = 0; i < nodes.length; i++) {
            let node = nodes[i];
            if (node.data.nodeName == name){
                rst = node;
                break;
            }
        }
        return rst;
    },
    refreshSpread: function (){
        if (this.mainSpread)
            this.mainSpread.refresh();
        if (this.billSpread)
            this.billSpread.refresh();
        if (this.rationSpread)
            this.rationSpread.refresh();
    },
    loadTreeContextMenu: function (){
        let me = this;
        $.contextMenu({
            selector: '#div_block_tree',
            build: function ($trigger, e) {
                SheetDataHelper.safeRightClickSelection($trigger, e, me.mainSpread);
                me.onEnterCell();
            },
            items: {
                "oneToOneClone": {
                    name: '一对一克隆',
                    icon: "fa-stop",
                    disabled: function () {
                        let ok = me.curIsBlock() && calcTools.isLeafBill(projectObj.project.mainTree.selected);
                        return !ok;
                    },
                    visible: function(key, opt){
                        return true;
                    },
                    callback: function (key, opt) {
                        blockLibObj.cloneType = 1;
                        $("#div_cloneOptions").modal({show: true});
                    }
                },
                "oneToMoreClone": {
                    name: '一对多克隆',
                    icon: "fa-th-list",
                    disabled: function () {
                        let ok = me.curIsBlock() && calcTools.isParentBill(projectObj.project.mainTree.selected);
                        return !ok;
                    },
                    visible: function(key, opt){
                        return true;
                    },
                    callback: function (key, opt) {
                        blockLibObj.cloneType = 2;
                        $("#div_cloneOptions").modal({show: true});
                    }
                },
                "moreToMoreClone": {
                    name: '多对多克隆',
                    icon: "fa-th",
                    disabled: function () {
                        let ok = me.curIsCategory() && calcTools.isParentBill(projectObj.project.mainTree.selected);
                        return !ok;
                    },
                    visible: function(key, opt){
                        return true;
                    },
                    callback: function (key, opt) {
                        blockLibObj.cloneType = 3;
                        $("#div_cloneOptions").modal({show: true});
                    }
                },
                "delete": {
                    name: '删除',
                    icon: "delete",
                    disabled: function () {
                        return $("#select_block_lib_names option:selected").prop("index") !== 0;
                    },
                    visible: function(key, opt){
                        return true;
                    },
                    callback: function (key, opt) {
                        let name = hintBox.fontRed(me.mainTree.selected.data.nodeName);
                        hintBox.infoBox('操作确认', `确定要删除"${name}"吗？`, 2, function () {
                            me.delete();
                        });
                    }
                },
                "moveBlock": {
                    name: '移动模板',
                    icon: "cut",
                    disabled: function () {
                        return true;
                    },
                    visible: function(key, opt){
                        // return me.curIsBlock();
                        return false;
                    },
                    callback: function (key, opt) {

                    }
                }
            }
        });
    },
    onEnterCell: function (sender, args) {
        let me = blockLibObj;
        me.mainTree.selected = me.mainTree.items[me.mainSheet.getActiveRowIndex()];
    },
    onCellDoubleClick: function (sender, args) {
        if (blockLibObj.curIsCategory()) {
            hintBox.infoBox('系统提示', `双击是“一对一克隆”，不支持分类操作，请在块文件上双击！`, 1);
            return;
        }
        let projectNode = projectObj.project.mainTree.selected;
        if (!calcTools.isLeafBill(projectNode)) {
            hintBox.infoBox('系统提示', `双击是“一对一克隆”，请在造价书界面选择最底层的分项/补项/清单进行操作！`, 1);
            return;
        }
        blockLibObj.cloneType = 1;
        $("#div_cloneOptions").modal({show: true});
    },
    oneToOneClone: function (projectNode, block, options) {
        return new Promise(function (resolve, reject) {        
            let canClone = true;
            if (options.checkCode)
                canClone = canClone && (projectNode.data.code.substr(0, 9) == block.data.code.substr(0, 9));
            if (options.checkName)
                canClone = canClone && (projectNode.data.name == block.data.name);
            if (options.checkUnit)
                canClone = canClone && (projectNode.data.unit == block.data.unit);
            if (!canClone) return resolve([[], []]);
            
            if (options.overwriteRations)
                projectObj.project.Bills.deleteChildren(projectNode);
            /*  这里封装成伟城的块文件格式，可直接使用伟城的“粘贴块”接口。
                但这里结构要作出调整：忽略叶子清单层，直接从定额开始（跟粘贴块有区别），始终强制在叶子清单下插入定额。
                该操作前提：当前块文件的全部数据已从后台取到前台。  */
            let vBlock_WC = {
                compilationID: block.data.compilationID,
                copyTime: block.data.copyTime,
                firstNodeType: 1,           // 强制改成1 (因为是从清单下的定额开始。清单自身的还是保留，暂不使用使用)。
                isFBFX: block.data.isFBFX,
                zeroQuantity: options.zeroQuantity,
                datas: block.data.children       // rations
            };
            vBlock_WC = JSON.parse(JSON.stringify(vBlock_WC));
            BlockController.confirmPaste(vBlock_WC, projectNode, 'sub',function(r, c){
                resolve([r, c])
            });
        })

    },
    checkShow: async function () {   // 这里需要处理异步：模板库装载完再弹出位置选择窗。
        if (!$("#kmbk").is(":visible")){  // 如果还没显示
            if (!blockLibObj.mainSpread){
                await blockLibObj.buildSheet();
            };
            $('#blockLibTab').click();  // 强制显示
        };
        $("#div_createBlocks").modal({show: true});
    }
};

$(document).ready(function(){    // 这里不需要处理异步：因为不需要弹出位置选择窗。
    $('#blockLibTab').on('click', function (){
        if ($("#kmbk").is(":visible")){    // 显示状态下
            if (!blockLibObj.mainSpread){
                blockLibObj.buildSheet();
            };
        }
    });

    $('#btn_block_newFolder').on('click', function (){
        $('#input_block_newFolder').val('');
    });

    $('#btn_block_newFolder_add').on('click', function (){
        let name = $('#input_block_newFolder').val();
        blockLibObj.newNode(1, name);
    });

    $('#btn_block_reName').on('click', function (){
        let select = blockLibObj.mainTree.selected;
        $('#input_block_reName').val(select.data.nodeName);
    });

    $('#btn_block_reName_OK').on('click', function (){
        let select = blockLibObj.mainTree.selected;
        let oldName = select.data.nodeName;
        let newName = $('#input_block_reName').val();
        if (oldName != newName) blockLibObj.reName(select, newName);
    });

    $("#select_block_lib_names").change(function() {
        const index = $("#select_block_lib_names option:selected").prop("index");
        if (index !== 0) {
            // 只读
            $('#btn_block_newFolder').hide();
            $('#btn_block_reName').hide();
            $('#btn_block_share').prop('disabled', true);
        } else {
            $('#btn_block_newFolder').show();
            $('#btn_block_reName').show();
            $('#btn_block_share').prop('disabled', false);
        }
        async function getLib(){
            let libID = $("#select_block_lib_names").val();
            let lib = await ajaxPost('/blockLib/getLib', {libID: libID});
            blockLibObj.loadLib(lib);
            if (userID === lib.userID) {
                $('#btn_block_share').attr('data-original-title', blockLibObj.initialShareTip);
            }
        };
        $.bootstrapLoading.start();
        getLib();
        $.bootstrapLoading.end();
    });

    $('#btn_block_share').click(function () {
        SHARE_TO.initModal(SHARE_TO.Mode.BLOCK_LIB);
    })
});