SCRUM4

昨天的成就:
完成了入职发展内的所有三个功能,包括新人入职,新人成长,转正申请。
新人入职:特定员工可以添加员工账号,可选部门,默认为初级员工。新人成长功能可以为新人寻找职级为2的导师。转正申请功能可以让已经有导师带领的新人发送转正的申请,同意后就能够成为职级为2的员工。
部分代码如下:
onboardingManagement.js:

// 动态加载入职发展内容
function loadOnboardingManagement(container) {
    container.innerHTML = `
        <div class="onboarding-management">
            <h3 style="font-size: 1.5rem;">入职发展</h3>
            <div id="onboardingContent"></div>
        </div>
    `;

    // 获取当前用户信息以判断是否显示入职功能
    fetch('/api/user/current-user-info')
        .then(response => {
            if (!response.ok) {
                throw new Error('网络响应失败');
            }
            return response.json();
        })
        .then(data => {
            const onboardingContent = document.getElementById('onboardingContent');
            const userId = data.userId;
            const permissionLevel = data.permissionLevel;
            const departmentId = data.departmentId;

            // 判断用户职级并显示相应内容
            if (permissionLevel === 1) {
                // 职级为1的用户,显示导师信息或提示无导师
                fetch('/api/user/current-mentorship-info')
                    .then(response => {
                        if (!response.ok) {
                            throw new Error('网络响应失败');
                        }
                        return response.json();
                    })
                    .then(data => {
                        if (data.mentor) {
                            onboardingContent.innerHTML = `
                                <p style="font-size: 1.2rem; margin-top: 10px;">您的导师是:员工ID ${data.mentor.id}</p>
                                <button onclick="showPromotionRequestForm()" style="font-size: 1.1rem; padding: 10px 20px; background-color: #007bff; color: white; border: none; border-radius: 4px; cursor: pointer; margin-top: 20px;">请求转正</button>
                                <div id="promotionRequestFormContainer" style="display: none; margin-top: 20px; padding: 20px; background-color: #f8f9fa; border-radius: 5px;"></div>
                            `;
                        } else {
                            onboardingContent.innerHTML = `
                                <p style="font-size: 1.2rem; margin-top: 10px;">暂未分配导师,请等待</p>
                            `;
                        }
                    })
                    .catch(error => {
                        console.error('获取导师信息出错:', error);
                        onboardingContent.innerHTML = '<p style="color: red; font-size: 1.2rem;">获取导师信息失败,请重试</p>';
                    });
            } else if (permissionLevel === 2) {
                // 职级为2的用户,显示带领的学员信息或提示无学员
                fetch('/api/user/current-mentorship-info')
                    .then(response => {
                        if (!response.ok) {
                            throw new Error('网络响应失败');
                        }
                        return response.json();
                    })
                    .then(data => {
                        if (data.mentees && data.mentees.length > 0) {
                            let menteesHtml = '<ul style="list-style-type: none; padding: 0; margin-top: 10px;">';
                            data.mentees.forEach(mentee => {
                                menteesHtml += `
                                    <li style="padding: 10px; border-bottom: 1px solid #eee; font-size: 1.1rem;">
                                        员工ID ${mentee.id},职位:${mentee.position}
                                    </li>
                                `;
                            });
                            menteesHtml += '</ul>';
                            onboardingContent.innerHTML = `
                                <p style="font-size: 1.2rem; margin-top: 10px;">您带领的学员:</p>
                                ${menteesHtml}
                            `;
                        } else {
                            onboardingContent.innerHTML = `
                                <p style="font-size: 1.2rem; margin-top: 10px;">暂未分配学员,请等待</p>
                            `;
                        }
                    })
                    .catch(error => {
                        console.error('获取学员信息出错:', error);
                        onboardingContent.innerHTML = '<p style="color: red; font-size: 1.2rem;">获取学员信息失败,请重试</p>';
                    });
            } else if (permissionLevel === 3 && departmentId === 4) {
                // 职级为3且部门为4的用户,显示新人入职、导师分配和查看请求功能
                onboardingContent.innerHTML = `
                    <button onclick="showNewHireForm()" style="font-size: 1.1rem; padding: 10px 20px; background-color: #007bff; color: white; border: none; border-radius: 4px; cursor: pointer; margin-bottom: 20px;">新人入职</button>
                    <button onclick="showMentorshipForm()" style="font-size: 1.1rem; padding: 10px 20px; background-color: #007bff; color: white; border: none; border-radius: 4px; cursor: pointer; margin-bottom: 20px;">新人成长</button>
                    <button onclick="showPromotionRequests()" style="font-size: 1.1rem; padding: 10px 20px; background-color: #007bff; color: white; border: none; border-radius: 4px; cursor: pointer; margin-bottom: 20px;">查看请求</button>
                    <div id="newHireFormContainer" style="display: none; margin-top: 20px; padding: 20px; background-color: #f8f9fa; border-radius: 5px;"></div>
                    <div id="mentorshipFormContainer" style="display: none; margin-top: 20px; padding: 20px; background-color: #f8f9fa; border-radius: 5px;"></div>
                    <div id="newHireResult" style="margin-top: 20px;"></div>
                    <div id="mentorshipInfoContainer" style="margin-top: 20px;"></div>
                    <div id="promotionRequestsContainer" style="display: none; margin-top: 20px; padding: 20px; background-color: #f8f9fa; border-radius: 5px;"></div>
                `;

                // 加载导师信息
                loadMentorshipInfo();
            } else {
                // 其他用户显示无权限提示
                onboardingContent.innerHTML = `
                    <p style="font-size: 1.2rem; color: #666;">您没有权限进行新人入职操作。</p>
                `;
            }
        })
        .catch(error => {
            console.error('获取当前用户信息出错:', error);
            document.getElementById('onboardingContent').innerHTML = '<p style="color: red; font-size: 1.2rem;">获取用户信息失败,请刷新重试</p>';
        });
}
// 显示转正请求表单
function showPromotionRequestForm() {
    const promotionRequestFormContainer = document.getElementById('promotionRequestFormContainer');
    promotionRequestFormContainer.style.display = 'block';
    promotionRequestFormContainer.innerHTML = `
        <h4 style="margin-top: 0; font-size: 1.3rem;">请求转正</h4>
        <div style="margin-top: 15px;">
            <label for="promotionReason" style="display: block; margin-bottom: 5px; font-size: 1.1rem;">申请原因:</label>
            <textarea id="promotionReason" placeholder="请输入申请原因" style="width: 100%; padding: 8px; font-size: 1rem; height: 100px;"></textarea>
        </div>
        <button onclick="submitPromotionRequest()" style="font-size: 1.1rem; padding: 10px 20px; background-color: #007bff; color: white; border: none; border-radius: 4px; cursor: pointer; margin-top: 10px;">提交请求</button>
    `;
}

