/** * 台账相关js * * @author Mai * @date 2018/02/05 * @version */ const ckBillsSpread = window.location.pathname + '-billsSelect'; function checkTzMeasureType () { return tender.measure_type === measureType.tz.value; } function getTenderId() { return window.location.pathname.split('/')[2]; } const copyBlockTag = 'zh.calc.copyBlock'; const invalidFields = { parent: ['sgfh_qty', 'sgfh_tp', 'sjcl_qty', 'sjcl_tp', 'qtcl_qty', 'qtcl_tp', 'deal_qty', 'deal_tp', 'unit_price'], gcl: ['dgn_qty1', 'dgn_qty2'], posCode: ['b_code'], posCalc: ['sgfh_qty', 'sgfh_tp', 'sjcl_qty', 'sjcl_tp', 'qtcl_qty', 'qtcl_tp'], posXmj: ['code'], }; function getExprInfo (field, converse = false) { const exprField = [ {qty: 'sgfh_qty', expr: 'sgfh_expr'}, {qty: 'sjcl_qty', expr: 'sjcl_expr'}, {qty: 'qtcl_qty', expr: 'qtcl_expr'}, ]; if (converse) return _.find(exprField, { expr: field }); return _.find(exprField, {qty: field}); } function transExpr(expr) { return expr.replace('=', '').replace(new RegExp('%', 'gm'), '/100'); } const checkOption = { sibling: { enable: 1 }, empty_code: { enable: 1 }, calc: { enable: 1, fields: ['sgfh_qty', 'qtcl_qty', 'sjcl_qty', 'quantity'], }, zero: { enable: 1 }, zeroPos: { enable: 1 }, pos_drawingCode: { enable: 1 }, tp: { enable: 1, fields: [ {qty: 'sgfh_qty', tp: 'sgfh_tp'}, {qty: 'sjcl_qty', tp: 'sjcl_tp'}, {qty: 'qtcl_qty', tp: 'qtcl_tp'}, {qty: 'quantity', tp: 'total_price'}, {qty: 'deal_qty', tp: 'deal_tp'}, ], }, same_code: { enable: 1 }, same_bills: { enable: 1 }, }; $(document).ready(function() { let stdXmj, stdGcl, dealBills, searchLedger; autoFlashHeight(); // 初始化台账 const ledgerSpread = SpreadJsObj.createNewSpread($('#ledger-spread')[0]); const ledgerSheet = ledgerSpread.getActiveSheet(); removeLocalCache('bills-fold'); const treeSetting = { id: 'ledger_id', pid: 'ledger_pid', order: 'order', level: 'level', rootId: -1, keys: ['id', 'tender_id', 'ledger_id'], preUrl: '/tender/' + getTenderId() + '/ledger', //treeCacheKey: 'ledger_bills_fold' + '_' + getTenderId(), autoExpand: 3, // markFoldKey: 'bills-fold', // markFoldSubKey: window.location.pathname.split('/')[2], markExpandKey: 'bills-expand', markExpandSubKey: window.location.pathname.split('/')[2], calcFields: ['deal_tp', 'sgfh_tp', 'sjcl_tp', 'qtcl_tp', 'total_price'], }; treeSetting.calcFun = function (node) { node.dgn_price = ZhCalc.round(ZhCalc.div(node.total_price, node.dgn_qty1), 2); }; const ledgerTree = createNewPathTree('ledger', treeSetting); //初始化所有附件列表 getAllList(); // 初始化 计量单元 const pos = new PosData({ id: 'id', ledgerId: 'lid', }); const posSpread = SpreadJsObj.createNewSpread($('#pos-spread')[0]); // 初始化 附属工程量 const ancGcl = createAncillaryGcl({ id: 'id', masterId: 'lid', sort: [['g_order', 'asc']] }); const ancGclSpread = SpreadJsObj.createNewSpread($('#anc-gcl-spread')[0]); const ancGclSheet = ancGclSpread.getActiveSheet(); const billsTag = $.billsTag({ relaTree: ledgerTree, selector: '#bills-tag', relaSpread: ledgerSpread, relaPosSpread: posSpread, updateUrl: window.location.pathname + '/tag', afterModify: function (nodes) { SpreadJsObj.repaintNodesRowHeader(ledgerSpread.getActiveSheet(), nodes); }, afterLocated: function (lid, pos_id) { posOperationObj.loadCurPosData(); ancGclObj.loadCurAncillaryGcl(); if (pos_id) { const posSheet = posSpread.getActiveSheet(); const relaPos = posSheet.zh_data.find(x => { return x.id === pos_id; }); SpreadJsObj.locateData(posSheet, relaPos); } }, afterShow: function () { ledgerSpread.refresh(); if (posSpread) posSpread.refresh(); if (ancGclSpread) ancGclSpread.refresh(); }, }); const errorList = $.cs_errorList({ tabSelector: '#error-list-tab', selector: '#error-list', relaSpread: ledgerSpread, storeKey: 'ledger-error-' + getTenderId(), afterLocated: function () { posOperationObj.loadCurPosData(); ancGclObj.loadCurAncillaryGcl(); }, afterShow: function () { ledgerSpread.refresh(); if (posSpread) posSpread.refresh(); if (ancGclSpread) ancGclSpread.refresh(); }, }); const checkList = $.ledger_checkList({ id: 'check-list', tabSelector: '#check-list-tab', selector: '#check-list', relaSpread: ledgerSpread, storeKey: 'ledger-check-' + getTenderId(), checkType: getCheckType(checkOption), afterLocated: function () { posOperationObj.loadCurPosData(); ancGclObj.loadCurAncillaryGcl(); }, afterShow: function () { ledgerSpread.refresh(); if (posSpread) posSpread.refresh(); if (ancGclSpread) ancGclSpread.refresh(); }, }); const gclGather = $.cs_gclGather({ selector: '#gcl-gather', id: 'gcl-gather', relaSheet: ledgerSpread.getActiveSheet(), }); $.subMenu({ menu: '#sub-menu', miniMenu: '#sub-mini-menu', miniMenuList: '#mini-menu-list', toMenu: '#to-menu', toMiniMenu: '#to-mini-menu', key: 'menu.1.0.0', miniHint: '#sub-mini-hint', hintKey: 'menu.hint.1.0.1', callback: function (info) { if (info.mini) { $('.panel-title').addClass('fluid'); $('#sub-menu').removeClass('panel-sidebar'); } else { $('.panel-title').removeClass('fluid'); $('#sub-menu').addClass('panel-sidebar'); } autoFlashHeight(); ledgerSpread.refresh(); if (posSpread) posSpread.refresh(); if (ancGclSpread) ancGclSpread.refresh(); if (stdXmj) stdXmj.spread.refresh(); if (stdGcl) stdGcl.spread.refresh(); if (dealBills) dealBills.spread.refresh(); if (searchLedger) searchLedger.spread.refresh(); if (errorList) errorList.spread.refresh(); if (checkList) checkList.spread.refresh(); if (gclGather) gclGather.spread.refresh(); } }); // 定义事件 const treeOperationObj = { loadExprToInput(sheet) { const sel = sheet.getSelections()[0]; const col = sheet.zh_setting.cols[sel.col], cell = sheet.getCell(sel.row, sel.col); if (col && col.type === 'Number') { const data = SpreadJsObj.getSelectObject(sheet); if (data) { const exprInfo = getExprInfo(col.field); if (exprInfo) { $('#bills-expr').val(data[exprInfo.expr] ? data[exprInfo.expr] : data[col.field]) .attr('field', col.field).attr('org', data[col.field]); } else { $('#bills-expr').val(data[col.field]) .attr('field', col.field).attr('org', data[col.field]); } if (col.field.indexOf('dgn') >= 0) { $('#bills-expr').attr('readOnly', readOnly || cell.locked() || (_.isString(data.b_code) && data.b_code !== '')); } else { const nodePos = pos.getLedgerPos(data.id); if (nodePos && nodePos.length > 0) { $('#bills-expr').val('').attr('readOnly', true); $('#bills-expr').removeAttr('data-row'); } else { $('#bills-expr').attr('readOnly', readOnly || cell.locked() || (data.children && data.children.length > 0)); } } $('#bills-expr').attr('data-row', sel.row); } else { $('#bills-expr').val('').attr('readOnly', true); $('#bills-expr').removeAttr('data-row'); } } else { $('#bills-expr').val('').attr('readOnly', true); $('#bills-expr').removeAttr('data-row'); } }, getSelectNode: function (sheet) { if (!sheet || !sheet.zh_tree) { return null; } else { const sel = sheet.getSelections()[0]; return sheet.zh_tree.nodes[sel.row]; } }, getDefaultSelectInfo: function (sheet) { const tree = sheet.zh_tree; if (!tree) return; const sel = sheet.getSelections()[0]; const node = sheet.zh_tree.nodes[sel.row]; if (!node) return; let count = 1; if (sel.rowCount > 1) { for (let r = 1; r < sel.rowCount; r++) { const rNode = sheet.zh_tree.nodes[sel.row + r]; if (rNode.level > node.level) continue; if ((rNode.level < node.level) || (rNode.level === node.level && rNode.pid !== node.pid)) { toastr.error('请选择同一清单下的节点,进行该操作'); return; } count += 1; } } return [tree, node, count]; }, /** * 刷新顶部按钮是否可用 * @param sheet * @param selections */ refreshOperationValid: function (sheet, selection) { const setObjEnable = function (obj, enable) { if (enable) { obj.removeClass('disabled'); } else { obj.addClass('disabled'); } }; const invalidAll = function () { setObjEnable($('#insert'), false); setObjEnable($('#delete'), false); setObjEnable($('#up-move'), false); setObjEnable($('#down-move'), false); setObjEnable($('#up-level'), false); setObjEnable($('#down-level'), false); }; const sel = selection ? selection[0] : sheet.getSelections()[0]; const row = sel ? sel.row : -1; const tree = sheet.zh_tree; if (!tree) { invalidAll(); return; } const first = sheet.zh_tree.nodes[row]; if (!first) { invalidAll(); return; } let last = first, sameParent = true; if (sel.rowCount > 1 && first) { for (let r = 1; r < sel.rowCount; r++) { const rNode = tree.nodes[row + r]; if (!rNode) { sameParent = false; break; } if (rNode.level > first.level) continue; if ((rNode.level < first.level) || (rNode.level === first.level && rNode.pid !== first.pid)) { sameParent = false; break; } last = rNode; } } const preNode = tree.getPreSiblingNode(first); const valid = !sheet.zh_setting.readOnly; setObjEnable($('#insert'), valid && first && first.level > 1); setObjEnable($('#delete'), valid && first && sameParent && !(first.level === 1 && first.node_type)); setObjEnable($('#up-move'), valid && first && sameParent && first.level > 1 && preNode); setObjEnable($('#down-move'), valid && first && sameParent && first.level > 1 && !tree.isLastSibling(last)); if (checkTzMeasureType()) { const posRange = last ? pos.getLedgerPos(last.id) : []; setObjEnable($('#up-level'), valid && first && sameParent && tree.getParent(first) && first.level > 2 && ((!posRange || posRange.length === 0) || tree.isLastSibling(last))); const preNodePosRange = preNode ? pos.getLedgerPos(preNode.id) : []; setObjEnable($('#down-level'), valid && first && sameParent && first.level > 1 && preNode && (!preNodePosRange || preNodePosRange.length === 0)); } else { setObjEnable($('#up-level'), valid && first && sameParent && first.level > 2 && tree.getParent(first)); setObjEnable($('#down-level'), valid && first && sameParent && first.level > 1 && preNode); } setObjEnable($('#cut'), valid); setObjEnable($('#paste'), valid); }, refreshTree: function (sheet, data) { SpreadJsObj.massOperationSheet(sheet, function () { const tree = sheet.zh_tree; // 处理删除 if (data.delete) { data.delete.sort(function (x, y) { return y.deleteIndex - x.deleteIndex; }); for (const d of data.delete) { sheet.deleteRows(d.deleteIndex, 1); } } // 处理新增 if (data.create) { const newNodes = data.create; if (newNodes) { newNodes.sort(function (a, b) { return a.index - b.index; }); for (const node of newNodes) { sheet.addRows(node.index, 1); SpreadJsObj.reLoadRowData(sheet, tree.nodes.indexOf(node), 1); } } } // 处理更新 if (data.update) { const rows = []; for (const u of data.update) { rows.push(tree.nodes.indexOf(u)); billsTag.refreshBillsTagView(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 (sheet, count = 1) { const self = this; const sel = sheet.getSelections()[0]; const row = sheet.getSelections()[0].row; const tree = sheet.zh_tree; if (!tree) { return; } const node = sheet.zh_tree.nodes[row]; if (!node) { return; } postData(window.location.pathname + '/update', { postType: 'add', postData: { id: tree.getNodeKey(node), count: count, } }, function (result) { const refreshNode = tree.loadPostData(result); self.refreshTree(sheet, refreshNode); sheet.setSelection(refreshNode.create[0].index, sel.col, sel.rowCount, sel.colCount); SpreadJsObj.reloadRowsBackColor(sheet, [sel.row, refreshNode.create[0].index]); self.refreshOperationValid(sheet); }); }, /** * 删除选中节点 * @param spread */ deleteNode: function (sheet) { const self = this; const [tree, node, count] = this.getDefaultSelectInfo(sheet); if (tree && node && count) { const data = { postType: 'delete', postData: { id: tree.getNodeKey(node), count: count } }; deleteAfterHint(function () { postData(window.location.pathname + '/update', data, function (result) { const refreshNode = tree.loadPostData(result); for (const d of refreshNode.delete) { pos.removeDatasByMasterId(d.id); ancGcl.removeDatasByMasterId(d.id); } self.refreshTree(sheet, refreshNode); self.refreshOperationValid(sheet); posOperationObj.loadCurPosData(); ancGclObj.loadCurAncillaryGcl(); billsTag.afterDeleteBills(refreshNode.delete); }); }); } }, /** * 上移选中节点 * @param spread */ upMove: function (sheet) { const self = this; const [tree, node, count] = this.getDefaultSelectInfo(sheet); if (tree && node && count) { const data = { postType: 'up-move', postData: { id: tree.getNodeKey(node), count: count } }; postData(window.location.pathname + '/update', data, function (result) { const refreshNode = tree.loadPostData(result); self.refreshTree(sheet, refreshNode); const sel = sheet.getSelections()[0]; sheet.setSelection(tree.nodes.indexOf(node), sel.col, sel.rowCount, sel.colCount); SpreadJsObj.reloadRowsBackColor(sheet, [sel.row, tree.nodes.indexOf(node)]); self.refreshOperationValid(sheet); }); } }, /** * 下移选中节点 * @param spread */ downMove: function (sheet) { const self = this; const [tree, node, count] = this.getDefaultSelectInfo(sheet); if (tree && node && count) { const data = { postType: 'down-move', postData: { id: tree.getNodeKey(node), count: count } }; postData(window.location.pathname + '/update', data, function (result) { const refreshNode = tree.loadPostData(result); self.refreshTree(sheet, refreshNode); const sel = sheet.getSelections()[0]; sheet.setSelection(tree.nodes.indexOf(node), sel.col, sel.rowCount, sel.colCount); SpreadJsObj.reloadRowsBackColor(sheet, [sel.row, tree.nodes.indexOf(node)]); self.refreshOperationValid(sheet); }); } }, /** * 升级选中节点 * @param spread */ upLevel: function (sheet) { const self = this; const [tree, node, count] = this.getDefaultSelectInfo(sheet); if (tree && node && count) { const data = { postType: 'up-level', postData: { id: tree.getNodeKey(node), count: count } }; postData(window.location.pathname + '/update', data, function (result) { const refreshNode = tree.loadPostData(result); self.refreshTree(sheet, refreshNode); self.refreshOperationValid(sheet); }); } }, /** * 降级选中节点 * @param spread */ downLevel: function (sheet) { const self = this; const [tree, node, count] = this.getDefaultSelectInfo(sheet); if (tree && node && count) { const data = { postType: 'down-level', postData: { id: tree.getNodeKey(node), count: count } }; postData(window.location.pathname + '/update', data, function (result) { const refreshNode = tree.loadPostData(result); self.refreshTree(sheet, refreshNode); self.refreshOperationValid(sheet); }); } }, /** * 编辑单元格响应事件 * @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 }; // 未改变值则不提交 const orgValue = node[col.field]; const newValue = col.wordWrap ? info.editingText : trimInvalidChar(info.editingText); if (orgValue == info.editingText || ((!orgValue || orgValue === '') && (newValue === ''))) { return; } // 台账模式,检查计量单元相关 if (checkTzMeasureType()) { if (col.field === 'sgfh_qty' || col.field === 'sgfh_tp' || col.field === 'sjcl_qty' || col.field === 'sjcl_tp' || col.field === 'qtcl_qty' || col.field === 'qtcl_tp') { if (!node.children || node.children.length ===0) { const lPos = pos.getLedgerPos(node.id); if (lPos && lPos.length > 0) { toastr.error('清单含有计量单元,请在计量单元输入数量'); SpreadJsObj.reLoadRowData(info.sheet, info.row); return; } } } if (col.field === 'b_code' && (info.editingText === '' || !info.editingText)) { const lPos = pos.getLedgerPos(node.id); if (lPos && lPos.length > 0) { toastr.error('清单含有计量单元,请先删除计量单元,再删除清单编号'); SpreadJsObj.reLoadRowData(info.sheet, info.row); return; } } } if (col.field === 'node_type' && newValue && newValue !== '0' && newValue !== '19') { const sameNodeType = sortData.find(x => { return x.node_type == newValue; }); if (sameNodeType) { toastr.error('已存在该费用类别,请勿重复选择'); SpreadJsObj.reLoadRowData(info.sheet, info.row); return; } } // 获取更新数据 if (col.type === 'Number') { const exprInfo = getExprInfo(col.field); if (newValue) { const num = _.toNumber(newValue); if (_.isFinite(num)) { data[col.field] = num; } else { try { data[col.field] = ZhCalc.mathCalcExpr(transExpr(newValue)); if (exprInfo) { data[exprInfo.expr] = newValue; } } catch(err) { toastr.error('输入的表达式非法'); SpreadJsObj.reLoadRowData(info.sheet, info.row); return; } } } else { data[col.field] = null; if (exprInfo) { data[exprInfo.expr] = ''; } } } else { data[col.field] = newValue; } // 更新至服务器 postData(window.location.pathname + '/update', {postType: 'update', postData: data}, function (result) { const refreshNode = ledgerTree.loadPostData(result); treeOperationObj.refreshTree(info.sheet, refreshNode); }); } }, /** * 粘贴单元格响应事件 * @param e * @param info */ clipboardPasted: function (e, info) { if (info.sheet.zh_setting && info.sheet.zh_dataType === 'tree') { const tree = info.sheet.zh_tree; if (!tree) { return; } const sortData = info.sheet.zh_tree.nodes; const datas = [], filterNodes = []; let bHint = false, bPaste; for (let iRow = 0; iRow < info.cellRange.rowCount; iRow ++) { bPaste = false; 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]; const value = col.wordWrap ? info.sheet.getText(curRow, curCol) : trimInvalidChar(info.sheet.getText(curRow, curCol)); const lPos = pos.getLedgerPos(node.id); if (lPos && lPos.length > 0) { if (value === '' && colSetting.field === 'b_code') { if (!bHint) { toastr.warning('清单含有计量单元,请先删除计量单元,再删除清单编号'); bHint = true; } continue; } if (colSetting.field === 'sgfh_qty' || colSetting.field === 'sgfh_tp' || colSetting.field === 'sjcl_qty' || colSetting.field === 'sjcl_tp' || colSetting.field === 'qtcl_qty' || colSetting.field === 'qtcl_tp') { if (!bHint) { toastr.warning('清单含有计量单元,数量金额根据计量单元汇总计算所得,不可编辑'); bHint = true; } continue; } } if (colSetting.type === 'Number') { const num = _.toNumber(value); if (num) { data[colSetting.field] = num; bPaste = true; } else { try { data[colSetting.field] = ZhCalc.mathCalcExpr(transExpr(value)); bPaste = true; } catch(err) { delete data[colSetting.field]; if (!bHint) { toastr.warning('输入的表达式非法'); bHint = true; } } } } else { data[colSetting.field] = value; bPaste = true; } } if (bPaste) { datas.push(data); } else { filterNodes.push(node); } } } if (datas.length > 0) { postData(window.location.pathname + '/update', {postType: 'update', postData: datas}, function (result) { const refreshNode = tree.loadPostData(result); if (refreshNode.update) { refreshNode.update = refreshNode.update.concat(filterNodes); } treeOperationObj.refreshTree(info.sheet, refreshNode); }, function () { SpreadJsObj.reLoadRowData(info.sheet, info.cellRange.row, info.cellRange.rowCount); }); } else { SpreadJsObj.reLoadRowData(info.sheet, info.cellRange.row, info.cellRange.rowCount); } } }, clipboardPasting: function (e, info) { const tree = info.sheet.zh_tree, setting = info.sheet.zh_setting; info.cancel = true; if (!setting || !tree) return; const pasteData = info.pasteData.html ? SpreadJsObj.analysisPasteHtml(info.pasteData.html) : (info.pasteData.text === '' ? SpreadJsObj.Clipboard.getAnalysisPasteText() : SpreadJsObj.analysisPasteText(info.pasteData.text)); const hint = { invalidExpr: {type: 'warning', msg: '粘贴的表达式非法'}, posCode: {type: 'warning', msg: '清单含有计量单元,不可粘贴清单编号为空'}, posQty: {type: 'warning', msg: '清单含有计量单元,数量金额根据计量单元汇总计算所得,不可粘贴'}, parent: {type: 'warning', msg: '含有子项的清单,不可粘贴数量、单价、金额'}, gcl: {type: 'warning', msg: '工程量清单,不可粘贴项目节数量'}, posXmj: {type: 'warning', msg: '清单含有计量单元,不可粘贴项目节编号'}, // sameParent: {type: 'warning', msg: '仅可粘贴同层节点'}, }; const datas = [], filterNodes = []; let pid, level, filterRow = 0; for (let iRow = 0; iRow < info.cellRange.rowCount + filterRow; iRow++) { const curRow = info.cellRange.row + iRow; const node = tree.nodes[curRow]; if (!node) continue; if (!pid) pid = node.ledger_pid; if (!level) level = node.level; // if (node.ledger_pid !== pid) { // toastMessageUniq(hint.sameParent); // filterRow+=1; // continue; // } if (node.level < level) break; let bPaste = false; 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]; const value = colSetting.wordWrap ? pasteData[iRow-filterRow][iCol] : trimInvalidChar(pasteData[iRow-filterRow][iCol]); const lPos = pos.getLedgerPos(node.id); if (node.children && node.children.length > 0 && invalidFields.parent.indexOf(colSetting.field) >= 0) { toastMessageUniq(hint.parent); continue; } if (!_.isEmpty(node.b_code) && invalidFields.gcl.indexOf(colSetting.field) >= 0) { toastMessageUniq(hint.gcl); continue; } if (lPos && lPos.length > 0) { if (value === '' && invalidFields.posCode.indexOf(colSetting.field) >= 0) { toastMessageUniq(hint.posCode); continue; } if (invalidFields.posCalc.indexOf(colSetting.field) >= 0) { toastMessageUniq(hint.posQty); continue; } if (value !== '' && invalidFields.posXmj.indexOf(colSetting.field) >= 0) { toastMessageUniq(hint.posXmj); continue; } } if (colSetting.type === 'Number') { const num = _.toNumber(value); if (num) { data[colSetting.field] = num; bPaste = true; } else { try { data[colSetting.field] = ZhCalc.mathCalcExpr(transExpr(value)); const exprInfo = getExprInfo(colSetting.field); if (exprInfo) { data[exprInfo.expr] = value; bPaste = true; } } catch(err) { toastMessageUniq(hint.invalidExpr); } } } else { data[colSetting.field] = value; bPaste = true; } } if (bPaste) { datas.push(data); } else { filterNodes.push(node); } } if (datas.length > 0) { postData(window.location.pathname + '/update', {postType: 'update', postData: datas}, function (result) { const refreshNode = tree.loadPostData(result); if (refreshNode.update) { refreshNode.update = refreshNode.update.concat(filterNodes); } treeOperationObj.refreshTree(info.sheet, refreshNode); }, function () { SpreadJsObj.reLoadRowData(info.sheet, info.cellRange.row, info.cellRange.rowCount); }); } else { SpreadJsObj.reLoadRowData(info.sheet, info.cellRange.row, info.cellRange.rowCount); } }, /** * 删除按钮响应事件 * @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]; let bHint = false; for (let iRow = sel.row; iRow < sel.row + sel.rowCount; iRow++) { const node = sortData[iRow]; if (node) { let bDel = false; const data = sheet.zh_tree.getNodeKeyData(node); for (let iCol = sel.col; iCol < sel.col + sel.colCount; iCol++) { const col = sheet.zh_setting.cols[iCol]; if (col.field === 'b_code' || col.field === 'sgfh_qty' || col.field === 'sgfh_tp' || col.field === 'sjcl_qty' || col.field === 'sjcl_tp' || col.field === 'qtcl_qty' || col.field === 'qtcl_tp') { const lPos = pos.getLedgerPos(node.id); if (lPos && lPos.length > 0) { if (!bHint) { if (col.field === 'code') { toastr.warning('清单含有计量单元,请先删除计量单元,再删除清单编号'); } else { toastr.warning('清单含有计量单元,数量金额根据计量单元汇总计算所得,不可删除'); } bHint = true; } continue; } } const style = sheet.getStyle(iRow, iCol); if (!style.locked) { const colSetting = sheet.zh_setting.cols[iCol]; data[colSetting.field] = null; const exprInfo = getExprInfo(colSetting.field); if (exprInfo) { data[exprInfo.expr] = ''; } bDel = true; } } if (bDel) { datas.push(data); nodes.push(node); } } } if (datas.length > 0) { postData(window.location.pathname + '/update', {postType: 'update', postData: datas}, function (result) { const refreshNode = tree.loadPostData(result); treeOperationObj.refreshTree(sheet, refreshNode); treeOperationObj.loadExprToInput(sheet); }); } } }, /** * 粘贴整块 * @param spread * @param block */ pasteBlock: function (spread, copyInfo) { 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; } postData(window.location.pathname + '/update', { postType: 'paste-block', postData: { id: tree.getNodeKey(node), tid: copyInfo.tid, block: copyInfo.block, } }, function (data) { pos.updateDatas(data.pos); if (data.ancGcl) ancGcl.updateDatas(data.ancGcl); const result = tree.loadPostData(data.ledger); self.refreshTree(sheet, result); sheet.setSelection(result.create[0].index, sel.col, sel.rowCount, sel.colCount); SpreadJsObj.reloadRowsBackColor(sheet, [sel.row, result.create[0].index]); self.refreshOperationValid(sheet); removeLocalCache(copyBlockTag); }, null, true); }, loadRelaData: function () { posOperationObj.loadCurPosData(); ancGclObj.loadCurAncillaryGcl(); posSearch.search($('#pos-keyword').val()); treeOperationObj.loadExprToInput(ledgerSpread.getActiveSheet()); }, selectionChanged: function (e, info) { if (!info.oldSelections || !info.oldSelections[0] || info.newSelections[0].row !== info.oldSelections[0].row) { SpreadJsObj.resetTopAndSelect(posSpread.getActiveSheet()); treeOperationObj.loadRelaData(); // 全选去除 $('#dqjiedian').find('.check-all-file').prop('checked', false); } SpreadJsObj.saveTopAndSelect(info.sheet, ckBillsSpread); }, topRowChanged(e, info) { SpreadJsObj.saveTopAndSelect(info.sheet, ckBillsSpread); }, cut: function (sheet, sel, callback) { if (!sheet || !sel) return; if (sel.colCount >= sheet.zh_setting.cols.length) { toastr.warning('请勿选中整行剪切'); return; } const sortData = SpreadJsObj.getSortData(sheet), datas = []; 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 col = sheet.zh_setting.cols[iCol]; if (col.field === 'b_code' || col.field === 'sgfh_qty' || col.field === 'sgfh_tp' || col.field === 'sjcl_qty' || col.field === 'sjcl_tp' || col.field === 'qtcl_qty' || col.field === 'qtcl_tp') { const lPos = pos.getLedgerPos(node.id); if (lPos && lPos.length > 0) { toastr.error('不可剪切'); return; } } const style = sheet.getStyle(iRow, iCol); if (style.locked) { toastr.error('不可剪切'); return; } const colSetting = sheet.zh_setting.cols[iCol]; data[colSetting.field] = null; const exprInfo = getExprInfo(colSetting.field); if (exprInfo) { data[exprInfo.expr] = ''; } } datas.push(data); } } if (datas.length > 0) { callback(); postData(window.location.pathname + '/update', {postType: 'update', postData: datas}, function (result) { const refreshNode = sheet.zh_tree.loadPostData(result); treeOperationObj.refreshTree(sheet, refreshNode); }); } }, editStarting(e, info) { if (!info.sheet.zh_setting || !info.sheet.zh_tree) return; const tree = info.sheet.zh_tree; const col = info.sheet.zh_setting.cols[info.col]; const node = info.sheet.zh_tree.nodes[info.row]; if (!node) { info.cancel = true; return; } const exprInfo = getExprInfo(col.field); if (exprInfo) { if (node[exprInfo.expr] && node[exprInfo.expr] !== '') { info.sheet.getCell(info.row, info.col).text(node[exprInfo.expr]); } } switch (col.field) { case 'code': const posRange = pos.getLedgerPos(node.id); info.cancel = posRange && posRange.length > 0; break; case 'unit_price': case 'sgfh_qty': case 'sgfh_tp': case 'sjcl_qty': case 'sjcl_tp': case 'qtcl_qty': case 'qtcl_tp': case 'deal_qty': case 'deal_tp': info.cancel = node.children && node.children.length > 0; break; case 'dgn_qty1': case 'dgn_qty2': info.cancel = !_.isEmpty(node.b_code); break; case 'node_type': const parent = tree.getParent(node); if (parent) { info.cancel = false; // const topParent = tree.getTopParent(node); // info.cancel = [1, 5].indexOf(topParent.node_type) < 0; } else { info.cancel = true; } break; } }, sortCode: function (sheet) { const tree = sheet.zh_tree; if (!tree) return; const select = SpreadJsObj.getSelectObject(sheet); if (!select || !select.code) return; const getChildSort = function (i, split) { if (i <= 0) throw '参数错误'; switch(split) { case '0': return i < 10 ? split + i : i + ''; case '-': default: return split + i; } }; const recursiveSortCode = function (data, parentCode, children, split) { if (!children || children.length === 0) return; for (const [i, child] of children.entries()) { if (!child.b_code || child.b_code === '') { const code = parentCode + getChildSort(i + 1, split); const cData = tree.getNodeKeyData(child); cData.code = code; data.push(cData); if (!tree.isLeafXmj(child)) { recursiveSortCode(data, code, child.children, split); } } } }; const data = []; recursiveSortCode(data, select.code, select.children, tree.getCodeSplit()); if (data.length > 0) { postData(window.location.pathname + '/update', {postType: 'update', postData: data}, function (result) { const refreshNode = tree.loadPostData(result); treeOperationObj.refreshTree(sheet, refreshNode); }) } }, batchReplace: function(orgInfo, newInfo) { const updateData = []; for (const d of ledgerTree.nodes) { if (!d.b_code) continue; const checkInfo = { code: d.b_code || '', name: d.name || '', unit: d.unit || '', unit_price: d.unit_price || 0 }; if (_.isMatch(checkInfo, orgInfo)) { const data = ledgerTree.getNodeKeyData(d); data.b_code = newInfo.code; data.name = newInfo.name; data.unit = newInfo.unit; data.unit_price = newInfo.unit_price; updateData.push(data); } } if (updateData.length === 0) { toastr.warning('没有可以替换的数据'); return; } postData(window.location.pathname + '/update', {postType: 'update', postData: updateData}, function (result) { const refreshNode = ledgerTree.loadPostData(result); treeOperationObj.refreshTree(ledgerSheet, refreshNode); }); }, }; sjsSettingObj.setFxTreeStyle(ledgerSpreadSetting, sjsSettingObj.FxTreeStyle.jz); if (thousandth) sjsSettingObj.setTpThousandthFormat(ledgerSpreadSetting); ledgerTreeCol.initSpreadSetting(ledgerSpreadSetting); ledgerSpreadSetting.headColWidth = [50]; ledgerSpreadSetting.rowHeader = [ { rowHeaderType: 'tag', setting: { indent: 14, tagSize: 0.8, tagFont: '8px 微软雅黑', getColor: function (index, data) { if (!data) return; return billsTag.getBillsTagsColor(data.id); }, getTagHtml: function (index, data) { if (!data) return; const getHtml = function (list) { if (!list || list.length === 0) return ''; const html = []; for (const l of list) { html.push('
'); html.push(`
`, '', '
'); html.push('
', '

', l.comment, '

', '
'); html.push('
'); } return html.join(''); }; return getHtml(billsTag.getBillsTagsInfo(data.id)); } }, }, ]; // ledgerSpreadSetting.cols.push( // {title: 'ledger_id', colSpan: '1', rowSpan: '2', field: 'ledger_id', hAlign: 2, width: 60, type: 'Number', readOnly: true}, // {title: 'ledger_pid', colSpan: '1', rowSpan: '2', field: 'ledger_pid', hAlign: 2, width: 60, type: 'Number', readOnly: true}, // {title: 'level', colSpan: '1', rowSpan: '2', field: 'level', hAlign: 2, width: 60, type: 'Number', readOnly: true}, // {title: 'order', colSpan: '1', rowSpan: '2', field: 'order', hAlign: 2, width: 60, type: 'Number', readOnly: true}, // {title: 'is_leaf', colSpan: '1', rowSpan: '2', field: 'is_leaf', hAlign: 2, width: 60, type: 'Number', readOnly: true}, // {title: 'full_path', colSpan: '1', rowSpan: '2', field: 'full_path', hAlign: 2, width: 60, type: 'Number', readOnly: true}, // {title: 'node_type', colSpan: '1', rowSpan: '2', field: 'node_type', hAlign: 2, width: 60, type: 'Number', readOnly: true} // ); sjsSettingObj.setNodeTypeCol(ledgerSpreadSetting.cols, [{ field: 'node_type' }]); SpreadJsObj.initSheet(ledgerSpread.getActiveSheet(), ledgerSpreadSetting); SpreadJsObj.selChangedRefreshBackColor(ledgerSpread.getActiveSheet()); // 绑定事件 ledgerSpread.bind(spreadNS.Events.SelectionChanged, treeOperationObj.selectionChanged); ledgerSpread.bind(spreadNS.Events.TopRowChanged, treeOperationObj.topRowChanged); ledgerSpread.bind(spreadNS.Events.ClipboardChanging, function (e, info) { const copyText = SpreadJsObj.getFilterCopyText(info.sheet); SpreadJsObj.Clipboard.setCopyData(copyText); }); if (!ledgerSpreadSetting.readOnly) { ledgerSpread.bind(spreadNS.Events.SelectionChanged, function (e, info) { treeOperationObj.refreshOperationValid(info.sheet, info.newSelections); }); ledgerSpread.bind(spreadNS.Events.EditEnded, treeOperationObj.editEnded); SpreadJsObj.addDeleteBind(ledgerSpread, treeOperationObj.deletePress); ledgerSpread.bind(spreadNS.Events.ClipboardPasting, treeOperationObj.clipboardPasting); ledgerSpread.bind(spreadNS.Events.EditStarting, treeOperationObj.editStarting); SpreadJsObj.addCutEvents(ledgerSpread, treeOperationObj.cut); // 绑定 删除等 顶部按钮 $('#insert').click(() => { treeOperationObj.addNode(ledgerSpread.getActiveSheet()); }); $('#delete').click(function () { treeOperationObj.deleteNode(ledgerSpread.getActiveSheet()); }); $('#up-move').click(function () { treeOperationObj.upMove(ledgerSpread.getActiveSheet()); }); $('#down-move').click(function () { treeOperationObj.downMove(ledgerSpread.getActiveSheet()); }); $('#up-level').click(function () { treeOperationObj.upLevel(ledgerSpread.getActiveSheet()); }); $('#down-level').click(function () { treeOperationObj.downLevel(ledgerSpread.getActiveSheet()); }); $('#copy').click(function () { ledgerSpread.commandManager().execute({ cmd: 'copy', sheetName: ledgerSpread.getActiveSheet().name() }); }); $('#paste').click(function () { ledgerSpread.commandManager().execute({ cmd: 'paste', sheetName: ledgerSpread.getActiveSheet().name() }); }); $('#cut').click(function () { ledgerSpread.commandManager().execute({ cmd: 'cut', sheetName: ledgerSpread.getActiveSheet().name() }); }); $('#bills-expr').bind('change onblur', function () { const expr = $(this); const row = expr.attr('data-row') ? _.toInteger(expr.attr('data-row')) : -1; const select = ledgerTree.getItemsByIndex(row); if (!select) return; const field = expr.attr('field'), orgValue = expr.attr('org'), newValue = trimInvalidChar(expr.val()); if (orgValue === newValue || (!orgValue && newValue == '')) { return; } // 台账模式,检查计量单元相关 if (checkTzMeasureType()) { if (field === 'sgfh_qty' || field === 'sgfh_tp' || field === 'sjcl_qty' || field === 'sjcl_tp' || field === 'qtcl_qty' || field === 'qtcl_tp') { if (!select.children || select.children.length === 0) { const lPos = pos.getLedgerPos(select.id); if (lPos && lPos.length > 0) { toastr.error('清单含有计量单元,请在计量单元输入数量'); expr.val(''); return; } } } } const data = { id: select.id, tender_id: select.tender_id, ledger_id: select.ledger_id }; const exprInfo = getExprInfo(field); if (newValue !== '') { const num = _.toNumber(newValue); if (num) { data[field] = num; if (exprInfo) { data[exprInfo.expr] = ''; } } else { try { data[field] = ZhCalc.mathCalcExpr(transExpr(newValue)); if (exprInfo) { data[exprInfo.expr] = newValue; } } catch (err) { toastr.error('输入的表达式非法'); return; } } } else { data[field] = null; if (exprInfo) { data[exprInfo.expr] = ''; } } // 更新至服务器 postData(window.location.pathname + '/update', {postType: 'update', postData: data}, function (result) { const refreshNode = ledgerTree.loadPostData(result); treeOperationObj.refreshTree(ledgerSpread.getActiveSheet(), refreshNode); }); }); } let batchInsertObj, contractExprObj; $.contextMenu.types.batchInsert = function (item, opt, root) { const self = this; if ($.isFunction(item.icon)) { item._icon = item.icon.call(this, this, $t, key, item); } else { if (typeof(item.icon) === 'string' && item.icon.substring(0, 3) === 'fa-') { // to enable font awesome item._icon = root.classNames.icon + ' ' + root.classNames.icon + '--fa fa ' + item.icon; } else { item._icon = root.classNames.icon + ' ' + root.classNames.icon + '-' + item.icon; } } this.addClass(item._icon); const $obj = $('
' + item.name + '
') .appendTo(this); const $input = $obj.find('input'); const event = () => { if (self.hasClass('context-menu-disabled')) return; item.batchInsert($input[0], root); }; $obj.on('click', event).keypress(function (e) {if (e.keyCode === 13) { event(); }}); $input.click((e) => {e.stopPropagation();}) .keyup((e) => {if (e.keyCode === 13) item.batchInsert($input[0], root);}) .on('input', function () {this.value = this.value.replace(/[^\d]/g, '');}); }; // $.contextMenu.types.switch = function (item, opt, root) { // const self = this; // if ($.isFunction(item.icon)) { // item._icon = item.icon.call(this, this, $t, key, item); // } else { // if (typeof(item.icon) === 'string' && item.icon.substring(0, 3) === 'fa-') { // // to enable font awesome // item._icon = root.classNames.icon + ' ' + root.classNames.icon + '--fa fa ' + item.icon; // } else { // item._icon = root.classNames.icon + ' ' + root.classNames.icon + '-' + item.icon; // } // } // const html = []; // html.push('
'); // html.push('
'); // const $obj = $('
' + item.name +) // }; // 右键菜单 const addTag = newTag({ledgerSheet: ledgerSpread.getActiveSheet(), posSheet: posSpread.getActiveSheet(), billsTag}); const billsContextMenuOptions = { selector: '#ledger-spread', build: function ($trigger, e) { const target = SpreadJsObj.safeRightClickSelection($trigger, e, ledgerSpread); treeOperationObj.loadRelaData(); return target.hitTestType === spreadNS.SheetArea.viewport || target.hitTestType === spreadNS.SheetArea.rowHeader; }, items: {}, }; if (!readOnly) { billsContextMenuOptions.items.create = { name: '新增', icon: 'fa-sign-in', callback: function (key, opt) { treeOperationObj.addNode(ledgerSpread.getActiveSheet()); }, disabled: function (key, opt) { const sheet = ledgerSpread.getActiveSheet(); const selection = sheet.getSelections(); const sel = selection ? selection[0] : sheet.getSelections()[0]; const row = sel ? sel.row : -1; const tree = sheet.zh_tree; if (!tree) return true; const first = sheet.zh_tree.nodes[row]; let last = first, sameParent = true; if (sel.rowCount > 1) { for (let r = 1; r < sel.rowCount; r++) { const rNode = tree.nodes[sel.row + r]; if (rNode.level > first.level) continue; if ((rNode.level < first.level) || (rNode.level === first.level && rNode.pid !== first.pid)) { sameParent = false; break; } last = rNode; } } const valid = !sheet.zh_setting.readOnly; return !(valid && first && first.level > 1); }, visible: function (key, opt) { return !readOnly; } }; billsContextMenuOptions.items.delete = { name: '删除', icon: 'fa-remove', callback: function (key, opt) { treeOperationObj.deleteNode(ledgerSpread.getActiveSheet()); }, disabled: function (key, opt) { const sheet = ledgerSpread.getActiveSheet(); const selection = sheet.getSelections(); const sel = selection ? selection[0] : sheet.getSelections()[0]; const row = sel ? sel.row : -1; const tree = sheet.zh_tree; if (!tree) return true; const first = sheet.zh_tree.nodes[row]; let last = first, sameParent = true; if (sel.rowCount > 1) { for (let r = 1; r < sel.rowCount; r++) { const rNode = tree.nodes[sel.row + r]; if (rNode.level > first.level) continue; if ((rNode.level < first.level) || (rNode.level === first.level && rNode.pid !== first.pid)) { sameParent = false; break; } last = rNode; } } const valid = !sheet.zh_setting.readOnly; return !(valid && first && sameParent && !(first.level === 1 && first.node_type)); }, visible: function (key, opt) { return !readOnly; } }; billsContextMenuOptions.items.sprBase = '----'; } if (!readOnly) { billsContextMenuOptions.items.batchInsert = { name: '批量插入', type: 'batchInsert', value: '2', icon: 'fa-sign-in', batchInsert: function (obj, root) { if (_.toNumber(obj.value) > _.toNumber(obj.max)) { obj.value = obj.max; toastr.warning('批量插入不可多于' + obj.max); } else if(_.toNumber(obj.value) < _.toNumber(obj.min)) { obj.value = obj.min; toastr.warning('批量插入不可少于' + obj.min); } else { treeOperationObj.addNode(ledgerSpread.getActiveSheet(), parseInt(obj.value)); root.$menu.trigger('contextmenu:hide'); } }, disabled: function (key, opt) { const sheet = ledgerSpread.getActiveSheet(); const selection = sheet.getSelections(); const sel = selection ? selection[0] : sheet.getSelections()[0]; const row = sel ? sel.row : -1; const tree = sheet.zh_tree; if (!tree) return true; const first = sheet.zh_tree.nodes[row]; let last = first, sameParent = true; if (sel.rowCount > 1) { for (let r = 1; r < sel.rowCount; r++) { const rNode = tree.nodes[sel.row + r]; if (rNode.level > first.level) continue; if ((rNode.level < first.level) || (rNode.level === first.level && rNode.pid !== first.pid)) { sameParent = false; break; } last = rNode; } } const valid = !sheet.zh_setting.readOnly; return !(valid && first && first.level > 1); }, visible: function (key, opt) { return !readOnly; } }; billsContextMenuOptions.items.batchInsertBillsPos = { name: '批量插入清单-计量单元', icon: 'fa-sign-in', disabled: function (key, opt) { if (!checkTzMeasureType()) return true; 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 true; } }, callback: function (key, opt) { if (!batchInsertObj) { batchInsertObj = new BatchInsertBillsPosObj($('#batch')); } else { batchInsertObj.initView(); } $('#batch').modal('show'); }, visible: function (key, opt) { return !readOnly; } }; billsContextMenuOptions.items.batchReplace = { name: '批量替换清单', icon: 'fa-sign-in', callback: function(key, opt) { const node = SpreadJsObj.getSelectObject(ledgerSheet); if (!node) return; BatchReplace.load(node.b_code, node.name, node.unit, node.unit_price, treeOperationObj.batchReplace); }, disabled: function (key, opt) { const node = SpreadJsObj.getSelectObject(ledgerSheet); return !node || !node.b_code; }, visible: function (key, opt) { return !readOnly; } }; billsContextMenuOptions.items.sprBatch = '----'; } billsContextMenuOptions.items.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) { toastr.error('仅可同时选中同层节点'); return; } const posterity = sheet.zh_tree.getPosterity(node); iRow += posterity.length + 1; posterity.unshift(node); copyBlockList.push(sheet.zh_tree.getDefaultData(posterity)); } for (const cbl of copyBlockList) { for (const b of cbl) { const posRange = pos.getLedgerPos(b.id); if (posRange && posRange.length > 0) b.pos = posRange; const gclRange = ancGcl.getPartData(b.id); if (gclRange && gclRange.length > 0) b.ancGcl = gclRange; } } setLocalCache(copyBlockTag, JSON.stringify({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; }, disabled: function (key, opt) { const sheet = ledgerSpread.getActiveSheet(); const selection = sheet.getSelections(); const row = selection[0].row; const select = ledgerTree.nodes[row]; return select && select.level <= 1; } }; billsContextMenuOptions.items.copyBlockXmj = { name: '复制整块(只复制项目节)', icon: 'fa-files-o', callback: function (key, opt) { 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) { toastr.error('仅可同时选中同层节点'); return; } const posterity = sheet.zh_tree.getPosterity(node); iRow += posterity.length + 1; const copyPosterity = posterity.filter(x => { return !x.b_code; }); copyPosterity.unshift(node); const copyData = sheet.zh_tree.getDefaultData(copyPosterity); for (const p of copyData) { const children = copyData.filter(y => {return y.ledger_pid === p.ledger_id}) || []; p.is_leaf = children.length === 0; } copyBlockList.push(copyData); } setLocalCache(copyBlockTag, JSON.stringify({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; }, disabled: function (key, opt) { const sheet = ledgerSpread.getActiveSheet(); const selection = sheet.getSelections(); const row = selection[0].row; const select = ledgerTree.nodes[row]; return select && select.level <= 1; } }; if (!readOnly) { billsContextMenuOptions.items.pasteBlock = { name: '粘贴整块', icon: 'fa-clipboard', disabled: function (key, opt) { //const block = treeOperationObj.block || []; const copyInfo = JSON.parse(getLocalCache(copyBlockTag)); return !(copyInfo && copyInfo.block && copyInfo.block.length > 0); }, callback: function (key, opt) { //const block = treeOperationObj.block || []; const copyInfo = JSON.parse(getLocalCache(copyBlockTag)); if (copyInfo.block.length > 0) { treeOperationObj.pasteBlock(ledgerSpread, copyInfo); } else { document.execCommand('paste'); } }, visible: function (key, opt) { return !readOnly; } }; } billsContextMenuOptions.items.sprBlock = '----'; if (!readOnly) { billsContextMenuOptions.items.sortChildren = { name: '顺序重排子项编号', icon: 'fa-sort-numeric-asc', disabled: function (key, opt) { const node = SpreadJsObj.getSelectObject(ledgerSpread.getActiveSheet()); return !node || !node.code || !node.children || node.children === 0 || node.code.length < 3; }, callback: function (key, opt) { treeOperationObj.sortCode(ledgerSpread.getActiveSheet()); }, visible: function (key, opt) { return !readOnly; } }; if (!checkTzMeasureType()) { billsContextMenuOptions.items.applyDeal2Sgfh = { name: '填设计量', icon: 'fa-pencil', callback: function (key, opt) { postData(window.location.pathname + '/deal2sgfh', null, function (result) { ledgerTree.loadDatas(result.bills); treeCalc.calculateAll(ledgerTree); SpreadJsObj.loadSheetData(ledgerSpread.getActiveSheet(), 'tree', ledgerTree); }); } }; } billsContextMenuOptions.items.sprSort = '----'; } if (!readOnly) { const tenderSelect = TenderSelect({ type: 'ledger', afterLoad: function (result) { const ledgerSheet = ledgerSpread.getActiveSheet(); const refreshNode = ledgerTree.loadPostData(result); treeOperationObj.refreshTree(ledgerSheet, refreshNode); treeOperationObj.refreshOperationValid(ledgerSheet); } }); billsContextMenuOptions.items.importExcel = { name: '导入分项清单Excel', icon: 'fa-file-excel-o', disabled: function (key, opt) { return readOnly; }, callback: function (key, opt) { importExcel.doImport({ template: { hint: '0号台账', url: 'https://jl-assets.oss-cn-shenzhen.aliyuncs.com/template/A/导入分项清单EXCEL格式.xlsx', }, filter: true, callback: function (sheet, filter) { postDataCompress(window.location.pathname + '/upload-excel/tz', {sheet, filter}, function (result) { ledgerTree.loadDatas(result.bills); treeCalc.calculateAll(ledgerTree); SpreadJsObj.loadSheetData(ledgerSpread.getActiveSheet(), 'tree', ledgerTree); pos.loadDatas(result.pos); posOperationObj.loadCurPosData(); ancGclObj.loadCurAncillaryGcl(); checkShowLast(result.bills.length); }, null); }, // callback: function (file, select) { // const formData = new FormData(); // formData.append('file', file.files[0]); // postDataWithFileProgress(window.location.pathname + '/upload-excel?ueType=tz&sheetName=' + select, formData, function (result) { // ledgerTree.loadDatas(result.bills); // treeCalc.calculateAll(ledgerTree); // SpreadJsObj.loadSheetData(ledgerSpread.getActiveSheet(), 'tree', ledgerTree); // pos.loadDatas(result.pos); // posOperationObj.loadCurPosData(); // }, null); // } //u_type: importExcel.uploadType.file, }); } }; billsContextMenuOptions.items.importGclBills2Xmj = { name: '导入工程量清单至项目节', icon: 'fa-file-excel-o', disabled: function (key, opt) { const node = SpreadJsObj.getSelectObject(ledgerSpread.getActiveSheet()); return readOnly || !node || (node.children && node.children.length > 0) || (!_.isNil(node.b_code) && node.b_code !== ''); }, callback: function (key, opt) { const node = SpreadJsObj.getSelectObject(ledgerSpread.getActiveSheet()); importExcel.doImport({ template: { hint: '工程量清单', url: '/template/导入工程量清单EXCEL格式.xls', }, callback: function (sheet) { postDataCompress(window.location.pathname + '/upload-excel/gcl2xmj', {id: node.id, sheet: sheet}, function (result) { const ledgerSheet = ledgerSpread.getActiveSheet(); const sel = ledgerSheet.getSelections(); const refreshNode = ledgerTree.loadPostData(result); treeOperationObj.refreshTree(ledgerSheet, refreshNode); if (refreshNode.create[0]) { if (sel && sel[0]) { ledgerSheet.setSelection(refreshNode.create[0].index, sel[0].col, sel[0].rowCount, sel[0].colCount); SpreadJsObj.reloadRowsBackColor(ledgerSheet, [sel[0].row, refreshNode.create[0].index]); } else { ledgerSheet.setSelection(refreshNode.create[0].index, 0, 1, 1); SpreadJsObj.reloadRowsBackColor(ledgerSheet, [refreshNode.create[0].index]); } } treeOperationObj.refreshOperationValid(ledgerSheet); }, null); } }); } }; billsContextMenuOptions.items.importOtherTender = { name: '导入(其他标段)工程量清单至项目节', icon: 'fa-link', disabled: function (key, opt) { const node = SpreadJsObj.getSelectObject(ledgerSpread.getActiveSheet()); return readOnly || !node || (node.children && node.children.length > 0) || !ledgerTree.isLeafXmj(node); }, callback: function (key, opt) { tenderSelect.showSelect(SpreadJsObj.getSelectObject(ledgerSpread.getActiveSheet())); } }; billsContextMenuOptions.items.sprImport = '----'; } billsContextMenuOptions.items.tag = { name: '书签', callback: function (key, opt, menu, e) { const node = SpreadJsObj.getSelectObject(ledgerSpread.getActiveSheet()); addTag.do(node); }, disabled: function (key, opt) { const node = SpreadJsObj.getSelectObject(ledgerSpread.getActiveSheet()); return !node; } }; billsContextMenuOptions.items.sprTag = '----'; billsContextMenuOptions.items.showLast = { name: '显示至最底层', callback: function (key, opt, menu, e) { const node = SpreadJsObj.getSelectObject(ledgerSpread.getActiveSheet()); setTimeout(() => { showWaitingView(); ledgerTree.expandByCustom(x => { return x.expanded ||(x.id === node.id) || (x.full_path.indexOf(node.ledger_id + '-') >= 0); }); SpreadJsObj.refreshTreeRowVisible(ledgerSpread.getActiveSheet()); closeWaitingView(); }, 100); }, }; billsContextMenuOptions.items.exportJSON = { name: '导出后台标准表json', callback: function (key, opt, menu, e) { const result = []; for (const node of ledgerTree.nodes) { result.push({ id: node.ledger_id, pid: node.ledger_pid, level: node.level, order: node.order, is_leaf: !node.children || node.children.length === 0, full_path: node.full_path, code: node.code || '', b_code: node.b_code || '', name: node.name || '', unit: node.unit || '', node_type: node.node_type, }); } const blob = new Blob([JSON.stringify(result, '', '\t')], { type: 'application/text'}); saveAs(blob, "台账分解.json"); }, visible: function() { return is_debug; } }; if (contractExpr && readOnly) { billsContextMenuOptions.items.exprTag = '----'; billsContextMenuOptions.items.contractExpr = { name: '预设本期合同计量公式', callback: function (key, opt, menu, e) { const node = SpreadJsObj.getSelectObject(ledgerSpread.getActiveSheet()); if (!contractExprObj) { contractExprObj = new ContractExpr({ sourceTree: ledgerTree }); } contractExprObj.initView(node); $('#contract_expr').modal('show'); }, visible: function (key, opt) { const node = SpreadJsObj.getSelectObject(ledgerSpread.getActiveSheet()); if (node.children && node.children.length > 0) return false; const posRange = pos.getLedgerPos(node.id); if (posRange && posRange.length > 0) return false; return true; } }; } $.contextMenu(billsContextMenuOptions); const posSearch = $.posSearch({selector: '#pos-search', searchSpread: posSpread}); // 台账模式加载计量单元数据 if (checkTzMeasureType()) { $.divResizer({ select: '#main-resize', callback: function () { ledgerSpread.refresh(); let bcontent = $(".bcontent-wrap") ? $(".bcontent-wrap").height() : 0; $(".sp-wrap").height(bcontent-30); posSpread.refresh(); if (ancGclSpread) ancGclSpread.refresh(); } }); sjsSettingObj.setGridSelectStyle(posSpreadSetting); } posSpreadSetting.headColWidth = [50]; posSpreadSetting.rowHeader = [ { rowHeaderType: 'tag', setting: { indent: 14, tagSize: 0.8, tagFont: '8px 微软雅黑', getColor: function (index, data) { if (!data) return; return billsTag.getPosTagsColor(data.lid, data.id); }, getTagHtml: function (index, data) { if (!data) return; const getHtml = function (list) { if (!list || list.length === 0) return ''; const html = []; for (const l of list) { html.push('
'); html.push(`
`, '', '
'); html.push('
', '

', l.comment, '

', '
'); html.push('
'); } return html.join(''); }; return getHtml(billsTag.getPosTagsInfo(data.lid, data.id)); } }, }, ]; SpreadJsObj.initSheet(posSpread.getActiveSheet(), posSpreadSetting); //绑定计量单元编辑事件 const posOperationObj = { /** * 刷新顶部按钮是否可用 * @param sheet * @param selections */ refreshOperationValid: function (sheet, selection) { const setObjEnable = function (obj, enable) { if (enable) { obj.removeClass('disabled'); } else { obj.addClass('disabled'); } }; const invalidAll = function () { setObjEnable($('a[name=pos-opr][type=up-move]'), false); setObjEnable($('a[name=pos-opr][type=down-move]'), false); }; const sel = selection ? selection[0] : sheet.getSelections()[0]; const row = sel ? sel.row : -1; const first = sheet.zh_data[row]; if (!first) { invalidAll(); return; } let last = first; if (sel.rowCount > 1 && first) { for (let r = 1; r < sel.rowCount; r++) { const rNode = sheet.zh_data[sel.row + r]; if (!rNode) break; last = rNode; } } const preNode = sheet.zh_data[row - 1]; const valid = !sheet.zh_setting.readOnly; setObjEnable($('a[name=pos-opr][type=up-move]'), valid && first && preNode); setObjEnable($('a[name=pos-opr][type=down-move]'), valid && first && (sheet.zh_data.indexOf(last) < sheet.zh_data.length - 1)); }, editStarting: function (e, info) { posOperationObj.ledgerTreeNode = SpreadJsObj.getSelectObject(ledgerSpread.getActiveSheet()); const sel = info.sheet.getSelections(); if (!sel || !sel[0]) return; const col = info.sheet.zh_setting.cols[sel[0].col]; const node = SpreadJsObj.getSelectObject(info.sheet); const exprInfo = getExprInfo(col.field); if (exprInfo) { if (node[exprInfo.expr] && node[exprInfo.expr] !== '') { info.sheet.getCell(info.row, info.col).text(node[exprInfo.expr]); } } }, loadExprToInput: function () { const sheet = posSpread.getActiveSheet(); const sel = sheet.getSelections()[0]; if (!sel || !sheet.zh_setting) return; const col = sheet.zh_setting.cols[sel.col], cell = sheet.getCell(sel.row, sel.col); if (col && col.type === 'Number') { const data = SpreadJsObj.getSelectObject(sheet); if (data) { const exprInfo = getExprInfo(col.field); const value = exprInfo ? (data[exprInfo.expr] ? data[exprInfo.expr] : data[col.field]) : data[col.field]; $('#pos-expr').val(value).attr('field', col.field).attr('org', data[col.field]) .attr('readOnly', readOnly || cell.locked()).attr('data-row', sel.row); } else { $('#pos-expr').val('').attr('readOnly', true); $('#pos-expr').removeAttr('data-row'); } } else { $('#pos-expr').val('').attr('readOnly', true); $('#pos-expr').removeAttr('data-row'); } }, /** * 加载计量单元 根据当前台账选择节点 */ loadCurPosData: function () { //spreadJsObj.reinitSheet(posSpread.getActiveSheet()); const node = treeOperationObj.getSelectNode(ledgerSpread.getActiveSheet()); if (node) { const posData = pos.ledgerPos[itemsPre + node.id] || []; SpreadJsObj.loadSheetData(posSpread.getActiveSheet(), 'data', posData); getNodeList(node.id); } else { SpreadJsObj.loadSheetData(posSpread.getActiveSheet(), 'data', []); } posOperationObj.loadExprToInput(); posOperationObj.refreshOperationValid(posSpread.getActiveSheet()); }, baseOpr: function (sheet, type) { const data = { updateType: type === 'delete' ? type : 'update', updateData: [], }; const selection = sheet.getSelections(); const row = selection[0].row, count = selection[0].rowCount; const first = sheet.zh_data[row]; if (type === 'delete') { for (let iRow = 0; iRow < count; iRow++) { const posData = sheet.zh_data[iRow + row]; if (posData) { data.updateData.push(sheet.zh_data[iRow + row].id); } } } else if (type === 'up-move') { const pre = sheet.zh_data[row - 1], preUpdate = {id: pre.id}; for (let iRow = 0; iRow < count; iRow++) { const posData = sheet.zh_data[iRow + row]; if (posData) { data.updateData.push({id: posData.id, lid: posData.lid, porder: sheet.zh_data[iRow + row - 1].porder}); preUpdate.porder = posData.porder; } } data.updateData.push(preUpdate); } else if (type === 'down-move') { const next = sheet.zh_data[row + count], nextUpdate = {id: next.id}; for (let iRow = count - 1; iRow >= 0; iRow--) { const posData = sheet.zh_data[iRow + row]; if (posData) { data.updateData.push({id: posData.id, lid: posData.lid, porder: sheet.zh_data[iRow + row + 1].porder}); nextUpdate.porder = posData.porder; } } data.updateData.push(nextUpdate); } if (data.updateData.length > 0) { postData('/tender/' + getTenderId() + '/pos/update', data, function (result) { if (type === 'delete') { for (const p of result.pos) { const posInfo = pos.getPos(p); billsTag.afterDeletePos([posInfo]); } pos.removeDatas(result.pos); sheet.deleteRows(row, count); const loadResult = ledgerTree.loadPostData(result.ledger); treeOperationObj.refreshTree(ledgerSpread.getActiveSheet(), loadResult); treeOperationObj.refreshOperationValid(ledgerSpread.getActiveSheet()); } else { const updateRst = pos.updateDatas(result.pos); billsTag.refreshPosTagView(updateRst.update); const sel = selection[0]; if (sel) { sheet.setSelection(sheet.zh_data.indexOf(first), sel.col, sel.rowCount, sel.colCount); SpreadJsObj.reloadRowsBackColor(sheet, [sel.row, sheet.zh_data.indexOf(first)]); } posOperationObj.loadCurPosData(); } }); } }, /** * 编辑单元格响应事件 * @param {Object} e * @param {Object} info */ editEnded: function (e, info) { if (info.sheet.zh_setting) { const posData = info.sheet.zh_data ? info.sheet.zh_data[info.row] : null; const col = info.sheet.zh_setting.cols[info.col]; const orgText = posData ? posData[col.field] : null; const newText = col.wordWrap ? info.editingText : trimInvalidChar(info.editingText); if (orgText === newText || ((!orgText || orgText === '') && (newText === ''))) { return; } const node = posOperationObj.ledgerTreeNode; if (!node) { toastr.error('数据错误,请选择台账节点后再试'); SpreadJsObj.reLoadRowData(info.sheet, info.row); return; } else if (newText && newText !== '' && node.children && node.children.length > 0) { toastr.error('父节点不可插入计量单元'); SpreadJsObj.reLoadRowData(info.sheet, info.row); return; }else if (newText && newText !== '' && (!node.b_code || node.b_code === '')) { toastr.error('项目节不可插入计量单元'); SpreadJsObj.reLoadRowData(info.sheet, info.row); return; } const data = { updateType: posData ? 'update' : 'add' }; if (!posData) { const sortData = info.sheet.zh_data; const order = (!sortData || sortData.length === 0) ? 1 : Math.max(sortData[sortData.length - 1].porder + 1, sortData.length + 1); data.updateData = { lid: node.id, tid: tender.id, porder: order }; } else { data.updateData = { id: posData.id }; } if (col.type === 'Number') { const exprInfo = getExprInfo(col.field); const num = _.toNumber(newText); if (_.isFinite(num)) { data.updateData[col.field] = num; if (exprInfo) { data.updateData[exprInfo.expr] = ''; } } else { try { data.updateData[col.field] = ZhCalc.mathCalcExpr(transExpr(newText)); if (exprInfo) { data.updateData[exprInfo.expr] = newText; } } catch(err) { toastr.error('输入的表达式非法'); SpreadJsObj.reLoadRowData(info.sheet, info.row); return; } } } else if (col.field.indexOf('_expr') > 0) { const exprInfo = getExprInfo(col.field, true); if (!exprInfo) return; if (newText) { try { data.updateData[exprInfo.qty] = ZhCalc.mathCalcExpr(transExpr(newText)); data.updateData[exprInfo.expr] = newText; } catch(err) { toastr.error('输入的表达式非法'); SpreadJsObj.reLoadRowData(info.sheet, info.row); return; } } else { data.updateData[exprInfo.qty] = 0; data.updateData[exprInfo.expr] = ''; } } else { data.updateData[col.field] = newText; } postData('/tender/' + getTenderId() + '/pos/update', data, function (result) { const updateRst = pos.updateDatas(result.pos); billsTag.refreshPosTagView(updateRst.update); // 刷新当前行, 不适用于新增(在非下一空白行新增) if (updateRst.create.length > 0) { // info.sheet.addRows(info.row, 1); // if (info.sheet.zh_data.length === 0) { // info.sheet.zh_data = pos.ledgerPos[itemsPre + node.id] || []; // } // SpreadJsObj.reLoadRowData(info.sheet, info.sheet.zh_data.length - 1); posOperationObj.loadCurPosData(); } else { SpreadJsObj.reLoadRowData(info.sheet, info.row); } const loadResult = ledgerTree.loadPostData(result.ledger); treeOperationObj.refreshTree(ledgerSpread.getActiveSheet(), loadResult); treeOperationObj.refreshOperationValid(ledgerSpread.getActiveSheet()); }, function () { SpreadJsObj.reLoadRowData(info.sheet, info.row); }); } }, /** * 删除按钮响应事件 * @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++) { let bDel = false; 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]; const style = sheet.getStyle(iRow, iCol); if (!style.locked) { const colSetting = sheet.zh_setting.cols[iCol]; if (colSetting.field.indexOf('_expr') > 0) { const exprInfo = getExprInfo(colSetting.field, true); if (!exprInfo) continue; data[exprInfo.expr] = ''; data[exprInfo.qty] = 0; } else { data[colSetting.field] = null; const exprInfo = getExprInfo(colSetting.field); if (exprInfo) data[exprInfo.expr] = ''; } bDel = true; } } if (bDel) { datas.push(data); posSelects.push(node); } } } if (datas.length > 0) { postData('/tender/' + getTenderId() + '/pos/update', {updateType: 'update', updateData: datas}, function (result) { const updateRst = pos.updateDatas(result.pos); billsTag.refreshPosTagView(updateRst.update); posOperationObj.loadCurPosData(); const loadResult = ledgerTree.loadPostData(result.ledger); treeOperationObj.refreshTree(ledgerSpread.getActiveSheet(), loadResult); treeOperationObj.refreshOperationValid(ledgerSpread.getActiveSheet()); }, function () { posOperationObj.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++) { if (sortData[iRow + row]) { data.updateData.push(sortData[iRow + row].id); } } if (data.updateData.length > 0) { postData('/tender/' + getTenderId() + '/pos/update', data, function (result) { for (const p of result.pos) { const posInfo = pos.getPos(p); billsTag.afterDeletePos([posInfo]); } pos.removeDatas(result.pos); sheet.deleteRows(row, count); const loadResult = ledgerTree.loadPostData(result.ledger); treeOperationObj.refreshTree(ledgerSpread.getActiveSheet(), loadResult); treeOperationObj.refreshOperationValid(ledgerSpread.getActiveSheet()); }); } }, insertPos: function (sheet) { const selection = sheet.getSelections(); const sortData = sheet.zh_data; const row = selection[0].row; const node = SpreadJsObj.getSelectObject(ledgerSpread.getActiveSheet()); const select = SpreadJsObj.getSelectObject(sheet); const porder = select ? select.porder : sortData.length + 1; const data = { updateType: 'insert', updateData: [ { lid: node.id, tid: tender.id, porder } ], }; postData('/tender/' + getTenderId() + '/pos/update', data, function (result) { const updateRst = pos.updateDatas(result.pos); posOperationObj.loadCurPosData(); treeOperationObj.refreshOperationValid(ledgerSpread.getActiveSheet()); }); }, /** * 粘贴单元格响应事件 * @param e * @param info */ clipboardPasted: function (e, info) { if (info.sheet.getColumnCount() > info.sheet.zh_setting.cols.length) { info.sheet.setColumnCount(info.sheet.zh_setting.cols.length); } const node = treeOperationObj.getSelectNode(ledgerSpread.getActiveSheet()); if (node.code && (node.code !== '')) { toastr.error('项目节不可含有清单明细'); posOperationObj.loadCurPosData(); return; } if (node.children && (node.children.length > 0)) { toastr.error('仅清单子项可以含有计量单元'); posOperationObj.loadCurPosData(); return; } const hint = { expr: {type: 'warning', msg: '粘贴了表达式非法,已过滤'}, }; if (info.sheet.zh_setting) { const data = []; const sortData = info.sheet.zh_data || []; if (sortData.length === 0 || info.cellRange.row + info.cellRange.rowCount > sortData.length) { const nameCol = info.sheet.zh_setting.cols.findIndex(x => { return x.field === 'name'; }); if (info.cellRange.col > nameCol || info.cellRange.col + info.cellRange.colCount < nameCol) { toastr.warning('新增计量单元请先输入名称'); posOperationObj.loadCurPosData(); return; } } const lastOrder = sortData.length > 0 ? sortData[sortData.length - 1].porder + 1 : 1; for (let iRow = 0; iRow < info.cellRange.rowCount; iRow++) { let bPaste = false; const curRow = info.cellRange.row + iRow; const posData = curRow >= sortData.length ? {lid: node.id, porder: lastOrder + curRow - sortData.length} : {id: sortData[curRow].id, lid: node.id}; for (let iCol = 0; iCol < info.cellRange.colCount; iCol++) { const curCol = info.cellRange.col + iCol; const colSetting = info.sheet.zh_setting.cols[curCol]; if (!colSetting) continue; posData[colSetting.field] = colSetting.wordWrap ? info.sheet.getText(curRow, curCol) : trimInvalidChar(info.sheet.getText(curRow, curCol)); if (colSetting.type === 'Number') { const num = _.toNumber(posData[colSetting.field]); if (num) { posData[colSetting.field] = num; bPaste = true; } else { try { posData[colSetting.field] = ZhCalc.mathCalcExpr(transExpr(posData[colSetting.field])); const exprInfo = getExprInfo(colSetting.field); if (exprInfo) { posData[exprInfo.expr] = trimInvalidChar(info.sheet.getText(curRow, curCol)); } bPaste = true; } catch (err) { delete posData[colSetting.field]; toastMessageUniq(hint.expr); } } } else if (colSetting.field.indexOf('_expr') > 0) { try { const exprInfo = getExprInfo(colSetting.field, true); posData[exprInfo.expr] = trimInvalidChar(info.sheet.getText(curRow, curCol)); if (posData[exprInfo.expr] || !posData[exprInfo.qty]) { posData[exprInfo.qty] = ZhCalc.mathCalcExpr(transExpr(posData[exprInfo.expr])); } bPaste = true; } catch (err) { toastMessageUniq(hint.expr); } } else { bPaste = true; } } if (bPaste) { data.push(posData); } } if (data.length > 0) { postData('/tender/' + getTenderId() + '/pos/paste', data, function (result) { const updateRst = pos.updateDatas(result.pos); billsTag.refreshPosTagView(updateRst.update); posOperationObj.loadCurPosData(); const loadResult = ledgerTree.loadPostData(result.ledger); treeOperationObj.refreshTree(ledgerSpread.getActiveSheet(), loadResult); posOperationObj.loadCurPosData(); treeOperationObj.refreshOperationValid(ledgerSpread.getActiveSheet()); }, function () { SpreadJsObj.reLoadRowData(info.sheet, info.cellRange.row, info.cellRange.rowCount); }); } else { SpreadJsObj.reLoadRowData(info.sheet, info.cellRange.row, info.cellRange.rowCount); } } }, selectionChanged: function (e, info) { posOperationObj.loadExprToInput(); posOperationObj.refreshOperationValid(posSpread.getActiveSheet()); }, addPegs: function (pegs) { if (!pegs || pegs.length <= 0) return; const node = SpreadJsObj.getSelectObject(ledgerSpread.getActiveSheet()); if (!node) return; const sheet = posSpread.getActiveSheet(); const sortData = sheet.zh_data || []; let order = sortData.length > 0 ? sortData[sortData.length - 1].porder + 1 : 1; pegs.forEach(function (p) {p.porder = ++order; p.lid = node.id}); postData('/tender/' + getTenderId() + '/pos/paste', pegs, function (result) { pos.updateDatas(result.pos); posOperationObj.loadCurPosData(); treeOperationObj.refreshOperationValid(ledgerSpread.getActiveSheet()); }); } }; posSpread.bind(spreadNS.Events.SelectionChanged, posOperationObj.selectionChanged); if (!posSpreadSetting.readOnly) { $('a[name="pos-opr"]').click(function () { posOperationObj.baseOpr(posSpread.getActiveSheet(), this.getAttribute('type')); }); $('#pos-expr').bind('change onblur', function () { const expr = $(this); const posSheet = posSpread.getActiveSheet(); const row = expr.attr('data-row') ? _.toInteger(expr.attr('data-row')) : -1; const select = posSheet.zh_data ? posSheet.zh_data[row] : null; if (!select) return; const field = expr.attr('field'), orgValue = expr.attr('org'), newValue = expr.val(); if (orgValue === newValue || (!orgValue && newValue == '')) { return; } const data = {id: select.id}; const exprInfo = getExprInfo(field); if (newValue !== '') { const num = _.toNumber(newValue); if (num) { data[field] = num; if (exprInfo) { data[exprInfo.expr] = ''; } } else { try { data[field] = ZhCalc.mathCalcExpr(transExpr(newValue)); if (exprInfo) { data[exprInfo.expr] = newValue; } } catch (err) { toastr.error('输入的表达式非法'); return; } } } else { data[field] = null; if (exprInfo) { data[exprInfo.expr] = ''; } } // 更新至服务器 postData('/tender/' + getTenderId() + '/pos/update', {updateType: 'update', updateData: data}, function (result) { const updateRst = pos.updateDatas(result.pos); SpreadJsObj.reLoadRowData(posSheet, _.toNumber(row)); const loadResult = ledgerTree.loadPostData(result.ledger); treeOperationObj.refreshTree(ledgerSpread.getActiveSheet(), loadResult); treeOperationObj.refreshOperationValid(ledgerSpread.getActiveSheet()); }); }); SpreadJsObj.addDeleteBind(posSpread, posOperationObj.deletePress); posSpread.bind(spreadNS.Events.EditStarting, posOperationObj.editStarting); posSpread.bind(spreadNS.Events.EditEnded, posOperationObj.editEnded); posSpread.bind(spreadNS.Events.ClipboardPasted, posOperationObj.clipboardPasted); } const mergePeg = NewMergePeg({ callback: posOperationObj.addPegs }); // 右键菜单 $.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: { 'insert': { name: '插入', icon: 'fa-plus', disabled: function (key, opt) { const node = SpreadJsObj.getSelectObject(ledgerSpread.getActiveSheet()); return node && node.children && node.children.length > 0; }, callback: function (key, opt) { posOperationObj.insertPos(posSpread.getActiveSheet()); }, visible: function(key, opt) { return !readOnly; } }, '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()); }, visible: function(key, opt) { return !readOnly; } }, 'merge-peg': { name: '合并起讫桩号', disabled: function (key, opt) { const node = SpreadJsObj.getSelectObject(ledgerSpread.getActiveSheet()); return _.isNil(node) || _.isNil(node.b_code) || node.b_code === ''; }, callback: function (key, opt) { mergePeg.show(); }, visible: function(key, opt) { return !readOnly; } }, tag: { name: '书签', disabled: function(key, opt) { const node = SpreadJsObj.getSelectObject(ledgerSpread.getActiveSheet()); const pos = SpreadJsObj.getSelectObject(posSpread.getActiveSheet()); return _.isNil(node) || _.isNil(pos); }, callback: function(key, opt) { const node = SpreadJsObj.getSelectObject(ledgerSpread.getActiveSheet()); const pos = SpreadJsObj.getSelectObject(posSpread.getActiveSheet()); addTag.do(node, pos); } } } }); // 附属工程量相关 const ancGclSpreadSetting = { cols: [ {title: '辅材', colSpan: '1', rowSpan: '1', field: 'is_aux', hAlign: 1, width: 40, cellType: 'checkbox'}, {title: '名称', colSpan: '1', rowSpan: '1', field: 'name', hAlign: 0, width: 120, formatter: '@'}, {title: '单位', colSpan: '1', rowSpan: '1', field: 'unit', hAlign: 1, width: 40, formatter: '@', cellType: 'unit'}, {title: '设计量', colSpan: '1', rowSpan: '1', field: 'quantity', hAlign: 2, width: 60, type: 'Number'}, {title: '设计量公式', colSpan: '1', rowSpan: '1', field: 'expr', hAlign: 0, width: 80, formatter: '@'}, {title: '图册号', colSpan: '1', rowSpan: '1', field: 'drawing_code', hAlign: 0, width: 80, formatter: '@'}, {title: '备注', colSpan: '1', rowSpan: '1', field: 'memo', hAlign: 0, width: 80, formatter: '@'}, ], emptyRows: 3, headRows: 1, headRowHeight: [32], headColWidth: [30], defaultRowHeight: 21, headerFont: '12px 微软雅黑', font: '12px 微软雅黑', }; SpreadJsObj.initSheet(ancGclSheet, ancGclSpreadSetting); const ancGclObj = { loadCurAncillaryGcl: function () { const node = treeOperationObj.getSelectNode(ledgerSheet); const gclData = node ? ancGcl.getPartData(node.id) || [] : []; SpreadJsObj.loadSheetData(ancGclSheet, SpreadJsObj.DataType.Data, gclData); }, baseOpr: function (type) { const data = {}; const gclRange = ancGclSheet.zh_data; if (type !== 'insert' && (!gclRange || gclRange.length === 0)) return; const sel = ancGclSheet.getSelections(); if (!sel[0]) return; const row = sel[0].row, count = sel[0].rowCount; const first = gclRange[row]; if (type === 'insert') { const node = SpreadJsObj.getSelectObject(ledgerSheet); data.add = [{ lid: node.id, g_order: gclRange.length + 1 }]; } else if (type === 'delete') { data.del = []; for (let iRow = 0; iRow < count; iRow++) { const gclData = gclRange[row + iRow]; if (!gclData) continue; data.del.push(gclData.id); } if (data.del.length === 0) return; } else if (type === 'up-move') { data.update = []; const pre = gclRange[row - 1]; if (!pre) return; const preUpdate = { id: pre.id }; for (let iRow = 0; iRow < count; iRow++) { const gclData = gclRange[iRow + row]; if (!gclData) continue; data.update.push({ id: gclData.id, g_order: gclRange[iRow + row - 1].g_order }); preUpdate.g_order = gclData.g_order; } data.update.push(preUpdate); if (data.update <= 1) return; } else if (type === 'down-move') { data.update = []; const next = gclRange[row + count]; if (!next) return; const nextUpdate = { id: next.id }; for (let iRow = count - 1; iRow >= 0; iRow--) { const gclData = gclRange[iRow + row]; if (!gclData) continue; data.update.push({ id: gclData.id, g_order: gclRange[iRow + row + 1].g_order}); nextUpdate.g_order = gclData.g_order; } data.update.push(nextUpdate); if (data.update <= 1) return; } postData('/tender/' + getTenderId() + '/anc-gcl/update', data, function(result) { ancGcl.updateDatas(result); ancGclObj.loadCurAncillaryGcl(); if (type !== 'delete') SpreadJsObj.locateData(ancGclSheet, first); }); }, editStarting: function (e, info) { ancGclObj.ledgerTreeNode = SpreadJsObj.getSelectObject(ledgerSheet); }, editEnded: function (e, info) { const setting = info.sheet.zh_setting; if (!setting) return; const gclData = SpreadJsObj.getSelectObject(info.sheet); const col = setting.cols[info.col]; const orgText = gclData ? gclData[col.field] : '', newText = trimInvalidChar(info.editingText); if (orgText === newText || (!orgText && !newText)) return; const node = ancGclObj.ledgerTreeNode; if (!node) { toastr.error('数据错误,请选择台账节点后再试'); SpreadJsObj.reLoadRowData(info.sheet, info.row); return; } if (!!newText && node.children && node.children.length > 0) { toastr.error('父节点不可添加附属工程量'); SpreadJsObj.reLoadRowData(info.sheet, info.row); return; } if (!!newText && (!node.b_code || node.b_code === '')) { toastr.error('项目节不可插入附属工程量'); SpreadJsObj.reLoadRowData(info.sheet, info.row); return; } const data = {}; if (gclData) { const updateData = { id: gclData.id }; if (col.type === 'Number') { const num = _.toNumber(newText); if (!_.isFinite(num)) { toastr.error('输入的数字非法'); SpreadJsObj.reLoadRowData(info.sheet, info.row); return; } updateData[col.field] = num; if (gclData.expr) updateData.expr = ''; } else if (col.field === 'expr') { try { updateData.expr = newText; updateData.quantity = ZhCalc.mathCalcExpr(transExpr(newText)); } catch(err) { toastr.error('输入的计算式非法'); SpreadJsObj.reLoadRowData(info.sheet, info.row); return; } } else { updateData[col.field] = newText; } data.update = [ updateData ]; } else { const sortData = info.sheet.zh_data; const order = (!sortData || sortData.length === 0) ? 1 : Math.max(sortData[sortData.length - 1].g_order + 1, sortData.length + 1); const addData = { lid: node.id, g_order: order }; if (col.type === 'Number') { const num = _.toNumber(newText); if (!_.isFinite(num)) { toastr.error('输入的数字非法'); SpreadJsObj.reLoadRowData(info.sheet, info.row); return; } addData[col.field] = num; if (gclData.expr) addData.expr = ''; } else if (col.field === 'expr') { try { addData.expr = newText; addData.quantity = ZhCalc.mathCalcExpr(transExpr(newText)); } catch(err) { toastr.error('输入的计算式非法'); SpreadJsObj.reLoadRowData(info.sheet, info.row); return; } } else { addData[col.field] = newText; } data.add = [addData]; } postData('/tender/' + getTenderId() + '/anc-gcl/update', data, function (result) { ancGcl.updateDatas(result); ancGclObj.loadCurAncillaryGcl(); }, function () { SpreadJsObj.reLoadRowData(info.sheet, info.row); }); }, deletePress: function (sheet) { const setting = sheet.zh_setting; if (!setting) return; const sortData = sheet.zh_data; if (!sortData || sortData.length === 0) return; const sel = sheet.getSelections()[0]; const data = { update: [] }; for (let iRow = sel.row; iRow < sel.row + sel.rowCount; iRow++) { let bDel = false; const node = sortData[iRow]; if (!node) continue; const updateData = { id: node.id }; for (let iCol = sel.col; iCol < sel.col + sel.colCount; iCol++) { const style = sheet.getStyle(iRow, iCol); if (style.locked) continue; const col = setting.cols[iCol]; if (col.field === 'expr') { updateData.expr = ''; updateData.quantity = 0; } else { updateData[col.field] = col.type === 'Number' ? 0 : ''; if (col.field === 'quantity') updateDataexpr = ''; } bDel = true; } if (bDel) data.update.push(updateData); } if (data.update.length === 0) return; postData('/tender/' + getTenderId() + '/anc-gcl/update', data, function (result) { ancGcl.updateDatas(result); ancGclObj.loadCurAncillaryGcl(); }, function () { SpreadJsObj.reLoadRowData(info.sheet, info.row); }); }, clipboardPasting: function(e, info) { info.cancel = true; const node = SpreadJsObj.getSelectObject(ledgerSheet); if (!node) { toastr.error('数据错误,请选择台账节点后再试'); SpreadJsObj.reLoadRowData(info.sheet, info.row); return; } if (node.children && node.children.length > 0) { toastr.error('父节点不可添加附属工程量'); SpreadJsObj.reLoadRowData(info.sheet, info.row); return; } if ((!node.b_code || node.b_code === '')) { toastr.error('项目节不可插入附属工程量'); SpreadJsObj.reLoadRowData(info.sheet, info.row); return; } const hint = { expr: {type: 'warning', msg: '输入的 计算式 非法,已过滤'}, num: {type: 'warning', msg: '输入的 数字 非法,已过滤'}, }; const setting = info.sheet.zh_setting; const sortData = info.sheet.zh_data || []; const pasteData = SpreadJsObj.analysisPasteText(info.pasteData.text); const data = {}; const analysisData = function(pasteRow, targetData) { pasteRow.forEach((value, iCol) => { const col = setting.cols[info.cellRange.col + iCol]; if (col.field === 'expr') { try { targetData.expr = trimInvalidChar(value); targetData.quantity = ZhCalc.mathCalcExpr(transExpr(targetData.expr)); } catch(err) { toastMessageUniq(hint.expr); targetData.expr = ''; return; } } else if (col.type === 'Number') { const num = _.toNumber(value); if (!_.isFinite(num)) { toastMessageUniq(hint.num); return; } targetData[col.field] = num; if (col.field === 'quantity') targetData.expr = ''; } else { targetData[col.field] = value; } }); }; for (let iRow = 0; iRow < pasteData.length; iRow++) { const curRow = iRow + info.cellRange.row; const gclData = sortData[curRow]; if (gclData) { if (!data.update) data.update = []; const updateData = { id: gclData.id }; analysisData(pasteData[iRow], updateData); data.update.push(updateData); } else { if (!data.add) data.add = []; const addData = { lid: node.id, g_order: curRow + 1}; analysisData(pasteData[iRow], addData); data.add.push(addData); } } if ((!data.update || data.update.length === 0) && (!data.add || data.add.length === 0)) return; postData('/tender/' + getTenderId() + '/anc-gcl/update', data, function (result) { ancGcl.updateDatas(result); ancGclObj.loadCurAncillaryGcl(); }, function () { SpreadJsObj.reLoadRowData(info.sheet, info.row); }); }, buttonClicked: function (e, info) { const setting = info.sheet.zh_setting; if (!setting) return; const node = SpreadJsObj.getSelectObject(info.sheet); if (!node) { toastr.warning('请先添加附属工程量再设置辅材'); SpreadJsObj.reLoadRowData(info.sheet, info.row); return; } const col = setting.cols[info.col]; const updateData = { id: node.id }; updateData[col.field] = node[col.field] ? 0 : 1; postData('/tender/' + getTenderId() + '/anc-gcl/update', { update: [updateData]}, function (result) { ancGcl.updateDatas(result); ancGclObj.loadCurAncillaryGcl(); }, function () { SpreadJsObj.reLoadRowData(info.sheet, info.row); }); }, }; SpreadJsObj.addDeleteBind(ancGclSpread, ancGclObj.deletePress); ancGclSpread.bind(spreadNS.Events.EditStarting, ancGclObj.editStarting); ancGclSpread.bind(spreadNS.Events.EditEnded, ancGclObj.editEnded); ancGclSpread.bind(spreadNS.Events.ClipboardPasting, ancGclObj.clipboardPasting); ancGclSpread.bind(spreadNS.Events.ButtonClicked, ancGclObj.buttonClicked); $.contextMenu({ selector: '#anc-gcl-spread', build: function ($trigger, e) { const target = SpreadJsObj.safeRightClickSelection($trigger, e, ancGclSpread); return target.hitTestType === GC.Spread.Sheets.SheetArea.viewport || target.hitTestType === GC.Spread.Sheets.SheetArea.rowHeader; }, items: { 'insert': { name: '插入', icon: 'fa-plus', disabled: function (key, opt) { const node = SpreadJsObj.getSelectObject(ledgerSheet); return !node || !node.b_code || (node.children && node.children.length > 0); }, callback: function (key, opt) { ancGclObj.baseOpr('insert'); } }, 'delete': { name: '删除', icon: 'fa-remove', disabled: function (key, opt) { const gclData = SpreadJsObj.getSelectObject(ancGclSheet); return !gclData; }, callback: function (key, opt) { ancGclObj.baseOpr('delete'); } }, 'down-move': { name: '下移', icon: 'fa-arrow-down', disabled: function(key, opt) { const sel = ancGclSheet.getSelections()[0]; const row = sel ? sel.row : -1; const first = ancGclSheet.zh_data[row]; const next = ancGclSheet.zh_data[sel.row + sel.rowCount]; return !first || !next; }, callback: function(key, opt) { ancGclObj.baseOpr('down-move'); } }, 'up-move': { name: '上移', icon: 'fa-arrow-up', disabled: function(key, opt) { const sel = ancGclSheet.getSelections()[0]; const row = sel ? sel.row : -1; const first = ancGclSheet.zh_data[row]; const preNode = ancGclSheet.zh_data[row - 1]; return !first || !preNode; }, callback: function(key, opt) { ancGclObj.baseOpr('up-move'); } }, } }); $('#filter-anc-gcl').change(function() { if (this.checked) { const condition = {}; condition[this.getAttribute('name')] = parseInt(this.value); ancGcl.filter = condition; } else { ancGcl.filter = null; } ancGclObj.loadCurAncillaryGcl(); }); postData(window.location.pathname + '/load', {}, function (data) { ledgerTree.loadDatas(data.bills); treeCalc.calculateAll(ledgerTree); checkShowLast(data.bills.length); pos.loadDatas(data.pos); ancGcl.loadDatas(data.ancGcl); for (const t of data.tags) { t.node = ledgerTree.datas.find(x => { return x.id === t.lid; }); if (t.pos_id) { const posRange = pos.getLedgerPos(t.lid) || []; t.pos = posRange.find(x => { return x.id === t.pos_id; }); } } billsTag.loadDatas(data.tags); SpreadJsObj.loadSheetData(ledgerSpread.getActiveSheet(), 'tree', ledgerTree); SpreadJsObj.loadTopAndSelect(ledgerSpread.getActiveSheet(), ckBillsSpread); posOperationObj.loadCurPosData(); SpreadJsObj.resetTopAndSelect(posSpread.getActiveSheet()); ancGclObj.loadCurAncillaryGcl(); SpreadJsObj.resetTopAndSelect(ancGclSheet); treeOperationObj.refreshOperationValid(ledgerSpread.getActiveSheet()); treeOperationObj.loadExprToInput(ledgerSpread.getActiveSheet()); checkList.loadHisCheckData(); }, null, true); $.divResizer({ select: '#right-spr', callback: function () { ledgerSpread.refresh(); if (posSpread) posSpread.refresh(); if (ancGclSpread) ancGclSpread.refresh(); if (stdXmj) stdXmj.spread.refresh(); if (stdGcl) stdGcl.spread.refresh(); if (dealBills) dealBills.spread.refresh(); if (searchLedger) searchLedger.spread.refresh(); if (errorList) errorList.spread.refresh(); if (checkList) checkList.spread.refresh(); if (gclGather) gclGather.spread.refresh(); } }); const stdLibCellDoubleClick = function (updateData, stdNode) { if (!stdNode) return; const mainNode = SpreadJsObj.getSelectObject(ledgerSheet); if (!mainNode) return; if (updateData.postData.stdType === 'gcl') { if (!!mainNode.code && !ledgerTree.isLeafXmj(mainNode)) { toastr.warning('非最底层项目下,不应添加清单'); return; } } updateData.postData.id = ledgerTree.getNodeKey(mainNode); updateData.postData.tender_id = mainNode.tender_id; postData(window.location.pathname + '/update', updateData, function (result) { const sel = ledgerSheet.getSelections()[0]; const refreshNode = ledgerTree.loadPostData(result); treeOperationObj.refreshTree(ledgerSheet, refreshNode); if (refreshNode.create && refreshNode.create.length > 0) { ledgerSheet.setSelection(refreshNode.create[refreshNode.create.length - 1].index, sel.col, sel.rowCount, sel.colCount); const refreshRow = [sel.row, refreshNode.create[refreshNode.create.length - 1].index]; const curIndex = ledgerTree.nodes.indexOf(mainNode); if (sel.row !== curIndex && curIndex >= 0) refreshRow.push(curIndex); SpreadJsObj.reloadRowsBackColor(ledgerSheet, refreshRow); } else { const node = _.find(ledgerTree.nodes, {code: stdNode.code, name: stdNode.name}); if (node) { ledgerSheet.setSelection(ledgerTree.nodes.indexOf(node), sel.col, sel.rowCount, sel.colCount); SpreadJsObj.reloadRowsBackColor(ledgerSheet, [sel.row, ledgerTree.nodes.indexOf(node)]); } } treeOperationObj.refreshOperationValid(ledgerSheet); ledgerSpread.focus(); treeOperationObj.loadRelaData(); }); }; const stdXmjSetting = { selector: '#std-xmj', stdType: 'xmj', libs: stdChapters, treeSetting: { id: 'chapter_id', pid: 'pid', order: 'order', level: 'level', rootId: -1, keys: ['id', 'list_id', 'chapter_id'], }, spreadSetting: { cols: [ {title: '项目节编号', field: 'code', hAlign: 0, width: 120, formatter: '@', readOnly: true, cellType: 'tree'}, {title: '名称', field: 'name', hAlign: 0, width: 150, formatter: '@', readOnly: true}, {title: '单位', field: 'unit', hAlign: 1, width: 50, formatter: '@', readOnly: true} ], treeCol: 0, emptyRows: 0, headRows: 1, headRowHeight: [32], defaultRowHeight: 21, headerFont: '12px 微软雅黑', font: '12px 微软雅黑', headColWidth: [30], selectedBackColor: '#fffacd', }, cellDoubleClick: stdLibCellDoubleClick, page: 'ledger', tid: getTenderId(), }; const stdGclSetting = { selector: '#std-gcl', stdType: 'gcl', libs: stdBills, treeSetting: { id: 'bill_id', pid: 'pid', order: 'order', level: 'level', rootId: -1, keys: ['id', 'list_id', 'bill_id'] }, spreadSetting: { cols: [ {title: '清单编号', field: 'b_code', hAlign: 0, width: 120, formatter: '@', readOnly: true, cellType: 'tree'}, {title: '名称', field: 'name', hAlign: 0, width: 150, formatter: '@', readOnly: true}, {title: '单位', field: 'unit', hAlign: 1, width: 50, formatter: '@', readOnly: true} ], treeCol: 0, emptyRows: 0, headRows: 1, headRowHeight: [32], defaultRowHeight: 21, headerFont: '12px 微软雅黑', font: '12px 微软雅黑', headColWidth: [30], selectedBackColor: '#fffacd', }, cellDoubleClick: stdLibCellDoubleClick, page: 'ledger', tid: getTenderId(), showAddType: 1, }; // 展开收起标准清单 $('a', '#side-menu').bind('click', function (e) { e.preventDefault(); const tab = $(this), tabPanel = $(tab.attr('content')); // 展开工具栏、切换标签 if (!tab.hasClass('active')) { // const close = $('.active', '#side-menu').length === 0; $('a', '#side-menu').removeClass('active'); $('.tab-content .tab-select-show.tab-pane.active').removeClass('active'); tab.addClass('active'); tabPanel.addClass('active'); // $('.tab-content .tab-pane').removeClass('active'); showSideTools(tab.hasClass('active')); if (tab.attr('content') === '#std-xmj') { if (!stdXmj) { stdXmj = $.stdLib(stdXmjSetting); } stdXmj.spread.refresh(); } else if (tab.attr('content') === '#std-gcl') { if (!stdGcl) { stdGcl = $.stdLib(stdGclSetting); } stdGcl.spread.refresh(); } else if (tab.attr('content') === '#deal-bills') { if (!dealBills) { dealBills = new DealBills('#deal-bills-spread', { cols: [ {title: '清单编号', field: 'code', hAlign: 0, width: 85, formatter: '@'}, {title: '名称', field: 'name', hAlign: 0, width: 150, formatter: '@'}, {title: '单位', field: 'unit', hAlign: 1, width: 50, formatter: '@'}, {title: '单价', field: 'unit_price', hAlign: 2, width: 50}, {title: '数量', field: 'quantity', hAlign: 2, width: 50}, {title: '金额', field: 'total_price', hAlign: 2, width: 50, readOnly: true}, ], emptyRows: 3, headRows: 1, headRowHeight: [32], defaultRowHeight: 21, headerFont: '12px 微软雅黑', font: '12px 微软雅黑', headColWidth: [30], selectedBackColor: '#fffacd', readOnly: true, }); dealBills.loadData(); } dealBills.spread.refresh(); } else if (tab.attr('content') === '#search') { if (!searchLedger) { searchLedger = $.billsSearch({ selector: '#search', searchSpread: ledgerSpread, resultSpreadSetting: { cols: [ {title: '项目节编号', field: 'code', hAlign: 0, width: 90, formatter: '@'}, {title: '清单编号', field: 'b_code', hAlign: 0, width: 80, formatter: '@'}, {title: '名称', field: 'name', width: 150, hAlign: 0, formatter: '@'}, {title: '单位', field: 'unit', width: 50, hAlign: 1, formatter: '@'}, {title: '单价', field: 'unit_price', hAlign: 2, width: 50}, {title: '数量', field: 'quantity', hAlign: 2, width: 50}, {title: '部位', field: 'bw', hAlign: 2, width: 90}, ], emptyRows: 0, headRows: 1, headRowHeight: [32], headColWidth: [30], defaultRowHeight: 21, headerFont: '12px 微软雅黑', font: '12px 微软雅黑', selectedBackColor: '#fffacd', readOnly: true, }, afterLocated: function () { posOperationObj.loadCurPosData(); ancGclObj.loadCurAncillaryGcl(); }, calcSum: function (result) { const sum = { name: '合计' }; for (const r of result) { sum.quantity = ZhCalc.add(r.quantity, sum.quantity); } return sum; } }); } searchLedger.spread.refresh(); } else if (tab.attr('content') === '#bills-tag') { // do something } else if (tab.attr('content') === '#error-list') { errorList.spread.refresh(); } else if (tab.attr('content') === '#check-list') { checkList.spread.refresh(); } else if (tab.attr('content') === '#fujian') { $('#showAttachment').hide(); const node = SpreadJsObj.getSelectObject(ledgerSpread.getActiveSheet()); getNodeList(node.id); getAllList(); } else if (tab.attr('content') === '#gcl-gather') { gclGather.spread.refresh(); } } else { // 收起工具栏 tab.removeClass('active'); tabPanel.removeClass('active'); showSideTools(tab.hasClass('active')); } ledgerSpread.refresh(); if (posSpread) { posSpread.refresh(); } if (ancGclSpread) ancGclSpread.refresh(); }); class DealBills { constructor (selector, spreadSetting) { const self = this; this.obj = $(selector)[0]; this.url = '/tender/' + getTenderId() + '/deal'; this.spreadSetting = spreadSetting; this.spread = SpreadJsObj.createNewSpread(this.obj); this.sheet = this.spread.getActiveSheet(); SpreadJsObj.initSheet(this.spread.getActiveSheet(), this.spreadSetting); this.OprObj = { /** * 删除按钮响应事件 * @param sheet */ deletePress: function (sheet) { if (!sheet.zh_setting || sheet.zh_setting.readOnly) return; const sortData = sheet.zh_data; const datas = []; const sels = sheet.getSelections(); if (!sels || !sels[0]) return; for (let iRow = sels[0].row; iRow < sels[0].row + sels[0].rowCount; iRow++) { let bDel = false; const node = sortData[iRow]; if (node) { const data = {id: node.id}; for (let iCol = sels[0].col; iCol < sels[0].col + sels[0].colCount; iCol++) { const colSetting = sheet.zh_setting.cols[iCol]; if (colSetting.field === 'code') { toastr.error('清单编号不能为空,如需删除签约清单请使用右键删除'); return; } const style = sheet.getStyle(iRow, iCol); if (!style.locked) { const colSetting = sheet.zh_setting.cols[iCol]; data[colSetting.field] = null; bDel = true; } } if (bDel) { datas.push(data); } } } if (datas.length > 0) { postData(self.url + '/update', {update: datas}, function (result) { self.loadUpdateData(result); SpreadJsObj.reLoadSheetData(sheet); }, function () { SpreadJsObj.reLoadSheetData(sheet); }); } }, delete: function (sheet) { if (!sheet.zh_setting || sheet.zh_setting.readOnly) return; const sortData = sheet.zh_data; const datas = []; const sels = sheet.getSelections(); if (!sels || !sels[0]) return; for (let iRow = sels[0].row, iLen = sels[0].row + sels[0].rowCount; iRow < iLen; iRow++) { const node = sortData[iRow]; datas.push(node.id); } if (datas.length > 0) { postData(self.url + '/update', {del: datas}, function (result) { self.loadUpdateData(result); SpreadJsObj.reLoadSheetData(sheet); }, function () { SpreadJsObj.reLoadSheetData(sheet); }); } }, editEnded: function (e, info) { if (!info.sheet.zh_setting || !info.sheet.zh_data || info.sheet.zh_setting.readOnly) return; const node = info.sheet.zh_data[info.row]; const col = info.sheet.zh_setting.cols[info.col]; const data = {}; if (node) { data.update = {}; data.update.id = node.id; const oldValue = node ? node[col.field] : null; const newValue = trimInvalidChar(info.editingText); if (oldValue == info.editingText || ((!oldValue || oldValue === '') && (newValue === ''))) { SpreadJsObj.reLoadRowData(info.sheet, info.row); return; } data.update[col.field] = newValue; } else { if (col.field !== 'code') { toastr.warning('新增签约清单,请先输入清单编号'); SpreadJsObj.reLoadRowData(info.sheet, info.row); return; } data.add = {}; data.add.order = info.row + 1; data.add.code = trimInvalidChar(info.editingText); } postData(self.url + '/update', data, function (result) { self.loadUpdateData(result); SpreadJsObj.reLoadSheetData(info.sheet); }, function () { SpreadJsObj.reLoadRowData(info.sheet, info.row); }); }, clipboardPasting(e, info) { const setting = info.sheet.zh_setting, sortData = info.sheet.zh_data; info.cancel = true; if (!setting || !sortData || setting.readOnly) return; const pasteData = info.pasteData.html ? SpreadJsObj.analysisPasteHtml(info.pasteData.html) : (info.pasteData.text === '' ? SpreadJsObj.Clipboard.getAnalysisPasteText() : SpreadJsObj.analysisPasteText(info.pasteData.text)); const hint = { code: {type: 'warning', msg: '签约清单编号不可为空,已过滤'}, unit_price: {type: 'warning', msg: '输入的 单价 非法,已过滤'}, quantity: {type: 'warning', msg: '输入的 数量 非法,已过滤'}, }; const uDatas = [], iDatas = []; for (let iRow = 0; iRow < info.cellRange.rowCount; iRow++) { const curRow = info.cellRange.row + iRow; const node = sortData[curRow]; let bPaste = false; const data = {}; for (let iCol = 0; iCol < info.cellRange.colCount; iCol++) { const curCol = info.cellRange.col + iCol; const colSetting = setting.cols[curCol]; const value = trimInvalidChar(pasteData[iRow][iCol]); if (colSetting.field === 'code' && (!value || value === '')) { toastMessageUniq(hint.code); break; } if (colSetting.type === 'Number') { const num = _.toNumber(value); if (num) { data[colSetting.field] = num; bPaste = true; } else if (colSetting.field === 'unit_price') { toastMessageUniq(hint.unit_price); } else if (colSetting.field === 'quantity') { toastMessageUniq(hint.quantity); } } else { data[colSetting.field] = value; bPaste = true; } } if (bPaste) { if (node) { data.id = node.id; uDatas.push(data); } else { data.order = curRow + 1; iDatas.push(data); } } } const updateData = {}; if (uDatas.length > 0) updateData.update = uDatas; if (iDatas.length > 0) updateData.add = iDatas; if (uDatas.length > 0 || iDatas.length > 0) { postData(self.url + '/update', updateData, function (result) { self.loadUpdateData(result); SpreadJsObj.reLoadSheetData(info.sheet); }); } else { SpreadJsObj.reLoadSheetData(info.sheet); } }, }; if (!readOnly) { this.spread.bind(spreadNS.Events.CellDoubleClick, function (e, info) { const dealSheet = info.sheet; if (!dealSheet.zh_setting.readOnly) return; const mainSheet = ledgerSpread.getActiveSheet(); const dealBills = SpreadJsObj.getSelectObject(dealSheet); if (!dealBills) { return; } const mainTree = mainSheet.zh_tree; const mainNode = SpreadJsObj.getSelectObject(mainSheet); if (!mainNode || !mainTree) { return; } if (mainNode.code && mainNode.code !== '' && !mainTree.isLeafXmj(mainNode)) { toastr.error('非最底层项目下,不应添加清单'); return; } postData(window.location.pathname + '/update', { postType: 'add-deal', postData: { id: mainNode.ledger_id, type: mainNode.code ? 'child' : 'next', dealBills: { b_code: dealBills.code, name: dealBills.name, unit: dealBills.unit, unit_price: dealBills.unit_price, } }, }, function (result) { const refreshData = mainTree.loadPostData(result); treeOperationObj.refreshTree(mainSheet, refreshData); const sel = mainSheet.getSelections()[0]; mainSheet.setSelection(refreshData.create[0].index, sel.col, sel.rowCount, sel.colCount); SpreadJsObj.reloadRowsBackColor(mainSheet, [sel.row, refreshData.create[0].index]); treeOperationObj.refreshOperationValid(mainSheet); ledgerSpread.focus(); posOperationObj.loadCurPosData(); ancGclObj.loadCurAncillaryGcl(); }); }); } const dealBillsPermission = $('[href="#upload-deal"]').length > 0; if (!readOnly || dealBillsPermission) { this.spread.bind(spreadNS.Events.EditEnded, this.OprObj.editEnded); this.spread.bind(spreadNS.Events.ClipboardPasting, this.OprObj.clipboardPasting); SpreadJsObj.addDeleteBind(this.spread, this.OprObj.deletePress); $.contextMenu({ selector: selector, build: function ($trigger, e) { const target = SpreadJsObj.safeRightClickSelection($trigger, e, self.spread); return target.hitTestType === spreadNS.SheetArea.viewport || target.hitTestType === spreadNS.SheetArea.rowHeader; }, items: { edit: { name: '进入编辑模式', icon: 'fa-edit', visible: function (key, opt) { return self.sheet.zh_setting.readOnly; }, callback: function (key, opt) { self.sheet.zh_setting.readOnly = false; SpreadJsObj.refreshSheetReadOnly(self.sheet); }, }, read: { name: '退出编辑模式', icon: 'fa-sign-out', visible: function (key, opt) { return !self.sheet.zh_setting.readOnly; }, callback: function (key, opt) { self.sheet.zh_setting.readOnly = true; SpreadJsObj.refreshSheetReadOnly(self.sheet); }, }, del: { name: '删除', icon: 'fa-times', visible: function (key, opt) { return !self.sheet.zh_setting.readOnly; }, disabled: function (key, opt) { const select = SpreadJsObj.getSelectObject(self.sheet); return !select; }, callback: function (key, opt) { self.OprObj.delete(self.sheet); }, }, sprEdit: '----', apply: { name: '应用全部清单单价至台账', icon: 'fa-magic', disabled: function (key, opt) { const sheet = self.spread.getActiveSheet(); return sheet.getRowCount() === 0 || readOnly; }, callback: function (key, opt) { const datas = [], sourceData = self.spread.getActiveSheet().zh_data; for (const db of sourceData) { const targets = ledgerTree.nodes.filter(function (x) { return x.b_code === db.code && x.name === db.name && x.unit === db.unit; }); for (const t of targets) { if (t.children && t.children.length > 0) continue; const data = ledgerTree.getNodeKeyData(t); data.unit_price = db.unit_price; datas.push(data); } } if (datas.length > 0) { doAfterHint({ fun: function() { postData(window.location.pathname + '/update', {postType: 'update', postData: datas}, function (result) { const refreshNode = ledgerTree.loadPostData(result); treeOperationObj.refreshTree(ledgerSpread.getActiveSheet(), refreshNode); }); }, hint: '此操作会替换台账里所有同编号、名称、单位的清单,请谨慎操作', }); } else { toastr.warning('没有可应用的清单。'); } }, } } }); } $('#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) { self.data = data; SpreadJsObj.loadSheetData(self.spread.getActiveSheet(), 'data', data); $('#upload-deal').modal('hide'); }, function () { $('#upload-deal').modal('hide'); }); }); this.initDealBillsSearch(); } search(keyword) { this.searchResult = []; this.searchCur = 0; if (keyword) { for (const [i, d] of this.data.entries()) { if (d.code.indexOf(keyword) >= 0 || d.name.indexOf(keyword) >= 0) this.searchResult.push(d); } } $('#dbs-count').html(`结果:${this.searchResult.length}`); if (this.searchResult.length > 0) SpreadJsObj.locateData(this.sheet, this.searchResult[0]); } searchPre() { this.searchCur = this.searchCur - 1; if (this.searchCur < 0) this.searchCur = this.searchResult.length - 1; SpreadJsObj.locateData(this.sheet, this.searchResult[this.searchCur]); } searchNext() { this.searchCur = this.searchCur + 1; if (this.searchCur >= this.searchResult.length) this.searchCur = 0; SpreadJsObj.locateData(this.sheet, this.searchResult[this.searchCur]); } searchClear() { $('#dbs-keyword').val(''); this.searchResult = []; this.searchCur = 0; $('#dbs-count').html(`结果:${this.searchResult.length}`); } initDealBillsSearch() { const self = this; $('#dbs-keyword').change(function () { self.search(this.value); }); $('#dbs-pre').click(function (e) { self.searchPre(); e.stopPropagation(); }); $('#dbs-next').click(function (e) { self.searchNext(); e.stopPropagation(); }); $('#dbs-clear').click(function (e) { self.searchClear(); e.stopPropagation(); }); } loadData () { const self = this; postData(this.url+'/get-data', {}, function (data) { self.data = data; SpreadJsObj.loadSheetData(self.spread.getActiveSheet(), 'data', data); if (data.length > 0) self.spread.getActiveSheet().setSelection(0, 0, 1, 1); }); } calculateData () { if (this.data) { for (const d of this.data) { d.total_price = _.multiply(d.quantity, d.unit_price); } } } loadUpdateData(updateData) { if (updateData.add) { for (const a of updateData.add) { this.data.push(a); } } if (updateData.update) { for (const u of updateData.update) { const d = this.data.find(function (x) { return u.id === x.id; }); if (d) { _.assign(d, u); } else { this.data.push(d); } } } if (updateData.del) { _.remove(this.data, function (d) { return updateData.del.indexOf(d.id) >= 0; }); } } } class BatchInsertBillsPosObj { constructor (obj) { const self = this; this.obj = obj; this.billsCount = 6; this.posCount = 1000; this.filter = getLocalCache('zh-calc-batch-filter'); if (!this.filter) { this.filter = '1'; } $('input[name=batch-filter]')[0].checked = this.filter && this.filter != '0'; // 初始化 清单编号窗口 参数 this.qdSpreadSetting = { cols: [ {title: '编号', field: 'code', hAlign: 0, width: 80, formatter: '@'}, {title: '名称', field: 'name', hAlign: 0, width: 120, formatter: '@'}, {title: '单位', field: 'unit', hAlign: 1, width: 50, formatter: '@'}, {title: '单价', field: 'unit_price', hAlign: 2, width: 50}, {title: '图册号', field: 'name', hAlign: 0, width: 60, formatter: '@'}, ], emptyRows: this.billsCount, headRows: 1, headRowHeight: [32], headerFont: '12px 微软雅黑', font: '12px 微软雅黑', }; this.qdSpread = SpreadJsObj.createNewSpread($('.batch-l-t', this.obj)[0]); // 初始化 部位数量复核表 参数 this.posSpreadSetting = { cols: [ {title: '计量单元', field: 'bw', hAlign: 0, width: 80, formatter: '@'}, {title: '图册号', field: 'drawingCode', hAlign: 0, formatter: '@', width: 60}, ], emptyRows: this.posCount, headRows: 1, headRowHeight: [32], headerFont: '12px 微软雅黑', font: '12px 微软雅黑', }; for (let iNum = 1; iNum <= this.billsCount; iNum++) { this.posSpreadSetting.cols.push( {title: '清单' + iNum, field: 'bills' + iNum, hAlign: 2, width: 50} ) } this.posSpread = SpreadJsObj.createNewSpread($('.batch-l-b', this.obj)[0]); // 初始化 签约清单 参数 this.dealSpreadSetting = { cols: [ {title: '清单编号', field: 'code', width: 80, hAlign: 0, formatter: '@', readOnly: true}, {title: '名称', field: 'name', width: 230, hAlign: 0, formatter: '@', readOnly: true}, {title: '单位', field: 'unit', hAlign: 1, width: 50, formatter: '@', readOnly: true}, {title: '单价', field: 'unit_price', hAlign: 2, width: 60, readOnly: true}, ], emptyRows: 0, headRows: 1, headRowHeight: [32], headerFont: '12px 微软雅黑', font: '12px 微软雅黑', }; this.dealSpread = SpreadJsObj.createNewSpread($('.batch-r', this.obj)[0]); this.dealSheet = this.dealSpread.getActiveSheet(); // 初始化 清单编号、部位数量复核表 表格 this.initView(); SpreadJsObj.initSheet(this.dealSpread.getActiveSheet(), this.dealSpreadSetting); SpreadJsObj.refreshColumnAlign(this.dealSpread.getActiveSheet()); $.contextMenu({ selector: '.batch-l-t', build: function ($trigger, e) { const target = SpreadJsObj.safeRightClickSelection($trigger, e, self.qdSpread); return target.hitTestType === spreadNS.SheetArea.viewport || target.hitTestType === spreadNS.SheetArea.rowHeader; }, items: { 'create': { name: '新增行', icon: 'fa-sign-in', callback: function (key, opt) { const qdSheet = self.qdSpread.getActiveSheet(); const posSheet = self.posSpread.getActiveSheet(); qdSheet.addRows(qdSheet.getRowCount(), 1); const index = qdSheet.getRowCount(); qdSheet.getCell(qdSheet.getRowCount() - 1, 0, spreadNS.SheetArea.rowHeader).text('清单' + index); posSheet.addColumns(posSheet.getColumnCount(), 1); posSheet.getCell(0, index + 2 - 1, spreadNS.SheetArea.colHeader).text('清单' + index); }, }, 'delete': { name: '删除行', icon: 'fa-remove', callback: function (key, opt) { const qdSheet = self.qdSpread.getActiveSheet(); const posSheet = self.posSpread.getActiveSheet(); const sel = qdSheet.getSelections()[0]; qdSheet.deleteRows(sel.row, sel.rowCount); posSheet.deleteColumns(sel.row + 2, sel.rowCount); for (let iRow = 0, iLen = qdSheet.getRowCount(); iRow < iLen; iRow++) { qdSheet.getCell(iRow, 0, spreadNS.SheetArea.rowHeader).text('清单' + (iRow+1)); } for (let iCol = 0, iLen = posSheet.getColumnCount() - 2; iCol < iLen; iCol++) { posSheet.getCell(0, iCol + 2, spreadNS.SheetArea.colHeader).text('清单' + (iCol+1)); } qdSheet.setSelection(sel.row, sel.col, 1, 1); }, } } }); // 拉取签约清单数据 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(spreadNS.Events.CellDoubleClick, function (e, info) { const deal = info.sheet.zh_data[info.row]; const qdSheet = self.qdSpread.getActiveSheet(), posSheet = self.posSpread.getActiveSheet(); const sel = qdSheet.getSelections()[0]; qdSheet.getCell(sel.row, 0).value(deal.code); qdSheet.getCell(sel.row, 1).value(deal.name); qdSheet.getCell(sel.row, 2).value(deal.unit); qdSheet.getCell(sel.row, 3).value(deal.unit_price); if (sel.row + 1 === qdSheet.getRowCount()) { const count = sel.row + 2; qdSheet.setRowCount(count); qdSheet.getCell(sel.row + 1, 0, GC.Spread.Sheets.SheetArea.rowHeader).text('清单' + count); const colCount = posSheet.getColumnCount() + 1 posSheet.setColumnCount(colCount); posSheet.getCell(0, colCount - 1, GC.Spread.Sheets.SheetArea.colHeader).text('清单' + count); } qdSheet.setSelection(sel.row + 1, sel.col, 1, 1); }); this.qdSpread.bind(spreadNS.Events.ClipboardPasting, function (e, info) { info.cancel = true; const transpose = $('[name=batch-transpose]')[0].checked; const pasteData = SpreadJsObj.analysisPasteText(info.pasteData.text, transpose); const billsSheet = info.sheet, posSheet = self.posSpread.getActiveSheet(); const billsCount = info.sheet.getRowCount(), finalCount = info.cellRange.row + pasteData.length + 1; SpreadJsObj.beginMassOperation(billsSheet); if (finalCount > billsCount) { billsSheet.setRowCount(finalCount); posSheet.setColumnCount(finalCount + 2); for (let i = billsCount - 1; i <= finalCount; i++) { billsSheet.getCell(i - 1, 0, spreadNS.SheetArea.rowHeader).text('清单' + i); posSheet.getCell(0, i + 2 - 1, spreadNS.SheetArea.colHeader).text('清单' + i); } } for (let iRow = 0; iRow < pasteData.length; iRow++) { const curRow = iRow + info.cellRange.row; pasteData[iRow].forEach((value, iCol) => { billsSheet.getCell(curRow, iCol + info.cellRange.col).value(value); }); if ([0, 1].indexOf(info.cellRange.col) >= 0) { const dealBills = self.dealSpread.getActiveSheet().zh_data; const bills = _.find(dealBills, {code: billsSheet.getText(curRow, 0)}); if (bills) { billsSheet.getCell(curRow, 1).value(bills.name); billsSheet.getCell(curRow, 2).value(bills.unit); billsSheet.getCell(curRow, 3).value(bills.unit_price); } } } SpreadJsObj.endMassOperation(billsSheet); }); this.posSpread.bind(spreadNS.Events.ClipboardPasted, function (e, info) { const billsCount = info.sheet.getColumnCount() - 2, qdSheet = self.qdSpread.getActiveSheet(); const count = qdSheet.getRowCount(); if (billsCount > count) { qdSheet.setRowCount(billsCount); for (let i = count + 1; i <= billsCount; i++) { qdSheet.getCell(i - 1, 0, spreadNS.SheetArea.rowHeader).text('清单' + i); info.sheet.getCell(0, i + 2 - 1, spreadNS.SheetArea.colHeader).text('清单' + i); } } }); this.qdSpread.bind(spreadNS.Events.EditEnded, function (e, info) { if (info.col === 0) { const dealBills = self.dealSpread.getActiveSheet().zh_data; if (dealBills && dealBills.length > 0) { const bills = _.find(dealBills, {code: info.editingText}); if (bills) { info.sheet.getCell(info.row, 1).value(bills.name); info.sheet.getCell(info.row, 2).value(bills.unit); info.sheet.getCell(info.row, 3).value(bills.unit_price); } } } }); 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 sel = sheet.getSelections()[0]; const row = sel.row; const select = ledgerTree.nodes[row]; if (select) { const insertData = {}; insertData.batchType = (select.code && select.code !== '') ? 'child' : 'next'; insertData.id = ledgerTree.getNodeKey(select); insertData.batchData = self.getBatchData(); if (insertData.batchData.length > 0) { postData(window.location.pathname + '/update', {postType: 'batch-insert', postData: insertData}, function (data) { pos.updateDatas(data.pos); const result = ledgerTree.loadPostData(data.ledger); treeOperationObj.refreshTree(sheet, result); sheet.setSelection(result.create[0].index, sel.col, sel.rowCount, sel.colCount); SpreadJsObj.reloadRowsBackColor(sheet, [sel.row, result.create[0].index]); treeOperationObj.refreshOperationValid(sheet); posOperationObj.loadCurPosData(); ancGclObj.loadCurAncillaryGcl(); self.obj.modal('hide'); }, null, true); } else { self.obj.modal('hide'); } } }); $('input[name=batch-filter]').change(function () { setLocalCache('zh-calc-batch-filter', this.checked ? 1 : 0); }); this.initDealBillsSearch(); } search(keyword) { this.searchResult = []; this.searchCur = 0; if (keyword) { for (const [i, d] of this.dealSheet.zh_data.entries()) { if (d.code.indexOf(keyword) >= 0 || d.name.indexOf(keyword) >= 0) this.searchResult.push(d); } } $('#batch-dbs-count').html(`结果:${this.searchResult.length}`); if (this.searchResult.length > 0) SpreadJsObj.locateData(this.dealSheet, this.searchResult[0]); } searchPre() { this.searchCur = this.searchCur - 1; if (this.searchCur < 0) this.searchCur = this.searchResult.length - 1; SpreadJsObj.locateData(this.dealSheet, this.searchResult[this.searchCur]); } searchNext() { this.searchCur = this.searchCur + 1; if (this.searchCur >= this.searchResult.length) this.searchCur = 0; SpreadJsObj.locateData(this.dealSheet, this.searchResult[this.searchCur]); } initDealBillsSearch() { const self = this; $('#batch-dbs-keyword').change(function () { self.search(this.value); }); $('#batch-dbs-pre').click(function (e) { self.searchPre(); e.stopPropagation(); }); $('#batch-dbs-next').click(function (e) { self.searchNext(); e.stopPropagation(); }); } // 初始化左侧表格 initView () { // 初始化 清单编号 const qdSheet = this.qdSpread.getActiveSheet(); qdSheet.setColumnWidth(0, 45, spreadNS.SheetArea.rowHeader); SpreadJsObj.initSheet(qdSheet, this.qdSpreadSetting); SpreadJsObj.refreshColumnAlign(qdSheet); // 清理原有数据 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); } qdSheet.setSelection(0, 0, 1 ,1); SpreadJsObj.endMassOperation(qdSheet); // 初始化 部位数量复核表 const posSheet = this.posSpread.getActiveSheet(); SpreadJsObj.initSheet(posSheet, this.posSpreadSetting); SpreadJsObj.refreshColumnAlign(posSheet); // 清理原有数据 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); posSheet.setSelection(0, 0, 1 ,1); SpreadJsObj.endMassOperation(posSheet); this.dealSpread.getActiveSheet().setSelection(0, 0, 1, 1); } // 获取界面数据 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: [], }; 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, porder: qd.pos.length + 1, }); } } if (!$('input[name=batch-filter]')[0].checked || qd.pos.length > 0) result.push(qd); } return result; } } class ContractExpr { constructor(setting) { const self = this; this.obj = $('#contract_expr'); this.exprObj = $('#ce-expr'); this.exprSpread = SpreadJsObj.createNewSpread($('#expr_spread')[0]); this.exprSheet = this.exprSpread.getActiveSheet(); const exprSpreadSetting = { cols: [ { title: '项目节编号', colSpan: '1', rowSpan: '2', field: 'code', hAlign: 0, width: 180, formatter: '@', cellType: 'tree' }, { title: '清单编号', colSpan: '1', rowSpan: '2', field: 'b_code', hAlign: 0, width: 100, formatter: '@' }, { title: '名称', colSpan: '1', rowSpan: '2', field: 'name', hAlign: 0, width: 230, formatter: '@' }, { title: '单位', colSpan: '1', rowSpan: '2', field: 'unit', hAlign: 1, width: 60, formatter: '@', cellType: 'unit' }, ], emptyRows: 0, headRows: 2, headRowHeight: [25, 25], defaultRowHeight: 21, headerFont: '12px 微软雅黑', font: '12px 微软雅黑', readOnly: true, getColor: function (sheet, data, row, col, defaultColor) { if (self.targetNode && data && data.id === self.targetNode.id) { return spreadColor.pay.expr_err; } if (self.invalidRows && self.invalidRows.indexOf(row + 1) >= 0) { return spreadColor.pay.yf_without; } else { return defaultColor; } } }; sjsSettingObj.setFxTreeStyle(exprSpreadSetting, sjsSettingObj.FxTreeStyle.jz); SpreadJsObj.initSheet(this.exprSheet, exprSpreadSetting); this.exprTree = createNewPathTree('ledger', { id: 'ledger_id', pid: 'ledger_pid', order: 'order', level: 'level', rootId: -1, keys: ['id', 'tender_id', 'ledger_id'], }); this.exprTree.loadDatas(setting.sourceTree.datas); SpreadJsObj.loadSheetData(this.exprSheet, SpreadJsObj.DataType.Tree, this.exprTree); // this.exprSpread.bind(spreadNS.Events.SelectionChanged, function(e, info) { // const select = SpreadJsObj.getSelectObject(info.sheet); // if (select && self.targetNode && select.id === self.targetNode.id) { // $('#select-row').html(''); // } else { // $('#select-row').html(`(${select.code || ''}${select.b_code || ''})`); // } // }); this.obj.bind('shown.bs.modal', function () { self.exprSpread.refresh(); }); $('td[exprValue]').dblclick(function() { const name = this.getAttribute('name'); let row; if (name === 'tr') { row = self.targetRow; } else { const node = SpreadJsObj.getSelectObject(self.exprSheet); if (node.id === self.targetNode.id) return; row = self.exprTree.nodes.indexOf(node) + 1; } if (self.invalidRows.indexOf(row) >= 0) return; self.exprObj.val(self.exprObj.val() + `<>`); }); $('#contract-expr-ok').click(function() { const exprStr = $('#ce-expr').val().toLowerCase(); if ((!exprStr && !self.orgExpr) || (exprStr === self.orgExpr)) { self.obj.modal('hide'); return; } const [valid, msg] = TreeExprCalc.checkExprValid(exprStr, self.invalidRows); if (!valid) { toastr.error(msg); return; } const expr = TreeExprCalc.exprStr2Expr(exprStr); if (expr.length > 500) { toastr.error('输入表达式过长'); return; } // $('#ce-expr-org').val(expr + ' ' + TreeExprCalc.expr2ExprStr(expr)); postData('expr/save', { calc_module: 'stage', calc_tag: 'contract', calc_id: self.targetNode.id, expr }, function() { self.targetNode.contract_expr = expr; self.obj.modal('hide'); }); }); this.initLedgerSearch(); this.initShowLevel(); TreeExprCalc.init({ tree: this.exprTree }); } search(keyword) { this.searchResult = []; this.searchCur = 0; if (keyword) { for (const [i, d] of this.exprSheet.zh_tree.nodes.entries()) { if (d.code && d.code.indexOf(keyword) >= 0) { this.searchResult.push(d); continue; } if (d.b_code && d.b_code.indexOf(keyword) >= 0) { this.searchResult.push(d); continue; } if (d.name && d.name.indexOf(keyword) >= 0) { this.searchResult.push(d); continue; } } } $('#expr_search_count').html(`结果:${this.searchResult.length}`); if (this.searchResult.length > 0) SpreadJsObj.locateTreeNode(this.exprSheet, this.searchResult[0].ledger_id); } searchPre() { this.searchCur = this.searchCur - 1; if (this.searchCur < 0) this.searchCur = this.searchResult.length - 1; SpreadJsObj.locateTreeNode(this.exprSheet, this.searchResult[this.searchCur].ledger_id); } searchNext() { this.searchCur = this.searchCur + 1; if (this.searchCur >= this.searchResult.length) this.searchCur = 0; SpreadJsObj.locateTreeNode(this.exprSheet, this.searchResult[this.searchCur].ledger_id); } initLedgerSearch() { const self = this; this.searchResult = []; this.searchCur = 0; $('#expr_search_count').html(`结果:${this.searchResult.length}`); $('#expr_search_keyword').change(function () { self.search(this.value); }); $('#expr_search_pre').click(function (e) { self.searchPre(); e.stopPropagation(); }); $('#expr_search_next').click(function (e) { self.searchNext(); e.stopPropagation(); }); } initShowLevel(){ // 显示层次 (function (select, sheet) { $(select).click(function () { const tag = $(this).attr('tag'); const tree = sheet.zh_tree; if (!tree) return; setTimeout(() => { showWaitingView(); switch (tag) { case "1": case "2": case "3": case "4": case "5": tree.expandByLevel(parseInt(tag)); SpreadJsObj.refreshTreeRowVisible(sheet); break; case "last": tree.expandByCustom(() => { return true; }); SpreadJsObj.refreshTreeRowVisible(sheet); break; case "leafXmj": tree.expandToLeafXmj(); SpreadJsObj.refreshTreeRowVisible(sheet); break; } closeWaitingView(); }, 100); }); })('a[name=ce-showLevel]', this.exprSheet); } async setTargetNode(node) { const self = this; this.targetNode = node; const relaNode = this.exprTree.getItems(node.ledger_id); this.invalidNode = this.exprTree.getAllParents(relaNode); this.invalidRows = this.invalidNode.map(x => { return self.exprTree.nodes.indexOf(x) + 1; }); this.targetRow = this.exprTree.nodes.indexOf(relaNode) + 1; if (node.contract_expr === undefined) { node.contract_expr = await postDataAsync('expr/load', {calc_module: 'stage', calc_tag: 'contract', calc_id: node.id}); } this.orgExpr = node.contract_expr; $('#ce-expr').val(TreeExprCalc.expr2ExprStr(this.orgExpr)); } initView(node) { this.orgExpr = ''; this.setTargetNode(node); $('#expr-hint').html(`${node.code || ''}${node.b_code || ''} ${node.name || ''}`); $('#target-row').html(`(${node.code || ''}${node.b_code || ''})`); SpreadJsObj.locateTreeNode(this.exprSheet, node.ledger_id); SpreadJsObj.reloadRowBackColor(this.exprSheet, 0, this.exprSheet.getRowCount()); this.exprSpread.refresh(); } } $('a', '#anc-gcl-nav').bind('click', function(e) { e.preventDefault(); const tab = $(this); const showSideTab = function (show) { const left = $('#pos-spread'), right = $('#pos-right'), parent = left.parent(); if (show) { right.show(); autoFlashHeight(); /** * right.show()后, parent被撑开成2倍left.height, 导致parent.width减少了10px * 第一次left.width调整后,parent的缩回left.height, 此时parent.width又增加了10px * 故需要通过最终的parent.width再计算一次left.width * * Q: 为什么不通过先计算left.width的宽度,以避免计算两次left.width? * A: 右侧工具栏不一定显示,当右侧工具栏显示过一次后,就必须使用parent和right来计算left.width * */ const percent = 100 - right.outerWidth() /parent.width() * 100; left.css('width', percent + '%'); } else { left.width(parent.width()); right.hide(); } }; if (!tab.hasClass('active')) { tab.addClass('active'); showSideTab(tab.hasClass('active')); } else { tab.removeClass('active'); showSideTab(tab.hasClass('active')); } if (posSpread) posSpread.refresh(); if (ancGclSpread) ancGclSpread.refresh(); }); $.divResizer({ select: '#pos-right-spr', callback: function () { if (posSpread) posSpread.refresh(); if (ancGclSpread) ancGclSpread.refresh(); } }); // $('#searchAccount').click(() => { // const data = { // keyword: $('#searchName').val(), // }; // postData('/search/user', data, (data) => { // const resultDiv = $('#searchResult'); // if (data) { // $('h5>span', resultDiv).text(data.name); // $('#addAuditor').attr('auditorId', data.id); // $('h6', resultDiv).text(data.role); // $('p', resultDiv).text(data.company); // resultDiv.show(); // } else { // toastr.info('未查询到该审核人'); // resultDiv.hide(); // } // }, () => { // $('#searchResult').hide(); // }); // }); // // 审批人分组选择 // $('#account_group').change(function () { // let account_html = ''; // for (const account of accountList) { // if (parseInt($(this).val()) === 0 || parseInt($(this).val()) === account.account_group) { // const role = account.role !== '' ? '(' + account.role + ')' : ''; // const company = account.company !== '' ? ' -' + account.company : ''; // account_html += ''; // } // } // $('#account_list').html(account_html); // }); let timer = null; let oldSearchVal = null; $('#gr-search').bind('input propertychange', function(e) { oldSearchVal = e.target.value timer && clearTimeout(timer) timer = setTimeout(() => { const newVal = $('#gr-search').val() let html = '' if (newVal && newVal === oldSearchVal) { accountList.filter(item => item && (item.name.indexOf(newVal) !== -1 || (item.mobile && item.mobile.indexOf(newVal) !== -1))).forEach(item => { html += `

${item.name}${item.mobile || ''}

${item.role || ''}
` }) $('.book-list').empty() $('.book-list').append(html) } else { if (!$('.acc-btn').length) { accountGroup.forEach((group, idx) => { if (!group) return html += `
${group.groupName}
` group.groupList.forEach(item => { html += `

${item.name}${item.mobile || ''}

${item.role || ''}
` }); html += '
' }) $('.book-list').empty() $('.book-list').append(html) } } }, 400); }); // 添加审批流程按钮逻辑 $('body').on('click', '.book-list dt', function () { const idx = $(this).find('.acc-btn').attr('data-groupid') const type = $(this).find('.acc-btn').attr('data-type') if (type === 'hide') { $(this).parent().find(`div[data-toggleid="${idx}"]`).show(() => { $(this).children().find('i').removeClass('fa-plus-square').addClass('fa-minus-square-o') $(this).find('.acc-btn').attr('data-type', 'show') }) } else { $(this).parent().find(`div[data-toggleid="${idx}"]`).hide(() => { $(this).children().find('i').removeClass('fa-minus-square-o').addClass('fa-plus-square') $(this).find('.acc-btn').attr('data-type', 'hide') }) } return false }); // 添加到审批流程中 $('#book-list').on('click', 'dd', function () { const auditorId = parseInt($(this).data('id')); if (!auditorId) return; postData('/tender/' + getTenderId() + '/ledger/audit/add', { auditorId }, (datas) => { const html = []; // 如果是重新上报,添加到重新上报列表中 const auditorshtml = []; for (const [index,data] of datas.entries()) { if (index !== 0) { html.push('
  • '); html.push(`
    ${index}
    `); html.push('
    '); for (const auditor of data) { html.push(`
    ${auditor.name} ${auditor.role}
    `); } html.push('
    '); html.push('
    '); if (data[0].audit_type !== auditType.key.common) { html.push(`${auditType.info[data[0].audit_type].long}`); } if (shenpi_status === shenpiConst.sp_status.sqspr || (shenpi_status === shenpiConst.sp_status.gdzs && index+1 !== datas.length)) { html.push('移除'); } html.push('
    '); html.push('
  • '); } auditorshtml.push('
  • '); auditorshtml.push(' '); auditorshtml.push(data.name + ' ' + data.role + ''); if (index === 0) { auditorshtml.push('原报'); } else if (index+1 === datas.length) { auditorshtml.push('终审'); } else { auditorshtml.push(''+ transFormToChinese(index) +'审'); } auditorshtml.push('
  • '); } $('#auditors').html(html.join('')); $('#auditors-list').html(auditorshtml.join('')); }); }); $('body').on('click', '#auditors li>div>a', function () { const li = $(this).parent().parent(); const data = { auditorId: parseInt(li.attr('auditorId')), }; postData('/tender/' + getTenderId() + '/ledger/audit/delete', data, (data2) => { li.remove(); for (const a of data2) { const aLi = $('li[auditorId=' + a.audit_id + ']'); $('div:first', aLi).text(a.audit_order); } // 如果是重新上报 // 令最后一个图标转换 $('#auditors-list li[data-auditorid="' + data.auditorId + '"]').remove(); if ($('#auditors-list li').length !== 0 && !$('#auditors-list li i').hasClass('fa-stop-circle')) { $('#auditors-list li').eq($('#auditors-list li').length-1).children('i') .removeClass('fa-chevron-circle-down').addClass('fa-stop-circle'); } // $('#auditors-list2 li[data-auditid="' + data.auditorId + '"]').remove(); // if ($('#auditors-list2 li').length !== 0 && !$('#auditors-list2 li i').hasClass('fa-stop-circle')) { // $('#auditors-list2 li').eq($('#auditors-list2 li').length-1).children('i') // .removeClass('fa-chevron-circle-down').addClass('fa-stop-circle'); // } for (let i = 0; i < $('#auditors-list li').length; i++) { $('#auditors-list li').eq(i).find('.pull-right').text(i === 0 ? '原报' : (i+1 === $('#auditors-list li').length ? '终' : transFormToChinese(i)) + '审') // $('#auditors-list2 li').eq(i).find('.pull-right').text((i+1 === $('#auditors-list2 li').length ? '终' : transFormToChinese(i+1)) + '审') } }); }); $('#hideSp').click(function () { $('#sp-list').modal('hide'); }); $('a[f-target]').click(function () { $($(this).attr('f-target')).modal('show'); }); // 多层modal关闭后的滚动bug修复 $('#sp-list').on('hidden.bs.modal', function (e) { $(document.body).addClass('modal-open'); }); // 管理员更改审批流程js部分 let timer2 = null; let oldSearchVal2 = null; $('body').on('input propertychange', '.gr-search', function(e) { oldSearchVal2 = e.target.value; timer2 && clearTimeout(timer2); timer2 = setTimeout(() => { const newVal = $(this).val(); const code = $(this).attr('data-code'); let html = ''; if (newVal && newVal === oldSearchVal2) { accountList.filter(item => item && (item.name.indexOf(newVal) !== -1 || (item.mobile && item.mobile.indexOf(newVal) !== -1))).forEach(item => { html += `

    ${item.name}${item.mobile || ''}

    ${item.role || ''}
    ` }); $('#' + code + '_dropdownMenu .book-list').empty(); $('#' + code + '_dropdownMenu .book-list').append(html); } else { if (!$('#' + code + '_dropdownMenu .acc-btn').length) { accountGroup.forEach((group, idx) => { if (!group) return; html += `
    ${group.groupName}
    `; group.groupList.forEach(item => { html += `

    ${item.name}${item.mobile || ''}

    ${item.role || ''}
    `; }); html += '
    '; }); $('#' + code + '_dropdownMenu .book-list').empty(); $('#' + code + '_dropdownMenu .book-list').append(html); } } }, 400); }); const getAdminEditShenpiListHtml = function(auditGroup) { const html = []; for (const [i, group] of auditGroup.entries()) { if (i === 0) continue; for (const [j, auditor] of group.entries()) { html.push(''); if (j === 0) { const auditTypeHtml = auditor.type === auditType.key.common ? '' : `${auditType.info[auditor.audit_type].short}`; html.push(`${i + '审'}${auditTypeHtml}`); } else { html.push(``); } html.push(` ${auditor.name} ${auditor.role}`); html.push(`${ auditor.status !== auditConst.status.uncheck ? auditConst.auditString[auditor.status] : '待审批' }`); html.push(''); if (auditor.status === auditConst.status.checking && j === group.length - 1) { html.push('', ``, makeSelectAudit(auditor.audit_id+'_add', auditor.audit_id, 'add'),'
    ', ''); } if (auditor.status === auditConst.status.uncheck) { if (j === group.length - 1) { html.push('', ``, makeSelectAudit(auditor.audit_id+'_add', auditor.audit_id, 'add'),'', ''); if (auditor.audit_type !== auditType.key.common) { html.push('', ``, makeSelectAudit(auditor.audit_id+'_add-sibling', auditor.audit_id, 'add-sibling'),'', ''); } } html.push('', ``, makeSelectAudit(auditor.audit_id+'_change', auditor.audit_id, 'change'),'', ''); html.push(` `); } html.push(''); html.push(''); } } return html.join(''); }; $('body').on('click', '#admin-edit-shenpi dl dd', function () { const id = parseInt($(this).attr('data-id')); if (!id) return; let this_aid = parseInt($(this).parents('.book-list').attr('data-aid')); let this_operate = $(this).parents('.book-list').attr('data-operate'); const user = _.find(accountList, function (item) { return item.id === id; }); const auditorIndex = _.findIndex(auditorList, { audit_id: id }); if (auditorIndex !== -1) { toastr.warning('该审核人已存在,请勿重复添加'); return; } const prop = { operate: this_operate, old_aid: this_aid, new_aid: user.id, }; postData('/tender/' + getTenderId() + '/ledger/audit/save', prop, (datas) => { auditorList = datas.auditors; $('#admin-edit-shenpi-list').html(getAdminEditShenpiListHtml(datas.auditorUniqs)); changeLiucheng(datas.auditorUniqs); }); }); // 移除审批人 $('body').on('click', '.remove-audit', function () { const id = parseInt($(this).attr('data-id')); const prop = { operate: 'del', old_aid: id, }; postData('/tender/' + getTenderId() + '/ledger/audit/save', prop, (datas) => { auditorList = datas.auditors; $('#admin-edit-shenpi-list').html(getAdminEditShenpiListHtml(datas.auditorUniqs)); changeLiucheng(datas.auditorUniqs); }); }); const getAuditTypeText = function (type) { if (type === auditType.key.common) return ''; return `${auditType.info[type].long}`; }; function changeLiucheng(datas) { const auditorshtml = []; let lastAuditorHtml = []; for (const [index,data] of datas.entries()) { auditorshtml.push('
  • '); if (index === 0) { auditorshtml.push(''); } else if (index+1 === datas.length) { auditorshtml.push(''); } else { auditorshtml.push(''); } auditorshtml.push(''); for (const u of data) { auditorshtml.push(`${u.name}`); } auditorshtml.push(''); auditorshtml.push('
    '); if (data[0].audit_type !== auditType.key.common) auditorshtml.push(`${auditType.info[data[0].audit_type].short}`); if (index === 0) { auditorshtml.push('原报'); } else if (index+1 === datas.length) { auditorshtml.push('终审'); } else { auditorshtml.push(''+ transFormToChinese(index) +'审'); } auditorshtml.push('
    '); auditorshtml.push('
  • '); if (data[0].status === auditConst.status.uncheck) { lastAuditorHtml.push('
  • '); if (index < datas.length - 1) { lastAuditorHtml.push('
    '); } lastAuditorHtml.push('
    '); lastAuditorHtml.push('
    '); lastAuditorHtml.push(`
    ${ index !== datas.length - 1 ? data[0].audit_order + '' : '终' }审 ${getAuditTypeText(data[0].audit_type)}
    `); lastAuditorHtml.push('
    '); for (const [i, auditor] of data.entries()) { lastAuditorHtml.push(`
    `); lastAuditorHtml.push(`
    ${auditor.name}${auditor.role}
    `); lastAuditorHtml.push('
    '); lastAuditorHtml.push('
    '); lastAuditorHtml.push('
    '); } lastAuditorHtml.push('
    '); lastAuditorHtml.push('
    '); lastAuditorHtml.push('
  • '); } } $('.last-auditor-list .is_uncheck').remove(); $('.last-auditor-list').append(lastAuditorHtml.join('')); $('.auditors-list').html(auditorshtml.join('')); } // 审批流程-选择审批人html 生成 function makeSelectAudit(code, aid, status) { let divhtml = ''; accountGroup.forEach((group, idx) => { let didivhtml = ''; if(group) { group.groupList.forEach(item => { didivhtml += '
    \n' + '

    ' + item.name + '' + item.mobile + '

    \n' + ' ' + item.role + '\n' + '
    \n'; }); divhtml += '
    ' + group.groupName + '
    \n' + '
    \n' + didivhtml + '
    \n'; } }); let html = '\n' + ' \n' + ' \n' + ' \n' + ' '; return html; } // 显示层次 (function (select, sheet) { $(select).click(function () { const tag = $(this).attr('tag'); const tree = sheet.zh_tree; if (!tree) return; setTimeout(() => { showWaitingView(); switch (tag) { case "1": case "2": case "3": case "4": case "5": tree.expandByLevel(parseInt(tag)); SpreadJsObj.refreshTreeRowVisible(sheet); break; case "last": tree.expandByCustom(() => { return true; }); SpreadJsObj.refreshTreeRowVisible(sheet); break; case "leafXmj": tree.expandToLeafXmj(); SpreadJsObj.refreshTreeRowVisible(sheet); break; } closeWaitingView(); }, 100); }); })('a[name=showLevel]', ledgerSpread.getActiveSheet()); // $('#exportLedger').click(function () { // const data = []; // const setting = { // header: ['项目节编号', '清单子目号', '部位明细', '名称', '单位', '清单数量', '设计数量1', '设计数量2', '单价', '合价', '图号', '备注'], // width: [100, 70, 70, 300, 60, 80, 80, 80, 80, 80, 100, 100], // hAlign: ['left', 'left', 'left', 'left','center', 'right', 'right', 'right', 'right', 'right', 'left', 'left'], // }; // for (const node of ledgerTree.nodes) { // data.push([node.code, node.b_code, '', node.name, node.unit, // node.quantity, node.dgn_qty1, node.dgn_qty2, node.unit_price, node.total_price, // node.drawing_code, node.memo // ]); // const posRange = pos.getLedgerPos(node.id); // if (posRange && posRange.length > 0) { // for (const [i, p] of posRange.entries()) { // data.push(['', '', (i + 1) + '', p.name, '', // p.quantity, '', '', '', '', // p.drawing_code, p.memo // ]); // } // } // } // // XLSXObj.exportXlsxSheet(setting, data, "台账分解.xlsx"); // }); $('#exportLedger').click(function () { const data = []; const setting = { cols: [ {title: '项目节编号', colSpan: '1', rowSpan: '1', field: 'code', hAlign: 0, width: 100, formatter: '@'}, {title: '清单子目号', colSpan: '1', rowSpan: '1', field: 'b_code', hAlign: 0, width: 70, formatter: '@'}, {title: '计量单元', colSpan: '1', rowSpan: '1', field: 'pos_code', hAlign: 1, width: 70, formatter: '@'}, {title: '名称', colSpan: '1', rowSpan: '1', field: 'name', hAlign: 0, width: 300, formatter: '@'}, {title: '单位', colSpan: '1', rowSpan: '1', field: 'unit', hAlign: 1, width: 60, formatter: '@'}, {title: '签约数量', colSpan: '1', rowSpan: '1', field: 'deal_qty', hAlign: 2, width: 80, type: 'Number'}, {title: '签约金额', colSpan: '1', rowSpan: '1', field: 'deal_tp', hAlign: 2, width: 80, type: 'Number'}, {title: '清单数量', colSpan: '1', rowSpan: '1', field: 'quantity', hAlign: 2, width: 80, type: 'Number'}, {title: '设计数量1', colSpan: '1', rowSpan: '1', field: 'dgn_qty1', hAlign: 2, width: 80, type: 'Number'}, {title: '设计数量2', colSpan: '1', rowSpan: '1', field: 'dgn_qty2', hAlign: 2, width: 80, type: 'Number'}, {title: '单价', colSpan: '1', rowSpan: '1', field: 'unit_price', hAlign: 2, width: 80, type: 'Number'}, {title: '合价', colSpan: '1', rowSpan: '1', field: 'total_price', hAlign: 2, width: 80, type: 'Number'}, {title: '图号', colSpan: '1', rowSpan: '1', field: 'drawing_code', hAlign: 0, width: 100, formatter: '@'}, {title: '备注', colSpan: '1', rowSpan: '1', field: 'memo', hAlign: 0, width: 100, formatter: '@'}, ], headRows: 1, headRowHeight: [32], defaultRowHeight: 21, headerFont: 'bold 10px 微软雅黑', font: '10px 微软雅黑' }; const hasCl = ledgerSpreadSetting.cols.find(x => { return x.field === 'sjcl_qty'}); const qtyF = hasCl ? 'quantity' : 'sgfh_qty'; const tpF = hasCl ? 'total_price' : 'sgfh_tp'; for (const node of ledgerTree.nodes) { data.push({ code: node.code, b_code: node.b_code, name: node.name, unit: node.unit, unit_price: node.unit_price, quantity: node[qtyF], total_price: node[tpF], deal_qty: node.deal_qty, deal_tp: node.deal_tp, dgn_qty1: node.dgn_qty1, dgn_qty2: node.dgn_qty2, drawing_code: node.drawing_code, memo: node.memo }); const posRange = pos.getLedgerPos(node.id); if (posRange && posRange.length > 0) { for (const [i, p] of posRange.entries()) { data.push({ pos_code: (i + 1) + '', name: p.name, quantity: p[qtyF], drawing_code: p.drawing_code, memo: p.memo }); } } } SpreadExcelObj.exportSimpleXlsxSheet(setting, data, "台账分解.xlsx"); }); $('#sync-ledger').click(function () { postData(syncLedgerUrl, {}, function (result) { ledgerTree.loadDatas(result.bills); treeCalc.calculateAll(ledgerTree); SpreadJsObj.loadSheetData(ledgerSpread.getActiveSheet(), 'tree', ledgerTree); pos.loadDatas(result.pos); posOperationObj.loadCurPosData(); ancGclObj.loadCurAncillaryGcl(); checkShowLast(result.bills.length); }); }); const dataChecker = DataChecker({ checkUrl: window.location.pathname + '/check', completeData: function (data) { pos.updateDatas({update: data.source.pos}); const loadResult = ledgerTree.loadPostData({update: data.source.bills}); treeOperationObj.refreshTree(ledgerSpread.getActiveSheet(), loadResult); posOperationObj.loadCurPosData(); ancGclObj.loadCurAncillaryGcl(); for (const e of data.error) { e.serialNo = ledgerTree.getNodeIndex(ledgerTree.getItems(e.ledger_id)) + 1; } }, errorList: errorList, }); $('[name=audit-start]').submit(function (e) { if (checkAuditorFrom()) { $(this).parent().parent().parent().modal('hide'); dataChecker.checkAndPost(this.action, {}); $('#hide-all').hide(); } return false; }); $('#ledger-check2').click(() => { ledgerCheck2({ ledgerTree: ledgerTree, ledgerPos: pos, checkList: checkList, decimal: tenderInfo.decimal, checkOption: checkOption, }).then(result => { check2Viewing({ extra: ZhCalc.div(ledgerTree.datas.length + pos.datas.length, 10000, 0), randomWait: true, prefix: 'check2-', checks: result, checkList: checkList, }); }); }); // 切换附件里节点和所有附件 $('#fujian .nav-link').on('click', function () { const tabPanel = $(this).attr('fujian-content'); if (tabPanel !== 'syfujian') { $('#showPage').hide(); $('#bach-download').prop('type', 'curr'); } else { $('#showPage').show(); $('#bach-download').prop('type', 'all'); } $('#showAttachment').hide(); }); // 上传附件 $('#upload-file-btn').click(function () { // if (curAuditor && curAuditor.aid !== cur_uid) { // return toastr.error('当前操作没有权限!'); // } const node = SpreadJsObj.getSelectObject(ledgerSpread.getActiveSheet()); if (!node) return; const files = $('#upload-file')[0].files; const formData = new FormData(); formData.append('lid', node.id); for (const file of files) { if (file === undefined) { toastr.error('未选择上传文件!'); return false; } const filesize = file.size; if (filesize > 30 * 1024 * 1024) { toastr.error('存在上传文件大小过大!'); return false; } const fileext = '.' + file.name.toLowerCase().split('.').splice(-1)[0]; if (whiteList && !whiteList.includes(fileext)) { toastr.error('只能上传指定格式的附件!'); return false; } formData.append('size', filesize); formData.append('file[]', file); } postDataWithFile('/tender/' + tender.id + '/ledger/upload/file', formData, function (data) { $('#upload').modal('hide'); // 插入到attData中 attData = data.concat(attData); // 重新生成List getAllList(); getNodeList(node.id); }, function () { toastr.error('附件上传失败'); }); $('#upload-file').val(''); }); // 获取附件信息 $('.list-table').on('click', '.att-file-name', function () { const fid = $(this).attr('file-id'); if ($('#showAttachment').attr('file-id') === fid && !$('#showAttachment').is(":hidden")) { return; } const att = attData.find(function (item) { return item.id === parseInt(fid); }); $('#edit-att').hide(); $('#show-att').show(); if (att !== undefined) { // 进来先把编辑功能隐藏 $('#btn-att a').eq(3).hide() $('#show-att tr').eq(0).children('td').text(att.filename + att.fileext); const name = att.code !== null && att.code !== '' ? att.code : (att.b_code !== null ? att.b_code : ''); $('#show-att tr').eq(1).children('td').text($.trim(name + ' ' + att.lname)); // $('#show-att tr').eq(2).find('a').attr('href', '/tender/' + tender.id + '/measure/stage/' + stage.order + '/download/file/' + att.id); // $('#show-att tr').eq(2).find('a').attr('href', att.filepath); $('#show-att tr').eq(2).children('td').eq(0).text(att.username); $('#show-att tr').eq(2).children('td').eq(1).text(att.in_time); $('#show-att tr').eq(3).children('td').text(att.remark); // 附件uid等于当前用户id, 附件上传本人 if (parseInt(cur_uid) === att.uid) { $('#btn-att').show(); const showDel = tender.ledger_status === auditConst.status.checked ? Boolean(att.extra_upload) : true; if (showDel) $('#btn-att a').eq(3).show(); // $('#btn-att a').eq(3).show(); $('#btn-att a').eq(2).hide(); $('#btn-att a').eq(4).hide(); $('#btn-att a').eq(5).hide(); } else { $('#btn-att').hide(); $('#btn-att a').eq(3).hide(); $('#btn-att a').eq(2).hide(); $('#btn-att a').eq(4).hide(); $('#btn-att a').eq(5).hide(); } $('#showAttachment').attr('file-id', fid); $('#showAttachment').show(); } else { $('#showAttachment').hide(); $('#showAttachment').attr('file-id', ''); toastr.error('附件信息获取失败'); } }); // $('body').on('click', '.alllist-table a', handleFileList); $('body').on('click', '#btn-att a', function () { const content = $(this).attr('content'); const fid = $('#showAttachment').attr('file-id'); const node = SpreadJsObj.getSelectObject(ledgerSpread.getActiveSheet()); if (content === 'edit') { $('#btn-att a').eq(3).hide(); $('#btn-att a').eq(2).show(); $('#btn-att a').eq(4).show(); $('#btn-att a').eq(5).show(); $('#show-att').hide(); $('#edit-att').show(); const att = attData.find(function (item) { return item.id === parseInt(fid); }); $('#edit-att .form-group').eq(0).find('input').val(att.filename); $('#edit-att .form-group').eq(0).find('span').eq(1).text(att.fileext); const name = att.code !== null && att.code !== '' ? att.code : (att.b_code !== null ? att.b_code : ''); $('#edit-att .form-group').eq(1).find('input').val($.trim(name + ' ' + att.lname)); $('#edit-att .form-group').eq(2).find('input').val(att.in_time); $('#edit-att .form-group').eq(3).find('input').val(att.remark); } else if (content === 'cancel') { $('#show-att').show(); $('#edit-att').hide(); $('#btn-att a').eq(3).show(); $('#btn-att a').eq(2).hide(); $('#btn-att a').eq(4).hide(); $('#btn-att a').eq(5).hide(); } else if (content === 'save') { const formData = new FormData(); formData.append('id', fid); formData.append('filename', $('#edit-att .form-group').eq(0).find('input').val()); formData.append('fileext', $('#edit-att .form-group').eq(0).find('span').eq(1).text()); formData.append('remark', $('#edit-att .form-group').eq(3).find('input').val()); const file = $('#change-att-btn')[0]; if (file.files[0] !== undefined) { const filesize = file.files[0].size; formData.append('size', filesize); formData.append('file', file.files[0]); } postDataWithFile('/tender/' + tender.id + '/ledger/save/file', formData, function (data) { // 替换到attData中 const att_index = attData.findIndex(function (item) { return item.id === parseInt(fid); }); attData.splice(att_index, 1, data); // 重新生成List getAllList(parseInt($('#currentPage').text())); getNodeList(node.id); $('#show-att').show(); $('#edit-att').hide(); $('#show-att tr').eq(0).children('td').text(data.filename + data.fileext); const name = data.code !== null && data.code !== '' ? data.code : (data.b_code !== null ? data.b_code : ''); $('#show-att tr').eq(1).children('td').text($.trim(name + ' ' + data.lname)); $('#show-att tr').eq(2).children('td').eq(0).text(data.username); $('#show-att tr').eq(2).children('td').eq(1).text(data.in_time); $('#show-att tr').eq(3).children('td').text(data.remark); $('#btn-att a').eq(3).show(); $('#btn-att a').eq(2).hide(); $('#btn-att a').eq(4).hide(); $('#btn-att a').eq(5).hide(); }, function () { toastr.error('附件上传失败'); }); $('#change-att-btn').val(''); } else if (content === 'del') { const data = {id: fid}; postData('/tender/' + tender.id + '/ledger/delete/file', data, function (result) { // 删除到attData中 const att_index = attData.findIndex(function (item) { return item.id === parseInt(fid); }); attData.splice(att_index, 1); // 重新生成List if ($('#alllist-table tr').length === 1) { getAllList(parseInt($('#currentPage').text()) - 1); } else { getAllList(parseInt($('#currentPage').text())); } getNodeList(node.id); $('#showAttachment').hide(); $('#showAttachment').attr('file-id', ''); }); } else if (content === 'view') { const data = {id: fid}; postData('/tender/' + tender.id + '/ledger/check/file', data, function (result) { const { filepath } = result $('#load-file').attr('href', filepath); $('#load-file')[0].click(); }); } else if (content === 'location') { const att = attData.find(item => item.id === parseInt(fid)); if (Object.keys(att).length) { SpreadJsObj.locateTreeNode(ledgerSpread.getActiveSheet(), att.ledger_id, true); posOperationObj.loadCurPosData(); ancGclObj.loadCurAncillaryGcl(); } } }); // 替换附件 $('#change-att-btn').on('change', function () { const file = $('#change-att-btn')[0].files[0]; const name = file.name; const filename = name.substring(0, name.lastIndexOf(".")); const fileext = name.substr(name.indexOf(".")); const filesize = file.size; if (filesize > 30 * 1024 * 1024) { toastr.error('文件大小过大!'); $('#change-att-btn').val(''); return false; } if (whiteList && !whiteList.includes(fileext)) { toastr.error('只能上传指定格式的附件!'); $('#change-att-btn').val(''); return false; } $('#edit-att .form-group').eq(0).find('input').val(filename); $('#edit-att .form-group').eq(0).find('span').eq(1).text(fileext); }); // 切换页数 $('.page-select').on('click', function () { const totalPageNum = parseInt($('#totalPage').text()); const lastPageNum = parseInt($('#currentPage').text()); const status = $(this).attr('content'); if (status === 'pre' && lastPageNum > 1) { getAllList(lastPageNum-1); $('#showAttachment').hide(); $('#syfujian .check-all-file').prop('checked', false) } else if (status === 'next' && lastPageNum < totalPageNum) { getAllList(lastPageNum+1); $('#showAttachment').hide(); $('#syfujian .check-all-file').prop('checked', false) } }); // 批量下载 $('#bach-download').click(function() { const fileIds = []; const type = $(this).attr('type'); let node = '' if (type === 'curr') { node = '#nodelist-table .check-file:checked' } else { node = '#alllist-table .check-file:checked' } $(node).each(function() { const fileId = $(this).attr('file-id'); fileId && fileIds.push(fileId); }); if (fileIds.length) { if (fileIds.length > 20) { return toastr.warning(`最大允许20个文件(当前${fileIds.length}个)`) } toastr.success('正在进行压缩文件...', '', { timeOut: 0, extendedTimeOut: 0}) $(this).attr('disabled', "true") const btn = $(this); const fileArr = []; for (const id of fileIds) { const fileInfo = _.find(currPageFileData, { id: parseInt(id) }); fileArr.push({ url: fileInfo.orginpath, //文件的oss存储路径 (必填) name: fileInfo.filename, // 文件名 (可选, 不需要填扩展名) foldPath: '' // (可选, 文件在压缩包中的存储路径) }); } const packageName = `${tender.name}-台账分解-附件.zip`; try { zipOss.downloadFromAliOss(fileArr, packageName, btn); } catch (e) { btn.removeAttr('disabled'); toastr.clear(); toastr.error('批量下载失败'); } // postCompressFile(`/tender/${tender.id}/ledger/compresse/file`, {fileIds}, function(result) { // toastr.clear() // toastr.success('压缩文件成功') // btn.removeAttr('disabled') // const href = window.URL.createObjectURL(result) // $('#zipDown').attr('href', href); // $('#zipDown').attr('download', `${tender.name}-台账分解-附件.zip`); // $("#zipDown")[0].click(); // }, () => { // btn.removeAttr('disabled') // toastr.clear() // toastr.error('批量下载失败') // }); // const url = `/tender/${tender.id}/ledger/compresse/file?fileIds=${JSON.stringify(fileIds)}`; } }); // 监听附件check是否选中 $('.list-table').on('click', '.check-file', function() { const checkedList = $(this).parents('.list-table').children().find('input:checked'); const childs = $(this).parents('.list-table').children().length; const checkBox = $(this).parents('.list-table').parent().find('.check-all-file'); if (checkedList.length === childs) { checkBox.prop("checked", true); } else { checkBox.prop("checked", false); } }); $('.check-all-file').click(function() { const isCheck = $(this).is(':checked'); $(this).parents('table').find('.list-table').each(function() { $(this).find('input:checkbox').prop("checked", isCheck); }) }); $('body').on('click', 'a[name=att-delete]', function() { const fid = this.getAttribute('file-id'); if (!fid) return; const node = SpreadJsObj.getSelectObject(ledgerSpread.getActiveSheet()); const data = {id: fid}; postData('/tender/' + tender.id + '/ledger/delete/file', data, function (result) { // 删除到attData中 const att_index = attData.findIndex(function (item) { return item.id === parseInt(fid); }); attData.splice(att_index, 1); // 重新生成List if ($('#alllist-table tr').length === 1) { getAllList(parseInt($('#currentPage').text()) - 1); } else { getAllList(parseInt($('#currentPage').text())); } getNodeList(node.id); $('#showAttachment').hide(); $('#showAttachment').attr('file-id', ''); }); }); $('#upload-ybp-file').click(function () { const file = $('#ybp-file')[0]; const formData = new FormData(); formData.append('file', file.files[0]); postDataWithFile('ledger/ybp', formData, function (result) { ledgerTree.loadDatas(result.bills); treeCalc.calculateAll(ledgerTree); SpreadJsObj.loadSheetData(ledgerSpread.getActiveSheet(), 'tree', ledgerTree); pos.loadDatas(result.pos); posOperationObj.loadCurPosData(); checkShowLast(result.bills.length); $('#upload-ybp').modal('hide'); }, function () { $('#upload-ybp').modal('hide'); }); }); $('#id-upload-ybp').click(function() { $('#import-dsk').modal('hide'); $('#upload-ybp').modal('show'); }); $('#id-post-dsk').click(async function() { if (await dsk.checkBind()) { $('#import-dsk').modal('hide'); dsk.chooseSubject({ validCheck: function (node, tree) { const checkType = node.type !== dsk.projectTypeKey.folder; if (!checkType) { toastr.warning('请勿选择文件夹'); return false; } const choosed = tree.datas.filter(x => { return !!x.selected; }); if (choosed.length === 0) return true; if (node.project_id !== choosed[0].project_id) { toastr.warning('请勿跨建设项目选择'); return false; } return true; }, callback: async function (subjects) { // console.log(await dsk.loadBills(subjects[0].compilationId, subjects[0].subjectId)); postData('ledger/dsk', {subjects}, function (result) { ledgerTree.loadDatas(result.bills); treeCalc.calculateAll(ledgerTree); SpreadJsObj.loadSheetData(ledgerSpread.getActiveSheet(), 'tree', ledgerTree); pos.loadDatas(result.pos); posOperationObj.loadCurPosData(); checkShowLast(result.bills.length); }); } }); } else { $('#binddskuser').modal('show'); } }); }); // 生成当前节点列表 function getNodeList(node) { let html = ''; for(const att of attData) { if (node === att.lid) { // html += ''+ att.filename + att.fileext +''+ att.username +''; const delHtml = deleteFilePermission && parseInt(cur_uid) === att.uid ? `` : ''; html += `
    ${att.filename}${att.fileext}
    ${delHtml}
    ${att.username}` } } $('#nodelist-table').html(html); $('#nodelist-table').on('click', 'tr', function() { $('#nodelist-table tr').removeClass('bg-light') $(this).addClass('bg-light') }) } // 生成所有附件列表 function getAllList(currPageNum = 1) { // 每页最多几个附件 const pageCount = 20; // 附件总数 const total = attData.length; // 总页数 const pageNum = Math.ceil(total/pageCount); $('#totalPage').text(pageNum); $('#currentPage').text(total === 0 ? 0 : currPageNum); // 当前页附件内容 const currPageAttData = attData.slice((currPageNum-1)*pageCount, currPageNum*pageCount); currPageFileData = currPageAttData; let html = ''; for(const att of currPageAttData) { const delHtml = deleteFilePermission && parseInt(cur_uid) === att.uid ? `` : ''; html += `
    ${att.filename}${att.fileext}
    ${delHtml}
    ${att.username}` } $('#alllist-table').html(html); $('#alllist-table').on('click', 'tr', function() { $('#alllist-table tr').removeClass('bg-light') $(this).addClass('bg-light') }) } // 检查上报情况 function checkAuditorFrom () { if ($('#auditors li').length === 0) { if(shenpi_status === shenpiConst.sp_status.gdspl) { toastr.error('请联系管理员添加审批人'); } else { toastr.error('请先选择审批人,再上报数据'); } return false; } else { $('#hide-all').show(); return true; } } // texterea换行 function auditCheck(i) { const opinion = $('textarea[name="opinion"]').eq(i).val().replace(/\r\n/g, '
    ').replace(/\n/g, '
    ').replace(/\s/g, ' '); $('textarea[name="opinion"]').eq(i).val(opinion); return true; }