商业贷

如果有利率浮动 就调整相应的利率, 例: 利率上浮10% 利率 = 利率 + 利率 x 10%

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    .item {
      display: flex;
      margin-top: 30px;
    }
    button {
      margin-top: 30px;
    }
  </style>
</head>
<body>
  <div id="app">
    <div class="item">
      <div>总金额:(/万)</div>
      <input type="number" v-model="total" name="" id="">
    </div>
    <div class="item">
      <div>利率:(%)</div>
      <input type="number" v-model="rate" name="" id="">
    </div>
    <div class="item">
      <div>期限:(/年)</div>
      <input type="number" v-model="year" name="" id="">
    </div>
    
    <div class="item">
      <div>月供:</div>
      <input type="text" v-model="result" name="" id="">
    </div>
    <div class="item">
      <div>还款总额:</div>
      <input type="text" v-model="total_er" name="" id="">
    </div>
    <div class="item">
      <div>利息总额:</div>
      <input type="text" v-model="total_lixi" name="" id="">
    </div>
    <div class="item">
      <div>递减</div>
      <input type="text" v-model="dijian" name="" id="">
    </div>
    <button @click="compontedBX">计算等额本息</button>
    <button @click="compontedBJ">计算等额本金</button>

    <div class="item" v-for="(item, index) in list" :key="index">
      <div> {{index + 1}} </div>--
      <div> {{item.res}} </div>--
      <div> {{item.yu}} </div>
    </div>

  </div>
  <script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.10/vue.common.dev.js"></script>
  <script>
    var vm = new Vue({
      el: '#app',
      data() {
        return {
          total: 10,
          rate: 4.9,
          year: 10,
          result: '',
          list: [],
          total_lixi: '',
          total_er: '',
          dijian: ''
        }
      },
      computed: {
        c_total() {
          return this.total * 10000
        },
        c_rate() {
          return this.rate / 100 / 12
        },
        c_mouths() {
          return this.year * 12
        }
      },
      methods: {
        // 等额本息  每月还本付息金额=[贷款本金×月利率×(1+月利率)^还款月数]÷[(1+月利率)^还款月数-1]

        // 每月应还利息=贷款本金×月利率×〔(1+月利率)^还款月数-(1+月利率)^(还款月序号-1)〕÷〔(1+月利率)^还款月数-1〕

        // 每月应还本金=贷款本金×月利率×(1+月利率)^(还款月序号-1)÷〔(1+月利率)^还款月数-1〕

        // 总利息=还款月数×每月月供额-贷款本金
        compontedBX() {
          // 每月月供       贷款本金      月利率                                       还款总月数 例: 10 年 就是 10 * 12 = 120 期
          let result = (this.c_total * this.c_rate * Math.pow( 1 + this.c_rate, this.c_mouths )) / ( Math.pow(1 + this.c_rate, this.c_mouths) - 1 )
          
          this.result = result.toFixed(2)
          let total_rate = result.toFixed(2) * this.c_mouths
          for(let i = 1; i <= this.c_mouths; i++) {
            this.list.push({res: result.toFixed(2), yu: (total_rate- result.toFixed(2) * i).toFixed(2)})
          }
          // 总利息
          this.total_lixi = (this.c_mouths * result - this.c_total).toFixed(2)
          this.total_er = (Number(this.total_lixi) + Number(this.c_total)).toFixed(2)
          console.log(result)
        },
        // 等额本金的计算公式为: 每月还本付息金额=(本金/还款月数)+(本金-累计已还本金)×月利率
        //  每月应还本金=贷款本金÷还款月数

        // 每月应还利息=剩余本金×月利率=(贷款本金-已归还本金累计额)×月利率。

        // 每月月供递减额=每月应还本金×月利率=贷款本金÷还款月数×月利率

        // 总利息=(还款月数+1)×贷款总额×月利率÷2
        compontedBJ() {
          // 月供
          let res
          // 已还本金
          let yhbj = 0;
          // 已还的本息
          let yhbx = 0
          // 贷款本金                还款月数                月利率
          let total = this.c_total, mouths = this.c_mouths, rate = this.c_rate
          res = (total / mouths) + (total - yhbj) * rate
          res = res.toFixed(2)
          yhbx = res + yhbx
          this.result = res
          this.total_lixi = (mouths + 1) * total * rate / 2
          this.total_er = this.total_lixi + this.c_total 
          this.list.push({res: res, yu: (this.total_er - yhbx).toFixed(2)})
          this.dijian = (total / mouths * rate).toFixed(2)
          for(let i = 1; i <= mouths; i++) {
            yhbj = total / mouths * i
            res = (total / mouths) + (total - yhbj) * rate
            res = res.toFixed(2)
            yhbx = Number(res) + Number(yhbx)
            this.list.push({res: res, yu: (this.total_er - yhbx).toFixed(2)})
          }
        }
      }
    })

