Browse Source

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

chenshilong 5 years ago
parent
commit
424a958991

+ 1 - 1
modules/main/models/project.js

@@ -143,7 +143,7 @@ Project.prototype.getDataSync = function(projectID){
                         const endTime = +new Date();
                         console.log(moduleName+'---------------'+(endTime - startTime));
                         cb(err, {moduleName: moduleName, data: data})
-                    })
+                    }, true); // true 返回调价后的数据
                 }
             })(itemName))
         }

+ 3 - 3
modules/users/controllers/user_controller.js

@@ -57,9 +57,9 @@ class UserController extends BaseController {
                 real_name: request.body.real_name,
                 province: request.body.province,
                 company: request.body.company,
-                version: request.body.version,
-                company_type: request.body.company_type,
-                company_scale: request.body.company_scale,
+                version: request.body.version ? request.body.version : null,
+                company_type: request.body.company_type ? request.body.company_type : null,
+                company_scale: request.body.company_scale ? request.body.company_scale : null,
             };
             let sessionUser = request.session.sessionUser;
             // 切换验证场景

+ 13 - 0
web/building_saas/main/js/models/calc_program.js

@@ -1016,6 +1016,19 @@ let calcTools = {
     isEmptyObject(obj){
         let arr = Object.keys(obj);
         return arr.length == 0;
+    },
+    // 清单价格是否大于最高限价
+    unitFeeGTMaxPrice: function (node, feeField) {
+        if (!this.isBill(node)) {
+            return false;
+        }
+        const totalFee = this.getFee(node, feeField);
+        const maxPrice = node.data.maxPrice;
+        // 最高限价有值才对比
+        if (!commonUtil.isDef(maxPrice)) {
+            return false;
+        }
+        return totalFee > maxPrice;
     }
 };
 

+ 14 - 4
web/building_saas/main/js/models/exportSEIInterface.js

@@ -188,7 +188,7 @@ async function exportSEI(projectID) {
                     name:q.name,
                     attrs:[
                         {name:"工程量指标",value:scMathUtil.roundToString(q.quantity,3)},
-                        {name:"单位",value:q.unit}
+                        {name:"单位",value:q.quantityIndexUnit}
                     ]
                 };
                 return quantity;
