/**
 * Created by Zhong on 2017/10/30.
 */
let gcTree = null;
let decDate = null;//恢复后的名称后缀(时间+恢复)
//恢复路径t = tender, e = engineering, p = project
const recPath = {t: 'T', t_e: 'T_E', t_e_p: 'T_E_P', e: 'E', e_p: 'E_P', p: 'P'};
const gcTreeObj = {
    tree: null,
    workBook: null,
    setting: {
        tree: {
            id: 'ID',
            pid: 'ParentID',
            nid: 'NextSiblingID',
            rootId: -1,
            autoUpdate: false
        },
        header: [
            {name: '工程列表', dataCode: 'name', width: 0.5, rateWidth: 0.5, vAlign: 'center', hAlign: 'left'},
            {name: '删除日期', dataCode: 'deleteDateTime', width: 0.1, rateWidth: 0.1, vAlign: 'center', hAlign: 'left'},
            {name: '创建日期', dataCode: 'createDateTime', width: 0.1, rateWidth: 0.1, vAlign: 'center', hAlign: 'left'},
            {name: '恢复', dataCode: 'recovery', width: 0.05, rateWidth: 0.05, vAlign: 'center', hAlign: 'left'},
            {name: '彻底删除', dataCode: 'delete', width: 0.05, rateWidth: 0.05, vAlign: 'center', hAlign: 'left'},
            {name: '单价文件', dataCode: 'unitPriceFile', width: 0.05, rateWidth: 0.05, vAlign: 'center', hAlign: 'left'},
            {name: '单价文件-清除', dataCode: 'unitPriceFile_delete', width: 0.05, rateWidth: 0.05, vAlign: 'center', hAlign: 'left'},
            {name: '费率文件', dataCode: 'feeRateFile', width: 0.05, rateWidth: 0.05, vAlign: 'center', hAlign: 'left'},
            {name: '费率文件-清除', dataCode: 'feeRateFile_delete', width: 0.05, rateWidth: 0.05, vAlign: 'center', hAlign: 'left'}
        ],
        //恢复和彻底删除字体色
        style: {
            recForeColor: '#007bff',
            delForeColor: '#dc3545'
        },
        options: {
            tabStripVisible:  false,
            allowContextMenu: false,
            allowCopyPasteExcelStyle : false,
            allowExtendPasteRange: false,
            allowUserDragDrop : false,
            allowUserDragFill: false,
            scrollbarMaxAlign : true
        }
    },
    renderSheetFuc: function (sheet, fuc) {
        sheet.suspendPaint();
        sheet.suspendEvent();
        fuc();
        sheet.resumePaint();
        sheet.resumeEvent();
    },
    setOptions: function (workbook, opts) {
        for(let opt in opts){
            workbook.options[opt] = opts[opt];
        }
    },
    bindEvent: function (workBook) {
        const _events = GC.Spread.Sheets.Events;
        let sheet = workBook.getActiveSheet();
        //改变选中节点set selected
        sheet.bind(_events.SelectionChanging, this.onSelectionChanging);
    },
    buildHeader: function (sheet, headers) {
        let me = this;
        let fuc = function () {
            sheet.options.isProtected = true;
            sheet.options.protectionOptions = {
                allowResizeRows: true,
                allowResizeColumns: true
            };
            let workBookWidth = getWorkBookWidth();
            sheet.setColumnCount(headers.length);
            sheet.setRowHeight(0, 40, GC.Spread.Sheets.SheetArea.colHeader);
            for(let i = 0, len = headers.length; i < len; i++){
                sheet.setColumnWidth(i, workBookWidth * headers[i].width, GC.Spread.Sheets.SheetArea.colHeader);
                if(headers[i].dataCode === 'unitPriceFile' || headers[i].dataCode === 'feeRateFile'){
                    //合并列
                    sheet.addSpan(0, i, 1, 2, GC.Spread.Sheets.SheetArea.colHeader);
                }
                if(headers[i].dataCode === 'unitPriceFile_delete' || headers[i].dataCode === 'feeRateFile_delete'){
                    continue;
                }
                sheet.setValue(0, i, headers[i].name, GC.Spread.Sheets.SheetArea.colHeader);
            }
        };
        me.renderSheetFuc(sheet, fuc);
    },
    buildSheet: function () {
        if(!this.workBook){
            this.workBook = new GC.Spread.Sheets.Workbook($('#gcSpread')[0], {sheetCount: 1});
            sheetCommonObj.spreadDefaultStyle(this.workBook);
            this.setOptions(this.workBook, this.setting.options);
            this.buildHeader(this.workBook.getActiveSheet(), this.setting.header);
            this.bindEvent(this.workBook);
        }
    },
    getSelStyle: function (backColor) {
        let style = new GC.Spread.Sheets.Style();
        style.backColor = backColor;
        style.borderLeft = new GC.Spread.Sheets.LineBorder("#D4D4D4", GC.Spread.Sheets.LineStyle.thin);
        style.borderTop = new GC.Spread.Sheets.LineBorder("#D4D4D4", GC.Spread.Sheets.LineStyle.thin);
        style.borderRight = new GC.Spread.Sheets.LineBorder("#D4D4D4", GC.Spread.Sheets.LineStyle.thin);
        style.borderBottom = new GC.Spread.Sheets.LineBorder("#D4D4D4", GC.Spread.Sheets.LineStyle.thin);
        return style;
    },
    //设置选中行底色
    setSelStyle: function (sel, backColor) {
        let me = this;
        let sheet = me.workBook.getSheet(0);
        me.renderSheetFuc(sheet, function () {
            let style = me.getSelStyle(backColor);
            /*sel.row = sel.row === -1 ? 0 : sel.row;*/
            for(let i = 0; i < sel.rowCount; i++){
                let row = i + sel.row;
                sheet.setStyle(row, -1, style);
            }
        });
    },
    initSelection: function (newSel, oldSel = null) {
        let me = this;
        let node = me.tree.items[newSel.row];
        me.tree.selected = node;
        //恢复底色
        if(oldSel){
            me.setSelStyle(oldSel, projTreeObj.setting.style.defalutBackColor);
        }
        //设置选中行底色
        if(newSel){
            me.setSelStyle(newSel, projTreeObj.setting.style.selectedColor);
        }
    },
    onSelectionChanging: function (sender, args) {
        let me = gcTreeObj;
        me.initSelection(args.newSelections[0], args.oldSelections[0]);
    },
    //点击恢复列,弹出恢复项目窗口
    oprProj: function (modalId, node) {
        let tenderNodes = m_getTenders(node);
        let type = modalId === '#rePoj' ? 'recovery' : 'delete';
        $(`${modalId} .modal-header`).empty();
        $('p', `${modalId} .modal-body`).remove();
        $(`${modalId} .modal-header`).html(v_getTitle(type, node));
        $(`${modalId} .modal-body`).html(v_getMoBody(type, node, tenderNodes));
        $(`${modalId}`).modal('show');
    },
    //点击单价文件恢复，弹出恢复单价文件窗口
    recoveryUnitPrc: function (node) {
        let unitPriceFiles = node.data.unitPriceFiles;
        let tenders = m_getTenders(node);
        $('#reFile h5').text('恢复单价文件');
        $('tr', '#reFile tbody').remove();
        $('#reFile tbody').html(v_getFiles(fileType.unitPriceFile, unitPriceFiles, tenders, 'recovery'));
        $('#reFile').modal('show');
    },
    recoveryFeeRate: function (node) {
        let feeRateFiles = node.data.feeRateFiles;
        let tenders = m_getTenders(node);
        $('#reFile h5').text('恢复费率文件');
        $('tr', '#reFile tbody').remove();
        $('#reFile tbody').html(v_getFiles(fileType.feeRateFile, feeRateFiles, tenders, 'recovery'));
        $('#reFile').modal('show');
    },
    //点击单价文件清除，弹出清除单价文件窗口
    deleteUnitPrc: function (node) {
        let unitPriceFiles = node.data.unitPriceFiles;
        let tenders = m_getTenders(node);
        $('#delFile h5').text('彻底删除单价文件');
        $('tr', '#delFile tbody').remove();
        $('#delFile tbody').html(v_getFiles(fileType.unitPriceFile, unitPriceFiles, tenders, 'delete'));
        $('#delFile').modal('show');
    },
    deleteFeeRate: function (node) {
        let feeRateFiles = node.data.feeRateFiles;
        let tenders = m_getTenders(node);
        $('#delFile h5').text('彻底删除费率文件');
        $('tr', '#delFile tbody').remove();
        $('#delFile tbody').html(v_getFiles(fileType.feeRateFile, feeRateFiles, tenders, 'delete'));
        $('#delFile').modal('show');
    },
    getTreeNodeCell: function (tree) {
        let indent = 20;
        let levelIndent = -5;
        let halfBoxLength = 5;
        let halfExpandLength = 3;
        let imgWidth = 18;
        let imgHeight = 14;
        let TreeNodeCellType = function () {
        };
        TreeNodeCellType.prototype = new GC.Spread.Sheets.CellTypes.Text();
        TreeNodeCellType.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];
            let showTreeLine = true;
            if (!node) { return; }

            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;
            // Draw Sibling Line
            const lineColor = '#ababab';
            if (showTreeLine) {
                // Draw Horizontal Line
                if (centerX < x + w) {
                    drawLine(ctx, centerX, centerY, Math.min(x1, x + w), centerY, lineColor);
                    let img;
                    if(node.data.projType === projectType.folder){
                        img = document.getElementById('folder_open_pic');
                        imgWidth = 15;
                    }
                    else if(node.data.projType === projectType.project){
                        img = document.getElementById('proj_pic');
                        imgWidth = 18;
                    }
                    else if(node.data.projType === projectType.engineering){
                        img = document.getElementById('eng_pic');
                        imgWidth = 14;
                    }
                    else if(node.data.projType === projectType.tender){
                        img = document.getElementById('tender_pic');
                        imgWidth = 14;
                    }
                    ctx.drawImage(img, centerX+indent/2+3, centerY - 7, imgWidth,imgHeight);
                }
                // Draw Vertical Line
                if (centerX < x + w) {
                    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
            if (showTreeLine) {
                var parent = node.parent, parentCenterX = centerX - indent - levelIndent;
                while (parent.parent) {
                    if (!parent.isLast()) {
                        if (parentCenterX < x + w) {
                            drawLine(ctx, parentCenterX, y, parentCenterX, y + h, lineColor);
                        }
                    }
                    parent = parent.parent;
                    parentCenterX -= (indent + levelIndent);
                }
            };
            // Draw Text
            //x = x + (node.depth() + 1) * indent +  node.depth() * levelIndent;
            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);
        };
        TreeNodeCellType.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;
        };
        TreeNodeCellType.prototype.processMouseDown = function (hitinfo) {
            let offset = -1;
            let node = tree.items[hitinfo.row];
            tree.selected = node;
            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;;
            if (!node || node.children.length === 0) { return; }

            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();
            }
        };
        TreeNodeCellType.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 = tree.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);
            }
        };
        TreeNodeCellType.prototype.processMouseLeave = function (hitinfo) {
            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 TreeNodeCellType();
    },
    getBaseCell: function () {
        let MyBaseCell = function () {
        };
        MyBaseCell.prototype = new GC.Spread.Sheets.CellTypes.Text();
        MyBaseCell.prototype.getHitInfo = function (x, y, cellStyle, cellRect, context) {
            return {
                x: x,
                y: y,
                row: context.row,
                col: context.col,
                cellStyle: cellStyle,
                cellRect: cellRect,
                sheetArea: context.sheetArea,
                isReservedLocation: true
            };
        };
        MyBaseCell.prototype.processMouseDown = function (hitinfo) {
            let dataCode = gcTreeObj.setting.header[hitinfo.col]['dataCode'];
            let node = gcTreeObj.tree.items[hitinfo.row];
            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});
            if(hitinfo.x - hitinfo.cellRect.x > 0 && hitinfo.x - hitinfo.cellRect.x < textLength){
                //恢复
                if(dataCode === 'recovery'){
                    gcTreeObj.oprProj('#rePoj', node);
                }
                //清除
                else if(dataCode === 'delete'){
                    gcTreeObj.oprProj('#delPoj', node)
                }
                //恢复单价文件
                else if(dataCode === 'unitPriceFile'){
                    gcTreeObj.recoveryUnitPrc(node);
                }
                //清除单价文件
                else if(dataCode === 'unitPriceFile_delete'){
                    gcTreeObj.deleteUnitPrc(node);
                }
                //恢复费率文件
                else if(dataCode === 'feeRateFile'){
                    gcTreeObj.recoveryFeeRate(node);
                }
                //清除费率文件
                else if(dataCode === 'feeRateFile_delete'){
                    gcTreeObj.deleteFeeRate(node);
                }
            }
        };
        MyBaseCell.prototype.processMouseMove = function (hitInfo) {
            let dataCode = gcTreeObj.setting.header[hitInfo.col]['dataCode'];
            if(dataCode === 'recovery' || dataCode === 'delete' || dataCode === 'unitPriceFile' || dataCode === 'unitPriceFile_delete' || dataCode === 'feeRateFile' || dataCode === 'feeRateFile_delete'){
                let sheet = hitInfo.sheet;
                let div = sheet.getParent().getHost();
                let canvasId = div.id + "vp_vp";
                let canvas = $(`#${canvasId}`)[0];
                //改变鼠标图案
                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});
                if (sheet && hitInfo.x - hitInfo.cellRect.x >  0 && hitInfo.x - hitInfo.cellRect.x < textLength) {
                    canvas.style.cursor='pointer';
                    return true;
                }else{
                    canvas.style.cursor='default';
                }
            }
            return false;
        };
        return new MyBaseCell();
    },
    setCellValue: function (cell, node) {
        const sheet = this.workBook.getActiveSheet();
        const {row, col} = cell;
        const dataCode = this.setting.header[col]['dataCode'];
        let value = '';
        if(dataCode === 'deleteDateTime' || dataCode === 'createDateTime'){
            if (node.data.projType === projectType.tender && deleted(node)) {
                let date = dataCode === 'deleteDateTime' ? node.data.deleteInfo.deleteDateTime : node.data.createDateTime;
                let localDateTime = new Date(date).toLocaleDateString();
                value = new Date(localDateTime).Format('yyyy-MM-dd');
            }
        }
        else if(dataCode === 'recovery'){
            if(deleted(node)){
                value = '恢复';
            }
        }
        else if(dataCode === 'delete'){
            if(deleted(node)){
                value = '彻底删除';
            }
        }
        else if(dataCode === 'unitPriceFile'){
            if(node.data.projType === projectType.project && node.data.unitPriceFiles !== undefined && node.data.unitPriceFiles.length > 0){
                value = '恢复';
            }
        }
        else if(dataCode === 'unitPriceFile_delete'){
            if(node.data.projType === projectType.project && node.data.unitPriceFiles !== undefined && node.data.unitPriceFiles.length > 0){
                value = '彻底删除';
            }
        }
        else if(dataCode === 'feeRateFile'){
            if(node.data.projType === projectType.project && node.data.feeRateFiles !== undefined && node.data.feeRateFiles.length > 0){
                value = '恢复';
            }
        }
        else if(dataCode === 'feeRateFile_delete'){
            if(node.data.projType === projectType.project && node.data.feeRateFiles !== undefined && node.data.feeRateFiles.length > 0){
                value = '彻底删除';
            }
        }
        else {
            value = node.data[dataCode] ? node.data[dataCode] : '';
        }
        sheet.setValue(row, col, value);
    },
    showTreeData: function (nodes, headers) {
        let me = this;
        let sheet = me.workBook.getActiveSheet();
        let fuc = function(){
            sheet.setRowCount(nodes.length);
            for(let i = 0; i < nodes.length; i++){
                let treeNodeCell = me.getTreeNodeCell(me.tree);
                sheet.getCell(i, 0).cellType(treeNodeCell);
                for(let j = 0; j < headers.length; j++){
                    sheet.getRange(-1, j, -1, 1).hAlign(GC.Spread.Sheets.HorizontalAlign[headers[j]['hAlign']]);
                    sheet.getRange(-1, j, -1, 1).vAlign(GC.Spread.Sheets.VerticalAlign[headers[j]['vAlign']]);
                    if(j !== 0){
                        sheet.getCell(i, j).cellType(me.getBaseCell());
                    }
                    let dataCode = headers[j].dataCode;
                    if(dataCode === 'recovery' || dataCode === 'unitPriceFile' || dataCode === 'feeRateFile'){
                        let style = new GC.Spread.Sheets.Style();
                        style.foreColor = me.setting.style.recForeColor;
                        sheet.setStyle(-1, j, style);
                    }
                    else if(dataCode === 'delete' || dataCode === 'unitPriceFile_delete' || dataCode === 'feeRateFile_delete'){
                        let style = new GC.Spread.Sheets.Style();
                        style.foreColor = me.setting.style.delForeColor;
                        sheet.setStyle(-1, j, style);
                    }
                    me.setCellValue({row: i, col: j}, nodes[i]);
                }
            }
        };
        me.renderSheetFuc(sheet, fuc);
    },
    refreshNodeData: function (node) {
        let me = this;
        let sheet = me.workBook.getActiveSheet();
        let header = me.setting.header;
        let rIdx = me.tree.items.indexOf(node);
        me.renderSheetFuc(sheet, function () {
            for(let i = 0; i < header.length; i++){
                me.setCellValue({row: rIdx, col: i}, node);
            }
        });
    },
    remove: function (node) {
        let me = this;
        let sheet = me.workBook.getActiveSheet();
        //删除行号
        let rIdx = me.tree.items.indexOf(node);
        //删除行数
        let count = node.posterityCount() + 1;
        me.tree.removeNode(node);
        me.renderSheetFuc(sheet, function () {
            sheet.deleteRows(rIdx, count);
            sheet.setRowCount(me.tree.items.length);
            me.initSelection({row: sheet.getActiveRowIndex(), rowCount: 1});
        });
    },
    move: function (orgRow, newRow) {
        this.workBook.getActiveSheet().deleteRows(orgRow, 1);
        this.addRow(this.tree.items[newRow]);
    }
};
$(document).ready(function () {
    $('#tab_pm_gc').on('show.bs.tab', function () {
        //侧滑隐藏
        $('.slide-sidebar').removeClass('open');
        $('.slide-sidebar').css('width', '0');
        gc_init();
        if(projTreeObj.workBook){
            projTreeObj.workBook.destroy();
            projTreeObj.workBook = null;
        }
        projTreeObj.tree = null;
    });
    e_recFiles($('#reFileBtn'));
    e_delFiles($('#delFileBtn'));
    e_recProj($('#rePojBtn'));
    e_delProj($('#delPojBtn'));
});

