/** * 台账相关js * * @author Mai * @date 2018/02/05 * @version */ $(document).ready(function() { autoFlashHeight(); const ledgerSpread = SpreadJsObj.createNewSpread($('#ledger-spread')[0]); SpreadJsObj.addDeleteBind(ledgerSpread); const ledgerTree = createNewPathTree({ id: 'ledger_id', pid: 'ledger_pid', order: 'order', level: 'level', rootId: -1, keys: ['id', 'tender_id', 'ledger_id'] }); ledgerTree.loadDatas(ledger); SpreadJsObj.initSheet(ledgerSpread.getActiveSheet(), { cols: [ {title: '项目节编号', field: 'code', width: 150, cellType: 'tree'}, {title: '清单编号', field: 'b_code', width: 80}, {title: '名称', field: 'name', width: 230}, {title: '单位', field: 'unit', width: 50}, {title: '单价', field: 'unit_price', width: 60, type: 'Number'}, {title: '数量', field: 'quantity', width: 60, type: 'Number'}, {title: '金额', field: 'total_price', width: 60, type: 'Number'}, {title: '施工图原设计', field: 'design', width: 60}, {title: '图(册)号', field: 'drawingCode', width: 80}, {title: '备注', field: 'memo', width: 100} ], treeCol: 0, emptyRows: 3, headRows: 2, headRowHeight: [40, 40], defaultRowHeight: 21, }); SpreadJsObj.loadSheetData(ledgerSpread.getActiveSheet(), 'tree', ledgerTree); const treeOperationObj = { /** * 刷新顶部按钮是否可用 * @param sheet * @param selections */ refreshOperationValid: function (sheet, selections) { const setObjEnable = function (obj, enable) { if (enable) { obj.removeClass('disabled'); } else { obj.addClass('disabled'); } }; const row = selections[0].row; const tree = sheet.zh_tree; if (!tree) { return; } const node = sheet.zh_tree.nodes[row]; setObjEnable($('#delete'), node); setObjEnable($('#up-move'), node && node.order > 1); setObjEnable($('#down-move'), node && !tree.isLastSibling(node)); setObjEnable($('#up-level'), node && tree.getParent(node)); setObjEnable($('#down-level'), node && node.order > 1); }, refreshTree: function (sheet, data) { SpreadJsObj.massOperationSheet(sheet, function () { const tree = sheet.zh_tree; // 处理删除 if (data.delete) { for (const d of data.delete) { sheet.deleteRows(tree.nodes.indexOf(d), 1); } } // 处理新增 if (data.create) { const newNodes = data.create; if (newNodes) { newNodes.sort(function (a, b) { const aIndex = tree.nodes.indexOf(a); const bIndex = tree.nodes.indexOf(b); return aIndex - bIndex; }); for (const node of newNodes) { const index = tree.nodes.indexOf(node); sheet.addRows(index, 1); SpreadJsObj.reLoadRowData(sheet, index, 1); } } } // 处理更新 if (data.update) { const rows = []; for (const u of data.update) { rows.push(tree.nodes.indexOf(u)); } SpreadJsObj.reLoadRowsData(sheet, rows); } // 处理展开 if (data.expand) { for (const e of data.expand) { const children = tree.getChildren(e); for (const child of children) { sheet.setRowVisible(tree.nodes.indexOf(child), child.visible); } } } }); }, /** * 新增节点 * @param spread */ addNode: function (spread) { const self = this; const sheet = spread.getActiveSheet(); const row = sheet.getSelections()[0].row; const tree = sheet.zh_tree; if (!tree) { return; } const node = sheet.zh_tree.nodes[row]; if (!node) { return; } SpreadJsObj.massOperationSheet(sheet, function () { tree.baseOperation('base-operation', node, 'add', function (result) { self.refreshTree(sheet, result); self.refreshOperationValid(sheet, sheet.getSelections()); }); }); }, /** * 删除选中节点 * @param spread */ deleteNode: function (spread) { const self = this; const sheet = spread.getActiveSheet(); const row = sheet.getSelections()[0].row; const tree = sheet.zh_tree; if (!tree) { return; } const node = sheet.zh_tree.nodes[row]; if (!node) { return; } const count = ledgerTree.getPosterity(node).length; tree.baseOperation('base-operation', node, 'delete', function (result) { sheet.deleteRows(row, count + 1); for (const data of result.update) { SpreadJsObj.reLoadRowData(sheet, tree.nodes.indexOf(data), tree.getPosterity(data).length + 1); } self.refreshOperationValid(sheet, sheet.getSelections()); }); }, /** * 上移选中节点 * @param spread */ upMove: function (spread) { const self = this; const sheet = spread.getActiveSheet(); const sel = sheet.getSelections()[0]; const row = sel.row; const tree = sheet.zh_tree; if (!tree) { return; } const node = tree.nodes[row]; if (!node) { return; } tree.baseOperation('base-operation', node, 'up-move', function (result) { for (const data of result.update) { SpreadJsObj.reLoadRowData(sheet, tree.nodes.indexOf(data), tree.getPosterity(data).length + 1); } sheet.setSelection(tree.nodes.indexOf(node), sel.col, sel.rowCount, sel.colCount); self.refreshOperationValid(sheet, sheet.getSelections()); //sheet.moveTo(row, -1, tree.nodes.indexOf(node), -1, tree.getPosterity(node).length + 1, -1, GC.Spread.Sheets.CopyToOptions.value); }); }, /** * 下移选中节点 * @param spread */ downMove: function (spread) { const self = this; const sheet = spread.getActiveSheet(); const sel = sheet.getSelections()[0]; const row = sel.row; const tree = sheet.zh_tree; if (!tree) { return; } const node = tree.nodes[row]; if (!node) { return; } tree.baseOperation('base-operation', node, 'down-move', function (result) { for (const data of result.update) { SpreadJsObj.reLoadRowData(sheet, tree.nodes.indexOf(data), tree.getPosterity(data).length + 1); } sheet.setSelection(tree.nodes.indexOf(node), sel.col, sel.rowCount, sel.colCount); self.refreshOperationValid(sheet, sheet.getSelections()); }); }, /** * 升级选中节点 * @param spread */ upLevel: function (spread) { const self = this; const sheet = spread.getActiveSheet(); const row = sheet.getSelections()[0].row; const tree = sheet.zh_tree; if (!tree) { return; } const node = tree.nodes[row]; if (!node) { return; } tree.baseOperation('base-operation', node, 'up-level', function (result) { self.refreshTree(sheet, result); self.refreshOperationValid(sheet, sheet.getSelections()); }); }, /** * 降级选中节点 * @param spread */ downLevel: function (spread) { const self = this; const sheet = spread.getActiveSheet(); const row = sheet.getSelections()[0].row; const tree = sheet.zh_tree; if (!tree) { return; } const node = tree.nodes[row]; if (!node) { return; } tree.baseOperation('base-operation', node, 'down-level', function (result) { self.refreshTree(sheet, result); self.refreshOperationValid(sheet, sheet.getSelections()); }); }, /** * 编辑单元格响应事件 * @param {Object} e * @param {Object} info */ editEnded: function (e, info) { if (info.sheet.zh_setting) { const col = info.sheet.zh_setting.cols[info.col]; const sortData = info.sheet.zh_dataType === 'tree' ? info.sheet.zh_tree.nodes : info.sheet.zh_data; const node = sortData[info.row]; const data = { id: node.id, tender_id: node.tender_id, ledger_id: node.ledger_id }; data[col.field] = col.type === 'Number' ? parseFloat(info.editingText) : info.editingText; info.sheet.zh_tree.update('update', data, function (result) { const rows = []; for (const r of result) { rows.push(sortData.indexOf(r)); } SpreadJsObj.reLoadRowsData(info.sheet, rows); }); } }, /** * 粘贴单元格响应事件 * @param e * @param info */ clipboardPasted: function (e, info) { if (info.sheet.zh_setting && info.sheet.zh_dataType === 'tree') { const sortData = info.sheet.zh_tree.nodes; const datas = [], nodes = []; for (let iRow = 0; iRow < info.cellRange.rowCount; iRow ++) { const curRow = info.cellRange.row + iRow; const node = sortData[curRow]; if (node) { const data = info.sheet.zh_tree.getNodeKeyData(node); for (let iCol = 0; iCol < info.cellRange.colCount; iCol++) { const curCol = info.cellRange.col + iCol; const colSetting = info.sheet.zh_setting.cols[curCol]; data[colSetting.field] = info.sheet.getText(curRow, curCol); } datas.push(data); nodes.push(node); } } info.sheet.zh_tree.update('update', datas, function (result) { const rows = []; for (const data of result) { rows.push(sortData.indexOf(data)); } SpreadJsObj.reLoadRowsData(info.sheet, rows); }); } }, /** * 删除按钮响应事件 * @param sheet */ deletePress: function (sheet) { if (sheet.zh_setting && sheet.zh_dataType === 'tree') { const sortData = sheet.zh_tree.nodes; const datas = [], nodes = []; const sel = sheet.getSelections()[0]; for (let iRow = sel.row; iRow < sel.row + sel.rowCount; iRow++) { const node = sortData[iRow]; if (node) { const data = sheet.zh_tree.getNodeKeyData(node); for (let iCol = sel.col; iCol < sel.col + sel.colCount; iCol++) { const colSetting = sheet.zh_setting.cols[iCol]; data[colSetting.field] = null; } datas.push(data); nodes.push(node); } } sheet.zh_tree.update('update-info', datas, function (result) { const rows = []; for (const data of result) { rows.push(sortData.indexOf(data)); } SpreadJsObj.reLoadRowsData(sheet, rows); }); } }, /** * 粘贴整块 * @param spread * @param block */ pasteBlock: function (spread, block) { const self = this; const sheet = spread.getActiveSheet(); const row = sheet.getSelections()[0].row; const tree = sheet.zh_tree; if (!tree) { return; } const node = tree.nodes[row]; if (!node) { return; } tree.pasteBlock('paste-block', node, block, function (result) { self.refreshTree(sheet, result); self.refreshOperationValid(sheet, sheet.getSelections()); }); } }; ledgerSpread.bind(GC.Spread.Sheets.Events.SelectionChanged, function (e, info) { treeOperationObj.refreshOperationValid(info.sheet, info.newSelections); }); ledgerSpread.bind(GC.Spread.Sheets.Events.EditEnded, treeOperationObj.editEnded); ledgerSpread.bind(GC.Spread.Sheets.Events.ClipboardPasted, treeOperationObj.clipboardPasted); SpreadJsObj.addDeleteBind(ledgerSpread, treeOperationObj.deletePress); ledgerSpread.bind(GC.Spread.Sheets.Events.ClipboardChanging, function (e, info) { const copyText = SpreadJsObj.getFilterCopyText(info.sheet); }); ledgerSpread.bind(GC.Spread.Sheets.Events.ClipboardChanged, function (e, info) { console.log(info.copyData.text); }); ledgerSpread.bind(GC.Spread.Sheets.Events.ClipboardPasting, function (e, info) { }); // 绑定 删除等 顶部按钮 $('#delete').click(function () { treeOperationObj.deleteNode(ledgerSpread); }); $('#up-move').click(function () { treeOperationObj.upMove(ledgerSpread); }); $('#down-move').click(function () { treeOperationObj.downMove(ledgerSpread); }); $('#up-level').click(function () { treeOperationObj.upLevel(ledgerSpread); }); $('#down-level').click(function () { treeOperationObj.downLevel(ledgerSpread); }); treeOperationObj.refreshOperationValid(ledgerSpread.getActiveSheet(), ledgerSpread.getActiveSheet().getSelections()); // 右键菜单 $.contextMenu({ selector: '#ledger-spread', build: function ($trigger, e) { const target = SpreadJsObj.safeRightClickSelection($trigger, e, ledgerSpread); return target.hitTestType === GC.Spread.Sheets.SheetArea.viewport || target.hitTestType === GC.Spread.Sheets.SheetArea.rowHeader; }, items: { 'create': { name: '新增', icon: 'fa-sign-in', callback: function (key, opt) { treeOperationObj.addNode(ledgerSpread); }, visible: function(key, opt){ const sheet = ledgerSpread.getActiveSheet(); const selection = sheet.getSelections(); const row = selection[0].row; const select = ledgerTree.nodes[row]; return select; } }, 'delete': { name: '删除', icon: 'fa-remove', callback: function (key, opt) { treeOperationObj.deleteNode(ledgerSpread); }, visible: function (key, opt) { const sheet = ledgerSpread.getActiveSheet(); const selection = sheet.getSelections(); const row = selection[0].row; const select = ledgerTree.nodes[row]; return select; } }, 'copyBlock': { name: '复制整块', icon: 'fa-files-o', callback: function (key, opt) { /*ledgerSpread.commandManager().execute({ cmd:"copy", sheetName:ledgerSpread.getActiveSheet().name() });*/ treeOperationObj.block = []; const copyBlockList = []; const sheet = ledgerSpread.getActiveSheet(); const sel = sheet.getSelections()[0]; let iRow = sel.row; const pid = sheet.zh_tree.nodes[iRow].ledger_pid; while (iRow < sel.row + sel.rowCount) { const node = sheet.zh_tree.nodes[iRow]; if (node.ledger_pid !== pid) { toast('error: 仅可同时选中同层节点', 'error', 'exclamation-circle'); return; } copyBlockList.push(node.ledger_id); iRow += sheet.zh_tree.getPosterity(node).length + 1; } treeOperationObj.block = copyBlockList; }, visible: function (key, opt) { const sheet = ledgerSpread.getActiveSheet(); const selection = sheet.getSelections(); const row = selection[0].row; const select = ledgerTree.nodes[row]; return select; } }, 'pasteBlock': { name: '粘贴', icon: 'fa-clipboard', disabled: function (key, opt) { const block = treeOperationObj.block || []; return block.length <= 0 && false; }, callback: function (key, opt) { const block = treeOperationObj.block || []; if (block.length > 0) { treeOperationObj.pasteBlock(ledgerSpread, block); } else { document.execCommand('paste'); } } } } }); let stdChapter, stdBills, dealBills; // 展开收起标准清单 $('a', '#side-menu').bind('click', function () { const tab = $(this), tabPanel = $(tab.attr('content')); const showSideTools = function (show) { if (show) { $('.c-body.col-12').removeClass('col-12').addClass('col-8'); $('.c-body.col-0').removeClass('col-0').addClass('col-4').show(); } else { $('.c-body.col-8').removeClass('col-8').addClass('col-12'); $('.c-body.col-4').removeClass('col-4').addClass('col-0').hide(); } } if (!tab.hasClass('active')) { $('a', '#side-menu').removeClass('active'); tab.addClass('active'); showSideTools(tab.hasClass('active')); $('.tab-content .tab-pane').hide(); tabPanel.show(); if (tab.attr('content') === '#std-chapter' && !stdChapter) { stdChapter = new stdLib($('#std-chapter-spread')[0], 'chapter', { id: 'chapter_id', pid: 'pid', order: 'order', level: 'level', rootId: -1, keys: ['id', 'list_id', 'chapter_id'], }, { cols: [ {title: '项目节编号', field: 'code', width: 120, readOnly: true, cellType: 'tree'}, {title: '名称', field: 'name', width: 230, readOnly: true}, {title: '单位', field: 'unit', width: 50, readOnly: true} ], treeCol: 0, emptyRows: 0 }); stdChapter.loadLib(1); } else if (tab.attr('content') === '#std-bills' && !stdBills) { stdBills = new stdLib($('#std-bills-spread')[0], 'bills', { id: 'bill_id', pid: 'pid', order: 'order', level: 'level', rootId: -1, keys: ['id', 'list_id', 'bill_id'] }, { cols: [ {title: '清单编号', field: 'code', width: 120, readOnly: true, cellType: 'tree'}, {title: '名称', field: 'name', width: 230, readOnly: true}, {title: '单位', field: 'unit', width: 50, readOnly: true} ], treeCol: 0, emptyRows: 0 }); stdBills.loadLib(1); } else if (tab.attr('content') === '#deal-bills' && !dealBills) { dealBills = new DealBills($('#deal-bills-spread')[0], { cols: [ {title: '清单编号', field: 'code', width: 120, readOnly: true, cellType: 'tree'}, {title: '名称', field: 'name', width: 230, readOnly: true}, {title: '单位', field: 'unit', width: 50, readOnly: true}, {title: '单价', field: 'unit_price', width: 50, readOnly: true}, {title: '数量', field: 'quantity', width: 50, readOnly: true}, ], emptyRows: 0, }); dealBills.loadData(); } } else { tab.removeClass('active'); showSideTools(tab.hasClass('active')); tabPanel.hide(); } ledgerSpread.refresh(); }); class stdLib { constructor(obj, stdType, treeSetting, spreadSetting) { this.obj = obj; this.url = '/std/' + stdType; this.treeSetting = treeSetting; treeSetting.preUrl = this.url; this.spreadSetting = spreadSetting; this.spread = SpreadJsObj.createNewSpread(this.obj); SpreadJsObj.initSheet(this.spread.getActiveSheet(), this.spreadSetting); this.spread.getActiveSheet().bind(GC.Spread.Sheets.Events.CellDoubleClick, function (e, info) { const stdSheet = info.sheet; const mainSheet = ledgerSpread.getActiveSheet(); if (!stdSheet.zh_setting || !stdSheet.zh_tree || !mainSheet.zh_tree) { return; } const stdTree = stdSheet.zh_tree; const stdNode = stdTree.nodes[info.row]; const mainTree = mainSheet.zh_tree; const sel = mainSheet.getSelections()[0]; const mainNode = mainTree.nodes[sel.row]; if (!stdNode) { return; } mainTree.postData('add-by-std', mainNode, { tender_id: mainNode.tender_id, stdType: stdType, stdLibId: stdNode.list_id, stdNode: stdTree.getNodeKey(stdNode) }, function (result) { treeOperationObj.refreshTree(mainSheet, result); treeOperationObj.refreshOperationValid(mainSheet, mainSheet.getSelections()); }); }); this.pathTree = createNewPathTree(this.treeSetting); } loadLib (listId) { const self = this; postData(this.url+'/get-data', {list_id: listId}, function (data) { self.pathTree.loadDatas(data); SpreadJsObj.loadSheetData(self.spread.getActiveSheet(), 'tree', self.pathTree); }); } }; class DealBills { constructor (obj, spreadSetting) { const self = this; this.obj = obj; this.url = '/deal'; this.spreadSetting = spreadSetting; this.spread = SpreadJsObj.createNewSpread(this.obj); SpreadJsObj.initSheet(this.spread.getActiveSheet(), this.spreadSetting); $('#upload-deal-bills').click(function () { const file = $('#deal-bills-file')[0]; const formData = new FormData(); formData.append('file', file.files[0]); postDataWithFile(self.url+'/upload-excel', formData, function (data) { SpreadJsObj.loadSheetData(self.spread.getActiveSheet(), 'data', data); $('#upload-deal').modal('hide'); }, function () { $('#upload-deal').modal('hide'); }); }) } loadData () { const self = this; postData(this.url+'/get-data', {}, function (data) { SpreadJsObj.loadSheetData(self.spread.getActiveSheet(), 'data', data); }); } } });