@@ -326,8 +326,8 @@ async function exportSEI(projectID) {
         }
 
         function getFeatrue(node,parentMap){
+            let name = node.exportName?node.exportName:node.name;
             if(parentMap[node.ID]){//如果有子节点,那么它就是一个节点
-                let name = node.exportName?node.exportName:node.name;
                 let tem = {
                     name:name.replace("*",""),
                     attrs:[],
@@ -340,11 +340,21 @@ async function exportSEI(projectID) {
                 return tem;
             }else {//如果没有子节点,那么它就是父节点的一个属性
                 if(node.isDetail == true){//如果是明细节点,则造一个明细节点
-                    return {name:"明细",attrs:[{name:"名称",value:node.value}],children:[]};
+                    return {name:"明细",attrs:[{name:"名称",value:getValue(node)}],children:[]};
                 }
-                return {name:node.name.replace("*",""),value:node.value};
+                return {name:name.replace("*",""),value:getValue(node)};
             }
         }
+
+        function getValue(node) {
+            let value = node.value;
+            if(node.required == true){//必填项的值为空时导出0
+                if(value == undefined || value == null || value == "") value = "0";
+            }
+            return value;
+        }
+
+
     }
 
 

+ 54 - 20
web/building_saas/main/js/models/exportStdInterfaceBase.js

@@ -162,7 +162,7 @@ const XML_EXPORT_BASE = (() => {
      * @return {Object} failHints没通过的属性提示 filterAttrs过滤后的属性数据(失败提示在属性是必须的时候才提示,如果该属性失败了,但是是非必要属性,那么该属性不显示)
      * */
     function check(eleName, datas) {
-        let rst = {failHints: [], filterAttrs: []};
+        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) {
             // 值统一转换成String
@@ -176,19 +176,15 @@ const XML_EXPORT_BASE = (() => {
                 data.value = data.value.trim();
                 data.value = data.value.replace(/\s{1,}/g, ' ');
             }
-            /*if (!data.value && !data.minLen && !data.enumeration) {  //值为空,且没有限制最小字符数,且没有限制值,则不需判断
-             rst.filterAttrs.push(data);
-             continue;
-             }*/
             let isFail = false;
             let tempFail = '';
             // 提示的名称需要处理,有的接口xml属性为英文,需要显示其展示名称
             const name = data.dName || data.name;
-            if (data.minLen && data.value.length < data.minLen){
+            if (data.minLen && data.value.length < data.minLen) {
                 isFail = true;
                 tempFail = data.failHint
                     ? `${data.failHint}字符数不可小于${data.minLen}个。`
-                    :`${eleName}-“${data.name}”字符数不可小于${data.minLen}个。`;
+                    : `${eleName}-“${data.name}”字符数不可小于${data.minLen}个。`;
             } else if (data.maxLen && data.value.length > data.maxLen) {
                 isFail = true;
                 tempFail = data.failHint
@@ -224,7 +220,7 @@ const XML_EXPORT_BASE = (() => {
                     tempFail = data.failHint
                         ? `${data.failHint}必须为数值。`
                         : `${eleName}-“${data.name}”必须为数值。`;
-                } else if (!data.value.length || (data.value.split('.').length > 1 && data.value.split('.')[1].length > 2)){
+                } 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(String(data.value))) {
@@ -466,7 +462,7 @@ const XML_EXPORT_BASE = (() => {
         let target = [],
             temp = {};
         for (let data of datas) {
-            temp[data.ID] = {me: data, next: null, prev: null};
+            temp[data.ID] = { me: data, next: null, prev: null };
         }
         for (let data of datas) {
             let next = temp[data.NextSiblingID] || null;
@@ -503,8 +499,8 @@ const XML_EXPORT_BASE = (() => {
         let projectData = _cache.projectData;
         // 没有数据,需要拉取
         if (!Object.keys(projectData).length) {
-            projectData = await ajaxPost('/pm/api/getProjectByGranularity', {user_id: userID, tenderID: tenderID, granularity: granularity});
-            _cache.projectData =  projectData;
+            projectData = await ajaxPost('/pm/api/getProjectByGranularity', { user_id: userID, tenderID: tenderID, granularity: granularity });
+            _cache.projectData = projectData;
         }
         return projectData;
     }
@@ -521,6 +517,9 @@ const XML_EXPORT_BASE = (() => {
         if (!tenderDetail) {
             tenderDetail = PROJECT.createNew(tenderID, userID);
             await tenderDetail.loadDataSync();
+            // 标记序号
+            const count = Object.keys(_cache.tenderDetailMap).length;
+            tenderDetail.serialNo = count + 1;
             _cache.tenderDetailMap[tenderID] = tenderDetail;
         }
         return tenderDetail;
@@ -562,7 +561,7 @@ const XML_EXPORT_BASE = (() => {
     // 1.有子项,则取固定清单对应基数
     // 2.无子项,有基数,a.优先转换为行代号(不可自身) b.不能转换为行代号则找对应字典
     // 3.基数中有无法转换的,根据导出类型决定
-    function transformCalcBase(exportKind, tenderDetail, node, {CalcBaseMap, FlagCalcBaseMap}) {
+    function transformCalcBase(exportKind, tenderDetail, node, { CalcBaseMap, FlagCalcBaseMap }) {
         let expr = node.data.calcBase || '';
         if (node.children.length) {
             let flag = node.getFlag();
@@ -612,7 +611,7 @@ const XML_EXPORT_BASE = (() => {
                 } else {
                     let totalFee = getFee(node.data.fees, 'common.totalFee'),
                         feeRate = node.data.feeRate;
-                    return +feeRate ? scMathUtil.roundTo(totalFee/(feeRate/100), -2) : totalFee
+                    return +feeRate ? scMathUtil.roundTo(totalFee / (feeRate / 100), -2) : totalFee
                 }
             }
             return expr;
@@ -655,7 +654,7 @@ const XML_EXPORT_BASE = (() => {
                     break;
                 }
                 newBase.push(node && node.data.name ? node.data.name : '');
-            } else if (CalcStateMap[base]){    //字典转换为中文
+            } else if (CalcStateMap[base]) {    //字典转换为中文
                 newBase.push(CalcStateMap[base]);
             } else if (/^\d+(\.\d+)?$/.test(base)) {    //金额
                 newBase.push(base);
@@ -738,6 +737,40 @@ const XML_EXPORT_BASE = (() => {
         });
     }
 
+    /**
+     * 弱自检自检,有错误非强制不可导的自检
+     * failList里存的是导出规定属性时,不符合标准规定的错误,存在这种错误就不允许导出
+     * 这里的错误是业务上的提示错误,与标准文件规定无关,存在这种错误是允许导出的
+     * @return {Array} - 提示信息数组 
+     */
+    function softCheck() {
+        const tenderDetailMap = _cache.tenderDetailMap;
+        // 检查清单综合单价是否大于最高限价,大于则提示
+        function checkMaxPrice(tenderDetail) {
+            return tenderDetail.mainTree.items
+                    .filter(node => calcTools.unitFeeGTMaxPrice(node, 'common.unitFee'))
+                    .map(node => {
+                        const code = node.data.code || '';
+                        const name = node.data.name || '';
+                        return `第${node.serialNo()}行“${code + name}”,清单综合单价 > 最高限价`;
+                    });
+        }
+        const infos = [];
+        // 按照获取顺序serialNo(根据树结构)排序
+        Object.values(tenderDetailMap)
+            .sort((a, b) => a.serialNo - b.serialNo)
+            .forEach(tenderDetail => {
+                const maxPriceInfos = checkMaxPrice(tenderDetail);
+                if (!maxPriceInfos.length) {
+                    return;
+                }
+                infos.push(`<span style="font-weight: bold">单位工程“${tenderDetail.projectInfo.name}”下:</span>`);
+                infos.push(...maxPriceInfos);
+            });
+        return infos;
+    }
+    
+
     const UTIL = Object.freeze({
         deWeightHints,
         isDef,
@@ -759,7 +792,8 @@ const XML_EXPORT_BASE = (() => {
         getCodeSheetData,
         getElementFromSrc,
         getParsedData,
-        setupCode
+        setupCode,
+        softCheck
     });
 
     // 开始标签
@@ -794,8 +828,8 @@ const XML_EXPORT_BASE = (() => {
         //调整格式
         let rgx = /\n(<(([^\?]).+?)(?:\s|\s*?>|\s*?(\/)>)(?:.*?(?:(?:(\/)>)|(?:<(\/)\2>)))?)/mg;
         let nodeStack = [];
-        let output = text.replace(rgx, function($0, all, name, isBegin, isCloseFull1, isCloseFull2, isFull1, isFull2){
-            let isClosed = (isCloseFull1 === '/') || (isCloseFull2 === '/' ) || (isFull1 === '/') || (isFull2 === '/');
+        let output = text.replace(rgx, function ($0, all, name, isBegin, isCloseFull1, isCloseFull2, isFull1, isFull2) {
+            let isClosed = (isCloseFull1 === '/') || (isCloseFull2 === '/') || (isFull1 === '/') || (isFull2 === '/');
             let prefix = '';
             if (isBegin === '!') {
                 prefix = getPrefix(nodeStack.length);
@@ -810,7 +844,7 @@ const XML_EXPORT_BASE = (() => {
                     prefix = getPrefix(nodeStack.length);
                 }
             }
-            let ret =  '\n' + prefix + all;
+            let ret = '\n' + prefix + all;
             return ret;
         });
         let outputText = output.substring(1);
@@ -818,7 +852,7 @@ const XML_EXPORT_BASE = (() => {
         function getPrefix(prefixIndex) {
             let span = '    ';
             let output = [];
-            for (let i = 0 ; i < prefixIndex; ++i) {
+            for (let i = 0; i < prefixIndex; ++i) {
                 output.push(span);
             }
             return output.join('');
@@ -847,7 +881,7 @@ const XML_EXPORT_BASE = (() => {
             xmlStr = `<?xml version="1.0" encoding="utf-8"?>${xmlStr}`;
             // 格式化
             xmlStr = _formatXml(xmlStr);
-            let blob = new Blob([xmlStr], {type: 'text/plain;charset=utf-8'});
+            let blob = new Blob([xmlStr], { type: 'text/plain;charset=utf-8' });
             return {
                 blob: blob,
                 exportKind: extractObj.exportKind,

+ 0 - 2
web/building_saas/main/js/models/overHeight.js

@@ -1064,8 +1064,6 @@ const OVER_HEIGHT = (() => {
      * 因此各种操作下改变了相关定额,都要重新计算超高子目
      * 为了降低复杂度和保证逻辑统一性,重新计取为重新走(删除新增逻辑)
      * 需要尽可能地降低操作的触发率
-     * @param {type}  - 
-     * @return: {type} - 
      */
     function reCalcOverHeightFee() {
         const project = projectObj.project;

+ 38 - 15
web/building_saas/main/js/views/export_view.js

@@ -59,6 +59,22 @@ const ExportView = (() => {
         _exportCache = [];
         _cache.clear();
     }
+    // 设置提示高度样式
+    function setHeightByInfo(infos) {
+        if (infos.length * 20 > 400) {
+            $('#hintBox_caption').addClass('export-check');
+        }
+    }
+    // 显示工程编码设置窗口
+    function showSetCodeModal(isPring) {
+        if (isPring) {
+            setTimeout(() => {
+                $('#exportCode').modal('show');
+            }, 300);
+        } else {
+            $('#exportCode').modal('show');
+        }
+    }
     //事件监听
     function exportListener() {
         //导出接口-项目自检
@@ -84,15 +100,18 @@ const ExportView = (() => {
                     }
                 }
                 failList = _util.deWeightHints(failList);
-                //设置提示弹窗
-                if (failList.length * 20 > 400) {
-                    $('#hintBox_caption').addClass('export-check');
-                }
                 if (failList.length) {
+                    //设置提示弹窗
+                    setHeightByInfo(failList);
                     throw failList.join('<br/>');
-                } else {
-                    throw '自检完成,未检测到错误数据。'
+                } 
+                // 弱自检
+                const infos = _util.softCheck();
+                if (infos.length) {
+                    setHeightByInfo(infos);
+                    throw infos.join('<br/>');
                 }
+                throw '自检完成,未检测到错误数据。'
             } catch (err) {
                 alert(err);
             }
@@ -128,21 +147,25 @@ const ExportView = (() => {
                     pr.end();
                 }
                 failList = _util.deWeightHints(failList);
-                //错误-设置提示弹窗
-                if (failList.length * 20 > 400) {
-                    $('#hintBox_caption').addClass('export-check');
-                }
                 if (failList.length) {
+                    //错误-设置提示弹窗
+                    setHeightByInfo(failList);
                     throw failList.join('<br/>');
                 }
-                //弹出工程编号设置窗口
-                if (isPring) {
+                // 如果没有自检过,需要进行弱自检,并且弹出的窗口包含“继续、取消”按钮
+                const infos = _util.softCheck();
+                if (infos.length) {
+                    const doYes = () => {
+                        showSetCodeModal(isPring);
+                    };
+                    hintBox.infoBox('系统提示', infos.join('<br/>'), hintBox.btnType.yesNo, doYes, null, ['继续', '取消']);
                     setTimeout(() => {
-                        $('#exportCode').modal('show');
+                        STATE.exporting = false;
                     }, 300);
-                } else {
-                    $('#exportCode').modal('show');
+                    return;
                 }
+                //弹出工程编号设置窗口
+                showSetCodeModal(isPring);
             } catch (err) {
                 console.log(err);
                 pr.end();

+ 2 - 10
web/building_saas/main/js/views/main_tree_col.js

@@ -558,20 +558,12 @@ let MainTreeCol = {
         }
         return tips
     },
+    // 字体颜色w
     foreColor: {
         // 清单综合单价>最高限价时,标红显示
         'feesIndex.common.unitFee': function (node) {
             const color = 'red';
-            if (!calcTools.isBill(node)) {
-                return;
-            }
-            const totalFee = calcTools.getFee(node, 'common.unitFee');
-            const maxPrice = node.data.maxPrice;
-            // 最高限价有值才对比
-            if (!commonUtil.isDef(maxPrice)) {
-                return;
-            }
-            return totalFee > maxPrice ? color : null;
+            return calcTools.unitFeeGTMaxPrice(node, 'common.unitFee') ? color : null;
         }
     }
 };

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

@@ -626,16 +626,6 @@ var projectObj = {
         let code = node.data.code ? node.data.code : '';
         if(node.sourceType == ModuleNames.bills){//当清单是“分部分项工程”、“措施项目工程”时,要展开清单规则节点
             if(BILLS.isFXorBX(node)||(node.data.type == billType.BILL && BILLS.isMeasure(node))){//是分项或补项,是清单并且属于措施项目节点
-              /*  if(billsLibObj.stdBillsTree === null){
-                    billsLibObj.doAfterLoadBills = function () {
-                        this.locateAtBills(code);
-                        this.doAfterLoadBills = null;
-                    };
-                }
-                else {
-                    billsLibObj.locateAtBills(code);
-                }
-                if(!$("#qd").is(":visible"))  $('#stdBillsTab').click();*/
                 if(!billsGuidance.bills.tree){
                     doAfterLoadGuidance = function () {
                         billsGuidance.locateAtBills(code);

+ 10 - 9
web/building_saas/main/js/views/std_ration_lib.js

@@ -205,14 +205,15 @@ var rationLibObj = {
                 return;
             }
             //提取需要匹配的章节名称
-            //去掉前缀
-            let toMatchArr = sectionName.split(' '),
-                toMatchStr = toMatchArr[toMatchArr.length - 1];
-            //去掉后缀
-            let sectionReg = /\(\w{9,}\)/g,
-                regMatch = toMatchStr.match(sectionReg);
-            if (regMatch) {
-                toMatchStr = toMatchStr.replace(regMatch[regMatch.length - 1], '');
+            // 去掉后缀
+            const suffixReg = /[((]编码[::]\d+[))]/;
+            const tempName = sectionName.split(suffixReg)[0];
+            // 获取第一个空格后的内容
+            const sReg = /\s(.+)/;
+            const tempTarget = tempName.match(sReg);
+            const target = tempTarget ? tempTarget[1] : null;
+            if (!target) {
+                return;
             }
             //简化匹配到的定额名称
             for (let data of datas) {
@@ -225,7 +226,7 @@ var rationLibObj = {
                     continue;
                 }
                 let matchName = nameArr[0];
-                if (matchName === toMatchStr) {
+                if (matchName === target) {
                     nameArr.shift();
                     data.name = nameArr.join(' ');
                 }

+ 2 - 2
web/building_saas/pm/html/project-management.html

@@ -250,7 +250,7 @@
                         </div>
                     </div>
                     <span class="form-text text-danger" id="proj-valuation-info" style="display: none;">请选择计价规则</span>
-                    <div class="form-group row">
+                    <div class="form-group row" id="project-dialog-fileKind">
                         <label for="staticEmail" class="col-auto col-form-label col-form-label-sm">文件类型</label>
                         <div class="col">
                             <div class="custom-control custom-radio custom-control-inline">
@@ -355,7 +355,7 @@
                             </div>
                         </div>
                         <span class="form-text text-danger" id="valuation-info" style="display: none;">请选择计价规则</span>
-                        <div class="form-group row">
+                        <div class="form-group row" id="tender-dialog-fileKind">
                             <label for="staticEmail" class="col-auto col-form-label col-form-label-sm">文件类型</label>
                             <div class="col">
                                 <div class="custom-control custom-radio custom-control-inline">

+ 19 - 0
web/building_saas/pm/js/pm_newMain.js

@@ -464,6 +464,8 @@ const projTreeObj = {
                             if(selectedItem.children[0] .projType === projectType.project ) return false;//如果文件夹有子项,并且是建设项目,可用
                         }
                     }
+                } else {
+                    return false;
                 }
                 return true;
             },
@@ -1647,6 +1649,9 @@ const projTreeObj = {
             parent = selectNode.parent;
             next = selectNode.nextSibling;
             updateData["update"] = {query:{ID:selectNode.id()}}
+        } else if (!selectNode) { // 默认在第一位
+            parent = selectNode ? selectNode.parent : projTreeObj.tree._root;
+            next = selectNode ? selectNode.nextSibling : projTreeObj.tree.firstNode();
         }
         updateData["self"] ={ParentID:parent.id(),NextSiblingID:next?next.id():-1};
         return updateData;
@@ -1850,12 +1855,26 @@ $(document).ready(function() {
         folderDialog.on('shown.bs.modal', function () {
             $('#folder-name').focus();
         });
+        projDialog.on('show.bs.modal', function () {
+            // 内蒙古费用定额,新建建设项目页面隐藏“文件类型:投标、招标”
+            const filterCompilationNames = ['内蒙古定额(2017)'];
+            if (filterCompilationNames.includes(compilationData.name)) {
+                $('#project-dialog-fileKind').hide();
+            }
+        });
         projDialog.on('shown.bs.modal', function () {
             $('#project-name').focus();
         });
         engDialog.on('shown.bs.modal', function () {
             $('#engineering-name').focus();
         });
+        tenderDialog.on('show.bs.modal', function () {
+            $('#tender-name').focus();
+            const filterCompilationNames = ['内蒙古定额(2017)'];
+            if (filterCompilationNames.includes(compilationData.name)) {
+                $('#tender-dialog-fileKind').hide();
+            }
+        });
         tenderDialog.on('shown.bs.modal', function () {
             $('#tender-name').focus();
         });