Files
PayrollManagementSystem/backend/app/models/calc_template.py
T
liuwenxin 1461a8d113 feat(后端): 添加授权体系、系统监控与试用期计提
按 2026-11-02 需求补齐计划交付后端能力:
- 角色授权:权限目录化,接口统一准入校验,未登记默认拒绝;
  管理员判断改为按数据库角色重新判定,防止权限码持有者绕过
- 系统监控:单进程采集资源、请求与异常指标,分钟级聚合,
  阈值配置化;敏感配置增加 repr 保护,Redis 密码 URL 转义
- 试用期计提:按回款日判定并写入快照,年度结清与调整单联动;
  人员模型补试用期、离职日期与工资版本历史字段
- 计提模板:公式骨架受控,页面维护名称与参数绑定
- T+ 采集:自动化配置表与进度查询

内置角色禁停用保护对齐模块注释;核算规则版本提为常量并
补充批量核算失败堆栈日志。

影响范围:后端全部模块、数据库迁移 V22-V28
验证:uv run ruff check 通过;922 个单元测试全部通过;
集成测试因本机 MySQL 数据卷被其他容器锁定暂未运行
2026-11-03 11:20:55 +08:00

53 lines
2.3 KiB
Python

"""计提公式模板定义模型。
把一期代码内注册表升级为数据库配置:模板名称、说明、参数绑定可在页面维护,
公式执行骨架仍是受控枚举(formula_type),不允许自由表达式,避免注入与算错。
岗位角色 `business_roles.calc_template` 绑定模板编码,编码创建后不可修改。
"""
from sqlalchemy import JSON, Integer, String
from sqlalchemy.orm import Mapped, mapped_column
from app.models.base import BIGINT_UNSIGNED, TINYINT_TYPE, Base, TimestampMixin, mysql_table_args
class CalcTemplateDefinition(Base, TimestampMixin):
"""计提公式模板定义表。内置模板随迁移初始化,页面可新增自定义模板。"""
__tablename__ = "calc_template_definitions"
__table_args__ = mysql_table_args("计提公式模板定义表(页面可维护,骨架受控)")
id: Mapped[int] = mapped_column(
BIGINT_UNSIGNED, primary_key=True, autoincrement=True, comment="主键ID"
)
template_code: Mapped[str] = mapped_column(
String(32),
nullable=False,
unique=True,
comment="模板编码,创建后不可修改;岗位表 business_roles.calc_template 引用",
)
template_name: Mapped[str] = mapped_column(String(64), nullable=False, comment="模板名称")
formula_type: Mapped[str] = mapped_column(
String(32),
nullable=False,
comment="公式骨架类型:linear_decay/fixed_profit/fixed_sales/manager_share/prepay_fixed,创建后不可修改",
)
params_json: Mapped[dict] = mapped_column(
JSON,
nullable=False,
comment="骨架参数角色到参数编码的 JSON 映射,如 {start:..., slope:...}",
)
description: Mapped[str | None] = mapped_column(String(255), comment="模板说明")
sort_order: Mapped[int] = mapped_column(
Integer, nullable=False, server_default="0", comment="显示排序"
)
status: Mapped[int] = mapped_column(
TINYINT_TYPE, nullable=False, server_default="1", comment="状态:1启用 0停用"
)
is_system: Mapped[int] = mapped_column(
TINYINT_TYPE,
nullable=False,
server_default="0",
comment="是否系统模板:1内置(禁删、骨架与编码锁定) 0自定义",
)