/** * 台账相关js * * @author Mai * @date 2018/02/05 * @version */ function checkTzMeasureType () { return tender.measure_type === measureType.tz.value; } function getTenderId() { return window.location.pathname.split('/')[2]; } $(document).ready(function() { autoFlashHeight(); // 初始化台账 const ledgerSpread = SpreadJsObj.createNewSpread($('#ledger-spread')[0]); SpreadJsObj.addDeleteBind(ledgerSpread); const treeSetting = { id: 'ledger_id', pid: 'ledger_pid', order: 'order', level: 'level', rootId: -1, keys: ['id', 'tender_id', 'ledger_id'], preUrl: '/tender/' + getTenderId() + '/ledger', }; if (checkTzMeasureType()) { treeSetting.calcFields = ['total_price']; } else { treeSetting.calcFields = ['deal_tp', 'total_price']; } treeSetting.calcFun = function (node) { if (checkZero(node.dgn_qty1)) { node.dgn_price = _.round(node.total_price/node.dgn_qty1, 6); } else { node.dgn_price = null; } }; const ledgerTree = createNewPathTree('ledger', treeSetting); ledgerTree.loadDatas(ledger); treeCalc.calculateAll(ledgerTree); SpreadJsObj.initSheet(ledgerSpread.getActiveSheet(), ledgerSpreadSetting); // 加载台账数据到界面 SpreadJsObj.loadSheetData(ledgerSpread.getActiveSheet(), 'tree', ledgerTree); // 初始化 部位明细 const pos = new PosData({ id: 'id', masterId: 'lid', }); const posSpread = SpreadJsObj.createNewSpread($('#pos-spread')[0]); // 定义事件 const treeOperationObj = { getSelectNode: function (sheet) { if (!sheet || !sheet.zh_tree) { return null; } else { const sel = sheet.getSelections()[0]; return sheet.zh_tree.nodes[sel.row]; } }, /** * 刷新顶部按钮是否可用 * @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]; const valid = !sheet.zh_setting.readOnly; setObjEnable($('#delete'), valid && node); setObjEnable($('#up-move'), valid && node && node.order > 1); setObjEnable($('#down-move'), valid && node && !tree.isLastSibling(node)); if (checkTzMeasureType()) { const posRange = node ? pos.getMasterRange(node.id) : []; setObjEnable($('#up-level'), valid && node && tree.getParent(node) && (!posRange || posRange.length === 0)); } else { setObjEnable($('#up-level'), valid && node && tree.getParent(node)); } setObjEnable($('#down-level'), valid && 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); } } // 处理新增 let cTime = new Date(); if (data.create) { const newNodes = data.create; if (newNodes) { let sTime = new Date(); newNodes.sort(function (a, b) { return a.index - b.index; }); sTime = new Date() - sTime; console.log('sort: ' + sTime); let lTime = new Date(); for (const node of newNodes) { sheet.addRows(node.index, 1); SpreadJsObj.reLoadRowData(sheet, tree.nodes.indexOf(node), 1); } lTime = new Date() - lTime; console.log('load: '+ lTime); } } cTime = new Date() - cTime; console.log('refreshNewNode: ' + cTime); // 处理更新 if (data.update) { const rows = []; for (const u of data.update) { rows.push(tree.nodes.indexOf(u)); } SpreadJsObj.reLoadRowsData(sheet, rows); } // 处理展开 if (data.expand) { const expanded = []; for (const e of data.expand) { if (expanded.indexOf(e) === -1) { const posterity = tree.getPosterity(e); for (const p of posterity) { sheet.setRowVisible(tree.nodes.indexOf(p), p.visible); expanded.push(p); } } } } }); }, /** * 新增节点 * @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('/tender/' + getTenderId() + '/ledger/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('/tender/' + getTenderId() + '/ledger/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()); for (const data of result.delete) { pos.removeDatasByMasterId(data.id); } posOperationObj.loadCurPosData(); }); }, /** * 上移选中节点 * @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('/tender/' + getTenderId() + '/ledger/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('/tender/' + getTenderId() + '/ledger/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('/tender/' + getTenderId() + '/ledger/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('/tender/' + getTenderId() + '/ledger/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('/tender/' + getTenderId() + '/ledger/update', data, function (result) { treeOperationObj.refreshTree(info.sheet, result); }); } }, /** * 粘贴单元格响应事件 * @param e * @param info */ clipboardPasted: function (e, info) { if (info.sheet.zh_setting && info.sheet.zh_dataType === 'tree') { const tree = sheet.zh_tree; if (!tree) { return; } 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('/tender/' + getTenderId() + '/ledger/update', datas, function (result) { treeOperationObj.refreshTree(info.sheet, result); }); } }, /** * 删除按钮响应事件 * @param sheet */ deletePress: function (sheet) { if (sheet.zh_setting && sheet.zh_dataType === 'tree') { const tree = sheet.zh_tree; if (!tree) { return; } 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('/tender/' + getTenderId() + '/ledger/update', datas, function (result) { treeOperationObj.refreshTree(sheet, result); }); } }, /** * 粘贴整块 * @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; } postData('/tender/' + getTenderId() + '/ledger/paste-block', { id: node[tree.setting.id], block: block, }, function (data) { pos.updateDatas(data.pos); tree.loadPostData(data.ledger, function (result) { self.refreshTree(sheet, result); self.refreshOperationValid(sheet, sheet.getSelections()); }); }); }, selectionChanged: function (e, info) { if (info.newSelections[0].row !== info.oldSelections[0].row) { posOperationObj.loadCurPosData(); } }, }; // 绑定事件 if (!ledgerSpreadSetting.readOnly) { 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) { }); ledgerSpread.bind(GC.Spread.Sheets.Events.SelectionChanged, treeOperationObj.selectionChanged); // 绑定 删除等 顶部按钮 $('#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); }); let batchInsertObj; // 右键菜单 $.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'); } } }, 'batchInsertBillsPos': { name: '批量插入清单部位', icon: 'fa-sign-in', disabled: function (key, opt) { const sheet = ledgerSpread.getActiveSheet(); const selection = sheet.getSelections(); const row = selection[0].row; const select = ledgerTree.nodes[row]; if (select) { if (select.code && select.code !== '') { return !ledgerTree.isLeafXmj(select); } else { const parent = ledgerTree.getParent(select); return !(parent && ledgerTree.isLeafXmj(parent)); } } else { return false; } }, callback: function (key, opt) { if (!batchInsertObj) { batchInsertObj = new BatchInsertBillsPosObj($('#batch')); } else { batchInsertObj.initView(); } $('#batch').modal('show'); } }, 'importExcel': { name: '导入分项清单Excel', icon: 'file-excel-o', disabled: function (key, opt) { return tender.ledger_status !== 1; }, callback: function (key, opt) { $('#upload-ledger').modal('show'); } } } }); } treeOperationObj.refreshOperationValid(ledgerSpread.getActiveSheet(), ledgerSpread.getActiveSheet().getSelections()); // 台账模式加载部位明细数据 if (checkTzMeasureType()) { SpreadJsObj.initSheet(posSpread.getActiveSheet(), posSpreadSetting); postData('/tender/' + getTenderId() + '/pos', null, function (data) { pos.loadDatas(data); }); } // 绑定部位明细编辑事件 const posOperationObj = { /** * 加载部位明细 根据当前台账选择节点 */ loadCurPosData: function () { const node = treeOperationObj.getSelectNode(ledgerSpread.getActiveSheet()); if (node) { const posData = pos.masterRange[itemsPre + node.id] || []; SpreadJsObj.loadSheetData(posSpread.getActiveSheet(), 'data', posData); } else { SpreadJsObj.loadSheetData(posSpread.getActiveSheet(), 'data', []); } }, /** * 编辑单元格响应事件 * @param {Object} e * @param {Object} info */ editEnding: function (e, info) { if (info.sheet.zh_setting) { const orgText = info.sheet.getCell(info.row, info.row).value(); if (orgText === info.editingText || ((!orgText || orgText === '') && (info.editingText === ''))) { return; } const node = treeOperationObj.getSelectNode(ledgerSpread.getActiveSheet()); if (!node) { toast('数据错误, 请刷新页面后再试', 'warning') info.cancel = true; return; } else if (info.editingText !== '' && node.children && node.children > 0) { toast('父节点不可插入部位明细', 'error'); info.cancel = true; return; } else if (info.editingText !== '' && node.code && node.code !== '') { toast('项目节不可插入部位明细', 'error'); info.cancel = true; return; } const curPosData = pos.getMasterRange(node.id); const position = curPosData ? curPosData[info.row] : null; const col = info.sheet.zh_setting.cols[info.col]; const data = {}; if (col.field === 'name') { console.log(1); if (info.editingText === '' && position) { console.log(2); toast('部位名称不可为空', 'error', 'exclamation-circle'); info.cancel = true; return; } else if (!position) { if (info.editingText !== '') { data.updateType = 'add'; data.updateData = { name: info.editingText, lid: node.id, tid: tender.id }; } else { return; } } else { data.updateType = 'update'; data.updateData = {id: position.id, name: info.editingText}; } } else if (!position) { toast('新增部位请先输入名称', 'warning'); } else { data.updateType = 'update'; data.updateData = {id: position.id}; data.updateData[col.field] = col.type === 'Number' ? parseFloat(info.editingText) : info.editingText; } postData('/tender/' + getTenderId() + '/pos/update', data, function (result) { pos.updateDatas(result.pos); posOperationObj.loadCurPosData(); ledgerTree.loadPostData(result.ledger, function (loadResult) { treeOperationObj.refreshTree(ledgerSpread.getActiveSheet(), loadResult); }); }, function () { posOperationObj.loadCurPosData(); }); } }, /** * 删除按钮响应事件 * @param sheet */ deletePress: function (sheet) { const self = this; if (sheet.zh_setting) { const sortData = sheet.zh_data; const datas = [], posSelects = []; const sel = sheet.getSelections()[0]; for (let iRow = sel.row; iRow < sel.row + sel.rowCount; iRow++) { const node = sortData[iRow]; if (node) { const data = {id: node.id}; for (let iCol = sel.col; iCol < sel.col + sel.colCount; iCol++) { const colSetting = sheet.zh_setting.cols[iCol]; if (colSetting.field === 'name') { toast('部位名称不能为空', 'error'); return; } data[colSetting.field] = null; } datas.push(data); posSelects.push(node); } } sheet.zh_tree.update('/tender/' + getTenderId() + '/pos/update', datas, function (result) { pos.updateDatas(result); // todo 只加载改变项 self.loadCurPosData(); }); } }, /** * 删除 部位明细 * @param sheet */ deletePos: function (sheet) { const selection = sheet.getSelections(); const data = { updateType: 'delete', updateData: [], } const row = selection[0].row, count = selection[0].rowCount; const sortData = sheet.zh_data; for (let iRow = 0; iRow < count; iRow++) { data.updateData.push(sortData[iRow + row].id); } postData('/tender/' + getTenderId() + '/pos/update', data, function (result) { pos.updateDatas(result.pos); sheet.deleteRows(row, count); ledgerTree.loadPostData(result.ledger, function (loadResult) { treeOperationObj.refreshTree(ledgerSpread.getActiveSheet(), loadResult); }); }); }, /** * 粘贴单元格响应事件 * @param e * @param info */ clipboardPasted: function (e, info) { const self = this; const node = treeOperationObj.getSelectNode(ledgerSpread.getActiveSheet()); if (node.code && (node.code !== '')) { toast('项目节不可含有清单明细', 'error'); self.loadCurPosData(); return; } if (node.children && (node.children.length > 0)) { toast('仅清单子项可以含有部位明细', 'error'); self.loadCurPosData(); return; } if (info.sheet.zh_setting) { const data = { updateType: '', updateData: [], }; const sortData = info.sheet.zh_data; if (sortData && (info.cellRange.row >= sortData.length)) { data.updateType = 'add'; if (info.cellRange.col !== 0) { toast('新增部位请先输入名称', 'warning'); self.loadCurPosData(); return; } for (let iRow = 0; iRow < info.cellRange.rowCount; iRow++) { const curRow = info.cellRange.row + iRow; const newData = {}; 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); if (colSetting.type === 'Number') { data[colSetting.field] = _.toNumber(data[colSetting.field]); } } data.updateData.push(newData); } } else { data.updateType = 'update'; for (let iRow = 0; iRow < info.cellRange.rowCount; iRow++) { const curRow = info.cellRange.row + iRow; const curPos = sortData[curRow]; if (curPos) { const newData = {id: curPos.id}; for (let iCol = 0; iCol < info.cellRange.colCount; iCol++) { const curCol = info.cellRange.col + iCol; const colSetting = info.sheet.zh_setting.cols[curCol]; newData[colSetting.field] = info.sheet.getText(curRow, curCol); if (colSetting.type === 'Number') { newData[colSetting.field] = _.toNumber(newData[colSetting.field]); } } data.updateData.push(newData); } } } postData('/tender/' + getTenderId() + '/pos/update', data, function (result) { pos.updateDatas(result.pos); posOperationObj.loadCurPosData(); ledgerTree.loadPostData(result.ledger, function (loadResult) { treeOperationObj.refreshTree(ledgerSpread.getActiveSheet(), loadResult); }); posOperationObj.loadCurPosData(); }); } }, }; posOperationObj.loadCurPosData(); if (!posSpreadSetting.readOnly) { SpreadJsObj.addDeleteBind(posSpread, posOperationObj.deletePress); posSpread.bind(GC.Spread.Sheets.Events.EditEnding, posOperationObj.editEnding); posSpread.bind(GC.Spread.Sheets.Events.ClipboardPasted, posOperationObj.clipboardPasted); // 右键菜单 $.contextMenu({ selector: '#pos-spread', build: function ($trigger, e) { const target = SpreadJsObj.safeRightClickSelection($trigger, e, posSpread); return target.hitTestType === GC.Spread.Sheets.SheetArea.viewport || target.hitTestType === GC.Spread.Sheets.SheetArea.rowHeader; }, items: { 'delete': { name: '删除', icon: 'fa-remove', disabled: function (key, opt) { const sheet = posSpread.getActiveSheet(); if (sheet.zh_data) { const selection = sheet.getSelections(); return sheet.zh_data.length < selection[0].row + selection[0].rowCount; } else { return true; } }, callback: function (key, opt) { posOperationObj.deletePos(posSpread.getActiveSheet()); } }, } }); } let stdChapter, stdBills, dealBills, searchLedger; // 展开收起标准清单 $('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(); autoFlashHeight(); if (tab.attr('content') === '#std-chapter') { if (!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, formatter: '@', readOnly: true, cellType: 'tree'}, {title: '名称', field: 'name', width: 230, formatter: '@', readOnly: true}, {title: '单位', field: 'unit', width: 50, formatter: '@', readOnly: true} ], treeCol: 0, emptyRows: 0, headRows: 1, headRowHeight: [40], defaultRowHeight: 21, }); stdChapter.loadLib(1); } stdChapter.spread.refresh(); } else if (tab.attr('content') === '#std-bills') { if (!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, formatter: '@', readOnly: true, cellType: 'tree'}, {title: '名称', field: 'name', width: 230, formatter: '@', readOnly: true}, {title: '单位', field: 'unit', width: 50, formatter: '@', readOnly: true} ], treeCol: 0, emptyRows: 0, headRows: 1, headRowHeight: [40], defaultRowHeight: 21, }); stdBills.loadLib(1); } stdBills.spread.refresh(); } else if (tab.attr('content') === '#deal-bills') { if (!dealBills) { dealBills = new DealBills($('#deal-bills-spread')[0], { cols: [ {title: '清单编号', field: 'code', width: 120, formatter: '@', readOnly: true}, {title: '名称', field: 'name', width: 230, formatter: '@', readOnly: true}, {title: '单位', field: 'unit', width: 50, formatter: '@', readOnly: true}, {title: '单价', field: 'unit_price', width: 50, readOnly: true}, {title: '数量', field: 'quantity', width: 50, readOnly: true}, ], emptyRows: 0, headRows: 1, headRowHeight: [40], defaultRowHeight: 21, }); dealBills.loadData(); } dealBills.spread.refresh(); } else if (tab.attr('content') === '#search' && !searchLedger) { if (!searchLedger) { searchLedger = new SearchLedger($('#search'), { cols: [ {title: '项目节编号', field: 'code', width: 120, formatter: '@', readOnly: true}, {title: '清单编号', field: 'b_code', width: 120, formatter: '@', readOnly: true}, {title: '名称', field: 'name', width: 230, formatter: '@', readOnly: true}, {title: '单位', field: 'unit', width: 50, formatter: '@', readOnly: true}, {title: '单价', field: 'unit_price', width: 50, readOnly: true}, {title: '数量', field: 'quantity', width: 50, readOnly: true}, ], emptyRows: 3, headRows: 1, headRowHeight: [40], defaultRowHeight: 21, }); } searchLedger.spread.refresh(); } } else { // 收起工具栏 tab.removeClass('active'); showSideTools(tab.hasClass('active')); tabPanel.hide(); } ledgerSpread.refresh(); posSpread.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('/tender/' + getTenderId() + '/ledger/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('base', 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 = '/tender/' + getTenderId() + '/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) { this.data = data; SpreadJsObj.loadSheetData(self.spread.getActiveSheet(), 'data', data); }); } } class BatchInsertBillsPosObj { constructor (obj) { const self = this; this.obj = obj; this.billsCount = 6; this.posCount = 1000; // 初始化 清单编号窗口 参数 this.qdSpreadSetting = { cols: [ {title: '编号', field: 'code', width: 80, formatter: '@'}, {title: '名称', field: 'name', width: 120, formatter: '@'}, {title: '单位', field: 'unit', width: 50, formatter: '@'}, {title: '单价', field: 'unit_price', width: 50}, {title: '图册号', field: 'name', width: 60, formatter: '@'}, ], emptyRows: this.billsCount, headRows: 1, headRowHeight: [40], }; this.qdSpread = SpreadJsObj.createNewSpread($('.batch-l-t', this.obj)[0]); // 初始化 部位数量复核表 参数 this.posSpreadSetting = { cols: [ {title: '部位', field: 'bw', width: 80, formatter: '@'}, {title: '图册号', field: 'drawingCode', formatter: '@', width: 60}, ], emptyRows: this.posCount, headRows: 1, headRowHeight: [40], }; for (let iNum = 1; iNum <= this.billsCount; iNum++) { this.posSpreadSetting.cols.push( {title: '清单' + iNum, field: 'bills' + iNum, width: 50} ) } this.posSpread = SpreadJsObj.createNewSpread($('.batch-l-b', this.obj)[0]); // 初始化 清单编号、部位数量复核表 表格 this.initView(); // 初始化 签约清单 参数 this.dealSpreadSetting = { cols: [ {title: '清单编号', field: 'code', width: 80, formatter: '@', readOnly: true}, {title: '名称', field: 'name', width: 120, formatter: '@', readOnly: true}, {title: '单位', field: 'unit', width: 50, formatter: '@', readOnly: true}, {title: '单价', field: 'unit_price', width: 50, readOnly: true}, ], emptyRows: 0, headRows: 1, headRowHeight: [40], }; this.dealSpread = SpreadJsObj.createNewSpread($('.batch-r', this.obj)[0]); SpreadJsObj.initSheet(this.dealSpread.getActiveSheet(), this.dealSpreadSetting); // 拉取签约清单数据 if (dealBills) { SpreadJsObj.loadSheetData(this.dealSpread.getActiveSheet(), 'data', dealBills.data); } else { postData('/tender/' + getTenderId() + '/deal/get-data', {}, function (data) { SpreadJsObj.loadSheetData(self.dealSpread.getActiveSheet(), 'data', data); }); } // 双击签约清单,自动添加到清单编号窗口 this.dealSpread.bind(GC.Spread.Sheets.Events.CellDoubleClick, function (e, info) { const deal = info.sheet.zh_data[info.row]; const sel = self.gclSpread.getActiveSheet().getSelections()[0]; self.qdSpread.getActiveSheet().getCell(sel.row, 0).value(deal.code); self.qdSpread.getActiveSheet().getCell(sel.row, 1).value(deal.name); self.qdSpread.getActiveSheet().getCell(sel.row, 2).value(deal.unit); self.qdSpread.getActiveSheet().getCell(sel.row, 3).value(deal.unit_price); if (sel.row + 1 === self.gclSpread.getActiveSheet().getRowCount()) { const count = sel.row + 2; self.qdSpread.getActiveSheet().setRowCount(count); self.qdSpread.getActiveSheet().getCell(sel.row + 1, 0, GC.Spread.Sheets.SheetArea.rowHeader).text('清单' + count); const colCount = self.posSpread.getActiveSheet().getColumnCount() + 1 self.posSpread.getActiveSheet().setColumnCount(colCount); self.posSpread.getActiveSheet().getCell(0, colCount - 1, GC.Spread.Sheets.SheetArea.colHeader).text('数量' + count); } self.qdSpread.getActiveSheet().setSelection(sel.row + 1, sel.col, 1, 1); }); this.obj.bind('shown.bs.modal', function () { self.qdSpread.refresh(); self.posSpread.refresh(); self.dealSpread.refresh(); }); $('#batch-ok').click(function () { const sheet = ledgerSpread.getActiveSheet(); const selection = sheet.getSelections(); const row = selection[0].row; const select = ledgerTree.nodes[row]; if (select) { const insertData = {}; insertData.batchType = (select.code && select.code !== '') ? 'child' : 'next'; insertData.id = select[ledgerTree.setting.id]; insertData.batchData = self.getBatchData(); postData('/tender/' + getTenderId() + '/ledger/batch-insert', insertData, function (data) { pos.updateDatas(data.pos); ledgerTree.loadPostData(data.ledger, function (result) { treeOperationObj.refreshTree(sheet, result); treeOperationObj.refreshOperationValid(sheet, selection); }); self.obj.modal('hide'); }); } }); } // 初始化左侧表格 initView () { // 初始化 清单编号 const qdSheet = this.qdSpread.getActiveSheet(); SpreadJsObj.initSheet(qdSheet, this.qdSpreadSetting); // 清理原有数据 SpreadJsObj.beginMassOperation(qdSheet); qdSheet.clear(0, 0, qdSheet.getRowCount(), qdSheet.getColumnCount(), GC.Spread.Sheets.SheetArea.viewport, GC.Spread.Sheets.StorageType.data); for (let iRow = 1; iRow <= this.billsCount; iRow ++) { qdSheet.getCell(iRow - 1, 0, GC.Spread.Sheets.SheetArea.rowHeader).text('清单' + iRow); } SpreadJsObj.endMassOperation(qdSheet); // 初始化 部位数量复核表 const posSheet = this.posSpread.getActiveSheet(); SpreadJsObj.initSheet(posSheet, this.posSpreadSetting); // 清理原有数据 SpreadJsObj.beginMassOperation(posSheet); posSheet.setColumnWidth(0, 45, GC.Spread.Sheets.SheetArea.rowHeader); posSheet.clear(0, 0, posSheet.getRowCount(), posSheet.getColumnCount(), GC.Spread.Sheets.SheetArea.viewport, GC.Spread.Sheets.StorageType.data); SpreadJsObj.endMassOperation(posSheet); } // 获取界面数据 getBatchData () { const result = []; const qdSheet = this.qdSpread.getActiveSheet(), posSheet = this.posSpread.getActiveSheet(); for (let iRow = 0; iRow < qdSheet.getRowCount(); iRow++) { if (qdSheet.getText(iRow, 0) === '') { continue; } const qd = { b_code: qdSheet.getText(iRow, 0), name: qdSheet.getText(iRow, 1), unit: qdSheet.getText(iRow, 2), price: _.toNumber(qdSheet.getText(iRow, 3)), pos: [], }; result.push(qd); for (let iPosRow = 0; iPosRow < posSheet.getRowCount(); iPosRow++) { const value = _.toNumber(posSheet.getText(iPosRow, iRow + 2)); if (value !== 0 && !isNaN(value)) { qd.pos.push({ name: posSheet.getText(iPosRow, 0), drawing_code: posSheet.getText(iPosRow, 1), quantity: value, }); } } } return result; } } class SearchLedger { constructor(obj, spreadSetting) { const self = this; this.obj = obj; this.url = '/ledger/search'; this.spreadSetting = spreadSetting; this.spread = SpreadJsObj.createNewSpread($('#search-result', this.obj)[0]); SpreadJsObj.initSheet(this.spread.getActiveSheet(), this.spreadSetting); $('#searchLedger', this.obj).bind('click', function () { const data = { keyword: $('input', self.obj).val() }; postData(preUrl + '/ledger/search', data, function (result) { SpreadJsObj.loadSheetData(self.spread.getActiveSheet(), 'data', result); }); }); this.spread.getActiveSheet().bind(GC.Spread.Sheets.Events.CellDoubleClick, function (e, info) { const sheet = info.sheet; const data = sheet.zh_data; if (!data) { return } const curBills = data[info.row]; if (!curBills) { return } const mainSheet = ledgerSpread.getActiveSheet(); const mainTree = mainSheet.zh_tree; mainTree.postData('locate', null, {id: curBills.ledger_id}, function (result) { treeOperationObj.refreshTree(mainSheet, result); treeOperationObj.refreshOperationValid(mainSheet, mainSheet.getSelections()); SpreadJsObj.locateTreeNode(mainSheet, curBills.ledger_id); }); }); } } $('#searchAccount').click(() => { const data = { keyword: $('#searchName').val(), } postData('/search/user', data, (data) => { const resultDiv = $('#searchResult'); $('h5>span', resultDiv).text(data.name); $('#addAuditor').attr('auditorId', data.id); $('h6', resultDiv).text(data.role); $('p', resultDiv).text(data.company); resultDiv.show(); }, () => { $('#searchResult').hide(); }); }); $('#addAuditor').click(() => { const data = { auditorId: $('#addAuditor').attr('auditorId'), }; console.log(data); postData('/tender/' + getTenderId() + '/ledger/audit/add', data, (data) => { const html = []; html.push('