SOURCE

function allReadyEdit() {
    var mstform = Ext.getCmp('p_form0000700102_m');
    var dgrid = Ext.getCmp('p_form0000700102_dgrid');
    var dstore = dgrid.store;
    var Toolbar = Ext.getCmp('toolbar');
    dgrid.hideColumn('xlbz', true);
    dgrid.hideColumn('checkboxcol_1', true);
    dgrid.hideColumn('ykkt_name', true);
    const holidayRanges = [
        { start: '2025-04-03', end: '2025-04-06' }, // 清明
        { start: '2025-04-30', end: '2025-05-05' }, // 五一
        { start: '2025-05-30', end: '2025-06-02' }  // 端午
    ];
    const workWeekends = [
        '2025-04-27', // 国庆节调休上班
        '2023-10-08'  // 国庆节调休上班
    ];
    Toolbar.insert(5, { itemId: "jc", text: "基础数据获取", width: this.itemWidth, iconCls: "icon-refuse" });   //指定位置插入按钮
    Toolbar.insert(6, { itemId: "ts", text: "非研发天数设置", width: this.itemWidth, iconCls: "icon-New" });   //指定位置插入按钮
    // Toolbar.insert(7, { itemId: "ts1", text: "研发天数设置", width: this.itemWidth, iconCls: "icon-New" });   //指定位置插入按钮 
    Toolbar.insert(8, { itemId: "js", text: "薪资计算", width: this.itemWidth, iconCls: "icon-New" });   //指定位置插入按钮
    Toolbar.insert(9, { itemId: "xz", text: "一键选择/清空", width: this.itemWidth, iconCls: "icon-New" });   //指定位置插入按钮 


Toolbar.get('js').on('click', function () {
    Ext.Msg.wait("正在处理数据...", "请稍候");
           /*
       a[m].get('jbgz')基本工资
       a[m].get('gzbz')岗位工资
       a[m].get('jxgz')绩效工资
       a[m].get('xlbz')学历补助
       a[m].get('zcbz')职称补助
       a[m].get('zwbz')驻外补助
       a[m].get('qtbz')其他补助
       a[m].get('bzhj')补助合计
       a[m].get('jj')奖金
       a[m].get('qjkk')请假扣款
       a[m].get('yfhj')应发合计
       a[m].get('grhj')个人合计
       a[m].get('ynshj')除专项附加扣除外应纳税工资合计
       a[m].get('u_grsdr')个人所得税
       a[m].get('u_jxgskk')绩效工资扣款
       a[m].get('u_qtkk')其他扣款
       a[m].get('numericcol_2')工会会员会费
       a[m].get('u_sfhj')实发合计
       */
    var a = dgrid.getStore().getRange(0, dstore.getCount() - 1);
    var index = 0;
    var batchSize = 10; // 每批处理 10 条
    
    function processBatch() {
        var end = Math.min(index + batchSize, dstore.getCount());
        for (; index < end; index++) {
            if (a[index].get('checkboxcol_2') == 1) {
                a[index].set('jbgz', a[index].get('gzbz') * 0.3 * (a[index].get('byts') / a[index].get('jxts')));
                // ... 其他计算逻辑 ...
            }
        }
        
        if (index < dstore.getCount()) {
            // 继续下一批(让 UI 有机会更新)
            setTimeout(processBatch, 0);
        } else {
            // 全部处理完成
            dgrid.getView().refresh();
            Ext.Msg.hide();
        }
    }
    
    processBatch(); // 开始处理
});




    Toolbar.get('xz').on('click', function () {
        var a = dgrid.getStore().getRange(0, dstore.getCount() - 1);
        var b = 1;
        if (a[0].get('checkboxcol_2') == 1) { b = 0; }
        for (var m = 0; m < dstore.getCount(); m++) {
                a[m].set('checkboxcol_2', b);
        }
    });

    mstform.getItem('yf').addListener('change', function () {

        var b = mstform.getItem('yf').getValue();
        var a = mstform.getItem('nd').getValue();
        if (b) {
            var pc = mstform.getItem('ocode').getValue()
            callServer('pc', [{ 'pc': pc }],
                function (res) {
                    if (res) {
                        mstform.getItem('title').setValue(res.record[0].oname + '人员2025年' + b + '月工资表');
                    }
                });
        }
        if (a && b) {
            var firstDay = new Date(a, +b - 1, 1);
            var nextMonthFirstDay = new Date(a, +b, 1);
            var lastDay = new Date(nextMonthFirstDay - 1);
            mstform.getItem('datetimecol_1').setValue(firstDay);
            mstform.getItem('datetimecol_2').setValue(lastDay);
        }
    });

    Toolbar.get('ts').on('click', function () {
        var nd = mstform.getItem('nd').getValue()
        var yf = mstform.getItem('yf').getValue()
        var date = timestampToTime(mstform.getItem('datetimecol_2').getValue())
        var dt = timestampToTime(mstform.getItem('datetimecol_1').getValue())
        var ts1; var ts2; var ts3; var ts4; var kqfz2; var lzrq; var fzts = 0; var fzts_tmp = 0;
        var qjts;

        var map_lzrq = new Map();//key--phid;valu--dimissdt 员工id,离职日期
        var map_kqtstj = new Map();//key--ry;valu--[aa,kgts] 员工id,[]
        var map_qjrqpd = new Map();

        if (Ext.isEmpty(nd)) {
            Ext.Msg.alert('提示', '请先选择年度!');
            return false;
        };
        if (Ext.isEmpty(Ext.getCmp('yf').getValue())) {
            Ext.Msg.alert('提示', '请先输入月份!');
            return false;
        };

        //2025.03.12 th优化
        //查询离职/异动日期
        callServer('lzrq', [{ 'date': date, 'date1': dt }], function (res) {
            res.record.forEach(element => {
                var arr = [];
                arr.push(element.appdtt);
                arr.push(element.chgtype);
                arr.push(element.phiddept);
                arr.push(element.dept);
                map_lzrq.set(element.phid, arr);
            });
        });



        //请假日期判断
        callServer('qijqpd', [{}], function (res) {
            if (res.record.length > 0) {
                res.record.forEach(element => {
                    var arr = [];
                    arr.push(element.factbdt);
                    arr.push(element.factend);
                    map_qjrqpd.set(element.ry, arr);
                });
            }
        });


        callServer('kqtstj', [{ 'nd': nd, 'yf': yf }], function (res) {
            if (res.record.length > 0) {
                res.record.forEach(element => {
                    var arr = [];
                    arr.push(element.aa);
                    arr.push(element.kgts);
                    arr.push(element.qjts);
                    map_kqtstj.set(element.ry, arr);
                });
            }
        });

        callServer('kqfz', [{ 'nd': nd, 'yf': yf }], function (res) {//辅助天数
            if (res.record.length > 0) {
                fzts_tmp = res.record[0].numericcol_1
            }
        });

        var a = dgrid.getStore().getRange(0, dstore.getCount() - 1);
        for (var m = 0; m < dstore.getCount(); m++) {
            if (a[m].get('checkboxcol_2') == 1) {
                var id = a[m].get('checkboxcol_1');
                var ry = a[m].get('empid');
                var rymb = a[m].get('empid') + a[m].get('deptid');
                var sfz = a[m].get('textcol_1');
                var cdt = a[m].get('datetimecol_1');
                if (id == '') {
                    var b = dgrid.getStore().getRange(0, dstore.getCount() - 1);

                    if (!Ext.isEmpty(map_kqtstj.get(rymb))) {
                        ts1 = map_kqtstj.get(rymb)[0];//aa
                        ts2 = map_kqtstj.get(rymb)[1];//kgts
                        qjts = map_kqtstj.get(rymb)[2];//qjts
                    }
                    if (!Ext.isEmpty(map_qjrqpd.get(ry))) {
                        ts3 = new Date(map_qjrqpd.get(ry)[0]);
                        ts4 = new Date(map_qjrqpd.get(ry)[1]);
                    }

                    if (cdt > timestampToTime(dt)) {
                        callServer('kcjjr', [{ 'cdt': cdt }], function (res) {
                            if (res.record.length > 0) {
                                kqfz2 = res.record[0].gs;
                            }
                            else {
                                return;
                            }
                        });
                    } else if (!Ext.isEmpty(map_lzrq.get(ry))) {

                        if (map_lzrq.get(ry)[1] == 6 || map_lzrq.get(ry)[2] == a[m].get('deptid')) {//离职和异动前
                           fzts = countMonthSpecialDays(map_lzrq.get(ry)[0], holidayRanges, workWeekends, "before")
                        } else {
                            if (map_lzrq.get(ry)[3] == a[m].get('deptid')) {//异动后
                           fzts = countMonthSpecialDays(map_lzrq.get(ry)[0], holidayRanges, workWeekends, "after")
                            } else {
                                 fzts = 0
                            }
                        }
                          kqfz2 = 0

                    }
                    else {
                        if (!ts3 && !ts4) {
                            fzts = countMonthSpecialDays(dt, holidayRanges, workWeekends, "all")
                        }
                        else if (timestampToTime(ts3) < dt && timestampToTime(ts4) > date) {
                            fzts = 0
                        }
                        else if (timestampToTime(ts3) > dt && timestampToTime(ts4) > date) {
                            fzts = countMonthSpecialDays(formatDate(ts3), holidayRanges, workWeekends, "before")
                        }
                        else {
                            fzts = countMonthSpecialDays(formatDate(ts4), holidayRanges, workWeekends, "after")
                        }
                        //fzts = fzts_tmp;
                        kqfz2 = 0
                    }
                    a[m].set('byts', ts1 - kqfz2 + fzts);
                    a[m].set('numericcol_4', qjts);
                    fzts = 0;ts3='';ts4='';

                }

            }
        }
    });

    mstform.getItem('empidmul').addListener('helpselected', async function () {
        var intArray = mstform.getItem('empidmul').getValue();
        var date = mstform.getItem('datetimecol_2').getValue();
        var array = intArray.split(",");

        // 将 callServer 封装为 Promise
        function callServerPromise(service, params) {
            return new Promise((resolve) => {
                callServer(service, params, function (res) {
                    resolve(res);
                });
            });
        }

        // 使用 async/await 确保顺序执行
        for (let i = 0; i < array.length; i++) {
            var hr_phid = array[i];

            // 第一个 callServer 调用
            var res1 = await callServerPromise('ryxx', [{ 'phid': hr_phid }]);
            if (res1.record.length > 0) {
                var arr2 = [];
                for (let j = 0; j < res1.record.length; j++) {
                    arr2.push({
                        empid: res1.record[j].phid,
                        empid_name: res1.record[j].cname,
                        textcol_1: res1.record[j].cardno,
                        datetimecol_1: res1.record[j].cdt
                    });
                }
                dstore.insert(dstore.getCount(), arr2);
            }
        }

        mstform.getItem('empidmul').setValue('');
    });

    mstform.getItem('userhelp_char_1').on('beforetriggerclick', function (eOp, ignoreBeforeEvent) {
        var a = mstform.getItem('ocode').getValue();
        mstform.getItem('userhelp_char_1').setClientSqlFilter('ocode = ' + a);              /*PC对应通用帮助拼接SQL语句条件过滤 
                                                                                                          *arr的用法可能不对,这里是SQL语句的拼接 arr数组无法In识别*/
    });


    mstform.getItem('userhelp_char_1').addListener('helpselected', async function () {
        try {
            var intArray = mstform.getItem('userhelp_char_1').getValue();
            var date = mstform.getItem('datetimecol_2').getValue();

            // 将 callServer 封装为 Promise
            function callServerPromise(service, params) {
                return new Promise((resolve) => {
                    callServer(service, params, function (res) {
                        resolve(res);
                    });
                });
            }

            // 获取 fxry 数据
            var fxryRes = await callServerPromise('fxry', [{ 'phid': intArray }]);

            // 遍历 fxry 数据
            for (let i = 0; i < fxryRes.record.length; i++) {
                var hr_phid = fxryRes.record[i].empid;

                // 获取 ryxx 数据
                var ryxxRes = await callServerPromise('ryxx', [{ 'phid': hr_phid }]);
                if (ryxxRes.record.length > 0) {
                    var arr2 = [];
                    for (let j = 0; j < ryxxRes.record.length; j++) {
                        arr2.push({
                            empid: ryxxRes.record[j].phid,
                            empid_name: ryxxRes.record[j].cname,
                            textcol_1: ryxxRes.record[j].cardno,
                            datetimecol_1: ryxxRes.record[j].cdt,
                            zz: ryxxRes.record[j].cboo,
                            zz_name: ryxxRes.record[j].cbooname,
                            deptid: ryxxRes.record[j].dept,
                            deptid_name: ryxxRes.record[j].dpname,
                            gw: ryxxRes.record[j].gw,
                            checkboxcol_2: 1,
                            numericcol_3: 1.0,
                            u_ygzt: ryxxRes.record[j].ygzt,
                        });
                    }
                    dstore.insert(dstore.getCount(), arr2);
                }

            }

            mstform.getItem('empidmul').setValue('');
        } catch (error) {
            Ext.Msg.alert('提示', '请检查没有出现组织和部门的员工企业员工库任职信息是否勾选发薪');
            console.error('处理过程中发生错误:', error);
            // 可以添加错误提示逻辑,例如:
            // mstform.showMessage('错误', '数据处理失败: ' + error.message);
        }
    });


    Toolbar.items.get('jc').on('click', function () {
        var nd = mstform.getItem('nd').getValue()
        var yf = mstform.getItem('yf').getValue()
        var date = timestampToTime(mstform.getItem('datetimecol_2').getValue())
        var date1 = timestampToTime(mstform.getItem('datetimecol_1').getValue())
        var map_lzrq = new Map();//key--phid;value--dimissdt 员工id,离职日期
        var map_yglx = new Map();//key--phid;value--emptype 员工id,离职日期
        var map_gzbz = new Map();//key--phid;value--salary 员工id,薪资
        var map_sbxx = new Map();//key--sfz;value--[numericcol_1,...,numericcol_10]
        var map_gjjxx = new Map();//key--sfz;value--[numericcol_9,numericcol_10]
        var map_gskk = new Map();//key--sfz;value--numericcol_1
        var map_zcbz = new Map();//key--sfz;value--numericcol_1

        if (Ext.isEmpty(nd)) {
            Ext.Msg.alert('提示', '请先选择年度!');
            return false;
        };
        if (Ext.isEmpty(Ext.getCmp('yf').getValue())) {
            Ext.Msg.alert('提示', '请先输入月份!');
            return false;
        };

        //查询工资标准
        callServer('gzbz', [{}], function (res) {
            res.record.forEach(element => {
                map_gzbz.set(element.must_phid, element.salary);
            });
        });

        //查询离职日期
        callServer('lzrq', [{ 'date': date, 'date1': date1 }], function (res) {
            res.record.forEach(element => {
                var arr = [];
                arr.push(element.appdtt);
                arr.push(element.chgtype);
                arr.push(element.phiddept);
                arr.push(element.dept);
                map_lzrq.set(element.phid, arr);
            });
        });

        //查询员工类型
        callServer('yglx', [{}], function (res3) {
            res3.record.forEach(element => {
                map_yglx.set(element.phid, element.emptype);
            });
        });

        //
        callServer('sbxx', [{ 'nd': nd, 'yf': yf }], function (res1) {
            res1.record.forEach(element => {
                var arr = [];
                arr.push(element.numericcol_1);
                arr.push(element.numericcol_2);
                arr.push(element.numericcol_3);
                arr.push(element.numericcol_4);
                arr.push(element.numericcol_5);
                arr.push(element.numericcol_6);
                arr.push(element.numericcol_7);
                arr.push(element.numericcol_8);
                arr.push(element.numericcol_9);
                arr.push(element.numericcol_10);
                map_sbxx.set(element.sfz, arr);
            });
        });

        //
        callServer('gjjxx', [{ 'nd': nd, 'yf': yf }], function (res2) {
            res2.record.forEach(element => {
                var arr = [];
                arr.push(element.numericcol_9);
                arr.push(element.numericcol_10);
                map_gjjxx.set(element.sfz, arr);
            });
        });

        //
        callServer('gskk', [{ 'nd': nd, 'yf': yf }], function (res2) {
            res2.record.forEach(element => {
                map_gskk.set(element.sfz, element.numericcol_1);
            });
        });

        //
        callServer('zcbz', [{ 'date1': date }], function (res2) {
            res2.record.forEach(element => {
                map_zcbz.set(element.sfz, element.numericcol_1);
            });
        });

        var a = dgrid.getStore().getRange(0, dstore.getCount() - 1);
        for (var m = 0; m < dstore.getCount(); m++) {
            if (a[m].get('checkboxcol_2') == 1) {
                var id = a[m].get('empid');
                var sfz = a[m].get('textcol_1');
                // var isyf = a[m].get('checkboxcol_1');
                var cdt = a[m].get('datetimecol_1');
                var dt = mstform.getItem('datetimecol_1').getValue()
                var ts1; var ts2; var sb1; var sb2; var sb3; var sb4; var sb5; var sb6; var sb7; var sb8; var sb9; var sb10; var gjj1; var gjj2;
                var gz;
                var jx;
                var gs;
                var zcbz;
                var kqfz;
                var kqfz2;
                var lzrq;

                gz = map_gzbz.get(id);
                lzrq = map_lzrq.get(id);
                a[m].set('gzbz', gz * a[m].get('numericcol_3'));
                gz = 0;

                if (map_yglx.get(id) == '806200805000002' || map_yglx.get(id) == '806200805000003') {
                    jx = 0.2;
                } else {
                    jx = 0.1;
                }

                a[m].set('u_jxbl', jx);

                //  var isyf = a[m].get('checkboxcol_1');
                var id = a[m].get('empid');

                if (!Ext.isEmpty(map_sbxx.get(sfz))) {
                    var sb1 = map_sbxx.get(sfz)[0];
                    var sb2 = map_sbxx.get(sfz)[1];
                    var sb3 = map_sbxx.get(sfz)[2];
                    var sb4 = map_sbxx.get(sfz)[3];
                    var sb5 = map_sbxx.get(sfz)[4];
                    var sb6 = map_sbxx.get(sfz)[5];
                    var sb7 = map_sbxx.get(sfz)[6];
                    var sb8 = map_sbxx.get(sfz)[7];
                    var sb9 = map_sbxx.get(sfz)[8];
                    var sb10 = map_sbxx.get(sfz)[9];

                    a[m].set('yldw', sb1);
                    a[m].set('ylgr', sb2);
                    a[m].set('yldw1', sb5);
                    a[m].set('ylgr1', sb6);
                    a[m].set('sydw', sb3);
                    a[m].set('sygr', sb4);
                    a[m].set('sydw1', sb8);
                    a[m].set('gsdw', sb7);
                    a[m].set('dedw', sb9);
                    a[m].set('degr', sb10);
                    a[m].set('dwhj', sb1 + sb3 + sb5 + sb7 + sb9);
                    a[m].set('grhj', sb2 + sb4 + sb6 + sb10);


                }



                /*if (cdt > timestampToTime(dt)) {
                    a[m].set('jxts', getDaysLeftInMonth(cdt) + 1);

                } else if (!Ext.isEmpty(map_lzrq.get(id))) {
                    if (map_lzrq.get(id)[1] == 6 || map_lzrq.get(id)[2] == a[m].get('deptid')) {
                        a[m].set('jxts', getDaysIncludingGivenDate(map_lzrq.get(id)[0]));
                        lzrq = '';
                    } else {
                        if (map_lzrq.get(id)[3] == a[m].get('deptid')) {
                            a[m].set('jxts', getDaysLeftInMonth(map_lzrq.get(id)[0]));
                        } else {
                            a[m].set('jxts', 0);
                        }
                    }
                }
                else {
                    a[m].set('jxts', getDaysInMonth(dt));
                }*/
                a[m].set('jxts', getDaysInMonth(dt));
                a[m].set('qjkk', ts2);



                if (!Ext.isEmpty(map_gskk.get(sfz))) {
                    var gs = map_gskk.get(sfz);
                    a[m].set('u_grsdr', gs);
                }

                if (!Ext.isEmpty(map_zcbz.get(sfz))) {
                    var gs = map_zcbz.get(sfz);
                    a[m].set('zcbz', gs);
                }

            }
        }
    });

    dgrid.addListener('edit', function (editor, e) {
        if (e.originalValue == e.value) return;

        if (e.field == 'gzbz') {
            var pdgw = dgrid.getSelectionModel().getSelection();

            // 检查是否选中了行
            if (!pdgw || pdgw.length === 0) {
                console.warn('编辑时没有选中任何行');
                return;
            }

            var record = pdgw[0];

            if (record.get('u_ygzt') == '正式') {
                var ls1 = record.get('empid');

                callServer('gzbz1', [{ 'ls1': ls1 }], function (res) {
                    // 检查服务器响应
                    if (!res) {
                        console.error('无服务器响应');
                        return;
                    }

                    if (res.record.length === 0) {
                        console.error('服务器返回空数据', res);
                        return;
                    }

                    // 再次检查记录是否存在(防止异步期间记录被删除)
                    if (record.destroyed) {
                        console.warn('记录已被删除');
                        return;
                    }

                    // 安全设置值
                    record.set('gzbz', res.record[0].salary || record.get('gzbz'));
                });

                Ext.Msg.alert('提示', '正式员工不允许修改薪资!');
                return false;
            }
        }
    });


}

