소스 검색

工程编号相关

zhongzewei 6 년 전
부모
커밋
3ebc3eaab4

+ 1 - 0
modules/all_models/projects.js

@@ -18,6 +18,7 @@ const ProjectSchema = new Schema({
     "ParentID": Number,
     "NextSiblingID": Number,
     "userID": String,
+    "code": {type: String, default: ''},
     "name": String,
     "projType": String,
     "recentDateTime": Date,

+ 9 - 0
public/web/sheet/sheet_common.js

@@ -372,6 +372,15 @@ var sheetCommonObj = {
                 sheet.getRange(-1,col, -1, 1, GC.Spread.Sheets.SheetArea.viewport).locked(true);
             }
         }
+        if (setting && Array.isArray(setting.view.lockRows) && setting.view.lockRows.length) {
+            if (!setting.view.lockColumns || !setting.view.lockColumns.length) {
+                sheet.options.isProtected = true;
+                sheet.getRange(-1, 0, -1, setting.header.length, GC.Spread.Sheets.SheetArea.viewport).locked(false);
+            }
+            setting.view.lockRows.forEach(row => {
+                sheet.getRange(row, -1, 1, -1, GC.Spread.Sheets.SheetArea.viewport).locked(true);
+            });
+        }
     },
     setCheckBoxCell(row,col,sheet,val){
         var c = this.getCheckBox();

+ 2 - 1
web/building_saas/main/html/main.html

@@ -2086,10 +2086,11 @@
             <div class="modal-body">
                 <div class="modal-auto-height" style="overflow: hidden" id="exportSpread">
                 </div>
+                <p>*工程编号作为单项、单位工程的标识,要求在建设项目下唯一。</p>
             </div>
             <div class="modal-footer">
+                <button type="button" class="btn btn-primary" id="exportCode-confirm">确定</button>
                 <button type="button" class="btn btn-secondary" data-dismiss="modal">关闭</button>
-                <button type="button" class="btn btn-primary" data-dismiss="modal" id="exportCode-confirm">确定</button>
             </div>
         </div>
     </div>

+ 76 - 22
web/building_saas/main/js/models/exportStandardInterface.js

@@ -181,6 +181,7 @@ const XMLStandard = (function () {
             exportKind = ExportKind.Tender;
         }
         this.exportKind = exportKind;
+        this.originalDatas = []; //未转换为xml字符串的数据
         this.fileDatas = [];
         /*
          * 检查
@@ -195,7 +196,7 @@ const XMLStandard = (function () {
             let rst = {failHints: [], filterAttrs: []};
             let dateReg = /([0-9]{3}[1-9]|[0-9]{2}[1-9][0-9]{1}|[0-9]{1}[1-9][0-9]{2}|[1-9][0-9]{3})-(((0[13578]|1[02])-(0[1-9]|[12][0-9]|3[01]))|((0[469]|11)-(0[1-9]|[12][0-9]|30))|(02-(0[1-9]|[1][0-9]|2[0-8])))/;
             for (let data of datas) {
-                data.value = typeof data.value === 'undefined' || data.value === null ? '' : data.value.toString();
+                data.value = typeof data.value === 'undefined' || data.value === null ? '' : String(data.value);
                 if (data.whiteSpace && data.whiteSpace === WHITE_SPACE.COLLAPSE) {  //处理空格相关
                     data.value = data.value.replace(/[\r,\n,\t]/g, ' ');
                     data.value = data.value.trim();
@@ -250,7 +251,7 @@ const XMLStandard = (function () {
                     } else if (!data.value.length || (data.value.split('.').length > 1 && data.value.split('.')[1].length > 2)){
                         isFail = true;
                     }
-                } else if (data.type && data.type === TYPE.BOOL && !['true', 'false'].includes(data.value.toString())) {
+                } else if (data.type && data.type === TYPE.BOOL && !['true', 'false'].includes(String(data.value))) {
                     isFail = true;
                     tempFail = data.failHint
                         ? `${data.failHint}必须为true或false。`
@@ -1283,7 +1284,7 @@ const XMLStandard = (function () {
             if (!expr) {
                 return '';
             }
-            expr = expr.toString();
+            expr = String(expr);
             //提取基数
             let bases = expr.split(/[\+\-\*\/]/g);
             //提取操作符
@@ -1322,7 +1323,6 @@ const XMLStandard = (function () {
             }
             return newExpr;
         }
-
         //获取需要导出的项目数据
         //@param {Number}tenderID(当前界面的单位工程ID,后台根据这个单位工程,去找其建设项目下所有数据)
         //@return {Object}(eleObj)
@@ -2260,7 +2260,7 @@ const XMLStandard = (function () {
                     let adjPrice = gljUtil.getAdjustPrice(glj, detail.projectGLJ.datas,
                         curPMData.tender.property.calcOptions, detail.labourCoe.datas, curPMData.tender.property.decimal, false, _, scMathUtil);
                     //获取人材机费用类别: 1=人工费 2=材料费 3=机械费 4=未计价费
-                    let feeType = glj.type.toString()[0];
+                    let feeType = String(glj.type)[0];
                     if (feeType && !['1', '2', '3'].includes(feeType)) {
                         feeType = '4';
                     }
@@ -2430,6 +2430,55 @@ const XMLStandard = (function () {
                 return output.join('');
             }
         }
+        //获取工程编号表格相关数据(导出需要弹出工程编号让用户选择)
+        this.getSheetData = function (PMData) {
+            let curCode = '0';
+            let sheetData = [];
+            sheetData.push(getObj(PMData));
+            PMData.children.forEach(eng => {
+                sheetData.push(getObj(eng));
+                eng.children.forEach(tender => {
+                    sheetData.push(getObj(tender));
+                });
+            });
+            //建设项目父ID设置为-1
+            if (sheetData.length) {
+                sheetData[0].ParentID = -1;
+                sheetData[0].code = '';
+            }
+            return sheetData;
+            function getObj(data) {
+                return {
+                    collapsed: false,
+                    ID: data.ID,
+                    ParentID: data.ParentID,
+                    NextSiblingID: data.NextSiblingID,
+                    name: data.name,
+                    code: data.code || String(curCode++)
+                };
+            }
+        };
+        //从srcNode节点中获取为target实例的节点
+        function getNodeFromSrc(srcNode, target) {
+            if (!srcNode || !srcNode.children || !srcNode.children.length) {
+                return [];
+            }
+            return srcNode.children.filter(node => node instanceof target);
+        }
+        //设置完工程编号后,更新原始数据
+        this.setupCode = function (codeDatas) {
+            this.originalDatas.forEach(orgData => {
+                let curIdx = 0;
+                let engs = getNodeFromSrc(orgData.data, Engineering);
+                engs.forEach(eng => {
+                    eng.attrs.find(attr => attr.name === '编号').value = codeDatas[curIdx++];
+                    let tenders = getNodeFromSrc(eng, Tender);
+                    tenders.forEach(tender => {
+                        tender.attrs.find(attr => attr.name === '编号').value = codeDatas[curIdx++];
+                    });
+                });
+            });
+        };
         /*
          * 导出数据
          * @param {Number}tenderID(当前界面的单位工程ID,后台根据这个单位工程,根据导出粒度去找其建设项目下相关数据)
@@ -2442,33 +2491,38 @@ const XMLStandard = (function () {
             }
             let eleData = await loadProject(tenderID);
             this.datas = eleData;
+            this.PMData = curPMData.project;
             if (!eleData) {
                 return;
             }
-            //转换成xml字符串
-            let xmlStr = toXMLStr([eleData]);
-            //加上xml声明
-            xmlStr = `<?xml version="1.0" encoding="utf-8"?>${xmlStr}`;
-            //格式化
-            xmlStr = formatXml(xmlStr);
-            let blob = new Blob([xmlStr], {type: 'text/plain;charset=utf-8'});
-            failList = [];
-            this.fileDatas.push({blob: blob, fileName: `重庆标准交换数据(${FILE_KIND[exportKind]}).QTF`});
-            return blob;
-            saveAs(blob, '重庆标准交换数据.QTF');
-        }
+            this.originalDatas.push({data: this.datas, fileName: `重庆标准交换数据(${FILE_KIND[exportKind]}).QTF`});
+        };
         //导出文件
         this.exportFile = async function () {
-            if (this.fileDatas.length === 1) {  //导出文件
-                saveAs(this.fileDatas[0].blob, this.fileDatas[0].fileName);
-            } else if (this.fileDatas.length > 1) { //导出压缩包
+            let fileDatas = [];
+            //源数据转换成blob
+            for (let orgData of this.originalDatas) {
+                //转换成xml字符串
+                let xmlStr = toXMLStr([orgData.data]);
+                //加上xml声明
+                xmlStr = `<?xml version="1.0" encoding="utf-8"?>${xmlStr}`;
+                //格式化
+                xmlStr = formatXml(xmlStr);
+                let blob = new Blob([xmlStr], {type: 'text/plain;charset=utf-8'});
+                fileDatas.push({blob: blob, fileName: orgData.fileName});
+            }
+            //导出文件
+            if (fileDatas.length === 1) {
+                saveAs(fileDatas[0].blob, fileDatas[0].fileName);
+            } else if (fileDatas.length > 1) { //导出压缩包
                 let zip = new JSZip();
-                for (let file of this.fileDatas) {
+                for (let file of fileDatas) {
                     zip.file(file.fileName, file.blob, {binary: true});
                 }
                 let zipFile = await zip.generateAsync({type: 'blob'});
                 saveAs(zipFile, '重庆标准交换数据.zip');
             }
-        }
+        };
+
     }
 })();

+ 5 - 1
web/building_saas/main/js/models/importStandardInterface.js

@@ -242,6 +242,7 @@ const ImportXML = (() => {
                 return {
                     projType: ProjectType.Engineering,
                     name: getValue(src, ['_名称']),
+                    code: getValue(src, ['_编号']),
                     tenders: loadTender(src)
                 };
             });
@@ -254,6 +255,7 @@ const ImportXML = (() => {
                 return {
                     projType: ProjectType.Tender,
                     name: getValue(src, ['_名称']),
+                    code: getValue(src, ['_编号']),
                     engineering: getValue(src, ['_专业']),    //可能跟我们软件里的工程专业对应不上
                     projectFeature: loadProjectFeature(src),
                     feeSummary: loadFeeSummary(src),     //单位工程费汇总
@@ -1291,7 +1293,7 @@ const ImportXML = (() => {
             };
             for (let i = 0; i < xmlObj.engs.length; i++) {
                 let curEng = xmlObj.engs[i],
-                    preEng = xmlObj.engs[i - 1];
+                    preEng = postConstructData.engs[i - 1];
                 curEng.ID = IDPlaceholder.project++;
                 curEng.ParentID = xmlObj.ID;
                 curEng.NextSiblingID = -1;
@@ -1302,6 +1304,7 @@ const ImportXML = (() => {
                     ID: curEng.ID,
                     ParentID: curEng.ParentID,
                     NextSiblingID: curEng.NextSiblingID,
+                    code: curEng.code,
                     name: curEng.name,
                     projType: curEng.projType,
                     shareInfo: [],
@@ -1336,6 +1339,7 @@ const ImportXML = (() => {
                 ID: tenderData.ID,
                 ParentID: tenderData.ParentID,
                 NextSiblingID: tenderData.NextSiblingID,
+                code: tenderData.code,
                 name: tenderData.name,
                 projType: tenderData.projType,
                 property: tenderData.property,

+ 114 - 14
web/building_saas/main/js/views/export_view.js

@@ -15,14 +15,40 @@ const ExportView = (() => {
         header: [
             {headerName: '名称', headerWidth: 200, dataCode: 'name', dataType: 'String'},
             {headerName: '工程编号', headerWidth: 200, dataCode: 'code', dataType: 'String'},
-        ]
+        ],
+        view: {
+            lockColumns: ['name'],
+            lockRows: [0]
+        }
     };
+    //操作状态
+    const STATE = {
+        checking: false,    //自检
+        exporting: false,   //导出
+        confirming: false   //导出确认
+    };
+    let spread = null;
     //初始化设置工程编号表格
-    function initSpread() {
-        let spread = SheetDataHelper.createNewSpread($("#exportSpread")[0], 1);
+    function initSpread(datas) {
+        if (spread) {
+            return;
+        }
+        spread = SheetDataHelper.createNewSpread($("#exportSpread")[0], 1);
         sheetCommonObj.spreadDefaultStyle(spread);
         let sheet = spread.getSheet(0);
         sheetCommonObj.initSheet(sheet, sheetSetting, 30);
+        sheet.setRowCount(datas.length);
+        sheetCommonObj.showTreeData(sheet, sheetSetting, datas);
+    }
+    //获取设置的工程编号
+    function getCodeFromSheet(sheet) {
+        let codeCol = 1;
+        let rst = [];
+        //排除建设项目行
+        for (let row = 1; row < sheet.getRowCount(); row++) {
+            rst.push(sheet.getValue(row, codeCol) || '');
+        }
+        return rst;
     }
     //事件监听
     function exportListener() {
@@ -32,10 +58,14 @@ const ExportView = (() => {
             if (!checkedDatas.length) {
                 return;
             }
+            if (STATE.checking) {
+                return;
+            }
+            STATE.checking = true;
             let pr = new SCComponent.InitProgressBar();
-            pr.start('导出数据接口', '正在自检,请稍候……');
             try {
-                if (!xmlObj || !xmlObj.fileDatas.length) {
+                if (!xmlObj || !xmlObj.originalDatas.length) {
+                    pr.start('导出数据接口', '正在自检,请稍候……');
                     xmlObj = new XMLStandard(userID, 1);
                     for (let checkedData of checkedDatas) {
                         let fileKind = $(checkedData).val();
@@ -53,50 +83,120 @@ const ExportView = (() => {
                 alert(err);
             }
             pr.end();
+            setTimeout(() => {
+                STATE.checking = false;
+            }, 300);
         });
 
-        //导出接口,如果选中多个文件,导出压缩包
+        //导出接口,如果没有错误,弹出工程编号设置窗口
         $('#export-confirm').click(async function () {
             let checkedDatas = $('#export input[type="checkbox"]:checked');
             if (!checkedDatas.length) {
                 return;
             }
+            if (STATE.exporting) {
+                return;
+            }
+            STATE.exporting = true;
             let pr = new SCComponent.InitProgressBar();
-            pr.start('导出数据接口', '正在导出文件,请稍候……')
             try {
-                if (!xmlObj || !xmlObj.fileDatas.length) {
+                let isPring = false;    //是否调用了进度条(控制工程窗口什么时候显示,优化交互)
+                if (!xmlObj || !xmlObj.originalDatas.length) {
+                    isPring = true;
+                    pr.start('导出数据接口', '正在导出文件,请稍候……');
                     xmlObj = new XMLStandard(userID, 1);
                     for (let checkedData of checkedDatas) {
                         let fileKind = $(checkedData).val();
                         await xmlObj.toXml(projectObj.project.ID(), fileKind);
                     }
+                    pr.end();
                 }
-                console.log(xmlObj);
-                //设置提示弹窗
+                //错误-设置提示弹窗
                 if (xmlObj.failList.length * 20 > 400) {
                     $('#hintBox_caption').addClass('export-check');
                 }
                 if (xmlObj.failList.length) {
                     throw xmlObj.failList.join('<br/>');
                 }
-                //可能先执行过自检了,已经有组装好的数据了,可以直接导出
+                //弹出工程编号设置窗口
+                if (isPring) {
+                    setTimeout(() => {
+                        $('#exportCode').modal('show');
+                    }, 300);
+                } else {
+                    $('#exportCode').modal('show');
+                }
+            } catch (err) {
                 pr.end();
+                alert(err);
+            }
+            setTimeout(() => {
+                STATE.exporting = false;
+            }, 300);
+        });
+        //工程编号设置窗口-----
+        //设置工程编号
+        $('#exportCode').on('shown.bs.modal', function () {
+            if (!xmlObj) {
+                alert('数据错误!');
+                $(this).modal('hide');
+                return false;
+            }
+            initSpread(xmlObj.getSheetData(xmlObj.PMData));
+        });
+        //设置完工程编号后,导出数据。如果选中多个文件,导出压缩包
+        $('#exportCode-confirm').click(async function () {
+            if (!spread || !xmlObj) {
+                return false;
+            }
+            if (STATE.confirming) {
+                return;
+            }
+            STATE.confirming = true;
+            let pr = new SCComponent.InitProgressBar();
+            try {
+                let codeDatas = getCodeFromSheet(spread.getSheet(0));
+                if (codeDatas.includes('')) {
+                    alert('单项、单位工程工程编号不可为空。');
+                    STATE.confirming = false;
+                    return false;
+                }
+                if ([...new Set(codeDatas)].length !== codeDatas.length) {
+                    alert('单项、单位工程工程编号必须唯一。');
+                    STATE.confirming = false;
+                    return false;
+                }
+                xmlObj.setupCode(codeDatas);
+                pr.start('导出数据接口', '正在导出文件,请稍候……');
                 await xmlObj.exportFile();
-                console.log(xmlObj);
-                $('#export').modal('hide');
             } catch (err) {
-                pr.end();
                 alert(err);
             }
+            console.log(xmlObj);
+            pr.end();
+            $('#exportCode').modal('hide');
+            $('#export').modal('hide');
+            setTimeout(() => {
+                STATE.confirming = false;
+            }, 300);
+
         });
+        //导出窗口--------
         $('#export').on('show.bs.modal', function () {
             xmlObj = null;
         });
         $('#export').on('hide.bs.modal', function() {
             xmlObj = null;
+            STATE.checking = false;
+            STATE.exporting = false;
+            STATE.confirming = false;
             //恢复设置提示弹窗 因为是共用的alert
             $('#hintBox_caption').removeClass('export-check');
             $('#export input[type="checkbox"]:eq(0)').prop('checked', true);
+            if (spread) {
+                spread.destroy();
+                spread = null;
+            }
         });
         $('#export input[type="checkbox"]').click(function () {
             xmlObj = null;

+ 7 - 1
web/building_saas/pm/js/pm_ajax.js

@@ -24,7 +24,7 @@ var GetAllProjectData = function (callback) {
     });
 }
 // 更新数据到服务器
-var UpdateProjectData = function (updateData, callback) {
+var UpdateProjectData = function (updateData, callback, errCB) {
     $.ajax({
         type:"POST",
         url: '/pm/api/updateProjects',
@@ -36,10 +36,16 @@ var UpdateProjectData = function (updateData, callback) {
             if (result.error === 0) {
                 callback(result.data);
             } else {
+                if (errCB) {
+                    errCB();
+                }
                 alert('error: ' + result.message);
             }
         },
         error: function(jqXHR, textStatus, errorThrown){
+            if (errCB) {
+                errCB();
+            }
             alert('error ' + textStatus + " " + errorThrown);
         }
     });

+ 12 - 3
web/building_saas/pm/js/pm_import.js

@@ -435,6 +435,10 @@ const importView = (() => {
         });
         //确认导入
         $('#import-confirm').click(async function () {
+            if (STATE.importing) {
+                return;
+            }
+            STATE.importing = true;
             if (tbcObj && tbcObj.checkValid()) {
                 return;
             }
@@ -467,9 +471,9 @@ const importView = (() => {
                 }
                 //console.log(xmlObj);
                 $('#importInterface').modal('hide');
-                //let importData = await importXML.transformData(xmlObj);
+                /*let importData = await importXML.transformData(xmlObj);
+                console.log(importData);*/
                 pr.start('导入文件', '正在生成文件,请稍候……');
-
                 let importData = await importXML.transformData(xmlObj);
                 let blob = new Blob([JSON.stringify(importData)], {type: 'text/plain;charset=utf-8'});
                 console.log(blob);
@@ -488,6 +492,9 @@ const importView = (() => {
                             doAfterImport(response.data);
                         }
                         pr.end();
+                        setTimeout(function () {
+                            STATE.importing = false;
+                        }, 500);
                     },
                     error: function(jqXHR){
                         pr.end();
@@ -495,7 +502,9 @@ const importView = (() => {
                     }
                 });
             } catch (err) {
-                console.log(err);
+                setTimeout(function () {
+                    STATE.importing = false;
+                }, 500);
                 pr.end();
                 alert(err);
             }

+ 125 - 46
web/building_saas/pm/js/pm_newMain.js

@@ -65,6 +65,15 @@ function delayKeyup(callback) {
     }, delayTime);
 }
 const addPath = {p_e_t: 'p_e_t', e_t: 'e_t', t: 't'};