// 提交转正请求
function submitPromotionRequest() {
    const promotionReason = document.getElementById('promotionReason').value;

    if (!promotionReason.trim()) {
        alert('请输入申请原因');
        return;
    }

    fetch('/api/user/submit-promotion-request', {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json',
        },
        body: JSON.stringify({
            content: promotionReason,
            change_type: 1
        })
    })
    .then(response => {
        if (!response.ok) {
            throw new Error('网络响应失败');
        }
        return response.json();
    })
    .then(data => {
        alert('转正请求提交成功!');
        // 刷新页面以显示新状态
        location.reload();
    })
    .catch(error => {
        console.error('提交转正请求出错:', error);
        alert('提交转正请求失败,请重试');
    });
}

// 显示转正请求列表
function showPromotionRequests() {
    const promotionRequestsContainer = document.getElementById('promotionRequestsContainer');
    promotionRequestsContainer.style.display = 'block';

    fetch('/api/user/get-promotion-requests')
        .then(response => {
            if (!response.ok) {
                throw new Error('网络响应失败');
            }
            return response.json();
        })
        .then(requests => {
            if (requests.length === 0) {
                promotionRequestsContainer.innerHTML = `
                    <p style="font-size: 1.2rem; margin-top: 10px;">暂无转正请求</p>
                `;
                return;
            }

            let requestsHtml = '<ul style="list-style-type: none; padding: 0; margin-top: 10px;">';
            requests.forEach(request => {
                requestsHtml += `
                    <li style="padding: 15px; border-bottom: 1px solid #eee; font-size: 1.1rem;">
                        <p>申请人ID:${request.user_id}</p>
                        <p>申请原因:${request.content}</p>
                        <button onclick="approvePromotionRequest(${request.id})" style="font-size: 1rem; padding: 5px 10px; background-color: #28a745; color: white; border: none; border-radius: 4px; cursor: pointer; margin-right: 10px;">同意</button>
                        <button onclick="rejectPromotionRequest(${request.id})" style="font-size: 1rem; padding: 5px 10px; background-color: #dc3545; color: white; border: none; border-radius: 4px; cursor: pointer;">拒绝</button>
                    </li>
                `;
            });
            requestsHtml += '</ul>';
            promotionRequestsContainer.innerHTML = requestsHtml;
        })
        .catch(error => {
            console.error('获取转正请求出错:', error);
            promotionRequestsContainer.innerHTML = '<p style="color: red; font-size: 1.2rem;">获取转正请求失败,请重试</p>';
        });
}

