医生排班开发:问题总结与反思

在开发医生排班系统的过程中,我遭遇了一系列棘手的问题,这些问题主要集中在多重循环渲染、数据处理以及弹窗和月份切换的控制上。通过对这些问题的梳理与总结,希望能为后续的开发优化以及遇到类似问题的开发者提供一些参考。

多重循环渲染问题

问题描述

在页面渲染环节,尤其是涉及到展示医生排班信息时,需要对医生数据、日期数据以及每个日期下的具体排班数据进行多层遍历。例如,在render函数中,首先要遍历医生数组来展示每个医生的基本信息,接着对于每个医生,又要遍历当前月份的每一天来展示对应的排班情况,在renderAgain函数中,还需进一步遍历每一天中具体的排班时段数据。这种多层嵌套的循环结构虽然能够实现数据的准确展示,但带来了性能和代码可读性方面的挑战。

 

function render() {
    let str = '';
    let days = getDaysInMonths();
    for (let i = page * pageSize; i < doctors.length && i < page * pageSize + pageSize; i++) {
        // 添加医生信息
        str += `<div class="nav_status">
            <div class="child_long">${doctors[i].name}</div>
            <div class="child_long">${doctors[i].office}</div></div>`;
        // 处理每一天 
        for (let d = 1; d <= days; d++) {
            if (data[d] == undefined) {
                continue;
            }
            renderAgain(d);
        }
    }
    $("#body_status").html(str)
    $(".notice_scroll").html(scroll_str);
    page_paging(data);
}

function renderAgain(d) {
    for (let j = 0; j < data[d].date.length; j++) {
        let day_ser = j + 1;
        // 拼接日期、上午、下午
        scroll_str += `
        <div class="scroll_item">
        <div class="specific_time">${data[d].date[j]}</div>
        <div class="am_pm" style="background-color: rgb(245, 247, 250)">
            <div class="am_title">上午</div>
            <div class="pm_title">下午</div>
        </div>`;
        let emptySlots = '';
        for (let k = page * pageSize; k < data.length && k < page * pageSize + pageSize; k++) {
            let am_source = data[k].shang[day_ser - 1].source? '号源:' + data[k].shang[day_ser - 1].source : '无';
            let pm_source = data[k].xia[day_ser - 1].source? '号源:' + data[k].xia[day_ser - 1].source : '无';
            emptySlots += `<div class="am_pm_child">`;
            emptySlots += `<div class="am_title">${am_source}</div>
                <div class="pm_title">${pm_source}</div>`;
            emptySlots += `</div>`;
        }
        scroll_str += emptySlots; 
        scroll_str += `</div></div>`;
    }
}

问题分析

在上述代码中,render函数中嵌套了两层循环,外层循环遍历医生,内层循环遍历日期。而renderAgain函数又包含了多层循环,用于处理每一天中的具体排班时段。这样的结构导致代码逻辑复杂,难以维护和调试。并且,过多的循环操作可能会在数据量较大时影响页面渲染性能,导致页面卡顿。

解决思路

  1. 优化数据结构:在数据获取阶段,对从服务器获取的数据进行预处理,将数据整理成更易于遍历和渲染的结构。例如,可以将医生信息和其对应的排班信息进行整合,减少在渲染过程中的多层查找和遍历。
  2. 使用更高效的算法:考虑使用一些数据处理算法,如哈希表,来优化数据查找的效率。在渲染过程中,通过哈希表快速定位到需要的数据,减少不必要的循环操作。
  3. 代码拆分与模块化:将复杂的渲染逻辑拆分成多个独立的函数,每个函数专注于处理某一层的数据遍历和渲染,提高代码的可读性和可维护性。

数据处理不当问题

问题描述

在数据处理过程中,存在数据格式不一致、数据验证不严谨以及数据更新后页面同步不及时等问题。例如,在保存排班数据时,需要对用户输入的时间、号源等信息进行验证,但当前的验证逻辑不够完善,容易导致非法数据提交到服务器。另外,当服务器返回新的排班数据时,页面有时未能及时更新显示最新信息。

