等本等息,等额本金,先息后本,一次性还本付息

61 阅读3分钟

使用:// const result = calculateLoanRepayment(Number(money), Number(rate), Number(term), wayType);

   // 定义还款方式枚举,用于标识不同的还款类型
    enum RepaymentType {
            EqualPrincipalAndInterest = '等本等息',
            EqualPrincipal = '等额本金',
            InterestFirst = '先息后本',
            BulletPayment = '一次性还本付息',
    }

// 定义每期还款明细的接口,包含期数、本金、利息和合计
interface RepaymentDetail {
        period: number; // 期数
        principal: number; // 本期偿还的本金金额
        interest: number; // 本期偿还的利息金额
        total: number; // 本期偿还的本金和利息的总和
}

// 定义贷款计算结果的接口,包含总本金、总利息和每期的还款明细
interface LoanCalculationResult {
        totalPrincipal: number; // 贷款的总本金金额
        totalInterest: number; // 贷款的总利息金额
        details: RepaymentDetail[]; // 每期的还款明细数组
}

// 公共方法:根据贷款金额、利率、期数和还款方式计算还款情况
// 公共方法:根据贷款金额、利率、期数和还款方式计算还款情况
function calculateLoanRepayment(
        amount: number, // 贷款金额
        rate: number, // 贷款年利率(百分比)
        periods: number, // 贷款总期数(月)
        repaymentType: RepaymentType, // 还款方式类型
): LoanCalculationResult {
        // 初始化结果对象,总本金默认为贷款金额,总利息初始为0,详情数组为空
        const result: LoanCalculationResult = {
                totalPrincipal: amount,
                totalInterest: 0,
                details: [],
        };

// 计算月利率,将年利率转换为月利率(年利率百分比转为小数,再除以12个月)
const monthlyRate = rate / 12 / 100;

// 根据不同的还款方式,使用不同的计算逻辑
switch (repaymentType) {
	case RepaymentType.EqualPrincipalAndInterest: {
		// 等本等息:每月偿还相同金额的利息,本金平均分配到每个月
		// 每月利息 = 贷款金额 × 月利率
		const monthlyInterest = amount * monthlyRate;
		// 总利息 = 每月利息 × 还款月数 - 贷款金额(因为本金也是分期偿还的)
		result.totalInterest = monthlyInterest * periods - amount;
		// 计算每期的还款明细
		for (let i = 1; i <= periods; i++) {
			// 每期偿还的本金 = 贷款金额 / 还款期数
			const principal = amount / periods;
			// 每期利息固定为 monthlyInterest
			const interest = monthlyInterest;
			// 每期合计 = 本金 + 利息
			const total = principal + interest;
			// 将本期明细添加到详情数组
			result.details.push({
				period: i,
				principal: parseFloat(principal.toFixed(2)),
				interest: parseFloat(interest.toFixed(2)),
				total: parseFloat(total.toFixed(2)),
			});
		}
		break;
	}
	case RepaymentType.EqualPrincipal: {
		// 等额本金:每月偿还相同金额的本金,利息逐月递减
		// 每期偿还的本金 = 贷款本金 / 还款期数
		const principalPerPeriod = amount / periods;
		// 计算每期的还款明细
		for (let i = 1; i <= periods; i++) {
			// 剩余本金 = 贷款本金 - 已还本金(已还期数 -1)× 每期本金
			const remainingPrincipal = amount - principalPerPeriod * (i - 1);
			// 每期利息 = 剩余本金 × 月利率
			const interest = remainingPrincipal * monthlyRate;
			// 每期合计 = 每期本金 + 每期利息
			const total = principalPerPeriod + interest;
			// 将本期明细添加到详情数组
			result.details.push({
				period: i,
				principal: parseFloat(principalPerPeriod.toFixed(2)),
				interest: parseFloat(interest.toFixed(2)),
				total: parseFloat(total.toFixed(2)),
			});
		}
		// 计算总利息:将每期利息相加
		result.totalInterest = result.details.reduce((acc, detail) => acc + detail.interest, 0);
		break;
	}
	case RepaymentType.InterestFirst: {
		// 先息后本:前几期只还利息,最后一期偿还全部本金和剩余利息
		// 每期利息 = 贷款本金 × 月利率
		const interestPerPeriod = amount * monthlyRate;
		// 总利息 = 每期利息 × 还款月数
		result.totalInterest = interestPerPeriod * periods;
		// 计算每期的还款明细
		for (let i = 1; i <= periods; i++) {
			// 前 periods-1 期只还利息,本金为0
			// 最后一期偿还全部本金和利息
			const principal = i === periods ? amount : 0;
			const interest = interestPerPeriod;
			const total = principal + interest;
			// 将本期明细添加到详情数组
			result.details.push({
				period: i,
				principal: parseFloat(principal.toFixed(2)),
				interest: parseFloat(interest.toFixed(2)),
				total: parseFloat(total.toFixed(2)),
			});
		}
		break;
	}
	case RepaymentType.BulletPayment: {
		// 一次性还本付息:最后一期偿还全部本金和利息
		// 总利息 = 贷款本金 × 月利率 × 还款月数
		result.totalInterest = parseFloat((amount * monthlyRate * periods).toFixed(2));
		// 总还款金额 = 本金 + 总利息
		const totalPayment = parseFloat((amount + result.totalInterest).toFixed(2));

		// 只添加一条还款明细,表示最后一期偿还全部本金和利息
		result.details.push({
			period: 1, // 只有一期
			principal: parseFloat(amount.toFixed(2)), // 全部本金,保留两位小数
			interest: result.totalInterest, // 全部利息,已格式化为两位小数
			total: totalPayment, // 总还款额,已格式化为两位小数
		});
		break;
	}
	default:
		// 如果传入了不支持的还款类型,抛出错误
		throw new Error('Unsupported repayment type');
}

// 返回计算结果
return result;

} const calcDebx=(amount,rate,periods)=>{

}

export { RepaymentType, calculateLoanRepayment };