'use strict'; const showSideTools = function (show) { const left = $('#left-view'), right = $('#right-view'), 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 * */ //left.css('width', parent.width() - right.outerWidth()); //left.css('width', parent.width() - right.outerWidth()); const percent = 100 - right.outerWidth() /parent.width() * 100; left.css('width', percent + '%'); } else { left.width(parent.width()); right.hide(); } }; $(document).ready(() => { autoFlashHeight(); const payUtils = { tips: { name: function(data) { const tips = []; if (data) { if (data.pause) tips.push('当前项已停用'); if (!data.is_yf) tips.push('当前项不参与本期应付计算'); } return tips.join('
'); }, range_tp: function (data) { if (!data || (!data.range_expr && !data.range_tp) || !data.dl_type) return ''; if (data.dl_type === 1) { return '计提期限为(当 计量期数 ≥ ' + data.dl_count + ')'; } else if (data.dl_type === 2) { switch (data.dl_tp_type) { case 'contract': return '计提期限为(累计合同计量 ≥ ' + data.dl_tp + ')'; case 'qc': return '计提期限为(累计变更计量 ≥ ' + data.dl_tp + ')'; case 'gather': return '计提期限为(累计完成计量 ≥ ' + data.dl_tp + ')'; } } } }, check: { isFixed: function(data) { return data.is_fixed; }, isStarted: function (data) { return data.pre_used; }, isYf: function(data) { return data.pay_type === 'bqyf'; }, isSf: function(data) { return data.pay_type === 'bqsf'; }, isGatherValid: function(data) { return !data.pay_type && (!data.children || data.children.length === 0); }, isOwner: function(data) { return data.create_user_id === userID; }, isFinish: function(data) { return data.pre_finish; }, isYB: function() { return userID === phasePay.create_user_id; }, isOld: function(data) { return data.phase_id !== data.create_phase_id; }, isLock: function (data) { const result = !!lockPayExpr && payUtils.check.isStarted(data) && payCalc.hasBase(data.expr); return result; }, tpReadOnly: function(data) { return payUtils.check.isYf(data) || payUtils.check.isLock(data); }, startTpReadOnly: function(data) { if (payUtils.check.isOld(data)) { return payUtils.check.isStarted(data) || !payUtils.check.isYB(data) || payUtils.check.isLock(data); } else { return payUtils.check.isWC(data) || payUtils.check.isSF(data) || payUtils.check.isYf(data) || !(payUtils.check.isOwner(data) || payUtils.check.isYB()); } } }, menuVisible: { pause: function (data) { if (payUtils.check.isOld(data)) { return payUtils.check.isYB(); } else { return payUtils.check.isOwner(data) || payUtils.check.isYB(); } }, deadline: function (data) { if (payUtils.check.isOld(data)) { return !payUtils.check.isFinish(data) && payUtils.check.isYB(); } else { return payUtils.check.isOwner(data) || payUtils.check.isYB(); } } }, }; const payCalc = (function (b, a) { class PayCalc { constructor (bases, add) { this.percentReg = /((\d+)|((\d+)(\.\d+)))%/g; this.bases = bases; this.bases.sort(function (a, b) { return a.sort - b.sort; }); for (const b of this.bases) { b.reg = new RegExp(b.code, 'igm'); } this.addBase = add; this.orderReg = /f\d+/ig; this.nodeReg = /<<[a-z0-9\-]+>>/ig; } hasBase(expr) { if (!expr) return false; for (const b of this.bases) { if (data.expr.indexOf(b.code) >= 0) return true; } return false; } trans2OrderExpr(expr, payTree) { const nodeParam = expr.match(this.nodeReg); if (nodeParam) { for (const op of nodeParam) { const id = op.substring(2, op.length - 2); const payNode = payTree.nodes.find(x => { return x.uuid === id; }); expr = expr.replace(op, payNode ? `f${payTree.getNodeIndex(payNode) + 1}` || '' : 0); } } return expr; } trans2NodeExpr(expr, payTree) { const orderParam = expr.match(this.orderReg); if (orderParam) { for (const op of orderParam) { const order = parseInt(op.substring(1, op.length)); const payNode = payTree.nodes[order - 1]; expr = expr.replace(op, payNode ? `<<${payNode.uuid}>>` || '' : 0); } } return expr; } checkExprValid(expr, invalidParam, selfId, payTree) { if (!expr) return [true, '']; const param = []; let num = '', base = ''; let fixedIdParam; for (let i = 0, iLen = expr.length; i < iLen; i++) { const subExpr = expr.substring(i, expr.length); if (/^[\d\.%]+/.test(expr[i])) { if (base !== '') { param.push({type: 'base', value: base}); base = ''; } num = num + expr[i]; } else if (this.nodeReg.test(subExpr)) { if (num !== '') { param.push({type: 'num', value: num}); num = ''; } if (base !== '') { param.push({type: 'base', value: base}); base = ''; } // const node = this.nodeReg.exec(subExpr); const node = subExpr.match(this.nodeReg); param.push({type: 'node', value: node[0]}); i = i + node[0].length - 1; } else if (/^[a-z]/.test(expr[i])) { if (num !== '') { param.push({type: 'num', value: num}); num = ''; } base = base + expr[i]; } else if (expr[i] === '(') { if (num !== '') { param.push({type: 'num', value: num}); num = ''; } if (base !== '') { param.push({type: 'base', value: base}); base = ''; } param.push({type: 'left', value: '('}); } else if (expr[i] === ')') { if (num !== '') { param.push({type: 'num', value: num}); num = ''; } if (base !== '') { param.push({type: 'base', value: base}); base = ''; } param.push({type: 'right', value: ')'}); } else if (/^[\+\-*\/]/.test(expr[i])) { if (num !== '') { param.push({type: 'num', value: num}); num = ''; } if (base !== '') { param.push({type: 'base', value: base}); base = ''; } param.push({type: 'calc', value: expr[i]}); } else { return [false, '输入的表达式含有非法字符: ' + expr[i]]; } } if (num !== '') { param.push({type: 'num', value: num}); num = ''; } if (base !== '') { param.push({type: 'base', value: base}); base = ''; } if (param.length === 0) return [true, '']; if (param.length > 1) { if (param[0].value === '-' && param[1].type === 'num') { param[1].value = '-' + param[1].value; param.shift(); } } const iLen = param.length; let iLeftCount = 0, iRightCount = 0; for (const [i, p] of param.entries()) { if (p.type === 'calc') { if (i === 0 || i === iLen - 1) return [false, '输入的表达式非法:计算符号' + p.value + '前后应有数字或计算基数']; } if (p.type === 'num') { num = p.value.replace('%', ''); if (p.value.length - num.length > 1) return [false, '输入的表达式非法:' + p.value + '不是一个有效的数字']; num = _.toNumber(num); if (num === undefined || num === null || _.isNaN(num)) return [false, '输入的表达式非法:' + p.value + '不是一个有效的数字']; if (i > 0) { if (param[i - 1].type !== 'calc' && param[i - 1].type !== 'left') { return [false, '输入的表达式非法:' + p.value + '前应有运算符']; } else if (param[i - 1].value === '/' && num === 0) { return [false, '输入的表达式非法:请勿除0']; } } } if (p.type === 'base') { const baseParam = _.find(calcBase, {code: p.value}); if (!baseParam) return [false, '输入的表达式非法:不存在计算基数' + p.value]; if (invalidParam && invalidParam.indexOf(p.value) >= 0) return [false, '不可使用计算基数' + p.value]; if (i > 0 && (param[i - 1].type === 'num' || param[i - 1].type === 'right')) return [false, '输入的表达式非法:' + p.value + '前应有运算符']; } if (p.type === 'node') { if (!selfId) return [false, '输入的表达式错误:不支持行号引用']; if ([`<<${selfId}>>`].indexOf(p.value) >= 0) return [false, '输入的表达式非法:请勿引用自己']; if (!fixedIdParam) { fixedIdParam = payTree.nodes.filter(x => { return x.is_fixed; }).map(x => { return `<<${x.uuid}>>`}); } if (fixedIdParam.indexOf(p.value) >= 0) return [false, '输入的表达式非法:请勿引用固定项']; } if (p.type === 'left') { iLeftCount += 1; if (i !== 0 && param[i-1].type !== 'calc') return [false, '输入的表达式非法:(前应有运算符']; } if (p.type === 'right') { iRightCount += 1; if (i !== iLen - 1 && param[i+1].type !== 'calc') return [false, '输入的表达式非法:)后应有运算符']; if (iRightCount > iLeftCount) return [false, '输入的表达式非法:")"前无对应的"("']; } } if (iLeftCount > iRightCount) return [false, '输入的表达式非法:"("后无对应的")"']; if (selfId) { const circular = payCalc.checkCircularExpr(expr, selfId, payTree); // 当前循环计算不检查父项 if (circular) return [false, '输入的表达式非法:循环引用']; } return [true, '']; } checkSfExpr(text, data, payNode, payTree) { if (text) { const num = _.toNumber(text); if (num) { data.expr = num; } else { const expr = this.trans2NodeExpr($.trim(text).replace('\t', '').replace('=', '').toLowerCase(), payTree); const [valid, msg] = this.checkExprValid(expr, [], payNode.uuid, payTree); if (!valid) return [valid, msg]; data.expr = expr; } } else { data.tp = 0; data.expr = ''; } return [true, '']; } checkExpr(text, data, payNode, payTree) { if (text) { const num = _.toNumber(text); if (num) { data.tp = num; data.expr = ''; } else { const expr = this.trans2NodeExpr($.trim(text).replace('\t', '').replace('=', '').toLowerCase(), payTree); const [valid, msg] = this.checkExprValid(expr, ['bqyf'], payNode.uuid, payTree); if (!valid) return [valid, msg]; data.expr = expr; data.tp = 0; } } else { data.tp = 0; data.expr = ''; } return [true, '']; } checkRangeExpr(payNode, text, data) { if (!payNode) return [false, '数据错误']; const num = text ? _.toNumber(text) : 0; let expr = text ? (num ? '' : text) : ''; expr = expr ? $.trim(expr).replace('\t', '').replace('=', '').toLowerCase() : ''; const [valid, msg] = this.checkExprValid(expr, ['bqwc', 'ybbqwc', 'bqht', 'bqbg', 'bqyf']); if (!valid) return [valid, msg]; if (payUtils.check.isStarted(payNode)) { if (payUtils.check.isSf(payNode)) { const value = expr ? payCalc.calculateExpr(expr) : num; if (payNode.pre_tp && value < payNode.pre_tp) return [false, '截止上期已计量' + payNode.pre_tp + ',扣款限额请勿少于改值']; data.range_tp = num; data.range_expr = expr; return [true, '']; } else { // if (payNode.pre_finish) return [false, '已达扣款限额,请勿修改']; // const value = expr ? payCalc.calculateExpr(expr) : num; // if (payNode.pre_tp && value < payNode.pre_tp) return [false, '截止上期已计量' + payNode.pre_tp + ',扣款限额请勿少于改值']; // data.range_tp = num; // data.range_expr = expr; return [false, '已经开始使用,请勿修改扣款限额']; } } else { data.range_tp = num; data.range_expr = expr; return [true, '']; } } checkStartExpr(payNode, text, data) { if (!payNode) return [false, '数据错误']; const num = text ? _.toNumber(text) : 0; let expr = text ? (num ? '' : text) : ''; expr = expr ? $.trim(expr).replace('\t', '').replace('=', '').toLowerCase() : ''; const [valid, msg] = this.checkExprValid(expr, ['bqwc', 'ybbqwc', 'bqht', 'bqbg', 'bqyf']); if (!valid) return [valid, msg]; if (payUtils.check.isStarted(payNode)) { return [false, '已经开始计量,请勿修改起扣金额']; } else { if (this.addBase.pre_gather_tp) { const value = expr ? payCalc.calculateExpr(expr) : num; if (this.addBase.pre_gather_tp && value < this.addBase.pre_gather_tp) return [false, '起扣金额请勿少于本期完成截止上期计量金额' + this.addBase.pre_gather_tp]; data.start_tp = num; data.start_expr = expr; return [true, '']; } else { data.start_tp = num; data.start_expr = expr; return [true, '']; } } } getExprInfo(field, converse = false) { const exprField = [ {qty: 'tp', expr: 'expr'}, {qty: 'start_tp', expr: 'start_expr'}, {qty: 'range_qty', expr: 'range_expr'}, ]; if (converse) return _.find(exprField, { expr: field }); return _.find(exprField, {qty: field}); } getLeafOrder(data, parentReg, tree) { if (!data) return []; const defaultResult = data.uuid ? [`<<${data.uuid}>>`] : []; if (!data.expr) return defaultResult; const nodeParam = data.expr.match(this.nodeReg); if (!nodeParam || nodeParam.length === 0) return defaultResult; const result = []; for (const op of nodeParam) { const id = op.substring(2, op.length - 2); if (data.uuid === id || op === parentReg) { result.push(op); } else { const payNode = tree.nodes.find(x => {return x.uuid === id; }); const subOrderParam = this.getLeafOrder(payNode, data.uuid ? `<<${data.uuid}>>` : parentReg, tree); result.push(...subOrderParam); } } return result; } checkCircularExpr(expr, selfId, tree) { const leafOrder = this.getLeafOrder({expr}, `<<${selfId}>>`, tree); if (leafOrder.indexOf(`<<${selfId}>>`) >= 0) return true; return false; } calculateExpr(expr) { let formula = expr; for (const b of this.bases) { formula = formula.replace(b.reg, b.value); } const percent = formula.match(this.percentReg); if (percent) { for (const p of percent) { const v = math.evaluate(p.replace(new RegExp('%', 'gm'), '/100')); formula = formula.replace(p, v); } } try { const value = ZhCalc.mathCalcExpr(formula); return value; } catch(err) { return 0; } } refreshBaseHtml() { const html = []; for (const [i, b] of this.bases.entries()) { html.push(''); html.push(`${i+1}${b.name}${b.code}`); if (b.code === 'bqyf') { html.push('--'); } else { html.push(`${b.formatValue}`); } html.push(''); } $('#base-list').html(html.join('')); } reloadBase(bases, add) { this.bases = bases; this.refreshBaseHtml(); this.bases.sort(function (a, b) { return a.sort - b.sort; }); for (const b of this.bases) { b.reg = new RegExp(b.code, 'igm'); } this.addBase = add; } } return new PayCalc(b, a); })(calcBase, addBase); const payObj = (function() { const spread = SpreadJsObj.createNewSpread($('#pay-spread')[0]); const sheet = spread.getActiveSheet(); const spreadSetting = { cols: [ {title: '名称', colSpan: '1', rowSpan: '1', field: 'name', hAlign: 0, width: 230, formatter: '@', cellType: 'tree', getTip: payUtils.tips.name}, {title: '本期金额(F)', colSpan: '1', rowSpan: '1', field: 'tp', hAlign: 2, width: 100, type: 'Number'}, {title: '截止上期金额', colSpan: '1', rowSpan: '1', field: 'pre_tp', hAlign: 2, width: 100, readOnly: true, type: 'Number'}, {title: '截止本期金额', colSpan: '1', rowSpan: '1', field: 'end_tp', hAlign: 2, width: 100, readOnly: true, type: 'Number'}, {title: '起扣金额', colSpan: '1', rowSpan: '1', field: 'start_tp', hAlign: 2, width: 100, type: 'Number'}, {title: '付(扣)款限额', colSpan: '1', rowSpan: '1', field: 'range_tp', hAlign: 2, width: 100, cellType: 'tip', type: 'Number', getTip: payUtils.tips.range_tp}, {title: '汇总', colSpan: '1', rowSpan: '1', field: 'is_gather', hAlign: 1, width: 60, cellType: 'signalCheckbox', show: payUtils.check.isGatherValid}, {title: '本期批注', colSpan: '1', rowSpan: '1', field: 'postil', hAlign: 0, width: 120, formatter: '@', cellType: 'autoTip'}, ], emptyRows: 0, headRows: 1, headRowHeight: [32], headColWidth: [30], defaultRowHeight: 21, headerFont: '12px 微软雅黑', font: '12px 微软雅黑', readOnly: readOnly, localCache: { key: 'phase-pay', colWidth: true, }, pos: SpreadJsObj.getObjPos($('#pay-spread')[0]), }; sjsSettingObj.setFxTreeStyle(spreadSetting, sjsSettingObj.FxTreeStyle.phasePay); SpreadJsObj.initSheet(sheet, spreadSetting); const payTree = createNewPathTree('base', { id: 'tree_id', pid: 'tree_pid', order: 'tree_order', level: 'tree_level', isLeaf: 'tree_is_leaf', fullPath: 'tree_full_path', rootId: -1, }); const payEvent = { refreshActn: function() { const setObjEnable = function (obj, enable) { if (enable) { obj.removeClass('disabled'); } else { obj.addClass('disabled'); } }; const select = SpreadJsObj.getSelectObject(sheet); if (!select) { setObjEnable($('a[name=base-opr][type=add]'), false); setObjEnable($('a[name=base-opr][type=del]'), false); setObjEnable($('a[name=base-opr][type=up-move]'), false); setObjEnable($('a[name=base-opr][type=down-move]'), false); return; } const preNode = payTree.getPreSiblingNode(select); setObjEnable($('a[name=base-opr][type=add]'), !readOnly && !payUtils.check.isSf(select) && !payUtils.check.isYf(select)); const delValid = !payUtils.check.isFixed(select) && !payUtils.check.isStarted(select); setObjEnable($('a[name=base-opr][type=delete]'), !readOnly && delValid); setObjEnable($('a[name=base-opr][type=up-move]'), !readOnly && !payUtils.check.isFixed(select) && preNode); setObjEnable($('a[name=base-opr][type=down-move]'), !readOnly && !payUtils.check.isFixed(select) && !payTree.isLastSibling(select)); }, loadExprToInput: function() { const sel = sheet.getSelections()[0]; const col = sheet.zh_setting.cols[sel.col]; const data = SpreadJsObj.getSelectObject(sheet); if (data && (!data.children || data.children.length === 0)) { if (col.field === 'tp') { const expr = payCalc.trans2OrderExpr(data.expr, payTree); $('#pay-expr').val(expr).attr('field', 'expr').attr('org', expr) .attr('readOnly', readOnly|| payUtils.check.tpReadOnly(data)); } else if (col.field === 'start_tp') { const expr = payCalc.trans2OrderExpr(data.start_expr, payTree) || data.start_tp; $('#pay-expr').val(expr).attr('field', 'start_expr').attr('org', expr) .attr('readOnly', readOnly|| payUtils.check.startTpReadOnly(data) || payUtils.check.isYf(data)); } else if (col.field === 'range_tp') { const expr = payCalc.trans2OrderExpr(data.range_expr, payTree); $('#pay-expr').val(expr).attr('field', 'range_expr').attr('org', expr) .attr('readOnly', readOnly|| payUtils.check.rangeTpReadOnly(data) || payUtils.check.isYf(data)); } else { $('#pay-expr').val('').attr('readOnly', true); } $('#pay-expr').attr('data-row', sel.row); } else { $('#pay-expr').val('').attr('readOnly', true); $('#pay-expr').removeAttr('data-row'); } }, refreshTree: function (data) { SpreadJsObj.massOperationSheet(sheet, function () { const tree = sheet.zh_tree; // 处理删除 if (data.delete) { data.delete.sort(function (a, b) { return b.deleteIndex - a.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)); } SpreadJsObj.reLoadRowsData(sheet, rows); } }); }, editStarting: function(e, info) { const col = info.sheet.zh_setting.cols[info.col]; const select = SpreadJsObj.getSelectObject(info.sheet); switch (col.field) { case 'name': info.cancel = payUtils.check.isFixed(select); break; case 'tp': case 'is_gather': info.cancel = select.children && select.children.length > 0; break; case 'start_tp': case 'range_tp': info.cancel = (select.children && select.children.length > 0) || payUtils.check.isYf(select); break; case 'is_gather': info.cancel = true; break; } if (col.field === 'tp') { if (select.expr && select.expr !== '') { info.sheet.getCell(info.row, info.col).text(payCalc.trans2OrderExpr(select.expr, payTree)); } } else if (col.field === 'start_tp') { if (select.start_expr && select.start_expr !== '') { info.sheet.getCell(info.row, info.col).text(select.start_expr); } } else if (col.field === 'range_tp') { if (select.range_expr && select.range_expr !== '') { info.sheet.getCell(info.row, info.col).text(select.range_expr); } } }, editEnded: function(e, info) { if (!info.sheet.zh_setting) return; const select = SpreadJsObj.getSelectObject(info.sheet); const col = info.sheet.zh_setting.cols[info.col]; if (col.field === 'is_gather') return; // 未改变值则不提交 const validText = info.editingText ? info.editingText.replace('\n', '') : ''; let orgValue; if (col.field === 'tp') { orgValue = select.expr ? payCalc.trans2OrderExpr(select.expr, payTree) : select.tp; } else if (col.field === 'start_tp') { orgValue = select.start_expr ? select.start_expr : select.start_tp; } else if (col.field === 'range_tp') { orgValue = select.range_expr ? select.range_expr : select.range_tp; } else { orgValue = select[col.field]; } orgValue = orgValue || ''; if (orgValue == validText) { SpreadJsObj.reLoadRowData(info.sheet, info.row); return; } const data = { postType: 'update', postData: { id: select.id } }; switch(col.field) { case 'tp': const [tpValid, tpMsg] = payUtils.check.isSf(select) ? payCalc.checkSfExpr(validText, data.postData, select, payTree) : payCalc.checkExpr(validText, data.postData, select, payTree); if (!tpValid) { toastr.warning(tpMsg); SpreadJsObj.reLoadRowData(info.sheet, info.row); return; } break; case 'start_tp': const [sValid, sMsg] = payCalc.checkStartExpr(select, validText, data.postData); if (!sValid) { toastr.warning(sMsg); SpreadJsObj.reLoadRowData(info.sheet, info.row); return; } break; case 'range_tp': const [rValid, rMsg] = payCalc.checkRangeExpr(select, validText, data.postData); if (!rValid) { toastr.warning(rMsg); SpreadJsObj.reLoadRowData(info.sheet, info.row); return; } break; default: if (col.type === 'Number') { data.postData[col.field] = _.toNumber(validText) || 0; } else { data.postData[col.field] = validText || ''; } break; } postData('update', data, function (result) { if (result.reload) { payEvent.reloadPays(result.reload); } else { const refreshData = payTree.loadPostData(result); payEvent.refreshTree(refreshData); } }, function () { SpreadJsObj.reLoadRowData(info.sheet, info.row); }); }, selectionChanged: function(e, info) { if (info.newSelections) { if (!info.oldSelections || info.newSelections[0].row !== info.oldSelections[0].row) { payEvent.refreshActn(); } } payEvent.loadExprToInput(); }, buttonClicked: function (e, info) { if (!info.sheet.zh_setting) return; const select = SpreadJsObj.getSelectObject(info.sheet); const col = info.sheet.zh_setting.cols[info.col]; if (col.field !== 'is_gather') return; if (!payUtils.check.isGatherValid(select)) return; if (info.sheet.isEditing()) info.sheet.endEdit(true); const data = { postType: 'update', postData: { id: select.id }, }; data.postData[col.field] = info.sheet.getValue(info.row, info.col) || 0; // 更新至服务器 postData('update', data, function (result) { if (result.reload) payEvent.reloadPays(result.reload); }); }, deletePress: function (sheet) { if (!sheet.zh_setting) return; const sel = sheet.getSelections()[0]; if (!sel) return; const col = sheet.zh_setting.cols[sel.col]; if (col.readOnly === true) return; if (sel.colCount > 1) toastr.warning('请勿同时删除多列数据'); const data = { postType: 'update', postData: [] }; for (let iRow = sel.row; iRow < sel.row + sel.rowCount; iRow ++) { const node = sheet.zh_tree.nodes[iRow]; if (node && (!node.pay_type || col.field === 'postil')) { const updateData = { id: node.id }; switch(col.field) { case 'tp': updateData.tp = 0; updateData.expr = ''; break; case 'start_tp': updateData.start_tp = 0; updateData.start_expr = ''; break; case 'range_tp': updateData.range_tp = 0; updateData.range_expr = ''; break; case 'is_gather': updateData.is_gather = 0; break; default: updateData[col.field] = col.type === 'Number' ? 0 : ''; } data.postData.push(updateData); } } postData('update', data, function (result) { if (result.reload) { payEvent.reloadPays(result.reload); } else { const refreshData = payTree.loadPostData(result); payEvent.refreshTree(refreshData); } }, function () { SpreadJsObj.reLoadRowData(sheet, sel.row, sel.rowCount); }); }, baseOpr: function(type) { const self = this; const node = SpreadJsObj.getSelectObject(sheet); if (type === 'delete') { postData('update', { postType: 'delete', postData: { id: node.tree_id }}, function(result) { payEvent.reloadPays(result.reload); }); } else { postData('update', { postType: type, postData: { id: node.tree_id }}, function (result) { const refreshData = payTree.loadPostData(result); payEvent.refreshTree(refreshData); const sel = sheet.getSelections()[0]; if (sel) { if (['up-move', 'down-move'].indexOf(type) > -1) { sheet.setSelection(payTree.getNodeIndex(node), sel.col, sel.rowCount, sel.colCount); SpreadJsObj.reloadRowsBackColor(sheet, [sel.row, payTree.getNodeIndex(node)]); } else if (type === 'add') { sheet.setSelection(payTree.getNodeIndex(refreshData.create[0]), sel.col, sel.rowCount, sel.colCount); SpreadJsObj.reloadRowsBackColor(sheet, [sel.row, payTree.getNodeIndex(refreshData.create[0])]); } } self.refreshActn(sheet); }); } }, calculateAll: function() { postData('update', { postType: 'calc', postData: {}}, function (result) { payEvent.reloadPays(result.reload); }); }, reloadCalcBase: function() { postData('update', { postType: 'refreshBase', postData: {}}, function (result) { payEvent.reloadPays(result.reload); payCalc.reloadBase(result.calcBase, result.addBase); }); }, reloadPays: function(datas){ payTree.loadDatas(datas); SpreadJsObj.loadSheetData(sheet, SpreadJsObj.DataType.Tree, payTree); payEvent.refreshActn(); } }; spread.bind(spreadNS.Events.SelectionChanged, payEvent.selectionChanged); if (!readOnly) { spread.bind(spreadNS.Events.EditStarting, payEvent.editStarting); spread.bind(spreadNS.Events.EditEnded, payEvent.editEnded); spread.bind(spreadNS.Events.ButtonClicked, payEvent.buttonClicked); SpreadJsObj.addDeleteBind(spread, payEvent.deletePress); $('a[name="base-opr"]').click(function () { payEvent.baseOpr(this.getAttribute('type')); }); $('#calc-all').click(function() { payEvent.calculateAll(); }); $('#reload-calc-base').click(function() { payEvent.reloadCalcBase(); }); const deadlineObj = { payNode: null, refreshHint: function() { const dlType = $('[name=dl-type]:checked').val(); const dt = deadlineType[dlType]; if (dlType && dt) { const dlValue = $('#dl-value').val(); $('#range-hint').text(`当 ${dt.name} >= ${dlValue} 时 `); $('#dl-hint').show(); } else { $('#dl-hint').hide(); } }, initView: function(data) { this.payNode = data; $('#dl-pay-name').html(data.name); // 模式 if (data.dl_type) { $('[name=dl-type][value=' + data.dl_type +']')[0].checked = true; } else { $('#dl-type-none')[0].checked = true; } $('#dl-value').val(data.dl_value); this.refreshHint(); }, getDlCount: function() { try { const result = parseInt($('#dl-value').val()); if (result <= 0) throw '限制值请输入正整数'; return result; } catch (err) { toastr.warning('限制值请输入正整数'); return 0; } }, getDlTp: function() { try { const result = parseFloat($('#dl-value').val()); return result; } catch (err) { toastr.warning('限制值请输入数值'); return 0; } }, getUpdateData: function() { const result = { postType: 'update', postData: { id: this.payNode.id } }; result.postData.dl_type = $('[name=dl-type]:checked').val(); if (result.postData.dl_type) { if (result.postData.dl_type === deadlineType.phaseCount.key) { result.postData.dl_value = this.getDlCount(); if (result.postData.dl_value < phasePay.phase_order) { toastr.warning(`已计量至第${phasePay.phase_order}期,计提期限不可小于该期`); return null; } } else if (result.postData.dl_type === deadlineType.stageCount.key) { result.postData.dl_value = this.getDlCount(); if (result.postData.dl_value < maxStageOrder) { toastr.warning(`已计量至第${maxStageOrder}期,计提期限不可小于该期`); return null; } } else { result.postData.dl_value = this.getDlTp(); const dt = deadlineType[result.postData.dl_type]; if (!dt) { toastr.warning('限制模式错误,请刷新页面重试'); return null; } const compareValue = payCalc.addBase[`pre_${dt.key}_tp`]; if (result.postData.dl_type < compareValue) { toastr.warning(`截止上期,${dt.name}已计量${compareValue},计提期限不可小于该值`); return null; } } } else { result.postData.dl_value = 0; } return result; }, }; $('[name=dl-type]').change(deadlineObj.refreshHint); $('#dl-value').change(deadlineObj.refreshHint); $('#deadline-ok').click(function() { const updateData = deadlineObj.getUpdateData(); if (!updateData) return; postData('update', updateData, function(result) { payEvent.reloadPays(result.reload); $('#deadline').modal('hide'); }); }); // 右键菜单 $.contextMenu({ selector: '#pay-spread', build: function ($trigger, e) { const target = SpreadJsObj.safeRightClickSelection($trigger, e, spread); return target.hitTestType === GC.Spread.Sheets.SheetArea.viewport || target.hitTestType === GC.Spread.Sheets.SheetArea.rowHeader; }, items: { 'start': { name: '启用', icon: 'fa-play', callback: function (key, opt) { const select = SpreadJsObj.getSelectObject(sheet); const data = { postType: 'update', postData: { id: select.id, is_pause: 0 } }; // 更新至服务器 postData('update', data, function (result) { payEvent.reloadPays(result.reload); }); }, visible: function (key, opt) { const select = SpreadJsObj.getSelectObject(sheet); return (!select.children || select.children.length ===0) && !readOnly && select.is_pause && payUtils.menuVisible.pause(select); } }, 'stop': { name: '停用', icon: 'fa-pause', callback: function (key, opt) { const select = SpreadJsObj.getSelectObject(sheet); const data = { postType: 'update', postData: { id: select.id, is_pause: 1 } }; // 更新至服务器 postData('update', data, function (result) { payEvent.reloadPays(result.reload); }); }, visible: function (key, opt) { const select = SpreadJsObj.getSelectObject(sheet); return (!select.children || select.children.length === 0) && !readOnly && !select.is_pause && payUtils.menuVisible.pause(select); }, }, 'setDeadline': { name: '设置计提期限', icon: 'fa-clipboard', callback: function (key, opt) { const select = SpreadJsObj.getSelectObject(sheet); if (select.range_tp) { deadlineObj.initView(select); $('#deadline').modal('show'); } else { toastr.warning('计提期限用于达到条件时,即刻计量至付(扣)款限额,应先设置付(扣)款限额'); } }, visible: function (key, opt) { const select = SpreadJsObj.getSelectObject(sheet); return (!select.children || select.children.length === 0) && !readOnly && payUtils.menuVisible.deadline(select); } }, } }); } return { spread, sheet, payTree, loadDatas: payEvent.reloadPays } })(); payObj.loadDatas(details); const payFile = $.ledger_att({ selector: '#fujian', key: 'uuid', masterKey: 'rela_id', uploadUrl: 'file/upload', deleteUrl: 'file/delete', checked: false, zipName: `附件.zip`, readOnly: false, fileIdType: 'string', fileInfo: { user_name: 'user_name', user_id: 'user_id', create_time: 'create_time', }, getCurHint: function(node) { return`${node.name || ''}`; }, locate: function (att) { if (!att) return; SpreadJsObj.locateTreeNode(payObj.sheet, att.node.tree_id, true); payFile.getCurAttHtml(att.node); } }); // 展开收起标准清单 $('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')); } else { // 收起工具栏 tab.removeClass('active'); tabPanel.removeClass('active'); showSideTools(tab.hasClass('active')); } payObj.spread.refresh(); }); postData('load', {filter: 'file'}, function(result) { for (const f of result.file) { f.node = payObj.payTree.datas.find(x => { return x.uuid === f.rela_id; }); } payFile.loadDatas(result.file); payFile.getCurAttHtml(SpreadJsObj.getSelectObject(payObj.sheet)); }); // 工具栏spr $.divResizer({ select: '#right-spr', callback: function () { payObj.spread.refresh(); } }); // todo 加载审批列表 $.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(); payObj.spread.refresh(); } }); });