浏览代码

导入项目增加检测机制

vian 5 年之前
父节点
当前提交
88fc42eb25

+ 6 - 2
modules/all_models/import_logs.js

@@ -9,9 +9,13 @@ let collectionName = 'import_logs';
 let modelSchema = {
     // 日志类型
     key: {type: String, index: true},
-    // 日志内容
-    userID: String,
+    // 日志简单内容
+    content: String,
     // 关联用户id
+    userID: String,
+    // 费用定额Id
+    compilationID: String,
+    // 状态
     status:String,
     // 建设项目ID
     projectID: Number,

+ 5 - 0
modules/complementary_ration_lib/models/sectionTreeModel.js

@@ -13,6 +13,11 @@ const sectionTemplateModel = mongoose.model('complementary_ration_section_templa
 class SectionTreeDao {
     //从补充定额章节树模板中拷贝数据到用户的补充定额章节树中
     async copyDataFromTemplate(userId, compilationId){
+        // 如果已经有数据则不再生成
+        const count = await compleRationSectionTreeModel.count({userId, compilationId});
+        if (count) {
+            return;
+        }
         let templateData = await sectionTemplateModel.find({compilationId: compilationId});
         if (templateData.length > 0) {
             let insertDatas = [],

+ 5 - 1
modules/import/controllers/import_controller.js

@@ -17,6 +17,10 @@ let controller = {
         let data = req.body;
         return await pm_facade.importChongqingProject(data);
     },
+    prepareInitialData: async function(req) {
+        const data = req.body;
+        return await pm_facade.prepareInitialData(data.userID, data.compilationID, data.example);
+    },
     exportProject:async function(req){
         let result={
             error:0
@@ -30,7 +34,7 @@ let controller = {
             error:0
         };
         let data = JSON.parse(req.body.dataString);
-        result.data = await pm_facade.copyProject(req.body.userID,req.body.compilationID,data);
+        result.data = await pm_facade.accessToCopyProject(req.body.userID,req.body.compilationID,data);
         return result
     },
     async importInterface (req) {

+ 1 - 0
modules/import/routes/import_route.js

@@ -13,6 +13,7 @@ module.exports = function (app) {
     importRouter.post('/getDataForInterface',importController.action);
     importRouter.post('/loadSEIProjectData',importController.action);
     importRouter.post('/importChongqingProject',importController.action);
+    importRouter.post('/prepareInitialData',importController.action);
     importRouter.get('/test',function (req,res) {
         res.json("hello word");
     })

+ 12 - 3
modules/pm/controllers/pm_controller.js

@@ -354,11 +354,18 @@ module.exports = {
     //第一次进入该费用定额时准备的初始数据
     prepareInitialData: async function(request, response) {
         try {
-            let sessionCompilation = request.session.sessionCompilation;
-            await pm_facade.prepareInitialData(request.session.sessionUser.id, sessionCompilation._id, sessionCompilation.example);
+            //let sessionCompilation = request.session.sessionCompilation;
+            const data = {
+                userID: request.session.sessionUser.id,
+                compilationID: request.session.sessionCompilation._id,
+                example: request.session.sessionCompilation.example
+            };
+            await redirectToImportServer(data, 'prepareInitialData', request);
+            //await pm_facade.prepareInitialData(request.session.sessionUser.id, sessionCompilation._id, sessionCompilation.example);
             callback(request, response, 0, 'success', null);
         } catch(err) {
-            callback(request, response, 1, err, null);
+            console.log(err);
+            callback(request, response, 1, err.toString(), null);
         }
     },
     // 获取单价文件列表
@@ -836,6 +843,8 @@ module.exports = {
         };
         try{
             let data = JSON.parse(req.body.data);
+            data.userID = req.session.sessionUser.id;
+            data.compilationID = req.session.sessionCompilation._id;
             result.data = await pm_facade.importProcessChecking(data);
         } catch (err){
             console.log(err);

+ 151 - 28
modules/pm/facade/pm_facade.js

@@ -17,6 +17,7 @@ module.exports={
     getShareInfoMap,
     getRecentShareList,
     moveProject:moveProject,
+    accessToCopyProject,
     copyProject:copyProject,
     copyExample: copyExample,
     setupSummaryFields: setupSummaryFields,
@@ -303,6 +304,7 @@ async function copyExample(userID, compilation, projIDs){
     //设置新的树结构数据
     let newDate = new Date(),
         parentBulks = [];
+    const projectMaps = [];
     for (let data of allProjs) {
         let orgID = data.ID;
         data.ID = IDMapping[data.ID];
@@ -326,7 +328,8 @@ async function copyExample(userID, compilation, projIDs){
                                 compilation: compilation, fileVer: data.fileVer, projType: data.projType, property: {rootProjectID: rootProjectID}}
                 }
             };
-            await copyProject(userID, compilation, {projectMap}, data.ID);
+            await copyProject(userID, compilation, {projectMap}, data.ID, true);
+            projectMaps.push(projectMap);
         }
     }
     //最末顶层项目(兼容测试时已存在有项目,正常用户第一次进费用定额,该费用定额不存在项目)
@@ -334,12 +337,40 @@ async function copyExample(userID, compilation, projIDs){
     if (lastProj) {
         parentBulks.push({updateOne: {filter: {ID: lastProj.ID}, update: {$set: {NextSiblingID: parentExample[0].ID}}}});
     }
-    //拷贝父级文件
-    await projectModel.bulkWrite(parentBulks);
+    // 处理项目数据
+    const projectTasks = [projectModel.bulkWrite(parentBulks), createProject(projectMaps)];
+    await Promise.all(projectTasks);
     return true;
 }
 
-async function copyProject(userID, compilationID,data,newProjectID = null) {
+async function accessToCopyProject(userID, compilationID, data, newProjectID) {
+    const logData = {
+        key: uuidV1(),
+        content: '正在拷贝项目,请稍候……',
+        userID,
+        compilationID,
+        status: 'start',
+        create_time: +new Date()
+    };
+    await importLogsModel.create(logData);
+    handleCopyProject(logData.key, userID, compilationID,data,newProjectID);
+    return 'copying project';
+}
+
+async function handleCopyProject(key, userID, compilationID, data, newProjectID) {
+    const doc = { status: 'finish' };
+    try {
+        const projectMap = await copyProject(userID, compilationID, data, newProjectID);
+        doc.projectID = projectMap.copy.document.ID;
+    } catch (err) {
+        doc.status = 'error';
+        doc.errorMsg = String(err);
+    } finally {
+        await importLogsModel.update({ key }, doc);
+    }
+}
+
+async function copyProject(userID, compilationID,data,newProjectID = null, delayProjectTask = false) {
     let projectMap = data.projectMap;
     let originalID = projectMap['copy'].document.ID;
     if (!newProjectID) {
@@ -400,7 +431,6 @@ async function copyProject(userID, compilationID,data,newProjectID = null) {
     let [billMap,rationMap,projectGLJMap] = await Promise.all(IDtasks);
     //所有复制任务异步处理,提升效率  复制清单,定额,4个文件,项目工料机, 定额工料机,人工系数,工程量明细,定额安装增加费,安装增加费
     let copyTasks = [
-        createProject(projectMap),
         copyProjectSetting(originalID,newProjectID),
         copyBills(newProjectID,billMap),
         copyRations(newProjectID,billMap.uuidMaping,rationMap,projectGLJMap.IDMap),
@@ -427,8 +457,15 @@ async function copyProject(userID, compilationID,data,newProjectID = null) {
     if(originalProperty.unitPriceFile){
         copyTasks.push(copyUnitPriceFile(newProjectID,originalProperty.rootProjectID,userID,originalProperty.unitPriceFile.id,unitPriceFileID,newUnitName));
     }
-    let p = await Promise.all(copyTasks);
-    return p[0];
+    await Promise.all(copyTasks);
+    // 最后再处理项目数据
+    // 可能会有最后再在外层方法插入项目数据的需求,如拷贝例题,暂时先不在这里插入项目数据
+    if (delayProjectTask) {
+        return [projectMap];
+    } else {
+        const projectMaps = await createProject([projectMap]);
+        return projectMaps[0];
+    }
 }
 
 async function createIDsAndReturn(originalID,model) {
@@ -461,14 +498,16 @@ async function getProjectGLJIDAndReturn(originalID,newProjectID) {
     return{IDMap:IDMap,datas:datas};
 }
 
-async function createProject(projectMap) {//复制项目
+async function createProject(projectMaps) {//复制项目
     let tasks = [];
-    if(projectMap['update']){//如果复制后存在前一个节点,则更新其NextSiblingID
-        tasks.push({updateOne:{filter : projectMap['update'].query, update : {NextSiblingID:projectMap['copy'].document.ID}}});
+    for (const projectMap of projectMaps) {
+        if(projectMap['update']){//如果复制后存在前一个节点,则更新其NextSiblingID
+            tasks.push({updateOne:{filter : projectMap['update'].query, update : {NextSiblingID:projectMap['copy'].document.ID}}});
+        }
+        tasks.push({insertOne: {document: projectMap['copy'].document}});//复制任务
     }
-    tasks.push({insertOne: {document: projectMap['copy'].document}});//复制任务
     await projectModel.bulkWrite(tasks);
-    return projectMap;
+    return projectMaps;
 }
 
 async function copyProjectSetting(originalID,newProjectID) {
@@ -1446,7 +1485,9 @@ async function importChongqingProject(data) {
 
     let log_data = {
         key:data.key,
+        content: '正在导入例题,请稍候……',
         userID:data.user_id,
+        compilationID: data.session.sessionCompilation._id,
         status:"start",
         create_time:+new Date()
     };
@@ -1473,21 +1514,44 @@ async function importChongqingProject(data) {
     }
 }
 
-
+function testTimeout(time) {
+    return new Promise(resolve => setTimeout(resolve, time));
+}
 
 //用户第一次进入费用定额的数据准备
 async function prepareInitialData(userId, compilation, example) {
     let first = await isFirst(userId, compilation);
     if (first) {
         await updateUsedList(userId, compilation);
-        let prepareTask = [
-            copyCompleRationSection(userId, compilation),
-            copyCompleGljSection(userId, compilation)
-        ];
-        if (example && example.length > 0) {
-            prepareTask.push(copyExample(userId, compilation, example));
+        const logData = {
+            key: uuidV1(),
+            content: '正在加载例题,请稍候……',
+            userID: userId,
+            compilationID: compilation,
+            status: 'start',
+            create_time: +new Date()
+        };
+        await importLogsModel.create(logData);
+        initData(logData.key, userId, compilation, example);
+        return 'start prepareInitialData';
+    }
+    async function initData(key, userId, compilation, example) {
+        const doc = { status: 'finish' };
+        try {
+            let prepareTask = [
+                copyCompleRationSection(userId, compilation),
+                copyCompleGljSection(userId, compilation)
+            ];
+            if (example && example.length > 0) {
+                prepareTask.push(copyExample(userId, compilation, example));
+            }
+            await Promise.all(prepareTask);
+        } catch (error) {
+            doc.errorMsg = '加载例题失败,请检查例题项目是否存在!';
+            doc.status = 'error';
+        } finally {
+            await importLogsModel.update({ key }, doc);
         }
-        await Promise.all(prepareTask);
     }
 }
 
@@ -1502,6 +1566,11 @@ async function copyCompleRationSection(userId, compilationId) {
 
 //拷贝补充人材机分类树
 async function copyCompleGljSection(userId, compilationId) {
+    // 如果已有数据则不再生成
+    const count = await compleGljSectionModel.count({userId, compilationId});
+    if (count) {
+        return;
+    }
     let templateData = await compleGljSectionTModel.find({compilationId: compilationId});
     if (templateData.length > 0) {
         let insertDatas = [],
@@ -1700,6 +1769,8 @@ async function importProject(importObj, userID, compilationID) {
     if (bulks.length > 0) {
         await projectModel.bulkWrite(bulks);
     }
+    return importObj.ID; // 返回建设项目ID
+    // TODO 删除
     let summaryInfo = await getSummaryInfo([importObj.ID]);
     //设置汇总字段
     for(let proj of toInsertProjects){
@@ -2100,7 +2171,9 @@ async function downLoadProjectFile(info) {
     console.log(privateDownloadUrl);
     let data = {
         key:info.key,
+        content: '正在导入建设项目,请稍候……',
         userID:info.session.sessionUser.id,
+        compilationID: info.session.sessionCompilation._id,
         status:"start",
         create_time:+new Date()
     };
@@ -2135,28 +2208,31 @@ async function doDownLoadAndImport(privateDownloadUrl,info) {
 
 async function importProcessChecking(data){
     let result = {error:0};
-    let log = await importLogsModel.findOne({key:data.key});
+    const query = data.key ? { key: data.key } : { userID: data.userID, compilationID: data.compilationID };
+    let log = await importLogsModel.findOne(query);
     if(log){
         if(log.status == "finish"){
             result.status = "complete";
-            await importLogsModel.remove({key:data.key});
+            await importLogsModel.remove(query);
             // 获取导入的项目数据
             if (log.projectID) {
                 const projects = await getPosterityProjects([log.projectID], true);
-                const summaryInfo = await getSummaryInfo([log.projectID]);
-                setupSummaryFields(summaryInfo, projects);
+                if (!(projects.length === 1 && projects[0].projType === projectType.tender)) { // 处理的是建设项目数据
+                    const summaryInfo = await getSummaryInfo([log.projectID]);
+                    setupSummaryFields(summaryInfo, projects);
+                }
                 result.data = projects;
             }
         }else if(log.status == "start"){
             result.status = "processing";
+            result.content = log.content;
         }else if(log.status == "error"){
             result.error = 1;
             result.msg = log.errorMsg;
-            await importLogsModel.remove({key:data.key});
+            await importLogsModel.remove(query);
         }
     }else {
-        result.error = 1;
-        result.msg = `导入过程中发生错误!`;
+        result.status = "complete";
     }
     return result;
 
@@ -2187,6 +2263,53 @@ async function downloadFileSync(key) {
 
 // 导入接口
 async function importInterface(key, session) {
+    const logData = {
+        key: key,
+        content: '正在导入接口文件,请稍候……',
+        userID: session.sessionUser.id,
+        compilationID: session.sessionCompilation._id,
+        status: 'start',
+        create_time: +new Date()
+    };
+    await importLogsModel.create(logData);
+    handleImportInterface(key, session);
+    return 'importing interface';
+}
+
+async function handleImportInterface(key, session) {
+    const doc = { status: 'finish' };
+    // 源文件内容文本
+    let downloadFilePath = '';
+    try {
+        const { path, srcData } = await downloadFileSync(key);
+        downloadFilePath = path;
+        if (!srcData) {
+            throw '无有效数据';
+        }
+        const userID = session.sessionUser.id;
+        const compilationID = session.sessionCompilation._id;
+        const importData = JSON.parse(srcData);
+        let tenderCount = 0;
+        importData.engs.forEach(eng => {
+            eng.tenders.forEach(() => {
+                tenderCount += 1;
+            });
+        });
+        if (await isTenderOverrun(tenderCount, session)) {
+            throw '您创建的项目个数超限,请联系我们的客服人员,或者导出建设项目保存到本地备份,删除云上数据。';
+        }
+        const projectID = await importProject(importData, userID, compilationID);
+        doc.projectID = projectID;
+    } catch (err) {
+        doc.errorMsg = typeof err === 'string' ? err : '导入接口失败,请检查接口文件!';
+        doc.status = 'error';
+    } finally {
+        await importLogsModel.update({ key }, doc);
+        fs.unlinkSync(downloadFilePath);
+    }
+}
+
+/* async function importInterface(key, session) {
     // 源文件内容文本
     let downloadFilePath = '';
     try {
@@ -2214,7 +2337,7 @@ async function importInterface(key, session) {
     } finally {
         fs.unlinkSync(downloadFilePath);
     }
-}
+} */
 
 async function importProjects(data,req,updateData) {
     let result = {error:0};

+ 0 - 15
modules/pm/models/project_model.js

@@ -84,21 +84,6 @@ ProjectsDAO.prototype.getUserProjects = async function (userId, compilation, cal
         // 设置汇总字段
         let summaryInfo = await pmFacade.getSummaryInfo(projIDs);
         pmFacade.setupSummaryFields(summaryInfo, projects);
-        /* for(let proj of projects){
-            let summaryProj = summaryInfo[proj.ID];
-            if(summaryProj){
-                proj.engineeringCost = summaryProj.engineeringCost;
-                proj.subEngineering = summaryProj.subEngineering;
-                proj.measure = summaryProj.measure;
-                proj.safetyConstruction = summaryProj.safetyConstruction;
-                proj.other = summaryProj.other;
-                proj.charge = summaryProj.charge;
-                proj.tax = summaryProj.tax;
-                proj.rate = summaryProj.rate;
-                proj.buildingArea = summaryProj.buildingArea;
-                proj.perCost = summaryProj.perCost;
-            }
-        } */
         callback(0, '', projects);
     }
     catch (err) {

+ 5 - 3
public/web/PerfectLoad.js

@@ -122,9 +122,11 @@ jQuery.bootstrapLoading = {
         }
     },
     progressEnd:function () {
-        $("#progress_modal_bar").css('width','100%');
-        $.bootstrapLoading.progressStop = true;
-        $("#progressModal").modal('hide');
+        if ($('#progressModal').is(':visible')) {
+            $("#progress_modal_bar").css('width','100%');
+            $.bootstrapLoading.progressStop = true;
+            $("#progressModal").modal('hide');
+        }
     }
 }
 

+ 4 - 4
public/web/common_ajax.js

@@ -163,7 +163,7 @@ $.ajaxSetup({
 
 
 
-async function ajaxPost(url, data, isPlainData = false) {
+async function ajaxPost(url, data, isPlainData = false, timeout = 200000) {
     return new Promise(function (resolve, reject) {
         $.ajax({
             type:"POST",
@@ -171,7 +171,7 @@ async function ajaxPost(url, data, isPlainData = false) {
             data: isPlainData ? data : {'data': JSON.stringify(data)},
             dataType: 'json',
             cache: false,
-            timeout: 200000,
+            timeout,
             success: function(result){
                 if (!result.error ||  commonUtil.isDef(result.err) && !result.err) {
                     resolve(result.data);
@@ -182,7 +182,7 @@ async function ajaxPost(url, data, isPlainData = false) {
                 }
             },
             error: function(jqXHR, textStatus, errorThrown){
-                ajaxErrorInfo(jqXHR, textStatus, errorThrown);
+                ajaxErrorInfo(url, jqXHR, textStatus, errorThrown);
                 reject("请求错误");
             }
         });
@@ -216,7 +216,7 @@ function getTopWindow() {
     return p;
 }
 
-function ajaxErrorInfo(jqXHR, textStatus, errorThrown) {
+function ajaxErrorInfo(url, jqXHR, textStatus, errorThrown) {
     if(textStatus == 'timeout'){
         alert('网络连接超时,请刷新您的网页。');
     }else {

+ 6 - 2
web/building_saas/complementary_ration_lib/js/global.js

@@ -75,8 +75,12 @@ function setLocalCache(key, value) {
     if (!storage || key === '' || value === '') {
         return;
     }
-
-    storage.setItem(key, value);
+    try {
+        storage.setItem(key, value);
+    } catch (err) {
+        storage.clear();
+        storage.setItem(key, value);
+    }
 }
 
 /**

+ 5 - 0
web/building_saas/css/custom.css

@@ -462,4 +462,9 @@ input.text-right{
     .middle-modal-height {
         height: 350px;
     }
+}
+/* 初始样式,防止projspread初始化完后背景从白突然变灰 */
+.poj-list {
+    height: 1000px; 
+    background: #f7f7f9;
 }

+ 8 - 6
web/building_saas/pm/js/pm_import.js

@@ -446,7 +446,9 @@ const importView = (() => {
                     xmlObj.name += `(${moment(Date.now()).format('YYYY-MM-DD HH:mm:ss')})`;
                 }
                 $('#importInterface').modal('hide');
-                pr.start('导入文件', '正在生成文件,请稍候……');
+                //pr.start('导入文件', '正在生成文件,请稍候……');
+                $.bootstrapLoading.progressStart('导入文件', true);
+                $("#progress_modal_body").text('正在导入接口文件,请稍候……');
                 let importData = await importXML.transformData(xmlObj);
                 console.log(importData);
                 let blob = new Blob([JSON.stringify(importData)], { type: 'text/plain;charset=utf-8' });
@@ -454,15 +456,15 @@ const importView = (() => {
                 const key = `${uuid.v1()}.json`;
                 const file = new File([blob], key);
                 // 上传文件
-                console.time();
                 await projTreeObj.getUploadToken();
                 await UPLOAD_CDN.uploadSync(file, key, projTreeObj.uptoken);
                 // 下载并处理文件
-                const rstData = await ajaxPost('/pm/import/importInterface', { key });
-                console.timeEnd();
+                /* const rstData = await ajaxPost('/pm/import/importInterface', { key });
                 if (Array.isArray(rstData)) {
                     doAfterImport(rstData);
-                }
+                } */
+                await ajaxPost('/pm/import/importInterface', { key });
+                await importProcessChecking(key, null, (projectData) => handleProjectAfterChecking(projectData));
             } catch (err) {
                 console.log(err);
                 alert(err);
@@ -471,7 +473,7 @@ const importView = (() => {
                 setTimeout(function () {
                     STATE.importing = false;
                 }, 500);
-                pr.end();
+                //pr.end();
             }
         });
         // 导入窗口激活

+ 100 - 76
web/building_saas/pm/js/pm_newMain.js

@@ -386,8 +386,8 @@ const projTreeObj = {
             name: '导入招投标接口文件',
             icon: 'fa-cloud-upload',
             visible: function () {
-                //return compilationData && compilationData.name === '重庆定额(2018)';
-                return true;
+                const names = ['重庆定额(2018)', '广东定额(2018)'];
+                return compilationData && names.includes(compilationData.name);
             },
             callback: function () {
                 $('#importInterface').modal('show');
@@ -2705,44 +2705,45 @@ $(document).ready(function() {
         });
     });
     // 复制到操作
-    $("#copy-to-confirm").click(function() {
-        let originalNode = projTreeObj.tree.selected;
-        let toNode = projTreeObj.copySelected;
-        let projectNode;    //建设项目节点
+    $("#copy-to-confirm").click(async function() {
+        try {
+            let originalNode = projTreeObj.tree.selected;
+            let toNode = projTreeObj.copySelected;
+            let projectNode;    //建设项目节点
         let parent = null,next = null,projectMap={};
-        if(toNode.data.projType == projectType.engineering){//复制为目标的子节点
-            projectNode = toNode.parent;
-            parent = toNode;
-            next = toNode.firstChild();
-        }else if(toNode.data.projType == projectType.tender){//复制为目标的后兄弟
-            projectNode = toNode.parent.parent;
-            parent = toNode.parent;
-            next = toNode.nextSibling;
-            projectMap['update'] = {query:{ID:toNode.id()}};//前一节点的下一个节点更新;
-        }
-        //目标建设项目的计税方法与单位工程的一致时,才可复制到,否则提示“当前单位工程计税方法与目标建设项目不一致,不可复制。 确定”。
-        if (projectNode.data.property.taxType != originalNode.data.property.taxType) {
-            alert('当前单位工程计税方法与目标建设项目不一致,不可复制。');
-            return false;
+            if(toNode.data.projType == projectType.engineering){//复制为目标的子节点
+                projectNode = toNode.parent;
+                parent = toNode;
+                next = toNode.firstChild();
+            }else if(toNode.data.projType == projectType.tender){//复制为目标的后兄弟
+                projectNode = toNode.parent.parent;
+                parent = toNode.parent;
+                next = toNode.nextSibling;
+                projectMap['update'] = {query:{ID:toNode.id()}};//前一节点的下一个节点更新;
+            }
+            //目标建设项目的计税方法与单位工程的一致时,才可复制到,否则提示“当前单位工程计税方法与目标建设项目不一致,不可复制。 确定”。
+            if (projectNode.data.property.taxType != originalNode.data.property.taxType) {
+                alert('当前单位工程计税方法与目标建设项目不一致,不可复制。');
+                return false;
+            }
+            let nextID = next?next.id():-1;
+            let projectData = _.cloneDeep(originalNode.data);
+            projectData['ParentID'] = parent.id();
+            projectData['NextSiblingID'] = nextID;
+            projectData['property'] ={};
+            projectData['property']['rootProjectID'] = parent.pid();
+            projectData['shareInfo'] = [];
+            let rename = projTreeObj.projectNameChecking(parent,originalNode,"复制");//重名检查
+            rename? projectData['name'] = rename:'';
+            projectMap['copy'] = {document:projectData};
+            $("#copy-to-dialog").modal('hide');
+            $.bootstrapLoading.progressStart('拷贝项目', true);
+            $("#progress_modal_body").text('正在拷贝项目,请稍候……');
+            await ajaxPost('/pm/api/copyProjects', {projectMap:projectMap,user_id: userID, tenderCount: 1});
+            await importProcessChecking(null, null, (newProjectData) => handleTenderAfterChecking(newProjectData[0], projectData));
+        } catch (err) {
+            alert(err);
         }
-        let nextID = next?next.id():-1;
-        let projectData = _.cloneDeep(originalNode.data);
-        projectData['ParentID'] = parent.id();
-        projectData['NextSiblingID'] = nextID;
-        projectData['property'] ={};
-        projectData['property']['rootProjectID'] = parent.pid();
-        projectData['shareInfo'] = [];
-        let rename = projTreeObj.projectNameChecking(parent,originalNode,"复制");//重名检查
-        rename? projectData['name'] = rename:'';
-        projectMap['copy'] = {document:projectData};
-        $("#copy-to-dialog").modal('hide');
-        $.bootstrapLoading.start();
-        CommonAjax.post('/pm/api/copyProjects',{projectMap:projectMap,user_id: userID, tenderCount: 1},function (result) {
-            let newNode = projTreeObj.insert(result['copy'].document,parent,next);
-            let refreshNodes = projTreeObj.calEngineeringCost(newNode);
-            projTreeObj.refreshNodeData(refreshNodes);
-            $.bootstrapLoading.end();
-        }, null, 1000 * 60 * 5);
 
     });
     $('#selectSameTypeProject').click(function(){
@@ -2988,17 +2989,6 @@ function initProjects(callback) {
             projTreeObj.tree = pmTree.createNew(projTreeObj.setting, datas);
             projTreeObj.tree.selected = projTreeObj.tree.items[0];
             projTreeObj.workBook = projTreeObj.buildSheet(projTreeObj.workBook,'projSpread',projTreeObj.setting);
-            // 调整列后自适应行高
-            /* projTreeObj.workBook.getSheet(0).bind(GC.Spread.Sheets.Events.ColumnWidthChanged, function (e, info) {
-                info.sheet.suspendPaint();
-                info.sheet.suspendEvent();
-                const rowCount = info.sheet.getRowCount();
-                for (let i = 0; i < rowCount; i++) {
-                    info.sheet.autoFitRow(i);
-                }
-                info.sheet.resumePaint();
-                info.sheet.resumeEvent();
-            }); */
             const sheet = projTreeObj.workBook.getSheet(0);
             sheet.options.frozenlineColor = '#ababab';
             sheet.frozenColumnCount(2);
@@ -3024,28 +3014,33 @@ function initProjects(callback) {
 
 /**
  * 初始化数据
- *
- * @return {void}
  */
-function init(refresh = false) {
+async function init(refresh = false) {
+    console.log('init');
     //init spread and pmTree
-    if(refresh == false) socketObject.connect('pm');//socket 连接;
-    if (isFirst) {
-        isFirst = false;
-        let pr = new SCComponent.InitProgressBar();
-        pr.start('欢迎使用大司空计价', '首次加载例题,请稍候……');
-        CommonAjax.post('/pm/api/prepareInitialData', {user_id: userID}, function () {
-            initProjects(function () {
-                pr.end();
+    try {
+        if(refresh == false) socketObject.connect('pm');//socket 连接;
+        if (isFirst) {
+            isFirst = false;
+            $.bootstrapLoading.progressStart('欢迎使用大司空计价', true);
+            $("#progress_modal_body").text('首次加载例题,请稍候……');
+            await ajaxPost('/pm/api/prepareInitialData', {user_id: userID});
+            await importProcessChecking(null, null, () => {
+                initProjects(() => $.bootstrapLoading.progressEnd());
             });
-        });
-    } else {
-        $.bootstrapLoading.start();
-        initProjects(function () {
-            $.bootstrapLoading.end();
-        })
+        } else {
+            await importProcessChecking(null, ({ content }) => {
+                $.bootstrapLoading.progressStart('欢迎使用大司空计价', true);
+                $("#progress_modal_body").text(content);
+            }, () => {
+                $.bootstrapLoading.start();
+                initProjects(() => $.bootstrapLoading.end());
+            });
+        }
+        engineering = engineeringList !== null && engineeringList !== undefined ? JSON.parse(engineeringList) : [];
+    } catch (error) {
+        alert(error)
     }
-    engineering = engineeringList !== null && engineeringList !== undefined ? JSON.parse(engineeringList) : [];
 }
 
 function refreshAllPage(){
@@ -4886,7 +4881,7 @@ $("#confirm-import").click(function() {
     async function  startImportProject(key) {
         try {
             let result = await ajaxPost("/pm/api/importProject",{key:key,updateData:projTreeObj.getImportProjectDate()});
-            importProcessChecking(key);
+            importProcessChecking(key, null, (projectData) => handleProjectAfterChecking(projectData));
         }catch (error){
             alert(error);
         }finally {
@@ -4921,6 +4916,7 @@ $('#import').on('show.bs.modal', function(){
 //设置分享给界面数据
 //@param {Object}selected @return {void}
 function setShareToModal(selected){
+    $.bootstrapLoading.start();
     const perHeight = 30; //每条分享给数据的高度
     $('#shareToInfo').empty();
     if(!selected){
@@ -4974,6 +4970,7 @@ function setShareToModal(selected){
         let infoHtml = infoArr.join('');
         $('#shareToInfo').html(infoHtml);
         bindCancelShareCheck(selected);
+        $.bootstrapLoading.end();
     });
 }
 //取消分享的勾选操作
@@ -5091,7 +5088,7 @@ $(function () {
             $.bootstrapLoading.progressStart("欢迎使用大司空云计价",true);
             $("#progress_modal_body").text("正在导入测评项目,请稍候……");
             let result = await ajaxPost("/pm/api/importChongqingProject",{user_id: userID,key:key});
-            importProcessChecking(key);
+            importProcessChecking(key, null, (projectData) => handleProjectAfterChecking(projectData));
         }catch (error){
             alert(error);
         }finally {
@@ -5100,7 +5097,24 @@ $(function () {
     })
 });
 
-async function importProcessChecking(key) {
+// 导入检查完成时,对新增建设项目的处理
+function handleProjectAfterChecking(projectData) {
+    const rootData = projectData.find(item => item.projType === projectType.project);
+    const sorted = commonUtil.getSortedTreeData(rootData.ParentID, projectData);
+    importView.doAfterImport(sorted);
+}
+// 导入检查完成时,对新增单位工程的处理
+function handleTenderAfterChecking(newTender, orgTender) {
+    const tenderData = {...orgTender, ...newTender};
+    const parent = projTreeObj.tree.findNode(tenderData.ParentID);
+    const next = projTreeObj.tree.findNode(tenderData.NextSiblingID);
+    const newNode = projTreeObj.insert(tenderData, parent, next);
+    const refreshNodes = projTreeObj.calEngineeringCost(newNode);
+    projTreeObj.refreshNodeData(refreshNodes);
+}
+
+async function importProcessChecking(key, processingFunc = null, completeFunc = null) {
+    let count = 0;
     setTimeout(checking,2000)
     async function checking() {
         let result = await ajaxPost("/pm/api/importProcessChecking",{key:key,user_id:userID});
@@ -5109,16 +5123,26 @@ async function importProcessChecking(key) {
             setTimeout(function () {
                 $.bootstrapLoading.progressEnd();//不做这个的话太快,页面不会自动关闭
             },500);
-            alert(message)
+            alert(message);
+            if (completeFunc) {
+                completeFunc();
+            }
         }else if(result.error == 0){
             if(result.status == "processing"){
+                // 只调用一次
+                if (processingFunc && count === 0) {
+                    processingFunc(result);
+                }
+                count++;
                 setTimeout(checking,2000);
             }else if(result.status == "complete"){
-                if (Array.isArray(result.data)) {
-                    const rootData = result.data.find(item => item.projType === projectType.project);
-                    const sorted = commonUtil.getSortedTreeData(rootData.ParentID, result.data);
-                    importView.doAfterImport(sorted);
-                }
+                if (completeFunc) {
+                    completeFunc(result.data);
+                }/*  else if (result.data && result.data.type === projectType.project) {
+                    handleProjectAfterChecking(result.data.projectData);
+                } else if (result.data && result.data.type === projectType.tender) {
+                    handleTenderAfterChecking(result.data.projectData);
+                } */
                 $.bootstrapLoading.progressEnd();
                 //refreshAllPage();
             }

+ 17 - 16
web/building_saas/pm/js/pm_share.js

@@ -897,15 +897,16 @@ const pmShare = (function () {
     }
     //拷贝分享的工程
     //@param {Object}selected {Number}parentID @return {void}
-    function copyShareProject(selected, projID, engID){
-        if(!engID || !selected){
-            return;
-        }
-        let copyMap = {copy: null, update: null};
-        let newName = getCopyName(selected);
-        //获取单项工程的单位工程
-        let tenderQuery = {$or: [{deleteInfo: null}, {'deleteInfo.deleted': false}], userID: userID, ParentID: engID};
-        CommonAjax.post('/pm/api/getProjectsByQuery', {user_id: userID, query: tenderQuery, options: '-_id -property'}, function (rstData) {
+    async function copyShareProject(selected, projID, engID){
+        try {
+            if(!engID || !selected){
+                return;
+            }
+            let copyMap = {copy: null, update: null};
+            let newName = getCopyName(selected);
+            //获取单项工程的单位工程
+            let tenderQuery = {$or: [{deleteInfo: null}, {'deleteInfo.deleted': false}], userID: userID, ParentID: engID};
+            const rstData = await ajaxPost('/pm/api/getProjectsByQuery', {user_id: userID, query: tenderQuery, options: '-_id -property'}, false, 10000);
             let updateTender = null;
             for(let tender of rstData){
                 if(tender.name === newName){
@@ -940,13 +941,13 @@ const pmShare = (function () {
             copyData.property.rootProjectID = projID;
             copyMap.copy = {document: copyData};
             $('#copyShare').modal('hide');
-            $.bootstrapLoading.start();
-            CommonAjax.post('/pm/api/copyProjects', {projectMap: copyMap, user_id: userID, tenderCount: 1}, function (rstData) {
-                $.bootstrapLoading.end();
-            }, function () {
-                $.bootstrapLoading.end();
-            }, 1000 * 60 * 5);
-        });
+            $.bootstrapLoading.progressStart('拷贝项目', true);
+            $("#progress_modal_body").text('正在拷贝项目,请稍候……');
+            await ajaxPost('/pm/api/copyProjects', {projectMap: copyMap, user_id: userID, tenderCount: 1});
+            importProcessChecking();
+        } catch (err) {
+            alert(err);
+        }
 
     }
     //获取拷贝后的名称