function timestampToTime(timestamp) {

    var date = new Date(timestamp);
    var y = date.getFullYear();
    var m = date.getMonth() + 1;
    m = m < 10 ? ('0' + m) : m;
    var d = date.getDate();
    d = d < 10 ? ('0' + d) : d;
    var h = date.getHours();
    var minute = date.getMinutes();
    minute = minute < 10 ? ('0' + minute) : minute;
    return y + '-' + m + '-' + d  //这里如果不需要小时 分  后边的可以不需要拼接

}


function getDaysLeftInMonth(dateStr) {
    var date = new Date(dateStr);
    var currentMonth = date.getMonth();
    var currentYear = date.getFullYear();
    var nextMonthFirstDay = new Date(currentYear, currentMonth + 1, 1);
    var currentDay = date.getDate();
    var daysInMonth = new Date(currentYear, currentMonth + 1, 0).getDate(); // 获取当前月的总天数
    var daysLeft = daysInMonth - currentDay;
    return daysLeft;
}

function getDaysIncludingGivenDate(dateStr) {
    // 创建一个 Date 对象
    var date = new Date(dateStr);

    // 获取当前日期在这个月中的天数
    var currentDay = date.getDate();

    // 计算当月中包括给定日期在内的天数
    var daysIncluding = currentDay;

    return daysIncluding;
}

