Prechádzať zdrojové kódy

Merge branch 'master' of http://192.168.1.41:3000/SmartCost/ConstructionCost

TonyKang 4 rokov pred
rodič
commit
511df040b7

+ 4 - 0
modules/import/controllers/import_controller.js

@@ -17,6 +17,10 @@ let controller = {
         let data = req.body;
         return await pm_facade.importChongqingProject(data);
     },
+    importExampleProject:async function(req){
+        let data = req.body;
+        return await pm_facade.importExampleProject(data);
+    },
     copyConstructionProject:async function(req){
       let data = req.body;
       return await pm_facade.copyConstructionProject(data);

+ 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('/importExampleProject',importController.action);
     importRouter.post('/copyConstructionProject',importController.action);
     importRouter.post('/prepareInitialData',importController.action);
     importRouter.get('/test',function (req,res) {

+ 15 - 0
modules/pm/controllers/pm_controller.js

@@ -964,6 +964,21 @@ module.exports = {
         }
         res.json(result);
     },
+    importExampleProject: async function (req, res) {
+        let data = JSON.parse(req.body.data);
+        let result = {
+            error: 0
+        };
+        try {
+            data.session = req.session;
+            result.data = await redirectToImportServer(data, "importExampleProject", req);
+        } catch (err) {
+            console.log(err);
+            result.error = 1;
+            result.message = err.message;
+        }
+        res.json(result);
+    },
     copyConstructionProject: async function (req, res) {
       let data = JSON.parse(req.body.data);
       let result = {

+ 38 - 23
modules/pm/facade/pm_facade.js

@@ -54,6 +54,7 @@ module.exports={
     uploadToken:uploadToken,
     downLoadProjectFile:downLoadProjectFile,
     importChongqingProject:importChongqingProject,
+    importExampleProject:importExampleProject,
     importProcessChecking:importProcessChecking,
     copyConstructionProject,
     importInterface,
@@ -1769,32 +1770,45 @@ async function importChongqingProject(data) {
     };
     await importLogsModel.create(log_data);
     doImport(data.user_id,data.session.sessionCompilation._id,data.session.sessionCompilation.adProjects,data.key);
+     return "start importing";
+}
+
+//加载例题
+async function importExampleProject(data) {
 
+    let log_data = {
+        key:data.key,
+        content: '正在导入例题,请稍候……',
+        userID:data.user_id,
+        compilationID: data.session.sessionCompilation._id,
+        status:"start",
+        create_time:+new Date()
+    };
+    await importLogsModel.create(log_data);
+    doImport(data.user_id,data.session.sessionCompilation._id,data.session.sessionCompilation.example,data.key);
      return "start importing";
-    async function doImport(user_id,compilationId,projectIDs,key) {
-        let doc = {status:"finish"};
-        try {
-           let r = await copyExample(user_id,compilationId,projectIDs);
-           if(r == false){
-               doc.errorMsg = "导入失败,请检查项目是否存在!";
-               doc.status = "error";
-           } else {
-               doc.projectID = r;
-           }
-        }catch (error){
-            console.log(error);
-            doc.errorMsg = "导入失败,请检查项目是否存在!";
-            doc.status = "error";
-        }finally {
-            await importLogsModel.update({key:key},doc);
-        }
-    }
 }
 
-function testTimeout(time) {
-    return new Promise(resolve => setTimeout(resolve, time));
+async function doImport(user_id,compilationId,projectIDs,key) {
+    let doc = {status:"finish"};
+    try {
+       let r = await copyExample(user_id,compilationId,projectIDs);
+       if(r == false){
+           doc.errorMsg = "导入失败,请检查项目是否存在!";
+           doc.status = "error";
+       } else {
+           doc.projectID = r;
+       }
+    }catch (error){
+        console.log(error);
+        doc.errorMsg = "导入失败,请检查项目是否存在!";
+        doc.status = "error";
+    }finally {
+        await importLogsModel.update({key:key},doc);
+    }
 }
 
+
 //用户第一次进入费用定额的数据准备
 async function prepareInitialData(userId, compilation, example) {
     let first = await isFirst(userId, compilation);
@@ -1802,7 +1816,7 @@ async function prepareInitialData(userId, compilation, example) {
         await updateUsedList(userId, compilation);
         const logData = {
             key: uuidV1(),
-            content: '正在加载例题,请稍候……',
+            content: '正在初始化数据,请稍候……',
             userID: userId,
             compilationID: compilation,
             status: 'start',
@@ -1819,9 +1833,10 @@ async function prepareInitialData(userId, compilation, example) {
                 copyCompleRationSection(userId, compilation),
                 copyCompleGljSection(userId, compilation)
             ];
-            if (example && example.length > 0) {
+           /* 2021-01-19 第一次的时候不自动加载例题,右键加载 
+              if (example && example.length > 0) {
                 prepareTask.push(copyExample(userId, compilation, example));
-            }
+            } */
             await Promise.all(prepareTask);
         } catch (error) {
             doc.errorMsg = '加载例题失败,请检查例题项目是否存在!';

+ 1 - 0
modules/pm/routes/pm_route.js

@@ -70,6 +70,7 @@ module.exports = function (app) {
     pmRouter.post('/exportProject', pmController.exportProject);
     pmRouter.post('/importProject', pmController.importProject);
     pmRouter.post('/importChongqingProject', pmController.importChongqingProject);
+    pmRouter.post('/importExampleProject', pmController.importExampleProject);
     pmRouter.post('/copyConstructionProject',systemMiddleware.tenderNumberChecking,pmController.copyConstructionProject);
     pmRouter.post('/importProcessChecking', pmController.importProcessChecking);
     pmRouter.post('/getBasicInfo', pmController.getBasicInfo);

+ 3 - 1
web/building_saas/complementary_glj_lib/js/glj.js

@@ -788,7 +788,9 @@ let repositoryGljObj = {
         // 输入编号、名称、规格时,如果输入回车符或粘贴回车符,提交时应转换为空格。
         let deESCFields = ['code', 'name', 'specs'];
         if (deESCFields.includes(me.setting.header[args.col]['dataCode'])) {
-            args.editingText = me.isDef(args.editingText) ? args.editingText.toString().replace(/[\r\n]/g, ' ') : '';
+            args.editingText = me.isDef(args.editingText) 
+                ? args.editingText.toString().replace(/[\r\n]/g, ' ').replace(/\s$/, '')
+                : '';
             args.sheet.setValue(args.row, args.col, args.editingText);
         }
         let rObj = sheetOpr.combineRowData(me.workBook.getSheet(0), me.setting, args.row, me),

+ 2 - 2
web/building_saas/css/custom.css

@@ -27,9 +27,9 @@ div.resize-x{
   cursor: w-resize;
   float: left;
 }
-/*.zlfb-check{
+.zlfb-check{
   margin-left: 20px;
-}*/
+}
 legend.legend{
   display:block;
   width:auto;

+ 71 - 26
web/building_saas/main/html/main.html

@@ -137,8 +137,18 @@
                     <a class="dropdown-item btn-sm" href="javascript:void(0);" id="displayZM">子目</a>
                     <a class="dropdown-item btn-sm" href="javascript:void(0);" id="displayZD">最底层</a>
                   </div>
-                  <a href="javascript:void(0);" id="ZLFB_btn" class="dropdown-item" data-placement="bottom"
-                    style="display: none;"><i class="fa fa-retweet" aria-hidden="true"></i> 整理分部</a>
+                  <!-- <a href="javascript:void(0);" id="ZLFB_btn" class="dropdown-item" data-placement="bottom"><i class="fa fa-retweet" aria-hidden="true"></i> 整理清单</a> -->
+                  <a  href="javascript:void(0);" id="ZLFB_MENU" data-toggle="dropdown"  class="dropdown-item dropdown-toggle"><i class="fa fa-retweet" aria-hidden="true"></i> 整理清单</a>
+                  <div style="position: relative;">
+                    <div id="ZLFB_MENU_sub" class="dropdown-menu dropdown-menu-left"
+                    style="min-width: 6.5rem; position: absolute; transform: translate3d(158px, 3px, 0px); top: -40px; left: 0px; will-change: transform;"
+                    x-placement="right-start">
+                    <a class="dropdown-item btn-sm" href="javascript:void(0);" id="ZLFB_btn" >分部整理</a>
+                    <a class="dropdown-item btn-sm" href="javascript:void(0);" id="ZLQD_btn" >清单整理</a>
+                  
+                  </div>
+                  </div>
+
                   <% if (region === '重庆市' || region === '广东省') { %>
                   <a id="interface-dropdown" href="javascript:void(0);" data-toggle="dropdown"
                     class="dropdown-item dropdown-toggle"><i class="fa fa-list-ol"></i> 数据接口...</a>
@@ -1466,7 +1476,7 @@
           </div>
         </div>
         <div class="modal-footer" style="position: relative;">
-          <a href="/complementaryGlj" target="_blank" class="btn btn-primary"
+          <a href=<%- "/complementaryGlj/" + userID %> target="_blank" class="btn btn-primary"
             style="position: absolute; left: 20px">新增人材机</a>
           <a href="javascript:void(0);" id="glj_selected_conf" class="btn btn-primary">确定</a>
           <a href="javascript:void(0);" id="replace_next_btn" class="btn btn-primary">下一步</a>
@@ -1802,48 +1812,38 @@
     <div class="modal-dialog" role="document">
       <div class="modal-content">
         <div class="modal-header">
-          <h5 class="modal-title">整理分部</h5>
+          <h5 class="modal-title">分部整理</h5>
           <button type="button" class="close" data-dismiss="modal" aria-label="Close">
             <span aria-hidden="true">&times;</span>
           </button>
         </div>
         <div class="modal-body">
-          <div class="form-check">
-            <input class="form-check-input zlfb-check" type="checkbox" id="bill_first">
+        
+          <div class="form-check zlfb-check">
+            <input class="form-check-input " type="checkbox"  id="bill_first">
             <label class="form-check-label">
               需要专业分部标题
             </label>
           </div>
-          <div class="form-check">
-            <input class="form-check-input zlfb-check" type="checkbox" checked id="bill_second">
+          <div class="form-check zlfb-check">
+            <input class="form-check-input " type="checkbox" checked  id="bill_second">
             <label class="form-check-label">
               需要章分部标题
             </label>
           </div>
-          <div class="form-check">
-            <input class="form-check-input zlfb-check" type="checkbox" id="bill_third">
+          <div class="form-check zlfb-check">
+            <input class="form-check-input " type="checkbox"  id="bill_third">
             <label class="form-check-label">
               需要节分部标题
             </label>
           </div>
-          <div class="form-check">
-            <input class="form-check-input zlfb-check" type="checkbox" checked disabled value="">
+          <div class="form-check zlfb-check">
+            <input class="form-check-input " type="checkbox" checked disabled>
             <label class="form-check-label">
               删除自定义分部标题
             </label>
           </div>
-          <div class="form-check">
-            <input class="form-check-input zlfb-check" type="checkbox" checked id="bill_resort">
-            <label class="form-check-label">
-              清单排序
-            </label>
-          </div>
-          <div class="form-check">
-            <input class="form-check-input zlfb-check" type="checkbox" id="bill_recode">
-            <label class="form-check-label">
-              清单重新编码
-            </label>
-          </div>
+      
           <div class="card mt-3">
             <div class="card-body p-2">
               <h5 class="card-title">操作说明</h5>
@@ -1852,8 +1852,6 @@
                 勾选“需要章分部标题”,表示分部整理时需要添加章标题;</br>
                 勾选“需要节分部标题”,表示分部整理时需要添加节标题;</br>
                 勾选“删除自定义分部标题”,将首先删除已有自定义分部标题,然后再执行分部整理;</br>
-                勾选“清单排序”,表示分部整理后对每个分部下的清单进行排序;</br>
-                勾选“清单重新编码”,表示分部整理后对每个分部下的清单重新生成流水号;
               </p>
             </div>
           </div>
@@ -1866,6 +1864,53 @@
     </div>
   </div>
 
+<!--弹出 整理清单-->
+<div class="modal fade" id="zlqd" data-backdrop="static">
+  <div class="modal-dialog" role="document">
+    <div class="modal-content">
+      <div class="modal-header">
+        <h5 class="modal-title">清单整理</h5>
+        <button type="button" class="close" data-dismiss="modal" aria-label="Close">
+          <span aria-hidden="true">&times;</span>
+        </button>
+      </div>
+      <div class="modal-body">
+        <div class="form-check ">
+          <input class="form-check-input " type="checkbox" checked id="bill_resort">
+          <label class="form-check-label">
+            清单排序
+          </label>
+        </div>
+        <div class="form-check">
+          <input class="form-check-input" type="checkbox" id="bill_recode">
+          <label class="form-check-label">
+            清单重新编码
+          </label>
+          <label class="form-check-label">
+            起始编码
+          </label>
+          <input type="number" value="1" id="bill_recode_start" style="width: 50px;">
+        
+        </div>
+        <div class="card mt-3">
+          <div class="card-body p-2">
+            <h5 class="card-title">操作说明</h5>
+            <p class="card-text">
+              勾选“清单排序”,表示分部整理后对每个分部下的清单进行排序;</br>
+              勾选“清单重新编码”,表示分部整理后对每个分部下的清单重新生成流水号;
+            </p>
+          </div>
+        </div>
+      </div>
+      <div class="modal-footer">
+        <button type="button" class="btn btn-primary" id="zlqd_confirm">确定</button>
+        <button type="button" class="btn btn-secondary" data-dismiss="modal">关闭</button>
+      </div>
+    </div>
+  </div>
+</div>
+
+
   <!--弹出 计取安装费用-->
   <div class="modal fade" id="calc_installation_fee" data-backdrop="static">
     <div class="modal-dialog modal-lg" style="max-width: 1100px" role="document">

+ 18 - 0
web/building_saas/main/js/views/project_view.js

@@ -2527,6 +2527,20 @@ $('#interface-dropdown').click(function() {
     return false;
 });
 
+let enterZLFB = false
+$('#ZLFB_MENU').mouseenter(function () {
+    enterZLFB = true;
+    $('#ZLFB_MENU_sub').addClass('show');
+});
+
+$('#ZLFB_MENU').mouseleave(function () {
+    enterZLFB = false;
+});
+
+$('#ZLFB_MENU').click(function() {
+    return false;
+});
+
 $('#moreMenu > a').mouseenter(function () {
     if (!enterDisplayA) {
         $('#subDisplay').removeClass('show');
@@ -2534,9 +2548,13 @@ $('#moreMenu > a').mouseenter(function () {
     if (!enterInterfaceDropdown) {
         $('#interface-dropdown-sub').removeClass('show');
     }
+    if(!enterZLFB){
+        $('#ZLFB_MENU_sub').removeClass('show');
+    }
 });
 
 
+
 $('#displayDXFY').click(function () {
    displayLevel(projectObj.project.mainTree.items, 0, 'DXFY')
 });

+ 145 - 1
web/building_saas/main/js/views/zlfb_view.js

@@ -65,7 +65,7 @@ let zlfb_object={
         let controller = projectObj.mainController, project = projectObj.project;
         let Bill = project.Bills;
         let FBFX = Bill.getFBFXNode(controller);//取分部分项工程节点;
-        let resort = $('#bill_resort').prop('checked'),recode=$('#bill_recode').prop('checked'),first=$('#bill_first').prop('checked');
+        let resort = true,recode=false,first=$('#bill_first').prop('checked');//清单排序和重新编码放到另外的页面
         let second =$('#bill_second').prop('checked'), third =$('#bill_third').prop('checked');
         let needSelf = first==true||second==true||third==true;//需要补充分部节点;
         if(me.sectionInfo){
@@ -146,6 +146,142 @@ let zlfb_object={
             me.submitRequest(newDataMap,allNewNode,updateData,FBFX,controller);
         }
     },
+    ZLQD:async function(){//只清单排序或者重新编码
+        //
+        let me = this;
+        let selected = projectObj.project.mainTree.selected;
+        let resort = $('#bill_resort').prop('checked'),recode=$('#bill_recode').prop('checked')
+        let startNum = parseInt($('#bill_recode_start').val());
+        let FBNodes = [],updateMap = {},codeMap={};
+        let recoverMap = {};//排序失败后用来恢复原状的缓存
+        let tree = projectObj.mainController.tree;
+        if(resort||recode){
+            //先找出需要排序和重新编码的节点
+            for(let node of tree.items){
+                if(node.sourceType===ModuleNames.bills){
+                    if(node.data.type == billType.FB && node.children.length > 1){//有两个以上的才需要排序
+                        let subType = node.children[0].data.type;
+                        if(subType ===  billType.FX || subType ===  billType.BX){
+                            FBNodes.push(node);
+                            recoverMap[node.data.ID] = node.children;
+                        } 
+                   } 
+                } 
+            }   
+            try {
+                if(resort){//如果需要重新排序  -- 重新排序还必须得先改变缓存,如果勾选了重新编码,顺序依赖于排好序的清单
+                    for(let FB of FBNodes){
+                        me.resortChildren(FB,updateMap)
+                    }
+                    tree.sortTreeItems(tree);
+                }
+        
+                if(recode){
+                    if(!(startNum >= 1)){
+                        return alert("起始编码必须大于1!")
+                    } 
+                    for(let node of tree.items){
+                        if(node.data.billsLibId){
+                            let l_code = me.getLibCode(node.data.code); 
+                            if(l_code !== false){
+                                if(codeMap[l_code]){
+                                    codeMap[l_code]+=1;
+                                }else {
+                                    codeMap[l_code]=startNum;
+                                }
+                                newCode = l_code+me.getEndCode(codeMap[l_code],3);
+                                if(updateMap[node.data.ID]){
+                                    updateMap[node.data.ID].data.code = newCode;
+                                }else{
+                                    updateMap[node.data.ID] =  {
+                                        type:'bills',
+                                        data:{
+                                               projectID:node.data.projectID,
+                                               ID:node.data.ID,
+                                               code :newCode
+                                            } 
+                                        };
+                                }
+                            }
+                        }
+                    }
+
+                }
+        
+                let datas = [];
+                for(let ID in updateMap){
+                    datas.push(updateMap[ID]);
+                }
+               if(datas.length > 0) await projectObj.project.syncUpdateNodesAndRefresh(datas);
+
+               projectObj.mainController.refreshTreeNode(FBNodes,true);
+               this.refreshVisable(FBNodes);
+               let sel = projectObj.mainController.sheet.getSelections()[0];
+               sel.row = selected.serialNo();
+               projectObj.mainController.sheet.setSelection(sel.row,sel.col,sel.rowCount,sel.colCount);
+               projectObj.mainController.setTreeSelected(selected);
+            } catch (error) {
+                alert('清单排序/重新编码失败,请重试!');
+                console.log(error);
+                //恢复排序
+                for(let FB of FBNodes){
+                    me.resortChildren(FB,{},recoverMap[FB.data.ID]);
+                }
+                tree.sortTreeItems(tree);
+                this.refreshVisable(FBNodes);
+            } 
+         
+         
+        }
+    },
+    refreshVisable:function (FBNodes) {
+      let sheet =  projectObj.mainController.sheet;
+      let tree = projectObj.mainController.tree;
+      sheet.suspendPaint();
+      sheet.suspendEvent();
+      for(let pnode of FBNodes){
+        TREE_SHEET_HELPER.refreshChildrenVisiable(sheet,tree,pnode,pnode.serialNo());
+        for(let node of pnode.children){
+            TREE_SHEET_HELPER.refreshChildrenVisiable(sheet,tree,node,node.serialNo());
+        }  
+      } 
+      sheet.resumeEvent();
+      sheet.resumePaint();  
+    },
+
+
+    resortChildren:function(node,updateMap,recoverChildren){
+        if(recoverChildren){
+            node.children = recoverChildren;
+        }else{
+            node.children = _.sortBy(node.children,'data.code');
+        } 
+       for(let i=0;i<node.children.length;i++){
+           let subNode = node.children[i];
+           let tem = {
+            type:'bills',
+            data:{
+                projectID:subNode.data.projectID,
+                ID:subNode.data.ID,
+                } 
+            }; 
+            if(i===0){
+                subNode.preSibling == 0;
+            }else{
+                subNode.preSibling = node.children[i-1];
+            }
+
+           if(i == node.children.length-1){//如果是最后一个节点
+            tem.data.NextSiblingID=-1;
+            subNode.nextSibling = null
+           }else{
+            tem.data.NextSiblingID= node.children[i+1].data.ID;
+            subNode.nextSibling = node.children[i+1];
+           }
+          updateMap[subNode.data.ID] = tem
+       } 
+    },
+
     addSubNode:function (parentNode,oldChildren,allNewNode,controller) {
         for(let c of oldChildren){
             let newChild = controller.tree.insert(parentNode.getID(), -1,c.getID());
@@ -300,6 +436,7 @@ let zlfb_object={
 
 
 $(function () {
+
     $('#zlfb_confirm').click(function (){
         $("#zlfb").modal('hide');
         zlfb_object.reorganizeNodes();
@@ -308,4 +445,11 @@ $(function () {
         zlfb_object.sectionInfo=null;
     })
 
+    $('#ZLQD_btn').click(function () {
+        $("#zlqd").modal('show');
+    });
+    $('#zlqd_confirm').click(function (){
+        $("#zlqd").modal('hide');
+        zlfb_object.ZLQD();
+    });
 });

+ 35 - 17
web/building_saas/pm/js/pm_newMain.js

@@ -474,6 +474,14 @@ const projTreeObj = {
                 $("#import").modal('show');
                 projTreeObj.getUploadToken();
             }
+        },
+        importExampleProject:{
+            name: "加载例题",
+            icon: 'fa-refresh',
+            callback: function (key, opt) {
+
+                projTreeObj.importExampleProjects();
+            }
         }
     },
     //全部-开始(新建)按钮弹出菜单(新建单位工程)
@@ -507,7 +515,8 @@ const projTreeObj = {
                 "manageFiles": me.contextMenuItems.manageFiles,
                 "refreshSummary": me.contextMenuItems.refreshSummary,
                 "exportProject":me.contextMenuItems.exportProject,
-                "importProject":me.contextMenuItems.importProject
+                "importProject":me.contextMenuItems.importProject,
+                "importExampleProject":me.contextMenuItems.importExampleProject
             }
         });
     },
@@ -1763,6 +1772,30 @@ const projTreeObj = {
             }
         }
         this.initTree(true, callback, expandCallback);
+    },
+    importExampleProjects:async function(isChongqing=false){
+        if (STATE.importing) {
+            return;
+        }
+        let textBody = '正在导入例师,请稍候……'
+        let url = 'importExampleProject';
+        STATE.importing = true;
+        if(isChongqing){
+            $('#welcomePage').modal('hide');
+            textBody = "正在导入测评项目,请稍候……";
+            url = 'importChongqingProject';
+        } 
+        try {
+            let key = uuid.v1();
+            $.bootstrapLoading.progressStart("欢迎使用大司空云计价",true);
+            $("#progress_modal_body").text(textBody);
+            let result = await ajaxPost(`/pm/api/${url}`,{user_id: userID,key:key});
+            importProcessChecking(key, null, (projectData) => handleProjectAfterChecking(projectData));
+        }catch (error){
+            alert(error);
+        }finally {
+            STATE.importing = false;
+        }
     }
 };
 // 新建项目必填项提示框设置“ 比如:注:为响应重庆地区指标采集标准数据要求,以上工程信息及特征必填项为必填项,请正确填写。”
@@ -4823,22 +4856,7 @@ function refreshProjSummary(project, summaryInfo) {
 $(function () {
     if(isShow)  $('#welcomePage').modal('show');//是否显示欢迎页
     $('#importChongqing').click(async function () {
-        if (STATE.importing) {
-            return;
-        }
-        STATE.importing = true;
-        $('#welcomePage').modal('hide');
-        try {
-            let key = uuid.v1();
-            $.bootstrapLoading.progressStart("欢迎使用大司空云计价",true);
-            $("#progress_modal_body").text("正在导入测评项目,请稍候……");
-            let result = await ajaxPost("/pm/api/importChongqingProject",{user_id: userID,key:key});
-            importProcessChecking(key, null, (projectData) => handleProjectAfterChecking(projectData));
-        }catch (error){
-            alert(error);
-        }finally {
-            STATE.importing = false;
-        }
+      await  projTreeObj.importExampleProjects(true);
     })
 });