Browse Source

导出接口相关

1.增加弱自检,检查清单单价是否大于最高限价
2.导出调价后的数据
vian 5 years ago
parent
commit
2d6baae517

+ 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);
                 }
             })(itemName))
         }

+ 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;
     }
 };
 

+ 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
     },
+    // 字体颜色
     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);