房贷计算器
概念
计算公式
月供金额 = 月供本金 + 月供利息
月供利息 =(总贷款额 - 已还本金)* 月利率
等额本金
等额本金是每个月偿还的本金相同,利息逐月减少,总贷款利息较少,起始月供较高,每月递减。
月供本金 = 总贷款额/月供期数
月供金额 = (总贷款额/月供期数) + 月供利息
等额本息
每个月偿还的月供金额相同,月供本金随利息的减少逐月递增,总贷款利息较高,月供固定不变,相对月供较低。
月供金额 = 总贷款额 * 月利率 * ( 1+月利率 ) ^ 还款期数 / ( ( 1+月利率 ) ^ 还款期数 -1 )
月供本金 = 月供金额 - 月供利息
代码
/** @Description: 房贷计算器* @Date: 2025-03-27 20:00:07*/
import React, { useState, useEffect } from 'react';
import { Button, Form, InputNumber, Table, Tabs } from 'antd';const FormItem = Form.Item;
const { TabPane } = Tabs;const MortgageCalculator = () => {const [form] = Form.useForm();const [activeKey, setActiveKey] = useState('1');/** 等额本息表格 */const [interestData, setInterestData] = useState<any>([]);/** 等额本金表格 */const [principalData, setPrincipalData] = useState<any>([]);useEffect(() => {if (activeKey === '1') {equalPrincipal();} else {equalInterest();}}, [activeKey])const calculateLoans = () => {if (activeKey === '1') {equalPrincipal();} else {equalInterest();}}/** 等额本息 */const equalInterest = () => {form.validateFields();const formValue = form.getFieldsValue();// 贷款期数const month = Number(formValue.years || 0) * 12;// 公积金总金额const providentFundAmount = Number(formValue.providentFundAmount || 0) * 10000;// 商业贷总金额const commercialLoanAmount = Number(formValue.commercialLoanAmount || 0) * 10000;// 公积金月利率const monthProvidentFundRate = Number(formValue.providentFundRate || 0) / 100 / 12;// 商业贷月利率const monthCommercialLoanRate = Number(formValue.commercialLoanRate || 0) / 100 / 12;// 每月还款额=总贷款额 * 月利率 * ( 1+月利率 ) ^ 还款期数 / ( ( 1+月利率 ) ^ 还款期数 -1 )let monthProvidentAmount = 0;if (providentFundAmount) {monthProvidentAmount = (providentFundAmount * monthProvidentFundRate * (Math.pow(1 + monthProvidentFundRate, month))) / (Math.pow(1 + monthProvidentFundRate, month) - 1);}let monthCommercialAmount = 0;if (commercialLoanAmount) {monthCommercialAmount = (commercialLoanAmount * monthCommercialLoanRate * (Math.pow(1 + monthCommercialLoanRate, month))) / (Math.pow(1 + monthCommercialLoanRate, month) - 1);}// 每月月供金额const monthAmount = monthProvidentAmount + monthCommercialAmount;// 已还公积金本金let repaymentProvidentPrincipal = 0;// 已还商贷本金let repaymentCommercialPrincipal = 0;// 已还公积金利息let repaymentProvidentInterest = 0;// 已还商贷利息let repaymentCommercialInterest = 0;const newInterestData: Record<string, any> = [];for (let i = 0; i < month; i++) {// 公积金月利息const monthProvidentInterest = getMonthInterest(providentFundAmount, repaymentProvidentPrincipal, Number(formValue.providentFundRate || 0));// 商业贷月利息const monthCommercialInterest = getMonthInterest(commercialLoanAmount, repaymentCommercialPrincipal, Number(formValue.commercialLoanRate || 0));// 月利息const monthInterest = monthProvidentInterest + monthCommercialInterest;// 已还本金 = 商业贷已还本金 + 公积金已还本金const repaymentAmount = repaymentProvidentPrincipal + repaymentCommercialPrincipal;newInterestData.push({period: i + 1,monthAmount: monthAmount,remainingAmount: providentFundAmount + commercialLoanAmount - repaymentAmount,repaymentAmount: repaymentAmount,repaymentInterest: repaymentProvidentInterest + repaymentCommercialInterest,monthPrincipal: monthAmount - monthInterest,monthInterest: monthInterest});repaymentProvidentPrincipal += (monthProvidentAmount - monthProvidentInterest);repaymentCommercialPrincipal += monthCommercialAmount - monthCommercialInterest;repaymentProvidentInterest += monthProvidentInterest;repaymentCommercialInterest += monthCommercialInterest;}setInterestData(newInterestData);}/** 等额本金 */const equalPrincipal = () => {form.validateFields();const formValue = form.getFieldsValue();// 贷款期数const month = Number(formValue.years || 0) * 12;// 公积金总金额const providentFundAmount = Number(formValue.providentFundAmount || 0) * 10000;// 商业贷总金额const commercialLoanAmount = Number(formValue.commercialLoanAmount || 0) * 10000// 公积金贷款月供本金const monthProvidentPrincipal = providentFundAmount / month;// 商业贷款月供本金const monthCommercialLoanPrincipal = commercialLoanAmount / month;// 月供本金const monthPrincipal = monthProvidentPrincipal + monthCommercialLoanPrincipal;// 已还公积金本金let repaymentProvidentPrincipal = 0;// 已还商贷本金let repaymentCommercialPrincipal = 0;// 已还公积金利息let repaymentProvidentInterest = 0;// 已还商贷利息let repaymentCommercialInterest = 0;const newPrincipalData: Record<string, any> = [];for (let i = 0; i < month; i++) {// 公积金月利息const monthProvidentInterest = getMonthInterest(providentFundAmount, repaymentProvidentPrincipal, Number(formValue.providentFundRate || 0));// 商业贷月利息const monthCommercialInterest = getMonthInterest(commercialLoanAmount, repaymentCommercialPrincipal, Number(formValue.commercialLoanRate || 0));// 月利息const monthInterest = monthProvidentInterest + monthCommercialInterest;// 月供金额 = 月利息 + 月供本金const monthAmount = monthInterest + monthPrincipal;// 已还本金 = 商业贷已还本金 + 公积金已还本金const repaymentAmount = repaymentProvidentPrincipal + repaymentCommercialPrincipal;newPrincipalData.push({period: i + 1,monthAmount: monthAmount,remainingAmount: providentFundAmount + commercialLoanAmount - repaymentAmount,repaymentAmount: repaymentAmount,repaymentInterest: repaymentProvidentInterest + repaymentCommercialInterest,monthPrincipal: monthPrincipal,monthInterest: monthInterest});repaymentProvidentPrincipal += monthProvidentPrincipal;repaymentCommercialPrincipal += monthCommercialLoanPrincipal;repaymentProvidentInterest += monthProvidentInterest;repaymentCommercialInterest += monthCommercialInterest;}setPrincipalData(newPrincipalData);}/** 每月应还利息 */const getMonthInterest = (amount: number,repaymentPrincipal: number,rate: number,) => {// 月利率const monthRate = rate / 100 / 12;// 每月应还利息 = (贷款本金-已还本金)*月利率return (amount - repaymentPrincipal) * monthRate;}/** 金额格式化 */const formatMoney = (value: number) => {if (value > 10000) {return (value / 10000).toFixed(2) + "万元";}return value.toFixed(2) + "元";}const columns = [{title: '期数',dataIndex: 'period',},{title: '月供总金额',dataIndex: 'monthAmount',render: (text, record) => {return formatMoney(text);},},{title: '月供本金',dataIndex: 'monthPrincipal',render: (text, record) => {return formatMoney(text);},},{title: '月供利息',dataIndex: 'monthInterest',render: (text, record) => {return formatMoney(text);},},{title: '剩余本金',dataIndex: 'remainingAmount',render: (text, record) => {return formatMoney(text);},},{title: '已还本金',dataIndex: 'repaymentAmount',render: (text, record) => {return formatMoney(text);},},{title: '已还利息',dataIndex: 'repaymentInterest',render: (text, record) => {return formatMoney(text);},},]return (<div><Form layout="vertical" form={form} initialValues={{years: 30,providentFundAmount: 60,providentFundRate: 2.85,commercialLoanAmount: 16,commercialLoanRate: 3.0,}}><FormItem label="贷款年限" name="years" required rules={[{ required: true, message: '请输入贷款年限' }]}><InputNumber addonAfter="年" style={{ width: 300 }} /></FormItem><FormItem label="公积金贷款金额" name="providentFundAmount"><InputNumber addonAfter="万" style={{ width: 300 }} /></FormItem><FormItem label="公积金贷款年利率" name="providentFundRate" ><InputNumber addonAfter="%" style={{ width: 300 }} /></FormItem><FormItem label="商业贷款金额" name="commercialLoanAmount"><InputNumber addonAfter="万" style={{ width: 300 }} /></FormItem><FormItem label="商业贷款年利率" name="commercialLoanRate" ><InputNumber addonAfter="%" style={{ width: 300 }} /></FormItem><FormItem ><Button type="primary" onClick={calculateLoans}>计算</Button></FormItem></Form><Tabs onChange={(activeKey: string) => setActiveKey(activeKey)}><TabPane tab="等额本金" key="1"><div>概念:每个月偿还的本金不变,利息逐月减少,总贷款利息较少,起始月供较高,每月递减。</div><div style={{ display: 'flex' }}><div style={{ marginRight: 24 }}>贷款总额度:{formatMoney(principalData[0]?.remainingAmount || 0)}</div><div>贷款总利息:{formatMoney(principalData[principalData.length - 1]?.repaymentInterest || 0)}</div></div><Table columns={columns} pagination={false} dataSource={principalData} /></TabPane><TabPane tab="等额本息" key="2"><div>概念:每个月偿还的月供固定,月供本金随利息的减少逐月递增,总贷款利息较高,月供固定不变,相对每月偿还基数较低。</div><div style={{ display: 'flex' }}><div style={{ marginRight: 24 }}>贷款总额度:{formatMoney(interestData[0]?.remainingAmount || 0)}</div><div>贷款总利息:{formatMoney(interestData[interestData.length - 1]?.repaymentInterest || 0)}</div></div><Table columns={columns} pagination={false} dataSource={interestData} /></TabPane></Tabs></div>)
}export default MortgageCalculator;
效果图