Explorar o código

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

TonyKang %!s(int64=6) %!d(string=hai) anos
pai
achega
39ea95836b

+ 1 - 1
Dockerfile

@@ -14,6 +14,6 @@ EXPOSE 2060
 
 ENV NODE_ENV=prod
 
-ENTRYPOINT babel-node server.js
+ENTRYPOINT babel-node --max-old-space-size=2048  server.js
 
 

+ 56 - 0
lib/rabbitmq/RabbitMQ.js

@@ -0,0 +1,56 @@
+/**
+ * Created by zhang on 2019/5/5.
+ */
+let amqp = require('amqplib');
+class RabbitMQ{
+    constructor(connect){
+        this.connect = connect;
+    }
+
+    static async connection(URL){
+        if(!RabbitMQ.instance){
+            RabbitMQ.instance =  new RabbitMQ(await amqp.connect(URL)) //'amqp://13726297388:123456@qa.smartcost.com.cn:5672'
+        }
+        return RabbitMQ.instance
+    }
+
+    static async sendMessage(queue,msg,durable=false){
+        if(RabbitMQ.instance){
+            let ch = await RabbitMQ.instance.connect.createChannel();
+            try {
+                await ch.assertQueue(queue, {durable: durable});
+                ch.sendToQueue(queue,Buffer.from(msg),{persistent: durable});
+                console.log(" Sent %s to :"+queue, msg);
+                ch.close();
+            }catch (e){
+                console.log(e);
+                ch.close();
+            }
+
+        }
+    }
+
+    static async receiveMessage(queue,callback,durable=false){
+        if(RabbitMQ.instance){
+            let ch = await RabbitMQ.instance.connect.createChannel();
+            try {
+                await ch.assertQueue(queue, {durable: durable});
+                ch.prefetch(1);
+                console.log(" [*] Waiting for messages in %s. To exit press CTRL+C", queue);
+                ch.consume(queue, function(msg) {
+                    console.log(" [x] Received %s", msg.content.toString());
+                    if(durable == true) ch.ack(msg);
+                    if(callback) callback(msg)
+                }, {
+                    noAck: !durable
+                });
+            }catch (e){
+                console.log(e);
+                ch.close();
+            }
+        }
+    }
+}
+
+export default RabbitMQ;
+

+ 27 - 21
logs/online_logs.js