// 同意转正请求
function approvePromotionRequest(requestId) {
    fetch(`/api/user/approve-promotion-request/${requestId}`, {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json',
        }
    })
    .then(response => {
        if (!response.ok) {
            throw new Error('网络响应失败');
        }
        return response.json();
    })
    .then(data => {
        alert('已同意转正请求,用户职级已更新!');
        // 刷新页面以显示新状态
        location.reload();
    })
    .catch(error => {
        console.error('同意转正请求出错:', error);
        alert('同意转正请求失败,请重试');
    });
}

// 拒绝转正请求
function rejectPromotionRequest(requestId) {
    fetch(`/api/user/reject-promotion-request/${requestId}`, {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json',
        }
    })
    .then(response => {
        if (!response.ok) {
            throw new Error('网络响应失败');
        }
        return response.json();
    })
    .then(data => {
        alert('已拒绝转正请求');
        // 刷新页面以显示新状态
        location.reload();
    })
    .catch(error => {
        console.error('拒绝转正请求出错:', error);
        alert('拒绝转正请求失败,请重试');
    });
}

// 显示新员工入职表单
function showNewHireForm() {
    const newHireFormContainer = document.getElementById('newHireFormContainer');
    newHireFormContainer.style.display = 'block';
    newHireFormContainer.innerHTML = `
        <h4 style="margin-top: 0; font-size: 1.3rem;">新人入职</h4>
        <div style="margin-top: 15px;">
            <label for="passwordInput" style="display: block; margin-bottom: 5px; font-size: 1.1rem;">密码(明码):</label>
            <input type="password" id="passwordInput" placeholder="设置新员工密码" style="width: 100%; padding: 8px; font-size: 1rem;">
        </div>
        <div style="margin-top: 15px;">
            <label for="departmentSelect" style="display: block; margin-bottom: 5px; font-size: 1.1rem;">选择部门:</label>
            <select id="departmentSelect" style="width: 100%; padding: 8px; font-size: 1rem;">
                <!-- 部门选项将通过AJAX动态加载 -->
            </select>
        </div>
        <button onclick="submitNewHire()" style="font-size: 1.1rem; padding: 10px 20px; background-color: #007bff; color: white; border: none; border-radius: 4px; cursor: pointer; margin-top: 10px;">确认入职</button>
    `;

    // 动态加载部门选项
    fetch('/api/department/all')
        .then(response => {
            if (!response.ok) {
                throw new Error('网络响应失败');
            }
            return response.json();
        })
        .then(departments => {
            const departmentSelect = document.getElementById('departmentSelect');
            departmentSelect.innerHTML = '';
            departments.forEach(dept => {
                const option = document.createElement('option');
                option.value = dept.departmentId;
                option.textContent = dept.departmentName;
                departmentSelect.appendChild(option);
            });
        })
        .catch(error => {
            console.error('加载部门数据出错:', error);
            alert('加载部门数据失败,请重试');
        });
}

