企业级软件研发团队绩效考核系统开发(持续更新 Day 2)

0 阅读10分钟

作者:呱牛 

发布日期:2026年3月23日

最后更新:2026年3月24日

标签:FastAPI、绩效考核、企业级应用、Python、MySQL

感谢:FastApiAdmin v2.0.0 一套现代、开源、全栈融合的中后台快速开发平台

🔥 今日亮点

2026年3月24日 - 数据清洗功能开发完成

  • 新增数据清洗工具类:实现通用数据清洗逻辑,支持所有考核明细表
  • 完善数据质量保证:严格检查业务字段空值,确保数据完整性
  • 添加清洗日志记录:详细记录被过滤的数据,便于后续分析
  • 优化处理逻辑:支持无有效数据的情况,提高系统稳定性
  • 无缝集成:与现有Excel解析流程完美融合

📋 文章目录

🎯 系统概述

1.1 项目背景

随着企业软件研发团队规模的扩大,传统的手工绩效考核方式已无法满足现代化管理的需求。我们开发了这套基于FastAPI的企业级绩效考核系统,旨在实现:

  • 自动化数据采集:支持Excel批量导入
  • 灵活配置:动态映射配置,无需修改代码
  • 多维度考核:覆盖需求、项目、运维三大类指标
  • 实时计算:基于规则的绩效分值计算
  • 安全可靠:完整的权限控制和数据审计

1.2 技术选型

技术栈版本说明
FastAPI0.104+高性能异步Web框架
SQLAlchemy2.0+ORM框架(异步模式)
MySQL8.0+主数据库
Pydantic2.0+数据验证和序列化
pandas2.0+Excel数据处理
JWT最新身份认证
RBAC自定义基于角色的权限控制

🏗️ 架构设计

2.1 整体架构

┌─────────────────────────────────────────────────────────┐
│                     前端层 (Vue3)                        │
│  ┌──────────┐  ┌──────────┐  ┌──────────┐              │
│  │  文件上传  │  │  数据展示  │  │  配置管理  │              │
│  └──────────┘  └──────────┘  └──────────┘              │
└─────────────────────────────────────────────────────────┘
                            ↓ HTTP/REST API
┌─────────────────────────────────────────────────────────┐
│                   控制器层 (Controller)                   │
│  ┌──────────────────────────────────────────────────┐  │
│  │  Excel上传控制器                                  │  │
│  │  - 文件上传解析                                    │  │
│  │  - 状态跟踪管理                                    │  │
│  └──────────────────────────────────────────────────┘  │
│  ┌──────────────────────────────────────────────────┐  │
│  │  绩效分值控制器                                   │  │
│  │  - 分值配置管理                                  │  │
│  │  - 绩效计算引擎                                  │  │
│  └──────────────────────────────────────────────────┘  │
└─────────────────────────────────────────────────────────┘
                            ↓
┌─────────────────────────────────────────────────────────┐
│                   服务层 (Service)                       │
│  ┌──────────────────────────────────────────────────┐  │
│  │  动态Excel解析器                                 │  │
│  │  - 映射配置解析                                  │  │
│  │  - 数据校验转换                                  │  │
│  └──────────────────────────────────────────────────┘  │
│  ┌──────────────────────────────────────────────────┐  │
│  │  分值计算引擎                                    │  │
│  │  - 规则解析执行                                  │  │
│  │  - 绩效结果生成                                  │  │
│  └──────────────────────────────────────────────────┘  │
│  ┌──────────────────────────────────────────────────┐  │
│  │  数据清洗工具                                    │  │
│  │  - 空值检测过滤                                  │  │
│  │  - 数据质量保证                                  │  │
│  └──────────────────────────────────────────────────┘  │
└─────────────────────────────────────────────────────────┘
                            ↓
┌─────────────────────────────────────────────────────────┐
│                   数据层 (CRUD/Model)                   │
│  ┌──────────┐  ┌──────────┐  ┌──────────┐              │
│  │ 27个指标表│  │ 配置表   │  │ 业务表   │              │
│  └──────────┘  └──────────┘  └──────────┘              │
└─────────────────────────────────────────────────────────┘

