Quellcode durchsuchen

优化数字处理

woody vor 9 Monaten
Ursprung
Commit
a2873db389

+ 32 - 3
framework-common/src/main/java/com/chelvc/framework/common/model/Region.java

@@ -1,10 +1,13 @@
 package com.chelvc.framework.common.model;
 
 import java.io.Serializable;
+import java.math.BigDecimal;
+import java.math.BigInteger;
 import java.util.Objects;
 import java.util.stream.Collectors;
 import java.util.stream.Stream;
 
+import com.chelvc.framework.common.util.ObjectUtils;
 import com.chelvc.framework.common.util.StringUtils;
 import com.fasterxml.jackson.annotation.JsonIgnore;
 import lombok.AllArgsConstructor;
@@ -171,6 +174,34 @@ public final class Region implements Serializable {
         return code / 10000 * 10000;
     }
 
+    /**
+     * 清理地区编码,截取数字前6位
+     *
+     * @param code 地区编码
+     * @param <T>  数字类型
+     * @return 地区编码
+     */
+    @SuppressWarnings("unchecked")
+    public static <T extends Number> T clear(T code) {
+        Integer value = ObjectUtils.ifNull(code, Number::intValue);
+        if (value == null || value <= MAX_VALUE) {
+            return code;
+        }
+        value = (int) (value / Math.pow(10, (int) Math.log10(value) - 5));
+        if (code instanceof Long) {
+            return (T) Long.valueOf(value);
+        } else if (code instanceof Float) {
+            return (T) Float.valueOf(value);
+        } else if (code instanceof Double) {
+            return (T) Double.valueOf(value);
+        } else if (code instanceof BigInteger) {
+            return (T) BigInteger.valueOf(value);
+        } else if (code instanceof BigDecimal) {
+            return (T) BigDecimal.valueOf(value);
+        }
+        return (T) value;
+    }
+
     /**
      * 构建地区编码
      *
@@ -186,10 +217,8 @@ public final class Region implements Serializable {
             return new Region(value, value + 9999);
         } else if (isCity(value)) {
             return new Region(value, value + 99);
-        } else if (isDistrict(value)) {
-            return new Region(value, 0);
         }
-        throw new IllegalArgumentException("Invalid region: " + code);
+        return new Region(value, 0);
     }
 
     /**

+ 0 - 199
framework-common/src/main/java/com/chelvc/framework/common/util/DecimalUtils.java

@@ -1,199 +0,0 @@
-package com.chelvc.framework.common.util;
-
-import java.math.BigDecimal;
-import java.math.RoundingMode;
-
-import lombok.NonNull;
-
-/**
- * 小数工具类
- *
- * @author Woody
- * @date 2024/1/30
- */
-public final class DecimalUtils {
-    /**
-     * 默认小数保留位数
-     */
-    public static final int DEFAULT_SCALE = 2;
-
-    /**
-     * 100
-     */
-    public static final BigDecimal HUNDRED = new BigDecimal(100);
-
-    /**
-     * 默认四舍五入模式
-     */
-    public static final RoundingMode DEFAULT_MODE = RoundingMode.HALF_UP;
-
-    private DecimalUtils() {
-    }
-
-    /**
-     * 除法
-     *
-     * @param dividend 被除数
-     * @param divisor  除数
-     * @return 结果
-     */
-    public static BigDecimal divide(Long dividend, Long divisor) {
-        return divide(dividend, divisor, DEFAULT_SCALE, DEFAULT_MODE);
-    }
-
-    /**
-     * 除法
-     *
-     * @param dividend 被除数
-     * @param divisor  除数
-     * @param scale    小数位数
-     * @param mode     四舍五入模式
-     * @return 结果
-     */
-    public static BigDecimal divide(Long dividend, Long divisor, int scale, RoundingMode mode) {
-        BigDecimal zero = BigDecimal.ZERO.setScale(scale, mode);
-        return dividend == null || dividend == 0 || divisor == null || divisor == 0 ? zero :
-                BigDecimal.valueOf(dividend).divide(BigDecimal.valueOf(divisor), scale, mode);
-    }
-
-    /**
-     * 除法
-     *
-     * @param dividend 被除数
-     * @param divisor  除数
-     * @return 结果
-     */
-    public static BigDecimal divide(BigDecimal dividend, BigDecimal divisor) {
-        return divide(dividend, divisor, DEFAULT_SCALE, DEFAULT_MODE);
-    }
-
-    /**
-     * 除法
-     *
-     * @param dividend 被除数
-     * @param divisor  除数
-     * @param scale    小数位数
-     * @param mode     四舍五入模式
-     * @return 结果
-     */
-    public static BigDecimal divide(BigDecimal dividend, BigDecimal divisor, int scale, RoundingMode mode) {
-        return dividend == null || dividend.equals(BigDecimal.ZERO) ||
-                divisor == null || divisor.equals(BigDecimal.ZERO) ?
-                BigDecimal.ZERO.setScale(scale, mode) : dividend.divide(divisor, scale, mode);
-    }
-
-    /**
-     * 除法
-     *
-     * @param dividend 被除数
-     * @param divisor  除数
-     * @return 结果
-     */
-    public static BigDecimal divide(BigDecimal dividend, Long divisor) {
-        return divide(dividend, divisor, DEFAULT_SCALE, DEFAULT_MODE);
-    }
-
-    /**
-     * 除法
-     *
-     * @param dividend 被除数
-     * @param divisor  除数
-     * @param scale    小数位数
-     * @param mode     四舍五入模式
-     * @return 结果
-     */
-    public static BigDecimal divide(BigDecimal dividend, Long divisor, int scale, RoundingMode mode) {
-        return dividend == null || dividend.equals(BigDecimal.ZERO) || divisor == null || divisor == 0 ?
-                BigDecimal.ZERO.setScale(scale, mode) : dividend.divide(BigDecimal.valueOf(divisor), scale, mode);
-    }
-
-    /**
-     * 除法
-     *
-     * @param dividend 被除数
-     * @param divisor  除数
-     * @return 结果
-     */
-    public static BigDecimal divide(Long dividend, BigDecimal divisor) {
-        return divide(dividend, divisor, DEFAULT_SCALE, DEFAULT_MODE);
-    }
-
-    /**
-     * 除法
-     *
-     * @param dividend 被除数
-     * @param divisor  除数
-     * @param scale    小数位数
-     * @param mode     四舍五入模式
-     * @return 结果
-     */
-    public static BigDecimal divide(Long dividend, BigDecimal divisor, int scale, RoundingMode mode) {
-        return dividend == null || dividend == 0 || divisor == null || divisor.equals(BigDecimal.ZERO) ?
-                BigDecimal.ZERO.setScale(scale, mode) : BigDecimal.valueOf(dividend).divide(divisor, scale, mode);
-    }
-
-    /**
-     * 格式化小数
-     *
-     * @param decimal 小数
-     * @return 小数字符串
-     */
-    public static String format(BigDecimal decimal) {
-        return format(decimal, false);
-    }
-
-    /**
-     * 格式化小数
-     *
-     * @param decimal   小数
-     * @param trimZeros 是否去掉多余的0
-     * @return 小数字符串
-     */
-    public static String format(BigDecimal decimal, boolean trimZeros) {
-        return format(decimal, DEFAULT_SCALE, RoundingMode.HALF_UP, trimZeros);
-    }
-
-    /**
-     * 格式化小数
-     *
-     * @param decimal 小数
-     * @param scale   小数保留位数
-     * @param mode    小数舍弃模式
-     * @return 小数字符串
-     */
-    public static String format(BigDecimal decimal, int scale, @NonNull RoundingMode mode) {
-        return format(decimal, scale, mode, false);
-    }
-
-    /**
-     * 格式化小数
-     *
-     * @param decimal   小数
-     * @param scale     小数保留位数
-     * @param mode      小数舍弃模式
-     * @param trimZeros 是否去掉多余的0
-     * @return 小数字符串
-     */
-    public static String format(BigDecimal decimal, int scale, @NonNull RoundingMode mode, boolean trimZeros) {
-        if (decimal == null) {
-            return null;
-        }
-        decimal = decimal.setScale(scale, mode);
-        if (trimZeros) {
-            decimal = decimal.stripTrailingZeros();
-        }
-        return decimal.toPlainString();
-    }
-
-    /**
-     * 判断数字是否在最大、最小之间
-     *
-     * @param value 数字
-     * @param min   最小值
-     * @param max   最大值
-     * @return true/false
-     */
-    public static boolean between(double value, double min, double max) {
-        return value >= min && value <= max;
-    }
-}