// 提交新员工入职信息
function submitNewHire() {
    const password = document.getElementById('passwordInput').value;
    const departmentId = parseInt(document.getElementById('departmentSelect').value);

    if (!password || isNaN(departmentId)) {
        alert('请输入密码并选择部门');
        return;
    }

    fetch('/api/department/' + departmentId + '/level1-position')
        .then(response => {
            if (!response.ok) {
                throw new Error('网络响应失败');
            }
            return response.json();
        })
        .then(data => {
            const position = data.level1_position;
            const userInfo = {
                password: password,
                departmentId: departmentId,
                position: position,
                permissionLevel: 1
            };

            return fetch('/api/user/create-new-user', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                },
                body: JSON.stringify(userInfo)
            });
        })
        .then(response => {
            if (!response.ok) {
                throw new Error('网络响应失败');
            }
            return response.json();
        })
        .then(data => {
            const newHireResult = document.getElementById('newHireResult');
            newHireResult.innerHTML = `
                <div style="padding: 15px; background-color: #d4edda; border-color: #c3e6cb; color: #155724; border-radius: 5px;">
                    <h4 style="margin-top: 0; font-size: 1.3rem;">新员工入职成功</h4>
                    <p style="margin: 10px 0; font-size: 1.1rem;">员工ID:${data.userId}</p>
                    <p style="margin: 10px 0; font-size: 1.1rem;">密码:${data.password}</p>
                    <p style="margin: 10px 0; font-size: 1.1rem;">部门:${data.departmentName}</p>
                    <p style="margin: 10px 0; font-size: 1.1rem;">职级:1</p>
                    <p style="margin: 10px 0; font-size: 1.1rem;">职位:${data.position}</p>
                </div>
            `;
            document.getElementById('passwordInput').value = '';
        })
        .catch(error => {
            console.error('提交新员工入职信息出错:', error);
            alert('入职操作失败,请重试');
        });
}

// 显示新人成长表单
function showMentorshipForm() {
    const mentorshipFormContainer = document.getElementById('mentorshipFormContainer');
    mentorshipFormContainer.style.display = 'block';
    mentorshipFormContainer.innerHTML = `
        <h4 style="margin-top: 0; font-size: 1.3rem;">新人成长</h4>
        <div id="level1UsersList"></div>
    `;

    // 获取当前用户信息
    fetch('/api/user/current-user-info')
        .then(response => {
            if (!response.ok) {
                throw new Error('网络响应失败');
            }
            return response.json();
        })
        .then(data => {
            const permissionLevel = data.permissionLevel;
            const departmentId = data.departmentId;

            // 如果是职级为1的员工
            if (permissionLevel === 1) {
                // 获取当前用户的导师信息
                fetch('/api/user/current-mentorship-info')
                    .then(response => {
                        if (!response.ok) {
                            throw new Error('网络响应失败');
                        }
                        return response.json();
                    })
                    .then(data => {
                        const mentorshipInfoContainer = document.getElementById('level1UsersList');
                        if (data.mentor) {
                            mentorshipInfoContainer.innerHTML = `
                                <p style="font-size: 1.2rem; margin-top: 10px;">您的导师是:员工ID ${data.mentor.id}</p>
                            `;
                        } else {
                            mentorshipInfoContainer.innerHTML = `
                                <p style="font-size: 1.2rem; margin-top: 10px;">暂未分配导师,请等待</p>
                            `;
                        }
                    })
                    .catch(error => {
                        console.error('获取当前用户导师信息出错:', error);
                        document.getElementById('level1UsersList').innerHTML = '<p style="color: red; font-size: 1.1rem;">获取导师信息失败,请重试</p>';
                    });
            } else if (departmentId === 4 && permissionLevel === 3) {
                // 如果是职级为3的员工,显示所有没有导师的职级为1的员工
                fetch('/api/user/get-all-level1-users')
                    .then(response => {
                        if (!response.ok) {
                            throw new Error('网络响应失败');
                        }
                        return response.json();
                    })
                    .then(level1Users => {
                        // 过滤掉已经有导师的员工
                        const usersWithoutMentor = level1Users.filter(user => !user.hasMentor);

                        // 渲染职级为1的员工列表
                        let usersHtml = '<ul style="list-style-type: none; padding: 0;">';
                        if (usersWithoutMentor.length === 0) {
                            usersHtml += `
                                <li style="padding: 10px; color: #666; font-size: 1.1rem;">
                                    所有职级为1的员工都有导师了。
                                </li>
                            `;
                        } else {
                            usersWithoutMentor.forEach(user => {
                                usersHtml += `
                                    <li style="padding: 10px; border-bottom: 1px solid #eee; font-size: 1.1rem;">
                                        员工ID ${user.id},职位:${user.position}
                                        <button onclick="showMentorList(${user.id})" style="font-size: 1rem; padding: 5px 10px; background-color: #007bff; color: white; border: none; border-radius: 4px; cursor: pointer; margin-left: 10px;">选择导师</button>
                                    </li>
                                `;
                            });
                        }
                        usersHtml += '</ul>';
                        document.getElementById('level1UsersList').innerHTML = usersHtml;
                    })
                    .catch(error => {
                        console.error('获取职级为1的员工出错:', error);
                        document.getElementById('level1UsersList').innerHTML = '<p style="color: red; font-size: 1.1rem;">获取职级为1的员工失败,请重试</p>';
                    });
            } else {
                // 其他情况显示无权限
                document.getElementById('level1UsersList').innerHTML = `
                    <p style="font-size: 1.2rem; color: #666;">您没有权限进行此操作。</p>
                `;
            }
        })
        .catch(error => {
            console.error('获取当前用户信息出错:', error);
            document.getElementById('level1UsersList').innerHTML = '<p style="color: red; font-size: 1.1rem;">获取用户信息失败,请重试</p>';
        });
}

