在这里插入图片描述

目录

  1. 概述
  2. 房贷计算基础
  3. 核心计算方法
  4. Kotlin 源代码
  5. JavaScript 编译代码
  6. ArkTS 调用代码
  7. 计算指标详解
  8. 实战应用

概述

购房是人生中最重要的财务决策之一。面对高额的房价和复杂的贷款方案,购房者往往需要进行详细的财务规划。房贷计算器是帮助购房者了解贷款特点、计算月供金额、制定购房财务方案的重要工具。本文档介绍如何在 Kotlin Multiplatform (KMP) 框架下,结合 OpenHarmony 鸿蒙操作系统,实现一个功能完整的房贷计算器。

房贷计算器是一个综合性的购房财务管理平台,它不仅能够计算各种贷款方案的月供,还能够进行贷款对比、生成还款计划、提供个性化的购房建议。通过KMP框架的跨端能力,这个工具可以在Android、iOS、Web和OpenHarmony等多个平台上运行,为购房者提供了一个强大的购房决策辅助工具。

房贷计算的重要性

房贷计算在现代购房中的重要性日益凸显:

  1. 财务规划:科学的计算能够帮助购房者进行合理的财务规划。
  2. 成本控制:详细的计算能够帮助购房者了解总成本。
  3. 方案对比:多方案对比能够帮助购房者选择最优方案。
  4. 风险评估:提前计算能够帮助评估购房风险。
  5. 决策支持:详细的数据能够支持购房决策。

工具的核心价值

房贷计算器提供以下价值:

  • 多种贷款方式:支持等额本息、等额本金、先息后本等多种方式
  • 灵活参数设置:支持自定义贷款金额、利率、年限等参数
  • 详细还款计划:提供月度和年度的详细还款计划
  • 贷款对比:支持多个贷款方案的对比分析
  • 成本分析:详细分析利息成本和总成本
  • 跨平台支持:一份代码可在多个平台运行,提高计算效率

房贷计算基础

核心概念

贷款金额(Loan Amount):购房者向银行借款的金额。

贷款利率(Interest Rate):银行对贷款收取的年利率。

贷款年限(Loan Term):贷款的期限,通常以年为单位。

月供(Monthly Payment):购房者每月需要偿还的金额。

总利息(Total Interest):购房者在整个贷款期间需要支付的利息总额。

还款方式(Repayment Method):贷款的还款方式,如等额本息、等额本金等。

常见的房贷计算维度

贷款维度:贷款金额、贷款利率、贷款年限等。

还款维度:月供、年供、总供等。

成本维度:利息成本、手续费、保险费等。

时间维度:还款期限、提前还款时间等。

方案维度:不同利率、不同年限、不同方式的方案对比。

风险维度:利率变化风险、还款能力风险等。

影响房贷计算的关键因素

贷款金额:贷款金额越大,月供越高。

贷款利率:利率越高,利息成本越大。

贷款年限:年限越长,月供越低但总利息越多。

还款方式:不同方式的月供和总利息不同。

利率变化:浮动利率会影响后期月供。

提前还款:提前还款能够减少利息成本。


核心计算方法

1. 等额本息计算

计算等额本息还款方式的月供和总利息。

2. 等额本金计算

计算等额本金还款方式的月供和总利息。

3. 先息后本计算

计算先息后本还款方式的月供和总利息。

4. 还款计划生成

生成详细的月度还款计划。

5. 贷款对比

对比不同贷款方案的差异。

6. 成本分析

分析贷款的成本构成。


Kotlin 源代码

// MortgageCalculator.kt
import java.time.LocalDateTime
import kotlin.math.pow

data class LoanInfo(
    val loanId: String,
    val loanAmount: Double,
    val annualRate: Double,
    val loanYears: Int,
    val repaymentMethod: String
)

data class MonthlyPayment(
    val month: Int,
    val principalPayment: Double,
    val interestPayment: Double,
    val monthlyPayment: Double,
    val remainingBalance: Double
)

data class LoanCalculation(
    val loanId: String,
    val loanAmount: Double,
    val annualRate: Double,
    val loanYears: Int,
    val repaymentMethod: String,
    val monthlyPayment: Double,
    val totalPayment: Double,
    val totalInterest: Double,
    val paymentSchedule: List<MonthlyPayment>,
    val timestamp: String
)

data class CalculationMetrics(
    val totalLoans: Long,
    val averageLoanAmount: Double,
    val averageMonthlyPayment: Double,
    val totalInterestCost: Double,
    val highestMonthlyPayment: Double,
    val lowestMonthlyPayment: Double
)