+//操作状态
+const STATE = {
+    addingTender: false,
+    addingEng: false,
+    addingProject: false,
+    addingFolder: false,
+    deleting: false,
+    importing: false
+};
 const projTreeObj = {
     tree: null,
     workBook: null,
@@ -1630,10 +1639,17 @@ $(document).ready(function() {
         if (!validRequiredData($('#projInfoStep'))) {
             return;
         }
+        if (STATE.addingProject) {
+            return;
+        }
+        STATE.addingProject = true;
         if (needfulInfoData && Array.isArray(needfulInfoData)) {
             updateRequiredData($('#projInfoStep'), needfulInfoData);
         }
-        AddProject();
+        let suc = AddProject();
+        if (suc === false) {
+            STATE.addingProject = false;
+        }
     });
     //新建建设项目-下一步
     $('#add-proj-next').click(function () {
@@ -1811,7 +1827,14 @@ $(document).ready(function() {
 
     // 新增单项工程操作
     $("#add-engineering-confirm").click(function() {
-        AddEngineering();
+        if (STATE.addingEng) {
+            return;
+        }
+        STATE.addingEng = true;
+        let suc = AddEngineering();
+        if (suc === false) {
+            STATE.addingEng = false;
+        }
     });
 
     //新建单位工程-建设项目提示
@@ -2205,12 +2228,16 @@ $(document).ready(function() {
 
     // 新增单位工程
     $("#add-tender-confirm").click(function() {
+        if (STATE.addingTender) {
+            return;
+        }
         if (getAddPath() === addPath.p_e_t && !validRequiredData($('#infoStep'))) {
             return;
         }
         if (!validRequiredData($('#featureStep'))) {
             return;
         }
+        STATE.addingTender = true;
         if (needfulInfoData && Array.isArray(needfulInfoData)) {
             updateRequiredData($('#infoStep'), needfulInfoData);
         }
@@ -2219,13 +2246,20 @@ $(document).ready(function() {
         }
         let suc = AddTender();
         if(suc === false){
-            $('#add-tender-confirm').removeClass('disabled');
+            STATE.addingTender = false;
         }
     });
 
     // 新增文件夹操作
     $("#add-folder-confirm").click(function() {
-        AddFolder();
+        if (STATE.addingFolder) {
+            return;
+        }
+        STATE.addingFolder = true;
+        let suc = AddFolder();
+        if (suc === false) {
+            STATE.addingFolder = false;
+        }
     });
 
     // 删除时文字替换
@@ -2264,9 +2298,13 @@ $(document).ready(function() {
 
     // 删除操作
     $('#delete-confirm').click(function () {
+        if (STATE.deleting) {
+            return;
+        }
+        STATE.deleting = true;
         let updateData = null;
         let dialog = $('#del');
-        if (projTreeObj.tree) {
+        if (projTreeObj.tree && projTreeObj.tree.selected) {
             updateData = GetDeleteUpdateData(projTreeObj.tree.selected);
             UpdateProjectData(updateData, function () {
                 dialog.modal('hide');
@@ -2283,6 +2321,14 @@ $(document).ready(function() {
                 if(selected.data.projType == projectType.tender||selected.data.projType == projectType.engineering){
                     projTreeObj.refreshNodeData(refreshNodes);//刷新工程造价信息
                 }
+                //快速点击时,第一个项目删除成功了,可能会删除多项目
+                setTimeout(function () {
+                    STATE.deleting = false;
+                }, 500);
+            }, function () {
+                setTimeout(function () {
+                    STATE.deleting = false;
+                }, 500);
             });
         }
     });
@@ -2696,11 +2742,21 @@ function AddProject() {
     }
     let existCallback = function () {
         setDangerInfo($('#project-name-info'), `已存在“${$("#project-name").val()}”`);
+        STATE.addingProject = false;
     };
     let sucCallback = function () {
+        $('#addProjOk').removeClass('disabled');
         $('#add-project-dialog').modal('hide');
         $('#project-name').val('');
         setDangerInfo($('#project-name-info'), '', false);
+        setTimeout(function () {
+            STATE.addingProject = false;
+        }, 500);
+    };
+    let errCB = function () {
+        setTimeout(function () {
+            STATE.addingProject = false;
+        }, 500);
     };
     let selectedItem = projTreeObj.tree.selected;
 
@@ -2718,18 +2774,18 @@ function AddProject() {
         valuationType: curValutionType
     };
     if(!selectedItem){
-        AddSiblingsItem(selectedItem, name, property, projectType.project, existCallback, sucCallback);
+        AddSiblingsItem(selectedItem, name, property, projectType.project, existCallback, sucCallback, errCB);
     }
     else {
         if(selectedItem.data.projType === projectType.project){
-            AddSiblingsItem(selectedItem, name, property, projectType.project, existCallback, sucCallback);
+            AddSiblingsItem(selectedItem, name, property, projectType.project, existCallback, sucCallback, errCB);
         }
         else if(selectedItem.data.projType === projectType.engineering || selectedItem.data.projType === projectType.tender){
             let proj = selectedItem.parent.data.projType === projectType.project ? selectedItem.parent : selectedItem.parent.parent;
-            AddSiblingsItem(proj, name, property, projectType.project, existCallback, sucCallback);
+            AddSiblingsItem(proj, name, property, projectType.project, existCallback, sucCallback, errCB);
         }
         else if(selectedItem.data.projType === projectType.folder){
-            AddChildrenItem(selectedItem, name, property, projectType.project, existCallback, sucCallback);
+            AddChildrenItem(selectedItem, name, property, projectType.project, existCallback, sucCallback, errCB);
         }
     }
 }
@@ -2788,7 +2844,7 @@ function getAddPath() {
     }
 }
 
-function AddTenderItems(selected, projName, engName, tenderName, property, callback){
+function AddTenderItems(selected, projName, engName, tenderName, property, callback, errCB){
     let path, updateDatas = [];
     let tempProjs = getProjs(selected);
     let tempProj = getNodeByName(projName, tempProjs);
@@ -2857,8 +2913,8 @@ function AddTenderItems(selected, projName, engName, tenderName, property, callb
                 let engNode = projTreeObj.insert(engData, pojNode, null);
                 projTreeObj.insert(tenderData, engNode, null);
                 callback();
-            });
-        });
+            }, errCB);
+        }, errCB);
     }
     else if(path === addPath.e_t){
         GetNewProjectId(2, function (IDs) {
@@ -2895,8 +2951,8 @@ function AddTenderItems(selected, projName, engName, tenderName, property, callb
                 let engNode = projTreeObj.insert(engData, tempProj, next);
                 projTreeObj.insert(tenderData, engNode, null);
                 callback();
-            });
-        });
+            }, errCB);
+        }, errCB);
     }
     else if(path === addPath.t){
         GetNewProjectId(1, function (IDs) {
@@ -2917,8 +2973,8 @@ function AddTenderItems(selected, projName, engName, tenderName, property, callb
                     }
                 });
                 callback();
-            });
-        });
+            }, errCB);
+        }, errCB);
     }
 }
 