function gc_init(){
    $.bootstrapLoading.start();
    a_getGC(function (datas) {
        m_buildVirtualTree(datas);
        let normalDatas = m_VTreeToDatas(datas);
        gcTreeObj.tree = pmTree.createNew(gcTreeObj.setting, normalDatas);
        gcTreeObj.tree.selected = gcTreeObj.tree.items[0];
        gcTreeObj.buildSheet();
        gcTreeObj.showTreeData(gcTreeObj.tree.items, gcTreeObj.setting.header);
        //初始选择
        let initSel = gcTreeObj.workBook.getSheet(0).getSelections()[0] ? gcTreeObj.workBook.getSheet(0).getSelections()[0] : {row: 0, rowCount: 1};
        gcTreeObj.initSelection(initSel);
        autoFlashHeight();
        gcTreeObj.workBook.refresh();
    });
}

//项目恢复模态框标题
function v_getTitle(type, node){
    let html = '';
    html += type === 'recovery' ? '<h5 class="modal-title">恢复 ' : '<h5 class="modal-title">彻底删除 ';
    if(node.data.projType === projectType.project){
        html += '<i class="fa fa-cubes"></i>建设项目</h5>';
    }
    else if(node.data.projType === projectType.engineering){
        html += '<i class="fa fa-cube"></i>单项工程</h5>';
    }
    else if(node.data.projType === projectType.tender){
        html += '<i class="fa fa-sticky-note-o"></i>单位工程</h5>';
    }
    html += '<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>';
    return html;
}