// 显示指定新人所在部门里职级为2的员工
function showMentorList(menteeId) {
    fetch(`/api/user/get-level2-users-by-mentee/${menteeId}`)
        .then(response => {
            if (!response.ok) {
                throw new Error('网络响应失败');
            }
            return response.json();
        })
        .then(level2Users => {
            // 确保 DOM 元素存在
            const mentorListContainer = document.getElementById('level2MentorsList');
            if (!mentorListContainer) {
                console.error('DOM 元素 level2MentorsList 不存在');
                return;
            }

            // 渲染职级为2的员工列表
            let mentorsHtml = '<ul style="list-style-type: none; padding: 0; margin-top: 20px;">';
            if (level2Users.length === 0) {
                mentorsHtml += `
                    <li style="padding: 10px; color: #666; font-size: 1.1rem;">
                        当前没有职级为2的导师。
                    </li>
                `;
            } else {
                level2Users.forEach(user => {
                    mentorsHtml += `
                        <li style="padding: 10px; border-bottom: 1px solid #eee; font-size: 1.1rem;">
                            员工ID ${user.id},职位:${user.position}
                            <button onclick="assignMentor(${menteeId}, ${user.id})" style="font-size: 1rem; padding: 5px 10px; background-color: #007bff; color: white; border: none; border-radius: 4px; cursor: pointer; margin-left: 10px;">选择</button>
                        </li>
                    `;
                });
            }
            mentorsHtml += '</ul>';
            mentorListContainer.innerHTML = mentorsHtml;
        })
        .catch(error => {
            console.error('获取职级为2的导师出错:', error);
            const mentorListContainer = document.getElementById('level2MentorsList');
            if (mentorListContainer) {
                mentorListContainer.innerHTML = '<p style="color: red; font-size: 1.1rem;">获取职级为2的导师失败,请重试</p>';
            }
        });
}
// 分配导师给新人
function assignMentor(menteeId, mentorId) {
    fetch('/api/mentorship/assign-mentor', {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json',
        },
        body: JSON.stringify({ menteeId, mentorId })
    })
    .then(response => {
        if (!response.ok) {
            throw new Error('网络响应失败');
        }
        return response.json();
    })
    .then(data => {
        alert('导师分配成功!');
        // 刷新页面以显示新数据
        location.reload();
    })
    .catch(error => {
        console.error('分配导师出错:', error);
        alert('分配导师失败,请重试');
    });
}

