Files
OnboardXAdmin/database/migrations/20260908_employee_contract_snapshot.sql
T
2026-09-09 14:57:41 +08:00

164 lines
9.6 KiB
SQL

-- 员工合同快照:一名正式员工的一份任务合同对应一条记录。
-- 常用字段独立存储用于筛选导出,VariablesJson 按 VariableCode 保存全部标准及自定义变量。
-- 适用数据库:MySQL 8.0+
SET NAMES utf8mb4;
CREATE TABLE IF NOT EXISTS `ob_employee_contract_snapshot` (
`Id` BIGINT NOT NULL COMMENT '主键',
`EmployeeId` BIGINT NOT NULL COMMENT '正式员工Id',
`TaskId` BIGINT NOT NULL COMMENT '来源入职任务Id',
`TaskContractId` BIGINT NOT NULL COMMENT '来源任务合同Id',
`TemplateId` BIGINT NOT NULL COMMENT '合同模板Id',
`TemplateVersionId` BIGINT NOT NULL COMMENT '合同模板版本Id',
`ContractName` VARCHAR(300) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '合同名称快照',
`ContractType` VARCHAR(50) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '合同类型快照',
`ContractStartDate` DATE DEFAULT NULL COMMENT '合同开始日期',
`ContractEndDate` DATE DEFAULT NULL COMMENT '合同结束日期',
`ContractTerm` VARCHAR(100) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '合同期限原始文本',
`ProbationStartDate` DATE DEFAULT NULL COMMENT '试用期开始日期',
`ProbationEndDate` DATE DEFAULT NULL COMMENT '试用期结束日期',
`ProbationTerm` VARCHAR(100) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '试用期期限原始文本',
`ProbationSalary` DECIMAL(18,2) DEFAULT NULL COMMENT '试用薪资,对应hr.ProbationSalary,不自动推算',
`BaseSalary` DECIMAL(18,2) DEFAULT NULL COMMENT '基本工资',
`PositionSalary` DECIMAL(18,2) DEFAULT NULL COMMENT '岗位工资',
`PerformanceAllowance` DECIMAL(18,2) DEFAULT NULL COMMENT '绩效津贴',
`AttendanceBonus` DECIMAL(18,2) DEFAULT NULL COMMENT '全勤奖',
`RegularSalary` DECIMAL(18,2) DEFAULT NULL COMMENT '转正后薪资',
`WorkCity` VARCHAR(300) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '工作地点或城市',
`PositionName` VARCHAR(300) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '合同岗位名称',
`EmployeeNo` VARCHAR(100) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '合同员工工号',
`VariablesJson` JSON NOT NULL COMMENT '按VariableCode索引的完整合同变量快照',
`SnapshotVersion` INT NOT NULL DEFAULT 1 COMMENT '快照结构版本',
`SnapshotAt` DATETIME(3) NOT NULL COMMENT '快照生成时间',
`ExtJson` LONGTEXT COLLATE utf8mb4_unicode_ci COMMENT '扩展信息',
`Status` VARCHAR(20) COLLATE utf8mb4_unicode_ci DEFAULT 'enable' COMMENT '记录状态',
`CreateTime` DATETIME(3) DEFAULT NULL COMMENT '创建时间',
`UpdateTime` DATETIME(3) DEFAULT NULL COMMENT '更新时间',
`CreateUserId` BIGINT DEFAULT NULL COMMENT '创建者Id',
`UpdateUserId` BIGINT DEFAULT NULL COMMENT '修改者Id',
`CreateUser` VARCHAR(200) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '创建人',
`UpdateUser` VARCHAR(200) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '更新人',
`IsDelete` TINYINT(1) DEFAULT 0 COMMENT '软删除',
PRIMARY KEY (`Id`),
UNIQUE KEY `uk_ob_employee_contract_snapshot_contract` (`TaskContractId`),
KEY `idx_ob_employee_contract_snapshot_employee` (`EmployeeId`, `IsDelete`),
KEY `idx_ob_employee_contract_snapshot_task` (`TaskId`, `IsDelete`),
KEY `idx_ob_employee_contract_snapshot_dates` (`ContractStartDate`, `ContractEndDate`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='正式员工合同业务快照';
-- 为已经审核建档且仍保留任务合同变量的员工补建快照。
INSERT IGNORE INTO `ob_employee_contract_snapshot` (
`Id`, `EmployeeId`, `TaskId`, `TaskContractId`, `TemplateId`, `TemplateVersionId`,
`ContractName`, `ContractType`, `ContractStartDate`, `ContractEndDate`, `ContractTerm`,
`ProbationStartDate`, `ProbationEndDate`, `ProbationTerm`, `ProbationSalary`,
`BaseSalary`, `PositionSalary`, `PerformanceAllowance`, `AttendanceBonus`, `RegularSalary`,
`WorkCity`, `PositionName`, `EmployeeNo`, `VariablesJson`, `SnapshotVersion`, `SnapshotAt`,
`Status`, `CreateTime`, `CreateUserId`, `CreateUser`, `IsDelete`
)
SELECT
contract.`Id`,
task.`EmployeeId`,
task.`Id`,
contract.`Id`,
contract.`TemplateId`,
contract.`TemplateVersionId`,
contract.`ContractName`,
contract.`ContractType`,
CASE
WHEN TRIM(variable.`ContractStartDateText`) REGEXP '^[0-9]{4}-[0-9]{1,2}-[0-9]{1,2}$'
THEN STR_TO_DATE(TRIM(variable.`ContractStartDateText`), '%Y-%m-%d')
ELSE NULL
END,
CASE
WHEN TRIM(variable.`ContractEndDateText`) REGEXP '^[0-9]{4}-[0-9]{1,2}-[0-9]{1,2}$'
THEN STR_TO_DATE(TRIM(variable.`ContractEndDateText`), '%Y-%m-%d')
ELSE NULL
END,
variable.`ContractTerm`,
CASE
WHEN TRIM(variable.`ProbationStartDateText`) REGEXP '^[0-9]{4}-[0-9]{1,2}-[0-9]{1,2}$'
THEN STR_TO_DATE(TRIM(variable.`ProbationStartDateText`), '%Y-%m-%d')
ELSE NULL
END,
CASE
WHEN TRIM(variable.`ProbationEndDateText`) REGEXP '^[0-9]{4}-[0-9]{1,2}-[0-9]{1,2}$'
THEN STR_TO_DATE(TRIM(variable.`ProbationEndDateText`), '%Y-%m-%d')
ELSE NULL
END,
variable.`ProbationTerm`,
CASE WHEN TRIM(variable.`ProbationSalaryText`) REGEXP '^-?[0-9]+([.][0-9]+)?$'
THEN CAST(TRIM(variable.`ProbationSalaryText`) AS DECIMAL(18,2)) ELSE NULL END,
CASE WHEN TRIM(variable.`BaseSalaryText`) REGEXP '^-?[0-9]+([.][0-9]+)?$'
THEN CAST(TRIM(variable.`BaseSalaryText`) AS DECIMAL(18,2)) ELSE NULL END,
CASE WHEN TRIM(variable.`PositionSalaryText`) REGEXP '^-?[0-9]+([.][0-9]+)?$'
THEN CAST(TRIM(variable.`PositionSalaryText`) AS DECIMAL(18,2)) ELSE NULL END,
CASE WHEN TRIM(variable.`PerformanceAllowanceText`) REGEXP '^-?[0-9]+([.][0-9]+)?$'
THEN CAST(TRIM(variable.`PerformanceAllowanceText`) AS DECIMAL(18,2)) ELSE NULL END,
CASE WHEN TRIM(variable.`AttendanceBonusText`) REGEXP '^-?[0-9]+([.][0-9]+)?$'
THEN CAST(TRIM(variable.`AttendanceBonusText`) AS DECIMAL(18,2)) ELSE NULL END,
CASE WHEN TRIM(variable.`RegularSalaryText`) REGEXP '^-?[0-9]+([.][0-9]+)?$'
THEN CAST(TRIM(variable.`RegularSalaryText`) AS DECIMAL(18,2)) ELSE NULL END,
variable.`WorkCity`,
variable.`PositionName`,
variable.`EmployeeNo`,
COALESCE(variable.`VariablesJson`, JSON_OBJECT()),
1,
COALESCE(task.`AuditedAt`, employee.`CreateTime`, NOW(3)),
'enable',
COALESCE(employee.`CreateTime`, NOW(3)),
employee.`CreateUserId`,
employee.`CreateUser`,
0
FROM `ob_onboarding_task` task
INNER JOIN `ob_employee` employee
ON employee.`Id` = task.`EmployeeId`
INNER JOIN `ob_task_contract` contract
ON contract.`TaskId` = task.`Id`
LEFT JOIN (
SELECT
row_value.`TaskContractId`,
MAX(CASE WHEN row_value.`VariableCode` = 'hr.ContractStartDate' THEN row_value.`VariableValue` END) AS `ContractStartDateText`,
MAX(CASE WHEN row_value.`VariableCode` = 'hr.ContractEndDate' THEN row_value.`VariableValue` END) AS `ContractEndDateText`,
MAX(CASE WHEN row_value.`VariableCode` = 'hr.ContractTerm' THEN row_value.`VariableValue` END) AS `ContractTerm`,
MAX(CASE WHEN row_value.`VariableCode` = 'hr.ProbationStartDate' THEN row_value.`VariableValue` END) AS `ProbationStartDateText`,
MAX(CASE WHEN row_value.`VariableCode` = 'hr.ProbationEndDate' THEN row_value.`VariableValue` END) AS `ProbationEndDateText`,
MAX(CASE WHEN row_value.`VariableCode` = 'hr.ProbationTerm' THEN row_value.`VariableValue` END) AS `ProbationTerm`,
MAX(CASE WHEN row_value.`VariableCode` = 'hr.ProbationSalary' THEN row_value.`VariableValue` END) AS `ProbationSalaryText`,
MAX(CASE WHEN row_value.`VariableCode` = 'hr.BaseSalary' THEN row_value.`VariableValue` END) AS `BaseSalaryText`,
MAX(CASE WHEN row_value.`VariableCode` = 'hr.PositionSalary' THEN row_value.`VariableValue` END) AS `PositionSalaryText`,
MAX(CASE WHEN row_value.`VariableCode` = 'hr.PerformanceAllowance' THEN row_value.`VariableValue` END) AS `PerformanceAllowanceText`,
MAX(CASE WHEN row_value.`VariableCode` = 'hr.AttendanceBonus' THEN row_value.`VariableValue` END) AS `AttendanceBonusText`,
MAX(CASE WHEN row_value.`VariableCode` = 'hr.RegularSalary' THEN row_value.`VariableValue` END) AS `RegularSalaryText`,
MAX(CASE WHEN row_value.`VariableCode` = 'hr.WorkCity' THEN row_value.`VariableValue` END) AS `WorkCity`,
MAX(CASE WHEN row_value.`VariableCode` = 'hr.PositionName' THEN row_value.`VariableValue` END) AS `PositionName`,
MAX(CASE WHEN row_value.`VariableCode` = 'hr.EmployeeNo' THEN row_value.`VariableValue` END) AS `EmployeeNo`,
JSON_OBJECTAGG(
row_value.`VariableCode`,
JSON_OBJECT(
'variableName', row_value.`VariableName`,
'variableType', row_value.`VariableType`,
'dataType', row_value.`DataType`,
'variableValue', row_value.`VariableValue`,
'sourceType', row_value.`SourceType`,
'isManualOverride', row_value.`IsManualOverride`,
'sortCode', row_value.`SortCode`
)
) AS `VariablesJson`
FROM `ob_task_contract_variable` row_value
WHERE row_value.`IsDelete` = 0
GROUP BY row_value.`TaskContractId`
) variable
ON variable.`TaskContractId` = contract.`Id`
WHERE task.`EmployeeId` IS NOT NULL
AND task.`IsDelete` = 0
AND employee.`IsDelete` = 0
AND contract.`IsDelete` = 0;
SELECT
COUNT(*) AS `员工合同快照数量`,
COUNT(DISTINCT `EmployeeId`) AS `已归档员工数量`,
COUNT(DISTINCT `TaskContractId`) AS `已归档合同数量`
FROM `ob_employee_contract_snapshot`
WHERE `IsDelete` = 0;