// ---------------------------------------------------------------------------------------------


  </script>
</body>
</html>

公积金贷

和商业贷差不多 ,只是利率不同

组合贷

就是把 商业贷 和公积金贷 分别算出来, 然后再相加

在uniapp上新增了完整代码

// 参数选择页面

<template>
	<view>
		<!-- 贷款类型 -->
		<view class="type-box">
			<view class="item" :class="{select: type==1}" @tap="setType(1)">
				商业贷款
			</view>
			<view class="item" :class="{select: type==2}" @tap="setType(2)">
				公积金贷款
			</view>
			<view class="item" :class="{select: type==3}" @tap="setType(3)">
				组合贷款
			</view>
		</view>
		<!-- 商贷 -->
		<view class="content" v-if="type == 1">
			<view class="item">
				<text>商业贷款总额:</text>
				<view class="" style="display: flex;">
					<input class="inp" type="number" v-model="total" />/万元
				</view>
			</view>
			<view class="item">
				<text>商业贷款利率:</text>
				<view class="" style="display: flex;">
					<input class="inp" type="number" v-model="lilv" />(默认4.9%)
				</view>
			</view>
			<view class="item">
				<text>商业贷款利率浮动:</text>
				<picker mode="selector" :range="rateChange" :range-key="'text'" @change="pickerChange">
					<view>{{ rateChange[rateIndex].text }}</view>
				</picker>
			</view>
			<view class="item">
				<text>贷款年限:</text>
				<picker mode="selector" :range="yearList" :range-key="'text'" @change="pickerChangeYear">
					<view>{{ yearList[yearListIndex].text }}</view>
				</picker>
			</view>
		</view>
		
		<!-- 公积金贷 -->
		<view class="content" v-if="type == 2">
			<view class="item">
				<text>公积金贷款总额:</text>
				<view class="" style="display: flex;">
					<input class="inp" type="number" v-model="total_g" />/万元
				</view>
			</view>
			<view class="item">
				<text>公积金贷款利率:</text>
				<view class="" style="display: flex;">
					<input class="inp" type="number" v-model="lilv_g" />(默认3.25%)
				</view>
			</view>
			<view class="item">
				<text>公积金贷款利率浮动:</text>
				<picker mode="selector" :range="rateChange" :range-key="'text'" @change="pickerChange_g">
					<view>{{ rateChange[rateIndex_g].text }}</view>
				</picker>
			</view>
			<view class="item">
				<text>贷款年限:</text>
				<picker mode="selector" :range="yearList" :range-key="'text'" @change="pickerChangeYear">
					<view>{{ yearList[yearListIndex].text }}</view>
				</picker>
			</view>
		</view>
		
		<!-- 组合贷 -->
		<view class="content" v-if="type == 3">
			<view class="item">
				<text>商业贷款总额:</text>
				<view class="" style="display: flex;">
					<input class="inp" type="number" v-model="total" />/万元
				</view>
			</view>
			<view class="item">
				<text>公积金贷款总额:</text>
				<view class="" style="display: flex;">
					<input class="inp" type="number" v-model="total_g" />/万元
				</view>
			</view>
			<view class="item">
				<text>商业贷款利率:</text>
				<view class="" style="display: flex;">
					<input class="inp" type="number" v-model="lilv" />(默认4.9%)
				</view>
			</view>
			<view class="item">
				<text>公积金贷款利率:</text>
				<view class="" style="display: flex;">
					<input class="inp" type="number" v-model="lilv_g" />(默认3.25%)
				</view>
			</view>
			<view class="item">
				<text>商业贷款利率浮动:</text>
				<picker mode="selector" :range="rateChange" :range-key="'text'" @change="pickerChange">
					<view>{{ rateChange[rateIndex].text }}</view>
				</picker>
			</view>
			<view class="item">
				<text>公积金贷款利率浮动:</text>
				<picker mode="selector" :range="rateChange" :range-key="'text'" @change="pickerChange_g">
					<view>{{ rateChange[rateIndex_g].text }}</view>
				</picker>
			</view>
			<view class="item">
				<text>贷款年限:</text>
				<picker mode="selector" :range="yearList" :range-key="'text'" @change="pickerChangeYear">
					<view>{{ yearList[yearListIndex].text }}</view>
				</picker>
			</view>
		</view>
		<button class="btn" type="primary" @tap="handleResult">计算结果</button>
		
	</view>