//项目恢复模态框主体
function v_getMoBody(type, oprNode, nodes){
    let html = '';
    if(type === 'recovery'){
        if(oprNode.data.projType === projectType.tender){
            decDate = '（' + new Date().Format('MM-dd hh:mm:ss') + '恢复）';
            let recName = oprNode.data.name + decDate;
            html += '<p>恢复后将重命名为 <b>' + recName + '</b></p>';
        }
        else {
            if(oprNode.data.projType === projectType.project){
                html += '<p><i class="fa fa-cubes"></i> ' + oprNode.data.name + '下的单位工程都将恢复，恢复后将重命名为</p>';
            }
            else if(oprNode.data.projType === projectType.engineering){
                html += '<p><i class="fa fa-cube"></i> ' + oprNode.data.name + '下的单位工程都将恢复，恢复后将重命名为</p>';
            }
            html += ('<p>');
            for(let i = 0, len = nodes.length; i < len; i++){
                let recName = nodes[i].data.name + '（' + new Date().Format('MM-dd hh:mm:ss') +'恢复）';
                html += '<b>' + recName + '</b>、';
            }
            html = html.slice(0, html.length - 1);
            html += ('</p>');
        }

        html += ('<p>点“确定”按钮，确认从回收站中恢复。</p>');
    }
    else{
        html += ('<p>点“确定”按钮，确认彻底删除数据。</p>');
    }
    return html;
}