function save() {
    isValid = true;
    if (switch_am_time == 1 && switch_pm_time == 1) {
        showPopup('请至少选择一个时间段', '#f44336', '#ffebee', '#f44336');
        return;
    }
    if (switch_am_time == 2) {
        const amStart = $('#am_start').val();
        const amEnd = $('#am_end').val();
        if (amStart == '') {
            showPopup('请选择上午开始时间', '#f44336', '#ffebee', '#f44336');
            return;
        }
        if (amEnd == '') {
            showPopup('请选择上午结束时间', '#f44336', '#ffebee', '#f44336');
            return;
        }
        if (amStart === amEnd) {
            showPopup('上午开始时间和结束时间不能一样', '#f44336', '#ffebee', '#f44336');
            return;
        }
        const startMinutes = convertTimeToMinutes(amStart);
        const endMinutes = convertTimeToMinutes(amEnd);
        if (startMinutes < 360) {
            showPopup('上午开始时间不得早于 6 点', '#f44336', '#ffebee', '#f44336');
            return;
        }
        if (endMinutes > 720) {
            showPopup('上午结束时间不得晚于 12 点', '#f44336', '#ffebee', '#f44336');
            return;
        }
        if ($('#am_source').val() == '') {
            showPopup('请填写上午号源', '#f44336', '#ffebee', '#f44336');
            return;
        }
    }
    // 下午时间和号源的验证逻辑类似
    if (switch_am_time == 2) {
        total_data.push({
            date: $('.part_text').html(),
            time_slot: $('#am_start').val().replace(/:\d{2}$/, '') + '-' + $('#am_end').val().replace(/:\d{2}$/, ''),
            depart_id: department_id,
            doctor_id: editId,
            time: 1,
            status: 1,
            num: 0,
            source: $('#am_source').val(),
            month: new Date().getMonth() + 1,
        })
    }
    if (switch_pm_time == 2) {
        total_data.push({
            date: $('.part_text').html(),
            time_slot: $('#pm_start').val().replace(/:\d{2}$/, '') + '-' + $('#pm_end').val().replace(/:\d{2}$/, ''),
            time: 2,
            source: $('#pm_source').val(),
            month: new Date().getMonth() + 1,
            status: 1,
            num: 0,
            doctor_id: editId,
            depart_id: department_id,
        })
    }
    $.ajax({
        type: "post",
        url: url + ``,
        headers: {
            token: token,
            id: uid
        },
        data: {
            doctor_id: editId,
            arr: JSON.stringify(total_data)
        },
        success: function (results) {
            if (results.code == 1) {
                $('.delete_back').hide();
                showPopup('添加成功', '#4caf50', '#e8f5e9', '#4caf50');
                getDaysInMonth();
                switch_am($('#switchs')[0]);
                switch_pm($('#switch')[0]);
                hide();
            } else if (results.code == 2) {
                showPopup(results.msg, '#f44336', '#ffebee', '#f44336');
            }
        },
    });
}

问题分析

save函数中,虽然对用户输入的时间和号源进行了部分验证,但验证逻辑较为分散,且对于一些边界情况的处理不够全面。例如,时间格式的验证仅通过简单的字符串比较,未考虑到时间格式错误的情况。在数据更新方面,当服务器返回成功响应后,虽然调用了getDaysInMonth函数重新获取数据,但在某些情况下,页面可能并未正确更新,这可能是由于数据更新与页面渲染之间的同步机制存在问题。

解决思路

  1. 完善数据验证:采用更严格的数据验证方法,例如使用正则表达式验证时间格式,确保输入的数据符合预期格式。同时,将验证逻辑进行整合,提高代码的可维护性。
  2. 优化数据更新机制:在数据更新时,确保页面渲染函数能够准确地获取最新的数据并进行更新。可以在数据更新后,触发特定的事件来通知页面进行重新渲染,或者在渲染函数中增加对数据变化的检测机制。

 多层弹窗下数据渲染显示和月份切换问题