@@ -2930,7 +2986,7 @@ function AddTenderItems(selected, projName, engName, tenderName, property, callb
  * @param {function} callback
  * @return {void}
  */
-function AddChildrenItem(selected, name, property, type, existCallback, sucCallback) {
+function AddChildrenItem(selected, name, property, type, existCallback, sucCallback, errCB) {
     if(!selected){
         selected = projTreeObj.tree.selected;
     }
@@ -2956,8 +3012,8 @@ function AddChildrenItem(selected, name, property, type, existCallback, sucCallb
                     }
                 });
                 sucCallback();
-            });
-        });
+            }, errCB);
+        }, errCB);
     }
 }
 
@@ -2969,14 +3025,13 @@ function AddChildrenItem(selected, name, property, type, existCallback, sucCallb
  * @param {function} callback
  * @return {void}
  */
-function AddSiblingsItem(selected, name, property, type, existCallback, sucCallback) {
+function AddSiblingsItem(selected, name, property, type, existCallback, sucCallback, errCB) {
     if(!selected){
         selected = projTreeObj.tree.selected;
     }
     let parent = selected ? selected.parent : projTreeObj.tree._root;
     let next = selected ? selected.nextSibling : projTreeObj.tree.firstNode();
     if(existName(name, parent.children, type)){
-        //alert('同级目录已存在相同名称数据.');
         existCallback();
     }
     else {
@@ -2995,8 +3050,8 @@ function AddSiblingsItem(selected, name, property, type, existCallback, sucCallb
                     }
                 });
                 sucCallback();
-            });
-        });
+            }, errCB);
+        }, errCB);
     }
 }
 