//单价、费率文件恢复弹出框数据
function v_getFiles(type, files, tenders, opr = null){
    let html = '';
    function hasTheFile(tenders, fileId, fileType){
        for(let tender of tenders){
            let fileAttr = fileType === 'UnitPriceFile' ? 'unitPriceFile' : 'feeFile';
            if(tender.data.property[fileAttr]['id'] == fileId){
                return true;
            }
        }
        return false;
    }
    for(let i = 0, len = files.length; i < len; i ++){
        let recName = type === fileType.unitPriceFile ?  files[i].name : files[i].name;
        let fileId = type === fileType.unitPriceFile ? files[i].id : files[i].ID;
        let recTimeA = formatDate(new Date(files[i].deleteInfo.deleteDateTime), 'yyyy-MM-dd');
        let recTimeB = formatDate(new Date(files[i].deleteInfo.deleteDateTime), 'HH:mm:ss');
        if(opr && opr === 'delete'){
            //还被引用，不可删除
            if(hasTheFile(tenders, fileId, type)){
                html += '<tr><td width="266px">'+ recName +'</td><td width="136px">' + recTimeA + '<br>' + recTimeB + '</td><td width="64px"><input disabled name="fileItems" type="checkbox" fileId = "' + fileId + '" fileType = "' + type + '"></td></tr>';
            }
            else {
                html += '<tr><td width="266px">'+ recName +'</td><td width="136px">' + recTimeA + '<br>' + recTimeB + '</td><td width="64px"><input name="fileItems" type="checkbox" fileId = "' + fileId + '" fileType = "' + type + '"></td></tr>';
            }
        }
        else{
            html += '<tr><td width="266px">'+ recName +'</td><td width="136px">' + recTimeA + '<br>' + recTimeB + '</td><td width="64px"><input name="fileItems" type="checkbox" fileId = "' + fileId + '" fileType = "' + type + '"></td></tr>';
        }
    }
    return html;
}