// 显示当前用户的新人成长信息
function loadMentorshipInfo() {
    fetch('/api/user/current-user-info')
        .then(response => {
            if (!response.ok) {
                throw new Error('网络响应失败');
            }
            return response.json();
        })
        .then(data => {
            const mentorshipInfoContainer = document.getElementById('mentorshipInfoContainer');
            const permissionLevel = data.permissionLevel;
            const departmentId = data.departmentId;

            // 清空容器
            mentorshipInfoContainer.innerHTML = '';

            if (departmentId === 4 && permissionLevel === 3) {
                // 如果用户属于部门4且职级为3,则不显示职级不支持的信息
                // 这里可以根据需要显示其他信息或保持为空
            } else {
                // 如果用户不属于部门4或职级不是3,则显示职级不支持的信息
                mentorshipInfoContainer.innerHTML = `
                    <p style="font-size: 1.2rem;">您当前的职级或部门不支持查看新人成长信息</p>
                `;
                return; // 退出函数,不继续执行后续逻辑
            }

            // 获取当前用户的新人成长信息
            fetch('/api/user/current-mentorship-info')
                .then(response => {
                    if (!response.ok) {
                        throw new Error('网络响应失败');
                    }
                    return response.json();
                })
                .then(data => {
                    if (data.isLevel1) {
                        if (data.mentor) {
                            mentorshipInfoContainer.innerHTML += `
                                <p style="font-size: 1.2rem; margin-top: 10px;">您的带队导师是:员工ID ${data.mentor.id},职位:${data.mentor.position}</p>
                            `;
                        } else {
                            mentorshipInfoContainer.innerHTML += `
                                <p style="font-size: 1.2rem; margin-top: 10px;">您目前没有带队导师</p>
                            `;
                        }
                    } else if (data.isLevel2) {
                        if (data.mentees && data.mentees.length > 0) {
                            let menteesHtml = '<ul style="list-style-type: none; padding: 0; margin-top: 10px;">';
                            data.mentees.forEach(mentee => {
                                menteesHtml += `
                                    <li style="padding: 8px; border-bottom: 1px solid #eee;">
                                        员工ID ${mentee.id},职位:${mentee.position}
                                    </li>
                                `;
                            });
                            menteesHtml += '</ul>';
                            mentorshipInfoContainer.innerHTML += `
                                <p style="font-size: 1.2rem; margin-top: 10px;">您带领的新人:</p>
                                ${menteesHtml}
                            `;
                        } else {
                            mentorshipInfoContainer.innerHTML += `
                                <p style="font-size: 1.2rem; margin-top: 10px;">您目前没有带领的新人</p>
                            `;
                        }
                    }
                })
                .catch(error => {
                    console.error('获取当前用户新人成长信息出错:', error);
                    mentorshipInfoContainer.innerHTML += '<p style="color: red; font-size: 1.2rem;">获取新人成长信息失败,请重试</p>';
                });
        })
        .catch(error => {
            console.error('获取当前用户信息出错:', error);
            document.getElementById('mentorshipInfoContainer').innerHTML = '<p style="color: red; font-size: 1.2rem;">获取用户信息失败,请刷新重试</p>';
        });
}

遇到的困难:
在我初步创建这个模块一直无法正运行,同样在使用开发者工具,一步步排查后才发现错误点,比如:在我的 onboardingManagement.js 文件里,代码尝试设置 innerHTML 属性时出错,原因是 departmentSelect 元素为 null,最后发现错误竟然是我忘记写入

导致的,之后也有类似的问题。

今天的任务:本来昨天是想做完真个员工管理模块,但因为误判了入职发展的规模,导致只能完成这个模块。今天希望完成这个大模块剩下的内容。

posted @ 2025-04-22 22:02  老汤姆233  阅读(14)  评论(0)    收藏  举报