gljType = gljUtil.gljType; let unitPriceObj = { unitPriceMap:{}, selectedData : null, setUntiPriceMap:function(){ for(let u of unitPriceList){ this.unitPriceMap[gljUtil.getIndex(u)] = u; } }, mainSpread:null, mainSetting:{ header: [ {headerName: "编号", headerWidth: 80, dataCode: "code", dataType: "String"}, {headerName: "名称", headerWidth: 160, dataCode: "name", dataType: "String"}, {headerName: "单位", headerWidth: 45, dataCode: "unit", hAlign: "center", dataType: "String"}, {headerName: "规格", headerWidth: 120, dataCode: "specs", hAlign: "left", dataType: "String"}, {headerName: "类型", headerWidth: 45, dataCode: "short_name", 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: "是否\n新增", headerWidth: 50, dataCode: "is_add", hAlign: "center", dataType: "String",cellType:'checkBox'} ], view: { lockColumns: ["code","name","specs","unit","short_name","basePrice"], colHeaderHeight:36 }, getStyle:function (data,row,activeRow) { if(row == activeRow){//选中黄色显示 return {backColor:"#FFFACD"}; } return null; } }, subSpread:null, subSetting:{ header:[ {headerName: "编号", headerWidth: 80, dataCode: "code", dataType: "String"}, {headerName: "名称", headerWidth: 240, dataCode: "name", dataType: "String"}, {headerName: "规格", headerWidth: 190, dataCode: "specs", dataType: "String"}, {headerName: "单位", headerWidth: 45, dataCode: "unit", hAlign: "center", dataType: "String"}, {headerName: "类型", headerWidth: 45, dataCode: "short_name", hAlign: "center", dataType: "String"}, {headerName: "定额价", headerWidth: 80, dataCode: "basePrice", hAlign: "right", dataType: "Number",validator:"number"},//,decimalField:'glj.unitPrice' {headerName: "预算价", headerWidth: 80, dataCode: "marketPrice", hAlign: "right", dataType: "Number",validator:"number"},//,decimalField:"glj.unitPrice" {headerName: "消耗量", headerWidth: 80, dataCode: "consumption", hAlign: "right", dataType: "Number",validator:"number",tofix:3} ], view: { lockColumns: [0,1,2,3,4,5,6], rowHeaderWidth: 25 } }, initMainSpread:function () { if(this.mainSpread) return this.mainSpread.refresh(); this.mainSpread = SheetDataHelper.createNewSpread($("#mainSpread")[0]); sheetCommonObj.spreadDefaultStyle(this.mainSpread); this.mainSheet = this.mainSpread.getSheet(0); sheetCommonObj.initSheet(this.mainSheet, this.mainSetting, 30); this.mainSheet.bind(GC.Spread.Sheets.Events.SelectionChanged,this.onMainSelectionChange); this.mainSpread.bind(GC.Spread.Sheets.Events.RangeChanged, this.onMainRangeChange); this.mainSheet.bind(GC.Spread.Sheets.Events.ValueChanged, this.onMainValueChange); this.mainSheet.bind(GC.Spread.Sheets.Events.EditStarting,this.onMainEditStarting); }, showMainDatas:function(){ unitPriceList = gljUtil.sortProjectGLJ(unitPriceList); this.setData(unitPriceList); let sel = this.mainSheet.getSelections()[0]; let oldData = this.selectedData; sheetCommonObj.showData(this.mainSheet, this.mainSetting,unitPriceList); this.mainSheet.setRowCount(unitPriceList.length); sel.row = oldData?_.findIndex(unitPriceList,{'id':oldData.id}):sel.row ; this.mainSheet.setSelection(sel.row==-1?0:sel.row,sel.col,sel.rowCount,sel.colCount); }, getShortNameByType : function (type) { return gljTypeMap["typeId" + type]?gljTypeMap["typeId" + type].shortName:''; }, setData:function(list){ for(let l of list){ l.bgColour = "white"; l.basePrice = this.getPrice('base_price',l); l.marketPrice = this.getPrice('market_price',l); l.short_name = this.getShortNameByType(l.type); if(l.base_price == l.market_price){//如果定额价等于市场价时,改底色。 优先度低于有组成物时的底色 l.bgColour = "#C4CAFB"; } let lindex = gljUtil.getIndex(l); if (gljUtil.notEditType.indexOf(l.type) >= 0 && mixRatioMap[lindex] && mixRatioMap[lindex].length>0) {//有组成物时 l.bgColour = "#E0E0E0"; } } }, getSelectedUnitPrice:function () { let me = this,data = null; let sheet = me.mainSpread.getActiveSheet(); let sel = sheet.getSelections()[0]; let srow = sel.row == -1||sel.row == ""?0:sel.row; if(unitPriceList.length>srow){ data = unitPriceList[srow]; } return data; }, onMainSelectionChange:function(sender,args){ let me = unitPriceObj; let newSel = args.newSelections[0]; let oldSel = args.oldSelections?args.oldSelections[0]:{}; args.sheet.suspendPaint(); args.sheet.suspendEvent(); if(newSel.row != oldSel.row){ let style = me.getSelStyle(true,{}); args.sheet.setStyle(newSel.row, -1, style); let orow = oldSel.row==''||oldSel.row==-1?0:oldSel.row; if(unitPriceList[orow]){ let tstyle = me.getSelStyle(false,{},unitPriceList[orow].bgColour); args.sheet.setStyle(orow, -1, tstyle); me.showSubDatas(); me.selectedData = unitPriceList[newSel.row]; } }else{ args.sheet.repaint(); } args.sheet.resumeEvent(); args.sheet.resumePaint(); }, onMainEditStarting:function(sender, args){ let me = unitPriceObj; let row = args.row; let col = args.col; if(me.mainEditChecking(row,col)==false){ args.cancel = true; } }, mainEditChecking:function(row,col,isPaste=false){ let me = unitPriceObj; if(row>=unitPriceList.length) return false; let data = unitPriceList[row]; let setting = me.mainSetting; let dataCode = setting.header[col].dataCode; if(isPaste == false &&dataCode=='is_add'){//除了粘贴,拖动填充等操作,其它的都不能编辑 return false; } if(dataCode=='marketPrice'){ let uindex = gljUtil.getIndex(data); if(mixRatioMap[uindex] && mixRatioMap[uindex].length > 0) return false;//有组成物的不能编辑 if(data.calcMaterial == 1) return false //有材料计算时不能修改 } return true; }, onMainValueChange:function(e,info){ let me = unitPriceObj; let value = info.newValue; if(info.newValue === undefined){ return; } if(value && !sheetCommonObj.checkData(info.col,me.mainSetting,value)) { alert('输入的数据类型不对,请重新输入!'); return me.showMainDatas(); } me.batchUpdateUnitPrice([{row:info.row,col:info.col,value:value}]); }, onMainRangeChange:function(sender,info){ let me = unitPriceObj; let canChange = true; let changeInfo = []; 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.mainEditChecking(c.row,c.col,true)==false){//如果不能编辑 canChange = false; break; } if (!sheetCommonObj.checkData(c.col,me.mainSetting,value)) { alert('输入的数据类型不对,请重新输入!'); canChange = false; break; } } if(canChange == false) return me.showMainDatas(); me.batchUpdateUnitPrice(changeInfo); }, batchUpdateUnitPrice:async function(changeInfo){ let me = unitPriceObj; let updateData = []; let newValueMap = {}; let refreshList = []; try { for(let ci of changeInfo){ let dataCode = me.mainSetting.header[ci.col].dataCode; let recode = unitPriceList[ci.row]; let ndata = newValueMap[recode.id]?newValueMap[recode.id]:{unit_price:recode}; if(dataCode=='basePrice'||dataCode=='marketPrice'){ let editField = dataCode === 'basePrice'?"base_price":"market_price"; let newValue = ci.value; if(recode && recode[editField]!=newValue){ newValue= scMathUtil.roundForObj(ci.value,3); ndata['field'] = editField; ndata['newval'] = newValue; newValueMap[recode.id]=ndata; } }else{ let ext = {}; if(dataCode === 'is_add'){ value = ci.value == true?1:0; } ext[dataCode] = value; ndata['ext'] = ext; newValueMap[recode.id]=ndata; } } for(let key in newValueMap){ updateData.push(newValueMap[key]); refreshList.push(newValueMap[key].unit_price) } if(updateData.length > 0){ $.bootstrapLoading.start(); let result = await ajaxPost("/glj/batchUpdatePrices",updateData); for(let r of refreshList){ let rdata = newValueMap[r.id]; if(rdata.field) r[rdata.field] = rdata.newval; if(rdata.ext){ for(let ekey in rdata.ext){ r[ekey] = rdata.ext[ekey]; } } } for(let r of result){ let pdata = r.updateOne.filter; let set = r.updateOne.update.$set; for(let skey in set){ let pindex = gljUtil.getIndex(pdata); me.unitPriceMap[pindex][skey] = set[skey]; } } } } catch (error) { console.log(error); alert(error); } $.bootstrapLoading.end(); me.onUnitPriceChange(); }, initSubSpread:function () { if(this.subSpread) return this.subSpread.refresh(); this.subSpread = SheetDataHelper.createNewSpread($("#subSpread")[0]); sheetCommonObj.spreadDefaultStyle(this.subSpread); this.subSheet = this.subSpread.getSheet(0); sheetCommonObj.initSheet(this.subSheet, this.subSetting, 30); this.subSheet.bind(GC.Spread.Sheets.Events.RangeChanged, this.onSubRangeChange); this.subSheet.bind(GC.Spread.Sheets.Events.ValueChanged, this.onSubValueChange); this.initSubRightClick(); }, showSubDatas:function(){ let parentData = this.getSelectedUnitPrice(); this.mixRatioList = mixRatioMap[gljUtil.getIndex(parentData)]; this.mixRatioList = this.mixRatioList?this.mixRatioList:[]; this.setMixRatioData(this.mixRatioList); let sel = this.subSheet.getSelections()[0]; this.subSheet.setRowCount(0); sheetCommonObj.showData(this.subSheet, this.subSetting,this.mixRatioList); this.subSheet.setRowCount(this.mixRatioList.length); this.subSheet.setSelection(sel.row==-1?0:sel.row,sel.col,sel.rowCount,sel.colCount); }, onSubValueChange:function(sender,info){ let me = unitPriceObj; let value = info.newValue; if(info.newValue === undefined){ return; } if(value && !sheetCommonObj.checkData(info.col,me.mainSetting,value)) { alert('输入的数据类型不对,请重新输入!'); return me.showMainDatas(); } me.batchUpdateConsumption([{row:info.row,col:info.col,value:value}]); }, onSubRangeChange:function(sender,info){ let me = unitPriceObj; let changeInfo=[]; let canChange = true; for(let c of info.changedCells){ let value = info.sheet.getCell(c.row, c.col).text(); if(_.isEmpty(value)) value = 0; if (!sheetCommonObj.checkData(c.col,me.subSetting,value)) { alert('输入的数据类型不对,请重新输入!'); canChange = false; break; }else { changeInfo.push({row:c.row,col:c.col,value:value}); } } if(canChange == false) me.showSubDatas(); me.batchUpdateConsumption(changeInfo); }, calcParentPrice:function(list,updateMap,deleteID){ let parentMarketPrice = 0; for(let sub of list){ if(deleteID && sub.id == deleteID) continue let marketPrice = scMathUtil.roundForObj(sub.marketPrice,6); let basePrice = scMathUtil.roundForObj(sub.basePrice,6); let consumption = updateMap[sub.id]?updateMap[sub.id].consumption:scMathUtil.roundForObj(sub.consumption,3); parentMarketPrice = scMathUtil.roundForObj(marketPrice*consumption + parentMarketPrice,6); // parentBasePrice = scMathUtil.roundForObj(basePrice*consumption + parentBasePrice,getDecimal("process")); } parentMarketPrice = scMathUtil.roundForObj(parentMarketPrice,2); return parentMarketPrice; }, deleteMixRatio:async function(row){ let me = this, deleteRecode = me.mixRatioList[row]; let parentMarketPrice = me.calcParentPrice(me.mixRatioList,{},deleteRecode.id); let parentData = me.getSelectedUnitPrice(); let updateData = {id: deleteRecode.id,connect_key:gljUtil.getIndex(parentData)}; updateData.parent = {connect_key:gljUtil.getIndex(parentData),query:{id:parentData.id},doc:{market_price: parentMarketPrice}}; try { $.bootstrapLoading.start(); await ajaxPost("/glj/delete-ratio",{id: updateData.id,parent:updateData.parent,unitPrice:updateData.unitPrice}); let mlist = mixRatioMap[updateData.connect_key]; _.remove(mlist,{id:updateData.id}); if(updateData.parent){ let pglj = me.unitPriceMap[updateData.parent.connect_key]; if(pglj) gljUtil.setProperty(pglj,updateData.parent.doc); } } catch (error) { alert(error); console.log(error); } $.bootstrapLoading.end(); me.onUnitPriceChange(); }, batchUpdateConsumption:async function(changeInfo){ let me = unitPriceObj; let updateMap = {},updateData = [],parentBasePrice = 0,parentMarketPrice = 0; let parentKey = '',unit_price_file_id=null; for(let c of changeInfo){ let record = me.mixRatioList[c.row]; let value = scMathUtil.roundForObj(c.value,3); updateMap[record.id] = {consumption: value,record:record}; updateData.push({type:'mix_ratio',connect_key:record.connect_key,query:{id:record.id},doc:{consumption:scMathUtil.roundToString(value,3)}}); parentKey = record.connect_key; unit_price_file_id = record.unit_price_file_id; } parentMarketPrice = me.calcParentPrice(me.mixRatioList,updateMap); let parentData = me.getSelectedUnitPrice(); if(parentData){ updateData.push({type:'unitPrice',connect_key:gljUtil.getIndex(parentData),query:{id:parentData.id},doc:{market_price:parentMarketPrice}}); } if(updateData.length > 0){ try { $.bootstrapLoading.start(); let result = await ajaxPost("/glj/batchUpdateConsumption",updateData); for(let up of updateData){ if(up.type == 'unitPrice'){ let nu = me.unitPriceMap[up.connect_key]; if(nu) gljUtil.setProperty(nu,up.doc); }else{ let nlist = mixRatioMap[up.connect_key]; for(let nc of nlist){ if(nc.id == up.query.id){ gljUtil.setProperty(nc,up.doc); } } } } } catch (error) { alert(error); console.log(error); } } $.bootstrapLoading.end(); me.onUnitPriceChange(); }, setMixRatioData:function(mixRatioList){ for(let m of mixRatioList){ m.short_name = this.getShortNameByType(m.type); let mu = this.unitPriceMap[gljUtil.getIndex(m)]; if(mu){ m.basePrice = this.getPrice("base_price",mu); m.marketPrice = this.getPrice("market_price",mu); }else{ console.log("组成物的单价信息未找到---"+m.code); } } }, getPrice:function(pricefield,unitprice){ let quantity = 3; let unitPriceHasMix = 2; let unitPrice = 3; let process_decimal = 6; let uIndex = gljUtil.getIndex(unitprice); if(mixRatioMap[uIndex] && mixRatioMap[uIndex].length > 0){ let total = unitprice[pricefield]; if(pricefield == "market_price"){ total = 0; for(let m of mixRatioMap[uIndex]){ let mu = unitPriceObj.unitPriceMap[gljUtil.getIndex(m)]; let price_m = unitPriceObj.getPrice(pricefield,mu); let temP = scMathUtil.roundForObj(price_m * scMathUtil.roundForObj(m.consumption,quantity),process_decimal); total = scMathUtil.roundForObj(temP+total,process_decimal); } } return scMathUtil.roundForObj(unitprice[pricefield],unitPriceHasMix); }else{ return scMathUtil.roundForObj(unitprice[pricefield],unitPrice); } }, getSelStyle: function (selected,settingStyle,rcolor) { let style = new GC.Spread.Sheets.Style(); if(settingStyle){ for(let key in settingStyle){ style[key] = settingStyle[key]; } } style.borderLeft = new GC.Spread.Sheets.LineBorder("#D4D4D4", GC.Spread.Sheets.LineStyle.thin); style.borderTop = new GC.Spread.Sheets.LineBorder("#D4D4D4", GC.Spread.Sheets.LineStyle.thin); style.borderRight = new GC.Spread.Sheets.LineBorder("#D4D4D4", GC.Spread.Sheets.LineStyle.thin); style.borderBottom = new GC.Spread.Sheets.LineBorder("#D4D4D4", GC.Spread.Sheets.LineStyle.thin); let selectedColor = "#FFFACD", recColor = rcolor?rcolor:'White'; style.backColor = selected ? selectedColor : recColor; return style; }, initSubRightClick:function(){ let me = this; $.contextMenu({ selector: '#subSpread', build: function ($trigger, e) { me.rightClickTarget = SheetDataHelper.safeRightClickSelection($trigger, e, me.subSpread); 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){ let projectGLJ = me.getSelectedUnitPrice(); return projectGLJ; } }, "addMixRatio":{ name: '添加', icon: 'fa-sign-in', disabled: function () { let projectGLJ = me.getSelectedUnitPrice(); return !_.includes(compositionTypes,projectGLJ.type); }, callback: function (key, opt) { projectGljObject.selectedProjectGLJ = me.getSelectedUnitPrice(); getGLJData('unitPriceAddMix',me.getGLJDataPaging, true, null); }, visible: function(key, opt){ let projectGLJ = me.getSelectedUnitPrice(); return projectGLJ ; } } } }); }, addMixRatio:async function(){ let me = this; for(let mix of me.mixRatioList){ let m_key = gljUtil.getIndex(mix); _.remove(gljOprObj.GLJSelection,n =>{ return m_key == n; }); } let result = await projectGljObject.addMixRatioFromLib(gljOprObj.GLJSelection) if(result.mixRatios && result.mixRatios.length > 0){ let mList = mixRatioMap[result.mixRatios[0].connect_key]; if(mList){ mixRatioMap[result.mixRatios[0].connect_key] = mixRatioMap[result.mixRatios[0].connect_key].concat(result.mixRatios); } } for(let u of result.newUnitPriceList){ me.unitPriceMap[gljUtil.getIndex(u)] = u; unitPriceList.push(u); } me.onUnitPriceChange(); }, onUnitPriceChange:async function(){ unitPriceObj.showMainDatas(); unitPriceObj.showSubDatas(); try { await ajaxPost("/project/markUpdateProject",{updateInfo:{unitFileID:unitPriceFileID,isInclude:true},type:"unitFile"}); socket.emit('unitFileChangeNotify', {projectID:_.isEmpty(projectID)?null:parseInt(projectID),'unitFileID':unitPriceFileID,userID:userID}); } catch (error) { console.log(error) alert(error) } }, getGLJDataPaging : function (condition, cb) { gljOprObj.loadingPagination = true; CommonAjax.post('/rationGlj/getGLJDataPaging', {condition}, function (data) { gljOprObj.curPageTotal = data.total; data.complementaryGLJs.forEach(glj => { glj.isComplementary = true; }); const gljType = condition.type === gljOprObj.pagingType.stdGLJ ? 'stdGLJ' : 'complementaryGLJs'; const newData = data[gljType]; // 添加组成物,类型为主材时,需要排除自身 if (projectGljObject.selectedProjectGLJ.type === gljType.MAIN_MATERIAL) { const pIndex = gljOprObj.getIndex(projectGljObject.selectedProjectGLJ, gljKeyArray); const delIndex = newData.findIndex(item => gljOprObj.getIndex(item, gljLibKeyArray) === pIndex); if (!~delIndex) { newData.splice(delIndex, 1); } } if (condition.init) { gljOprObj.treeData = data.treeData; gljOprObj.distTypeTree = gljOprObj.getComboData(data.distTypeTree); } // 需要重置当前页面数据(点击了分类树、搜索等等) if (condition.reset) { gljOprObj.stdGLJ = data.stdGLJ; gljOprObj.complementaryGLJs = data.complementaryGLJs; gljOprObj.AllRecode = [...gljOprObj.stdGLJ, ...gljOprObj.complementaryGLJs]; } else { gljOprObj[gljType].splice(condition.index, 0, ...newData); gljOprObj.AllRecode.splice(condition.index, 0, ...newData); } // 根据缓存选中数据,设置人材机是否选中 newData.forEach(item => { const connectKey = gljOprObj.getIndex(item, gljLibKeyArray); if (gljOprObj.GLJSelection.includes(connectKey)) { item.select = 1; } }); // 设置人材机类型名称 gljOprObj.setTypeName(gljOprObj.distTypeTree.comboDatas, newData); if (data.priceProperties && data.priceProperties.length > 0) { let tregion = '全省'; if(!_.isEmpty(region)) tregion = region; let tmp = _.find(data.priceProperties, {region: tregion, taxModel: parseInt(taxType)}); if (tmp) { let dataCode = tmp.price.dataCode; let allData = data.stdGLJ.concat(data.complementaryGLJs); for (let glj of allData) { if (glj.priceProperty && gljUtil.isDef(glj.priceProperty[dataCode])) { glj.basePrice = glj.priceProperty[dataCode]; } } } } if (data.libData) { const html = data.libData.reduce((acc, lib) => acc += ``, ''); $('#glj-lib-select').html(html); } cb(data[gljType], data); gljOprObj.loadingPagination = false; }, function () { if ($.bootstrapLoading.isLoading()) { $.bootstrapLoading.end(); } }); } } function initPageHeight(){ let headerHeight = $(".header").height(); $(".main-data-top").height($(window).height()*0.6-headerHeight); $(".main-data-bottom").height($(window).height()-headerHeight-$(".main-data-top").height()-$(".nav-item").height()); } function initPage(){ $('[data-toggle="tooltip"]').tooltip({html: true}); initPageHeight(); unitPriceObj.initMainSpread(); unitPriceObj.initSubSpread(); unitPriceObj.showMainDatas(); unitPriceObj.showSubDatas(); socketObject.connect("unitPrice"); } unitPriceObj.setUntiPriceMap(); initPage(); $(window).resize(initPage);