@@ -10,28 +10,34 @@ import moment from "moment";
 let logs_model = mongoose.model("online_logs");
 
 async function saveOnlineTime(req) {
-    let interval_time = 10 * 60 *1000;
-    let start = req.session.online_start_time;
+    let online_times = 0;
     let end = + new Date();
-    if(start === undefined) return req.session.online_start_time ==end;
-    let online_times =  end - start;
-    //1秒内只记一次就好
-    if(online_times < 500) return;//如果间隔太短,则忽略
-    if(online_times > interval_time ){//如果间隔超过有效时长,则不累加这次时长,从头开始算
-        req.session.online_start_time = end;
-        return
-    }
-    if(!req.session.sessionUser||!req.session.sessionCompilation) return;
-    let dataString = moment(end).format('YYYY-MM-DD');
-    let condition = {userID:req.session.sessionUser.id,compilationID:req.session.sessionCompilation._id,dateString:dataString};
-    let record = await logs_model.findOne(condition);
-    if(record){ //如果找到,则累加
-        await logs_model.update(condition,{$inc:{'online_times' : online_times }});
-    }else {//如果没找到,则新增一条记录
-        condition["online_times"] = online_times;
-        let today = moment(dataString).toDate();
-        condition["dateTime"] = +today;
-        await logs_model.create(condition);
+    try {
+        let interval_time = 10 * 60 *1000;
+        let start = req.session.online_start_time;
+        if(start === undefined) return req.session.online_start_time ==end;
+        online_times =  end - start;
+        //1秒内只记一次就好
+        if(online_times < 500) return;//如果间隔太短,则忽略
+        if(online_times > interval_time ){//如果间隔超过有效时长,则不累加这次时长,从头开始算
+            req.session.online_start_time = end;
+            return
+        }
+        if(!req.session.sessionUser||!req.session.sessionCompilation) return;
+        let dataString = moment(end).format('YYYY-MM-DD');
+        let condition = {userID:req.session.sessionUser.id,compilationID:req.session.sessionCompilation._id,dateString:dataString};
+        let record = await logs_model.findOne(condition);
+        if(record){ //如果找到,则累加
+            await logs_model.update(condition,{$inc:{'online_times' : online_times }});
+        }else {//如果没找到,则新增一条记录
+            condition["online_times"] = online_times;
+            let today = moment(dataString).toDate();
+            condition["dateTime"] = +today;
+            await logs_model.create(condition);
+        }
+    }catch (e){
+        console.log("统计登录时间错误,online_times值:"+online_times);
+        console.log(e)
     }
     req.session.online_start_time = end;
 }

+ 4 - 1
modules/all_models/compleRation_ration.js

@@ -24,7 +24,10 @@ const compleRationAssItemSchema = new Schema({
     decimal: Number,
     carryBit: String,
     minValue: String,
-    maxValue: String
+    maxValue: String,
+    paramName:String,//参数名称
+    param:String,//参数
+    thirdRationCode:String//第三定额
 }, { _id: false });
 
 //定额安装增加费用

+ 5 - 1
modules/all_models/ration.js

@@ -17,7 +17,11 @@ var rationAssItemSchema = mongoose.Schema({
     carryBit: String,
     minValue: String,
     maxValue: String,
-    isAdjust:Number //0不调整,1调整
+    paramName:String,//参数名称
+    param:String,//参数
+    thirdRationCode:String,//第三定额
+    isAdjust:Number,//0不调整,1调整
+    groupList:[Schema.Types.Mixed]//当有分组的时候用这个
 }, { _id: false });
 
 // 定额、量价、工料机定额 合并存储

+ 4 - 1
modules/all_models/stdRation_ration.js

@@ -19,7 +19,10 @@ const rationAssItemSchema = new Schema({
     decimal: Number,
     carryBit: String,
     minValue: String,
-    maxValue: String
+    maxValue: String,
+    paramName:String,//参数名称
+    param:String,//参数
+    thirdRationCode:String//第三定额
 }, { _id: false });
 
 //定额安装增加费用

+ 40 - 16
modules/complementary_ration_lib/models/searchModel.js

@@ -15,27 +15,30 @@ class SearchDao{
     async getRationItem(userId, compilationId, rationRepIds, code, ID, callback){
         let ration = null;
         try{
+            let firstLib = rationRepIds.shift();//优先取第一个
+            if(rationRepIds.includes(firstLib)) {//去掉重复的库ID
+                rationRepIds.splice(rationRepIds.indexOf(firstLib), 1);
+            }
             if(rationRepIds.includes(compleRationLib)) {
                 rationRepIds.splice(rationRepIds.indexOf(compleRationLib), 1);
             }
-            let stdQuery = {rationRepId: {$in: rationRepIds}, code: code, $or: [{isDeleted: null}, {isDeleted: false}]};
-            if(ID){
-                stdQuery = {ID: ID, $or: [{isDeleted: null}, {isDeleted: false}]};
-            }
-            let stdRation = await stdRationModel.findOne(stdQuery);
-            if(isDef(stdRation)){
-                ration = stdRation._doc;
-                ration.type = 'std';
-            } else{
-                let compleQuery = {userId: userId, compilationId: compilationId, code: code, $or: [{deleteInfo: null}, {'deleteInfo.deleted': false}]};
+            if(firstLib == compleRationLib){//说明选中的是补充定额库
+                ration = await this.getCompleRation(userId,compilationId,code,ID);
+            }else {
+                firstLib = parseInt(firstLib);
+                let firstQuery = {rationRepId: firstLib, code: code, $or: [{isDeleted: null}, {isDeleted: false}]};
                 if(ID){
-                    compleQuery.ID = ID;
+                    firstQuery = {ID: ID, $or: [{isDeleted: null}, {isDeleted: false}]};
                 }
-                let compleRation = await compleRationModel.findOne(compleQuery);
-                if(isDef(compleRation)){
-                    ration = compleRation._doc;
-                    ration.type = 'complementary';
+                ration = await this.getStdRation(firstQuery);
+            }
+            if(ration == null){//选中的定额库或者默认的定额库中没有找到定额,才走常规的流程查找其它定额库
+                let stdQuery = {rationRepId: {$in: rationRepIds}, code: code, $or: [{isDeleted: null}, {isDeleted: false}]};
+                if(ID){
+                    stdQuery = {ID: ID, $or: [{isDeleted: null}, {isDeleted: false}]};
                 }
+                ration = await this.getStdRation(stdQuery);
+                if(ration == null) ration = await this.getCompleRation(userId,compilationId,code,ID);
             }
             if(isDef(ration)){
                 if (ration.type === 'std') {
@@ -61,7 +64,28 @@ class SearchDao{
         }
         return ration;
     }
-
+    async getCompleRation(userId,compilationId,code,ID){
+        let ration = null;
+        let compleQuery = {userId: userId, compilationId: compilationId, code: code, $or: [{deleteInfo: null}, {'deleteInfo.deleted': false}]};
+        if(ID){
+            compleQuery.ID = ID;
+        }
+        let compleRation = await compleRationModel.findOne(compleQuery);
+        if(isDef(compleRation)){
+            ration = compleRation._doc;
+            ration.type = 'complementary';
+        }
+        return ration
+    }
+    async getStdRation(query){
+        let ration = null;
+        let stdRation = await stdRationModel.findOne(query);
+        if(isDef(stdRation)){
+            ration = stdRation._doc;
+            ration.type = 'std';
+        }
+        return ration;
+    }
     //@param {Object}skip({std: Number, comple: Number})
     async findRation(userId, compilationId, rationRepId, keyword, skip, callback){
         //每次限制结果数

+ 17 - 2
modules/main/facade/ration_facade.js

@@ -594,13 +594,28 @@ async function setEmptyRation(projectID,rationID){
 function createRationAss(std) {
     let  rationAssList = [];//生成辅助定额
     if(std.hasOwnProperty('rationAssList')&&std.rationAssList.length>0){
-        for(let i=0;i<std.rationAssList.length;i++){
-            let ass = std.rationAssList[i];
+        let assGroup =  _.groupBy(std.rationAssList,'name');
+        for(let key in assGroup){
+            let assList = assGroup[key];
+            let ass = assList[0];
             ass._doc.actualValue = ass.stdValue;
             ass._doc.isAdjust = 0;
             if(_.isString(ass._doc.assistCode)) ass._doc.assistCode = ass._doc.assistCode.replace("\n","");
+            if(_.isString(ass._doc.thirdRationCode)) ass._doc.thirdRationCode = ass._doc.thirdRationCode.replace("\n","");
+            if(assList.length > 1){
+                ass._doc.groupList = JSON.parse(JSON.stringify(assList))  ;
+                ass._doc.maxValue = assList[assList.length-1]._doc.maxValue;
+            }
             rationAssList.push(ass);
         }
+      /*  for(let i=0;i<std.rationAssList.length;i++){
+            let ass = std.rationAssList[i];
+            ass._doc.actualValue = ass.stdValue;
+            ass._doc.isAdjust = 0;
+            if(_.isString(ass._doc.assistCode)) ass._doc.assistCode = ass._doc.assistCode.replace("\n","");
+            if(_.isString(ass._doc.thirdRationCode)) ass._doc.thirdRationCode = ass._doc.thirdRationCode.replace("\n","");
+            rationAssList.push(ass);
+        }*/
     }
     return rationAssList;
 }

+ 54 - 6
modules/ration_glj/facade/glj_calculate_facade.js

@@ -56,14 +56,30 @@ async function calculateQuantity(query,noNeedCal=null,refreshRationName = false)
              return null;
          }
          if(impactRation._doc.hasOwnProperty("rationAssList")&&impactRation.rationAssList.length>0){
+             prepareAss(impactRation.rationAssList);
+             let temTimes = [];
+             let thirdRationCodes=[];
              for(let i=0;i<impactRation.rationAssList.length;i++){
                  let times = calculateTimes(impactRation.rationAssList[i]);
                  if(times!=0){
+                     let thirdRationCode = impactRation.rationAssList[i].thirdRationCode;
+                     if(thirdRationCode && thirdRationCode !=''){
+                         temTimes.push(times);
+                         thirdRationCodes.push(thirdRationCode)
+                     }
                      assRation = await  std_ration_lib_ration_items.findOne({rationRepId:impactRation.libID,code:impactRation.rationAssList[i].assistCode});
                      assList.push({times:times,assRation:assRation});
                      adjustState.push({index:stateSeq.ass,content:impactRation.rationAssList[i].name+" "+impactRation.rationAssList[i].actualValue+" : +"+impactRation.rationAssList[i].assistCode+"x"+times});
                  }
              }
+             if(temTimes.length == 2 &&thirdRationCodes[0] == thirdRationCodes[1] ){ //说明有第三定额
+                 let times_t = temTimes[0] * temTimes[1];
+                 let tration =  await  std_ration_lib_ration_items.findOne({rationRepId:impactRation.libID,code:thirdRationCodes[0]});
+                 if(tration){
+                     assList.push({times:times_t,assRation:tration});
+                     adjustState.push({index:stateSeq.ass,content:"+"+thirdRationCodes[0]+"x"+times_t});
+                 }
+             }
          }
          for(let glj of gljList){//先把混凝土,砂浆,配合比有自定义消耗的挑出来
              if(gljUtil.isConcreteType(glj.type)) await getMixRatioMap(glj,gljList,coeList,assList,mixRatioMap);
@@ -96,12 +112,26 @@ async function calculateQuantity(query,noNeedCal=null,refreshRationName = false)
 
 function generateRationName(ration,gljList) {
     let caption = ration.caption ? ration.caption:ration.name;
-    if(ration.rationAssList && ration.rationAssList.length > 0){
-        let ass = ration.rationAssList[0];
-        if( ass.isAdjust == 1 && ass.actualValue != null && ass.actualValue != undefined ){
-            caption =  caption.replace('%s',ass.actualValue);
-        }else {
-            caption =  caption.replace('%s',ass.stdValue);//没勾选的时候要恢复成标准值
+    let replaceList = [];
+    if(ration.rationAssList && ration.rationAssList.length > 0){//这里要处理第三定额和多辅助定额的情况
+        let isThird = ration.rationAssList.length == 2 && ration.rationAssList[0].thirdRationCode&&ration.rationAssList[0].thirdRationCode!='';//说明有第三定额的情况
+        let adjustMatch = "",notAdjust="";
+        for(let ass of ration.rationAssList){
+            let tem = "";
+            if( ass.isAdjust == 1 && ass.actualValue != null && ass.actualValue != undefined ){
+                tem = ass.actualValue;
+                adjustMatch = tem;
+            }else {
+                tem = ass.stdValue;
+                notAdjust = tem;
+            }
+            if(isThird) replaceList.push(tem);
+        }
+        if(replaceList.length == 0){
+            adjustMatch!=""?replaceList.push(adjustMatch):replaceList.push(notAdjust);
+        }
+        for(let r of replaceList){
+            caption =  caption.replace('%s',r);
         }
     }
     let reNameList = [];
@@ -348,6 +378,22 @@ function getContent(coes) {
 
 }
 
+function prepareAss(assList) {//处理辅助定额,支持多个辅助定额的情况
+    for(let a of assList){
+        if(a.groupList && a.groupList.length > 1){//组里有多个定额的情况
+            let newList = _.sortByAll(a.groupList,['param']);//先按参数排序
+            for(let n of newList){
+                if(a.actualValue > n.stdValue && a.actualValue <= parseFloat(n.param)){//落在中间,则用组里的这条定额
+                    a._doc.param = n.param;
+                    a._doc.paramName = n.paramName;
+                    a._doc.assistCode = n.assistCode;
+                    break;
+                }
+            }
+        }
+    }
+}
+
 function calculateTimes(ass){
     if(ass.isAdjust == 0) return 0;//打勾辅助定额才计算
     let times =(ass.actualValue-ass.stdValue)/ass.stepValue;
@@ -360,6 +406,8 @@ function calculateTimes(ass){
         times = _.round(times,ass.decimal);
     }else if (ass.carryBit=='进一'){
         times =_.ceil(times,ass.decimal);
+    }else if(ass.carryBit == '舍一'){
+        times = _.floor(times,ass.decimal);
     }
     if(r){
         times=times*-1;

+ 1 - 1
modules/users/controllers/boot_controller.js

@@ -55,4 +55,4 @@ class BootController extends BaseController {
     }
 
 }
-export default BootController;
+export default BootController;

+ 1 - 0
modules/users/controllers/login_controller.js

@@ -99,6 +99,7 @@ class LoginController {
                     request.session.sessionCompilation = compilationData;
                     if(request.session.sessionUser.latest_used !== preferenceSetting.select_version) await userModel.updateLatestUsed(request.session.sessionUser.id,preferenceSetting.select_version);
                 }
+                request.session.online_start_time = +new Date();
                 console.log(`${request.session.sessionUser.real_name}--id:${request.session.sessionUser.id}--登录了系统`);
                 if (preferenceSetting.login_ask === 1 || preferenceSetting.select_version === '') {
                     let renderData = {

+ 23 - 0
public/cipher.js

@@ -0,0 +1,23 @@
+/**
+ * Created by zhang on 2019/5/10.
+ */
+let crypto = require('crypto');
+module.exports ={
+    aesEncrypt:aesEncrypt,
+    aesDecrypt:aesDecrypt
+};
+
+
+function aesEncrypt(data, key = 'SmartCost') {
+    const cipher = crypto.createCipher('aes192', key);
+    var crypted = cipher.update(data, 'utf8', 'hex');
+    crypted += cipher.final('hex');
+    return crypted;
+}
+
+function aesDecrypt(encrypted, key= 'SmartCost') {
+    const decipher = crypto.createDecipher('aes192', key);
+    var decrypted = decipher.update(encrypted, 'hex', 'utf8');
+    decrypted += decipher.final('utf8');
+    return decrypted;
+}

+ 2 - 2
public/web/slideResize.js

@@ -92,7 +92,7 @@ const SlideResize = (function() {
                         callback();
                         mouseMoveCount = 0;
                     }
-                }, 20);
+                }, 30);
                /* mouseMoveCount += Math.abs(moveSize);
                 if (mouseMoveCount > triggerCBSize && callback) {
                     callback();
@@ -185,7 +185,7 @@ const SlideResize = (function() {
                         callback();
                         mouseMoveCount = 0;
                     }
-                }, 20);
+                }, 30);
                 /*if (mouseMoveCount > triggerCBSize && callback) {
                     callback();
                     mouseMoveCount = 0;

+ 37 - 20
web/building_saas/complementary_glj_lib/js/glj.js

@@ -25,6 +25,10 @@ $(document).ready(function () {
     rightElesObj.left = $('#midContent');
     rightElesObj.right = $('#rightContent');
     SlideResize.horizontalSlide(rightElesObj, {min: 200, max: `$('#dataRow').width() - $('#leftContent').width() - 200`}, function () {
+        let resizeRate = 500 / $('#midContent').width(),
+            sheetRate = 100 - resizeRate;
+        $('#leftResize').css('width', `${resizeRate}%`);
+        $('#GLJListSheet').css('width', `${sheetRate}%`);
         refreshALlWorkBook();
     });
 });
@@ -154,6 +158,10 @@ let repositoryGljObj = {
             }
         });
     },
+    //获取工料机类型大类
+    getParentType: function (type) {
+        return parseInt(type.toString()[0]);
+    },
     getGljTree: function(gljLibId, callback) {
         let me = this;
         CommonAjax.post('complementartGlj/api/getGljTree', {gljLibId: gljLibId}, function (rstData) {
@@ -390,26 +398,35 @@ let repositoryGljObj = {
         } else{
             me.currentGlj = null;
         }
-        //组成物表能编辑则显示,否则隐藏该工作表
-        let rightWidth = getLocalCache('compleGLjrightContentWidth') || '25%';
-        rightWidth = rightWidth.replace('%', '');
-        let curMidWidth = $('#midContent')[0].style.width.replace('%', ''),
-            curRightWidth = $('#rightContent')[0].style.width.replace('%', '');
-        if (componentCanEdit && curRightWidth === '0') {
-            curMidWidth = parseFloat(curMidWidth) - parseFloat(rightWidth);
-            $('#midContent').css('width', `${curMidWidth}%`);
-            $('#rightContent').css('width', `${rightWidth}%`);
-        } else if(!componentCanEdit && curRightWidth !== '0') {
-            curMidWidth = parseFloat(curMidWidth) + parseFloat(rightWidth);
-            $('#midContent').css('width', `${curMidWidth}%`);
-            $('#rightContent').css('width', `0%`);
-        }
         //减少触发
         if (me.preComponentCanEdit !== componentCanEdit) {
+            me.spreadControl(componentCanEdit);
             refreshALlWorkBook();
         }
         me.preComponentCanEdit = componentCanEdit;
     },
+    //组成物表能编辑则显示,否则隐藏该工作表
+    spreadControl: function (showComponent) {
+        let leftWidth = getLocalCache('compleGLjleftContentWidth') || '50%',
+            midWidth = getLocalCache('compleGLjmidContentWidth') || '25%',
+            rightWidth = getLocalCache('compleGLjrightContentWidth') || '25%';
+        [leftWidth, midWidth, rightWidth] = [leftWidth, midWidth, rightWidth].map((v) => parseFloat(v.replace('%', '')));
+        let curMidWidth = parseFloat($('#midContent')[0].style.width.replace('%', '')),
+            curRightWidth = parseFloat($('#rightContent')[0].style.width.replace('%', ''));
+        if (showComponent) {
+            if (leftWidth + midWidth + rightWidth > 100) {
+                leftWidth = 50;
+                midWidth = rightWidth = 25;
+            }
+        } else {
+            midWidth = curMidWidth + curRightWidth;
+            rightWidth = 0;
+            leftWidth = 100 - midWidth;
+        }
+        $('#leftContent').css('width', `${leftWidth}%`);
+        $('#midContent').css('width', `${midWidth}%`);
+        $('#rightContent').css('width', `${rightWidth}%`);
+    },
     onEnterCell: function (sender, args) {
         let me = repositoryGljObj;
         args.sheet.repaint();
@@ -496,7 +513,7 @@ let repositoryGljObj = {
         if(args.row < me.currentCache.length){
             me.currentGlj = me.currentCache[args.row];
             //费率数据列只有普通材料能用,可添加组成物的人材机,基价只读
-            if (dataCode === 'code'|| (me.feeDataCode.includes(dataCode) && me.currentGlj.gljType !== 201) ||
+            if (dataCode === 'code'|| (me.feeDataCode.includes(dataCode) && me.getParentType(me.currentGlj.gljType) !== 2) ||
                 (dataCode === 'basePrice' && allowComponent.includes(me.currentGlj.gljType)) ||
                 dataCode === 'isComplementary'){
                 args.cancel = true;
@@ -529,7 +546,7 @@ let repositoryGljObj = {
                                 me.currentGlj.component = [];
                             }
                             //工料机类型不为普通材料时,情况费率数据
-                            if (me.currentEditingGlj.gljType === 201 && rObj.gljType !== 201) {
+                            if (me.getParentType(me.currentEditingGlj.gljType) === 2 && me.getParentType(rObj.gljType) !== 2) {
                                 for (let feeCode of me.feeDataCode) {
                                     if (me.currentEditingGlj[feeCode]) {
                                         rObj[feeCode] = null;
@@ -831,7 +848,7 @@ let repositoryGljObj = {
                     pasteObj.gljType = me.distTypeTree.comboDatas[i].value;
                     isExsit = true;
                     reCalBasePrc = true;
-                    if (pasteObj.gljType !== 201 && tempObj.gljType === 201) {
+                    if (me.getParentType(pasteObj.gljType) !== 2 && me.getParentType(tempObj.gljType) === 2) {
                         for (let feeCode of me.feeDataCode) {
                             tempObj[feeCode] = null;
                         }
@@ -860,8 +877,8 @@ let repositoryGljObj = {
         }
         for (let feeCode of me.feeDataCode) {
             if (typeof pasteObj[feeCode] !== 'undefined' && !isNaN(pasteObj[feeCode])) {
-                if ((typeof pasteObj.gljType !== 'undefined' && pasteObj.gljType === 201) ||
-                    (tempObj.gljType && tempObj.gljType === 201)) {
+                if ((typeof pasteObj.gljType !== 'undefined' && me.getParentType(pasteObj.gljType) === 2) ||
+                    (tempObj.gljType && me.getParentType(tempObj.gljType) === 2)) {
                     tempObj[feeCode] = pasteObj[feeCode];
                 } else {
                     isValid = false;
@@ -934,7 +951,7 @@ let repositoryGljObj = {
 
         }
         for (let feeCode of me.feeDataCode) {
-            if (typeof pasteObj[feeCode] !== 'undefined' && (isNaN(pasteObj[feeCode]) || pasteObj.gljType !== 201)) {
+            if (typeof pasteObj[feeCode] !== 'undefined' && (isNaN(pasteObj[feeCode]) || me.getParentType(pasteObj.gljType) !== 2)) {
                 return false;
             }
         }

+ 3 - 0
web/building_saas/main/js/models/ration.js

@@ -392,6 +392,9 @@ var Ration = {
             if(libIDs == null){
                 return;
             }
+            //设置定额库的优先级,默认先取选中的定额库,如果没有再取default定额库
+            let selectedLib = sessionStorage.getItem("stdRationLib");
+            selectedLib&&selectedLib!='undefined'?libIDs.unshift(selectedLib):libIDs.unshift(defaultLibID);
             for(let r of recodes){
                 let needInstall = false;
                 if(projectObj.project.isInstall()) {//如果是安装工程,要看需不需要生成安装增加费

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

@@ -620,7 +620,7 @@ var projectObj = {
                 libID = rationLibObj.compleRationLibId;
             }
             if(!rationLibObj.tree){
-                sessionStorage.setItem('stdRationLib', libID);
+                if(isDef(libID)) sessionStorage.setItem('stdRationLib', libID);
                 rationLibObj.doAfterGetRationTree = function () {
                     this.locateAtRation(libID, code);
                     this.doAfterGetRationTree = null;
@@ -2315,7 +2315,6 @@ $('#property_default').click(function () {
     });
 });
 $('#property_ok').click(function () {
-    debugger;
     let project = projectObj.project,
         projectID = project.ID(),
 

+ 25 - 6
web/building_saas/main/js/views/std_billsGuidance_lib.js

@@ -138,6 +138,20 @@ const billsGuidance = (function () {
             row = sheet.getActiveColumnIndex(),
             col = sheet.getActiveColumnIndex();
         if (compareData.postData.length > 0) {
+            //如果插入的是固定清单,则需要判断该固定清单在造价书中是否已存在,造价书中不可存在相同的固定清单
+            let fixedDatas = compareData.postData.filter((data) =>
+            data.updateType === updateType.create && Array.isArray(data.updateData.flags));
+            if (fixedDatas.length > 0) {
+                //提示已存在此固定清单并且定位
+                let firstFixed = fixedDatas[0].updateData;
+                let existNode = projectObj.project.mainTree.items.find((node) =>
+                node.data && node.data.flagsIndex && node.data.flagsIndex.fixed && node.data.flagsIndex.fixed.flag === firstFixed.flags[0].flag);
+                if (existNode) {
+                    alert(`固定清单<strong>“${firstFixed.name}”</strong>已被第${existNode.serialNo() + 1}行清单占用。`);
+                    locateAtSpread(sheet, existNode.serialNo(), col);
+                    return;
+                }
+            }
             isInserting = true;
             CommonAjax.post('/bills/insertBills', {postData: compareData.postData}, function () {
                 //插入
@@ -163,9 +177,7 @@ const billsGuidance = (function () {
                     //该清单节点在主树的位置
                     row = projectObj.project.mainTree.nodes[projectObj.project.mainTree.prefix + compareData.locateNode.data.ID].serialNo();
                 }
-                sheet.setSelection(row, col, 1, 1);
-                projectObj.mainController.setTreeSelected(projectObj.mainController.tree.items[row]);//触发树节点选中事件
-                sheet.showRow(row, GC.Spread.Sheets.VerticalPosition.center);
+                locateAtSpread(sheet, row, col);
                 isInserting = false;
             }, function () {
                 isInserting = false;
@@ -173,11 +185,14 @@ const billsGuidance = (function () {
         } else if (compareData.locateNode) {
             //该清单节点在主树的位置
             row = projectObj.project.mainTree.nodes[projectObj.project.mainTree.prefix + compareData.locateNode.data.ID].serialNo();
-            sheet.setSelection(row, col, 1, 1);
-            projectObj.mainController.setTreeSelected(projectObj.mainController.tree.items[row]);//触发树节点选中事件
-            sheet.showRow(row, GC.Spread.Sheets.VerticalPosition.center);
+            locateAtSpread(sheet, row, col);
         }
     }
+    function locateAtSpread(sheet, row, col) {
+        sheet.setSelection(row, col, 1, 1);
+        projectObj.mainController.setTreeSelected(projectObj.mainController.tree.items[row]);//触发树节点选中事件
+        sheet.showRow(row, GC.Spread.Sheets.VerticalPosition.center);
+    }
     /*
     *
     * 1.选中的树结构(清单规则选中的节点及其所有父项)与主树对比(主树中节点“编码-名称-单位”与选中树~组合相同视为同一节点),
@@ -336,6 +351,10 @@ const billsGuidance = (function () {
             stdData.comments = stdNode.data.comments;
             stdData.programID = stdNode.data.engineering;
             stdData.billsLibId = stdNode.data.billsLibId;
+            if (stdNode.data.fixedFlag) {
+                stdData.flags = [{flag : stdNode.data.fixedFlag, fieldName : 'fixed'}];
+                stdData.flagsIndex = {fixed: {fieldName: 'fixed', flag: stdNode.data.fixedFlag}};   //前端用
+            }
             return stdData;
         }
         //从同层节点中获取更新数据

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

@@ -343,6 +343,7 @@ var rationLibObj = {
         me.loadSectionRations(sectionNode && sectionNode.children.length === 0 ? sectionNode.data.ID : null);
     },
     locateAtRation: function(libID, code){
+        if(!isDef(libID)) return;
         let me = rationLibObj;
         if ($('#rationSearchResult').is(':visible')) {
             $('#rationSearchResult a').click();