ori1.js 11.6 KB
var laydate = layui.laydate
//年月选择器
laydate.render({elem: '#layui01',type: 'month'});

document.getElementById('monthlyTab').addEventListener('click', function() {
    switchTab('monthly');
});
document.getElementById('averageTab').addEventListener('click', function() {
    switchTab('average');
})
document.getElementById('addMonthlyIncome').addEventListener('click', function(e) {
    addMonthlyIncome()
})
document.getElementById('monthlyCalculate').addEventListener('click', function(e) {
    calculate('monthly')
})
document.getElementById('averageCalculate').addEventListener('click', function(e) {
    calculate('average')
})

function switchTab(type) {
    const tabs = document.querySelectorAll('.tab');
    const monthlyContent = document.getElementById('monthlyContent');
    const averageContent = document.getElementById('averageContent');

    tabs.forEach(tab => tab.classList.remove('active'));
    if (type === 'monthly') {
        tabs[1].classList.add('active');
        monthlyContent.style.display = 'block';
        averageContent.style.display = 'none';

        document.getElementById('two').style.display = 'none';
        document.getElementById('one').style.display = 'block';
    } else {
        tabs[0].classList.add('active');
        monthlyContent.style.display = 'none';
        averageContent.style.display = 'block';

        document.getElementById('one').style.display = 'none';
        document.getElementById('two').style.display = 'block';
    }
}

function addMonthlyIncome() {
    const monthlyForm = document.getElementById('monthlyForm');
    const monthCount = monthlyForm.children.length + 1;
    
    let id = 'layui'+new Date().getTime()

    const monthItem = document.createElement('div');
    monthItem.className = 'month-item';
    monthItem.innerHTML = `
        <div class="header">
            <span>第${monthCount}个月</span>
            <button class="delete-month" onclick="this.parentElement.parentElement.remove()">删除</button>
        </div>
        <div class="form-group">
            <label class="required">月份</label>
            <input type="text" id="${id}" class="layui-input" placeholder="请选择月份" readonly>
        </div>
        <div class="form-group">
            <label class="required">收入(元)</label>
            <input class="onlyIncome" type="number" placeholder="请填写">
        </div>
    `;
    
    monthlyForm.appendChild(monthItem);
    laydate.render({elem: '#'+id,type: 'month'});
}

function calculateTax(arr) {
    let yArr = arr.map(item => item.year)
    yArr = [...new Set(yArr)].sort((a,b)=>{
        return a - b
    })

    let resArr = []
    yArr.forEach(yitem=>{
        let mArr = arr.filter(item => item.year == yitem)
        mArr.sort((a,b)=>{
            return a.month - b.month
        })

        let rFn = function(taxableIncome){
            let rate = 0.03, deductionNumber = 0;

            if (taxableIncome <= 36000) {
                rate = 0.03; deductionNumber = 0;
            } else if (taxableIncome <= 144000) {
                rate = 0.1; deductionNumber = 2520;
            } else if (taxableIncome <= 300000) {
                rate = 0.2; deductionNumber = 16920;
            } else if (taxableIncome <= 420000) {
                rate = 0.25; deductionNumber = 31920;
            } else if (taxableIncome <= 660000) {
                rate = 0.3; deductionNumber = 52920;
            } else if (taxableIncome <= 960000) {
                rate = 0.35; deductionNumber = 85920;
            } else {
                rate = 0.45; deductionNumber = 181920;
            }

            return [rate,deductionNumber]
        }
        let fn = function(farr){
            let all = farr.map(item=> item.income).reduce((acc, curr) => acc + curr, 0)*0.8 - 5000*farr.length
            let rate = rFn(all)[0]
            let taxAll = farr.map(item=> item.tax).reduce((acc, curr) => acc + curr, 0)

            let value = (all*rate-taxAll).toFixed(2) - rFn(all)[1]
            farr[farr.length-1].rate = rate
            farr[farr.length-1].tax = Number(value>0?value:0)

            return farr
        }

        let lArr = [] //累计计算的月数
        mArr.forEach(mitem=>{
            mitem.tax = 0
            mitem.addTax = 0
            mitem.mAddTax = 0
            if(mitem.income > 100000){
                mitem.addTax = (mitem.income*0.01)
                mitem.mAddTax = (mitem.income*0.01*0.06)
            }
            if(lArr.length==0 || lArr[lArr.length-1].month+1 == mitem.month){
                lArr.push(mitem)
            }else{
                resArr = resArr.concat(lArr)

                lArr = []
                lArr.push(mitem)
            }
            lArr = fn(lArr)
        })

        resArr = resArr.concat(lArr)
    })

    return resArr
}

