HR_DASHBOARD_PART2_MODULES.md 15 KB

人事板块首页分析与实现方案 - 第2部分:核心功能模块

📋 续:功能模块详细分析

2️⃣ 招聘流程优化页面 (Recruitment Tab - 续)

2.2 招聘流程跟踪

功能描述:跟踪候选人在招聘各阶段的进展

数据来源:需要新建 RecruitmentProcess

新建表RecruitmentProcess

RecruitmentProcess {
  resume: Pointer<Resume>         // 关联简历
  candidate: {
    name: string
    phone: string
    email: string
  },
  jobPosition: string             // 应聘职位
  department: Pointer<Department> // 部门
  
  currentStage: string            // 当前阶段
  stages: Array<{
    id: string
    name: string                  // 简历筛选/初试/复试/终试/发offer
    status: 'completed' | 'active' | 'pending' | 'blocked'
    completedDate: Date
    responsible: Pointer<Profile>
    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<Profile>
    reason: string
  }
}

实现方案

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

PerformanceRecord {
  profile: Pointer<Profile>       // 关联员工
  department: Pointer<Department> // 部门
  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'
}

实现方案

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 绩效筛选功能

功能描述:按部门、职位、时间段筛选绩效数据

实现方案

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

查询逻辑

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

OnboardingCheckpoint {
  profile: Pointer<Profile>       // 关联新人
  title: string                   // 检查点标题
  description: string             // 描述
  type: 'week1' | 'week2' | 'month1' | 'month2' | 'month3'  // 阶段
  dueDate: Date                   // 截止日期
  completed: boolean              // 是否完成
  completedDate: Date             // 完成日期
  responsible: Pointer<Profile>   // 负责人(导师/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
  }>
}

实现方案

// 自动为新人创建检查点(入职时触发)
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部分:实施步骤和优先级...