</template>

<script>
	export default {
		data() {
			return {
				type: 1,
				total: '',// 商贷总额
				lilv: 4.9,// 商贷利率
				total_g: '',// 公积金总额
				lilv_g: 3.25,// 公积金利率
				// 利率浮动列表
				rateChange: [
					{text: '基准利率7成', num: 0.7},
					{text: '基准利率8成', num: 0.8},
					{text: '基准利率9成', num: 0.9},
					{text: '基准利率', num: 1},
					{text: '基准利率上浮5%', num: 1.05},
					{text: '基准利率上浮10%', num: 1.1},
					{text: '基准利率上浮15%', num: 1.15},
					{text: '基准利率上浮20%', num: 1.2},
					{text: '基准利率上浮25%', num: 1.25},
					{text: '基准利率上浮30%', num: 1.3},
				],
				rateIndex: 3,// 利率浮动列表下标
				rateIndex_g: 3,
				yearList: [
					{text: '5年(60期)', num: 60},
					{text: '10年(120期)', num: 120},
					{text: '15年(180期)', num: 180},
					{text: '20年(240期)', num: 240},
					{text: '25年(300期)', num: 300},
					{text: '30年(360期)', num: 360},
				],
				yearListIndex: 1
			}
		},
		computed: {
			lilv_result() {
				return this.lilv / (100 * 12)
			},
			mouths() {
				return this.year * 12
			}
		},
		methods: {
			setType(id) {
				if(this.type !== id) {
					this.total = ''
					this.total_g = ''
					this.rateIndex = 3
					this.rateIndex_g = 3
					this.yearListIndex = 1
					this.type = id
				}
			},
			pickerChange(e) {
				this.rateIndex = e.target.value
				console.log(e.target.value)
			},
			pickerChange_g(e) {
				this.rateIndex_g = e.target.value
				console.log(e.target.value)
			},
			pickerChangeYear(e) {
				this.yearListIndex = e.target.value
				console.log(e.target.value)
			},
			// 开始计算
			handleResult() {
				let isTrue = 1
				if(this.type == 1) {
					if(this.total == '') { isTrue = 2 }
				} else if(this.type == 2) {
					if(this.total_g == '') { isTrue = 2 }
				} else {
					if(this.total_g == '' || this.total == '') { isTrue = 2 }
				}
				if(isTrue === 2) {
					uni.showToast({ title: '请输入金额', icon:'none' }); return false
				}
				let data = {}
				if(this.type == 1) {
					data.type = 1
					data.total = this.total * 10000
					data.rate = this.lilv * this.rateChange[this.rateIndex].num / 12 / 100
				} else if(this.type == 2) {
					data.type = 2
					data.total = this.total_g * 10000
					data.rate = this.lilv_g * this.rateChange[this.rateIndex_g].num / 12 / 100
				} else {
					data.type = 3
					data.total = this.total * 10000
					data.total_g = this.total_g * 10000
					data.rate = this.lilv * this.rateChange[this.rateIndex].num / 12 / 100
					data.rate_g = this.lilv_g * this.rateChange[this.rateIndex_g].num / 12 / 100
				}
				data.mouths = this.yearList[this.yearListIndex].num
				//this.$navTo('/pages/computedResult/computedResult?data=' + encodeURIComponent(JSON.stringify(data)))
				uni.navigateTo({
					url: '/pages/computedResult/computedResult?data=' + encodeURIComponent(JSON.stringify(data))),
				 	success: res => {},
				 	fail: () => {},
				 	complete: () => {}
				});
			},
			
		}
	}
