Browse Source

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

Conflicts:
	web/building_saas/main/js/views/project_view.js
zhangweicheng 7 years ago
parent
commit
a1d23b338b

+ 87 - 0
modules/main/facade/calc_program_facade.js

@@ -0,0 +1,87 @@
+/**
+ * Created by CSL on 2017-10-22.
+ */
+
+const uuidV1 = require('uuid/v1');
+let logger = require("../../../logs/log_helper").logger;
+let mongoose = require('mongoose');
+let stdCalcProgramsModel = mongoose.model('std_calc_programs');
+let projectCalcProgramsModel = mongoose.model('calc_programs');
+let EngineeringLibModel = require("../../users/models/engineering_lib_model");
+let _=require("lodash");
+let consts = require('../models/project_consts');
+let projectConsts = consts.projectConst;
+
+module.exports = {
+    newProjectCalcProgramFile: newProjectCalcProgramFile,
+    getProjectCalcProgramFile: getProjectCalcProgramFile,
+    getStdCalcProgramFile: getStdCalcProgramFile,
+    getData: getData,
+    save: save
+};
+
+async function newProjectCalcProgramFile(data) {
+    logger.info(`Create new CalcProgram file for project : ${data.ID}`);
+    let rst = null;
+    let egnrModel = new EngineeringLibModel();
+    let egnr = await egnrModel.getEngineering(data.property.engineering_id);
+    if(!egnr) return rst;
+    let valid_CP_libs = egnr._doc.program_lib;
+    if (valid_CP_libs == undefined  || valid_CP_libs.length == 0) return rst;
+    // 绑定多个计算程序标准文件时,默认取第一个作为标准模板。
+    let stdCP = await getStdCalcProgramFile(valid_CP_libs[0].id);
+    let doc={
+        ID: uuidV1(),
+        projectID: data.ID,
+        name: data.name,
+        libID: stdCP.ID,
+        libName: stdCP.libName,
+        templates: stdCP.templates
+    };
+    await projectCalcProgramsModel.create(doc);
+    rst = {ID: doc.ID, name: doc.name};
+    return rst;
+};
+
+async function getProjectCalcProgramFile(ID) {
+    let projLC = await projectCalcProgramsModel.findOne({ID:ID});
+    return projLC;
+};
+
+async function getStdCalcProgramFile(libID) {
+    let stdLC = await stdCalcProgramsModel.findOne({ID:libID});
+    return stdLC;
+};
+
+// 统一的 getData() 方法供project调用
+function getData(projectID, callback) {
+    projectCalcProgramsModel.findOne({projectID: projectID}, '-_id', function (err, datas) {
+        if (!err) {
+            // 旧项目没有计算程序文件,默认给它生成一个。
+            if (!datas) {
+                logger.info(`Create a calcProgram file for old project : ${projectID}`);
+                getStdCalcProgramFile(1).then(function (stdCP) {
+                    let doc = {
+                        ID: uuidV1(),
+                        projectID: projectID,
+                        name: '[旧项目补计算程序文件]',
+                        libID: stdCP.ID,
+                        libName: stdCP.libName,
+                        templates: stdCP.templates
+                    };
+                    projectCalcProgramsModel.create(doc);
+                    callback(0, projectConsts.CALC_PROGRAM, stdCP);
+                });
+            } else {
+                callback(0, projectConsts.CALC_PROGRAM, datas);
+            };
+        } else {
+            callback(1, projectConsts.CALC_PROGRAM, null);
+        };
+    });
+};
+
+// 统一的 save() 方法供project调用
+function save (user_id, datas, callback) {
+    projectCalcProgramsModel.update({"projectID": 553}, {"libName":"goo—test"}, callback(null, {data: 'test'}));
+}

+ 7 - 6
modules/main/facade/labour_coe_facade.js

