# 人事板块首页分析与实现方案 - 第2部分:核心功能模块 ## 📋 续:功能模块详细分析 ### 2️⃣ **招聘流程优化页面** (Recruitment Tab - 续) #### 2.2 招聘流程跟踪 **功能描述**:跟踪候选人在招聘各阶段的进展 **数据来源**:需要新建 `RecruitmentProcess` 表 **新建表**:`RecruitmentProcess` ```typescript RecruitmentProcess { resume: Pointer // 关联简历 candidate: { name: string phone: string email: string }, jobPosition: string // 应聘职位 department: Pointer // 部门 currentStage: string // 当前阶段 stages: Array<{ id: string name: string // 简历筛选/初试/复试/终试/发offer status: 'completed' | 'active' | 'pending' | 'blocked' completedDate: Date responsible: Pointer notes: string evaluationResults: Array<{ evaluator: string result: 'pass' | 'fail' | 'pending' score: number comments: string }> }>, status: 'in_progress' | 'passed' | 'rejected' | 'withdrawn' finalDecision: { result: string decisionDate: Date decisionMaker: Pointer reason: string } } ``` **实现方案**: ```typescript async loadRecruitmentProcesses() { const query = new Parse.Query('RecruitmentProcess'); query.equalTo('status', 'in_progress'); query.include('resume'); query.include('department'); query.descending('createdAt'); query.limit(50); const processes = await query.find(); // 统计各阶段人数 const stageStats = { '简历筛选': 0, '初试': 0, '复试': 0, '终试': 0, '发offer': 0 }; processes.forEach(process => { const currentStage = process.get('currentStage'); if (stageStats[currentStage] !== undefined) { stageStats[currentStage]++; } }); return { processes: processes.map(p => this.formatProcessData(p)), statistics: stageStats }; } // 推进候选人到下一阶段 async advanceToNextStage(processId: string, stageId: string, evaluation: any) { const process = await new Parse.Query('RecruitmentProcess').get(processId); const stages = process.get('stages'); // 更新当前阶段 const currentStage = stages.find(s => s.id === stageId); currentStage.status = 'completed'; currentStage.completedDate = new Date(); currentStage.evaluationResults.push(evaluation); // 激活下一阶段 const currentIndex = stages.findIndex(s => s.id === stageId); if (currentIndex < stages.length - 1) { stages[currentIndex + 1].status = 'active'; process.set('currentStage', stages[currentIndex + 1].name); } process.set('stages', stages); await process.save(); } ``` --- ### 3️⃣ **绩效统计与分析页面** (Performance Tab) #### 3.1 绩效对比分析 **功能描述**:横向对比员工、部门或项目的绩效 **数据来源**:复用 `Project` 表 + 新建 `PerformanceRecord` 表 **新建表**:`PerformanceRecord` ```typescript PerformanceRecord { profile: Pointer // 关联员工 department: Pointer // 部门 period: { year: number month: number quarter: number }, // 项目相关绩效 projectMetrics: { totalProjects: number // 负责项目总数 completedProjects: number // 完成项目数 excellentProjects: number // 优秀项目数 overdueProjects: number // 延期项目数 averageQuality: number // 平均质量评分 averageSatisfaction: number // 平均客户满意度 }, // 个人能力评估 capabilities: { design: number // 设计能力 (0-100) communication: number // 沟通能力 execution: number // 执行能力 innovation: number // 创新能力 teamwork: number // 团队协作 growth: number // 成长潜力 }, // 综合评分 overallScore: number, rank: string, // 排名 level: 'excellent' | 'good' | 'average' | 'below_average' } ``` **实现方案**: ```typescript async loadPerformanceComparison(comparisonType: 'employee' | 'department' | 'project') { const currentPeriod = { year: new Date().getFullYear(), month: new Date().getMonth() + 1, quarter: Math.ceil((new Date().getMonth() + 1) / 3) }; const query = new Parse.Query('PerformanceRecord'); query.equalTo('period.year', currentPeriod.year); query.equalTo('period.month', currentPeriod.month); query.include('profile'); query.include('department'); query.descending('overallScore'); query.limit(20); const records = await query.find(); if (comparisonType === 'employee') { return this.formatEmployeeComparison(records); } else if (comparisonType === 'department') { return this.aggregateDepartmentPerformance(records); } else { return this.aggregateProjectPerformance(records); } } // 自动生成绩效记录(定时任务) async generateMonthlyPerformanceRecords() { const profiles = await this.getActiveDesigners(); const lastMonth = this.getLastMonthPeriod(); await Promise.all(profiles.map(async profile => { // 查询该员工上月的项目数据 const projectQuery = new Parse.Query('Project'); projectQuery.equalTo('assignee', profile); projectQuery.greaterThanOrEqualTo('createdAt', lastMonth.startDate); projectQuery.lessThanOrEqualTo('createdAt', lastMonth.endDate); const projects = await projectQuery.find(); // 计算项目指标 const metrics = this.calculateProjectMetrics(projects); // 计算能力评估(从项目反馈和评价中提取) const capabilities = await this.calculateCapabilities(profile, projects); // 计算综合评分 const overallScore = this.calculateOverallScore(metrics, capabilities); // 保存绩效记录 const PerformanceRecordClass = Parse.Object.extend('PerformanceRecord'); const record = new PerformanceRecordClass(); record.set('profile', profile); record.set('department', profile.get('department')); record.set('period', lastMonth.period); record.set('projectMetrics', metrics); record.set('capabilities', capabilities); record.set('overallScore', overallScore); record.set('level', this.getPerformanceLevel(overallScore)); await record.save(); })); } ``` --- #### 3.2 绩效筛选功能 **功能描述**:按部门、职位、时间段筛选绩效数据 **实现方案**: ```typescript async filterPerformanceRecords(filters: { department?: string, position?: string, startDate?: Date, endDate?: Date, level?: string }) { const query = new Parse.Query('PerformanceRecord'); if (filters.department) { const deptQuery = new Parse.Query('Department'); deptQuery.equalTo('name', filters.department); const dept = await deptQuery.first(); query.equalTo('department', dept); } if (filters.position) { const profileQuery = new Parse.Query('Profile'); profileQuery.equalTo('roleName', filters.position); query.matchesQuery('profile', profileQuery); } if (filters.startDate && filters.endDate) { query.greaterThanOrEqualTo('createdAt', filters.startDate); query.lessThanOrEqualTo('createdAt', filters.endDate); } if (filters.level) { query.equalTo('level', filters.level); } query.include('profile'); query.include('department'); query.descending('overallScore'); return await query.find(); } ``` --- ### 4️⃣ **新人跟进管理页面** (Onboarding Tab) #### 4.1 新人列表 **功能描述**:展示所有试用期员工的信息 **数据来源**:复用 `Profile` 表 **查询逻辑**: ```typescript async loadNewbieList() { const query = new Parse.Query('Profile'); query.equalTo('isActivated', true); query.notEqualTo('isDeleted', true); // 筛选试用期员工 query.equalTo('data.hrData.employmentStatus', 'probation'); query.include('department'); query.ascending('createdAt'); const profiles = await query.find(); return profiles.map(profile => ({ id: profile.id, name: profile.get('data')?.realname || profile.get('name'), department: profile.get('department')?.get('name'), position: profile.get('roleName'), hireDate: profile.get('data')?.hrData?.hireDate, daysInCompany: this.calculateDaysInCompany(profile.get('createdAt')), mentor: profile.get('data')?.hrData?.mentor, // 导师 status: this.getOnboardingStatus(profile) })); } getOnboardingStatus(profile: any) { const daysInCompany = this.calculateDaysInCompany(profile.get('createdAt')); if (daysInCompany <= 7) return { text: '第一周', color: 'green' }; if (daysInCompany <= 30) return { text: '第一个月', color: 'blue' }; if (daysInCompany <= 60) return { text: '第二个月', color: 'orange' }; if (daysInCompany <= 90) return { text: '第三个月', color: 'red' }; return { text: '即将转正', color: 'purple' }; } ``` --- #### 4.2 跟进检查点 **功能描述**:管理新人入职各阶段的跟进任务 **数据来源**:新建 `OnboardingCheckpoint` 表 **新建表**:`OnboardingCheckpoint` ```typescript OnboardingCheckpoint { profile: Pointer // 关联新人 title: string // 检查点标题 description: string // 描述 type: 'week1' | 'week2' | 'month1' | 'month2' | 'month3' // 阶段 dueDate: Date // 截止日期 completed: boolean // 是否完成 completedDate: Date // 完成日期 responsible: Pointer // 负责人(导师/HR) interviewTemplate: Array<{ question: string answer: string }>, // 访谈问题和答案 feedback: { newbieFeedback: string // 新人反馈 mentorFeedback: string // 导师反馈 hrFeedback: string // HR反馈 }, issues: Array<{ description: string severity: 'high' | 'medium' | 'low' resolved: boolean resolution: string }> } ``` **实现方案**: ```typescript // 自动为新人创建检查点(入职时触发) async createOnboardingCheckpoints(profileId: string) { const profile = await new Parse.Query('Profile').get(profileId); const hireDate = profile.get('data')?.hrData?.hireDate || new Date(); const checkpointTemplates = [ { type: 'week1', title: '第一周访谈', description: '了解新人适应情况,解答疑问', daysFromHire: 7, questions: [ '工作环境是否适应?', '团队成员是否友好?', '是否遇到困难?', '对公司的第一印象如何?' ] }, { type: 'month1', title: '第一个月评估', description: '评估工作表现,提供改进建议', daysFromHire: 30, questions: [ '是否熟悉工作流程?', '完成了哪些工作任务?', '遇到的主要挑战是什么?', '需要哪些培训和支持?' ] }, { type: 'month2', title: '第二个月中期评估', description: '检查进步情况', daysFromHire: 60, questions: [ '技能提升了多少?', '能否独立完成任务?', '与团队协作如何?', '职业发展规划是什么?' ] }, { type: 'month3', title: '转正前评估', description: '决定是否转正', daysFromHire: 85, questions: [ '整体工作表现如何?', '达到转正标准了吗?', '长期发展意向如何?', '对公司的建议?' ] } ]; const OnboardingCheckpointClass = Parse.Object.extend('OnboardingCheckpoint'); await Promise.all(checkpointTemplates.map(async template => { const checkpoint = new OnboardingCheckpointClass(); checkpoint.set('profile', profile); checkpoint.set('title', template.title); checkpoint.set('description', template.description); checkpoint.set('type', template.type); const dueDate = new Date(hireDate); dueDate.setDate(dueDate.getDate() + template.daysFromHire); checkpoint.set('dueDate', dueDate); checkpoint.set('completed', false); checkpoint.set('interviewTemplate', template.questions.map(q => ({ question: q, answer: '' }))); await checkpoint.save(); })); } // 加载某个新人的所有检查点 async loadNewbieCheckpoints(profileId: string) { const query = new Parse.Query('OnboardingCheckpoint'); const profilePtr = new Parse.Object('Profile'); profilePtr.id = profileId; query.equalTo('profile', profilePtr); query.ascending('dueDate'); return await query.find(); } // 完成检查点 async completeCheckpoint(checkpointId: string, data: { interviewAnswers: Array<{ question: string, answer: string }>, feedback: any, issues?: any[] }) { const checkpoint = await new Parse.Query('OnboardingCheckpoint').get(checkpointId); checkpoint.set('completed', true); checkpoint.set('completedDate', new Date()); checkpoint.set('interviewTemplate', data.interviewAnswers); checkpoint.set('feedback', data.feedback); if (data.issues && data.issues.length > 0) { checkpoint.set('issues', data.issues); } await checkpoint.save(); } ``` --- ## 📊 数据库表总览 ### 现有表(可复用) 1. **Profile** - 员工信息 ✅ - 用于:职级分布、新人列表、绩效记录 2. **Project** - 项目信息 ✅ - 用于:绩效总览、部门绩效对比 3. **Department** - 部门信息 ✅ - 用于:所有需要部门维度的分析 --- ### 新建表(需要创建) 1. **ResignationRecord** - 离职记录 🆕 - 用于:离职原因分析 2. **Resume** - 简历信息 🆕 - 用于:AI简历分析、招聘流程跟踪 3. **ResumeAnalysis** - 简历AI分析结果 🆕 - 用于:AI简历筛选 4. **RecruitmentProcess** - 招聘流程 🆕 - 用于:招聘流程跟踪 5. **PerformanceRecord** - 绩效记录 🆕 - 用于:绩效对比分析 6. **OnboardingCheckpoint** - 入职检查点 🆕 - 用于:新人跟进管理 --- ## 🔄 与现有功能的复用关系 ### 1. 员工档案管理 (employee-records) **可复用**: - `Profile` 表的员工数据 - 职级分布统计 - 入离职数据统计 ### 2. 项目管理 (project-management) **可复用**: - `Project` 表的项目数据 - 项目完成率、延期率 - 客户满意度评分 ### 3. 部门管理 **可复用**: - `Department` 表 - 部门维度的所有统计 --- 待续第3部分:实施步骤和优先级...