index.js 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  1. /**
  2. * FeHelper 进制转换工具
  3. */
  4. new Vue({
  5. el: '#containerPayback',
  6. data: {
  7. money: 10000,
  8. months: 12,
  9. yearRate: 24,
  10. paybackMode: 1,
  11. billList: [],
  12. formula: {
  13. "1": '等额本息:月供=贷款本金×[年化利率÷12×(1+年化利率÷12) ^ 还款月数]÷{[(1+年化利率÷12) ^ 还款月数]-1}',
  14. "2": '等额本金:月供=贷款本金÷还款月数x(1+年化利率÷12x剩余还款期数)'
  15. }
  16. },
  17. mounted: function () {
  18. // 进制转换的初始化
  19. this.paybackConvert();
  20. },
  21. methods: {
  22. paybackConvert: function () {
  23. this.$nextTick(() => {
  24. if (!this.dataCheck()) {
  25. return;
  26. }
  27. if (parseInt(this.paybackMode) === 1) {
  28. this.avgCapitalPlusInterest();
  29. } else {
  30. this.avgCapitalOnly();
  31. }
  32. });
  33. },
  34. /**
  35. * 数据合法性校验
  36. */
  37. dataCheck: function () {
  38. if (!this.money || /\D/.test(this.money) || parseInt(this.money) <= 0) {
  39. alert('请输入正确的贷款金额!');
  40. return false;
  41. }
  42. if (!this.months || /\D/.test(this.months) || parseInt(this.months) <= 0) {
  43. alert('请输入正确的贷款期限!');
  44. return false;
  45. }
  46. if (parseInt(this.months) > 360) {
  47. alert('在哪儿能贷30年?');
  48. return false;
  49. }
  50. if (!this.yearRate || /\D|\./.test(this.yearRate) || parseFloat(this.yearRate) <= 0) {
  51. alert('请输入正确的贷款年化利率!');
  52. return false;
  53. }
  54. return true;
  55. },
  56. /**
  57. * 等额本息计算方式
  58. * 每月还款额=贷款本金×[月利率×(1+月利率) ^ 还款月数]÷{[(1+月利率) ^ 还款月数]-1}
  59. */
  60. avgCapitalPlusInterest: function () {
  61. let rate = this.yearRate / 12 / 100;
  62. let mRate = Math.pow(rate + 1, this.months);
  63. // 每月账单金额
  64. let bill = Math.round(this.money * rate * mRate / (mRate - 1) * 100) / 100;
  65. // 累计还款额
  66. let allBillsAmount = bill * this.months;
  67. // 总利息
  68. let allInterest = allBillsAmount - this.money;
  69. // 剩余本金
  70. let leftOver = this.money;
  71. // 剩余利息
  72. let leftInterest = allInterest;
  73. // 剩余期限
  74. let leftTime = this.months;
  75. // 每期利息
  76. let interest = 0;
  77. // 每期本金
  78. let amount = 0;
  79. // 累计数据先入队
  80. this.billList = [{
  81. name: '合计',
  82. amount: Number(this.money).toFixed(2),
  83. interest: (Math.round(allInterest * 100) / 100).toFixed(2),
  84. bill: (Math.round(allBillsAmount * 100) / 100).toFixed(2),
  85. totalAmount:'-',
  86. totalInterest: '-',
  87. leftOver: (Math.round(leftOver * 100) / 100).toFixed(2),
  88. leftInterest: (Math.round(allInterest * 100) / 100).toFixed(2)
  89. }];
  90. // 生成账单列表
  91. for (; leftTime > 0; leftTime--) {
  92. mRate = Math.pow(rate + 1, leftTime || 0);
  93. // 特殊处理最后一期
  94. if (leftTime === 1) {
  95. interest = leftInterest;
  96. amount = leftOver;
  97. } else {
  98. // 月供利息
  99. interest = leftOver * rate;
  100. // 月供本金
  101. amount = bill - interest;
  102. }
  103. leftOver -= amount;
  104. leftInterest -= interest;
  105. this.billList.push({
  106. name: `第${this.months - leftTime + 1}期`,
  107. amount: (Math.round(amount * 100) / 100).toFixed(2),
  108. interest: (Math.round(interest * 100) / 100).toFixed(2),
  109. bill: (Math.round(bill * 100) / 100).toFixed(2),
  110. totalAmount:(Math.round((this.money - leftOver) * 100) / 100).toFixed(2),
  111. totalInterest: (Math.round((allInterest - leftInterest) * 100) / 100).toFixed(2),
  112. leftOver: (Math.round(leftOver * 100) / 100).toFixed(2),
  113. leftInterest: (Math.round(leftInterest * 100) / 100).toFixed(2)
  114. });
  115. }
  116. },
  117. /**
  118. * 等额本金还款公式
  119. *
  120. * 月供本金=贷款本金÷还款月数
  121. * 月供利息=月供本金×月利率x剩余还款期数
  122. * 月供总额=月供本金+月供利率 = 贷款本金÷还款月数x(1+月利率x剩余还款期数)
  123. *
  124. */
  125. avgCapitalOnly: function () {
  126. let rate = this.yearRate / 12 / 100;
  127. let amount = this.money / this.months;
  128. let deltaInterest = amount * rate;
  129. let allBillsAmount = (amount + this.money * rate + amount * (1 + rate)) / 2 * this.months;
  130. let allInterest = allBillsAmount - this.money;
  131. // 剩余本金
  132. let leftOver = this.money;
  133. // 剩余利息
  134. let leftInterest = allInterest;
  135. // 累计数据先入队
  136. this.billList = [{
  137. name: '合计',
  138. amount: Number(this.money).toFixed(2),
  139. interest: (Math.round(allInterest * 100) / 100).toFixed(2),
  140. bill: (Math.round(allBillsAmount * 100) / 100).toFixed(2),
  141. totalAmount:'-',
  142. totalInterest: '-',
  143. leftOver: (Math.round(leftOver * 100) / 100).toFixed(2),
  144. leftInterest: (Math.round(allInterest * 100) / 100).toFixed(2)
  145. }];
  146. // 每期利息
  147. let interest = 0;
  148. // 生成账单列表
  149. for (let leftTime = this.months; leftTime > 0; leftTime--) {
  150. interest = leftTime * deltaInterest;
  151. leftOver -= amount;
  152. leftInterest -= interest;
  153. this.billList.push({
  154. name: `第${this.months - leftTime + 1}期`,
  155. amount: (Math.round(amount * 100) / 100).toFixed(2),
  156. interest: (Math.round(interest * 100) / 100).toFixed(2),
  157. bill: (Math.round((amount + interest) * 100) / 100).toFixed(2),
  158. totalAmount:(Math.round((this.money - leftOver) * 100) / 100).toFixed(2),
  159. totalInterest: (Math.round((allInterest - leftInterest) * 100) / 100).toFixed(2),
  160. leftOver: (Math.round(leftOver * 100) / 100).toFixed(2),
  161. leftInterest: (Math.round(leftInterest * 100) / 100).toFixed(2)
  162. });
  163. }
  164. }
  165. }
  166. });