/**
 * Created by zhang on 2018/3/13.
 */
projectGljObject={
    showTag:'ration',//mixRatio/machine
    showMixRatioMark:'',
    displayType:filterType.ALL,
    mixRatioType: [gljType.CONCRETE, gljType.MORTAR, gljType.MIX_RATIO,gljType.MAIN_MATERIAL],
    machineType: [gljType.GENERAL_MACHINE],
    projectGljSetting:{},
    projectGljSpread:null,
    projectGljSheet:null,
    materialTreeSheet:null,
    projectGljSheetData:[],
    mixRatioSetting:{},
    relatedRationSetting:{
      header:[
        {headerName: "编码", headerWidth: 100, dataCode: "code", dataType: "String"},
        {headerName: "名称", headerWidth: 180, dataCode: "name", dataType: "String"},
        {headerName: "单位", headerWidth: 50, dataCode: "unit", dataType: "String",hAlign: "center"},
        {headerName: "工程量", headerWidth: 65, dataCode: "quantity", dataType: "Number", hAlign: "right",decimalField: "ration.quantity"},
        {headerName: "单价", headerWidth: 65, dataCode: "feesIndex.common.unitFee", dataType: "Number", hAlign: "right",decimalField: "ration.unitPrice"}
    ],
    view: {
        lockColumns: [0,1,2,3,4]//,
        //colHeaderHeight:30
      }
    },
    materialTreeSetting:{
        "emptyRows":0,
        "headRows":1,
        "headRowHeight":[21],
        "defaultRowHeight": 21,
        "treeCol": 0,
        "cols":[]
    },
    materialSetting:{
        header:[
            {headerName: "编码", headerWidth: 200, dataCode: "code", dataType: "String"},
            {headerName: "名称", headerWidth: 160, dataCode: "name", dataType: "String"},
            {headerName: "规格型号", headerWidth: 160, dataCode: "specs", hAlign: "left", dataType: "String"},
            {headerName: "单位", headerWidth: 45, dataCode: "unit", hAlign: "center", dataType: "String"},
            {headerName: "定额价", headerWidth: 70, dataCode: "basePrice", hAlign: "right", dataType: "Number",validator:"number"},//,decimalField:'glj.unitPrice'
            {headerName: "预算价", headerWidth: 70, dataCode: "marketPrice", hAlign: "right", dataType: "Number",validator:"number"},//,decimalField:"glj.unitPrice"
            {headerName: "总消耗量", headerWidth: 70, dataCode: "quantity", hAlign: "right", dataType: "Number",decimalField:'glj.quantity'},
            {headerName: "三材系数", headerWidth: 70, dataCode: "materialCoe", hAlign: "right", dataType: "Number",validator:"number"},//,decimalField:'material'
            {headerName: "三材量", headerWidth: 100, dataCode: "materialQuantity", hAlign: "right", dataType: "Number",decimalField:'glj.quantity'},
            {headerName: "三材类别", headerWidth: 70, dataCode: "materialType", hAlign: "center", dataType: "String",cellType:'comboBox',editorValueType:true,options:materialComboMap}
        ],
        view: {
            lockColumns: [0,1,2,3,6,8]
        }
    },
    mixRatioSpread:null,
    mixRatioSheet:null,
    mixRatioData:[],
    usedTenderList:[],
    usedUnitPriceInfo:null,
    displayTypeMap:[
        {ID:'LABOUR',text:'人工'},
        {ID:'GENERAL_MATERIAL',text:'材料'},
        {ID:'GENERAL_MACHINE',text:'机械'}
        /*{ID:'MAIN_MATERIAL',text:'主材'},
        {ID:'EQUIPMENT',text:'设备'}*/
    ],
    initProjectGljSpread:function () {
        if(!this.projectGljSpread){
            this.projectGljSpread = SheetDataHelper.createNewSpread($("#project_glj_sheet")[0],2);
            sheetCommonObj.spreadDefaultStyle(this.projectGljSpread);
        }
        this.projectGljSpread.bind(GC.Spread.Sheets.Events.RangeChanged, this.onProjectGljRangeChange);
        this.projectGljSpread.getActiveSheet().options.frozenlineColor = '#ababab';
        this.initProjectGljSheet();
        this.initMaterialTreeSheet();
        //打开别人分享的项目，只读
        if(projectReadOnly){
            //锁定逻辑走disabledSpread里的
            if(this.projectGljSetting.view.lockColumns){
                this.projectGljSetting.view.lockColumns = null;
            }
            disableSpread(this.projectGljSpread);  //disableRightMenu("project_glj_sheet",this.projectGljSpread,this.rightClickCallback);
        }else {
            this.initProjectGljRightClick();
        }
    },
    initProjectGljSheet:function () {
        this.projectGljSheet = this.projectGljSpread .getSheet(0);

        this.initSheet(this.projectGljSheet,this.projectGljSetting);
        this.projectGljSheet.bind(GC.Spread.Sheets.Events.SelectionChanged,this.onProjectGljSelectionChange);
        this.projectGljSheet.bind(GC.Spread.Sheets.Events.EditStarting,this.onProjectGljEditStarting);
        this.projectGljSheet.bind(GC.Spread.Sheets.Events.CellDoubleClick, this.onProjectGljDoubleClick);
        this.projectGljSheet.name('projectGljSheet');
        this.projectGljSheet.setRowHeight(0, 36, 1);
    },
    initMixRatio:function () {
        let me = projectGljObject;
        if(me.mixRatioSpread==null){
            me.initMixRatioSpread();
            if(!projectReadOnly){
                me.initMixRatioRightClick();
            }
        }
    },
    initMixRatioSpread:function () {
        this.mixRatioSpread = SheetDataHelper.createNewSpread($("#mix_ratio_sheet")[0],2);
        sheetCommonObj.spreadDefaultStyle(this.mixRatioSpread);
        this.mixRatioSheet = this.mixRatioSpread.getSheet(0);
        this.initSheet(this.mixRatioSheet,this.mixRatioSetting);
        this.mixRatioSheet.name('mixRatioSheet');
        this.mixRatioSheet.bind(GC.Spread.Sheets.Events.EditStarting,this.onMixRatioEditStarting);
        this.mixRatioSheet.bind(GC.Spread.Sheets.Events.RangeChanged, this.onMixRatioRangeChange);

        this.initRelatedRationSheet();
        if(projectReadOnly){
            if(this.mixRatioSetting.view.lockColumns){
                this.mixRatioSetting.view.lockColumns = null;
            }
            disableSpread(this.mixRatioSpread);
        }
    },
    initRelatedRationSheet:function(){
      this.relatedRationSheet = this.mixRatioSpread.getSheet(1); 
      sheetCommonObj.initSheet(this.relatedRationSheet, this.relatedRationSetting, 30);
      this.relatedRationSheet.name('relatedRation');
      this.relatedRationSheet.bind(GC.Spread.Sheets.Events.CellDoubleClick, this.onRelatedRationDoubleClick);
      //this.mixRatioSheet.bind(GC.Spread.Sheets.Events.RangeChanged, this.onMixRatioRangeChange);
    },

    initMaterialTreeSheet:function () {
        this.materialTreeSheet = this.projectGljSpread.getSheet(1);
        this.materialTreeSetting = this.createMaterialTreeSheetSetting();
        this.materialTree = cacheTree.createNew(this);
        this.materialTreeController = TREE_SHEET_CONTROLLER.createNew(this.materialTree, this.materialTreeSheet, this.materialTreeSetting);
        this.materialTreeController.bind(TREE_SHEET_CONTROLLER.eventName.treeSelectedChanged, this.onSelectionChange);
        this.materialTreeSheet.bind(GC.Spread.Sheets.Events.EditStarting,this.onProjectGljEditStarting);
        this.materialTreeSheet.bind(GC.Spread.Sheets.Events.ValueChanged, this.onProjectGLJValueChange);
        this.materialTreeSheet.name('materialTreeSheet');
        if(projectReadOnly && this.materialSetting.view.lockColumns){
            if(this.materialSetting.view.lockColumns){
                this.materialSetting.view.lockColumns = null;
            }
        }
    },
    createMaterialTreeSheetSetting:function () {
        return sheetCommonObj.transferToTreeSetting(this.materialSetting,this.materialTreeSetting);
    },
    unitPriceFileInit:function() {
        let me = this;
        let projectGLJ = projectObj.project.projectGLJ;
        let data = projectGLJ.datas;
        me.usedTenderList = data.usedTenderList !== undefined ? data.usedTenderList : [];
        me.usedUnitPriceInfo = data.constData.usedUnitPriceInfo !== undefined ?
            data.constData.usedUnitPriceInfo : {};
        $("#current-name").text(me.usedUnitPriceInfo.name);
        let usedCount = me.usedTenderList.length <= 0 ? 1 : me.usedTenderList.length;
        $("#used-project-count").text(usedCount);
        $("#editUnitFile").attr("href",`/unitPrice/index/${me.usedUnitPriceInfo.id}`)
    },
    getUsedTenderInfo:function() {
        return "人材机单价的变化，将自动影响以下单位工程造价：<br>"+projectGljObject.usedTenderList.join("<br>");
    },
    filterLibGLJForMixRatio:function () {
        let me = this;
        if(me.selectedProjectGLJ){
            let showTypes = [];
            if(me.selectedProjectGLJ.type == gljType.MAIN_MATERIAL){//对于主材，只显示没有组成物并且除了自已的主材
                showTypes = [gljType.MAIN_MATERIAL];
            }else if(_.includes(gljUtil.hasCompMaterial,me.selectedProjectGLJ.type)){//混凝土、砂浆、配合比
                showTypes = [gljType.GENERAL_MATERIAL];
            }else if(_.includes(gljUtil.hasCompMachine,me.selectedProjectGLJ.type)){//me.selectedProjectGLJ.type == gljType.GENERAL_MACHINE//机械中有组成物的类型
                showTypes = gljUtil.machineComposition;
            }
            gljOprObj.gljLibSheetData = _.filter(gljOprObj.gljLibSheetData, function (item) {
                if(me.selectedProjectGLJ.type == gljType.MAIN_MATERIAL){
                    let p_index = gljOprObj.getIndex(me.selectedProjectGLJ,gljKeyArray);
                    let i_index = gljOprObj.getIndex(item,gljLibKeyArray);
                    return item.gljType == gljType.MAIN_MATERIAL &&item.component.length == 0 && p_index!=i_index
                }else {
                    return _.includes(showTypes,item.gljType);
                }
            });
        }
    },
    addMixRatio:async function () {
      let me = this, projectGLJ = projectObj.project.projectGLJ;
      for(let mix of me.mixRatioData){
        let m_key = gljUtil.getIndex(mix);
        _.remove(gljOprObj.GLJSelection,n =>{
          return m_key == n;
        });
      }
      await me.addMixRatioFromLib(gljOprObj.GLJSelection,()=>{
        me.showMixRatioData();//这里添加的组成物的消耗量默认都是0，所以对父工料机的价格不会有影响，不用触发计算
        projectGLJ.loadData(function () {
            me.showProjectGljData();
            gljOprObj.showRationGLJSheetData();
            me.onUnitFileChange(me.selectedProjectGLJ);
        });
      });
    },
    addMixRatioFromLib:async function(selections,callback){
      let gljList = [],allGLJ = gljOprObj.AllRecode;
      let url = "/glj/add-ratio";
      let result = null;
      if(selections.length == 0) {
          return;
      }
      try {
        for(let glj of allGLJ){
        let i_key = gljUtil.getIndex(glj,gljLibKeyArray);
        if(_.includes(selections,i_key)){
            let pglj = {
                glj_id: glj.ID,
                name: glj.name,
                code: glj.code,
                original_code: glj.code,
                unit: glj.unit,
                specs: glj.specs,
                base_price: glj.basePrice,
                market_price: glj.basePrice,
                shortName: glj.shortName,
                type: glj.gljType,
                model:glj.model,
                adjCoe: glj.adjCoe,
                from:'std',
                repositoryId:glj.repositoryId,
                materialType:glj.materialType,
                materialCoe:glj.materialCoe,
                grossWeightCoe:glj.grossWeightCoe,
                purchaseStorageRate:glj.purchaseStorageRate,
                offSiteTransportLossRate:glj.offSiteTransportLossRate,
                handlingLossRate:glj.handlingLossRate
            };
            if(typeof projectObj !== 'undefined')  pglj.project_id = projectObj.project.ID();
            if (glj.hasOwnProperty("compilationId")) {
                pglj.from = "cpt";
                if (glj.code.indexOf('-') != -1) {//这条工料机是用户通过修改名称、规格、型号等保存到补充工料机库的
                    pglj.original_code = glj.code.split('-')[0];//取-前的编号作为原始编号
                }
            }
            gljList.push(pglj);
          }
        }
        gljList = _.sortByAll(gljList, ['type', 'code']);
        if(gljList.length == 0) return;
        let parentInfo ={};
        if(typeof unitPriceObj !== 'undefined'){
          url = "/unitPrice/addMixRatio";
          pdata = unitPriceObj.getSelectedUnitPrice();
          parentInfo = {
            unit_price_file_id:pdata.unit_price_file_id,
            connect_key:gljUtil.getIndex(pdata)
          };
        }else{
          parentInfo = {
            unit_price_file_id:projectObj.project.property.unitPriceFile.id,
            connect_key:gljOprObj.getIndex(projectGljObject.selectedProjectGLJ,gljKeyArray)
          };
        }

        $.bootstrapLoading.start();
        result= await ajaxPost(url,{gljList:gljList,parentInfo:parentInfo})
        if(callback) callback(result);
      } catch (error) {
        alert(error);
        console.log(error);
      }
      $.bootstrapLoading.end();
      return result;
    },
    getSelectedProjectGLJ:function () {
        let me = this,data = null;
        let sheet = me.projectGljSpread.getActiveSheet();
        if(sheet.name() == 'projectGljSheet'){//projectGljSheet/materialSheet 工料机汇总和三材汇总表
            let sel = me.projectGljSheet.getSelections()[0];
            let srow = sel.row == -1||sel.row == ""?0:sel.row;
            if(me.projectGljSheetData.length>srow){
                data = me.projectGljSheetData[srow];
            }
        }else if(sheet.name() == 'materialTreeSheet'){
            if(this.materialTree.selected){
                data = this.materialTree.selected.data;
            }
        }
        return data;
    },

    showMixRatioData:function () {
        let me = this,gljId = null,gljType = null;
        if(!$('#mixRatio-nav').hasClass('active')) return;
        me.mixRatioSpread.setActiveSheetIndex(0);
        let oldSel = me.mixRatioSheet.getSelections()[0];
        let projectGLJData = me.getSelectedProjectGLJ();
        if(projectGLJData){
            gljId = projectGLJData.id;
            gljType = projectGLJData.type;
        }
        if(compositionTypes.indexOf(gljType)==-1){//如果不是有组成物的类型，工料机id设置为空，组成物表设置为空
            gljId = null
        }
        projectObj.project.projectGLJ.getRatioData(gljId,function (data) {
            if(gljId !== projectObj.project.projectGLJ.getRatioId){//两个id不一致说明不是最新的请求，不用往下执行。
                return;
            }
            let ratioList =[];
            for(let glj of data){
                ratioList.push(me.getMixRatioSheetData(glj)) ;
            }
            ratioList = gljUtil.sortMixRatio(ratioList);
            me.mixRatioData = ratioList;
            me.mixRatioSheet.setRowCount(0);
            sheetCommonObj.showData(me.mixRatioSheet, me.mixRatioSetting,me.mixRatioData);
            me.mixRatioSheet.setRowCount(me.mixRatioData.length);
            me.mixRatioSheet.setSelection(oldSel.row==-1?0:oldSel.row,oldSel.col,oldSel.rowCount,oldSel.colCount);
        })
    },
    showRelatedRationDatas:function(){
      let me = this,gljId = null,gljType = null;
      if(!$('#ration-nav').hasClass('active')) return;
      me.mixRatioSpread.setActiveSheetIndex(1);
      let projectGLJData = me.getSelectedProjectGLJ();
      let rationIDMap = {};
      let rations = [];
      if(projectGLJData){
         for(let rg of projectObj.project.ration_glj.datas){
            if(rg.projectGLJID == projectGLJData.id) rationIDMap[rg.rationID] = true;
         } 
         for(let r of projectObj.project.Ration.datas){
            if(rationIDMap[r.ID] || (r.subType == rationType.gljRation && r.projectGLJID== projectGLJData.id)){
              rations.push(r);
            }
         } 
      }
      this.relatedRationSheetData = rations;
      sheetCommonObj.showData(me.relatedRationSheet, me.relatedRationSetting,rations);
      me.relatedRationSheet.setRowCount(rations.length);
    },

    getMixRatioSheetData:function (glj) {
        let data ={
            id:glj.id,
            mix_ratio_id:glj.ratio_data.id,
            code:glj.code,
            name:glj.name,
            specs:glj.specs,
            unit:glj.unit,
            type:glj.type,
            short_name:projectObj.project.projectGLJ.getShortNameByID(glj.type),
            consumption:glj.ratio_data.consumption,
            unit_price:glj.unit_price,
            connect_key:glj.ratio_data.connect_key
        };
        gljOprObj.setGLJPrice(data,glj);
        return data;
    },
    onProjectGljEditStarting:function (sender, args) {
        let me = projectGljObject;
        let row = args.row;
        let col = args.col;
        if(me.projectGljEditChecking(row,col)==false){
            args.cancel = true;
        }
    },
    projectGljEditChecking:function (row,col,isPaste=false) {//return false表示不能编辑
        let me = projectGljObject;
        let data = null, setting=null;
        let sheet = me.projectGljSpread.getActiveSheet();
        if(sheet.name() ==  'projectGljSheet'){
            if(row>=me.projectGljSheetData.length) return false;
            data = me.projectGljSheetData[row];
            setting = me.projectGljSetting;
        }else if(sheet.name() ==  'materialTreeSheet'){
            data = me.materialTree.selected.data;
            setting = me.materialSetting;
            let notEditId= ['GC','GJ','MC','SN','SZ'];
            if(notEditId.indexOf(data.id)!= -1){
                return false;
            }
        }
        let dataCode = setting.header[col].dataCode;
        let lockColumns = setting.view.lockColumns;

        if(lockColumns.indexOf(col)!= -1){
            return false;
        }

        if(isPaste == false &&(dataCode=='is_adjust_price'||dataCode=='is_evaluate'||dataCode=='is_main_material')){//除了粘贴，拖动填充等操作，其它的都不能编辑
            return false;
        }
        if(dataCode=='basePrice'||dataCode=='marketPrice'||dataCode=='supply'){//有组成物时，市场单价、定额价、供货方式不能修改
            if((dataCode=='basePrice'||dataCode=='marketPrice')&&gljUtil.isConcreteType(data.type)){//混凝土，浆砂，配合比，不能修改市场单价，定额价
                return false;
            }
            if (data.ratio_data  && data.ratio_data.length > 0){
                return false;
            }
            if(dataCode=='basePrice'&&data.is_add!=1){//如果不是新增，定额价不可修改。
                return false;
            }
            if(dataCode=='marketPrice' && data.calcMaterial == 1) return false //有材料计算时不能修改

        }
        if(dataCode == 'supply_quantity'){
            if (data.supply != 1) {// 如果为部分甲供则甲供数量需要可编辑,其它的都不能编辑
                return false;
            }
        }
        if(dataCode == 'materialCoe'){//三材类别为空时，三材系数应只读，不允许输入。
            if(data.materialType == undefined || data.materialType == null||data.materialType==''){
                return false;
            }
        }
        return true;
    },
    onSelectionChange:function (){
        let me = projectGljObject;
        me.showMixRatioData();
        me.materialTreeSheet.repaint();
    },
    onProjectGljDoubleClick:function (sender,args) {
        let me = projectGljObject;
        let recode = me.projectGljSheetData[args.row];
        let dataCode = me.projectGljSetting.header[args.col].dataCode;
        if(dataCode=='name'&& recode && gljUtil.isMaterialType(recode.type)) projectObj.project.projectGLJ.updateCalcMaterial(recode,'calcMaterial',1);
    },
    onRelatedRationDoubleClick:function (sender,args) {
      let me = projectGljObject;
      let record = me.relatedRationSheetData[args.row];
      $("#tab_zaojiashu").click();
      locateObject.locateNode(record.ID);
    },
    setSelectionWhenMaterialChange:function(material){
      if(material){
        let i = _.findIndex(this.projectGljSheetData,{id:material.id})
        if(i != -1){
          let os = this.projectGljSheet.getSelections();
          let ns = [{col:os[0].col,colCount:1,row:i,rowCount:1}]
          this.projectGljSheet.setSelection(ns[0].row,ns[0].col,ns[0].rowCount,ns[0].colCount);
          this.projectGljSheet.showRow(i, GC.Spread.Sheets.VerticalPosition.center);
          this.onProjectGljSelectionChange({},{newSelections:ns,oldSelections:os},true);
        }


      }
    },
    onProjectGljSelectionChange:function (sender, args,fromMaterial=false) {
        let me = projectGljObject;
        console.log(args)
        let newSel = args.newSelections[0];
        let oldSel = args.oldSelections?args.oldSelections[0]:{};
        me.projectGljSheet.suspendPaint();
        me.projectGljSheet.suspendEvent();
        if(newSel.row != oldSel.row){
            let style = gljOprObj.getSelStyle(true,{});
            me.projectGljSheet.setStyle(newSel.row, -1, style);
            let orow = oldSel.row==''||oldSel.row==-1?0:oldSel.row;
            if(me.projectGljSheetData[orow]){
              let tstyle = gljOprObj.getSelStyle(false,{},me.projectGljSheetData[orow].bgColour);
              me.projectGljSheet.setStyle(orow, -1, tstyle);
              me.projectGljRowChang(fromMaterial);
            }
        }else{
          me.projectGljSheet.repaint();
        }
        me.projectGljSheet.resumeEvent();
        me.projectGljSheet.resumePaint();
    },
    projectGljRowChang:function(fromMaterial){
        let me = projectGljObject;
        let sel = me.mixRatioSheet.getSelections()[0];
        sel.row = -1;
        sel.col = 0;
        sel.rowCount = 1;
        sel.colCount = 1;
        me.showMixRatioData();
        me.showRelatedRationDatas();
        if(fromMaterial != true) materialCalcObj.showDatas();
    },
    rightClickCallback:function (row) {
        let me = projectGljObject;
        let sheet =  me.projectGljSpread.getActiveSheet();
        if(sheet.name() == 'projectGljSheet'){
            me.projectGljRowChang(row);
        }else if(sheet.name() == 'materialTreeSheet'){
            me.materialTreeController.setTreeSelected(me.materialTreeController.tree.items[row]);
        }
    },
    onProjectGljRangeChange:function (sender,info) {
        let me = projectGljObject;
        let changeInfo=[];
        let canChange = true;
        if(info.action == GC.Spread.Sheets.RangeChangedAction.clear){
            if(me.projectGljEditChecking(info.row,info.col) == false){
                canChange = false;
            }else {
                info.newValue = null;
                me.onProjectGLJValueChange(sender,info);
                return ;
            }
        }
        for(let c of info.changedCells){
            let value=  info.sheet.getCell(c.row, c.col).text();
            changeInfo.push({row:c.row,col:c.col,value:value});
            if(me.projectGljEditChecking(c.row,c.col,true)==false){//如果不能编辑
                canChange = false;
                break;
            }
            if (!me.checkData(c.col,me.projectGljSetting,value)) {
                alert('输入的数据类型不对，请重新输入!');
                canChange = false;
                break;
            }
        }
        if(canChange == false){//恢复原来的值
            info.sheetName =="materialTreeSheet"?me.showMaterialTreeData():me.showProjectGljData();
        }else if(info.sheetName =="projectGljSheet"){
            me.batchUpdateProjectGLJ(changeInfo,info.sheetName);
        }
    },
    onMixRatioEditStarting:function (sender,info) {
        let me = projectGljObject,row = info.row, col = info.col;
        let parentSheet =  me.projectGljSpread.getActiveSheet();
        let prow = parentSheet.getActiveRowIndex();//取父机械或组成物的下标
        let prowData = parentSheet.name() == 'projectGljSheet'?me.projectGljSheetData[prow]:me.materialTree.items[prow].data;
        console.log(prowData);
        if(gljUtil.isConcreteType(prowData.type))  info.cancel = true;
    },
    onMixRatioRangeChange:function (sender,info){
        let me = projectGljObject;
        let canChange = true;
        let changeInfo=[];
       /*  if (info.action == GC.Spread.Sheets.RangeChangedAction.clear) {
            info.newValue = 0;
            me.onMixRatioValueChange(sender,info);
            info.sheet.getCell(info.row, info.col).text(0);
            return ;
        } */
        for(let c of info.changedCells){
            let value = info.sheet.getCell(c.row, c.col).text();
            if(_.isEmpty(value)) value = 0;
            if (!me.checkData(c.col,me.mixRatioSetting,value)) {
                alert('输入的数据类型不对，请重新输入!');
                canChange = false;
                break;
            }else {
                changeInfo.push({row:c.row,col:c.col,value:value});
            }
        }
        if(canChange == false) me.showMixRatioData();//数据类型不对
            
        
        if(changeInfo.length > 0)me.batchUpdateConsumption(changeInfo);
    },
    batchUpdateProjectGLJ:function(changeInfo,sheetName){
        let projectGLJ = projectObj.project.projectGLJ;
        let me = projectGljObject;
        let propertyCells=[],priceCells=[];
        let setting = sheetName =="materialTreeSheet"?me.materialSetting:me.projectGljSetting;
        for(let c of changeInfo){
            c.dataCode = setting.header[c.col].dataCode;
            if(c.dataCode == 'basePrice'||c.dataCode=='marketPrice'){
                priceCells.push(c);
            }else {
                propertyCells.push(c);
            }
        }
        me.batchUpdateGLJProperty(propertyCells,sheetName,function () {
            //价格属于单价文件表，如果与项目工料机的其它属性一起的话计算起来会比较复杂，同时出现价格与其它属性一起更新的情况也会比较少;
            projectGLJ.batchUpdatePrice(priceCells,sheetName,function (impactList) {
                me.refreshBySheetName(sheetName);
                gljOprObj.refreshView();
            });
        });
    },
    refreshBySheetName:function (sheetName) {
        let me = projectGljObject;
        if(sheetName =="projectGljSheet"){
            me.showProjectGljData();
        }else if(sheetName =="materialTreeSheet"){
            me.showMaterialTreeData();
        }
    },
    batchUpdateGLJProperty:function (changeInfo,sheetName,callback) {
        let me = projectGljObject,updateMap = {};
        let projectGLJ = projectObj.project.projectGLJ;
        for(let c of changeInfo){
            let recode = sheetName =="materialTreeSheet"?me.materialTree.items[c.row].data:me.projectGljSheetData[c.row];
            if(recode[c.dataCode] == c.value){
                continue;
            }
            me.getUpdateData(recode.id,c.value,c.dataCode,recode.quantity,updateMap);
        }
        if(_.isEmpty(updateMap)){
            callback?callback():'';
            return;
        }
        projectGLJ.batchUpdateGLJProperty(updateMap,callback);
    },
    getUpdateData :function (id,value,dataCode,quantity,updateMap) {
        let me = projectGljObject;
        let supplyMap = {"自行采购":0,"部分甲供":1,"完全甲供":2,"甲定乙供":3};
        let materialMap = {"钢材":1,"钢筋":2,"木材":3,"水泥":4,"标准砖":5};
        let data = updateMap[id]?updateMap[id]:{};
        //供货方式 和三材类型 粘贴和填充过来的数据，要做对应转换，因为这里value只是中文文本，并不是实际的值
        // 如果是供货方式则需要处理数据
        if (dataCode === 'supply') {
            if(supplyMap[value]!==undefined||supplyMap[value]!==null){
                value = supplyMap[value];
            }
            data.supply_quantity = me.getSupplyQuantity(value,quantity);
        }
        if(dataCode === 'supply_quantity'){//修改数量需做4舍5入
            value =  scMathUtil.roundForObj(value,getDecimal('glj.quantity'));
        }
        if(dataCode === 'is_evaluate'||dataCode === 'is_adjust_price'||dataCode === 'is_main_material'){
            value = value? 1:0;
        }
        if(dataCode === 'materialType'){//三材类型要做对应转换，因为这里value只是中文文本，并不是实际的值
            if(materialMap[value]!==undefined||materialMap[value]!==null){
                value =  materialMap[value];
            }
            if(value == null || value==""){//删除三材类别时，清空三材系数
                value = null;
                data.materialCoe = null;
            }
        }
        if(dataCode == 'materialCoe'){
            value = scMathUtil.roundForObj(value,getDecimal("material"));
        }

        data[dataCode] = value ;
        updateMap[id] = data;
    },
    batchUpdateConsumption:function(changeInfo){
        let projectGLJ = projectObj.project.projectGLJ;
        let me = projectGljObject;
        let updateMap = {},updateData = [],parentBasePrice = 0,parentMarketPrice = 0;
        let parentKey = '',unit_price_file_id=null;
        for(let c of changeInfo){
            let record = me.mixRatioData[c.row];
            let value = scMathUtil.roundForObj(c.value,getDecimal("glj.quantity"));
            updateMap[record.mix_ratio_id] = {consumption: value,record:record };
            updateData.push({type:'mix_ratio',query:{id:record.mix_ratio_id},doc:{consumption:value}});
            parentKey = record.connect_key;
            unit_price_file_id = record.unit_price.unit_price_file_id;
        }
        if(!gljUtil.isConcreteType(parseInt(parentKey.split("|-|")[4]))){//父类型不属于混凝土浆砂配合比，才要计算
            for(let sub of me.mixRatioData){
                let marketPrice = scMathUtil.roundForObj(sub.unit_price.market_price,getDecimal("process"));
                let basePrice = scMathUtil.roundForObj(sub.unit_price.base_price,getDecimal("process"));
                let consumption =  updateMap[sub.mix_ratio_id]?updateMap[sub.mix_ratio_id].consumption:scMathUtil.roundForObj(sub.consumption,getDecimal("glj.quantity"));
                parentMarketPrice = scMathUtil.roundForObj(marketPrice*consumption + parentMarketPrice,getDecimal("process"));
               // parentBasePrice = scMathUtil.roundForObj(basePrice*consumption + parentBasePrice,getDecimal("process"));
            }
        }
       // parentBasePrice = scMathUtil.roundForObj(parentBasePrice,getDecimal("glj.unitPrice"));
        parentMarketPrice = scMathUtil.roundForObj(parentMarketPrice,getDecimal("glj.unitPrice"));
        let parentData = me.getSelectedProjectGLJ();
        if(parentData){  //计算受影响的综合电价
            let ext = {};
            ext[parentData.id] = {marketPrice:parentMarketPrice};
            let elecP = electrovalenceObj.clacNewElecPrice(ext);
            if(elecP){
                updateData.push({type:'unitPrice',projectGLJID:elecP.projectGLJID,query:{id:elecP.id},doc:elecP.doc});
            }
            updateData.push({type:'unitPrice',isParent:true,projectGLJID:parentData.id,query:{id:parentData.unit_price.id},doc:{market_price:parentMarketPrice}});//base_price:parentBasePrice,
        }

       // updateData.push({type:'parent',connect_key:parentKey,base_price:parentBasePrice,market_price:parentMarketPrice,unit_price_file_id:unit_price_file_id});
        projectGLJ.batchUpdateConsumption(updateData,updateMap,async function () {
            //更新人材机汇总表
            me.refreshDataSheet();
            let materialGljList  = await projectGLJ.calcAllMaterialWhenChange();
            if(materialGljList.length == 0)me.onUnitFileChange(true);
            gljOprObj.refreshView();
        });

    },
    showProjectGljData:function () {
        this.projectGljSpread.setActiveSheetIndex(0);
        let sel = this.projectGljSheet.getSelections()[0];
        let oldData = sel.row<this.projectGljSheetData.length?this.projectGljSheetData[sel.row]:"";
        let projectGljSheetData = [];
        let gljList = projectObj.project.projectGLJ.datas.gljList;
        gljList = this.filterProjectGLJ(gljList);
        gljList = sortProjectGLJ(gljList);
        for(let glj of gljList){
            projectGljSheetData.push(this.getSheetDataByGLJ(glj));
        }
        this.projectGljSheetData = projectGljSheetData;
        this.projectGljSheet.setRowCount(this.projectGljSheetData.length);
        sheetCommonObj.showData(this.projectGljSheet, this.projectGljSetting,this.projectGljSheetData);
        //this.projectGljSheet.setRowCount(this.projectGljSheetData.length);
        sel.row = oldData?_.findIndex(this.projectGljSheetData,{'id':oldData.id}):0;
        this.projectGljSheet.setSelection(sel.row==-1?0:sel.row,sel.col,sel.rowCount,sel.colCount);
    },
    showMaterialTreeData:function () {
        this.projectGljSpread.setActiveSheetIndex(1);
        let sel = this.materialTreeSheet.getSelections()[0];
        let oldNodeID = this.materialTree.selected?this.materialTree.selected.data.id:"";
        let gljList = projectObj.project.projectGLJ.datas.gljList;
        gljList = _.sortByAll(gljList, [ 'code']);
        this.createMaterialTree(gljList);
        this.materialTreeController.showTreeData();
        let newNode = this.materialTree.getNodeByID(oldNodeID);
        sel.row = newNode?newNode.serialNo():-1;
        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]);
    },
    refreshDataSheet:function () {
        let me = projectGljObject;
        if(!me.projectGljSpread)  return;
        let quantityCol = _.findIndex(me.projectGljSetting.header,function (header) {
            return header.dataCode ==  'quantity'|| header.dataCode == 'techQuantity' || header.dataCode =='subdivisionQuantity';
        });
        if(me.displayType == filterType.FBFX){//分部分项人材机，将“总消耗量”替换显示为“分部分项总消耗量”。
            me.projectGljSetting.header[quantityCol].dataCode = 'subdivisionQuantity';
            if(me.projectGljSheet) me.projectGljSheet.setValue(0, quantityCol, "分部分项总消耗量", GC.Spread.Sheets.SheetArea.colHeader);
        }else if(me.displayType == filterType.TECH) {//措施项目人材机，将“总消耗量”替换显示为“措施项目总消耗量”。
            me.projectGljSetting.header[quantityCol].dataCode = 'techQuantity';
            if(me.projectGljSheet) me.projectGljSheet.setValue(0, quantityCol, "措施项目总消耗量", GC.Spread.Sheets.SheetArea.colHeader);
        }else {
            me.projectGljSetting.header[quantityCol].dataCode = 'quantity';
            if(me.projectGljSheet) me.projectGljSheet.setValue(0, quantityCol, "总消耗量", GC.Spread.Sheets.SheetArea.colHeader);
        }
        if(me.displayType == filterType.SCHZ){//三材汇总树节点
            me.showMaterialTreeData();
        }else {
            me.showProjectGljData();
            me.showMixRatioData();
            me.showRelatedRationDatas();
        }
    },
    createMaterialTree:function (gljList) {
        let me = projectGljObject;
        let q_decimal = getDecimal("glj.quantity");
        let GC = {id:'GC',name:materialType[materialTypeMap.GC],code:'GC',unit:'t',ParentID:-1,NextSiblingID:'MC'};
        let GJ = {id:'GJ',name:materialType[materialTypeMap.GJ],code:'GJ',unit:'t',ParentID:'GC',NextSiblingID:-1};
        let MC = {id:'MC',name:materialType[materialTypeMap.MC],code:'MC',unit:'m3',ParentID:-1,NextSiblingID:'SN'};
        let SN = {id:'SN',name:materialType[materialTypeMap.SN],code:'SN',unit:'t',ParentID:-1,NextSiblingID:'SZ'};
        let SZ = {id:'SZ',name:materialType[materialTypeMap.SZ],code:'BZZ',unit:'千块',ParentID:-1,NextSiblingID:-1};
        let rootDatas= [GC,GJ,MC,SN,SZ];
        let parentMap = {};
        let sumMap = {};
        this.materialTree.nodes={},this.materialTree.selected = null,this.materialTree.roots = [],this.materialTree.items=[];
        for(let r of rootDatas){
            let baseNode = null;
            if(r.id == 'GJ'){
                baseNode = createMaterialNode(r,parentMap['GC'],null);//钢筋的父节点为钢材
            }else {
                baseNode = createMaterialNode(r,null,null);
            }
            parentMap[r.id] = baseNode;
        }
        for(let g of gljList){
            if(g.quantity !== 0 && g.quantity !== '0'){
                if(g.materialType){
                    let tem = me.getMaterialSheetDataByGLJ(g);
                    if(tem.materialQuantity){
                        sumMap[g.materialType] = sumMap[g.materialType]?sumMap[g.materialType] + tem.materialQuantity:tem.materialQuantity;
                        tem.materialQuantity = scMathUtil.roundToString(tem.materialQuantity,q_decimal);//转成string
                    }
                    if(g.materialType == materialTypeMap.GC){ //钢材的下一节点是钢筋
                        createMaterialNode(tem,parentMap['GC'],parentMap['GJ']);
                    }else {
                        createMaterialNode(tem,parentMap[materialTypeMap[g.materialType]]);
                    }
                }
            }
        }
        for(let mkey in sumMap){
            if(mkey == materialTypeMap.GC && sumMap[materialTypeMap.GJ]){//钢材汇总要加上钢筋的总量
                parentMap['GC'].data.materialQuantity = scMathUtil.roundToString(sumMap[mkey]+sumMap[materialTypeMap.GJ],q_decimal);
            }else {
                parentMap[materialTypeMap[mkey]].data.materialQuantity = scMathUtil.roundToString(sumMap[mkey],q_decimal);
            }
        }
        this.materialTree.sortTreeItems();
        function createMaterialNode(data,parent,next) {
            let newNode = me.materialTree.addNode(parent, next, data.id);
            newNode.data = data;
            return newNode;
        }
    },
    getMaterialSheetDataByGLJ:function (glj) {
        let q_decimal = getDecimal("glj.quantity");
        let m_decimal = getDecimal("material");
        let p_decimal = getDecimal("glj.unitPrice");
        let projectGLJ = projectObj.project.projectGLJ;
        let data ={
            id:glj.id,
            code:glj.code,
            name:glj.name,
            specs:glj.specs,
            unit:glj.unit,
            type:glj.type,
            short_name:projectGLJ.getShortNameByID(glj.type),
            quantity:scMathUtil.roundToString(glj.quantity,q_decimal),
            supply:glj.supply,
            supply_quantity:glj.supply_quantity,
            materialType:glj.materialType,
            delivery:glj.delivery,
            delivery_address:glj.delivery_address,
            is_adjust_price:glj.is_adjust_price,
            ratio_data:glj.ratio_data,
            is_add:glj.unit_price.is_add,
            bgColour:'white'
        };
        if(glj.materialCoe){
            data.materialCoe = scMathUtil.roundForObj(glj.materialCoe,m_decimal);
            data.materialQuantity = scMathUtil.roundForObj(glj.materialCoe * glj.quantity,q_decimal);//还要做汇总，汇总完再转成string
        }
        gljOprObj.setGLJPrice(data,glj);
        data.basePrice = scMathUtil.roundToString(data.basePrice,p_decimal);
        data.marketPrice = scMathUtil.roundToString(data.marketPrice,p_decimal);
        return data;
    },
    filterProjectGLJ:function (gljList) {
        let me = projectGljObject;
        if(gljList.length>0){
            gljList = _.filter(gljList,function (item) {
                return me.displayTypeFilter(item);
            });
        }
        return gljList;
    },
    displayTypeFilter:function (item) {
        let me = this;
        if(item.quantity !== 0 && item.quantity !== '0'){//过滤掉消耗量为0的工料机
            if(me.displayType == filterType.ALL){//所有工料机
                return true;
            }else if(filterTypeArray.indexOf(me.displayType) != -1){//人工、材料、机械、主材、设备
                let typeString = item.type+"";
                return typeString.startsWith(me.displayType);
            }else if(me.displayType == filterType.FBFX){//“分部分项总消耗量”≠0的工料机行
                return item.subdivisionQuantity !== 0 && item.subdivisionQuantity !== '0';
            }else if(me.displayType == filterType.TECH){//筛选“措施项目总消耗量”≠0的工料机行
                return item.techQuantity !== 0 && item.techQuantity !== '0';
            }else if(me.displayType == filterType.JGCL){//筛选“供货方式”=“完全甲供”或“部分甲供”的工料机行
                return item.supply == supplyType.WQJG || item.supply == supplyType.BFJG;
            }else if(me.displayType == filterType.ZGCL){//筛选“是否暂估”=“是”的工料机行。
                return item.is_evaluate == 1;
            }else if(me.displayType == filterType.ZYCL){//筛选“主要材料”=“是”的工料机行。
                return item.is_main_material == 1;
            }
        }
        return false;
    },
    getSheetDataByGLJ:function (glj) {
        let projectGLJ = projectObj.project.projectGLJ;
        let materialIdList = projectGLJ.datas.constData.materialIdList;
        let data ={
            id:glj.id,
            code:glj.code,
            name:glj.name,
            specs:glj.specs,
            unit:glj.unit,
            type:glj.type,
            short_name:projectGLJ.getShortNameByID(glj.type),
            quantity:glj.quantity,
            supply:glj.supply,
            supply_quantity:glj.supply_quantity,
            materialType:glj.materialType,
            materialCoe:glj.materialCoe,
            grossWeightCoe:glj.grossWeightCoe,
            purchaseStorageRate:glj.purchaseStorageRate,
            offSiteTransportLossRate:glj.offSiteTransportLossRate,
            handlingLossRate:glj.handlingLossRate,
            delivery:glj.delivery,
            delivery_address:glj.delivery_address,
            is_adjust_price:glj.is_adjust_price,
            ratio_data:glj.ratio_data,
            unit_price:glj.unit_price,
            calcMaterial:glj.unit_price.calcMaterial,
            is_add:glj.unit_price.is_add,
            bgColour:'white',
            techQuantity:glj.techQuantity,
            subdivisionQuantity:glj.subdivisionQuantity,
            remark:glj.remark
        };
        gljOprObj.setGLJPrice(data,glj);

        data.is_main_material = glj.is_main_material == 1?1:0;
        //供货方式为完全甲供时设置甲供数量为总消耗量
        if (data.supply == 2) {
            data.supply_quantity = glj.quantity;
        }
        // 只有材料才显示是否暂估
        if (materialIdList.indexOf(glj.type) >= 0) {
            data.is_evaluate = glj.is_evaluate;
        }
        if(glj.materialCoe !== null && glj.materialCoe !==undefined){
            data.materialCoe =  scMathUtil.roundForObj(glj.materialCoe,getDecimal("material"));
        }
        //bgColour
        if(data.basePrice == data.marketPrice){//如果定额价等于市场价时，改底色。 优先度低于有组成物时的底色
            data.bgColour = "#C4CAFB";
        }
        if (gljUtil.notEditType.indexOf(glj.type) >= 0) {
            if (data.ratio_data  && data.ratio_data.length > 0){//有组成物时
                //设置底色
                data.bgColour = "#E0E0E0";
            }
        }
        if(gljUtil.isConcreteType(glj.type)) data.bgColour = "#E0E0E0";//混凝土、砂浆、配合比的底色显示为 灰色#E0E0E0,灰色底色提醒用户不可修改。
        return data;
    },
    refreshProjectGljRow:function (row) {
        let me = projectGljObject;
        let rowData = me.projectGljSheetData[row];
        let glj = projectObj.project.projectGLJ.getByID(rowData.id);
        let newRow = null;
        if(glj){
            newRow = me.getSheetDataByGLJ(glj);
        }
        if(me.displayTypeFilter(newRow) == true){
            me.projectGljSheetData[row] = newRow;
            sheetCommonObj.showRowData(this.projectGljSheet, this.projectGljSetting,row,this.projectGljSheetData);
        }else {
            me.projectGljSheetData.splice(row,1);
            me.projectGljSheet.deleteRows(row,1);
            me.showMixRatioData();
            me.showRelatedRationDatas();
        }
        //me.projectGljSheetData[row] = me.getSheetDataByGLJ(glj);
    },
    initSheet: function (sheet,setting) {
        var me = this;
        sheetCommonObj.initSheet(sheet, setting, 30);
        sheet.bind(GC.Spread.Sheets.Events.ValueChanged, me.onSheetValueChange);
    },
    onSheetValueChange:function (e,info) {
        let me = projectGljObject;
        if(info.sheetName=='projectGljSheet'){
            me.onProjectGLJValueChange(e,info);
        }else if(info.sheetName == 'mixRatioSheet'){
            me.onMixRatioValueChange(e,info);
        }
    },
    onMixRatioValueChange:function (e,info){
        let composition = projectObj.project.composition;
        let me = projectGljObject,row = info.row, col = info.col;
        let dataCode = me.mixRatioSetting.header[col].dataCode;
        let recode = me.mixRatioData[row];
        let value = info.newValue;
        let parentSheet =  me.projectGljSpread.getActiveSheet();//三材汇总表和工料机汇总表
        if (!me.checkData(col,me.mixRatioSetting,value)) {
            alert('输入的数据类型不对，请重新输入!');
            me.mixRatioSheet.setValue(row, col, info.oldValue);
            return false;
        }
        value = scMathUtil.roundToString(value,getDecimal("glj.quantity"));
        me.batchUpdateConsumption([{row:row,col:col,value}]);
    },
    onUnitFileChange:function (isInclude,changeMark = 'unitFile') { //include用来标计是否排除本身， true时，不排除本身
        if(isInclude == true) projectObj.project.projectInfo.changeMark = changeMark; //项目单价文件修改标记
        projectObj.project.markUpdateProject({projectID:projectObj.project.ID(),'unitFileID':socketObject.getUnitFileRoomID(),isInclude:isInclude},"unitFile",function(){
            //socket.emit('unitFileChangeNotify', JSON.stringify(data));
            socket.emit('unitFileChangeNotify', {projectID:projectObj.project.ID(),userID:userID,'unitFileID':socketObject.getUnitFileRoomID()});
        });
    },
    deleteMixRatio:function (row) {
        let me = this, deleteRecode = me.mixRatioData[row];
        let consumption = deleteRecode.consumption;
        let [parentMarketPrice, parentBasePrice] = me.getCompositionSumPrice('delete', row);
        let prowData =  me.getSelectedProjectGLJ();
        let updateData = {id: deleteRecode.mix_ratio_id, field: 'mix_ratio.consumption' , value: 0, market_price: parentMarketPrice, base_price: parentBasePrice};
        let ext = {};
        ext[prowData.id] = {marketPrice:parentMarketPrice};
        updateData.parent = {query:{id:prowData.unit_price.id},doc:{market_price: parentMarketPrice}}
        let elecP = electrovalenceObj.clacNewElecPrice(ext);
        if(elecP){
            updateData.unitPrice = {projectGLJID:elecP.projectGLJID,query:{id:elecP.id},doc:elecP.doc};
        }
        projectObj.project.composition.deleteComposition(updateData,deleteRecode,prowData.id,function () {
            _.remove(me.mixRatioData,{"mix_ratio_id":deleteRecode.mix_ratio_id});
            //me.refreshParentData(prow,prowData.id);
            me.refreshDataSheet();
            me.mixRatioSheet.deleteRows(row,1);
            me.onUnitFileChange(true);
        });
    },
    getCompositionSumPrice : function(scene, affectRow, newValue = 0) {
        let me = this;
        let parentMarketPrice = 0;
        let parentBasePrice = 0;
        let parentKey = me.mixRatioData[affectRow].connect_key;
        let parentType = parentKey.split("|-|")[4];
        if(gljUtil.isConcreteType(parseInt(parentType))) return [0,0]; //父工料机是混凝土浆砂，配合比，则父价格为0，不用计算
        for(let i = 0;i < me.mixRatioData.length;i++){
            let ratio = me.mixRatioData[i];
            let marketPrice = ratio.unit_price.market_price;
            let basePrice = ratio.unit_price.base_price;
            // 如果是删除则忽略即将被删除的行数据
            if (scene === 'delete' && affectRow === i) {
                continue;
            }
            let consumption = i === affectRow ? newValue : ratio.consumption;
            parentMarketPrice += operationWithRound(consumption,marketPrice,"glj.unitPrice","*");
            parentBasePrice += operationWithRound(consumption,basePrice,"glj.unitPrice","*");
        }
        parentMarketPrice = parentMarketPrice.toDecimal(getDecimal("glj.unitPrice"));
        parentBasePrice = parentBasePrice.toDecimal(getDecimal("glj.unitPrice"));
        return [parentMarketPrice, parentBasePrice];

    },
    onProjectGLJValueChange:function (e,info) {//me.projectGljSetting
        let projectGLJ = projectObj.project.projectGLJ;
        let me = projectGljObject,row = info.row, col = info.col;
        let setting = info.sheetName =="materialTreeSheet"?me.materialSetting:me.projectGljSetting;
        let dataCode = setting.header[col].dataCode;
        let recode = info.sheetName =="materialTreeSheet"?me.materialTree.selected.data:me.projectGljSheetData[row];
        let value = info.newValue;
        if(info.newValue === undefined ){
            return;
        }
        if(value && !me.checkData(col,setting,value)) {
            alert('输入的数据类型不对，请重新输入!');
            info.sheetName =="materialTreeSheet"?me.materialTreeController.refreshTreeNode([me.materialTree.selected]):me.refreshProjectGljRow(row);
            return;
        }
        let callback=function (impactList) {
            info.sheet.suspendPaint();
            info.sheet.suspendEvent();
            if(info.sheetName =="materialTreeSheet"){
                me.showMaterialTreeData();
            }else {
                me.refreshProjectGljRow(row);
                for(let g of impactList){
                    me.refreshProjectGljRowByID(g.id,row);
                }
            }
            info.sheet.resumeEvent();
            info.sheet.resumePaint();
            if (dataCode === 'supply' || dataCode === 'supply_quantity'){    // basePrice、marketPrice 有自己的计算代码，无需走这里重复计算
                let rations = calcTools.getRationsByProjectGLJ(recode.id);
                projectObj.project.calcProgram.calcNodesAndSave(rations, function () {
                    projectObj.mainController.refreshTreeNode(projectObj.project.mainTree.roots);
                });
            }
            gljOprObj.refreshView();
        };
        if(dataCode=='basePrice'||dataCode=='marketPrice'){//修改市场价和修改定额价时需要重新记算很多受影响的树节点，现在改成与定字额工料机那里调相同的方法。
            let editField = dataCode === 'basePrice'?"base_price":"market_price";
            projectObj.project.projectGLJ.updatePrice(recode,editField,value,'pg',callback);
        }else {
            let extend = {};
            // 如果是供货方式则需要处理数据
            if (dataCode === 'supply') {
                extend.supply_quantity = me.getSupplyQuantity(value, recode.quantity);
            }
            if(dataCode === 'supply_quantity'){//修改数量需做4舍5入
                value=  scMathUtil.roundForObj(value,getDecimal('glj.quantity'));
            }
            if(dataCode === 'is_evaluate'||dataCode === 'is_adjust_price'||dataCode === 'is_main_material'){
                value = value == true?1:0;
            }
            if(dataCode === 'materialType' && (value == null || value=="")){//删除三材类别时，清空三材系数
                value = null;
                extend.materialCoe = null;
            }
            if(dataCode == 'materialCoe'){
                value = scMathUtil.roundForObj(value,getDecimal("material"));
            }
            extend = Object.keys(extend).length > 0 ?  JSON.stringify(extend) : '';
            if(recode[dataCode] == value) return;
            let updateData = {id: recode.id, field: dataCode, value: value, extend: extend};
            projectGLJ.pGljUpdate(updateData,callback);
        };
    },
    refreshProjectGljRowByID:function (ID,row) {//row 可以不传，如果row 和 index 相等就不刷新
        let me = this;
        let index = _.findIndex(me.projectGljSheetData, { 'id': ID});
        if(index>=0&&index != row){
            me.refreshProjectGljRow(index);
        }
    },
    getSupplyQuantity : function(supplyType, quantity) {
        // 自行采购和甲定乙供则把甲供数量设置为0，其余情况则设置为当前总消耗量
        let supplyQuantity = supplyType == 0 || supplyType == 3 ? 0 : quantity;
        supplyQuantity = parseFloat(supplyQuantity);
        return supplyQuantity;
    },
    getSupplyQuantityByGlj:function (glj) {
        //{"自行采购":0,"部分甲供":1,"完全甲供":2,"甲定乙供":3};
        let supply_quantity = glj.supply_quantity;
        switch (glj.supply){
            case 0:
                supply_quantity = 0;
                break;
            case 1:
                break;
            case 2:
                supply_quantity = glj.quantity;
                break;
            case 3:
                supply_quantity = 0;
                break;
        }
        return supply_quantity
    },
    checkData : function(col,setting, value) {
        return sheetCommonObj.checkData(col,setting, value);
    },
    getProjectGLJSelected:function () {
        let me = projectGljObject;
        let sheet = me.projectGljSpread.getActiveSheet();
        let selectedProjectGLJ = null;
        if(sheet.name() == 'projectGljSheet'){//projectGljSheet/materialSheet 工料机汇总和三材汇总表
            let sel = me.projectGljSheet.getSelections()[0];
            if(sel.row != -1 && me.projectGljSheetData.length>sel.row){
                selectedProjectGLJ = me.projectGljSheetData[sel.row]
            }
        }else if(sheet.name() == 'materialTreeSheet' ){
            if(me.materialTree.selected){
                selectedProjectGLJ = me.materialTree.selected.data;
            }
        }
        return selectedProjectGLJ;
    },
    initProjectGljRightClick:function(){
        //如果当前行是无组成物的“普通材料”、“绿化苗木”、“外购砼构件”、“商品混凝土”、“商品砂浆”，则右键“添加计算材料”按钮有效。
        let me = this;
        $.contextMenu({
            selector: '#project_glj_sheet',
            build: function ($trigger, e) {
                me.rightClickTarget = SheetDataHelper.safeRightClickSelection($trigger, e, me.projectGljSpread);
                return me.rightClickTarget.hitTestType === GC.Spread.Sheets.SheetArea.viewport ||
                    me.rightClickTarget.hitTestType === GC.Spread.Sheets.SheetArea.rowHeader;
            },
            items: {
                "addCalcMaterial": {
                    name: "添加计算材料",
                    icon: 'fa-sign-in',
                    disabled: function () {
                        let projectGLJ = projectGljObject.getProjectGLJSelected();
                        return  !projectGLJ || !gljUtil.isMaterialType(projectGLJ.type);
                    },
                    callback: function (key, opt) {
                        let projectGLJ = projectGljObject.getProjectGLJSelected();
                        projectObj.project.projectGLJ.updateCalcMaterial(projectGLJ,'calcMaterial',1);
                    }
                },
                "calcElectrovalence": {
                    name: "计算综合电价",
                    icon: 'fa-sign-in',
                    disabled: function () {
                        return  false;
                    },
                    callback: function (key, opt) {
                        $("#electrovalenceDiv").modal("show")
                    }
                }
            }
        });


    },
    initMixRatioRightClick : function() {
        let activeSheet = this.mixRatioSheet;
        let me = this;
        $.contextMenu({
            selector: '#mix_ratio_sheet',
            build: function ($trigger, e) {
                me.rightClickTarget = SheetDataHelper.safeRightClickSelection($trigger, e, me.mixRatioSpread);
                return me.rightClickTarget.hitTestType === GC.Spread.Sheets.SheetArea.viewport ||
                    me.rightClickTarget.hitTestType === GC.Spread.Sheets.SheetArea.rowHeader;
            },
            items: {
                "deleteMixRatio": {
                    name: "删除",
                    icon: 'fa-trash-o',
                    disabled: function () {
                        return me.rightClickTarget.row === undefined;
                    },
                    callback: function (key, opt) {
                        let row = me.rightClickTarget.row;
                        me.deleteMixRatio(row);
                    },
                    visible: function(key, opt){
                        if(!$('#mixRatio-nav').hasClass('active')) return false;
                        let projectGLJ = projectGljObject.getProjectGLJSelected();
                        return  projectGLJ && !gljUtil.isConcreteType(projectGLJ.type);
                    }
                },
                "addMixRatio":{
                    name: '添加',
                    icon: 'fa-sign-in',
                    disabled: function () {
                        let projectGLJ = projectGljObject.getProjectGLJSelected();
                        return !_.includes(compositionTypes,projectGLJ.type);
                    },
                    callback: function (key, opt) {
                        me.selectedProjectGLJ = projectGljObject.getProjectGLJSelected();
                        getGLJData('addMix');
                    },
                    visible: function(key, opt){
                        if(!$('#mixRatio-nav').hasClass('active')) return false;
                        let projectGLJ = projectGljObject.getProjectGLJSelected();
                        return  projectGLJ && !gljUtil.isConcreteType(projectGLJ.type);
                    }
                }
            }
        });
    },
    changeFileCallback:function(){
        projectGljObject.unitPriceFileInit();
        projectGljObject.refreshDataSheet();
        projectGljObject.initVvTax();
        materialCalcObj.showDatas();
        projectObj.project.calcProgram.calcAllNodesAndSave(calcAllType.catAll,function () {
            if(socketObject.roomInfo){
                let data ={
                    projectID:projectObj.project.ID(),
                    oldRoom:socketObject.roomInfo.unitFile,
                    newRoom:socketObject.getUnitFileRoomID(),
                    userID:userID,
                    name:'unitFile'
                };
                socket.emit('changeNewRoom',data);
                socketObject.roomInfo.unitFile = socketObject.getUnitFileRoomID();
            }
        });
        gljOprObj.refreshView();

    },
    calcPartASupplyFeeByProjectGLJs: function (projectGLJsArr) {
        for (let pGLJ of projectGLJsArr){
            if (pGLJ.supply == supplyType.BFJG){
                let rations = calcTools.getRationsByProjectGLJ(pGLJ.id);
                projectObj.project.calcProgram.calcNodesAndSave(rations, function () {
                    projectObj.mainController.refreshTreeNode(projectObj.project.mainTree.roots);
                });
            }
        }
    },
    checkUnitFileName:function (name,callback) {
        let projectGLJ = projectObj.project.projectGLJ;
        projectGLJ.checkUnitFileName(name,function (data) {
            if(data){
                $("#save-as-tips").text('已存在同名单价文件').show();
                $('#save-as-confirm').attr("disabled","disabled");
            }else {
                $("#save-as-tips").hide();
                $('#save-as-confirm').removeAttr("disabled");
                if(callback) callback();
            }
        });
    },
    initFilterTypeList:function () {//初始化人材机汇总工料机类型过滤列表
        let htmlString = '';
        for(let t of this.displayTypeMap){
            htmlString += '<li class="nav-item "><a class="nav-link pl-4" href="javascript:void(0)" id="'+t.ID+'">'+t.text+'</a></li>';
        }
        $('#ALL').after(htmlString);
    },
    initVvTax:async function () {//初始化车船税选择
        try {
            let engineeringID = projectObj.project.projectInfo.property.engineering_id;
            let result =  await ajaxGet("/glj/getVvTaxList",{engineeringID:engineeringID});
            let optionString = ` <option value="">车船税标准</option>`;
            for(let r of result){
                optionString += `<option value="${r.id}">${r.name}</option>`
            }
            $('#vvTax').empty();
            $('#vvTax').html(optionString);
            $('#vvTax').val(projectObj.project.projectGLJ.datas.constData.vvTaxFileID?projectObj.project.projectGLJ.datas.constData.vvTaxFileID:'');

        }catch (e){
            console.log(e)
        }
    },
    refreshSubViews:function () {
        if($("#mix_ratio_sheet").is(':visible')&&this.mixRatioSpread) this.mixRatioSpread.refresh();
        if($('#materialCalcSheet').is(':visible')&&materialCalcObj.materialSpread) materialCalcObj.materialSpread.refresh();
        if($('#freightSheet').is(':visible')&&materialCalcObj.freightSpread) materialCalcObj.freightSpread.refresh();
        if($('#priceSheet').is(':visible')&&materialCalcObj.priceSpread) materialCalcObj.priceSpread.refresh();
        if($('#freight_ration').is(':visible')&&materialCalcObj.freightRationSpread) materialCalcObj.freightRationSpread.refresh();
        if($('#price_ration').is(':visible')&&materialCalcObj.priceRationSpread) materialCalcObj.priceRationSpread.refresh();
    }
};