2.2 数据分层架构

系统采用三层数据架构,确保数据的一致性和可维护性:

配置层 (Configuration)

  • *_pa_indicator_mapping:Excel列与数据库字段映射关系
  • *_pa_perf_indicator_score:指标分值配置和评分标准规则

业务层 (Business)

  • *_pa_excel_upload_record:文件上传记录和解析状态跟踪

数据层 (Data)

  • 24个考核指标明细表:覆盖需求工作、项目工作、运维工作三大类

💾 数据模型

3.1 核心表结构

3.1.1 绩效指标分值表(核心配置)

CREATE TABLE *_pa_perf_indicator_score (
    id INT PRIMARY KEY AUTO_INCREMENT,
    uuid VARCHAR(64) UNIQUE,
    indicator_category VARCHAR(50) NOT NULL,     -- 指标分类
    indicator_level1_code VARCHAR(20) NOT NULL,  -- 指标一级编码
    indicator_level1_name VARCHAR(100) NOT NULL, -- 指标名称
    indicator_condition_code VARCHAR(20) NOT NULL, -- 判断条件编码(唯一键)
    judgment_condition VARCHAR(100) NOT NULL,     -- 判断条件
    indicator_score DECIMAL(5,2),                -- 指标分值
    unit VARCHAR(20),                            -- 计量单位
    sub_indicator_rule TEXT,                     -- 评分标准规则
    indicator_status TINYINT DEFAULT 1,          -- 指标状态
    -- 基础字段...
    UNIQUE KEY uk_condition_code (indicator_condition_code)
);

3.1.2 Excel上传记录表

CREATE TABLE *_pa_excel_upload_record (
    id INT PRIMARY KEY AUTO_INCREMENT,
    uuid VARCHAR(64) UNIQUE,
    assessment_period VARCHAR(6) NOT NULL,      -- 考核期次
    data_date DATE NOT NULL,                     -- 数据时点
    file_name VARCHAR(255),                      -- 文件名
    file_path VARCHAR(500),                      -- 文件路径
    parse_status VARCHAR(10) DEFAULT '0',         -- 解析状态
    parse_error_msg TEXT,                        -- 解析错误信息
    -- 基础字段...
);

3.2 数据流转机制

Excel文件上传 → 动态解析 → 数据清洗 → 指标明细表 → 分值计算 → 绩效结果
    ↓              ↓           ↓           ↓           ↓          ↓
映射配置表     指标分值表     质量保证     业务数据     评分规则     考核结果


⚙️ 核心功能

4.1 动态Excel解析

4.1.1 设计理念

通过数据库配置表实现Excel列与数据库字段的动态映射,避免硬编码,提高系统灵活性。

4.1.2 核心代码

class DynamicExcelParser:
    """动态Excel解析器"""
    
    def __init__(self, file_path: str, mappings: list[dict], common_fields: dict, start_row: int):
        self.file_path = file_path
        self.mappings = mappings  # 从数据库读取的映射配置
        self.common_fields = common_fields
        self.start_row = start_row - 1
    
    def parse(self) -> list[dict]:
        """解析Excel数据"""
        # 根据映射配置动态解析
        column_mapping = {}
        for mapping in self.mappings:
            col_index = self._column_name_to_index(mapping['column_index'])
            column_mapping[col_index] = mapping['target_field_name']
        
        # 使用pandas读取Excel
        df = pd.read_excel(self.file_path, header=self.start_row)
        
        # 数据转换和校验
        data_list = []
        for _, row in df.iterrows():
            item = {}
            for col_idx, field_name in column_mapping.items():
                if col_idx < len(row):
                    item[field_name] = row.iloc[col_idx]
            
            # 添加公共字段
            item.update(self.common_fields)
            data_list.append(item)
        
        return data_list

4.2 绩效分值计算引擎

4.2.1 分值计算模式

基于配置化的评分规则引擎,实现灵活的绩效考核计算逻辑。

4.2.2 核心实现