function getDaysInMonth(dateStr) {
    // 创建一个 Date 对象
    const date = new Date(dateStr);

    // 获取当前日期所在的年份和月份
    const year = date.getFullYear();
    const month = date.getMonth();

    // 创建一个表示下个月第一天的 Date 对象,然后将日期设置为 0
    // 这样 getDate() 方法就会返回当前月份的总天数
    const daysInMonth = new Date(year, month + 1, 0).getDate();

    return daysInMonth;
}




/**
 * 计算给定日期所在月份的周末和节假日天数(支持节假日区间)
 * @param {Date|string} date - 基准日期
 * @param {Array} holidayRanges - 节假日区间数组,格式如 [{ start: 'YYYY-MM-DD', end: 'YYYY-MM-DD' }]
 * @param {string} [range="all"] - 计算范围: "before"(之前)、"after"(之后)、"all"(全部)
 * @returns {number} 符合条件的周末和节假日天数
 */
function countMonthSpecialDays(date, holidayRanges = [], workWeekends = [], range = "all") {
    // 处理输入日期
    const inputDate = typeof date === 'string' ? new Date(date) : new Date(date);
    if (isNaN(inputDate.getTime())) {
        throw new Error('Invalid date input');
    }

    // 获取月份的第一天和最后一天
    const year = inputDate.getFullYear();
    const month = inputDate.getMonth();
    const firstDay = new Date(year, month, 1);
    const lastDay = new Date(year, month + 1, 0);
    const currentDay = inputDate.getDate();

    let count = 0;

    // 遍历整个月份
    for (let day = new Date(firstDay); day <= lastDay; day.setDate(day.getDate() + 1)) {
        const dayOfMonth = day.getDate();
        const dayOfWeek = day.getDay(); // 0=周日, 6=周六
        const formattedDate = formatDate(day); // 'YYYY-MM-DD'

        // 检查是否在计算范围内
        let isInRange = false;
        if (range === "before" && dayOfMonth < currentDay) {
            isInRange = true;
        } else if (range === "after" && dayOfMonth > currentDay) {
            isInRange = true;
        } else if (range === "all") {
            isInRange = true;
        }

        if (isInRange) {
            // 检查是否是调休工作日(周末需要上班)
            const isWorkWeekend = workWeekends.includes(formattedDate);

            // 计算周末(跳过调休日)
            if (!isWorkWeekend) {
                const isWeekend = dayOfWeek === 0 || dayOfWeek === 6;
                const isHoliday = isDateInHolidayRanges(day, holidayRanges);

                if (isHoliday) {
                    count += 1; // 节假日统一算1天
                } else if (isWeekend) {
                    if (dayOfWeek === 0) {
                        count += 1; // 周日算1天
                    } else if (dayOfWeek === 6) {
                        count += 0.5; // 周六算0.5天
                    }
                }
            }
        }
    }

    return count;
}

// 辅助函数:检查某一天是否在节假日区间内
function isDateInHolidayRanges(date, holidayRanges) {
    const checkDate = new Date(date);
    for (const range of holidayRanges) {
        const startDate = new Date(range.start);
        const endDate = new Date(range.end);
        if (checkDate >= startDate && checkDate <= endDate) {
            return true;
        }
    }
    return false;
}

// 辅助函数:格式化日期为 'YYYY-MM-DD'
function formatDate(date) {
    const year = date.getFullYear();
    const month = String(date.getMonth() + 1).padStart(2, '0');
    const day = String(date.getDate()).padStart(2, '0');
    return `${year}-${month}-${day}`;
}
console 命令行工具 X clear

                    
>
console