import { chain, bignumber, format } from 'mathjs'; /** 格式化 保留2位小数 */ export const format2 = (value: number | string) => { if (value === Infinity) return ''; if (`${value}` === 'NaN') return ''; if (typeof value === 'string') value = parseFloat(value); return parseFloat(value.toFixed(2)); }; /** 格式化 保留15位数字 */ export const format15 = (value: number | string, defaultFractionDigits: number = 8) => { if (value === Infinity) return ''; if (`${value}` === 'NaN') return ''; if (typeof value === 'string') value = parseFloat(value); const fractionDigits = 15 - `${value || 0}`.indexOf('.'); return nonScientificNotation(value, fractionDigits > defaultFractionDigits ? defaultFractionDigits : fractionDigits) as number | undefined | ''; }; /** * 金额(含税) = 数量 * 单价(含税) * @param quantity 数量 * @param priceIncludeTax 单价(含税) * @returns 金额(含税) */ export function countAmountIncludeTax(quantity?: number | string, priceIncludeTax?: number | string, calculatingDigits?: number): number | undefined { if (!quantity && quantity !== 0) return undefined; if (!priceIncludeTax && priceIncludeTax !== 0) return undefined; quantity = format15(quantity, calculatingDigits); priceIncludeTax = format15(priceIncludeTax, calculatingDigits); return parseFloat(chain(bignumber(priceIncludeTax)).multiply(bignumber(quantity)).done().toNumber().toFixed(2)); // return parseFloat(evaluate(`${priceIncludeTax} * ${quantity}`).toFixed(2)); } /** * 不含税金额 = 含税金额-税额 * @param amountIncludeTax 含税金额 * @param taxAmount 税额 * @returns 不含税金额 */ export function countAmountExcludeTax(amountIncludeTax: string | number, taxAmount: number): number | undefined { if (!amountIncludeTax && amountIncludeTax !== 0) return undefined; if (!taxAmount && taxAmount !== 0) return undefined; return chain(bignumber(amountIncludeTax)).subtract(bignumber(taxAmount)).done().toNumber(); } /** * 税额 = (含税金额-扣除额)/(1+税率)*税率 * @param amountIncludeTax 含税金额 * @param deduction 扣除额 * @param taxRate 税率 * @returns 税额 */ export function countTaxAmount(amountIncludeTax: string | number, deduction: number, taxRate: number): number | undefined { if (!amountIncludeTax && amountIncludeTax !== 0) return undefined; if (!deduction && deduction !== 0) return undefined; if (!taxRate && taxRate !== 0) return undefined; const taxRateBu = chain(bignumber(taxRate)).divide(bignumber(100)).done(); return parseFloat(chain(bignumber(amountIncludeTax)) .subtract(bignumber(deduction)) .divide(chain(bignumber(1)).add(taxRateBu).done()) .multiply(taxRateBu) .done() .toNumber() .toFixed(2)) } /** * 单价 = 金额/数量 * @param amount 金额 * @param quantity 数量 * @returns 单价 */ export function countPrice(amount: string | number, quantity: string | number, calculatingDigits?: number): number | undefined | '' { if (!amount && amount !== 0) return undefined; if (!quantity && quantity !== 0) return undefined; return format15(chain(bignumber(amount)).divide(bignumber(quantity)) .done() .toNumber(), calculatingDigits) } // /** // * 单价 = 金额/数量 不做小数限制 // * @param amount 金额 // * @param quantity 数量 // * @returns 单价 // */ // export function countPriceNoLimit(amount: string | number, quantity: string | number, calculatingDigits?: number): number | undefined | '' { // if (!amount && amount !== 0) return undefined; // if (!quantity && quantity !== 0) return undefined; // return chain(bignumber(amount)).divide(bignumber(quantity)) // .done() // .toString().substr(0,25) // } /** * 数量 = 金额/单价 * @param amount 金额 * @param price 单价 * @returns 数量 */ export function countQuantity(amount: string | number, price: string | number, calculatingDigits?: number): number | undefined | '' { if (!amount && amount !== 0) return undefined; if (!price && price !== 0) return undefined; return format15(chain(bignumber(amount)).divide(bignumber(price)) .done() .toNumber(), calculatingDigits) } /** * 将数值转化为非科学计数法的字符串,忽略小数多余的0 * 无法转化的返回空字符串 * @param value 数值或字符串 * @param precision 精度 * @returns 字符串 */ export function nonScientificNotation (value: number | string | undefined, precision?: number ): string { try { if (!value && value !== 0) { return '' } else { // 先按照精度fixed if (precision) { value = format(bignumber(value), {notation: 'fixed', precision}); } // 去掉小数位多余的0 return format(bignumber(value), {notation: 'fixed'}) } } catch (e){ console.error(e); return '' } }