function getProjectResizeEles() {
    let pojGljResizeEles = {};
    pojGljResizeEles.eleObj = {
        module: 'projectGlj',
        resize: $('#projectGljResize'),
        top: $('#projectGljTop'),
        topSpread: $('#project_glj_sheet'),
        bottom: $('#projectGljBottom'),
        bottomSpread: [$('#mix_ratio_sheet'),$('#materialCalcSheet'),$('#calcDiv')]
    };
    pojGljResizeEles.limit = {
        min: 150,
        max: `$(window).height()-$('.header').height()-$('#projectGljToolsBar').height()-150-5`,//5: resize.height()
        notTopSpread: 0,
        notBottomSpread: 0,
        bottomNav:`$('#projectGljBottom ul').height()`,
        totalHeight: `$(window).height()-$('.header').height()-$('#projectGljToolsBar').height()-5`
    };
    return pojGljResizeEles;
}


function loadProjectGljSize() {
    let me = projectGljObject;
    let pojGljResizeEles = getProjectResizeEles();
    SlideResize.loadVerticalHeight(pojGljResizeEles.eleObj.module, pojGljResizeEles.eleObj, pojGljResizeEles.limit, function () {
        me.projectGljSpread?me.projectGljSpread.refresh():'';
        materialCalcObj.initTabWidth();
        me.refreshSubViews();
    });
}
//从其他建设项目中复制中，建设项目的文件层次结构名称和顺序
function getFileHierarchyInfo(treeData){
    let tree = idTree.createNew({id: 'ID', pid: 'ParentID', nid: 'NextSiblingID', rootId: -1});
    tree.loadDatas(treeData);
    let items = tree.items;
    let rst = [];
    function getFileHierarchyName(node){
        let nodeName = node.data.name;
        let name = [];
        while (node.parent){
            name.push(node.parent.data.name ? node.parent.data.name : '');
            node = node.parent;
        }
        name = name.reverse();
        name.push(nodeName);
        return name.join('\\');
    }
    for(let node of items){
        if(node.children.length === 0 ){//project
            rst.push({ID: node.data.ID, fileHierarchyName: getFileHierarchyName(node)})
        }
    }
    return rst;
}

