来了,资金类交易业务(如电商交易、支付)中,经常提到的Money类! ...

打印 上一主题 下一主题

主题 913|帖子 913|积分 2739

资金类交易业务中 经常提到的Money类,大家相识一下。  相识了Money类,就会对资金类业务如电商交易、支付更相识。
资金类业务中,金额如果处理得不好,带来的直接后果就是资金损失(资损风险)。
对于研发经验不足的团队而言,经常会犯以下几种错误:
不同一,存在各体系使用BigDecimal、double、long等数据类型来定义金额。
手动对金额进行加、减、乘、除运算,单元(元与分)换算。
带来的后果,通常就是资金损失,再细化一下,最常见的情况有下面3种:
1)手动做单元换算导致金额被放大或缩小100倍。好比大家规定传的是元,但是此中有位同砚忘记了,以为传的是分,外部渠道要求传元,就手动乘以100。或者反过来。
2)1分钱归属问题。好比结算给商家,或盘算手续费时,碰到除不尽时,使用四舍五入,还是向零舍入,还是银行家舍入?这取决于财政战略。
3)精度丢失。在大金额时,double有大概会有精度丢失问题。
这时间,解决方案就是定义同一的 Money 类。而且,要明确同一使用 Money 类来处理金额数据。
1. 同一的Money 类

talk is cheap , show you the code directly.
[code]package com.emaxpay.common.trans;import cn.hutool.core.lang.Assert;import lombok.Getter;import java.io.Serializable;import java.math.BigDecimal;import java.math.RoundingMode;/** * 资金类交易业务(如电商交易、支付)中,经常提到的Money类。 *
该类是不可变的(immutable),而且实现了Comparable和Serializable接口。 *
原始文章 * * @author zhangguozhan * @date 2025-01-07 14:40 */@Getterpublic class Money implements Serializable, Comparable {    private static final long serialVersionUID = 1L;    private BigDecimal yuan;    private long fen;    /**     * 私有构造函数,确保通过工厂方法{@link #of}来创建实例。     *     * @param yuan     * @param fen     */    private Money(BigDecimal yuan, long fen) {        this.yuan = yuan;        this.fen = fen;    }    public static Money of(BigDecimal yuan) {        Assert.notNull(yuan, "yuan is null");        return new Money(yuan, yuan.movePointRight(2).longValue());    }    public static Money of(Long fen) {        Assert.notNull(fen, "fen is null");        return new Money(BigDecimal.valueOf(fen * 100), fen);    }    /**     * 加法操作,返回新的Money实例。(注意Money类是不可变类,此操作不会修改当前Money对象的属性值)     *     * @param other     * @return     */    public Money add(Money other) {        Assert.notNull(other, "other is null");        Assert.notNull(other.yuan, "other.yuan is null");        BigDecimal sum = this.yuan.add(other.yuan);        return of(sum);    }    /**     * (按百分比费率)盘算手续费     *     * @param feeRatePercentage 百分比 的手续费费率比例,例如 5.5% 传 5.5     * @return     */    public BigDecimal calculateFeeByPercentageRate(BigDecimal feeRatePercentage) {        return calculateFeeByPercentageRate(feeRatePercentage, RoundingMode.HALF_UP);    }    /**     * (按百分比费率)盘算手续费     *     * @param feeRatePercentage 百分比 的手续费费率比例,例如 5.5% 传 5.5     * @param roundingMode     * @return     */    public BigDecimal calculateFeeByPercentageRate(BigDecimal feeRatePercentage, RoundingMode roundingMode) {        Assert.notNull(feeRatePercentage, "feeRatePercentage is null");        return yuan.multiply(feeRatePercentage).divide(BigDecimal.valueOf(100), 2, roundingMode);    }    /**     * (按
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

西河刘卡车医

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表