| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279 | /** * Created by Zhong on 2017/10/30. */let gcTree = null;let decDate = null;//恢复后的名称后缀(时间+恢复)//恢复路径t = tender, e = engineering, p = projectconst 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            if (showTreeLine) {                // Draw Horizontal Line                if (centerX < x + w) {                    drawLine(ctx, centerX, centerY, Math.min(x1, x + w), centerY, 'gray');                    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, 'gray');                    } else {                        drawLine(ctx, centerX, y, centerX, y1, 'gray');                    }                }            }            // 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, 'gray');                        }                    }                    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 && hitinfo.x < centerX + halfBoxLength && hitinfo.y > centerY - halfBoxLength && hitinfo.y < centerY + halfBoxLength) {                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();        $.bootstrapLoading.end();    });}//项目恢复模态框标题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">×</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;}//获得勾选的单价、费率文件的idfunction 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 dispName = $('td:eq(0)', $(nodes[i])[0].parentNode.parentNode)[0].textContent;            let name = dispName.slice(0, dispName.length - 4);            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 () {        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}));        }        //恢复建设项目        if(updateDatas.length > 0 && deleted(selected)){            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);                }            }        }    });}//点击单价、费率文件的清除操作(确认)function e_delFiles(btn){    btn.bind('click', function () {        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 () {        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);        }    });}function e_delProj(btn){    btn.bind('click', function () {        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);        }    });}function a_rec(nodes, callback){    CommonAjax.post('/pm/api/recGC', {user_id: userID, nodes: nodes}, function (rstData) {        if(callback){            callback();        }    });}function a_delGC(delDatas, callback){    CommonAjax.post('/pm/api/delGC', {user_id: userID, delDatas: delDatas}, function(rstData){        if(callback){            callback();        }    })}//去除重名,回收站不处理重名,只保证恢复到项目管理中不出现重名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 feeRateFilefunction 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;}
 |