add backend source code

This commit is contained in:
2026-02-28 15:06:52 +08:00
parent 1bc330e20c
commit 2c37aa9064
67 changed files with 11654 additions and 0 deletions

View File

@@ -0,0 +1,182 @@
"""${message}
Revision ID: initial
Revises:
Create Date: 2024-01-01 00:00:00.000000
"""
from typing import Sequence, Union
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision: str = 'initial'
down_revision: Union[str, None] = None
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None
def upgrade() -> None:
# 创建科室表
op.create_table(
'departments',
sa.Column('id', sa.Integer(), autoincrement=True, nullable=False),
sa.Column('name', sa.String(length=100), nullable=False, comment='科室名称'),
sa.Column('code', sa.String(length=20), nullable=False, comment='科室编码'),
sa.Column('dept_type', sa.String(length=50), nullable=False, comment='科室类型'),
sa.Column('parent_id', sa.Integer(), nullable=True, comment='上级科室'),
sa.Column('level', sa.Integer(), nullable=True, comment='层级'),
sa.Column('sort_order', sa.Integer(), nullable=True, comment='排序'),
sa.Column('is_active', sa.Boolean(), nullable=True, comment='是否启用'),
sa.Column('description', sa.Text(), nullable=True, comment='描述'),
sa.Column('created_at', sa.DateTime(), nullable=True, comment='创建时间'),
sa.Column('updated_at', sa.DateTime(), nullable=True, comment='更新时间'),
sa.PrimaryKeyConstraint('id'),
sa.UniqueConstraint('code')
)
op.create_index('idx_dept_type', 'departments', ['dept_type'])
op.create_index('idx_dept_parent', 'departments', ['parent_id'])
# 创建员工表
op.create_table(
'staff',
sa.Column('id', sa.Integer(), autoincrement=True, nullable=False),
sa.Column('employee_id', sa.String(length=20), nullable=False, comment='工号'),
sa.Column('name', sa.String(length=50), nullable=False, comment='姓名'),
sa.Column('department_id', sa.Integer(), nullable=False, comment='所属科室'),
sa.Column('position', sa.String(length=50), nullable=False, comment='职位'),
sa.Column('title', sa.String(length=50), nullable=True, comment='职称'),
sa.Column('phone', sa.String(length=20), nullable=True, comment='联系电话'),
sa.Column('email', sa.String(length=100), nullable=True, comment='邮箱'),
sa.Column('base_salary', sa.Numeric(precision=10, scale=2), nullable=True, comment='基本工资'),
sa.Column('performance_ratio', sa.Numeric(precision=5, scale=2), nullable=True, comment='绩效系数'),
sa.Column('status', sa.String(length=50), nullable=True, comment='状态'),
sa.Column('hire_date', sa.DateTime(), nullable=True, comment='入职日期'),
sa.Column('created_at', sa.DateTime(), nullable=True, comment='创建时间'),
sa.Column('updated_at', sa.DateTime(), nullable=True, comment='更新时间'),
sa.ForeignKeyConstraint(['department_id'], ['departments.id']),
sa.PrimaryKeyConstraint('id'),
sa.UniqueConstraint('employee_id')
)
op.create_index('idx_staff_dept', 'staff', ['department_id'])
op.create_index('idx_staff_status', 'staff', ['status'])
# 创建指标表
op.create_table(
'indicators',
sa.Column('id', sa.Integer(), autoincrement=True, nullable=False),
sa.Column('name', sa.String(length=100), nullable=False, comment='指标名称'),
sa.Column('code', sa.String(length=20), nullable=False, comment='指标编码'),
sa.Column('indicator_type', sa.String(length=50), nullable=False, comment='指标类型'),
sa.Column('weight', sa.Numeric(precision=5, scale=2), nullable=True, comment='权重'),
sa.Column('max_score', sa.Numeric(precision=5, scale=2), nullable=True, comment='最高分值'),
sa.Column('target_value', sa.Numeric(precision=10, scale=2), nullable=True, comment='目标值'),
sa.Column('unit', sa.String(length=20), nullable=True, comment='计量单位'),
sa.Column('calculation_method', sa.Text(), nullable=True, comment='计算方法'),
sa.Column('description', sa.Text(), nullable=True, comment='描述'),
sa.Column('is_active', sa.Boolean(), nullable=True, comment='是否启用'),
sa.Column('created_at', sa.DateTime(), nullable=True, comment='创建时间'),
sa.Column('updated_at', sa.DateTime(), nullable=True, comment='更新时间'),
sa.PrimaryKeyConstraint('id'),
sa.UniqueConstraint('code')
)
op.create_index('idx_indicator_type', 'indicators', ['indicator_type'])
# 创建考核记录表
op.create_table(
'assessments',
sa.Column('id', sa.Integer(), autoincrement=True, nullable=False),
sa.Column('staff_id', sa.Integer(), nullable=False, comment='员工ID'),
sa.Column('period_year', sa.Integer(), nullable=False, comment='考核年度'),
sa.Column('period_month', sa.Integer(), nullable=False, comment='考核月份'),
sa.Column('period_type', sa.String(length=20), nullable=True, comment='考核周期类型'),
sa.Column('total_score', sa.Numeric(precision=5, scale=2), nullable=True, comment='总分'),
sa.Column('weighted_score', sa.Numeric(precision=5, scale=2), nullable=True, comment='加权得分'),
sa.Column('status', sa.String(length=50), nullable=True, comment='状态'),
sa.Column('assessor_id', sa.Integer(), nullable=True, comment='考核人'),
sa.Column('reviewer_id', sa.Integer(), nullable=True, comment='审核人'),
sa.Column('submit_time', sa.DateTime(), nullable=True, comment='提交时间'),
sa.Column('review_time', sa.DateTime(), nullable=True, comment='审核时间'),
sa.Column('remark', sa.Text(), nullable=True, comment='备注'),
sa.Column('created_at', sa.DateTime(), nullable=True, comment='创建时间'),
sa.Column('updated_at', sa.DateTime(), nullable=True, comment='更新时间'),
sa.ForeignKeyConstraint(['staff_id'], ['staff.id']),
sa.ForeignKeyConstraint(['assessor_id'], ['staff.id']),
sa.ForeignKeyConstraint(['reviewer_id'], ['staff.id']),
sa.PrimaryKeyConstraint('id')
)
op.create_index('idx_assessment_staff', 'assessments', ['staff_id'])
op.create_index('idx_assessment_period', 'assessments', ['period_year', 'period_month'])
op.create_index('idx_assessment_status', 'assessments', ['status'])
# 创建考核明细表
op.create_table(
'assessment_details',
sa.Column('id', sa.Integer(), autoincrement=True, nullable=False),
sa.Column('assessment_id', sa.Integer(), nullable=False, comment='考核记录ID'),
sa.Column('indicator_id', sa.Integer(), nullable=False, comment='指标ID'),
sa.Column('actual_value', sa.Numeric(precision=10, scale=2), nullable=True, comment='实际值'),
sa.Column('score', sa.Numeric(precision=5, scale=2), nullable=True, comment='得分'),
sa.Column('evidence', sa.Text(), nullable=True, comment='佐证材料'),
sa.Column('remark', sa.Text(), nullable=True, comment='备注'),
sa.Column('created_at', sa.DateTime(), nullable=True, comment='创建时间'),
sa.Column('updated_at', sa.DateTime(), nullable=True, comment='更新时间'),
sa.ForeignKeyConstraint(['assessment_id'], ['assessments.id']),
sa.ForeignKeyConstraint(['indicator_id'], ['indicators.id']),
sa.PrimaryKeyConstraint('id')
)
op.create_index('idx_detail_assessment', 'assessment_details', ['assessment_id'])
op.create_index('idx_detail_indicator', 'assessment_details', ['indicator_id'])
# 创建工资记录表
op.create_table(
'salary_records',
sa.Column('id', sa.Integer(), autoincrement=True, nullable=False),
sa.Column('staff_id', sa.Integer(), nullable=False, comment='员工ID'),
sa.Column('period_year', sa.Integer(), nullable=False, comment='年度'),
sa.Column('period_month', sa.Integer(), nullable=False, comment='月份'),
sa.Column('base_salary', sa.Numeric(precision=10, scale=2), nullable=True, comment='基本工资'),
sa.Column('performance_score', sa.Numeric(precision=5, scale=2), nullable=True, comment='绩效得分'),
sa.Column('performance_bonus', sa.Numeric(precision=10, scale=2), nullable=True, comment='绩效奖金'),
sa.Column('deduction', sa.Numeric(precision=10, scale=2), nullable=True, comment='扣款'),
sa.Column('allowance', sa.Numeric(precision=10, scale=2), nullable=True, comment='补贴'),
sa.Column('total_salary', sa.Numeric(precision=10, scale=2), nullable=True, comment='应发工资'),
sa.Column('status', sa.String(length=50), nullable=True, comment='状态'),
sa.Column('remark', sa.Text(), nullable=True, comment='备注'),
sa.Column('created_at', sa.DateTime(), nullable=True, comment='创建时间'),
sa.Column('updated_at', sa.DateTime(), nullable=True, comment='更新时间'),
sa.ForeignKeyConstraint(['staff_id'], ['staff.id']),
sa.PrimaryKeyConstraint('id')
)
op.create_index('idx_salary_staff', 'salary_records', ['staff_id'])
op.create_index('idx_salary_period', 'salary_records', ['period_year', 'period_month'])
# 创建用户表
op.create_table(
'users',
sa.Column('id', sa.Integer(), autoincrement=True, nullable=False),
sa.Column('username', sa.String(length=50), nullable=False, comment='用户名'),
sa.Column('password_hash', sa.String(length=255), nullable=False, comment='密码哈希'),
sa.Column('staff_id', sa.Integer(), nullable=True, comment='关联员工'),
sa.Column('role', sa.String(length=20), nullable=True, comment='角色'),
sa.Column('is_active', sa.Boolean(), nullable=True, comment='是否启用'),
sa.Column('last_login', sa.DateTime(), nullable=True, comment='最后登录'),
sa.Column('created_at', sa.DateTime(), nullable=True, comment='创建时间'),
sa.Column('updated_at', sa.DateTime(), nullable=True, comment='更新时间'),
sa.ForeignKeyConstraint(['staff_id'], ['staff.id']),
sa.PrimaryKeyConstraint('id'),
sa.UniqueConstraint('username')
)
op.create_index('idx_user_username', 'users', ['username'])
def downgrade() -> None:
op.drop_table('users')
op.drop_table('salary_records')
op.drop_table('assessment_details')
op.drop_table('assessments')
op.drop_table('indicators')
op.drop_table('staff')
op.drop_table('departments')