//恢复或清除单价、费率文件后前端显示变化
function v_refreshFiles(project, fileIds, type){
    let projFiles;
    if(type === fileType.unitPriceFile){
        projFiles = project.data.unitPriceFiles;
    }
    else if(type === fileType.feeRateFile){
        projFiles = project.data.feeRateFiles;
    }
    if(projFiles && projFiles.length > 0){
        let tempFiles = [];
        for(let i = 0, len = projFiles.length; i < len; i++){
            let isExist = false;
            for(let j = 0, jLen = fileIds.length; j < jLen; j++){
                let id = projFiles[i].id || projFiles[i].ID || null;
                if(id && id === fileIds[j]){
                    isExist = true;
                    break;
                }
            }
            if(!isExist){
                tempFiles.push(projFiles[i]);
            }
        }
        if(type === fileType.unitPriceFile){
            project.data.unitPriceFiles = tempFiles;
        }
        else if(type === fileType.feeRateFile){
           project.data.feeRateFiles = tempFiles;
        }
    }
}

function v_removeNode(node){
    gcTreeObj.remove(node);
    let parent = node.parent || null;
    if(parent && parent.children.length === 0 && parent.data !== undefined){
        if(parent.data.projType === projectType.project && fileEmpty(parent)){
            v_removeNode(parent);
        }
        else if(parent.data.projType !== projectType.project){
            v_removeNode(parent);
        }
    }
}

function v_refreshNode(node, recovery = true){
    if(recovery){
        if(deleted(node)){
            delete node.data.deleteInfo;
        }
    }
    gcTreeObj.refreshNodeData(node);
    let parent = node.parent || null;
    if(parent && parent.data !== undefined){
        v_refreshNode(parent, recovery);
    }
}

//将获取的回收站中的数据建虚拟树
function m_buildVirtualTree(datas){
    for(let i = 0, len = datas.length; i < len; i++){
        if(datas[i].projType === projectType.project){
            datas[i].ParentID = -1;
        }
        let children = datas[i].children || null;
        if(children){
            m_buildVirtualTree(children);
        }
        let next = datas[i+1] || null;
        if(next){
            datas[i].NextSiblingID = next.ID;
        }
        else {
            datas[i].NextSiblingID = -1;
        }
    }
}

function m_VTreeToDatas(datas){
    let rst = [];
    let projs = datas;
    rst = rst.concat(projs);
    for(let i = 0, len = projs.length; i < len; i++){
        let p_engs = projs[i].children || null;
        if(p_engs){
            rst = rst.concat(p_engs);
            for(let j = 0, jLen = p_engs.length; j < jLen; j ++){
                let e_tenders = p_engs[j].children || null;
                if(e_tenders){
                    rst = rst.concat(e_tenders);
                }
            }
        }
    }
    return rst;
}

//获得当前节点的tenders数据，模态提示框用
function m_getTenders(node){
    if(node.data.projType === projectType.tender) return [node];
    else {
        let rst = [];
        if(node.children.length > 0){
            node.children.forEach(function (cNode) {
                if(cNode.children.length > 0){
                    cNode.children.forEach(function (ccNode) {
                       if(ccNode.data.projType === projectType.tender) rst.push(ccNode);
                    });
                }
                else if(cNode.children.length === 0 && cNode.data.projType === projectType.tender){
                    rst.push(cNode);
                }
            });
        }
        return rst;
    }
}