</script>

<style lang="scss">
	.type-box {
		display: flex;
		justify-content: space-around;
		margin: 20rpx auto;
		.item {
			line-height: 56rpx;
			padding: 0 auto;
		}
		.select {
			border-bottom: 1px solid #1296db;
			color: #1296db;
		}
	}
	.content {
		width: 90%;
		margin: 0 auto;
		.item {
			height: 80rpx;
			display: flex;
			justify-content: space-between;
			align-items: center;
			border-bottom: 1rpx solid #333;
			color: #666;
			.inp {
				border: 1rpx solid #ccc;
				border-radius: 10rpx;
				text-align: right;
				width: 200rpx;
			}
		}
	}
	.xian {
		width: 750rpx;
		height: 1px;
		border-bottom: 1px solid #007AFF;
	}
	.btn {
		margin-top: 60rpx;
	}
</style>

// 计算结果页面

<template>
	<view>
		<view class="type-box">
			<view class="item" :class="{select: type==1}" @tap="setType(1)">
				本息
			</view>
			<view class="item" :class="{select: type==2}" @tap="setType(2)">
				本金
			</view>
		</view>
		
		<!-- 月供 总利息 总利息+贷款金额 渲染一个列表 -->
		<view class="">
			月供:{{result}}
		</view>
		<view class="">
			总利息:{{total_lixi}}
		</view>
		<view class="">
			贷款金额 + 总利息:{{total_er}}
		</view>
		<view class="">
			递减:{{dijian}}
		</view>
		<view class="list">
			<view class="item">
				<view class="item-item">期数</view>
				<view class="item-item">月供</view>
				<view class="item-item">剩余</view>
			</view>
			<view class="item" v-for="(item, index) in list" :key="index">
				<view class="item-item">{{index + 1}}</view>
				<view class="item-item">{{item.res}}</view>
				<view class="item-item">{{item.yu}}</view>
			</view>
		</view>
	</view>
</template>

