/** * Created by zhang on 2018/5/10. */ let BlockController = { datas:[], copyBtnDisable:function (selected) { if(this.isDXFYorMainEq(selected)){ return true; } if(selected.sourceType == ModuleNames.ration && selected.data.type == rationType.install){ return true; } return false; }, pasteBtnDisable:function (selected) { let blockData = this.getBlockData(); let Bills = projectObj.project.Bills; if(this.isDXFYorMainEq(selected)){ return true; } if(blockData == null){ return true; } if(blockData.firstNodeType != blockType.RATION && blockData.isFBFX != Bills.isFBFX(selected)){//除了复制定额外,焦点行和复制的块不是来自同一个地方(分部分项工其它) return true; } if(selected.sourceType == Bills.getSourceType() && selected.data.type == billType.FX && blockData.firstNodeType == blockType.FB){//焦点行是分项,复制块的第一层是分部,则无效。 return true; } if(blockData.firstNodeType == blockType.RATION && selected.sourceType == Bills.getSourceType()){ //复制的是定额/量价/工料机、焦点行是分部/清单父项则无效 if( selected.data.type == billType.FB ){ return true; } if(MainTreeCol.readOnly.billsParent(selected)){ return true; } } if(blockData.firstNodeType != blockType.RATION && selected.sourceType == ModuleNames.ration){ return true; } return false; }, isDXFYorMainEq:function (node) {//焦点行是大项费用或定额下的主材设备 if(node.sourceType == ModuleNames.bills && node.data.type == billType.DXFY){//焦点行是大项费用则无效; return true; } if(node.sourceType == ModuleNames.ration_glj){// 焦点行是定额下的主材设备则无效; return true; } return false; }, getBlockData:function () { let blockString =getLocalCache('project_block'); if(blockString !=null){ return JSON.parse(blockString); } return null; }, copyBlock:function (selected) { let startTime = +new Date(); let blockOjb = { compilationID:projectInfoObj.projectInfo.compilation }; if(selected.sourceType == projectObj.project.Bills.getSourceType()){ blockOjb.firstNodeType = selected.data.type; }else if(selected.sourceType == projectObj.project.Ration.getSourceType()){ blockOjb.firstNodeType = blockType.RATION; } blockOjb.isFBFX = projectObj.project.Bills.isFBFX(selected); let ration_glj_Map = _.groupBy(projectObj.project.ration_glj.datas, 'rationID'); blockOjb.data = this.getNodeDatas(selected,ration_glj_Map); let getDataTime = +new Date(); console.log(`复制所用时间——${getDataTime - startTime}`); blockOjb.copyTime = +new Date();//设置复制时间,可以用来做过期处理 setLocalCache('project_block',JSON.stringify(blockOjb)); let endTime = +new Date(); console.log(`复制所用时间——${endTime - startTime}`); }, getNodeDatas : function (node,ration_glj_Map) { let data = node.data; data.sourceType = node.sourceType; if(node.sourceType == projectObj.project.Bills.getSourceType()){ data.quantity_details = projectObj.project.quantity_detail.getDetailByBillID(data.ID); } if(node.sourceType == projectObj.project.Ration.getSourceType()){ if(node.data.type == rationType.install){ //如果是生成的安装增加费,则跳过 return null; } let gljList = ration_glj_Map[data.ID]?ration_glj_Map[data.ID]:[];//gljOprObj.filterGljByRation(node.data, datas); gljList = gljOprObj.combineWithProjectGlj(gljList,false); data.ration_gljs = gljList; data.ration_coes = projectObj.project.ration_coe.getCoeByRationID(data.ID); data.ration_installations = projectObj.project.ration_installation.getInstallationByRationID(data.ID); data.quantity_details = projectObj.project.quantity_detail.getDetailByRationID(data.ID); }else if(node.children.length>0){ let children = []; for(let c of node.children){ let tem_data = this.getNodeDatas(c,ration_glj_Map); tem_data?children.push(tem_data):''; } data.children = children; } return data; }, pasteBlock:function (selected) { let blockData = this.getBlockData(); let position = this.initOptionDiv(selected,blockData); if(position == null){ return; } this.confirmPaste(blockData,selected,position); //do paste }, initOptionDiv:function (selected,blockData) { let Bills = projectObj.project.Bills; if( blockData.firstNodeType == blockType.RATION){//如果剪切板中是复制的定额块 if(selected.sourceType == ModuleNames.ration && selected.data.type != rationType.install ){//焦点行是定额/量价/工料机,则粘贴为后项 return "next"; } if(isFXorBX(selected)||(selected.sourceType === Bills.getSourceType()&& selected.source.children.length == 0)){//焦点行是分项/叶子清单,且无基数计算,则粘贴到分项/叶子清单下 if(selected.data.calcBase ==null||selected.data.calcBase ==undefined|| selected.data.calcBase == ""){//无基数计算 return "sub"; } } } //设置选项的初始值 setRadioProp('next_node',{checked:true,disabled:false}); setRadioProp('pre_node',{checked:false,disabled:false}); if(Bills.isFBFX(selected)){// (2.1)、焦点行属于“分部分项工程”: //复制块的第一层、焦点行的类型都是“分部” if(blockData.firstNodeType == blockType.FB && isFB(selected)){ //默认为当前行的后项,可选前项、子项。 setRadioProp('sub_node',{checked:false,disabled:false}); } //复制块的第一层、焦点行的类型都是“分项”或补项 if(blockIsFXorBX(blockData.firstNodeType) && isFXorBX(selected)){ //默认为当前行的后项,可选前项,子项灰显不可选。 setRadioProp('sub_node',{checked:false,disabled:true}); } //复制块的第一层是分项,焦点行是分部,且分部下无子项或者子项是分项 if(blockIsFXorBX(blockData.firstNodeType)&& isFB(selected)){ if(selected.children.length == 0 || isFXorBX(selected.children[0])){ return 'sub';//不弹出选择窗口,直接粘贴为子项。 } } }else {//焦点行不属于“分部分项工程” if(blockData.firstNodeType == blockType.BILL &&selected.sourceType == Bills.getSourceType()){//如果剪切板中是从“分部分项工程”以外复制的清单块 if(selected.children.length==0 || selected.children[0].sourceType == Bills.getSourceType()){//焦点行没有子项,或者子项是清单,判断是否有基数计算 if(selected.data.calcBase && selected.data.calcBase!=""){//如果焦点行有基数计算,则子项灰显不可选。 setRadioProp('sub_node',{checked:false,disabled:true}); }else{//如果焦点行没有基数计算,则子项可选。 setRadioProp('sub_node',{checked:false,disabled:false}); } }else { setRadioProp('sub_node',{checked:false,disabled:true}); } } } $("#pastePosition").modal({show:true}); return null; function setRadioProp(id,options) { $("#"+id).prop("checked",options.checked); $("#"+id).prop("disabled",options.disabled); } function isFB(selected) { return selected.sourceType == Bills.getSourceType() && selected.data.type == billType.FB; } function isFXorBX(selected) {//是分项或者补项 if(selected.sourceType == Bills.getSourceType()){ return selected.data.type == billType.FX || selected.data.type == billType.BX; } return false; } function blockIsFXorBX(type) { return type == blockType.FX||blockType.BX; } }, /** * @param blockData * @param selected * @param position next/pre/sub */ confirmPaste:function (blockData,selected,position) { let Bills = projectObj.project.Bills; let parent = null,next = null,pre = null; let updateData = [],billUpdate = null; let billsIDMap = {};//用来做新旧ID映射 if(blockData.compilationID != projectInfoObj.projectInfo.compilation){//如果编办不一样,不能复制 alert("编办不一致,不能粘贴!"); return; } if(position == 'next'){ //插入为选中节点的后项,即选中节点为前项 parent = selected.parent; next = selected.nextSibling; pre = selected; } if(position == 'pre'){//插入为选中节点的前项,即选中节点为后项 parent = selected.parent; next = selected; pre = selected.preSibling; } if(position == 'sub'){//即选中节点为父项 parent = selected; pre = selected.lastChild(); } let parentID = parent?parent.getID():-1; let nextID = next?next.getID():-1; if(blockData.firstNodeType == blockType.RATION){ //复制的是定额,需根据新的父项信息和工程量明细计算工程量 blockData.data.billsItemID = parentID; let billsQuantity = scMathUtil.roundForObj(parent.data.quantity,getDecimal("quantity",parent)); this.calcRationQuantityAndContain(billsQuantity,blockData.data); //如果粘贴位置不属于分部分项工程,或者不是安装工程,则把安装增加费内容置空 if(!Bills.isFBFX(parent)|| projectInfoObj.projectInfo.property.engineering!=engineeringType.BUILD_IN){ blockData.data.ration_installations = []; } //计算序列号 this.calcRationSerialNo(parentID,blockData,updateData,pre,next); }else { blockData.data.ParentID = parentID; blockData.data.NextSiblingID=nextID; if(pre){ billUpdate = {type:blockData.data.sourceType,query:{ID:pre.getID()},doc:{NextSiblingID:blockData.data.ID}}; } } let dataMap = this.preparePasteData(blockData.data,billsIDMap); if(billUpdate){ billUpdate.doc.NextSiblingID = billsIDMap[billUpdate.doc.NextSiblingID]; updateData.push(billUpdate); } dataMap.updateData = updateData; console.log(dataMap); $.bootstrapLoading.start(); CommonAjax.post('/bills/pasteBlock',dataMap,function (data) { $.bootstrapLoading.end(); }) // delete fees / feesIndex /__v }, preparePasteData : function (data,billsIDMap) { let me = this; me.datas = _.cloneDeep(projectObj.project.Bills.datas); let bills = [],rations=[],ration_gljs = [],ration_coes = [],quantity_details = [],ration_installations = []; eachData(data); for(let b of bills){//更新ID billsIDMap[b.ParentID]?b.ParentID = billsIDMap[b.ParentID]:''; billsIDMap[b.NextSiblingID]?b.NextSiblingID = billsIDMap[b.NextSiblingID]:''; } return {bills:bills,rations:rations,ration_gljs:ration_gljs,ration_coes:ration_coes,quantity_details:quantity_details,ration_installations:ration_installations}; function eachData(data) { if(data.sourceType == 'bills'){ let tem_b = createBillsData(data); bills.push(tem_b); for(let d of data.quantity_details){ quantity_details.push(createQuantityDetails(d,tem_b,'bills')); } if(data.children && data.children.length>0){ for(let c of data.children){ eachData(c); } } } if( data.sourceType == 'ration'){ let tem_r = createRationData(data); rations.push(tem_r); for(let d of data.quantity_details){ quantity_details.push(createQuantityDetails(d,tem_r, 'ration')); } for(let g of data.ration_gljs){ let tem_rg = createSubList(g,tem_r); tem_rg.billsItemID = tem_r.billsItemID; ration_gljs.push(tem_rg); } for(let o of data.ration_coes){ ration_coes.push(createSubList(o,tem_r)); } for(let ri of data.ration_installations){ ration_installations.push(createSubList(ri,tem_r)); } } } function createSubList(subData,rationData) { let tem_sub = _.cloneDeep(subData); delete tem_sub._id; tem_sub.ID = uuid.v1(); tem_sub.projectID = projectObj.project.ID(); tem_sub.rationID = rationData.ID; return tem_sub; } function createQuantityDetails(detailData,pdata,type) { let tem_detail = _.cloneDeep(detailData); tem_detail.ID = uuid.v1(); tem_detail.projectID = projectObj.project.ID(); if(type == 'bills'){ tem_detail.billID = pdata.ID; } if(type == 'ration'){ tem_detail.rationID = pdata.ID; } return tem_detail; } function createRationData(rationData) { let tem_ration = _.cloneDeep(rationData); //删除旧数据 delete tem_ration.fees; delete tem_ration.feesIndex; delete tem_ration.ration_gljs; delete tem_ration.ration_coes; delete tem_ration.ration_installations; delete tem_ration.quantity_details; delete tem_ration.__v; delete tem_ration.sourceType; tem_ration.projectID = projectObj.project.ID(); tem_ration.ID = uuid.v1(); billsIDMap[tem_ration.billsItemID]?tem_ration.billsItemID = billsIDMap[tem_ration.billsItemID]:''; let firstLibID = rationLibObj.getFirstStdRationLibID(); if(firstLibID){ tem_ration.prefix = projectObj.project.Ration.getRationPrefix(firstLibID,tem_ration); } return tem_ration; } function createBillsData(billsData) { //ID、重新生成code let temData = _.cloneDeep(billsData); //删除旧数据 delete temData.fees; delete temData.feesIndex; delete temData.children; delete temData.quantity_details; delete temData.__v; delete temData.sourceType; temData.projectID = projectObj.project.ID(); let newID = uuid.v1(); //新的清单ID billsIDMap[temData.ID] = newID; temData.ID = newID; //新的清单ID if(temData.billsLibId && temData.billsLibId!="" && temData.code.length == 12){//是从清单库来的 let value = temData.code.substr(0,9); if (value&&value.length === 9 && /^[\d]+$/.test(value)) { temData.code = projectObj.project.Bills.newFormatCode(value); } } me.datas.push(temData);//为了下一个清单的std code 一样 return temData; } }, calcRationSerialNo:function (billsItemID,blockData,updateData,pre,next) { let br = projectObj.project.Ration.getBillsSortRation(billsItemID); if(next == null){ //没有下一树节点,即为最后节点 blockData.data.serialNo = br.length > 0 ? br[br.length - 1].serialNo + 1 : 1; }else {//有下一节点 let startIndex =0; if(pre){ startIndex = br.indexOf(pre.data)+1; } blockData.data.serialNo = br[startIndex].serialNo; for(let i = startIndex;i < br.length; i++){ let br_serialNo = i < br.length - 1 ? br [i + 1].serialNo : br[i].serialNo + 1; updateData.push({type:blockData.data.sourceType,query:{ID:br[i].ID},doc:{serialNo:br_serialNo}});//更新兄弟节点序列号 } } }, calcRationQuantityAndContain : function (billsQuantity,ration) {//计算定额工程量和含量 let EXPString = ration.quantityEXP+""; if(EXPString.indexOf("QDL") != -1){ if(EXPString=="QDL"){//定额的工程量是直接通过清单量填进来的; let times = parseInt(ration.unit); if(isNaN(times)){ times = 1; } ration.quantity = scMathUtil.roundForObj(billsQuantity / times,getDecimal("ration.quantity")); billsQuantity?ration.contain = scMathUtil.roundForObj(ration.quantity/billsQuantity,getDecimal("process")):ration.contain = 0; } else {//如果定额的工程量是通过计算出来的,则应该重新计算。 let tem_contain = scMathUtil.roundForObj(ration.contain,getDecimal("process")); let tem_quantity = scMathUtil.roundForObj(billsQuantity*tem_contain,getDecimal("ration.quantity")); //this.autoTransformQuantity(tem_quantity,rationNode); ration.quantity = tem_quantity; } }else {//GCLMXHJ let tem_contain=0; if(billsQuantity&&billsQuantity!=0){ let children_quantity = scMathUtil.roundForObj(ration.quantity,getDecimal("ration.quantity")); // children_quantity = scMathUtil.roundForObj(this.reverseQuantity(children_quantity,rationNode),getDecimal("quantity",rationNode)); 原先是要反算的,现在改成不用反算了 tem_contain =scMathUtil.roundForObj(children_quantity/billsQuantity,getDecimal("process")); } ration.contain = tem_contain; } }, newFormatCode : function (stdCode, filterCode) { let matchs = this.sameStdCode(stdCode, filterCode); let format = function (Number) { let s = Number + ''; while (s.length < 3) { s = '0' + s; } return s; }; for (let i = 0; i <= matchs.length; i++) { let formatCode = stdCode + format(i+1); if (matchs.indexOf(formatCode) === -1) { return formatCode; } } }, sameStdCode : function (stdCode, filterCode) { let reg = new RegExp('^' + stdCode), matchs= []; for (let data of this.datas) { if (data.code && data.code.length === 12 && reg.test(data.code) && data.code !== filterCode) { matchs.push(data.code); } } return matchs; }, removeBlock:function () { removeLocalCache('project_block'); } };