//获得要更新的数据（包含恢复的数据，维护项目管理树的数据）
function m_getRecDatas(oprNode){
    let rst = Object.create(null);
    let rstProj = [], rstFile = [];
    let path;
    if(oprNode.data.projType === projectType.tender){
        path = recPath.t;
        let engineering = oprNode.parent || null;
        if(!engineering) return null;
        let project = engineering.parent || null;
        if(!project) return null;
        if(engineering && deleted(engineering)){
            path = recPath.t_e;
        }
        //恢复建设项目
        if(project && deleted(project)){
            path = recPath.t_e_p;
        }
        //恢复单价、费率文件
        rstFile = rstFile.concat(getUpdateFiles([oprNode], project));
        if(path === recPath.t){
            rstProj = rstProj.concat(getUpdateDatas(projectType.tender, oprNode, -1, true));
        }
        else if(path === recPath.t_e){
            rstProj = rstProj.concat(getUpdateDatas(projectType.tender, oprNode, -1, false));
            rstProj = rstProj.concat(getUpdateDatas(projectType.engineering, engineering, -1, true));
        }
        else if(path === recPath.t_e_p){
            rstProj = rstProj.concat(getUpdateDatas(projectType.tender, oprNode, -1, false));
            rstProj = rstProj.concat(getUpdateDatas(projectType.engineering, engineering, -1, false));
            rstProj = rstProj.concat(getUpdateDatas(projectType.project, project, -1, false));
        }
    }
    else if(oprNode.data.projType === projectType.engineering){
        path = recPath.e;
        let project = oprNode.parent || null;
        if(!project) return null;
        //恢复建设项目
        if(project && deleted(project)){
            path = recPath.e_p;
        }
        let tenders = oprNode.children;
        if(tenders.length > 0){
            for(let i = 0, len = tenders.length; i < len; i++){
                rstProj = rstProj.concat(getUpdateDatas(projectType.tender, tenders[i], tenders[i].data.NextSiblingID, false));
            }
            rstProj = deWeightName(rstProj);
            //恢复单价、费率文件
            rstFile = rstFile.concat(getUpdateFiles(tenders, project));
        }
        if(path === recPath.e){
            rstProj= rstProj.concat(getUpdateDatas(projectType.engineering, oprNode, -1, true));
        }
        else if(path === recPath.e_p){
            rstProj= rstProj.concat(getUpdateDatas(projectType.engineering, oprNode, -1, false));
            rstProj= rstProj.concat(getUpdateDatas(projectType.project, project, -1, false));
        }
    }
    else if(oprNode.data.projType === projectType.project){
        path = recPath.p;
        let engineerings = oprNode.children;
        if(engineerings.length > 0){
            let allTenders = [], rstEngs = [];
            for(let i = 0, len = engineerings.length; i < len; i++){
                //恢复单项工程
                rstEngs = rstEngs.concat(getUpdateDatas(projectType.engineering, engineerings[i], engineerings[i].data.NextSiblingID, false));
                let tenders = engineerings[i].children;
                allTenders = allTenders.concat(tenders);
                let rstTends = [];
                for(let j = 0, jLen = tenders.length; j < jLen; j++){
                    //恢复单位工程
                    rstTends = rstTends.concat(getUpdateDatas(projectType.tender, tenders[j], tenders[j].data.NextSiblingID, false));
                }
                //去除重名
                rstTends = deWeightName(rstTends);
                rstProj = rstProj.concat(rstTends);
            }
            //去除重名
            rstEngs = deWeightName(rstEngs);
            rstProj = rstProj.concat(rstEngs);
            //恢复单价、费率文件
            rstFile = rstFile.concat(getUpdateFiles(allTenders, oprNode));

        }
        //恢复建设项目
        rstProj = rstProj.concat(getUpdateDatas(projectType.project, oprNode, false, false));
    }
    rst.proj = rstProj;
    rst.file = rstFile;
    return rst;
}

//获取清除的数据
function m_getDelDatas(oprNode){
    let rst = [];
    if(!oprNode){
        return rst;
    }
    function getChild(node){
        rst.push({updateType: 'Project', ID: node.data.ID});
        if(node.children.length > 0){
            for(let child of node.children){
                getChild(child);
            }
        }
    }
    getChild(oprNode);
    //父节点只有一个单位工程，则清除此单位工程的时候，父节点也清除，（建设项目单价、费率文件存在时不清除）
    if(oprNode.data.projType === projectType.tender){
        let eng = oprNode.parent, proj = null;
        if(eng && deleted(eng)){
            proj = eng.parent;
            rst.push({updateType: 'Project', ID: eng.data.ID});
        }
        if(proj && deleted(proj) && fileEmpty(proj)){
            rst.push({updateType: 'Project', ID: proj.data.ID})
        }
    }
    else if(oprNode.data.projType === projectType.engineering){
        let proj = oprNode.parent;
        if(proj && deleted(proj) && fileEmpty(proj)){
            rst.push({updateType: 'Project', ID: proj.data.ID});
        }
    }
    else if(oprNode.data.projType === projectType.project){
        for(let uf of oprNode.data.unitPriceFiles){
            rst.push({updateType: fileType.unitPriceFile, ID: uf.id});
        }
        for(let ff of oprNode.data.feeRateFiles){
            rst.push({updateType: fileType.feeRateFile, ID: ff.ID});
        }
    }
    return rst;
}

//获得勾选的单价、费率文件的id
function m_getFilesObjs(nodes){
    let rst = [];
    for(let i = 0, len = nodes.length; i < len; i++){
        let fileId = $(nodes[i]).attr('fileId') || null;
        if(fileId){
            let name = $('td:eq(0)', $(nodes[i])[0].parentNode.parentNode)[0].textContent;
            if($(nodes[i]).attr('fileType') === fileType.unitPriceFile){
                fileId = parseInt(fileId);
            }
            let obj = Object.create(null);
            obj.id = fileId;
            obj.name = name;
            rst.push(obj);
        }
    }
    return rst;
}

function m_project(node){
    if(node && node.data.projType === projectType.project) return node;
    if(!node) return null;
    let parent = node.parent || null;
    if(!parent) return null;
    if(parent && parent.data.projType === projectType.project) return parent;

    let gParent = parent.parent || null;
    if(!gParent) return null;
    if(gParent && gParent.data.projType === projectType.project) return gParent;
    return null;
}

