Browse Source

增加还款计算器小工具

zxlie 6 years ago
parent
commit
f6be624fd7

+ 2 - 2
apps/manifest.json

@@ -1,6 +1,6 @@
 {
-  "name": "WEB前端助手(FeHelper)",
-  "version": "2019.05.0816",
+  "name": "WEB前端助手(FeHelper)-Dev",
+  "version": "2019.05.2816",
   "manifest_version": 2,
   "default_locale": "zh_CN",
   "description": "FE助手:JSON格式化、JSON比对、二维码生成与解码、信息编解码、代码压缩&美化、页面取色、Markdown与HTML、网页截屏、编码设置、正则、时间转换、网页性能检测、Ajax调试、密码生成器、便签笔记、chrome插件下载等",

BIN
apps/options/donate.png


File diff suppressed because it is too large
+ 0 - 0
apps/options/index.html


BIN
apps/static/screenshot/crx/WEB前端助手(FeHelper)_v2019.05.2816.crx


+ 1 - 1
apps/toolkit/index.html

@@ -1 +1 @@
-<!DOCTYPE HTML>
<html lang="zh-CN">
    <head>
        <title>多维小工具集</title>
        <meta charset="UTF-8">
        <link rel="stylesheet" href="../static/vendor/jquery/jquery-ui.min.css">
        <link rel="stylesheet" href="index.css" />
        <script type="text/javascript" src="../static/vendor/vue/vue.js"></script>
        <script src="../static/vendor/require/require.js"></script>
    </head>
    <body>

    <div class="wrapper" id="pageContainer">
        <div class="panel panel-default" style="margin-bottom: 0px;">
            <div class="panel-heading">
                <h3 class="panel-title">
                    <a href="http://www.baidufe.com/fehelper/feedback.html" target="_blank" class="x-a-high">
                        <img src="../static/img/fe-16.png" alt="fehelper"/> FeHelper</a>:多维小工具集</h3>
            </div>
        </div>
        <div class="panel-body mod-password">

            <div class="row">
                <div id="tabs">
                    <ul>
                        <li><a href="#tab-radix">进制转换</a></li>
                        <li><a href="#tab-color">颜色转换</a></li>
                    </ul>

                    <div id="tab-radix" class="mod-tab"></div>
                    <div id="tab-color" class="mod-tab"></div>

                </div>
            </div>

        </div>
    </div>
    <script src="../static/vendor/jquery/jquery-3.3.1.min.js"></script>
    <script src="../static/vendor/jquery/jquery.extend.js"></script>
    <script type="text/javascript" src="../static/vendor/jquery/jquery-ui.min.js"></script>
    <script type="text/javascript" src="index.js"></script>
    </body>
</html>
+<!DOCTYPE HTML>
<html lang="zh-CN">
    <head>
        <title>多维小工具集</title>
        <meta charset="UTF-8">
        <link rel="stylesheet" href="../static/vendor/jquery/jquery-ui.min.css">
        <link rel="stylesheet" href="index.css" />
        <script type="text/javascript" src="../static/vendor/vue/vue.js"></script>
        <script src="../static/vendor/require/require.js"></script>
    </head>
    <body>

    <div class="wrapper" id="pageContainer">
        <div class="panel panel-default" style="margin-bottom: 0px;">
            <div class="panel-heading">
                <h3 class="panel-title">
                    <a href="http://www.baidufe.com/fehelper/feedback.html" target="_blank" class="x-a-high">
                        <img src="../static/img/fe-16.png" alt="fehelper"/> FeHelper</a>:多维小工具集</h3>
            </div>
        </div>
        <div class="panel-body mod-password">

            <div class="row">
                <div id="tabs">
                    <ul>
                        <li v-for="t in Object.keys(tools)"><a :href="'#tab-'+t">{{tools[t]}}</a></li>
                    </ul>

                    <div v-for="t in Object.keys(tools)" :id="'tab-'+t" class="mod-tab"></div>
                </div>
            </div>

        </div>
    </div>
    <script src="../static/vendor/jquery/jquery-3.3.1.min.js"></script>
    <script src="../static/vendor/jquery/jquery.extend.js"></script>
    <script type="text/javascript" src="../static/vendor/jquery/jquery-ui.min.js"></script>
    <script type="text/javascript" src="index.js"></script>
    </body>
</html>

+ 12 - 7
apps/toolkit/index.js

@@ -4,10 +4,12 @@
 new Vue({
     el: '#pageContainer',
     data: {
-        loadManager: {
-            radix: 0,
-            color: 0
-        }
+        tools: {
+            radix: '进制转换',
+            color: '颜色转换',
+            payback: '还款计算器'
+        },
+        loadManager: {}
     },
 
     mounted: function () {
@@ -15,11 +17,16 @@ new Vue({
         // 通过Tab的切换,来动态加载小工具
         jQuery('#tabs').tabs({
             show: (event, ui) => {
+
                 window.location.hash = ui.panel.id;
                 let widget = ui.panel.id.replace('tab-', '');
+
+                document.title = '多维小工具集 - ' + this.tools[widget];
+
                 if (this.loadManager[widget]) {
                     return;
                 }
+
                 fetch(widget + '/index.html').then(resp => {
                     resp.text().then(html => {
                         this.loadManager[widget] = true;
@@ -42,7 +49,5 @@ new Vue({
         });
     },
 
-    methods: {
-
-    }
+    methods: {}
 });

+ 73 - 0
apps/toolkit/payback/index.css

@@ -0,0 +1,73 @@
+.mod-radios {
+    font-size: 14px;
+}
+.mod-value label{
+    margin-right: 0;
+    font-size: 16px;
+}
+.mod-value .x-input {
+    display: inline-block;
+    width: 400px;
+}
+select.x-select {
+    display: inline-block;
+    width: 114px;
+}
+.radix-tips {
+    margin-left: 160px;
+    font-size: 12px;
+    color: #bbb;
+    font-style: italic;
+}
+
+#containerPayback table th {
+    vertical-align: middle;
+    text-align: center;
+    background-color: #f9f9f9;
+}
+#containerPayback table td {
+    font-weight: normal;
+    font-size: 14px;
+}
+#containerPayback table td.x-name {
+    text-align: center;
+}
+#containerPayback table td.x-bill {
+    color: #000;
+}
+#containerPayback table td.x-left {
+     color: #aaa;
+}
+#containerPayback table tr.x-all,
+#containerPayback table tr.x-last td.x-total {
+    background-color: #ffffe4;
+}
+#containerPayback table tr.x-all td.x-name ,
+#containerPayback table tr.x-all td.x-bill ,
+#containerPayback table tr.x-all td.x-amount ,
+#containerPayback table tr.x-all td.x-interest  {
+    color: #f00;
+}
+.mod-inputs {
+    font-size: 14px;
+}
+.mod-inputs .form-control {
+    width: 120px;
+    display: inline-block;
+    margin:0 10px 10px 0;
+}
+.mod-inputs label {
+    margin-right: 0;
+}
+.mod-inputs .x-sp {
+    margin-left: 50px;
+}
+.mod-inputs span {
+    color: #aaa;
+}
+#containerPayback .x-tips {
+    margin: 10px 0 20px 0;
+}
+#containerPayback .x-btn {
+    margin-left: 20px;
+}

File diff suppressed because it is too large
+ 0 - 0
apps/toolkit/payback/index.html


+ 194 - 0
apps/toolkit/payback/index.js

@@ -0,0 +1,194 @@
+/**
+ * FeHelper 进制转换工具
+ */
+new Vue({
+    el: '#containerPayback',
+    data: {
+        money: 10000,
+        months: 12,
+        yearRate: 24,
+        paybackMode: 1,
+        billList: [],
+        formula: {
+            "1": '等额本息:月供=贷款本金×[年化利率÷12×(1+年化利率÷12) ^ 还款月数]÷{[(1+年化利率÷12) ^ 还款月数]-1}',
+            "2": '等额本金:月供=贷款本金÷还款月数x(1+年化利率÷12x剩余还款期数)'
+        }
+    },
+
+    mounted: function () {
+        // 进制转换的初始化
+        this.paybackConvert();
+    },
+
+    methods: {
+
+        paybackConvert: function () {
+
+            this.$nextTick(() => {
+
+                if (!this.dataCheck()) {
+                    return;
+                }
+
+                if (parseInt(this.paybackMode) === 1) {
+                    this.avgCapitalPlusInterest();
+                } else {
+                    this.avgCapitalOnly();
+                }
+            });
+        },
+
+        /**
+         * 数据合法性校验
+         */
+        dataCheck: function () {
+            if (!this.money || /\D/.test(this.money) || parseInt(this.money) <= 0) {
+                alert('请输入正确的贷款金额!');
+                return false;
+            }
+            if (!this.months || /\D/.test(this.months) || parseInt(this.months) <= 0) {
+                alert('请输入正确的贷款期限!');
+                return false;
+            }
+            if (parseInt(this.months) > 360) {
+                alert('在哪儿能贷30年?');
+                return false;
+            }
+            if (!this.yearRate || /\D|\./.test(this.yearRate) || parseFloat(this.yearRate) <= 0) {
+                alert('请输入正确的贷款年化利率!');
+                return false;
+            }
+            return true;
+        },
+
+        /**
+         * 等额本息计算方式
+         * 每月还款额=贷款本金×[月利率×(1+月利率) ^ 还款月数]÷{[(1+月利率) ^ 还款月数]-1}
+         */
+        avgCapitalPlusInterest: function () {
+
+            let rate = this.yearRate / 12 / 100;
+            let mRate = Math.pow(rate + 1, this.months);
+
+            // 每月账单金额
+            let bill = Math.round(this.money * rate * mRate / (mRate - 1) * 100) / 100;
+
+            // 累计还款额
+            let allBillsAmount = bill * this.months;
+            // 总利息
+            let allInterest = allBillsAmount - this.money;
+
+            // 剩余本金
+            let leftOver = this.money;
+            // 剩余利息
+            let leftInterest = allInterest;
+            // 剩余期限
+            let leftTime = this.months;
+            // 每期利息
+            let interest = 0;
+            // 每期本金
+            let amount = 0;
+
+            // 累计数据先入队
+            this.billList = [{
+                name: '合计',
+                amount: Number(this.money).toFixed(2),
+                interest: (Math.round(allInterest * 100) / 100).toFixed(2),
+                bill: (Math.round(allBillsAmount * 100) / 100).toFixed(2),
+                totalAmount:'-',
+                totalInterest: '-',
+                leftOver: (Math.round(leftOver * 100) / 100).toFixed(2),
+                leftInterest: (Math.round(allInterest * 100) / 100).toFixed(2)
+            }];
+
+            // 生成账单列表
+            for (; leftTime > 0; leftTime--) {
+
+                mRate = Math.pow(rate + 1, leftTime || 0);
+
+                // 特殊处理最后一期
+                if (leftTime === 1) {
+                    interest = leftInterest;
+                    amount = leftOver;
+                } else {
+                    // 月供利息
+                    interest = leftOver * rate;
+                    // 月供本金
+                    amount = bill - interest;
+                }
+
+                leftOver -= amount;
+                leftInterest -= interest;
+
+                this.billList.push({
+                    name: `第${this.months - leftTime + 1}期`,
+                    amount: (Math.round(amount * 100) / 100).toFixed(2),
+                    interest: (Math.round(interest * 100) / 100).toFixed(2),
+                    bill: (Math.round(bill * 100) / 100).toFixed(2),
+                    totalAmount:(Math.round((this.money - leftOver) * 100) / 100).toFixed(2),
+                    totalInterest: (Math.round((allInterest - leftInterest) * 100) / 100).toFixed(2),
+                    leftOver: (Math.round(leftOver * 100) / 100).toFixed(2),
+                    leftInterest: (Math.round(leftInterest * 100) / 100).toFixed(2)
+                });
+            }
+        },
+
+
+        /**
+         * 等额本金还款公式
+         *
+         * 月供本金=贷款本金÷还款月数
+         * 月供利息=月供本金×月利率x剩余还款期数
+         * 月供总额=月供本金+月供利率 = 贷款本金÷还款月数x(1+月利率x剩余还款期数)
+         *
+         */
+        avgCapitalOnly: function () {
+
+            let rate = this.yearRate / 12 / 100;
+            let amount = this.money / this.months;
+            let deltaInterest = amount * rate;
+            let allBillsAmount = (amount + this.money * rate + amount * (1 + rate)) / 2 * this.months;
+            let allInterest = allBillsAmount - this.money;
+
+            // 剩余本金
+            let leftOver = this.money;
+            // 剩余利息
+            let leftInterest = allInterest;
+
+            // 累计数据先入队
+            this.billList = [{
+                name: '合计',
+                amount: Number(this.money).toFixed(2),
+                interest: (Math.round(allInterest * 100) / 100).toFixed(2),
+                bill: (Math.round(allBillsAmount * 100) / 100).toFixed(2),
+                totalAmount:'-',
+                totalInterest: '-',
+                leftOver: (Math.round(leftOver * 100) / 100).toFixed(2),
+                leftInterest: (Math.round(allInterest * 100) / 100).toFixed(2)
+            }];
+
+
+            // 每期利息
+            let interest = 0;
+
+            // 生成账单列表
+            for (let leftTime = this.months; leftTime > 0; leftTime--) {
+
+                interest = leftTime * deltaInterest;
+                leftOver -= amount;
+                leftInterest -= interest;
+
+                this.billList.push({
+                    name: `第${this.months - leftTime + 1}期`,
+                    amount: (Math.round(amount * 100) / 100).toFixed(2),
+                    interest: (Math.round(interest * 100) / 100).toFixed(2),
+                    bill: (Math.round((amount + interest) * 100) / 100).toFixed(2),
+                    totalAmount:(Math.round((this.money - leftOver) * 100) / 100).toFixed(2),
+                    totalInterest: (Math.round((allInterest - leftInterest) * 100) / 100).toFixed(2),
+                    leftOver: (Math.round(leftOver * 100) / 100).toFixed(2),
+                    leftInterest: (Math.round(leftInterest * 100) / 100).toFixed(2)
+                });
+            }
+        }
+    }
+});

+ 1 - 0
gulpfile.js

@@ -139,6 +139,7 @@ gulp.task('zip', () => {
 
     // web_accessible_resources 中也不需要加载这些冗余的文件了
     manifest.web_accessible_resources = manifest.web_accessible_resources.filter(f => fileList.indexOf(f) === -1);
+    manifest.name = manifest.name.replace('-Dev','');
     fs.writeFileSync(pathOfMF, JSON.stringify(manifest));
 
     // ============压缩打包================================================

Some files were not shown because too many files changed in this diff