data class LoanComparison(
    val loans: List<LoanCalculation>,
    val lowestMonthlyPayment: String,
    val lowestTotalInterest: String,
    val recommendation: String
)

class MortgageCalculator {
    private val loans = mutableListOf<LoanInfo>()
    private val calculations = mutableListOf<LoanCalculation>()
    private var loanIdCounter = 0
    
    // 添加贷款
    fun addLoan(
        loanAmount: Double,
        annualRate: Double,
        loanYears: Int,
        repaymentMethod: String
    ): LoanInfo {
        val id = "LOAN${++loanIdCounter}"
        val loan = LoanInfo(id, loanAmount, annualRate, loanYears, repaymentMethod)
        loans.add(loan)
        return loan
    }
    
    // 计算房贷
    fun calculateMortgage(
        loanId: String
    ): LoanCalculation {
        val loan = loans.find { it.loanId == loanId }
            ?: return LoanCalculation("", 0.0, 0.0, 0, "", 0.0, 0.0, 0.0, emptyList(), "")
        
        val monthlyRate = loan.annualRate / 12 / 100
        val totalMonths = loan.loanYears * 12
        
        val (monthlyPayment, totalPayment, totalInterest, schedule) = when (loan.repaymentMethod) {
            "等额本息" -> calculateEqualPayment(loan.loanAmount, monthlyRate, totalMonths)
            "等额本金" -> calculateEqualPrincipal(loan.loanAmount, monthlyRate, totalMonths)
            "先息后本" -> calculateInterestFirst(loan.loanAmount, monthlyRate, totalMonths)
            else -> calculateEqualPayment(loan.loanAmount, monthlyRate, totalMonths)
        }
        
        val calculation = LoanCalculation(
            loanId, loan.loanAmount, loan.annualRate, loan.loanYears, loan.repaymentMethod,
            monthlyPayment, totalPayment, totalInterest, schedule, LocalDateTime.now().toString()
        )
        
        calculations.add(calculation)
        return calculation
    }
    
    // 等额本息计算
    private fun calculateEqualPayment(
        principal: Double,
        monthlyRate: Double,
        months: Int
    ): Tuple4<Double, Double, Double, List<MonthlyPayment>> {
        val monthlyPayment = principal * monthlyRate * (1 + monthlyRate).pow(months) / 
                             ((1 + monthlyRate).pow(months) - 1)
        val totalPayment = monthlyPayment * months
        val totalInterest = totalPayment - principal
        
        val schedule = mutableListOf<MonthlyPayment>()
        var remainingBalance = principal
        
        for (month in 1..months) {
            val interestPayment = remainingBalance * monthlyRate
            val principalPayment = monthlyPayment - interestPayment
            remainingBalance -= principalPayment
            
            schedule.add(MonthlyPayment(
                month, principalPayment, interestPayment, monthlyPayment, 
                maxOf(remainingBalance, 0.0)
            ))
        }
        
        return Tuple4(monthlyPayment, totalPayment, totalInterest, schedule)
    }
    
    // 等额本金计算
    private fun calculateEqualPrincipal(
        principal: Double,
        monthlyRate: Double,
        months: Int
    ): Tuple4<Double, Double, Double, List<MonthlyPayment>> {
        val principalPayment = principal / months
        val schedule = mutableListOf<MonthlyPayment>()
        var totalInterest = 0.0
        var remainingBalance = principal
        var totalPayment = 0.0
        
        for (month in 1..months) {
            val interestPayment = remainingBalance * monthlyRate
            val monthlyPayment = principalPayment + interestPayment
            remainingBalance -= principalPayment
            totalInterest += interestPayment
            totalPayment += monthlyPayment
            
            schedule.add(MonthlyPayment(
                month, principalPayment, interestPayment, monthlyPayment,
                maxOf(remainingBalance, 0.0)
            ))
        }
        
        return Tuple4(schedule[0].monthlyPayment, totalPayment, totalInterest, schedule)
    }
    
    // 先息后本计算
    private fun calculateInterestFirst(
        principal: Double,
        monthlyRate: Double,
        months: Int
    ): Tuple4<Double, Double, Double, List<MonthlyPayment>> {
        val monthlyInterest = principal * monthlyRate
        val schedule = mutableListOf<MonthlyPayment>()
        var totalInterest = 0.0
        
        for (month in 1 until months) {
            totalInterest += monthlyInterest
            schedule.add(MonthlyPayment(
                month, 0.0, monthlyInterest, monthlyInterest, principal
            ))
        }
        
        val lastPayment = principal + monthlyInterest
        totalInterest += monthlyInterest
        schedule.add(MonthlyPayment(
            months, principal, monthlyInterest, lastPayment, 0.0
        ))
        
        val totalPayment = principal + totalInterest
        return Tuple4(monthlyInterest, totalPayment, totalInterest, schedule)
    }
    