function calculate(type) {
    let result = '';

    let htmlFn = function(monthlyData){
        let taxResult = calculateTax(monthlyData)

        let onlyTax = taxResult.map(item => item.tax).reduce((acc, curr) => acc + curr, 0)
        let addTax = taxResult.map(item => item.addTax).reduce((acc, curr) => acc + curr, 0)
        let mAddTax = taxResult.map(item => item.mAddTax).reduce((acc, curr) => acc + curr, 0)
        let allTax = onlyTax + addTax + mAddTax

        let harr = taxResult.map(item => item.year)
        harr = [...new Set(harr)]

        let str = `
                <div class="result-title">预缴税款测算结果:</div>
                <div class="result-item">
                    <span>个税:</span>
                    <span class="right">¥${onlyTax.toFixed(2)}</span>
                </div>
                <div class="result-item">
                    <span>增值税:</span>
                    <span class="right">¥${addTax.toFixed(2)}</span>
                </div>
                <div class="result-item">
                    <span>附加税:</span>
                    <span class="right">¥${mAddTax.toFixed(2)}</span>
                </div>
                <div class="result-item">
                    <span>累计税额:</span>
                    <span class="right">¥${allTax.toFixed(2)}</span>
                </div>
        `

        harr.forEach(item=>{
            let arr = taxResult.filter(i=>i.year == item)

            let tArr = []
            let lArr = []
            let mnum = 0
            arr.forEach(aitem => {
                if(mnum == 0){
                    lArr[0] = aitem
                    mnum = aitem.month
                }else if(aitem.month-mnum == 1){
                    lArr[lArr.length] = aitem
                    mnum = aitem.month
                }else{
                    tArr[tArr.length] = lArr

                    lArr = []
                    lArr[0] = aitem
                    mnum = aitem.month
                }
            })
            tArr[tArr.length] = lArr

            tArr.forEach(titem => {
                str += `
                <div style="width:100%;overflow:auto;">
                    <table class="result-table">
                        <thead>
                            <tr>
                                <th>月份</th>
                                <th>本期收入</th>
                                <th>本期应预扣预缴个税</th>
                                <th>本期应预扣预缴增值税</th>
                                <th>预扣率</th>
                            </tr>
                        </thead>
                        <tbody>
                            ${titem.map((data,index) => `
                                <tr>
                                    <td>${type!='monthly'?('第'+(index+1)+'个月'):(data.year+'年'+data.month+'月')}</td>
                                    <td>${data.income.toFixed(2)}</td>
                                    <td>${data.tax.toFixed(2)}</td>
                                    <td>${data.addTax.toFixed(2)}</td>
                                    <td>${data.rate*100}%</td>
                                </tr>
                            `).join('')}
                        </tbody>
                    </table>    
                </div>
            `
            })
        })

        return str
    }
    
    if (type === 'monthly') {
        const monthItems = document.querySelectorAll('.month-item');
        let monthlyData = [];

        for(let i=0,j=monthItems.length;i<j;i++){
            let time = monthItems[i].querySelector('.layui-input').value || ''
            let income = parseFloat(monthItems[i].querySelector('.onlyIncome').value) || 0;

            if(!time){
                toast('请选择第'+(i+1)+'个月的月份')
                return
            }
            if(!income){
                toast('请输入第'+(i+1)+'个月的收入')
                return
            }

            if(time){
                let year = Number(time.split('-')[0])
                let month = Number(time.split('-')[1])

                monthlyData.push({
                    year,
                    month,
                    income
                });
            }
        }
        
        let arr = monthlyData.map(item => (item.year+''+item.month))
        if(new Set(arr).size !== arr.length){
            toast('月份不可重复')
            return
        }
        
        result = htmlFn(monthlyData)

        // 显示结果
        let resultContainer = document.getElementById('one');
        resultContainer.style.padding = '8px'
        resultContainer.style.border = '1px solid #c8defd'
        resultContainer.innerHTML = result
    } else {
        const averageIncome = parseFloat(document.getElementById('averageIncome').value) || 0;
        const monthCount = parseInt(document.getElementById('monthCount').value) || 0;

        if(!averageIncome){
            toast('请输入月均收入')
            return
        }

        if(!monthCount){
            toast('请输入连续收入月数')
            return
        }
        
        if(Number(monthCount) > 12){
            toast('连续月数不可超过12个月')
            return
        }

        let arr = []
        for(let i=0; i<monthCount; i++){
            arr.push({
                year: 2025,
                month: i+1,
                income: averageIncome
            })
        }

        result = htmlFn(arr)

        // 显示结果
        let resultContainer = document.getElementById('two')
        resultContainer.style.padding = '8px'
        resultContainer.style.border = '1px solid #c8defd'
        resultContainer.innerHTML = result
    }
}


var blackId = ""
function toast(str){
    if (document.getElementById("blackDiv")) {
        document.getElementById("blackSpan").innerHTML = str;
    } else {
        var blackDiv = document.createElement("div");

        blackDiv.id = "blackDiv";
        blackDiv.className = "blackts";
        blackDiv.style.position = "fixed";
        blackDiv.style.left = "0";
        blackDiv.style.bottom = "20%";
        blackDiv.style.width = "100%";
        blackDiv.style.textAlign = "center";
        blackDiv.style.zIndex = "999999";
        blackDiv.style.display = 'flex'
        blackDiv.style.justifyContent = 'center'

        var html = '<div id="blackSpan" style="background: rgba(42,45,50,.94);color: white;';
        html += 'border-radius: 5px;font-size:13px;padding:5px 10px;max-width: 80%;">';
        html += str + '</div>';
        blackDiv.innerHTML = html;

        document.getElementsByTagName("body")[0].appendChild(blackDiv);
    }

    if (blackId && blackId != "") {
        clearTimeout(blackId);
    }
    blackId = setTimeout(function () {
        if (document.getElementById("blackDiv")) {
            document.getElementsByTagName("body")[0].removeChild(document.getElementById("blackDiv"));
        }
    }, 2000);
}