/** * Created by Zhong on 2017/8/15. */ let gljComponentOprObj = { workBook: null, processDecimal: -6, setting: { owner: "gljComponent", header: [ { headerName: "编码", headerWidth: 80, dataCode: "code", dataType: "String", formatter: "@", hAlign: "left", vAlign: "center" }, { headerName: "名称", headerWidth: 90, dataCode: "name", dataType: "String", hAlign: "left", vAlign: "center" }, { headerName: "单位", headerWidth: 45, dataCode: "unit", dataType: "String", hAlign: "center", vAlign: "center" }, { headerName: "单价", headerWidth: 60, dataCode: "basePrice", dataType: "Number", formatter: "0.00", hAlign: "right", vAlign: "center" }, { headerName: "消耗量", headerWidth: 70, dataCode: "consumeAmt", dataType: "Number", formatter: "0.000", hAlign: "right", vAlign: "center" } ], view: { lockedCols: [0, 1, 2, 3] } }, //生成列头(多单价)(多消耗量) initHeaders: function (priceProperties, consumeAmtProperties) { let headers = [ { headerName: "编码", headerWidth: 80, dataCode: "code", dataType: "String", formatter: "@", hAlign: "left", vAlign: "center" }, { headerName: "名称", headerWidth: 90, dataCode: "name", dataType: "String", formatter: "@", hAlign: "left", vAlign: "center" }, { headerName: "单位", headerWidth: 45, dataCode: "unit", dataType: "String", hAlign: "center", vAlign: "center" }, ]; //生成消耗量列 if (!consumeAmtProperties || consumeAmtProperties.length === 0) { headers.push({ headerName: "消耗量", headerWidth: 70, dataCode: "consumeAmt", dataType: "Number", formatter: "0.000", hAlign: "right", vAlign: "center" }); } else { for (let consumeAmtProp of consumeAmtProperties) { let colData = { headerName: consumeAmtProp.consumeAmt.dataName, headerWidth: 60, dataCode: consumeAmtProp.consumeAmt.dataCode, dataType: 'Number', formatter: '0.000', hAlign: 'right', vAlign: 'center' }; headers.push(colData); } } //生成单价列 if (!priceProperties || priceProperties.length === 0) { headers.push({ headerName: "定额价", headerWidth: 80, dataCode: "basePrice", dataType: "Number", formatter: "0.00", hAlign: "right", vAlign: "center" }); } else { for (let priceProp of priceProperties) { let colData = { headerName: priceProp.price.dataName, headerWidth: 100, dataCode: priceProp.price.dataCode, dataType: 'Number', formatter: '0.00', hAlign: 'right', vAlign: 'center' }; headers.push(colData); } } return headers; }, setFrozen: function (sheet) { const fixedHeadersLen = 3; let frozenCol = 0; if (consumeAmtProperties && consumeAmtProperties.length > 0) { frozenCol = fixedHeadersLen + consumeAmtProperties.length; } else if (priceProperties && priceProperties.length > 0) { frozenCol = fixedHeadersLen + 1; } if (frozenCol > 0) { sheet.frozenColumnCount(frozenCol); } }, buildHeader: function (sheet, header) { sheet.setRowCount(2, GC.Spread.Sheets.SheetArea.colHeader); for (let i = 0; i < header.length; i++) { sheet.setValue(1, i, header[i].headerName, GC.Spread.Sheets.SheetArea.colHeader); sheet.setColumnWidth(i, header[i].headerWidth ? header[i].headerWidth : 100); } sheet.setValue(0, 0, '组成物信息', GC.Spread.Sheets.SheetArea.colHeader); sheet.addSpan(0, 0, 1, header.length, GC.Spread.Sheets.SheetArea.colHeader); }, buildSheet: function (container) { let me = gljComponentOprObj; //生成人材机组成物表格列头 me.setting.header = me.initHeaders(priceProperties, consumeAmtProperties); //生成人材机组成物列映射 sheetCommonObj.initColMapping(me, me.setting.header); repositoryGljObj.initPriceCols.call(me, priceProperties, me.colMapping); me.initConsumeAmtCols(consumeAmtProperties, me.colMapping); me.workBook = sheetOpr.buildSheet(container, me.setting, 30, false); me.setFrozen(me.workBook.getSheet(0)); me.buildHeader(me.workBook.getSheet(0), me.setting.header); sheetCommonObj.spreadDefaultStyle(me.workBook); me.workBook.getSheet(0).setColumnWidth(0, 20, GC.Spread.Sheets.SheetArea.rowHeader); me.workBook.getSheet(0).setFormatter(-1, 0, "@", GC.Spread.Sheets.SheetArea.viewport); sheetOpr.cleanData(me.workBook.getSheet(0), me.setting, -1); if (isReadOnly) { sheetCommonObj.disableSpread(me.workBook); } me.onContextmenuOpr();//右键菜单 me.gljComponentDelOpr(); me.workBook.getSheet(0).bind(GC.Spread.Sheets.Events.EditStarting, me.onCellEditStart); me.workBook.getSheet(0).bind(GC.Spread.Sheets.Events.EditEnded, me.onCellEditEnd); me.workBook.bind(GC.Spread.Sheets.Events.ClipboardPasting, me.onClipboardPasting); me.workBook.bind(GC.Spread.Sheets.Events.ClipboardPasted, me.onClipboardPasted); }, getRowData: function (sheet, row, setting) { let rst = { priceProperty: {}, consumeAmtProperty: {} }; for (let i = 0; i < setting.header.length; i++) { let v = sheet.getValue(row, i); if (this.pricePropertyCols.includes(i)) { rst.priceProperty[setting.header[i].dataCode] = v && v !== '' ? v : 0; } else if (this.consumeAmtPropertyCols.includes(i)) { rst.consumeAmtProperty[setting.header[i].dataCode] = v && v !== '' ? v : 0; } else { rst[setting.header[i].dataCode] = v; } } return rst; }, getComponent: function (sheet, rowCount) { let component = []; for (let row = 0; row < rowCount; row++) { let obj = {}; obj.consumeAmt = sheet.getValue(row, 4); obj.ID = sheet.getTag(row, 0); component.push(obj); } return component; }, //根据消耗量字段设置组成物消耗量 setConsumeAmt: function (component, field, value) { const compareStr = 'consumeAmt'; if (field.includes(compareStr)) { if (field === compareStr) { component[field] = value; } else { component['consumeAmtProperty'][field] = value; } } }, initConsumeAmtCols: function (consumeAmtProperties, colMapping) { let consumeAmtCols = [], consumeAmtPropertyCols = []; if (!consumeAmtProperties || consumeAmtProperties.length === 0) { consumeAmtCols.push(colMapping.fieldToCol['consumeAmt']); } for (let consumeAmtProp of consumeAmtProperties) { consumeAmtPropertyCols.push(colMapping.fieldToCol[consumeAmtProp.consumeAmt.dataCode]); consumeAmtCols.push(colMapping.fieldToCol[consumeAmtProp.consumeAmt.dataCode]); } this.consumeAmtCols = consumeAmtCols; this.consumeAmtPropertyCols = consumeAmtPropertyCols; }, //消耗量赋初值 initConsumeAmt: function (component) { if (!consumeAmtProperties || consumeAmtProperties.length === 0) { component.consumeAmt = 0; } else { let consumeAmtProperty = {}; for (let consumeAmtProp of consumeAmtProperties) { consumeAmtProperty[consumeAmtProp.consumeAmt.dataCode] = 0; } component.consumeAmtProperty = consumeAmtProperty; } }, copyConsumeAmt: function (gljA, gljB) { if (!consumeAmtProperties || consumeAmtProperties.length === 0) { gljA.consumeAmt = gljB.consumeAmt; } else { gljA.consumeAmtProperty = _.cloneDeep(gljB.consumeAmtProperty); } }, consumeAmtChanged: function (component, consumeAmt, col) { if (!consumeAmtProperties || consumeAmtProperties.length === 0) { if (consumeAmt !== component.consumeAmt) { return true; } } else { if (consumeAmt !== component.consumeAmtProperty[this.colMapping.colToField[col]]) { return true; } } return false; }, consumeAmtIsEqual: function (consumeAmtA, consumeAmtB) { if (!consumeAmtProperties || consumeAmtProperties.length === 0) { return consumeAmtA.consumeAmt === consumeAmtB.consumeAmt; } return _.isEqual(consumeAmtA.consumeAmtProperty, consumeAmtB.consumeAmtProperty); }, onContextmenuOpr: function () { let me = gljComponentOprObj, that = repositoryGljObj, co = componentOprObj; $.contextMenu({ selector: '#gljComponentSheet', build: function ($triggerElement, e) { //控制允许右键菜单在哪个位置出现 let sheet = me.workBook.getSheet(0); let offset = $("#gljComponentSheet").offset(), x = e.pageX - offset.left, y = e.pageY - offset.top; let target = sheet.hitTest(x, y); if (target.hitTestType === 3 && typeof target.row !== 'undefined' && typeof target.col !== 'undefined') {//在表格内 sheet.setActiveCell(target.row, target.col); //getCurrentGlj let thatRow = that.workBook.getSheet(0).getSelections()[0].row that.currentGlj = thatRow < that.currentCache.length ? that.currentCache[thatRow] : null; that.currentComponent = that.currentGlj ? that.getCurrentComponent(that.currentGlj.component) : []; //控制按钮是否可用 let insertDis = false, delDis = false; if (!(that.currentGlj && allowComponent.includes(that.currentGlj.gljType)) || (that.currentGlj.gljType === 4 && that.isComponent(that.currentGlj.ID, that.stdGljList.concat(that.complementaryGljList)))) { insertDis = true; } if (!that.currentGlj || typeof that.currentComponent === 'undefined' || (typeof that.currentComponent !== 'undefined' && target.row >= that.currentComponent.length)) {//右键定位在有组成物的行,删除键才显示可用 delDis = true; } return { callback: function () { }, items: { "insert": { name: "插入", disabled: isReadOnly || insertDis, icon: "fa-sign-in", callback: function (key, opt) { let oprFunc = function () { //默认radio所有工料机 co.initRadio(); co.gljCurTypeId = null; //默认点击树根节点 co.initClassTree('std', gljClassTreeObj.treeData.std); //弹出窗口 $('#component').modal('show'); }; if (repositoryGljObj.pullCompleteData) { oprFunc(); } else { repositoryGljObj.getStdItems(pageOprObj.stdGljLibId, oprFunc); } } }, "delete": { name: "删除", disabled: isReadOnly || delDis, icon: "fa-remove", callback: function (key, opt) { //删除 let deleteObj = that.currentComponent[target.row]; let gljComponent = that.currentGlj.component; let updateArr = []; //更新当前工料机的组成物列表 for (let i = 0, len = gljComponent.length; i < len; i++) { if (gljComponent[i].ID === deleteObj.ID) { gljComponent.splice(i, 1); break; } } //重新计算工料机 let gljBasePrc = me.reCalGljBasePrc(that.getCurrentComponent(gljComponent)); if (that.isGljPriceChange(that.currentGlj, gljBasePrc)) { that.setPrice(that.currentGlj, gljBasePrc); that.reshowGljBasePrc(that.currentGlj); //updateBasePrc.push({gljId: that.currentGlj.ID, gljType: that.currentGlj.gljType, basePrice: that.currentGlj.basePrice}); } /* if (gljBasePrc !== that.currentGlj.basePrice) { that.currentGlj.basePrice = gljBasePrc; that.reshowGljBasePrc(that.currentGlj); //updateBasePrc.push({gljId: that.currentGlj.ID, gljType: that.currentGlj.gljType, basePrice: that.currentGlj.basePrice}); } */ updateArr.push(that.currentGlj); me.updateComponent(updateArr); } } } }; } else { return false; } } }); }, gljComponentDelOpr: function () { let me = gljComponentOprObj, that = repositoryGljObj, updateArr = [], removeArr = [], isUpdate = false, updateBasePrc = []; /* me.workBook.commandManager().register('gljComponentDel', function () { let sels = me.workBook.getSheet(0).getSelections(); if (sels.length > 0 && that.currentComponent.length > 0) { let component = that.currentGlj.component; for (let i = 0; i < sels.length > 0; i++) { if (sels[i].colCount === me.setting.header.length) {//可删除 for (let j = 0; j < sels[i].rowCount; j++) { if (sels[i].row + j < that.currentComponent.length) { removeArr.push(that.currentComponent[sels[i].row + j].ID); } } } else if (sels[i].col === 0) { //编码不可为空 alert("编码不可为空!"); } else if (sels[i].col === 4) {//消耗量修改为0 if (sels[i].row === -1) {//全修改 for (let j = 0; j < that.currentComponent.length; j++) { isUpdate = true; that.currentComponent[j].consumeAmt = 0; for (let k = 0; k < component.length; k++) { if (component[k].ID === that.currentComponent[j].ID) { component[k].consumeAmt = 0; break; } } } } else {//部分修改 for (let j = 0; j < sels[i].rowCount; j++) { if (sels[i].row + j < that.currentComponent.length) { isUpdate = true; that.currentComponent[sels[i].row + j].consumeAmt = 0; for (let k = 0; k < component.length; k++) { if (component[k].ID === that.currentComponent[sels[i].row + j].ID) { component[k].consumeAmt = 0; break; } } } } } } } if (removeArr.length > 0 || isUpdate) { for (let i = 0; i < removeArr.length; i++) { for (let j = 0; j < that.currentComponent.length; j++) { if (that.currentComponent[j].ID === removeArr[i]) { that.currentComponent.splice(j--, 1); } } for (let j = 0; j < component.length; j++) { if (component[j].ID === removeArr[i]) { component.splice(j--, 1); } } } //重新计算工料机 let gljBasePrc = me.reCalGljBasePrc(that.currentComponent); if (gljBasePrc !== that.currentGlj.basePrice) { that.currentGlj.basePrice = gljBasePrc; that.reshowGljBasePrc(that.currentGlj); updateBasePrc.push({ gljId: that.currentGlj.ID, gljType: that.currentGlj.gljType, basePrice: that.currentGlj.basePrice }); } updateArr.push(that.currentGlj); me.updateComponent(updateArr); if (updateBasePrc.length > 0) { that.updateRationBasePrcRq(updateBasePrc); } } } }); */ me.workBook.commandManager().setShortcutKey(null, GC.Spread.Commands.Key.del, false, false, false, false); //me.workBook.commandManager().setShortcutKey('gljComponentDel', GC.Spread.Commands.Key.del, false, false, false, false); }, onCellEditStart: function (sender, args) { let me = gljComponentOprObj, that = repositoryGljObj; let rObj = me.getRowData(args.sheet, args.row, me.setting); me.currentEditingComponent = rObj; let thatRow = that.workBook.getSheet(0).getSelections()[0].row; if (thatRow < that.currentCache.length) { that.currentGlj = that.currentCache[thatRow]; //消耗量可编辑 if (!(me.colMapping.colToField[args.col].includes('consumeAmt')) || !allowComponent.includes(that.currentGlj.gljType) || (that.currentGlj.gljType === 4 && that.isComponent(that.currentGlj.ID, that.gljList)) || (args.col === 4 && (!that.currentComponent || args.row >= that.currentComponent.length))) { args.cancel = true; } } else { args.cancel = true; } }, onCellEditEnd: function (sender, args) { let me = gljComponentOprObj, that = repositoryGljObj, updateBasePrc = []; let updateArr = []; let dataCode = me.colMapping.colToField[args.col]; if (dataCode.includes('consumeAmt') && me.currentEditingComponent.code && args.editingText && args.editingText.trim().length > 0) {//消耗量 let consumeAmt = parseFloat(args.editingText); if (!isNaN(consumeAmt) && me.consumeAmtChanged(me.currentEditingComponent, consumeAmt, args.col)) { let roundCons = scMathUtil.roundTo(parseFloat(consumeAmt), -3); let component = that.currentGlj.component; for (let i = 0; i < component.length; i++) { if (component[i].ID === that.currentComponent[args.row].ID) { me.setConsumeAmt(component[i], dataCode, roundCons); //component[i].consumeAmt = roundCons; } } //that.currentComponent[args.row].consumeAmt = roundCons; me.setConsumeAmt(that.currentComponent[args.row], dataCode, roundCons); //计算工料机单价 let gljBasePrc = me.reCalGljBasePrc(that.currentComponent); if (that.isGljPriceChange(that.currentGlj, gljBasePrc)) { that.setPrice(that.currentGlj, gljBasePrc); that.reshowGljBasePrc(that.currentGlj); //工料机单价改变,重算引用了该工料机的定额单价 //updateBasePrc.push({gljId: that.currentGlj.ID, gljType: that.currentGlj.gljType, basePrice: that.currentGlj.basePrice}); } updateArr.push(that.currentGlj); } else { //只能输入数值 sheetOpr.showData(me, me.workBook.getSheet(0), me.setting, that.currentComponent); /* args.sheet.setValue(args.row, args.col, me.currentEditingComponent[me.setting.header[args.col].dataCode] ? me.currentEditingComponent[me.setting.header[args.col].dataCode] : 0); */ } } else { //args.sheet.setValue(args.row, args.col, me.currentEditingComponent.consumeAmt); sheetOpr.showData(me, me.workBook.getSheet(0), me.setting, that.currentComponent); } if (updateArr.length > 0) { me.updateComponent(updateArr); /*if(updateBasePrc.length > 0){ that.updateRationBasePrcRq(updateBasePrc) }*/ } }, onClipboardPasting: function (sender, info) { let me = gljComponentOprObj, that = repositoryGljObj; let maxCol = info.cellRange.col + info.cellRange.colCount - 1; /* if (info.cellRange.col !== 4 && info.cellRange.colCount > 1 || (that.currentGlj.gljType === 4 && that.isComponent(that.currentGlj.ID, that.stdGljList.concat(that.complementaryGljList)))) { args.cancel = true; } */ //复制的列数超过正确的列数,不可复制 if (maxCol > me.setting.header.length - 1) { return info.cancel = true; } if (that.currentGlj.gljType === 4 && that.isComponent(that.currentGlj.ID, that.stdGljList.concat(that.complementaryGljList))) { return info.cancel = true; } //粘贴的字段只能是消耗量 for (let i = 0; i < info.cellRange.colCount; i++) { let col = info.cellRange.col + i; let dataCode = me.colMapping.colToField[col]; if (!dataCode.includes('consumeAmt')) { return info.cancel = true; } } }, onClipboardPasted: function (sender, info) { let me = gljComponentOprObj, that = repositoryGljObj, updateArr = [], materialComponent = [202, 203, 204], machineComponent = [302, 303], component = that.currentGlj.component, newComponent = [], concatComponent = [], isChange = false, updateBasePrc = []; let gljCache = that.gljList; //消耗量 if (me.colMapping.colToField[info.cellRange.col].includes('consumeAmt')) { let items = sheetCommonObj.analyzePasteData(me.setting, info); let row = info.cellRange.row; for (let i = 0; i < items.length; i++) { if (row + i < that.currentComponent.length) { let currentObj = that.currentComponent[row + i]; if (!me.consumeAmtIsEqual(items[i], currentObj)) { isChange = true; if (!consumeAmtProperties || consumeAmtProperties.length === 0) { let roundCons = scMathUtil.roundTo(parseFloat(items[i].consumeAmt), -3); currentObj.consumeAmt = roundCons; for (let j = 0; j < component.length; j++) { if (component[j].ID === currentObj.ID) { component[j].consumeAmt = currentObj.consumeAmt; break; } } } else { for (let attr in items[i]) { //是消耗量字段 if (attr.includes('consumeAmt') && items[i][attr] && !isNaN(parseFloat(items[i][attr]))) { let roundCons = scMathUtil.roundTo(parseFloat(items[i][attr]), -3); currentObj.consumeAmtProperty[attr] = roundCons; } } for (let j = 0; j < component.length; j++) { if (component[j].ID === currentObj.ID) { component[j].consumeAmtProperty = currentObj.consumeAmtProperty; break; } } } } else { sheetOpr.showData(me, me.workBook.getSheet(0), me.setting, that.currentComponent); //me.workBook.getSheet(0).setValue(row + i, info.cellRange.col, currentObj.consumeAmt); } } else { me.workBook.getSheet(0).setValue(row + i, info.cellRange.col, ''); } } if (isChange) { //计算工料机单价 let gljBasePrc = me.reCalGljBasePrc(that.currentComponent); if (that.isGljPriceChange(that.currentGlj, gljBasePrc)) { that.setPrice(that.currentGlj, gljBasePrc); that.reshowGljBasePrc(that.currentGlj); //updateBasePrc.push({gljId: that.currentGlj.ID, gljType: that.currentGlj.gljType, basePrice: that.currentGlj.basePrice}); } updateArr.push(that.currentGlj); } } if (updateArr.length > 0) { me.updateComponent(updateArr); /* if(updateBasePrc.length > 0){ that.updateRationBasePrcRq(updateBasePrc); }*/ } }, updateComponent: function (updateArr) { let me = gljComponentOprObj, that = repositoryGljObj; that.saveInString(updateArr); $.ajax({ type: 'post', url: '/complementartGlj/api/updateComponent', data: { "userId": pageOprObj.userId, "updateArr": JSON.stringify(updateArr) }, dataType: 'json', success: function (result) { if (!result.error) { that.currentComponent = that.getCurrentComponent(result.data[0].component); sheetOpr.cleanData(me.workBook.getSheet(0), me.setting, -1); sheetOpr.showData(me, me.workBook.getSheet(0), me.setting, that.currentComponent); } else { sheetOpr.cleanData(me.workBook.getSheet(0), me.setting, -1); } $('#componentsCacnel').click(); } }) }, round: function (v, e) { let t = 1; for (; e > 0; t *= 10, e--); for (; e < 0; t /= 10, e++); return Math.round(v * t) / t; }, reCalGljBasePrc: function (components) { /* let me = gljComponentOprObj; let gljBasePrc = 0; for(let i = 0; i < component.length; i++){ let roundBasePrc = scMathUtil.roundTo(parseFloat(component[i].basePrice), -2); let roundConsumeAmt = scMathUtil.roundTo(parseFloat(component[i].consumeAmt), -3); gljBasePrc = scMathUtil.roundTo(scMathUtil.roundTo(roundBasePrc * roundConsumeAmt, me.processDecimal) + gljBasePrc, me.processDecimal); } return gljBasePrc; */ let me = gljComponentOprObj, re = repositoryGljObj; // 只有一个单价的情况,只有一个单价则只有一个消耗量 if (!priceProperties || priceProperties.length === 0) { let gljBasePrc = 0; for (let i = 0; i < components.length; i++) { let roundBasePrc = scMathUtil.roundTo(parseFloat(components[i].basePrice), -2); let roundConsumeAmt = scMathUtil.roundTo(parseFloat(components[i].consumeAmt), -3); gljBasePrc = scMathUtil.roundTo(scMathUtil.roundTo(roundBasePrc * roundConsumeAmt, me.processDecimal) + gljBasePrc, me.processDecimal); } return scMathUtil.roundTo(gljBasePrc, -2); } else { // 多单价的情况 let gljPriceProperty = re.getPriceProperty(priceProperties); for (let priceProp in gljPriceProperty) { let consumeAmtField = re.getConsumeAmtField(consumeAmtProperties, priceProp); for (let component of components) { let roundBasePrc = scMathUtil.roundTo(parseFloat(component['priceProperty'][priceProp]), -2); let roundConsumeAmt = scMathUtil.roundTo(parseFloat(component['consumeAmtProperty'][consumeAmtField]), -3); gljPriceProperty[priceProp] = scMathUtil.roundTo(scMathUtil.roundTo(roundBasePrc * roundConsumeAmt, me.processDecimal) + gljPriceProperty[priceProp], me.processDecimal); } scMathUtil.roundTo(gljPriceProperty[priceProp], -2); } return gljPriceProperty; } } };