$(function () {
    let pojGljResizeEles =  getProjectResizeEles();
    SlideResize.verticalSlide(pojGljResizeEles.eleObj, pojGljResizeEles.limit, function () {
        projectGljObject.projectGljSpread.refresh();
        projectGljObject.refreshSubViews();
    });
    $('#tab_project_glj').on('shown.bs.tab', function (e) {
        sessionStorage.setItem('mainTab', '#tab_project_glj');
        let me = projectGljObject;
        $(e.relatedTarget.hash).removeClass('active');
        if(me.projectGljSpread==null){
            me.initProjectGljSpread();
        }
        me.unitPriceFileInit();
        me.initMixRatio();
        //projectObj.project.projectGLJ.calcQuantity(); 在工程量有更新的地方调用
        me.refreshDataSheet();
        loadProjectGljSize();
        me.initVvTax();
        materialCalcObj.initTabWidth();
        materialCalcObj.showDatas();
    });
    /*  $('#ration_link').on('shown.bs.tab', function (e) {
     let me = projectGljObject;
     me.showTag='ration';
     me.showProjectGljData();
     });
     $('#mix_ratio_link').on('shown.bs.tab', function (e) {
     let me = projectGljObject;
     me.showTag='mixRatio';
     me.showProjectGljData();
     me.initMixRatio();
     });
     $('#machine_ratio_link').on('shown.bs.tab', function (e) {
     let me = projectGljObject;
     me.showTag='machine';
     me.showProjectGljData();
     me.initMixRatio();
     });*/
    $('#pop-used-list').tooltip({
            placement: "bottom",
            html: true,
            trigger: "hover | focus",
            title: projectGljObject.getUsedTenderInfo
        }
    );
    // 单价文件切换弹框
    $('#change-unitFile').on('shown.bs.modal', function () {
        let rootProjectID = projectObj.project.projectInfo.property.rootProjectID;
        // 获取切换单价文件相关数据
        $.ajax({
            url: '/glj/get-project-info',
            type: 'post',
            data: {project_id: scUrlUtil.GetQueryString('project'),rootProjectID:rootProjectID},
            dataType: 'json',
            success: function (response) {
                if (response.err === 1) {
                    alert('数据传输错误!');
                    return false;
                }
                let data = response.data;
                projectGljObject.changeInfo = data;
                $("#current-project-name").text(data.currentProjectName);
                // 本项目中的单价文件
                if (data.self.length > 0) {
                    let selfFileHtml = '';
                    for (let tmp of data.self) {
                        let select = usedUnitPriceInfo === tmp.id ? ' selected="selected"' : '';
                        selfFileHtml += '<option' + select + ' value="' + tmp.id + '">' + tmp.name + '</option>';
                    }
                    $("#self-file").html(selfFileHtml);
                }
                // 其他建设项目数据
                let newDataOther = [];
                if (data.other.length > 0) {
                    //转换成按项目管理顺序，名称包含文件夹层次
                    let fileHierarchyDatas = getFileHierarchyInfo(data.treeData);
                    for(let fileHierarchyData of fileHierarchyDatas){
                        let projData = _.find(data.other, {ID: fileHierarchyData.ID});
                        if(projData){
                            projData.name = fileHierarchyData.fileHierarchyName;
                            newDataOther.push(projData);
                        }
                    }
                    data.other = newDataOther;
                    let otherProjectHtml = '';
                    let otherFileHtml = '';
                    for (let tmp of data.other) {
                        otherProjectHtml += '<option value="' + tmp.ID + '">' + tmp.name + '</option>';
                        otherFileData[tmp.ID] = tmp.unitPriceList;
                        if (otherFileHtml !== '') {
                            continue;
                        }
                        for (let unitPrice of tmp.unitPriceList) {
                            otherFileHtml += '<option value="' + unitPrice.id + '">' + unitPrice.name + '</option>';
                        }
                    }
                    $("#other-project").html(otherProjectHtml);
                    $("#other-file").html(otherFileHtml);
                }
            }
        });
    });
    // 单价文件切换确认
    $("#change-file-confirm").click(function () {
        let type = $("input[name='change-type']:checked").val();
        type = parseInt(type);
        let changeUnitPriceId = 0;
        $('#change-unitFile').modal("hide");
        if (type === 0) {
            // 从本项目中选择
            changeUnitPriceId = $("#self-file").val();
            if(!changeUnitPriceId){
                alert('单价文件不可为空');
                return;
            }
            submitFileChange(changeUnitPriceId,type);
        } else {
            // 从其他项目中复制
            changeUnitPriceId = $("#other-file").val();
            let newName = $("#other-file").children("option:selected").text();
            projectObj.project.projectGLJ.checkUnitFileName(newName,function (need_rename) {
                if(need_rename){
                    $("#rename-unitFile").modal({show:true});
                    $("#newUnitFileID").val(changeUnitPriceId);
                    $("#newUnitFileName").val(newName);
                }else {
                    submitFileChange(changeUnitPriceId,type);
                }
            });
        }

        function submitFileChange(changeUnitPriceId,type)  {
            let data = {project_id: scUrlUtil.GetQueryString('project'), change_id: changeUnitPriceId, type: type};
            projectObj.project.projectGLJ.changeFile(data,function () {
                projectGljObject.changeFileCallback();
            })
        }
    });
    // 单价文件选项切换
    $("input[name='change-type']").change(function () {
        let type = $(this).val();
        type = parseInt(type);
        $("#change-unitFile .option").hide();
        if (type === 0) {
            $(".option.select").show();
        } else {
            $(".option.copy").show();
        }
    });
    $("#vvTax").change(function () {
       let newVvTaxFileID = $(this).val();
       console.log(newVvTaxFileID);
        projectObj.project.projectGLJ.changeVvTaxFile(newVvTaxFileID);
    });

    $("#unitFile-save-as").on('shown.bs.modal', function () {
        // 获取当前建设项数据
        $("#save-as-name").val(projectGljObject.usedUnitPriceInfo.name + '副本');
        projectGljObject.checkUnitFileName(projectGljObject.usedUnitPriceInfo.name + '副本');
    });

    // 从其他建设项目中复制 选择建设项目
    $("#other-project").change(function () {
        let projectId = $(this).val();
        if (otherFileData[projectId] === undefined) {
            return false;
        }
        let otherFileHtml = '';
        for (let unitPrice of otherFileData[projectId]) {
            otherFileHtml += '<option value="' + unitPrice.id + '">' + unitPrice.name + '</option>';
        }
        $("#other-file").html(otherFileHtml);
    });

    $('#save-as-name').change(function () {
        projectGljObject.checkUnitFileName(this.value);
    });

    $('#newUnitFileName').change(function () {
        let projectGLJ = projectObj.project.projectGLJ;
        projectGLJ.checkUnitFileName(this.value,function (data) {
            if(data){
                $("#renameError_unitFile").text('已存在同名单价文件').show();
                //$('#renameUnitFileConfirm').attr("disabled","disabled");
            }else {
                $("#renameError_unitFile").hide();
                // $('#renameUnitFileConfirm').removeAttr("disabled");
            }
        });

    });
    $("#renameUnitFileConfirm").click(function () {
        let projectGLJ = projectObj.project.projectGLJ;
        let newName = $('#newUnitFileName').val();
        let changeUnitPriceId = $('#newUnitFileID').val();
        projectGLJ.checkUnitFileName(newName,function (data) {
            if(data){
                $("#renameError_unitFile").text('已存在同名单价文件').show();
                //$('#renameUnitFileConfirm').attr("disabled","disabled");
            }else {
                $("#renameError_unitFile").hide();
                $('#rename-unitFile').modal('hide');
                // $('#renameUnitFileConfirm').removeAttr("disabled");
                let data = {project_id: scUrlUtil.GetQueryString('project'), change_id: changeUnitPriceId, type: 1,newName:newName};
                projectObj.project.projectGLJ.changeFile(data,function () {
                    projectGljObject.changeFileCallback();
                })
            }
        });
    });
    // 单价文件另存为操作
    $("#save-as-confirm").click(function () {
        let projectGLJ = projectObj.project.projectGLJ;
        let name = $("#save-as-name").val();
        if (name === '') {
            $("#save-as-tips").text('请填写单价文件名称').show();
            return false;
        }
        let saveData = {name: name, project_id: scUrlUtil.GetQueryString('project')};
        projectGljObject.checkUnitFileName(name,function () {
            projectGLJ.saveAs(saveData,function () {
                projectGljObject.changeFileCallback();
                $("#unitFile-save-as").modal("hide");
            });
        });
    });

    $("#filterType").on("click","ul li a",function(e){
        let children = $('#filterType a');
        for(let c of children){
            $(c).removeClass('active');
        }
        $(this).addClass('active');
        let me = projectGljObject;
        me.displayType = filterType[this.id];
        me.refreshDataSheet();
    });

    $("#mixRatio-nav").on('shown.bs.tab', function () {
        projectGljObject.mixRatioSpread.refresh();
        projectGljObject.showMixRatioData();
    });
    $("#ration-nav").on('shown.bs.tab', function () {
      projectGljObject.mixRatioSpread.refresh();
      projectGljObject.showRelatedRationDatas();
      console.log('hehe');
  });
});


