浏览代码

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

TonyKang 7 年之前
父节点
当前提交
71efef2e42
共有 27 个文件被更改,包括 1819 次插入1524 次删除
  1. 8 1
      modules/glj/controllers/glj_controller.js
  2. 9 0
      modules/main/controllers/bills_controller.js
  3. 20 2
      modules/main/models/bills.js
  4. 16 1
      modules/main/models/bills_sub_schemas.js
  5. 3 1
      modules/main/routes/bills_route.js
  6. 3 3
      modules/ration_glj/facade/glj_calculate_facade.js
  7. 2 1
      modules/ration_repository/controllers/ration_controller.js
  8. 2 2
      modules/ration_repository/models/ration_item.js
  9. 1 1
      public/web/sheet/sheet_common.js
  10. 11 4
      web/building_saas/glj/js/common_spread.js
  11. 12 2
      web/building_saas/glj/js/composition.js
  12. 7 7
      web/building_saas/glj/js/composition_spread.js
  13. 41 41
      web/building_saas/glj/js/project_glj.js
  14. 27 11
      web/building_saas/glj/js/project_glj_spread.js
  15. 15 5
      web/building_saas/main/js/models/calc_base.js
  16. 4 1
      web/building_saas/main/js/models/calc_program.js
  17. 6 0
      web/building_saas/main/js/models/main_consts.js
  18. 104 88
      web/building_saas/main/js/models/project_glj.js
  19. 369 339
      web/building_saas/main/js/models/ration_glj.js
  20. 1 2
      web/building_saas/main/js/views/calc_base_view.js
  21. 7 196
      web/building_saas/main/js/views/calc_program_view.js
  22. 190 110
      web/building_saas/main/js/views/character_content_view.js
  23. 854 654
      web/building_saas/main/js/views/glj_view.js
  24. 57 42
      web/building_saas/main/js/views/main_tree_col.js
  25. 1 1
      web/building_saas/main/js/views/project_property_decimal_view.js
  26. 10 9
      web/building_saas/main/js/views/project_view.js
  27. 39 0
      web/building_saas/main/js/views/sub_view.js

+ 8 - 1
modules/glj/controllers/glj_controller.js

@@ -128,8 +128,15 @@ class GLJController extends BaseController {
                         if (mixRatioData.length <= 0) {
                             break;
                         }
+                        let indexList = ['code','name','specs','unit','type'];
+                        let keyList = mixRatioData.connect_key.split("|-|");
                         // 更新市场单价和基价单价
-                        let condition = {code: mixRatioData.connect_code, unit_price_file_id: mixRatioData.unit_price_file_id};
+                        let condition = {unit_price_file_id: mixRatioData.unit_price_file_id};
+                        for(let i = 1;i<keyList.length;i++){
+                            if(keyList[i]!='null'){
+                                condition[indexList[i]]=keyList[i];
+                            }
+                        }
                         let unitPriceUpdate = {
                             base_price: basePrice,
                             market_price: marketPrice

+ 9 - 0
modules/main/controllers/bills_controller.js

@@ -49,6 +49,15 @@ module.exports = {
         billsData.updateCharacterContent(findSet, updateObj, txtObj, function (err, message) {
             callback(req, res, err, message, null);
         });
+    },
+    updateBill: async function(request, response) {
+        const data = JSON.parse(request.body.data);
+        const findSet = data.findSet;
+        const updateData = data.updateData;
+        const result = await billsData.updateBill(findSet, updateData);
+        const message = !result ? '修改失败' : '修改成功';
+        const err = !result ? 1 : 0;
+        callback(request, response, err, message, null);
     }
 
 };

+ 20 - 2
modules/main/models/bills.js

@@ -60,7 +60,9 @@ let billsSchema = new Schema({
     fees: [subSchema.feesSchema],
     // 标记字段
     flags: [subSchema.flagsSchema],
-    deleteInfo: deleteSchema
+    deleteInfo: deleteSchema,
+    // 添加规则
+    addRule: subSchema.addRuleSchema,
 });
 
 let bills = db.model("bills", billsSchema);
@@ -143,6 +145,22 @@ class billsModel extends baseModel {
            }
        });
     };
-};
+    async updateBill(findSet, updateData) {
+        let update = {};
+        if (!updateData instanceof Array) {
+            return false;
+        }
+
+        for (const tmp of updateData) {
+            update[tmp.field] = tmp.value;
+        }
+
+        if (Object.keys(update).length <= 0) {
+            return false;
+        }
+
+        return bills.update(findSet, update);
+    };
+}
 
 module.exports = new billsModel();

+ 16 - 1
modules/main/models/bills_sub_schemas.js

@@ -44,5 +44,20 @@ let itemCharacterSchema = new Schema({
     eigenvalue: [eigenvalueSchema],//特征值
     isChecked: Boolean //是否勾选(输出)
 }, {_id: false});
+// 添加规则字段
+let addRuleSchema = new Schema({
+    // 添加位置
+    position: Number,
+    // 添加内容
+    addContent: Number,
+    // 显示格式
+    displayFormat: Number,
+    // 特征生成方式
+    characterFormat: Number,
+    // 子目生成方式
+    childDisplayFormat: Number,
+    // 序号格式
+   serialType: Number,
+}, {_id: false});
 
-module.exports = {feesSchema: feesSchema, flagsSchema: flagsSchema, jobContentSchema: jobContentSchema, itemCharacterSchema: itemCharacterSchema};
+module.exports = {feesSchema: feesSchema, flagsSchema: flagsSchema, jobContentSchema: jobContentSchema, itemCharacterSchema: itemCharacterSchema, addRuleSchema};

+ 3 - 1
modules/main/routes/bills_route.js

@@ -9,7 +9,9 @@ module.exports = function (app) {
     billsRouter.post('/getData', billsController.getData);
     billsRouter.post('/getItemTemplate', billsController.getItemTemplate);
     billsRouter.post('/allocIDs', billsController.allocIDs);
-    billsRouter.post('/updateCharacterContent', billsController.updateCharacterContent)//特征及内容更新 zhong 2017-9-1
+    billsRouter.post('/updateCharacterContent', billsController.updateCharacterContent);//特征及内容更新 zhong 2017-9-1
+    // 批量更新bill数据
+    billsRouter.post('/updateBill', billsController.updateBill);
     app.use('/bills', billsRouter);
 };
 

+ 3 - 3
modules/ration_glj/facade/glj_calculate_facade.js