+ 325 - 0
framework-common/src/main/java/com/chelvc/framework/common/util/NumberUtils.java

@@ -0,0 +1,325 @@
+package com.chelvc.framework.common.util;
+
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.math.RoundingMode;
+
+import lombok.NonNull;
+
+/**
+ * 数字处理工具类
+ *
+ * @author Woody
+ * @date 2024/1/30
+ */
+public final class NumberUtils {
+    /**
+     * 默认小数保留位数
+     */
+    public static final int DEFAULT_DECIMAL_SCALE = 8;
+
+    /**
+     * 默认小数四舍五入模式
+     */
+    public static final RoundingMode DEFAULT_ROUND_MODE = RoundingMode.HALF_UP;
+
+    /**
+     * 100小数
+     */
+    private static final BigDecimal HUNDRED_DECIMAL = new BigDecimal(100);
+
+    private NumberUtils() {
+    }
+
+    /**
+     * 判断数字是否等于0
+     *
+     * @param number 数字
+     * @return true/false
+     */
+    public static boolean isZero(Number number) {
+        if (number instanceof BigInteger) {
+            return BigInteger.ZERO.equals(number);
+        } else if (number instanceof BigDecimal) {
+            return BigDecimal.ZERO.equals(number);
+        }
+        return number != null && number.intValue() == 0;
+    }
+
+    /**
+     * 将数字转换成小数
+     *
+     * @param number 数字
+     * @return 大数字小数
+     */
+    public static BigDecimal number2decimal(Number number) {
+        if (number == null) {
+            return null;
+        } else if (number instanceof BigDecimal) {
+            return (BigDecimal) number;
+        } else if (number instanceof BigInteger) {
+            return new BigDecimal((BigInteger) number);
+        } else if (number instanceof Float || number instanceof Double) {
+            return BigDecimal.valueOf(number.doubleValue());
+        }
+        return BigDecimal.valueOf(number.longValue());
+    }
+
+    /**
+     * 乘以10
+     *
+     * @param number 数字
+     * @return 结果
+     */
+    public static BigDecimal multiply10(Number number) {
+        return number == null || isZero(number) ? BigDecimal.ZERO : number2decimal(number).multiply(BigDecimal.TEN);
+    }
+
+    /**
+     * 乘以100
+     *
+     * @param number 数字
+     * @return 结果
+     */
+    public static BigDecimal multiply100(Number number) {
+        return number == null || isZero(number) ? BigDecimal.ZERO : number2decimal(number).multiply(HUNDRED_DECIMAL);
+    }
+
+    /**
+     * 除以10
+     *
+     * @param number 被除数
+     * @return 结果
+     */
+    public static BigDecimal divide10(Number number) {
+        return divide(number, BigDecimal.TEN);
+    }
+
+    /**
+     * 除以10
+     *
+     * @param number 被除数
+     * @param scale  小数位数
+     * @return 结果
+     */
+    public static BigDecimal divide10(Number number, int scale) {
+        return divide(number, BigDecimal.TEN, scale);
+    }
+
+    /**
+     * 除以10
+     *
+     * @param number 被除数
+     * @param mode   四舍五入模式
+     * @return 结果
+     */
+    public static BigDecimal divide10(Number number, @NonNull RoundingMode mode) {
+        return divide(number, BigDecimal.TEN, mode);
+    }
+
+    /**
+     * 除以10
+     *
+     * @param number 被除数
+     * @param scale  小数位数
+     * @param mode   四舍五入模式
+     * @return 结果
+     */
+    public static BigDecimal divide10(Number number, int scale, @NonNull RoundingMode mode) {
+        return divide(number, BigDecimal.TEN, scale, mode);
+    }
+
+    /**
+     * 除以100
+     *
+     * @param number 被除数
+     * @return 结果
+     */
+    public static BigDecimal divide100(Number number) {
+        return divide(number, HUNDRED_DECIMAL);
+    }
+
+    /**
+     * 除以100
+     *
+     * @param number 被除数
+     * @param scale  小数位数
+     * @return 结果
+     */
+    public static BigDecimal divide100(Number number, int scale) {
+        return divide(number, HUNDRED_DECIMAL, scale);
+    }
+
+    /**
+     * 除以100
+     *
+     * @param number 被除数
+     * @param mode   四舍五入模式
+     * @return 结果
+     */
+    public static BigDecimal divide100(Number number, @NonNull RoundingMode mode) {
+        return divide(number, HUNDRED_DECIMAL, mode);
+    }
+
+    /**
+     * 除以100
+     *
+     * @param number 被除数
+     * @param scale  小数位数
+     * @param mode   四舍五入模式
+     * @return 结果
+     */
+    public static BigDecimal divide100(Number number, int scale, @NonNull RoundingMode mode) {
+        return divide(number, HUNDRED_DECIMAL, scale, mode);
+    }
+
+    /**
+     * 除法
+     *
+     * @param dividend 被除数
+     * @param divisor  除数
+     * @return 结果
+     */
+    public static BigDecimal divide(Number dividend, Number divisor) {
+        return divide(dividend, divisor, DEFAULT_DECIMAL_SCALE);
+    }
+
+    /**
+     * 除法
+     *
+     * @param dividend 被除数
+     * @param divisor  除数
+     * @param scale    小数位数
+     * @return 结果
+     */
+    public static BigDecimal divide(Number dividend, Number divisor, int scale) {
+        return divide(dividend, divisor, scale, DEFAULT_ROUND_MODE);
+    }
+
+    /**
+     * 除法
+     *
+     * @param dividend 被除数
+     * @param divisor  除数
+     * @param mode     四舍五入模式
+     * @return 结果
+     */
+    public static BigDecimal divide(Number dividend, Number divisor, @NonNull RoundingMode mode) {
+        return divide(dividend, divisor, DEFAULT_DECIMAL_SCALE, mode);
+    }
+
+    /**
+     * 除法
+     *
+     * @param dividend 被除数
+     * @param divisor  除数
+     * @param scale    小数位数
+     * @param mode     四舍五入模式
+     * @return 结果
+     */
+    public static BigDecimal divide(Number dividend, Number divisor, int scale, @NonNull RoundingMode mode) {
+        if (dividend == null || divisor == null || isZero(dividend) || isZero(divisor)) {
+            return BigDecimal.ZERO.setScale(scale, mode);
+        }
+        return number2decimal(dividend).divide(number2decimal(divisor), scale, mode);
+    }
+
+    /**
+     * 格式化小数
+     *
+     * @param decimal 小数
+     * @return 小数字符串
+     */
+    public static String format(BigDecimal decimal) {
+        return format(decimal, false);
+    }
+
+    /**
+     * 格式化小数
+     *
+     * @param decimal 小数
+     * @param scale   小数保留位数
+     * @return 小数字符串
+     */
+    public static String format(BigDecimal decimal, int scale) {
+        return format(decimal, scale, RoundingMode.HALF_UP, false);
+    }
+
+    /**
+     * 格式化小数
+     *
+     * @param decimal 小数
+     * @param mode    小数舍弃模式
+     * @return 小数字符串
+     */
+    public static String format(BigDecimal decimal, @NonNull RoundingMode mode) {
+        return format(decimal, DEFAULT_DECIMAL_SCALE, mode, false);
+    }
+
+    /**
+     * 格式化小数
+     *
+     * @param decimal   小数
+     * @param trimZeros 是否去掉多余的0
+     * @return 小数字符串
+     */
+    public static String format(BigDecimal decimal, boolean trimZeros) {
+        return format(decimal, DEFAULT_DECIMAL_SCALE, RoundingMode.HALF_UP, trimZeros);
+    }
+
+    /**
+     * 格式化小数
+     *
+     * @param decimal 小数
+     * @param scale   小数保留位数
+     * @param mode    小数舍弃模式
+     * @return 小数字符串
+     */
+    public static String format(BigDecimal decimal, int scale, @NonNull RoundingMode mode) {
+        return format(decimal, scale, mode, false);
+    }
+
+    /**
+     * 格式化小数
+     *
+     * @param decimal   小数
+     * @param scale     小数保留位数
+     * @param trimZeros 是否去掉多余的0
+     * @return 小数字符串
+     */
+    public static String format(BigDecimal decimal, int scale, boolean trimZeros) {
+        return format(decimal, scale, DEFAULT_ROUND_MODE, trimZeros);
+    }
+
+    /**
+     * 格式化小数
+     *
+     * @param decimal   小数
+     * @param mode      小数舍弃模式
+     * @param trimZeros 是否去掉多余的0
+     * @return 小数字符串
+     */
+    public static String format(BigDecimal decimal, @NonNull RoundingMode mode, boolean trimZeros) {
+        return format(decimal, DEFAULT_DECIMAL_SCALE, mode, trimZeros);
+    }
+
+    /**
+     * 格式化小数
+     *
+     * @param decimal   小数
+     * @param scale     小数保留位数
+     * @param mode      小数舍弃模式
+     * @param trimZeros 是否去掉多余的0
+     * @return 小数字符串
+     */
+    public static String format(BigDecimal decimal, int scale, @NonNull RoundingMode mode, boolean trimZeros) {
+        if (decimal == null) {
+            return null;
+        }
+        decimal = decimal.setScale(scale, mode);
+        if (trimZeros) {
+            decimal = decimal.stripTrailingZeros();
+        }
+        return decimal.toPlainString();
+    }
+}

