This commit is contained in:
fuenmao
2026-08-25 20:37:17 +08:00
parent 38801533e9
commit be20a31332
22 changed files with 1090 additions and 336 deletions
@@ -96,6 +96,47 @@ public class OnboardingPublicFormFieldOutput
public bool Required { get; set; }
}
/// <summary>
/// 员工端需要填写的合同员工变量。
/// </summary>
public class OnboardingPublicContractVariableOutput
{
/// <summary>
/// 合同变量编码。
/// </summary>
public string VariableCode { get; set; }
/// <summary>
/// 合同变量显示名称。
/// </summary>
public string VariableName { get; set; }
/// <summary>
/// 变量来源类型。
/// </summary>
public string VariableType { get; set; }
/// <summary>
/// 变量数据类型。
/// </summary>
public string DataType { get; set; }
/// <summary>
/// 变量默认值。
/// </summary>
public string DefaultValue { get; set; }
/// <summary>
/// 选择型变量的可选项 JSON。
/// </summary>
public string OptionsJson { get; set; }
/// <summary>
/// 是否必填。
/// </summary>
public bool Required { get; set; }
}
/// <summary>
/// 员工端材料上传要求。
/// </summary>
@@ -166,4 +207,9 @@ public class OnboardingTaskPublicDetailOutput
/// 候选人已上传材料列表。
/// </summary>
public List<ObTaskMaterial> Materials { get; set; }
/// <summary>
/// 合同中由员工填写的扩展变量。
/// </summary>
public List<OnboardingPublicContractVariableOutput> ContractVariables { get; set; }
}
@@ -19,7 +19,7 @@ public class OnboardingTaskService : IOnboardingTaskService
}
/// <summary>
/// 校验公司、岗位和入职模板后创建任务,并冻结合同、补充字段及材料要求。
/// 校验公司、岗位和入职模板后创建任务,并冻结合同及材料要求。
/// </summary>
public async Task<OnboardingTaskCreatedOutput> Create(OnboardingTaskCreateInput input)
{
@@ -53,10 +53,6 @@ public class OnboardingTaskService : IOnboardingTaskService
if (contractConfigs.Count == 0)
throw Oops.Bah("入职模板尚未配置合同文件");
var fieldConfigs = await _db.Queryable<ObOnboardingTemplateFormField>()
.Where(item => item.OnboardingTemplateId == onboardingTemplate.Id)
.OrderBy(item => item.SortCode)
.ToListAsync();
var materialConfigs = await _db.Queryable<ObOnboardingTemplateMaterial>()
.Where(item => item.OnboardingTemplateId == onboardingTemplate.Id)
.OrderBy(item => item.SortCode)
@@ -73,14 +69,12 @@ public class OnboardingTaskService : IOnboardingTaskService
if (enabledVersionCount != versionIds.Count)
throw Oops.Bah("入职模板包含未启用的合同版本,请先调整模板配置");
var fieldIds = fieldConfigs.Select(item => item.FieldId).Distinct().ToList();
var fields = fieldIds.Count == 0
? new List<ObFormField>()
: await _db.Queryable<ObFormField>().Where(item => fieldIds.Contains(item.Id)).ToListAsync();
var materialIds = materialConfigs.Select(item => item.MaterialTypeId).Distinct().ToList();
var materialTypes = materialIds.Count == 0
? new List<ObMaterialType>()
: await _db.Queryable<ObMaterialType>().Where(item => materialIds.Contains(item.Id)).ToListAsync();
if (materialTypes.Count != materialIds.Count)
throw Oops.Bah("入职模板包含不存在的材料类型,请先调整模板配置");
var expiryConfig = await _configService.GetByConfigKey(
CateGoryConst.CONFIG_BIZ_DEFINE,
@@ -108,6 +102,8 @@ public class OnboardingTaskService : IOnboardingTaskService
Remark = input.Remark
};
ValidateInitialContractDateRanges(input.ContractVariables);
await _db.Ado.BeginTranAsync();
try
{
@@ -121,6 +117,15 @@ public class OnboardingTaskService : IOnboardingTaskService
ExpiresAt = expiresAt
}).ExecuteCommandAsync();
// 初始化空白的员工入职登记表
await _db.Insertable(new ObTaskEmployeeInfo
{
Id = global::SimpleAdmin.Core.Utils.CommonUtils.GetSingleId(),
TaskId = taskId,
Status = CommonStatusConst.ENABLE,
CreateTime = DateTime.Now
}).ExecuteCommandAsync();
var contracts = contractConfigs.Select(config =>
{
var template = contractTemplates.First(item => item.Id == config.ContractTemplateId);
@@ -138,27 +143,6 @@ public class OnboardingTaskService : IOnboardingTaskService
}).ToList();
await _db.Insertable(contracts).ExecuteCommandAsync();
if (fieldConfigs.Count > 0)
{
var fieldSnapshots = fieldConfigs.Select(config =>
{
var field = fields.First(item => item.Id == config.FieldId);
return new ObTaskFormRequirement
{
Id = global::SimpleAdmin.Core.Utils.CommonUtils.GetSingleId(),
TaskId = taskId,
FieldId = field.Id,
FieldCode = field.FieldCode,
FieldName = field.FieldName,
DataType = field.DataType,
OptionsJson = field.OptionsJson,
Required = config.Required,
SortCode = config.SortCode
};
}).ToList();
await _db.Insertable(fieldSnapshots).ExecuteCommandAsync();
}
if (materialConfigs.Count > 0)
{
var materialSnapshots = materialConfigs.Select(config =>
@@ -212,8 +196,12 @@ public class OnboardingTaskService : IOnboardingTaskService
var definitions = await _db.Queryable<ObTemplateVariable>()
.Where(item => versionIds.Contains(item.TemplateVersionId)
&& item.HrEditable
&& (item.VariableType == ContractVariableType.Contract
|| item.VariableType == ContractVariableType.Company))
&& (item.VariableType == "hr"
|| item.VariableType == "contract"
|| item.VariableType == "company"
|| item.VariableType == ContractVariableType.Contract
|| item.VariableType == ContractVariableType.Company
|| item.VariableCode.StartsWith("hr.")))
.ToListAsync();
var duplicateInput = inputs
@@ -268,4 +256,42 @@ public class OnboardingTaskService : IOnboardingTaskService
if (changedRows.Count > 0)
await _db.Updateable(changedRows).ExecuteCommandAsync();
}
/// <summary>
/// 校验人事创建任务时填写的合同日期先后关系。
/// </summary>
private static void ValidateInitialContractDateRanges(
List<OnboardingInitialContractVariableInput> inputs)
{
inputs ??= new List<OnboardingInitialContractVariableInput>();
foreach (var group in inputs.GroupBy(item => item.ContractTemplateVersionId))
{
ValidateDateRange(group, "hr.ContractStartDate", "hr.ContractEndDate", "合同");
ValidateDateRange(group, "hr.ProbationStartDate", "hr.ProbationEndDate", "试用期");
}
}
/// <summary>
/// 校验同一合同版本内一组开始、结束日期。
/// </summary>
private static void ValidateDateRange(
IEnumerable<OnboardingInitialContractVariableInput> inputs,
string startCode,
string endCode,
string rangeName)
{
var startValue = inputs.FirstOrDefault(item =>
string.Equals(item.VariableCode, startCode, StringComparison.OrdinalIgnoreCase))?.VariableValue;
var endValue = inputs.FirstOrDefault(item =>
string.Equals(item.VariableCode, endCode, StringComparison.OrdinalIgnoreCase))?.VariableValue;
if (string.IsNullOrWhiteSpace(startValue) || string.IsNullOrWhiteSpace(endValue))
return;
if (!DateTime.TryParse(startValue, out var startDate))
throw Oops.Bah($"{rangeName}开始日期格式不正确");
if (!DateTime.TryParse(endValue, out var endDate))
throw Oops.Bah($"{rangeName}结束日期格式不正确");
if (endDate.Date < startDate.Date)
throw Oops.Bah($"{rangeName}结束日期不能早于开始日期");
}
}