class PerformanceScoreCalculator:
    """绩效分值计算引擎"""
    
    async def calculate_score(self, indicator_code: str, employee_data: dict) -> Decimal:
        """计算员工绩效分值"""
        # 获取指标配置
        score_config = await self._get_score_config(indicator_code)
        if not score_config:
            return Decimal('0.00')
        
        # 解析评分规则
        rule = score_config.sub_indicator_rule
        
        # 执行规则计算
        score = await self._execute_rule(rule, employee_data, score_config)
        return score
    
    async def _execute_rule(self, rule: str, data: dict, config) -> Decimal:
        """执行评分规则计算"""
        # 支持多种规则类型
        if "×" in rule:  # 乘法规则
            parts = rule.split("×")
            quantity_field = self._extract_field(parts[0])
            score_per_unit = self._extract_score(parts[1])
            quantity = data.get(quantity_field, 0)
            return Decimal(quantity) * score_per_unit
        
        # 条件规则、分段规则等...
        return Decimal('0.00')

4.3 数据清洗功能

4.3.1 设计理念

通过数据清洗工具,确保进入系统的数据质量,避免空值和无效数据导致的计算错误。

4.3.2 核心实现

class DataCleaningUtil:
    """数据清洗工具类"""
    
    # 系统保留字段列表
    SYSTEM_RESERVED_FIELDS = [
        'id', 'uuid', 'status', 'description',
        'created_time', 'updated_time', 'created_id', 'updated_id',
        'staff_no', 'real_name', 'position',
        'assessment_period', 'data_date'
    ]
    
    def clean_data(self, table_name: str, data: dict) -> tuple[bool, str]:
        """清洗单条数据"""
        # 检查业务数据字段是否存在空值
        empty_fields = []
        
        for field_name, field_value in data.items():
            # 跳过系统保留字段
            if field_name in self.SYSTEM_RESERVED_FIELDS:
                continue
            
            # 检查业务字段是否为空
            if self.is_empty_value(field_value):
                empty_fields.append(field_name)
        
        # 如果存在空字段,则过滤该数据
        if empty_fields:
            reason = f"业务字段存在空值: {', '.join(empty_fields)}"
            self._log_filtered_record(table_name, data, reason)
            return False, reason
        
        return True, ""
    
    def clean_batch_data(self, table_name: str, data_list: list[dict]) -> list[dict]:
        """批量清洗数据"""
        cleaned_data = []
        
        for data in data_list:
            is_valid, reason = self.clean_data(table_name, data)
            if is_valid:
                cleaned_data.append(data)
        
        log.info(f"表 {table_name} 数据清洗完成,原始数据 {len(data_list)} 条,清洗后 {len(cleaned_data)} 条,过滤 {len(data_list) - len(cleaned_data)} 条")
        
        return cleaned_data


🔧 开发指南

5.1 新增指标表开发步骤

5.1.1 创建数据库表

CREATE TABLE *_pa_kpi_c999 (
    id INT PRIMARY KEY AUTO_INCREMENT,
    uuid VARCHAR(64) UNIQUE,
    staff_no VARCHAR(20) NOT NULL,              -- 员工工号
    real_name VARCHAR(30) NOT NULL,             -- 员工姓名
    -- 业务字段...
    -- 基础字段...
    UNIQUE KEY uk_c999_staff_period (staff_no, assessment_period, data_date)
);

5.1.2 生成代码模块

使用代码生成器创建Model、Schema、CRUD、Service、Router文件。

5.1.3 配置映射关系

INSERT INTO *_pa_indicator_mapping 
(uuid, status, start_row, column_index, target_table_name, target_field_name, mapping_description)
VALUES 
(UUID(), '0', 5, 'A', '*_pa_kpi_c999', 'real_name', 'C999表-员工姓名'),
(UUID(), '0', 5, 'B', '*_pa_kpi_c999', 'staff_no', 'C999表-员工工号');

5.2 事务管理最佳实践

5.2.1 嵌套事务处理

# 使用嵌套事务确保单条记录失败不影响整体
for item in parsed_data:
    try:
        async with auth.db.begin_nested():
            await kpi_crud.create(data=item)
        inserted_count += 1
    except Exception as insert_error:
        if 'Duplicate entry' in str(insert_error):
            skipped_count += 1
            log.warning(f"跳过重复记录")
        else:
            log.error(f"插入失败: {str(insert_error)}")
            skipped_count += 1

