Explorar o código

Merge branch 'master' of http://smartcost.f3322.net:3000/SmartCost/ConstructionCost

zhangweicheng %!s(int64=7) %!d(string=hai) anos
pai
achega
783028534c

+ 29 - 25
modules/reports/rpt_component/helper/jpc_helper_common_output.js

@@ -2,7 +2,7 @@ let JV = require('../jpc_value_define');
 let JpcFieldHelper = require('./jpc_helper_field');
 
 let JpcCommonOutputHelper = {
-    createCommonOutputWithoutDecorate: function (node, value, controls) {
+    createCommonOutputWithoutDecorate: function (node, value) {
         let rst = {};
         //1. font/style/control
         rst[JV.PROP_FONT] = node[[JV.PROP_FONT]];
@@ -10,20 +10,11 @@ let JpcCommonOutputHelper = {
         rst[JV.PROP_STYLE] = node[[JV.PROP_STYLE]];
         //2. value
         rst[JV.PROP_VALUE] = value;
-        if (node[JV.PROP_FORMAT]) {
-            if (!(isNaN(parseFloat(rst[JV.PROP_VALUE])))) {
-                let dotIdx = node[JV.PROP_FORMAT].indexOf(".");
-                if (dotIdx >= 0) {
-                    rst[JV.PROP_VALUE] = parseFloat(rst[JV.PROP_VALUE]).toFixed(node[JV.PROP_FORMAT].length - dotIdx - 1);
-                } else {
-                    rst[JV.PROP_VALUE] = parseFloat(rst[JV.PROP_VALUE]).toFixed(0);
-                }
-            }
-        }
-        if (node[JV.PROP_PREFIX] && rst[JV.PROP_VALUE] != null) {
+        innerFormat(node[JV.PROP_FORMAT], rst);
+        if (node[JV.PROP_PREFIX] && rst[JV.PROP_VALUE] !== null) {
             rst[JV.PROP_VALUE] = node[JV.PROP_PREFIX] + rst[JV.PROP_VALUE];
         }
-        if (node[JV.PROP_SUFFIX] && rst[JV.PROP_VALUE] != null) {
+        if (node[JV.PROP_SUFFIX] && rst[JV.PROP_VALUE] !== null) {
             rst[JV.PROP_VALUE] = rst[JV.PROP_VALUE] + node[JV.PROP_SUFFIX];
         }
         return rst;
@@ -37,24 +28,37 @@ let JpcCommonOutputHelper = {
         //2. value
         rst[JV.PROP_VALUE] = value;
         JpcFieldHelper.decorateValue(rst, controls);
-        if (node[JV.PROP_FORMAT]) {
-            if (!(isNaN(parseFloat(rst[JV.PROP_VALUE])))) {
-                let dotIdx = node[JV.PROP_FORMAT].indexOf(".");
-                if (dotIdx >= 0) {
-                    rst[JV.PROP_VALUE] = parseFloat(rst[JV.PROP_VALUE]).toFixed(node[JV.PROP_FORMAT].length - dotIdx - 1);
-                } else {
-                    rst[JV.PROP_VALUE] = parseFloat(rst[JV.PROP_VALUE]).toFixed(0);
-                }
-            }
-        }
-        if (node[JV.PROP_PREFIX] && rst[JV.PROP_VALUE] != null && rst[JV.PROP_VALUE] != "") {
+        innerFormat(node[JV.PROP_FORMAT], rst);
+        if (node[JV.PROP_PREFIX] && rst[JV.PROP_VALUE] !== null && rst[JV.PROP_VALUE] !== "") {
             rst[JV.PROP_VALUE] = node[JV.PROP_PREFIX] + rst[JV.PROP_VALUE];
         }
-        if (node[JV.PROP_SUFFIX] && rst[JV.PROP_VALUE] != null && rst[JV.PROP_VALUE] != "") {
+        if (node[JV.PROP_SUFFIX] && rst[JV.PROP_VALUE] !== null && rst[JV.PROP_VALUE] !== "") {
             rst[JV.PROP_VALUE] = rst[JV.PROP_VALUE] + node[JV.PROP_SUFFIX];
         }
         return rst;
     }
+};
+
+function innerFormat(formatStr, rst) {
+    if (formatStr) {
+        if (!(isNaN(parseFloat(rst[JV.PROP_VALUE])))) {
+            let dotIdx = formatStr.indexOf(".");
+            if (dotIdx >= 0) {
+                rst[JV.PROP_VALUE] = parseFloat(rst[JV.PROP_VALUE]).toFixed(formatStr.length - dotIdx - 1);
+            } else {
+                rst[JV.PROP_VALUE] = parseFloat(rst[JV.PROP_VALUE]).toFixed(0);
+            }
+            let commaIdx = formatStr.indexOf(",");
+            if (commaIdx >= 0) {
+                rst[JV.PROP_VALUE] = comdify(rst[JV.PROP_VALUE].toString());
+            }
+        }
+    }
+}
+
+function comdify(numStr){
+    let re = /\d{1,3}(?=(\d{3})+$)/g;
+    return numStr.replace(/^(\d+)((\.\d+)?)$/,function(s,s1,s2){return s1.replace(re,"$&,")+s2;});
 }
 
 module.exports = JpcCommonOutputHelper;

+ 1 - 0
modules/reports/rpt_component/jpc_bill_tab.js

@@ -1,4 +1,5 @@
 let JV = require('./jpc_value_define');
+let JE = require('./jpc_rte');
 let JpcFieldHelper = require('./helper/jpc_helper_field');
 let JpcBandHelper = require('./helper/jpc_helper_band');
 let JpcCommonHelper = require('./helper/jpc_helper_common');

+ 2 - 1
modules/reports/rpt_component/jpc_rte.js

@@ -1,9 +1,10 @@
 /**
  * Created by Tony on 2016/12/28.
  */
-
+let strUtil = require('../../../public/stringUtil');
 let JV = require('./jpc_value_define');
 let JE = {
+    $STR_UTIL: strUtil,
     F: function(fID, $CURRENT_RPT) {
         let rst = null;
         if ($CURRENT_RPT && ($CURRENT_RPT.fields[JV.NODE_DETAIL_FIELDS][JV.PROP_ID + "_" + fID])) {

+ 13 - 5
public/stringUtil.js

@@ -149,6 +149,10 @@ module.exports = {
         let regExp = new RegExp(FindText, "gm");
         return targetStr.replace(regExp, RepText);
     },
+    comdify: function(numStr){
+        let re = /\d{1,3}(?=(\d{3})+$)/g;
+        return numStr.replace(/^(\d+)((\.\d+)?)$/,function(s,s1,s2){return s1.replace(re,"$&,")+s2;});
+    },
     convertToCaptionNum: function(num, isCurrency, isTraditionalCap) {
         let me = this, rst = "";
         if (/^\d*(\.\d*)?$/.test(num)) {
@@ -187,12 +191,16 @@ module.exports = {
                 //小数部分处理
                 if (numSplitArr.length > 1) {
                     len = numSplitArr[1].length;
-                    if (isCurrency && len > 2) len = 2;
-                    let fractionStr = [];
-                    for (let idx = 0; idx < len; idx++) {
-                        fractionStr.push(capChars[ parseInt(numSplitArr[1].charAt(idx))]+ (isCurrency?((idx === 0)?"角":"分"):""));
+                    if (parseInt(numSplitArr[1]) === 0) {
+                        rst = rst + (isCurrency?"元整":"");
+                    } else {
+                        if (isCurrency && len > 2) len = 2;
+                        let fractionStr = [];
+                        for (let idx = 0; idx < len; idx++) {
+                            fractionStr.push(capChars[ parseInt(numSplitArr[1].charAt(idx))]+ (isCurrency?((idx === 0)?"角":"分"):""));
+                        }
+                        rst = rst + (isCurrency?"元":"点") + fractionStr.join("");
                     }
-                    rst = rst + (isCurrency?"元":"点") + fractionStr.join("");
                 } else {
                     rst = rst + (isCurrency?"元整":"");
                 }

+ 2 - 2
public/web/sheet/sheet_common.js

@@ -235,7 +235,7 @@ var sheetCommonObj = {
         ComboCellForActiveCell.prototype = new GC.Spread.Sheets.CellTypes.ComboBox();
         ComboCellForActiveCell.prototype.paintValue = function (ctx, value, x, y, w, h, style, options) {
             let sheet = options.sheet;
-            if (options.row === sheet.getActiveRowIndex() && options.col === sheet.getActiveColumnIndex()) {
+            if (options.row === sheet.getActiveRowIndex() && options.col === sheet.getActiveColumnIndex() && !sheet.getCell(options.row, options.col).locked()) {
                 GC.Spread.Sheets.CellTypes.ComboBox.prototype.paintValue.apply(this, arguments);
 
             } else {
@@ -244,7 +244,7 @@ var sheetCommonObj = {
         };
         ComboCellForActiveCell.prototype.getHitInfo = function (x, y, cellStyle, cellRect, options) {
             let sheet = options.sheet;
-            if (options.row === sheet.getActiveRowIndex() && options.col === sheet.getActiveColumnIndex()) {
+            if (options.row === sheet.getActiveRowIndex() && options.col === sheet.getActiveColumnIndex() && !sheet.getCell(options.row, options.col).locked()) {
                 return GC.Spread.Sheets.CellTypes.ComboBox.prototype.getHitInfo.apply(this, arguments);
 
             } else {

+ 43 - 5
test/demo/stringTest.js

@@ -55,9 +55,47 @@ var strUtil = require('../../public/stringUtil');
 //     t.end();
 // })
 
-test('test typeof', function(t){
-    t.equal(typeof(true), "boolean");
-    t.equal((typeof("abc")).toUpperCase(), "STRING");
-    t.equal(typeof(1), "number");
+// test('test typeof', function(t){
+//     t.equal(typeof(true), "boolean");
+//     t.equal((typeof("abc")).toUpperCase(), "STRING");
+//     t.equal(typeof(1), "number");
+//     t.end();
+// })
+
+test('test 千分位', function(t){
+    let num = 123.01;
+    t.equal( strUtil.comdify(num.toString()), "123.01");
+    num = 123456.01;
+    t.equal( strUtil.comdify(num.toString()), "123,456.01");
+    num = 1234567.01;
+    t.equal( strUtil.comdify(num.toString()), "1,234,567.01");
+    num = 1234567;
+    t.equal( strUtil.comdify(String(num)), "1,234,567");
+    t.end();
+})
+
+
+test('test number to Chinese', function(t){
+    t.equal(strUtil.convertToCaptionNum(0, false, false), '零');
+    t.equal(strUtil.convertToCaptionNum(0, true, false), '零元整');
+    t.equal(strUtil.convertToCaptionNum(0.68, true, false), '零元六角八分');
+    t.equal(strUtil.convertToCaptionNum(0.68, true, true), '零元陆角捌分');
+    t.equal(strUtil.convertToCaptionNum(10, false, false), '一十');
+    t.equal(strUtil.convertToCaptionNum(10, false, true), '壹拾');
+    t.equal(strUtil.convertToCaptionNum(11, false, false), '一十一');
+    t.equal(strUtil.convertToCaptionNum(11, false, true), '壹拾壹');
+    t.equal(strUtil.convertToCaptionNum(12, false, false), '一十二');
+    t.equal(strUtil.convertToCaptionNum(12, false, true), '壹拾贰');
+    t.equal(strUtil.convertToCaptionNum(21, false, false), '二十一');
+    t.equal(strUtil.convertToCaptionNum(21, false, true), '贰拾壹');
+
+    t.equal(strUtil.convertToCaptionNum(0.123456789, false, false), '零点一二三四五六七八九');
+    t.equal(strUtil.convertToCaptionNum(10.123456789, false, false), '一十点一二三四五六七八九');
+
+    t.equal(strUtil.convertToCaptionNum(123456789.15, false, false), '一亿二千三百四十五万六千七百八十九点一五');
+    t.equal(strUtil.convertToCaptionNum(123456789.15, false, true), '壹億贰仟叁佰肆拾伍萬陆仟柒佰捌拾玖点壹伍');
+    t.equal(strUtil.convertToCaptionNum(123456789.15, true, false), '一亿二千三百四十五万六千七百八十九元一角五分');
+    t.equal(strUtil.convertToCaptionNum(123456789.15, true, true), '壹億贰仟叁佰肆拾伍萬陆仟柒佰捌拾玖元壹角伍分');
+
     t.end();
-})
+})

+ 14 - 8
web/building_saas/main/js/models/calc_program.js

@@ -341,18 +341,24 @@ let executeObj = {
                 if (!me.treeNode.data.gljList) return 0;
                 let result = 0;
                 for (let glj of me.treeNode.data.gljList) {
-                    let price = 0;
+                    let price = 0, temp = 0;
                     if (base.gljTypes.indexOf(glj.type) >= 0) {
-                        if (base.calcType == baseCalcType.baseCalc){ price = parseFloat(glj["basePrice"]);}
-                        else if (base.calcType == baseCalcType.adjustCalc){price = parseFloat(glj["adjustPrice"]);}
-                        else if (base.calcType == baseCalcType.budgetCalc){price = parseFloat(glj["marketPrice"]);}
-                        else if (base.calcType == baseCalcType.diffCalc){
+                        if (base.calcType == baseCalcType.diffCalc){
                             let aprice = glj["adjustPrice"] ? glj["adjustPrice"] : 0;
+                            aprice = parseFloat(aprice);
                             let mprice = glj["marketPrice"] ? glj["marketPrice"] : 0;
-                            price = (parseFloat(mprice) - parseFloat(aprice)).toDecimal(decimalObj.process);
+                            mprice = parseFloat(mprice);
+                            temp = (glj["quantity"] * mprice).toDecimal(decimalObj.ration.unitPrice) - (glj["quantity"] * aprice).toDecimal(decimalObj.ration.unitPrice);
+                            temp = temp.toDecimal(decimalObj.ration.unitPrice);
+                        }
+                        else {
+                            if (base.calcType == baseCalcType.baseCalc){ price = parseFloat(glj["basePrice"]);}
+                            else if (base.calcType == baseCalcType.adjustCalc){price = parseFloat(glj["adjustPrice"]);}
+                            else if (base.calcType == baseCalcType.budgetCalc){price = parseFloat(glj["marketPrice"]);}
+                            temp = (glj["quantity"] * price).toDecimal(decimalObj.ration.unitPrice);
                         };
-                        result = result + (glj["quantity"] * price).toDecimal(decimalObj.process);
-                        result = (result).toDecimal(decimalObj.process);
+
+                        result = (result + temp).toDecimal(decimalObj.ration.unitPrice);
                     };
                 };
                 return result;

+ 1 - 1
web/building_saas/main/js/views/main_tree_col.js

@@ -85,7 +85,7 @@ let MainTreeCol = {
             return node.sourceType === projectObj.project.Bills.getSourceType();
         },
         ration: function (node) {
-            return node.sourceType === projectObj.project.Ration.getSourceType();
+            return projectObj.project.calcProgram.isRation(node);
         },
         glj: function (node) {
             return node.sourceType == projectObj.project.ration_glj.getSourceType();

+ 0 - 1
web/building_saas/main/js/views/project_property_decimal_view.js

@@ -79,7 +79,6 @@ function isValidDigit(v){
 //newV用户可编辑数据
 function toUpdateDecimal(orgV, newV){
     let rst = false;
-    let len = Object.keys(newV).length;
     reCompare(orgV, newV);
     function reCompare(orgV, newV){
         for(let attr in newV){

+ 95 - 2
web/building_saas/main/js/views/project_view.js

@@ -465,6 +465,7 @@ var projectObj = {
                 that.mainSpread.bind(GC.Spread.Sheets.Events.EnterCell, that.mainSpreadEnterCell);
                 that.mainSpread.bind(GC.Spread.Sheets.Events.EditEnded, that.mainSpreadEditEnded);
                 that.mainSpread.bind(GC.Spread.Sheets.Events.RangeChanged, that.mainSpreadRangeChanged);
+                that.mainSpread.bind(GC.Spread.Sheets.Events.SelectionChanged, that.amountAreaNumber);
                 that.loadMainSpreadContextMenu();
                 that.loadFocusLocation();
             }
@@ -611,7 +612,95 @@ var projectObj = {
             this.mainController.setTreeSelected(this.mainController.tree.items[row]);//触发树节点选中事件
         }
     },
+    // 选中区域合计数字
+    amountAreaNumber: function(e, info) {
+        if (info.newSelections === undefined || info.newSelections.length <= 0) {
+            return false;
+        }
+        const selectedArea = info.newSelections[0];
+        const sheet = info.sheet;
+        if (selectedArea.colCount <= 1 && selectedArea.rowCount <= 1) {
+            return false;
+        }
+        // 获取鼠标位置
+        let x = window.event.clientX;
+        let y = window.event.clientY;
+
+        // 匹配数字或小数
+        const regular = /^([0-9]+[.]{1}[0-9]+)$|^([1-9]{1}\d+)$/;
+        // 小数点最高位数
+        let max = 0;
+        let total = 0;
+        for (let col = selectedArea.col; col < (selectedArea.colCount + selectedArea.col); col++) {
+            for (let row = selectedArea.row; row < (selectedArea.rowCount + selectedArea.row); row++) {
+                const value = sheet.getCell(row, col).value();
+                if (!regular.test(value)) {
+                    continue;
+                }
+                // 获取当前数据小数位数
+                let pointPosition = value.toString().indexOf(".");
+                pointPosition = pointPosition < 0 ? pointPosition : pointPosition + 1;
+                const current = pointPosition > 0 ? value.toString().substring(pointPosition, value.toString().length).length : 0;
+                max = current > max ? current : max;
+                total += parseFloat(value);
+            }
+        }
+        // 如果不为0则悬浮显示
+        if (total > 0) {
+            const div = $('<div id="total-tips"><p>合计: <input type="text" id="total" readonly="readonly" style="border: none;"/></p><p><a href="javascript:void(0);">复制</a></p></div>');
+            div.css({
+                position: "absolute",
+                border: "1px #C0C0C0 solid",
+                background: "#fff",
+                boxShadow: "1px 2px 5px rgba(0,0,0,0.4)",
+            });
+            div.children("p").css({
+                textAlign: "center",
+                padding: 8,
+                marginBottom: 2,
+            });
+            div.children("p").first().css({
+                borderBottom: "1px #C0C0C0 solid"
+            });
+            const totalString = total.toFixed(max);
+            // input长度
+            const inputWidth = totalString.length * 8;
+            // 计算是否会超出显示范围
+            const baseWidth = 48;
+            const baseHeight = 81;
+            const canvasWidth = $("#billsSpreadvp_vp").width();
+            const canvasHeight = $("#billsSpreadvp_vp").height();
+            x = x + baseWidth + inputWidth > canvasWidth ? x - baseWidth - inputWidth : x;
+            y = y + baseHeight > canvasHeight ? y - baseHeight : y;
+            div.css({
+                left: x,
+                top: y,
+            });
+
+            div.children().children("#total").width(inputWidth).val(totalString);
+            $("body").append(div);
+            // 用于判断是否要关闭窗体
+            setTimeout(function() {
+                isTotalShowing = true;
+            }, 200);
+        };
+    }
 };
+// 点击合计框中的复制
+$("body").on("click", "#total-tips a", function() {
+    const totalElement = $(this).parent().siblings("p").find("#total");
+    totalElement.select();
+    document.execCommand("Copy");
+    $(this).text("已复制");
+});
+// 合计框点击其他位置关闭
+let isTotalShowing = false;
+$("body").on("click",  function(e) {
+    if (isTotalShowing && !$(e.target).is("#total-tips") && !$(e.target).is("#total-tips p") && !$(e.target).is("#total-tips p a")) {
+        $("#total-tips").remove();
+        isTotalShowing = false;
+    }
+});
 
 $('#insert').click(function () {
     var controller = projectObj.mainController, project = projectObj.project;
@@ -762,12 +851,16 @@ $('#property_ok').click(function () {
     }
     //小数位数
     let updateDecimal = m_getDecimalData($('input', '#poj-settings-decimal'));
-    if(toUpdateDecimal(decimalObj, updateDecimal)){
+    if(toUpdateDecimal(decimalObj, updateDecimal)) {
+        let frChanged = decimalObj.feeRate != updateDecimal.feeRate;
         setDecimal(decimalObj, updateDecimal);
+        if (frChanged) {
+            project.calcProgram.compileAllTemps()
+        }
         reCalcRations = true;
         reCalcBills = true;
         properties['property.decimal'] = updateDecimal;
-    };
+    }
     // 呈现选项
     projDisplayView.updateChecking(projectID, properties);