@@ -3337,24 +3392,33 @@ function AddEngineering() {
     name = whiteSpaceCollapse(name);
     let existCallback = function () {
         setDangerInfo($('#engineering-name-info'), `已存在“${$("#engineering-name").val()}”`);
+        STATE.addingEng = false;
     };
     let sucCallback = function () {
         $('#add-engineering-dialog').modal('hide');
         $('#engineering-name').val('');
         setDangerInfo($('#engineering-name-info'), '', false);
+        setTimeout(function () {
+            STATE.addingEng = false;
+        }, 500);
+    };
+    let errCB = function () {
+        setTimeout(function () {
+            STATE.addingEng = false;
+        }, 500);
     };
     let selectedItem = projTreeObj.tree.selected;
     // 如果选择的是单项工程则新增同级数据
     if(selectedItem){
         if(selectedItem.data.projType === projectType.project){
-            AddChildrenItem(selectedItem, name, null, projectType.engineering, existCallback, sucCallback);
+            AddChildrenItem(selectedItem, name, null, projectType.engineering, existCallback, sucCallback, errCB);
         }
         else if(selectedItem.data.projType === projectType.engineering){
-            AddSiblingsItem(selectedItem, name, null, projectType.engineering, existCallback, sucCallback);
+            AddSiblingsItem(selectedItem, name, null, projectType.engineering, existCallback, sucCallback, errCB);
         }
         else if(selectedItem.data.projType === projectType.tender){
             let proj = selectedItem.parent;
-            AddSiblingsItem(proj, name, null, projectType.engineering, existCallback, sucCallback);
+            AddSiblingsItem(proj, name, null, projectType.engineering, existCallback, sucCallback, errCB);
         }
     }
 }
