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

Merge branch '1.0.0_online' of http://smartcost.f3322.net:3000/SmartCost/ConstructionCost into 1.0.0_online

zhongzewei 6 лет назад
Родитель
Сommit
a141d83594

+ 3 - 3
config/config.js

@@ -28,7 +28,7 @@ module.exports = {
             useMongoClient: true
         }
     },
-    pp:{  server: "172.18.111.231",
+    pp:{  server: "112.74.42.187",
         port: "27017",
         options:{
             user:'smartcost',
@@ -39,8 +39,8 @@ module.exports = {
             connectTimeoutMS: 50000,
             useMongoClient: true
         }},
-    ab:{  server: "112.74.42.187",
-        port: "27017",
+    prod_s:{  server: "112.74.42.187",
+        port: "28066",
         options:{
             user:'smartcost',
             pass:'SmartCost3850888',

+ 2 - 0
config/gulpConfig.js

@@ -111,6 +111,7 @@ module.exports = {
         'web/building_saas/main/js/models/cache_tree.js',
         'web/building_saas/main/js/calc/calc_fees.js',
         'web/building_saas/main/js/models/exportStandardInterface.js',
+        'web/building_saas/main/js/models/exportSEIInterface.js',
         // 'web/building_saas/main/js/calc/ration_calc.js',
         // 'web/building_saas/main/js/calc/bills_calc.js',
         // 'public/calc_util.js',
@@ -144,6 +145,7 @@ module.exports = {
         'web/building_saas/main/js/views/confirm_modal.js',
         'web/building_saas/main/js/views/zlfb_view.js',
         'web/building_saas/main/js/views/installation_fee_view.js',
+        'web/building_saas/main/js/views/material_adjust_view.js',
         'web/building_saas/main/js/views/project_glj_view.js',
         'web/building_saas/main/js/views/importBills.js',
         'public/web/rpt_tpl_def.js',

+ 2 - 0
modules/all_models/bills.js

@@ -65,6 +65,8 @@ let billsSchema = new Schema({
     deleteInfo: deleteSchema,
     isEstimate:{type: Number,default:0},       // 1 true 0 false 是否暂估
     mainBills:{type:Schema.Types.Mixed,default:false},//true 是,false否,null 不确定,三个状态
+    outPutMaxPrice:{type:Schema.Types.Mixed,default:false},//输出最高限价 true 是,false否,null 不确定,三个状态
+    maxPrice:String,//最高限价
     remark:String,
     engineeringContent:String,//工程内容
     serviceContent:String,//服务内容

+ 8 - 2
modules/all_models/project_glj.js

@@ -104,13 +104,19 @@ let modelSchema = {
     mix_ratio_id: Number,
     // 显示关联父级工料机code(组合物用)
     connect_code: String,
-    materialType: Number,   //三材类别
-    materialCoe: Number,    //三材系数
+    materialType: Number,//三材类别
+    materialCoe: Number,//三材系数
     // 是否主要材料 (0为否 1为是)
     is_main_material: {
         type: Number,
         default: 0
     },
+    is_info_adjust:{type: Number, default: 0},//是否造价信息差额调整
+    is_coe_adjust:{type: Number, default: 0},//是否价格指数调整
+    riskCoe:String,//风险系数
+    standardPrice:String,//standardPrice
+    FO:String,//基本价格指数
+    FI:String,//现行价格指数
     ratio_data: Schema.Types.Mixed,
     remark:String,
     originPlace:String,//产地

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

@@ -85,7 +85,7 @@ class GLJController extends BaseController {
         };
         try {
             // 可编辑的字段
-            let editableField = ['is_evaluate', 'unit_price.market_price', 'is_adjust_price', 'mix_ratio.consumption','is_eval_material','no_tax_eqp',
+            let editableField = ['is_evaluate', 'unit_price.market_price', 'is_adjust_price', 'mix_ratio.consumption','is_eval_material','no_tax_eqp','is_coe_adjust','is_info_adjust','FI','FO','standardPrice','riskCoe',
                 'supply', 'supply_quantity','delivery_address','delivery','materialType','materialCoe','is_main_material','originPlace','vender','qualityGrace','brand','remark'];
             if (editableField.indexOf(field) < 0) {
                 throw '对应字段不能编辑';

+ 16 - 0
modules/main/controllers/project_controller.js

@@ -151,5 +151,21 @@ module.exports = {
             result.message = err.message;
         }
         res.json(result);
+    },
+    getSEIProjects:async function(req,res){
+        let data = JSON.parse(req.body.data);
+        let result={
+            error: 0,
+            data: null
+        };
+        try{
+            result.data = await project_facade.getSEIProjects(data.projectID);
+        }
+        catch(err){
+            logger.err(err);
+            result.error=1;
+            result.message = err.message;
+        }
+        res.json(result);
     }
 };

+ 62 - 1
modules/main/facade/project_facade.js

@@ -9,7 +9,8 @@ module.exports = {
     calcInstallationFee:calcInstallationFee,
     saveProperty: saveProperty,
     getDefaultColSetting: getDefaultColSetting,
-    markProjectsToChange:markProjectsToChange
+    markProjectsToChange:markProjectsToChange,
+    getSEIProjects:getSEIProjects
 };
 
 let mongoose = require('mongoose');
@@ -274,4 +275,64 @@ function saveProperty(data, callback){
 
 async function getDefaultColSetting(libID){
     return await stdColSettingModel.findOne({ID: libID, deleted: false}, '-_id main_tree_col');
+}
+
+function sortChildren(lists) {
+    let IDMap ={},nextMap = {}, firstNode = null,newList=[];
+    for(let l of lists){
+        if(l.children&&l.children.length > 0) l.children = sortChildren(l.children);//递规排序
+        IDMap[l.ID] = l;
+        if(l.NextSiblingID!=-1) nextMap[l.NextSiblingID] = l;
+    }
+    for(let t of lists){
+        if(!nextMap[t.ID]){ //如果在下一节点映射没找到,则是第一个节点
+            firstNode = t;
+            break;
+        }
+    }
+    if(firstNode){
+        newList.push(firstNode);
+        delete IDMap[firstNode.ID];
+        setNext(firstNode,newList);
+    }
+    //容错处理,如果链断了的情况,直接添加到后面
+    for(let key in IDMap){
+        if(IDMap[key]) newList.push(IDMap[key])
+    }
+    return newList;
+
+    function setNext(node,array) {
+        if(node.NextSiblingID != -1){
+            let next = IDMap[node.NextSiblingID];
+            if(next){
+                array.push(next);
+                delete IDMap[next.ID];
+                setNext(next,array);
+            }
+        }
+    }
+
+}
+
+async  function getSEIProjects(projectID) {
+    let project = await  projectsModel.findOne({ID:projectID});
+    if(!project) throw new Error(`找不到建设项目:${projectID}`);
+    let tem_e = await projectsModel.find({ParentID:4061});
+    let engineers = [];
+    for(let e of tem_e){
+        if(!e.deleteInfo || !e.deleteInfo.deleted){
+            let tenders =  await projectsModel.find({ParentID:e.ID});
+            let children = [];
+            for(let t of tenders){
+                if(!t.deleteInfo || !t.deleteInfo.deleted){
+                    children.push(t);
+                }
+            }
+            e._doc.children = children;
+            engineers.push(e);
+        }
+    }
+    engineers = sortChildren(engineers);
+    project._doc.children = engineers;
+    return project;
 }

+ 1 - 1
modules/main/routes/project_route.js

@@ -15,7 +15,7 @@ module.exports = function (app) {
     projectRouter.post('/calcInstallationFee', projectController.calcInstallationFee);
     projectRouter.post('/saveProperty', projectController.saveProperty);
     projectRouter.post('/getDefaultColSetting', projectController.getDefaultColSetting);
-
+    projectRouter.post('/getSEIProjects', projectController.getSEIProjects);
     app.use('/project',projectRouter);
 };
 

+ 26 - 25
modules/ration_glj/facade/ration_glj_facade.js

@@ -1,6 +1,31 @@
 /**
  * Created by chen on 2017/6/29.
  */
+module.exports = {
+    save: save,
+    getData: getData,
+    deleteByRation: deleteByRation,
+    getQuantityByProjectGLJ: getQuantityByProjectGLJ,
+    getLibInfo: getLibInfo,
+    getGLJData: getGLJData,
+    getGLJDataByCodes:getGLJDataByCodes,
+    addGLJ: addGLJ,
+    deleteGLJ:deleteGLJ,
+    insertAddTypeGLJ:insertAddTypeGLJ,
+    replaceGLJ: replaceGLJ,
+    replaceGLJByData:replaceGLJByData,
+    mReplaceGLJ: mReplaceGLJ,
+    updateRationGLJByEdit: updateRationGLJByEdit,
+    getGLJClass: getGLJClass,
+    insertGLJAsRation: insertGLJAsRation,
+    getRationTypeGLJQuantity:getRationTypeGLJQuantity,
+    getInfoFromProjectGLJ:getInfoFromProjectGLJ,
+    createNewRecord:createNewRecord,
+    getGLJSearchInfo:getGLJSearchInfo,
+    updateRationGLJFromDoc:updateRationGLJFromDoc,
+    getGLJLibByEngineerID:getGLJLibByEngineerID,
+    prepareExtData:prepareExtData
+}
 
 let mongoose = require('mongoose');
 const uuidV1 = require('uuid/v1');
@@ -29,31 +54,7 @@ const gljClassModel = mongoose.model('std_glj_lib_gljClass');
 const projectDao = require('../../pm/models/project_model').project;
 const compleClassModel = mongoose.model('complementary_glj_section');
 
-module.exports = {
-    save: save,
-    getData: getData,
-    deleteByRation: deleteByRation,
-    getQuantityByProjectGLJ: getQuantityByProjectGLJ,
-    getLibInfo: getLibInfo,
-    getGLJData: getGLJData,
-    getGLJDataByCodes:getGLJDataByCodes,
-    addGLJ: addGLJ,
-    deleteGLJ:deleteGLJ,
-    insertAddTypeGLJ:insertAddTypeGLJ,
-    replaceGLJ: replaceGLJ,
-    replaceGLJByData:replaceGLJByData,
-    mReplaceGLJ: mReplaceGLJ,
-    updateRationGLJByEdit: updateRationGLJByEdit,
-    getGLJClass: getGLJClass,
-    insertGLJAsRation: insertGLJAsRation,
-    getRationTypeGLJQuantity:getRationTypeGLJQuantity,
-    getInfoFromProjectGLJ:getInfoFromProjectGLJ,
-    createNewRecord:createNewRecord,
-    getGLJSearchInfo:getGLJSearchInfo,
-    updateRationGLJFromDoc:updateRationGLJFromDoc,
-    getGLJLibByEngineerID:getGLJLibByEngineerID,
-    prepareExtData:prepareExtData
-}
+
 
 let operationMap = {
     'ut_create': create_ration_glj,

+ 59 - 38
modules/reports/util/rpt_pdf_util.js

@@ -5,11 +5,12 @@
  * Created by zhang on 2017/8/14.
  */
 
-let pdf = require('pdfkit');
-let fs = require('fs');
-let jpcCmnHelper = require('../rpt_component/helper/jpc_helper_common');
-let DPI = jpcCmnHelper.getScreenDPI()[0];
-let JV = require('../rpt_component/jpc_value_define');
+const pdf = require('pdfkit');
+const PDF_SCALE = 0.75;
+const fs = require('fs');
+const jpcCmnHelper = require('../rpt_component/helper/jpc_helper_common');
+const DPI = jpcCmnHelper.getScreenDPI()[0] * PDF_SCALE;
+const JV = require('../rpt_component/jpc_value_define');
 const uuidV1 = require('uuid/v1');
 
 let fontUtil = require('./rpt_font_util');
@@ -84,7 +85,7 @@ function export_pdf_file (pageData, paperSize, fName, callback) {
 
     function private_drawCell(cell, fonts, styles, controls, mergedBand) {
         doc.save();
-        //doc.translate(0.5,0.5);
+        // doc.translate(0.5,0.5); //跟H5的canvas不同,不需要这样切换
         let style = styles[cell[JV.PROP_STYLE]];
         if (style) {
             let isNeedMergeBand = private_chkIfInMergedBand(mergedBand, cell);
@@ -106,10 +107,12 @@ function export_pdf_file (pageData, paperSize, fName, callback) {
                 destStyle = styles[mergedBand[JV.PROP_STYLE][JV.PROP_ID]];
             }
         }
-        doc.moveTo(cell[JV.PROP_AREA][startP[0]] + offsetX, cell[JV.PROP_AREA][startP[1]] + offsetY);
+        // doc.moveTo(cell[JV.PROP_AREA][startP[0]] + offsetX, cell[JV.PROP_AREA][startP[1]] + offsetY);
+        doc.moveTo( (cell[JV.PROP_AREA][startP[0]] + offsetX) * PDF_SCALE, (cell[JV.PROP_AREA][startP[1]] + offsetY) * PDF_SCALE);
         if (destStyle[styleBorderDest] && parseFloat(destStyle[styleBorderDest][JV.PROP_LINE_WEIGHT]) !== 0) {
             doc.lineWidth(1.0 * destStyle[styleBorderDest][JV.PROP_LINE_WEIGHT]);
-            doc.lineTo(cell[JV.PROP_AREA][destP[0]] + offsetX, cell[JV.PROP_AREA][destP[1]] + offsetY);
+            // doc.lineTo(cell[JV.PROP_AREA][destP[0]] + offsetX, cell[JV.PROP_AREA][destP[1]] + offsetY);
+            doc.lineTo((cell[JV.PROP_AREA][destP[0]] + offsetX) * PDF_SCALE, (cell[JV.PROP_AREA][destP[1]] + offsetY) * PDF_SCALE);
             doc.strokeColor(destStyle[styleBorderDest][JV.PROP_COLOR]);
         }
         doc.stroke();
@@ -162,34 +165,39 @@ function export_pdf_file (pageData, paperSize, fName, callback) {
             }
         };
         inner_setupControl(area, dftFontHeight, output);
-        let w = area[JV.IDX_RIGHT] - JV.OUTPUT_OFFSET[JV.OFFSET_IDX_RIGHT] - area[JV.IDX_LEFT] - JV.OUTPUT_OFFSET[JV.OFFSET_IDX_RIGHT];
+        let validAreaTxtWidth = area[JV.IDX_RIGHT] - JV.OUTPUT_OFFSET[JV.OFFSET_IDX_RIGHT] - area[JV.IDX_LEFT] - JV.OUTPUT_OFFSET[JV.OFFSET_IDX_RIGHT];
+        let validTxtLines = Math.floor((area[JV.IDX_BOTTOM] - area[JV.IDX_TOP]) / (dftFontHeight + JV.OUTPUT_OFFSET[JV.OFFSET_IDX_BOTTOM] + JV.OUTPUT_OFFSET[JV.OFFSET_IDX_TOP] + 4));
         if (parseInt(font.FontAngle) !== 0) {
-            w = area[JV.IDX_BOTTOM] - JV.OUTPUT_OFFSET[JV.OFFSET_IDX_BOTTOM] - area[JV.IDX_TOP] - JV.OUTPUT_OFFSET[JV.OFFSET_IDX_TOP];
+            validAreaTxtWidth = area[JV.IDX_BOTTOM] - JV.OUTPUT_OFFSET[JV.OFFSET_IDX_BOTTOM] - area[JV.IDX_TOP] - JV.OUTPUT_OFFSET[JV.OFFSET_IDX_TOP];
+            validTxtLines = Math.floor((area[JV.IDX_RIGHT] - area[JV.IDX_LEFT]) / (dftFontHeight + JV.OUTPUT_OFFSET[JV.OFFSET_IDX_RIGHT] + JV.OUTPUT_OFFSET[JV.OFFSET_IDX_LEFT] + 4));
         }
 
-        function private_drawUnderline() {
+        function private_drawUnderline(underLineVal, underLineArea) {
             //A. 暂不支持角度; B. PDF输出时,坐标没有translate
             let ctx = doc;
             //1. 计算下划线的相关坐标
-            let width = ctx.widthOfString(val);
+            let width = ctx.widthOfString(underLineVal);
+            if (width > underLineArea[JV.IDX_RIGHT] - underLineArea[JV.IDX_LEFT]) {
+                width = underLineArea[JV.IDX_RIGHT] - underLineArea[JV.IDX_LEFT];
+            }
             let height = dftFontHeight;
-            let startX = area[JV.IDX_LEFT], startY = area[JV.IDX_TOP], endX = area[JV.IDX_RIGHT], endY = area[JV.IDX_BOTTOM];
+            let startX = underLineArea[JV.IDX_LEFT], startY = underLineArea[JV.IDX_TOP], endX = underLineArea[JV.IDX_RIGHT], endY = underLineArea[JV.IDX_BOTTOM];
             // let startX = 0, startY = 0, endX = width, endY = startY;
             if (control.Horizon === "left") {
-                startX = Math.round(area[JV.IDX_LEFT] + JV.OUTPUT_OFFSET[JV.IDX_LEFT]);
+                startX = Math.round(underLineArea[JV.IDX_LEFT] + JV.OUTPUT_OFFSET[JV.IDX_LEFT]);
             } else if (control.Horizon === "right") {
-                startX = Math.round(area[JV.IDX_RIGHT] - width - JV.OUTPUT_OFFSET[JV.IDX_RIGHT]);
+                startX = Math.round(underLineArea[JV.IDX_RIGHT] - width - JV.OUTPUT_OFFSET[JV.IDX_RIGHT]);
             } else {
-                startX = Math.round( area[JV.IDX_LEFT] + (area[JV.IDX_RIGHT] - area[JV.IDX_LEFT] - width) / 2);
+                startX = Math.round( underLineArea[JV.IDX_LEFT] + (underLineArea[JV.IDX_RIGHT] - underLineArea[JV.IDX_LEFT] - width) / 2);
             }
             endX = Math.round(startX + width);
 
             if (control.Vertical === "top") {
-                startY = Math.round(area[JV.IDX_TOP] + JV.OUTPUT_OFFSET[JV.IDX_TOP] + JV.OUTPUT_OFFSET[JV.IDX_BOTTOM] + height);
+                startY = Math.round(underLineArea[JV.IDX_TOP] + JV.OUTPUT_OFFSET[JV.IDX_TOP] + JV.OUTPUT_OFFSET[JV.IDX_BOTTOM] + height);
             } else if (control.Vertical === "bottom") {
-                startY = Math.round(area[JV.IDX_BOTTOM] + JV.OUTPUT_OFFSET[JV.IDX_BOTTOM]);
+                startY = Math.round(underLineArea[JV.IDX_BOTTOM] + JV.OUTPUT_OFFSET[JV.IDX_BOTTOM]);
             } else {
-                startY = Math.round( area[JV.IDX_TOP] + (area[JV.IDX_BOTTOM] - area[JV.IDX_TOP] + height) / 2) + JV.OUTPUT_OFFSET[JV.IDX_TOP] + JV.OUTPUT_OFFSET[JV.IDX_BOTTOM];
+                startY = Math.round( underLineArea[JV.IDX_TOP] + (underLineArea[JV.IDX_BOTTOM] - underLineArea[JV.IDX_TOP] + height) / 2) + JV.OUTPUT_OFFSET[JV.IDX_TOP] + JV.OUTPUT_OFFSET[JV.IDX_BOTTOM];
             }
             endY = Math.round(startY);
             //2. 画线
@@ -198,42 +206,50 @@ function export_pdf_file (pageData, paperSize, fName, callback) {
                 ctx.translate(0,0.5);
             }
             // ctx.beginPath();
-            ctx.moveTo(startX, startY);
+            // ctx.moveTo(startX, startY);
+            ctx.moveTo(startX * PDF_SCALE, startY * PDF_SCALE);
             ctx.lineWidth(1);
             ctx.strokeStyle = "BLACK";
-            ctx.lineTo(endX, endY);
+            // ctx.lineTo(endX, endY);
+            ctx.lineTo(endX * PDF_SCALE, endY * PDF_SCALE);
             ctx.stroke();
             // ctx.restore();
         }
 
         let rotateOptions;
-        if (font[JV.FONT_PROPS[5]] === 'T' && parseInt(font.FontAngle) === 0) {
-            private_drawUnderline();
-        }
+        // if (font[JV.FONT_PROPS[5]] === 'T' && parseInt(font.FontAngle) === 0) {
+        //     private_drawUnderline(val);
+        // }
         if (parseInt(font.FontAngle) !== 0) {
             if (control){
-                rotateOptions = private_setupAreaRotateOption(area,w,control.Vertical,dftFontHeight, output);
+                rotateOptions = private_setupAreaRotateOption(area,validAreaTxtWidth,control.Vertical,dftFontHeight, output);
             } else {
-                rotateOptions = private_setupAreaRotateOption(area,w,"bottom",dftFontHeight, output);
+                rotateOptions = private_setupAreaRotateOption(area,validAreaTxtWidth,"bottom",dftFontHeight, output);
             }
             doc.rotate(font.FontAngle,rotateOptions);
         }
-        if (w >= doc.widthOfString(val) || (control && control.Shrink !== 'T')) {
-            options.width = w;
-            options.height = dftFontHeight;
-            doc.text(val,output[0], output[1], options);
+        if (validAreaTxtWidth >= doc.widthOfString(val) ||
+            (control && control.Shrink !== 'T' && validTxtLines < private_splitString(val, validAreaTxtWidth, doc)) ) {
+            options.width = validAreaTxtWidth * PDF_SCALE;
+            options.height = dftFontHeight * PDF_SCALE;
+            doc.fontSize(dftFontHeight);
+            if (font[JV.FONT_PROPS[5]] === 'T' && parseInt(font.FontAngle) === 0) {
+                private_drawUnderline(val, area);
+            }
+            doc.fontSize(dftFontHeight * PDF_SCALE);
+            doc.text(val,output[0] * PDF_SCALE, output[1] * PDF_SCALE, options);
             doc.font(__dirname + '/pdf_base_files/simhei_bold_italic.ttf');
         } else {
             while (true) {
                 //*/
                 let lines = Math.floor((area[JV.IDX_BOTTOM] - area[JV.IDX_TOP]) / (dftFontHeight + JV.OUTPUT_OFFSET[JV.OFFSET_IDX_BOTTOM] + JV.OUTPUT_OFFSET[JV.OFFSET_IDX_TOP] + 4));
                 lines = (lines === 0)?1:lines;
-                let actLines = private_splitString(val, w, doc);
+                let actLines = private_splitString(val, validAreaTxtWidth, doc);
                 if (actLines.length > lines && dftFontHeight >= 6) {
                     dftFontHeight--;
                     doc.fontSize(dftFontHeight);
-                    options.width = w;
-                    options.height = dftFontHeight;
+                    options.width = validAreaTxtWidth * PDF_SCALE;
+                    options.height = dftFontHeight * PDF_SCALE;
                     // doc.text(val,output[0], output[1], options);
                 } else {
                     let aH = dftFontHeight + JV.OUTPUT_OFFSET[JV.OFFSET_IDX_BOTTOM] + JV.OUTPUT_OFFSET[JV.OFFSET_IDX_TOP] + 4;
@@ -249,21 +265,26 @@ function export_pdf_file (pageData, paperSize, fName, callback) {
                     for (let ai = 0; ai < area.length; ai++) {
                         newArea[ai] = area[ai];
                     }
-                    options.width = w;
-                    options.height = dftFontHeight;
+                    options.width = validAreaTxtWidth * PDF_SCALE;
+                    options.height = dftFontHeight * PDF_SCALE;
                     for (let lIdx = 0; lIdx < actLines.length; lIdx++) {
                         newArea[JV.IDX_TOP] = Math.round(aH * lIdx + baseTop);
                         newArea[JV.IDX_BOTTOM] = Math.round(aH * (lIdx + 1) + baseTop);
                         inner_setupControl(newArea, dftFontHeight, output);
-                        doc.text(actLines[lIdx], output[0], output[1], options);
+                        doc.fontSize(dftFontHeight);
+                        if (font[JV.FONT_PROPS[5]] === 'T' && parseInt(font.FontAngle) === 0) {
+                            private_drawUnderline(actLines[lIdx], newArea);
+                        }
+                        doc.fontSize(dftFontHeight * PDF_SCALE);
+                        doc.text(actLines[lIdx], output[0] * PDF_SCALE, output[1] * PDF_SCALE, options);
                     }
                     break;
                 }
                 /*/
                 dftFontHeight--;
                 doc.fontSize(dftFontHeight);
-                if (w >= doc.widthOfString(val) || dftFontHeight < 6) {
-                    options.width = w;
+                if (validAreaTxtWidth >= doc.widthOfString(val) || dftFontHeight < 6) {
+                    options.width = validAreaTxtWidth;
                     options.height = dftFontHeight;
                     doc.text(val,output[0], output[1], options);
                     doc.font(__dirname + '/pdf_base_files/simhei_bold_italic.ttf');

+ 1 - 7
public/web/tree_sheet/tree_sheet_helper.js

@@ -181,7 +181,7 @@ var TREE_SHEET_HELPER = {
                 var cell = sheet.getCell(iRow, iCol, GC.Spread.Sheets.SheetArea.viewport);
                 if (colSetting.data.getText && Object.prototype.toString.apply(colSetting.data.getText) === "[object Function]") {
                     cell.value(colSetting.data.getText(node));
-                }else if(colSetting.data.field=="mainBills"&&MainTreeCol.mainBillsEnable(node)){//主要清单有三种状态,所以直接显示就好,不走最后的逻辑
+                }else if((colSetting.data.field=="mainBills"||colSetting.data.field=="outPutMaxPrice")&&MainTreeCol.mainBillsEnable(node)){//主要清单有三种状态,所以直接显示就好,不走最后的逻辑
                     cell.value(node.data[colSetting.data.field]===undefined?false:node.data[colSetting.data.field]);
                 } else {
                     cell.value(getFieldText2());
@@ -557,11 +557,6 @@ var TREE_SHEET_HELPER = {
                 $editor.children('div').height(cellRect.height+2);
                 return $editor;
             };
-
-            TreeNodeCellType.prototype.deactivateEditor = function (editorContext, context) {
-                    console.log("hehe")
-            };
-
             TreeNodeCellType.prototype.updateEditor = function (editorContext, cellStyle, cellRect, context) {
                 let me = this;
                 $(editorContext).append(`<div><ul class="es-list" style="display: block;"></ul></div>`);//<li class="" data-value="" style=""> <br></li> //background-color:${cellStyle.backColor}
@@ -595,7 +590,6 @@ var TREE_SHEET_HELPER = {
                     });
                     if( $('#esInput').val()) setCursor( $("#esInput")[0], $('#esInput').val().length)
                 });
-                console.log("update")
             };
 
             TreeNodeCellType.prototype.processKeyDown = function (e, context){ //当用isReservedKey 不拦截编辑模式时的input框ctrl + c时,在非编辑模式的ctrl + c事件也需要自已处理,所以在这里再调用一下复制命令

+ 9 - 8
test/unit/reports/test_rpt_test_template.js

@@ -46,9 +46,9 @@ let demoPrjId = - 1;
 // let demoRptId = 2260; //测试基本信息
 // let demoRptId = 613; //09-4 2018
 // let demoRptId = 726; //定制:清单子目表
-// let demoRptId = 756; //江西 封1
+let demoRptId = 756; //江西 封1
 // let demoRptId = 475; //计日工
-let demoRptId = 551; //表05
+// let demoRptId = 551; //表05
 let pagesize = "A4";
 
 //288: 11-2表(新)
@@ -62,7 +62,8 @@ let userId_me = "5b6a60b1c4ba33000dd417c0"; //我的
 //demoPrjId = 1626; //QA:
 // demoPrjId = 2260; //QA:
 // demoPrjId = 5029; //
-demoPrjId = 4552; //
+// demoPrjId = 5029; //项目名称过长
+demoPrjId = 5113; //
 // demoPrjId = 4107; //UAT:
 //*/
 let userId_Dft = userId_me;
@@ -89,7 +90,7 @@ test('测试 - 测试模板啦: ', function (t) {
         let rptDataUtil = new rptDataExtractor();
         rptDataUtil.initialize(rptTpl._doc);
         let filter = rptDataUtil.getDataRequestFilter();
-        console.log(filter);
+        // console.log(filter);
         //正常应该根据报表模板定义的数据类型来请求数据
         rptTplDataFacade.prepareProjectData(userId_Dft, demoPrjId, filter, function (err, msg, rawDataObj) {
             if (!err) {
@@ -109,13 +110,13 @@ test('测试 - 测试模板啦: ', function (t) {
                     let customizeCfg = {"fillZero": true};
                     let pageRst = printCom.outputAsSimpleJSONPageArray(rptTpl, tplData, 1, maxPages, defProperties, customizeCfg);
                     if (pageRst) {
-                        fsUtil.writeObjToFile(pageRst, "D:/GitHome/ConstructionCost/tmp/testBuiltPageResult_测试模板.jsp");
+                        // fsUtil.writeObjToFile(pageRst, "D:/GitHome/ConstructionCost/tmp/testBuiltPageResult_测试模板.jsp");
                         // rpt_xl_util.exportExcel(pageRst, pagesize, "local_test_rpt_excel", true, null, null, function(uuidName){
                         //     console.log("excel uuid: " + uuidName);
                         // });
-                        // rpt_pdf_util.export_pdf_file(pageRst, pagesize, 'local_test_rpt_pdf', function(uuidName){
-                        //     console.log("pdf uuid: " + uuidName);
-                        // });
+                        rpt_pdf_util.export_pdf_file(pageRst, pagesize, 'local_test_rpt_pdf', function(uuidName){
+                            console.log("pdf uuid: " + uuidName);
+                        });
                     } else {
                         console.log("oh! no pages were created!");
                     }

+ 73 - 1
web/building_saas/glj/html/project_glj.html

@@ -8,6 +8,10 @@
         <label class="mx-2">使用单价文件:<span id="current-name"></span>(<label class="a_color" id="pop-used-list" data-original-title="" title="">与<span id="used-project-count">0</span>个单位工程同步</label>)
             <a class="btn btn-sm ml-1" href="#" data-toggle="modal" data-target="#change-unitFile"><i class="fa fa-exchange"></i> 选择其他</a>
             <a class="btn btn-sm ml-1" href="#" data-toggle="modal" data-target="#unitFile-save-as"><i class="fa fa-files-o"></i> 另存单独用</a></label>
+        <select class="form-control form-control-sm" style="width: auto; font-size: .875rem ;color: #007bff" id="adjustType">
+            <option value="priceInfo">造价信息差额调整法</option>
+            <option value="priceCoe" selected>价格指数调整法</option>
+        </select>
     </div>
 </div>
 
@@ -27,9 +31,14 @@
                 <li class="nav-item"><a class="nav-link" href="javascript:void(0)" id="ZGCL">暂估材料</a></li>
                 <li class="nav-item"><a class="nav-link" href="javascript:void(0)" id="SCHZ">三材汇总</a></li>
                 <li class="nav-item"><a class="nav-link" href="javascript:void(0)" id="ZYCL">主要材料</a></li>
+                <li class="nav-item"><a class="nav-link" href="javascript:void(0)" id="AMAE">添加承包人提供主要材料和工程设备</a></li>
             </ul>
         </div>
-        <div class="main-content col p-0" id="project-glj-main" style="overflow: hidden;">
+        <div class="main-content col p-0" id="material_adjust" style="overflow: hidden; display: none">
+            <div class="" id="material_adjust_sheet" style="overflow: hidden;width: 100%">
+            </div>
+        </div>
+        <div class="main-content col p-0" id="project-glj-main" style="overflow: hidden; ">
             <div class="top-content" id="projectGljTop" style="overflow: hidden">
                 <div class="main-data-top" style="width: 100%; overflow: hidden" id="project_glj_sheet">
                 </div>
@@ -163,3 +172,66 @@
         </div>
     </div>
 </div>
+<!--弹出 从人材机汇总中选择-->
+<div class="modal fade" id="selectFromGLJ" data-backdrop="static">
+    <div class="modal-dialog modal-lg" role="document">
+        <div class="modal-content">
+            <div class="modal-header">
+                <h5 class="modal-title">从人才机汇总中选择</h5>
+                <button type="button" class="close" data-dismiss="modal" aria-label="Close">
+                    <span aria-hidden="true">&times;</span>
+                </button>
+            </div>
+            <div class="modal-body" style="padding: 0px">
+                <div class="btn-toolbar" style="margin: 10px">
+                    <div class="btn-group btn-group-sm mr-2">
+                        <button type="button" class="btn btn-outline-primary glj_sel_check_btn">全选</button>
+                        <button type="button" class="btn btn-outline-primary glj_sel_check_btn">全选主材</button>
+                        <button type="button" class="btn btn-outline-primary glj_sel_check_btn">全选设备</button>
+                    </div>
+                    <!--前面3个按钮 有选中状态,出现 取消 按钮-->
+                    <button type="button" class="btn btn-outline-danger btn-sm mr-2 glj_sel_check_btn">取消</button>
+                    <div class="input-group input-group-sm mr-2" style="width:200px">
+                        <input type="text" class="form-control form-control-sm"  placeholder="查找" id="glj_sel_input" value="">
+                        <div class="input-group-append">
+                            <button class="btn btn-outline-primary btn-sm" id="glj_sel_btn_find" type="button"><i class="fa fa-search" aria-hidden="true"></i></button>
+                        </div>
+                    </div>
+                    <div class="input-group input-group-sm">
+                        <div class="form-check form-check-inline">
+                            <input class="form-check-input glj_sel_input" type="checkbox" id="glj_sel_all" value="0">
+                            <label class="form-check-label" for="glj_sel_all">所有</label>
+                        </div>
+                        <div class="form-check form-check-inline">
+                            <input class="form-check-input glj_sel_input" type="checkbox" id="glj_sel_labour" value="1">
+                            <label class="form-check-label" for="glj_sel_labour">人</label>
+                        </div>
+                        <div class="form-check form-check-inline">
+                            <input class="form-check-input glj_sel_input" type="checkbox" id="glj_sel_material" checked value="2">
+                            <label class="form-check-label" for="glj_sel_material">材</label>
+                        </div>
+                        <div class="form-check form-check-inline">
+                            <input class="form-check-input glj_sel_input" type="checkbox" id="glj_sel_machine" value="3">
+                            <label class="form-check-label" for="glj_sel_machine">机</label>
+                        </div>
+                        <div class="form-check form-check-inline">
+                            <input class="form-check-input glj_sel_input" type="checkbox" id="glj_sel_main" checked value="4">
+                            <label class="form-check-label" for="glj_sel_main">主材</label>
+                        </div>
+                        <div class="form-check form-check-inline">
+                            <input class="form-check-input glj_sel_input" type="checkbox" id="glj_sel_eqp" checked value="5">
+                            <label class="form-check-label" for="glj_sel_eqp">设备</label>
+                        </div>
+                    </div>
+                </div>
+                <div class="modal-auto-height" style="margin-top:10px; border: 1px solid #ccc">
+                    <div  id="glj_from_sheet" style="overflow: hidden;height: 100%"></div>
+                </div>
+            </div>
+            <div class="modal-footer">
+                <button type="button" class="btn btn-secondary" data-dismiss="modal">取消</button>
+                <button type="button" class="btn btn-primary" id="glj_sel_confirm" data-dismiss="modal">确定</button>
+            </div>
+        </div>
+    </div>
+</div>

+ 1 - 0
web/building_saas/js/global.js

@@ -34,6 +34,7 @@ function autoFlashHeight(){
     $('#comments').find('textarea').height($('#comments').height() - 25);
     typeof(adaptiveTzjnrWidth)== 'function' ?adaptiveTzjnrWidth():'';
     $('#project-glj-main').width($(window).width()-($('.main-nav').width()+ 2)-($('.filterType').width()+12)-5); //2、12是padding宽度,width 是不算padding宽度的
+    $('#material_adjust').width($(window).width()-($('.main-nav').width()+ 2)-($('.filterType').width()+12)-5);//材料调差
     //typeof zmhs_obj === 'object' ? zmhs_obj.loadSideResize() : '';
 };
 

+ 3 - 0
web/building_saas/main/html/main.html

@@ -146,6 +146,7 @@
                       <% } %>
                       <a id="switchTznr" href="javascript:void(0);"  class="btn btn-light btn-sm"><i class="fa fa-eye" aria-hidden="true"></i> 显示特征</a>-->
                   </div>
+                 <!-- <a href="javascript:void(0)" class="btn btn-light btn-sm" onclick="exportSEI('<%= projectData.property.rootProjectID%>')">导出经济指标</a>-->
                   <div class="side-tabs">
                       <ul class="nav nav-tabs" role="tablist">
                          <!-- <li class="nav-item">
@@ -2086,6 +2087,7 @@
     <script type="text/javascript" src="/web/building_saas/main/js/models/cache_tree.js"></script>
     <script type="text/javascript" src="/web/building_saas/main/js/calc/calc_fees.js"></script>
     <script type="text/javascript" src="/web/building_saas/main/js/models/exportStandardInterface.js"></script>
+    <script type="text/javascript" src="/web/building_saas/main/js/models/exportSEIInterface.js"></script>
     <!--<script type="text/javascript" src="/web/building_saas/main/js/calc/ration_calc.js"></script>-->
     <!--<script type="text/javascript" src="/web/building_saas/main/js/calc/bills_calc.js"></script>-->
     <!--<script type="text/javascript" src="/public/calc_util.js"></script>-->
@@ -2121,6 +2123,7 @@
     <script type="text/javascript" src='/web/building_saas/main/js/views/confirm_modal.js'></script>
     <script type="text/javascript" src='/web/building_saas/main/js/views/zlfb_view.js'></script>
     <script type="text/javascript" src='/web/building_saas/main/js/views/installation_fee_view.js'></script>
+    <script type="text/javascript" src='/web/building_saas/main/js/views/material_adjust_view.js'></script>
     <script type="text/javascript" src='/web/building_saas/main/js/views/project_glj_view.js'></script>
     <script type="text/javascript" src="/web/building_saas/main/js/views/importBills.js"></script>
     <!--报表-->

+ 226 - 0
web/building_saas/main/js/models/exportSEIInterface.js

@@ -0,0 +1,226 @@
+/**
+ * Created by zhang on 2019/5/20.
+ */
+async function exportSEI(projectID) {
+
+    let tenderProjects = [];
+
+    let result = await ajaxPost("/project/getSEIProjects",{projectID:projectID});
+    console.log(result);
+    let project = getProject(result);
+
+    prepareTenderDatas(tenderProjects,project);
+
+
+
+    toXml(project);
+
+
+
+
+
+
+    function getProject(orignal) {//取建设项目信息
+        let basicInformation = getBaseInfo(orignal);
+        let project = {
+            name: "建设项目",
+            attrs: [
+                {name: "项目名称", value: orignal.name},
+                {name:"建设单位",value:getItemValueBykey(basicInformation.items,"constructionUnit")},
+                {name:"施工单位",value:getItemValueBykey(basicInformation.items,"buildingUnit")},
+                {name: "标准名称", value: "重庆市建设工程造价指标采集标准(清单计价)"},
+                {name: "标准版本号", value: "1.1"}
+            ],
+            basicInformation:basicInformation,
+            children:[]
+        };
+        initAtts(project.attrs);
+        for(let c of orignal.children){
+            project.children.push(getEngineering(c));
+        }
+        return project;
+    }
+
+    function getEngineering(source){
+        let engineer = {
+            name:"单项工程",
+            attrs:[
+                {name: "名称", value: source.name}
+            ],
+            children:[]
+        };
+
+        for(let c of source.children){
+            let tenderProject = getTender(c);
+            engineer.children.push(tenderProject);
+            tenderProjects.push(tenderProject);
+        }
+        return engineer
+    };
+
+    function getTender(source) {
+        let tender = {
+            ID:source.ID,
+            name:"单位工程",
+            attrs:[
+                {name: "名称", value: source.name}
+            ],
+            children:[],
+            valuationType:source.property.valuationType,
+            taxType:source.property.taxType
+        };
+        return tender;
+    }
+
+
+    function prepareTenderDatas(tenders,project) {
+        for(let t of tenders){
+            setTenderData(t,project);
+        }
+
+
+
+
+    }
+
+
+
+    function setTenderData(tender,project) {
+
+        tender.children.push(setEngineerInfo(tender,project));
+
+
+
+    }
+
+    function setEngineerInfo(tender,project) {
+        let baseInfo = project.basicInformation;
+        let calcType ={"bill":"工程量清单计价","ration":"定额计价"};
+        let info = {
+            name:"工程信息",
+            attrs:[
+                {name:"造价编制单位",value:getItemValueBykey(baseInfo.items,"establishmentUnit")},
+                {name:"造价审核单位",value:getItemValueBykey(baseInfo.items,"auditUnit")},
+                {name:"项目负责人",value:""},
+                {name:"施工单位编制人员",value:""},
+                {name:"编制人员",value:""},
+                {name:"审核人员",value:""},
+                {name:"开工日期",value:""},
+                {name:"竣工日期",value:""},
+                {name:"工程地点",value:""},
+                {name:"工程类型",value:""},
+                {name:"合同价类型",value:""},
+                {name:"造价类型",value:""},
+                {name:"计价方式及依据",value:calcType[tender.valuationType]},
+                {name:"工程类别",value:""},
+                {name:"编制日期",value:""},
+                {name:"审查日期",value:""}
+
+            ]
+        };
+        initAtts(info.attrs);
+        return info;
+    }
+//造价编制单位="" 造价审核单位="" 项目负责人="" 施工单位编制人员="" 编制人员="" 审核人员="" 开工日期="" 竣工日期="" 工程地点="" 工程类型="" 合同价类型="" 造价类型="" 计价方式及依据="" 工程类别="" 编制日期="" 计税方法="一般计税"
+
+    function getBaseInfo(project){
+        let basicInformation = {items:[]};
+        let tem = null;
+        if(project.property&&project.property.basicInformation) tem =_.find(project.property.basicInformation,{"key":"basicInfo"});
+        if(tem) basicInformation = tem;
+        return basicInformation;
+    }
+
+
+    function getItemValueBykey(items,key) {
+        let item = _.find(items,{"key":key});
+        if(item) return item.value;
+        return ""
+    }
+
+    function initAtts(arrs) {
+        _.remove(arrs,function (item) {
+            return item.required == false && _.isEmpty(item.value)
+        })
+    }
+
+    //开始标签
+    function startTag(ele) {
+        let rst = `<${ele.name}`;
+        for (let attr of ele.attrs) {
+            rst += ` ${attr.name}="${attr.value}"`;
+        }
+        rst += ele.children&&ele.children.length > 0 ? '>' : '/>';
+        return rst;
+    }
+    //结束标签
+    function endTag(ele) {
+        return `</${ele.name}>`;
+    }
+    //拼接成xml字符串
+    function toXMLStr(eles) {
+        let rst = '';
+        for (let ele of eles) {
+            rst += startTag(ele);
+            if (ele.children&& ele.children.length > 0) {
+                rst += toXMLStr(ele.children);
+                rst += endTag(ele);
+            }
+        }
+        return rst;
+    }
+    //格式化xml字符串
+    function formatXml(text) {
+        //去掉多余的空格
+        text = '\n' + text.replace(/>\s*?</g, ">\n<");
+        //调整格式
+        let rgx = /\n(<(([^\?]).+?)(?:\s|\s*?>|\s*?(\/)>)(?:.*?(?:(?:(\/)>)|(?:<(\/)\2>)))?)/mg;
+        let nodeStack = [];
+        let output = text.replace(rgx, function($0, all, name, isBegin, isCloseFull1, isCloseFull2, isFull1, isFull2){
+            let isClosed = (isCloseFull1 === '/') || (isCloseFull2 === '/' ) || (isFull1 === '/') || (isFull2 === '/');
+            let prefix = '';
+            if (isBegin === '!') {
+                prefix = getPrefix(nodeStack.length);
+            } else {
+                if (isBegin !== '/') {
+                    prefix = getPrefix(nodeStack.length);
+                    if (!isClosed) {
+                        nodeStack.push(name);
+                    }
+                } else {
+                    nodeStack.pop();
+                    prefix = getPrefix(nodeStack.length);
+                }
+            }
+            let ret =  '\n' + prefix + all;
+            return ret;
+        });
+        let outputText = output.substring(1);
+        return outputText;
+        function getPrefix(prefixIndex) {
+            let span = '    ';
+            let output = [];
+            for (let i = 0 ; i < prefixIndex; ++i) {
+                output.push(span);
+            }
+            return output.join('');
+        }
+    }
+    /*
+     * 导出数据
+     * @param {Number}tenderID(当前界面的单位工程ID,后台根据这个单位工程,根据导出粒度去找其建设项目下相关数据)
+     * @return {void}
+     * */
+     function toXml(eleData) {
+         //转换成xml字符串
+         let xmlStr = toXMLStr([eleData]);
+         //加上xml声明
+         xmlStr = `<?xml version="1.0" encoding="utf-8"?>${xmlStr}`;
+         //格式化
+         xmlStr = formatXml(xmlStr);
+         let blob = new Blob([xmlStr], {type: 'text/plain;charset=utf-8'});
+         saveAs(blob, '经济指标.ZBF');
+     }
+
+}
+

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

@@ -384,7 +384,8 @@ const filterType = {
     JGCL:'8',
     ZGCL:'9',
     SCHZ:'10',
-    ZYCL:'11'
+    ZYCL:'11',
+    AMAE:'12'
 };
 const filterTypeArray = ['1','2','3','4','5'];
 

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

@@ -397,15 +397,13 @@ var PROJECT = {
             }
             return true;
         };
-        project.prototype.updateMainBills = function(node,newval){
+        project.prototype.updateCasCadeBills = function(node,newval,fieldName){
             let datas = [];
             let data =  {
                 type:node.sourceType,
-                data:{
-                    ID:node.data.ID,
-                    mainBills:newval
-                }
+                data:{ID:node.data.ID}
             };
+            setData(data.data,newval,fieldName);
             datas.push(data);
             setChildren(node,newval,datas);//同步设置所有子项
             setParent(node,newval,datas);//设置父节点
@@ -415,7 +413,10 @@ var PROJECT = {
                 for(let d of datas){
                     let node = projectObj.project.mainTree.findNode(d.data.ID);
                     if(node){
-                        node.data.mainBills = d.data.mainBills;
+                        for(let key in d.data){
+                            if(key == 'ID') continue;
+                            node.data[key] = d.data[key];
+                        }
                         nodes.push(node)
                     }
                 }
@@ -428,11 +429,9 @@ var PROJECT = {
                     for(let c of pnode.children){
                         let data =  {
                             type:c.sourceType,
-                            data:{
-                                ID:c.data.ID,
-                                mainBills:newValue
-                            }
+                            data:{ID:c.data.ID}
                         };
+                        setData(data.data,newval,fieldName);
                         datas.push(data);
                         setChildren(c,newValue,datas)
                     }
@@ -443,7 +442,7 @@ var PROJECT = {
                 if(cnode.parent && !projectObj.project.Bills.isMeasureNode(cnode.parent)){//排除措施项目节点
                     for(b of cnode.parent.children){
                         if(b == cnode) continue
-                        if(b.data.mainBills!== newValue){//有兄弟节点的值和本节点不一样,则父节点设置为null
+                        if(b.data[fieldName]!== newValue){//有兄弟节点的值和本节点不一样,则父节点设置为null
                             diferrent = true;
                             break;
                         }
@@ -451,15 +450,17 @@ var PROJECT = {
                     let pvalue = diferrent === true?null:newValue;
                     let data =  {
                         type:cnode.parent.sourceType,
-                        data:{
-                            ID:cnode.parent.data.ID,
-                            mainBills:pvalue
-                        }
+                        data:{ID:cnode.parent.data.ID}
                     };
+                    setData(data.data,pvalue,fieldName);
                     datas.push(data);
                     setParent(cnode.parent,pvalue,datas);
                 }
             }
+            function setData(data,avalue,fieldName) {
+                data[fieldName] = avalue;
+                if(fieldName == "outPutMaxPrice") data.maxPrice = null;
+            }
 
         };
 

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

@@ -69,6 +69,13 @@ let MainTreeCol = {
                 if (rate) return rate.rate;
             }
             return node.data.feeRate;
+        },
+        maxPrice:function (node) {
+            if(node.data.outPutMaxPrice == true){
+                if(node.data.maxPrice === null&&node.data.feesIndex &&node.data.feesIndex.common) return node.data.feesIndex.common.unitFee?node.data.feesIndex.common.unitFee:"";
+                return node.data.maxPrice?node.data.maxPrice:"";
+            }
+            return "";
         }
     },
     readOnly: {
@@ -130,7 +137,6 @@ let MainTreeCol = {
             }
             return false;
         },
-
         //根据节点、父节点类型判断是否可用计算基数
         calcBaseType: function (node) {
             function isDef(v) {
@@ -264,6 +270,9 @@ let MainTreeCol = {
                 }
             }
             return true;
+        },
+        maxPrice:function (node) {
+            return node.data.outPutMaxPrice!==true;
         }
     },
     cellType: {
@@ -357,6 +366,9 @@ let MainTreeCol = {
         },
         mainBills:function (node) {
             if(MainTreeCol.mainBillsEnable(node)) return sheetCommonObj.getCheckBox(true);
+        },
+        outPutMaxPrice:function (node) {
+            if(MainTreeCol.mainBillsEnable(node)) return sheetCommonObj.getCheckBox(true);
         }
     },
     mainBillsEnable:function (node) {

+ 387 - 0
web/building_saas/main/js/views/material_adjust_view.js

@@ -0,0 +1,387 @@
+/**
+ * Created by zhang on 2019/5/15.
+ */
+let materialAdjustObj = {
+    spread:null,
+    priceInfoSheet:null,
+    priceCoeSheet:null,
+    priceInfoDatas:[],
+    priceCoeDatas:[],
+    priceInfoSetting:{
+        header: [
+            {headerName: "编号", headerWidth: 80, dataCode: "code", dataType: "String"},
+            {headerName: "材料名称", headerWidth: 160, dataCode: "name", dataType: "String",cellType:'tipsCell'},
+            {headerName: "规格型号", headerWidth: 120, dataCode: "specs", hAlign: "left", dataType: "String",cellType:'tipsCell'},
+            {headerName: "单位", headerWidth: 45, dataCode: "unit", hAlign: "center", dataType: "String"},
+            {headerName: "数量", headerWidth: 90, dataCode: "quantity", hAlign: "right", dataType: "Number",decimalField:'glj.quantity'},
+            {headerName: "风险系数", headerWidth: 90, dataCode: "riskCoe", hAlign: "right", dataType: "Number",validator:"number"},
+            {headerName: "基准单价", headerWidth: 70, dataCode: "standardPrice", hAlign: "right", dataType: "Number",validator:"number"},
+            {headerName: "投标单价", headerWidth: 70, dataCode: "marketPrice", hAlign: "right", dataType: "Number",validator:"number"},
+            {headerName: "合价", headerWidth: 70, dataCode: "totalPrice", hAlign: "right", dataType: "Number",validator:"number"},
+            {headerName: "产地", headerWidth: 80, dataCode: "originPlace", hAlign: "left", dataType: "String"},
+            {headerName: "厂家", headerWidth: 80, dataCode: "vender", hAlign: "left", dataType: "String"},
+            {headerName: "供货方式", headerWidth: 70, dataCode: "supply", hAlign: "center", dataType: "String",cellType:'comboBox',editorValueType:true,options:supplyComboMap},
+            {headerName: "备注", headerWidth: 100, dataCode: "remark", hAlign: "left", dataType: "String"}
+        ],
+        view:{ lockColumns: ["code","name","specs","unit","quantity","totalPrice","originPlace","vender","supply","remark"]}
+    },
+    priceCoeSetting:{
+        header: [
+            {headerName: "编号", headerWidth: 80, dataCode: "code", dataType: "String"},
+            {headerName: "材料名称", headerWidth: 160, dataCode: "name", dataType: "String",cellType:'tipsCell'},
+            {headerName: "规格型号", headerWidth: 120, dataCode: "specs", hAlign: "left", dataType: "String",cellType:'tipsCell'},
+            {headerName: "单位", headerWidth: 45, dataCode: "unit", hAlign: "center", dataType: "String"},
+            {headerName: "变值权重B", headerWidth: 90, dataCode: "varWeight", hAlign: "right", dataType: "Number",validator:"number"},
+            {headerName: "基本价格指数FO", headerWidth: 70, dataCode: "FO", hAlign: "right", dataType: "Number",validator:"number"},
+            {headerName: "现行价格指数FI", headerWidth: 70, dataCode: "FI", hAlign: "right", dataType: "Number",validator:"number"},
+            {headerName: "数量", headerWidth: 90, dataCode: "quantity", hAlign: "right", dataType: "Number",decimalField:'glj.quantity'},
+            {headerName: "单价", headerWidth: 70, dataCode: "marketPrice", hAlign: "right", dataType: "Number",validator:"number"},
+            {headerName: "合价", headerWidth: 70, dataCode: "totalPrice", hAlign: "right", dataType: "Number",validator:"number"},
+            {headerName: "产地", headerWidth: 80, dataCode: "originPlace", hAlign: "left", dataType: "String"},
+            {headerName: "厂家", headerWidth: 80, dataCode: "vender", hAlign: "left", dataType: "String"},
+            {headerName: "供货方式", headerWidth: 70, dataCode: "supply", hAlign: "center", dataType: "String",cellType:'comboBox',editorValueType:true,options:supplyComboMap},
+            {headerName: "备注", headerWidth: 100, dataCode: "remark", hAlign: "left", dataType: "String"}
+        ],
+        view:{ lockColumns: ["code","name","specs","unit","quantity","totalPrice","originPlace","vender","supply","remark"]}
+    },
+    refreshSheetDatas:function () {
+        $("#adjustType").val() == "priceInfo" ? materialAdjustObj.showPriceInfoDatas():materialAdjustObj.showPriceCoeDatas();
+        //let sheetIndex = $("#adjustType").val()
+    },
+    initSpread:function () {
+        if(!this.spread){
+            this.spread = SheetDataHelper.createNewSpread($("#material_adjust_sheet")[0],2);
+            sheetCommonObj.spreadDefaultStyle(this.spread);
+        }
+        this.initPriceInfoSheet();
+        this.initPriceCoeSheet();
+        //disableRightMenu("project_glj_sheet",this.projectGljSpread,this.rightClickCallback);
+        //打开别人分享的项目,只读
+        if(projectReadOnly){
+            disableSpread(this.spread);
+        }else {
+            this.initRightClick();
+        }
+    },
+    initPriceInfoSheet:function () {
+        this.priceInfoSheet = this.spread.getSheet(0);
+        sheetCommonObj.initSheet(this.priceInfoSheet,this.priceInfoSetting,30);
+        this.priceInfoSheet.bind(GC.Spread.Sheets.Events.ValueChanged, this.onSheetValueChange);
+        this.priceInfoSheet.name('priceInfoSheet');
+        this.priceInfoSheet.setRowHeight(0, 45, 1);
+    },
+    initPriceCoeSheet:function () {
+        this.priceCoeSheet = this.spread.getSheet(1);
+        sheetCommonObj.initSheet(this.priceCoeSheet,this.priceCoeSetting,30);
+        this.priceCoeSheet.bind(GC.Spread.Sheets.Events.ValueChanged, this.onSheetValueChange);
+        this.priceCoeSheet.name('priceCoeSheet');
+        this.priceCoeSheet.setRowHeight(0, 45, 1);
+    },
+    onSheetValueChange:function (a,args) {
+        let me = materialAdjustObj,row = args.row, col = args.col;
+        let projectGLJ = projectObj.project.projectGLJ;
+        let setting = $("#adjustType").val() == "priceInfo"?me.priceInfoSetting:me.priceCoeSetting;
+        let datas = $("#adjustType").val() == "priceInfo"?me.priceInfoDatas:me.priceCoeDatas;
+        let dataCode = setting.header[col].dataCode;
+        let recode = datas[row];
+        let value = args.newValue;
+        if(value === undefined ){
+            me.refreshSheetDatas();
+            return;
+        }
+        if (value&&!projectGljObject.checkData(col,setting,value)) {
+            alert('输入的数据类型不对,请重新输入!');
+            me.refreshSheetDatas();
+            return ;
+        }
+        if(recode[dataCode] == value) return;
+
+        if(dataCode=='marketPrice'){//修改市场价和修改定额价时需要重新记算很多受影响的树节点,现在改成与定字额工料机那里调相同的方法。
+            let editField ="market_price";
+            projectGLJ.updatePrice(recode,editField,value,'pg',me.refreshSheetDatas);
+            return;
+        }
+        value = scMathUtil.roundForObj(value,getDecimal("process"));
+        let updateData = {id: recode.id, field: dataCode, value: value+""};
+        projectGLJ.pGljUpdate(updateData,me.refreshSheetDatas);
+
+    },
+    deleteAdjust:function (row) {
+        let me = this;
+        let projectGLJ = projectObj.project.projectGLJ;
+        let field =  $("#adjustType").val() == "priceInfo"?"is_info_adjust":"is_coe_adjust";
+        let datas = $("#adjustType").val() == "priceInfo"?me.priceInfoDatas:me.priceCoeDatas;
+        let recode = datas[row];
+        let updateData = {id: recode.id, field: field, value: 0};
+        projectGLJ.pGljUpdate(updateData,me.refreshSheetDatas);
+    },
+    showPriceInfoDatas:function () {
+        this.spread.setActiveSheetIndex(0);
+        this.priceInfoDatas = this.getPirceInfoDatas();
+        sheetCommonObj.showData(this.priceInfoSheet, this.priceInfoSetting,this.priceInfoDatas);
+        this.priceInfoSheet.setRowCount(this.priceInfoDatas.length);
+    },
+    showPriceCoeDatas:function () {
+        this.spread.setActiveSheetIndex(1);
+        this.priceCoeDatas = this.getPriceCoeDatas();
+        sheetCommonObj.showData(this.priceCoeSheet, this.priceCoeSetting,this.priceCoeDatas);
+        this.priceCoeSheet.setRowCount(this.priceCoeDatas.length);
+    },
+    getPirceInfoDatas:function(){
+        let datas = [];
+        let gljList = this.filterAdjustGlj();
+        gljList = sortProjectGLJ(gljList);
+        for(let glj of gljList){
+            datas.push(getInfoObject(glj));
+        }
+        return datas;
+        function getInfoObject(glj) {
+            let data = materialAdjustObj.getCommonObject(glj);
+            data.riskCoe = glj.riskCoe;
+            data.standardPrice = glj.standardPrice;
+            data.totalPrice = materialAdjustObj.getTotalPrice(data);
+            return data;
+        }
+    },
+    filterAdjustGlj:function () {
+        let gljList = projectObj.project.projectGLJ.datas.gljList;
+        let field =  $("#adjustType").val() == "priceInfo"?"is_info_adjust":"is_coe_adjust";
+        return _.filter(gljList,function (item) {
+            return item.quantity !== 0 && item.quantity !== '0' && item[field] ===1
+        });
+    },
+    getPriceCoeDatas:function () {
+        let datas = [];
+        let node =  projectObj.project.Bills.getEngineeringCostNode(projectObj.mainController);
+        let totalFee = node && node.data.feesIndex && node.data.feesIndex.common?node.data.feesIndex.common.totalFee:0;
+        let gljList = this.filterAdjustGlj();
+         gljList = sortProjectGLJ(gljList);
+        for(let glj of gljList){
+            datas.push(getCoeObject(glj,totalFee));
+        }
+        return datas;
+        function getCoeObject(glj,totalFee) {
+            let data = materialAdjustObj.getCommonObject(glj);
+            data.FO = glj.FO;
+            data.FI = glj.FI;
+            data.totalPrice = materialAdjustObj.getTotalPrice(data);
+            if(totalFee !==0) data.varWeight = scMathUtil.roundForObj(data.totalPrice/totalFee,2);
+            return data;
+        }
+    },
+    getTotalPrice:function (data) {
+        return scMathUtil.roundForObj(data.quantity * data.marketPrice,getDecimal("bills.totalPrice"))
+    },
+    initRightClick : function() {
+        let me = this;
+        $.contextMenu({
+            selector: '#material_adjust_sheet',
+            build: function ($trigger, e) {
+                me.rightClickTarget = SheetDataHelper.safeRightClickSelection($trigger, e, me.spread);
+                return me.rightClickTarget.hitTestType === GC.Spread.Sheets.SheetArea.viewport ||
+                    me.rightClickTarget.hitTestType === GC.Spread.Sheets.SheetArea.rowHeader;
+            },
+            items: {
+                "addFromGLJ":{
+                    name: '从人材机汇总中选择',
+                    icon: 'fa-sign-in',
+                    disabled: function () {
+                        return false;
+                    },
+                    callback: function (key, opt) {
+                        $("#selectFromGLJ").modal('show');
+                    }
+                },
+                "deleteAdjust": {
+                    name: "删除",
+                    icon: 'fa-trash-o',
+                    disabled: function () {
+                        return me.rightClickTarget.row === undefined;
+                    },
+                    callback: function (key, opt) {
+                        let row = me.rightClickTarget.row;
+                        me.deleteAdjust(row);
+                    }
+                }
+            }
+        });
+    },
+    getCommonObject:function (glj) {
+        let data ={
+            select:0,
+            id:glj.id,
+            code:glj.code,
+            name:glj.name,
+            specs:glj.specs,
+            unit:glj.unit,
+            type:glj.type,
+            quantity:glj.quantity,
+            supply:glj.supply,
+            originPlace:glj.originPlace,
+            vender:glj.vender,
+            brand:glj.brand,
+            remark:glj.remark
+        };
+        gljOprObj.setGLJPrice(data,glj);
+        return data;
+    }
+};
+
+let gljFromObj={
+    spread:null,
+    sheet:null,
+    datas:[],
+    setting:{
+        header: [
+            {headerName: "选择", headerWidth: 45, dataCode: "select", hAlign: "center", dataType: "String",cellType:'checkBox'},
+            {headerName: "编码", headerWidth: 80, dataCode: "code", dataType: "String"},
+            {headerName: "类型", headerWidth: 30, dataCode: "short_name", hAlign: "center", dataType: "String"},
+            {headerName: "名称", headerWidth: 160, dataCode: "name", dataType: "String",cellType:'tipsCell'},
+            {headerName: "规格型号", headerWidth: 100, dataCode: "specs", hAlign: "left", dataType: "String",cellType:'tipsCell'},
+            {headerName: "单位", headerWidth: 45, dataCode: "unit", hAlign: "center", dataType: "String"},
+            {headerName: "总消耗量", headerWidth: 90, dataCode: "quantity", hAlign: "right", dataType: "Number",decimalField:'glj.quantity'},
+            {headerName: "市场价", headerWidth: 70, dataCode: "marketPrice", hAlign: "right", dataType: "Number",validator:"number"},//,decimalField:"glj.unitPrice"
+            {headerName: "供货方式", headerWidth: 70, dataCode: "supply", hAlign: "center", dataType: "String",cellType:'comboBox',editorValueType:true,options:supplyComboMap},
+            {headerName: "暂估", headerWidth: 45, dataCode: "is_evaluate", hAlign: "center", dataType: "String",cellType:'checkBox'},
+            {headerName: "产地", headerWidth: 80, dataCode: "originPlace", hAlign: "left", dataType: "String"},
+            {headerName: "厂家", headerWidth: 80, dataCode: "vender", hAlign: "left", dataType: "String"},
+            {headerName: "备注", headerWidth: 100, dataCode: "remark", hAlign: "left", dataType: "String"}
+        ],
+        view: {
+            lockColumns: ["is_evaluate"]
+        }
+    },
+    initSpread:function () {
+        if(!this.spread){
+            this.spread = SheetDataHelper.createNewSpread($("#glj_from_sheet")[0]);
+            sheetCommonObj.spreadDefaultStyle(this.spread);
+        }
+        this.sheet = this.spread.getSheet(0);
+        sheetCommonObj.initSheet(this.sheet,this.setting);
+        this.sheet.bind(GC.Spread.Sheets.Events.EditStarting,this.onEditStarting);
+        this.sheet.bind(GC.Spread.Sheets.Events.ClipboardPasting, this.onClipboardPasting);
+        this.sheet.bind(GC.Spread.Sheets.Events.ValueChanged, this.onValueChanged);
+        this.sheet.setRowHeight(0, 45, 1);
+        disableRightMenu("glj_from_sheet",this.spread);
+    },
+    onEditStarting:function (e,args) {
+         args.cancel = true;
+    },
+    onClipboardPasting:function (e,args) {
+        args.cancel = true;
+    },
+    onValueChanged:function (e,args) {
+        let me = gljFromObj;
+        let value = args.newValue;
+        value = value == true?1:0;
+        me.datas[args.row].select = value;
+    },
+    showDatas:function () {
+        this.datas = [];
+        let gljList = projectObj.project.projectGLJ.datas.gljList;
+        gljList = this.filterGLJ(gljList);
+        gljList = sortProjectGLJ(gljList);
+        for(let glj of gljList){
+            this.datas.push(this.getSheetDatas(glj));
+        }
+        this.refreshDatas();
+    },
+    filterGLJ:function (gljList) {
+        let field =  $("#adjustType").val() == "priceInfo"?"is_info_adjust":"is_coe_adjust";
+        let typeMap = {};
+        for(let ch of $(".glj_sel_input:checked")){
+            typeMap[$(ch).val()] = true;
+        }
+        let inputV = $("#glj_sel_input").val();
+        return _.filter(gljList,function (item) {
+            if(item.quantity === 0 || item.quantity === '0' || item[field] ===1) return false;
+            if(!typeMap[0]){//如果没有勾选所有,下面再细分
+                let firstS = (item.type+"").substring(0,1);
+                if(!typeMap[firstS]) return false
+            }
+            if(inputV!=""){//输入的关键字过滤
+                if(item.code.indexOf(inputV)==-1 && item.name.indexOf(inputV)==-1) return false
+            }
+            return true;
+        });
+    },
+    refreshDatas:function () {
+        sheetCommonObj.showData(this.sheet, this.setting,this.datas);
+        this.sheet.setRowCount(this.datas.length);
+    },
+    getSheetDatas(glj){
+        let projectGLJ = projectObj.project.projectGLJ;
+        let materialIdList = projectGLJ.datas.constData.materialIdList;
+        let data = materialAdjustObj.getCommonObject(glj);
+        data.select = 0;
+        data.short_name = projectGLJ.getShortNameByID(glj.type);
+        // 只有材料才显示是否暂估
+        if (materialIdList.indexOf(glj.type) >= 0) data.is_evaluate = glj.is_evaluate;
+        return data;
+    },
+    checkByType:function (type) {
+        for(let d of this.datas){
+            d.select = 0;
+            switch (type){
+                case "全选":
+                    d.select = 1;
+                    break;
+                case "全选主材":
+                    if(d.type == 4) d.select = 1;
+                    break;
+                case "全选设备":
+                    if(d.type == 5) d.select = 1;
+                    break;
+                case "取消":
+                    d.select = 0;
+                    break;
+            }
+        }
+        this.refreshDatas();
+    },
+    confirmSelect:function () {
+        let updateMap = {};
+        let adjustType =  $("#adjustType").val()
+        for(let d of this.datas){
+            if(d.select == 1){
+                let tem;
+                if(adjustType== "priceInfo"){
+                    tem = {is_info_adjust:1,riskCoe:"",standardPrice:d.marketPrice+""};
+                }else {
+                    tem = {is_coe_adjust:1,FI:"",FO:""};
+                }
+                updateMap[d.id] = tem;
+            }
+        }
+        if( _.isEmpty(updateMap)) return;
+        projectObj.project.projectGLJ.batchUpdateGLJProperty(updateMap,function () {
+            materialAdjustObj.refreshSheetDatas();
+        });
+    }
+};
+
+
+$(function () {
+    $("#adjustType").change(function () {
+        materialAdjustObj.refreshSheetDatas();
+    });
+    $('#selectFromGLJ').on('shown.bs.modal',function(e){
+        gljFromObj.initSpread();
+        gljFromObj.showDatas();
+    });
+    $(".glj_sel_input").change(function () {
+        gljFromObj.showDatas();
+    });
+
+    $("#glj_sel_btn_find").click(function () {
+        gljFromObj.showDatas();
+    });
+
+    $(".glj_sel_check_btn").click(function () {
+        gljFromObj.checkByType($(this).text())
+    })
+    
+    $("#glj_sel_confirm").click(function () {
+        gljFromObj.confirmSelect();
+    })
+});

+ 42 - 15
web/building_saas/main/js/views/project_glj_view.js

@@ -50,6 +50,10 @@ projectGljObject={
         {ID:'MAIN_MATERIAL',text:'主材'},
         {ID:'EQUIPMENT',text:'设备'}
     ],
+    initSpreads:function(){
+        if(this.projectGljSpread==null) this.initProjectGljSpread();
+        if(materialAdjustObj.spread == null) materialAdjustObj.initSpread();
+    },
     initProjectGljSpread:function () {
         if(!this.projectGljSpread){
             this.projectGljSpread = SheetDataHelper.createNewSpread($("#project_glj_sheet")[0],2);
@@ -513,6 +517,23 @@ projectGljObject={
         this.materialTreeSheet.setSelection(sel.row==-1?0:sel.row,sel.col,sel.rowCount,sel.colCount);
         this.materialTreeController.setTreeSelected(this.materialTree.items[sel.row==-1?0:sel.row]);
     },
+    initSheetViews:function(){
+        let me = projectGljObject;
+        if(me.displayType == filterType.AMAE){
+            $('#material_adjust').show();
+            $('#adjustType').show();
+            $('#project-glj-main').hide();
+        } else {
+            $('#material_adjust').hide();
+            $('#adjustType').hide();
+            $('#project-glj-main').show();
+        }
+    },
+    refreshViewsData:function(){
+        let me = projectGljObject;
+        if(me.displayType == filterType.AMAE) return materialAdjustObj.refreshSheetDatas();
+        me.refreshDataSheet();
+    },
     refreshDataSheet:function () {
         let me = projectGljObject;
         let quantityCol = _.findIndex(me.projectGljSetting.header,function (header) {
@@ -904,11 +925,7 @@ projectGljObject={
                 value=  scMathUtil.roundForObj(value,getDecimal('glj.quantity'));
             }
             if(dataCode === 'is_evaluate'||dataCode === 'is_adjust_price'||dataCode === 'is_main_material'||dataCode === 'no_tax_eqp'||dataCode == 'is_eval_material'){
-                if(value == true){
-                    value = 1;
-                }else if(value == false){
-                    value = 0;
-                }
+                value = value == true?1:0;
             }
             if(dataCode === 'materialType' && (value == null || value=="")){//删除三材类别时,清空三材系数
                 value = null;
@@ -1028,7 +1045,7 @@ projectGljObject={
     },
     changeFileCallback:function(){
         projectGljObject.unitPriceFileInit();
-        projectGljObject.refreshDataSheet();
+        projectGljObject.refreshViewsData();
         gljOprObj.refreshView();
         projectObj.project.calcProgram.calcAllNodesAndSave(calcAllType.catAll,function () {
             if(socketObject.roomInfo){
@@ -1099,12 +1116,19 @@ function getProjectResizeEles() {
 
 
 function loadProjectGljSize() {
-    let me = projectGljObject;
-    let pojGljResizeEles = getProjectResizeEles();
-    SlideResize.loadVerticalHeight(pojGljResizeEles.eleObj.module, pojGljResizeEles.eleObj, pojGljResizeEles.limit, function () {
-        me.projectGljSpread?me.projectGljSpread.refresh():'';
-        me.mixRatioSpread?me.mixRatioSpread.refresh():'';
-    });
+
+    if($('#project-glj-main').is(':visible')){
+        let me = projectGljObject;
+        let pojGljResizeEles = getProjectResizeEles();
+        SlideResize.loadVerticalHeight(pojGljResizeEles.eleObj.module, pojGljResizeEles.eleObj, pojGljResizeEles.limit, function () {
+            me.projectGljSpread?me.projectGljSpread.refresh():'';
+            me.mixRatioSpread?me.mixRatioSpread.refresh():'';
+        });
+    }else if($('#material_adjust').is(':visible')){
+        $('#material_adjust_sheet').height($(window).height()-$('.header').height()-$('#projectGljToolsBar').height()+3);
+        if(materialAdjustObj.spread)materialAdjustObj.spread.refresh();
+    }
+
 }
 //从其他建设项目中复制中,建设项目的文件层次结构名称和顺序
 function getFileHierarchyInfo(treeData){
@@ -1142,12 +1166,13 @@ $(function () {
         let me = projectGljObject;
         $(e.relatedTarget.hash).removeClass('active');
         if(me.projectGljSpread==null){
-            me.initProjectGljSpread();
+            me.initSpreads();
         }
         me.unitPriceFileInit();
         me.initMixRatio();
+        me.initSheetViews();
         //projectObj.project.projectGLJ.calcQuantity(); 在工程量有更新的地方调用
-        me.refreshDataSheet();
+        me.refreshViewsData();
         loadProjectGljSize();
     });
     /*  $('#ration_link').on('shown.bs.tab', function (e) {
@@ -1358,7 +1383,9 @@ $(function () {
         $(this).addClass('active');
         let me = projectGljObject;
         me.displayType = filterType[this.id];
-        me.refreshDataSheet();
+        me.initSheetViews();
+        me.refreshViewsData();
+        loadProjectGljSize();
     });
 });
 

+ 21 - 5
web/building_saas/main/js/views/project_view.js

@@ -540,6 +540,13 @@ var projectObj = {
                 project.calcProgram.calcAndSave(node);
             } else {
                 if (node.sourceType === project.Bills.getSourceType()) {
+                    if(fieldName == "maxPrice"){
+                        if(value == null){
+                            value = "";
+                        }else {
+                            value = scMathUtil.roundToString(value,getDecimal("unitPrice", node))
+                        }
+                    }
                     project.Bills.updateField(node.source, fieldName, value, false);
                 } else if (node.sourceType === project.Ration.getSourceType()) {
                     project.Ration.updateField(node.source, fieldName, value);
@@ -960,7 +967,7 @@ var projectObj = {
                     // if (col.data.field.hasSubStr("common")){
                         if (col.data.field.hasSubStr(".totalFee"))
                             col.data.formatter = MainTreeCol.getNumberFormatter(decimalObj.ration.totalPrice, true);
-                        else if (col.data.field.hasSubStr(".unitFee"))
+                        else if (col.data.field.hasSubStr(".unitFee")||col.data.field.hasSubStr("maxPrice"))
                             col.data.formatter = MainTreeCol.getNumberFormatter(decimalObj.ration.unitPrice, true);
                     // }
 
@@ -1734,10 +1741,9 @@ var projectObj = {
             projectObj.onIsEstimateClick(node,info);
         }else if(fieldName == "evaluationProject"){
             projectObj.onEvaluationProjectClic(node,info);
-        }else if(fieldName == "mainBills"){
-            projectObj.onMainBillsClick(node,info);
+        }else if(fieldName == "mainBills"||fieldName == "outPutMaxPrice"){
+            projectObj.onCasCadeButtonClick(node,info,fieldName);
         }
-
     },
     onEvaluationProjectClic:function (node,info) {
         let checkboxValue = info.sheet.getCell(info.row, info.col).value();
@@ -1767,7 +1773,7 @@ var projectObj = {
             projectObj.project.projectGLJ.pGljUpdate(updateData);
         }
     },
-    onMainBillsClick:function (node,info) {//清单有三种状态,true,false,null。 打勾:true, 不打勾 false 子项有打勾和不打勾的情况 null
+   /* onMainBillsClick:function (node,info) {//清单有三种状态,true,false,null。 打勾:true, 不打勾 false 子项有打勾和不打勾的情况 null
         let checkboxValue = info.sheet.getCell(info.row, info.col).value();
         let cell = info.sheet.getCell(info.row, info.col), newval = true;
         if (checkboxValue == true) {
@@ -1776,6 +1782,16 @@ var projectObj = {
             newval = true;
         }
         projectObj.project.updateMainBills(node,newval);
+    },*/
+    onCasCadeButtonClick:function (node,info,fieldName) {
+        let checkboxValue = info.sheet.getCell(info.row, info.col).value();
+        let cell = info.sheet.getCell(info.row, info.col), newval = true;
+        if (checkboxValue == true) {
+            newval = false;
+        } else {
+            newval = true;
+        }
+        projectObj.project.updateCasCadeBills(node,newval,fieldName);
     },
     onSubcontractClick:function (node) {//点击分包费checkbox
         if (node.data.isSubcontract) node.data.isSubcontract = false;

+ 14 - 5
web/building_saas/report/js/jpc_output.js

@@ -147,10 +147,13 @@ let JpcCanvasOutput = {
                 validTxtLines = Math.floor((area[JV.IDX_RIGHT] - area[JV.IDX_LEFT]) / (dftFontHeight + JV.OUTPUT_OFFSET[JV.OFFSET_IDX_RIGHT] + JV.OUTPUT_OFFSET[JV.OFFSET_IDX_LEFT] + 4));
             }
 
-            function private_drawUnderline() {
+            function private_drawUnderline(underLineVal) {
                 //A. 暂不支持角度; B. 坐标已经translate
                 //1. 计算下划线的相关坐标
-                let width = ctx.measureText(val).width;
+                let width = ctx.measureText(underLineVal).width;
+                if (width > area[JV.IDX_RIGHT] - area[JV.IDX_LEFT]) {
+                    width = area[JV.IDX_RIGHT] - area[JV.IDX_LEFT];
+                }
                 let height = dftFontHeight;
                 // let startX = area[JV.IDX_LEFT], startY = area[JV.IDX_TOP], endX = area[JV.IDX_RIGHT], endY = area[JV.IDX_BOTTOM];
                 let startX = 0, startY = 0, endX = width, endY = startY;
@@ -189,9 +192,9 @@ let JpcCanvasOutput = {
 
             ctx.save();
             ctx.translate(output[0], output[1]);
-            if (font[JV.FONT_PROPS[5]] === 'T' && parseInt(font.FontAngle) === 0) {
-                private_drawUnderline();
-            }
+            // if (font[JV.FONT_PROPS[5]] === 'T' && parseInt(font.FontAngle) === 0) {
+            //     private_drawUnderline(val);
+            // }
             if (font.FontAngle === JV.VERTICAL_ANGLE) {
                 ctx.rotate(Math.PI/2);
             } else if (font.FontAngle === JV.ANTI_VERTICAL_ANGLE) {
@@ -199,6 +202,9 @@ let JpcCanvasOutput = {
             }
             if (validAreaTxtWidth >= ctx.measureText(val).width ||
                 (control && control.Shrink !== 'T' && validTxtLines < private_splitString(val, validAreaTxtWidth, ctx)) ) {
+                if (font[JV.FONT_PROPS[5]] === 'T' && parseInt(font.FontAngle) === 0) {
+                    private_drawUnderline(val);
+                }
                 ctx.fillText(val, 0, 0);
             } else {
                 while (true) {
@@ -228,6 +234,9 @@ let JpcCanvasOutput = {
                             ctx.translate(-output[0], -output[1]);
                             inner_setupControl(newArea, dftFontHeight, output);
                             ctx.translate(output[0], output[1]);
+                            if (font[JV.FONT_PROPS[5]] === 'T' && parseInt(font.FontAngle) === 0) {
+                                private_drawUnderline(actLines[lIdx]);
+                            }
                             ctx.fillText(actLines[lIdx], 0, 0);
                         }
                         break;

+ 2 - 1
web/building_saas/report/js/rpt_print.js

@@ -237,7 +237,8 @@ function buildText(destRst, cell, font, control, offsetX, offsetY, adjustY, canv
                 x +"' y='" + y + "' text-anchor='" + text_anchor + "' xml:space='preserve'" + HtoVStr + ">" + innerTxt + "</text>");
         }
         let actLines = private_splitString(textValue, (area[JV.IDX_RIGHT] - area[JV.IDX_LEFT]), ctx);
-        if (actLines.length === 1 || (control && control.Shrink !== 'T')) {
+        let validTxtLines = Math.floor((area[JV.IDX_BOTTOM] - area[JV.IDX_TOP]) / (dftFontHeight + JV.OUTPUT_OFFSET[JV.OFFSET_IDX_BOTTOM] + JV.OUTPUT_OFFSET[JV.OFFSET_IDX_TOP] + 4));
+        if (actLines.length === 1  || (control && control.Shrink !== 'T' && validTxtLines < actLines)) {
             inner_build_text(textValue, area);
         } else {
             while (true) {