<script>
	export default {
		data() {
			return {
				type: 1,// 1本息   2本金
				datas: {},
				list: [],
				result: '',// 月供
				total_lixi: '',//总利息
				dijian: '',// 递减
				total_er: ''// 贷款金额 + 总利息
			}
		},
		onLoad(option) {
			let data = JSON.parse(decodeURIComponent(option.data));
			console.log(data)
			this.datas = data
			this.computedResult()
		},
		methods: {
			setType(id) {
				if(this.type !== id) {
					this.type = id
					this.computedResult()
				}
			},
			// 计算结果
			computedResult() {
				let data = {list: []}
				// 判断是否组合贷
				if(this.datas.type == 3) {
					let data1, data2
					// 判断是 本息 还是本金
					if(this.type == 1) {
						data1 = this.computedBX(this.datas.total, this.datas.rate, this.datas.mouths)
						data2 = this.computedBX(this.datas.total_g, this.datas.rate_g, this.datas.mouths)
					} else {
						data1 = this.computedBJ(this.datas.total, this.datas.rate, this.datas.mouths)
						data2 = this.computedBJ(this.datas.total_g, this.datas.rate_g, this.datas.mouths)
					}
					data.result = Number(data1.result.toFixed(2)) + Number(data2.result.toFixed(2))
					data.total_lixi = Number(data1.total_lixi) + Number(data2.total_lixi)
					data.total_er = Number(data1.total_er) + Number(data2.total_er)
					data.total = Number(data1.total) + Number(data2.total)
					data.dijian = Number(data1.dijian.toFixed(2)) + Number(data2.dijian.toFixed(2))
					for(let i = 0; i < data1.list.length; i++) {
						data1.list[i].res = ( Number(data1.list[i].res) + Number(data2.list[i].res) ).toFixed(2)
						data1.list[i].yu = ( Number(data1.list[i].yu) + Number(data2.list[i].yu) ).toFixed(2)
						// data.list.push({
						// 	res: Number(data1.list[i].res) + Number(data2.list[i].res),
						// 	yu: Number(data1.list[i].yu) + Number(data2.list[i].yu)
						// })
					}
					data.list = data1.list
				} else {
					// 判断是 本息 还是本金
					if(this.type == 1) {
						data = this.computedBX(this.datas.total, this.datas.rate, this.datas.mouths)
					} else {
						data = this.computedBJ(this.datas.total, this.datas.rate, this.datas.mouths)
					}
				}
				this.list = data.list
				this.result = data.result.toFixed(2)
				this.total_lixi = data.total_lixi.toFixed(2)
				this.dijian = data.dijian
				this.total_er = data.total_er.toFixed(2)

			},
			// 等额本息计算方法
			computedBX(total, rate, mouths) {
				// 等额本息  每月还本付息金额=[贷款本金×月利率×(1+月利率)^还款月数]÷[(1+月利率)^还款月数-1]
				// 每月应还利息=贷款本金×月利率×〔(1+月利率)^还款月数-(1+月利率)^(还款月序号-1)〕÷〔(1+月利率)^还款月数-1〕
				// 每月应还本金=贷款本金×月利率×(1+月利率)^(还款月序号-1)÷〔(1+月利率)^还款月数-1〕
				// 总利息=还款月数×每月月供额-贷款本金
				let result = (total * rate * Math.pow(1 + rate, mouths)) / (Math.pow(1 + rate, mouths) - 1)

				// result = result.toFixed(2)
				let total_rate = result.toFixed(2) * mouths
				let list = []
				for (let i = 1; i <= mouths; i++) {
					list.push({
						res: Number( result.toFixed(2) ),
						yu: Number( (total_rate - result.toFixed(2) * i).toFixed(2) )
					})
				}
				// 总利息
				let total_lixi = Number( (mouths * result - total).toFixed(2) )
				// 总利息 + 贷款本金
				let total_er = Number( (Number(total_lixi) + Number(total)).toFixed(2) )
				
				return {
					result: Number( result.toFixed(2) ),
					total_lixi,
					total_er,
					list,
					total,
					dijian: 0
				}
			},
			// 等额本金计算方法
			// 贷款本金  月利率 还款月数 
			computedBJ(total, rate, mouths) {
				// 等额本金的计算公式为: 每月还本付息金额=(本金/还款月数)+(本金-累计已还本金)×月利率
				//  每月应还本金=贷款本金÷还款月数
				// 每月应还利息=剩余本金×月利率=(贷款本金-已归还本金累计额)×月利率。
				// 每月月供递减额=每月应还本金×月利率=贷款本金÷还款月数×月利率
				// 总利息=(还款月数+1)×贷款总额×月利率÷2
				
				// 月供
				let res
				// 已还本金
				let yhbj = 0;
				// 已还的本息
				let yhbx = 0
				// 递减金额
				let dijian
				res = (total / mouths) + (total - yhbj) * rate
				res = res.toFixed(2)
				yhbx = res + yhbx
				let result = Number(res)
				let total_lixi = (mouths + 1) * total * rate / 2
				let total_er = total_lixi + total
				let list = []
				list.push({
					res: res,
					yu: (total_er - yhbx).toFixed(2)
				})
				dijian = Number( (total / mouths * rate).toFixed(2) )
				for (let i = 1; i < mouths; i++) {
					yhbj = total / mouths * i
					res = (total / mouths) + (total - yhbj) * rate
					res = res.toFixed(2)
					yhbx = Number(res) + Number(yhbx)
					list.push({
						res: res,
						yu: Number( (total_er - yhbx).toFixed(2) )
					})
				}
				return {
					result,
					total_lixi,
					total_er,
					list,
					total,
					dijian
				}
			},
			

		}
	}
</script>

<style lang="scss">
	.list {
		.item {
			display: flex;
			justify-content: space-around;
			.item-item {
				flex: 1;
			}
		}
	}
	.type-box {
		display: flex;
		justify-content: space-around;
		margin: 20rpx auto;
		.item {
			line-height: 56rpx;
			padding: 0 auto;
		}
		.select {
			border-bottom: 1px solid #1296db;
			color: #1296db;
		}
	}
</style>