|  | @@ -1673,73 +1673,9 @@ $(document).ready(() => {
 | 
	
		
			
				|  |  |                      return !node || !!node.b_code;
 | 
	
		
			
				|  |  |                  }
 | 
	
		
			
				|  |  |              },
 | 
	
		
			
				|  |  | -            'remainByExpr': {
 | 
	
		
			
				|  |  | -                name: '计算本期合同计量',
 | 
	
		
			
				|  |  | -                callback: function(key, opt) {
 | 
	
		
			
				|  |  | -                    const sheet = spSpread.getActiveSheet();
 | 
	
		
			
				|  |  | -                    const node = SpreadJsObj.getSelectObject(slSpread.getActiveSheet());
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -                    const [formula, value] = TreeExprCalc.calcExpr(node.calc_expr);
 | 
	
		
			
				|  |  | -                    const updateData = {lid: node.id, contract_expr: formula};
 | 
	
		
			
				|  |  | -                    if (node.is_tp) {
 | 
	
		
			
				|  |  | -                        updateData.contract_tp = value;
 | 
	
		
			
				|  |  | -                    } else {
 | 
	
		
			
				|  |  | -                        updateData.contract_qty = value;
 | 
	
		
			
				|  |  | -                    }
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -                    postData(window.location.pathname + '/update', {bills: { stage: [updateData] }}, function (result) {
 | 
	
		
			
				|  |  | -                        const nodes = stageTree.loadPostStageData(result);
 | 
	
		
			
				|  |  | -                        stageTreeSpreadObj.refreshTreeNodes(slSpread.getActiveSheet(), nodes);
 | 
	
		
			
				|  |  | -                        if (detail) {
 | 
	
		
			
				|  |  | -                            detail.loadStageLedgerUpdateData(result, nodes);
 | 
	
		
			
				|  |  | -                        } else {
 | 
	
		
			
				|  |  | -                            stageIm.loadUpdateLedgerData(result, nodes);
 | 
	
		
			
				|  |  | -                        }
 | 
	
		
			
				|  |  | -                        stageTreeSpreadObj.loadExprToInput(sheet);
 | 
	
		
			
				|  |  | -                    });
 | 
	
		
			
				|  |  | -                },
 | 
	
		
			
				|  |  | -                visible: function(key, opt) {
 | 
	
		
			
				|  |  | -                    return !readOnly;
 | 
	
		
			
				|  |  | -                },
 | 
	
		
			
				|  |  | -                disabled: function (key, opt) {
 | 
	
		
			
				|  |  | -                    const node = SpreadJsObj.getSelectObject(slSpread.getActiveSheet());
 | 
	
		
			
				|  |  | -                    return !node || !node.calc_expr;
 | 
	
		
			
				|  |  | -                }
 | 
	
		
			
				|  |  | -            },
 | 
	
		
			
				|  |  | -            'remainByExprAll3': {
 | 
	
		
			
				|  |  | -                name: '计算本期合同计量(全部公式项-缓存)',
 | 
	
		
			
				|  |  | -                callback: function(key, opt) {
 | 
	
		
			
				|  |  | -                    const sheet = spSpread.getActiveSheet();
 | 
	
		
			
				|  |  | -                    TreeExprCalc.setCalcType(TreeExprCalc.calcType.cache);
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -                    const calcExpr = stageTree.nodes.filter(x => {
 | 
	
		
			
				|  |  | -                        return !!x.calc_expr;
 | 
	
		
			
				|  |  | -                    }).map(x => { return { id: x.id, expr: x.calc_expr, unit_price: x.unit_price, calcField: x.is_tp ? 'tp' : 'qty' }});
 | 
	
		
			
				|  |  | -                    TreeExprCalc.calcAllExpr(calcExpr);
 | 
	
		
			
				|  |  | -                    const updateData = calcExpr.map(x => {
 | 
	
		
			
				|  |  | -                        const data = { lid: x.id, contract_expr: x.formula };
 | 
	
		
			
				|  |  | -                        const field = x.calcField === 'qty' ? 'contract_qty' : 'contract_tp';
 | 
	
		
			
				|  |  | -                        data[field] = x.value;
 | 
	
		
			
				|  |  | -                        return data;
 | 
	
		
			
				|  |  | -                    });
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -                    postData(window.location.pathname + '/update', {bills: { stage: updateData }}, function (result) {
 | 
	
		
			
				|  |  | -                        const nodes = stageTree.loadPostStageData(result);
 | 
	
		
			
				|  |  | -                        stageTreeSpreadObj.refreshTreeNodes(slSpread.getActiveSheet(), nodes);
 | 
	
		
			
				|  |  | -                        if (detail) {
 | 
	
		
			
				|  |  | -                            detail.loadStageLedgerUpdateData(result, nodes);
 | 
	
		
			
				|  |  | -                        } else {
 | 
	
		
			
				|  |  | -                            stageIm.loadUpdateLedgerData(result, nodes);
 | 
	
		
			
				|  |  | -                        }
 | 
	
		
			
				|  |  | -                        stageTreeSpreadObj.loadExprToInput(sheet);
 | 
	
		
			
				|  |  | -                    });
 | 
	
		
			
				|  |  | -                },
 | 
	
		
			
				|  |  | -                visible: function(key, opt) {
 | 
	
		
			
				|  |  | -                    return !readOnly;
 | 
	
		
			
				|  |  | -                },
 | 
	
		
			
				|  |  | -            },
 | 
	
		
			
				|  |  |              'remainByExprAll4': {
 | 
	
		
			
				|  |  | -                name: '计算本期合同计量(全部公式项-排序&缓存)',
 | 
	
		
			
				|  |  | +                name: '计算本期合同计量',
 | 
	
		
			
				|  |  | +                icon: 'fa-forward',
 | 
	
		
			
				|  |  |                  callback: function(key, opt) {
 | 
	
		
			
				|  |  |                      const sheet = spSpread.getActiveSheet();
 | 
	
		
			
				|  |  |                      TreeExprCalc.setCalcType(TreeExprCalc.calcType.sortCache);
 |