5.3 数据清洗集成

5.3.1 集成到Excel解析流程

# 数据清洗
cleaned_data = data_cleaner.clean_batch_data(table_name, parsed_data)
total_cleaned += len(cleaned_data)

if cleaned_data:
    # 插入数据库
    for item in cleaned_data:
        try:
            async with auth.db.begin_nested():
                await kpi_crud.create(data=item)
            inserted_count += 1
        except Exception as insert_error:
            # 处理异常
else:
    log.info(f"表 {table_name} 数据清洗后无有效数据,跳过处理")


🚀 最佳实践

6.1 代码规范

6.1.1 命名规范

  • 类名: 大驼峰命名法( ***** PaKpiC402Model
  • 函数名: 小写+下划线(create_ ***** _pa_kpi_c402_service
  • 变量名: 小写+下划线(assessment_period

6.1.2 注释规范

def create_service(cls, auth: AuthSchema, data: CreateSchema) -> dict:
    """
    创建考核指标明细
    
    参数:
    - auth: 认证信息
    - data: 创建数据
    
    返回:
    - dict: 创建后的数据
    """
    # 实现代码...

6.2 性能优化

6.2.1 索引设计

-- 为常用查询字段添加索引
CREATE INDEX idx_staff_no ON *_pa_kpi_c402(staff_no);
CREATE INDEX idx_assessment_period ON *_pa_kpi_c402(assessment_period);

6.2.2 批量操作

# 使用批量插入代替循环插入
await crud.create_batch(data=items)  # 推荐

# 避免
for item in items:
    await crud.create(data=item)     # 不推荐


📊 系统规模统计

7.1 数据表统计

层级表数量说明
配置层2个映射配置 + 分值配置
业务层1个上传记录管理
数据层24个考核指标明细表
总计27个完整的企业级系统

7.2 指标分类统计

指标类型表数量占比
需求工作8个33.3%
项目工作13个54.2%
运维工作3个12.5%

🔍 常见问题

Q1: 如何添加新的指标表?

A: 参考 5.1 新增指标表开发步骤

Q2: Excel上传后数据没有插入成功?

A: 检查以下问题:

  • Excel文件格式是否正确
  • 映射配置是否完整
  • 员工工号字段是否包含在Excel中
  • 数据库连接是否正常

Q3: 如何处理重复数据?

A: 系统通过唯一键约束自动处理重复数据,重复记录会被跳过并记录警告日志。

Q4: 数据清洗后无有效数据怎么办?

A: 系统会自动跳过无有效数据的表,不影响其他表的处理。


📈 更新日志

2026年3月24日 - 数据清洗功能开发完成

🎉 今日重点工作

  • 核心功能开发

    • 新增 数据清洗工具类(DataCleaningUtil)
    • 实现 通用数据清洗逻辑
    • 集成 数据清洗到Excel解析流程
    • 新增 数据清洗日志记录功能
  • 功能优化

    • 优化 数据清洗处理逻辑,支持无有效数据的情况
    • 完善 开发手册文档
  • 技术亮点

    • 🚀 通用化设计:支持所有考核明细表的数据清洗
    • 📊 数据质量保证:严格检查业务字段空值
    • 📋 详细日志记录:便于数据质量分析和问题追踪
    • 🔄 无缝集成:与现有Excel解析流程完美融合

2026年3月23日

  • 新增 绩效指标分值表( ***** _pa_perf_indicator_score)
  • 优化 三层数据架构设计
  • 新增 分值计算引擎
  • 完善 开发手册文档
  • 优化 事务管理机制

2026年3月22日

  • 完成 24个考核指标表的开发
  • 实现 动态Excel解析功能
  • 建立 映射配置系统

💡 后续规划

短期目标(1个月内)

  • 数据可视化报表

中期目标(3个月内)

  • 多维度绩效分析
  • 自动化报告生成

长期目标(6个月内)

  • 开源合作

版权声明:本文由呱牛原创,转载请注明出处。

技术交流:欢迎在评论区留言讨论,我们会及时回复。

持续更新:本文档将随着系统开发持续更新,敬请关注!