package cn.iocoder.yudao.framework.common.util.number; import cn.hutool.core.math.Money; import cn.hutool.core.util.NumberUtil; import java.math.BigDecimal; import java.math.RoundingMode; /** * 金额工具类 * * @author 超级管理员 */ public class MoneyUtils { /** * 金额的小数位数 */ private static final int PRICE_SCALE = 2; /** * 百分比对应的 BigDecimal 对象 */ public static final BigDecimal PERCENT_100 = BigDecimal.valueOf(100); /** * 计算百分比金额,四舍五入 * * @param price 金额 * @param rate 百分比,例如说 56.77% 则传入 56.77 * @return 百分比金额 */ public static Integer calculateRatePrice(Integer price, Double rate) { return calculateRatePrice(price, rate, 0, RoundingMode.HALF_UP).intValue(); } /** * 计算百分比金额,向下传入 * * @param price 金额 * @param rate 百分比,例如说 56.77% 则传入 56.77 * @return 百分比金额 */ public static Integer calculateRatePriceFloor(Integer price, Double rate) { return calculateRatePrice(price, rate, 0, RoundingMode.FLOOR).intValue(); } /** * 计算百分比金额 * * @param price 金额(单位分) * @param count 数量 * @param percent 折扣(单位分),列如 60.2%,则传入 6020 * @return 商品总价 */ public static Integer calculator(Integer price, Integer count, Integer percent) { price = price * count; if (percent == null) { return price; } return MoneyUtils.calculateRatePriceFloor(price, (double) (percent / 100)); } /** * 计算百分比金额 * * @param price 金额 * @param rate 百分比,例如说 56.77% 则传入 56.77 * @param scale 保留小数位数 * @param roundingMode 舍入模式 */ public static BigDecimal calculateRatePrice(Number price, Number rate, int scale, RoundingMode roundingMode) { return NumberUtil.toBigDecimal(price).multiply(NumberUtil.toBigDecimal(rate)) // 乘以 .divide(BigDecimal.valueOf(100), scale, roundingMode); // 除以 100 } /** * 分转元 * * @param fen 分 * @return 元 */ public static BigDecimal fenToYuan(int fen) { return new Money(0, fen).getAmount(); } /** * 分转元(字符串) * * 例如说 fen 为 1 时,则结果为 0.01 * * @param fen 分 * @return 元 */ public static String fenToYuanStr(int fen) { return new Money(0, fen).toString(); } /** * 金额相乘,默认进行四舍五入 * * 位数:{@link #PRICE_SCALE} * * @param price 金额 * @param count 数量 * @return 金额相乘结果 */ public static BigDecimal priceMultiply(BigDecimal price, BigDecimal count) { if (price == null || count == null) { return null; } return price.multiply(count).setScale(PRICE_SCALE, RoundingMode.HALF_UP); } /** * 金额相乘(百分比),默认进行四舍五入 * * 位数:{@link #PRICE_SCALE} * * @param price 金额 * @param percent 百分比 * @return 金额相乘结果 */ public static BigDecimal priceMultiplyPercent(BigDecimal price, BigDecimal percent) { if (price == null || percent == null) { return null; } return price.multiply(percent).divide(PERCENT_100, PRICE_SCALE, RoundingMode.HALF_UP); } /** * 计算含税总价里的税额(单价为含税单价时使用) * * 税额 = 含税总价 × 税率 ÷(100 + 税率) * 例如:含税总价 113.00,税率 13% → 税额 13.00 * * @param totalPriceWithTax 含税总价 * @param taxPercent 税率,例如 13% 传入 13 * @return 税额;含税总价为空时返回 null,税率为空或非正数时返回 0.00 */ public static BigDecimal priceCalculateTaxIncluded(BigDecimal totalPriceWithTax, BigDecimal taxPercent) { if (totalPriceWithTax == null) { return null; } if (taxPercent == null || taxPercent.compareTo(BigDecimal.ZERO) <= 0) { return BigDecimal.ZERO.setScale(PRICE_SCALE, RoundingMode.HALF_UP); } return totalPriceWithTax.multiply(taxPercent) .divide(PERCENT_100.add(taxPercent), PRICE_SCALE, RoundingMode.HALF_UP); } /** * 含税总价拆出不含税金额 * * 不含税金额 = 含税总价 − 税额(税额见 {@link #priceCalculateTaxIncluded}) * * @param totalPriceWithTax 含税总价 * @param taxPercent 税率,例如 13% 传入 13 * @return 不含税金额;含税总价为空时返回 null */ public static BigDecimal priceExcludeTax(BigDecimal totalPriceWithTax, BigDecimal taxPercent) { BigDecimal taxPrice = priceCalculateTaxIncluded(totalPriceWithTax, taxPercent); if (taxPrice == null) { return null; } return totalPriceWithTax.subtract(taxPrice).setScale(PRICE_SCALE, RoundingMode.HALF_UP); } }