当前位置: 首页 > news >正文

房贷计算器

废话不多说,直接上代码。

/*
 * @Description: 房贷计算器
 * @LastEditTime: 2025-03-28 09:51:08
 */
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 = () => {
        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 = () => {
        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">
                    <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;

效果图

在这里插入图片描述
在这里插入图片描述

相关文章:

  • Python 中常用的内置数据结构详解
  • 六十天前端强化训练之第三十七天之Docker 容器化部署实战指南(大师级详解)
  • 【Linux】U-Boot 加载并启动 Linux 系统程序
  • Linux C++ 利用 io_uring 技术批量读取 tun 文件描述符的数据。
  • 基于大模型预测的慢性稳定性心绞痛全周期管理系统技术方案文档
  • Flink介绍——发展历史
  • 克魔ios开发助手查看苹果手机各个硬件组件使用历史记录和耗能历史记录
  • MySQL主从数据库搭建
  • sort排序
  • 使用Python进行数据挖掘时如何有效的数据脱敏?
  • 资源单元(RU)分配和映射
  • 【JavaScript】十一、DOM对象的获取和修改
  • 多输入多输出 | Matlab实现CPO-LSTM冠豪猪算法优化长短期记忆神经网络多输入多输出预测
  • 05-02-自考数据结构(20331)- 动态查找-知识点
  • 离线知识库文档问答用唤醒+VOSK离线听写+DS-V2-16B+离线合成轻松高效实现
  • Rocky Linux 9.5中完美迁移mysql5.6.17到mysql5.7.11
  • 20250330-傅里叶级数专题之离散时间傅里叶变换(4/6)
  • js 强引用 ​弱引用
  • leetcode 28 Find the Index of the First Occurrence in a String
  • uv vs pip 速度实测
  • 网上做预算有哪些网站/加盟教育培训哪个好
  • 网站空间500mb/定制网站建设推广服务
  • 网站搭建的步骤/亚马逊免费的关键词工具
  • 泰安网站开发哪家便宜/免费发广告的平台有哪些
  • 工业设计手绘/seo还有用吗
  • 广州网站设计企业/开发一个app需要多少钱