//点击单价文件、费率文件下的恢复操作(确认)
function e_recFiles(btn){
    btn.bind('click', function () {
        $.bootstrapLoading.start();
        decDate = '（' + new Date().Format('MM-dd hh:mm:ss') + '恢复）';
        let recObjs = m_getFilesObjs($('[name = "fileItems"]:checked'));
        let recIds = [];
        for(let i of recObjs){
            recIds.push(i.id);
        }
        let type = $('[name = "fileItems"]:checked').attr('fileType');
        let selected = gcTreeObj.tree.selected;
        //backend
        let updateDatas = [];
        for(let i = 0, len = recObjs.length; i < len; i++){
            let findData = type === fileType.unitPriceFile ? {id: recObjs[i].id} : {ID: recObjs[i].id};
            updateDatas.push(getUpdateObj(type, findData, {deleteInfo: null, name: delPostFix(recObjs[i].name) + decDate}));
        }
        let isRecoverProj = false;
        //恢复建设项目
        if(updateDatas.length > 0 && deleted(selected)){
            isRecoverProj = true;
            updateDatas.push(getUpdateObj(projectType.project, {ID: selected.data.ID}, {deleteInfo: null, name: delPostFix(selected.data.name) + decDate}));
        }
        updateDatas = deWeightName(updateDatas);
        a_rec(updateDatas, caller);
        function caller(){
            //front
            if(recIds.length > 0){
                v_refreshFiles(selected, recIds, type);
                if(deleted(selected)){
                    delete selected.data.deleteInfo;
                }
                if(fileEmpty(selected) && selected.children.length === 0){
                    gcTreeObj.remove(selected);
                }
                else {
                    gcTreeObj.refreshNodeData(selected);
                }
            }
            if (isRecoverProj) {
                projTreeObj.emitTreeChange();
            }
        }
    });
}

//点击单价、费率文件的清除操作（确认)
function e_delFiles(btn){
    btn.bind('click', function () {
        $.bootstrapLoading.start();
        let selected = gcTreeObj.tree.selected;//project
        let delObjs = m_getFilesObjs($('[name = "fileItems"]:checked'));
        let type = $('[name = "fileItems"]:checked').attr('fileType');
        let delDatas = [];
        let delIds = [];
        for(let delObj of delObjs){
            delIds.push(delObj.id);
            delDatas.push({updateType: type, ID: delObj.id});
        }
        //此操作造成了建设项目的文件为空，则清除建设项目
        if(fileWillEmpty(selected, delIds, type)){
            //delDatas.push({updateType: 'Project', ID: selected.data.ID});
        }
        if(delDatas.length > 0){
            //backend
            a_delGC(delDatas, caller);
            //front
            function caller(){
                v_refreshFiles(selected, delIds, type);
                if(fileEmpty(selected) && selected.children.length === 0){
                    gcTreeObj.remove(selected);
                }
                else {
                    gcTreeObj.refreshNodeData(selected);
                }
            }
        }
    });
}

//点击项目下的恢复操作（确认）
function e_recProj(btn){
    btn.bind('click', function () {
        $.bootstrapLoading.start();
        let selected = gcTreeObj.tree.selected;
        //backend
        let updateObj = m_getRecDatas(selected);
        let updateDatas = updateObj.proj.concat(updateObj.file);
        let fileObj = getRecFileObj(updateObj.file);
        //保存成功后回调front
        a_rec(updateDatas, caller);
        function caller() {
            let project = m_project(selected);
            if(project){
                if(fileObj[fileType.unitPriceFile].length > 0){
                    v_refreshFiles(project, fileObj[fileType.unitPriceFile], fileType.unitPriceFile);
                }
                if(fileObj[fileType.feeRateFile].length > 0){
                    v_refreshFiles(project, fileObj[fileType.feeRateFile], fileType.feeRateFile);
                }
            }
            v_removeNode(selected);
            v_refreshNode(selected, true);
            projTreeObj.emitTreeChange();
        }
    });
}

function e_delProj(btn){
    btn.bind('click', function () {
        $.bootstrapLoading.start();
        let selected  = gcTreeObj.tree.selected;
        //backend
        let delDatas = m_getDelDatas(selected);
        if(delDatas.length > 0){
            a_delGC(delDatas, caller);
        }
        //front
        function caller() {
            v_removeNode(selected);
            v_refreshNode(selected, false);
        }
    });
}

function a_getGC(callback){
    CommonAjax.post('/pm/api/getGCDatas', {user_id: userID}, function (rstData) {
        if(callback){
            callback(rstData);
        }
        $.bootstrapLoading.end();
    }, function () {
        $.bootstrapLoading.end();
    });
}

function a_rec(nodes, callback){
    CommonAjax.post('/pm/api/recGC', {user_id: userID, nodes: nodes}, function (rstData) {
        if(callback){
            callback();
        }
        $.bootstrapLoading.end();
    }, function () {
        $.bootstrapLoading.end();
    });
}

function a_delGC(delDatas, callback){
    CommonAjax.post('/pm/api/delGC', {user_id: userID, delDatas: delDatas}, function(rstData){
        if(callback){
            callback();
        }
        $.bootstrapLoading.end();
    }, function () {
        $.bootstrapLoading.end();
    });
}

//去除重名，回收站不处理重名，只保证恢复到项目管理中不出现重名
function deWeightName(datas){
    let rst = [];
    let _deWeight = Object.create(null), prefix = 'name_';
    //按同名分组
    for(let i = 0, len = datas.length; i < len; i++){
        let data = datas[i];
        let _names = _deWeight[prefix + data.updateData.name] || null;
        if(!_names){
            _names = _deWeight[prefix + data.updateData.name] = [];
        }
        if(_names){
            _names.push(data);
        }
    }
    for(let _name in _deWeight){
        let sameNameDatas = _deWeight[_name];
        let count = 0;
        for(let i = 0, len = sameNameDatas.length; i < len; i++){
            let postFix = '（' + count + '）';
            if(i > 0){
                sameNameDatas[i].updateData.name = sameNameDatas[i].updateData.name + postFix;
            }
            count ++;
            rst.push(sameNameDatas[i]);
        }
    }
    return rst;
}

//去除名称后缀(Date恢复)
function delPostFix (str){
    let rst = '';
    rst = delPostRecFix(delPostNameFix(str));
    return rst;
}
function delPostRecFix (str){
    let rst = '';
    let re = /（+[0-9]{2}-[0-9]{2}\s+[0-9]{2}:[0-9]{2}:[0-9]{2}恢复）/g;
    rst = str.replace(re, '');
    return rst;
}
function delPostNameFix (str){
    let rst = '';
    let re = /（+[0-9][0-9]*）/g;
    rst = str.replace(re, '');
    return rst;
}