+ 2 - 2
framework-wechat/src/main/java/com/chelvc/framework/wechat/DefaultWechatPaymentHandler.java

@@ -7,8 +7,8 @@ import java.util.Objects;
 import com.chelvc.framework.base.context.ApplicationContextHolder;
 import com.chelvc.framework.base.context.RestContextHolder;
 import com.chelvc.framework.common.util.AssertUtils;
-import com.chelvc.framework.common.util.DecimalUtils;
 import com.chelvc.framework.common.util.HostUtils;
+import com.chelvc.framework.common.util.NumberUtils;
 import com.chelvc.framework.common.util.ObjectUtils;
 import com.chelvc.framework.common.util.StringUtils;
 import com.chelvc.framework.wechat.config.WechatProperties;
@@ -91,7 +91,7 @@ public class DefaultWechatPaymentHandler implements com.chelvc.framework.wechat.
             parameters.put("attach", request.getContext());
         }
         parameters.put("fee_type", "CNY");
-        parameters.put("total_fee", String.valueOf(request.getAmount().multiply(DecimalUtils.HUNDRED).intValue()));
+        parameters.put("total_fee", NumberUtils.format(NumberUtils.multiply100(request.getAmount()), true));
         parameters.put("spbill_create_ip", HostUtils.LOCAL_ADDRESS);
         parameters.put("notify_url", callback);
         parameters.put("trade_type", payment.getMode().name());