    // 获取计算指标
    fun getCalculationMetrics(): CalculationMetrics {
        if (calculations.isEmpty()) {
            return CalculationMetrics(0, 0.0, 0.0, 0.0, 0.0, 0.0)
        }
        
        val totalLoans = loans.size.toLong()
        val averageLoanAmount = calculations.map { it.loanAmount }.average()
        val averageMonthlyPayment = calculations.map { it.monthlyPayment }.average()
        val totalInterestCost = calculations.map { it.totalInterest }.sum()
        val highestMonthlyPayment = calculations.maxOf { it.monthlyPayment }
        val lowestMonthlyPayment = calculations.minOf { it.monthlyPayment }
        
        return CalculationMetrics(
            totalLoans, averageLoanAmount, averageMonthlyPayment, totalInterestCost,
            highestMonthlyPayment, lowestMonthlyPayment
        )
    }
    
    // 获取所有计算
    fun getAllCalculations(): List<LoanCalculation> {
        return calculations.toList()
    }
    
    // 贷款对比
    fun compareLoans(loanIds: List<String>): LoanComparison {
        val comparisonCalcs = calculations.filter { it.loanId in loanIds }
        
        val lowestMonthlyPayment = comparisonCalcs.minByOrNull { it.monthlyPayment }
            ?.let { ${String.format("%.2f", it.monthlyPayment)}" } ?: ""
        val lowestTotalInterest = comparisonCalcs.minByOrNull { it.totalInterest }
            ?.let { ${String.format("%.2f", it.totalInterest)}" } ?: ""
        
        val avgMonthly = comparisonCalcs.map { it.monthlyPayment }.average()
        val recommendation = when {
            avgMonthly < 5000 -> "月供较低,还款压力小"
            avgMonthly < 10000 -> "月供适中,还款压力适度"
            else -> "月供较高,需要谨慎评估还款能力"
        }
        
        return LoanComparison(comparisonCalcs, lowestMonthlyPayment, lowestTotalInterest, recommendation)
    }
    
    // 生成还款报告
    fun generateMortgageReport(): Map<String, Any> {
        val metrics = getCalculationMetrics()
        
        return mapOf(
            "timestamp" to LocalDateTime.now().toString(),
            "metrics" to metrics,
            "calculations" to calculations.toList(),
            "recommendations" to generateRecommendations(metrics)
        )
    }
    
    // 生成建议
    private fun generateRecommendations(metrics: CalculationMetrics): List<String> {
        val recommendations = mutableListOf<String>()
        
        if (metrics.averageMonthlyPayment < 5000) {
            recommendations.add("💰 平均月供较低,购房压力小")
        } else if (metrics.averageMonthlyPayment > 10000) {
            recommendations.add("💰 平均月供较高,需要谨慎评估")
        }
        
        if (metrics.totalInterestCost > 1000000) {
            recommendations.add("📊 总利息成本较高,可考虑提前还款")
        }
        
        recommendations.add("✅ 根据自身情况选择合适的贷款方案")
        
        return recommendations
    }
    
    // 清空数据
    fun clearData() {
        loans.clear()
        calculations.clear()
    }
}

// 辅助数据类
data class Tuple4<A, B, C, D>(val first: A, val second: B, val third: C, val fourth: D)

fun main() {
    val calculator = MortgageCalculator()
    
    // 添加贷款
    calculator.addLoan(3000000.0, 4.1, 30, "等额本息")
    calculator.addLoan(3000000.0, 4.1, 30, "等额本金")
    
    // 计算房贷
    val calc1 = calculator.calculateMortgage("LOAN1")
    val calc2 = calculator.calculateMortgage("LOAN2")
    
    println("房贷计算结果:")
    println("${calc1.repaymentMethod}: 月供 ¥${String.format("%.2f", calc1.monthlyPayment)}, 总利息 ¥${String.format("%.2f", calc1.totalInterest)}")
    println("${calc2.repaymentMethod}: 月供 ¥${String.format("%.2f", calc2.monthlyPayment)}, 总利息 ¥${String.format("%.2f", calc2.totalInterest)}")
    
    // 生成报告
    val report = calculator.generateMortgageReport()
    println("\n房贷报告已生成")
}

Kotlin代码说明:这个Kotlin实现提供了完整的房贷计算功能。MortgageCalculator 类能够管理贷款信息、进行房贷计算、生成还款计划、进行贷款对比。通过使用数据类和科学的计算方法,代码既简洁又准确。系统支持多种还款方式,从单个贷款的详细计算到多个贷款的对比分析,为购房者提供了全面的房贷决策支持。


JavaScript 编译代码

// MortgageCalculator.js
class LoanInfo {
    constructor(loanId, loanAmount, annualRate, loanYears, repaymentMethod) {
        this.loanId = loanId;
        this.loanAmount = loanAmount;
        this.annualRate = annualRate;
        this.loanYears = loanYears;
        this.repaymentMethod = repaymentMethod;
    }
}

class MonthlyPayment {
    constructor(month, principalPayment, interestPayment, monthlyPayment, remainingBalance) {
        this.month = month;
        this.principalPayment = principalPayment;
        this.interestPayment = interestPayment;
        this.monthlyPayment = monthlyPayment;
        this.remainingBalance = remainingBalance;
    }
}

class LoanCalculation {
    constructor(loanId, loanAmount, annualRate, loanYears, repaymentMethod, monthlyPayment, totalPayment, totalInterest, paymentSchedule, timestamp) {
        this.loanId = loanId;
        this.loanAmount = loanAmount;
        this.annualRate = annualRate;
        this.loanYears = loanYears;
        this.repaymentMethod = repaymentMethod;
        this.monthlyPayment = monthlyPayment;
        this.totalPayment = totalPayment;
        this.totalInterest = totalInterest;
        this.paymentSchedule = paymentSchedule;
        this.timestamp = timestamp;
    }
}

class CalculationMetrics {
    constructor(totalLoans, averageLoanAmount, averageMonthlyPayment, totalInterestCost, highestMonthlyPayment, lowestMonthlyPayment) {
        this.totalLoans = totalLoans;
        this.averageLoanAmount = averageLoanAmount;
        this.averageMonthlyPayment = averageMonthlyPayment;
        this.totalInterestCost = totalInterestCost;
        this.highestMonthlyPayment = highestMonthlyPayment;
        this.lowestMonthlyPayment = lowestMonthlyPayment;
    }
}

class MortgageCalculator {
    constructor() {
        this.loans = [];
        this.calculations = [];
        this.loanIdCounter = 0;
    }
    
    addLoan(loanAmount, annualRate, loanYears, repaymentMethod) {
        const id = `LOAN${++this.loanIdCounter}`;
        const loan = new LoanInfo(id, loanAmount, annualRate, loanYears, repaymentMethod);
        this.loans.push(loan);
        return loan;
    }
    
    calculateMortgage(loanId) {
        const loan = this.loans.find(l => l.loanId === loanId);
        if (!loan) return null;
        
        const monthlyRate = loan.annualRate / 12 / 100;
        const totalMonths = loan.loanYears * 12;
        
        let monthlyPayment, totalPayment, totalInterest, schedule;
        
        if (loan.repaymentMethod === "等额本息") {
            [monthlyPayment, totalPayment, totalInterest, schedule] = this.calculateEqualPayment(loan.loanAmount, monthlyRate, totalMonths);
        } else if (loan.repaymentMethod === "等额本金") {
            [monthlyPayment, totalPayment, totalInterest, schedule] = this.calculateEqualPrincipal(loan.loanAmount, monthlyRate, totalMonths);
        } else if (loan.repaymentMethod === "先息后本") {
            [monthlyPayment, totalPayment, totalInterest, schedule] = this.calculateInterestFirst(loan.loanAmount, monthlyRate, totalMonths);
        } else {
            [monthlyPayment, totalPayment, totalInterest, schedule] = this.calculateEqualPayment(loan.loanAmount, monthlyRate, totalMonths);
        }
        
        const calculation = new LoanCalculation(loanId, loan.loanAmount, loan.annualRate, loan.loanYears, loan.repaymentMethod, monthlyPayment, totalPayment, totalInterest, schedule, new Date().toISOString());
        
        this.calculations.push(calculation);
        return calculation;
    }
    
    calculateEqualPayment(principal, monthlyRate, months) {
        const monthlyPayment = principal * monthlyRate * Math.pow(1 + monthlyRate, months) / (Math.pow(1 + monthlyRate, months) - 1);
        const totalPayment = monthlyPayment * months;
        const totalInterest = totalPayment - principal;
        
        const schedule = [];
        let remainingBalance = principal;
        
        for (let month = 1; month <= months; month++) {
            const interestPayment = remainingBalance * monthlyRate;
            const principalPayment = monthlyPayment - interestPayment;
            remainingBalance -= principalPayment;
            
            schedule.push(new MonthlyPayment(month, principalPayment, interestPayment, monthlyPayment, Math.max(remainingBalance, 0)));
        }
        
        return [monthlyPayment, totalPayment, totalInterest, schedule];
    }
    
    calculateEqualPrincipal(principal, monthlyRate, months) {
        const principalPayment = principal / months;
        const schedule = [];
        let totalInterest = 0;
        let remainingBalance = principal;
        let totalPayment = 0;
        
        for (let month = 1; month <= months; month++) {
            const interestPayment = remainingBalance * monthlyRate;
            const monthlyPayment = principalPayment + interestPayment;
            remainingBalance -= principalPayment;
            totalInterest += interestPayment;
            totalPayment += monthlyPayment;
            
            schedule.push(new MonthlyPayment(month, principalPayment, interestPayment, monthlyPayment, Math.max(remainingBalance, 0)));
        }
        
        return [schedule[0].monthlyPayment, totalPayment, totalInterest, schedule];
    }
    
    calculateInterestFirst(principal, monthlyRate, months) {
        const monthlyInterest = principal * monthlyRate;
        const schedule = [];
        let totalInterest = 0;
        
        for (let month = 1; month < months; month++) {
            totalInterest += monthlyInterest;
            schedule.push(new MonthlyPayment(month, 0, monthlyInterest, monthlyInterest, principal));
        }
        
        const lastPayment = principal + monthlyInterest;
        totalInterest += monthlyInterest;
        schedule.push(new MonthlyPayment(months, principal, monthlyInterest, lastPayment, 0));
        
        const totalPayment = principal + totalInterest;
        return [monthlyInterest, totalPayment, totalInterest, schedule];
    }
    
    getCalculationMetrics() {
        if (this.calculations.length === 0) {
            return new CalculationMetrics(0, 0, 0, 0, 0, 0);
        }
        
        const totalLoans = this.loans.length;
        const averageLoanAmount = this.calculations.reduce((sum, c) => sum + c.loanAmount, 0) / this.calculations.length;
        const averageMonthlyPayment = this.calculations.reduce((sum, c) => sum + c.monthlyPayment, 0) / this.calculations.length;
        const totalInterestCost = this.calculations.reduce((sum, c) => sum + c.totalInterest, 0);
        const highestMonthlyPayment = Math.max(...this.calculations.map(c => c.monthlyPayment));
        const lowestMonthlyPayment = Math.min(...this.calculations.map(c => c.monthlyPayment));
        
        return new CalculationMetrics(totalLoans, averageLoanAmount, averageMonthlyPayment, totalInterestCost, highestMonthlyPayment, lowestMonthlyPayment);
    }
    
    getAllCalculations() {
        return this.calculations;
    }
    
    compareLoans(loanIds) {
        const comparisonCalcs = this.calculations.filter(c => loanIds.includes(c.loanId));
        
        const lowestMonthlyPayment = comparisonCalcs.reduce((min, c) => c.monthlyPayment < min.monthlyPayment ? c : min);
        const lowestTotalInterest = comparisonCalcs.reduce((min, c) => c.totalInterest < min.totalInterest ? c : min);
        
        const avgMonthly = comparisonCalcs.reduce((sum, c) => sum + c.monthlyPayment, 0) / comparisonCalcs.length;
        let recommendation;
        if (avgMonthly < 5000) recommendation = "月供较低,还款压力小";
        else if (avgMonthly < 10000) recommendation = "月供适中,还款压力适度";
        else recommendation = "月供较高,需要谨慎评估还款能力";
        
        return {
            loans: comparisonCalcs,
            lowestMonthlyPayment: `¥${lowestMonthlyPayment.monthlyPayment.toFixed(2)}`,
            lowestTotalInterest: `¥${lowestTotalInterest.totalInterest.toFixed(2)}`,
            recommendation: recommendation
        };
    }
    
    generateMortgageReport() {
        const metrics = this.getCalculationMetrics();
        
        return {
            timestamp: new Date().toISOString(),
            metrics: metrics,
            calculations: this.calculations,
            recommendations: this.generateRecommendations(metrics)
        };
    }
    
    generateRecommendations(metrics) {
        const recommendations = [];
        
        if (metrics.averageMonthlyPayment < 5000) {
            recommendations.push("💰 平均月供较低,购房压力小");
        } else if (metrics.averageMonthlyPayment > 10000) {
            recommendations.push("💰 平均月供较高,需要谨慎评估");
        }
        
        if (metrics.totalInterestCost > 1000000) {
            recommendations.push("📊 总利息成本较高,可考虑提前还款");
        }
        
        recommendations.push("✅ 根据自身情况选择合适的贷款方案");
        
        return recommendations;
    }
    
    clearData() {
        this.loans = [];
        this.calculations = [];
    }
}

// 使用示例
const calculator = new MortgageCalculator();

calculator.addLoan(3000000, 4.1, 30, "等额本息");
calculator.addLoan(3000000, 4.1, 30, "等额本金");

const calc1 = calculator.calculateMortgage("LOAN1");
const calc2 = calculator.calculateMortgage("LOAN2");

console.log("房贷计算结果:");
console.log(`${calc1.repaymentMethod}: 月供 ¥${calc1.monthlyPayment.toFixed(2)}, 总利息 ¥${calc1.totalInterest.toFixed(2)}`);
console.log(`${calc2.repaymentMethod}: 月供 ¥${calc2.monthlyPayment.toFixed(2)}, 总利息 ¥${calc2.totalInterest.toFixed(2)}`);

const report = calculator.generateMortgageReport();
console.log("\n房贷报告已生成");

JavaScript代码说明:JavaScript版本是Kotlin代码的直接转译。我们使用ES6的class语法定义各个类,使用数学函数进行计算。整体逻辑和算法与Kotlin版本保持一致,确保跨平台的一致性。JavaScript的灵活性使得代码更加简洁,同时保持了清晰的结构和完整的功能。


ArkTS 调用代码

// MortgageCalculatorPage.ets
import { MortgageCalculator } from './MortgageCalculator';

@Entry
@Component
struct MortgageCalculatorPage {
    @State loanAmount: number = 3000000;
    @State annualRate: number = 4.1;
    @State loanYears: number = 30;
    @State repaymentMethod: string = '等额本息';
    @State selectedTab: number = 0;
    @State calculations: Array<any> = [];
    @State metrics: any = null;
    @State isLoading: boolean = false;
    @State errorMessage: string = '';
    @State report: any = null;
    
    private calculator: MortgageCalculator = new MortgageCalculator();
    private repaymentMethods = ['等额本息', '等额本金', '先息后本'];
    
    addAndCalculate() {
        if (this.loanAmount <= 0) {
            this.errorMessage = '请输入有效的贷款金额';
            return;
        }
        
        this.isLoading = true;
        this.errorMessage = '';
        
        try {
            this.calculator.addLoan(
                this.loanAmount,
                this.annualRate,
                this.loanYears,
                this.repaymentMethod
            );
            
            const loanId = `LOAN${this.calculator.loans.length}`;
            this.calculator.calculateMortgage(loanId);
            
            this.calculations = this.calculator.getAllCalculations();
            this.metrics = this.calculator.getCalculationMetrics();
            
            AlertDialog.show({ message: '房贷已计算' });
            
            // 重置表单
            this.loanAmount = 3000000;
            this.annualRate = 4.1;
            this.loanYears = 30;
        } catch (error) {
            this.errorMessage = '计算失败: ' + error.message;
        } finally {
            this.isLoading = false;
        }
    }
    
    generateReport() {
        this.isLoading = true;
        
        try {
            this.report = this.calculator.generateMortgageReport();
        } catch (error) {
            this.errorMessage = '生成报告失败: ' + error.message;
        } finally {
            this.isLoading = false;
        }
    }
    
    build() {
        Column() {
            Text('房贷计算器')
                .fontSize(24)
                .fontWeight(FontWeight.Bold)
                .margin({ top: 20, bottom: 20 })
            
            Tabs({ barPosition: BarPosition.Start }) {
                TabContent() {
                    Column() {
                        Text('贷款参数').fontSize(14).fontWeight(FontWeight.Bold).margin({ bottom: 15 })
                        
                        Text('贷款金额(元):').fontSize(12).margin({ bottom: 5 })
                        TextInput({ placeholder: '3000000' })
                            .type(InputType.Number)
                            .value(this.loanAmount.toString())
                            .onChange((value: string) => { this.loanAmount = parseFloat(value) || 0; })
                            .height(40).padding(10).border({ width: 1, color: '#cccccc' }).margin({ bottom: 15 })
                        
                        Row() {
                            Column() {
                                Text('年利率(%):').fontSize(12).margin({ bottom: 5 })
                                TextInput({ placeholder: '4.1' })
                                    .type(InputType.Number)
                                    .value(this.annualRate.toString())
                                    .onChange((value: string) => { this.annualRate = parseFloat(value) || 0; })
                                    .height(40).padding(10).border({ width: 1, color: '#cccccc' })
                            }
                            .flex(1)
                            
                            Column() {
                                Text('贷款年限(年):').fontSize(12).margin({ bottom: 5 })
                                TextInput({ placeholder: '30' })
                                    .type(InputType.Number)
                                    .value(this.loanYears.toString())
                                    .onChange((value: string) => { this.loanYears = parseInt(value) || 0; })
                                    .height(40).padding(10).border({ width: 1, color: '#cccccc' })
                            }
                            .flex(1)
                            .margin({ left: 10 })
                        }
                        .margin({ bottom: 15 })
                        
                        Text('还款方式:').fontSize(12).margin({ bottom: 5 })
                        Select(this.repaymentMethods.map(m => ({ value: m })))
                            .value(this.repaymentMethod)
                            .onSelect((index: number, value?: string) => {
                                this.repaymentMethod = value || '等额本息';
                            })
                            .height(40).margin({ bottom: 15 })
                        
                        Button('计算房贷').width('100%').height(40).margin({ bottom: 15 })
                            .onClick(() => { this.addAndCalculate(); }).enabled(!this.isLoading)
                        
                        if (this.errorMessage) {
                            Text(this.errorMessage).fontSize(12).fontColor('#F44336').margin({ bottom: 15 })
                        }
                    }
                    .padding(15)
                }
                .tabBar('➕ 计算')
                
                TabContent() {
                    Column() {
                        if (this.calculations.length > 0) {
                            Text('计算结果').fontSize(16).fontWeight(FontWeight.Bold).margin({ bottom: 15 })
                            
                            List() {
                                ForEach(this.calculations, (calc: any) => {
                                    ListItem() {
                                        Column() {
                                            Row() {
                                                Text(calc.repaymentMethod).fontSize(14).fontWeight(FontWeight.Bold).flex(1)
                                                Text(`¥${calc.monthlyPayment.toFixed(2)}`).fontSize(12).fontColor('#2196F3')
                                                    .fontWeight(FontWeight.Bold)
                                            }
                                            .margin({ bottom: 10 })
                                            
                                            Row() {
                                                Text('贷款金额:').fontSize(11)
                                                Text(`¥${calc.loanAmount.toFixed(0)}`).fontSize(11).fontWeight(FontWeight.Bold)
                                            }
                                            .margin({ bottom: 5 })
                                            
                                            Row() {
                                                Text('总利息:').fontSize(11)
                                                Text(`¥${calc.totalInterest.toFixed(2)}`).fontSize(11).fontWeight(FontWeight.Bold)
                                            }
                                            .margin({ bottom: 5 })
                                            
                                            Row() {
                                                Text('总金额:').fontSize(11)
                                                Text(`¥${calc.totalPayment.toFixed(2)}`).fontSize(11).fontWeight(FontWeight.Bold)
                                            }
                                        }
                                        .padding(10).border({ width: 1, color: '#eeeeee' }).borderRadius(5)
                                    }
                                }, (calc: any) => calc.loanId)
                            }
                        } else {
                            Text('请先计算房贷').fontSize(12).fontColor('#999999')
                        }
                    }
                    .padding(15)
                }
                .tabBar('📊 结果')
                
                TabContent() {
                    Column() {
                        if (this.metrics) {
                            Text('统计指标').fontSize(16).fontWeight(FontWeight.Bold).margin({ bottom: 15 })
                            
                            Row() {
                                Column() {
                                    Text('平均月供').fontSize(11).fontColor('#999999')
                                    Text(`¥${this.metrics.averageMonthlyPayment.toFixed(0)}`).fontSize(18)
                                        .fontWeight(FontWeight.Bold).fontColor('#2196F3').margin({ top: 5 })
                                }
                                .flex(1).alignItems(HorizontalAlign.Center).padding(15).backgroundColor('#F5F5F5').borderRadius(5)
                                
                                Column() {
                                    Text('总利息').fontSize(11).fontColor('#999999')
                                    Text(`¥${this.metrics.totalInterestCost.toFixed(0)}`).fontSize(18)
                                        .fontWeight(FontWeight.Bold).fontColor('#FF9800').margin({ top: 5 })
                                }
                                .flex(1).alignItems(HorizontalAlign.Center).padding(15).backgroundColor('#F5F5F5').borderRadius(5)
                                .margin({ left: 10 })
                            }
                            .margin({ bottom: 15 })
                            
                            Column() {
                                Row() {
                                    Text('最高月供:').fontSize(12)
                                    Text(`¥${this.metrics.highestMonthlyPayment.toFixed(2)}`).fontSize(12).fontWeight(FontWeight.Bold)
                                }
                                .margin({ bottom: 10 })
                                
                                Row() {
                                    Text('最低月供:').fontSize(12)
                                    Text(`¥${this.metrics.lowestMonthlyPayment.toFixed(2)}`).fontSize(12).fontWeight(FontWeight.Bold)
                                }
                                .margin({ bottom: 10 })
                                
                                Row() {
                                    Text('平均贷款:').fontSize(12)
                                    Text(`¥${this.metrics.averageLoanAmount.toFixed(0)}`).fontSize(12).fontWeight(FontWeight.Bold)
                                }
                            }
                            .padding(10).backgroundColor('#F5F5F5').borderRadius(5)
                        } else {
                            Text('请先计算房贷').fontSize(12).fontColor('#999999')
                        }
                    }
                    .padding(15)
                }
                .tabBar('📈 指标')
                
                TabContent() {
                    Column() {
                        Button('生成报告').width('100%').height(40).margin({ bottom: 15 })
                            .onClick(() => { this.generateReport(); })
                        
                        if (this.report) {
                            Text('房贷报告').fontSize(16).fontWeight(FontWeight.Bold).margin({ bottom: 15 })
                            
                            if (this.report.recommendations && this.report.recommendations.length > 0) {
                                Text('建议:').fontSize(14).fontWeight(FontWeight.Bold).margin({ bottom: 10 })
                                
                                Column() {
                                    ForEach(this.report.recommendations, (rec: string, index: number) => {
                                        Row() {
                                            Text('•').fontSize(14).fontWeight(FontWeight.Bold).margin({ right: 10 })
                                            Text(rec).fontSize(11).flex(1)
                                        }
                                        .padding(10).margin({ bottom: 8 }).backgroundColor('#E3F2FD').borderRadius(5)
                                    }, (rec: string, index: number) => index.toString())
                                }
                            }
                        }
                    }
                    .padding(15)
                }
                .tabBar('📋 报告')
            }
            .width('100%')
            .flex(1)
        }
        .padding(10)
        .width('100%')
        .height('100%')
    }
}

ArkTS代码说明:这个ArkTS实现展示了如何在OpenHarmony应用中集成房贷计算器。通过使用标签页组件,用户可以在参数输入、结果查看、指标统计和报告生成之间切换。UI设计直观,提供了良好的用户体验。每个标签页都有不同的功能,用户可以全面地进行房贷计算和财务规划。


计算指标详解

房贷计算维度

贷款金额:购房者向银行借款的金额,通常以万元为单位。

年利率:银行对贷款收取的年利率,通常以百分比表示。

贷款年限:贷款的期限,通常为5年、10年、20年、30年等。

月供:购房者每月需要偿还的金额,是购房者最关心的指标。

总利息:购房者在整个贷款期间需要支付的利息总额。

总金额:贷款本金加上总利息,是购房者需要支付的总金额。

还款方式

等额本息:每月还款金额相同,前期利息多本金少,后期本金多利息少。

等额本金:每月还款本金相同,利息逐月递减,前期还款压力大。

先息后本:前期只还利息,最后一期还本金和利息,适合短期贷款。


实战应用

应用场景1:购房前规划

购房者可以使用这个计算器进行购房前的财务规划,了解不同贷款方案的差异。

应用场景2:贷款方案对比

购房者可以对比不同银行、不同利率、不同年限的贷款方案,选择最优方案。

应用场景3:还款计划制定

购房者可以生成详细的还款计划,了解每月的还款情况。

应用场景4:提前还款评估

购房者可以评估提前还款的效果,制定最优的还款策略。


总结

房贷计算器是现代购房中的重要工具。通过KMP框架和OpenHarmony操作系统的结合,我们可以实现一个功能完整、高效可靠的房贷计算系统。

这个工具不仅能够计算各种贷款方案的月供和总利息,还能够进行贷款对比、生成还款计划、提供个性化的购房建议。通过本文介绍的Kotlin实现、JavaScript编译和ArkTS调用,购房者可以快速构建自己的房贷计算系统。

在实际应用中,房贷计算的价值远不止于此。从帮助购房者做出最优决策到支持银行进行贷款管理,从促进房地产市场发展到推动金融创新,房贷计算都发挥着重要的作用。通过持续改进和优化,可以构建更加科学和高效的房贷计算体系。

掌握好房贷计算的方法和工具,对于实现购房梦想和进行财务规划都有重要的帮助。通过这个系统的学习和使用,希望能够帮助购房者更好地进行房贷计算,制定科学的购房方案,最终成功实现购房目标。欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net

Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