@@ -3366,7 +3430,6 @@ function AddEngineering() {
  */
 function AddTender() {
     try {
-        $('#add-tender-confirm').addClass('disabled');
         let projName = $("#poj-name").val().trim();
         if(projName === ''){
             replaceClass($('#poj-name-info'), 'text-info', 'text-danger');
@@ -3442,7 +3505,7 @@ function AddTender() {
         let libs = getEngineeringLib(engineeringName + feeName, engineeringList);
         if(!libs){
             alert('数据错误,无法确定工程专业库!');
-            return;
+            return false;
         }
         // 一个项目里面,这两个文件必须得有,而界面又没有像费率、单价文件那样给出可选项。所以这里给出提示。
         if (!libs.artificial_lib)  throw '编办没有绑定人工系数标准文件';
@@ -3454,18 +3517,24 @@ function AddTender() {
         let calcProgramName = $('#tender-calcProgram').children("option:selected").text();
 
         let callback = function() {
-            $('#add-tender-confirm').removeClass('disabled');
-            $("#add-tender-dialog").modal("hide");
-            $('#tender-name').val('');
-            $("#tender-fee-rate").children("option").removeAttr("selected");
-            $("#tender-engineering").children("option").removeAttr("selected");
-            $("#tender-calcProgram").children("option").removeAttr("selected");
-            $("#poj-name").val('');
-            $("#poj-name-info").hide();
-            $("#eng-name").val('');
-            $("#eng-name-info").hide();
-
-        };
+                $("#add-tender-dialog").modal("hide");
+                $('#tender-name').val('');
+                $("#tender-fee-rate").children("option").removeAttr("selected");
+                $("#tender-engineering").children("option").removeAttr("selected");
+                $("#tender-calcProgram").children("option").removeAttr("selected");
+                $("#poj-name").val('');
+                $("#poj-name-info").hide();
+                $("#eng-name").val('');
+                $("#eng-name-info").hide();
+                setTimeout(function () {
+                    STATE.addingTender = false;
+                }, 500);
+            },
+            errCB = function () {
+                setTimeout(function () {
+                    STATE.addingTender = false;
+                }, 500);
+            };
         let selectedItem = projTreeObj.tree.selected;
         //地区
         let region = $('#regionDiv').find('select').val() || '全省';
@@ -3498,9 +3567,10 @@ function AddTender() {
         if(libs.main_quantity_lib && libs.main_quantity_lib.length > 0) tenderInfo.mainQuantityLibID = libs.main_quantity_lib[0].id;
         if(libs.material_lib && libs.material_lib.length > 0) tenderInfo.materialLibID = libs.material_lib[0].id;
 
-        AddTenderItems(selectedItem, projName, engName, tenderName, tenderInfo, callback);
+        AddTenderItems(selectedItem, projName, engName, tenderName, tenderInfo, callback, errCB);
 
     } catch (error) {
+        ('#add-tender-confirm').removeClass('disabled');
         alert(error);
     }
 }
@@ -3552,11 +3622,20 @@ function AddFolder() {
     let selectedItem = projTreeObj.tree.selected;
     let existCallback = function () {
         setDangerInfo($('#folder-name-info'), `已存在“${$("#folder-name").val()}”`);
+        STATE.addingFolder = false;
     };
     let sucCallback = function () {
         $('#add-folder-dialog').modal('hide');
         $('#folder-name').val('');
         setDangerInfo($('#folder-name-info'), '', false);
+        setTimeout(function () {
+            STATE.addingFolder = false;
+        }, 500);
+    };
+    let errCB = function () {
+        setTimeout(function () {
+            STATE.addingFolder = false;
+        }, 500);
     };
     if (selectedItem) {
         // 判断是否超过3层
@@ -3565,14 +3644,14 @@ function AddFolder() {
             return false;
         }
         if(selectedItem.data.projType === projectType.folder || selectedItem.data.projType === projectType.project){
-            AddSiblingsItem(null, name, null, projectType.folder, existCallback, sucCallback);
+            AddSiblingsItem(null, name, null, projectType.folder, existCallback, sucCallback, errCB);
         }
         else if(selectedItem.data.projType === projectType.engineering || selectedItem.data.projType === projectType.tender){
             let proj = selectedItem.parent.data.projType === projectType.project ? selectedItem.parent : selectedItem.parent.parent;
-            AddSiblingsItem(proj, name, null, projectType.folder, existCallback, sucCallback);
+            AddSiblingsItem(proj, name, null, projectType.folder, existCallback, sucCallback, errCB);
         }
     } else {
-        AddSiblingsItem(null, name, null, projectType.folder, existCallback, sucCallback);
+        AddSiblingsItem(null, name, null, projectType.folder, existCallback, sucCallback, errCB);
     }
 }
 
@@ -3725,10 +3804,10 @@ function GetNeedUpdatePreNode(parent, next) {
  * @param {function} callback
  * @return {void}
  */
-function GetNewProjectId(count, callback) {
+function GetNewProjectId(count, callback, errCB) {
     CommonAjax.post('/pm/api/getNewProjectID', {count: count}, function(data) {
         callback(data);
-    });
+    }, errCB);
 }
 
 /**