@@ -20,7 +20,7 @@ module.exports={
 //辅助定额调整、替换工料机、标准附注条件调整、添加工料机、自定义消耗量(包括删除工料机)、自定义乘系数、市场单价调整
 let stateSeq ={
     ass:1,
-    replase:2,
+    replace:2,
     coe:3,
     add:4,
     cusQuantity:5,
@@ -139,8 +139,8 @@ function calculateAss(quantity,assList,glj) {
 
 function generateAdjustState(glj,coeList,adjustState,index,quantity) {
    //替换工料机 and 添加工料机
-    if(glj._doc.createType=='replace'){
-        adjustState.push({index:stateSeq.replase,content:glj.rcode+'换'+glj.code});
+    if(glj._doc.createType=='replace'&&glj.rcode!=glj.code){
+        adjustState.push({index:stateSeq.replace,content:glj.rcode+'换'+glj.code});
     }else if(glj._doc.createType=='add'){
         adjustState.push({index:stateSeq.add,content:'添'+glj.code+'量'+parseFloat(quantity)});
     }

+ 2 - 1
modules/ration_repository/controllers/ration_controller.js

@@ -10,7 +10,8 @@ var callback = function(req, res, err, message, data){
 module.exports = {
     getRationItemsBySection: function(req, res){
         var sectionId = req.body.sectionID;
-        rationItem.getRationItemsBySection(sectionId, function(err, message, rst){
+        var rationRepId = req.body.rationRepId;
+        rationItem.getRationItemsBySection(rationRepId, sectionId, function(err, message, rst){
             if (err) {
                 callback(req, res, err, message, null);
             } else {

+ 2 - 2
modules/ration_repository/models/ration_item.js

@@ -47,8 +47,8 @@ import stdGljListModel from '../../common/std/schemas/std_ration_lib_glj_list';
 
 var rationItemDAO = function(){};
 
-rationItemDAO.prototype.getRationItemsBySection = function(sectionId,callback){
-    rationItemModel.find({"sectionId": sectionId, "$or": [{"isDeleted": null}, {"isDeleted": false} ]}, null, {sort: {code: 1}}, function(err,data){
+rationItemDAO.prototype.getRationItemsBySection = function(rationRepId, sectionId,callback){
+    rationItemModel.find({"rationRepId": rationRepId, "sectionId": sectionId, "$or": [{"isDeleted": null}, {"isDeleted": false} ]}, null, {sort: {code: 1}}, function(err,data){
         if(err) callback(true, "Fail to get items", "")
         else callback(false,"Get items successfully", data);
     })

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

@@ -131,7 +131,7 @@ var sheetCommonObj = {
                     if(setting.header[col].hasOwnProperty('tofix')){
                         val =scMathUtil.roundToString(val,setting.header[col].tofix);
                     }
-                    if(setting.header[col].hasOwnProperty('decimalField')){
+                    else if(setting.header[col].hasOwnProperty('decimalField')){
                         var decimal = getDecimal(setting.header[col].decimalField);
                         val =scMathUtil.roundToString(val,decimal);
                         sheet.setFormatter(-1, col,getFormatter(decimal), GC.Spread.Sheets.SheetArea.viewport);

+ 11 - 4
web/building_saas/glj/js/common_spread.js

@@ -36,7 +36,12 @@ CommonSpreadJs.prototype.init = function(target) {
     for(let tmp of this.header) {
         let width = tmp.width==undefined ? 120 : tmp.width;
         setting.header.push({headerName: tmp.name, headerWidth: width});
-        this.columnInfo.push({name: tmp.field, displayName: tmp.name, visible: tmp.visible, cellType: tmp.cellType, size: width});
+        let options= {name: tmp.field, displayName: tmp.name, visible: tmp.visible, cellType: tmp.cellType, size: width};
+        if(tmp.decimalField){
+            let decimal = getDecimal(tmp.decimalField);
+            options.formatter = getFormatter(decimal);
+        }
+        this.columnInfo.push(options);
     }
 
     this.spread = sheetCommonObj.buildSheet(document.getElementById(target), setting, 10);
@@ -260,11 +265,13 @@ CommonSpreadJs.prototype.checkData = function(column, value) {
  * @param {boolean} appendMode
  * @return {void}
  */
-CommonSpreadJs.prototype.setCellByField = function(field, value, appendMode) {
-    let row = this.sheet.getActiveRowIndex();
+CommonSpreadJs.prototype.setCellByField = function(field, value, appendMode,row) {
+     row = row?row:this.sheet.getActiveRowIndex();
     let columnIndex = this.getFieldColumn(field);
+    let decimal = field=="quantity"?getDecimal("glj.quantity"):getDecimal("glj.unitPrice")
     if (appendMode) {
-        let oldValue = this.sheet.getValue(row, columnIndex);
+        let oldValue = scMathUtil.roundForObj(this.sheet.getValue(row, columnIndex),decimal);
+        value = scMathUtil.roundForObj(value,decimal);
         value = (oldValue + value).toDecimal(2);
     }
     this.sheet.setValue(row, columnIndex, value);

+ 12 - 2
web/building_saas/glj/js/composition.js

@@ -64,13 +64,23 @@ $(document).ready(function() {
  */
 function compositionSuccess(info) {
     // 成功则对相应的总消耗量进行设置
-    projectGLJSheet.setCellByField('quantity', info.change, true);
+    let row= projectGLJSheet.sheet.getActiveRowIndex();//取父机械或组成物的下标
+    let parentData = jsonData[row];
+    let ratioData = _.find(parentData.ratio_data,{"id":info.id});
+    let con_key = gljOprObj.getIndex(ratioData,['code', 'name', 'specs', 'unit', 'type']);
+    for(let i=0;i< jsonData.length;i++){
+        let tem_key = gljOprObj.getIndex(jsonData[i],['code', 'name', 'specs', 'unit', 'type']);
+        if(con_key == tem_key){
+            //乘以父工料机的消耗量得到该组成物总消耗量的改变量
+            info.change = operationWithRound(parentData.quantity,info.change,"glj.quantity","*");
+            projectGLJSheet.setCellByField('quantity', info.change, true,i);
+        }
+    }
 
     // 设置父级3个价格
     projectGLJSheet.setCellByField('unit_price.market_price', info.parentMarketPrice, false);
     projectGLJSheet.setCellByField('unit_price.base_price', info.parentBasePrice, false);
     projectGLJSheet.setCellByField('adjust_price', info.parentMarketPrice, false);
-
     // 更新组成物缓存
     projectObj.project.composition.loadData();
 }

+ 7 - 7
web/building_saas/glj/js/composition_spread.js

@@ -32,10 +32,10 @@ CompositionSpread.prototype.init = function(target) {
         {name: '单位', field: 'unit', visible: true},
         {name: 'ID', field: 'id', visible: false},
         {name: '类型', field: 'unit_price.type', visible: false},
-        {name: '基价单价', field: "unit_price.base_price", visible: true},
-        {name: '调整价', field: 'adjust_price', visible: true},
-        {name: '市场价', field: "unit_price.market_price", visible: true},
-        {name: name, field: 'consumption', visible: true, validator: 'number'},
+        {name: '定额价', field: "unit_price.base_price", visible: true,decimalField:"glj.unitPrice"},
+        {name: '调整价', field: 'adjust_price', visible: true,decimalField:"glj.unitPrice"},
+        {name: '市场价', field: "unit_price.market_price", visible: true,decimalField:"glj.unitPrice"},
+        {name: name, field: 'consumption', visible: true, validator: 'number',decimalField:'glj.quantity'},
         {name: 'CID', field: 'mix_ratio_id', visible: false},
     ];
 
@@ -223,6 +223,7 @@ CompositionSpread.prototype.updateConsumption = function(info, callback) {
                 activeSheet.setValue(row, column, info.oldValue);
                 alert('更改数据失败!');
             } else {
+                info.id = id;
                 info.parentMarketPrice = parentMarketPrice;
                 info.parentBasePrice = parentBasePrice;
                 info.change = info.newValue - info.oldValue;
@@ -265,9 +266,8 @@ CompositionSpread.prototype.getCompositionSumPrice = function(scene, affectRow,
 
         // 获取消耗量(如果是当前修改的行则替换数据)
         let consumption = i === affectRow ? newValue : activeSheet.getValue(i, consumptionColumn);
-
-        parentMarketPrice += consumption * marketPrice;
-        parentBasePrice += consumption * basePrice;
+        parentMarketPrice += operationWithRound(consumption,marketPrice,"glj.unitPrice","*");
+        parentBasePrice += operationWithRound(consumption,basePrice,"glj.unitPrice","*");
     }
 
     parentMarketPrice = parentMarketPrice.toDecimal(2);

+ 41 - 41
web/building_saas/glj/js/project_glj.js

@@ -19,7 +19,7 @@ let GLJTypeConst = [];
 // spreadjs载入数据所需
 let jsonData = [];
 let mixRatioConnectData = [];
-let mixRatioMap={};
+let mixRatioMap = {};
 // 单价文件相关
 let usedUnitPriceInfo = {};
 let usedTenderList = [];
@@ -32,7 +32,7 @@ $(document).ready(function () {
         init();
     });
 
-    slideResize($("#glj-main"), function() {
+    slideResize($("#glj-main"), function () {
         projectGLJSpread.sheetObj.spread.refresh();
     });
 
@@ -40,7 +40,7 @@ $(document).ready(function () {
     $('#change-dj').on('shown.bs.modal', function () {
         // 获取当前建设项数据
         let projectName = projectInfoObj.projectInfo.fullFolder !== undefined &&
-            projectInfoObj.projectInfo.fullFolder.length > 0 ? projectInfoObj.projectInfo.fullFolder[0] : '';
+        projectInfoObj.projectInfo.fullFolder.length > 0 ? projectInfoObj.projectInfo.fullFolder[0] : '';
         $("#current-project-name").text(projectName);
 
         // 获取切换单价文件相关数据
@@ -49,7 +49,7 @@ $(document).ready(function () {
             type: 'post',
             data: {project_id: scUrlUtil.GetQueryString('project')},
             dataType: 'json',
-            success: function(response) {
+            success: function (response) {
                 if (response.err === 1) {
                     alert('数据传输错误!');
                     return false;
@@ -58,9 +58,9 @@ $(document).ready(function () {
                 // 本项目中的单价文件
                 if (data.self.length > 0) {
                     let selfFileHtml = '';
-                    for(let tmp of data.self) {
+                    for (let tmp of data.self) {
                         let select = usedUnitPriceInfo === tmp.id ? ' selected="selected"' : '';
-                        selfFileHtml += '<option'+ select +' value="'+ tmp.id +'">'+ tmp.name +'</option>';
+                        selfFileHtml += '<option' + select + ' value="' + tmp.id + '">' + tmp.name + '</option>';
                     }
                     $("#self-file").html(selfFileHtml);
                 }
@@ -69,14 +69,14 @@ $(document).ready(function () {
                 if (data.other.length > 0) {
                     let otherProjectHtml = '';
                     let otherFileHtml = '';
-                    for(let tmp of data.other) {
-                        otherProjectHtml += '<option value="'+ tmp.ID +'">'+ tmp.name +'</option>';
+                    for (let tmp of data.other) {
+                        otherProjectHtml += '<option value="' + tmp.ID + '">' + tmp.name + '</option>';
                         otherFileData[tmp.ID] = tmp.unitPriceList;
                         if (otherFileHtml !== '') {
                             continue;
                         }
-                        for(let unitPrice of tmp.unitPriceList) {
-                            otherFileHtml += '<option value="'+ unitPrice.id +'">'+ unitPrice.name +'</option>';
+                        for (let unitPrice of tmp.unitPriceList) {
+                            otherFileHtml += '<option value="' + unitPrice.id + '">' + unitPrice.name + '</option>';
                         }
                     }
                     $("#other-project").html(otherProjectHtml);
@@ -87,13 +87,13 @@ $(document).ready(function () {
     });
 
     // 单价文件另存为弹框
-    $("#file-save-as-dialog").on('shown.bs.modal', function() {
+    $("#file-save-as-dialog").on('shown.bs.modal', function () {
         // 获取当前建设项数据
         $("#save-as-name").val(usedUnitPriceInfo.name + '(复件)');
     });
 
     // 单价文件另存为操作
-    $("#save-as-confirm").click(function() {
+    $("#save-as-confirm").click(function () {
         let name = $("#save-as-name").val();
         if (name === '') {
             $("#save-as-tips").text('请填写单价文件名称').show();
@@ -108,13 +108,13 @@ $(document).ready(function () {
             type: 'post',
             data: {name: name, project_id: scUrlUtil.GetQueryString('project')},
             dataType: 'json',
-            error: function() {
+            error: function () {
                 isChanging = false;
             },
-            beforeSend: function() {
+            beforeSend: function () {
                 isChanging = true;
             },
-            success: function(response) {
+            success: function (response) {
                 isChanging = false;
                 if (response.err === 1) {
                     let msg = response.msg !== undefined && response.msg !== '' ? response.msg : '另存为失败!';
@@ -128,20 +128,20 @@ $(document).ready(function () {
     });
 
     // 从其他建设项目中复制 选择建设项目
-    $("#other-project").change(function() {
+    $("#other-project").change(function () {
         let projectId = $(this).val();
         if (otherFileData[projectId] === undefined) {
             return false;
         }
         let otherFileHtml = '';
-        for(let unitPrice of otherFileData[projectId]) {
-            otherFileHtml += '<option value="'+ unitPrice.id +'">'+ unitPrice.name +'</option>';
+        for (let unitPrice of otherFileData[projectId]) {
+            otherFileHtml += '<option value="' + unitPrice.id + '">' + unitPrice.name + '</option>';
         }
         $("#other-file").html(otherFileHtml);
     });
 
     // 单价文件选项切换
-    $("input[name='change-type']").change(function() {
+    $("input[name='change-type']").change(function () {
         let type = $(this).val();
         type = parseInt(type);
         $("#change-dj .option").hide();
@@ -153,7 +153,7 @@ $(document).ready(function () {
     });
 
     // 单价文件切换确认
-    $("#change-file-confirm").click(function() {
+    $("#change-file-confirm").click(function () {
         if (isChanging) {
             return false;
         }
@@ -173,14 +173,14 @@ $(document).ready(function () {
             url: '/glj/change-file',
             type: 'post',
             data: {project_id: scUrlUtil.GetQueryString('project'), change_id: changeUnitPriceId, type: type},
-            error: function() {
+            error: function () {
                 isChanging = false;
                 $.bootstrapLoading.end();
             },
-            beforeSend: function() {
+            beforeSend: function () {
                 isChanging = true;
             },
-            success: function(response) {
+            success: function (response) {
                 isChanging = false;
                 if (response.err === 1) {
                     let msg = response.msg !== undefined ? response.msg : '未知错误';
@@ -200,19 +200,19 @@ $(document).ready(function () {
     });
 
     // 是否主动更改数据
-    $("#message").on('click', '#load-data', function() {
+    $("#message").on('click', '#load-data', function () {
         $("#message").html('正在加载...');
         // 重新加载数据到缓存
-        projectObj.project.projectGLJ.loadData(function() {
+        projectObj.project.projectGLJ.loadData(function () {
             projectObj.project.projectGLJ.loadCacheData();
             $("#notify").slideUp('fast');
         });
     });
 
     $('#pop-dj').popover({
-            placement:"bottom",
-            html:true,
-            trigger:"hover | focus",
+            placement: "bottom",
+            html: true,
+            trigger: "hover | focus",
             content: getUsedTenderInfo
         }
     );
@@ -224,11 +224,11 @@ $(document).ready(function () {
  * @return {void|boolean}
  */
 function init() {
-    projectObj.project.projectGLJ.loadData(function(data) {
+    projectObj.project.projectGLJ.loadData(function (data) {
         if (jsonData.length <= 0) {
             // 赋值
             jsonData = data.gljList !== undefined && data.gljList.length > 0 ? data.gljList : [];
-            jsonData= filterProjectGLJ(jsonData);
+            jsonData = filterProjectGLJ(jsonData);
             jsonData = sortProjectGLJ(jsonData);
             mixRatioConnectData = data.mixRatioConnectData !== undefined ? data.mixRatioConnectData : mixRatioConnectData;
             mixRatioMap = data.mixRatioMap !== undefined ? data.mixRatioMap : mixRatioMap;
@@ -291,7 +291,7 @@ function spreadInit() {
         }
     });
 
-    loadSize("glj-main", function() {
+    loadSize("glj-main", function () {
         projectGLJSpread.sheetObj.spread.refresh();
     });
 }
@@ -306,7 +306,7 @@ function spreadInit() {
 function unitPriceFileInit() {
     let projectGLJ = projectObj.project.projectGLJ;
     let data = projectGLJ.datas;
-     usedTenderList = data.usedTenderList !== undefined ? data.usedTenderList : [];
+    usedTenderList = data.usedTenderList !== undefined ? data.usedTenderList : [];
     usedUnitPriceInfo = data.constData.usedUnitPriceInfo !== undefined ?
         data.constData.usedUnitPriceInfo : {};
     $("#used-name").text(usedUnitPriceInfo.name);
@@ -315,7 +315,7 @@ function unitPriceFileInit() {
 }
 
 function getUsedTenderInfo() {
-   return usedTenderList.join("<br>");
+    return usedTenderList.join("<br>");
 }
 
 /**
@@ -357,7 +357,7 @@ function successTrigger(field, info) {
  */
 function socketInit() {
     if (socket === null) {
-        socket = io('http://'+ host +':3300');
+        socket = io('http://' + host + ':3300');
         socket.on('connect', function () {
             socket.emit('join', roomId);
             console.log('单价文件同步连接成功');
@@ -365,7 +365,7 @@ function socketInit() {
     }
 
     // 接收到改变
-    socket.on('dataChange', function(data) {
+    socket.on('dataChange', function (data) {
         data = JSON.parse(data);
         if (data.newValue === undefined) {
             return false;
@@ -380,8 +380,8 @@ function filterProjectGLJ(jsonData) {
     if (jsonData.length > 0) {
         // 不显示消耗量为0的数据
         let tmpData = [];
-        for(let data of jsonData) {
-            if (data.quantity !== 0&&data.quantity !=='0') {
+        for (let data of jsonData) {
+            if (data.quantity !== 0 && data.quantity !== '0') {
                 tmpData.push(data);
             }
         }
@@ -391,10 +391,10 @@ function filterProjectGLJ(jsonData) {
 }
 
 function sortProjectGLJ(jsonData) {
-    if (jsonData.length > 0){
-        jsonData = _.sortByAll(jsonData,[function (item) {
-            return item.unit_price.type+"";
-        },'code']);
+    if (jsonData.length > 0) {
+        jsonData = _.sortByAll(jsonData, [function (item) {
+            return item.unit_price.type + "";
+        }, 'code']);
     }
     return jsonData
 }

+ 27 - 11
web/building_saas/glj/js/project_glj_spread.js

@@ -19,7 +19,7 @@ function ProjectGLJSpread() {
     this.successCallback = null;
     this.supplyType = ['自行采购', '部分甲供', '完全甲供', '甲定乙供'];
     // 工料机类型是混凝土、砂浆、配合比、机械(不包括机械组成物)时,供货方式列只读。
-    this.supplyReadonlyType = [GLJTypeConst.CONCRETE, GLJTypeConst.MORTAR, GLJTypeConst.MIX_RATIO, GLJTypeConst.GENERAL_MACHINE];
+    this.supplyReadonlyType = notEditType;
 }
 
 /**
@@ -47,10 +47,10 @@ ProjectGLJSpread.prototype.init = function () {
         {name: '类型', field: 'unit_price.short_name', visible: true,width:45},
         {name: 'ID', field: 'id', visible: false},
         {name: '类型', field: 'unit_price.type', visible: false},
-        {name: '总消耗量', field: 'quantity', visible: true,width:100},
-        {name: '定额价', field: "unit_price.base_price", visible: true,width:70},
-        {name: '调整价', field: 'adjust_price', visible: true,width:70},
-        {name: '市场价', field: "unit_price.market_price", visible: true, validator: 'number',width:70},
+        {name: '总消耗量', field: 'quantity', visible: true,width:100,decimalField:'glj.quantity'},
+        {name: '定额价', field: "unit_price.base_price", visible: true,width:70,decimalField:"glj.unitPrice"},
+        {name: '调整价', field: 'adjust_price', visible: true,width:70,decimalField:"glj.unitPrice"},
+        {name: '市场价', field: "unit_price.market_price", visible: true, validator: 'number',width:70,decimalField:"glj.unitPrice"},
         {
             name: '是否暂估',
             field: 'is_evaluate',
@@ -75,7 +75,7 @@ ProjectGLJSpread.prototype.init = function () {
         {name: '工料机ID', field: 'glj_id', visible: false},
         {name: '组成物消耗量', field: 'consumption', visible: false},
         {name: '父级关联编码', field: 'connect_code', visible: false},
-        {name: '消耗量', field: 'ratio_data', visible: false},
+        {name: '组成物信息', field: 'ratio_data', visible: false},
     ];
     let sourceData = jsonData;
 
@@ -92,6 +92,8 @@ ProjectGLJSpread.prototype.init = function () {
     let marketPriceColumn = this.sheetObj.getFieldColumn('unit_price.market_price');
     let supplyColumn = this.sheetObj.getFieldColumn('supply');
     let shortNameColumn = this.sheetObj.getFieldColumn('unit_price.short_name');
+    let supplyQuantity = this.sheetObj.getFieldColumn('supply_quantity');
+
 
     // 居中样式
     let centerStyleSetting = {hAlign: 1};
@@ -107,6 +109,7 @@ ProjectGLJSpread.prototype.init = function () {
     this.sheetObj.setStyle(-1, adjustPriceColumn, rightStyleSetting);
     this.sheetObj.setStyle(-1, marketPriceColumn, rightStyleSetting);
     this.sheetObj.setStyle(-1, supplyColumn, rightStyleSetting);
+    this.sheetObj.setStyle(-1, supplyQuantity, rightStyleSetting);
 
     // 设置可编辑列
     this.sheetObj.setColumnEditable(marketPriceColumn);
@@ -135,9 +138,14 @@ ProjectGLJSpread.prototype.init = function () {
         let typeColumn = self.sheetObj.getFieldColumn('unit_price.type');
         let type = activeSheet.getValue(row, typeColumn);
 
+        let ratioColumn = self.sheetObj.getFieldColumn('ratio_data');
+        let ratioData = activeSheet.getValue(row, ratioColumn);
+
         // 如果类型为混凝土、砂浆、配合比、机械,则提示
         if (field === 'unit_price.market_price' && canNotChangeTypeId.indexOf(type) >= 0) {
-            alert('当前工料机的市场单价由组成物计算得出,不可直接修改');
+            if(ratioData&&ratioData.length>0){
+                alert('当前工料机的市场单价由组成物计算得出,不可直接修改');
+            }
         }
     });
 
@@ -208,7 +216,9 @@ ProjectGLJSpread.prototype.updateProjectGLJField = function(info, callback) {
     if(field === 'supply_quantity'){//修改数量需做4舍5入
         value= value.toDecimal(getDecimal('glj.quantity'));
     }
-
+    if(field === 'unit_price.market_price'){
+        value= value.toDecimal(getDecimal('glj.unitPrice'));
+    }
     extend = Object.keys(extend).length > 0 ?  JSON.stringify(extend) : '';
     $.ajax({
         url: '/glj/update',
@@ -280,10 +290,14 @@ ProjectGLJSpread.prototype.specialColumn = function (sourceData) {
             // 锁定该单元格
             activeSheet.getCell(rowCounter, supplyColumn,  GC.Spread.Sheets.SheetArea.viewport).locked(true);
         }
-        // 如果为部分甲供或者为全部甲供则甲供数量需要可编辑
-        if (data.supply === 1 || data.supply === 2) {
+        // 如果为部分甲供则甲供数量需要可编辑
+        if (data.supply === 1) {
             activeSheet.getCell(rowCounter, supplyQuantity,  GC.Spread.Sheets.SheetArea.viewport).locked(false);
         }
+        //供货方式为完全甲供时设置甲供数量为总消耗量
+        if (data.supply === 2) {
+            activeSheet.setValue(rowCounter, supplyQuantity,  data.quantity);
+        }
         // 供货方式数据
         let supplyIndex = parseInt(data.supply);
         supplyIndex = isNaN(supplyIndex) ? 0 : supplyIndex;
@@ -297,7 +311,9 @@ ProjectGLJSpread.prototype.specialColumn = function (sourceData) {
             this.firstMachineRow = this.firstMachineRow === -1 && data.unit_price.type === GLJTypeConst.GENERAL_MACHINE ?
                 rowCounter : this.firstMachineRow;
             // 锁定该单元格
-            activeSheet.getCell(rowCounter, marketPriceColumn,  GC.Spread.Sheets.SheetArea.viewport).locked(true);
+            if (data.ratio_data  && data.ratio_data.length > 0){//有组成物时,市场单价不可修改
+                activeSheet.getCell(rowCounter, marketPriceColumn,  GC.Spread.Sheets.SheetArea.viewport).locked(true);
+            }
             activeSheet.getCell(rowCounter, supplyColumn,  GC.Spread.Sheets.SheetArea.viewport).locked(true);
         }
 

+ 15 - 5
web/building_saas/main/js/models/calc_base.js

@@ -462,6 +462,7 @@ let cbAnalyzer = {
                 let bill = baseFigures[figure]['fixedBill']['bill'];
                 if(checkStack(getRefStack([bill.ID]), sbillID)){
                     console.log('循环计算');
+                    calcBase.errMsg = '表达式出现循环计算';
                     return true;
                 }
             }
@@ -522,6 +523,9 @@ let cbParser = {
 
     //将表达式转换为可编译的表达式
     toCompileExpr: function(v){
+        if(v === ''){
+            return '$CBC.base(\'NONE\')';
+        }
         let strs = this.getFigure(v);
         let exps = [];
         for(let i = 0, len = strs.length; i < len; i++){
@@ -541,6 +545,9 @@ let cbParser = {
 let cbCalctor = {
     //计算基数
     base: function (figure) {
+        if(figure === 'NONE'){
+            return 0;
+        }
         return baseFigureTemplate[calcBase.baseFigures[figure]['base']]();
     },
     //计算
@@ -550,6 +557,7 @@ let cbCalctor = {
 };
 
 let calcBase = {
+    errMsg: '表达式不正确',
     success: false,
     //清单固定行
     fixedFlag: null,
@@ -566,7 +574,6 @@ let calcBase = {
         cbTools.setFixedBills(project, me.fixedBills, me.fixedFlag);
         me.baseFigures = baseFigureMap;
         cbTools.setBaseBills(me.baseFigures, me.fixedBills);
-        //me.baseFigures.fixedBills = me.fixedBills;
         cbTools.setBaseFigureClass(me.baseFigures, me.baseFigureClass);
     },
     getBase: function (figure) {
@@ -586,11 +593,13 @@ let calcBase = {
             $CBC = cbCalctor;
         try {
             me.success = false;
+            me.errMsg = '表达式不正确';
             //分析输入式合法性
             let exp = $CBA.legalExp(node);
-            if(!exp){
+            if(!cbTools.isDef(exp)){
                 throw '表达式不正确';
             }
+
             //输入式转换表达式
             let compileExp = $CBP.toCompileExpr(exp);
 
@@ -599,15 +608,16 @@ let calcBase = {
             if(!cbTools.isNum(calcBaseValue)){
                 throw '表达式不正确';
             }
+
             //存储
             me.success = true;
             node.data.calcBase = exp;
             node.data.calcBaseValue = parseFloat(calcBaseValue).toDecimal(decimalObj.decimal('totalPrice', node));
-            me.project.calcProgram.calculate(node);
-            me.project.calcProgram.saveNode(node);
+           /* me.project.calcProgram.calculate(node);
+            me.project.calcProgram.saveNode(node);*/
         }
         catch (err){
-            alert('表达式不正确');
+            alert(me.errMsg);
         }
     }
 };

+ 4 - 1
web/building_saas/main/js/models/calc_program.js

@@ -846,10 +846,12 @@ class CalcProgram {
 
                     let feeRate = calcItem.feeRate;
                     if (!feeRate) feeRate = 100;    // 100%
+                    feeRate = feeRate.toDecimal(decimalObj.feeRate);
                     calcItem.unitFee = (eval(calcItem.compiledExpr) * feeRate * 0.01).toDecimal(decimalObj.decimal('unitPrice', treeNode));   // 如果eval()对清单树有影响,就换成小麦的Expression对象再试
 
                     let quantity = treeNode.data.quantity;
-                    if (!quantity) quantity = 0;
+                    if (!quantity) quantity = 0
+                    else quantity = parseFloat(quantity).toDecimal(decimalObj.decimal('quantity', treeNode));
                     calcItem.totalFee = (calcItem.unitFee * quantity).toDecimal(decimalObj.decimal('totalPrice', treeNode));
 
                     checkFee(treeNode, calcItem);
@@ -861,6 +863,7 @@ class CalcProgram {
     // 计算本节点(默认同时递归计算所有父节点,可选)
     calculate(treeNode, calcParents = true){
         let me = this;
+        if (treeNode.sourceType === me.project.ration_glj.getSourceType()) return;     // 仅用作树节点显示的工料机不能参与计算。
         let isRation = treeNode.sourceType === me.project.Ration.getSourceType();
         let isBill = treeNode.sourceType === me.project.Bills.getSourceType();
 

+ 6 - 0
web/building_saas/main/js/models/main_consts.js

@@ -47,6 +47,12 @@ const gljType = {
     EQUIPMENT: 5
 };
 
+const notEditType = [
+    gljType.CONCRETE,
+    gljType.MORTAR,
+    gljType.MIX_RATIO,
+    gljType.GENERAL_MACHINE
+];
 
 const CP_Col_Width = {          // 多处计算程序界面的列宽统一设置
     rowHeader: 30,

+ 104 - 88
web/building_saas/main/js/models/project_glj.js

@@ -27,13 +27,13 @@ ProjectGLJ.prototype.loadData = function (callback = null) {
         type: 'post',
         dataType: 'json',
         data: {project_id: scUrlUtil.GetQueryString('project')},
-        error: function() {
+        error: function () {
             // alert('数据传输错误');
         },
-        beforeSend: function() {
+        beforeSend: function () {
             self.isLoading = true;
         },
-        success: function(response) {
+        success: function (response) {
             self.isLoading = false;
             if (response.err === 1) {
                 let msg = response.msg !== undefined && response.msg !== '' ? response.msg : '读取工料机数据失败!';
@@ -53,7 +53,7 @@ ProjectGLJ.prototype.loadData = function (callback = null) {
 
 ProjectGLJ.prototype.loadToCache = function (data) {
     this.datas = data;
-    projectObj.project.projectGLJ=this;
+    projectObj.project.projectGLJ = this;
 }
 
 
@@ -74,7 +74,7 @@ ProjectGLJ.prototype.getDataByCode = function (code) {
         return result;
     }
 
-    for(let tmp of gljList) {
+    for (let tmp of gljList) {
         if (tmp.code === code) {
             result = tmp;
             break;
@@ -91,7 +91,7 @@ ProjectGLJ.prototype.getDataByCode = function (code) {
  * @param {Object} data
  * @return {boolean}
  */
-ProjectGLJ.prototype.updateData = function(id, data) {
+ProjectGLJ.prototype.updateData = function (id, data) {
     let result = false;
     if (this.datas === null) {
         return result;
@@ -104,7 +104,7 @@ ProjectGLJ.prototype.updateData = function(id, data) {
 
     // 查找对应的index
     let index = -1;
-    for(let tmp in gljList) {
+    for (let tmp in gljList) {
         if (gljList[tmp].id === id) {
             index = tmp;
             break;
@@ -116,8 +116,8 @@ ProjectGLJ.prototype.updateData = function(id, data) {
     }
 
     // 修改数据
-    for(let tmpIndex in data) {
-        if(tmpIndex.indexOf('_price') >= 0) {
+    for (let tmpIndex in data) {
+        if (tmpIndex.indexOf('_price') >= 0) {
             // 修改unit_price中的对象
             this.datas.gljList[index]['unit_price'][tmpIndex] = data[tmpIndex];
         } else {
@@ -132,110 +132,110 @@ ProjectGLJ.prototype.updateData = function(id, data) {
  *
  * @return {void}
  */
-ProjectGLJ.prototype.loadCacheData = function() {
+ProjectGLJ.prototype.loadCacheData = function () {
     // 加载工料机数据
     let data = this.datas === null ? null : this.datas;
     if (data === null) {
         return;
     }
     jsonData = data.gljList !== undefined && data.gljList.length > 0 ? data.gljList : [];
-    jsonData=filterProjectGLJ(jsonData);
+    jsonData = filterProjectGLJ(jsonData);
     jsonData = sortProjectGLJ(jsonData);
     projectGLJSheet.setData(jsonData);
     projectGLJSpread.specialColumn(jsonData);
 };
 
-ProjectGLJ.prototype.updatePriceFromRG=function(recode,updateField,newval){
-    if(updateField=='marketPrice'){
-        this.updateBasePriceFromRG(recode,"market_price",newval);
+ProjectGLJ.prototype.updatePriceFromRG = function (recode, updateField, newval) {
+    if (updateField == 'marketPrice') {
+        this.updateBasePriceFromRG(recode, "market_price", newval);
     }
-    if(updateField=='basePrice'){
-        this.updateBasePriceFromRG(recode,"base_price",newval);
+    if (updateField == 'basePrice') {
+        this.updateBasePriceFromRG(recode, "base_price", newval);
     }
 };
 
-ProjectGLJ.prototype.updatePropertyFromMainSpread = function (node,updateField,newval) {
-   if(updateField=="contain"){
+ProjectGLJ.prototype.updatePropertyFromMainSpread = function (node, updateField, newval) {
+    if (updateField == "contain") {
 
-   }else {
-       this.updateGLJProperty(node,updateField,newval);
-   }
+    } else {
+        this.updateGLJProperty(node, updateField, newval);
+    }
 };
 
 
-ProjectGLJ.prototype.updateGLJProperty=function (node,updateField,newval) {
+ProjectGLJ.prototype.updateGLJProperty = function (node, updateField, newval) {
     let rationTypeGLJ = node.data;
     let postData = {};
-    if(rationTypeGLJ[updateField]==newval){
+    if (rationTypeGLJ[updateField] == newval) {
         return;
     }
-    let data ={
+    let data = {
         glj_id: rationTypeGLJ.GLJID,
         project_id: rationTypeGLJ.projectID,
         code: rationTypeGLJ.code,
-        original_code:rationTypeGLJ.original_code,
+        original_code: rationTypeGLJ.original_code,
         name: rationTypeGLJ.name,
-        shortName:rationTypeGLJ.shortName,
+        shortName: rationTypeGLJ.shortName,
         specs: rationTypeGLJ.specs,
         unit: rationTypeGLJ.unit,
-        type:rationTypeGLJ.subType,
-        type_of_work:rationTypeGLJ.subType,
+        type: rationTypeGLJ.subType,
+        type_of_work: rationTypeGLJ.subType,
         base_price: rationTypeGLJ.basePrice,
         market_price: rationTypeGLJ.basePrice,
-        repositoryId:rationTypeGLJ.repositoryId,
-        adjCoe:rationTypeGLJ.adjCoe,
-        from:rationTypeGLJ.from?rationTypeGLJ.from:'std'//std:标准工料机库, cpt:补充工料机库
+        repositoryId: rationTypeGLJ.repositoryId,
+        adjCoe: rationTypeGLJ.adjCoe,
+        from: rationTypeGLJ.from ? rationTypeGLJ.from : 'std'//std:标准工料机库, cpt:补充工料机库
     };
-    if(updateField=='subType'){
+    if (updateField == 'subType') {
         data.type = newval;
         data.type_of_work = newval;
         data.shortName = this.getShortNameByID(newval);
-    }else {
-        data[updateField]=newval;
+    } else {
+        data[updateField] = newval;
     }
     postData.ration = {
-        ID:rationTypeGLJ.ID,
-        projectID:rationTypeGLJ.projectID
+        ID: rationTypeGLJ.ID,
+        projectID: rationTypeGLJ.projectID
     };
     postData.updateData = data;
     $.bootstrapLoading.start();
-    CommonAjax.post("/glj/modifyKeyValue",postData,function (result) {
+    CommonAjax.post("/glj/modifyKeyValue", postData, function (result) {
         console.log(result);  //更新节点信息
-        rationTypeGLJ[updateField]=newval;
+        rationTypeGLJ[updateField] = newval;
         rationTypeGLJ.projectGLJID = result.id;
         rationTypeGLJ.code = result.code;
         rationTypeGLJ.basePrice = result.unit_price.base_price;
         rationTypeGLJ.marketUnitFee = result.unit_price.market_price;
         rationTypeGLJ.isAdd = result.unit_price.is_add;
-        rationTypeGLJ.isEstimate=result.is_evaluate;
+        rationTypeGLJ.isEstimate = result.is_evaluate;
         rationTypeGLJ.shortName = result.unit_price.short_name;
         //触发计算并更新节点信息
-        node.changed=true;
+        node.changed = true;
         projectObj.project.projectGLJ.loadData(function () {
             projectObj.project.calcProgram.calculate(node);
             projectObj.project.calcProgram.saveNode(node);
             $.bootstrapLoading.end();
         });//重新加载项目工料机数据
         //上面两步都是异步操作,这句应该是要等上面两步做完了再执行的
-    },function (err) {
+    }, function (err) {
         $.bootstrapLoading.end();
     });
-    
+
 }
 
-ProjectGLJ.prototype.updateBasePriceFromRG=function(recode,updateField,newval){
+ProjectGLJ.prototype.updateBasePriceFromRG = function (recode, updateField, newval) {
     let me = this;
     let projectGljs = this.datas.gljList;
-    let glj = _.find(projectGljs,{'id':recode.projectGLJID});
+    let glj = _.find(projectGljs, {'id': recode.projectGLJID});
     console.log(glj);
-    if(glj){
-        let data = {id:glj.unit_price.id,field:updateField,newval:newval};
-        let callback =function (data) {
-            if(updateField=='base_price'){
-                glj.unit_price.base_price=newval;
+    if (glj) {
+        let data = {id: glj.unit_price.id, field: updateField, newval: newval};
+        let callback = function (data) {
+            if (updateField == 'base_price') {
+                glj.unit_price.base_price = newval;
                 me.setAdjustPrice(glj);
-            }else {
-                glj.unit_price.market_price=newval;
+            } else {
+                glj.unit_price.market_price = newval;
             }
             //更新项目工料机价格
             me.refreshProjectGLJPrice(data);
@@ -247,17 +247,17 @@ ProjectGLJ.prototype.updateBasePriceFromRG=function(recode,updateField,newval){
             $.bootstrapLoading.end();
         }
         $.bootstrapLoading.start();
-        CommonAjax.post("/glj/updatePrice",data,callback,function (err) {
+        CommonAjax.post("/glj/updatePrice", data, callback, function (err) {
             $.bootstrapLoading.end();
         });
-    }else {
+    } else {
         gljOprObj.showRationGLJSheetData();
     }
 }
 ProjectGLJ.prototype.refreshTreeNodePriceIfNeed = function (data) {
-    if((data.unit_price.type = gljType.MAIN_MATERIAL||data.unit_price.type==gljType.EQUIPMENT)&&projectInfoObj.projectInfo.property.displaySetting.disPlayMainMaterial==true){
-        var nodes = _.filter(projectObj.project.mainTree.items,function (tem) {
-            if(tem.sourceType==ModuleNames.ration_glj&&tem.data.projectGLJID ==data.id){
+    if ((data.unit_price.type = gljType.MAIN_MATERIAL || data.unit_price.type == gljType.EQUIPMENT) && projectInfoObj.projectInfo.property.displaySetting.disPlayMainMaterial == true) {
+        var nodes = _.filter(projectObj.project.mainTree.items, function (tem) {
+            if (tem.sourceType == ModuleNames.ration_glj && tem.data.projectGLJID == data.id) {
                 tem.data.marketUnitFee = data.unit_price.market_price;
                 return true;
             }
@@ -269,35 +269,35 @@ ProjectGLJ.prototype.refreshTreeNodePriceIfNeed = function (data) {
 
 //根据工料机,取得所有受影响的定额节点
 ProjectGLJ.prototype.getImpactRationNodes = function (glj) {
-    let nodes=[];
+    let nodes = [];
     let rationMap = {};
     //先根据项目工料机ID,找到受影响定额的ID
-    let ration_glj_list =projectObj.project.ration_glj.datas; //取定额工料机数据
-    for(let rg of ration_glj_list){
-        if(rg.projectGLJID==glj.id){
+    let ration_glj_list = projectObj.project.ration_glj.datas; //取定额工料机数据
+    for (let rg of ration_glj_list) {
+        if (rg.projectGLJID == glj.id) {
             rationMap[rg.rationID] = true;  //取所有定额ID,用MAP方式去重
         }
     }
-    for(let item of projectObj.project.mainTree.items){
-        if(item.sourceType==ModuleNames.ration){
-            if(item.data.type==rationType.gljRation){//取定额类型的工料机
-                if(item.data.projectGLJID == glj.id){
+    for (let item of projectObj.project.mainTree.items) {
+        if (item.sourceType == ModuleNames.ration) {
+            if (item.data.type == rationType.gljRation) {//取定额类型的工料机
+                if (item.data.projectGLJID == glj.id) {
                     item.data.marketUnitFee = glj.unit_price.market_price; //更新市场单价
                     nodes.push(item);
                 }
-            }else if( rationMap[item.data.ID]==true){  //受影响的定额
-                   nodes.push(item)
+            } else if (rationMap[item.data.ID] == true) {  //受影响的定额
+                nodes.push(item)
             }
         }
     }
     return nodes;
 };
-ProjectGLJ.prototype.refreshRationGLJPrice=function (glj) {
-    for(let ration_glj of gljOprObj.sheetData){
-        if(ration_glj.projectGLJID ==glj.id){
-            ration_glj.basePrice=glj.unit_price.base_price;
-            ration_glj.marketPrice=glj.unit_price.market_price;
-            ration_glj.adjustPrice=this.getAdjustPrice(glj);
+ProjectGLJ.prototype.refreshRationGLJPrice = function (glj) {
+    for (let ration_glj of gljOprObj.sheetData) {
+        if (ration_glj.projectGLJID == glj.id) {
+            ration_glj.basePrice = glj.unit_price.base_price;
+            ration_glj.marketPrice = glj.unit_price.market_price;
+            ration_glj.adjustPrice = this.getAdjustPrice(glj);
         }
     }
 }
@@ -306,19 +306,19 @@ ProjectGLJ.prototype.refreshRationTypeGLJ = function (glj) {
 
 }
 
-ProjectGLJ.prototype.refreshProjectGLJPrice=function(data){
+ProjectGLJ.prototype.refreshProjectGLJPrice = function (data) {
     let projectGljs = this.datas.gljList;
-    let indexList = ['code','name','specs','unit','type'];
-    for(let d of data){
-        if(d){
+    let indexList = ['code', 'name', 'specs', 'unit', 'type'];
+    for (let d of data) {
+        if (d) {
             let condition = {};
-            for(let index of indexList){
-                if(d[index]!=null&&d[index]!=undefined&&d[index]!=''){
-                    condition[index]=d[index]
+            for (let index of indexList) {
+                if (d[index] != null && d[index] != undefined && d[index] != '') {
+                    condition[index] = d[index]
                 }
             }
-            let glj = _.find(projectGljs,condition);
-            if(glj){
+            let glj = _.find(projectGljs, condition);
+            if (glj) {
                 glj.unit_price.base_price = d.base_price;
                 glj.unit_price.market_price = d.market_price;
                 this.setAdjustPrice(glj);
@@ -329,7 +329,7 @@ ProjectGLJ.prototype.refreshProjectGLJPrice=function(data){
     }
 }
 
-ProjectGLJ.prototype.setAdjustPrice=function(glj){
+ProjectGLJ.prototype.setAdjustPrice = function (glj) {
     switch (glj.unit_price.type + '') {
         // 人工: 调整基价=基价单价*调整系数
         case GLJTypeConst.LABOUR:
@@ -348,18 +348,34 @@ ProjectGLJ.prototype.setAdjustPrice=function(glj){
 
 ProjectGLJ.prototype.getAdjustPrice = function (glj) {
     GLJTypeConst = this.datas.constData.GLJTypeConst !== undefined ? JSON.parse(this.datas.constData.GLJTypeConst) : GLJTypeConst;
-    if(glj.unit_price.type==GLJTypeConst.LABOUR||glj.unit_price.type==GLJTypeConst.MACHINE_LABOUR){
+    let decimal = getDecimal("glj.unitPrice");
+    let quantity_decimal = getDecimal("glj.quantity")
+    if (glj.unit_price.type == GLJTypeConst.LABOUR || glj.unit_price.type == GLJTypeConst.MACHINE_LABOUR) {//人工、机上人工,调整价根据定额价*调整系数计算得出。
         let labour = projectObj.project.calcProgram.compiledLabourCoes[glj.adjCoe];
         //let labour=1;
-        let coe = labour&&labour.coe?labour.coe:1;
-        let decimal = getDecimal("glj.unitPrice");
-        return scMathUtil.roundTo(parseFloat(coe*glj.unit_price.base_price),-decimal);
-    }else {
+        let coe = labour && labour.coe ? labour.coe : 1;
+        return scMathUtil.roundTo(parseFloat(coe * scMathUtil.roundForObj(glj.unit_price.base_price,decimal)), -decimal);
+    } else if (notEditType.indexOf(glj.unit_price.type)>0) {//对于混凝土、配合比、砂浆、机械台班,调整价根据组成物计算得出。
+        let p =0;
+        for(let ratio of glj.ratio_data){
+           let tem =  _.find( projectObj.project.projectGLJ.datas.gljList,{
+               'code': ratio.code,
+               'name': ratio.name,
+               'specs':ratio.specs,
+               'type': ratio.type,
+               'unit': ratio.unit
+           })
+            if(tem){
+                p+=scMathUtil.roundForObj(this.getAdjustPrice(tem)*scMathUtil.roundForObj(ratio.consumption,quantity_decimal),decimal);
+            }
+        }
+        return scMathUtil.roundForObj(p,decimal);
+    } else {//对于其他普通材料等,无调整系数,调整价=定额价。
         return glj.unit_price.base_price
     }
 }
 
 ProjectGLJ.prototype.getShortNameByID = function (ID) {
     let gljTypeMap = this.datas.constData.gljTypeMap;
-    return gljTypeMap["typeId"+ID].shortName;
+    return gljTypeMap["typeId" + ID].shortName;
 }

文件差异内容过多而无法显示
+ 369 - 339
web/building_saas/main/js/models/ration_glj.js


+ 1 - 2
web/building_saas/main/js/views/calc_base_view.js

@@ -195,8 +195,7 @@ let calcBaseView = {
         let me = calcBaseView;
         me.confirmBtn.bind('click', function () {
             let selected = projectObj.project.mainTree.selected;
-            selected.data.userCalcBase = me.getInputExpr();
-            projectObj.project.calcBase.calculate(selected);
+            projectObj.updateCellValue(selected, me.getInputExpr(), {data: {field: 'calcBase'}});
             if(projectObj.project.calcBase.success){
                 $('#qd-jsjs').modal('hide');
             }

+ 7 - 196
web/building_saas/main/js/views/calc_program_view.js

@@ -4,197 +4,6 @@
  * 整合清单、定额的计算程序,代码合并、类合并、剔除多余单元。
  */
 
-
-let calcProgramSetting ={
-    "emptyRows":0,
-    "headRows":1,
-    "headRowHeight":[
-        35
-    ],
-    "cols":[
-        {
-            "width":75,
-            "readOnly": true,
-            "head":{
-                "titleNames":["序号"],
-                "spanCols":[1],
-                "spanRows":[1],
-                "vAlign":[1],
-                "hAlign":[1],
-                "font":["Arial"]
-            },
-            "data":{
-                "field":"serialNo",
-                "vAlign":1,
-                "hAlign":1,
-                "font":"Arial"
-            }
-        },
-        {
-            "width":75,
-            "readOnly": false,
-            "head":{
-                "titleNames":["费用代号"],
-                "spanCols":[1],
-                "spanRows":[1],
-                "vAlign":[1],
-                "hAlign":[1],
-                "font":["Arial"]
-            },
-            "data":{
-                "field":"code",
-                "vAlign":1,
-                "hAlign":0,
-                "font":"Arial"
-            }
-        },
-        {
-            "width":200,
-            "readOnly":false,
-            "head":{
-                "titleNames":["名称"],
-                "spanCols":[1],
-                "spanRows":[1],
-                "vAlign":[1],
-                "hAlign":[1],
-                "font":["Arial"]
-            },
-            "data":{
-                "field":"name",
-                "vAlign":1,
-                "hAlign":0,
-                "font":"Arial"
-            }
-        },
-        {
-            "width":280,
-            "readOnly":false,
-            "head":{
-                "titleNames":["计算基数"],
-                "spanCols":[1],
-                "spanRows":[1],
-                "vAlign":[1],
-                "hAlign":[1],
-                "font":["Arial"]
-            },
-            "data":{
-                "field":"dispExpr",
-                "vAlign":1,
-                "hAlign":0,
-                "font":"Arial"
-            }
-        },
-        {
-            "width":220,
-            "readOnly":false,
-            "head":{
-                "titleNames":["基数说明"],
-                "spanCols":[1],
-                "spanRows":[1],
-                "vAlign":[1],
-                "hAlign":[1],
-                "font":["Arial"]
-            },
-            "data":{
-                "field":"statement",
-                "vAlign":1,
-                "hAlign":0,
-                "font":"Arial"
-            }
-        },
-        {
-            "width":80,
-            "readOnly": false,
-            "head":{
-                "titleNames":["费率"],
-                "spanCols":[1],
-                "spanRows":[1],
-                "vAlign":[1],
-                "hAlign":[1],
-                "font":["Arial"]
-            },
-            "data":{
-                "field":"feeRate",
-                "vAlign":1,
-                "hAlign":2,
-                "font":"Arial"
-            }
-        },
-        {
-            "width": 100,
-            "readOnly":true,
-            "head":{
-                "titleNames":["单价"],
-                "spanCols":[1],
-                "spanRows":[1],
-                "vAlign":[1],
-                "hAlign":[1],
-                "font":["Arial"]
-            },
-            "data":{
-                "field":"unitFee",
-                "vAlign":1,
-                "hAlign":2,
-                "font":"Arial"
-            }
-        },
-        {
-            "width":100,
-            "readOnly":true,
-            "head":{
-                "titleNames":["合价"],
-                "spanCols":[1],
-                "spanRows":[1],
-                "vAlign":[1],
-                "hAlign":[1],
-                "font":["Arial"]
-            },
-            "data":{
-                "field":"totalFee",
-                "vAlign":1,
-                "hAlign":2,
-                "font":"Arial"
-            }
-        },
-        {
-            "width":80,
-            "readOnly": true,
-            "head":{
-                "titleNames":["费用类别"],
-                "spanCols":[1],
-                "spanRows":[1],
-                "vAlign":[1],
-                "hAlign":[1],
-                "font":["Arial"]
-            },
-            "data":{
-                "field":"type",
-                "vAlign":1,
-                "hAlign":0,
-                "font":"Arial"
-            }
-        },
-        {
-            "width":120,
-            "readOnly":false,
-            "head":{
-                "titleNames":["备注"],
-                "spanCols":[1],
-                "spanRows":[1],
-                "vAlign":[1],
-                "hAlign":[1],
-                "font":["Arial"]
-            },
-            "data":{
-                "field":"memo",
-                "vAlign":1,
-                "hAlign":0,
-                "font":"Arial"
-            }
-        }
-    ]
-};
-
 let calcProgramObj = {
     sheet: null,
     treeNode: null,
@@ -204,8 +13,8 @@ let calcProgramObj = {
             {headerName: "费用代号", headerWidth: CP_Col_Width.code, dataCode: "code", dataType: "String", hAlign: "left"},
             {headerName: "费用名称", headerWidth: CP_Col_Width.name, dataCode: "name", dataType: "String"},
             {headerName: "计算基数", headerWidth: CP_Col_Width.dispExprUser, dataCode: "dispExprUser", dataType: "String"},
-            {headerName: "费率", headerWidth: CP_Col_Width.feeRate, dataCode: "feeRate", dataType: "Number"},   // precision: 3
-            {headerName: "单价", headerWidth: CP_Col_Width.unitFee, dataCode: "unitFee", dataType: "Number"},  // execRst
+            {headerName: "费率", headerWidth: CP_Col_Width.feeRate, dataCode: "feeRate", dataType: "Number"},
+            {headerName: "单价", headerWidth: CP_Col_Width.unitFee, dataCode: "unitFee", dataType: "Number"},
             {headerName: "合价", headerWidth: CP_Col_Width.totalFee, dataCode: "totalFee", dataType: "Number"},
             {headerName:"费用类别", headerWidth:CP_Col_Width.displayFieldName, dataCode:"displayFieldName", dataType: "String", hAlign: "center"},
             {headerName: "基数说明", headerWidth: CP_Col_Width.statement, dataCode: "statement", dataType: "String"},
@@ -222,6 +31,11 @@ let calcProgramObj = {
     initSheet: function (sheet) {
         var me = this;
         me.sheet = sheet;
+        for (let col of me.setting.header){
+            if (col.headerName == '费率') col.tofix = decimalObj.feeRate;
+            if (col.headerName == '单价') col.tofix = decimalObj.ration.unitPrice;
+            if (col.headerName == '合价') col.tofix = decimalObj.ration.totalPrice;
+        };
         sheetCommonObj.initSheet(me.sheet, me.setting, 1);
     },
 
@@ -235,9 +49,6 @@ let calcProgramObj = {
         me.datas = treeNode.data.calcTemplate ? treeNode.data.calcTemplate.calcItems : [];
         sheetCommonObj.initSheet(me.sheet, me.setting, me.datas.length);
         sheetCommonObj.showData(me.sheet, me.setting, me.datas);
-
-        // SheetDataHelper.loadSheetHeader(calcProgramSetting, me.sheet);
-        //  SheetDataHelper.loadSheetData(calcProgramSetting, me.sheet, baseCalcField);
     },
 
     clearData: function (){

+ 190 - 110
web/building_saas/main/js/views/character_content_view.js

@@ -742,26 +742,71 @@ let pageCCOprObj = {
         CommonAjax.post(url, postData, function (rstData) {
             //更新节点数据
             if(updateCol){
-                if (!oprObj.hasOwnProperty("getID")) {
-                    // 已当前选中行更新数据
-                    let selectedNode = projectObj.mainController.tree.selected;
-                    selectedNode.data[updateObj.field] = updateObj.updateArr;
-                    selectedNode.data[txtObj.field] = txtObj.text;
-                    me.showData(oprObj.workBook.getSheet(0), oprObj.setting, oprObj.currentCache);//刷新特征及内容Spread
+                // 已当前选中行更新数据
+                let selectedNode = projectObj.mainController.tree.selected;
+                selectedNode.data[updateObj.field] = updateObj.updateArr;
+                selectedNode.data[txtObj.field] = txtObj.text;
+                me.showData(oprObj.workBook.getSheet(0), oprObj.setting, oprObj.currentCache);//刷新特征及内容Spread
 
-                    let activeCell = projectObj.mainSpread.getActiveSheet().getSelections()[0];
-                    projectObj.mainSpread.getActiveSheet().setValue(activeCell.row, updateCol, txtObj.text + ''); //刷新输出显示
-                    projectObj.mainSpread.getActiveSheet().autoFitRow(activeCell.row);
-                } else {
-                    // 以节点更新数据
-                    const row = oprObj.getID() - 1;
-                    projectObj.mainSpread.getActiveSheet().setValue(row, updateCol, txtObj.text + ''); //刷新输出显示
-                    projectObj.mainSpread.getActiveSheet().autoFitRow(row);
-                }
+                let activeCell = projectObj.mainSpread.getActiveSheet().getSelections()[0];
+                projectObj.mainSpread.getActiveSheet().setValue(activeCell.row, updateCol, txtObj.text + ''); //刷新输出显示
+                projectObj.mainSpread.getActiveSheet().autoFitRow(activeCell.row);
             }
         });
     },
     /**
+     * 更新bill数据
+     *
+     * @param {Object} findSet - 更新条件
+     * @param {Object} updateData - 更新数据
+     * @param {Function} callback - 回调函数
+     * @return {void}
+     */
+    updateBill: function(findSet, updateData, callback) {
+        if (!updateData instanceof Array || updateData.length <= 0) {
+            return;
+        }
+        let url = '/bills/updateBill';
+        let postData = { findSet, updateData };
+        CommonAjax.post(url, postData, function (response) {
+            callback(response);
+        });
+    },
+    /**
+     * 刷新节点数据
+     *
+     * @param {Object} node - 节点数据
+     * @param {Object} refreshData - 刷新的数据
+     * @param {Object} defaultData - 默认数据
+     * @return {void}
+     */
+    refreshView: function(node, refreshData, defaultData) {
+        // 更新清单行特征列或内容列
+        let updateCol = [
+            { name: 'character', col: 4 },
+            { name: 'content', col: 5 },
+            { name: 'name', col: 2 }
+        ];
+        if (updateCol === '') {
+            return;
+        }
+        const row = node.getID() - 1;
+        // 刷新输出显示
+        for (const tmp of updateCol) {
+            // 没有默认的数据则跳过刷新
+            if (defaultData[tmp.name] === undefined) {
+                continue;
+            }
+            // 不存在更新的数据则全部用默认数据替代
+            if (refreshData[tmp.name] === undefined) {
+                projectObj.mainSpread.getActiveSheet().setValue(row, tmp.col, defaultData[tmp.name] + '');
+            } else {
+                projectObj.mainSpread.getActiveSheet().setValue(row, tmp.col, refreshData[tmp.name] + '');
+            }
+        }
+        projectObj.mainSpread.getActiveSheet().autoFitRow(row);
+    },
+    /**
      * 根据配置设置清单项目特征
      *
      * @param {Object} node - 选中的node节点
@@ -770,91 +815,46 @@ let pageCCOprObj = {
      */
     setCharacterBySetting: function(node, setting) {
         let contentArray = [];
-        // 特征部分
-        const itemCharacter = node.data.itemCharacter;
-        // 内容数据
-        const itemJob = node.data.jobContent;
+        let self = this;
 
-        if (itemCharacter === undefined || itemCharacter.length <= 0 || itemJob === undefined || itemJob.length <= 0) {
-            return;
-        }
         // 保存的条件数据
         const findSet = { ID: node.data.ID, projectID: node.data.projectID };
-        const baseData = { findSet, itemJob, itemCharacter };
-        let characterArray = [];
-        for (const tmp of itemCharacter) {
-            if (tmp.eigenvalue === undefined || tmp.eigenvalue.length <= 0 || !tmp.isChecked) {
-                continue;
-            }
-            // 获取选中的特征值
-            let selectedEigen = '';
-            for (const eigen of tmp.eigenvalue) {
-                if (eigen.isSelected) {
-                    selectedEigen = eigen.value;
-                }
-            }
-            // 匹配设置的序号格式
-            const serialNo = this.formatSerialNumber(setting.serialType, tmp.serialNo);
-            let characterString = '';
-            // 特征生成方式
-            switch (setting.characterFormat) {
-                case '1':
-                    // 特征值
-                    characterString = serialNo + selectedEigen;
-                    break;
-                case '2':
-                    // 特征:特征值
-                    characterString = serialNo + tmp.character + ': ' + selectedEigen;
-                    break;
-            }
-            characterArray.push(characterString);
-        }
+        // 获取默认数据
+        const defaultData = this.getDataBySetting(node, {
+            serialType: "1",
+            characterFormat: "2",
+        });
+        // console.log(defaultData);return false;
+        defaultData.character = defaultData.character.join("\r\n");
+        defaultData.content = defaultData.content.join("\r\n");
 
-        // 内容部分
-        let jobArray = [];
-        for (const tmp of itemJob) {
-            if (!tmp.isChecked) {
-                continue;
-            }
-            // 匹配设置的序号格式
-            const serialNo = this.formatSerialNumber(setting.serialType, tmp.serialNo);
-            jobArray.push(serialNo + tmp.content)
-        }
+        // 获取当前设置数据
+        const currentData = this.getDataBySetting(node, setting);
 
         // 组合数据
         let content = '';
-        const jobContent = jobArray.join("\r\n");
-        const characterContent = characterArray.join("\r\n");
-        let nodeNameList = node.data.name.split("\n");
-        const nameContent = nodeNameList[0] !== undefined ? nodeNameList[0] : '';
-        // 存入对象,生成数据时用
-        let defaultContentInfo = {
-            jobContent,
-            characterContent,
-            nameContent
-        };
         switch (setting.addContent) {
             case "1":
                 // 项目特征+工作内容
                 contentArray.push('[项目特征]');
-                contentArray.push.apply(contentArray, characterArray);
+                contentArray.push.apply(contentArray, currentData.character);
                 contentArray.push('[工作内容]');
-                contentArray.push.apply(contentArray, jobArray);
+                contentArray.push.apply(contentArray, currentData.content);
                 break;
             case "2":
                 // 工作内容+项目特征
                 contentArray.push('[工作内容]');
-                contentArray.push.apply(contentArray, jobArray);
+                contentArray.push.apply(contentArray, currentData.content);
                 contentArray.push('[项目特征]');
-                contentArray.push.apply(contentArray, characterArray);
+                contentArray.push.apply(contentArray, currentData.character);
                 break;
             case "3":
                 // 项目特征
-                contentArray.push.apply(contentArray, characterArray);
+                contentArray.push.apply(contentArray, currentData.character);
                 break;
             case "4":
                 // 工作内容
-                contentArray.push.apply(contentArray, jobArray);
+                contentArray.push.apply(contentArray, currentData.content);
                 break;
             case "5":
                 // 定额子目
@@ -880,53 +880,57 @@ let pageCCOprObj = {
                 content = '(' + contentArray.join(',') + ')';
                 break;
         }
-        // 还原数据
-        this.restoreData(node, setting.position, baseData, defaultContentInfo);
         // 添加到对应位置
-        let saveObj = {};
+        let saveObj = [];
+        let refreshData = {};
+        saveObj.push({ field: 'addRule', value: setting });
         switch (setting.position) {
             case "1":
                 // 添加到项目特征列
-                saveObj = {field: 'itemCharacterText', text: content};
-                // 更新到数据库
-                pageCCOprObj.updateCharacterContent(findSet, {field: 'itemCharacter', updateArr: itemCharacter},
-                    saveObj, node);
+                saveObj.push({field: 'itemCharacterText', value: content});
+                // 还原名称及内容
+                saveObj.push({field: 'name', value: defaultData.name});
+                saveObj.push({field: 'jobContentText', value: defaultData.content});
+                // 刷新数据
+                refreshData = {'character': content};
                 break;
             case "2":
                 // 添加到清单名称列
-                const column = this.mainActiveCell.col !== undefined ? this.mainActiveCell.col : -1;
-                let colSetting = projectObj.mainController.setting.cols[column];
-                if (colSetting !== undefined) {
-                    content = node.data.name + "\r\n" + content;
-                    projectObj.project.Bills.updateField(node.source, 'name', content, true);
-                    projectObj.mainController.refreshTreeNode([node], false);
-                }
+                content = defaultData.name + "\r\n" + content;
+                saveObj.push({field: 'name', value: content});
+                // 还原特征及内容
+                saveObj.push({field: 'itemCharacterText', value: defaultData.character});
+                saveObj.push({field: 'jobContentText', value: defaultData.content});
+                // 刷新数据
+                refreshData = {'name': content};
                 break;
             case "3":
                 // 添加到工作内容列
-                saveObj =  {field: 'jobContentText', text: content};
-                // 更新到数据库
-                pageCCOprObj.updateCharacterContent(findSet, {field: 'jobContent', updateArr: itemJob},
-                    saveObj, node);
+                saveObj.push({field: 'jobContentText', value: content});
+                // 还原名称以及特征
+                saveObj.push({field: 'itemCharacterText', value: defaultData.character});
+                saveObj.push({field: 'name', value: defaultData.name});
+                // 刷新数据
+                refreshData = {'content': content};
                 break;
             case "4":
                 // 分别添加到对应列
-                if (Object.keys(defaultContentInfo).length <= 0) {
+                if (Object.keys(defaultData).length <= 0) {
                     return;
                 }
-                // 名称
-                projectObj.project.Bills.updateField(node.source, 'name', defaultContentInfo.nameContent, true);
-                projectObj.mainController.refreshTreeNode([node], false);
                 // 特征
-                saveObj = {field: 'itemCharacterText', text: defaultContentInfo.characterContent};
-                pageCCOprObj.updateCharacterContent(findSet, {field: 'itemCharacter', updateArr: itemCharacter},
-                    saveObj, node);
+                saveObj.push({field: 'itemCharacterText', value: defaultData.character});
                 // 内容
-                saveObj = {field: 'jobContentText', text: defaultContentInfo.jobContent};
-                pageCCOprObj.updateCharacterContent(findSet, {field: 'jobContent', updateArr: itemJob},
-                    saveObj, node);
+                saveObj.push({field: 'jobContentText', value: defaultData.content});
+                // 名称
+                saveObj.push({field: 'name', value: defaultData.name});
+                refreshData = {};
                 break;
         }
+        // 更新到数据库
+        pageCCOprObj.updateBill(findSet, saveObj, function(response) {
+            self.refreshView(node, refreshData, defaultData);
+        });
 
     },
     /**
@@ -952,6 +956,9 @@ let pageCCOprObj = {
                 // 英文字母(大写)
                 serialNo = letter[serialNo - 1] !== undefined ? letter[serialNo - 1].toUpperCase() + '. ' : '';
                 break;
+            default:
+                serialNo = '';
+                break;
         }
         return serialNo;
     },
@@ -974,13 +981,86 @@ let pageCCOprObj = {
                 continue;
             }
             const serialNo = this.formatSerialNumber(setting.serialType, count.toString());
-            result.push(serialNo +  tmp.data.code + ':' + tmp.data.name);
+            setting.childDisplayFormat === "1" ? result.push(tmp.data.code + ':' + tmp.data.name) : result.push(serialNo + tmp.data.name);
             count++;
         }
 
         return result;
     },
+    /**
+     * 获取默认数据
+     *
+     * @param {Object} node - 节点数据
+     * @param {Object} setting - 设置
+     * @return {Object}
+     */
+    getDataBySetting: function(node, setting) {
+        let result = {};
+        try {
+            if (node.data === undefined) {
+                throw '数据错误';
+            }
+            const itemCharacter = node.data.itemCharacter;
+            const itemJob = node.data.jobContent;
+            if (itemCharacter === undefined || itemCharacter.length <= 0 || itemJob === undefined || itemJob.length <= 0) {
+                throw '内部数据错误';
+            }
+            // 默认名称
+            let nodeNameList = node.data.name.split("\r\n");
+            const nameContent = nodeNameList[0] !== undefined ? nodeNameList[0] : '';
+            result['name'] = nameContent;
 
+            // 特征
+            let characterArray = [];
+            let count = 1;
+            for (const tmp of itemCharacter) {
+                if (tmp.eigenvalue === undefined || tmp.eigenvalue.length <= 0 || !tmp.isChecked) {
+                    continue;
+                }
+                // 获取选中的特征值
+                let selectedEigen = '';
+                for (const eigen of tmp.eigenvalue) {
+                    if (eigen.isSelected) {
+                        selectedEigen = eigen.value;
+                    }
+                }
+                // 匹配设置的序号格式
+                const serialNo = this.formatSerialNumber(setting.serialType, count.toString());
+                let characterString = '';
+                // 特征生成方式
+                switch (setting.characterFormat) {
+                    case '1':
+                        // 特征值
+                        characterString = serialNo + selectedEigen;
+                        break;
+                    case '2':
+                        // 特征:特征值
+                        characterString = serialNo + tmp.character + ': ' + selectedEigen;
+                        break;
+                }
+                characterArray.push(characterString);
+                count++;
+            }
+            result['character'] = characterArray;
+
+            // 内容部分
+            let jobArray = [];
+            count = 1;
+            for (const tmp of itemJob) {
+                if (!tmp.isChecked) {
+                    continue;
+                }
+                // 匹配设置的序号格式
+                const serialNo = this.formatSerialNumber(setting.serialType, count.toString());
+                jobArray.push(serialNo + tmp.content);
+                count++;
+            }
+            result['content'] = jobArray;
+        } catch (error) {
+            result = {};
+        }
+        return result;
+    },
     /**
      * 还原数据
      *
@@ -1005,16 +1085,16 @@ let pageCCOprObj = {
                 projectObj.mainController.refreshTreeNode([node], false);
                 // 还原工作内容
                 pageCCOprObj.updateCharacterContent(baseData.findSet, {field: 'jobContent', updateArr: baseData.itemJob},
-                    {field: 'jobContentText', text: defaultContentInfo.jobContent}, node);
+                    {field: 'jobContentText', text: contentOprObj.lastTextCache}, node);
                 break;
             case "2":
                 // 添加到清单名称
                 // 还原特征
                 pageCCOprObj.updateCharacterContent(baseData.findSet, {field: 'itemCharacter', updateArr: baseData.itemCharacter},
-                    {field: 'itemCharacterText', text: defaultContentInfo.characterContent}, node);
+                    {field: 'itemCharacterText', text: characterOprObj.lastTextCache}, node);
                 // 还原工作内容
                 pageCCOprObj.updateCharacterContent(baseData.findSet, {field: 'jobContent', updateArr: baseData.itemJob},
-                    {field: 'jobContentText', text: defaultContentInfo.jobContent}, node);
+                    {field: 'jobContentText', text: contentOprObj.lastTextCache}, node);
                 break;
             case "3":
                 // 添加到工作内容列
@@ -1023,7 +1103,7 @@ let pageCCOprObj = {
                 projectObj.mainController.refreshTreeNode([node], false);
                 // 还原特征
                 pageCCOprObj.updateCharacterContent(baseData.findSet, {field: 'itemCharacter', updateArr: baseData.itemCharacter},
-                    {field: 'jobContentText', text: defaultContentInfo.characterContent}, node);
+                    {field: 'itemCharacterText', text: characterOprObj.lastTextCache}, node);
                 break;
         }
     },

文件差异内容过多而无法显示
+ 854 - 654
web/building_saas/main/js/views/glj_view.js


+ 57 - 42
web/building_saas/main/js/views/main_tree_col.js

@@ -7,21 +7,27 @@ let MainTreeCol = {
         subType: function (node) {
             if (node.sourceType === projectObj.project.Bills.getSourceType()) {
                 return '';
-            // CSL, 2017-11-29
+                // CSL, 2017-11-29
             } else if (node.sourceType === projectObj.project.Ration.getSourceType()) {
                 if (node.data.type == 1 || node.data.type == undefined)    // 兼容旧定额
                     return '定'
-                else if (node.data.type == 2){    // 量价
+                else if (node.data.type == 2) {    // 量价
                     return volumePriceMaps[node.data.subType];
                 }
-                else if (node.data.type == 3){    // 工料机定额
-                    return  projectObj.project.projectGLJ.getShortNameByID(node.data.subType);//工料机名字缩写
+                else if (node.data.type == 3) {    // 工料机定额
+                    return projectObj.project.projectGLJ.getShortNameByID(node.data.subType);//工料机名字缩写
                 }
             } else if (node.sourceType === projectObj.project.ration_glj.getSourceType()) {
                 return projectObj.project.projectGLJ.getShortNameByID(node.data.subType);//工料机名字缩写
             }
         },
-
+        quantity:function (node) {
+          if(node.sourceType === projectObj.project.ration_glj.getSourceType()){
+              return gljOprObj.getTotalQuantity(node.data);
+          }else {
+              return node.data["quantity"];
+          }
+        },
         // CSL, 2017-11-28
         calcProgramName: function (node) {
             let programID = node.data.programID;
@@ -31,8 +37,8 @@ let MainTreeCol = {
     },
     readOnly: {
         // CSL, 2017-11-28
-        subType: function (node){
-            return (node.data.type != 2 && node.data.type != 3&&!MainTreeCol.readOnly.glj(node))||(node.data.type==rationType.gljRation&&MainTreeCol.readOnly.non_editSubType(node));
+        subType: function (node) {
+            return (node.data.type != 2 && node.data.type != 3 && !MainTreeCol.readOnly.glj(node)) || (node.data.type == rationType.gljRation && MainTreeCol.readOnly.non_editSubType(node));
         },
         calcProgramName: function (node) {
             if (
@@ -41,31 +47,33 @@ let MainTreeCol = {
             ) return false
             else return true;
         },
-        non_editSubType:function (node) {
-           return node.data.subType!=201&&node.data.subType!=4&&node.data.subType!=5
+        non_editSubType: function (node) {
+            return node.data.subType != 201 && node.data.subType != 4 && node.data.subType != 5
         },
-        commonUnitFee: function(node){
+        commonUnitFee: function (node) {
             return !projectObj.project.calcProgram.isNullBill(node);
         },
         //根据节点、父节点类型判断是否可用计算基数
         calcBaseType: function (node) {
-            function isDef (v) {
+            function isDef(v) {
                 return v !== undefined && v !== null;
             }
-            function isFlag (v) {
+
+            function isFlag(v) {
                 return this.isDef(v.flagsIndex) && this.isDef(v.flagsIndex.fixed);
             }
+
             let calcBase = projectObj.project.calcBase;
             let parent = node.parent;
-            if(isFlag(node.data) && (node.data.flagsIndex.fixed.flag === calcBase.fixedFlag.SUB_ENGINERRING
-                || node.data.flagsIndex.fixed.flag === calcBase.fixedFlag.CONSTRUCTION_TECH)){
+            if (isFlag(node.data) && (node.data.flagsIndex.fixed.flag === calcBase.fixedFlag.SUB_ENGINERRING
+                || node.data.flagsIndex.fixed.flag === calcBase.fixedFlag.CONSTRUCTION_TECH)) {
                 return true;
             }
-            else if(isFlag(node.data) && node.data.flagsIndex.fixed.flag === calcBase.fixedFlag.CONSTRUCTION_ORGANIZATION){
+            else if (isFlag(node.data) && node.data.flagsIndex.fixed.flag === calcBase.fixedFlag.CONSTRUCTION_ORGANIZATION) {
                 return false;
             }
             else {
-                if(!parent){
+                if (!parent) {
                     return false;
                 }
                 else {
@@ -102,7 +110,7 @@ let MainTreeCol = {
         },
         forCalcBase: function (node) {
             // to do according to billsParentType
-            return MainTreeCol.readOnly.billsParent(node) || MainTreeCol.readOnly.non_bills(node)||MainTreeCol.readOnly.leafBillsWithDetail(node) ||MainTreeCol.readOnly.calcBaseType(node);
+            return MainTreeCol.readOnly.billsParent(node) || MainTreeCol.readOnly.non_bills(node) || MainTreeCol.readOnly.leafBillsWithDetail(node) || MainTreeCol.readOnly.calcBaseType(node);
         },
         forUnitFee: function (node) {
             return MainTreeCol.readOnly.ration(node) || MainTreeCol.readOnly.billsParent(node) || MainTreeCol.readOnly.leafBillsWithDetail(node);
@@ -110,17 +118,17 @@ let MainTreeCol = {
         forTotalFee: function (node) {
             return MainTreeCol.readOnly.non_bills(node) || MainTreeCol.readOnly.billsParent(node) || (MainTreeCol.readOnly.leafBillsWithDetail(node));
         },
-        forQuantifyDetail:function (node) {
-            return !(node.sourceType==ModuleNames.ration||!MainTreeCol.readOnly.billsParent(node));
+        forQuantifyDetail: function (node) {
+            return !(node.sourceType == ModuleNames.ration || !MainTreeCol.readOnly.billsParent(node));
         },
-        forFeeRate:function (node) {
-            return MainTreeCol.readOnly.non_bills(node)||MainTreeCol.readOnly.billsParent(node)||MainTreeCol.readOnly.leafBillsWithDetail(node)
+        forFeeRate: function (node) {
+            return MainTreeCol.readOnly.non_bills(node) || MainTreeCol.readOnly.billsParent(node) || MainTreeCol.readOnly.leafBillsWithDetail(node)
         },
-        forQuantity:function (node) {
-            return MainTreeCol.readOnly.glj(node)||MainTreeCol.readOnly.billsParent(node)
+        forQuantity: function (node) {
+            return MainTreeCol.readOnly.glj(node) || MainTreeCol.readOnly.billsParent(node)
         },
-        forMarketPrice:function (node) {
-            return MainTreeCol.readOnly.bills(node)||(MainTreeCol.readOnly.ration(node)&&node.data.type == rationType.ration)||gljOprObj.marketPriceReadOnly(node);
+        forMarketPrice: function (node) {
+            return MainTreeCol.readOnly.bills(node) || (MainTreeCol.readOnly.ration(node) && node.data.type == rationType.ration) || gljOprObj.marketPriceReadOnly(node);
         }
     },
     cellType: {
@@ -150,7 +158,8 @@ let MainTreeCol = {
                 node.sourceType === projectObj.project.Ration.getSourceType() ||
                 (projectObj.project.calcProgram.isLeafBill(node) && projectObj.project.property.billsCalcMode === leafBillGetFeeType.billsPrice)
             ) {
-                var names = new GC.Spread.Sheets.CellTypes.ComboBox();
+                // var names = new GC.Spread.Sheets.CellTypes.ComboBox();
+                var names = sheetCommonObj.getDynamicCombo();
                 names.items(projectObj.project.calcProgram.compiledTemplateNames);
                 return names;
             }
@@ -158,21 +167,21 @@ let MainTreeCol = {
 
         // CSL, 2017-11-28
         subType: function (node) {
-            if (node.data.type == rationType.volumePrice || node.data.type == rationType.gljRation||node.sourceType === projectObj.project.ration_glj.getSourceType()){
-                let VPType = sheetCommonObj.getDynamicCombo();;
-
+            if (node.data.type == rationType.volumePrice || node.data.type == rationType.gljRation || node.sourceType === projectObj.project.ration_glj.getSourceType()) {
+                let VPType = sheetCommonObj.getDynamicCombo();
                 if (node.data.type == rationType.volumePrice)
-                    VPType.itemHeight(5).items(["人工","材料","机械","主材","设备"])
-                else if (node.data.type == rationType.gljRation||node.sourceType === projectObj.project.ration_glj.getSourceType())
-                    if(!MainTreeCol.readOnly.non_editSubType(node)){
-                        VPType.itemHeight(3).items(["材料","主材","设备"]);
-                    }else {
+                    VPType.itemHeight(5).items(["人工", "材料", "机械", "主材", "设备"])
+                else if (node.data.type == rationType.gljRation || node.sourceType === projectObj.project.ration_glj.getSourceType())
+                    if (!MainTreeCol.readOnly.non_editSubType(node)) {
+                        VPType.itemHeight(3).items(["材料", "主材", "设备"]);
+                    } else {
                         return null;
                     }
                 return VPType;
-            };
+            }
+            ;
         },
-     },
+    },
     getEvent: function (eventName) {
         let names = eventName.split('.');
         let event = this;
@@ -206,9 +215,10 @@ let MainTreeCol = {
                     return '0.000000';
                 default:
                     return '0.00';
-            };
+            }
+            ;
         }
-        else{
+        else {
             switch (digit) {
                 case 1:
                     return '0.#';
@@ -224,7 +234,8 @@ let MainTreeCol = {
                     return '0.######';
                 default:
                     return '0.##';
-            };
+            }
+            ;
         }
     }
 };
@@ -251,11 +262,12 @@ let colSettingObj = {
                     sheet.addSpan(index, iCol, col.head.spanRows[i], col.head.spanCols[i], GC.Spread.Sheets.SheetArea.rowHeader);
                 }
                 iCol += col.head.spanRows[i];
-            };
+            }
+            ;
             let colWidth = sheet.getColumnWidth(index, GC.Spread.Sheets.SheetArea.rowHeader);
             colWidth = colWidth > col.width ? colWidth : col.width;
             sheet.setColumnWidth(index, colWidth, GC.Spread.Sheets.SheetArea.rowHeader);
-            cell = sheet.getCell(index, 0).value(col.visible);            
+            cell = sheet.getCell(index, 0).value(col.visible);
             sheet.autoFitRow(index);
         });
     },
@@ -279,5 +291,8 @@ $('#column').on('hide.bs.modal', function () {
         projectObj.project.projSetting.mainGridSetting.cols[iRow].visible = sheet.getValue(iRow, 0);
     }
     SheetDataHelper.refreshColumnVisible(projectObj.project.projSetting.mainGridSetting, projectObj.mainSpread.getActiveSheet());
-    projectObj.project.pushNow('editColSetting', projectObj.project.projSetting.moduleName, {projectID: projectObj.project.ID(), main_tree_col: projectObj.project.projSetting.main_tree_col});
+    projectObj.project.pushNow('editColSetting', projectObj.project.projSetting.moduleName, {
+        projectID: projectObj.project.ID(),
+        main_tree_col: projectObj.project.projSetting.main_tree_col
+    });
 });

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

@@ -37,7 +37,7 @@ decimalObj.decimal = function (field, node) {
             else if(node.sourceType === projectObj.project.Ration.getSourceType()){
                 return returnV(this['ration'][field], this.process);
             }
-            else if(node.sourceType === projectObj.project.GLJ.getSourceType()){
+            else if(node.sourceType === projectObj.project.ration_glj.getSourceType()){
                 return returnV(this['glj'][field], this.process);
             }
         }

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

@@ -301,16 +301,17 @@ var projectObj = {
                 }
                 else if (fieldName === 'calcBase') {
                     //zhong
-                    if(value){
-                        node.data.userCalcBase = value;
-                        project.calcBase.calculate(node);
-                        if(!project.calcBase.success){
-                            let activeCell = projectObj.mainSpread.getActiveSheet().getSelections()[0];
-                            projectObj.mainSpread.getActiveSheet().setValue(activeCell.row, activeCell.col, node.data.calcBase? node.data.calcBase: '');
-                        }
+                    if(value === undefined ||value === null || value.toString().trim() === ''){
+                        value = '';
+                    }
+                    node.data.userCalcBase = value;
+                    project.calcBase.calculate(node);
+                    if(!project.calcBase.success){
+                        let activeCell = projectObj.mainSpread.getActiveSheet().getSelections()[0];
+                        projectObj.mainSpread.getActiveSheet().setValue(activeCell.row, activeCell.col, node.data.calcBase? node.data.calcBase: '');
+                        return;
                     }
-                    return;
-                   // if (value) {value = parseFloat(value).toDecimal(decimalObj.decimal("totalPrice", node))};
+                    // if (value) {value = parseFloat(value).toDecimal(decimalObj.decimal("totalPrice", node))};
                 };
                 node.changed = true;
                 if (fieldName == 'feesIndex.common.unitFee'){

+ 39 - 0
web/building_saas/main/js/views/sub_view.js

@@ -104,6 +104,10 @@ $("#linkTZJNR").click(function () {
     pageCCOprObj.active = true;
     refreshSubSpread();
     let selectedNode = projectObj.mainController.tree.selected;
+    if (selectedNode.data.addRule !== undefined) {
+        setRule(selectedNode.data.addRule);
+    }
+
     pageCCOprObj.mainActiveCell = projectObj.mainSpread.getActiveSheet().getSelections()[0];
     if(selectedNode && selectedNode.sourceType === projectObj.project.Bills.getSourceType()){
         pageCCOprObj.setCacheAndShow(selectedNode);
@@ -189,6 +193,11 @@ $("#add-content").change(function() {
             serialTypeEle.val('');
             serialTypeEle.attr('disabled', 'disabled');
             break;
+        case '1':
+        case '2':
+        case '3':
+            characterFormatEle.removeAttr('disabled');
+            break;
         case '4':
             // 当“添加内容”是“定额子目”或“工作内容”,则“特征生成方式”灰显,不需选择;否则有效可选。
             characterFormatEle.attr('disabled', 'disabled');
@@ -210,6 +219,7 @@ $("#child-display-format").change(function() {
         serialTypeEle.val("");
         serialTypeEle.attr('disabled', 'disabled');
     } else {
+        serialTypeEle.val(1);
         serialTypeEle.removeAttr('disabled');
     }
 });
@@ -228,6 +238,8 @@ function getAddRuleSetting() {
     const displayFormat = $("#display-format").val();
     // 特征生成方式
     const characterFormat = $("#character-format").val();
+    // 子目生成方式
+    const childDisplayFormat = $("#child-display-format").val();
 
     // 序号格式
     const serialType = $("#serial-type").val();
@@ -237,11 +249,38 @@ function getAddRuleSetting() {
         addContent,
         position,
         displayFormat,
+        childDisplayFormat,
     };
 
     return setting;
 }
 
+/**
+ * 根据配置设置规则
+ *
+ * @param {Object} setting - 数据库中读取的数据
+ * @return {void}
+ */
+function setRule(setting) {
+    if (Object.keys(setting).length <= 0) {
+        return;
+    }
+    $("#add-position").val(setting.position);
+    $("#add-position").change();
+
+    $("#add-content").val(setting.addContent);
+    $("#add-content").change();
+
+    $("#display-format").val(setting.displayFormat);
+
+    $("#character-format").val(setting.characterFormat);
+
+    $("#child-display-format").val(setting.childDisplayFormat);
+    $("#child-display-format").change();
+
+    $("#serial-type").val(setting.serialType);
+}
+
 function activeSubSheetIs(idx){
     let rst = subSpread.getActiveSheetIndex() == idx;
     return rst;