/** * Created by Zhong on 2018/1/19. **/ const locked = lockUtil.getLocked(); $(document).ready(function () { feeItemObj.buildSheet(); const lockedSpreads = [ feeItemObj.workBook, sectionObj.workBook, feeRuleObj.workBook ]; lockUtil.lockSpreads(lockedSpreads, locked); $('#sectionTreeModal').on('shown.bs.modal', function (e) { batchSectionObj.workBook.refresh(); //bind confirm btn batchSectionObj.onConfirmBtn(); }); $('#sectionTreeModal').on('hidden.bs.modal', function () { batchSectionObj.clearChecked(); }); $('#delConfirm').click(function () { if(curDeleteType === feeItemObj.deleteType){ let me = feeItemObj, se = sectionObj, fr = feeRuleObj; let fiPostData = [], sePostData = []; let sels = me.workBook.getSheet(0).getSelections(); for(let i = 0, len = sels.length; i < len; i++){ let sel = sels[i]; //delete if(sel.colCount === me.setting.header.length){ for(let j = 0, jLen = sel.rowCount; j < jLen; j++){ let row = sel.row + j; let feeItem = me.cache[row]; //有数据,删除数据 if(me.isDef(feeItem)){ fiPostData.push({updateType: me.updateType.update, updateData: {ID: feeItem.ID, deleted: true}}); //delete feeItem section for(let section of feeItem.section){ sePostData.push({updateType: me.updateType.update, updateData: {ID: section.ID, deleted: true}}); } } } //front delete me.cache.splice(sel.row, sel.rowCount); } } //update currentFeeItem me.currentFeeItem = me.getCurrentData(me.sheet, me.cache); se.cache = me.isDef(me.currentFeeItem) ? me.currentFeeItem.section : []; if(fiPostData.length > 0){ me.updateFeeItem(fiPostData, function () { me.sheet.setRowCount(me.cache.length + 10); sheetCommonObj.showData(me.sheet, me.setting, me.cache); $('#delAlert').modal('hide'); }); if(sePostData.length > 0){ se.updateSection(sePostData); } sheetCommonObj.cleanData(se.sheet, se.setting, 10); sheetCommonObj.cleanData(fr.sheet, fr.setting, 10); } else { $('#delAlert').modal('hide'); } } else if(curDeleteType === sectionObj.deleteType){ let me = sectionObj, fi = feeItemObj, fr = feeRuleObj; let sePostData = [], fiPostData = []; let sels = me.workBook.getSheet(0).getSelections(); for(let i = 0, len = sels.length; i < len; i++){ let sel = sels[i]; //delete if(sel.colCount === me.setting.header.length){ for(let j = 0, jLen = sel.rowCount; j < jLen; j++){ let row = sel.row + j; let section = me.cache[row]; //有数据,删除数据 if(me.isDef(section)){ sePostData.push({updateType: me.updateType.update, updateData: {ID: section.ID, deleted: true}}); fiPostData.push({updateType: me.updateType.update, updateData: {ID: fi.currentFeeItem.ID, $pull: {section: {ID: section.ID}}}}); } } //front delete me.cache.splice(sel.row, sel.rowCount); } } //update currentSection me.currentSection = fi.getCurrentData(me.sheet, me.cache); fr.cache = me.isDef(me.currentSection) ? me.currentSection.feeRule : []; if(sePostData.length > 0){ me.updateSection(sePostData, function () { me.sheet.setRowCount(me.cache.length + 5); sheetCommonObj.showData(me.sheet, me.setting, me.cache); $('#delAlert').modal('hide'); }); if(fiPostData.length > 0){ fi.updateFeeItem(fiPostData); } sheetCommonObj.cleanData(fr.sheet, fr.setting, 10); } else{ $('#delAlert').modal('hide'); } } }); }); let curDeleteType = null; //费用项 let feeItemObj = { rationRepId: null, workBook: null, sheet: null, cache: [], currentFeeItem: null, feeType: {ZM: '子目费用', FX: '分项费用', CS: '措施费用'}, updateType: {update: 'update', new: 'new'}, deleteType: 'feeItem', setting: { header:[ {headerName:"费用项",headerWidth:200,dataCode:"feeItem", dataType: "String", formatter: "@", hAlign: "left", vAlign: "center"}, {headerName:"费用类型",headerWidth:80,dataCode:"feeType", dataType: "String", hAlign: "center", vAlign: "center"}, {headerName:"记取位置",headerWidth:100,dataCode:"position", dataType: "String", formatter: "@", hAlign: "left", vAlign: "center"} ], view: {lockColumns: []}, comboItems: {feeType: ['子目费用', '分项费用', '措施费用']}, options: { tabStripVisible: false, allowCopyPasteExcelStyle : false, allowExtendPasteRange: true, allowUserDragDrop : false, allowUserDragFill: false, scrollbarMaxAlign : true } }, isDef: function (v) { return v !== undefined && v !== null; }, //sheet things setOptions: function (workbook, opts) { for(let opt in opts){ workbook.options[opt] = opts[opt]; } }, setCombo: function (sheet, col, comboItems) { let combo = sheetCommonObj.getDynamicCombo(); combo.items(comboItems).editable = false; sheet.getRange(-1, col, -1, 1).cellType(combo); }, getCurrentData: function (sheet, cache) { let acRow = sheet.getActiveRowIndex(); return this.isDef(cache[acRow]) ? cache[acRow] : null; }, buildSheet: function () { let me = this, se = sectionObj, fr = feeRuleObj, bs = batchSectionObj; if(!this.isDef(this.workBook)){ this.workBook = sheetCommonObj.buildSheet($('#feeItemSpread')[0], this.setting, 10); this.sheet = this.workBook.getActiveSheet(); sheetCommonObj.bindEscKey(this.workBook, [{sheet: this.sheet, editStarting: me.onEditStarting, editEnded: me.onEditEnded}]); this.setOptions(this.workBook, this.setting.options); this.sheet.options.clipBoardOptions = GC.Spread.Sheets.ClipboardPasteOptions.values; this.bindEvents(this.sheet); this.rationRepId = parseInt(getQueryString("repository")); //init combo this.setCombo(this.sheet, 1, this.setting.comboItems.feeType); //init sectionSpread se.buildSheet(); //init feeRuleSpread fr.buildSheet(); //init installation this.getInstallation(this.rationRepId, function (rstData) { me.cache = rstData; me.sheet.setRowCount(me.cache.length + 10); sheetCommonObj.showData(me.sheet, me.setting, me.cache); me.initSelection(me.cache[0]); }); //init batchSectionSpread bs.getSectionTree(this.rationRepId); } }, bindEvents: function (sheet) { let me = this; const Events = GC.Spread.Sheets.Events; sheet.bind(Events.SelectionChanged, me.onSelectionChanged); sheet.bind(Events.EnterCell, me.onEnterCell); sheet.bind(Events.EditStarting, me.onEditStarting); sheet.bind(Events.EditEnded, me.onEditEnded); sheet.bind(Events.ClipboardPasting, me.onClipboardPasting); sheet.bind(Events.ClipboardPasted, me.onClipboardPasted); me.feeItemDelOpr(); }, initSelection: function (feeItem) { let me = this, se = sectionObj, fr = feeRuleObj; sheetCommonObj.cleanSheet(se.sheet, se.setting, -1); sheetCommonObj.cleanSheet(fr.sheet, fr.setting, -1); if(!me.isDef(feeItem)){ me.workBook.focus(true); me.currentFeeItem = null; return; } fr.addObj = null; fr.updateObj = null; me.currentFeeItem = feeItem; se.cache = me.currentFeeItem.section; se.sheet.setRowCount(se.cache.length + 5); sheetCommonObj.showData(se.sheet, se.setting, se.cache); se.initSelection(se.cache[0]); me.workBook.focus(true); }, onSelectionChanged: function (sender, info) { let me = feeItemObj; if(info.oldSelections.length === 0 && info.newSelections.length > 0 || info.oldSelections[0].row !== info.newSelections[0].row){ let row = info.newSelections[0].row; let node = me.cache[row]; me.initSelection(node); } }, onEnterCell: function (sender, args) { let me = feeItemObj; me.sheet.repaint(); }, onEditStarting: function (sender, args) { let me = feeItemObj; //费用类型为子目时,记取位置不可编辑 let feeItem = me.cache[args.row]; if(me.isDef(feeItem) && (feeItem.feeType === me.feeType.ZM || !me.isDef(feeItem.feeType) || feeItem.feeType == '') && args.col === 2){ args.cancel = true; } }, onEditEnded: function (sender, args) { let me = feeItemObj, se = sectionObj; let v = me.isDef(args.editingText) ? args.editingText.toString().trim() : ''; let feeItem = me.cache[args.row]; let updateObj = {updateType: '', updateData: {}}; //update if(me.isDef(feeItem)){ feeItem[me.setting.header[args.col]['dataCode']] = !me.isDef(feeItem[me.setting.header[args.col]['dataCode']]) ? '' : feeItem[me.setting.header[args.col]['dataCode']]; if(v == feeItem[me.setting.header[args.col]['dataCode']]){ return; } updateObj.updateType = me.updateType.update; //当费用类型切换为子目费用时,自动清空记取位置 if(args.col === 1 && v === me.feeType.ZM){ feeItem.position = ''; args.sheet.setValue(args.row, 2, ''); updateObj.updateData.position = ''; } feeItem[me.setting.header[args.col]['dataCode']] = v; updateObj.updateData.ID = feeItem.ID; updateObj.updateData[me.setting.header[args.col]['dataCode']] = v; } //insert else { if(v === ''){ return; } updateObj.updateType = me.updateType.new; updateObj.updateData[me.setting.header[args.col]['dataCode']] = v; updateObj.updateData.rationRepId = me.rationRepId; updateObj.updateData.ID = uuid.v1(); updateObj.updateData.section = []; me.cache.push(updateObj.updateData); me.currentFeeItem = updateObj.updateData; se.cache = me.currentFeeItem.section; } me.sheet.setRowCount(me.cache.length + 10); sheetCommonObj.showData(me.sheet, me.setting, me.cache); //ajax me.updateFeeItem([updateObj]); }, onClipboardPasting: function (sender, info) { let me = this; if(info.cellRange.col + info.cellRange.colCount > me.setting.header.length){ info.cancel = true; } }, onClipboardPasted: function (sender, info) { let me = feeItemObj, se = sectionObj; let postData = []; let items = sheetCommonObj.analyzePasteData(me.setting, info); for(let i = 0, len = items.length; i < len; i++){ let row = info.cellRange.row + i; let feeItem = me.cache[row]; //update if(me.isDef(feeItem)){ if(me.validData(items[i])){ for(let attr in items[i]){ feeItem[attr] = items[i][attr]; } postData.push(me.getUpdateObj(me.updateType.update, feeItem)); } } //insert else{ if(me.validData(items[i])){ items[i].ID = uuid.v1(); items[i].rationRepId = me.rationRepId; items[i].section = []; postData.push(me.getUpdateObj(me.updateType.new, items[i])); me.cache.push(items[i]); } } } //update currentFeeItem me.currentFeeItem = me.getCurrentData(me.sheet, me.cache); se.cache = me.currentFeeItem.section; me.sheet.setRowCount(me.cache.length + 10); sheetCommonObj.showData(me.sheet, me.setting, me.cache); if(postData.length > 0){ //ajax then refresh me.updateFeeItem(postData); } }, feeItemDelOpr: function () { if (locked) { return; } let me = this; me.workBook.commandManager().register('feeItemDel', function () { curDeleteType = me.deleteType; let sels = me.workBook.getSheet(0).getSelections(); for(let i = 0, len = sels.length; i < len; i++){ let sel = sels[i]; //delete if(sel.colCount === me.setting.header.length){ $('#delAlert').modal('show'); break; } } }); me.workBook.commandManager().setShortcutKey(null, GC.Spread.Commands.Key.del, false, false, false, false); me.workBook.commandManager().setShortcutKey('feeItemDel', GC.Spread.Commands.Key.del, false, false, false, false); }, getUpdateObj: function (updateType, data) { let rst = {updateType: '', updateData: {}}; rst.updateType = updateType; for(let attr in data){ rst.updateData[attr] = data[attr]; } return rst; }, validData: function (pasteData) { if(this.isDef(pasteData.feeType)){ if(this.setting.comboItems.feeType.indexOf(pasteData.feeType) < 0){ return false; } //费用类型为子目时,不可有记取位置 if(pasteData.feeType === this.feeType.ZM && this.isDef(pasteData.position) && pasteData.position !== ''){ return false; } } return true; }, getInstallation: function (rationRepId, callback) { let me = this; CommonAjax.post('/rationRepository/api/getInstallation', {rationRepId: rationRepId}, function (rstData) { me.cache = rstData; if(callback){ callback(rstData); } }); }, updateFeeItem: function (updateData, callback) { let me = this; CommonAjax.post('/rationRepository/api/updateFeeItem', {updateData: updateData}, function (rstData) { if(callback){ callback(); } }); } }; //分册章节 let sectionObj = { workBook: null, sheet: null, cache: [], currentSection: null, updateType: {update: 'update', new: 'new'}, deleteType: 'section', setting: { header:[ {headerName:"分册章节",headerWidth:330,dataCode:"name", dataType: "String", formatter: "@", hAlign: "left", vAlign: "center"} ], view: {lockColumns: []}, options: { tabStripVisible: false, allowCopyPasteExcelStyle : false, allowExtendPasteRange: true, allowUserDragDrop : false, allowUserDragFill: false, scrollbarMaxAlign : true } }, isDef: function (v) { return v !== undefined && v !== null; }, //sheet things setOptions: function (workbook, opts) { for(let opt in opts){ workbook.options[opt] = opts[opt]; } }, renderFunc: function (sheet, func) { sheet.suspendPaint(); sheet.suspendEvent(); if(this.isFunc(func)){ func(); } sheet.resumePaint(); sheet.resumeEvent(); }, buildSheet: function () { if(!this.isDef(this.workBook)){ this.workBook = sheetCommonObj.buildSheet($('#instSectionSpread')[0], this.setting, 10); this.sheet = this.workBook.getActiveSheet(); sheetCommonObj.bindEscKey(this.workBook, [{sheet: this.sheet, editStarting: this.onEditStarting, editEnded: this.onEditEnded}]); this.setOptions(this.workBook, this.setting.options); this.sheet.options.clipBoardOptions = GC.Spread.Sheets.ClipboardPasteOptions.values; this.bindEvents(this.sheet); } }, bindEvents: function (sheet) { let me = sectionObj; const Events = GC.Spread.Sheets.Events; sheet.bind(Events.SelectionChanged, me.onSelectionChanged); sheet.bind(Events.EditStarting, me.onEditStarting); sheet.bind(Events.EditEnded, me.onEditEnded); sheet.bind(Events.ClipboardPasting, me.onClipboardPasting); sheet.bind(Events.ClipboardPasted, me.onClipboardPasted); me.sectionDelOpr(); me.onContextmenuOpr(); }, initSelection: function (section) { let me = sectionObj, fr = feeRuleObj; sheetCommonObj.cleanSheet(fr.sheet, fr.setting, -1); this.workBook.focus(true); if(!this.isDef(section)){ me.currentSection = null; return; } me.currentSection = section; fr.addObj = null; fr.updateObj = null; fr.cache = section.feeRule; fr.sheet.setRowCount(fr.cache.length + 5); sheetCommonObj.showData(fr.sheet, fr.setting, fr.cache); }, onContextmenuOpr: function () { let me = this; $.contextMenu({ selector: '#instSectionSpread', build: function($triggerElement, e){ //控制允许右键菜单在哪个位置出现 let sheet = me.sheet; let offset = $("#instSectionSpread").offset(), x = e.pageX - offset.left, y = e.pageY - offset.top; let target = sheet.hitTest(x, y); if(target.hitTestType === 3 && me.isDef(target.row) && me.isDef(target.col)){//在表格内 sheet.setActiveCell(target.row, target.col); me.initSelection(me.cache[target.row]); return { callback: function(){}, items: { "ref": { name: "批量关联至定额", disabled: function () { const inValidCell = !commonUtil.isDef(target.row) || !commonUtil.isDef(target.col); const inValidData = target.row >= me.cache.length; return locked || inValidCell || inValidData; }, icon: "fa-arrow-left", callback: function (key, opt) { $('#sectionTreeModal').modal('show'); } } } }; } else{ return false; } } }); }, onSelectionChanged: function (sender, info) { let me = sectionObj; if(info.oldSelections.length === 0 && info.newSelections.length > 0 || info.oldSelections[0].row !== info.newSelections[0].row){ let row = info.newSelections[0].row; let section = me.cache[row]; me.initSelection(section); } }, onEditStarting: function (sender, args) { let me = sectionObj, fi = feeItemObj; if(!me.isDef(fi.currentFeeItem)){ args.cancel = true; } }, onEditEnded: function (sender, args) { let me = sectionObj, fi = feeItemObj, fr = feeRuleObj; let v = me.isDef(args.editingText) ? args.editingText.toString().trim() : ''; let section = me.cache[args.row]; let updateObj = {updateType: '', updateData: {}}; //update if(me.isDef(section)){ section.name = !me.isDef(section.name) ? '' : section.name; if(section.name === v){ return; } if(v === ''){ me.sheet.setValue(args.row, args.col, section.name); return; } section.name = v; updateObj.updateType = me.updateType.update; updateObj.updateData.ID = section.ID; updateObj.updateData.name = v; } //insert else{ if(v === ''){ return; } updateObj.updateType = me.updateType.new; updateObj.updateData.ID = uuid.v1(); updateObj.updateData.rationRepId = fi.rationRepId; updateObj.updateData.name = v; updateObj.updateData.feeItemId = fi.currentFeeItem.ID; updateObj.updateData.feeRule = []; me.cache.push(updateObj.updateData); me.currentSection = updateObj.updateData; fr.cache = me.currentSection.feeRule; } me.sheet.setRowCount(me.cache.length + 5); sheetCommonObj.showData(me.sheet, me.setting, me.cache); me.updateSection([updateObj]); fi.updateFeeItem([{updateType: fi.updateType.update, updateData: {ID: fi.currentFeeItem.ID, $addToSet: {section: {ID: updateObj.updateData.ID}}}}]); }, onClipboardPasting: function (sender, info) { let me = sectionObj, fi = feeItemObj; if(info.cellRange.col + info.cellRange.colCount > me.setting.header.length || !me.isDef(fi.currentFeeItem)){ info.cancel = true; } }, onClipboardPasted: function (sender, info) { let me = sectionObj, fi = feeItemObj, fr = feeRuleObj; let sePostData = [], fiPostData = []; let items = sheetCommonObj.analyzePasteData(me.setting, info); for(let i = 0, len = items.length; i < len; i++){ let row = info.cellRange.row + i; let section = me.cache[row]; //update if(me.isDef(section)){ section.name = items[i].name; let updateObj = {updateType: me.updateType.update, updateData: {ID: section.ID, name: items[i].name}}; sePostData.push(updateObj); } //insert else{ let updateObj = {updateType: me.updateType.new, updateData: {ID: uuid.v1(), rationRepId: fi.rationRepId, name: items[i].name, feeItemId: fi.currentFeeItem.ID, feeRule: []}}; sePostData.push(updateObj); me.cache.push(updateObj.updateData); fiPostData.push({updateType: fi.updateType.update, updateData: {ID: fi.currentFeeItem.ID, $addToSet: {section: {ID: updateObj.updateData.ID}}}}); } } //update currentSection me.currentSection = fi.getCurrentData(me.sheet, me.cache); fr.cache = me.currentSection.feeRule; me.sheet.setRowCount(me.cache.length + 5); sheetCommonObj.showData(me.sheet, me.setting, me.cache); if(sePostData.length > 0){ me.updateSection(sePostData); if(fiPostData.length > 0){ fi.updateFeeItem(fiPostData); } } }, sectionDelOpr: function () { if (locked) { return; } let me = this; me.workBook.commandManager().register('sectionDel', function () { curDeleteType = me.deleteType; let sels = me.workBook.getSheet(0).getSelections(); for(let i = 0, len = sels.length; i < len; i++){ let sel = sels[i]; //delete if(sel.colCount === me.setting.header.length){ $('#delAlert').modal('show'); break; } } }); me.workBook.commandManager().setShortcutKey(null, GC.Spread.Commands.Key.del, false, false, false, false); me.workBook.commandManager().setShortcutKey('sectionDel', GC.Spread.Commands.Key.del, false, false, false, false); }, updateSection: function (updateData, callback) { CommonAjax.post('/rationRepository/api/updateSection', {updateData: updateData}, function (rstData) { if(callback){ callback(); } }); } }; //费用规则 let feeRuleObj = { workBook: null, sheet: null, addObj: null, updateObj: null, avtiveCell: {row: 0, col: 0}, cache: [], base: {RCJ: '分别按人材机乘系数', RG: '人工', CL: '材料', JX: '机械'}, setting: { header:[ {headerName:"编码",headerWidth:80,dataCode:"code", dataType: "String", formatter: "@", hAlign: "left", vAlign: "center", span:{row: 0, rowCount: 2, colCount: 1}}, {headerName:"费用规则",headerWidth:280,dataCode:"rule", dataType: "String", formatter: "@", hAlign: "left", vAlign: "center", span:{row: 0, rowCount: 2, colCount: 1}}, {headerName:"基数",headerWidth:140,dataCode:"base", dataType: "String", formatter: "@", hAlign: "left", vAlign: "center", span:{row: 0, rowCount: 2, colCount: 1}}, {headerName:"费率(%)",headerWidth:70,dataCode:"feeRate", dataType: "String", formatter: "@", hAlign: "center", vAlign: "center", span:{row: 0, rowCount: 2, colCount: 1}}, {headerName:"人工(%)",headerWidth:70,dataCode:"labour", dataType: "String", formatter: "@", hAlign: "center", vAlign: "center", span:{row: 1, rowCount: 1, colCount: 1}}, {headerName:"材料(%)",headerWidth:70,dataCode:"material", dataType: "String", formatter: "@", hAlign: "center", vAlign: "center", span:{row: 1, rowCount: 1, colCount: 1}}, {headerName:"机械(%)",headerWidth:70,dataCode:"machine", dataType: "String", formatter: "@", hAlign: "center", vAlign: "center", span:{row: 1, rowCount: 1, colCount: 1}} ], view: {lockColumns: []}, comboItems: {base: ['分别按人材机乘系数', '人工', '材料', '机械']}, options: { tabStripVisible: false, allowCopyPasteExcelStyle : false, allowExtendPasteRange: true, allowUserDragDrop : false, allowUserDragFill: false, scrollbarMaxAlign : true } }, isDef: function (v) { return v !== undefined && v !== null; }, //sheet things setOptions: function (workbook, opts) { for(let opt in opts){ workbook.options[opt] = opts[opt]; } }, buildHeader: function () { if(!this.sheet){ return; } this.sheet.suspendPaint(); this.sheet.suspendEvent(); let ch = GC.Spread.Sheets.SheetArea.colHeader; this.sheet.setRowCount(2, ch); for(let i = 0; i < this.setting.header.length; i++){ let header = this.setting.header[i]; this.sheet.addSpan(header.span.row, i, header.span.rowCount, header.span.colCount, ch); this.sheet.setValue(header.span.row, i, header.headerName, ch); if(header.dataCode === 'feeRate'){ this.sheet.addSpan(header.span.row, i + 1, 1, 3, ch); this.sheet.setValue(header.span.row, i + 1, '其中', ch); } } this.sheet.resumePaint(); this.sheet.resumeEvent(); }, buildSheet: function () { let fi = feeItemObj; if(!this.isDef(this.workBook)){ this.workBook = sheetCommonObj.buildSheet($('#instFeeRuleSpread')[0], this.setting, 10); this.sheet = this.workBook.getActiveSheet(); this.buildHeader(); this.sheet.setRowCount(); sheetCommonObj.bindEscKey(this.workBook, [{sheet: this.sheet, editStarting: this.onEditStarting, editEnded: this.onEditEnded}]) this.setOptions(this.workBook, this.setting.options); this.sheet.options.clipBoardOptions = GC.Spread.Sheets.ClipboardPasteOptions.values; this.bindEvents(this.sheet); //init combo fi.setCombo(this.sheet, 2, this.setting.comboItems.base); } }, bindEvents: function (sheet) { let me = feeRuleObj; const Events = GC.Spread.Sheets.Events; sheet.bind(Events.SelectionChanged, me.onSelectionChanged); sheet.bind(Events.EnterCell, me.onEnterCell); sheet.bind(Events.EditStarting, me.onEditStarting); sheet.bind(Events.EditEnded, me.onEditEnded); sheet.bind(Events.ClipboardPasting, me.onClipboardPasting); sheet.bind(Events.ClipboardPasted, me.onClipboardPasted); me.feeRuleDelOpr(); }, canSave: function (addObj) { return this.isDef(addObj.code) && addObj.code !== '' && !this.hasCode(addObj) && this.validRCJ(addObj); }, hasCode: function (obj) { let fi = feeItemObj; for(let feeItem of fi.cache){ for(let section of feeItem.section){ for(let feeRule of section.feeRule){ if(obj.code == feeRule.code && (this.isDef(obj.ID) && obj.ID !== feeRule.ID || !this.isDef(obj.ID))){ return true; } } } } return false; }, //费用类型为人、材、机时人材机总和一定要为100 validRCJ: function (feeRule) { if(!this.isDef(feeRule.base) || feeRule.base === this.base.RCJ){ return true; } let sum = 0; if(this.isDef(feeRule.labour)){ sum = parseFloat(sum + feeRule.labour).toDecimal(2); } if(this.isDef(feeRule.material)){ sum = parseFloat(sum + feeRule.material).toDecimal(2); } if(this.isDef(feeRule.machine)){ sum = parseFloat(sum + feeRule.machine).toDecimal(2); } return sum == 100; }, validPasteData: function (data) { //插入须有编码 if(!this.isDef(data.code)){ return false; } //编码须唯一 if(this.isDef(data.code) && this.hasCode(data)){ return false; } //基数要合法 if(this.isDef(data.base) && this.setting.comboItems.base.indexOf(data.base) < 0){ return false; } //费率、人工、材料、机械,须数字 if(this.isDef(data.feeRate) && isNaN(data.feeRate)){ return false; } if(this.isDef(data.labour) && isNaN(data.labour)){ return false; } if(this.isDef(data.material) && isNaN(data.material)){ return false; } if(this.isDef(data.machine) && isNaN(data.machine)){ return false; } //基数为分别按人材机时,费率须为空 if(this.isDef(data.base) && data.base === this.base.RCJ && this.isDef(data.feeRate) && data.feeRate !== ''){ return false; } //基数为 人工、材料、机械时 三者之和须为100 if(this.isDef(data.base) && data.base !== this.base.RCJ && this.validRCJ(data)){ return false; } return true; }, decimalPasteData: function (data) { if(this.isDef(data.feeRate) && isNaN(data.feeRate)){ data.feeRate = parseFloat(data.feeRate).toDecimal(2); } if(this.isDef(data.labour) && isNaN(data.labour)){ data.labour = parseFloat(data.labour).toDecimal(2); } if(this.isDef(data.material) && isNaN(data.material)){ data.material = parseFloat(data.material).toDecimal(2); } if(this.isDef(data.machine) && isNaN(data.machine)){ data.machine = parseFloat(data.machine).toDecimal(2); } }, getFocusToCol: function (feeRule) { if(!this.isDef(feeRule.labour) || feeRule.labour === '' || feeRule.labour > 100 || feeRule.labour == 0){ return 4; } if(!this.isDef(feeRule.material) || feeRule.material === '' || feeRule.material > 100 || feeRule.material == 0){ return 5; } if(!this.isDef(feeRule.machine) || feeRule.machine === '' || feeRule.machine > 100 || feeRule.machine == 0){ return 6; } return 4; }, onSelectionChanged: function (sender, info) { let me = feeRuleObj, se = sectionObj; if(info.oldSelections.length === 0 && info.newSelections.length > 0 || info.oldSelections[0].row !== info.newSelections[0].row){ if(me.isDef(me.updateObj) && !me.validRCJ(me.updateObj)){ $('#rcjAlert').modal('show'); $('#aleCanceBtn').bind('click', function () { me.updateObj.base = me.base.RCJ; me.updateObj.labour = 0; me.updateObj.material = 0; me.updateObj.machine = 0; me.sheet.setRowCount(me.cache.length + 5); sheetCommonObj.showData(me.sheet, me.setting, me.cache); se.updateSection([{updateType: se.updateType.update, updateData: se.currentSection}]); $(this).unbind(); }); $('#aleConfBtn').bind('click', function () { me.sheet.setActiveCell(me.avtiveCell.row, me.getFocusToCol(me.updateObj)); $(this).unbind(); }); } if(me.isDef(me.addObj)){ if(!me.isDef(me.addObj.code) || me.addObj.code === ''){ $('#alertText').text('请输入编码'); $('#codeAlert').modal('show'); $('#codAleClose').click(function () { me.addObj.code = ''; me.sheet.setActiveCell(me.avtiveCell.row, 0); $(this).unbind(); }); $('#codAlertQR').click(function () { me.addObj.code = ''; me.sheet.setActiveCell(me.avtiveCell.row, 0); $(this).unbind(); }); //取消插入 $('#codAlertQX').click(function () { me.addObj = null; me.sheet.setRowCount(me.cache.length + 5); sheetCommonObj.showData(me.sheet, me.setting, me.cache); $(this).unbind(); }); } else if(me.isDef(me.addObj.code) && me.hasCode(me.addObj)){ $('#alertText').text('输入的编号已存在,请重新输入'); $('#codeAlert').modal('show'); $('#codAleClose').click(function () { me.addObj.code = ''; me.sheet.setValue(me.avtiveCell.row, 0, ''); me.sheet.setActiveCell(me.avtiveCell.row,0); $(this).unbind(); }); $('#codAlertQR').click(function () { me.addObj.code = ''; me.sheet.setValue(me.avtiveCell.row, 0, ''); me.sheet.setActiveCell(me.avtiveCell.row, 0); $(this).unbind(); }); //取消插入 $('#codAlertQX').click(function () { me.addObj = null; me.sheet.setRowCount(me.cache.length + 5); sheetCommonObj.showData(me.sheet, me.setting, me.cache); $(this).unbind(); }); } else if(!me.validRCJ(me.addObj)){ $('#rcjAlert').modal('show'); $('#aleCanceBtn').bind('click', function () { me.addObj = null; me.sheet.setRowCount(me.cache.length + 5); sheetCommonObj.showData(me.sheet, me.setting, me.cache); $(this).unbind(); }); $('#aleConfBtn').bind('click', function () { me.sheet.setActiveCell(me.avtiveCell.row, me.getFocusToCol(me.addObj)); $(this).unbind(); }); } } } }, onEnterCell: function (sender, args) { let me = feeRuleObj; me.sheet.repaint(); }, onEditStarting: function (sender, args) { let me = feeRuleObj, se = sectionObj; let feeRule = me.cache[args.row]; let rcjCols = [4, 5, 6]; if(!me.isDef(se.currentSection)){ args.cancel = true; } if(me.isDef(feeRule) && me.isDef(feeRule.base) && feeRule.base === me.base.RCJ && args.col === 3){ args.cancel = true; } else if(!me.isDef(feeRule) && rcjCols.indexOf(args.col) > 0){ args.cancel = true; } }, onEditEnded: function (sender, args) { let me = feeRuleObj, se = sectionObj; let v = me.isDef(args.editingText) ? args.editingText.toString().trim() : ''; let updateObj = {updateType: '', updateData: {}}; let feeRule = me.cache[args.row]; let field = me.setting.header[args.col]['dataCode']; let orgV = me.isDef(feeRule) && me.isDef(feeRule[field]) ? feeRule[field] : ''; me.updateObj = feeRule; me.avtiveCell.row = args.row; me.avtiveCell.col = args.col; //update if(me.isDef(feeRule)){ feeRule[field] = me.isDef(feeRule[field]) ? feeRule[field] : ''; if(v === feeRule[field]){ return; } if(field === 'base' && v === me.base.RCJ){ //基数为人材机时,费率清空 feeRule.feeRate = ''; me.sheet.setValue(args.row, 3, ''); } else if(field === 'base' && (v === me.base.RG || v === me.base.CL || v === me.base.JX)){ if(!me.validRCJ(feeRule)){//基数变为人工、材料、机械时,若人材机之和不为100,则清空 feeRule.labour = 0; feeRule.material = 0; feeRule.machine = 0; } } else if(field === 'labour' || field === 'material' || field === 'machine' || field === 'feeRate'){ if(isNaN(v)){ alert('只能输入数值'); me.sheet.setValue(args.row, args.col, orgV); return; } v = parseFloat(v).toDecimal(2); me.sheet.setValue(args.row, args.col, v); } feeRule[field] = v; //编码重复,不可更新 if(field === 'code'){ if(v == ''){ me.sheet.setValue(args.row, args.col, orgV); return; feeRule[field] = orgV; } if(me.hasCode(feeRule)){ $('#codeAlert').modal('show'); $('#codAleClose').bind('click', function () { me.sheet.setActiveCell(args.row, 0); me.sheet.setValue(args.row, args.col, orgV); }); $('#codAlertQR').bind('click', function () { me.sheet.setActiveCell(args.row, 0); me.sheet.setValue(args.row, args.col, orgV); }); feeRule[field] = orgV; return; } } //是否能更新 //人材机之和不为100,不解决之和为100取消操作的话,则基数自动换成分别按人材机 if(!me.validRCJ(feeRule)){ return; } updateObj.updateType = se.updateType.update; updateObj.updateData.ID = se.currentSection.ID; updateObj.updateData.feeRule = me.cache; me.updateObj = null; se.updateSection([{updateType: se.updateType.update, updateData: se.currentSection}]); } //insert else{ if(v === ''){ return; } if(!me.isDef(me.addObj)){ me.addObj = Object.create(null); } me.addObj[me.setting.header[args.col]['dataCode']] = v; if(me.canSave(me.addObj)){ me.addObj.ID = uuid.v1(); me.cache.push(me.addObj); updateObj.updateType = se.updateType.update; updateObj.updateData.ID = se.currentSection.ID; updateObj.updateData.feeRule = me.cache; me.sheet.setRowCount(me.cache.length + 5); sheetCommonObj.showData(me.sheet, me.setting, me.cache); se.updateSection([{updateType: se.updateType.update, updateData: se.currentSection}]); me.addObj = null; } } }, onClipboardPasting: function (sender, info) { let me = feeRuleObj, se = sectionObj; if(info.cellRange.col + info.cellRange.colCount > me.setting.header.length){ info.cancel = true; } if(!me.isDef(se.currentSection)){ info.cancel = true; } }, onClipboardPasted: function (sender, info) { let me = feeRuleObj, se = sectionObj, fi = feeItemObj; let items = sheetCommonObj.analyzePasteData(me.setting, info); me.toUpdate = false; for(let i = 0, len = items.length; i < len; i++){ let row = info.cellRange.row + i; let feeRule = me.cache[row]; //update if(me.isDef(feeRule)){ let tempObj = {}; for(let attr in feeRule){ tempObj[attr] = feeRule[attr]; } for(let attr in items[i]){ tempObj[attr] = items[i][attr] } if(me.validPasteData(tempObj)){ me.decimalPasteData(tempObj); //front feeRule = tempObj; me.toUpdate = true; } } //insert else{ if(me.validPasteData(items[i])){ me.decimalPasteData(items[i]); items[i].ID = uuid.v1(); //front me.cache.push(items[i]); me.toUpdate = true; } } } me.sheet.setRowCount(me.cache.length + 5); sheetCommonObj.showData(me.sheet, me.setting, me.cache); if(me.toUpdate){ se.updateSection([{updateType: se.updateType.update, updateData: se.currentSection}]); } }, feeRuleDelOpr: function () { if (locked) { return; } let me = feeRuleObj, se = sectionObj; me.workBook.commandManager().register('feeRuleDel', function () { me.toUpdate = false; let sels = me.workBook.getSheet(0).getSelections(); for(let i = 0, len = sels.length; i < len; i++){ let sel = sels[i]; //delete if(sel.colCount === me.setting.header.length){ for(let j = 0, jLen = sel.rowCount; j < jLen; j++){ let row = sel.row + j; let feeRule = me.cache[row]; //有数据,删除数据 if(me.isDef(feeRule)){ me.toUpdate = true; } } //front delete me.cache.splice(sel.row, sel.rowCount); } } if(me.toUpdate){ se.updateSection([{updateType: se.updateType.update, updateData: se.currentSection}], function () { me.sheet.setRowCount(me.cache.length + 5); sheetCommonObj.showData(me.sheet, me.setting, me.cache); }); } }); me.workBook.commandManager().setShortcutKey(null, GC.Spread.Commands.Key.del, false, false, false, false); me.workBook.commandManager().setShortcutKey('feeRuleDel', GC.Spread.Commands.Key.del, false, false, false, false); } }; let batchSectionObj = { cache: null, tree: null, controller: null, workBook: null, sheet: null, IDRowMapping: null, //树节点ID与行号映射 setting: { sheet: { cols:[ { head: { titleNames: ['选择'], spanCols: [1], spanRows: [2], vAlign: [1, 1], hAlign: [1, 1], font: 'Arial' }, data: { field: 'select', vAlign: 1, hAlign: 0, font: 'Arial' }, width: 50 }, { head: { titleNames: ['名称'], spanCols: [1], spanRows: [2], vAlign: [1, 1], hAlign: [1, 1], font: 'Arial' }, data: { field: 'name', vAlign: 1, hAlign: 0, font: 'Arial' }, width: 400 } ], headRows: 1, headRowHeight: [47], emptyRows: 0, treeCol: 1 }, tree: { id: 'ID', pid: 'ParentID', nid: 'NextSiblingID', rootId: -1 }, options: { tabStripVisible: false, allowCopyPasteExcelStyle : false, allowExtendPasteRange: true, allowUserDragDrop : false, allowUserDragFill: false, scrollbarMaxAlign : true } }, isDef: function (v) { return v !== undefined && v !== null; }, renderFunc: function (sheet, func) { sheet.suspendPaint(); sheet.suspendEvent(); if(func){ func(); } sheet.resumePaint(); sheet.resumeEvent(); }, setOptions: function (workbook, opts) { for(let opt in opts){ workbook.options[opt] = opts[opt]; } }, buildSheet: function () { if(!this.isDef(this.workBook)){ this.workBook = new GC.Spread.Sheets.Workbook($('#batchSectionSpread')[0], {sheetCount: 1}); this.sheet = this.workBook.getActiveSheet(); this.setOptions(this.workBook, this.setting.options); this.bindEvents(this.sheet); } }, bindEvents: function (sheet) { let me = this; const Events = GC.Spread.Sheets.Events; sheet.bind(Events.EditStarting, me.onEditStarting); sheet.bind(Events.EditEnded, me.onEditEnded); sheet.bind(Events.ClipboardPasting, me.onClipboardPasting); me.workBook.bind(Events.ButtonClicked, me.onButtonClicked);//复选框点击事件 }, getSectionTree: function (repId) { let me = this; let url = 'api/getRationTree'; let postData = {rationLibId: repId}; let sucFunc = function (rstData) { //init me.buildSheet(); me.initTree(rstData); me.buildMapping(me.tree.items); me.cache = me.tree.items; me.initController(me.tree, me.sheet, me.setting.sheet); me.controller.showTreeData(); me.sheet.setFormatter(-1, 1, '@'); //init checkBox let checkBox = new GC.Spread.Sheets.CellTypes.CheckBox(); me.sheet.getRange(-1, 0, -1, 1).cellType(checkBox); me.sheet.getRange(-1, 0, -1, 1).hAlign(GC.Spread.Sheets.HorizontalAlign.center); }; let errFunc = function () { }; CommonAjax.post(url, postData, sucFunc, errFunc); }, buildMapping: function (items) { this.IDRowMapping = {}; for(let i = 0, len = items.length; i < len; i++){ this.IDRowMapping[items[i].data.ID] = i; } }, initTree: function (datas) { this.tree = idTree.createNew(this.setting.tree); this.tree.loadDatas(datas); this.tree.selected = this.tree.items.length > 0 ? this.tree.items[0] : null; }, initController: function (tree, sheet, setting) { this.controller = TREE_SHEET_CONTROLLER.createNew(tree, sheet, setting); }, onEditStarting: function (sender, args) { args.cancel = true; }, onButtonClicked: function (sender, args) { let me = batchSectionObj; if(args.sheet.isEditing()){ args.sheet.endEdit(true); } let node = me.cache[args.row]; let checked = args.sheet.getValue(args.row, args.col); if(!me.isDef(node)){ return; } let rows = me.getChildRows(node); me.setChecked(rows, checked); }, onClipboardPasting: function (sender, info) { info.cancel = true; }, getChildRows: function (node) { let rst = [], ids = []; getChildIds(node); for(id of ids){ let row = this.IDRowMapping[id]; if(this.isDef(row)){ rst.push(row); } } return rst; function getChildIds(node){ ids.push(node.data.ID); for(let child of node.children){ getChildIds(child); } } }, //设置勾选,跟随父节点 setChecked: function (rows, checked) { let me = this; this.renderFunc(this.sheet, function () { for(let row of rows){ me.sheet.setValue(row, 0, checked); } }); }, //获得勾选的章节ID getCheckedSection: function (sheet) { let rst = []; let rowCount = sheet.getRowCount(); for(let i = 0, len = rowCount; i < len; i++){ let checked = sheet.getValue(i, 0); //只返回叶子节点 if(this.isDef(checked) && checked == true && this.isDef(this.cache[i]) && this.isDef(this.cache[i].data.ID) && this.cache[i].children.length === 0){ rst.push(this.cache[i].data.ID); } } return Array.from(new Set(rst)); }, clearChecked: function () { let me = this; this.renderFunc(this.sheet, function () { let rowCount = me.sheet.getRowCount(); for(let i = 0, len = rowCount; i < len; i++){ me.sheet.setValue(i, 0, false); } }); }, onConfirmBtn: function () { let me = this, fi = feeItemObj, se = sectionObj; $('#bsTree_conf').bind('click', function () { let feeItemId = fi.currentFeeItem.ID; let sectionId = se.currentSection.ID; let rationSection = me.getCheckedSection(me.sheet); me.batchUpdate(feeItemId, sectionId, rationSection); $(this).unbind(); }); }, //inst: 定额安装费用, rationSection: 定额章节树IDs batchUpdate: function (feeItemId, sectionId, rationSection) { CommonAjax.post('/rationRepository/api/batchUpdateInst', {inst: {feeItemId: feeItemId, sectionId: sectionId}, rationSection: rationSection}, function (rstData) { $('#sectionTreeModal').modal('hide'); }); } };