Просмотр исходного кода

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

TonyKang 7 лет назад
Родитель
Сommit
e09897e635

+ 1 - 1
config/gulpConfig.js

@@ -7,6 +7,7 @@ module.exports = {
     common_jspaths:[
         'lib/jquery/jquery-3.2.1.min.js',
         'lib/popper/popper.min.js',
+        'lib/jquery-ui/jquery-ui.min.js',
         'lib/bootstrap/bootstrap.min.js',
         'web/building_saas/js/*.js',
         'public/web/scMathUtil.js',
@@ -39,7 +40,6 @@ module.exports = {
     main_jspaths:[
         'lib/JSExpressionEval_src/*.js',
         '!lib/JSExpressionEval_src/JsHashMap.js',
-        'lib/jquery-ui/jquery-ui.min.js',
         'lib/jquery-ui/jquery-ui-datepickerCN.js',
         'lib/jquery-contextmenu/*.js',
         'lib/lodash/lodash.js',

+ 8 - 2
modules/main/routes/main_route.js

@@ -4,16 +4,22 @@
 
 
 import BaseController from "../../common/base/base_controller";
+const projectModel = require("../../pm/models/project_model");
 module.exports =function (app) {
     const baseController = new BaseController();
     app.get('/main', baseController.init, function(req, res) {
         let pm = require('../../pm/controllers/pm_controller');
-        pm.checkProjectRight(req.session.sessionUser.ssoId, req.query.project, function (hasRight) {
+
+        pm.checkProjectRight(req.session.sessionUser.ssoId, req.query.project, async function (hasRight) {
             if (hasRight) {
+                // 获取项目信息
+                const projectId = req.query.project;
+                const projectData = await projectModel.project.getProject(projectId);
                 res.render('building_saas/main/html/main.html',
                     {
                         userAccount: req.session.userAccount,
-                        userID: req.session.sessionUser.ssoId
+                        userID: req.session.sessionUser.ssoId,
+                        projectData: projectData,
                     });
             } else {
                 res.redirect('/pm');

+ 14 - 0
public/web/scMathUtil.js

@@ -7,14 +7,28 @@ let scMathUtil = {
         let lFactor = Math.pow(10, digit);
         let fOffSet = 0.5;
         let sign = '';
+        // 处理符号
         if (num < 0){
             sign = '-';
             num = Math.abs(num);
         }
+        // 计算
         let result = Math.floor((num / lFactor) + fOffSet).toString();
         let iLength = result.length;
+        // 因为数值被转为整数计算,当目标位数在小数点后,且数值小于0,需要补齐前面的位数
+        if (iLength < -digit){
+            result = this.zeroString(-digit) + result;
+        }
+        // 当目标位数在小数点前,需要补齐后面的位数
+        else if ((digit > 0) && (iLength < digit)){
+            result = result + this.zeroString(digit);
+        }
+        iLength = result.length;
+        // 获得小数点前的数字
         let r1 = result.substring(0, iLength + digit);
+        // 获得小数点后的数字
         let r2 = result.substring(iLength + digit, iLength);
+        // 拼出完整结果
         return Number(sign + r1 + '.' + r2);
     },
     floatToBin: function(num) {

+ 28 - 28
web/building_saas/main/html/main.html

@@ -5,7 +5,7 @@
     <meta charset="utf-8">
     <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
     <meta http-equiv="x-ua-compatible" content="ie=edge">
-    <title>造价书-纵横云造价</title>
+    <title><%= projectData.name !== undefined ? projectData.name : '造价书' %>-纵横云造价</title>
     <!-- inject:css -->
     <link rel="stylesheet" href="/lib/bootstrap/css/bootstrap.min.css">
     <link rel="stylesheet" href="/web/building_saas/css/main.css">
@@ -55,7 +55,7 @@
               <div class="toolsbar px-1 d-flex justify-content-between">
                   <div class="tools-btn btn-group align-top">
                     <a href="" class="btn btn-sm" title="复制"><i class="fa fa-files-o" aria-hidden="true"></i></a>
-                    <a href="" class="btn btn-sm" title="切"><i class="fa fa-scissors" aria-hidden="true"></i></a>
+                    <a href="" class="btn btn-sm" title="切"><i class="fa fa-scissors" aria-hidden="true"></i></a>
                     <a href="" class="btn btn-sm" title="粘贴"><i class="fa fa-clipboard" aria-hidden="true"></i></a>
                     <a href="javascript:void(0)" class="btn btn-sm" id="insert" title="插入"><i class="fa fa-sign-in" aria-hidden="true"></i></a>
                     <a href="javascript:void(0)" class="btn btn-sm" id="delete" title="删除"><i class="fa fa-remove" aria-hidden="true"></i></a>
@@ -128,57 +128,57 @@
                                               <p style="text-align: center">添加规则</p>
                                               <p>
                                                   <label class="title">添加位置:</label>
-                                                  <select name="" id="add-position">
-                                                      <option value="">添加到项目特征列</option>
-                                                      <option value="">添加到清单名称列</option>
-                                                      <option value="">添加到工作内容列</option>
-                                                      <option value="">分别添加到对应列</option>
+                                                  <select id="add-position">
+                                                      <option value="1" selected="selected">添加到项目特征列</option>
+                                                      <option value="2">添加到清单名称列</option>
+                                                      <option value="3">添加到工作内容列</option>
+                                                      <option value="4">分别添加到对应列</option>
                                                   </select>
                                               </p>
                                               <p>
                                                   <label class="title">添加内容:</label>
-                                                  <select name="" id="add-content">
+                                                  <select id="add-content">
                                                       <option value="">无</option>
-                                                      <option value="">项目特征+工作内容</option>
-                                                      <option value="">工作内容+项目特征</option>
-                                                      <option value="">项目特征</option>
-                                                      <option value="">工作内容</option>
-                                                      <option value="">定额子目</option>
+                                                      <option value="1" selected="selected">项目特征+工作内容</option>
+                                                      <option value="2">工作内容+项目特征</option>
+                                                      <option value="3">项目特征</option>
+                                                      <option value="4">工作内容</option>
+                                                      <option value="5">定额子目</option>
                                                   </select>
                                               </p>
                                               <p>
                                                   <label class="title">显示格式:</label>
-                                                  <select name="" id="format">
-                                                      <option value="">换行分隔</option>
-                                                      <option value="">逗号分隔</option>
-                                                      <option value="">括号分隔</option>
+                                                  <select id="display-format">
+                                                      <option value="1" selected="selected">换行分隔</option>
+                                                      <option value="2">逗号分隔</option>
+                                                      <option value="3">括号分隔</option>
                                                   </select>
                                               </p>
                                               <p>
                                                   <label class="title">特征生成方式:</label>
-                                                  <select name="" id="">
-                                                      <option value="">特征值</option>
-                                                      <option value="">特征:特征值</option>
+                                                  <select id="character-format">
+                                                      <option value="1">特征值</option>
+                                                      <option value="2" selected="selected">特征:特征值</option>
                                                   </select>
                                               </p>
                                               <p>
                                                   <label class="title">子目生成方式:</label>
-                                                  <select name="" id="">
-                                                      <option value="">编号+定额名称</option>
-                                                      <option value="">序号+定额名称</option>
+                                                  <select id="child-display-format">
+                                                      <option value="1" selected="selected">编号+定额名称</option>
+                                                      <option value="2">序号+定额名称</option>
                                                   </select>
                                               </p>
                                               <p>
                                                   <label class="title">序号格式:</label>
-                                                  <select name="" id="">
+                                                  <select id="serial-type" disabled="disabled">
                                                       <option value="">无</option>
-                                                      <option value="">1.</option>
-                                                      <option value="">a.</option>
-                                                      <option value="">A.</option>
+                                                      <option value="1" selected="selected">1.</option>
+                                                      <option value="2">a.</option>
+                                                      <option value="3">A.</option>
                                                   </select>
                                               </p>
                                               <p style="text-align: center">
-                                                  <button class="btn btn-primary btn-sm" type="button">应用到选中清单</button>
+                                                  <button class="btn btn-primary btn-sm" type="button" id="use-to-current">应用到选中清单</button>
                                                   <button class="btn btn-primary btn-sm" type="button">应用到所有清单</button>
                                               </p>
                                           </div>

+ 1 - 2
web/building_saas/main/js/controllers/project_controller.js

@@ -68,8 +68,7 @@ ProjectController = {
 
                 newNode = project.mainTree.insert(selected.getID(), selected.tree.rootID());
             }
-        }
-        else if (selected.sourceType === project.Ration.getSourceType()) {
+        } else if (selected.sourceType === project.Ration.getSourceType()) {
             if (std) {
                 newSource = project.Ration.insertStdRation(selected.source[project.masterField.ration], selected.source, std);
                 project.ration_glj.addRationGLJ(newSource,std);

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

@@ -407,6 +407,7 @@ class CalcProgram {
 
     loadData (datas) {
         this.datas = datas;
+        this.compileAllTemps();
     };
 
     doAfterUpdate (err, data) {

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

@@ -108,6 +108,13 @@ const volumePriceMaps = {
     5: "量设"
 };
 
+const gljTypeMap = {
+   201:'材',
+   4:'主',
+   5:'设'
+}
+
+
 const rationType = {
     ration: 1,
     volumePrice: 2,

+ 16 - 0
web/building_saas/main/js/models/project.js

@@ -48,6 +48,7 @@ var PROJECT = {
                     me.modules[module].setMaxID(counter[module]);
                 }
             }
+
             me._project.loadMainTree();
             //me.test(result[0].data[0]);
             callback(0);
@@ -123,6 +124,17 @@ var PROJECT = {
 
         project.prototype.loadMainTree = function () {
             var that = this;
+            let loadRationGLJNode = function (cacheNode) {
+                var newNode, bj = that.ration_glj.getMainAndEquGLJ(cacheNode.source.ID), i;
+                for(i=0;i<bj.length;i++){
+                    that.ration_glj.transferToNodeData(bj[i]);
+                    newNode = that.mainTree.addNode(cacheNode);
+                    newNode.source = bj[i];
+                    newNode.sourceType = that.ration_glj.getSourceType();
+                    newNode.data = bj[i];
+                }
+            };
+
             var loadRationNode = function (rations, cacheNode) {
                 var newNode, br = that.Ration.getBillsSortRation(cacheNode.source.getID()), i;
                 for (i = 0; i < br.length; i++) {
@@ -130,6 +142,9 @@ var PROJECT = {
                     newNode.source = br[i];
                     newNode.sourceType = that.Ration.getSourceType();
                     newNode.data = br[i];
+                    if(projectInfoObj.projectInfo.property.displaySetting.disPlayMainMateria==true){
+                        loadRationGLJNode(newNode);
+                    }
                 }
             };
 /*            let loadVolumePriceNode = function (cacheNode) {
@@ -141,6 +156,7 @@ var PROJECT = {
                     newNode.data = v;
                 }
             };*/
+
             var loadIdTreeNode = function (nodes, parent) {
                 var newNode, i;
                 for (i = 0; i < nodes.length; i++) {

+ 1 - 0
web/building_saas/main/js/models/project_glj.js

@@ -235,6 +235,7 @@ 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 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);

+ 10 - 6
web/building_saas/main/js/models/quantity_detail.js

@@ -41,7 +41,6 @@ var quantity_detail = {
             }
         };
         quantity_detail.prototype.refreshAfterSave=function(data){
-            console.log(data);
             var me = this;
             if(data.hasOwnProperty('resort')){
                 this.resortData(data.doc,1);
@@ -108,10 +107,10 @@ var quantity_detail = {
         quantity_detail.prototype.refreshSheetData=function () {
             gljOprObj.showQuantityDetailData();
         };
-        quantity_detail.prototype.saveQuantityDetail=function (args,dataCode) {
+        quantity_detail.prototype.saveQuantityDetail=function (args,dataCode,selected) {
             var me = this;
             var doc={};
-            var selected = projectObj.project.mainTree.selected;
+            var selected = selected?selected:projectObj.project.mainTree.selected;
             if(selected.sourceType==ModuleNames.ration){
                 doc.rationID=selected.data.ID;
             }
@@ -123,6 +122,7 @@ var quantity_detail = {
             doc.seq=args.row;
             if(dataCode=='regex'){
                 if(!this.regexChecking(args.editingText)||!this.referenceChecking(args.editingText,args.row,doc)){
+                    gljOprObj.showQuantityDetailData();
                     return;
                 }
                 doc.refreshQuantity=true;
@@ -147,6 +147,8 @@ var quantity_detail = {
                 }else {
                     data.newRecord?me.refreshAfterSave(data.newRecord):me.refreshAfterSave(data);
                     data.node?gljOprObj.refreshTreeNode(data.node):"";
+                    //gljOprObj.detailSheet.setActiveCell(0,0);
+                    //gljOprObj.detailSheet.clearSelection();
                 }
                 $.bootstrapLoading.end();
             }
@@ -238,13 +240,13 @@ var quantity_detail = {
             let regExp = new RegExp(FindText, "g");
             return str.replace(regExp, RepText);
         };
-        quantity_detail.prototype.updateQuantityDetail=function (args,dataCode,recode) {
+        quantity_detail.prototype.updateQuantityDetail=function (args,dataCode,recode,selected) {
             var doc ={};
             var query={
                 ID:recode.ID,
                 projectID:recode.projectID
             };
-            var selected = projectObj.project.mainTree.selected;
+            var selected = selected?selected:projectObj.project.mainTree.selected;
             doc[dataCode]=args.editingText;
             if (dataCode == 'regex') {
                 if(recode.hasOwnProperty('rationID')){
@@ -256,7 +258,9 @@ var quantity_detail = {
                 if(!selected.data.hasOwnProperty('isFromDetail')||selected.data.isFromDetail==0){
                     var c = confirm("确定要使用工程量明细替换原工程量吗?");
                     if(!c){
-                        query.refreshQuantity=false;
+                        //query.refreshQuantity=false;
+                        this.cleanQuantityDetail(selected,true);
+                        return;
                     }
                 }
                 query.index = args.row;

+ 49 - 7
web/building_saas/main/js/models/ration_glj.js

@@ -112,6 +112,8 @@ var ration_glj = {
                 projectObj.project.ration_glj.datas = neRecodes;
             }
             gljOprObj.showRationGLJSheetData(true);
+            //add to mainTree;
+
             let node = project.mainTree.selected;
             project.calcProgram.calculate(node);
             project.calcProgram.saveNode(node);
@@ -278,14 +280,14 @@ var ration_glj = {
             updateData.push(newobj);
             return updateData;
         };
-        ration_glj.prototype.updateRationGLJByEdit=function (recode,updateField,newval) {
+        ration_glj.prototype.updateRationGLJByEdit=function (recode,updateField,newval,node) {
             var me=this;
             $.bootstrapLoading.start();
             var callback=function (data) {
                 let initShow = false;//是否需要表格初始化显示
                 if(updateField=='customQuantity'){
                     console.log(data);
-                    me.refreshAfterQuantityUpdate(data);
+                    me.refreshAfterQuantityUpdate(data,node);
                 }else {
                     var doc = data.doc;
                     for(var key in doc){
@@ -293,7 +295,7 @@ var ration_glj = {
                     }
                     console.log(data);
                     if(data.hasOwnProperty('adjustState')){//更新定额调整状态
-                        me.updateRationAdjustState(data.adjustState,recode.rationID);
+                        me.updateRationAdjustState(data.adjustState,recode.rationID,node);
                     }
                     if(recode.subList&&recode.subList.length>0){
                         initShow = true;
@@ -320,25 +322,33 @@ var ration_glj = {
             }
             var doc = {};
             doc[updateField]=newval;
+            if(updateField=="type"){
+                doc.shortName = gljTypeMap[newval];
+            }
             CommonAjax.post("/rationGlj/updateRationGLJByEdit",{query:query,doc:doc,priceInfo:priceInfo},callback,function (err) {
                 $.bootstrapLoading.end();
             });
         }
-        ration_glj.prototype.refreshAfterQuantityUpdate=function (data) {
+        ration_glj.prototype.refreshAfterQuantityUpdate=function (data,node) {
             var me=this;
             data.glj_result.forEach(function (item) {
                 me.refreshEachItme(item.doc,item.query);
             })
-            me.updateRationAdjustState(data.adjustState,data.rationID);
+            me.updateRationAdjustState(data.adjustState,data.rationID,node);
         };
-        ration_glj.prototype.updateRationAdjustState=function(adjustState,rationID){
+        ration_glj.prototype.updateRationAdjustState=function(adjustState,rationID,rnode){
+            var nodes=[];
             var node = _.find(projectObj.project.mainTree.items,function (n) {
                 return n.sourceType==ModuleNames.ration&&n.data.ID==rationID;
             })
             if(node){
                 node.data.adjustState=adjustState;
+                nodes.push(node)
             }
-            projectObj.mainController.refreshTreeNode([node]);
+            if(rnode){
+                nodes.push(rnode);
+            }
+            projectObj.mainController.refreshTreeNode(nodes);
         };
         ration_glj.prototype.getGLJData = function(cb){
             CommonAjax.get('/rationGlj/getGLJData', function (data) {
@@ -465,6 +475,38 @@ var ration_glj = {
                 $.bootstrapLoading.end();
             });
         };
+
+        ration_glj.prototype.getMainAndEquGLJ = function (rationID) {
+           var gljList = _.filter(this.datas,function (n) {
+              return n.rationID == rationID&&(n.type==gljType.MAIN_MATERIAL||n.type==gljType.EQUIPMENT)
+           });
+           return gljOprObj.combineWithProjectGlj(gljList);
+        };
+        ration_glj.prototype.transferToNodeData = function (data) {
+            data.subType = data.type;
+            data.marketUnitFee = data.marketPrice;
+        };
+        ration_glj.prototype.updateFromMainSpread=function (value,node,fieldName) {
+            console.log(fieldName);
+            console.log(value);
+            if(node.data[fieldName]===value){
+                return;
+            }
+            if(fieldName=="marketUnitFee"){
+
+            }else {
+                if(value!==undefined&&value!==null){
+                    if(fieldName=="subType"){
+                        node.data.subType = value;
+                        fieldName = "type";//转换成更新工料机类型
+                    }
+                    this.updateRationGLJByEdit(node.data,fieldName,value,node);
+                    return;
+                }
+            }
+           // node.data.subType = value;
+            projectObj.mainController.refreshTreeNode([node]);
+        };
         return new ration_glj(project);
     }
 };

+ 144 - 1
web/building_saas/main/js/views/character_content_view.js

@@ -751,5 +751,148 @@ let pageCCOprObj = {
                 projectObj.mainSpread.getActiveSheet().autoFitRow(activeCell.row);
             }
         });
-    }
+    },
+    /**
+     * 根据配置转换清单项目特征
+     *
+     * @param {Object} node - 选中的node节点
+     * @param {Object} setting - 设置
+     * @return {void}
+     */
+    buildCharacterBySetting: function(node, setting) {
+        let contentArray = [];
+        // 特征部分
+        const itemCharacter = node.data.itemCharacter;
+
+        if (itemCharacter === undefined || itemCharacter.length <= 0) {
+            return;
+        }
+        let characterArray = [];
+        for (const tmp of itemCharacter) {
+            if (tmp.eigenvalue === undefined || tmp.eigenvalue.length <= 0) {
+                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 itemJob = node.data.jobContent;
+        if (itemJob === undefined || itemJob.length <= 0) {
+            return;
+        }
+        let jobArray = [];
+        for (const tmp of itemJob) {
+            // 匹配设置的序号格式
+            const serialNo = this.formatSerialNumber(setting.serialType, tmp.serialNo);
+            jobArray.push(serialNo + tmp.content)
+        }
+
+        // 组合数据
+        let content = '';
+        switch (setting.addContent) {
+            case "1":
+                // 项目特征+工作内容
+                contentArray.push('[项目特征]');
+                contentArray.push.apply(contentArray, characterArray);
+                contentArray.push('[工作内容]');
+                contentArray.push.apply(contentArray, jobArray);
+                break;
+            case "2":
+                // 工作内容+项目特征
+                contentArray.push('[工作内容]');
+                contentArray.push.apply(contentArray, jobArray);
+                contentArray.push('[项目特征]');
+                contentArray.push.apply(contentArray, characterArray);
+                break;
+            case "3":
+                // 项目特征
+                contentArray.push(characterArray);
+                break;
+            case "4":
+                // 工作内容
+                contentArray.push(jobArray);
+                break;
+            case "5":
+                // 定额子目
+                break;
+        }
+        // 显示格式
+        switch (setting.displayFormat) {
+            case "1":
+                // 换行分隔
+                content = contentArray.join('\r\n');
+                break;
+            case "2":
+                // 逗号分隔
+                content = contentArray.join(',');
+                break;
+            case "3":
+                // 括号分隔
+                content = '(' + contentArray.join(',') + ')';
+                break;
+        }
+        // 添加到对应位置
+        switch (setting.position) {
+            case "1":
+                // 添加到项目特征列
+                node.data.itemCharacterText = content;
+                break;
+            case "2":
+                // 添加到清单名称列
+                node.data.name = content;
+                break;
+            case "3":
+                // 添加到工作内容列
+                node.data.jobContentText = content;
+                break;
+        }
+
+    },
+    /**
+     * 格式化序号格式
+     *
+     * @param {Number} type - 格式化的类型
+     * @param {String} serialNo - 待格式化的序号
+     * @return {String} - 返回格式化后的字符
+     */
+    formatSerialNumber: function(type, serialNo) {
+        const letter = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r',
+            's', 't', 'u', 'v', 'w', 'x', 'y', 'z'];
+        switch (type) {
+            case '1':
+                // 数字
+                serialNo = serialNo + '.';
+                break;
+            case '2':
+                // 英文字母(小写)
+                serialNo = letter[serialNo - 1] !== undefined ? letter[serialNo - 1] + '.' : '';
+                break;
+            case '3':
+                // 英文字母(大写)
+                serialNo = letter[serialNo - 1] !== undefined ? letter[serialNo - 1].toUpperCase() + '.' : '';
+                break;
+        }
+        return serialNo;
+    },
 }

+ 22 - 14
web/building_saas/main/js/views/glj_view.js

@@ -54,8 +54,8 @@ var gljOprObj = {
     assSetting:{
         header:[
             {headerName: "调整名称", headerWidth: 100, dataCode: "name", dataType: "String"},
-            {headerName: "定额值", headerWidth: 120, dataCode: "stdValue", dataType: "String"},
-            {headerName: "实际值", headerWidth: 120, dataCode: "actualValue", dataType: "String"}
+            {headerName: "定额值", headerWidth: 120, dataCode: "stdValue", hAlign: "right", dataType: "String"},
+            {headerName: "实际值", headerWidth: 120, dataCode: "actualValue", hAlign: "right", dataType: "String"}
         ],
         view:{
             lockColumns:[0,1]
@@ -170,8 +170,10 @@ var gljOprObj = {
         var me = this;
         me.detailSheet = sheet;
         sheetCommonObj.initSheet(me.detailSheet, me.detailSetting, 30);
+       // me.detailSheet.selectionUnit(0);//0 cell,1 row,2 col;
         sheet.name('quantity_detail');
         me.bindSheetEvent(sheet);
+
     },
     showCoeData:function(sheet,setting,datas){
         sheet.floatingObjects.remove("customerCoe");
@@ -229,12 +231,18 @@ var gljOprObj = {
         if(args.row==me.detailData.length&&args.editingText==null){
             return;
         }
-       if(args.row==me.detailData.length){
-           projectObj.project.quantity_detail.saveQuantityDetail(args,me.detailSetting.header[args.col].dataCode);
-       }
-        if(args.row<me.detailData.length){
-            projectObj.project.quantity_detail.updateQuantityDetail(args,me.detailSetting.header[args.col].dataCode,me.detailData[args.row]);
-        }
+        var selected = projectObj.project.mainTree.selected;//因为使用了延时方法,所以要先取得选中行;
+        var detailList = me.detailData;
+        args.editingText = args.editingText.replace(/(/g,"(");//替换中文左右括号;
+        args.editingText = args.editingText.replace(/)/g,")");
+        setTimeout(function () {//这里须用延时执行的办法,不然的弹窗确认窗口会和spreadjs 的事件有冲突,造成定额工料机数据不会根据树结点更新的问题
+            if(args.row==detailList.length){
+                projectObj.project.quantity_detail.saveQuantityDetail(args,me.detailSetting.header[args.col].dataCode,selected);
+            }
+            if(args.row<detailList.length){
+                projectObj.project.quantity_detail.updateQuantityDetail(args,me.detailSetting.header[args.col].dataCode,detailList[args.row],selected);
+            }
+        },100);
 
     },
     onEditGLJSheet:function(args){
@@ -348,7 +356,7 @@ var gljOprObj = {
         $('#manual').val(data.coes[1].amount);
         $('#material').val(data.coes[2].amount);
         $('#manchine').val(data.coes[3].amount);
-        $('#main').val(data.coes[4].amount);
+        $('#mainM').val(data.coes[4].amount);
         $('#equipment').val(data.coes[5].amount);
     },
     onInputChange(id,name){
@@ -364,7 +372,7 @@ var gljOprObj = {
                 $('#manual').val(newValue);
                 $('#material').val(newValue);
                 $('#manchine').val(newValue);
-                $('#main').val(newValue);
+                $('#mainM').val(newValue);
                 $('#equipment').val(newValue);
             }else {
                 $('#'+id).val(newValue);
@@ -384,7 +392,7 @@ var gljOprObj = {
         var manual=$('#manual').val();
         var material = $('#material').val();
         var manchine= $('#manchine').val();
-        var main = $('#main').val();
+        var mainM = $('#mainM').val();
         var equipment=$('#equipment').val();
         if(coe_ration!=data.coes[0].amount){
             result.isNeed =true;
@@ -402,9 +410,9 @@ var gljOprObj = {
             result.isNeed =true;
             data.coes[3].amount =manchine;
         }
-        if(main!=data.coes[4].amount){
+        if(mainM!=data.coes[4].amount){
             result.isNeed =true;
-            data.coes[4].amount =main;
+            data.coes[4].amount =mainM;
         }
         if(equipment!=data.coes[5].amount){
             result.isNeed =true;
@@ -495,7 +503,7 @@ var gljOprObj = {
         newString += this.getOneRow('人工',1,'manual');
         newString += this.getOneRow('材料',2,'material');
         newString += this.getOneRow('机械',3,'manchine');
-        newString += this.getOneRow('主材',4,'main');
+        newString += this.getOneRow('主材',4,'mainM');
         newString += this.getOneRow('设备',5,'equipment');
         newString +="</table></form>";
 

+ 10 - 4
web/building_saas/main/js/views/main_tree_col.js

@@ -18,7 +18,7 @@ let MainTreeCol = {
                     return '工料机';     // 这里明细值等张伟城确定
                 }
             } else if (node.sourceType === projectObj.project.ration_glj.getSourceType()) {
-                return '主';
+                return gljTypeMap[node.data.subType];
             }
         },
 
@@ -32,7 +32,7 @@ let MainTreeCol = {
     readOnly: {
         // CSL, 2017-11-28
         subType: function (node){
-            return (node.data.type != 2 && node.data.type != 3);
+            return (node.data.type != 2 && node.data.type != 3&&!MainTreeCol.readOnly.glj(node));
         },
         calcProgramName: function (node) {
             if (
@@ -77,6 +77,9 @@ let MainTreeCol = {
         ration: function (node) {
             return node.sourceType === projectObj.project.Ration.getSourceType();
         },
+        glj: function (node) {
+            return node.sourceType == projectObj.project.ration_glj.getSourceType();
+        },
         volumePrice: function (node) {
             return (node.data.type == rationType.volumePrice || node.data.type == rationType.gljRation);
         },
@@ -110,6 +113,9 @@ let MainTreeCol = {
         },
         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)
         }
     },
     cellType: {
@@ -146,12 +152,12 @@ let MainTreeCol = {
 
         // CSL, 2017-11-28
         subType: function (node) {
-            if (node.data.type == rationType.volumePrice || node.data.type == rationType.gljRation){
+            if (node.data.type == rationType.volumePrice || node.data.type == rationType.gljRation||node.sourceType === projectObj.project.ration_glj.getSourceType()){
                 let VPType = new GC.Spread.Sheets.CellTypes.ComboBox();
 
                 if (node.data.type == rationType.volumePrice)
                     VPType.items(["人工","材料","机械","主材","设备"])
-                else if (node.data.type == rationType.gljRation)
+                else if (node.data.type == rationType.gljRation||node.sourceType === projectObj.project.ration_glj.getSourceType())
                     VPType.items(["材料","主材","设备"]);
 
                 return VPType;

+ 5 - 2
web/building_saas/main/js/views/project_info.js

@@ -6,8 +6,9 @@ var projectInfoObj = {
     projectInfo: null,
     getFullPathHtml: function (proj) {
         let fullPath = [], i, pm = '<span class="text-truncate"><a href="/pm">项目管理</a></span>', angleRight = '<span class="text-truncate"><i class="fa fa-angle-right fa-fw"></i></span>';
-        fullPath.push(pm);
+        // fullPath.push(pm);
         if (proj && proj.fullFolder) {
+            /*
             for (i = 0; i < proj.fullFolder.length; i++) {
                 if (i <= proj.fullFolder.length - 3) {
                     fullPath.push(angleRight, '<span class="text-truncate" data-toggle="tooltip" data-placement="bottom" title="', proj.fullFolder[i], '"><i class="fa fa-folder-open-o"></i></span>');
@@ -19,7 +20,9 @@ var projectInfoObj = {
                     // fullPath.push(angleRight, '<span class="text-truncate" data-toggle="tooltip" data-placement="bottom" title="' + proj.fullFolder[i] + '"><i class="fa fa-cube"></i>' + proj.fullFolder[i] + '</span>');
                 }
             }
-            fullPath.push(angleRight, '<span class="text-truncate" data-toggle="tooltip" data-placement="bottom" title="' + proj.name + '"><i class="fa fa-sticky-note-o"></i>' + proj.name + '</span>');
+             */
+            fullPath.push('<span class="text-truncate" data-toggle="tooltip" data-placement="bottom" title="' + proj.name + '"><i class="fa fa-sticky-note-o"></i> ' + proj.name + '</span>');
+
         }
         return fullPath.join('');
     },

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

@@ -19,7 +19,7 @@ let decimalObj = Object.create(null);
 
 decimalObj.decimal = function (field, node) {
     if(isDef(field)){
-        if(field === 'feeRate'){
+        if(field === 'feeRate'||field==="quantity_detail"){
             return this[field];
         }
         else if (field.sameText('unitFee')) field = 'unitPrice'

+ 16 - 5
web/building_saas/main/js/views/project_property_display_view.js

@@ -2,21 +2,32 @@
  * Created by Zhong on 2017/11/24.
  */
 let projDisplayView = {
-
-    datas: {},//just for view
-
+    datas: null,//just for view
     init:function () {
         this.datas = projectInfoObj.projectInfo.property.displaySetting;
         this.datas = this.datas === undefined ? { autoHeight: true, disPlayMainMaterial: true } : this.datas;
         $("#autoHeight").attr("checked",this.datas.autoHeight);
         $("#disPlayMainMaterial").attr("checked",this.datas.disPlayMainMaterial);
         //$('#disPlayMainMateria').prop('checked')
-    },
+ },
 
     needUpdate: function(autoHeight, disPlayMainMaterial) {
         return autoHeight !== this.datas.autoHeight || disPlayMainMaterial !== this.datas.disPlayMainMaterial;
-    }
+    },
 
+    updateChecking:function (projectID,properties) {
+        if(this.datas==null){
+            return;
+        }
+        var autoHeight = $('#autoHeight').prop('checked');
+        var disPlayMainMateria = $('#disPlayMainMateria').prop('checked');
+        if(this.datas.autoHeight!==autoHeight||this.datas.disPlayMainMateria!==disPlayMainMateria){
+            this.datas.autoHeight=autoHeight;
+            this.datas.disPlayMainMateria=disPlayMainMateria;
+        }
+        let updateData = {updateType: 'update', updateData: {ID: projectID, 'property.displaySetting':this.datas}};
+        properties.push(updateData);
+    }
 };
 
 $(document).ready(function () {

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

@@ -266,7 +266,9 @@ var projectObj = {
     },
     updateCellValue: function (node, value, colSetting) {
         let project = projectObj.project, fieldName = colSetting.data.field;
-        if (value !== calcFees.getFee(node.data, fieldName)) {
+        if(node.sourceType==project.ration_glj.getSourceType()){
+            project.ration_glj.updateFromMainSpread(value,node,fieldName);
+        }else if (value !== calcFees.getFee(node.data, fieldName)) {
             if (fieldName === 'code') {
                 projectObj.updateCode(node, value);
             }
@@ -301,7 +303,6 @@ var projectObj = {
                             projectObj.mainSpread.getActiveSheet().setValue(activeCell.row, activeCell.col, node.data.calcBase? node.data.calcBase: '');
                         }
                     }
-                    $.bootstrapLoading.end();
                     return;
                    // if (value) {value = parseFloat(value).toDecimal(decimalObj.decimal("totalPrice", node))};
                 };
@@ -333,10 +334,8 @@ var projectObj = {
         } else {
             projectObj.mainController.refreshTreeNode([node], false);
         }
-        $.bootstrapLoading.end();
     },
     mainSpreadEditEnded: function (sender, info) {
-        $.bootstrapLoading.start();
         let project = projectObj.project;
         let node = project.mainTree.items[info.row];
         let colSetting = projectObj.mainController.setting.cols[info.col];
@@ -376,7 +375,7 @@ var projectObj = {
 
             if (!err) {
                 that.project.property = projectInfoObj.projectInfo.property;
-                that.project.calcProgram.compileAllTemps();
+                //that.project.calcProgram.compileAllTemps();
                 that.project.calcBase.init(that.project);
                 that.project.calcFields = JSON.parse(JSON.stringify(feeType));
                 // that.project.initCalcFields();
@@ -416,10 +415,9 @@ var projectObj = {
                     if (col.data.field === 'name' || col.data.field === 'itemCharacterText' ||
                         col.data.field === 'jobContentText' || col.data.field === 'adjustState') {
                         if (!autoHeight) {
-                            col.data.wordWrap = false;
+                            col.data.autoFitRow();
                             col.showHint = true;
                         } else {
-                            col.data.wordWrap = true;
                             col.showHint = false;
                         }
                     }
@@ -676,9 +674,6 @@ $('#property_ok').click(function () {
     let properties = [], projectID = parseInt(scUrlUtil.GetQueryString('project'));
     let project = projectObj.project, reCalc= false;
     let b = parseInt($("input[name='calcFlag']:checked").val());
-    // 呈现选项
-    const autoHeight = $("#autoHeight:checked").length > 0;
-    const disPlayMainMaterial = $("#disPlayMainMaterial:checked").length > 0;
     if (b !== project.property.billsCalcMode) {
         let data1 = {updateType: 'update', updateData: {ID: projectID, 'property.billsCalcMode': b}};
         properties.push(data1);
@@ -725,12 +720,9 @@ $('#property_ok').click(function () {
         let updateData = {updateType: 'update', updateData: {ID: projectID, 'property.decimal': updateDecimal}};
         properties.push(updateData);
     }
-    // 呈现选项
-    if (projDisplayView.needUpdate(autoHeight, disPlayMainMaterial)) {
-        const displaySetting = { autoHeight, disPlayMainMaterial };
-        let updateData = {updateType: 'update', updateData: {ID: projectID, 'property.displaySetting': displaySetting}};
-        properties.push(updateData);
-    }
+ // 呈现选项
+    projDisplayView.updateChecking(projectID,properties);
+
     console.log(properties);
     if(properties.length > 0){
         CommonAjax.post('/pm/api/updateProjects', {user_id: userID, updateData: properties}, function (rstData) {

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

@@ -114,6 +114,67 @@ $("#linkTZJNR").click(function () {
     gljOprObj.activeTab='#linkTZJNR';
 });
 
+// 应用到选中清单
+$("#use-to-current").click(function() {
+    // 添加位置
+    const position = $("#add-position").val();
+    // 添加内容
+    const addContent = $("#add-content").val();
+    // 显示格式
+    const displayFormat = $("#display-format").val();
+    // 特征生成方式
+    const characterFormat = $("#character-format").val();
+
+    // 序号格式
+    const serialType = $("#serial-type").val();
+    const setting = {
+        serialType,
+        characterFormat,
+        addContent,
+        position,
+        displayFormat,
+    };
+    let selectedNode = projectObj.mainController.tree.selected;
+    pageCCOprObj.buildCharacterBySetting(selectedNode, setting);
+    // console.log(changeNode);
+    projectObj.mainController.refreshTreeNode([selectedNode], false);
+});
+// 添加位置选择
+$("#add-position").change(function() {
+    const selected = $(this).children(":selected").val();
+    const addContentEle = $("#add-content");
+    const displayFormatEle = $("#display-format");
+    switch (selected) {
+        case '4':
+            // 分别添加到对应列
+            // 当“添加位置”是“分别添加到对应列”,则“添加内容”恢复默认“无”,且灰显;“显示格式”恢复默认“换行分隔”,且灰显。
+            addContentEle.val('');
+            addContentEle.attr('disabled', 'disabled');
+            displayFormatEle.val(1);
+            displayFormatEle.attr('disabled', 'disabled');
+            console.log('hello');
+            break;
+        default:
+            addContentEle.removeAttr('disabled');
+            displayFormatEle.removeAttr('disabled');
+            break;
+    }
+});
+
+// 子目生成方式选择事件
+$("#child-display-format").change(function() {
+    const selected = $(this).children(":selected").val();
+    const serialTypeEle = $("#serial-type");
+    // 如果是编号+定额名称则序号格式不能选择
+    if (selected === '1') {
+        // 默认选中数字显示模式
+        serialTypeEle.val(1);
+        serialTypeEle.attr('disabled', 'disabled');
+    } else {
+        serialTypeEle.removeAttr('disabled');
+    }
+});
+
 function activeSubSheetIs(idx){
     let rst = subSpread.getActiveSheetIndex() == idx;
     return rst;

+ 4 - 1
web/building_saas/pm/html/project-management.html

@@ -26,13 +26,16 @@
         #summary-engineering,#summary-project{
             display: none;
         }
+        #header-menu{
+            display: none;
+        }
     </style>
 </head>
 
 <body>
 <div class="header">
     <div class="top-msg clearfix">
-        <div class="alert alert-warning mb-0 py-0" role="alert">
+        <div class="alert alert-warning mb-0 py-0" role="alert" style="display: none;">
             <button type="button" class="close" data-dismiss="alert" aria-label="Close">
                 <span aria-hidden="true">&times;</span>
             </button>

+ 3 - 3
web/common/html/header.html

@@ -1,6 +1,6 @@
 <nav class="navbar navbar-expand-lg p-0 d-flex">
-    <span class="header-logo px-2">纵横云造价</span>
-    <ul class="nav navbar-nav px-1">
+    <a class="header-logo px-2" href="/pm" style="text-decoration: none;">纵横云造价</a>
+    <ul class="nav navbar-nav px-1" id="header-menu">
         <li class="nav-item">
             <a class="nav-link" href="#" aria-expanded="false" data-toggle="modal" data-target="#poj-set"><i class="fa fa-cube"></i> 项目属性</a>
         </li>
@@ -29,7 +29,7 @@
     </ul>
     <div class="navbar-text navbar-crumb p-0" id="fullpath">
         <% if (action !== 'index' || controller !== 'pm') {%>
-        <span class="text-truncate"><a href="/pm">项目管理</a></span>
+        <!--<span class="text-truncate"><a href="/pm">项目管理</a></span>-->
         <% } %>
     </div>
     <div class="ml-auto navbar-text p-0">