function deleted(node){
    return node.data.deleteInfo !== undefined && node.data.deleteInfo && node.data.deleteInfo.deleted;
}

function fileEmpty(node){
    return node.data.unitPriceFiles.length === 0 && node.data.feeRateFiles.length === 0;
}

function fIsExist(files, id, type){
    let isExist = false;
    for(let i = 0, len = files.length; i < len; i++){
        if((type === fileType.unitPriceFile && files[i].id === parseInt(id)) || (type === fileType.feeRateFile && files[i].ID === id)){
            isExist = true;
            break;
        }
    }
    return isExist;
}

//删除的文件是否会导致建设项目不再存有文件
function fileWillEmpty(proj, delIds, type){
    let ufs = proj.data.unitPriceFiles,
        ffs = proj.data.feeRateFiles;
    let theFiles = type === fileType.unitPriceFile ? ufs : ffs;
        otherFiles = type === fileType.unitPriceFile ? ffs : ufs;
    let uniqIds = Array.from(new Set(delIds));
    if(theFiles.length === delIds.length){
        for(let id of uniqIds){
            if(!fIsExist(theFiles, id, type)){
                return false;
            }
        }
    }
    if(otherFiles.length === 0){
        return true;
    }
    return false;
}

function getRecFileObj(files){
    let rst = Object.create(null);
    let rst_UF = [], rst_FF = [];
    for(let i = 0, len = files.length; i < len; i++){
        if(files[i].findData !== undefined){
            if(files[i].updateType === fileType.unitPriceFile && files[i].findData.id !== undefined){
                rst_UF.push(files[i].findData.id);
            }
            else if(files[i].updateType === fileType.feeRateFile && files[i].findData.ID !== undefined){
                rst_FF.push(files[i].findData.ID);
            }
        }
    }
    rst[fileType.unitPriceFile] = rst_UF;
    rst[fileType.feeRateFile] = rst_FF;
    return rst;
}

function getUpdateObj(updateType, findData, updateData){
    let obj = Object.create(null);
    obj.updateType = updateType;
    obj.findData = findData;
    obj.updateData = updateData;
    return obj;
}

function getUpdateDatas(updateType, node, mtNID, mtPM){
    let rst = [];
    decDate = '（' + new Date().Format('MM-dd hh:mm:ss') + '恢复）';
    let newName = delPostFix(node.data.name) + decDate;
    if(updateType === projectType.tender || updateType === projectType.engineering){
        //维护项目管理树
        if(mtPM){
            rst.push(getUpdateObj(updateType, {ParentID: node.data.ParentID, NextSiblingID: -1, deleteInfo: null}, {NextSiblingID: node.data.ID}));
        }
        //恢复
        if(mtNID){
            rst.push(getUpdateObj(updateType, {ID: node.data.ID}, {name: newName, deleteInfo: null, NextSiblingID: mtNID}));
        }
        else {
            rst.push(getUpdateObj(updateType, {ID: node.data.ID}, {name: newName, deleteInfo: null}));
        }
    }
    else if(updateType === projectType.project){
        //恢复
        rst.push(getUpdateObj(updateType, {ID: node.data.ID}, {deleteInfo: null, name: newName}));//NextSibling为undefined,后端处理
    }
    return rst;
}
//unitPriceFile or feeRateFile
function getUpdateFiles(tenders, project){
    let rstUF = [], rstFF = [], rst = [];
    let _unitFiles = Object.create(null), _feeFiles = Object.create(null), prefix = '_id';
    decDate = '（' + new Date().Format('MM-dd hh:mm:ss') + '恢复）';
    for(let i = 0, len = tenders.length; i < len; i++){
        //恢复单价文件
        if(project && project.data.unitPriceFiles.length > 0 && fIsExist(project.data.unitPriceFiles, tenders[i].data.property.unitPriceFile.id, fileType.unitPriceFile)){
            //unitFiles.push(tenders[i].data.property.unitPriceFile.id);
            let propId = tenders[i].data.property.unitPriceFile.id;
            let propName = tenders[i].data.property.unitPriceFile.name;
            let _uf = _unitFiles[prefix + propId] || null;
            if(!_uf){
                let obj = Object.create(null);
                obj.id = parseInt(propId);
                obj.name = propName;
                _unitFiles[prefix + propId] = obj;
            }
        }
        //恢复费率文件
        if(project && project.data.feeRateFiles.length > 0 && fIsExist(project.data.feeRateFiles, tenders[i].data.property.feeFile.id, fileType.feeRateFile)){
            //feeFiles.push(tenders[i].data.property.feeFile.id);
            let propId = tenders[i].data.property.feeFile.id;
            let propName = tenders[i].data.property.feeFile.name;
            let _ff = _feeFiles[prefix + propId] || null;
            if(!_ff){
                let obj = Object.create(null);
                obj.id = propId;
                obj.name = propName;
                _feeFiles[prefix + propId] = obj;
            }
        }
    }
    for(let uf in _unitFiles){
        rstUF.push(getUpdateObj(fileType.unitPriceFile, {id: _unitFiles[uf].id}, {deleteInfo: null, name: delPostFix(_unitFiles[uf].name) + decDate}));
    }
    for(let ff in _feeFiles){
        rstFF.push(getUpdateObj(fileType.feeRateFile, {ID: _feeFiles[ff].id}, {deleteInfo: null, name: delPostFix(_feeFiles[ff].name) + decDate}));
    }
    rst = rst.concat(deWeightName(rstUF));
    rst = rst.concat(deWeightName(rstFF));
    return rst;
}