@@ -22,11 +22,12 @@ module.exports = {
 
 async function newProjectLabourCoe(data) {
     logger.info(`Create new LabourCoe file for project : ${data.ID}`);
-    let valid_LC_libs = [];
-    let egnrID = data.property.engineering_id;
+    let rst = null;
     let egnrModel = new EngineeringLibModel();
-    let egnr = await egnrModel.getEngineering(egnrID);
-    if(egnr){ valid_LC_libs = egnr._doc.artificial_lib };
+    let egnr = await egnrModel.getEngineering(data.property.engineering_id);
+    if(!egnr) return rst;
+    let valid_LC_libs = egnr._doc.artificial_lib;
+    if (valid_LC_libs == undefined  || valid_LC_libs.length == 0) return rst;
     // 绑定多个人工系数标准文件时,默认取第一个作为标准模板。
     let stdLC = await getStdLabourCoe(valid_LC_libs[0].id);
     let doc={
@@ -38,8 +39,8 @@ async function newProjectLabourCoe(data) {
         coes: stdLC.coes
     };
     await projectLabourCoesModel.create(doc);
-    let newLC = {ID: doc.ID, name: doc.name};
-    return newLC;
+    rst = {ID: doc.ID, name: doc.name};
+    return rst;
 };
 
 async function getProjectLabourCoe(ID) {

+ 44 - 0
modules/main/models/calc_program_model.js

@@ -0,0 +1,44 @@
+/**
+ * Created by CSL on 2017-10-22.
+ */
+let mongoose = require('mongoose');
+let Schema = mongoose.Schema;
+
+let calcItemSchema = new Schema({
+    ID: Number,
+    code: String,
+    name: String,
+    fieldName: String,
+    dispExpr: String,
+    expression: String,
+    compiledExpr: String,
+    statement: String,
+    feeRateID: Number,
+    feeRate: Number,
+    labourCoeID: Number
+},{versionKey:false, _id: false});
+
+let templateSchema = new Schema({
+    ID: Number,
+    name: String,
+    calcItems: [calcItemSchema]
+},{versionKey:false, _id: false});
+
+let stdCalcPrograms = new Schema({
+    ID: Number,
+    region: String,
+    libName: String,
+    templates: [templateSchema]
+},{versionKey:false, _id: false});
+
+let projectCalcPrograms = new Schema({
+    ID: String,
+    projectID: Number,
+    name: String,
+    libID: Number,
+    libName: String,
+    templates: [templateSchema]
+},{versionKey:false});
+
+mongoose.model('std_calc_programs', stdCalcPrograms, 'std_calc_programs');
+mongoose.model('calc_programs', projectCalcPrograms, 'calc_programs');

+ 7 - 2
modules/main/models/proj_setting_model.js

@@ -3,7 +3,7 @@
  */
 
 let baseModel = require('./base_model');
-import {default as projSettingSchema, collectionName as collectionName} from "./schemas/proj_setting";
+import {default as projSettingSchema, collectionName as collectionName, billsCalcModeConst as billsCalcModeConst} from "./schemas/proj_setting";
 
 class projSettingModel extends baseModel {
 
@@ -15,7 +15,12 @@ class projSettingModel extends baseModel {
     getData (projectID, callback) {
         this.model.findOne({"projectID": projectID}, '-_id', function (err, result) {
             if (!err) {
-                callback(0, collectionName, result);
+                let data = JSON.parse(JSON.stringify(result));
+                if (!data.billsCalcMode) {
+                    data.billsCalcMode = billsCalcModeConst.rationContent;
+                }
+                data.billsCalcModeConst = billsCalcModeConst;
+                callback(0, collectionName, data);
             } else {
                 callback(1, '查询数据失败。', null);
             }

+ 4 - 2
modules/main/models/project.js

@@ -12,7 +12,8 @@ var fee_rate_data = require('../../fee_rates/facade/fee_rates_facade');
 let projCounter = require('./proj_counter_model');
 let projSetting = require('./proj_setting_model');
 let volumePriceData = require('../../volume_price/models/volume_price_model');
-var labour_coe_data = require('../facade/labour_coe_facade');
+var labour_coe_facade = require('../facade/labour_coe_facade');
+var calc_program_facade = require('../facade/calc_program_facade');
 var consts = require('./project_consts');
 var projectConsts = consts.projectConst;
 var async = require("async");
@@ -30,7 +31,8 @@ moduleMap[projCounter.collectionName] = projCounter;
 moduleMap[projSetting.collectionName] = projSetting;
 moduleMap[volumePriceData.collectionName] = volumePriceData;
 moduleMap[projectConsts.FEERATE] = fee_rate_data;
-moduleMap[projectConsts.LABOUR_COE] = labour_coe_data;
+moduleMap[projectConsts.LABOUR_COE] = labour_coe_facade;
+moduleMap[projectConsts.CALC_PROGRAM] = calc_program_facade;
 
 var Project = function (){};
 

+ 2 - 1
modules/main/models/project_consts.js

@@ -15,7 +15,8 @@ var projectConst = {
     PROPERTIES: 'properties',
     VOLUMEPRICE: 'volume_price',
     FEERATE:'feeRate',
-    LABOUR_COE:'labour_coe'
+    LABOUR_COE:'labour_coe',
+    CALC_PROGRAM:'calc_program'
 };
 
 var commonConst = {

+ 9 - 1
modules/main/models/schemas/proj_setting.js

@@ -5,13 +5,21 @@
 let mongoose = require("mongoose");
 let Schema = mongoose.Schema;
 let collectionName = 'proj_setting';
+let billsCalcModeConst = {
+    rationContent: 0, rationPrice: 1, rationPriceConverse: 2, billsPrice: 3
+};
 let projSettingSchema = {
     projectID: Number,
     // 列设置
     main_tree_col: {
         type: Schema.Types.Mixed,
         default: {}
+    },
+    billsCalcMode: {
+        type: Number,
+        default: billsCalcModeConst.rationContent
+        // rationContent = 0, rationPrice = 1, rationPriceConverse = 2, billsPrice = 3
     }
 };
 let model = mongoose.model(collectionName, new Schema(projSettingSchema, {versionKey: false, collection: collectionName}));
-export {model as default, collectionName as collectionName};
+export {model as default, collectionName as collectionName, billsCalcModeConst as billsCalcModeConst};

+ 4 - 0
modules/pm/models/project_model.js

@@ -8,6 +8,7 @@ let newProjController = require('../controllers/new_proj_controller');
 let copyProjController = require('../controllers/copy_proj_controller');
 let feeRateFacade = require('../../fee_rates/facade/fee_rates_facade');
 let labourCoeFacade = require('../../main/facade/labour_coe_facade');
+let calcProgramFacade = require('../../main/facade/calc_program_facade');
 let logger = require("../../../logs/log_helper").logger;
 
 let Projects = require("./project_schema");
@@ -97,6 +98,9 @@ ProjectsDAO.prototype.updateUserProjects = async function(userId, datas, callbac
                     // 新建人工系数文件 CSL, 2017.10.13
                     let lcFile = await labourCoeFacade.newProjectLabourCoe(data.updateData);
                     newProject.property.labourCoeFile = lcFile ? lcFile : null;
+                    // 新建计算程序文件 CSL, 2017.10.23
+                    let cpFile = await calcProgramFacade.newProjectCalcProgramFile(data.updateData);
+                    newProject.property.calcProgramFile = cpFile ? cpFile : null;
                 }
                 newProject.save(async function (err, result) {
                     if (!err && result._doc.projType === projectType.tender) {

+ 1 - 0
server.js

@@ -30,6 +30,7 @@ fileUtils.getGlobbedFiles('./modules/reports/models/*.js').forEach(function(mode
 
 // 引入人工系数模块
 require('./modules/main/models/labour_coe_model');
+require('./modules/main/models/calc_program_model');
 
 //config.setupCache();
 let cfgCacheUtil = require("./config/cacheCfg");

+ 7 - 6
web/building_saas/main/html/main.html

@@ -444,7 +444,7 @@
                                         <fieldset class="form-group">
                                             <div class="form-check">
                                                 <label class="form-check-label">
-                                                    <input class="form-check-input" name="calcFlag" id="rationContent" value="0" checked="" type="radio">
+                                                    <input class="form-check-input" name="calcFlag" id="rationContent" value="0" type="radio">
                                                     子目含量取费
                                                 </label>
                                             </div>
@@ -541,15 +541,15 @@
     </div>
     <!--弹出清单单位选择设置-->
     <div class="modal fade" id="std_bills_unit" data-backdrop="static">
-        <div class="modal-dialog modal-lg" role="document">
+        <div class="modal-dialog" role="document">
             <div class="modal-content">
                 <div class="modal-header">
-                    <h5 class="modal-title"><i class="fa fa-table"></i> 请选择清单计量单位</h5>
+                    <h5 class="modal-title"><i class="fa fa-superscript"></i> 请选择清单计量单位</h5>
                     <button type="button" class="close" id='std_bills_unit_close' aria-label="Close">
                         <span aria-hidden="true">&times;</span>
                     </button>
                 </div>
-                <div class="modal-body modal-auto-height" id="std_bills_unit_spread" style="height: 200px; overflow: hidden;">
+                <div class="modal-body modal-auto-height" id="std_bills_unit_spread" style="height: 200px; width: 500px; overflow: hidden;">
                 </div>
                 <div class="modal-footer">
                     <a href="javascript:void(0);" id="std_bills_unit_ok" class="btn btn-primary">确定</a>
@@ -670,8 +670,7 @@
     <script src="/public/web/uuid.js"></script>
 
     <script type="text/javascript" src="/public/web/sheet/sheet_common.js"></script>
-    <script type="text/javascript" src="/web/building_saas/main/js/models/calc_program.js"></script>
-    <script type="text/javascript" src="/web/building_saas/main/js/views/calc_program_manage.js"></script>
+
 
     <!-- JS. -->
     <script src="/lib/popper/popper.min.js"></script>
@@ -710,6 +709,8 @@
     <script type="text/javascript" src="/web/building_saas/main/js/models/ration_ass.js"></script>
     <script type="text/javascript" src="/web/building_saas/main/js/models/volume_price.js"></script>
     <script type="text/javascript" src="/web/building_saas/main/js/models/labour_coe.js"></script>
+    <script type="text/javascript" src="/web/building_saas/main/js/models/calc_program.js"></script>
+    <script type="text/javascript" src="/web/building_saas/main/js/views/calc_program_manage.js"></script>
 
     <script type="text/javascript" src="/public/web/id_tree.js"></script>
     <script type="text/javascript" src="/test/tmp_data/test_ration_calc/ration_calc_base.js"></script>

+ 14 - 0
web/building_saas/main/js/controllers/project_controller.js

@@ -82,6 +82,20 @@ ProjectController = {
             this.syncDisplayNewNode(sheetController, newNode);
         }
     },
+    replaceRation: function (project, sheetController, std) {
+        if (!project || !sheetController) { return; }
+
+        let selected = project.mainTree.selected, newSource = null, newNode = null;
+        if (selected === null) { return; }
+
+        if (selected.sourceType === project.Ration.getSourceType()) {
+            project.Ration.replaceRation(selected.source, std);
+            project.ration_glj.addRationGLJ(selected.source, std);
+            sheetController.refreshTreeNode([selected], false);
+        } else {
+            alert('当前焦点行不是定额,无法替换。');
+        }
+    },
     addVolumePrice: function (project, sheetController) {
         if (!project || !sheetController) { return null; }
 

+ 13 - 5
web/building_saas/main/js/models/bills.js

@@ -261,23 +261,31 @@ var Bills = {
             this.project.pushNow('updateBills', this.getSourceType(), updateData);
         };
 
-        bills.prototype.updateAll = function () {
+        bills.prototype.getUpdateAllData = function () {
             let updateData = [];
             for (let data of this.datas) {
                 updateData.push({'updateType': 'ut_update', 'updateData': tools.formatBillsUpdateData(data)});
             }
-            this.project.pushNow('updateAllBills', this.getSourceType(), updateData);
+            return updateData;
         };
 
-        bills.prototype.updateNodes = function (nodes, updateNow) {
+        bills.prototype.updateAll = function () {
+            this.project.pushNow('updateAllBills', this.getSourceType(), this.getUpdateAllData());
+        };
+
+        bills.prototype.getUpdateNodesData = function (nodes) {
             let updateData = [];
             for (let node of nodes) {
                 updateData.push({'updateType': 'ut_update', 'updateData': tools.formatBillsUpdateData(node.data)});
             }
+            return updateData;
+        }
+
+        bills.prototype.updateNodes = function (nodes, updateNow) {
             if (updateNow) {
-                this.project.pushNow('updateBills', this.getSourceType(), updateData);
+                this.project.pushNow('updateBills', this.getSourceType(), this.getUpdateNodesData(nodes));
             } else {
-                this.project.push(this.getSourceType(), updateData);
+                this.project.push(this.getSourceType(), this.getUpdateNodesData(nodes));
             }
         };
 

File diff suppressed because it is too large
+ 24 - 3598
web/building_saas/main/js/models/calc_program.js


+ 2 - 1
web/building_saas/main/js/models/main_consts.js

@@ -13,5 +13,6 @@ const ModuleNames = {
     quantity_detail:'quantity_detail',
     volume_price: 'volume_price',
     projectGLJ: 'project_glj',
-    labour_coe: 'labour_coe'
+    labour_coe: 'labour_coe',
+    calc_program: 'calc_program'
 };

+ 11 - 6
web/building_saas/main/js/models/project.js

@@ -87,7 +87,8 @@ var PROJECT = {
                     totalFee: 2
                 }
             };
-            this.LabourCoe = new LabourCoe(this);
+            this.labourCoe = new LabourCoe(this);
+            this.calcProgram = new CalcProgram(this);
 
             this.masterField = {ration: 'billsItemID', volumePrice: 'billsItemID'};
         };
@@ -288,21 +289,25 @@ var PROJECT = {
             }
         };
 
-        project.prototype.setCalcFlag = function (calcFlag) {
-            this.calcFlag = calcFlag;
+        project.prototype.setBillsCalcMode = function (calcMode) {
+            this.projSetting.billsCalcMode = calcMode;
+            this.initCalcFields();
+        };
+
+        project.prototype.initCalcFields = function () {
             if (this.calcFields) {
                 for (let field of this.calcFields) {
                     // unitFeeCalcFlag
-                    if (this.calcFlag === rationContent) {
+                    if (this.projSetting.billsCalcMode === this.projSetting.billsCalcModeConst.rationContent) {
                         field.unitFeeFlag = rationContentUnitFeeFlag;
-                    } else if ( this.calcFlag === billsPrice) {
+                    } else if ( this.projSetting.billsCalcMode === this.projSetting.billsCalcModeConst.billsPrice) {
                         field.unitFeeFlag = billsPriceUnitFeeFlag;
                     } else {
                         field.unitFeeFlag = averageQtyUnitFeeFlag;
                     }
                     // totalFeeCalcFlag
                     if (field.type === 'common') {
-                        if (this.calcFlag === rationPriceConverse) {
+                        if (this.projSetting.billsCalcMode === this.projSetting.billsCalcModeConst.rationPriceConverse) {
                             field.totalFeeFlag = sumTotalFeeFlag;
                         } else {
                             field.totalFeeFlag = totalFeeFlag;

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

@@ -37,7 +37,7 @@ let rationPM = {
 
     buildSheet: function (){
         let me = this;
-        me.datas = calcTemplates;
+        me.datas = projectObj.project.calcProgram.datas.templates;
         if (me.mainSpread) {
             me.mainSpread.destroy();
             me.mainSpread = null;

+ 4 - 3
web/building_saas/main/js/views/confirm_modal.js

@@ -74,8 +74,9 @@ let ConfirmModal = {
         },
         check: function (std, okCallBack, cancelCallBack) {
             if (!this.spread) {
-                this.spread = SheetDataHelper.createNewSpread($('#std_bills_unit_spread')[0]);
-                SheetDataHelper.loadSheetHeader(this.setting, ConfirmModal.stdBillsUnit.spread.getActiveSheet());
+                this.spread = SheetDataHelper.createNewSpread($('#std_bills_unit_spread')[0], {sheetCount: 1});
+                this.spread.options.showScrollTip = GC.Spread.Sheets.ShowScrollTip.vertical;
+                SheetDataHelper.loadSheetHeader(this.setting, this.spread.getActiveSheet());
             }
             let sheet = ConfirmModal.stdBillsUnit.spread.getActiveSheet();
             let modalObj = this.modalObj;
@@ -102,7 +103,7 @@ let ConfirmModal = {
                 datas.push({'code': std.code, 'name': std.name, 'unit': unit});
             }
             SheetDataHelper.loadSheetData(this.setting, sheet, datas);
-            this.modalObj.modal({backdrop: false, keyboard: false});  
+            this.modalObj.modal('show');  
             ConfirmModal.stdBillsUnit.spread.refresh();  
         }
     }

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

@@ -93,7 +93,7 @@ let labourCoeView = {
 
     showData(){
         let me = this;
-        let datas = projectObj.project.LabourCoe.datas !== null ? projectObj.project.LabourCoe.datas.coes : [];
+        let datas = projectObj.project.labourCoe.datas !== null ? projectObj.project.labourCoe.datas.coes : [];
         me.init();
         me.buildSheet();
         me.loadData(datas);

+ 27 - 8
web/building_saas/main/js/views/project_view.js

@@ -290,7 +290,7 @@ var projectObj = {
         this.project.loadDatas(function (err) {
             if (!err) {
                 that.project.calcFields = JSON.parse(JSON.stringify(feeType));
-                that.project.setCalcFlag(rationContent);
+                that.project.initCalcFields();
                 var feeRateCol = 0;
                 let str = JSON.stringify(that.project.projSetting.main_tree_col);
                 that.project.projSetting.mainGridSetting = JSON.parse(str);
@@ -320,7 +320,6 @@ var projectObj = {
                     }
                 });
 
-                that.project.calcProgram = new CalcProgram(that.project);
                 that.project.calcProgram.compileAllTemps();
 
                 that.mainController = TREE_SHEET_CONTROLLER.createNew(that.project.mainTree, that.mainSpread.getActiveSheet(), that.project.projSetting.mainGridSetting);
@@ -542,11 +541,31 @@ $('#downMove').click(function () {
     }
 });
 
-$('#rationContent').val(rationContent);
-$('#rationPrice').val(rationPrice);
-$('#rationPriceConverse').val(rationPriceConverse);
-$('#billsPrice').val(billsPrice);
+$('#poj-set').on('show.bs.modal', function () {
+    let setCalcFlag = function (obj, val, curFlag) {
+        obj.val(val);
+        if (val === curFlag) {
+            obj.attr('checked', true);
+        } else {
+            obj.removeAttr('checked');
+        }
+    }
+    if (projectObj.project) {
+        let mode = projectObj.project.projSetting.billsCalcMode;
+        setCalcFlag($('#rationContent'), projectObj.project.projSetting.billsCalcModeConst.rationContent, mode);
+        setCalcFlag($('#rationPrice'), projectObj.project.projSetting.billsCalcModeConst.rationPrice, mode);
+        setCalcFlag($('#rationPriceConverse'), projectObj.project.projSetting.billsCalcModeConst.rationPriceConverse, mode);
+        setCalcFlag($('#billsPrice'), projectObj.project.projSetting.billsCalcModeConst.billsPrice, mode);
+    }
+});
 $('#property_ok').click(function () {
-    projectObj.project.setCalcFlag(parseInt($("input[name='calcFlag']:checked").val()));
-    projectObj.calculateAll();
+    let project = projectObj.project, mode = parseInt($("input[name='calcFlag']:checked").val());
+    if (mode !== project.projSetting.billsCalcMode) {
+        project.setBillsCalcMode(mode);
+        projectObj.calculateAll();
+        project.pushNow('editBillsCalcMode',
+            [project.projSetting.moduleName, project.Bills.getSourceType()],
+            [{projectID: project.ID(), billsCalcMode: project.projSetting.billsCalcMode}, project.Bills.getUpdateAllData()]
+        );
+    }
 });

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

@@ -86,6 +86,44 @@ var rationLibObj = {
             });
         }
     },
+    loadStdRationContextMenu: function () {
+        let rationSpread = rationLibObj.sectionRationsSpread, rationSheet = rationSpread.getActiveSheet();
+        $.contextMenu({
+            selector: '#stdSectionRations',
+            build: function ($trigger, e) {
+                let target = SheetDataHelper.safeRightClickSelection($trigger, e, rationSpread);
+                return target.hitTestType === GC.Spread.Sheets.SheetArea.viewport || target.hitTestType === GC.Spread.Sheets.SheetArea.rowHeader;
+            },
+            items: {
+                "insertStdRation": {
+                    name: "插入定额",
+                    icon: 'fa-sign-in',
+                    callback: function (key, opt) {
+                        let select = $('#stdRationLibSelect'), rationSelect = rationSheet.getSelections();
+                        let rationCode = rationSelect.length > 0 ? rationSheet.getText(rationSelect[0].row, 0) : '';
+                        if (rationCode !== '') {
+                            CommonAjax.postRationLib('/rationRepository/api/getRationItem', {user_id: userID, rationLibId: select.val(), code: rationCode}, function (data) {
+                                ProjectController.addRation(projectObj.project, projectObj.mainController, data);
+                            });
+                        }
+                    }
+                },
+                "replaceStdRation": {
+                    name: "替换定额",
+                    icon: 'fa-sign-in',
+                    callback: function (key, opt) {
+                        let select = $('#stdRationLibSelect'), rationSelect = rationSheet.getSelections();
+                        let rationCode = rationSelect.length > 0 ? rationSheet.getText(rationSelect[0].row, 0) : '';
+                        if (rationCode !== '') {
+                            CommonAjax.postRationLib('/rationRepository/api/getRationItem', {user_id: userID, rationLibId: select.val(), code: rationCode}, function (data) {
+                                ProjectController.replaceRation(projectObj.project, projectObj.mainController, data);
+                            });
+                        }
+                    }
+                },
+            }
+        });
+    },
     rationChapterTreeSetting: {
         "emptyRows":0,
         "headRows":1,
@@ -195,6 +233,7 @@ $('#stdRationTab').bind('click', function () {
     rationLibObj.checkSpread();
     if (select[0].options.length === 0) {
         rationLibObj.loadStdRationLibs();
+        rationLibObj.loadStdRationContextMenu();
     };
 });
 $('#stdRationLibSelect').change(function () {

+ 7 - 0
web/building_saas/pm/js/pm_main.js

@@ -741,12 +741,19 @@ function AddTender() {
                 break;
             }
         }
+
+        let libs = null;
         for(let tmp of engineeringList) {
             if (tmp.engineering == engineering) {
                 engineering_id = tmp.engineering_id;
+                libs = tmp.lib;
                 break;
             }
         }
+        // 一个项目里面,这两个文件必须得有,而界面又没有像费率、单价文件那样给出可选项。所以这里给出提示。
+        if (!libs.artificial_lib)  throw '编办没有绑定人工系数标准文件';
+        if (!libs.program_lib)  throw '编办没有绑定计算程序标准文件';
+
         let engineeringName = $('#tender-engineering').children("option:selected").text();
 
         let callback = function() {