问题描述

在系统中存在多层弹窗,当用户在弹窗中进行操作时,有时会出现数据重复渲染或者不必要的渲染情况。例如,在编辑医生排班的弹窗中,切换月份时,弹窗内的数据可能会出现异常渲染,显示的数据与所选月份不匹配。另外,在多层弹窗嵌套的情况下,如何禁止某些弹窗内的数据渲染,以提高系统性能和用户体验,也是一个难题。

function redact(id) {
    editId = id;
    $('.examine').show(); 
    let date_time = ``;
    let getdate = getDatesInMonth(new Date().getFullYear(), new Date().getMonth() + 1);
    for (let h = 0; h < getdate.length; h++) {
        $(".work_time").html(getdate[h]);
    }
    $("#nowDay").trigger("click");
    for (let i = 0; i < data.length; i++) {
        if (data[i].id == id) {
            department_id = data[i].depart_id;
            sessionStorage.setItem('SourceId', data[i].id);
            for (let j = 0; j < data[i].date.length; j++) {
                let shangData = data[i].shang[j];
                let date = new Date(data[i].date[j]);
                let day = date.getDate();
                let formattedDate = `${day}`;
                $('#person').html(data[i].name);
                let shang = data[i].shang[j];
                let weekDay = getWeekDay(data[i].date[j]);
                $('.week').html(weekDay);
                let sourceText = shangData.source === undefined? '无号源' : '号源: ' + shangData.source;
                let sourceClass = shangData.source === undefined? 'no-source' : 'has-source';
                date_time += `
                    <div class="plan_box" data-day="${day}">
                        <span>${formattedDate}</span><br>
                        <span class="${sourceClass}">${sourceText}</span>
                    </div>`;
            }
            $('.date_box').html(date_time);
            details_id = id;
        }
    }
}

$('#monthSelect').on('change', function () {
    let selectedMonth = parseInt(this.value);
    let currentDate = new Date();
    let currentYear = currentDate.getFullYear();
    let currentMonth = currentDate.getMonth() + 1;
    if (currentYear === new Date().getFullYear() && selectedMonth < currentMonth) {
        $(this).val($(this).data('lastValue'));
    } else {
        $(this).data('lastValue', selectedMonth);
        if (selectedMonth) {
            calendar(selectedMonth); 
        }
    }
});

问题分析

redact函数中,当打开编辑弹窗时,会根据当前月份渲染相关数据。但在月份切换时,由于没有对已渲染的数据进行有效的清理和重新加载控制,导致数据显示异常。在$('#monthSelect').on('change'事件中,虽然实现了月份切换功能,但对于多层弹窗下的特殊情况考虑不足,没有处理好如何禁止某些弹窗内数据的不必要渲染。

解决思路

  1. 数据清理与缓存:在打开弹窗或切换月份时,首先清理弹窗内已有的数据,避免数据残留导致的显示异常。同时,可以考虑使用数据缓存机制,在切换月份时,如果数据未发生变化,则直接从缓存中读取数据,减少不必要的渲染。
  2. 事件委托与控制:通过事件委托机制,在父元素上统一监听与弹窗和月份切换相关的事件,根据当前弹窗的状态和用户操作,精确控制哪些数据需要渲染,哪些需要禁止渲染。例如,在多层弹窗中,可以设置标志位,当处于特定弹窗层级时,禁止某些数据渲染函数的执行。

通过对这些问题的总结,我深刻认识到在开发医生排班系统过程中,需要更加严谨地处理数据,优化渲染逻辑,以及精细控制页面交互。这些问题的解决将有助于提升系统的性能、稳定性和用户体验,为后续的开发工作积累宝贵经验。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值